Octopus
perturbation_ionic.F90
Go to the documentation of this file.
1!! Copyright (C) 2007 X. Andrade
2!! Copyright (C) 2021 N. Tancogne-Dejean
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19
20#include "global.h"
21
25 use debug_oct_m
27 use epot_oct_m
28 use global_oct_m
29 use grid_oct_m
32 use ions_oct_m
34 use math_oct_m
35 use mesh_oct_m
39 use mpi_oct_m
44 use space_oct_m
51
52 implicit none
53
54 private
55 public :: &
59
60 type, extends(perturbation_t) :: perturbation_ionic_t
61 private
62
63 type(ions_t), pointer :: ions => null()
64
69 logical :: pure_dir
70 integer :: atom1, atom2
71 real(real64), allocatable :: mix1(:,:)
72 real(real64), allocatable :: mix2(:,:)
73
77 real(real64), allocatable :: dvxc_core(:,:)
78
79 contains
80 procedure :: copy_to => perturbation_ionic_copy
81 generic :: assignment(=) => copy_to
82 procedure :: info => perturbation_ionic_info
83 procedure :: dapply => dperturbation_ionic_apply
84 procedure :: zapply => zperturbation_ionic_apply
85 procedure :: dapply_order_2 => dperturbation_ionic_apply_order_2
86 procedure :: zapply_order_2 => zperturbation_ionic_apply_order_2
87 procedure :: setup_dir => perturbation_ionic_setup_dir
88 procedure :: setup_atom => perturbation_ionic_setup_atom
89 procedure :: setup_mix_dir => perturbation_ionic_setup_mixed_dir
90 procedure :: set_nlcc_response => perturbation_ionic_set_nlcc_response
93
94 interface perturbation_ionic_t
95 procedure perturbation_ionic_constructor
96 end interface perturbation_ionic_t
97
98contains
99
100 ! ---------------------------------------------------------
105 function perturbation_ionic_constructor(namespace, ions) result(pert)
106 class(perturbation_ionic_t), pointer :: pert
107 type(namespace_t), intent(in) :: namespace
108 type(ions_t), target, intent(in) :: ions
109
111
112 safe_allocate(pert)
113
114 call perturbation_ionic_init(pert, namespace, ions)
115
118
119
120 ! --------------------------------------------------------------------
121 subroutine perturbation_ionic_init(this, namespace, ions)
122 type(perturbation_ionic_t), intent(out) :: this
123 type(namespace_t), intent(in) :: namespace
124 type(ions_t), target, intent(in) :: ions
125
127
128 this%dir = -1
129 this%dir2 = -1
130 this%atom1 = -1
131 this%atom2 = -1
132
133 this%ions => ions
134
135 this%pure_dir = .false.
136
137 safe_allocate(this%mix1(1:ions%natoms, 1:ions%space%dim))
138 safe_allocate(this%mix2(1:ions%natoms, 1:ions%space%dim))
139
141 end subroutine perturbation_ionic_init
142
143 ! --------------------------------------------------------------------
144 subroutine perturbation_ionic_copy(this, source)
145 class(perturbation_ionic_t), intent(out) :: this
146 class(perturbation_ionic_t), intent(in) :: source
147
149
150 call perturbation_copy(this, source)
151 this%atom1 = source%atom1
152 this%atom2 = source%atom2
153 this%ions => source%ions
154
155 this%pure_dir = source%pure_dir
156
157 safe_allocate(this%mix1(1:source%ions%natoms, 1:source%ions%space%dim))
158 safe_allocate(this%mix2(1:source%ions%natoms, 1:source%ions%space%dim))
159 this%mix1 = source%mix1
160 this%mix2 = source%mix2
161
162 if (allocated(source%dvxc_core)) then
163 safe_allocate(this%dvxc_core(1:size(source%dvxc_core, dim=1), 1:size(source%dvxc_core, dim=2)))
164 this%dvxc_core = source%dvxc_core
165 end if
168 end subroutine perturbation_ionic_copy
169
170
171 ! --------------------------------------------------------------------
173 type(perturbation_ionic_t), intent(inout) :: this
174
177 safe_deallocate_a(this%mix1)
178 safe_deallocate_a(this%mix2)
179 safe_deallocate_a(this%dvxc_core)
184 ! --------------------------------------------------------------------
185 subroutine perturbation_ionic_info(this)
186 class(perturbation_ionic_t), intent(in) :: this
187
189
191 end subroutine perturbation_ionic_info
192
193 ! --------------------------------------------------------------------
194 subroutine perturbation_ionic_setup_dir(this, dir, dir2)
195 class(perturbation_ionic_t), intent(inout) :: this
196 integer, intent(in) :: dir
197 integer, optional, intent(in) :: dir2
198
201 this%dir = dir
202 if (present(dir2)) this%dir2 = dir2
203
204 this%pure_dir = .true.
205
206 this%mix1 = m_zero
207 this%mix2 = m_zero
208
209 if (this%dir > 0 .and. this%atom1 > 0) this%mix1(this%atom1, this%dir ) = m_one
210 if (this%dir2 > 0 .and. this%atom2 > 0) this%mix2(this%atom2, this%dir2) = m_one
211
213 end subroutine perturbation_ionic_setup_dir
214
215 ! --------------------------------------------------------------------
216 subroutine perturbation_ionic_setup_atom(this, iatom, iatom2)
217 class(perturbation_ionic_t), intent(inout) :: this
218 integer, intent(in) :: iatom
219 integer, optional, intent(in) :: iatom2
220
222
223 this%atom1 = iatom
224 if (present(iatom2)) this%atom2 = iatom2
225
226 this%pure_dir = .true.
227
228 this%mix1 = m_zero
229 this%mix2 = m_zero
230
231 if (this%dir > 0 .and. this%atom1 > 0) this%mix1(this%atom1, this%dir ) = m_one
232 if (this%dir2 > 0 .and. this%atom2 > 0) this%mix2(this%atom2, this%dir2) = m_one
233
235 end subroutine perturbation_ionic_setup_atom
236
237 ! --------------------------------------------------------------------
238 subroutine perturbation_ionic_setup_mixed_dir(this, iatom, idir, val, jatom, jdir, valuej)
239 class(perturbation_ionic_t), intent(inout) :: this
240 integer, intent(in) :: iatom
241 integer, intent(in) :: idir
242 real(real64), intent(in) :: val
243 integer, optional, intent(in) :: jatom
244 integer, optional, intent(in) :: jdir
245 real(real64), optional, intent(in) :: valuej
246
247 logical :: have_dir_2
248
250
251 this%pure_dir = .false.
252
253 this%mix1(iatom, idir) = val
254
255 have_dir_2 = present(jatom) .and. present(jdir) .and. present(jatom)
256
257 if (have_dir_2) then
258 this%mix1(jatom, jdir) = valuej
259 else
260 assert(.not. present(jatom) .and. .not. present(jdir) .and. .not. present(jatom))
261 end if
262
265
266 ! --------------------------------------------------------------------
270 subroutine perturbation_ionic_set_nlcc_response(this, dvxc_core)
271 class(perturbation_ionic_t), intent(inout) :: this
272 real(real64), intent(in) :: dvxc_core(:,:)
273
275
276 safe_deallocate_a(this%dvxc_core)
277 safe_allocate(this%dvxc_core(1:size(dvxc_core, dim=1), 1:size(dvxc_core, dim=2)))
278 this%dvxc_core = dvxc_core
279
282
283
284
285#include "undef.F90"
286#include "real.F90"
287#include "perturbation_ionic_inc.F90"
288
289#include "undef.F90"
290#include "complex.F90"
291#include "perturbation_ionic_inc.F90"
292
294
295!! Local Variables:
296!! mode: f90
297!! coding: utf-8
298!! End:
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:118
Module implementing boundary conditions in Octopus.
Definition: boundaries.F90:124
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
real(real64), parameter, public m_zero
Definition: global.F90:200
real(real64), parameter, public m_one
Definition: global.F90:201
This module implements the underlying real-space grid.
Definition: grid.F90:119
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
This module defines functions over batches of mesh functions.
Definition: mesh_batch.F90:118
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
subroutine perturbation_ionic_setup_mixed_dir(this, iatom, idir, val, jatom, jdir, valuej)
subroutine, public zionic_pert_matrix_elements_2(gr, namespace, space, ions, hm, ik, st, vib, matrix)
Computes the second order term.
subroutine perturbation_ionic_setup_atom(this, iatom, iatom2)
subroutine perturbation_ionic_init(this, namespace, ions)
subroutine perturbation_ionic_set_nlcc_response(this, dvxc_core)
Variation of the xc potential with respect to the atom position. This is solely due to the displaced ...
subroutine perturbation_ionic_copy(this, source)
subroutine dperturbation_ionic_apply(this, namespace, space, gr, hm, ik, f_in, f_out, set_bc)
Returns f_out = H' f_in, where H' is perturbation Hamiltonian Note that e^ikr phase is applied to f_i...
subroutine, public dionic_pert_matrix_elements_2(gr, namespace, space, ions, hm, ik, st, vib, matrix)
Computes the second order term.
subroutine perturbation_ionic_info(this)
subroutine zperturbation_ionic_apply_order_2(this, namespace, space, gr, hm, ik, f_in, f_out)
subroutine zperturbation_ionic_apply(this, namespace, space, gr, hm, ik, f_in, f_out, set_bc)
Returns f_out = H' f_in, where H' is perturbation Hamiltonian Note that e^ikr phase is applied to f_i...
subroutine perturbation_ionic_finalize(this)
subroutine perturbation_ionic_setup_dir(this, dir, dir2)
class(perturbation_ionic_t) function, pointer perturbation_ionic_constructor(namespace, ions)
The factory routine (or constructor) allocates a pointer of the corresponding type and then calls the...
subroutine dperturbation_ionic_apply_order_2(this, namespace, space, gr, hm, ik, f_in, f_out)
subroutine, public perturbation_copy(this, source)
This module handles spin dimensions of the states and the k-point distribution.
int true(void)