TABLE OF CONTENTS


ABINIT/m_slc_dynamics [ Modules ]

[ Top ] [ Modules ]

NAME

 m_slc_potential

FUNCTION

 This module contains the dynamics for coupled spin-lattice dynamics

COPYRIGHT

 Copyright (C) 2001-2022 ABINIT group (hexu, NH)
 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

 18 #if defined HAVE_CONFIG_H
 19 #include "config.h"
 20 #endif
 21 #include "abi_common.h"
 22 
 23 module  m_slc_dynamics
 24 
 25   use defs_basis
 26   use m_errors
 27   use m_abicore
 28   use m_xmpi
 29   use m_io_tools, only : get_unit, open_file, close_unit
 30   use m_mpi_scheduler, only: mpi_scheduler_t, init_mpi_info
 31 
 32 
 33   use m_abstract_potential, only: abstract_potential_t
 34   use m_abstract_mover, only: abstract_mover_t
 35   use m_spin_mover, only: spin_mover_t
 36   use m_lattice_mover, only: lattice_mover_t
 37   use m_hashtable_strval, only: hash_table_t
 38   use m_slc_potential, only: slc_potential_t
 39 
 40   private
 41 
 42   type, public, extends(abstract_mover_t) :: slc_mover_t
 43     class(spin_mover_t),    pointer :: spin_mover
 44     class(lattice_mover_t), pointer :: lattice_mover    
 45 
 46   CONTAINS
 47     procedure :: initialize
 48     procedure :: finalize
 49     procedure :: run_one_step
 50     procedure :: run_time
 51 
 52   end type slc_mover_t
 53 
 54   contains
 55 
 56   subroutine initialize(self, spin_mover, lattice_mover)
 57 
 58     class(slc_mover_t) :: self
 59     class(spin_mover_t), target :: spin_mover
 60     class(lattice_mover_t), target :: lattice_mover
 61 
 62     self%spin_mover => spin_mover
 63     self%lattice_mover => lattice_mover
 64 
 65   end subroutine initialize
 66 
 67   subroutine finalize(self)
 68 
 69     class(slc_mover_t) :: self
 70   
 71     nullify(self%spin_mover)
 72     nullify(self%lattice_mover)
 73 
 74   end subroutine finalize
 75 
 76   subroutine run_time(self, calculator, displacement, strain, spin, lwf, energy_table)
 77 
 78     class(slc_mover_t),          intent(inout) :: self
 79     class(abstract_potential_t), intent(inout) :: calculator
 80 
 81     real(dp), optional, intent(inout) :: displacement(:,:), strain(:,:), lwf(:), spin(:,:)
 82     type(hash_table_t),optional, intent(inout) :: energy_table
 83 
 84     real(dp):: t
 85     integer :: counter
 86     character(len=80) :: msg, msg_empty
 87     real(dp):: etotal, espin, elatt, eslc
 88 
 89     integer :: master, my_rank, comm, nproc
 90     logical :: iam_master
 91     call init_mpi_info(master, iam_master, my_rank, comm, nproc) 
 92 
 93 
 94    !if(self%spin_mover%total_time .ne. self%lattice_mover%total_time) then
 95    !  ABI_ERROR("Total time for spin and lattice dynamics are different, check your input file.")
 96    !endif
 97 
 98    !if(self%spin_mover%dt .ne. self%lattice_mover%dt) then
 99    !  ABI_ERROR("Different time steps for spin and lattice dynamics not yet implemented, check your input file.")
100    !endif
101      
102 
103   t=0.0
104   counter=0
105 
106   if(iam_master) then
107     msg_empty=ch10
108 
109     msg=repeat("=", 80)
110     call wrtout(std_out,msg,'COLL')
111     call wrtout(ab_out, msg, 'COLL')
112     write(msg, '(A20)') "Coupled spin-lattice dynamic steps:"
113     call wrtout(std_out,msg,'COLL')
114     call wrtout(ab_out, msg, 'COLL')
115     msg=repeat("=", 80)
116     call wrtout(std_out,msg,'COLL')
117     call wrtout(ab_out, msg, 'COLL')
118 
119     write(msg, "(5X, A9, 6X, A10, 5X, A10, 5X, A10, 5X, A10)")  "Iteration", "E_spin(Ha)", "E_latt(Ha)", "E_slc(Ha)", "E_tot(Ha)"
120     call wrtout(std_out,msg,'COLL')
121     call wrtout(ab_out, msg, 'COLL')
122 
123     msg=repeat("-", 80)
124     call wrtout(std_out,msg,'COLL')
125     call wrtout(ab_out, msg, 'COLL')
126   end if
127 
128   !thermalization of spin degrees of freedom
129   if (abs(self%spin_mover%thermal_time) > 1e-30) then
130     if (iam_master) then
131       msg="Thermalization run:"
132       call wrtout(std_out,msg,'COLL')
133       call wrtout(ab_out, msg, 'COLL')
134     end if
135 
136     do while(t<self%spin_mover%thermal_time)
137       counter=counter+1
138       call self%run_one_step(effpot=calculator, spin=spin, displacement=displacement, strain=strain, &
139          & lwf=lwf, energy_table=energy_table)
140       if (iam_master) then
141         call self%spin_mover%hist%set_vars( time=t,  inc=.True.)
142         if(mod(counter, self%spin_mover%hist%spin_nctime)==0) then
143           call self%spin_mover%spin_ob%get_observables( self%spin_mover%hist%S(:,:, self%spin_mover%hist%ihist_prev), &
144              self%spin_mover%hist%Snorm(:,self%spin_mover%hist%ihist_prev), & 
145              self%spin_mover%hist%etot(self%spin_mover%hist%ihist_prev))
146           etotal = energy_table%sum_val()
147           espin = energy_table%sum_val(label='SpinPotential')
148           elatt = energy_table%sum_val(label='Lattice_harmonic_potential')
149           elatt = elatt + energy_table%sum_val(label='Lattice kinetic energy')
150           eslc = energy_table%sum_val(prefix='SLCPotential')
151           write(msg, "(A1, 1X, I13, 2X, ES13.5, 2X, ES13.5, 2X, ES13.5, 2X, ES13.5)") "-", counter, espin, elatt, eslc, etotal
152           call wrtout(std_out,msg,'COLL')
153           call wrtout(ab_out, msg, 'COLL')
154         endif
155       end if
156       t=t+self%spin_mover%dt
157     end do
158   endif
159 
160   t=0.0
161   counter=0
162   if (iam_master) then
163     call self%spin_mover%hist%reset(array_to_zero=.False.)
164   end if
165   
166   if(iam_master) then
167     call self%spin_mover%spin_ob%reset()
168     msg="Measurement run:"
169     call wrtout(std_out,msg,'COLL')
170     call wrtout(ab_out, msg, 'COLL')
171   endif
172 
173   do while(t<self%spin_mover%total_time)
174     counter=counter+1
175     !one step in coupled spin-lattice dynamics
176     call self%run_one_step(effpot=calculator, spin=spin, displacement=displacement, strain=strain, lwf=lwf, &
177          & energy_table=energy_table)
178 
179     if (iam_master) then
180       call self%spin_mover%hist%set_vars(time=t,  inc=.True.)
181       call self%spin_mover%spin_ob%get_observables(self%spin_mover%hist%S(:,:, self%spin_mover%hist%ihist_prev), &
182            self%spin_mover%hist%Snorm(:,self%spin_mover%hist%ihist_prev), &
183            self%spin_mover%hist%etot(self%spin_mover%hist%ihist_prev))
184       if(modulo(counter, self%spin_mover%hist%spin_nctime)==0) then
185         call self%spin_mover%spin_ncfile%write_one_step(self%spin_mover%hist)
186         etotal = energy_table%sum_val()
187         espin = energy_table%sum_val(label='SpinPotential')
188         elatt = energy_table%sum_val(label='Lattice_harmonic_potential')
189         elatt = elatt + energy_table%sum_val(label='Lattice kinetic energy')
190         eslc = energy_table%sum_val(prefix='SLCPotential')
191         write(msg, "(A1, 1X, I13, 2X, ES13.5, 2X, ES13.5, 2X, ES13.5, 2X, ES13.5)") "-", counter, espin, elatt, eslc, etotal
192         call wrtout(std_out,msg,'COLL')
193         call wrtout(ab_out, msg, 'COLL')
194       endif
195     end if
196     !NH: add calculation of observables here.
197 
198     t=t+self%spin_mover%dt
199   enddo
200 
201   end subroutine run_time
202 
203 
204   subroutine run_one_step(self, effpot, displacement, strain, spin, lwf, energy_table)
205 
206     class(slc_mover_t),          intent(inout) :: self
207     class(abstract_potential_t), intent(inout) :: effpot
208 
209     real(dp), optional, intent(inout) :: displacement(:,:), strain(:,:), lwf(:), spin(:,:)
210     type(hash_table_t), optional, intent(inout) :: energy_table
211 
212 
213     call self%spin_mover%run_one_step(effpot=effpot, displacement=displacement, strain=strain, &
214         &    lwf=lwf, energy_table=energy_table)
215 
216     call self%lattice_mover%run_one_step(effpot=effpot, spin=spin, lwf=lwf, energy_table=energy_table)
217 
218   end subroutine run_one_step