From b0b7678a97e97287e88f9d4e4425a5d7e66bb992 Mon Sep 17 00:00:00 2001
From: Nicolas Essing <nicolas.essing@rwth-aachen.de>
Date: Fri, 21 Jan 2022 15:47:04 +0100
Subject: [PATCH] Fixing a critical bug for constraint magnetism.

The constraining fields were only updated in the master group, so not on
all ranks. Some ranks kept applying the initial constraining fields.

To fix this, the constraining fields are now communicated similarly to
the potential.
---
 source/KKRnano/source/KKRnano.F90             |  8 ++++-
 source/KKRnano/source/Makefile                |  2 +-
 source/KKRnano/source/bfield/bfield.f90       |  6 ++++
 .../source/parallel/KKRnano_Comm_mod.F90      | 32 ++++++++++++++++++-
 4 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/source/KKRnano/source/KKRnano.F90 b/source/KKRnano/source/KKRnano.F90
index 4118a7ec2..d236a131c 100644
--- a/source/KKRnano/source/KKRnano.F90
+++ b/source/KKRnano/source/KKRnano.F90
@@ -24,7 +24,7 @@ program KKRnano
 
   use KKRnanoParallel_mod, only: KKRnanoParallel, create, destroy
 
-  use KKRnano_Comm_mod, only: setKKRnanoNumThreads, printKKRnanoInfo, communicatePotential
+  use KKRnano_Comm_mod, only: setKKRnanoNumThreads, printKKRnanoInfo, communicatePotential, communicateNoncoBfields
 
   use main2_aux_mod, only: is_abort_by_rank0
   use EnergyMesh_mod, only: EnergyMesh, create, destroy, load, store, update, broadcast
@@ -266,6 +266,12 @@ program KKRnano
         atomdata => getAtomdata(calc_data, ila)
         call communicatePotential(mp, atomdata%potential%VISP, atomdata%potential%VINS, atomdata%core%ECORE)
       enddo ! ila
+      ! If noncollinear magnetic fields are used, communicate them analogously to the potentials
+      if (params%noncobfield) then
+        do ila = 1, calc_data%num_local_atoms
+          call communicateNoncoBfields(mp, calc_data%bfields(ila))
+        end do
+      end if
 
       ! Core relaxation - only mastergroup needs results
       if (mp%isInMasterGroup.and.params%npol /= 0) then
diff --git a/source/KKRnano/source/Makefile b/source/KKRnano/source/Makefile
index 9bc6e4fe6..dd7f93a9b 100644
--- a/source/KKRnano/source/Makefile
+++ b/source/KKRnano/source/Makefile
@@ -470,7 +470,7 @@ ProcessKKRresults_mod.o: arraytest2_mod.o KKRnanoParallel_mod.o AtomicForce_mod.
 NearField_kkr_mod.o: Constants_mod.o
 NearField_calc_mod.o: RadialMeshData_mod.o NearField_com_mod.o BasisAtom_mod.o CalculationData_mod.o
 NearField_mod.o: Harmonics_mod.o MadelungCalculator_mod.o Constants_mod.o NearField_kkr_mod.o
-KKRnano_Comm_mod.o: KKRnanoParallel_mod.o jij_calc_mod.o comm_patterns_mod.o Exceptions_mod.o
+KKRnano_Comm_mod.o: KKRnanoParallel_mod.o jij_calc_mod.o comm_patterns_mod.o Exceptions_mod.o bfield.o
 InputParams_mod.o: ConfigReader_mod.o
 PolygonFaces_mod.o: Constants_mod.o
 ShapeGeometryHelpers_mod.o: Exceptions_mod.o Constants_mod.o
diff --git a/source/KKRnano/source/bfield/bfield.f90 b/source/KKRnano/source/bfield/bfield.f90
index c157fdfc2..6076fbb99 100644
--- a/source/KKRnano/source/bfield/bfield.f90
+++ b/source/KKRnano/source/bfield/bfield.f90
@@ -41,6 +41,12 @@ module mod_bfield
 
     ! Precalculated intermediate results
     double precision, dimension(:,:,:), allocatable :: thetallmat !! shapefun in the ll' expansion
+
+    ! Notes on parallelization: bfield_ext is read by each rank and does not
+    ! change. bfield_constr is updated only by the master group and communicated
+    ! to all other ranks. mag_torque, mag_mom and mean_xc_bfield are calculated
+    ! by all ranks. thetallmat is calculated by all ranks before the calculation
+    ! and does not change.
   end type
 
 contains
diff --git a/source/KKRnano/source/parallel/KKRnano_Comm_mod.F90 b/source/KKRnano/source/parallel/KKRnano_Comm_mod.F90
index 76d54bfa3..8d0cda312 100644
--- a/source/KKRnano/source/parallel/KKRnano_Comm_mod.F90
+++ b/source/KKRnano/source/parallel/KKRnano_Comm_mod.F90
@@ -23,7 +23,7 @@ module KKRnano_Comm_mod
   private
   public :: jijSpinCommunication_com, jijLocalEnergyIntegration, jijReduceIntResults_com
   public :: collectMSResults_com, redistributeInitialGuess
-  public :: setKKRnanoNumThreads, printKKRnanoInfo, communicatePotential
+  public :: setKKRnanoNumThreads, printKKRnanoInfo, communicatePotential, communicateNoncoBfields
 
   interface redistributeInitialGuess
     module procedure redistributeInitialGuess_c, redistributeInitialGuess_z
@@ -242,6 +242,36 @@ module KKRnano_Comm_mod
 
   endsubroutine ! communicate
 
+  subroutine communicateNoncoBfields(mp, bfields)
+    use KKRnanoParallel_mod, only: KKRnanoParallel, getNumSERanks, mapToWorldRankSE
+    use comm_patternsD_mod, only: comm_bcastD
+    use mod_bfield, only: bfield_data
+
+    type(KKRnanoParallel), intent(in) :: mp
+    type(bfield_data), intent(inout)  :: bfields
+
+    integer, allocatable :: ranks(:)
+    integer :: memory_stat, owner, numSERanks, ind
+
+    ! Get number of MPI ranks for this atom
+    numSERanks = getNumSERanks(mp)
+
+    ! Get owner rank for this atom
+    owner = mapToWorldRankSE(mp, mp%myAtomId, 1)
+
+    ! Get all other ranks for this atom
+    ALLOCATECHECK(ranks(numSERanks))
+    do ind = 1, numSERanks
+      ranks(ind) = mapToWorldRankSE(mp, mp%myAtomId, ind)
+    enddo
+
+    ! Brodcast data from owner of this atom to all other ranks dealing with this atom
+    call comm_bcastD(mp%myWorldRank, bfields%bfield_constr, 3, ranks, owner)
+
+    DEALLOCATECHECK(ranks)
+
+  end subroutine
+
 ! ---------------------- Jij --------------------------------------------------
 
   !----------------------------------------------------------------------------
-- 
GitLab