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