67 integer :: points_number
68 integer,
allocatable :: points_map(:)
69 integer,
allocatable :: points_map_inv(:)
71 real(real64) :: refl_error
72 real(real64),
allocatable :: kappa(:,:)
73 real(real64),
allocatable :: sigma_e(:,:)
74 real(real64),
allocatable :: sigma_m(:,:)
75 real(real64),
allocatable :: a(:,:)
76 real(real64),
allocatable :: b(:,:)
77 real(real64),
allocatable :: c(:,:)
78 real(real64),
allocatable :: mask(:)
79 complex(real64),
allocatable :: aux_ep(:,:,:)
80 complex(real64),
allocatable :: aux_mu(:,:,:)
81 complex(real64),
allocatable :: conv_plus(:,:,:)
82 complex(real64),
allocatable :: conv_minus(:,:,:)
83 complex(real64),
allocatable :: conv_plus_old(:,:,:)
84 complex(real64),
allocatable :: conv_minus_old(:,:,:)
85 logical :: parameters_initialized = .false.
87 type(accel_mem_t) :: buff_a, buff_b, buff_c, buff_conv_plus, buff_conv_minus, buff_map, buff_conv_plus_old
92 integer :: bc_ab_type(3)
93 real(real64) :: bc_bounds(2, 3)
94 logical :: ab_user_def
95 real(real64),
allocatable :: ab_ufn(:)
97 real(real64) :: ab_width
98 real(real64) :: mask_width
99 integer :: mask_points_number(3)
100 integer,
allocatable :: mask_points_map(:,:)
101 real(real64),
allocatable :: mask(:,:)
103 integer :: der_bndry_mask_points_number
104 integer,
allocatable :: der_bndry_mask_points_map(:)
105 real(real64),
allocatable :: der_bndry_mask(:)
108 type(single_medium_box_t) :: medium(3)
110 integer :: constant_points_number
111 integer,
allocatable :: constant_points_map(:)
112 complex(real64),
allocatable :: constant_rs_state(:,:)
113 type(accel_mem_t) :: buff_constant_points_map
115 integer :: mirror_points_number(3)
116 integer,
allocatable :: mirror_points_map(:,:)
118 logical :: do_plane_waves = .false.
119 type(external_waves_t) :: plane_wave
120 logical :: plane_waves_dims(1:3) = .false.
122 real(real64) :: zero_width
123 integer :: zero_points_number(3)
124 integer,
allocatable :: zero_points_map(:,:)
125 real(real64),
allocatable :: zero(:,:)
128 integer,
public,
parameter :: &
137 integer,
parameter :: &
138 MXLL_PLANE_WAVES_NEGATIVE_SIDE = -1, &
141 integer,
public,
parameter :: &
142 MXLL_AB_NOT_ABSORBING = 0, &
151 type(bc_mxll_t),
intent(inout) :: bc
152 type(namespace_t),
intent(in) :: namespace
153 class(space_t),
intent(in) :: space
154 type(grid_t),
intent(in) :: gr
155 type(states_mxll_t),
intent(inout) :: st
157 integer :: idim, nlines, icol, ncols, ab_shape_dim
158 real(real64) :: bounds(2, space%dim), ab_bounds(2, space%dim)
160 character(len=1024) :: string
161 character(len=50) :: ab_type_str
162 character(len=1),
dimension(3),
parameter :: dims = [
"x",
"y",
"z"]
163 logical :: plane_waves_check, ab_mask_check, ab_pml_check
164 logical :: constant_check, zero_check
165 real(real64) :: ep_factor, mu_factor, sigma_e_factor, sigma_m_factor
171 plane_waves_check = .false.
172 ab_mask_check = .false.
173 ab_pml_check = .false.
174 constant_check = .false.
177 bc%ab_user_def = .false.
178 bc%bc_ab_type(:) = mxll_ab_not_absorbing
202 if (
parse_block(namespace,
'MaxwellAbsorbingBoundaries', blk) == 0)
then
205 if (nlines /= 1)
then
206 message(1) =
'MaxwellAbsorbingBounaries has to consist of one line!'
212 message(1) =
'MaxwellAbsorbingBoundaries has to consist of three columns!'
227 if (bc%bc_type(idim) == mxll_bc_zero) zero_check = .
true.
230 if (ab_mask_check .or. ab_pml_check)
then
233 write(
message(1),
'(a)')
"Please keep in mind that"
234 write(
message(2),
'(a)')
"with larger ABWidth, comes great responsibility."
235 write(
message(3),
'(a)')
"AbsorbingBoundaries occupy space in the simulation box,"
236 write(
message(4),
'(a)')
"hence choose your Lsize wisely."
242 select case (bc%bc_type(idim))
246 bounds(1, idim) = (gr%idx%nr(2, idim) - gr%idx%enlarge(idim))*gr%spacing(idim)
247 bounds(2, idim) = (gr%idx%nr(2, idim)) * gr%spacing(idim)
251 bounds(1, idim) = (gr%idx%nr(2, idim) - 2*gr%idx%enlarge(idim))*gr%spacing(idim)
252 bounds(2, idim) = (gr%idx%nr(2, idim)) * gr%spacing(idim)
256 bounds(1, idim) = (gr%idx%nr(2, idim) - 2*gr%idx%enlarge(idim))*gr%spacing(idim)
257 bounds(2, idim) = (gr%idx%nr(2, idim)) * gr%spacing(idim)
258 plane_waves_check = .
true.
259 bc%do_plane_waves = .
true.
262 call bc_mxll_medium_init(gr, namespace, bounds, idim, ep_factor, mu_factor, sigma_e_factor, sigma_m_factor)
268 select type (box => gr%box)
271 if (space%is_periodic())
then
272 message(1) =
"Sphere box shape can only work for non-periodic systems"
276 if (bc%bc_type(idim) ==
mxll_bc_periodic .and. .not. box%axes%orthogonal)
then
277 message(1) =
"Maxwell propagation does not work for non-orthogonal boxes with periodic boundary conditions."
281 ab_shape_dim = space%dim
282 ab_bounds(1, idim) = bounds(1, idim)
283 ab_bounds(2, idim) = bounds(1, idim)
285 message(1) =
"Box shape for Maxwell propagation not supported yet"
289 if (bc%bc_ab_type(idim) /= mxll_ab_not_absorbing)
then
293 select case (bc%bc_ab_type(idim))
296 message(1) =
"Zero absorbing boundary conditions do not work in periodic directions"
301 bc%zero_width = bc%ab_width
305 bc%mask_width = bc%ab_width
311 message(1) =
"Absorbing boundary type not implemented for Maxwell propagation"
317 select case (bc%bc_ab_type(idim))
319 bounds(1, idim) = ab_bounds(1, idim)
320 bounds(2, idim) = bounds(2, idim)
321 bc%bc_bounds(:, idim) = bounds(:, idim)
323 bc%bc_bounds(:, idim) = bounds(:, idim)
326 select type (box => gr%box)
328 select case (bc%bc_ab_type(idim))
341 string = trim(ab_type_str)//
" Absorbing Boundary"
342 write(string,
'(2a, f10.3,3a)') trim(string),
" in "//dims(idim)//
' direction spans from: ', &
345 write(
message(1),
'(a)') trim(string)
348 write(string,
'(a,f10.3,3a)') trim(string),&
352 write(
message(2),
'(a)') trim(string)
358 write(
message(1),
'(a,es10.3,3a)') &
361 write(
message(2),
'(a,es10.3,3a)') &
374 if (ab_mask_check)
then
379 if (ab_pml_check)
then
384 if (constant_check)
then
389 if (plane_waves_check)
then
399 if (ab_mask_check)
then
403 if (ab_pml_check)
then
411 if (ab_mask_check .or. ab_pml_check)
then
428 safe_deallocate_a(bc%ab_ufn)
430 safe_deallocate_a(bc%mask_points_map)
431 safe_deallocate_a(bc%mask)
433 safe_deallocate_a(bc%der_bndry_mask)
434 safe_deallocate_a(bc%der_bndry_mask_points_map)
441 safe_deallocate_a(bc%constant_points_map)
442 safe_deallocate_a(bc%constant_rs_state)
447 safe_deallocate_a(bc%mirror_points_map)
451 safe_deallocate_a(bc%zero_points_map)
452 safe_deallocate_a(bc%zero)
459 type(
pml_t),
intent(inout) :: pml
463 safe_deallocate_a(pml%points_map)
464 safe_deallocate_a(pml%points_map_inv)
465 safe_deallocate_a(pml%kappa)
466 safe_deallocate_a(pml%sigma_e)
467 safe_deallocate_a(pml%sigma_m)
468 safe_deallocate_a(pml%a)
469 safe_deallocate_a(pml%b)
470 safe_deallocate_a(pml%c)
471 safe_deallocate_a(pml%mask)
472 safe_deallocate_a(pml%aux_ep)
473 safe_deallocate_a(pml%aux_mu)
474 safe_deallocate_a(pml%conv_plus)
475 safe_deallocate_a(pml%conv_minus)
476 safe_deallocate_a(pml%conv_plus_old)
477 safe_deallocate_a(pml%conv_minus_old)
495 subroutine bc_mxll_medium_init(gr, namespace, bounds, idim, ep_factor, mu_factor, sigma_e_factor, sigma_m_factor)
496 type(
grid_t),
intent(in) :: gr
497 type(namespace_t),
intent(in) :: namespace
498 real(real64),
intent(inout) :: bounds(:,:)
499 integer,
intent(in) :: idim
500 real(real64),
intent(out) :: ep_factor
501 real(real64),
intent(out) :: mu_factor
502 real(real64),
intent(out) :: sigma_e_factor
503 real(real64),
intent(out) :: sigma_m_factor
505 real(real64) :: width
519 bounds(1,idim) = ( gr%idx%nr(2, idim) - gr%idx%enlarge(idim) ) * gr%spacing(idim)
520 bounds(1,idim) = bounds(1,idim) - width
521 bounds(2,idim) = ( gr%idx%nr(2, idim) ) * gr%spacing(idim)
567 type(
grid_t),
intent(in) :: gr
568 type(namespace_t),
intent(in) :: namespace
569 real(real64),
intent(inout) :: ab_bounds(:,:)
570 integer,
intent(in) :: idim
572 real(real64) :: default_width
584 default_width =
m_two * gr%der%order * maxval(gr%spacing(1:3))
587 if (bc%ab_width < default_width)
then
588 bc%ab_width = default_width
589 write(
message(1),
'(a)')
'Absorbing boundary width has to be larger or equal than twice the derivatives order times spacing!'
590 write(
message(2),
'(a,es10.3)')
'Absorbing boundary width is set to: ', default_width
594 ab_bounds(1, idim) = ab_bounds(2, idim) - bc%ab_width
602 type(
grid_t),
intent(in) :: gr
603 type(namespace_t),
intent(in) :: namespace
604 real(real64),
intent(inout) :: ab_bounds(:,:)
605 integer,
intent(in) :: idim
610 bc%pml%width = bc%ab_width
629 call parse_variable(namespace,
'MaxwellABPMLReflectionError', 1.0e-16_real64, bc%pml%refl_error,
unit_one)
637 class(
mesh_t),
intent(in) :: mesh
638 type(namespace_t),
intent(in) :: namespace
639 class(
space_t),
intent(in) :: space
641 integer :: err, idim, idim2
642 real(real64),
allocatable :: tmp(:)
643 logical :: mask_check, pml_check, medium_check
644 character(1) :: dim_label(3)
652 medium_check = .false.
654 dim_label = (/
'x',
'y',
'z'/)
664 medium_check = .
true.
669 safe_allocate(tmp(1:mesh%np))
675 safe_deallocate_a(tmp)
676 else if (pml_check)
then
677 safe_allocate(tmp(1:mesh%np))
682 call write_files(
"maxwell_sigma_e-"//dim_label(idim), tmp)
687 call write_files(
"maxwell_sigma_m-"//dim_label(idim), tmp)
692 call write_files(
"maxwell_sigma_pml_a_e-"//dim_label(idim), tmp)
694 safe_deallocate_a(tmp)
697 if (medium_check)
then
698 safe_allocate(tmp(1:mesh%np))
703 call write_files(
"maxwell_ep"//dim_label(idim), tmp)
707 call write_files(
"maxwell_mu"//dim_label(idim), tmp)
711 call write_files(
"maxwell_c"//dim_label(idim), tmp)
716 call write_files(
"maxwell_aux_ep-"//dim_label(idim)//
"-"//dim_label(idim2), tmp)
721 call write_files(
"maxwell_aux_mu-"//dim_label(idim)//
"-"//dim_label(idim2), tmp)
725 safe_deallocate_a(tmp)
734 real(real64),
intent(in) :: pml_func(:)
736 real(real64),
intent(inout) :: io_func(:)
740 do ip_in = 1, bc%pml%points_number
741 ip = bc%pml%points_map(ip_in)
742 io_func(ip) = pml_func(ip_in)
748 real(real64),
intent(in) :: mask_func(:,:)
750 real(real64),
intent(inout) :: io_func(:)
751 integer,
intent(in) :: idim
755 do ip_in = 1, bc%mask_points_number(idim)
756 ip = bc%mask_points_map(ip_in, idim)
757 io_func(ip) = mask_func(ip_in, idim)
763 real(real64),
intent(in) :: medium_func(:)
765 real(real64),
intent(inout) :: io_func(:)
766 integer,
intent(in) :: idim
770 do ip_in = 1, bc%medium(idim)%points_number
771 ip = bc%medium(idim)%points_map(ip_in)
772 io_func(ip) = medium_func(ip_in)
778 character(len=*),
intent(in) :: filename
779 real(real64),
intent(in) :: tmp(:)
802 class(
mesh_t),
intent(in) :: mesh
803 real(real64),
intent(in) :: bounds(:,:)
805 integer :: ip, ip_in, ip_in_max, point_info, idim
817 if ((point_info == 1) .and. (abs(mesh%x(ip, idim)) >= bounds(1, idim)))
then
821 if (ip_in > ip_in_max) ip_in_max = ip_in
822 bc%mask_points_number(idim) = ip_in
825 safe_allocate(bc%mask(1:ip_in_max, 1:idim))
826 safe_allocate(bc%mask_points_map(1:ip_in_max, 1:idim))
834 if ((point_info == 1) .and. (abs(mesh%x(ip, idim)) >= bounds(1, idim)))
then
836 bc%mask_points_map(ip_in, idim) = ip
849 class(
mesh_t),
intent(in) :: mesh
850 real(real64),
intent(in) :: bounds(:,:)
852 integer :: ip, ip_in, point_info
862 if (point_info == 1)
then
866 bc%pml%points_number = ip_in
867 safe_allocate(bc%pml%points_map(1:ip_in))
868 safe_allocate(bc%pml%points_map_inv(1:mesh%np))
869 bc%pml%points_map_inv = 0
873 if (point_info == 1)
then
875 bc%pml%points_map(ip_in) = ip
876 bc%pml%points_map_inv(ip) = ip_in
888 class(
mesh_t),
intent(in) :: mesh
889 real(real64),
intent(in) :: bounds(:,:)
891 integer :: ip, ip_in, point_info
901 if (point_info == 1)
then
905 bc%constant_points_number = ip_in
906 safe_allocate(bc%constant_points_map(1:ip_in))
907 safe_allocate(bc%constant_rs_state(1:ip_in, 1:3))
913 if (point_info == 1)
then
915 bc%constant_points_map(ip_in) = ip
921 call accel_write_buffer(bc%buff_constant_points_map, bc%constant_points_number, bc%constant_points_map)
932 class(
mesh_t),
intent(in) :: mesh
933 real(real64),
intent(in) :: bounds(:,:)
934 type(namespace_t),
intent(in) :: namespace
936 integer :: ip, ip_in, point_info
948 if (point_info == 1)
then
952 bc%plane_wave%points_number = ip_in
953 safe_allocate(bc%plane_wave%points_map(1:ip_in))
959 if (point_info == 1)
then
961 bc%plane_wave%points_map(ip_in) = ip
967 call accel_write_buffer(bc%plane_wave%buff_map, bc%plane_wave%points_number, bc%plane_wave%points_map)
978 class(
mesh_t),
intent(in) :: mesh
979 real(real64),
intent(in) :: bounds(:,:)
981 integer :: ip, ip_in, ip_in_max, point_info, idim
989 if (bc%bc_type(idim) == mxll_bc_zero)
then
994 if ((point_info == 1) .and. (abs(mesh%x(ip, idim)) >= bounds(1, idim)))
then
998 if (ip_in > ip_in_max) ip_in_max = ip_in
1001 bc%zero_points_number = ip_in
1002 safe_allocate(bc%zero(1:ip_in_max,3))
1003 safe_allocate(bc%zero_points_map(1:ip_in_max, 1:3))
1006 if (bc%bc_type(idim) == mxll_bc_zero)
then
1011 if ((point_info == 1) .and. (abs(mesh%x(ip, idim)) >= bounds(1, idim)))
then
1013 bc%zero_points_map(ip_in, idim) = ip
1027 class(
mesh_t),
intent(in) :: mesh
1028 real(real64),
intent(in) :: bounds(:,:)
1030 integer :: ip, ip_in, ip_in_max, ip_bd, ip_bd_max, point_info, boundary_info, idim
1046 if ((point_info == 1) .and. (abs(mesh%x(ip, idim)) >= bounds(1, idim)))
then
1049 if ((boundary_info == 1) .and. (abs(mesh%x(ip, idim)) >= bounds(1, idim)))
then
1053 bc%medium(idim)%points_number = ip_in
1054 bc%medium(idim)%bdry_number = ip_bd
1058 safe_allocate(bc%medium(idim)%points_map(1:ip_in_max))
1059 safe_allocate(bc%medium(idim)%bdry_map(1:ip_bd_max))
1069 if ((point_info == 1) .and. (abs(mesh%x(ip, idim)) >= bounds(1, idim)))
then
1071 bc%medium(idim)%points_map(ip_in) = ip
1073 if ((boundary_info == 1) .and. (abs(mesh%x(ip, idim)) >= bounds(1, idim)))
then
1075 bc%medium(idim)%bdry_map(ip_bd) = ip
1089 class(
space_t),
intent(in) :: space
1096 safe_allocate(bc%pml%kappa(1:bc%pml%points_number, 1:space%dim))
1097 safe_allocate(bc%pml%sigma_e(1:bc%pml%points_number, 1:space%dim))
1098 safe_allocate(bc%pml%sigma_m(1:bc%pml%points_number, 1:space%dim))
1099 safe_allocate(bc%pml%a(1:bc%pml%points_number, 1:space%dim))
1100 safe_allocate(bc%pml%b(1:bc%pml%points_number, 1:space%dim))
1101 safe_allocate(bc%pml%c(1:bc%pml%points_number, 1:3))
1102 safe_allocate(bc%pml%mask(1:bc%pml%points_number))
1103 safe_allocate(bc%pml%conv_plus(1:bc%pml%points_number, 1:3, 1:3))
1104 safe_allocate(bc%pml%conv_minus(1:bc%pml%points_number, 1:3, 1:3))
1105 safe_allocate(bc%pml%conv_plus_old(1:bc%pml%points_number, 1:3, 1:3))
1106 safe_allocate(bc%pml%conv_minus_old(1:bc%pml%points_number, 1:3, 1:3))
1107 safe_allocate(bc%pml%aux_ep(1:bc%pml%points_number, 1:3, 1:3))
1108 safe_allocate(bc%pml%aux_mu(1:bc%pml%points_number, 1:3, 1:3))
1110 bc%pml%kappa =
m_one
1117 bc%pml%conv_plus =
m_z0
1119 bc%pml%conv_plus_old =
m_z0
1120 bc%pml%conv_minus_old =
m_z0
1128 int(bc%pml%points_number, int64)*space%dim*space%dim)
1130 int(bc%pml%points_number, int64)*space%dim*space%dim)
1132 int(bc%pml%points_number, int64)*space%dim*space%dim)
1134 call accel_write_buffer(bc%pml%buff_a, int(bc%pml%points_number, int64)*space%dim, bc%pml%a)
1135 call accel_write_buffer(bc%pml%buff_b, int(bc%pml%points_number, int64)*space%dim, bc%pml%b)
1136 call accel_write_buffer(bc%pml%buff_c, int(bc%pml%points_number, int64)*space%dim, bc%pml%c)
1137 call accel_write_buffer(bc%pml%buff_conv_plus, int(bc%pml%points_number, int64)*space%dim*space%dim, bc%pml%conv_plus)
1138 call accel_write_buffer(bc%pml%buff_conv_minus, int(bc%pml%points_number, int64)*space%dim*space%dim, bc%pml%conv_minus)
1139 call accel_write_buffer(bc%pml%buff_conv_plus_old, int(bc%pml%points_number, int64)*space%dim*space%dim, bc%pml%conv_plus_old)
1151 class(
space_t),
intent(in) :: space
1152 type(
grid_t),
intent(in) :: gr
1153 real(real64),
intent(in) :: c_factor
1154 real(real64),
optional,
intent(in) :: dt
1156 integer :: ip, ip_in, idim
1157 real(real64) :: width(3)
1158 real(real64) :: ddv(3), ss_e, ss_m, ss_max, aa_e, aa_m, bb_e, bb_m, gg, hh, kk, ll_e, ll_m
1159 real(real64),
allocatable :: tmp(:), tmp_grad(:,:)
1163 safe_allocate(tmp(gr%np_part))
1164 safe_allocate(tmp_grad(gr%np, 1:space%dim))
1170 width(1:3) = (/ bc%pml%width, bc%pml%width, bc%pml%width /)
1173 do ip_in = 1, bc%pml%points_number
1174 ip = bc%pml%points_map(ip_in)
1175 ddv(1:3) = abs(gr%x(ip, 1:3)) - bc%bc_bounds(1, 1:3)
1176 do idim = 1, space%dim
1177 if (ddv(idim) >=
m_zero)
then
1178 gg = (ddv(idim)/bc%pml%width)**bc%pml%power
1179 hh = (
m_one-ddv(idim)/bc%pml%width)**bc%pml%power
1181 ss_max = -(bc%pml%power +
m_one)*
p_c*c_factor*
p_ep*
log(bc%pml%refl_error)/(
m_two * bc%pml%width)
1192 bc%pml%sigma_e(ip_in, idim) = ss_e
1193 bc%pml%sigma_m(ip_in, idim) = ss_m
1194 bc%pml%a(ip_in, idim) = aa_e
1195 bc%pml%b(ip_in, idim) = bb_e
1196 bc%pml%kappa(ip_in, idim) = kk
1197 bc%pml%mask(ip_in) = bc%pml%mask(ip_in) * (
m_one -
sin(ddv(idim)*
m_pi/(
m_two*(width(idim))))**2)
1199 bc%pml%kappa(ip_in, idim) =
m_one
1200 bc%pml%sigma_e(ip_in, idim) =
m_zero
1201 bc%pml%sigma_m(ip_in, idim) =
m_zero
1202 bc%pml%a(ip_in, idim) =
m_zero
1203 bc%pml%b(ip_in, idim) =
m_zero
1204 bc%pml%mask(ip_in) =
m_one
1210 do idim = 1, space%dim
1212 do ip_in = 1, bc%pml%points_number
1213 ip = bc%pml%points_map(ip_in)
1214 tmp(ip) =
p_ep / bc%pml%kappa(ip_in, idim)
1217 do ip_in = 1, bc%pml%points_number
1218 ip = bc%pml%points_map(ip_in)
1219 bc%pml%aux_ep(ip_in, :, idim) = tmp_grad(ip, :)/(
m_four*
p_ep*bc%pml%kappa(ip_in, idim))
1224 do idim = 1, space%dim
1226 tmp =
p_mu/c_factor**2
1227 do ip_in = 1, bc%pml%points_number
1228 ip = bc%pml%points_map(ip_in)
1229 tmp(ip) =
p_mu/c_factor**2 / bc%pml%kappa(ip_in, idim)
1232 do ip_in = 1, bc%pml%points_number
1233 ip = bc%pml%points_map(ip_in)
1234 bc%pml%aux_mu(ip_in, :, idim) = tmp_grad(ip, :)/(
m_four*
p_mu/c_factor**2 * bc%pml%kappa(ip_in, idim))
1239 do idim = 1, space%dim
1240 do ip_in = 1, bc%pml%points_number
1241 bc%pml%c(ip_in, idim) =
p_c*c_factor/bc%pml%kappa(ip_in, idim)
1244 safe_deallocate_a(tmp)
1245 safe_deallocate_a(tmp_grad)
1249 call accel_write_buffer(bc%pml%buff_a, int(bc%pml%points_number, int64)*space%dim, bc%pml%a)
1250 call accel_write_buffer(bc%pml%buff_b, int(bc%pml%points_number, int64)*space%dim, bc%pml%b)
1251 call accel_write_buffer(bc%pml%buff_c, int(bc%pml%points_number, int64)*space%dim, bc%pml%c)
1252 call accel_write_buffer(bc%pml%buff_conv_plus, int(bc%pml%points_number, int64)*space%dim*space%dim, bc%pml%conv_plus)
1253 call accel_write_buffer(bc%pml%buff_conv_minus, int(bc%pml%points_number, int64)*space%dim*space%dim, bc%pml%conv_minus)
1256 bc%pml%parameters_initialized = .
true.
1265 class(
space_t),
intent(in) :: space
1266 type(
grid_t),
intent(in) :: gr
1267 real(real64),
intent(in) :: c_factor
1268 real(real64),
intent(in) :: dt
1270 integer :: ip_in, ip, idir
1271 real(real64) :: ddv(1:space%dim), kappa, sigma, alpha
1275 do ip_in = 1, bc%pml%points_number
1276 ip = bc%pml%points_map(ip_in)
1277 ddv(1:3) = abs(gr%x(ip, 1:3)) - bc%bc_bounds(1, 1:3)
1278 do idir = 1, space%dim
1279 if (ddv(idir) >=
m_zero)
then
1280 sigma = (ddv(idir)/bc%pml%width)**bc%pml%power * &
1286 bc%pml%b(ip_in, idir) =
exp(-(alpha + sigma/kappa)/
p_ep*dt)
1288 bc%pml%c(ip_in, idir) =
m_zero
1290 bc%pml%c(ip_in, idir) =
m_one/(kappa + kappa**2*alpha/sigma) * &
1291 (bc%pml%b(ip_in, idir) - 1)
1294 bc%pml%b(ip_in, idir) =
m_zero
1295 bc%pml%c(ip_in, idir) =
m_zero
1301 bc%pml%points_number, bc%pml%points_map)
1303 int(bc%pml%points_number, int64)*space%dim, bc%pml%b)
1305 int(bc%pml%points_number, int64)*space%dim, bc%pml%c)
1313 class(
mesh_t),
intent(in) :: mesh
1314 real(real64),
intent(in) :: bounds(:,:)
1316 integer :: ip, ip_in, idim, ip_in_max
1317 real(real64) :: ddv(3), tmp(3), width(3)
1318 real(real64),
allocatable :: mask(:)
1324 ip_in_max = maxval(bc%mask_points_number(:))
1326 safe_allocate(mask(1:mesh%np))
1330 width(1:3) = bounds(2, 1:3) - bounds(1, 1:3)
1336 ddv(1:3) = abs(mesh%x(ip, 1:3)) - bounds(1, 1:3)
1337 do idim = 1, mesh%box%dim
1338 if (ddv(idim) >=
m_zero)
then
1339 if (ddv(idim) <= width(idim))
then
1345 mask(ip) = mask(ip) * tmp(idim)
1349 do idim = 1, mesh%box%dim
1350 do ip_in = 1, bc%mask_points_number(idim)
1351 ip = bc%mask_points_map(ip_in, idim)
1352 bc%mask(ip_in,idim) = mask(ip)
1356 safe_deallocate_a(mask)
1364 subroutine bc_mxll_generate_medium(bc, space, gr, bounds, ep_factor, mu_factor, sigma_e_factor, sigma_m_factor)
1366 class(
space_t),
intent(in) :: space
1367 type(
grid_t),
intent(in) :: gr
1368 real(real64),
intent(in) :: bounds(:,:)
1369 real(real64),
intent(in) :: ep_factor
1370 real(real64),
intent(in) :: mu_factor
1371 real(real64),
intent(in) :: sigma_e_factor
1372 real(real64),
intent(in) :: sigma_m_factor
1374 integer :: ip, ipp, ip_in, ip_in_max, ip_bd, idim, point_info
1375 real(real64) :: dd, dd_min, dd_max, xx(3), xxp(3)
1376 real(real64),
allocatable :: tmp(:), tmp_grad(:,:)
1382 ip_in_max = max(bc%medium(1)%points_number, bc%medium(2)%points_number, bc%medium(3)%points_number)
1383 dd_max = max(2*gr%spacing(1), 2*gr%spacing(2), 2*gr%spacing(3))
1387 safe_allocate(tmp(gr%np_part))
1388 safe_allocate(tmp_grad(1:gr%np_part,1:space%dim))
1389 bc%medium(idim)%aux_ep =
m_zero
1390 bc%medium(idim)%aux_mu =
m_zero
1391 bc%medium(idim)%c =
p_c
1394 do ip = 1, gr%np_part
1396 if ((point_info /= 0) .and. (abs(gr%x(ip, idim)) <= bounds(1, idim)))
then
1399 do ip_bd = 1, bc%medium(idim)%bdry_number
1400 ipp = bc%medium(idim)%bdry_map(ip_bd)
1401 xxp(:) = gr%x(ipp, :)
1402 dd = norm2(xx(1:3) - xxp(1:3))
1403 if (dd < dd_min) dd_min = dd
1409 do ip_in = 1, bc%medium(idim)%points_number
1410 ip = bc%medium(idim)%points_map(ip_in)
1411 bc%medium(idim)%aux_ep(ip_in, :) = &
1418 do ip = 1, gr%np_part
1420 if ((point_info == 1) .and. (abs(gr%x(ip, idim)) <= bounds(1, idim)))
then
1423 do ip_bd = 1, bc%medium(idim)%bdry_number
1424 ipp = bc%medium(idim)%bdry_map(ip_bd)
1425 xxp(:) = gr%x(ipp,:)
1426 dd = norm2(xx(1:3) - xxp(1:3))
1427 if (dd < dd_min) dd_min = dd
1433 do ip_in = 1, bc%medium(idim)%points_number
1434 ip = bc%medium(idim)%points_map(ip_in)
1435 bc%medium(idim)%aux_mu(ip_in, :) = &
1441 do ip_in = 1, bc%medium(idim)%points_number
1442 ip = bc%medium(idim)%points_map(ip_in)
1445 do ip_bd = 1, bc%medium(idim)%bdry_number
1446 ipp = bc%medium(idim)%bdry_map(ip_bd)
1447 xxp(:) = gr%x(ipp, :)
1448 dd = norm2(xx(1:3) - xxp(1:3))
1449 if (dd < dd_min) dd_min = dd
1451 bc%medium(idim)%ep(ip_in) =
p_ep * (
m_one + ep_factor &
1453 bc%medium(idim)%mu(ip_in) =
p_mu * (
m_one + mu_factor &
1455 bc%medium(idim)%sigma_e(ip_in) = (
m_one + sigma_e_factor &
1457 bc%medium(idim)%sigma_m(ip_in) = (
m_one + sigma_m_factor &
1459 bc%medium(idim)%c(ip_in) =
m_one /
sqrt(bc%medium(idim)%ep(ip_in) * bc%medium(idim)%mu(ip_in))
1463 safe_deallocate_a(tmp)
1464 safe_deallocate_a(tmp_grad)
1473 class(
mesh_t),
intent(in) :: mesh
1475 real(real64),
intent(in) :: bounds(:,:)
1483 st%surface(1, 1)%spacing =
m_half*(mesh%spacing(2) + mesh%spacing(3))
1484 st%surface(1, 1)%origin(:) =
m_zero
1485 st%surface(1, 1)%origin(1) = -bounds(1, 1)
1486 st%surface(1, 1)%n(:) =
m_zero
1487 st%surface(1, 1)%n(1) = -
m_one
1488 st%surface(1, 1)%u(:) =
m_zero
1489 st%surface(1, 1)%u(2) = -
m_one
1490 st%surface(1, 1)%v(:) =
m_zero
1491 st%surface(1, 1)%v(3) =
m_one
1492 st%surface(1, 1)%nu = -int(bounds(1, 2)/mesh%spacing(2))
1493 st%surface(1, 1)%mu = int(bounds(1, 2)/mesh%spacing(2))
1494 st%surface(1, 1)%nv = -int(bounds(1, 3)/mesh%spacing(3))
1495 st%surface(1, 1)%mv = int(bounds(1, 3)/mesh%spacing(3))
1498 st%surface(2, 1)%spacing =
m_half*(mesh%spacing(2) + mesh%spacing(3))
1499 st%surface(2, 1)%origin(:) =
m_zero
1500 st%surface(2, 1)%origin(1) = bounds(1, 1)
1501 st%surface(2, 1)%n(:) =
m_zero
1502 st%surface(2, 1)%n(1) =
m_one
1503 st%surface(2, 1)%u(:) =
m_zero
1504 st%surface(2, 1)%u(2) =
m_one
1505 st%surface(2, 1)%v(:) =
m_zero
1506 st%surface(2, 1)%v(3) =
m_one
1507 st%surface(2, 1)%nu = -int(bounds(1, 2)/mesh%spacing(2))
1508 st%surface(2, 1)%mu = int(bounds(1, 2)/mesh%spacing(2))
1509 st%surface(2, 1)%nv = -int(bounds(1, 3)/mesh%spacing(3))
1510 st%surface(2, 1)%mv = int(bounds(1, 3)/mesh%spacing(3))
1513 st%surface(1, 2)%spacing =
m_half*(mesh%spacing(1) + mesh%spacing(3))
1514 st%surface(1, 2)%origin(:) =
m_zero
1515 st%surface(1, 2)%origin(2) = -bounds(1, 2)
1516 st%surface(1, 2)%n(:) =
m_zero
1517 st%surface(1, 2)%n(2) = -
m_one
1518 st%surface(1, 2)%u(:) =
m_zero
1519 st%surface(1, 2)%u(1) =
m_one
1520 st%surface(1, 2)%v(:) =
m_zero
1521 st%surface(1, 2)%v(3) =
m_one
1522 st%surface(1, 2)%nu = -int(bounds(1, 1)/mesh%spacing(1))
1523 st%surface(1, 2)%mu = int(bounds(1, 1)/mesh%spacing(1))
1524 st%surface(1, 2)%nv = -int(bounds(1, 3)/mesh%spacing(3))
1525 st%surface(1, 2)%mv = int(bounds(1, 3)/mesh%spacing(3))
1528 st%surface(2, 2)%spacing =
m_half*(mesh%spacing(1) + mesh%spacing(3))
1529 st%surface(2, 2)%origin(:) =
m_zero
1530 st%surface(2, 2)%origin(2) = bounds(1, 2)
1531 st%surface(2, 2)%n(:) =
m_zero
1532 st%surface(2, 2)%n(2) =
m_one
1533 st%surface(2, 2)%u(:) =
m_zero
1534 st%surface(2, 2)%u(1) =
m_one
1535 st%surface(2, 2)%v(:) =
m_zero
1536 st%surface(2, 2)%v(3) = -
m_one
1537 st%surface(2, 2)%nu = -int(bounds(1, 1)/mesh%spacing(1))
1538 st%surface(2, 2)%mu = int(bounds(1, 1)/mesh%spacing(1))
1539 st%surface(2, 2)%nv = -int(bounds(1, 3)/mesh%spacing(3))
1540 st%surface(2, 2)%mv = int(bounds(1, 3)/mesh%spacing(3))
1543 st%surface(1, 3)%spacing =
m_half*(mesh%spacing(1) + mesh%spacing(2))
1544 st%surface(1, 3)%origin(:) =
m_zero
1545 st%surface(1, 3)%origin(3) = -bounds(1, 3)
1546 st%surface(1, 3)%n(:) =
m_zero
1547 st%surface(1, 3)%n(3) = -
m_one
1548 st%surface(1, 3)%u(:) =
m_zero
1549 st%surface(1, 3)%u(1) =
m_one
1550 st%surface(1, 3)%v(:) =
m_zero
1551 st%surface(1, 3)%v(2) = -
m_one
1552 st%surface(1, 3)%nu = -int(bounds(1, 1)/mesh%spacing(1))
1553 st%surface(1, 3)%mu = int(bounds(1, 1)/mesh%spacing(1))
1554 st%surface(1, 3)%nv = -int(bounds(1, 2)/mesh%spacing(2))
1555 st%surface(1, 3)%mv = int(bounds(1, 2)/mesh%spacing(2))
1558 st%surface(2, 3)%spacing =
m_half*(mesh%spacing(1) + mesh%spacing(2))
1559 st%surface(2, 3)%origin(:) =
m_zero
1560 st%surface(2, 3)%origin(3) = bounds(1, 3)
1561 st%surface(2, 3)%n(:) =
m_zero
1562 st%surface(2, 3)%n(3) =
m_one
1563 st%surface(2, 3)%u(:) =
m_zero
1564 st%surface(2, 3)%u(1) =
m_one
1566 st%surface(2, 3)%v(2) =
m_one
1567 st%surface(2, 3)%nu = -int(bounds(1, 1)/mesh%spacing(1))
1568 st%surface(2, 3)%mu = int(bounds(1, 1)/mesh%spacing(1))
1569 st%surface(2, 3)%nv = -int(bounds(1, 2)/mesh%spacing(2))
1570 st%surface(2, 3)%mv = int(bounds(1, 2)/mesh%spacing(2))
1580 class(
mesh_t),
intent(in) :: mesh
1581 integer,
intent(in) :: ip
1582 real(real64),
intent(in) :: bounds(:,:)
1583 integer,
intent(out) :: point_info
1585 real(real64) :: rr, dd, xx(3), width(3)
1589 width(1:3) = bounds(2, 1:3) - bounds(1, 1:3)
1591 xx(1:mesh%box%dim) = mesh%x(ip, 1:mesh%box%dim)
1593 if (bc%ab_user_def)
then
1595 dd = bc%ab_ufn(ip) - bounds(1, 1)
1597 if (bc%ab_ufn(ip) < bounds(2, 1))
then
1604 select type (box => mesh%box)
1606 rr = norm2(xx - box%center)
1607 dd = rr - bounds(1, 1)
1609 if (dd < width(1))
then
1616 if (all(abs(xx(1:3) - box%center) <= bounds(2, 1:3)))
then
1617 if (any(abs(xx(1:3) - box%center) > bounds(1, 1:3)))
then
1636 class(
mesh_t),
intent(in) :: mesh
1637 integer,
intent(in) :: ip
1638 real(real64),
intent(in) :: bounds(:,:)
1639 integer,
intent(out) :: boundary_info
1641 real(real64) :: xx(3)
1646 xx(1:mesh%box%dim) = mesh%x(ip, 1:mesh%box%dim)
1647 if (
is_close(abs(xx(1)), bounds(1, 1)) .and. (all(abs(xx(2:3)) <= bounds(1, 2:3))) .or. &
1648 is_close(abs(xx(2)), bounds(1, 2)) .and. (all(abs(xx(1:3:2)) <= bounds(1, 1:3:2))) .or. &
1649 is_close(abs(xx(3)), bounds(1, 3)) .and. (all(abs(xx(1:2)) <= bounds(1, 1:2))))
then
1659 class(
mesh_t),
intent(in) :: mesh
1661 real(real64),
intent(in) :: bounds(:,:)
1663 integer :: ip, ip_in, ip_bd, point_info
1664 real(real64) :: xx(mesh%box%dim)
1675 if (all(abs(xx) <= bounds(2,1:mesh%box%dim)))
then
1676 if (any(abs(xx) > bounds(1,1:mesh%box%dim)))
then
1684 if (point_info == 0)
then
1690 st%inner_points_number = ip_in
1691 safe_allocate(st%inner_points_map(1:ip_in))
1692 safe_allocate(st%inner_points_mask(1:mesh%np))
1693 st%boundary_points_number = ip_bd
1694 safe_allocate(st%boundary_points_map(1:ip_bd))
1695 safe_allocate(st%boundary_points_mask(1:mesh%np))
1696 st%inner_points_mask = .false.
1697 st%boundary_points_mask = .false.
1704 if (all(abs(xx) <= bounds(2,1:mesh%box%dim)))
then
1705 if (any(abs(xx) > bounds(1,1:mesh%box%dim)))
then
1713 if (point_info == 0)
then
1715 st%inner_points_map(ip_in) = ip
1716 st%inner_points_mask(ip) = .
true.
1719 st%boundary_points_map(ip_bd) = ip
1720 st%boundary_points_mask(ip) = .
true.
1726 call accel_write_buffer(st%buff_inner_points_map, st%inner_points_number, st%inner_points_map)
1738 class(
mesh_t),
intent(in) :: mesh
1740 real(real64),
intent(in) :: bounds(:,:)
1742 integer :: ix, ix_max, iix, iy, iy_max, iiy, iz, iz_max, iiz, idx1, idx2, nn_max
1743 integer(int64) :: ip_global
1744 integer,
allocatable :: nn(:,:,:,:)
1745 real(real64) :: rr(3), delta(3), vec(2), min_1(3), max_1(3), min_2(3), max_2(3)
1751 st%surface_grid_rows_number(1) = 3
1752 ix_max = st%surface_grid_rows_number(1)
1753 st%surface_grid_rows_number(2) = 3
1754 iy_max = st%surface_grid_rows_number(2)
1755 st%surface_grid_rows_number(3) = 3
1756 iz_max = st%surface_grid_rows_number(3)
1758 delta(1) =
m_two * abs(bounds(1,1)) / real(ix_max, real64)
1759 delta(2) =
m_two * abs(bounds(1,2)) / real(iy_max, real64)
1760 delta(3) =
m_two * abs(bounds(1,3)) / real(iz_max, real64)
1762 st%surface_grid_element(1) = delta(2) * delta(3)
1763 st%surface_grid_element(2) = delta(1) * delta(3)
1764 st%surface_grid_element(3) = delta(1) * delta(2)
1766 safe_allocate(nn(1:2, 1:3, 1:3, 1:3))
1768 st%surface_grid_center(1, 1, :, :) = -int(bounds(1,1))
1771 rr(2) = -bounds(1,2) + delta(2)/
m_two + (iy-1) * delta(2)
1772 rr(3) = -bounds(1,3) + delta(3)/
m_two + (iz-1) * delta(3)
1773 st%surface_grid_center(1, 2, iy, iz) = int(rr(2))
1774 st%surface_grid_center(1, 3, iy, iz) = int(rr(3))
1777 st%surface_grid_center(2, 1, :, :) = int(bounds(1,1))
1780 rr(2) = -bounds(1,2) + delta(2)/
m_two + (iy-1) * delta(2)
1781 rr(3) = -bounds(1,3) + delta(3)/
m_two + (iz-1) * delta(3)
1782 st%surface_grid_center(2, 2, iy, iz) = int(rr(2))
1783 st%surface_grid_center(2, 3, iy, iz) = int(rr(3))
1787 st%surface_grid_center(1, 2, :, :) = -int(bounds(1,2))
1790 rr(1) = -bounds(1,1) + delta(1)/
m_two + (ix-1) * delta(1)
1791 rr(3) = -bounds(1,3) + delta(3)/
m_two + (iz-1) * delta(3)
1792 st%surface_grid_center(1, 1, ix, iz) = int(rr(1))
1793 st%surface_grid_center(1, 3, ix, iz) = int(rr(3))
1796 st%surface_grid_center(2, 2, :, :) = int(bounds(1,2))
1799 rr(1) = -bounds(1,2) + delta(1)/
m_two + (ix-1) * delta(1)
1800 rr(3) = -bounds(1,3) + delta(3)/
m_two + (iz-1) * delta(3)
1801 st%surface_grid_center(2, 1, ix, iz) = int(rr(1))
1802 st%surface_grid_center(2, 3, ix, iz) = int(rr(3))
1806 st%surface_grid_center(1, 3, :, :) = -int(bounds(1,3))
1809 rr(1) = -bounds(1,1) + delta(1)/
m_two + (ix-1) * delta(1)
1810 rr(2) = -bounds(1,2) + delta(2)/
m_two + (iy-1) * delta(2)
1811 st%surface_grid_center(1, 1, ix, iy) = int(rr(1))
1812 st%surface_grid_center(1, 2, ix, iy) = int(rr(2))
1815 st%surface_grid_center(2, 3, :, :) = int(bounds(1,3))
1818 rr(1) = -bounds(1,2) + delta(1)/
m_two + (ix-1) * delta(1)
1819 rr(2) = -bounds(1,2) + delta(2)/
m_two + (iy-1) * delta(2)
1820 st%surface_grid_center(2, 1, ix, iy) = int(rr(1))
1821 st%surface_grid_center(2, 2, ix, iy) = int(rr(2))
1825 st%surface_grid_points_number(:,:,:) = 0
1831 min_1(iy) = -bounds(1,2) + (iy-1) * delta(2)
1832 max_1(iy) = -bounds(1,2) + iy * delta(2)
1833 min_2(iz) = -bounds(1,3) + (iz-1) * delta(3)
1834 max_2(iz) = -bounds(1,3) + iz * delta(3)
1837 do iiy = mesh%idx%nr(1,2), mesh%idx%nr(2,2)
1838 do iiz = mesh%idx%nr(1,3), mesh%idx%nr(2,3)
1839 vec(1) = iiy * mesh%spacing(2)
1840 vec(2) = iiz * mesh%spacing(3)
1842 if (idx1 /= 0 .and. idx2 /= 0)
then
1843 st%surface_grid_points_number(1, idx1, idx2) = st%surface_grid_points_number(1, idx1, idx2) + 1
1844 if (nn_max < st%surface_grid_points_number(1, idx1, idx2))
then
1845 nn_max = st%surface_grid_points_number(1, idx1, idx2)
1853 min_1(ix) = -bounds(1,1) + (ix-1) * delta(1)
1854 max_1(ix) = -bounds(1,1) + ix * delta(1)
1855 min_2(iz) = -bounds(1,3) + (iz-1) * delta(3)
1856 max_2(iz) = -bounds(1,3) + iz * delta(3)
1859 do iix = mesh%idx%nr(1, 1), mesh%idx%nr(2, 1)
1860 do iiz = mesh%idx%nr(1, 3), mesh%idx%nr(2, 3)
1861 vec(1) = iix * mesh%spacing(1)
1862 vec(2) = iiz * mesh%spacing(3)
1864 if (idx1 /= 0 .and. idx2 /= 0)
then
1865 st%surface_grid_points_number(2,idx1,idx2) = st%surface_grid_points_number(2,idx1,idx2)+1
1866 if (nn_max < st%surface_grid_points_number(2, idx1, idx2))
then
1867 nn_max = st%surface_grid_points_number(2, idx1, idx2)
1875 min_1(ix) = -bounds(1,1) + (ix-1) * delta(1)
1876 max_1(ix) = -bounds(1,1) + ix * delta(1)
1877 min_2(iy) = -bounds(1,2) + (iy-1) * delta(2)
1878 max_2(iy) = -bounds(1,2) + iy * delta(2)
1881 do iix = mesh%idx%nr(1,1), mesh%idx%nr(2,1)
1882 do iiy = mesh%idx%nr(1,2), mesh%idx%nr(2,2)
1883 vec(1) = iix * mesh%spacing(1)
1884 vec(2) = iiy * mesh%spacing(2)
1886 if (idx1 /= 0 .and. idx2 /= 0)
then
1887 st%surface_grid_points_number(3, idx1, idx2) = st%surface_grid_points_number(3, idx1, idx2) + 1
1888 if (nn_max < st%surface_grid_points_number(3, idx1, idx2))
then
1889 nn_max = st%surface_grid_points_number(3, idx1, idx2)
1896 safe_allocate(st%surface_grid_points_map(1:2, 1:st%dim, 1:ix_max, 1:iy_max, 1:nn_max))
1902 min_1(iy) = -bounds(1,2) + (iy-1) * delta(2)
1903 max_1(iy) = -bounds(1,2) + iy * delta(2)
1904 min_2(iz) = -bounds(1,3) + (iz-1) * delta(3)
1905 max_2(iz) = -bounds(1,3) + iz * delta(3)
1908 do iiy = mesh%idx%nr(1,2), mesh%idx%nr(2,2)
1909 do iiz = mesh%idx%nr(1,3), mesh%idx%nr(2,3)
1910 vec(1) = iiy * mesh%spacing(2)
1911 vec(2) = iiz * mesh%spacing(3)
1913 if (idx1 /= 0 .and. idx2 /= 0)
then
1914 nn(1, 1, idx1, idx2) = nn(1, 1, idx1, idx2) + 1
1915 rr(1) = -bounds(1, 1)
1916 rr(2) = iiy * mesh%spacing(2)
1917 rr(3) = iiz * mesh%spacing(3)
1918 iix = int(-bounds(1,1)/mesh%spacing(1))
1920 st%surface_grid_points_map(1, 1, idx1, idx2, nn(1, 1, idx1, idx2)) = ip_global
1921 nn(2, 1, idx1, idx2) = nn(2, 1, idx1, idx2) + 1
1923 rr(2) = iiy * mesh%spacing(2)
1924 rr(3) = iiz * mesh%spacing(3)
1925 iix = int(bounds(1,1)/mesh%spacing(1))
1927 st%surface_grid_points_map(2, 1, idx1, idx2, nn(2, 1, idx1, idx2)) = ip_global
1934 min_1(ix) = -bounds(1,1) + (ix-1) * delta(1)
1935 max_1(ix) = -bounds(1,1) + ix * delta(1)
1936 min_2(iz) = -bounds(1,3) + (iz-1) * delta(3)
1937 max_2(iz) = -bounds(1,3) + iz * delta(3)
1940 do iix = mesh%idx%nr(1,1), mesh%idx%nr(2,1)
1941 do iiz = mesh%idx%nr(1,3), mesh%idx%nr(2,3)
1942 vec(1) = iix * mesh%spacing(1)
1943 vec(2) = iiz * mesh%spacing(3)
1945 if (idx1 /= 0 .and. idx2 /= 0)
then
1946 nn(1, 2, idx1, idx2) = nn(1, 2, idx1, idx2) + 1
1947 rr(1) = iix * mesh%spacing(1)
1948 rr(2) = -bounds(1, 2)
1949 rr(3) = iiz * mesh%spacing(3)
1950 iiy = int(-bounds(1,2)/mesh%spacing(2))
1952 st%surface_grid_points_map(1, 2, idx1, idx2, nn(1, 2, idx1, idx2)) = ip_global
1953 nn(2, 2, idx1, idx2) = nn(2, 2, idx1, idx2) + 1
1954 rr(1) = iix * mesh%spacing(1)
1956 rr(3) = iiz * mesh%spacing(3)
1957 iiy = int(bounds(1,2)/mesh%spacing(2))
1959 st%surface_grid_points_map(2, 2, idx1, idx2, nn(2, 2, idx1, idx2)) = ip_global
1966 min_1(ix) = -bounds(1,1) + (ix-1) * delta(1)
1967 max_1(ix) = -bounds(1,1) + ix * delta(1)
1968 min_2(iy) = -bounds(1,2) + (iy-1) * delta(2)
1969 max_2(iy) = -bounds(1,2) + iy * delta(2)
1972 do iix = mesh%idx%nr(1,1), mesh%idx%nr(2,1)
1973 do iiy = mesh%idx%nr(1,2), mesh%idx%nr(2,2)
1974 vec(1) = iix * mesh%spacing(1)
1975 vec(2) = iiy * mesh%spacing(2)
1977 if (idx1 /= 0 .and. idx2 /= 0)
then
1978 nn(1, 3, idx1, idx2) = nn(1, 3, idx1, idx2) + 1
1979 rr(1) = iix * mesh%spacing(1)
1980 rr(2) = iiy * mesh%spacing(2)
1981 rr(3) = -bounds(1,3)
1982 iiz = int(-bounds(1,3)/mesh%spacing(3))
1984 st%surface_grid_points_map(1, 3, idx1, idx2, nn(1, 3, idx1, idx2)) = ip_global
1985 nn(2, 3, idx1, idx2) = nn(2, 3, idx1, idx2) + 1
1986 rr(1) = iix * mesh%spacing(1)
1987 rr(2) = iiy * mesh%spacing(2)
1989 iiz = int(bounds(1,3)/mesh%spacing(3))
1991 st%surface_grid_points_map(2, 3, idx1, idx2, nn(2, 3, idx1, idx2)) = ip_global
1996 safe_deallocate_a(nn)
2004 real(real64),
intent(in) :: vec(:)
2005 real(real64),
intent(in) :: min_1(:)
2006 real(real64),
intent(in) :: max_1(:)
2007 real(real64),
intent(in) :: min_2(:)
2008 real(real64),
intent(in) :: max_2(:)
2009 integer,
intent(out) :: index_1
2010 integer,
intent(out) :: index_2
2012 if (vec(1) >= min_1(1) .and. vec(1) <= max_1(1) .and. vec(2) >= min_2(1) .and. vec(2) <= max_2(1))
then
2015 else if (vec(1) >= min_1(2) .and. vec(1) <= max_1(2) .and. vec(2) >= min_2(1) .and. vec(2) <= max_2(1))
then
2018 else if (vec(1) >= min_1(3) .and. vec(1) <= max_1(3) .and. vec(2) >= min_2(1) .and. vec(2) <= max_2(1))
then
2021 else if (vec(1) >= min_1(1) .and. vec(1) <= max_1(1) .and. vec(2) >= min_2(2) .and. vec(2) <= max_2(2))
then
2024 else if (vec(1) >= min_1(2) .and. vec(1) <= max_1(2) .and. vec(2) >= min_2(2) .and. vec(2) <= max_2(2))
then
2027 else if (vec(1) >= min_1(3) .and. vec(1) <= max_1(3) .and. vec(2) >= min_2(2) .and. vec(2) <= max_2(2))
then
2030 else if (vec(1) >= min_1(1) .and. vec(1) <= max_1(1) .and. vec(2) >= min_2(3) .and. vec(2) <= max_2(3))
then
2033 else if (vec(1) >= min_1(2) .and. vec(1) <= max_1(2) .and. vec(2) >= min_2(3) .and. vec(2) <= max_2(3))
then
2036 else if (vec(1) >= min_1(3) .and. vec(1) <= max_1(3) .and. vec(2) >= min_2(3) .and. vec(2) <= max_2(3))
then
double log(double __x) __attribute__((__nothrow__
double exp(double __x) __attribute__((__nothrow__
double sin(double __x) __attribute__((__nothrow__
subroutine get_surface_indices(vec, min_1, max_1, min_2, max_2, index_1, index_2)
subroutine get_medium_io_function(medium_func, bc, io_func, idim)
subroutine get_mask_io_function(mask_func, bc, io_func, idim)
subroutine write_files(filename, tmp)
subroutine get_pml_io_function(pml_func, bc, io_func)
integer, parameter, public accel_mem_read_write
subroutine, public accel_release_buffer(this)
pure logical function, public accel_is_enabled()
integer, parameter, public accel_mem_read_only
type(debug_t), save, public debug
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public dderivatives_grad(der, ff, op_ff, ghost_update, set_bc, to_cartesian)
apply the gradient to a mesh function
subroutine, public external_waves_end(external_waves)
subroutine, public external_waves_init(external_waves, namespace)
Here, plane wave is evaluated from analytical formulae on grid.
real(real64), parameter, public m_two
real(real64), parameter, public m_huge
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 p_mu
real(real64), parameter, public p_ep
complex(real64), parameter, public m_z0
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_five
This module implements the underlying real-space grid.
This module implements the index, used for the mesh points.
subroutine, public dio_function_output(how, dir, fname, namespace, space, mesh, ff, unit, ierr, pos, atoms, grp, root)
Top-level IO routine for functions defined on the mesh.
integer(int64) function, public io_function_fill_how(where)
Use this function to quickly plot functions for debugging purposes: call dio_function_output(io_funct...
subroutine, public single_medium_box_allocate(medium_box, n_points)
Allocation of medium_box components.
subroutine, public single_medium_box_end(medium_box)
Deallocation of medium_box components.
This module is intended to contain "only mathematical" functions and procedures.
integer, parameter, public mxll_ab_mask_zero
subroutine maxwell_zero_points_mapping(bc, mesh, bounds)
integer, parameter, public mxll_bc_mirror_pmc
integer, parameter mxll_plane_waves_positive_side
subroutine maxwell_boundary_point_info(mesh, ip, bounds, boundary_info)
integer, parameter, public mxll_bc_periodic
subroutine, public bc_mxll_init(bc, namespace, space, gr, st)
subroutine bc_mxll_generate_medium(bc, space, gr, bounds, ep_factor, mu_factor, sigma_e_factor, sigma_m_factor)
subroutine maxwell_surfaces_init(mesh, st, bounds)
subroutine maxwell_box_point_info(bc, mesh, ip, bounds, point_info)
integer, parameter, public mxll_bc_mirror_pec
integer, parameter, public mxll_ab_mask
subroutine bc_mxll_medium_init(gr, namespace, bounds, idim, ep_factor, mu_factor, sigma_e_factor, sigma_m_factor)
subroutine, public surface_grid_points_mapping(mesh, st, bounds)
integer, parameter, public mxll_bc_plane_waves
subroutine, public bc_mxll_initialize_pml_simple(bc, space, gr, c_factor, dt)
integer, parameter, public mxll_bc_medium
subroutine maxwell_constant_points_mapping(bc, mesh, bounds)
subroutine bc_mxll_generate_pml(bc, space)
subroutine bc_mxll_write_info(bc, mesh, namespace, space)
subroutine maxwell_plane_waves_points_mapping(bc, mesh, bounds, namespace)
subroutine, public bc_mxll_generate_pml_parameters(bc, space, gr, c_factor, dt)
subroutine bc_mxll_generate_mask(bc, mesh, bounds)
subroutine, public inner_and_outer_points_mapping(mesh, st, bounds)
integer, parameter, public mxll_bc_constant
subroutine bc_mxll_pml_init(bc, gr, namespace, ab_bounds, idim)
subroutine maxwell_medium_points_mapping(bc, mesh, bounds)
subroutine bc_mxll_ab_bounds_init(bc, gr, namespace, ab_bounds, idim)
subroutine, public bc_mxll_end(bc)
integer, parameter, public mxll_ab_cpml
subroutine maxwell_pml_points_mapping(bc, mesh, bounds)
subroutine maxwell_mask_points_mapping(bc, mesh, bounds)
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
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.
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
character(len=512), private msg
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, 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)
Some general things and nomenclature:
integer function, public parse_block(namespace, name, blk, check_varinfo_)
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.
type(type_t), public type_float
type(type_t), public type_cmplx
type(type_t), public type_integer
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
character(len=20) pure function, public units_abbrev(this)
This module defines the unit system, used for input and output.
type(unit_system_t), public units_inp
the units systems for reading and writing
type(unit_t), public unit_one
some special units required for particular quantities
Class implementing a parallelepiped box. Currently this is restricted to a rectangular cuboid (all th...
Class implementing a spherical box.
Description of the grid, containing information on derivatives, stencil, and symmetries.
Describes mesh distribution to nodes.