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, &
294 psib2=ff_rs_inhom_meanb, deltat2=-inter_dt*
m_half)
300 call ff_rs_inhom_2b%end()
301 call ff_rs_inhom_meanb%end()
304 do ii = 1, inter_steps
307 inter_time = time + inter_dt * (ii-1)
318 hm%cpml_hamiltonian = pml_check
319 call tr%te%apply_batch(namespace, gr, hm, ff_rs_stateb, dt)
320 hm%cpml_hamiltonian = .false.
327 if ((hm%ma_mx_coupling_apply) .or. hm%current_density_ext_flag .or. hm%current_density_from_medium)
then
328 if (tr%tr_etrs_approx == mxwll_etrs_full)
then
329 call ff_rs_stateb%copy_to(ff_rs_inhom_1b)
330 call ff_rs_stateb%copy_to(ff_rs_inhom_2b)
331 call ff_rs_stateb%copy_to(ff_rs_inhom_meanb)
334 do istate = 1, hm%dim
335 call batch_set_state(ff_rs_inhom_meanb, istate, gr%np, ff_rs_inhom_t2(:, istate))
336 call batch_set_state(ff_rs_inhom_1b, istate, gr%np, ff_rs_inhom_t1(:, istate))
340 call ff_rs_inhom_1b%copy_data_to(gr%np, ff_rs_inhom_2b)
341 call batch_axpy(gr%np, ii / real(inter_steps, real64) , ff_rs_inhom_meanb, ff_rs_inhom_2b)
342 call batch_axpy(gr%np, (ii-1) / real(inter_steps, real64) , ff_rs_inhom_meanb, ff_rs_inhom_1b)
344 hm%cpml_hamiltonian = .false.
345 call tr%te%apply_batch(namespace, gr, hm, ff_rs_inhom_1b, inter_dt)
350 do istate = 1, hm%dim
351 call batch_set_state(ff_rs_inhom_1b, istate, gr%np, ff_rs_inhom_t1(:, istate))
352 call batch_set_state(ff_rs_inhom_2b, istate, gr%np, ff_rs_inhom_t2(:, istate))
356 call tr%te%apply_batch(namespace, gr, hm, ff_rs_inhom_1b, inter_dt/
m_two, &
357 psib2=ff_rs_inhom_2b, deltat2=-inter_dt/
m_two)
363 call ff_rs_inhom_1b%end()
364 call ff_rs_inhom_2b%end()
365 call ff_rs_inhom_meanb%end()
379 if (tr%bc_constant)
then
382 if (st%rs_state_const_external)
then
404 if (any(hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__mask))
then
410 if (tr%bc_plane_waves)
then
419 if (tr%tr_etrs_approx == option__maxwelltdetrsapprox__const_steps)
then
420 call ff_rs_inhom_1b%end()
423 call ff_rs_stateb%end()
426 call ff_rs_state_pmlb%end()
429 safe_deallocate_a(rs_state)
439 type(namespace_t),
intent(in) :: namespace
440 type(
grid_t),
intent(inout) :: gr
443 real(real64),
intent(in) :: time
444 real(real64),
intent(in) :: dt
445 integer,
intent(in) :: counter
451 call st%rs_stateb%copy_to(rs_state_tmpb)
459 if (any(hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__cpml))
then
470 if (counter == 0)
then
472 call batch_xpay(gr%np, st%rs_stateb, dt, rs_state_tmpb)
479 call st%rs_stateb%copy_data_to(gr%np, st%rs_state_prevb)
481 call rs_state_tmpb%copy_data_to(gr%np, st%rs_stateb)
484 if (any(hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__cpml))
then
488 call rs_state_tmpb%end()
509 type(namespace_t),
intent(in) :: namespace
510 type(
grid_t),
intent(inout) :: gr
513 real(real64),
intent(in) :: time
514 real(real64),
intent(in) :: dt
520 call st%rs_stateb%copy_to(rs_state_tmpb)
529 if (any(hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__cpml))
then
535 call hm%zapply(namespace, gr, st%rs_stateb, rs_state_tmpb)
538 if (hm%current_density_ext_flag .or. hm%current_density_from_medium)
then
540 call mxll_set_batch(st%inhomogeneousb, st%rs_current_density_t1, gr%np, st%dim)
545 call tr%te%apply_phi_batch(namespace, gr, hm, rs_state_tmpb, dt, 1)
547 call batch_axpy(gr%np, dt, rs_state_tmpb, st%rs_stateb)
549 call rs_state_tmpb%end()
552 if (any(hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__cpml))
then
581 type(namespace_t),
intent(in) :: namespace
582 type(
grid_t),
intent(inout) :: gr
585 real(real64),
intent(in) :: time
586 real(real64),
intent(in) :: dt
592 call st%rs_stateb%copy_to(rs_state_tmpb)
601 if (any(hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__cpml))
then
607 call hm%zapply(namespace, gr, st%rs_stateb, rs_state_tmpb)
610 if (hm%current_density_ext_flag .or. hm%current_density_from_medium)
then
612 call mxll_set_batch(st%inhomogeneousb, st%rs_current_density_t1, gr%np, st%dim)
616 call mxll_set_batch(st%inhomogeneousb, st%rs_current_density_t2, gr%np, st%dim)
621 call tr%te%apply_phi_batch(namespace, gr, hm, rs_state_tmpb, dt, 1)
623 call batch_axpy(gr%np, dt, rs_state_tmpb, st%rs_stateb)
624 if (hm%current_density_ext_flag .or. hm%current_density_from_medium)
then
627 call mxll_set_batch(st%inhomogeneousb, st%rs_current_density_t1, gr%np, st%dim)
631 call mxll_set_batch(st%inhomogeneousb, st%rs_current_density_t2, gr%np, st%dim)
636 call tr%te%apply_phi_batch(namespace, gr, hm, rs_state_tmpb, dt, 2)
638 call batch_axpy(gr%np, dt, rs_state_tmpb, st%rs_stateb)
642 if (any(hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__cpml))
then
646 call rs_state_tmpb%end()
654 type(
grid_t),
intent(in) :: gr
657 integer :: ip, ip_in, il, idim
661 assert(
allocated(st%ep) .and.
allocated(st%mu))
665 if (hm%calc_medium_box)
then
666 do il = 1,
size(hm%medium_boxes)
667 assert(.not. hm%medium_boxes(il)%has_mapping)
668 do ip = 1, hm%medium_boxes(il)%points_number
669 if (abs(hm%medium_boxes(il)%c(ip)) <=
m_epsilon) cycle
670 st%ep(ip) = hm%medium_boxes(il)%ep(ip)
671 st%mu(ip) = hm%medium_boxes(il)%mu(ip)
678 do ip_in = 1, hm%bc%medium(idim)%points_number
679 ip = hm%bc%medium(idim)%points_map(ip_in)
680 st%ep(ip) = hm%bc%medium(idim)%ep(ip_in)
681 st%mu(ip) = hm%bc%medium(idim)%mu(ip_in)
694 type(
grid_t),
intent(in) :: gr
696 type(
batch_t),
intent(inout) :: rs_stateb
697 type(
batch_t),
intent(inout) :: ff_rs_stateb
698 integer,
intent(in) :: sign
700 complex(real64),
allocatable :: rs_state(:,:)
701 complex(real64),
allocatable :: rs_state_tmp(:,:)
702 integer :: ii, np, ip
711 safe_allocate(rs_state(1:gr%np, 1:st%dim))
714 if (sign == rs_trans_forward)
then
723 safe_allocate(rs_state_tmp(1:gr%np, 1:st%dim))
729 rs_state(ip, ii) =
m_half * (rs_state(ip, ii) + conjg(rs_state_tmp(ip, ii)))
734 safe_deallocate_a(rs_state_tmp)
737 if (sign == rs_trans_forward)
then
738 call rs_stateb%copy_data_to(gr%np, ff_rs_stateb)
740 call ff_rs_stateb%copy_data_to(gr%np, rs_stateb)
743 safe_deallocate_a(rs_state)
754 class(
mesh_t),
intent(in) :: mesh
755 complex(real64),
intent(inout) :: rs_current_density(:,:)
756 complex(real64),
intent(inout) :: ff_density(:,:)
757 integer,
intent(in) :: sign
761 assert(
size(rs_current_density, dim=2) == 3)
768 if (sign == rs_trans_forward)
then
774 if (sign == rs_trans_forward)
then
775 ff_density(1:mesh%np, 1:3) = rs_current_density(1:mesh%np, 1:3)
777 rs_current_density(1:mesh%np, 1:3) = ff_density(1:mesh%np, 1:3)
789 class(
mesh_t),
intent(in) :: mesh
790 complex(real64),
intent(in) :: rs_current_density(:,:)
791 complex(real64),
intent(inout) :: rs_density_6x6(:,:)
795 assert(
size(rs_current_density, dim=2) == 3)
796 assert(
size(rs_density_6x6, dim=2) == 6)
800 rs_density_6x6(1:mesh%np, ii) = rs_current_density(1:mesh%np, ii)
801 rs_density_6x6(1:mesh%np, ii+3) = rs_current_density(1:mesh%np, ii)
808 class(
mesh_t),
intent(in) :: mesh
809 complex(real64),
intent(in) :: rs_density_6x6(:,:)
810 complex(real64),
intent(inout) :: rs_current_density(:,:)
814 assert(
size(rs_current_density, dim=2) == 3)
815 assert(
size(rs_density_6x6, dim=2) == 6)
822 rs_current_density(ip, ii) =
m_half * &
823 real(rs_density_6x6(ip, ii) + rs_density_6x6(ip, ii+3), real64)
832 type(
grid_t),
intent(in) :: gr_mxll
835 type(
grid_t),
intent(in) :: gr_elec
837 complex(real64),
intent(inout) :: rs_state_matter(:,:)
839 complex(real64),
allocatable :: tmp_pot_mx_gr(:,:), tmp_grad_mx_gr(:,:)
841 safe_allocate(tmp_pot_mx_gr(1:gr_mxll%np_part,1))
842 safe_allocate(tmp_grad_mx_gr(1:gr_mxll%np,1:gr_mxll%box%dim))
848 tmp_grad_mx_gr(:,:) =
m_zero
849 call zderivatives_grad(gr_mxll%der, tmp_pot_mx_gr(:,1), tmp_grad_mx_gr(:,:), set_bc = .false.)
850 tmp_grad_mx_gr = - tmp_grad_mx_gr
852 rs_state_matter =
m_z0
853 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, &
854 rs_state_matter(1:gr_mxll%np,:), gr_mxll, st_mxll%ep(1:gr_mxll%np), st_mxll%mu(1:gr_mxll%np), &
857 safe_deallocate_a(tmp_pot_mx_gr)
858 safe_deallocate_a(tmp_grad_mx_gr)
865 poisson_solver, helmholtz, field, transverse_field, vector_potential)
866 type(namespace_t),
intent(in) :: namespace
867 type(
grid_t),
intent(in) :: gr_mxll
872 type(
poisson_t),
intent(in) :: poisson_solver
874 complex(real64),
intent(inout) :: field(:,:)
875 complex(real64),
intent(inout) :: transverse_field(:,:)
876 real(real64),
intent(inout) :: vector_potential(:,:)
878 integer :: np, ip, idir
879 complex(real64),
allocatable :: rs_state_plane_waves(:, :)
888 if (hm_mxll%ma_mx_coupling)
then
893 if (tr_mxll%bc_plane_waves .and. hm_mxll%plane_waves_apply)
then
894 safe_allocate(rs_state_plane_waves(1:gr_mxll%np, 1:st_mxll%dim))
895 call mxll_get_batch(st_mxll%rs_state_plane_wavesb, rs_state_plane_waves, gr_mxll%np, st_mxll%dim)
899 if (tr_mxll%bc_plane_waves .and. hm_mxll%plane_waves_apply)
then
901 do idir = 1,
size(transverse_field, dim=2)
903 transverse_field(ip,idir) = field(ip,idir) - rs_state_plane_waves(ip,idir)
908 transverse_field(1:np,:) = field(1:np,:)
911 call helmholtz%get_trans_field(namespace, transverse_field, total_field=field)
913 if (tr_mxll%bc_plane_waves .and. hm_mxll%plane_waves_apply)
then
914 do idir = 1,
size(transverse_field, dim=2)
915 call lalg_axpy(np,
m_one, rs_state_plane_waves(:, idir), transverse_field(:, idir))
917 safe_deallocate_a(rs_state_plane_waves)
922 transverse_field(1:np,:) = field
933 type(namespace_t),
intent(in) :: namespace
934 type(
poisson_t),
intent(in) :: poisson_solver
935 type(
grid_t),
intent(in) :: gr
937 complex(real64),
intent(in) :: field(:,:)
938 real(real64),
contiguous,
intent(inout) :: vector_potential(:,:)
941 real(real64),
allocatable :: dtmp(:,:)
943 safe_allocate(dtmp(1:gr%np_part,1:3))
948 dtmp = vector_potential
951 call dpoisson_solve(poisson_solver, namespace, dtmp(:,idim), vector_potential(:,idim), .
true.)
955 safe_deallocate_a(dtmp)
960 subroutine energy_mxll_calc(gr, st, hm, energy_mxll, rs_field, rs_field_plane_waves)
961 type(
grid_t),
intent(in) :: gr
965 complex(real64),
intent(in) :: rs_field(:,:)
966 complex(real64),
optional,
intent(in) :: rs_field_plane_waves(:,:)
968 real(real64),
allocatable :: energy_density(:), e_energy_density(:), b_energy_density(:), energy_density_plane_waves(:)
974 safe_allocate(energy_density(1:gr%np))
975 safe_allocate(e_energy_density(1:gr%np))
976 safe_allocate(b_energy_density(1:gr%np))
977 if (
present(rs_field_plane_waves) .and. hm%plane_waves)
then
978 safe_allocate(energy_density_plane_waves(1:gr%np))
982 b_energy_density, hm%plane_waves, rs_field_plane_waves, energy_density_plane_waves)
983 energy_mxll%energy =
dmf_integrate(gr, energy_density, mask=st%inner_points_mask)
984 energy_mxll%e_energy =
dmf_integrate(gr, e_energy_density, mask=st%inner_points_mask)
985 energy_mxll%b_energy =
dmf_integrate(gr, b_energy_density, mask=st%inner_points_mask)
986 if (
present(rs_field_plane_waves) .and. hm%plane_waves)
then
987 energy_mxll%energy_plane_waves =
dmf_integrate(gr, energy_density_plane_waves, mask=st%inner_points_mask)
989 energy_mxll%energy_plane_waves =
m_zero
992 energy_mxll%boundaries =
dmf_integrate(gr, energy_density, mask=st%boundary_points_mask)
994 safe_deallocate_a(energy_density)
995 safe_deallocate_a(e_energy_density)
996 safe_deallocate_a(b_energy_density)
997 if (
present(rs_field_plane_waves) .and. hm%plane_waves)
then
998 safe_deallocate_a(energy_density_plane_waves)
1008 type(
grid_t),
intent(in) :: gr
1012 type(
batch_t),
intent(in) :: rs_fieldb
1013 type(
batch_t),
intent(in) :: rs_field_plane_wavesb
1015 type(
batch_t) :: e_fieldb, b_fieldb, e_field_innerb, b_field_innerb, rs_field_plane_waves_innerb
1016 real(real64) :: tmp(1:st%dim)
1017 complex(real64) :: ztmp(1:st%dim)
1024 if (st%pack_states)
then
1025 call e_fieldb%do_pack(copy=.false.)
1027 call e_fieldb%copy_to(b_fieldb)
1028 call e_fieldb%copy_to(e_field_innerb)
1029 call e_fieldb%copy_to(b_field_innerb)
1037 call batch_copy_with_map(st%inner_points_number, st%buff_inner_points_map, e_fieldb, e_field_innerb)
1038 call batch_copy_with_map(st%inner_points_number, st%buff_inner_points_map, b_fieldb, b_field_innerb)
1040 call batch_copy_with_map(st%inner_points_number, st%inner_points_map, e_fieldb, e_field_innerb)
1041 call batch_copy_with_map(st%inner_points_number, st%inner_points_map, b_fieldb, b_field_innerb)
1044 energy_mxll%e_energy = sum(tmp)
1046 energy_mxll%b_energy = sum(tmp)
1047 energy_mxll%energy = energy_mxll%e_energy + energy_mxll%b_energy
1050 energy_mxll%boundaries = sum(tmp)
1052 energy_mxll%boundaries = energy_mxll%boundaries + sum(tmp)
1053 energy_mxll%boundaries = energy_mxll%boundaries - energy_mxll%energy
1055 if (hm%plane_waves)
then
1056 call rs_field_plane_wavesb%copy_to(rs_field_plane_waves_innerb)
1060 rs_field_plane_wavesb, rs_field_plane_waves_innerb)
1063 rs_field_plane_wavesb, rs_field_plane_waves_innerb)
1066 energy_mxll%energy_plane_waves = sum(real(ztmp, real64) )
1067 call rs_field_plane_waves_innerb%end()
1069 energy_mxll%energy_plane_waves =
m_zero
1074 call e_field_innerb%end()
1075 call b_field_innerb%end()
1084 type(namespace_t),
intent(in) :: namespace
1085 type(
grid_t),
intent(in) :: gr
1089 real(real64),
intent(in) :: time
1090 real(real64),
intent(in) :: dt
1091 real(real64),
intent(in) :: time_delay
1092 complex(real64),
intent(inout) :: rs_state(:,:)
1094 integer :: ip, ip_in, idim
1095 logical :: mask_check
1100 mask_check = .false.
1103 if (hm%bc%bc_ab_type(idim) == option__maxwellabsorbingboundaries__mask)
then
1108 if (mask_check)
then
1109 if (tr%bc_plane_waves .and. hm%plane_waves_apply)
then
1111 call mxll_get_batch(st%rs_state_plane_wavesb, st%rs_state_plane_waves, gr%np, st%dim)
1112 rs_state = rs_state - st%rs_state_plane_waves
1114 rs_state = rs_state + st%rs_state_plane_waves
1115 else if (tr%bc_constant .and. hm%spatial_constant_apply)
then
1118 do ip_in=1, hm%bc%constant_points_number
1119 ip = hm%bc%constant_points_map(ip_in)
1120 rs_state(ip,:) = rs_state(ip,:) - st%rs_state_const(:)
1123 do ip_in=1, hm%bc%constant_points_number
1124 ip = hm%bc%constant_points_map(ip_in)
1125 rs_state(ip,:) = rs_state(ip,:) + st%rs_state_const(:)
1140 complex(real64),
intent(inout) :: rs_state(:,:)
1142 integer :: ip, ip_in, idim
1149 if (hm%bc%bc_ab_type(idim) == option__maxwellabsorbingboundaries__mask)
then
1150 do ip_in = 1, hm%bc%mask_points_number(idim)
1151 ip = hm%bc%mask_points_map(ip_in,idim)
1152 rs_state(ip,:) = rs_state(ip,:) * hm%bc%mask(ip_in,idim)
1165 type(
grid_t),
intent(in) :: gr
1168 type(
batch_t),
intent(in) :: ff_rs_stateb
1169 type(
batch_t),
intent(inout) :: ff_rs_state_pmlb
1172 complex(real64),
allocatable :: rs_state_constant(:,:)
1173 type(
batch_t) :: rs_state_constantb
1179 if (tr%bc_plane_waves .and. hm%plane_waves_apply)
then
1181 ff_rs_state_pmlb, rs_trans_forward)
1183 else if (tr%bc_constant .and. hm%spatial_constant_apply)
then
1188 safe_allocate(rs_state_constant(1:gr%np,1:3))
1190 rs_state_constant(1:gr%np, ii) = st%rs_state_const(ii)
1192 call ff_rs_stateb%copy_to(rs_state_constantb)
1193 call mxll_set_batch(rs_state_constantb, rs_state_constant, gr%np, 3)
1196 ff_rs_state_pmlb, rs_trans_forward)
1199 call rs_state_constantb%end()
1201 safe_deallocate_a(rs_state_constant)
1204 call ff_rs_stateb%copy_data_to(gr%np, ff_rs_state_pmlb)
1215 type(namespace_t),
intent(in) :: namespace
1216 type(
grid_t),
intent(in) :: gr
1219 real(real64),
intent(in) :: time
1220 real(real64),
intent(in) :: dt
1221 real(real64),
intent(in) :: time_delay
1222 type(
batch_t),
intent(inout) :: ff_rs_state_pmlb
1223 type(
batch_t),
intent(inout) :: ff_rs_stateb
1225 integer :: ii, ff_dim
1226 complex(real64),
allocatable :: rs_state_constant(:,:), ff_rs_state_constant(:,:)
1227 type(
batch_t) :: ff_rs_state_plane_wavesb, ff_rs_constantb, rs_state_constantb
1233 if (tr%bc_plane_waves .and. hm%plane_waves_apply)
then
1234 hm%cpml_hamiltonian = .
true.
1235 call tr%te%apply_batch(namespace, gr, hm, ff_rs_state_pmlb, dt)
1236 hm%cpml_hamiltonian = .false.
1239 call ff_rs_stateb%copy_to(ff_rs_state_plane_wavesb)
1245 ff_rs_state_pmlb, ff_rs_state_plane_wavesb, ff_rs_stateb)
1247 call batch_add_with_map(hm%bc%plane_wave%points_number, hm%bc%plane_wave%points_map, &
1248 ff_rs_state_pmlb, ff_rs_state_plane_wavesb, ff_rs_stateb)
1251 call ff_rs_state_plane_wavesb%end()
1253 else if (tr%bc_constant .and. hm%spatial_constant_apply)
then
1254 hm%cpml_hamiltonian = .
true.
1255 call tr%te%apply_batch(namespace, gr, hm, ff_rs_state_pmlb, dt)
1256 hm%cpml_hamiltonian = .false.
1258 call ff_rs_stateb%copy_to(ff_rs_constantb)
1259 ff_dim = ff_rs_stateb%nst_linear
1260 safe_allocate(rs_state_constant(1:gr%np, 1:st%dim))
1264 rs_state_constant(1:gr%np, ii) = st%rs_state_const(ii)
1266 call ff_rs_stateb%copy_to(rs_state_constantb)
1267 call mxll_set_batch(rs_state_constantb, rs_state_constant, gr%np, st%dim)
1272 call batch_add_with_map(hm%bc%constant_points_number, hm%bc%buff_constant_points_map, &
1273 ff_rs_state_pmlb, ff_rs_constantb, ff_rs_stateb)
1276 ff_rs_state_pmlb, ff_rs_constantb, ff_rs_stateb)
1279 call ff_rs_constantb%end()
1280 call rs_state_constantb%end()
1282 safe_deallocate_a(rs_state_constant)
1283 safe_deallocate_a(ff_rs_state_constant)
1294 type(
grid_t),
intent(in) :: gr
1295 type(
batch_t),
intent(inout) :: ff_rs_state_pmlb
1312 type(
grid_t),
intent(in) :: gr
1313 type(
batch_t),
intent(inout) :: ff_rs_state_pmlb
1315 integer :: ip, ip_in, np_part, rs_sign
1316 complex(real64) :: pml_a, pml_b, pml_g, grad
1317 integer :: pml_dir, field_dir, ifield, idir
1318 integer,
parameter :: field_dirs(3, 2) = reshape([2, 3, 1, 3, 1, 2], [3, 2])
1319 logical :: with_medium
1320 type(
batch_t) :: gradb(gr%der%dim)
1322 integer :: bsize, gsize
1328 assert(hm%dim == 3 .or. hm%dim == 6)
1330 np_part = gr%np_part
1331 rs_sign = hm%rs_sign
1335 with_medium = hm%dim == 6
1337 do pml_dir = 1, hm%st%dim
1338 select case (gradb(pml_dir)%status())
1340 do ip_in=1, hm%bc%pml%points_number
1341 ip = hm%bc%pml%points_map(ip_in)
1342 pml_a = hm%bc%pml%a(ip_in,pml_dir)
1343 pml_b = hm%bc%pml%b(ip_in,pml_dir)
1345 field_dir = field_dirs(pml_dir, ifield)
1346 grad = gradb(pml_dir)%zff_linear(ip, field_dir)
1347 pml_g = hm%bc%pml%conv_plus(ip_in, pml_dir, field_dir)
1348 hm%bc%pml%conv_plus(ip_in, pml_dir, field_dir) = pml_a * grad + pml_b * pml_g
1349 if (with_medium)
then
1350 grad = gradb(pml_dir)%zff_linear(ip, field_dir+3)
1351 pml_g = hm%bc%pml%conv_minus(ip_in, pml_dir, field_dir)
1352 hm%bc%pml%conv_minus(ip_in, pml_dir, field_dir) = pml_a * grad + pml_b * pml_g
1357 do ip_in=1, hm%bc%pml%points_number
1358 ip = hm%bc%pml%points_map(ip_in)
1359 pml_a = hm%bc%pml%a(ip_in,pml_dir)
1360 pml_b = hm%bc%pml%b(ip_in,pml_dir)
1362 field_dir = field_dirs(pml_dir, ifield)
1363 grad = gradb(pml_dir)%zff_pack(field_dir, ip)
1364 pml_g = hm%bc%pml%conv_plus(ip_in, pml_dir, field_dir)
1365 hm%bc%pml%conv_plus(ip_in, pml_dir, field_dir) = pml_a * grad + pml_b * pml_g
1366 if (with_medium)
then
1367 grad = gradb(pml_dir)%zff_pack(field_dir+3, ip)
1368 pml_g = hm%bc%pml%conv_minus(ip_in, pml_dir, field_dir)
1369 hm%bc%pml%conv_minus(ip_in, pml_dir, field_dir) = pml_a * grad + pml_b * pml_g
1376 if (with_medium)
then
1399 do idir = 1, gr%der%dim
1400 call gradb(idir)%end()
1415 type(namespace_t),
intent(in) :: namespace
1419 integer :: il, nlines, idim, ncols, ierr
1420 real(real64) :: e_field(st%dim), b_field(st%dim)
1421 character(len=1024) :: mxf_expression
1444 if (
parse_block(namespace,
'UserDefinedConstantSpatialMaxwellField', blk) == 0)
then
1445 st%rs_state_const_external = .
true.
1447 safe_allocate(st%rs_state_const_td_function(1:nlines))
1448 safe_allocate(st%rs_state_const_amp(1:st%dim, 1:nlines))
1455 if (ncols /= 7)
then
1456 message(1) =
'Each line in the UserDefinedConstantSpatialMaxwellField block must have'
1467 call build_rs_vector(e_field, b_field, st%rs_sign, st%rs_state_const_amp(:,il))
1468 call tdf_read(st%rs_state_const_td_function(il), namespace, trim(mxf_expression), ierr)
1482 call parse_variable(namespace,
'PropagateSpatialMaxwellField', .
true., hm%spatial_constant_propagate)
1491 logical,
intent(in) :: constant_calc
1493 type(
grid_t),
intent(in) :: gr
1495 real(real64),
intent(in) :: time
1496 real(real64),
intent(in) :: dt
1497 real(real64),
intent(in) :: delay
1498 complex(real64),
intent(inout) :: rs_state(:,:)
1499 logical,
optional,
intent(in) :: set_initial_state
1501 integer :: ip, ic, icn
1502 real(real64) :: tf_old, tf_new
1503 logical :: set_initial_state_
1509 set_initial_state_ = .false.
1510 if (
present(set_initial_state)) set_initial_state_ = set_initial_state
1512 if (hm%spatial_constant_apply)
then
1513 if (constant_calc)
then
1514 icn =
size(st%rs_state_const_td_function(:))
1515 st%rs_state_const(:) =
m_z0
1517 tf_old =
tdf(st%rs_state_const_td_function(ic), time-delay-dt)
1518 tf_new =
tdf(st%rs_state_const_td_function(ic), time-delay)
1520 if (set_initial_state_ .or. (.not. hm%spatial_constant_propagate))
then
1521 rs_state(ip,:) = st%rs_state_const_amp(:,ic) * tf_new
1523 rs_state(ip,:) = rs_state(ip,:) + st%rs_state_const_amp(:,ic) * (tf_new - tf_old)
1526 st%rs_state_const(:) = st%rs_state_const(:) + st%rs_state_const_amp(:, ic) * tf_new
1538 logical,
intent(in) :: constant_calc
1542 complex(real64),
intent(inout) :: rs_state(:,:)
1544 integer :: ip_in, ip
1549 if (hm%spatial_constant_apply)
then
1550 if (constant_calc)
then
1551 do ip_in = 1, bc%constant_points_number
1552 ip = bc%constant_points_map(ip_in)
1553 rs_state(ip,:) = st%rs_state_const(:)
1554 bc%constant_rs_state(ip_in,:) = st%rs_state_const(:)
1568 complex(real64),
intent(inout) :: rs_state(:,:)
1570 integer :: ip, ip_in, idim
1571 real(real64) :: e_field(st%dim), b_field(st%dim)
1577 do ip_in = 1, bc%mirror_points_number(idim)
1578 ip = bc%mirror_points_map(ip_in, idim)
1581 call build_rs_vector(e_field(:), b_field(:), st%rs_sign, rs_state(ip,:), st%ep(ip), st%mu(ip))
1593 complex(real64),
intent(inout) :: rs_state(:,:)
1595 integer :: ip, ip_in, idim
1596 real(real64) :: e_field(st%dim), b_field(st%dim)
1602 do ip_in = 1, bc%mirror_points_number(idim)
1603 ip = bc%mirror_points_map(ip_in,idim)
1606 call build_rs_vector(e_field(:), b_field(:), st%rs_sign, rs_state(ip,:), st%ep(ip), st%mu(ip))
1618 class(
mesh_t),
intent(in) :: mesh
1619 real(real64),
intent(in) :: time
1620 real(real64),
intent(in) :: time_delay
1621 complex(real64),
intent(inout) :: rs_state(:,:)
1623 integer :: ip, ip_in, wn
1624 real(real64) :: x_prop(mesh%box%dim), rr, vv(mesh%box%dim), k_vector(mesh%box%dim)
1625 real(real64) :: k_vector_abs, nn
1626 complex(real64) :: e0(mesh%box%dim)
1627 real(real64) :: e_field(mesh%box%dim), b_field(mesh%box%dim)
1628 complex(real64) :: rs_state_add(mesh%box%dim)
1629 complex(real64) :: mx_func
1635 if (hm%plane_waves_apply)
then
1636 do wn = 1, hm%bc%plane_wave%number
1637 k_vector(:) = hm%bc%plane_wave%k_vector(1:mesh%box%dim, wn)
1638 k_vector_abs = norm2(k_vector(1:mesh%box%dim))
1639 vv(:) = hm%bc%plane_wave%v_vector(1:mesh%box%dim, wn)
1640 e0(:) = hm%bc%plane_wave%e_field(1:mesh%box%dim, wn)
1641 do ip_in = 1, hm%bc%plane_wave%points_number
1642 ip = hm%bc%plane_wave%points_map(ip_in)
1644 if (wn == 1) rs_state(ip,:) =
m_z0
1646 x_prop(1:mesh%box%dim) = mesh%x(1:mesh%box%dim, ip) - vv(1:mesh%box%dim) * (time - time_delay)
1647 rr = norm2(x_prop(1:mesh%box%dim))
1648 if (hm%bc%plane_wave%modus(wn) == option__maxwellincidentwaves__plane_wave_mx_function)
then
1650 mx_func =
mxf(hm%bc%plane_wave%mx_function(wn), x_prop(1:mesh%box%dim))
1651 e_field(1:mesh%box%dim) = real(e0(1:mesh%box%dim) * mx_func, real64)
1654 call build_rs_vector(e_field, b_field, st%rs_sign, rs_state_add, st%ep(ip), st%mu(ip))
1655 rs_state(ip, :) = rs_state(ip, :) + rs_state_add(:)
1659 do ip_in = 1, hm%bc%plane_wave%points_number
1660 ip = hm%bc%plane_wave%points_map(ip_in)
1661 rs_state(ip,:) =
m_z0
1674 type(namespace_t),
intent(in) :: namespace
1676 type(
grid_t),
intent(in) :: gr
1677 real(real64),
intent(in) :: time
1678 real(real64),
intent(in) :: dt
1679 real(real64),
intent(in) :: time_delay
1689 call zbatch_init(ff_rs_stateb, 1, 1, hm%dim, gr%np_part)
1690 if (st%pack_states)
call ff_rs_stateb%do_pack(copy=.false.)
1696 hm%cpml_hamiltonian = .false.
1697 call tr%te%apply_batch(namespace, gr, hm, ff_rs_stateb, dt)
1700 call mxll_get_batch(st%rs_state_plane_wavesb, st%rs_state_plane_waves, gr%np, st%dim)
1702 call mxll_set_batch(st%rs_state_plane_wavesb, st%rs_state_plane_waves, gr%np, st%dim)
1703 call ff_rs_stateb%end()
1712 real(real64),
intent(in) :: time
1713 class(
mesh_t),
intent(in) :: mesh
1716 complex(real64),
intent(inout) :: rs_state(:,:)
1718 real(real64) :: e_field_total(mesh%np,st%dim), b_field_total(mesh%np,st%dim)
1719 complex(real64) :: rs_state_add(mesh%np,st%dim)
1730 rs_state_add(1:mesh%np,:), mesh, st%ep, st%mu)
1732 call lalg_axpy(mesh%np,
m_one, rs_state_add(:, idir), rs_state(:, idir))
1745 type(
grid_t),
intent(in) :: gr
1746 type(namespace_t),
intent(in) :: namespace
1747 real(real64),
intent(in) :: time
1748 real(real64),
intent(in) :: dt
1749 type(
batch_t),
intent(inout) :: rs_stateb
1751 complex(real64),
allocatable :: rs_state(:, :)
1755 safe_allocate(rs_state(gr%np, st%dim))
1757 if (tr%bc_constant)
then
1760 if (st%rs_state_const_external)
then
1781 if (any(hm%bc%bc_ab_type == option__maxwellabsorbingboundaries__mask))
then
1788 if (tr%bc_plane_waves)
then
1795 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:
constant times a vector plus a vector
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.