Octopus
maxwell.F90
Go to the documentation of this file.
1!! Copyright (C) 2019-2020 Franco Bonafe, Heiko Appel, Rene Jestaedt
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
21module maxwell_oct_m
22 use accel_oct_m
23 use batch_oct_m
28 use debug_oct_m
35 use global_oct_m
36 use grid_oct_m
39 use index_oct_m
44 use io_oct_m
49 use loct_oct_m
51 use math_oct_m
53 use mesh_oct_m
56 use mpi_oct_m
62 use output_oct_m
65 use parser_oct_m
77 use sort_oct_m
78 use space_oct_m
79 use system_oct_m
84 use types_oct_m
85 use unit_oct_m
87
88
89 implicit none
90
91 private
92 public :: &
93 maxwell_t, &
95
96 integer, parameter, public :: &
97 MULTIGRID_MX_TO_MA_EQUAL = 1, &
99
102 type, extends(system_t) :: maxwell_t
103 type(space_t) :: space
104 type(states_mxll_t) :: st
105 type(hamiltonian_mxll_t) :: hm
106 type(grid_t) :: gr
107 type(output_t) :: outp
108 type(multicomm_t) :: mc
109
110 type(mesh_interpolation_t) :: mesh_interpolate
111
112 type(propagator_mxll_t) :: tr_mxll
113 type(td_write_t) :: write_handler
114 type(c_ptr) :: output_handle
115
116 complex(real64), allocatable :: ff_rs_inhom_t1(:,:), ff_rs_inhom_t2(:,:)
117 complex(real64), allocatable :: rs_state_init(:,:)
118 type(time_interpolation_t), pointer :: current_interpolation
119 real(real64) :: bc_bounds(2, 3), dt_bounds(2, 3)
120 integer :: energy_update_iter
121 type(restart_t) :: restart_dump
122 type(restart_t) :: restart
123
124 type(lattice_vectors_t) :: latt
125
126 type(helmholtz_decomposition_t) :: helmholtz
127
128 logical :: write_previous_state = .false.
129
130 contains
131 procedure :: init_interaction => maxwell_init_interaction
132 procedure :: init_parallelization => maxwell_init_parallelization
133 procedure :: initialize => maxwell_initialize
134 procedure :: do_algorithmic_operation => maxwell_do_algorithmic_operation
135 procedure :: is_tolerance_reached => maxwell_is_tolerance_reached
136 procedure :: init_interaction_as_partner => maxwell_init_interaction_as_partner
137 procedure :: copy_quantities_to_interaction => maxwell_copy_quantities_to_interaction
138 procedure :: output_start => maxwell_output_start
139 procedure :: output_write => maxwell_output_write
140 procedure :: output_finish => maxwell_output_finish
141 procedure :: update_interactions_start => maxwell_update_interactions_start
142 procedure :: update_interactions_finish => maxwell_update_interactions_finish
143 procedure :: restart_write_data => maxwell_restart_write_data
144 procedure :: restart_read_data => maxwell_restart_read_data
145 procedure :: update_kinetic_energy => maxwell_update_kinetic_energy
146 procedure :: get_current => maxwell_get_current
147 final :: maxwell_finalize
148 end type maxwell_t
149
150 interface maxwell_t
151 procedure maxwell_constructor
152 end interface maxwell_t
153
154contains
155
156 ! ---------------------------------------------------------
157 function maxwell_constructor(namespace) result(sys)
158 class(maxwell_t), pointer :: sys
159 type(namespace_t), intent(in) :: namespace
160
161 push_sub(maxwell_constructor)
162
163 allocate(sys)
164
165 call maxwell_init(sys, namespace)
166
167 pop_sub(maxwell_constructor)
168 end function maxwell_constructor
169
170
171 ! ---------------------------------------------------------
172 subroutine maxwell_init(this, namespace)
173 class(maxwell_t), intent(inout) :: this
174 type(namespace_t), intent(in) :: namespace
175
176
177 push_sub(maxwell_init)
178
179 call profiling_in("MAXWELL_INIT")
180
181 this%namespace = namespace
182
183 call messages_obsolete_variable(this%namespace, 'SystemName')
184 call messages_print_with_emphasis(msg='Maxwell Simulation Start', namespace=this%namespace)
185 this%space = space_t(this%namespace)
186 if (this%space%is_periodic()) then
187 call messages_not_implemented('Maxwell for periodic systems', namespace=namespace)
188 end if
190 call grid_init_stage_1(this%gr, this%namespace, this%space)
191 call states_mxll_init(this%st, this%namespace, this%space)
192 this%latt = lattice_vectors_t(this%namespace, this%space)
193
194 this%quantities(e_field)%required = .true.
195 this%quantities(e_field)%updated_on_demand = .false.
196 this%quantities(b_field)%required = .true.
197 this%quantities(b_field)%updated_on_demand = .false.
198 this%quantities(vector_potential)%required = .true.
199 this%quantities(vector_potential)%updated_on_demand = .false.
201 call mesh_interpolation_init(this%mesh_interpolate, this%gr)
202
203 this%supported_interactions = [linear_medium_to_em_field, current_to_mxll_field]
204 this%supported_interactions_as_partner = [lorentz_force, mxll_e_field_to_matter, mxll_b_field_to_matter, mxll_vec_pot_to_matter]
206 call profiling_out("MAXWELL_INIT")
208 pop_sub(maxwell_init)
209 end subroutine maxwell_init
211 ! ---------------------------------------------------------
212 subroutine maxwell_init_interaction(this, interaction)
213 class(maxwell_t), target, intent(inout) :: this
214 class(interaction_t), intent(inout) :: interaction
216 integer :: depth
220 select type (interaction)
222 call interaction%init(this%gr)
224 call interaction%init(this%gr, this%st%dim)
225 call interaction%init_space_latt(this%space, this%latt)
227 ! set interpolation depth for interaction
228 ! interpolation depth depends on the propagator
229 select type (prop => this%algo)
231 depth = 2
233 depth = 2
235 depth = 2
237 depth = 4
238 class default
239 message(1) = "The chosen propagator does not yet support interaction interpolation"
240 call messages_fatal(1, namespace=this%namespace)
241 end select
242 call interaction%init_interpolation(depth, interaction%label, cmplx=.true.)
243
244 this%hm%current_density_from_medium = .true.
245 class default
246 message(1) = "Trying to initialize an unsupported interaction by Maxwell."
247 call messages_fatal(1, namespace=this%namespace)
248 end select
249
251 end subroutine maxwell_init_interaction
252
253 ! ---------------------------------------------------------
254 subroutine maxwell_init_parallelization(this, grp)
255 class(maxwell_t), intent(inout) :: this
256 type(mpi_grp_t), intent(in) :: grp
257
258 integer(int64) :: index_range(4)
259 integer :: ierr, ip, pos_index, rankmin
260 real(real64) :: dmin
261
263
264 call system_init_parallelization(this, grp)
266 ! store the ranges for these two indices (serves as initial guess
267 ! for parallelization strategy)
268 index_range(1) = this%gr%np_global ! Number of points in mesh
269 index_range(2) = this%st%nst ! Number of states
270 index_range(3) = 1 ! Number of k-points
271 index_range(4) = 100000 ! Some large number
272
273 ! create index and domain communicators
274 call multicomm_init(this%mc, this%namespace, mpi_world, calc_mode_par, mpi_world%size, &
275 index_range, (/ 5000, 1, 1, 1 /))
276
277 call grid_init_stage_2(this%gr, this%namespace, this%space, this%mc)
278 call output_mxll_init(this%outp, this%namespace, this%space)
279 call hamiltonian_mxll_init(this%hm, this%namespace, this%gr, this%st)
280
281 this%st%energy_rate = m_zero
282 this%st%delta_energy = m_zero
283 this%st%energy_via_flux_calc = m_zero
284 this%st%trans_energy_rate = m_zero
285 this%st%trans_delta_energy = m_zero
286 this%st%trans_energy_via_flux_calc = m_zero
287 this%st%plane_waves_energy_rate = m_zero
288 this%st%plane_waves_delta_energy = m_zero
289 this%st%plane_waves_energy_via_flux_calc = m_zero
290
291 safe_allocate(this%rs_state_init(1:this%gr%np_part, 1:this%st%dim))
292 this%rs_state_init(:,:) = m_z0
293
294 this%energy_update_iter = 1
295
296 call poisson_init(this%st%poisson, this%namespace, this%space, this%gr%der, this%mc, this%gr%stencil)
297
298 call propagator_mxll_init(this%gr, this%namespace, this%st, this%hm, this%tr_mxll)
299 call states_mxll_allocate(this%st, this%gr)
300 call external_current_init(this%st, this%space, this%namespace, this%gr)
301 this%hm%propagation_apply = .true.
302
303 if (parse_is_defined(this%namespace, 'MaxwellIncidentWaves') .and. (this%tr_mxll%bc_plane_waves)) then
304 this%st%rs_state_plane_waves(:,:) = m_z0
305 end if
306
307 ! set map for selected points
308 do ip = 1, this%st%selected_points_number
309 pos_index = mesh_nearest_point(this%gr, this%st%selected_points_coordinate(:,ip), dmin, rankmin)
310 if (this%gr%mpi_grp%rank == rankmin) then
311 this%st%selected_points_map(ip) = pos_index
312 else
313 this%st%selected_points_map(ip) = -1
314 end if
315 end do
316 if (accel_is_enabled()) then
317 call accel_create_buffer(this%st%buff_selected_points_map, accel_mem_read_only, type_integer, &
318 this%st%selected_points_number)
319 call accel_write_buffer(this%st%buff_selected_points_map, this%st%selected_points_number, &
320 this%st%selected_points_map)
321 end if
322
323 this%hm%plane_waves_apply = .true.
324 this%hm%spatial_constant_apply = .true.
325
326 call bc_mxll_init(this%hm%bc, this%namespace, this%space, this%gr, this%st)
327 this%bc_bounds(:,1:3) = this%hm%bc%bc_bounds(:,1:3)
328 call inner_and_outer_points_mapping(this%gr, this%st, this%bc_bounds)
329 this%dt_bounds(2, 1:3) = this%bc_bounds(1, 1:3)
330 this%dt_bounds(1, 1:3) = this%bc_bounds(1, 1:3) - this%gr%der%order * this%gr%spacing(1:3)
331 call surface_grid_points_mapping(this%gr, this%st, this%dt_bounds)
332
333 call restart_init(this%restart, this%namespace, restart_td, restart_type_load, this%mc, ierr, mesh=this%gr)
334 call restart_init(this%restart_dump, this%namespace, restart_td, restart_type_dump, this%mc, ierr, mesh=this%gr)
335
336 ! initialize batches
337 call zbatch_init(this%st%rs_stateb, 1, 1, this%st%dim, this%gr%np_part)
338 if (this%st%pack_states) call this%st%rs_stateb%do_pack()
339 call this%st%rs_stateb%copy_to(this%st%rs_state_prevb)
340 call this%st%rs_stateb%copy_to(this%st%inhomogeneousb)
341 if (this%tr_mxll%bc_plane_waves) then
342 call this%st%rs_stateb%copy_to(this%st%rs_state_plane_wavesb)
343 end if
344
345 ! the order should depend on the propagator
346 !this%current_interpolation => time_interpolation_t(this%gr%np, this%st%dim, 2, .true., "current")
347 ! Initialize Helmholtz decomposition
348 call this%helmholtz%init(this%namespace, this%gr, this%mc, this%space)
349
351 end subroutine maxwell_init_parallelization
352
353 ! ---------------------------------------------------------
354 subroutine maxwell_initialize(this)
355 class(maxwell_t), intent(inout) :: this
356
357 real(real64) :: courant
358
359
360 push_sub(maxwell_initialize)
361
362 call profiling_in("MAXWELL_INIT_CONDITIONS")
363
364 select type (algo => this%algo)
365 class is (propagator_t)
366
367 ! The reference Courant–Friedrichs–Lewy condition for stability here
368 ! is calculated with respect to R. Courant, K. Friedrichs, and H. Lewy
369 ! On the Partial Difference Equations of
370 ! Mathematical Physics, IBM Journal of Research and Development, vol. 11
371 ! pp. 215-234, Mar. 1967.
372 courant = m_one/(p_c * sqrt(m_one/this%gr%spacing(1)**2 + m_one/this%gr%spacing(2)**2 + &
373 m_one/this%gr%spacing(3)**2))
374
375 if (algo%dt > (m_one + m_fourth) * courant) then
376 write(message(1),'(a)') 'The timestep is too large compared to the Courant-Friedrichs-Lewy'
377 write(message(2),'(a)') 'stability condition. Time propagation might not be stable.'
378 call messages_warning(2, namespace=this%namespace)
379 end if
380
381 if (parse_is_defined(this%namespace, 'UserDefinedInitialMaxwellStates')) then
382 call states_mxll_read_user_def(this%namespace, this%space, this%gr, this%gr%der, this%st, this%hm%bc,&
383 this%rs_state_init)
384 call messages_print_with_emphasis(msg="Setting initial EM field inside box", namespace=this%namespace)
385 ! TODO: add consistency check that initial state fulfills Gauss laws
386 this%st%rs_state(:,:) = this%st%rs_state + this%rs_state_init
387 if (this%tr_mxll%bc_plane_waves) then
388 this%st%rs_state_plane_waves(:,:) = this%rs_state_init
389 end if
390 end if
391
392 ! initialize the spatial constant field according to the conditions set in the
393 ! UserDefinedConstantSpatialMaxwellField block
394 if (this%tr_mxll%bc_constant) then
395 call spatial_constant_calculation(this%tr_mxll%bc_constant, this%st, this%gr, this%hm, m_zero, &
396 algo%dt, m_zero, this%st%rs_state, set_initial_state = .true.)
397 ! for mesh parallelization, this needs communication!
398 this%st%rs_state_const(:) = this%st%rs_state(mesh_global_index_from_coords(this%gr, [0,0,0]),:)
399 end if
400
401 if (parse_is_defined(this%namespace, 'UserDefinedInitialMaxwellStates')) then
402 safe_deallocate_a(this%rs_state_init)
403 end if
404
405 call hamiltonian_mxll_update(this%hm, time = m_zero)
406
407 ! calculate Maxwell energy
408 call energy_mxll_calc(this%gr, this%st, this%hm, this%hm%energy, this%st%rs_state, &
409 this%st%rs_state_plane_waves)
410
411 ! Get RS states values for selected points
412 call get_rs_state_at_point(this%st%selected_points_rs_state(:,:), this%st%rs_state, &
413 this%st%selected_points_coordinate(:,:), this%st, this%gr)
414
415 call mxll_set_batch(this%st%rs_stateb, this%st%rs_state, this%gr%np, this%st%dim)
416 call batch_set_zero(this%st%inhomogeneousb)
417 if (this%tr_mxll%bc_plane_waves) then
418 call mxll_set_batch(this%st%rs_state_plane_wavesb, this%st%rs_state_plane_waves, this%gr%np, this%st%dim)
419 end if
420 end select
421
422 call profiling_out("MAXWELL_INIT_CONDITIONS")
423
424 pop_sub(maxwell_initialize)
425 end subroutine maxwell_initialize
426
427 ! ---------------------------------------------------------
428 logical function maxwell_do_algorithmic_operation(this, operation, updated_quantities) result(done)
429 class(maxwell_t), intent(inout) :: this
430 class(algorithmic_operation_t), intent(in) :: operation
431 integer, allocatable, intent(out) :: updated_quantities(:)
432
433 complex(real64), allocatable :: charge_density_ext(:)
434 real(real64) :: current_time
435
437 call profiling_in(trim(this%namespace%get())//":"//trim(operation%id))
438
439 current_time = this%iteration%value()
440
441 select type (algo => this%algo)
442 class is (propagator_t)
443
444 done = .true.
445 select case (operation%id)
447 ! For the moment we do nothing
448
449 case (expmid_start)
450 safe_allocate(this%ff_rs_inhom_t1(1:this%gr%np_part, 1:this%hm%dim))
451 safe_allocate(this%ff_rs_inhom_t2(1:this%gr%np_part, 1:this%hm%dim))
452
453 case (expmid_finish)
454 safe_deallocate_a(this%ff_rs_inhom_t1)
455 safe_deallocate_a(this%ff_rs_inhom_t2)
456
457 case (expmid_extrapolate)
458 if (this%hm%current_density_ext_flag .or. this%hm%current_density_from_medium) then
459 call this%get_current(current_time, this%st%rs_current_density_t1)
460 call this%get_current(current_time+algo%dt, this%st%rs_current_density_t2)
461 end if
462
463 case (expmid_propagate)
464 ! Propagation
465
466 !We first compute three external charge and current densities and we convert them as RS vectors
467 safe_allocate(charge_density_ext(1:this%gr%np))
468
469 !No charge density at the moment
470 charge_density_ext = m_z0
471
472 call transform_rs_densities(this%hm, this%gr, charge_density_ext, &
473 this%st%rs_current_density_t1, this%ff_rs_inhom_t1, rs_trans_forward)
474 call transform_rs_densities(this%hm, this%gr, charge_density_ext, &
475 this%st%rs_current_density_t2, this%ff_rs_inhom_t2, rs_trans_forward)
476
477 safe_deallocate_a(charge_density_ext)
478
479 ! Propagation dt with H_maxwell
480 call mxll_propagation_step(this%hm, this%namespace, this%gr, this%space, this%st, this%tr_mxll,&
481 this%st%rs_stateb, this%ff_rs_inhom_t1, this%ff_rs_inhom_t2, current_time, algo%dt)
482
483 updated_quantities = [e_field, b_field, vector_potential]
484
485 case (leapfrog_start)
486 if (any(this%hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__cpml)) then
487 call bc_mxll_initialize_pml_simple(this%hm%bc, this%space, this%gr, this%hm%c_factor, algo%dt)
488 end if
489
490 case (leapfrog_finish)
491
492 case (leapfrog_propagate)
493 if (this%hm%current_density_ext_flag .or. this%hm%current_density_from_medium) then
494 call this%get_current(current_time, this%st%rs_current_density_t1)
495 call mxll_set_batch(this%st%inhomogeneousb, this%st%rs_current_density_t1, this%gr%np, this%st%dim)
496 call batch_scal(this%gr%np, -m_one, this%st%inhomogeneousb)
497 end if
498
499 call mxll_propagate_leapfrog(this%hm, this%namespace, this%gr, this%space, this%st, this%tr_mxll, &
500 current_time, algo%dt, this%iteration%counter())
501
502 updated_quantities = [e_field, b_field, vector_potential]
503
504 case (exp_gauss1_start)
505 safe_allocate(this%ff_rs_inhom_t1(1:this%gr%np_part, 1:this%hm%dim))
506 if (any(this%hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__cpml)) then
507 call bc_mxll_initialize_pml_simple(this%hm%bc, this%space, this%gr, this%hm%c_factor, algo%dt)
508 end if
509
510 case (exp_gauss1_finish)
511 safe_deallocate_a(this%ff_rs_inhom_t1)
512
514 if (this%hm%current_density_ext_flag .or. this%hm%current_density_from_medium) then
515 call this%get_current(current_time+algo%dt*m_half, this%st%rs_current_density_t1)
516 end if
517
519 ! the propagation step is
520 ! F_{n+1} = F_n + dt * phi_1(-i*dt*H) [-i*H F_n - J_1]
521 ! where J_1 = J(t_n + dt/2)
522 call mxll_propagate_expgauss1(this%hm, this%namespace, this%gr, this%space, this%st, this%tr_mxll, &
523 current_time, algo%dt)
524
525 updated_quantities = [e_field, b_field, vector_potential]
526
527 case (exp_gauss2_start)
528 safe_allocate(this%ff_rs_inhom_t1(1:this%gr%np_part, 1:this%hm%dim))
529 safe_allocate(this%ff_rs_inhom_t2(1:this%gr%np_part, 1:this%hm%dim))
530 if (any(this%hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__cpml)) then
531 call bc_mxll_initialize_pml_simple(this%hm%bc, this%space, this%gr, this%hm%c_factor, algo%dt)
532 end if
533
534 case (exp_gauss2_finish)
535 safe_deallocate_a(this%ff_rs_inhom_t1)
536 safe_deallocate_a(this%ff_rs_inhom_t2)
537
539 if (this%hm%current_density_ext_flag .or. this%hm%current_density_from_medium) then
540 call this%get_current(current_time+algo%dt*(m_half-sqrt(m_three)/6.0_real64), this%st%rs_current_density_t1)
541 call this%get_current(current_time+algo%dt*(m_half+sqrt(m_three)/6.0_real64), this%st%rs_current_density_t2)
542 end if
543
545 ! the propagation step is
546 ! F_{n+1} = F_n + dt * phi_1(-i*dt*H) [-i*H F_n - a_1 J_1 - a_2 J_2]
547 ! + dt * phi_2(-i*dt*H) [-b_1 J_1 - b_2 J_2]
548 ! where J_1 = J(t_n + (1/2 - sqrt(3)/6)*dt),
549 ! J_2 = J(t_n + (1/2 + sqrt(3)/6)*dt),
550 ! a_1 = 1/2*(1+sqrt(3)),
551 ! a_2 = 1/2*(1-sqrt(3)),
552 ! b_1 = -sqrt(3),
553 ! b_2 = sqrt(3)
554 call mxll_propagate_expgauss2(this%hm, this%namespace, this%gr, this%space, this%st, this%tr_mxll, &
555 current_time, algo%dt)
556
557 updated_quantities = [e_field, b_field, vector_potential]
558
559 case (iteration_done)
561 done = .false.
562
563 case default
564 done = .false.
565 end select
566
567 end select
568
569 call profiling_out(trim(this%namespace%get())//":"//trim(operation%id))
572
573 ! ---------------------------------------------------------
574 logical function maxwell_is_tolerance_reached(this, tol) result(converged)
575 class(maxwell_t), intent(in) :: this
576 real(real64), intent(in) :: tol
577
579
580 converged = .false.
581
584
585 ! ---------------------------------------------------------
586 subroutine maxwell_init_interaction_as_partner(partner, interaction)
587 class(maxwell_t), intent(in) :: partner
588 class(interaction_surrogate_t), intent(inout) :: interaction
589
591
592 select type (interaction)
593 type is (lorentz_force_t)
594 ! Nothing to be initialized for the Lorentz force.
596 call interaction%init_from_partner(partner%gr, partner%space, partner%namespace)
598 call interaction%init_from_partner(partner%gr, partner%space, partner%namespace)
600 call interaction%init_from_partner(partner%gr, partner%space, partner%namespace)
601 class default
602 message(1) = "Unsupported interaction."
603 call messages_fatal(1, namespace=partner%namespace)
604 end select
605
608
609 ! ---------------------------------------------------------
610 subroutine maxwell_copy_quantities_to_interaction(partner, interaction)
611 class(maxwell_t), intent(inout) :: partner
612 class(interaction_surrogate_t), intent(inout) :: interaction
613
614 integer :: ip
615 complex(real64) :: interpolated_value(3)
616 real(real64), allocatable :: b_field(:,:), vec_pot(:,:)
617
619 call profiling_in(trim(partner%namespace%get())//":"//"COPY_QUANTITY_INTER")
620
621 select type (interaction)
622 type is (lorentz_force_t)
623 call mxll_get_batch(partner%st%rs_stateb, partner%st%rs_state, partner%gr%np, partner%st%dim)
624
625 do ip = 1, interaction%system_np
626 call mesh_interpolation_evaluate(partner%mesh_interpolate, partner%st%rs_state(:,1), &
627 interaction%system_pos(:, ip), interpolated_value(1))
628 call mesh_interpolation_evaluate(partner%mesh_interpolate, partner%st%rs_state(:,2), &
629 interaction%system_pos(:, ip), interpolated_value(2))
630 call mesh_interpolation_evaluate(partner%mesh_interpolate, partner%st%rs_state(:,3), &
631 interaction%system_pos(:, ip), interpolated_value(3))
632 call get_electric_field_vector(interpolated_value, interaction%partner_e_field(:, ip))
633 call get_magnetic_field_vector(interpolated_value, 1, interaction%partner_b_field(:, ip))
634 end do
635
637 call mxll_get_batch(partner%st%rs_stateb, partner%st%rs_state, partner%gr%np, partner%st%dim)
638 select case (interaction%type)
639
640 case (mxll_field_total)
641 call get_electric_field_state(partner%st%rs_state, partner%gr, interaction%partner_field)
642
643 case (mxll_field_trans)
644 call get_transverse_rs_state(partner%helmholtz, partner%st, partner%namespace)
645 call get_electric_field_state(partner%st%rs_state_trans, partner%gr, interaction%partner_field)
646
647 case (mxll_field_long)
648 call partner%helmholtz%get_long_field(partner%namespace, partner%st%rs_state_long, total_field=partner%st%rs_state)
649 call get_electric_field_state(partner%st%rs_state_long, partner%gr, interaction%partner_field)
650
651 case default
652 message(1) = "Unknown type of field requested by interaction."
653 call messages_fatal(1, namespace=partner%namespace)
654 end select
655 call interaction%do_mapping()
656
658 call mxll_get_batch(partner%st%rs_stateb, partner%st%rs_state, partner%gr%np, partner%st%dim)
659 safe_allocate(b_field(1:partner%gr%np_part, 1:partner%gr%box%dim))
660 safe_allocate(vec_pot(1:partner%gr%np_part, 1:partner%gr%box%dim))
661 ! magnetic field is always transverse
662 call get_magnetic_field_state(partner%st%rs_state, partner%gr, partner%st%rs_sign, b_field, &
663 partner%st%mu(1:partner%gr%np), partner%gr%np)
664 ! vector potential stored in partner_field
665 call partner%helmholtz%get_vector_potential(partner%namespace, vec_pot, trans_field=b_field)
666 ! in the convention used by the electronic system, the -1/c factor is included in the vector potential
667 ! but we do not divide by it, because the Maxwell code is in SI units, so the vector potential units
668 ! are suitable for a (p + q.A) minimal coupling interaction
669 interaction%partner_field(1:partner%gr%np,1:partner%gr%box%dim) = &
670 vec_pot(1:partner%gr%np,1:partner%gr%box%dim)
671 safe_deallocate_a(b_field)
672 safe_deallocate_a(vec_pot)
673 call interaction%do_mapping()
674
676 call mxll_get_batch(partner%st%rs_stateb, partner%st%rs_state, partner%gr%np, partner%st%dim)
677 call get_magnetic_field_state(partner%st%rs_state, partner%gr, partner%st%rs_sign, &
678 interaction%partner_field, partner%st%mu(1:partner%gr%np), partner%gr%np)
679 call interaction%do_mapping()
680
681 class default
682 message(1) = "Unsupported interaction."
683 call messages_fatal(1, namespace=partner%namespace)
684 end select
685
686 call profiling_out(trim(partner%namespace%get())//":"//"COPY_QUANTITY_INTER")
689
690 ! ---------------------------------------------------------
691 subroutine maxwell_output_start(this)
692 class(maxwell_t), intent(inout) :: this
693
694 real(real64) :: itr_value
695
696 push_sub(maxwell_output_start)
697 call profiling_in(trim(this%namespace%get())//":"//"OUTPUT_START")
698
699 select type (algo => this%algo)
700 class is (propagator_t)
701 call mxll_get_batch(this%st%rs_stateb, this%st%rs_state, this%gr%np, this%st%dim)
702
703 call td_write_mxll_init(this%write_handler, this%namespace, this%iteration%counter(), algo%dt)
704 if (this%st%fromScratch) then
705 call td_write_mxll_iter(this%write_handler, this%space, this%gr, this%st, this%hm, this%helmholtz, algo%dt, &
706 this%iteration%counter(), this%namespace)
707 itr_value = this%iteration%value()
708 call td_write_mxll_free_data(this%write_handler, this%namespace, this%space, this%gr, this%st, this%hm, this%helmholtz, &
709 this%outp, this%iteration%counter(), itr_value)
710 end if
711
712 end select
713
714 call profiling_out(trim(this%namespace%get())//":"//"OUTPUT_START")
715 pop_sub(maxwell_output_start)
716 end subroutine maxwell_output_start
717
718 ! ---------------------------------------------------------
719 subroutine maxwell_output_write(this)
720 class(maxwell_t), intent(inout) :: this
721
722 logical :: stopping, reached_output_interval
723 real(real64) :: itr_value
724 integer :: iout
725
726 push_sub(maxwell_output_write)
727 call profiling_in(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
728
729 select type (algo => this%algo)
730 class is (propagator_t)
731 stopping = clean_stop(this%mc%master_comm)
732
733 call td_write_mxll_iter(this%write_handler, this%space, this%gr, this%st, this%hm, this%helmholtz, algo%dt, &
734 this%iteration%counter(), this%namespace)
735
736 reached_output_interval = .false.
737 do iout = 1, out_maxwell_max
738 if (this%outp%output_interval(iout) > 0) then
739 if (mod(this%iteration%counter(), this%outp%output_interval(iout)) == 0) then
740 reached_output_interval = .true.
741 exit
742 end if
743 end if
744 end do
745
746 if (reached_output_interval .or. stopping) then
747 call mxll_get_batch(this%st%rs_stateb, this%st%rs_state, this%gr%np, this%st%dim)
748
749 itr_value = this%iteration%value()
750 call td_write_mxll_free_data(this%write_handler, this%namespace, this%space, this%gr, this%st, this%hm, this%helmholtz, &
751 this%outp, this%iteration%counter(), itr_value)
752 end if
753
754 end select
755
756 call profiling_out(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
757 pop_sub(maxwell_output_write)
758 end subroutine maxwell_output_write
759
760 ! ---------------------------------------------------------
761 subroutine maxwell_output_finish(this)
762 class(maxwell_t), intent(inout) :: this
763
764
765 push_sub(maxwell_output_finish)
766
767 call profiling_in("MAXWELL_OUTPUT_FINISH")
768
769 select type (algo => this%algo)
770 class is (propagator_t)
771 call td_write_mxll_end(this%write_handler)
772 end select
773
774 call profiling_out("MAXWELL_OUTPUT_FINISH")
775
776 pop_sub(maxwell_output_finish)
777 end subroutine maxwell_output_finish
778
779 ! ---------------------------------------------------------
780 subroutine maxwell_update_interactions_start(this)
781 class(maxwell_t), intent(inout) :: this
782
783 type(interaction_iterator_t) :: iter
784 integer :: int_counter
785
787
788 int_counter = 0
789 call iter%start(this%interactions)
790 do while (iter%has_next())
791 select type (interaction => iter%get_next())
793 int_counter = int_counter + 1
794 end select
795 end do
796
797 if (int_counter /= 0 .and. .not. allocated(this%hm%medium_boxes)) then
798 safe_allocate(this%hm%medium_boxes(1:int_counter))
799 this%hm%calc_medium_box = .true.
800 end if
801
804
805 ! ---------------------------------------------------------
807 class(maxwell_t), intent(inout) :: this
808
809 type(interaction_iterator_t) :: iter
810 integer :: iint
811
813
814 iint = 0
815
816 call iter%start(this%interactions)
817 do while (iter%has_next())
818 select type (interaction => iter%get_next())
820 if (allocated(this%hm%medium_boxes) .and. .not. this%hm%medium_boxes_initialized) then
821 iint = iint + 1
822 this%hm%medium_boxes(iint) = interaction%medium_box
823 end if
824 end select
825 end do
826
827 if (allocated(this%hm%medium_boxes) .and. .not. this%hm%medium_boxes_initialized) then
828 call set_medium_rs_state(this%st, this%gr, this%hm)
829 this%hm%medium_boxes_initialized = .true.
830 end if
831
832 if (this%hm%medium_boxes_initialized .and. this%hm%operator == faraday_ampere) then
833 message(1) = "A linear medium has been defined in the input file but the Hamiltonian"
834 message(2) = "type you specified is not capable of dealing with the medium."
835 message(3) = "Please use MaxwellHamiltonianOperator = faraday_ampere_medium or simple to enable"
836 message(4) = "the medium propagation."
837 call messages_fatal(4, namespace=this%namespace)
838 end if
839
840 if (.not. this%hm%medium_boxes_initialized .and. this%hm%operator == faraday_ampere_medium) then
841 message(1) = "The variable MaxwellHamiltonianOperator has been defined as faraday_ampere_medium"
842 message(2) = "in the input file but no linear medium has been defined in the system block."
843 message(3) = "Please either use a different option for MaxwellHamiltonianOperator or add"
844 message(4) = "a linear medium to the system block."
845 call messages_fatal(4, namespace=this%namespace)
846 end if
847
850
851 ! ---------------------------------------------------------
852 subroutine maxwell_restart_write_data(this)
853 class(maxwell_t), intent(inout) :: this
855 integer :: ierr, err, zff_dim, id, id1, id2, ip_in, offset, iout
856 logical :: pml_check, write_previous_state
857 complex(real64), allocatable :: zff(:,:)
858 type(interaction_iterator_t) :: iter
859 class(interaction_t), pointer :: interaction
860
862 call profiling_in(trim(this%namespace%get())//":"//"RESTART_WRITE")
863
864 ierr = 0
865
866 if (mpi_grp_is_root(mpi_world)) then
867 do iout = 1, out_maxwell_max
868 if (this%write_handler%out(iout)%write) then
869 call write_iter_flush(this%write_handler%out(iout)%handle)
870 end if
871 end do
872 end if
874 if (.not. restart_skip(this%restart_dump)) then
875 pml_check = any(this%hm%bc%bc_ab_type(1:3) == option__maxwellabsorbingboundaries__cpml)
876
877 message(1) = "Debug: Writing td_maxwell restart."
878 call messages_info(1, namespace=this%namespace, debug_only=.true.)
879
880 if (this%tr_mxll%bc_plane_waves) then
881 zff_dim = 2 * this%st%dim
882 else
883 zff_dim = 1 * this%st%dim
884 end if
885 if (pml_check) then
886 zff_dim = zff_dim + 18
887 end if
888 select type (prop => this%algo)
889 type is (propagator_leapfrog_t)
890 write_previous_state = .true.
891 zff_dim = zff_dim + this%st%dim
892 class default
893 write_previous_state = .false.
894 end select
895 if (pml_check .and. accel_is_enabled()) then
896 call accel_read_buffer(this%hm%bc%pml%buff_conv_plus, &
897 int(this%hm%bc%pml%points_number, int64)*3*3, this%hm%bc%pml%conv_plus)
898 call accel_read_buffer(this%hm%bc%pml%buff_conv_minus, &
899 int(this%hm%bc%pml%points_number, int64)*3*3, this%hm%bc%pml%conv_minus)
900 end if
901
902 call mxll_get_batch(this%st%rs_stateb, this%st%rs_state, this%gr%np, this%st%dim)
903 if (write_previous_state) then
904 call mxll_get_batch(this%st%rs_state_prevb, this%st%rs_state_prev, this%gr%np, this%st%dim)
905 end if
906
907 safe_allocate(zff(1:this%gr%np,1:zff_dim))
908 zff = m_z0
909
910 zff(1:this%gr%np, 1:this%st%dim) = this%st%rs_state(1:this%gr%np, 1:this%st%dim)
911 if (this%tr_mxll%bc_plane_waves) then
912 call mxll_get_batch(this%st%rs_state_plane_wavesb, this%st%rs_state_plane_waves, &
913 this%gr%np, this%st%dim)
914 zff(1:this%gr%np, this%st%dim+1:this%st%dim+this%st%dim) = &
915 this%st%rs_state_plane_waves(1:this%gr%np, 1:this%st%dim)
916 offset = 2*this%st%dim
917 else
918 offset = this%st%dim
919 end if
920 if (pml_check) then
921 id = 0
922 do id1 = 1, 3
923 do id2 = 1, 3
924 id = id + 1
925 do ip_in = 1, this%hm%bc%pml%points_number
926 zff(ip_in, offset+id) = this%hm%bc%pml%conv_plus(ip_in, id1, id2)
927 zff(ip_in, offset+9+id) = this%hm%bc%pml%conv_minus(ip_in, id1, id2)
928 end do
929 end do
930 end do
931 offset = offset + 18
932 end if
933 if (write_previous_state) then
934 zff(1:this%gr%np, offset+1:offset+this%st%dim) = &
935 this%st%rs_state_prev(1:this%gr%np, 1:this%st%dim)
936 end if
937
938 call states_mxll_dump(this%restart_dump, this%st, this%space, this%gr, zff, zff_dim, err, this%iteration%counter())
939 if (err /= 0) ierr = ierr + 1
940
941 if (this%hm%current_density_from_medium) then
942 !call this%current_interpolation%write_restart(this%gr, this%space, this%restart_dump, err)
943 call iter%start(this%interactions)
944 do while (iter%has_next())
945 interaction => iter%get_next()
946 select type (interaction)
947 class is (current_to_mxll_field_t)
948 call interaction%write_restart(this%gr, this%space, this%restart_dump, err)
949 end select
950 end do
951 if (err /= 0) ierr = ierr + 1
952 end if
953
954 message(1) = "Debug: Writing td_maxwell restart done."
955 call messages_info(1, namespace=this%namespace, debug_only=.true.)
956
957 safe_deallocate_a(zff)
958
959 if (ierr /=0) then
960 message(1) = "Unable to write time-dependent Maxwell restart information."
961 call messages_warning(1, namespace=this%namespace)
962 end if
963 end if
964
965 call profiling_out(trim(this%namespace%get())//":"//"RESTART_WRITE")
967 end subroutine maxwell_restart_write_data
968
969 ! ---------------------------------------------------------
970 ! this function returns true if restart data could be read
971 logical function maxwell_restart_read_data(this)
972 class(maxwell_t), intent(inout) :: this
973
974 integer :: ierr, err, zff_dim, id, id1, id2, ip_in, offset
975 logical :: pml_check, read_previous_state
976 complex(real64), allocatable :: zff(:,:)
977 type(interaction_iterator_t) :: iter
978 class(interaction_t), pointer :: interaction
979
981 call profiling_in(trim(this%namespace%get())//":"//"RESTART_READ")
982
983 if (.not. restart_skip(this%restart)) then
984 ierr = 0
985 pml_check = any(this%hm%bc%bc_ab_type(1:3) == option__maxwellabsorbingboundaries__cpml)
986
987 if (restart_skip(this%restart)) then
988 ierr = -1
989 call profiling_out(trim(this%namespace%get())//":"//"RESTART_READ")
991 return
992 end if
993
994 message(1) = "Debug: Reading td_maxwell restart."
995 call messages_info(1, namespace=this%namespace, debug_only=.true.)
996
997 if (this%tr_mxll%bc_plane_waves) then
998 zff_dim = 2 * this%st%dim
999 else
1000 zff_dim = 1 * this%st%dim
1001 end if
1002 if (pml_check) then
1003 zff_dim = zff_dim + 18
1004 end if
1005 select type (prop => this%algo)
1006 type is (propagator_leapfrog_t)
1007 read_previous_state = .true.
1008 zff_dim = zff_dim + this%st%dim
1009 class default
1010 read_previous_state = .false.
1011 end select
1012
1013 safe_allocate(zff(1:this%gr%np,1:zff_dim))
1014
1015 call states_mxll_load(this%restart, this%st, this%gr, this%namespace, this%space, zff, &
1016 zff_dim, err, label = ": td_maxwell")
1017 this%st%rs_current_density_restart = .true.
1018
1019 this%st%rs_state(1:this%gr%np,1:this%st%dim) = zff(1:this%gr%np, 1:this%st%dim)
1020 if (this%tr_mxll%bc_plane_waves) then
1021 this%st%rs_state_plane_waves(1:this%gr%np,1:this%st%dim) = &
1022 zff(1:this%gr%np,this%st%dim+1:this%st%dim+3)
1023 offset = 2*this%st%dim
1024 else
1025 offset = this%st%dim
1026 end if
1027 if (pml_check) then
1028 id = 0
1029 do id1 = 1, 3
1030 do id2 = 1, 3
1031 id = id+1
1032 do ip_in = 1, this%hm%bc%pml%points_number
1033 this%hm%bc%pml%conv_plus(ip_in,id1,id2) = zff(ip_in, offset+ id)
1034 this%hm%bc%pml%conv_minus(ip_in,id1,id2) = zff(ip_in, offset+9+id)
1035 end do
1036 end do
1037 end do
1038 this%hm%bc%pml%conv_plus_old = this%hm%bc%pml%conv_plus
1039 this%hm%bc%pml%conv_minus_old = this%hm%bc%pml%conv_minus
1040 offset = offset + 18
1041 end if
1042 if (read_previous_state) then
1043 this%st%rs_state_prev(1:this%gr%np, 1:this%st%dim) = &
1044 zff(1:this%gr%np, offset+1:offset+this%st%dim)
1045 end if
1046
1047 if (err /= 0) then
1048 ierr = ierr + 1
1049 end if
1050
1051 message(1) = "Debug: Reading td restart done."
1052 call messages_info(1, namespace=this%namespace, debug_only=.true.)
1053
1054 safe_deallocate_a(zff)
1055
1056 if (pml_check .and. accel_is_enabled()) then
1057 call accel_write_buffer(this%hm%bc%pml%buff_conv_plus, &
1058 int(this%hm%bc%pml%points_number, int64)*3*3, this%hm%bc%pml%conv_plus)
1059 call accel_write_buffer(this%hm%bc%pml%buff_conv_minus, &
1060 int(this%hm%bc%pml%points_number, int64)*3*3, this%hm%bc%pml%conv_minus)
1061 call accel_write_buffer(this%hm%bc%pml%buff_conv_plus_old, &
1062 int(this%hm%bc%pml%points_number, int64)*3*3, this%hm%bc%pml%conv_plus_old)
1063 end if
1065 if (this%hm%current_density_from_medium) then
1066 !call this%current_interpolation%read_restart(this%gr, this%space, this%restart, err)
1067 call iter%start(this%interactions)
1068 do while (iter%has_next())
1069 interaction => iter%get_next()
1070 select type (interaction)
1071 class is (current_to_mxll_field_t)
1072 call interaction%read_restart(this%gr, this%space, this%restart, err)
1073 end select
1074 end do
1075 if (err /= 0) then
1076 ierr = ierr + 1
1077 end if
1078 end if
1079
1080 ! set batches
1081 call mxll_set_batch(this%st%rs_stateb, this%st%rs_state, this%gr%np, this%st%dim)
1082 if (read_previous_state) then
1083 call mxll_set_batch(this%st%rs_state_prevb, this%st%rs_state_prev, this%gr%np, this%st%dim)
1084 end if
1085 call batch_set_zero(this%st%inhomogeneousb)
1086 if (this%tr_mxll%bc_plane_waves) then
1087 call mxll_set_batch(this%st%rs_state_plane_wavesb, this%st%rs_state_plane_waves, this%gr%np, this%st%dim)
1088 end if
1089
1090 this%st%fromScratch = .false.
1092 else
1093 message(1) = "Unable to read time-dependent Maxwell restart information: Starting from scratch"
1094 call messages_warning(1, namespace=this%namespace)
1096 end if
1097
1098 call profiling_out(trim(this%namespace%get())//":"//"RESTART_READ")
1100 end function maxwell_restart_read_data
1101
1102 subroutine maxwell_update_kinetic_energy(this)
1103 class(maxwell_t), intent(inout) :: this
1104
1106
1107 ! the energy has already been computed at the end of the timestep
1108
1109 ! the energy of the EM wave is computed and stored in energy_mxll%energy;
1110 ! energy_mxll%energy = energy_mxll%e_energy + energy_mxll%b_energy
1111 ! here this%hm%energy is 'energy_mxll'
1112 this%kinetic_energy = this%hm%energy%energy
1113
1115 end subroutine maxwell_update_kinetic_energy
1116
1117 ! ---------------------------------------------------------
1118 subroutine maxwell_exec_end_of_timestep_tasks(this)
1119 class(maxwell_t), intent(inout) :: this
1120
1122 call profiling_in(trim(this%namespace%get())//":"//"END_TIMESTEP")
1123
1124 ! calculate Maxwell energy
1125 call energy_mxll_calc_batch(this%gr, this%st, this%hm, this%hm%energy, this%st%rs_stateb, this%st%rs_state_plane_wavesb)
1126
1127 ! get RS state values for selected points
1128 call get_rs_state_batch_selected_points(this%st%selected_points_rs_state(:,:), this%st%rs_stateb, &
1129 this%st, this%gr)
1130
1131 call profiling_out(trim(this%namespace%get())//":"//"END_TIMESTEP")
1134
1135 ! ---------------------------------------------------------
1136 subroutine maxwell_get_current(this, time, current)
1137 class(maxwell_t), intent(inout) :: this
1138 real(real64), intent(in) :: time
1139 complex(real64), contiguous, intent(inout) :: current(:, :)
1140
1141 type(interaction_iterator_t) :: iter
1142 complex(real64), allocatable :: current_density_ext(:, :)
1143
1144 push_sub(maxwell_get_current)
1145
1146 safe_allocate(current_density_ext(1:this%gr%np, 1:this%st%dim))
1147 current = m_z0
1148 if (this%hm%current_density_from_medium) then
1149 ! interpolate current from interaction
1150 call iter%start(this%interactions)
1151 do while (iter%has_next())
1152 select type (interaction => iter%get_next())
1153 class is (current_to_mxll_field_t)
1154 call interaction%interpolate(time, current_density_ext)
1155 call lalg_axpy(this%gr%np, 3, m_one, current_density_ext * this%hm%current_factor, current)
1156 end select
1157 end do
1158 end if
1159 ! calculation of external RS density
1160 if (this%hm%current_density_ext_flag) then
1161 call get_rs_density_ext(this%st, this%space, this%gr, time, current_density_ext)
1162 call lalg_axpy(this%gr%np, 3, m_one, current_density_ext, current)
1163 end if
1164 safe_deallocate_a(current_density_ext)
1165
1166 pop_sub(maxwell_get_current)
1167 end subroutine maxwell_get_current
1168
1169 ! ---------------------------------------------------------
1170 subroutine maxwell_finalize(this)
1171 type(maxwell_t), intent(inout) :: this
1172
1173
1174 push_sub(maxwell_finalize)
1175
1176 call profiling_in("MAXWELL_FINALIZE")
1177
1178 call system_end(this)
1179
1180 ! free memory
1181 safe_deallocate_a(this%rs_state_init)
1182 call hamiltonian_mxll_end(this%hm)
1183
1184 call multicomm_end(this%mc)
1185
1186 call this%st%rs_stateb%end()
1187 call this%st%rs_state_prevb%end()
1188 call this%st%inhomogeneousb%end()
1189 if (this%tr_mxll%bc_plane_waves) then
1190 call this%st%rs_state_plane_wavesb%end()
1191 end if
1192
1193 call states_mxll_end(this%st)
1194
1195 call grid_end(this%gr)
1196
1197 call restart_end(this%restart)
1198 call restart_end(this%restart_dump)
1199
1200 call poisson_end(this%st%poisson)
1201
1202 call profiling_out("MAXWELL_FINALIZE")
1203
1204 pop_sub(maxwell_finalize)
1205 end subroutine maxwell_finalize
1206
1207end module maxwell_oct_m
1208
1209!! Local Variables:
1210!! mode: f90
1211!! coding: utf-8
1212!! End:
scale a batch by a constant or vector
Definition: batch_ops.F90:162
constant times a vector plus a vector
Definition: lalg_basic.F90:170
pure logical function, public accel_is_enabled()
Definition: accel.F90:400
integer, parameter, public accel_mem_read_only
Definition: accel.F90:183
This module defines the abstract interfact for algorithm factories.
This module implements the basic elements defining algorithms.
Definition: algorithm.F90:141
character(len=algo_label_len), parameter, public iteration_done
Definition: algorithm.F90:172
This module implements batches of mesh functions.
Definition: batch.F90:133
subroutine, public zbatch_init(this, dim, st_start, st_end, np, special, packed)
initialize a TYPE_CMPLX valued batch to given size without providing external memory
Definition: batch.F90:1774
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:116
subroutine, public batch_set_zero(this, np, async)
fill all mesh functions of the batch with zero
Definition: batch_ops.F90:242
This module handles the calculation mode.
type(calc_mode_par_t), public calc_mode_par
Singleton instance of parallel calculation mode.
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public get_rs_density_ext(st, space, mesh, time, rs_current_density_ext)
subroutine, public external_current_init(st, space, namespace, mesh)
This module implements the field transfer.
real(real64), parameter, public m_zero
Definition: global.F90:187
real(real64), parameter, public m_fourth
Definition: global.F90:196
complex(real64), parameter, public m_z0
Definition: global.F90:197
real(real64), parameter, public m_half
Definition: global.F90:193
real(real64), parameter, public p_c
Electron gyromagnetic ratio, see Phys. Rev. Lett. 130, 071801 (2023)
Definition: global.F90:223
real(real64), parameter, public m_one
Definition: global.F90:188
real(real64), parameter, public m_three
Definition: global.F90:190
This module implements the underlying real-space grid.
Definition: grid.F90:117
subroutine, public grid_init_stage_1(gr, namespace, space, symm, latt, n_sites, site_position)
First stage of the grid initialization.
Definition: grid.F90:194
subroutine, public grid_init_stage_2(gr, namespace, space, mc, qvector)
Second stage of the grid initialization.
Definition: grid.F90:465
subroutine, public grid_end(gr)
finalize a grid object
Definition: grid.F90:493
subroutine, public hamiltonian_mxll_init(hm, namespace, gr, st)
Initializing the Maxwell Hamiltonian.
integer, parameter, public faraday_ampere
subroutine, public hamiltonian_mxll_end(hm)
integer, parameter, public faraday_ampere_medium
subroutine, public hamiltonian_mxll_update(this, time)
Maxwell Hamiltonian update (here only the time is updated, can maybe be added to another routine)
The Helmholtz decomposition is intended to contain "only mathematical" functions and procedures to co...
This module implements the index, used for the mesh points.
Definition: index.F90:122
integer, parameter, public mxll_vec_pot_to_matter
integer, parameter, public linear_medium_to_em_field
integer, parameter, public lorentz_force
integer, parameter, public mxll_b_field_to_matter
integer, parameter, public mxll_e_field_to_matter
integer, parameter, public current_to_mxll_field
This module defines the abstract interaction_t class, and some auxiliary classes for interactions.
Definition: io.F90:114
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:115
subroutine, public bc_mxll_init(bc, namespace, space, gr, st)
subroutine, public surface_grid_points_mapping(mesh, st, bounds)
subroutine, public bc_mxll_initialize_pml_simple(bc, space, gr, c_factor, dt)
subroutine, public inner_and_outer_points_mapping(mesh, st, bounds)
subroutine maxwell_update_interactions_start(this)
Definition: maxwell.F90:874
subroutine maxwell_exec_end_of_timestep_tasks(this)
Definition: maxwell.F90:1212
subroutine maxwell_init_interaction(this, interaction)
Definition: maxwell.F90:306
subroutine maxwell_output_start(this)
Definition: maxwell.F90:785
subroutine maxwell_update_interactions_finish(this)
Definition: maxwell.F90:900
subroutine maxwell_init_interaction_as_partner(partner, interaction)
Definition: maxwell.F90:680
subroutine maxwell_output_finish(this)
Definition: maxwell.F90:855
subroutine maxwell_restart_write_data(this)
Definition: maxwell.F90:946
logical function maxwell_do_algorithmic_operation(this, operation, updated_quantities)
Definition: maxwell.F90:522
integer, parameter, public multigrid_mx_to_ma_large
Definition: maxwell.F90:189
subroutine maxwell_init_parallelization(this, grp)
Definition: maxwell.F90:348
subroutine maxwell_get_current(this, time, current)
Definition: maxwell.F90:1230
subroutine, public maxwell_init(this, namespace)
Definition: maxwell.F90:266
subroutine maxwell_initialize(this)
Definition: maxwell.F90:448
subroutine maxwell_output_write(this)
Definition: maxwell.F90:813
logical function maxwell_is_tolerance_reached(this, tol)
Definition: maxwell.F90:668
class(maxwell_t) function, pointer maxwell_constructor(namespace)
Definition: maxwell.F90:251
subroutine maxwell_update_kinetic_energy(this)
Definition: maxwell.F90:1196
logical function maxwell_restart_read_data(this)
Definition: maxwell.F90:1065
subroutine maxwell_finalize(this)
Definition: maxwell.F90:1264
subroutine maxwell_copy_quantities_to_interaction(partner, interaction)
Definition: maxwell.F90:704
subroutine, public mesh_interpolation_init(this, mesh)
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:118
integer(int64) function, public mesh_global_index_from_coords(mesh, ix)
This function returns the true global index of the point for a given vector of integer coordinates.
Definition: mesh.F90:916
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:380
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
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1057
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_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:624
logical function mpi_grp_is_root(grp)
Is the current MPI process of grpcomm, root.
Definition: mpi.F90:430
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:266
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:145
subroutine, public multicomm_end(mc)
Definition: multicomm.F90:889
subroutine, public multicomm_init(mc, namespace, base_grp, mode_para, n_node, index_range, min_range)
create index and domain communicators
Definition: multicomm.F90:264
integer, parameter, public mxll_field_total
integer, parameter, public mxll_field_trans
integer, parameter, public mxll_field_long
this module contains the output system
Definition: output_low.F90:115
subroutine, public output_mxll_init(outp, namespace, space)
this module contains the output system
Definition: output.F90:115
logical function, public parse_is_defined(namespace, name)
Definition: parser.F90:502
subroutine, public poisson_init(this, namespace, space, der, mc, stencil, qtot, label, solver, verbose, force_serial, force_cmplx)
Definition: poisson.F90:238
subroutine, public poisson_end(this)
Definition: poisson.F90:714
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:623
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:552
character(len=algo_label_len), parameter, public exp_gauss1_start
character(len=algo_label_len), parameter, public exp_gauss1_finish
character(len=algo_label_len), parameter, public exp_gauss1_extrapolate
character(len=algo_label_len), parameter, public exp_gauss1_propagate
character(len=algo_label_len), parameter, public exp_gauss2_finish
character(len=algo_label_len), parameter, public exp_gauss2_propagate
character(len=algo_label_len), parameter, public exp_gauss2_extrapolate
character(len=algo_label_len), parameter, public exp_gauss2_start
character(len=algo_label_len), parameter, public expmid_extrapolate
character(len=algo_label_len), parameter, public expmid_finish
character(len=algo_label_len), parameter, public expmid_start
character(len=algo_label_len), parameter, public expmid_propagate
character(len=algo_label_len), parameter, public leapfrog_propagate
character(len=algo_label_len), parameter, public leapfrog_finish
character(len=algo_label_len), parameter, public leapfrog_start
subroutine, public mxll_propagate_expgauss2(hm, namespace, gr, space, st, tr, time, dt)
Exponential propagation scheme with Gauss collocation points, s=2.
subroutine, public energy_mxll_calc_batch(gr, st, hm, energy_mxll, rs_fieldb, rs_field_plane_wavesb)
integer, parameter, public rs_trans_forward
subroutine, public mxll_propagate_leapfrog(hm, namespace, gr, space, st, tr, time, dt, counter)
subroutine, public mxll_propagate_expgauss1(hm, namespace, gr, space, st, tr, time, dt)
Exponential propagation scheme with Gauss collocation points, s=1.
subroutine, public mxll_propagation_step(hm, namespace, gr, space, st, tr, rs_stateb, ff_rs_inhom_t1, ff_rs_inhom_t2, time, dt)
subroutine, public spatial_constant_calculation(constant_calc, st, gr, hm, time, dt, delay, rs_state, set_initial_state)
subroutine, public set_medium_rs_state(st, gr, hm)
subroutine, public transform_rs_densities(hm, mesh, rs_charge_density, rs_current_density, ff_density, sign)
subroutine, public energy_mxll_calc(gr, st, hm, energy_mxll, rs_field, rs_field_plane_waves)
subroutine, public propagator_mxll_init(gr, namespace, st, hm, tr)
This module implements the basic propagator framework.
Definition: propagator.F90:117
character(len=algo_label_len), parameter, public store_current_status
Definition: propagator.F90:169
This module defines the quantity_t class and the IDs for quantities, which can be exposed by a system...
Definition: quantity.F90:137
integer, parameter, public b_field
Definition: quantity.F90:146
integer, parameter, public current
Definition: quantity.F90:146
integer, parameter, public vector_potential
Definition: quantity.F90:146
integer, parameter, public e_field
Definition: quantity.F90:146
Implementation details for regridding.
Definition: regridding.F90:170
logical function, public clean_stop(comm)
returns true if a file named stop exists
Definition: restart.F90:276
subroutine, public restart_init(restart, namespace, data_type, type, mc, ierr, mesh, dir, exact)
Initializes a restart object.
Definition: restart.F90:516
integer, parameter, public restart_type_dump
Definition: restart.F90:245
logical pure function, public restart_skip(restart)
Returns true if the restart information should neither be read nor written. This might happen because...
Definition: restart.F90:969
integer, parameter, public restart_td
Definition: restart.F90:200
integer, parameter, public restart_type_load
Definition: restart.F90:245
subroutine, public restart_end(restart)
Definition: restart.F90:722
This module is intended to contain "only mathematical" functions and procedures.
Definition: sort.F90:117
subroutine, public mxll_set_batch(rs_stateb, rs_state, np, dim, offset)
subroutine, public get_rs_state_at_point(rs_state_point, rs_state, pos, st, mesh)
subroutine, public get_electric_field_vector(rs_state_vector, electric_field_vector, ep_element)
subroutine, public get_transverse_rs_state(helmholtz, st, namespace)
subroutine, public mxll_get_batch(rs_stateb, rs_state, np, dim, offset)
subroutine, public get_rs_state_batch_selected_points(rs_state_point, rs_stateb, st, mesh)
subroutine, public states_mxll_end(st)
subroutine, public states_mxll_allocate(st, mesh)
Allocates the Maxwell states defined within a states_mxll_t structure.
subroutine, public states_mxll_init(st, namespace, space)
subroutine, public get_electric_field_state(rs_state, mesh, electric_field, ep_field, np)
subroutine, public get_magnetic_field_state(rs_state, mesh, rs_sign, magnetic_field, mu_field, np)
subroutine, public get_magnetic_field_vector(rs_state_vector, rs_sign, magnetic_field_vector, mu_element)
subroutine, public states_mxll_load(restart, st, mesh, namespace, space, zff, zff_dim, ierr, iter, lowest_missing, label, verbose)
subroutine, public states_mxll_dump(restart, st, space, mesh, zff, zff_dim, ierr, iter, st_start_writing, verbose)
subroutine, public states_mxll_read_user_def(namespace, space, mesh, der, st, bc, user_def_rs_state)
This module implements the abstract system type.
Definition: system.F90:118
subroutine, public system_init_parallelization(this, grp)
Basic functionality: copy the MPI group. This function needs to be implemented by extended types that...
Definition: system.F90:1215
subroutine, public system_end(this)
Definition: system.F90:1124
integer, parameter, public out_maxwell_max
Definition: td_write.F90:289
subroutine, public td_write_mxll_init(writ, namespace, iter, dt)
Definition: td_write.F90:3556
subroutine, public td_write_mxll_end(writ)
Definition: td_write.F90:3744
subroutine, public td_write_mxll_free_data(writ, namespace, space, gr, st, hm, helmholtz, outp, iter, time)
Definition: td_write.F90:4202
subroutine, public td_write_mxll_iter(writ, space, gr, st, hm, helmholtz, dt, iter, namespace)
Definition: td_write.F90:3760
type(type_t), public type_integer
Definition: types.F90:135
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.
Descriptor of one algorithmic operation.
Definition: algorithm.F90:163
Class to transfer a current to a Maxwell field.
These class extend the list and list iterator to make an interaction list.
abstract interaction class
surrogate interaction class to avoid circular dependencies between modules.
Lorenz force between a systems of particles and an electromagnetic field.
Class describing Maxwell systems.
Definition: maxwell.F90:195
This is defined even when running serial.
Definition: mpi.F90:142
class to transfer a Maxwell B field to a matter system
class to transfer a Maxwell field to a medium
class to transfer a Maxwell vector potential to a medium
Implements the an exponential RK scheme with Gauss collocation points, s=1 see also Hochbruck,...
Implements the an exponential RK scheme with Gauss collocation points, s=2 see also Hochbruck,...
Implements the explicit exponential midpoint propagator (without predictor-corrector)
Implements a propagator for the leap frog algorithm.
Abstract class implementing propagators.
Definition: propagator.F90:138
Abstract class for systems.
Definition: system.F90:172
int true(void)