From 67d7a37e3f854ef536111ef094ec1bfcc6d6897d Mon Sep 17 00:00:00 2001 From: "M. Sallermann" Date: Thu, 11 Feb 2021 14:52:21 +0100 Subject: [PATCH] Configuration: Fix for antiparallel spins in Homogeneous_Rotation. If two images had antiparallel spins, eg +z and -z, the resulting interpolated spins were not of unit length. This was due to the definition of the rotation axis as s1xs2, resulting in the null vector. The new behaviour is that either ex or ey is chosen as rotation axis and a warning is logged. --- core/src/utility/Configuration_Chain.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/core/src/utility/Configuration_Chain.cpp b/core/src/utility/Configuration_Chain.cpp index 224771fa1..48ec24cd4 100644 --- a/core/src/utility/Configuration_Chain.cpp +++ b/core/src/utility/Configuration_Chain.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -31,12 +32,24 @@ namespace Utility scalar angle, rot_angle; Vector3 rot_axis; + Vector3 ex = {1,0,0}; + Vector3 ey = {0,1,0}; + bool antiparallel = false; for( int i = 0; i < c->images[0]->nos; ++i ) { rot_angle = Engine::Vectormath::angle(spins_1[i], spins_2[i]); rot_axis = spins_1[i].cross(spins_2[i]).normalized(); + if(std::abs(rot_angle - Constants::Pi) < 1e-4) // If spins are antiparallel, we choose an arbitrary rotation axis + { + antiparallel = true; + if(std::abs(spins_1[i].dot(ex)) - 1 > 1e-4) + rot_axis = ex; + else + rot_axis = ey; + } + // If they are not strictly parallel we can rotate if( rot_angle > 1e-8 ) { @@ -55,6 +68,8 @@ namespace Utility } } } + if(antiparallel) + Log(Log_Level::Warning, Log_Sender::All, "For the interpolation of antiparallel spins an arbitrary rotation axis has been chosen."); } }//end namespace Configuration_Chain }//end namespace Utility \ No newline at end of file