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