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