99 logical :: bc_add_ab_region = .false.
100 logical :: bc_zero = .false.
101 logical :: bc_constant = .false.
102 logical :: bc_mirror_pec = .false.
103 logical :: bc_mirror_pmc = .false.
104 logical :: bc_plane_waves = .false.
105 logical :: bc_medium = .false.
106 type(exponential_t) :: te
107 logical :: plane_waves_in_box
108 integer :: tr_etrs_approx
111 integer,
public,
parameter :: &
112 RS_TRANS_FORWARD = 1, &
115 integer,
parameter :: &
116 MXWLL_ETRS_FULL = 0, &
123 type(grid_t),
intent(in) :: gr
124 type(namespace_t),
intent(in) :: namespace
125 type(states_mxll_t),
intent(inout) :: st
126 type(hamiltonian_mxll_t),
intent(inout) :: hm
127 type(propagator_mxll_t),
intent(inout) :: tr
136 select case (hm%bc%bc_type(idim))
141 tr%bc_constant = .
true.
142 tr%bc_add_ab_region = .
true.
143 hm%bc_constant = .
true.
144 hm%bc_add_ab_region = .
true.
146 tr%bc_mirror_pec = .
true.
147 hm%bc_mirror_pec = .
true.
149 tr%bc_mirror_pmc = .
true.
150 hm%bc_mirror_pmc = .
true.
152 tr%bc_plane_waves = .
true.
153 tr%bc_add_ab_region = .
true.
154 hm%plane_waves = .
true.
155 hm%bc_plane_waves = .
true.
156 hm%bc_add_ab_region = .
true.
162 safe_allocate(st%rs_state_const(1:st%dim))
163 st%rs_state_const =
m_z0
177 call parse_variable(namespace,
'MaxwellTDETRSApprox', mxwll_etrs_full, tr%tr_etrs_approx)
187 call parse_variable(namespace,
'MaxwellPlaneWavesInBox', .false., tr%plane_waves_in_box)
188 if (tr%plane_waves_in_box .and. .not. hm%bc%do_plane_waves)
then
203 subroutine mxll_propagation_step(hm, namespace, gr, space, st, tr, rs_stateb, ff_rs_inhom_t1, ff_rs_inhom_t2, time, dt)
205 type(namespace_t),
intent(in) :: namespace
207 class(
space_t),
intent(in) :: space
211 complex(real64),
contiguous,
intent(in) :: ff_rs_inhom_t1(:,:)
212 complex(real64),
contiguous,
intent(in) :: ff_rs_inhom_t2(:,:)
213 real(real64),
intent(in) :: time
214 real(real64),
intent(in) :: dt
216 integer :: ii, ff_dim, idim, istate, inter_steps
217 real(real64) :: inter_dt, inter_time
221 type(
batch_t) :: ff_rs_stateb, ff_rs_state_pmlb
222 type(
batch_t) :: ff_rs_inhom_1b, ff_rs_inhom_2b, ff_rs_inhom_meanb
223 complex(real64),
allocatable :: rs_state(:, :)
230 if (hm%ma_mx_coupling_apply)
then
231 message(1) =
"Maxwell-matter coupling not implemented yet"
234 safe_allocate(rs_state(gr%np, st%dim))
236 if (tr%plane_waves_in_box)
then
240 safe_deallocate_a(rs_state)
246 if (hm%bc%bc_ab_type(idim) == option__maxwellabsorbingboundaries__cpml)
then
252 if (pml_check .and. .not. hm%bc%pml%parameters_initialized) &
259 inter_dt =
m_one / inter_steps * dt
261 call zbatch_init(ff_rs_stateb, 1, 1, hm%dim, gr%np_part)
262 if (st%pack_states)
call ff_rs_stateb%do_pack(copy=.false.)
265 call ff_rs_stateb%copy_to(ff_rs_state_pmlb)
269 if ((hm%ma_mx_coupling_apply .or. hm%current_density_ext_flag .or. hm%current_density_from_medium) .and. &
271 call ff_rs_stateb%copy_to(ff_rs_inhom_1b)
272 call ff_rs_stateb%copy_to(ff_rs_inhom_2b)
273 call ff_rs_stateb%copy_to(ff_rs_inhom_meanb)
275 do istate = 1, hm%dim
276 call batch_set_state(ff_rs_inhom_meanb, istate, gr%np, ff_rs_inhom_t1(:, istate))
277 call batch_set_state(ff_rs_inhom_2b, istate, gr%np, ff_rs_inhom_t2(:, istate))
282 call ff_rs_inhom_meanb%copy_data_to(gr%np, ff_rs_inhom_1b)
283 call ff_rs_inhom_meanb%copy_data_to(gr%np, ff_rs_inhom_2b)
286 hm%cpml_hamiltonian = .false.
287 call tr%te%apply_batch(namespace, gr, hm, ff_rs_inhom_2b, inter_dt)
291 call ff_rs_inhom_meanb%copy_data_to(gr%np, ff_rs_inhom_2b)
293 call tr%te%apply_batch(namespace, gr, hm, ff_rs_inhom_2b, inter_dt*
m_half)
296 call ff_rs_inhom_meanb%copy_data_to(gr%np, ff_rs_inhom_2b)
298 call tr%te%apply_batch(namespace, gr, hm, ff_rs_inhom_2b, -inter_dt*
m_half)
301 call ff_rs_inhom_2b%end()
302 call ff_rs_inhom_meanb%end()
305 do ii = 1, inter_steps
308 inter_time = time + inter_dt * (ii-1)
319 hm%cpml_hamiltonian = pml_check
320 call tr%te%apply_batch(namespace, gr, hm, ff_rs_stateb, dt)
321 hm%cpml_hamiltonian = .false.
328 if ((hm%ma_mx_coupling_apply) .or. hm%current_density_ext_flag .or. hm%current_density_from_medium)
then
329 if (tr%tr_etrs_approx == mxwll_etrs_full)
then
330 call ff_rs_stateb%copy_to(ff_rs_inhom_1b)
331 call ff_rs_stateb%copy_to(ff_rs_inhom_2b)
332 call ff_rs_stateb%copy_to(ff_rs_inhom_meanb)
335 do istate = 1, hm%dim
336 call batch_set_state(ff_rs_inhom_meanb, istate, gr%np, ff_rs_inhom_t2(:, istate))
337 call batch_set_state(ff_rs_inhom_1b, istate, gr%np, ff_rs_inhom_t1(:, istate))
341 call ff_rs_inhom_1b%copy_data_to(gr%np, ff_rs_inhom_2b)
342 call batch_axpy(gr%np, ii / real(inter_steps, real64) , ff_rs_inhom_meanb, ff_rs_inhom_2b)
343 call batch_axpy(gr%np, (ii-1) / real(inter_steps, real64) , ff_rs_inhom_meanb, ff_rs_inhom_1b)
345 hm%cpml_hamiltonian = .false.
346 call tr%te%apply_batch(namespace, gr, hm, ff_rs_inhom_1b, inter_dt)
351 do istate = 1, hm%dim
352 call batch_set_state(ff_rs_inhom_1b, istate, gr%np, ff_rs_inhom_t1(:, istate))
353 call batch_set_state(ff_rs_inhom_2b, istate, gr%np, ff_rs_inhom_t2(:, istate))
356 call ff_rs_inhom_1b%copy_data_to(gr%np, ff_rs_inhom_2b)
358 call tr%te%apply_batch(namespace, gr, hm, ff_rs_inhom_1b, inter_dt/
m_two)
359 call tr%te%apply_batch(namespace, gr, hm, ff_rs_inhom_2b, -inter_dt/
m_two)
365 call ff_rs_inhom_1b%end()
366 call ff_rs_inhom_2b%end()
367 call ff_rs_inhom_meanb%end()
381 if (tr%bc_constant)
then
384 if (st%rs_state_const_external)
then
406 if (any(hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__mask))
then
412 if (tr%bc_plane_waves)
then
421 if (tr%tr_etrs_approx == option__maxwelltdetrsapprox__const_steps)
then
422 call ff_rs_inhom_1b%end()
425 call ff_rs_stateb%end()
428 call ff_rs_state_pmlb%end()
431 safe_deallocate_a(rs_state)
441 type(namespace_t),
intent(in) :: namespace
442 type(
grid_t),
intent(inout) :: gr
445 real(real64),
intent(in) :: time
446 real(real64),
intent(in) :: dt
447 integer,
intent(in) :: counter
453 call st%rs_stateb%copy_to(rs_state_tmpb)
461 if (any(hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__cpml))
then
472 if (counter == 0)
then
474 call batch_xpay(gr%np, st%rs_stateb, dt, rs_state_tmpb)
481 call st%rs_stateb%copy_data_to(gr%np, st%rs_state_prevb)
483 call rs_state_tmpb%copy_data_to(gr%np, st%rs_stateb)
486 if (any(hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__cpml))
then
490 call rs_state_tmpb%end()
511 type(namespace_t),
intent(in) :: namespace
512 type(
grid_t),
intent(inout) :: gr
515 real(real64),
intent(in) :: time
516 real(real64),
intent(in) :: dt
522 call st%rs_stateb%copy_to(rs_state_tmpb)
531 if (any(hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__cpml))
then
537 call hm%zapply(namespace, gr, st%rs_stateb, rs_state_tmpb)
540 if (hm%current_density_ext_flag .or. hm%current_density_from_medium)
then
542 call mxll_set_batch(st%inhomogeneousb, st%rs_current_density_t1, gr%np, st%dim)
547 call tr%te%apply_phi_batch(namespace, gr, hm, rs_state_tmpb, dt, 1)
549 call batch_axpy(gr%np, dt, rs_state_tmpb, st%rs_stateb)
551 call rs_state_tmpb%end()
554 if (any(hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__cpml))
then
583 type(namespace_t),
intent(in) :: namespace
584 type(
grid_t),
intent(inout) :: gr
587 real(real64),
intent(in) :: time
588 real(real64),
intent(in) :: dt
594 call st%rs_stateb%copy_to(rs_state_tmpb)
603 if (any(hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__cpml))
then
609 call hm%zapply(namespace, gr, st%rs_stateb, rs_state_tmpb)
612 if (hm%current_density_ext_flag .or. hm%current_density_from_medium)
then
614 call mxll_set_batch(st%inhomogeneousb, st%rs_current_density_t1, gr%np, st%dim)
618 call mxll_set_batch(st%inhomogeneousb, st%rs_current_density_t2, gr%np, st%dim)
623 call tr%te%apply_phi_batch(namespace, gr, hm, rs_state_tmpb, dt, 1)
625 call batch_axpy(gr%np, dt, rs_state_tmpb, st%rs_stateb)
626 if (hm%current_density_ext_flag .or. hm%current_density_from_medium)
then
629 call mxll_set_batch(st%inhomogeneousb, st%rs_current_density_t1, gr%np, st%dim)
633 call mxll_set_batch(st%inhomogeneousb, st%rs_current_density_t2, gr%np, st%dim)
638 call tr%te%apply_phi_batch(namespace, gr, hm, rs_state_tmpb, dt, 2)
640 call batch_axpy(gr%np, dt, rs_state_tmpb, st%rs_stateb)
644 if (any(hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__cpml))
then
648 call rs_state_tmpb%end()
656 type(
grid_t),
intent(in) :: gr
659 integer :: ip, ip_in, il, idim
663 assert(
allocated(st%ep) .and.
allocated(st%mu))
667 if (hm%calc_medium_box)
then
668 do il = 1,
size(hm%medium_boxes)
669 assert(.not. hm%medium_boxes(il)%has_mapping)
670 do ip = 1, hm%medium_boxes(il)%points_number
671 if (abs(hm%medium_boxes(il)%c(ip)) <=
m_epsilon) cycle
672 st%ep(ip) = hm%medium_boxes(il)%ep(ip)
673 st%mu(ip) = hm%medium_boxes(il)%mu(ip)
680 do ip_in = 1, hm%bc%medium(idim)%points_number
681 ip = hm%bc%medium(idim)%points_map(ip_in)
682 st%ep(ip) = hm%bc%medium(idim)%ep(ip_in)
683 st%mu(ip) = hm%bc%medium(idim)%mu(ip_in)
696 type(
grid_t),
intent(in) :: gr
698 type(
batch_t),
intent(inout) :: rs_stateb
699 type(
batch_t),
intent(inout) :: ff_rs_stateb
700 integer,
intent(in) :: sign
702 complex(real64),
allocatable :: rs_state(:,:)
703 complex(real64),
allocatable :: rs_state_tmp(:,:)
713 safe_allocate(rs_state(1:gr%np, 1:st%dim))
716 if (sign == rs_trans_forward)
then
725 safe_allocate(rs_state_tmp(1:gr%np, 1:st%dim))
729 rs_state(1:np, ii) =
m_half * (rs_state(1:np, ii) + conjg(rs_state_tmp(1:np, ii)))
732 safe_deallocate_a(rs_state_tmp)
735 if (sign == rs_trans_forward)
then
736 call rs_stateb%copy_data_to(gr%np, ff_rs_stateb)
738 call ff_rs_stateb%copy_data_to(gr%np, rs_stateb)
741 safe_deallocate_a(rs_state)
752 class(
mesh_t),
intent(in) :: mesh
753 complex(real64),
intent(inout) :: rs_current_density(:,:)
754 complex(real64),
intent(inout) :: ff_density(:,:)
755 integer,
intent(in) :: sign
759 assert(
size(rs_current_density, dim=2) == 3)
766 if (sign == rs_trans_forward)
then
772 if (sign == rs_trans_forward)
then
773 ff_density(1:mesh%np, 1:3) = rs_current_density(1:mesh%np, 1:3)
775 rs_current_density(1:mesh%np, 1:3) = ff_density(1:mesh%np, 1:3)
787 class(
mesh_t),
intent(in) :: mesh
788 complex(real64),
intent(in) :: rs_current_density(:,:)
789 complex(real64),
intent(inout) :: rs_density_6x6(:,:)
793 assert(
size(rs_current_density, dim=2) == 3)
794 assert(
size(rs_density_6x6, dim=2) == 6)
798 rs_density_6x6(1:mesh%np, ii) = rs_current_density(1:mesh%np, ii)
799 rs_density_6x6(1:mesh%np, ii+3) = rs_current_density(1:mesh%np, ii)
806 class(
mesh_t),
intent(in) :: mesh
807 complex(real64),
intent(in) :: rs_density_6x6(:,:)
808 complex(real64),
intent(inout) :: rs_current_density(:,:)
812 assert(
size(rs_current_density, dim=2) == 3)
813 assert(
size(rs_density_6x6, dim=2) == 6)
817 rs_current_density(1:mesh%np, ii) =
m_half * &
818 real(rs_density_6x6(1:mesh%np, ii) + rs_density_6x6(1:mesh%np, ii+3), real64)
825 type(
grid_t),
intent(in) :: gr_mxll
828 type(
grid_t),
intent(in) :: gr_elec
830 complex(real64),
intent(inout) :: rs_state_matter(:,:)
832 complex(real64),
allocatable :: tmp_pot_mx_gr(:,:), tmp_grad_mx_gr(:,:)
834 safe_allocate(tmp_pot_mx_gr(1:gr_mxll%np_part,1))
835 safe_allocate(tmp_grad_mx_gr(1:gr_mxll%np,1:gr_mxll%box%dim))
840 tmp_pot_mx_gr(:,:) =
m_zero
841 tmp_grad_mx_gr(:,:) =
m_zero
842 call zderivatives_grad(gr_mxll%der, tmp_pot_mx_gr(:,1), tmp_grad_mx_gr(:,:), set_bc = .false.)
843 tmp_grad_mx_gr = - tmp_grad_mx_gr
846 call build_rs_state(real(tmp_grad_mx_gr(1:gr_mxll%np,:)), aimag(tmp_grad_mx_gr(1:gr_mxll%np,:)), st_mxll%rs_sign, &
847 rs_state_matter(1:gr_mxll%np,:), gr_mxll, st_mxll%ep(1:gr_mxll%np), st_mxll%mu(1:gr_mxll%np), &
850 safe_deallocate_a(tmp_pot_mx_gr)
851 safe_deallocate_a(tmp_grad_mx_gr)
858 poisson_solver, helmholtz, field, transverse_field, vector_potential)
859 type(namespace_t),
intent(in) :: namespace
860 type(
grid_t),
intent(in) :: gr_mxll
865 type(
poisson_t),
intent(in) :: poisson_solver
867 complex(real64),
intent(inout) :: field(:,:)
868 complex(real64),
intent(inout) :: transverse_field(:,:)
869 real(real64),
intent(inout) :: vector_potential(:,:)
872 complex(real64),
allocatable :: rs_state_plane_waves(:, :)
876 transverse_field =
m_z0
881 if (hm_mxll%ma_mx_coupling)
then
886 if (tr_mxll%bc_plane_waves .and. hm_mxll%plane_waves_apply)
then
887 safe_allocate(rs_state_plane_waves(1:gr_mxll%np, 1:st_mxll%dim))
888 call mxll_get_batch(st_mxll%rs_state_plane_wavesb, rs_state_plane_waves, gr_mxll%np, st_mxll%dim)
892 if (tr_mxll%bc_plane_waves .and. hm_mxll%plane_waves_apply)
then
893 transverse_field(1:np,:) = field(1:np,:) - rs_state_plane_waves(1:np,:)
895 transverse_field(1:np,:) = field(1:np,:)
898 call helmholtz%get_trans_field(namespace, transverse_field, total_field=field)
900 if (tr_mxll%bc_plane_waves .and. hm_mxll%plane_waves_apply)
then
901 transverse_field(1:np,:) = transverse_field(1:np,:) + rs_state_plane_waves(1:np,:)
902 safe_deallocate_a(rs_state_plane_waves)
907 transverse_field(1:np,:) = field
918 type(namespace_t),
intent(in) :: namespace
920 type(
grid_t),
intent(in) :: gr
922 complex(real64),
intent(in) :: field(:,:)
923 real(real64),
contiguous,
intent(inout) :: vector_potential(:,:)
926 real(real64),
allocatable :: dtmp(:,:)
928 safe_allocate(dtmp(1:gr%np_part,1:3))
933 dtmp = vector_potential
936 call dpoisson_solve(poisson_solver, namespace, dtmp(:,idim), vector_potential(:,idim), .
true.)
940 safe_deallocate_a(dtmp)
945 subroutine energy_mxll_calc(gr, st, hm, energy_mxll, rs_field, rs_field_plane_waves)
946 type(
grid_t),
intent(in) :: gr
950 complex(real64),
intent(in) :: rs_field(:,:)
951 complex(real64),
optional,
intent(in) :: rs_field_plane_waves(:,:)
953 real(real64),
allocatable :: energy_density(:), e_energy_density(:), b_energy_density(:), energy_density_plane_waves(:)
959 safe_allocate(energy_density(1:gr%np))
960 safe_allocate(e_energy_density(1:gr%np))
961 safe_allocate(b_energy_density(1:gr%np))
962 if (
present(rs_field_plane_waves) .and. hm%plane_waves)
then
963 safe_allocate(energy_density_plane_waves(1:gr%np))
967 b_energy_density, hm%plane_waves, rs_field_plane_waves, energy_density_plane_waves)
968 energy_mxll%energy =
dmf_integrate(gr, energy_density, mask=st%inner_points_mask)
969 energy_mxll%e_energy =
dmf_integrate(gr, e_energy_density, mask=st%inner_points_mask)
970 energy_mxll%b_energy =
dmf_integrate(gr, b_energy_density, mask=st%inner_points_mask)
971 if (
present(rs_field_plane_waves) .and. hm%plane_waves)
then
972 energy_mxll%energy_plane_waves =
dmf_integrate(gr, energy_density_plane_waves, mask=st%inner_points_mask)
974 energy_mxll%energy_plane_waves =
m_zero
977 energy_mxll%boundaries =
dmf_integrate(gr, energy_density, mask=st%boundary_points_mask)
979 safe_deallocate_a(energy_density)
980 safe_deallocate_a(e_energy_density)
981 safe_deallocate_a(b_energy_density)
982 if (
present(rs_field_plane_waves) .and. hm%plane_waves)
then
983 safe_deallocate_a(energy_density_plane_waves)
993 type(
grid_t),
intent(in) :: gr
997 type(
batch_t),
intent(in) :: rs_fieldb
998 type(
batch_t),
intent(in) :: rs_field_plane_wavesb
1000 type(
batch_t) :: e_fieldb, b_fieldb, e_field_innerb, b_field_innerb, rs_field_plane_waves_innerb
1001 real(real64) :: tmp(1:st%dim)
1002 complex(real64) :: ztmp(1:st%dim)
1009 if (st%pack_states)
then
1010 call e_fieldb%do_pack(copy=.false.)
1012 call e_fieldb%copy_to(b_fieldb)
1013 call e_fieldb%copy_to(e_field_innerb)
1014 call e_fieldb%copy_to(b_field_innerb)
1022 call batch_copy_with_map(st%inner_points_number, st%buff_inner_points_map, e_fieldb, e_field_innerb)
1023 call batch_copy_with_map(st%inner_points_number, st%buff_inner_points_map, b_fieldb, b_field_innerb)
1025 call batch_copy_with_map(st%inner_points_number, st%inner_points_map, e_fieldb, e_field_innerb)
1026 call batch_copy_with_map(st%inner_points_number, st%inner_points_map, b_fieldb, b_field_innerb)
1029 energy_mxll%e_energy = sum(tmp)
1031 energy_mxll%b_energy = sum(tmp)
1032 energy_mxll%energy = energy_mxll%e_energy + energy_mxll%b_energy
1035 energy_mxll%boundaries = sum(tmp)
1037 energy_mxll%boundaries = energy_mxll%boundaries + sum(tmp)
1038 energy_mxll%boundaries = energy_mxll%boundaries - energy_mxll%energy
1040 if (hm%plane_waves)
then
1041 call rs_field_plane_wavesb%copy_to(rs_field_plane_waves_innerb)
1045 rs_field_plane_wavesb, rs_field_plane_waves_innerb)
1048 rs_field_plane_wavesb, rs_field_plane_waves_innerb)
1051 energy_mxll%energy_plane_waves = sum(real(ztmp, real64) )
1052 call rs_field_plane_waves_innerb%end()
1054 energy_mxll%energy_plane_waves =
m_zero
1059 call e_field_innerb%end()
1060 call b_field_innerb%end()
1069 type(namespace_t),
intent(in) :: namespace
1070 type(
grid_t),
intent(in) :: gr
1074 real(real64),
intent(in) :: time
1075 real(real64),
intent(in) :: dt
1076 real(real64),
intent(in) :: time_delay
1077 complex(real64),
intent(inout) :: rs_state(:,:)
1079 integer :: ip, ip_in, idim
1080 logical :: mask_check
1085 mask_check = .false.
1088 if (hm%bc%bc_ab_type(idim) == option__maxwellabsorbingboundaries__mask)
then
1093 if (mask_check)
then
1094 if (tr%bc_plane_waves .and. hm%plane_waves_apply)
then
1096 call mxll_get_batch(st%rs_state_plane_wavesb, st%rs_state_plane_waves, gr%np, st%dim)
1097 rs_state = rs_state - st%rs_state_plane_waves
1099 rs_state = rs_state + st%rs_state_plane_waves
1100 else if (tr%bc_constant .and. hm%spatial_constant_apply)
then
1103 do ip_in=1, hm%bc%constant_points_number
1104 ip = hm%bc%constant_points_map(ip_in)
1105 rs_state(ip,:) = rs_state(ip,:) - st%rs_state_const(:)
1108 do ip_in=1, hm%bc%constant_points_number
1109 ip = hm%bc%constant_points_map(ip_in)
1110 rs_state(ip,:) = rs_state(ip,:) + st%rs_state_const(:)
1125 complex(real64),
intent(inout) :: rs_state(:,:)
1127 integer :: ip, ip_in, idim
1134 if (hm%bc%bc_ab_type(idim) == option__maxwellabsorbingboundaries__mask)
then
1135 do ip_in = 1, hm%bc%mask_points_number(idim)
1136 ip = hm%bc%mask_points_map(ip_in,idim)
1137 rs_state(ip,:) = rs_state(ip,:) * hm%bc%mask(ip_in,idim)
1150 type(
grid_t),
intent(in) :: gr
1153 type(
batch_t),
intent(in) :: ff_rs_stateb
1154 type(
batch_t),
intent(inout) :: ff_rs_state_pmlb
1157 complex(real64),
allocatable :: rs_state_constant(:,:)
1158 type(
batch_t) :: rs_state_constantb
1164 if (tr%bc_plane_waves .and. hm%plane_waves_apply)
then
1166 ff_rs_state_pmlb, rs_trans_forward)
1168 else if (tr%bc_constant .and. hm%spatial_constant_apply)
then
1173 safe_allocate(rs_state_constant(1:gr%np,1:3))
1175 rs_state_constant(1:gr%np, ii) = st%rs_state_const(ii)
1177 call ff_rs_stateb%copy_to(rs_state_constantb)
1178 call mxll_set_batch(rs_state_constantb, rs_state_constant, gr%np, 3)
1181 ff_rs_state_pmlb, rs_trans_forward)
1184 call rs_state_constantb%end()
1186 safe_deallocate_a(rs_state_constant)
1189 call ff_rs_stateb%copy_data_to(gr%np, ff_rs_state_pmlb)
1200 type(namespace_t),
intent(in) :: namespace
1201 type(
grid_t),
intent(in) :: gr
1204 real(real64),
intent(in) :: time
1205 real(real64),
intent(in) :: dt
1206 real(real64),
intent(in) :: time_delay
1207 type(
batch_t),
intent(inout) :: ff_rs_state_pmlb
1208 type(
batch_t),
intent(inout) :: ff_rs_stateb
1210 integer :: ii, ff_dim
1211 complex(real64),
allocatable :: rs_state_constant(:,:), ff_rs_state_constant(:,:)
1212 type(
batch_t) :: ff_rs_state_plane_wavesb, ff_rs_constantb, rs_state_constantb
1218 if (tr%bc_plane_waves .and. hm%plane_waves_apply)
then
1219 hm%cpml_hamiltonian = .
true.
1220 call tr%te%apply_batch(namespace, gr, hm, ff_rs_state_pmlb, dt)
1221 hm%cpml_hamiltonian = .false.
1224 call ff_rs_stateb%copy_to(ff_rs_state_plane_wavesb)
1230 ff_rs_state_pmlb, ff_rs_state_plane_wavesb, ff_rs_stateb)
1232 call batch_add_with_map(hm%bc%plane_wave%points_number, hm%bc%plane_wave%points_map, &
1233 ff_rs_state_pmlb, ff_rs_state_plane_wavesb, ff_rs_stateb)
1236 call ff_rs_state_plane_wavesb%end()
1238 else if (tr%bc_constant .and. hm%spatial_constant_apply)
then
1239 hm%cpml_hamiltonian = .
true.
1240 call tr%te%apply_batch(namespace, gr, hm, ff_rs_state_pmlb, dt)
1241 hm%cpml_hamiltonian = .false.
1243 call ff_rs_stateb%copy_to(ff_rs_constantb)
1244 ff_dim = ff_rs_stateb%nst_linear
1245 safe_allocate(rs_state_constant(1:gr%np, 1:st%dim))
1249 rs_state_constant(1:gr%np, ii) = st%rs_state_const(ii)
1251 call ff_rs_stateb%copy_to(rs_state_constantb)
1252 call mxll_set_batch(rs_state_constantb, rs_state_constant, gr%np, st%dim)
1257 call batch_add_with_map(hm%bc%constant_points_number, hm%bc%buff_constant_points_map, &
1258 ff_rs_state_pmlb, ff_rs_constantb, ff_rs_stateb)
1261 ff_rs_state_pmlb, ff_rs_constantb, ff_rs_stateb)
1264 call ff_rs_constantb%end()
1265 call rs_state_constantb%end()
1267 safe_deallocate_a(rs_state_constant)
1268 safe_deallocate_a(ff_rs_state_constant)
1279 type(
grid_t),
intent(in) :: gr
1280 type(
batch_t),
intent(inout) :: ff_rs_state_pmlb
1297 type(
grid_t),
intent(in) :: gr
1298 type(
batch_t),
intent(inout) :: ff_rs_state_pmlb
1300 integer :: ip, ip_in, np_part, rs_sign
1301 complex(real64) :: pml_a, pml_b, pml_g, grad
1302 integer :: pml_dir, field_dir, ifield, idir
1303 integer,
parameter :: field_dirs(3, 2) = reshape([2, 3, 1, 3, 1, 2], [3, 2])
1304 logical :: with_medium
1305 type(
batch_t) :: gradb(gr%der%dim)
1307 integer :: bsize, gsize
1313 assert(hm%dim == 3 .or. hm%dim == 6)
1315 np_part = gr%np_part
1316 rs_sign = hm%rs_sign
1320 with_medium = hm%dim == 6
1322 do pml_dir = 1, hm%st%dim
1323 select case (gradb(pml_dir)%status())
1325 do ip_in=1, hm%bc%pml%points_number
1326 ip = hm%bc%pml%points_map(ip_in)
1327 pml_a = hm%bc%pml%a(ip_in,pml_dir)
1328 pml_b = hm%bc%pml%b(ip_in,pml_dir)
1330 field_dir = field_dirs(pml_dir, ifield)
1331 grad = gradb(pml_dir)%zff_linear(ip, field_dir)
1332 pml_g = hm%bc%pml%conv_plus(ip_in, pml_dir, field_dir)
1333 hm%bc%pml%conv_plus(ip_in, pml_dir, field_dir) = pml_a * grad + pml_b * pml_g
1334 if (with_medium)
then
1335 grad = gradb(pml_dir)%zff_linear(ip, field_dir+3)
1336 pml_g = hm%bc%pml%conv_minus(ip_in, pml_dir, field_dir)
1337 hm%bc%pml%conv_minus(ip_in, pml_dir, field_dir) = pml_a * grad + pml_b * pml_g
1342 do ip_in=1, hm%bc%pml%points_number
1343 ip = hm%bc%pml%points_map(ip_in)
1344 pml_a = hm%bc%pml%a(ip_in,pml_dir)
1345 pml_b = hm%bc%pml%b(ip_in,pml_dir)
1347 field_dir = field_dirs(pml_dir, ifield)
1348 grad = gradb(pml_dir)%zff_pack(field_dir, ip)
1349 pml_g = hm%bc%pml%conv_plus(ip_in, pml_dir, field_dir)
1350 hm%bc%pml%conv_plus(ip_in, pml_dir, field_dir) = pml_a * grad + pml_b * pml_g
1351 if (with_medium)
then
1352 grad = gradb(pml_dir)%zff_pack(field_dir+3, ip)
1353 pml_g = hm%bc%pml%conv_minus(ip_in, pml_dir, field_dir)
1354 hm%bc%pml%conv_minus(ip_in, pml_dir, field_dir) = pml_a * grad + pml_b * pml_g
1361 if (with_medium)
then
1384 do idir = 1, gr%der%dim
1385 call gradb(idir)%end()
1400 type(namespace_t),
intent(in) :: namespace
1404 integer :: il, nlines, idim, ncols, ierr
1405 real(real64) :: e_field(st%dim), b_field(st%dim)
1406 character(len=1024) :: mxf_expression
1429 if (
parse_block(namespace,
'UserDefinedConstantSpatialMaxwellField', blk) == 0)
then
1430 st%rs_state_const_external = .
true.
1432 safe_allocate(st%rs_state_const_td_function(1:nlines))
1433 safe_allocate(st%rs_state_const_amp(1:st%dim, 1:nlines))
1440 if (ncols /= 7)
then
1441 message(1) =
'Each line in the UserDefinedConstantSpatialMaxwellField block must have'
1452 call build_rs_vector(e_field, b_field, st%rs_sign, st%rs_state_const_amp(:,il))
1453 call tdf_read(st%rs_state_const_td_function(il), namespace, trim(mxf_expression), ierr)
1467 call parse_variable(namespace,
'PropagateSpatialMaxwellField', .
true., hm%spatial_constant_propagate)
1476 logical,
intent(in) :: constant_calc
1478 type(
grid_t),
intent(in) :: gr
1480 real(real64),
intent(in) :: time
1481 real(real64),
intent(in) :: dt
1482 real(real64),
intent(in) :: delay
1483 complex(real64),
intent(inout) :: rs_state(:,:)
1484 logical,
optional,
intent(in) :: set_initial_state
1486 integer :: ip, ic, icn
1487 real(real64) :: tf_old, tf_new
1488 logical :: set_initial_state_
1494 set_initial_state_ = .false.
1495 if (
present(set_initial_state)) set_initial_state_ = set_initial_state
1497 if (hm%spatial_constant_apply)
then
1498 if (constant_calc)
then
1499 icn =
size(st%rs_state_const_td_function(:))
1500 st%rs_state_const(:) =
m_z0
1502 tf_old =
tdf(st%rs_state_const_td_function(ic), time-delay-dt)
1503 tf_new =
tdf(st%rs_state_const_td_function(ic), time-delay)
1505 if (set_initial_state_ .or. (.not. hm%spatial_constant_propagate))
then
1506 rs_state(ip,:) = st%rs_state_const_amp(:,ic) * tf_new
1508 rs_state(ip,:) = rs_state(ip,:) + st%rs_state_const_amp(:,ic) * (tf_new - tf_old)
1511 st%rs_state_const(:) = st%rs_state_const(:) + st%rs_state_const_amp(:, ic) * tf_new
1523 logical,
intent(in) :: constant_calc
1527 complex(real64),
intent(inout) :: rs_state(:,:)
1529 integer :: ip_in, ip
1534 if (hm%spatial_constant_apply)
then
1535 if (constant_calc)
then
1536 do ip_in = 1, bc%constant_points_number
1537 ip = bc%constant_points_map(ip_in)
1538 rs_state(ip,:) = st%rs_state_const(:)
1539 bc%constant_rs_state(ip_in,:) = st%rs_state_const(:)
1553 complex(real64),
intent(inout) :: rs_state(:,:)
1555 integer :: ip, ip_in, idim
1556 real(real64) :: e_field(st%dim), b_field(st%dim)
1562 do ip_in = 1, bc%mirror_points_number(idim)
1563 ip = bc%mirror_points_map(ip_in, idim)
1566 call build_rs_vector(e_field(:), b_field(:), st%rs_sign, rs_state(ip,:), st%ep(ip), st%mu(ip))
1578 complex(real64),
intent(inout) :: rs_state(:,:)
1580 integer :: ip, ip_in, idim
1581 real(real64) :: e_field(st%dim), b_field(st%dim)
1587 do ip_in = 1, bc%mirror_points_number(idim)
1588 ip = bc%mirror_points_map(ip_in,idim)
1591 call build_rs_vector(e_field(:), b_field(:), st%rs_sign, rs_state(ip,:), st%ep(ip), st%mu(ip))
1603 class(
mesh_t),
intent(in) :: mesh
1604 real(real64),
intent(in) :: time
1605 real(real64),
intent(in) :: time_delay
1606 complex(real64),
intent(inout) :: rs_state(:,:)
1608 integer :: ip, ip_in, wn
1609 real(real64) :: x_prop(mesh%box%dim), rr, vv(mesh%box%dim), k_vector(mesh%box%dim)
1610 real(real64) :: k_vector_abs, nn
1611 complex(real64) :: e0(mesh%box%dim)
1612 real(real64) :: e_field(mesh%box%dim), b_field(mesh%box%dim)
1613 complex(real64) :: rs_state_add(mesh%box%dim)
1614 complex(real64) :: mx_func
1620 if (hm%plane_waves_apply)
then
1621 do wn = 1, hm%bc%plane_wave%number
1622 k_vector(:) = hm%bc%plane_wave%k_vector(1:mesh%box%dim, wn)
1623 k_vector_abs = norm2(k_vector(1:mesh%box%dim))
1624 vv(:) = hm%bc%plane_wave%v_vector(1:mesh%box%dim, wn)
1625 e0(:) = hm%bc%plane_wave%e_field(1:mesh%box%dim, wn)
1626 do ip_in = 1, hm%bc%plane_wave%points_number
1627 ip = hm%bc%plane_wave%points_map(ip_in)
1629 if (wn == 1) rs_state(ip,:) =
m_z0
1631 x_prop(1:mesh%box%dim) = mesh%x(1:mesh%box%dim, ip) - vv(1:mesh%box%dim) * (time - time_delay)
1632 rr = norm2(x_prop(1:mesh%box%dim))
1633 if (hm%bc%plane_wave%modus(wn) == option__maxwellincidentwaves__plane_wave_mx_function)
then
1635 mx_func =
mxf(hm%bc%plane_wave%mx_function(wn), x_prop(1:mesh%box%dim))
1636 e_field(1:mesh%box%dim) = real(e0(1:mesh%box%dim) * mx_func, real64)
1639 call build_rs_vector(e_field, b_field, st%rs_sign, rs_state_add, st%ep(ip), st%mu(ip))
1640 rs_state(ip, :) = rs_state(ip, :) + rs_state_add(:)
1644 do ip_in = 1, hm%bc%plane_wave%points_number
1645 ip = hm%bc%plane_wave%points_map(ip_in)
1646 rs_state(ip,:) =
m_z0
1659 type(namespace_t),
intent(in) :: namespace
1661 type(
grid_t),
intent(in) :: gr
1662 real(real64),
intent(in) :: time
1663 real(real64),
intent(in) :: dt
1664 real(real64),
intent(in) :: time_delay
1674 call zbatch_init(ff_rs_stateb, 1, 1, hm%dim, gr%np_part)
1675 if (st%pack_states)
call ff_rs_stateb%do_pack(copy=.false.)
1681 hm%cpml_hamiltonian = .false.
1682 call tr%te%apply_batch(namespace, gr, hm, ff_rs_stateb, dt)
1685 call mxll_get_batch(st%rs_state_plane_wavesb, st%rs_state_plane_waves, gr%np, st%dim)
1687 call mxll_set_batch(st%rs_state_plane_wavesb, st%rs_state_plane_waves, gr%np, st%dim)
1688 call ff_rs_stateb%end()
1697 real(real64),
intent(in) :: time
1698 class(
mesh_t),
intent(in) :: mesh
1701 complex(real64),
intent(inout) :: rs_state(:,:)
1703 real(real64) :: e_field_total(mesh%np,st%dim), b_field_total(mesh%np,st%dim)
1704 complex(real64) :: rs_state_add(mesh%np,st%dim)
1714 rs_state_add(1:mesh%np,:), mesh, st%ep, st%mu)
1715 rs_state(1:mesh%np,:) = rs_state(1:mesh%np,:) + rs_state_add(1:mesh%np,:)
1727 type(
grid_t),
intent(in) :: gr
1728 type(namespace_t),
intent(in) :: namespace
1729 real(real64),
intent(in) :: time
1730 real(real64),
intent(in) :: dt
1731 type(
batch_t),
intent(inout) :: rs_stateb
1733 complex(real64),
allocatable :: rs_state(:, :)
1737 safe_allocate(rs_state(gr%np, st%dim))
1739 if (tr%bc_constant)
then
1742 if (st%rs_state_const_external)
then
1763 if (any(hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__mask))
then
1770 if (tr%bc_plane_waves)
then
1777 safe_deallocate_a(rs_state)
batchified version of the BLAS axpy routine:
scale a batch by a constant or vector
There are several ways how to call batch_set_state and batch_get_state:
double sqrt(double __x) __attribute__((__nothrow__
subroutine, public accel_kernel_start_call(this, file_name, kernel_name, flags)
subroutine, public accel_finish()
pure logical function, public accel_is_enabled()
integer pure function, public accel_max_block_size()
This module implements batches of mesh functions.
integer, parameter, public batch_not_packed
functions are stored in CPU memory, unpacked order
integer, parameter, public batch_device_packed
functions are stored in device memory in packed order
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
subroutine, public dbatch_init(this, dim, st_start, st_end, np, special, packed)
initialize a TYPE_FLOAT valued batch to given size without providing external memory
integer, parameter, public batch_packed
functions are stored in CPU memory, in transposed (packed) order
This module implements common operations on batches of mesh functions.
subroutine, public batch_split_complex(np, xx, yy, zz)
extract the real and imaginary parts of a complex batch
subroutine, public batch_set_zero(this, np, async)
fill all mesh functions of the batch with zero
This module implements a calculator for the density and defines related functions.
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public dderivatives_curl(der, ff, op_ff, ghost_update, set_bc)
apply the curl operator to a vector of mesh functions
subroutine, public zderivatives_batch_grad(der, ffb, opffb, ghost_update, set_bc, to_cartesian, factor)
apply the gradient to a batch of mesh functions
subroutine, public zderivatives_grad(der, ff, op_ff, ghost_update, set_bc, to_cartesian)
apply the gradient to a mesh function
subroutine, public energy_density_calc(mesh, st, rs_field, energy_dens, e_energy_dens, b_energy_dens, plane_waves_check, rs_field_plane_waves, energy_dens_plane_waves)
subroutine, public exponential_init(te, namespace, full_batch)
subroutine, public external_waves_eval(external_waves, time, mesh, type_of_field, out_field_total, der)
Calculation of external waves from parsed formula.
subroutine, public external_waves_init(external_waves, namespace)
Here, plane wave is evaluated from analytical formulae on grid.
Fast Fourier Transform module. This module provides a single interface that works with different FFT ...
real(real64), parameter, public m_two
real(real64), parameter, public m_zero
real(real64), parameter, public m_four
real(real64), parameter, public m_pi
some mathematical constants
real(real64), parameter, public m_fourth
real(real64), parameter, public p_mu
real(real64), parameter, public p_ep
complex(real64), parameter, public m_z0
complex(real64), parameter, public m_zi
real(real64), parameter, public m_epsilon
real(real64), parameter, public m_half
real(real64), parameter, public p_c
Electron gyromagnetic ratio, see Phys. Rev. Lett. 130, 071801 (2023)
real(real64), parameter, public m_one
real(real64), parameter, public m_three
This module implements the underlying real-space grid.
subroutine, public hamiltonian_mxll_apply_simple(hm, namespace, mesh, psib, hpsib, terms, set_bc)
subroutine, public mxll_update_pml_simple(hm, rs_stateb)
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)
subroutine, public mxll_copy_pml_simple(hm, rs_stateb)
The Helmholtz decomposition is intended to contain "only mathematical" functions and procedures to co...
This module implements the index, used for the mesh points.
This module is intended to contain "only mathematical" functions and procedures.
pure real(real64) function, dimension(1:3), public dcross_product(a, b)
integer, parameter, public mxll_bc_mirror_pmc
integer, parameter, public mxll_bc_mirror_pec
integer, parameter, public mxll_bc_plane_waves
integer, parameter, public mxll_bc_medium
subroutine, public bc_mxll_generate_pml_parameters(bc, space, gr, c_factor, dt)
integer, parameter, public mxll_bc_constant
integer, parameter, public mxll_bc_zero
This module defines functions over batches of mesh functions.
subroutine, public zmesh_batch_dotp_vector(mesh, aa, bb, dot, reduce, cproduct)
A simple switch between specialized kernels and generic kernels.
subroutine, public dmesh_batch_dotp_vector(mesh, aa, bb, dot, reduce, cproduct)
A simple switch between specialized kernels and generic kernels.
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
this module contains the output system
Some general things and nomenclature:
subroutine, public parse_block_string(blk, l, c, res, convert_to_c)
integer function, public parse_block(namespace, name, blk, check_varinfo_)
subroutine, public dpoisson_solve(this, namespace, pot, rho, all_nodes, kernel, reset)
Calculates the Poisson equation. Given the density returns the corresponding potential.
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
subroutine, public transform_rs_densities(hm, mesh, rs_current_density, ff_density, sign)
subroutine, public mirror_pec_boundaries_calculation(bc, st, rs_state)
subroutine td_function_mxll_init(st, namespace, hm)
subroutine, public get_vector_pot_and_transverse_field(namespace, gr_mxll, hm_mxll, st_mxll, tr_mxll, hm, poisson_solver, helmholtz, field, transverse_field, vector_potential)
subroutine, public plane_waves_in_box_calculation(bc, time, mesh, der, st, rs_state)
subroutine, public energy_mxll_calc_batch(gr, st, hm, energy_mxll, rs_fieldb, rs_field_plane_wavesb)
subroutine plane_waves_propagation(hm, tr, namespace, st, gr, time, dt, time_delay)
subroutine cpml_conv_function_update(hm, gr, ff_rs_state_pmlb)
subroutine transform_rs_state_batch(hm, gr, st, rs_stateb, ff_rs_stateb, sign)
subroutine, public mxll_propagate_leapfrog(hm, namespace, gr, st, tr, time, dt, counter)
subroutine, public constant_boundaries_calculation(constant_calc, bc, hm, st, rs_state)
subroutine, public mask_absorbing_boundaries(namespace, gr, hm, st, tr, time, dt, time_delay, rs_state)
subroutine, public calculate_vector_potential(namespace, poisson_solver, gr, st, field, vector_potential)
subroutine pml_propagation_stage_2_batch(hm, namespace, gr, st, tr, time, dt, time_delay, ff_rs_state_pmlb, ff_rs_stateb)
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 plane_waves_boundaries_calculation(hm, st, mesh, time, time_delay, rs_state)
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 cpml_conv_function_update_via_riemann_silberstein(hm, gr, ff_rs_state_pmlb)
subroutine maxwell_mask(hm, rs_state)
integer, parameter mxwll_etrs_const
subroutine, public calculate_matter_longitudinal_field(gr_mxll, st_mxll, hm_mxll, gr_elec, hm_elec, rs_state_matter)
subroutine, public mxll_propagate_expgauss1(hm, namespace, gr, st, tr, time, dt)
Exponential propagation scheme with Gauss collocation points, s=1.
subroutine transform_rs_densities_to_6x6_rs_densities_forward(mesh, rs_current_density, rs_density_6x6)
subroutine, public energy_mxll_calc(gr, st, hm, energy_mxll, rs_field, rs_field_plane_waves)
subroutine, public mxll_propagate_expgauss2(hm, namespace, gr, st, tr, time, dt)
Exponential propagation scheme with Gauss collocation points, s=2.
integer, parameter, public rs_trans_backward
subroutine transform_rs_densities_to_6x6_rs_densities_backward(mesh, rs_density_6x6, rs_current_density)
subroutine, public mirror_pmc_boundaries_calculation(bc, st, rs_state)
subroutine, public mxll_apply_boundaries(tr, st, hm, gr, namespace, time, dt, rs_stateb)
subroutine pml_propagation_stage_1_batch(hm, gr, st, tr, ff_rs_stateb, ff_rs_state_pmlb)
subroutine, public propagator_mxll_init(gr, namespace, st, hm, tr)
This module defines the quantity_t class and the IDs for quantities, which can be exposed by a system...
subroutine, public mxll_set_batch(rs_stateb, rs_state, np, dim, offset)
subroutine, public get_electric_field_vector(rs_state_vector, electric_field_vector, ep_element)
subroutine, public build_rs_vector(e_vector, b_vector, rs_sign, rs_vector, ep_element, mu_element)
subroutine, public mxll_get_batch(rs_stateb, rs_state, np, dim, offset)
subroutine, public build_rs_state(e_field, b_field, rs_sign, rs_state, mesh, ep_field, mu_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 tdf_read(f, namespace, function_name, ierr)
This function initializes "f" from the TDFunctions block.
Class defining batches of mesh functions.
class representing derivatives
Description of the grid, containing information on derivatives, stencil, and symmetries.
Describes mesh distribution to nodes.