Line data Source code
1 : !!****m* ABINIT/m_slc_dynamics
2 : !! NAME
3 : !! m_slc_potential
4 : !!
5 : !! FUNCTION
6 : !! This module contains the dynamics for coupled spin-lattice dynamics
7 : !!
8 : !!
9 : !! COPYRIGHT
10 : !! Copyright (C) 2001-2026 ABINIT group (hexu, NH)
11 : !! This file is distributed under the terms of the
12 : !! GNU General Public License, see ~abinit/COPYING
13 : !! or http://www.gnu.org/copyleft/gpl.txt .
14 : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
15 : !!
16 : !! SOURCE
17 :
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 : implicit none
41 :
42 : private
43 :
44 : type, public, extends(abstract_mover_t) :: slc_mover_t
45 : class(spin_mover_t), pointer :: spin_mover
46 : class(lattice_mover_t), pointer :: lattice_mover
47 :
48 : CONTAINS
49 : procedure :: initialize
50 : procedure :: finalize
51 : procedure :: run_one_step
52 : procedure :: run_time
53 :
54 : end type slc_mover_t
55 :
56 : contains
57 :
58 2 : subroutine initialize(self, spin_mover, lattice_mover)
59 :
60 : class(slc_mover_t) :: self
61 : class(spin_mover_t), target :: spin_mover
62 : class(lattice_mover_t), target :: lattice_mover
63 :
64 2 : self%spin_mover => spin_mover
65 2 : self%lattice_mover => lattice_mover
66 :
67 2 : end subroutine initialize
68 :
69 6 : subroutine finalize(self)
70 :
71 : class(slc_mover_t) :: self
72 :
73 6 : nullify(self%spin_mover)
74 6 : nullify(self%lattice_mover)
75 :
76 6 : end subroutine finalize
77 :
78 2 : subroutine run_time(self, calculator, displacement, strain, spin, lwf, energy_table)
79 :
80 : class(slc_mover_t), intent(inout) :: self
81 : class(abstract_potential_t), intent(inout) :: calculator
82 :
83 : real(dp), optional, intent(inout) :: displacement(:,:), strain(:,:), lwf(:), spin(:,:)
84 : type(hash_table_t),optional, intent(inout) :: energy_table
85 :
86 : real(dp):: t
87 : integer :: counter
88 : character(len=80) :: msg, msg_empty
89 : real(dp):: etotal, espin, elatt, eslc
90 :
91 : integer :: master, my_rank, comm, nproc
92 : logical :: iam_master
93 2 : call init_mpi_info(master, iam_master, my_rank, comm, nproc)
94 :
95 :
96 : !if(self%spin_mover%total_time .ne. self%lattice_mover%total_time) then
97 : ! ABI_ERROR("Total time for spin and lattice dynamics are different, check your input file.")
98 : !endif
99 :
100 : !if(self%spin_mover%dt .ne. self%lattice_mover%dt) then
101 : ! ABI_ERROR("Different time steps for spin and lattice dynamics not yet implemented, check your input file.")
102 : !endif
103 :
104 :
105 2 : t=0.0
106 2 : counter=0
107 :
108 2 : if(iam_master) then
109 2 : msg_empty=ch10
110 :
111 2 : msg=repeat("=", 80)
112 2 : call wrtout(std_out,msg,'COLL')
113 2 : call wrtout(ab_out, msg, 'COLL')
114 2 : write(msg, '(A20)') "Coupled spin-lattice dynamic steps:"
115 2 : call wrtout(std_out,msg,'COLL')
116 2 : call wrtout(ab_out, msg, 'COLL')
117 2 : msg=repeat("=", 80)
118 2 : call wrtout(std_out,msg,'COLL')
119 2 : call wrtout(ab_out, msg, 'COLL')
120 :
121 2 : 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)"
122 2 : call wrtout(std_out,msg,'COLL')
123 2 : call wrtout(ab_out, msg, 'COLL')
124 :
125 2 : msg=repeat("-", 80)
126 2 : call wrtout(std_out,msg,'COLL')
127 2 : call wrtout(ab_out, msg, 'COLL')
128 : end if
129 :
130 : !thermalization of spin degrees of freedom
131 2 : if (abs(self%spin_mover%thermal_time) > 1e-30) then
132 0 : if (iam_master) then
133 0 : msg="Thermalization run:"
134 0 : call wrtout(std_out,msg,'COLL')
135 0 : call wrtout(ab_out, msg, 'COLL')
136 : end if
137 :
138 0 : do while(t<self%spin_mover%thermal_time)
139 0 : counter=counter+1
140 : call self%run_one_step(effpot=calculator, spin=spin, displacement=displacement, strain=strain, &
141 0 : & lwf=lwf, energy_table=energy_table)
142 0 : if (iam_master) then
143 0 : call self%spin_mover%hist%set_vars( time=t, inc=.True.)
144 0 : if(mod(counter, self%spin_mover%hist%spin_nctime)==0) then
145 : call self%spin_mover%spin_ob%get_observables( self%spin_mover%hist%S(:,:, self%spin_mover%hist%ihist_prev), &
146 : self%spin_mover%hist%Snorm(:,self%spin_mover%hist%ihist_prev), &
147 0 : self%spin_mover%hist%etot(self%spin_mover%hist%ihist_prev))
148 0 : etotal = energy_table%sum_val()
149 0 : espin = energy_table%sum_val(label='SpinPotential')
150 0 : elatt = energy_table%sum_val(label='Lattice_harmonic_potential')
151 0 : elatt = elatt + energy_table%sum_val(label='Lattice kinetic energy')
152 0 : eslc = energy_table%sum_val(prefix='SLCPotential')
153 0 : write(msg, "(A1, 1X, I13, 2X, ES13.5, 2X, ES13.5, 2X, ES13.5, 2X, ES13.5)") "-", counter, espin, elatt, eslc, etotal
154 0 : call wrtout(std_out,msg,'COLL')
155 0 : call wrtout(ab_out, msg, 'COLL')
156 : endif
157 : end if
158 0 : t=t+self%spin_mover%dt
159 : end do
160 : endif
161 :
162 2 : t=0.0
163 2 : counter=0
164 2 : if (iam_master) then
165 2 : call self%spin_mover%hist%reset(array_to_zero=.False.)
166 : end if
167 :
168 2 : if(iam_master) then
169 2 : call self%spin_mover%spin_ob%reset()
170 2 : msg="Measurement run:"
171 2 : call wrtout(std_out,msg,'COLL')
172 2 : call wrtout(ab_out, msg, 'COLL')
173 : endif
174 :
175 2004 : do while(t<self%spin_mover%total_time)
176 2002 : counter=counter+1
177 : !one step in coupled spin-lattice dynamics
178 : call self%run_one_step(effpot=calculator, spin=spin, displacement=displacement, strain=strain, lwf=lwf, &
179 6006 : & energy_table=energy_table)
180 :
181 2002 : if (iam_master) then
182 2002 : call self%spin_mover%hist%set_vars(time=t, inc=.True.)
183 : call self%spin_mover%spin_ob%get_observables(self%spin_mover%hist%S(:,:, self%spin_mover%hist%ihist_prev), &
184 : self%spin_mover%hist%Snorm(:,self%spin_mover%hist%ihist_prev), &
185 2002 : self%spin_mover%hist%etot(self%spin_mover%hist%ihist_prev))
186 2002 : if(modulo(counter, self%spin_mover%hist%spin_nctime)==0) then
187 200 : call self%spin_mover%spin_ncfile%write_one_step(self%spin_mover%hist)
188 200 : etotal = energy_table%sum_val()
189 200 : espin = energy_table%sum_val(label='SpinPotential')
190 200 : elatt = energy_table%sum_val(label='Lattice_harmonic_potential')
191 200 : elatt = elatt + energy_table%sum_val(label='Lattice kinetic energy')
192 200 : eslc = energy_table%sum_val(prefix='SLCPotential')
193 200 : write(msg, "(A1, 1X, I13, 2X, ES13.5, 2X, ES13.5, 2X, ES13.5, 2X, ES13.5)") "-", counter, espin, elatt, eslc, etotal
194 200 : call wrtout(std_out,msg,'COLL')
195 200 : call wrtout(ab_out, msg, 'COLL')
196 : endif
197 : end if
198 : !NH: add calculation of observables here.
199 :
200 2002 : t=t+self%spin_mover%dt
201 : enddo
202 :
203 2 : end subroutine run_time
204 :
205 :
206 2002 : subroutine run_one_step(self, effpot, displacement, strain, spin, lwf, energy_table)
207 :
208 : class(slc_mover_t), intent(inout) :: self
209 : class(abstract_potential_t), intent(inout) :: effpot
210 :
211 : real(dp), optional, intent(inout) :: displacement(:,:), strain(:,:), lwf(:), spin(:,:)
212 : type(hash_table_t), optional, intent(inout) :: energy_table
213 :
214 :
215 : call self%spin_mover%run_one_step(effpot=effpot, displacement=displacement, strain=strain, &
216 6006 : & lwf=lwf, energy_table=energy_table)
217 :
218 4004 : call self%lattice_mover%run_one_step(effpot=effpot, spin=spin, lwf=lwf, energy_table=energy_table)
219 :
220 2002 : end subroutine run_one_step
221 :
222 : !!***
223 0 : end module m_slc_dynamics
224 :
|