Line data Source code
1 : !!****m* ABINIT/m_lattice_verlet_mover
2 : !! NAME
3 : !! m_lattice_verlet_mover
4 : !!
5 : !! FUNCTION
6 : !! This module contains the verlet (NVE) lattice mover.
7 : !!
8 : !!
9 : !!
10 : !! Datatypes:
11 : !!
12 : !! * lattice_verlet_mover_t: defines the lattice movers
13 : !!
14 : !! Subroutines:
15 : !! TODO: add this when F2003 doc style is determined.
16 : !!
17 : !!
18 : !! COPYRIGHT
19 : !! Copyright (C) 2001-2026 ABINIT group (hexu)
20 : !! This file is distributed under the terms of the
21 : !! GNU General Public License, see ~abinit/COPYING
22 : !! or http://www.gnu.org/copyleft/gpl.txt .
23 : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
24 : !!
25 : !! SOURCE
26 :
27 :
28 :
29 : #if defined HAVE_CONFIG_H
30 : #include "config.h"
31 : #endif
32 :
33 : #include "abi_common.h"
34 :
35 : module m_lattice_verlet_mover
36 : use defs_basis
37 : use m_abicore
38 : use m_errors
39 :
40 : use m_multibinit_dataset, only: multibinit_dtset_type
41 : use m_abstract_potential, only: abstract_potential_t
42 : use m_abstract_mover, only: abstract_mover_t
43 : use m_lattice_mover, only: lattice_mover_t
44 : use m_multibinit_cell, only: mbcell_t, mbsupercell_t
45 : use m_random_xoroshiro128plus, only: rng_t
46 : use m_hashtable_strval, only: hash_table_t
47 : !!***
48 :
49 : implicit none
50 :
51 : private
52 :
53 : type, public, extends(lattice_mover_t) :: lattice_verlet_mover_t
54 : contains
55 : procedure :: initialize
56 : procedure :: finalize
57 : procedure :: run_one_step
58 : end type lattice_verlet_mover_t
59 :
60 : contains
61 :
62 :
63 3 : subroutine initialize(self,params, supercell, rng)
64 : class(lattice_verlet_mover_t), intent(inout) :: self
65 : type(multibinit_dtset_type), target, intent(in):: params
66 : type(mbsupercell_t), target, intent(in) :: supercell
67 : type(rng_t), target, intent(in) :: rng
68 3 : call self%lattice_mover_t%initialize(params, supercell, rng)
69 3 : self%label = "Velocity Verlet lattice mover"
70 3 : end subroutine initialize
71 :
72 3 : subroutine finalize(self)
73 : class(lattice_verlet_mover_t), intent(inout) :: self
74 3 : call self%lattice_mover_t%finalize()
75 3 : end subroutine finalize
76 :
77 :
78 : !===================== run_one_step===============================!
79 : ! run one md step
80 : ! effpot: effective potential
81 : ! displacement: Should NOT be given, because it is stored in the mover already.
82 : ! strain: Should Not be given. Because 1) it is stored in the mover,
83 : ! and 2) this is a constant volume mover.
84 : ! spin: spin of atoms. Useful with spin-lattice coupling.
85 : ! lwf: lattice wannier function. Useful with lattice-lwf coupling (perhaps useless.)
86 : ! energy_table: energy table
87 3002 : subroutine run_one_step(self, effpot,displacement, strain, spin, lwf, energy_table)
88 : class(lattice_verlet_mover_t), intent(inout) :: self
89 : class(abstract_potential_t), intent(inout) :: effpot
90 : real(dp), optional, intent(inout) :: displacement(:,:), strain(:,:), spin(:,:), lwf(:)
91 : type(hash_table_t), optional, intent(inout) :: energy_table
92 : integer :: i
93 : character(len=40) :: key
94 :
95 :
96 : ! first half of velocity update. And full displacement update.
97 : ! v(t+1/2 dt) = v(t) + F/m * 1/2 dt
98 : ! x(t+dt) = x(t) + v(t+1/2 dt) * dt
99 12971642 : self%forces(:, :) =0.0
100 3002 : self%energy = 0.0
101 : call effpot%calculate( displacement=self%displacement, strain=self%strain, &
102 7004 : & spin=spin, lwf=lwf, force=self%forces, stress=self%stress, energy=self%energy, energy_table=energy_table)
103 3245162 : do i=1, self%natom
104 : self%current_vcart(:,i) = self%current_vcart(:,i) + &
105 12971642 : & (0.5_dp * self%dt) * self%forces(:,i)/self%masses(i)
106 : end do
107 : !call self%force_stationary()
108 :
109 12971642 : self%displacement(:,:) = self%displacement(:,:)+self%current_vcart(:,:) * self%dt
110 : ! No need to update xcart.
111 : !self%current_xcart(:,:) = self%supercell%lattice%xcart(:,:) + self%displacement(:,:)
112 :
113 :
114 : ! second half of velocity update.
115 : ! v(t+dt) = v(t + 1/2 dt) + F/m * 1/2 dt
116 : ! NOTE: energy and forces should be initialized before every calculation!
117 3002 : self%energy=0.0
118 12971642 : self%forces(:,:)=0.0
119 : call effpot%calculate( displacement=self%displacement, &
120 : & strain=self%strain, spin=spin, lwf=lwf, force=self%forces, &
121 7004 : & stress=self%stress, energy=self%energy, energy_table=energy_table)
122 3245162 : do i=1, self%natom
123 : self%current_vcart(:,i) = self%current_vcart(:,i) &
124 12971642 : & + (0.5_dp * self%dt) * self%forces(:,i)/self%masses(i)
125 : end do
126 : !call self%force_stationary()
127 3002 : call self%get_T_and_Ek()
128 3002 : if (present(energy_table)) then
129 3002 : key = 'Lattice kinetic energy'
130 3002 : call energy_table%put(key, self%Ek)
131 : end if
132 3002 : ABI_UNUSED_A(strain)
133 3002 : ABI_UNUSED_A(displacement)
134 3002 : end subroutine run_one_step
135 :
136 :
137 3 : end module m_lattice_verlet_mover
138 :
|