Octopus
classical_particle.F90
Go to the documentation of this file.
1!! Copyright (C) 2019 N. Tancogne-Dejean
2!! Copyright (C) 2020 M. Oliveira
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
26 use global_oct_m
31 use io_oct_m
35 use parser_oct_m
39 use space_oct_m
40 use system_oct_m
41 use unit_oct_m
43
44 implicit none
45
46 private
47 public :: &
50
51 integer, parameter :: &
52 OUTPUT_COORDINATES = 1, &
54
58 contains
59 procedure :: init_interaction => classical_particle_init_interaction
60 procedure :: initial_conditions => classical_particle_initial_conditions
61 procedure :: update_quantity => classical_particle_update_quantity
62 procedure :: init_interaction_as_partner => classical_particle_init_interaction_as_partner
63 procedure :: copy_quantities_to_interaction => classical_particle_copy_quantities_to_interaction
66
67 interface classical_particle_t
68 procedure classical_particle_constructor
69 end interface classical_particle_t
70
71contains
72
73 ! ---------------------------------------------------------
78 function classical_particle_constructor(namespace) result(sys)
79 class(classical_particle_t), pointer :: sys
80 type(namespace_t), intent(in) :: namespace
81
83
84 allocate(sys)
85
86 call classical_particle_init(sys, namespace)
87
90
91 ! ---------------------------------------------------------
96 ! ---------------------------------------------------------
97 subroutine classical_particle_init(this, namespace)
98 class(classical_particle_t), intent(inout) :: this
99 type(namespace_t), intent(in) :: namespace
100
102
103 this%namespace = namespace
104
105 this%space = space_t(namespace)
106 if (this%space%is_periodic()) then
107 call messages_not_implemented('Classical particle for periodic systems')
108 end if
109
110 call messages_print_with_emphasis(msg="Classical Particle", namespace=namespace)
111
112 call classical_particles_init(this, 1)
113
114 !%Variable ParticleMass
115 !%Type float
116 !%Section ClassicalParticles
117 !%Description
118 !% Mass of classical particle in Kg.
119 !%End
120 call parse_variable(namespace, 'ParticleMass', m_one, this%mass(1))
121 call messages_print_var_value('ParticleMass', this%mass(1), namespace=namespace)
122
123 this%supported_interactions = [this%supported_interactions, gravity, lennard_jones]
124 this%supported_interactions_as_partner = [this%supported_interactions_as_partner, gravity, lennard_jones]
125
126 !%Variable LennardJonesEpsilon
127 !%Type float
128 !%Section ClassicalParticles
129 !%Description
130 !% Epsilon parameter (dispersion energy) of Lennard-Jones interaction for this species.
131 !% In case two particles have a different epsilon, the combination rule will be computed
132 !% <math>\epsilon_{12} = \sqrt{\epsilon_1 + \epsilon_2}</math>.
133 !%End
134 call parse_variable(namespace, 'LennardJonesEpsilon', m_one, this%lj_epsilon(1))
135 call messages_print_var_value('LennardJonesEpsilon', this%lj_epsilon(1), namespace=namespace)
136
137 !%Variable LennardJonesSigma
138 !%Type float
139 !%Section ClassicalParticles
140 !%Description
141 !% Sigma parameter (particle size) of Lennard-Jones interaction for this species.
142 !% In case two particles have a different sigma, the combination rule will be computed
143 !% <math>\sigma_{12} = (\sigma_1 + \sigma_2) / 2.
144 !%End
145 call parse_variable(namespace, 'LennardJonesSigma', m_one, this%lj_sigma(1))
146 call messages_print_var_value('LennardJonesSigma', this%lj_sigma(1), namespace=namespace)
147
148 call messages_print_with_emphasis(namespace=namespace)
149
151 end subroutine classical_particle_init
153 ! ---------------------------------------------------------
154 subroutine classical_particle_init_interaction(this, interaction)
155 class(classical_particle_t), target, intent(inout) :: this
156 class(interaction_t), intent(inout) :: interaction
159
160 select type (interaction)
161 type is (gravity_t)
162 call interaction%init(this%space%dim, 1, this%mass, this%pos)
163 type is (lennard_jones_t)
164 if (.not. (parse_is_defined(this%namespace, 'LennardJonesSigma') .and. &
165 parse_is_defined(this%namespace, 'LennardJonesEpsilon') )) then
166 write(message(1),'(a,es9.2)') 'Using default value for Lennard-Jones parameter.'
167 call messages_warning(1, namespace=this%namespace)
168 end if
169
170 call interaction%init(this%space%dim, 1, this%pos, this%lj_epsilon(1), this%lj_sigma(1))
171 class default
172 call classical_particles_init_interaction(this, interaction)
173 end select
174
177
178 ! ---------------------------------------------------------
180 class(classical_particle_t), intent(inout) :: this
181
182 integer :: n_rows, idir
183 type(block_t) :: blk
184
186
187 !%Variable ParticleInitialPosition
188 !%Type block
189 !%Section ClassicalParticles
190 !%Description
191 !% Initial position of classical particle, in Km.
192 !%End
193 this%pos = m_zero
194 if (parse_block(this%namespace, 'ParticleInitialPosition', blk) == 0) then
195 n_rows = parse_block_n(blk)
196 if (n_rows > 1) call messages_input_error(this%namespace, 'ParticleInitialPosition')
197
198 do idir = 1, this%space%dim
199 call parse_block_float(blk, 0, idir - 1, this%pos(idir, 1))
200 end do
201 call parse_block_end(blk)
202 end if
203 call messages_print_var_value('ParticleInitialPosition', this%pos(1:this%space%dim, 1), namespace=this%namespace)
204
205 !%Variable ParticleInitialVelocity
206 !%Type block
207 !%Section ClassicalParticles
208 !%Description
209 !% Initial velocity of classical particle in Km/s.
210 !%End
211 this%vel = m_zero
212 if (parse_block(this%namespace, 'ParticleInitialVelocity', blk) == 0) then
213 n_rows = parse_block_n(blk)
214 if (n_rows > 1) call messages_input_error(this%namespace, 'ParticleInitialVelocity')
215 do idir = 1, this%space%dim
216 call parse_block_float(blk, 0, idir - 1, this%vel(idir, 1))
217 end do
218 call parse_block_end(blk)
219 end if
220 call messages_print_var_value('ParticleInitialVelocity', this%vel(1:this%space%dim, 1), namespace=this%namespace)
221
224
225 ! ---------------------------------------------------------
226 subroutine classical_particle_update_quantity(this, iq)
227 class(classical_particle_t), intent(inout) :: this
228 integer, intent(in) :: iq
229
231
232 ! We are only allowed to update quantities that can be updated on demand
233 assert(this%quantities(iq)%updated_on_demand)
234
235 select case (iq)
236 case default
237 ! Other quantities should be handled by the parent class
239 end select
240
243
244 ! ---------------------------------------------------------
245 subroutine classical_particle_init_interaction_as_partner(partner, interaction)
246 class(classical_particle_t), intent(in) :: partner
247 class(interaction_surrogate_t), intent(inout) :: interaction
248
250
251 select type (interaction)
252 type is (gravity_t)
253 interaction%partner_np = 1
254 safe_allocate(interaction%partner_mass(1))
255 safe_allocate(interaction%partner_pos(1:partner%space%dim, 1))
256 interaction%partner_pos = m_zero
257
258 type is (lennard_jones_t)
259 interaction%partner_np = 1
260 safe_allocate(interaction%partner_pos(1:partner%space%dim, 1))
261 ! in case the LennardJones epsilon and sigma of system and partner are different,
262 ! we compute the combination rules with arithmetic and geometric means:
263 ! (they give back the original parameters if they happen to be equal):
264 ! sigma_12 = (sigma_1 + sigma_2)/2, epsilon_12 = sqrt(epsilon_1 * epsilon_2)
265 interaction%lj_sigma = m_half * (partner%lj_sigma(1) + interaction%lj_sigma)
266 interaction%lj_epsilon = sqrt(partner%lj_epsilon(1) * interaction%lj_epsilon)
267
268 class default
269 ! Other interactions should be handled by the parent class
270 call classical_particles_init_interaction_as_partner(partner, interaction)
271 end select
275
276 ! ---------------------------------------------------------
277 subroutine classical_particle_copy_quantities_to_interaction(partner, interaction)
278 class(classical_particle_t), intent(inout) :: partner
279 class(interaction_surrogate_t), intent(inout) :: interaction
280
282
283 select type (interaction)
284 type is (gravity_t)
285 interaction%partner_mass(1) = partner%mass(1)
286 interaction%partner_pos(:,1) = partner%pos(:,1)
287
288 type is (lennard_jones_t)
289 interaction%partner_pos(:,1) = partner%pos(:,1)
290
291 class default
292 message(1) = "Unsupported interaction."
293 call messages_fatal(1, namespace=partner%namespace)
294 end select
295
298
299 ! ---------------------------------------------------------
300 subroutine classical_particle_finalize(this)
301 type(classical_particle_t), intent(inout) :: this
302
304
305 call classical_particles_end(this)
306
308 end subroutine classical_particle_finalize
309
311
312!! Local Variables:
313!! mode: f90
314!! coding: utf-8
315!! End:
Prints out to iunit a message in the form: ["InputVariable" = value] where "InputVariable" is given b...
Definition: messages.F90:180
This module implements the basic elements defining algorithms.
Definition: algorithm.F90:141
subroutine, public classical_particle_init(this, namespace)
The init routine is a module level procedure This has the advantage that different classes can have d...
subroutine classical_particle_init_interaction_as_partner(partner, interaction)
subroutine classical_particle_initial_conditions(this)
subroutine classical_particle_finalize(this)
integer, parameter output_energy
class(classical_particle_t) function, pointer classical_particle_constructor(namespace)
The factory routine (or constructor) allocates a pointer of the corresponding type and then calls the...
subroutine classical_particle_update_quantity(this, iq)
subroutine classical_particle_init_interaction(this, interaction)
subroutine classical_particle_copy_quantities_to_interaction(partner, interaction)
subroutine, public classical_particles_init_interaction_as_partner(partner, interaction)
subroutine, public classical_particles_end(this)
subroutine, public classical_particles_init(this, np)
The init routine is a module level procedure This has the advantage that different classes can have d...
subroutine, public classical_particles_update_quantity(this, iq)
subroutine, public classical_particles_init_interaction(this, interaction)
real(real64), parameter, public m_zero
Definition: global.F90:187
real(real64), parameter, public m_half
Definition: global.F90:193
real(real64), parameter, public m_one
Definition: global.F90:188
integer, parameter, public lennard_jones
integer, parameter, public gravity
This module defines the abstract interaction_t class, and some auxiliary classes for interactions.
Definition: io.F90:114
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:930
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1125
character(len=512), private msg
Definition: messages.F90:165
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:543
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:420
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:723
logical function, public parse_is_defined(namespace, name)
Definition: parser.F90:502
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:618
This module implements the basic propagator framework.
Definition: propagator.F90:117
This module defines the quantity_t class and the IDs for quantities, which can be exposed by a system...
Definition: quantity.F90:137
This module implements the abstract system type.
Definition: system.F90:118
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.
class for a neutral classical particle
Gravity interaction between two systems of particles. This should be used for testing purposes only....
Definition: gravity.F90:135
abstract interaction class
surrogate interaction class to avoid circular dependencies between modules.
Lennard-Jones interaction between two systems of particles.