diff --git a/source/KKRnano/source/KKRnano.F90 b/source/KKRnano/source/KKRnano.F90 index 4118a7ec29be4448e5e263f96714714d35ff7194..d236a131c912db11419697d0223e924bbe435dd6 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 9bc6e4fe624d983cd41ac190456f5463c914c85b..dd7f93a9b0e3d9cfcf8ba4ce4f923cbba298e089 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 c157fdfc2e661a7270bd74c75b8302e25bd7fffd..6076fbb99de51446fab7c08dec9ca23ec3a17e55 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 76d54bfa3004c6e0b19bcd9a06489ef4740b1396..8d0cda312e137b2b475760994e0ff4ac0ef0aae2 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 -------------------------------------------------- !----------------------------------------------------------------------------