Branch data 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 : :
|