Octopus
charged_particle.F90
Go to the documentation of this file.
1!! Copyright (C) 2020 H. Appel, S. Ohlmann, M. Oliveira, N. Tancogne-Dejean
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
19#include "global.h"
20
26 use debug_oct_m
27 use global_oct_m
34 use mpi_oct_m
36 use parser_oct_m
39 use space_oct_m
40 use system_oct_m
41
42 implicit none
43
44 private
45 public :: &
48
52 ! Note that we extend classical_particle_t and not charged_particles_t. Both
53 ! choices have pros and cons. In the end extending classical_particle_t was
54 ! chosen because charged_particles_t was only introduced after
55 ! charged_particle_t.
56 private
57
58 real(real64) :: charge(1)
59
60 contains
61 procedure :: init_interaction => charged_particle_init_interaction
62 procedure :: initialize => charged_particle_initialize
63 procedure :: is_tolerance_reached => charged_particle_is_tolerance_reached
64 procedure :: update_quantity => charged_particle_update_quantity
65 procedure :: init_interaction_as_partner => charged_particle_init_interaction_as_partner
66 procedure :: copy_quantities_to_interaction => charged_particle_copy_quantities_to_interaction
67 end type charged_particle_t
68
69 interface charged_particle_t
70 procedure charged_particle_constructor
71 end interface charged_particle_t
72
73contains
74
75 ! ---------------------------------------------------------
80 function charged_particle_constructor(namespace, grp) result(sys)
81 class(charged_particle_t), pointer :: sys
82 type(namespace_t), intent(in) :: namespace
83 type(mpi_grp_t), intent(in) :: grp
84
86
87 allocate(sys)
88
89 call charged_particle_init(sys, namespace, grp)
90
93
94 ! ---------------------------------------------------------
99 subroutine charged_particle_init(this, namespace, grp)
100 class(charged_particle_t), intent(inout) :: this
101 type(namespace_t), intent(in) :: namespace
102 type(mpi_grp_t), intent(in) :: grp
103
104 push_sub(charged_particle_init)
105
106 call classical_particle_init(this%classical_particle_t, namespace, grp)
107
108 !%Variable ParticleCharge
109 !%Type float
110 !%Section ClassicalParticles
111 !%Description
112 !% Charge of classical particle
113 !%End
114 call parse_variable(namespace, 'ParticleCharge', m_one, this%charge(1))
115 call messages_print_var_value('ParticleCharge', this%charge(1), namespace=namespace)
117 this%supported_interactions = [this%supported_interactions, lorentz_force, coulomb_force]
118 this%supported_interactions_as_partner = [this%supported_interactions_as_partner, coulomb_force, current_to_mxll_field]
119
120 call this%quantities%add(quantity_t("charge", updated_on_demand = .false., always_available = .true.))
121 call this%quantities%add(quantity_t("current", parents=[character(8) :: "charge", "velocity"]))
122
123
124 pop_sub(charged_particle_init)
125 end subroutine charged_particle_init
126
127 ! ---------------------------------------------------------
128 subroutine charged_particle_init_interaction(this, interaction)
129 class(charged_particle_t), target, intent(inout) :: this
130 class(interaction_t), intent(inout) :: interaction
131
133
134 select type (interaction)
135 type is (coulomb_force_t)
136 call interaction%init(this%space%dim, 1, this%charge, this%pos)
137 type is (lorentz_force_t)
138 call interaction%init(this%space%dim, 1, this%charge, this%pos, this%vel, this%namespace)
139 class default
140 call this%classical_particle_t%init_interaction(interaction)
141 end select
142
145
146 ! ---------------------------------------------------------
147 subroutine charged_particle_initialize(this)
148 class(charged_particle_t), intent(inout) :: this
149
151
152 call this%classical_particle_t%initialize()
155 end subroutine charged_particle_initialize
157 ! ---------------------------------------------------------
158 logical function charged_particle_is_tolerance_reached(this, tol) result(converged)
159 class(charged_particle_t), intent(in) :: this
160 real(real64), intent(in) :: tol
163
164 converged = this%classical_particle_t%is_tolerance_reached(tol)
165
168
169 ! ---------------------------------------------------------
170 subroutine charged_particle_update_quantity(this, label)
171 class(charged_particle_t), intent(inout) :: this
172 character(len=*), intent(in) :: label
173
176 select case (label)
177 case ("current")
178 ! we do not explicitly compute the current as it is only needed
179 ! by the current_to_mxll_field_t interaction where it is mapped
180 ! to a grid using charge, position and velocity
181 case default
182 ! Other quantities should be handled by the parent class
183 call this%classical_particle_t%update_quantity(label)
184 end select
185
188
189 ! ---------------------------------------------------------
190 subroutine charged_particle_init_interaction_as_partner(partner, interaction)
191 class(charged_particle_t), intent(in) :: partner
192 class(interaction_surrogate_t), intent(inout) :: interaction
193
195
196 select type (interaction)
197 type is (coulomb_force_t)
198 interaction%partner_np = 1
199 safe_allocate(interaction%partner_charge(1))
200 safe_allocate(interaction%partner_pos(1:partner%space%dim, 1))
202 interaction%partner_np = 1
203 interaction%grid_based_partner = .false.
204 safe_allocate(interaction%partner_charge(1))
205 safe_allocate(interaction%partner_pos(1:partner%space%dim, 1))
206 safe_allocate(interaction%partner_vel(1:partner%space%dim, 1))
207 class default
208 ! Other interactions should be handled by the parent class
209 call partner%classical_particle_t%init_interaction_as_partner(interaction)
210 end select
211
214
215 ! ---------------------------------------------------------
216 subroutine charged_particle_copy_quantities_to_interaction(partner, interaction)
217 class(charged_particle_t), intent(inout) :: partner
218 class(interaction_surrogate_t), intent(inout) :: interaction
219
221
222 select type (interaction)
224 interaction%partner_charge(1) = partner%charge(1)
225 interaction%partner_pos(:,1) = partner%pos(:, 1)
226
228 interaction%partner_charge(1) = partner%charge(1)
229 interaction%partner_pos(:,1) = partner%pos(:, 1)
230 interaction%partner_vel(:,1) = partner%vel(:, 1)
231 call interaction%do_mapping()
232
233 class default
234 call partner%classical_particle_t%copy_quantities_to_interaction(interaction)
235 end select
236
239
240end module charged_particle_oct_m
241
242!! Local Variables:
243!! mode: f90
244!! coding: utf-8
245!! End:
Prints out to iunit a message in the form: ["InputVariable" = value] where "InputVariable" is given b...
Definition: messages.F90:182
This module implements the basic elements defining algorithms.
Definition: algorithm.F90:143
subroutine charged_particle_init_interaction_as_partner(partner, interaction)
subroutine, public charged_particle_init(this, namespace, grp)
The init routine is a module level procedure This has the advantage that different classes can have d...
subroutine charged_particle_update_quantity(this, label)
class(charged_particle_t) function, pointer charged_particle_constructor(namespace, grp)
The factory routine (or constructor) allocates a pointer of the corresponding type and then calls the...
subroutine charged_particle_initialize(this)
subroutine charged_particle_copy_quantities_to_interaction(partner, interaction)
subroutine charged_particle_init_interaction(this, interaction)
logical function charged_particle_is_tolerance_reached(this, tol)
subroutine, public classical_particle_init(this, namespace, grp)
The init routine is a module level procedure This has the advantage that different classes can have d...
real(real64), parameter, public m_one
Definition: global.F90:201
integer, parameter, public lorentz_force
integer, parameter, public current_to_mxll_field
integer, parameter, public coulomb_force
This module defines the abstract interaction_t class, and some auxiliary classes for interactions.
This module implements the multisystem debug functionality.
This module defines the quantity_t class and the IDs for quantities, which can be exposed by a system...
Definition: quantity.F90:140
This module implements the abstract system type.
Definition: system.F90:120
class for a charged classical particle
class for a neutral classical particle
Coulomb interaction between two systems of particles.
Class to transfer a current to a Maxwell field.
surrogate interaction class to avoid circular dependencies between modules.
Lorenz force between a systems of particles and an electromagnetic field.
Systems (system_t) can expose quantities that can be used to calculate interactions with other system...
Definition: quantity.F90:173
int true(void)