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. &
834 .not. any(this%hm%bc%bc_type == mxll_bc_medium) .and. &
835 this%hm%operator == faraday_ampere_medium) then
836 message(1) = "The variable MaxwellHamiltonianOperator has been defined as faraday_ampere_medium"
837 message(2) = "in the input file but neither a medium boundary nor a linear medium system"
838 message(3) = "has been defined. Please either use a different option for"
839 message(4) = "MaxwellHamiltonianOperator or define a Maxwell medium."
840 call messages_fatal(4, namespace=this%namespace)
841 end if
842
845
846 ! ---------------------------------------------------------
847 subroutine maxwell_restart_write_data(this)
848 class(maxwell_t), intent(inout) :: this
850 integer :: ierr, err, zff_dim, id, id1, id2, ip_in, offset, iout
851 logical :: pml_check, write_previous_state
852 complex(real64), allocatable :: zff(:,:)
853 type(interaction_iterator_t) :: iter
854 class(interaction_t), pointer :: interaction
855
857 call profiling_in(trim(this%namespace%get())//":"//"RESTART_WRITE")
858
859 ierr = 0
860
861 if (mpi_world%is_root()) then
862 do iout = 1, out_maxwell_max
863 if (this%write_handler%out(iout)%write) then
864 call write_iter_flush(this%write_handler%out(iout)%handle)
865 end if
866 end do
867 end if
869 if (.not. this%restart_dump%skip()) then
870 pml_check = any(this%hm%bc%bc_ab_type(1:3) == option__maxwellabsorbingboundaries__cpml)
871
872 message(1) = "Debug: Writing td_maxwell restart."
873 call messages_info(1, namespace=this%namespace, debug_only=.true.)
874
875 if (this%tr_mxll%bc_plane_waves) then
876 zff_dim = 2 * this%st%dim
877 else
878 zff_dim = 1 * this%st%dim
879 end if
880 if (pml_check) then
881 zff_dim = zff_dim + 18
882 end if
883 select type (prop => this%algo)
884 type is (propagator_leapfrog_t)
885 write_previous_state = .true.
886 zff_dim = zff_dim + this%st%dim
887 class default
888 write_previous_state = .false.
889 end select
890 if (pml_check .and. accel_is_enabled()) then
891 call accel_read_buffer(this%hm%bc%pml%buff_conv_plus, &
892 this%hm%bc%pml%points_number, 3, 3, this%hm%bc%pml%conv_plus)
893 call accel_read_buffer(this%hm%bc%pml%buff_conv_minus, &
894 this%hm%bc%pml%points_number, 3, 3, this%hm%bc%pml%conv_minus)
895 end if
896
897 call mxll_get_batch(this%st%rs_stateb, this%st%rs_state, this%gr%np, this%st%dim)
898 if (write_previous_state) then
899 call mxll_get_batch(this%st%rs_state_prevb, this%st%rs_state_prev, this%gr%np, this%st%dim)
900 end if
901
902 safe_allocate(zff(1:this%gr%np,1:zff_dim))
903 zff = m_z0
904
905 zff(1:this%gr%np, 1:this%st%dim) = this%st%rs_state(1:this%gr%np, 1:this%st%dim)
906 if (this%tr_mxll%bc_plane_waves) then
907 call mxll_get_batch(this%st%rs_state_plane_wavesb, this%st%rs_state_plane_waves, &
908 this%gr%np, this%st%dim)
909 zff(1:this%gr%np, this%st%dim+1:this%st%dim+this%st%dim) = &
910 this%st%rs_state_plane_waves(1:this%gr%np, 1:this%st%dim)
911 offset = 2*this%st%dim
912 else
913 offset = this%st%dim
914 end if
915 if (pml_check) then
916 id = 0
917 do id1 = 1, 3
918 do id2 = 1, 3
919 id = id + 1
920 do ip_in = 1, this%hm%bc%pml%points_number
921 zff(ip_in, offset+id) = this%hm%bc%pml%conv_plus(ip_in, id1, id2)
922 zff(ip_in, offset+9+id) = this%hm%bc%pml%conv_minus(ip_in, id1, id2)
923 end do
924 end do
925 end do
926 offset = offset + 18
927 end if
928 if (write_previous_state) then
929 zff(1:this%gr%np, offset+1:offset+this%st%dim) = &
930 this%st%rs_state_prev(1:this%gr%np, 1:this%st%dim)
931 end if
932
933 call states_mxll_dump(this%restart_dump, this%st, this%space, this%gr, zff, zff_dim, err, this%iteration%counter())
934 if (err /= 0) ierr = ierr + 1
935
936 if (this%hm%current_density_from_medium) then
937 !call this%current_interpolation%write_restart(this%gr, this%space, this%restart_dump, err)
938 call iter%start(this%interactions)
939 do while (iter%has_next())
940 interaction => iter%get_next()
941 select type (interaction)
943 call interaction%write_restart(this%gr, this%space, this%restart_dump, err)
944 end select
945 end do
946 if (err /= 0) ierr = ierr + 1
947 end if
948
949 message(1) = "Debug: Writing td_maxwell restart done."
950 call messages_info(1, namespace=this%namespace, debug_only=.true.)
951
952 safe_deallocate_a(zff)
953
954 if (ierr /=0) then
955 message(1) = "Unable to write time-dependent Maxwell restart information."
956 call messages_warning(1, namespace=this%namespace)
957 end if
958 end if
959
960 call profiling_out(trim(this%namespace%get())//":"//"RESTART_WRITE")
962 end subroutine maxwell_restart_write_data
963
964 ! ---------------------------------------------------------
965 ! this function returns true if restart data could be read
966 logical function maxwell_restart_read_data(this)
967 class(maxwell_t), intent(inout) :: this
968
969 integer :: ierr, err, zff_dim, id, id1, id2, ip_in, offset
970 logical :: pml_check, read_previous_state
971 complex(real64), allocatable :: zff(:,:)
972 type(interaction_iterator_t) :: iter
973 class(interaction_t), pointer :: interaction
974
976 call profiling_in(trim(this%namespace%get())//":"//"RESTART_READ")
977
978 if (.not. this%restart%skip()) then
979 ierr = 0
980 pml_check = any(this%hm%bc%bc_ab_type(1:3) == option__maxwellabsorbingboundaries__cpml)
981
982 if (this%restart%skip()) then
983 ierr = -1
984 call profiling_out(trim(this%namespace%get())//":"//"RESTART_READ")
986 return
987 end if
988
989 message(1) = "Debug: Reading td_maxwell restart."
990 call messages_info(1, namespace=this%namespace, debug_only=.true.)
991
992 if (this%tr_mxll%bc_plane_waves) then
993 zff_dim = 2 * this%st%dim
994 else
995 zff_dim = 1 * this%st%dim
996 end if
997 if (pml_check) then
998 zff_dim = zff_dim + 18
999 end if
1000 select type (prop => this%algo)
1001 type is (propagator_leapfrog_t)
1002 read_previous_state = .true.
1003 zff_dim = zff_dim + this%st%dim
1004 class default
1005 read_previous_state = .false.
1006 end select
1007
1008 safe_allocate(zff(1:this%gr%np,1:zff_dim))
1009
1010 call states_mxll_load(this%restart, this%st, this%gr, this%namespace, this%space, zff, &
1011 zff_dim, err, label = ": td_maxwell")
1012 this%st%rs_current_density_restart = .true.
1013
1014 this%st%rs_state(1:this%gr%np,1:this%st%dim) = zff(1:this%gr%np, 1:this%st%dim)
1015 if (this%tr_mxll%bc_plane_waves) then
1016 this%st%rs_state_plane_waves(1:this%gr%np,1:this%st%dim) = &
1017 zff(1:this%gr%np,this%st%dim+1:this%st%dim+3)
1018 offset = 2*this%st%dim
1019 else
1020 offset = this%st%dim
1021 end if
1022 if (pml_check) then
1023 id = 0
1024 do id1 = 1, 3
1025 do id2 = 1, 3
1026 id = id+1
1027 do ip_in = 1, this%hm%bc%pml%points_number
1028 this%hm%bc%pml%conv_plus(ip_in,id1,id2) = zff(ip_in, offset+ id)
1029 this%hm%bc%pml%conv_minus(ip_in,id1,id2) = zff(ip_in, offset+9+id)
1030 end do
1031 end do
1032 end do
1033 this%hm%bc%pml%conv_plus_old = this%hm%bc%pml%conv_plus
1034 this%hm%bc%pml%conv_minus_old = this%hm%bc%pml%conv_minus
1035 offset = offset + 18
1036 end if
1037 if (read_previous_state) then
1038 this%st%rs_state_prev(1:this%gr%np, 1:this%st%dim) = &
1039 zff(1:this%gr%np, offset+1:offset+this%st%dim)
1040 end if
1041
1042 if (err /= 0) then
1043 ierr = ierr + 1
1044 end if
1045
1046 message(1) = "Debug: Reading td restart done."
1047 call messages_info(1, namespace=this%namespace, debug_only=.true.)
1048
1049 safe_deallocate_a(zff)
1050
1051 if (pml_check .and. accel_is_enabled()) then
1052 call accel_write_buffer(this%hm%bc%pml%buff_conv_plus, this%hm%bc%pml%points_number, 3, 3, &
1053 this%hm%bc%pml%conv_plus)
1054 call accel_write_buffer(this%hm%bc%pml%buff_conv_minus, this%hm%bc%pml%points_number, 3, 3, &
1055 this%hm%bc%pml%conv_minus)
1056 call accel_write_buffer(this%hm%bc%pml%buff_conv_plus_old, this%hm%bc%pml%points_number, 3, 3, &
1057 this%hm%bc%pml%conv_plus_old)
1058 end if
1059
1060 if (this%hm%current_density_from_medium) then
1061 !call this%current_interpolation%read_restart(this%gr, this%space, this%restart, err)
1062 call iter%start(this%interactions)
1063 do while (iter%has_next())
1064 interaction => iter%get_next()
1065 select type (interaction)
1066 class is (current_to_mxll_field_t)
1067 call interaction%read_restart(this%gr, this%space, this%restart, err)
1068 end select
1069 end do
1070 if (err /= 0) then
1071 ierr = ierr + 1
1072 end if
1073 end if
1074
1075 ! set batches
1076 call mxll_set_batch(this%st%rs_stateb, this%st%rs_state, this%gr%np, this%st%dim)
1077 if (read_previous_state) then
1078 call mxll_set_batch(this%st%rs_state_prevb, this%st%rs_state_prev, this%gr%np, this%st%dim)
1079 end if
1080 call batch_set_zero(this%st%inhomogeneousb)
1081 if (this%tr_mxll%bc_plane_waves) then
1082 call mxll_set_batch(this%st%rs_state_plane_wavesb, this%st%rs_state_plane_waves, this%gr%np, this%st%dim)
1083 end if
1084
1085 this%st%fromScratch = .false.
1087 else
1088 message(1) = "Unable to read time-dependent Maxwell restart information: Starting from scratch"
1089 call messages_warning(1, namespace=this%namespace)
1091 end if
1092
1093 call profiling_out(trim(this%namespace%get())//":"//"RESTART_READ")
1095 end function maxwell_restart_read_data
1096
1097 subroutine maxwell_update_kinetic_energy(this)
1098 class(maxwell_t), intent(inout) :: this
1099
1101
1102 ! the energy has already been computed at the end of the timestep
1103
1104 ! the energy of the EM wave is computed and stored in energy_mxll%energy;
1105 ! energy_mxll%energy = energy_mxll%e_energy + energy_mxll%b_energy
1106 ! here this%hm%energy is 'energy_mxll'
1107 this%kinetic_energy = this%hm%energy%energy
1108
1110 end subroutine maxwell_update_kinetic_energy
1111
1112 ! ---------------------------------------------------------
1113 subroutine maxwell_exec_end_of_timestep_tasks(this)
1114 class(maxwell_t), intent(inout) :: this
1115
1117 call profiling_in(trim(this%namespace%get())//":"//"END_TIMESTEP")
1118
1119 ! calculate Maxwell energy
1120 call energy_mxll_calc_batch(this%gr, this%st, this%hm, this%hm%energy, this%st%rs_stateb, this%st%rs_state_plane_wavesb)
1121
1122 ! get RS state values for selected points
1123 call get_rs_state_batch_selected_points(this%st%selected_points_rs_state(:,:), this%st%rs_stateb, &
1124 this%st, this%gr)
1125
1126 call profiling_out(trim(this%namespace%get())//":"//"END_TIMESTEP")
1129
1130 ! ---------------------------------------------------------
1131 subroutine maxwell_get_current(this, time, current)
1132 class(maxwell_t), intent(inout) :: this
1133 real(real64), intent(in) :: time
1134 complex(real64), contiguous, intent(inout) :: current(:, :)
1135
1136 type(interaction_iterator_t) :: iter
1137 complex(real64), allocatable :: current_density_ext(:, :)
1138
1139 push_sub(maxwell_get_current)
1140
1141 safe_allocate(current_density_ext(1:this%gr%np, 1:this%st%dim))
1142 current = m_z0
1143 if (this%hm%current_density_from_medium) then
1144 ! interpolate current from interaction
1145 call iter%start(this%interactions)
1146 do while (iter%has_next())
1147 select type (interaction => iter%get_next())
1148 class is (current_to_mxll_field_t)
1149 call interaction%interpolate(time, current_density_ext)
1150 call lalg_axpy(this%gr%np, 3, m_one, current_density_ext * this%hm%current_factor, current)
1151 end select
1152 end do
1153 end if
1154 ! calculation of external RS density
1155 if (this%hm%current_density_ext_flag) then
1156 call get_rs_density_ext(this%st, this%space, this%gr, time, current_density_ext)
1157 call lalg_axpy(this%gr%np, 3, m_one, current_density_ext, current)
1158 end if
1159 safe_deallocate_a(current_density_ext)
1160
1161 pop_sub(maxwell_get_current)
1162 end subroutine maxwell_get_current
1163
1164 ! ---------------------------------------------------------
1165 subroutine maxwell_finalize(this)
1166 type(maxwell_t), intent(inout) :: this
1167
1168
1169 push_sub(maxwell_finalize)
1170
1171 call profiling_in("MAXWELL_FINALIZE")
1172
1173 call system_end(this)
1174
1175 ! free memory
1176 safe_deallocate_a(this%rs_state_init)
1177 call hamiltonian_mxll_end(this%hm)
1178
1179 call multicomm_end(this%mc)
1180
1181 call this%st%rs_stateb%end()
1182 call this%st%rs_state_prevb%end()
1183 call this%st%inhomogeneousb%end()
1184 if (this%tr_mxll%bc_plane_waves) then
1185 call this%st%rs_state_plane_wavesb%end()
1186 end if
1187
1188 call states_mxll_end(this%st)
1189
1190 call grid_end(this%gr)
1191
1192 call this%restart%end()
1193 call this%restart_dump%end()
1194
1195 call poisson_end(this%st%poisson)
1196
1197 call profiling_out("MAXWELL_FINALIZE")
1198
1199 pop_sub(maxwell_finalize)
1200 end subroutine maxwell_finalize
1201
1202end module maxwell_oct_m
1203
1204!! Local Variables:
1205!! mode: f90
1206!! coding: utf-8
1207!! 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:402
integer, parameter, public accel_mem_read_only
Definition: accel.F90:185
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)
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:869
subroutine maxwell_exec_end_of_timestep_tasks(this)
Definition: maxwell.F90:1209
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:943
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:1227
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:1193
logical function maxwell_restart_read_data(this)
Definition: maxwell.F90:1062
subroutine maxwell_finalize(this)
Definition: maxwell.F90:1261
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:897
character(len=512), private msg
Definition: messages.F90:166
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:524
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:999
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:161
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:409
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:593
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:233
subroutine, public poisson_end(this)
Definition: poisson.F90:689
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:3882
subroutine, public td_write_mxll_init(writ, namespace, iter, dt, grp)
Definition: td_write.F90:3691
subroutine, public td_write_mxll_free_data(namespace, space, gr, st, hm, helmholtz, outp, iter, time)
Definition: td_write.F90:4342
subroutine, public td_write_mxll_iter(writ, space, gr, st, hm, helmholtz, dt, iter, namespace)
Definition: td_write.F90:3898
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)