Octopus
current_to_mxll_field.F90
Go to the documentation of this file.
1!! Copyright (C) 2022 F. Bonafé
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18#include "global.h"
19
21 use debug_oct_m
23 use global_oct_m
24 use grid_oct_m
26 use, intrinsic :: iso_fortran_env
28 use mesh_oct_m
31 use parser_oct_m
34 use space_oct_m
37 use unit_oct_m
40
41 implicit none
42
43 private
44 integer, parameter :: COS2 = 1
45 public :: &
47
56 private
57 logical, public :: grid_based_partner = .true.
58 complex(real64), allocatable :: rs_current(:, :)
59
61 integer, public :: partner_np = 0
62 real(real64), allocatable, public :: partner_charge(:)
63 real(real64), allocatable, public :: partner_pos(:,:)
64 real(real64), allocatable, public :: partner_vel(:,:)
65
66 integer :: reg_type
67 real(real64) :: reg_width
68 real(real64), allocatable :: reg(:)
69
70 type(space_t), pointer :: system_space => null()
71 type(lattice_vectors_t), pointer :: system_latt => null()
72
73
74 contains
75 procedure :: init => current_to_mxll_field_init
76
77 procedure :: init_space_latt => current_to_mxll_field_init_space_latt
78
79 procedure :: do_mapping => current_to_mxll_field_do_mapping
80
81 procedure :: calculate_energy => current_to_mxll_field_calculate_energy
82
85
86
89 end interface current_to_mxll_field_t
90
91contains
92
93 subroutine current_to_mxll_field_init(this, gr, ndim)
94 class(current_to_mxll_field_t), intent(inout) :: this
95 type(grid_t), target, intent(in) :: gr
96 integer, intent(in) :: ndim
97
99
100 call field_transfer_init(this, gr, ndim)
101 safe_allocate(this%rs_current(1:gr%np, 1:ndim))
102
104 end subroutine current_to_mxll_field_init
105
106 ! ---------------------------------------------------------
107 function current_to_mxll_field_constructor(partner) result(this)
108 class(interaction_partner_t), target, intent(inout) :: partner
109 class(current_to_mxll_field_t), pointer :: this
110
112
113 allocate(this)
114
115 this%label = "current_to_mxll_field"
116 this%partner => partner
117
118 ! TODO: For point-wise systems, this should be different, as we
119 ! need there the charge and velocity to do the charge regularization.
120 ! Once each partner has a basis class, we can do a derived type
121 ! TODO: look for user input option of the regularization function for point partner
122 this%couplings_from_partner = ["current"]
123
124 !%Variable RegularizationFunction
125 !%Type integer
126 !%Default COS2
127 !%Section Maxwell
128 !%Description
129 !% The current arising from charged point particles must be mapped onto the Maxwell
130 !% propagation grid. This requires a smearing or regularization function $\phi(\mathbf{r})$ attached to
131 !% each particle position $\mathbf{r}_i$ with user defined cutoff width, $\sigma$
132 !%Option COS2 1
133 !% $\phi(r)=\text{cos}^2(\frac{\pi}{2}\frac{|\mathbf{r}-\mathbf{r}_i|}{\sigma})$
134 !% if $|\mahtbf{r}-\mathbf{r}_i|<\sigma$, and 0 otherwise.
135 !%End
136
137 call parse_variable(partner%namespace, 'RegularizationFunction', cos2, this%reg_type)
138 if (.not. varinfo_valid_option('RegularizationFunction', this%reg_type)) &
139 call messages_input_error(partner%namespace, 'RegularizationFunction')
140
141 !%Variable RegularizationFunctionWidth
142 !%Type float
143 !%Default 2
144 !%Section Maxwell
145 !%Description
146 !% The current arising from charged point particles must be mapped onto the Maxwell
147 !% propagation grid. This requires a smearing or regularization function $\phi(\mathbf{r})$ attached to
148 !% each particle position $\mathbf{r}_i$ with user defined cutoff width, $\sigma$.
149 !% Default 2 bohrradii
150 !%End
152 call parse_variable(partner%namespace, 'RegularizationFunctionWidth', 2.0_real64, &
153 this%reg_width, units_inp%length)
155 this%intra_interaction = .false.
161 subroutine current_to_mxll_field_init_space_latt(this, space, latt)
162 class(current_to_mxll_field_t), intent(inout) :: this
163 class(space_t), target, intent(in) :: space
164 type(lattice_vectors_t), target, intent(in) :: latt
165
167
168 this%system_space => space
169 this%system_latt => latt
173
174 ! ---------------------------------------------------------
175 subroutine current_to_mxll_field_finalize(this)
176 type(current_to_mxll_field_t), intent(inout) :: this
177
179
180 call this%end()
181 nullify(this%system_space)
182 nullify(this%system_latt)
183 safe_deallocate_a(this%rs_current)
184
187
188 ! ---------------------------------------------------------
189 subroutine current_to_mxll_field_do_mapping(this)
190 class(current_to_mxll_field_t), intent(inout) :: this
191
192 integer :: part_ind, i_dim, ip
193 type(submesh_t) :: submesh
194 real(real64) :: norm, time
195
196 push_sub_with_profile(current_to_mxll_field_do_mapping)
197
198 if(this%grid_based_partner) then
199 call this%regridding%do_transfer(this%system_field, this%partner_field)
200 else
201 this%system_field = m_zero
202 do part_ind = 1, this%partner_np
203 call submesh_init(submesh, this%system_space, this%system_gr, &
204 this%system_latt, this%partner_pos(:,part_ind), this%reg_width)
205
206 safe_allocate(this%reg(1:submesh%np))
207 if (this%reg_type == cos2) then
208 do ip = 1, submesh%np
209 this%reg(ip) = cos( (m_pi/m_two) * (submesh%r(ip)/this%reg_width) )**2
210 end do
211 end if
212
213 norm = dsm_integrate(this%system_gr, submesh, this%reg)
214
215 do i_dim = 1, this%system_space%dim
216 call submesh_add_to_mesh(submesh, this%reg, this%system_field(:,i_dim), &
217 this%partner_charge(part_ind)*this%partner_vel(i_dim,part_ind)/norm)
218 end do
219 safe_deallocate_a(this%reg)
220
221 call submesh_end(submesh)
222 end do
223
224 end if
225 ! add the RS current to the interpolation
226 call build_rs_current_state(this%system_field, this%system_gr, this%rs_current)
227 assert(this%interpolation_initialized)
228 associate(coupling => this%partner%quantities%get(this%couplings_from_partner(1)))
229 time = coupling%iteration%value()
230 end associate
231 call this%interpolation%add_time(time, this%rs_current)
232
233 pop_sub_with_profile(current_to_mxll_field_do_mapping)
235
236 ! ---------------------------------------------------------
238 class(current_to_mxll_field_t), intent(inout) :: this
239
241
242 ! interaction energy is zero, since it is only re-gridding the quantities of one system
243 ! on the mesh of the other
244 this%energy = m_zero
245
248
250
251!! Local Variables:
252!! mode: f90
253!! coding: utf-8
254!! End:
double cos(double __x) __attribute__((__nothrow__
subroutine current_to_mxll_field_init_space_latt(this, space, latt)
subroutine current_to_mxll_field_finalize(this)
class(current_to_mxll_field_t) function, pointer current_to_mxll_field_constructor(partner)
subroutine current_to_mxll_field_do_mapping(this)
subroutine current_to_mxll_field_init(this, gr, ndim)
subroutine current_to_mxll_field_calculate_energy(this)
This module implements the field transfer.
subroutine, public field_transfer_init(this, gr, ndim)
the system field is allocated and initialized to 0
real(real64), parameter, public m_two
Definition: global.F90:190
real(real64), parameter, public m_zero
Definition: global.F90:188
real(real64), parameter, public m_pi
some mathematical constants
Definition: global.F90:186
This module implements the underlying real-space grid.
Definition: grid.F90:117
This module defines classes and functions for interaction partners.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:713
Implementation details for regridding.
Definition: regridding.F90:170
subroutine, public build_rs_current_state(current_state, mesh, rs_current_state, ep_field, np)
real(real64) function, public dsm_integrate(mesh, sm, ff, reduce)
Definition: submesh.F90:1165
subroutine, public submesh_end(this)
Definition: submesh.F90:735
subroutine, public submesh_init(this, space, mesh, latt, center, rc)
Definition: submesh.F90:280
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:132
This module defines the unit system, used for input and output.
type(unit_system_t), public units_inp
the units systems for reading and writing
Class to transfer a current to a Maxwell field.
class defining the field_transfer interaction
A submesh is a type of mesh, used for the projectors in the pseudopotentials It contains points on a ...
Definition: submesh.F90:175
int true(void)