TABLE OF CONTENTS


ABINIT/m_spin_mover [ Modules ]

[ Top ] [ Modules ]

NAME

 m_spin_mover

FUNCTION

 This module contains the spin mover, which controls how the spin 


 Datatypes:

 * spin_mover_t

 Subroutines:

 * spin_mover_t_initialize
 * spin_mover_t_run_one_step
 * spin_mover_t_run_time
 * TODO: update this when F2003 documentation format decided.

COPYRIGHT

 Copyright (C) 2001-2024 ABINIT group (hexu)
 This file is distributed under the terms of the
 GNU General Public License, see ~abinit/COPYING
 or http://www.gnu.org/copyleft/gpl.txt .
 For the initials of contributors, see ~abinit/doc/developers/contributors.txt .

SOURCE

31 #if defined HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34 
35 #include "abi_common.h"
36 
37 
38 module m_spin_mover
39 
40   use defs_basis
41   use m_nctk
42 #if defined HAVE_NETCDF
43   use netcdf
44 #endif
45   use m_errors
46   use m_abicore
47   use m_xmpi
48   use m_io_tools, only : get_unit, open_file, close_unit
49   use m_mpi_scheduler, only: mpi_scheduler_t, init_mpi_info
50   use m_mathfuncs, only : cross
51   use m_spin_observables , only : spin_observable_t
52   use m_spin_potential, only:  spin_potential_t
53   use m_spin_hist, only: spin_hist_t
54   use m_spin_ncfile, only: spin_ncfile_t
55   use m_multibinit_dataset, only: multibinit_dtset_type
56   use m_multibinit_cell, only: mbcell_t, mbsupercell_t
57   use m_random_xoroshiro128plus, only: set_seed, rand_normal_array, rng_t
58   use m_abstract_potential, only: abstract_potential_t
59   use m_abstract_mover, only: abstract_mover_t
60   use m_spin_mc_mover, only : spin_mc_t
61   use m_hashtable_strval, only: hash_table_t
62   implicit none
63   private

m_spin_mover/current_spin [ Functions ]

[ Top ] [ m_spin_mover ] [ Functions ]

NAME

 current_spin

FUNCTION

 return the current spin state

INPUTS

OUTPUT

SOURCE

1060   function current_spin(self) result(ret)
1061     class(spin_mover_t), target, intent(inout) :: self
1062     real(dp), pointer :: ret(:,:)
1063     integer :: i
1064     i=self%hist%findIndex(step=0)
1065     ret => self%hist%S(:,:,i)
1066   end function current_spin

m_spin_mover/finalize [ Functions ]

[ Top ] [ m_spin_mover ] [ Functions ]

NAME

 finalize

FUNCTION

 finalize spin mover.

INPUTS

OUTPUT

NOTES

   does nothing. But it's better to preserve initialize-finalize symmetry.

SOURCE

1088   subroutine finalize(self)
1089 
1090     class(spin_mover_t), intent(inout):: self
1091     if(allocated(self%gyro_ratio) ) then
1092        ABI_FREE(self%gyro_ratio)
1093     end if
1094 
1095     if(allocated(self%damping) ) then
1096        ABI_FREE(self%damping)
1097     end if
1098 
1099     if(allocated(self%gamma_l) ) then
1100        ABI_FREE(self%gamma_l)
1101     end if
1102 
1103     if(allocated(self%H_lang_coeff) ) then
1104        ABI_FREE(self%H_lang_coeff)
1105     end if
1106 
1107     if(allocated(self%ms) ) then
1108        ABI_FREE(self%ms)
1109     end if
1110 
1111 
1112 
1113     if(self%method==3) then
1114        call self%spin_mc%finalize()
1115     end if
1116 
1117     if(allocated(self%Stmp)) then
1118        ABI_FREE(self%Stmp)
1119     end if
1120 
1121     if(allocated(self%Stmp2)) then
1122        ABI_FREE(self%Stmp2)
1123     end if
1124 
1125 
1126     if(allocated(self%Heff_tmp)) then
1127        ABI_FREE(self%Heff_tmp)
1128     end if
1129 
1130     if(allocated(self%Htmp)) then
1131        ABI_FREE(self%Htmp)
1132     end if
1133 
1134     if(allocated(self%Hrotate)) then
1135        ABI_FREE(self%Hrotate)
1136     end if
1137 
1138     if(allocated(self%H_lang)) then
1139        ABI_FREE(self%H_lang)
1140     end if
1141 
1142     if(allocated(self%buffer)) then
1143        ABI_FREE(self%buffer)
1144     end if
1145 
1146 
1147     nullify(self%supercell)
1148     nullify(self%params)
1149     nullify(self%rng)
1150     call self%mps%finalize()
1151     call self%hist%finalize()
1152     call self%spin_ob%finalize()
1153     !call self%spin_ncfile%close()
1154     call self%spin_ob%finalize()
1155   end subroutine finalize

m_spin_mover/initialize [ Functions ]

[ Top ] [ m_spin_mover ] [ Functions ]

NAME

  initialize

FUNCTION

  initialize the spin mover

INPUTS

OUTPUT

NOTES

SOURCE

132   subroutine initialize(self, params, supercell, rng)
133     class(spin_mover_t), intent(inout) :: self
134     type(multibinit_dtset_type), target :: params
135     type(mbsupercell_t), target :: supercell
136     type(rng_t), target, intent(in) :: rng
137     integer ::  nspin
138 
139     integer :: master, my_rank, comm, nproc, ierr
140     logical :: iam_master
141     call init_mpi_info(master, iam_master, my_rank, comm, nproc) 
142 
143     self%params=>params
144     self%supercell=>supercell
145     self%rng => rng
146     if (iam_master) then
147        nspin=supercell%spin%nspin
148        self%nspin=nspin
149        self%dt= params%spin_dt
150        self%thermal_time= params%spin_ntime_pre * self%dt
151        self%total_time= params%spin_ntime * self%dt
152        self%temperature=params%spin_temperature
153        if(params%spin_dynamics>=0) then
154           self%method=params%spin_dynamics
155        endif
156        if(params%spin_init_state==3) then
157          self%init_qpoint = params%spin_init_qpoint
158          self%init_rotate_axis = params%spin_init_rotate_axis
159          self%init_orientation = params%spin_init_orientation
160        endif
161     end if
162     if(params%spin_dynamics==3) then ! Monte carlo
163        call self%spin_mc%initialize(nspin=nspin, angle=1.0_dp, temperature=params%spin_temperature)
164     end if
165     call xmpi_bcast(self%nspin, master, comm, ierr)
166     call xmpi_bcast(self%dt, master, comm, ierr)
167     call xmpi_bcast(self%thermal_time, master, comm, ierr)
168     call xmpi_bcast(self%total_time, master, comm, ierr)
169     call xmpi_bcast(self%temperature, master, comm, ierr)
170     call xmpi_bcast(self%method, master, comm, ierr)
171 
172     ABI_MALLOC(self%ms, (self%nspin) )
173     ABI_MALLOC(self%gyro_ratio, (self%nspin) )
174     ABI_MALLOC(self%damping, (self%nspin) )
175     ABI_MALLOC(self%gamma_l, (self%nspin) )
176     ABI_MALLOC(self%H_lang_coeff, (self%nspin) )
177 
178     ABI_MALLOC(self%Heff_tmp, (3,self%nspin) )
179     ABI_MALLOC(self%Htmp, (3,self%nspin) )
180     ABI_MALLOC(self%Hrotate, (3,self%nspin) )
181     ABI_MALLOC(self%Stmp, (3,self%nspin) )
182     ABI_MALLOC(self%Stmp2, (3,self%nspin) )
183     ABI_MALLOC(self%buffer, (3,self%nspin) )
184     ABI_MALLOC(self%H_lang, (3,self%nspin) )
185 
186     self%gamma_l_calculated=.False.
187     call self%mps%initialize(ntasks=nspin,master=master, comm=comm)
188 
189 
190     call xmpi_bcast(params%spin_damping, master, comm, ierr)
191 
192     if (iam_master) then
193        if (params%spin_damping >=0) then
194           self%damping(:)= params%spin_damping
195        else
196           self%damping(:)=supercell%spin%gilbert_damping(:)
197        end if
198 
199        self%gyro_ratio(:)=supercell%spin%gyro_ratio(:)
200        self%ms(:)=supercell%spin%ms(:)
201     endif
202 
203     call xmpi_bcast(self%damping, master, comm, ierr)
204     call xmpi_bcast(self%gyro_ratio, master, comm, ierr)
205     call xmpi_bcast(self%ms, master, comm, ierr)
206     call self%set_temperature(temperature=params%spin_temperature)
207 
208     ! Hist and set initial spin state
209     if(iam_master) then
210        call self%hist%initialize(nspin=self%nspin, &
211             &   mxhist=3, has_latt=.False.)
212        call self%hist%set_params(spin_nctime=params%spin_nctime, &
213             &     spin_temperature=params%spin_temperature)
214     endif
215 
216     call self%set_initial_state(mode=params%spin_init_state)
217 
218     ! observable
219     if(iam_master) then
220        call self%spin_ob%initialize(self%supercell, params)
221     endif
222 
223   end subroutine initialize

m_spin_mover/run_MvT [ Functions ]

[ Top ] [ m_spin_mover ] [ Functions ]

NAME

 run_MvT

FUNCTION

 run M vs Temperature

INPUTS

 pot: potential
 T_start, Tend, T_nstep

OUTPUT

SOURCE

 879   subroutine  run_MvT(self, pot, ncfile_prefix, displacement, strain, spin, lwf, energy_table)
 880     class(spin_mover_t), intent(inout) :: self
 881     class(abstract_potential_t), intent(inout) :: pot
 882     real(dp), optional, intent(inout) :: displacement(:,:), strain(:,:), lwf(:), spin(:,:)
 883     character(fnlen), intent(inout) :: ncfile_prefix
 884     type(hash_table_t), optional, intent(inout) :: energy_table
 885     real(dp) :: T_start, T_end
 886     integer :: T_nstep
 887     !type(spin_ncfile_t) :: spin_ncfile
 888     character(len=4) :: post_fname
 889     real(dp) :: T, T_step
 890     integer :: i, ii, Tfile, iostat
 891     character(len=90) :: msg
 892     character(len=4200) :: Tmsg ! to write to var T file
 893     character(len=150) :: iomsg
 894     character(fnlen) :: Tfname ! file name for output various T calculation
 895     real(dp), allocatable :: Tlist(:), chi_list(:), Cv_list(:), binderU4_list(:)
 896     real(dp), allocatable :: Mst_sub_norm_list(:, :)
 897     real(dp), allocatable ::  Mst_norm_total_list(:)
 898 
 899     integer :: master, my_rank, comm, nproc, ierr
 900     logical :: iam_master
 901     call init_mpi_info(master, iam_master, my_rank, comm, nproc) 
 902 
 903     if (iam_master) then
 904        T_start=self%params%spin_temperature_start
 905        T_end=self%params%spin_temperature_end
 906        T_nstep=self%params%spin_temperature_nstep
 907        Tfile=get_unit()
 908        Tfname = trim(ncfile_prefix)//'.varT'
 909        iostat=open_file(file=Tfname, unit=Tfile, iomsg=iomsg )
 910        if (T_nstep<=1) then
 911           T_step=0.0
 912        else
 913           T_step=(T_end-T_start)/(T_nstep-1)
 914        endif
 915        write(msg, "(A52, ES13.5, A11, ES13.5, A1)") & 
 916             & "Starting temperature dependent calculations. T from ", &
 917             & T_start*Ha_K, "K to ", T_end*Ha_K, " K."
 918        call wrtout(std_out, msg, "COLL")
 919        call wrtout(ab_out, msg, "COLL")
 920 
 921        ABI_MALLOC(Tlist, (T_nstep))
 922        ABI_MALLOC(chi_list, (T_nstep))
 923        ABI_MALLOC(Cv_list, (T_nstep))
 924        ABI_MALLOC(binderU4_list, (T_nstep))
 925        ABI_MALLOC(Mst_sub_norm_list, (self%spin_ob%nsublatt, T_nstep))
 926        ABI_MALLOC( Mst_norm_total_list, (T_nstep))
 927     end if
 928 
 929     call xmpi_bcast(T_nstep, 0, comm, ierr)
 930 
 931     ! write header of varT file
 932     if(iam_master) then
 933        write(Tmsg, "(A1, 1X, A11, 3X, A13, 3X, A13, 3X, A13, 3X, A13, 3X, *(I13, 3X) )" ) &
 934             "#", "Temperature (K)", "Cv (1)", "chi (1)",  "BinderU4 (1)", "Mst/Ms(1)", (ii, ii=1, self%spin_ob%nsublatt)
 935        call wrtout(Tfile, Tmsg, "COLL")
 936        flush(Tfile)
 937     endif
 938 
 939 
 940 
 941 
 942     do i=1, T_nstep
 943        if(iam_master) then
 944           T=T_start+(i-1)*T_step
 945           msg=repeat("=", 79)
 946           call wrtout(std_out, msg, "COLL")
 947           call wrtout(ab_out, msg, "COLL")
 948 
 949           write(msg, "(A13, 5X, ES13.5, A3)") "Temperature: ", T*Ha_K, " K."
 950           call wrtout(std_out, msg, "COLL")
 951           call wrtout(ab_out,  msg, "COLL")
 952 
 953           call self%hist%reset(array_to_zero=.False.)
 954           ! set temperature
 955           ! TODO make this into a subroutine set_params
 956           self%params%spin_temperature=T
 957        endif
 958        call self%set_temperature(temperature=T)
 959        if(iam_master) then
 960           call self%hist%set_params(spin_nctime=self%params%spin_nctime, &
 961                &     spin_temperature=T)
 962           call self%spin_ob%reset(self%params)
 963           ! uncomment if then to use spin initializer at every temperature. otherwise use last temperature
 964           if(i==1) then
 965              call self%set_initial_state(mode=self%params%spin_init_state)
 966           else
 967              call self%hist%inc1()
 968           endif
 969 
 970           write(post_fname, "(I4.4)") i
 971           call self%prepare_ncfile( self%params, &
 972                & trim(ncfile_prefix)//'_T'//post_fname//'_spinhist.nc')
 973           call self%spin_ncfile%write_one_step(self%hist)
 974        endif
 975 
 976        ! run in parallel
 977        call self%run_time(pot, displacement=displacement, strain=strain, spin=spin, &
 978             & lwf=lwf, energy_table=energy_table)
 979 
 980        if(iam_master) then
 981           call self%spin_ncfile%close()
 982           ! save observables
 983           Tlist(i)=T
 984           chi_list(i)=self%spin_ob%chi
 985           Cv_list(i)=self%spin_ob%Cv
 986           binderU4_list(i)=self%spin_ob%binderU4
 987           !Mst_sub_list(:,:,i)=self%spin_ob%Mst_sub(:,:)  ! not useful
 988           Mst_sub_norm_list(:,i)=self%spin_ob%Avg_Mst_sub_norm(:)
 989           Mst_norm_total_list(i)=self%spin_ob%Avg_Mst_norm_total
 990 
 991           ! write to varT file
 992           write(Tmsg, "(2X, F11.5, 3X, ES13.5, 3X, ES13.5, 3X, E13.5, 3X, ES13.5, 3X, *(ES13.5, 3X) )" ) &
 993                   Tlist(i)*Ha_K, Cv_list(i), chi_list(i),  binderU4_list(i), Mst_norm_total_list(i)/self%spin_ob%snorm_total,&
 994                   & (Mst_sub_norm_list(ii,i)/mu_B, ii=1, self%spin_ob%nsublatt)
 995           call wrtout(Tfile, Tmsg, "COLL")
 996           flush(Tfile)
 997 
 998        endif
 999 
1000     end do
1001 
1002 
1003     if(iam_master) then
1004        ! write summary of MvT run
1005        msg=repeat("=", 79)
1006        call wrtout(std_out, msg, "COLL")
1007        call wrtout(ab_out, msg, "COLL")
1008 
1009        write(msg, *) "Summary of various T run: "
1010        call wrtout(std_out, msg, "COLL")
1011        call wrtout(ab_out, msg, "COLL")
1012 
1013        write(msg, "(A1, 1X, A11, 3X, A13, 3X, A13, 3X, A13, 3X, A13)" ) &
1014             "#", "Temperature", "Cv", "chi",  "BinderU4", "Mst"
1015        call wrtout(std_out, msg, "COLL")
1016        call wrtout(ab_out,  msg, "COLL")
1017 
1018        do i = 1, T_nstep
1019           write(msg, "(2X, F11.5, 3X, ES13.5, 3X, ES13.5, 3X, E13.5, 3X, ES13.5 )" ) &
1020                Tlist(i)*Ha_K, Cv_list(i), chi_list(i),  binderU4_list(i), Mst_norm_total_list(i)/self%spin_ob%snorm_total
1021           call wrtout(std_out, msg, "COLL")
1022           call wrtout(ab_out, msg, "COLL")
1023        end do
1024 
1025        msg=repeat("=", 79)
1026        call wrtout(std_out, msg, "COLL")
1027        call wrtout(ab_out, msg, "COLL")
1028 
1029 
1030        ! close varT file
1031        iostat= close_unit(unit=Tfile, iomsg=iomsg)
1032 
1033        ABI_FREE(Tlist)
1034        ABI_FREE(chi_list)
1035        ABI_FREE(Cv_list)
1036        ABI_FREE(binderU4_list)
1037        ABI_FREE(Mst_sub_norm_list)
1038        ABI_FREE( Mst_norm_total_list)
1039 
1040     endif
1041   end subroutine run_MvT

m_spin_mover/spin_mover_t [ Types ]

[ Top ] [ m_spin_mover ] [ Types ]

NAME

 spin_mover_t

FUNCTION

 this type contains the parameters for the spin mover.

 It contains:
 dt: time step
 total_time
 temperature.
 nspin number of magnetic atoms

SOURCE

 82   type, public, extends(abstract_mover_t) :: spin_mover_t
 83      integer :: nspin, method=0
 84      real(dp), allocatable :: gyro_ratio(:), damping(:), gamma_L(:), H_lang_coeff(:), ms(:), Stmp(:,:), Stmp2(:,:)
 85      real(dp), allocatable :: Heff_tmp(:,:), Htmp(:,:), Hrotate(:,:), H_lang(:,:), buffer(:,:)
 86      real(dp) :: init_qpoint(3), init_rotate_axis(3) ! qpoint and rotation axis to set up initial spin configuration
 87      real(dp) :: init_orientation(3) ! spin orientation in primitive cell which is then rotated
 88      type(spin_hist_t) :: hist
 89      logical :: gamma_l_calculated
 90      type(spin_mc_t) :: spin_mc
 91      type(mpi_scheduler_t) :: mps
 92      type(spin_observable_t) :: spin_ob
 93      type(spin_ncfile_t) :: spin_ncfile
 94      type(multibinit_dtset_type), pointer :: params
 95    CONTAINS
 96      procedure :: initialize
 97      procedure :: finalize
 98      procedure :: set_initial_state
 99      procedure :: read_hist_spin_state
100      procedure, private :: run_one_step_DM => spin_mover_t_run_one_step_DM
101      procedure, private :: run_one_step_HeunP => spin_mover_t_run_one_step_HeunP
102      procedure, private :: run_one_step_dummy=> spin_mover_t_run_one_step_dummy
103      procedure, private :: run_one_step_MC=> spin_mover_t_run_one_step_MC
104      procedure :: run_one_step => spin_mover_t_run_one_step
105      procedure :: run_time => spin_mover_t_run_time
106      procedure :: run_MvT
107      procedure :: set_temperature
108      procedure, private :: prepare_ncfile
109      procedure, private ::get_Langevin_Heff
110      procedure :: current_spin
111      procedure :: set_ncfile_name
112   end type spin_mover_t

m_spin_mover/spin_mover_t_run_one_step_dummy [ Functions ]

[ Top ] [ m_spin_mover ] [ Functions ]

NAME

  spin_mover_t_run_one_step_dummy

FUNCTION

 run one spin step using dummy method

INPUTS

 effpot: abstract_potential_t type.
 S_in : input spin. (3*nspin)

OUTPUT

 etot: energy (scalar)

SOURCE

530   subroutine spin_mover_t_run_one_step_dummy(self, effpot, S_in, etot, &
531        & displacement, strain, lwf, energy_table)
532     !class (spin_mover_t), intent(inout):: self
533     class(spin_mover_t), intent(inout):: self
534     class(abstract_potential_t), intent(inout) :: effpot
535 
536     real(dp), optional, intent(inout):: displacement(:,:), &
537          strain(:,:), lwf(:)
538     real(dp), intent(inout) :: S_in(3,self%nspin)
539     real(dp), intent(out) ::  etot
540     type(hash_table_t),optional, intent(inout) :: energy_table
541     integer :: i
542     real(dp) ::  Htmp(3), Ri(3)
543 
544     ! predict
545     etot=0.0
546     self%Heff_tmp(:,:)=0.0
547     call effpot%calculate(displacement=displacement, strain=strain, lwf=lwf, spin=S_in, &
548          & bfield=self%Heff_tmp, energy=etot, energy_table=energy_table)
549     call self%get_Langevin_Heff(self%H_lang)
550     do i=self%mps%istart, self%mps%iend
551        Htmp=self%Heff_tmp(:,i)+self%H_lang(:,i)
552        !Ri = cross(S_in(:,i),Htmp)
553        !dSdt = -self%gamma_L(i)*(Ri+self%damping(i)* cross(S_in(:,i), Ri))
554        Ri=S_in(:,i)!+dSdt*self%dt
555        Ri=Ri/sqrt(Ri(1)*Ri(1)+Ri(2)*Ri(2)+Ri(3)*Ri(3))
556        self%Stmp(:,i)=Ri
557     end do
558     call self%mps%allgatherv_dp2d(self%Stmp2, 3, buffer=self%buffer)
559 
560   end subroutine spin_mover_t_run_one_step_dummy

m_spin_mover/spin_mover_t_run_one_step_HeunP [ Functions ]

[ Top ] [ m_spin_mover ] [ Functions ]

NAME

  spin_mover_t_run_one_step_HeunP

FUNCTION

 run one spin step using HeunP method

INPUTS

 effpot: abstract_potential_t type.
 S_in : input spin. (3*nspin)

OUTPUT

 etot: energy (scalar)

SOURCE

461   subroutine spin_mover_t_run_one_step_HeunP(self, effpot, S_in, &
462        & etot, displacement, strain, lwf, energy_table)
463     !class (spin_mover_t), intent(inout):: self
464     class(spin_mover_t), intent(inout):: self
465     class(abstract_potential_t), intent(inout) :: effpot
466 
467     real(dp), optional, intent(inout):: displacement(:,:), &
468          strain(:,:), lwf(:)
469     real(dp), intent(inout) :: S_in(3,self%nspin)
470     real(dp), intent(out) ::  etot
471     integer :: i
472     real(dp) :: dSdt(3), Htmp(3), Ri(3)
473     type(hash_table_t),optional, intent(inout) :: energy_table
474 
475     !integer :: master, my_rank, comm, nproc, ierr
476     !logical :: iam_master
477     !call init_mpi_info(master, iam_master, my_rank, comm, nproc) 
478 
479     ! predict
480     etot=0.0
481     self%Heff_tmp(:,:)=0.0
482     call effpot%calculate(displacement=displacement, strain=strain, lwf=lwf, spin=S_in, &
483          & bfield=self%Heff_tmp, energy=etot, energy_table=energy_table)
484     call self%get_Langevin_Heff(self%H_lang)
485     do i=self%mps%istart, self%mps%iend
486        Htmp=self%Heff_tmp(:,i)+self%H_lang(:,i)
487        Ri = cross(S_in(:,i),Htmp)
488        dSdt = -self%gamma_L(i)*(Ri+self%damping(i)* cross(S_in(:,i), Ri))
489        Ri=S_in(:,i)+dSdt*self%dt
490        Ri=Ri/sqrt(Ri(1)*Ri(1)+Ri(2)*Ri(2)+Ri(3)*Ri(3))
491        self%Stmp2(:,i)=Ri
492     end do
493     call self%mps%allgatherv_dp2d(self%Stmp2, 3, buffer=self%buffer)
494 
495     ! correction
496     self%Htmp(:,:)=0.0
497     etot=0.0
498     call effpot%calculate(displacement=displacement, strain=strain, lwf=lwf,spin=self%Stmp2, &
499          & bfield=self%Htmp, energy=etot, energy_table=energy_table)
500     do i=self%mps%istart, self%mps%iend
501        Htmp=(self%Heff_tmp(:,i)+self%Htmp(:,i))*0.5_dp+self%H_lang(:,i)
502        Ri = cross(S_in(:,i),Htmp)
503        dSdt = -self%gamma_L(i)*(Ri+self%damping(i)* cross(S_in(:,i), Ri))
504        Ri=S_in(:,i)+dSdt*self%dt
505        Ri=Ri/sqrt(Ri(1)*Ri(1)+Ri(2)*Ri(2)+Ri(3)*Ri(3))
506        self%Stmp(:,i)=Ri
507     end do
508     call self%mps%allgatherv_dp2d(self%Stmp, 3, buffer=self%buffer)
509   end subroutine spin_mover_t_run_one_step_HeunP

m_spin_mover/spin_mover_t_run_time [ Functions ]

[ Top ] [ m_spin_mover ] [ Functions ]

NAME

  spin_mover_t_run_time

FUNCTION

 run all spin step

INPUTS

OUTPUT

NOTES

SOURCE

706   subroutine spin_mover_t_run_time(self, calculator, displacement, strain, spin, lwf, energy_table)
707 
708     class(spin_mover_t), intent(inout):: self
709     class(abstract_potential_t), intent(inout) :: calculator
710 
711     real(dp), optional, intent(inout) :: displacement(:,:), strain(:,:), lwf(:), spin(:,:)
712 
713     type(hash_table_t),optional, intent(inout) :: energy_table
714     !type(spin_hist_t), intent(inout) :: hist
715     !type(spin_ncfile_t), intent(inout) :: ncfile
716     !type(spin_observable_t), intent(inout) :: ob
717     !real(dp) ::  S(3, self%nspin)
718     real(dp):: t, etotal
719     integer :: counter, i, ii
720     character(len=80) :: msg, msg_empty
721 
722     integer :: master, my_rank, comm, nproc
723     logical :: iam_master
724 
725     call init_mpi_info(master, iam_master, my_rank, comm, nproc) 
726 
727     t=0.0
728     counter=0
729     if(iam_master) then
730        msg_empty=ch10
731 
732        msg=repeat("=", 80)
733        call wrtout(std_out,msg,'COLL')
734        call wrtout(ab_out, msg, 'COLL')
735        write(msg, '(A20)') "Spin dynamic steps:"
736        call wrtout(std_out,msg,'COLL')
737        call wrtout(ab_out, msg, 'COLL')
738        msg=repeat("=", 80)
739        call wrtout(std_out,msg,'COLL')
740        call wrtout(ab_out, msg, 'COLL')
741 
742        write(msg, "(A13, 4X, A13, 6X, A13, 4X, A13)")  "Iteration", "time(s)", "Avg_Mst/Ms", "ETOT(Ha/uc)"
743        call wrtout(std_out,msg,'COLL')
744        call wrtout(ab_out, msg, 'COLL')
745 
746        msg=repeat("-", 80)
747        call wrtout(std_out,msg,'COLL')
748        call wrtout(ab_out, msg, 'COLL')
749     end if
750 
751     if (abs(self%thermal_time) > 1e-30) then
752        if (iam_master) then
753           msg="Thermalization run:"
754           call wrtout(std_out,msg,'COLL')
755           call wrtout(ab_out, msg, 'COLL')
756        end if
757 
758        do while(t<self%thermal_time)
759           counter=counter+1
760           call self%run_one_step(effpot=calculator, displacement=displacement, strain=strain, &
761                & lwf=lwf, energy_table=energy_table)
762           if (iam_master) then
763              call self%hist%set_vars( time=t,  inc=.True.)
764              if(mod(counter, self%hist%spin_nctime)==0) then
765                 call self%spin_ob%get_observables( self%hist%S(:,:, self%hist%ihist_prev), &
766                      self%hist%Snorm(:,self%hist%ihist_prev),self%hist%etot(self%hist%ihist_prev))
767                 etotal = energy_table%sum_val()
768                 write(msg, "(A1, 1X, I13, 4X, ES13.5, 4X, ES13.5, 4X, ES13.5)") "-", counter, t*Time_Sec, &
769                      & self%spin_ob%Mst_norm_total/self%spin_ob%Snorm_total, &
770                      & etotal/self%spin_ob%nscell
771                 ! total : 13+4+...= 64 
772                 call wrtout(std_out,msg,'COLL')
773                 call wrtout(ab_out, msg, 'COLL')
774              endif
775           end if
776           t=t+self%dt
777        end do
778 
779        t=0.0
780        counter=0
781        if (iam_master) then
782           call self%hist%reset(array_to_zero=.False.)
783        end if
784     endif
785     if(iam_master) then
786        call self%spin_ob%reset()
787     endif
788 
789     if (iam_master) then
790        msg="Measurement run:"
791        call wrtout(std_out,msg,'COLL')
792        call wrtout(ab_out, msg, 'COLL')
793     end if
794 
795     do while(t<self%total_time)
796        counter=counter+1
797        call self%run_one_step(effpot=calculator, displacement=displacement, strain=strain, &
798             & spin=spin, lwf=lwf, energy_table=energy_table)
799        if (iam_master) then
800           call self%hist%set_vars(time=t,  inc=.True.)
801           call self%spin_ob%get_observables(self%hist%S(:,:, self%hist%ihist_prev), &
802                self%hist%Snorm(:,self%hist%ihist_prev), self%hist%etot(self%hist%ihist_prev))
803           if(modulo(counter, self%hist%spin_nctime)==0) then
804              call self%spin_ncfile%write_one_step(self%hist)
805              etotal = energy_table%sum_val()
806              write(msg, "(A1, 1X, I13, 4X, ES13.5, 4X, ES13.5, 4X, ES13.5)") "-", counter, t*Time_Sec, &
807                   & self%spin_ob%Mst_norm_total/self%spin_ob%Snorm_total, &
808                   & etotal/self%spin_ob%nscell
809              call wrtout(std_out,msg,'COLL')
810              call wrtout(ab_out, msg, 'COLL')
811           endif
812        end if
813        t=t+self%dt
814     enddo
815 
816     if (iam_master) then
817        msg=repeat("-", 80)
818        call wrtout(std_out,msg,'COLL')
819        call wrtout(ab_out, msg, 'COLL')
820 
821        write(msg, "(A27)") "Summary of spin dynamics:"
822        call wrtout(std_out,msg,'COLL')
823        call wrtout(ab_out, msg, 'COLL')
824 
825        write(msg, "(A65)") "At the end of the run, the average spin at each sublattice is"
826        call wrtout(std_out,msg,'COLL')
827        call wrtout(ab_out, msg, 'COLL')
828 
829        write(msg, "(6X, A10, 5X, 3A10, A11)")  'Sublattice', '<M_i>(x)', '<M_i>(y)', '<M_i>(z)', '||<M_i>||'
830        call wrtout(std_out,msg,'COLL')
831        call wrtout(ab_out, msg, 'COLL')
832 
833        do i =1, self%spin_ob%nsublatt
834           write(msg, "(A1, 5X, 2X, I5.4, 8X, 4F10.5)") '-', i, &
835                (self%spin_ob%Mst_sub(ii,i)/self%spin_ob%nspin_sub(i)/mu_B , ii=1, 3), &
836                sqrt(sum((self%spin_ob%Mst_sub(:, i)/self%spin_ob%nspin_sub(i)/mu_B)**2))
837           call wrtout(std_out,msg,'COLL')
838           call wrtout(ab_out, msg, 'COLL')
839        end do
840 
841        call wrtout(std_out,msg_empty,'COLL')
842        call wrtout(ab_out, msg_empty, 'COLL')
843 
844        write(msg, "(A1, 1X, A11, 3X, A13, 3X, A13, 3X, A13, 3X, A13 )" ) &
845             "#", "Temperature", "Cv", "chi",  "BinderU4", "Mst"
846        call wrtout(std_out, msg, "COLL")
847        call wrtout(ab_out, msg, "COLL")
848        write(msg, "(2X, F11.5, 3X, ES13.5, 3X, ES13.5, 3X, E13.5, 3X, ES13.5, 3X )" ) &
849             self%temperature*Ha_K , self%spin_ob%Cv, self%spin_ob%chi, &
850             self%spin_ob%binderU4, self%spin_ob%Avg_Mst_norm_total/self%spin_ob%snorm_total
851        call wrtout(std_out, msg, "COLL")
852        call wrtout(ab_out,  msg, "COLL")
853 
854        msg=repeat("=", 80)
855        call wrtout(std_out,msg,'COLL')
856        call wrtout(ab_out, msg, 'COLL')
857     end if
858   end subroutine spin_mover_t_run_time