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