Octopus
external_waves.F90
Go to the documentation of this file.
1!! Copyright (C) 2023 E.I. Albar, F. Bonafe and Heiko Appel
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 accel_oct_m
24 use clock_oct_m
26 use debug_oct_m
29 use global_oct_m
31 use grid_oct_m
32 use index_oct_m
37 use, intrinsic :: iso_fortran_env
39 use io_oct_m
41 use lasers_oct_m
45 use mesh_oct_m
47 use mpi_oct_m
50 use parser_oct_m
54 use string_oct_m
55 use types_oct_m
56 use unit_oct_m
60
61 implicit none
62
63 private
64 public :: &
71
72 type bessel_beam_t
73 integer, allocatable :: helicity(:)
74 integer, allocatable :: m_order(:)
75 real(real64), allocatable :: amp(:)
76 real(real64), allocatable :: theta_k(:)
77 real(real64), allocatable :: omega(:)
78 real(real64), allocatable :: shift(:,:)
79 logical, allocatable :: envelope(:)
80 integer, allocatable :: lin_dir(:)
81 contains
82 procedure :: init => bessel_beam_init
83 procedure :: function => bessel_beam_function
85 end type bessel_beam_t
86
88 integer :: points_number
89 integer, allocatable :: points_map(:)
90 integer :: number
91 integer, allocatable :: modus(:)
92 ! !! (see MAXWELLINCIDENTWAVES)
93 integer, allocatable :: field_type(:)
94 character(len=1024), allocatable :: e_field_string(:,:)
95 real(real64), allocatable :: k_vector(:,:)
96 real(real64), allocatable :: v_vector(:,:)
97 complex(real64), allocatable :: e_field(:,:)
98 real(real64), allocatable :: pw_phase(:)
99 type(mxf_t), allocatable :: mx_function(:)
100 integer :: out_file
101 logical :: output_from_point = .false.
102 real(real64), allocatable :: selected_point_coordinate(:)
103 real(real64), allocatable :: selected_point_field(:)
104 real(real64) :: c_factor
105 type(accel_mem_t) :: buff_map
106 type(bessel_beam_t) :: bessel
107 contains
108 procedure :: init_interaction_as_partner => external_waves_init_interaction_as_partner
109 procedure :: update_quantity => external_waves_update_quantity
110 procedure :: copy_quantities_to_interaction => external_waves_copy_quantities_to_interaction
111 final :: external_waves_end
112 end type external_waves_t
113
114 interface external_waves_t
116 end interface external_waves_t
117
118contains
119
120 function external_waves_constructor(namespace) result(this)
121 class(external_waves_t), pointer :: this
122 type(namespace_t), intent(in) :: namespace
123
124 integer :: iq
125 character(len=:), allocatable :: quantities(:)
126
128
129 safe_allocate(this)
130
131 this%namespace = namespace_t("ExternalSource", parent=namespace)
132
133 message(1) = 'Plane-wave is currently always 3D and non-periodic.'
134 call messages_warning(1)
135 call external_waves_init(this, this%namespace)
136
137 quantities = [character(16) :: "E field", "vector potential", "B field"]
138 do iq = 1, size(quantities)
139 call this%quantities%add(quantity_t(quantities(iq), always_available = .true., &
140 updated_on_demand = .true., iteration = clock_t()))
141 end do
142
143 this%supported_interactions_as_partner = [mxll_e_field_to_matter, mxll_b_field_to_matter, &
145
147 end function external_waves_constructor
148
149 ! ---------------------------------------------------------
150 subroutine external_waves_init_interaction_as_partner(partner, interaction)
151 class(external_waves_t), intent(in) :: partner
152 class(interaction_surrogate_t), intent(inout) :: interaction
153
155
156 select type (interaction)
157 type is (lorentz_force_t)
158 ! Nothing to be initialized
160 ! Nothing to be initialized
162 ! Nothing to be initialized
164 ! Nothing to be initialized
165 class default
166 message(1) = "Unsupported interaction."
167 call messages_fatal(1, namespace=partner%namespace)
168 end select
172 ! ---------------------------------------------------------
173 subroutine external_waves_update_quantity(this, label)
174 class(external_waves_t), intent(inout) :: this
175 character(len=*), intent(in) :: label
176
179 select case (label)
180 case ("E field", "B field", "vector potential")
181 ! We will not update the quantities here because they are computed
182 ! on-the-fly when copying them to the corresponding interaction (see
183 ! copy_quantities_to_interaction routine)
184 case default
185 message(1) = "Incompatible quantity."
186 call messages_fatal(1, namespace=this%namespace)
187 end select
192 ! ---------------------------------------------------------
193 subroutine external_waves_copy_quantities_to_interaction(partner, interaction)
194 class(external_waves_t), intent(inout) :: partner
195 class(interaction_surrogate_t), intent(inout) :: interaction
197 class(quantity_t), pointer :: quantity
201 select type(interaction)
202 class is (mxll_e_field_to_matter_t)
203 quantity => partner%quantities%get("E field")
204 interaction%system_field = m_zero
205 call external_waves_eval(partner, quantity%iteration%value(), interaction%system_gr, "E field", &
206 interaction%system_field)
207 call interaction%do_mapping()
208
209 class is (mxll_vec_pot_to_matter_t)
210 quantity => partner%quantities%get("vector potential")
211 interaction%system_field = m_zero
212 call external_waves_eval(partner, quantity%iteration%value(), interaction%system_gr, &
213 "vector potential", interaction%system_field)
214 call interaction%do_mapping()
216 class is (mxll_b_field_to_matter_t)
217 quantity => partner%quantities%get("B field")
218 interaction%system_field = m_zero
219 call external_waves_eval(partner, quantity%iteration%value(), interaction%system_gr, "B field", &
220 interaction%system_field, der=interaction%system_gr%der)
221 call interaction%do_mapping()
222
223 class default
224 message(1) = "Incompatible interaction."
225 call messages_fatal(1, namespace=partner%namespace)
226 end select
227
230
231 ! ---------------------------------------------------------
232 ! Load the external source for the multisystem framework
233 subroutine load_external_waves(partners, namespace)
234 class(partner_list_t), intent(inout) :: partners
235 type(namespace_t), intent(in) :: namespace
236
237 logical :: has_source
238
239 push_sub(load_external_waves)
240
241 !%Variable AnalyticalExternalSource
242 !%Type logical
243 !%Default no
244 !%Section Maxwell
245 !%Description
246 !% This means the analytical evaluation of formula will be used, Maxwell propagation will not be used.
247 !%End
248 call parse_variable(namespace, 'AnalyticalExternalSource', .false., has_source)
249
250 if (has_source) then
251 call partners%add(external_waves_t(namespace))
252 end if
253
254 pop_sub(load_external_waves)
255 end subroutine load_external_waves
256
257
259 ! ---------------------------------------------------------
260 subroutine external_waves_init(external_waves, namespace)
261 type(external_waves_t), intent(inout) :: external_waves
262 type(namespace_t), intent(in) :: namespace
263 type(block_t) :: blk
264 integer :: il, nlines, ncols, iex_norm, idim
265 integer, parameter :: sys_dim = 3
266 real(real64) :: k_vector(sys_dim), velocity(sys_dim), x_pos(sys_dim)
267 real(real64) :: x_norm, dummy(sys_dim), k_dot_e , test_limit, k_norm, output_pos(3)
268 complex(real64) :: e_field(sys_dim)
269 character(len=1024) :: k_string(sys_dim)
270 character(len=1), dimension(sys_dim), parameter :: dims = ["x", "y", "z"]
271 character(len=1024) :: mxf_expression
272
273 push_sub(external_waves_init)
274
275 call profiling_in('EXTERNAL_WAVES_INIT')
276
277 test_limit = 10.0e-9_real64
278
279 !%Variable ExternalSourceBesselOutput
280 !%Type block
281 !%Section Maxwell
282 !%Description
283 !% The ExternalSourceBesselOutput block allows to output analytically calculated fields at a
284 !% particular point in space. The columns denote the x, y, and z coordinate of the point.
285 !% Please be aware that ExternalSource lives on the grid of the system that it is applied to.
286 !% Therefore, it might not be evaluated at every point in space. When comparing, please be sure
287 !% to check the log and compare if your required point in space matches the evaluated position.
288 !%
289 !% <tt>%ExternalSourceBesselOutput
290 !% <br>&nbsp;&nbsp; -1.0 | 2.0 | 4.0
291 !% <br>%</tt>
292 !%
293 !%End
294
295 if (parse_block(namespace, 'ExternalSourceBesselOutput', blk) == 0) then
296 nlines = parse_block_n(blk)
297 if (nlines > 1 ) then
298 message(2) = 'ExternalSource output is limited to one point.'
299 call messages_fatal(1, namespace=namespace)
300 end if
301 ncols = parse_block_cols(blk,0)
302 if (ncols /= 3 ) then
303 message(1) = 'ExternalSourceBesselOutput must have 3 columns.'
304 call messages_fatal(1, namespace=namespace)
305 end if
306 external_waves%output_from_point= .true.
307 safe_allocate(external_waves%selected_point_coordinate(1:3))
308 safe_allocate(external_waves%selected_point_field(1:3))
309
310 do idim = 1, 3
311 call parse_block_float(blk, 0, idim-1, output_pos(idim), units_inp%length)
312 end do
313 external_waves%selected_point_coordinate(1:3) = output_pos(1:3)
314 external_waves%selected_point_field(1:3) = m_zero
315
316 call parse_block_end(blk)
317 call io_mkdir('ExternalSource')
318 external_waves%out_file = io_open('bessel_source_at_point', namespace=namespace, action='write')
319 write(external_waves%out_file, '(12a) ') '# Time (a.u.) ' , ' Field-x ' , ' Field-y ' , ' Field-z '
320
321 else
322 external_waves%output_from_point= .false.
323
324 end if
325
326 ! This variable is documented in hamiltonian_mxll.F90
327 call parse_variable(namespace, 'SpeedOfLightFactor', m_one, external_waves%c_factor)
329 !%Variable MaxwellIncidentWaves
330 !%Type block
331 !%Section Maxwell
332 !%Description
333 !% The initial electromagnetic fields can be set by the user
334 !% with the <tt>MaxwellIncidentWaves</tt> block variable.
335 !% The electromagnetic fields have to fulfill the
336 !% Maxwells equations in vacuum.
337 !% For a Maxwell propagation, setting the electric field is sufficient,
338 !% the magnetic field (for plane waves) will be calculated from it as 1/(c.|k|) . (k x E).
339 !%
340 !% Example:
341 !%
342 !% <tt>%MaxwellIncidentWaves
343 !% <br>&nbsp;&nbsp; plane_wave_parser | "field_type"| "k1x" | "k1y" | "k1z" | "E1x" | "E1z" | "E1x"
344 !% <br>&nbsp;&nbsp; plane_wave_mx_function | "field_type"| "E4x" | "E4y" | "E4z" | mx_envelope_name | phase
345 !% <br>&nbsp;&nbsp; bessel_function | "field_type"| A_0 | m | omega | helicity | <math>\theta_{k}</math> |
346 !% mx_envelope_name | lin_dir
347 !% <br>%</tt>
348 !%
349 !% Field type can be "electric_field" or "vector_potential". Note that in order to couple to an
350 !% electronic system, the <tt>MaxwellCouplingMode</tt> variable needs to be set to a coupling type
351 !% compatible with the requested field type ("electric_field" is compatible with length gauge,
352 !% while "vector_potential" is compatible with velocity gauge and full minimal coupling).
353 !% Otherwise, the field will not be calculated or applied to the electronic Hamiltonian.
354 !%
355 !%Option plane_wave_parser 0
356 !% Parser input modus
357 !%Option plane_wave_mx_function 1
358 !% The incident wave envelope is defined by an mx_function
359 !%Option bessel_function 2
360 !% The incident source is a generalized Bessel beam, parametrized by its amplitude, opening angle, helicity,
361 !% order and frequency. This beam is a solution of Maxwell equations, and inherently circularly polarized
362 !% and is parametrized by its amplitude,opening angle, helicity, order and frequency.
363 !% Please keep in mind, if you set linear polarization lin_dir,
364 !% you will obtain a linearly polarized Bessel beam.
365 !%End
366
367 if (parse_block(namespace, 'MaxwellIncidentWaves', blk) == 0) then
368
369 call messages_print_with_emphasis(msg='Substitution of the electromagnetic incident waves', namespace=namespace)
370
371 ! find out how many lines (i.e. states) the block has
372 nlines = parse_block_n(blk)
373
374 external_waves%number = nlines
375 safe_allocate(external_waves%modus(1:nlines))
376 safe_allocate(external_waves%e_field_string(1:3, 1:nlines))
377 safe_allocate(external_waves%e_field(1:3, 1:nlines))
378 safe_allocate(external_waves%k_vector(1:3, 1:nlines))
379 safe_allocate(external_waves%v_vector(1:3, 1:nlines))
380 safe_allocate(external_waves%mx_function(1:nlines))
381 safe_allocate(external_waves%field_type(1:nlines))
382 safe_allocate(external_waves%pw_phase(1:nlines))
383 external_waves%pw_phase = m_zero
384
385 call external_waves%bessel%init(nlines, 3)
386
387 do il = 1, nlines
388 ncols = parse_block_cols(blk, il - 1)
389 if ((ncols < 5) .or. (ncols > 9)) then
390 message(1) = 'Each line in the MaxwellIncidentWaves block must have five to nine columns.'
391 call messages_fatal(1, namespace=namespace)
392 end if
393
394 ! check input modus e.g. parser of defined functions
395 call parse_block_integer(blk, il - 1, 0, external_waves%modus(il))
396 call parse_block_integer(blk, il - 1, 1, external_waves%field_type(il))
397
398 ! parse formula string
399 if (external_waves%modus(il) == option__maxwellincidentwaves__plane_wave_parser) then
400 do idim = 1, 3
401 call parse_block_string( blk, il - 1, idim + 1, k_string(idim))
402 call parse_block_string( blk, il - 1, 3 + idim + 1, external_waves%e_field_string(idim, il))
403 end do
404 write(message(1), '(a,i2,a) ') 'Substituting electromagnetic incident wave ', il, ' with the expressions: '
405 call messages_info(1, namespace=namespace)
406 do idim = 1, 3
407 write(message(idim), '(6a)') ' Wave vector k('//dims(idim)//') = ', trim(k_string(idim))
408 write(message(idim+1), '(2a)') ' E-field('//dims(idim)//') for t_0 = ', &
409 trim(external_waves%e_field_string(idim, il))
410 end do
411 call messages_info(6, namespace=namespace)
412
413 do idim = 1, 3
414 call conv_to_c_string(k_string(idim))
415 call conv_to_c_string(external_waves%e_field_string(idim, il))
416 end do
417
418 x_pos(:) = m_zero
419 x_norm = m_zero
420 do idim = 1, 3
421 call parse_expression(k_vector(idim), dummy(idim), idim, x_pos, x_norm, m_zero, k_string(idim))
422 end do
423
424 k_norm = norm2(k_vector)
425
426 velocity(:) = k_vector(:) / k_norm * p_c * external_waves%c_factor
427 external_waves%k_vector(:,il) = k_vector(:)
428 external_waves%v_vector(:,il) = velocity(:)
429
430 else if (external_waves%modus(il) == option__maxwellincidentwaves__plane_wave_mx_function) then
431 do idim = 1, 3
432 call parse_block_cmplx( blk, il - 1, idim + 1, e_field(idim))
433 end do
434 call parse_block_string( blk, il - 1, 3 + 2, mxf_expression)
435
436 write(message(1), '(a,i2) ') 'Substituting electromagnetic incident wave ', il
437 write(message(2), '(a)' ) 'with the expression: '
438 call messages_info(2, namespace=namespace)
439
440 do idim = 1, 3
441 write(message(idim), '(a,f9.4,sp,f9.4,"i")') ' E-field('//trim(dims(idim))//') complex amplitude = ', &
442 real(e_field(idim)), aimag(e_field(idim))
443 end do
444 write(message(4), '(2a)' ) ' Maxwell wave function name = ', trim(mxf_expression)
445 call messages_info(4, namespace=namespace)
446
447 call mxf_read(external_waves%mx_function(il), namespace, trim(mxf_expression), iex_norm)
448 if (iex_norm /= 0) then
449 write(message(1),'(3A)') 'Ex_norm in the ""', trim(mxf_expression), &
450 '"" field defined in the MaxwellIncidentWaves block'
451 call messages_fatal(1, namespace=namespace)
452 end if
453 if (parse_block_cols(blk, il-1) == 7) then
454 call parse_block_float( blk, il - 1, 3 + 3 , external_waves%pw_phase(il))
455 end if
456 k_vector(1:3) = external_waves%mx_function(il)%k_vector(1:3)
457 k_norm = norm2(k_vector)
458
459 k_dot_e = real(dot_product(k_vector, e_field), real64)
460 if (abs(k_dot_e) > test_limit) then
461 write(message(1), '(a) ') 'The wave vector k or its electric field are not perpendicular. '
462 write(message(2), '(a,f8.3,a)' ) 'Their dot product yields the magnitude', abs(k_dot_e) , ' while'
463 write(message(3), '(a,f8.3,a)' ) 'tolerance is ', test_limit ,'.'
464 call messages_fatal(3, namespace=namespace)
465 end if
466 if (k_norm < 1e-10_real64) then
467 message(1) = 'The k vector is not set correctly: |k|~0 .'
468 call messages_fatal(1, namespace=namespace)
469 end if
470
471 external_waves%e_field(:,il) = e_field(:)
472 external_waves%k_vector(:,il) = k_vector(:)
473 external_waves%v_vector(:,il) = k_vector(:) / k_norm * p_c * external_waves%c_factor
474
475 else if (external_waves%modus(il) == option__maxwellincidentwaves__bessel_function) then
476 call parse_block_float( blk, il - 1, 2 , external_waves%bessel%amp(il))
477 call parse_block_integer( blk, il - 1, 3 , external_waves%bessel%m_order(il))
478 call parse_block_float( blk, il - 1, 4 , external_waves%bessel%omega(il))
479 call parse_block_integer( blk, il - 1, 5 , external_waves%bessel%helicity(il))
480 call parse_block_float( blk, il - 1, 6 , external_waves%bessel%theta_k(il))
481 if (parse_block_cols(blk, il-1) > 7) then
482 call parse_block_string( blk, il - 1, 7 , mxf_expression)
483 external_waves%bessel%envelope(il) = .true.
484 call mxf_read(external_waves%mx_function(il), namespace, trim(mxf_expression), iex_norm)
485 end if
486 if (parse_block_cols(blk, il-1) == 9) then
487 call parse_block_integer( blk, il - 1, 8 , external_waves%bessel%lin_dir(il))
488 end if
489
490 write(message(1), '(a,i2) ') 'Incident Bessel Beam', il
491 call messages_info(1, namespace=namespace)
492
493 if (abs(external_waves%bessel%helicity(il)) /= 1) then
494 write(message(1),'(A)') 'Helicity has to be either +1 or -1 !'
495 call messages_fatal(1, namespace=namespace)
496 end if
497
498 write(message(1), '(a,f5.3)' ) ' Bessel Amplitude ', external_waves%bessel%amp(il)
499 write(message(2), '(a,i2)' ) ' Bessel Order m', external_waves%bessel%m_order(il)
500 write(message(3), '(a,f5.3)' ) ' Bessel Frequency ', external_waves%bessel%omega(il)
501 write(message(4), '(a,i2)' ) ' Bessel Helicity ', external_waves%bessel%helicity(il)
502 write(message(5), '(a,f5.3)' ) ' Bessel Opening Angle ', external_waves%bessel%theta_k(il)
503 call messages_info(4, namespace=namespace)
504
505 if (external_waves%bessel%lin_dir(il)/= 0) then
506 write(message(5), '(a,i2)' ) ' Bessel is Linearly Polarized in Direction : ', external_waves%bessel%lin_dir(il)
507 call messages_info(4, namespace=namespace)
508 end if
509
510 end if
511 end do
512
513 call parse_block_end(blk)
514
515 call messages_print_with_emphasis(namespace=namespace)
516 else
517 external_waves%number = 0
518
519 end if
520
521 !%Variable BesselBeamAxisShift
522 !%Type block
523 !%Section Maxwell
524 !%Description
525 !% The BesselBeamAxisShift block allows to shift the Bessel Beam, which is centered at (0,0,0) as default.
526 !% Selected position point will be used as the new center of the Bessel Beam.
527 !% When defining a BesselBeamAxisShift, please make sure to define a shift for each Bessel source you use,
528 !% then it is possible to tell which source is shifted according to which BesselShift, respectively.
529 !% <tt>%BesselBeamAxisShift
530 !% <br>&nbsp;&nbsp; 0.0 | 2.0 | 5.0
531 !% <br>%</tt>
532 !%
533 !%End
534
535 if (parse_block(namespace, 'BesselBeamAxisShift', blk) == 0) then
536 nlines = parse_block_n(blk)
537 ncols = parse_block_cols(blk,0)
538 if (ncols /= 3 ) then
539 message(1) = 'BesselBeamAxisShift must have 3 columns.'
540 call messages_fatal(1, namespace=namespace)
541 end if
542
543 do il = 1, nlines
544 do idim = 1, 3
545 call parse_block_float(blk, il-1, idim-1, external_waves%bessel%shift(il, idim), units_inp%length)
546 end do
547 end do
548
549 call parse_block_end(blk)
550 end if
551
552 call profiling_out('EXTERNAL_WAVES_INIT')
553
554 pop_sub(external_waves_init)
555 end subroutine external_waves_init
556
557 ! ---------------------------------------------------------
558 subroutine external_waves_end(external_waves)
559 type(external_waves_t), intent(inout) :: external_waves
560
561 push_sub(external_waves_end)
562
563 if (external_waves%output_from_point) then
564 call io_close(external_waves%out_file)
565 safe_deallocate_a(external_waves%selected_point_coordinate)
566 safe_deallocate_a(external_waves%selected_point_field)
567 end if
568
569 safe_deallocate_a(external_waves%bessel%shift)
570 safe_deallocate_a(external_waves%points_map)
571 safe_deallocate_a(external_waves%modus)
572 safe_deallocate_a(external_waves%e_field_string)
573 safe_deallocate_a(external_waves%k_vector)
574 safe_deallocate_a(external_waves%v_vector)
575 safe_deallocate_a(external_waves%e_field)
576 safe_deallocate_a(external_waves%mx_function)
577 safe_deallocate_a(external_waves%pw_phase)
578
579 if (accel_is_enabled()) then
580 call accel_free_buffer(external_waves%buff_map)
581 end if
582
583 pop_sub(external_waves_end)
584 end subroutine external_waves_end
585
586 ! ---------------------------------------------------------
588 subroutine external_waves_eval(external_waves, time, mesh, type_of_field, out_field_total, der)
589 type(external_waves_t), intent(inout) :: external_waves
590 real(real64), intent(in) :: time
591 class(mesh_t), intent(in) :: mesh
592 character(len=*), intent(in) :: type_of_field
593 real(real64), intent(out) :: out_field_total(:, :)
594 type(derivatives_t), optional, intent(in):: der
595
596
597 push_sub(external_waves_eval)
598
599 call profiling_in('EXTERNAL_WAVES_EVAL')
600
601 out_field_total = m_zero
602
603 call plane_waves_eval(external_waves, time, mesh, type_of_field, out_field_total, der=der)
604 call bessel_source_eval(external_waves, time, mesh, type_of_field, out_field_total, der=der)
605
606 call profiling_out('EXTERNAL_WAVES_EVAL')
607
608 pop_sub(external_waves_eval)
609 end subroutine external_waves_eval
610
611 ! ---------------------------------------------------------
613 subroutine plane_waves_eval(external_waves, time, mesh, type_of_field, out_field_total, der)
614 type(external_waves_t), intent(inout) :: external_waves
615 real(real64), intent(in) :: time
616 class(mesh_t), intent(in) :: mesh
617 character(len=*), intent(in) :: type_of_field
618 real(real64), intent(out) :: out_field_total(:, :)
619 type(derivatives_t), optional, intent(in):: der
620
621 integer :: wn, idir
622 real(real64), allocatable :: pw_field(:,:), ztmp(:,:), b_field_aux(:,:)
623 real(real64) :: p_c_
624 integer, allocatable :: indices_pw_parser(:)
625 integer, allocatable :: indices_mx_ftc(:)
626 integer :: n_plane_waves, n_points
627
628 push_sub(plane_waves_eval)
629
630 call profiling_in('PLANE_WAVES_EVAL')
631
632 indices_pw_parser = pack([(wn, wn = 1,external_waves%number)], &
633 external_waves%modus == option__maxwellincidentwaves__plane_wave_parser)
634
635 indices_mx_ftc = pack([(wn, wn = 1,external_waves%number)], &
636 external_waves%modus == option__maxwellincidentwaves__plane_wave_mx_function)
637
638 n_plane_waves = size(indices_pw_parser) + size(indices_mx_ftc)
639
640 p_c_ = p_c * external_waves%c_factor
641
642 if (n_plane_waves == 0) then
643 call profiling_out('PLANE_WAVES_EVAL')
644 pop_sub(plane_waves_eval)
645 return
646 end if
647
648 if (type_of_field == "B field" .and. any(external_waves%field_type == e_field_vector_potential)) then
649 assert(present(der))
650 safe_allocate(ztmp(mesh%np, size(out_field_total, dim=2)))
651 n_points = mesh%np_part
652 else
653 n_points = mesh%np
654 end if
655 safe_allocate(pw_field(n_points, size(out_field_total, dim=2)))
656 pw_field(:,:) = m_zero
657
658 ! The E_field (or A_field, rescaled later) we calculate always
659 do wn = 1, external_waves%number
660
661 select case(external_waves%modus(wn))
662 case (option__maxwellincidentwaves__plane_wave_parser)
663 call pw_parsed_evaluation(external_waves, wn, time, mesh, n_points, pw_field)
664
665 case (option__maxwellincidentwaves__plane_wave_mx_function)
666 call pw_mx_function_evaluation(external_waves, wn, time, mesh, n_points, pw_field)
667 end select
668
669 select case (external_waves%field_type(wn))
670
671 case(e_field_electric)
672
673 select case (type_of_field)
674 case ("E field")
675 do idir = 1, size(out_field_total, dim=2)
676 call lalg_axpy(mesh%np, m_one, pw_field(:, idir), out_field_total(:, idir))
677 end do
678 case ("vector potential")
679 call messages_not_implemented("Calculation of a vector potential from a plane wave specified as electric field")
680 case ("B field")
681 safe_allocate(b_field_aux(1:mesh%np, 1:mesh%box%dim))
682 call get_pw_b_field(external_waves, mesh, wn, pw_field, b_field_aux)
683 out_field_total(:,:) = out_field_total(:,:) + b_field_aux(:,:)
684 safe_deallocate_a(b_field_aux)
685 end select
686
688
689 select case (type_of_field)
690 case ("E field")
691 call messages_not_implemented("Calculation of an electric field from a plane wave specified as vector potential")
692 case ("vector potential")
693 do idir = 1, 3
694 call lalg_axpy(mesh%np, -m_one/p_c_, pw_field(:, idir), out_field_total(:, idir))
695 end do
696 case ("B field")
697 call dderivatives_curl(der, pw_field(1:mesh%np_part,1:3), ztmp(1:mesh%np,1:3), set_bc = .false.)
698 do idir = 1, 3
699 call lalg_axpy(mesh%np, -m_one/p_c_, ztmp(:, idir), out_field_total(:, idir))
700 end do
701 end select
702
703 end select
704 end do
705
706 safe_deallocate_a(pw_field)
707 safe_deallocate_a(ztmp)
708 call profiling_out('PLANE_WAVES_EVAL')
709
710 pop_sub(plane_waves_eval)
711
712 end subroutine plane_waves_eval
713
714 ! ---------------------------------------------------------
716 subroutine pw_parsed_evaluation(external_waves, wn, time, mesh, n_points, pw_field)
717 type(external_waves_t), intent(inout) :: external_waves
718 integer, intent(in) :: wn
719 real(real64), intent(in) :: time
720 class(mesh_t), intent(in) :: mesh
721 integer, intent(in) :: n_points
722 real(real64), intent(out) :: pw_field(:,:)
723
724 real(real64) :: x_prop(3), x_norm
725 real(real64) :: velocity_time(3)
726 real(real64) :: parsed_field(3)
727 real(real64) :: dummy(3)
728 integer :: idim, ip
729
730 velocity_time(:) = external_waves%v_vector(1:3, wn) * time
731 do idim = 1, 3
732 do ip = 1, n_points
733 x_prop = mesh%x(:, ip) - velocity_time
734 x_norm = norm2(x_prop(1:3))
735 call parse_expression(parsed_field(idim), dummy(idim), 3, x_prop, x_norm, m_zero, &
736 external_waves%e_field_string(idim, wn))
737 pw_field(ip, idim) = units_to_atomic(units_inp%energy/units_inp%length, parsed_field(idim))
738 end do
739 end do
740
741 end subroutine pw_parsed_evaluation
742
743 ! ---------------------------------------------------------
745 subroutine pw_mx_function_evaluation(external_waves, wn, time, mesh, n_points, pw_field)
746 type(external_waves_t), intent(inout) :: external_waves
747 integer, intent(in) :: wn
748 real(real64), intent(in) :: time
749 class(mesh_t), intent(in) :: mesh
750 integer, intent(in) :: n_points
751 real(real64), intent(out) :: pw_field(:,:)
752
753 real(real64) :: x_prop(3), x_norm
754 real(real64) :: velocity_time(3)
755 complex(real64) :: efield_ip(3)
756 complex(real64) :: e0(3)
757 integer :: ip
758
759 velocity_time(:) = external_waves%v_vector(1:3, wn) * time
760 e0(:) = external_waves%e_field(1:3, wn)
761 do ip = 1, n_points
762 x_prop = mesh%x(:, ip) - velocity_time
763 x_norm = norm2(x_prop(1:3))
764 efield_ip = mxf(external_waves%mx_function(wn), x_prop, external_waves%pw_phase(wn))
765 pw_field(ip, :) = real(e0(1:3) * efield_ip, real64)
766 end do
767
768 end subroutine pw_mx_function_evaluation
769
770 ! ---------------------------------------------------------
772 subroutine get_pw_b_field(external_waves, mesh, pwidx, e_field, b_field)
773 type(external_waves_t), intent(in) :: external_waves
774 class(mesh_t), intent(in) :: mesh
775 real(real64), intent(in) :: e_field(:,:)
776 real(real64), intent(out) :: b_field(:,:)
777 integer, intent(in) :: pwidx
778
779 real(real64) :: k_vector(3), k_vector_abs
780 real(real64) :: velocity(3)
781 real(real64) :: P_c_
782 complex(real64) :: e0(3)
783 integer :: ip
784
785 velocity = external_waves%v_vector(1:3, pwidx)
786 k_vector = external_waves%k_vector(1:3, pwidx)
787 k_vector_abs = norm2(k_vector(1:3))
788 e0 = external_waves%e_field(1:3, pwidx)
789 p_c_ = p_c * external_waves%c_factor
790
791 b_field = m_zero
792 do ip = 1, mesh%np
793 b_field(ip, :) = m_one/(p_c_ * k_vector_abs) * dcross_product(k_vector, e_field(ip, :))
794 end do
795
796 end subroutine get_pw_b_field
797
798 ! ---------------------------------------------------------
800 subroutine bessel_source_eval(external_waves, time, mesh, type_of_field, out_field_total, der)
801 type(external_waves_t), intent(inout) :: external_waves
802 real(real64), intent(in) :: time
803 class(mesh_t), intent(in) :: mesh
804 character(len=*), intent(in) :: type_of_field
805 real(real64), intent(out) :: out_field_total(:, :)
806 type(derivatives_t), optional, intent(in):: der
807
808 real(real64) :: dmin, omega, k_vector(3), c_factor
809 integer :: iline, wn, pos_index, n_points, rankmin, ip, idir
810 real(real64), allocatable :: shift(:,:)
811 complex(real64), allocatable :: bessel_field_total(:,:), ztmp(:,:), vec_pot(:,:)
812 integer, allocatable :: indices_bessel_ftc(:)
813 type(mxf_t) :: envelope_mxf
814
815 push_sub(bessel_source_eval)
816
817 call profiling_in('BESSEL_SOURCE_EVAL')
818
819 indices_bessel_ftc = pack([(wn, wn = 1,external_waves%number)], &
820 external_waves%modus == option__maxwellincidentwaves__bessel_function)
821
822 if (size(indices_bessel_ftc) == 0) then
823 call profiling_out('BESSEL_SOURCE_EVAL')
824 pop_sub(bessel_source_eval)
825 return
826 end if
827
828 ! Check if the BesselBeamAxisShift is defined for every incoming Bessel Beam.
829 if (allocated(external_waves%bessel%shift) .and. &
830 size(external_waves%bessel%shift(:,1)) /= size(indices_bessel_ftc)) then
831 message(1) = 'Number of BesselBeamAxisShift defined in input file'
832 message(2) = 'does not match the number of Bessel beams.'
833 call messages_fatal(2)
834 end if
835
836 safe_allocate(shift(size(indices_bessel_ftc), 3))
837 if (allocated(external_waves%bessel%shift)) then
838 shift = external_waves%bessel%shift
839 else
840 shift = m_zero
841 end if
842
843 if (type_of_field == "B field") then
844 assert(present(der))
845 safe_allocate(vec_pot(mesh%np_part, size(out_field_total, dim=2)))
846 safe_allocate(ztmp(size(out_field_total, dim=1), size(out_field_total, dim=2)))
847 n_points = mesh%np_part ! needed for curl
848 else
849 n_points = mesh%np
850 end if
851
852
853 safe_allocate(bessel_field_total(1:n_points, 1:3))
854 bessel_field_total = m_zero
855
856 do iline = 1, size(indices_bessel_ftc)
857 wn = indices_bessel_ftc(iline)
858 omega = external_waves%bessel%omega(wn)
859 k_vector = external_waves%mx_function(wn)%k_vector
860 c_factor = external_waves%c_factor
861 envelope_mxf = external_waves%mx_function(wn)
862
863 call external_waves%bessel%function(wn, shift, mesh, n_points, time, k_vector, c_factor, envelope_mxf, bessel_field_total)
864
865 select case (external_waves%field_type(wn))
866
868 ! interpreting bessel_field_total as a vector potential (as requested by the user)
869 select case (type_of_field)
870 case ("E field")
871 !$omp parallel do collapse(2)
872 do idir = 1, 3
873 do ip = 1, mesh%np
874 out_field_total(ip,idir) = out_field_total(ip,idir) + real(m_zi*omega*bessel_field_total(ip,idir), real64)
875 end do
876 end do
877 !$omp end parallel do
878 case ("vector potential")
879 ! For the vector potential, we multiply by -1/c becuase of the electronic Hamiltonian
880 ! being in Gaussian units
881 !$omp parallel do collapse(2)
882 do idir = 1, 3
883 do ip = 1, mesh%np
884 out_field_total(ip,idir) = out_field_total(ip,idir) - m_one/p_c * real(bessel_field_total(ip,idir), real64)
885 end do
886 end do
887 !$omp end parallel do
888 case ("B field")
889 call zderivatives_curl(der, bessel_field_total(1:mesh%np_part,1:3), ztmp(1:mesh%np,1:3), set_bc = .false.)
890 !$omp parallel do collapse(2)
891 do idir = 1, 3
892 do ip = 1, mesh%np
893 out_field_total(ip,idir) = out_field_total(ip,idir) - m_one/p_c * real(ztmp(ip,idir), real64)
894 end do
895 end do
896 !$omp end parallel do
897 end select
898
899 case(e_field_electric)
900 ! interpreting bessel_field_total as an electric field (as requested by the user)
901 select case (type_of_field)
902 case ("E field")
903 !$omp parallel do collapse(2)
904 do idir = 1, 3
905 do ip = 1, mesh%np
906 out_field_total(ip,idir) = out_field_total(ip,idir) + real(bessel_field_total(ip,idir), real64)
907 end do
908 end do
909 !$omp end parallel do
910 case ("vector potential")
911 ! We calculate the vector potential as real(E/i*omega),
912 ! and convert it to the proper units by multiplying by -1/c
913 !$omp parallel do collapse(2)
914 do idir = 1, 3
915 do ip = 1, mesh%np
916 out_field_total(ip,idir) = out_field_total(ip,idir) - m_one/p_c * &
917 real(bessel_field_total(ip,idir)/m_zi/omega, real64)
918 end do
919 end do
920 !$omp end parallel do
921 case ("B field")
922 !$omp parallel do collapse(2)
923 do idir = 1, 3
924 do ip = 1, mesh%np_part
925 vec_pot(ip,idir) = - m_one/p_c * real(bessel_field_total(ip,idir)/m_zi/omega, real64)
926 end do
927 end do
928 !$omp end parallel do
929 call zderivatives_curl(der, vec_pot(1:mesh%np_part,1:3), ztmp(1:mesh%np,1:3), set_bc = .false.)
930 !$omp parallel do collapse(2)
931 do idir = 1, 3
932 do ip = 1, mesh%np
933 out_field_total(ip,idir) = out_field_total(ip,idir) - real(ztmp(ip,idir), real64)
934 end do
935 end do
936 !$omp end parallel do
937 end select
938
939 end select
940 end do
941
942 if (external_waves%output_from_point) then
943 pos_index = mesh_nearest_point(mesh, external_waves%selected_point_coordinate(1:3), dmin, rankmin)
944 if (mesh%mpi_grp%rank == rankmin) then
945 external_waves%selected_point_field(:) = out_field_total(pos_index,:)
946 write(external_waves%out_file, "(4F14.8, 4x)") time, external_waves%selected_point_field(:)
947 end if
948 end if
949
950 safe_deallocate_a(shift)
951 safe_deallocate_a(ztmp)
952 safe_deallocate_a(vec_pot)
953 safe_deallocate_a(bessel_field_total)
954 call profiling_out('BESSEL_SOURCE_EVAL')
955
956 pop_sub(bessel_source_eval)
957
958 end subroutine bessel_source_eval
959
960 ! ---------------------------------------------------------
962 subroutine bessel_beam_function(this, iline, shift, mesh, n_points, time, k_vector, c_factor, envelope_mxf, bessel_field)
963 class(bessel_beam_t), intent(in) :: this
964 integer, intent(in) :: iline
965 real(real64), intent(in) :: shift(:,:), time, k_vector(3), c_factor
966 class(mesh_t), intent(in) :: mesh
967 integer, intent(in) :: n_points
968 type(mxf_t), intent(in) :: envelope_mxf
969 complex(real64), intent(out) :: bessel_field(:,:)
970
971 real(real64) :: pos(3), temp, temp2, temp3, rho, phi_rho, wigner(3)
972 real(real64) :: hel, theta, omega, amp, kappa, proj, k_norm, velocity_time(3), x_prop(3)
973 complex(real64) :: efield_ip(3)
974 real(real64) :: bessel_plus, bessel_minus
975 integer :: ip, mm, pol
976
977 assert(iline <= size(this%omega))
978 hel = real(this%helicity(iline), real64)
979 theta = this%theta_k(iline)
980 mm = this%m_order(iline)
981 amp = this%amp(iline) / sqrt(m_two)
982 omega = this%omega(iline)
983 proj = omega * cos(theta) / p_c ! k_z
984 kappa = sqrt(omega**2 - (proj* p_c)**2) ! parse omega
985 ! Set Wigner Coefficients from theta
986 wigner(1) = hel * sin(theta) / sqrt(m_two) ! mu = 0
987 wigner(2) = 0.5 * (1 + hel * cos(theta)) ! mu = 1
988 wigner(3) = 0.5 * (1 - hel * cos(theta)) ! mu = -1
989 proj = omega * cos(theta) / p_c ! k_z
990 pol = this%lin_dir(iline) ! Incoming polarization corresponding to beam in question
991
992 do ip = 1, n_points
993 pos(:) = mesh%x(:, ip) - shift(iline,:)
994 rho = norm2(pos(1:2))
995 phi_rho = atan2(pos(2) , pos(1))
996 temp = proj * pos(3) + phi_rho * (mm + 1) - omega*time ! temp, temp2 and temp3 should be unitless
997 temp2 = proj * pos(3) + phi_rho * (mm - 1) - omega*time
998 temp3 = proj * pos(3) + phi_rho * mm - omega*time
999 bessel_plus = loct_bessel(mm+1, kappa * rho / p_c)
1000 bessel_minus = loct_bessel(mm-1, kappa * rho / p_c)
1001
1002 ! Calculate complex Ax component, if generalized bessel OR x -polarized bessel
1003 if (pol /= 2) then
1004 bessel_field(ip, 1) = amp * (exp(m_zi*temp) * wigner(3) * bessel_plus + exp(m_zi*temp2) * wigner(2) * bessel_minus)
1005 end if
1006 ! Calculate complex Ay component if generalized bessel OR y -polarized bessel
1007 if (pol/=1) then
1008 bessel_field(ip, 2) = m_zi * amp * (-exp(m_zi*temp) * wigner(3) * bessel_plus + &
1009 exp(m_zi*temp2) * wigner(2) * bessel_minus)
1010 end if
1011 ! Calculate complex Az component, only iff generalized Bessel
1012 if (pol == 0) then
1013 bessel_field(ip, 3) = - m_zi * amp * sqrt(m_two) * wigner(1) * loct_bessel(mm, kappa * rho / p_c) * exp(m_zi*temp3)
1014 end if
1015
1016 if (this%envelope(iline)) then
1017 k_norm = norm2(k_vector)
1018 velocity_time = k_vector * p_c * c_factor * time / k_norm
1019 x_prop(:) = pos(:) - velocity_time(:)
1020 efield_ip = mxf_envelope_eval(envelope_mxf, x_prop)
1021 bessel_field(ip, :) = bessel_field(ip, :) * real(efield_ip, real64)
1022 end if
1023
1024 end do
1025
1026 end subroutine bessel_beam_function
1027
1029 subroutine bessel_beam_init(this, nlines, dim)
1030 class(bessel_beam_t), intent(out) :: this
1031 integer, intent(in) :: nlines
1032 integer, intent(in) :: dim
1033
1034 safe_allocate(this%amp(1: nlines))
1035 safe_allocate(this%omega(1:nlines))
1036 safe_allocate(this%theta_k(1:nlines))
1037 safe_allocate(this%m_order(1:nlines))
1038 safe_allocate(this%helicity(1:nlines))
1039 safe_allocate(this%shift(1:nlines, 1:dim))
1040 safe_allocate(this%envelope(1:nlines))
1041 safe_allocate(this%lin_dir(1:nlines))
1042 this%amp = m_zero
1043 this%omega = m_zero
1044 this%theta_k = m_zero
1045 this%m_order = m_zero
1046 this%helicity = m_zero
1047 this%shift = m_zero
1048 this%lin_dir = m_zero
1049 this%envelope = .false.
1050
1051 end subroutine bessel_beam_init
1052
1054 subroutine bessel_beam_finalize(this)
1055 type(bessel_beam_t), intent(inout) :: this
1056
1057 safe_deallocate_a(this%amp)
1058 safe_deallocate_a(this%omega)
1059 safe_deallocate_a(this%theta_k)
1060 safe_deallocate_a(this%m_order)
1061 safe_deallocate_a(this%helicity)
1062 safe_deallocate_a(this%shift)
1063 safe_deallocate_a(this%lin_dir)
1064 safe_deallocate_a(this%envelope)
1065
1066 end subroutine bessel_beam_finalize
1067
1068end module external_waves_oct_m
1069
1070!! Local Variables:
1071!! mode: f90
1072!! coding: utf-8
1073!! End:
constant times a vector plus a vector
Definition: lalg_basic.F90:173
double exp(double __x) __attribute__((__nothrow__
double sin(double __x) __attribute__((__nothrow__
double cos(double __x) __attribute__((__nothrow__
double atan2(double __y, double __x) __attribute__((__nothrow__
subroutine, public accel_free_buffer(this, async)
Definition: accel.F90:1006
pure logical function, public accel_is_enabled()
Definition: accel.F90:403
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public zderivatives_curl(der, ff, op_ff, ghost_update, set_bc)
apply the curl operator to a vector of mesh functions
subroutine, public dderivatives_curl(der, ff, op_ff, ghost_update, set_bc)
apply the curl operator to a vector of mesh functions
subroutine, public load_external_waves(partners, namespace)
subroutine bessel_beam_function(this, iline, shift, mesh, n_points, time, k_vector, c_factor, envelope_mxf, bessel_field)
Evaluation of the Bessel beam expression.
subroutine, public bessel_source_eval(external_waves, time, mesh, type_of_field, out_field_total, der)
Calculation of Bessel beam from parsed formula.
subroutine external_waves_update_quantity(this, label)
subroutine pw_mx_function_evaluation(external_waves, wn, time, mesh, n_points, pw_field)
Evaluate expression for plane wave that uses predefeined Maxwell function.
subroutine bessel_beam_init(this, nlines, dim)
. Initialization of Bessel beam arrays
subroutine external_waves_copy_quantities_to_interaction(partner, interaction)
subroutine, public external_waves_eval(external_waves, time, mesh, type_of_field, out_field_total, der)
Calculation of external waves from parsed formula.
class(external_waves_t) function, pointer external_waves_constructor(namespace)
subroutine, public external_waves_end(external_waves)
subroutine pw_parsed_evaluation(external_waves, wn, time, mesh, n_points, pw_field)
Evaluate expression for plane wave parsing the provided formula.
subroutine plane_waves_eval(external_waves, time, mesh, type_of_field, out_field_total, der)
Calculation of plane waves from parsed formula.
subroutine get_pw_b_field(external_waves, mesh, pwidx, e_field, b_field)
Calculation of magnetic field for a plane wave.
subroutine external_waves_init_interaction_as_partner(partner, interaction)
subroutine, public external_waves_init(external_waves, namespace)
Here, plane wave is evaluated from analytical formulae on grid.
subroutine bessel_beam_finalize(this)
. Finalize Bessel beam arrays
real(real64), parameter, public m_two
Definition: global.F90:202
real(real64), parameter, public m_zero
Definition: global.F90:200
complex(real64), parameter, public m_zi
Definition: global.F90:214
real(real64), parameter, public p_c
Electron gyromagnetic ratio, see Phys. Rev. Lett. 130, 071801 (2023)
Definition: global.F90:242
real(real64), parameter, public m_one
Definition: global.F90:201
This module implements the underlying real-space grid.
Definition: grid.F90:119
This module implements the index, used for the mesh points.
Definition: index.F90:124
integer, parameter, public mxll_vec_pot_to_matter
integer, parameter, public mxll_b_field_to_matter
integer, parameter, public mxll_e_field_to_matter
This module defines the abstract interaction_t class, and some auxiliary classes for interactions.
This module defines classes and functions for interaction partners.
Definition: io.F90:116
subroutine, public io_close(iunit, grp)
Definition: io.F90:467
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:361
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
Definition: io.F90:402
integer, parameter, public e_field_electric
Definition: lasers.F90:180
integer, parameter, public e_field_vector_potential
Definition: lasers.F90:180
complex(real64) function mxf_envelope_eval(f, x)
Evaluation of envelope itself.
subroutine, public mxf_read(f, namespace, function_name, ierr)
This function initializes "f" from the MXFunctions block.
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
integer function, public mesh_nearest_point(mesh, pos, dmin, rankmin)
Returns the index of the point which is nearest to a given vector position pos.
Definition: mesh.F90:386
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:898
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1068
character(len=512), private msg
Definition: messages.F90:167
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:525
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
Maxwell-field-to-matter interactions.
Some general things and nomenclature:
Definition: par_vec.F90:173
subroutine, public parse_block_string(blk, l, c, res, convert_to_c)
Definition: parser.F90:818
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:623
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:631
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:554
This module defines the quantity_t class and the IDs for quantities, which can be exposed by a system...
Definition: quantity.F90:140
subroutine, public conv_to_c_string(str)
converts to c string
Definition: string.F90:234
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
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 representing derivatives
abstract class for general interaction partners
surrogate interaction class to avoid circular dependencies between modules.
Lorenz force between a systems of particles and an electromagnetic field.
Describes mesh distribution to nodes.
Definition: mesh.F90:187
class to transfer a Maxwell B field to a matter system
class to transfer a Maxwell electric field to a medium
class to transfer a Maxwell vector potential to a medium
Systems (system_t) can expose quantities that can be used to calculate interactions with other system...
Definition: quantity.F90:173
int true(void)