66 integer :: points_number
67 integer,
allocatable :: points_map(:)
68 integer,
allocatable :: points_map_inv(:)
70 real(real64) :: refl_error
71 real(real64),
allocatable :: kappa(:,:)
72 real(real64),
allocatable :: sigma_e(:,:)
73 real(real64),
allocatable :: sigma_m(:,:)
74 real(real64),
allocatable :: a(:,:)
75 real(real64),
allocatable :: b(:,:)
76 real(real64),
allocatable :: c(:,:)
77 real(real64),
allocatable :: mask(:)
78 complex(real64),
allocatable :: aux_ep(:,:,:)
79 complex(real64),
allocatable :: aux_mu(:,:,:)
80 complex(real64),
allocatable :: conv_plus(:,:,:)
81 complex(real64),
allocatable :: conv_minus(:,:,:)
82 complex(real64),
allocatable :: conv_plus_old(:,:,:)
83 complex(real64),
allocatable :: conv_minus_old(:,:,:)
84 logical :: parameters_initialized = .false.
86 type(accel_mem_t) :: buff_a, buff_b, buff_c, buff_conv_plus, buff_conv_minus, buff_map, buff_conv_plus_old
91 integer :: bc_ab_type(3)
92 real(real64) :: bc_bounds(2, 3)
93 logical :: ab_user_def
94 real(real64),
allocatable :: ab_ufn(:)
96 real(real64) :: ab_width
97 real(real64) :: mask_width
98 integer :: mask_points_number(3)
99 integer,
allocatable :: mask_points_map(:,:)
100 real(real64),
allocatable :: mask(:,:)
103 type(single_medium_box_t) :: medium(3)
105 integer :: constant_points_number
106 integer,
allocatable :: constant_points_map(:)
107 complex(real64),
allocatable :: constant_rs_state(:,:)
108 type(accel_mem_t) :: buff_constant_points_map
110 integer :: mirror_points_number(3)
111 integer,
allocatable :: mirror_points_map(:,:)
113 logical :: do_plane_waves = .false.
114 type(external_waves_t) :: plane_wave
115 logical :: plane_waves_dims(1:3) = .false.
117 real(real64) :: zero_width
118 integer :: zero_points_number(3)
119 integer,
allocatable :: zero_points_map(:,:)
120 real(real64),
allocatable :: zero(:,:)
123 integer,
public,
parameter :: &
131 integer,
parameter :: &
132 MXLL_PLANE_WAVES_NEGATIVE_SIDE = -1, &
135 integer,
public,
parameter :: &
136 MXLL_AB_NOT_ABSORBING = 0, &
145 type(bc_mxll_t),
intent(inout) :: bc
146 type(namespace_t),
intent(in) :: namespace
147 class(space_t),
intent(in) :: space
148 type(grid_t),
intent(in) :: gr
149 type(states_mxll_t),
intent(inout) :: st
151 integer :: idim, nlines, icol, ncols, ab_shape_dim
152 real(real64) :: bounds(2, space%dim), ab_bounds(2, space%dim)
154 character(len=1024) :: string
155 character(len=50) :: ab_type_str
156 character(len=1),
dimension(3),
parameter :: dims = [
"x",
"y",
"z"]
157 logical :: plane_waves_check, ab_mask_check, ab_pml_check, plane_waves_set
158 logical :: constant_check, zero_check
159 real(real64) :: ep_factor, mu_factor, sigma_e_factor, sigma_m_factor
165 plane_waves_set = .false.
166 bc%bc_type(:) = mxll_bc_zero
167 bc%medium(:)%points_number = 0
168 bc%medium(:)%bdry_number = 0
198 if (
parse_block(namespace,
'MaxwellBoundaryConditions', blk) == 0)
then
203 if (nlines /= 1)
then
217 select case (bc%bc_type(icol))
223 string =
'PEC Mirror'
225 string =
'PMC Mirror'
227 string =
'Plane waves'
229 string =
'Medium boundary'
231 write(
message(1),
'(a)')
'Unknown Maxwell boundary condition'
234 write(
message(1),
'(a,I1,a,a)')
'Maxwell boundary condition in direction ', icol,
': ', trim(string)
236 if (plane_waves_set .and. .not. (
parse_is_defined(namespace,
'MaxwellIncidentWaves')))
then
237 write(
message(1),
'(a)')
'Input: Maxwell boundary condition option is set to "plane_waves".'
238 write(
message(2),
'(a)')
'Input: User defined Maxwell plane waves have to be defined!'
243 plane_waves_check = .false.
244 ab_mask_check = .false.
245 ab_pml_check = .false.
246 constant_check = .false.
249 bc%ab_user_def = .false.
250 bc%bc_ab_type(:) = mxll_ab_not_absorbing
274 if (
parse_block(namespace,
'MaxwellAbsorbingBoundaries', blk) == 0)
then
277 if (nlines /= 1)
then
278 message(1) =
'MaxwellAbsorbingBounaries has to consist of one line!'
284 message(1) =
'MaxwellAbsorbingBoundaries has to consist of three columns!'
299 if (bc%bc_type(idim) == mxll_bc_zero) zero_check = .
true.
302 if (ab_mask_check .or. ab_pml_check)
then
305 write(
message(1),
'(a)')
"Please keep in mind that"
306 write(
message(2),
'(a)')
"with larger ABWidth, comes great responsibility."
307 write(
message(3),
'(a)')
"AbsorbingBoundaries occupy space in the simulation box,"
308 write(
message(4),
'(a)')
"hence choose your Lsize wisely."
313 bounds(1, :) = (gr%idx%nr(2, :) - gr%idx%enlarge(:))*gr%spacing(:)
314 bounds(2, :) = gr%idx%nr(2, :) * gr%spacing(:)
316 select case (bc%bc_type(idim))
320 bounds(1, idim) = (gr%idx%nr(2, idim) - gr%idx%enlarge(idim))*gr%spacing(idim)
321 bounds(2, idim) = (gr%idx%nr(2, idim)) * gr%spacing(idim)
325 bounds(1, idim) = (gr%idx%nr(2, idim) - 2*gr%idx%enlarge(idim))*gr%spacing(idim)
326 bounds(2, idim) = (gr%idx%nr(2, idim)) * gr%spacing(idim)
330 bounds(1, idim) = (gr%idx%nr(2, idim) - 2*gr%idx%enlarge(idim))*gr%spacing(idim)
331 bounds(2, idim) = (gr%idx%nr(2, idim)) * gr%spacing(idim)
332 plane_waves_check = .
true.
333 bc%do_plane_waves = .
true.
336 call bc_mxll_medium_init(gr, namespace, bounds, idim, ep_factor, mu_factor, sigma_e_factor, sigma_m_factor)
342 select type (box => gr%box)
345 if (space%is_periodic())
then
346 message(1) =
"Sphere box shape can only work for non-periodic systems"
350 if (.not. box%axes%orthogonal)
then
351 message(1) =
"Maxwell propagation does not work for non-orthogonal grids."
355 ab_shape_dim = space%dim
356 ab_bounds(1, idim) = bounds(1, idim)
357 ab_bounds(2, idim) = bounds(1, idim)
359 message(1) =
"Box shape for Maxwell propagation not supported yet"
363 if (bc%bc_ab_type(idim) /= mxll_ab_not_absorbing)
then
367 select case (bc%bc_ab_type(idim))
370 bc%zero_width = bc%ab_width
374 bc%mask_width = bc%ab_width
380 message(1) =
"Absorbing boundary type not implemented for Maxwell propagation"
386 select case (bc%bc_ab_type(idim))
388 bounds(1, idim) = ab_bounds(1, idim)
389 bounds(2, idim) = bounds(2, idim)
390 bc%bc_bounds(:, idim) = bounds(:, idim)
392 bc%bc_bounds(:, idim) = bounds(:, idim)
395 select type (box => gr%box)
397 select case (bc%bc_ab_type(idim))
410 string = trim(ab_type_str)//
" Absorbing Boundary"
411 write(string,
'(2a, f10.3,3a)') trim(string),
" in "//dims(idim)//
' direction spans from: ', &
414 write(
message(1),
'(a)') trim(string)
417 write(string,
'(a,f10.3,3a)') trim(string),&
421 write(
message(2),
'(a)') trim(string)
427 write(
message(1),
'(a,es10.3,3a)') &
430 write(
message(2),
'(a,es10.3,3a)') &
443 if (ab_mask_check)
then
448 if (ab_pml_check)
then
453 if (constant_check)
then
454 bounds(1, :) = gr%idx%nr(2, :) * gr%spacing(:)
455 bounds(2, :) = gr%idx%nr(2, :) * gr%spacing(:)
458 bounds(1, idim) = (gr%idx%nr(2, idim) - 2*gr%idx%enlarge(idim))*gr%spacing(idim)
459 bounds(2, idim) = (gr%idx%nr(2, idim)) * gr%spacing(idim)
466 if (plane_waves_check)
then
467 bounds(1, :) = gr%idx%nr(2, :) * gr%spacing(:)
468 bounds(2, :) = gr%idx%nr(2, :) * gr%spacing(:)
471 bounds(1, idim) = (gr%idx%nr(2, idim) - 2*gr%idx%enlarge(idim))*gr%spacing(idim)
472 bounds(2, idim) = (gr%idx%nr(2, idim)) * gr%spacing(idim)
481 bounds(1, :) = gr%idx%nr(2, :) * gr%spacing(:)
482 bounds(2, :) = gr%idx%nr(2, :) * gr%spacing(:)
484 if (bc%bc_type(idim) == mxll_bc_zero)
then
485 bounds(1, idim) = (gr%idx%nr(2, idim) - gr%idx%enlarge(idim))*gr%spacing(idim)
486 bounds(2, idim) = (gr%idx%nr(2, idim)) * gr%spacing(idim)
492 if (ab_mask_check)
then
496 if (ab_pml_check)
then
504 if (ab_mask_check .or. ab_pml_check)
then
521 safe_deallocate_a(bc%ab_ufn)
523 safe_deallocate_a(bc%mask_points_map)
524 safe_deallocate_a(bc%mask)
531 safe_deallocate_a(bc%constant_points_map)
532 safe_deallocate_a(bc%constant_rs_state)
537 safe_deallocate_a(bc%mirror_points_map)
541 safe_deallocate_a(bc%zero_points_map)
542 safe_deallocate_a(bc%zero)
549 type(
pml_t),
intent(inout) :: pml
553 safe_deallocate_a(pml%points_map)
554 safe_deallocate_a(pml%points_map_inv)
555 safe_deallocate_a(pml%kappa)
556 safe_deallocate_a(pml%sigma_e)
557 safe_deallocate_a(pml%sigma_m)
558 safe_deallocate_a(pml%a)
559 safe_deallocate_a(pml%b)
560 safe_deallocate_a(pml%c)
561 safe_deallocate_a(pml%mask)
562 safe_deallocate_a(pml%aux_ep)
563 safe_deallocate_a(pml%aux_mu)
564 safe_deallocate_a(pml%conv_plus)
565 safe_deallocate_a(pml%conv_minus)
566 safe_deallocate_a(pml%conv_plus_old)
567 safe_deallocate_a(pml%conv_minus_old)
585 subroutine bc_mxll_medium_init(gr, namespace, bounds, idim, ep_factor, mu_factor, sigma_e_factor, sigma_m_factor)
586 type(
grid_t),
intent(in) :: gr
587 type(namespace_t),
intent(in) :: namespace
588 real(real64),
intent(inout) :: bounds(:,:)
589 integer,
intent(in) :: idim
590 real(real64),
intent(out) :: ep_factor
591 real(real64),
intent(out) :: mu_factor
592 real(real64),
intent(out) :: sigma_e_factor
593 real(real64),
intent(out) :: sigma_m_factor
595 real(real64) :: width
609 bounds(1,idim) = ( gr%idx%nr(2, idim) - gr%idx%enlarge(idim) ) * gr%spacing(idim)
610 bounds(1,idim) = bounds(1,idim) - width
611 bounds(2,idim) = ( gr%idx%nr(2, idim) ) * gr%spacing(idim)
657 type(
grid_t),
intent(in) :: gr
658 type(namespace_t),
intent(in) :: namespace
659 real(real64),
intent(inout) :: ab_bounds(:,:)
660 integer,
intent(in) :: idim
662 real(real64) :: default_width
674 default_width =
m_two * gr%der%order * maxval(gr%spacing(1:3))
677 if (bc%ab_width < default_width)
then
678 bc%ab_width = default_width
679 write(
message(1),
'(a)')
'Absorbing boundary width has to be larger or equal than twice the derivatives order times spacing!'
680 write(
message(2),
'(a,es10.3)')
'Absorbing boundary width is set to: ', default_width
684 ab_bounds(1, idim) = ab_bounds(2, idim) - bc%ab_width
692 type(
grid_t),
intent(in) :: gr
693 type(namespace_t),
intent(in) :: namespace
694 real(real64),
intent(inout) :: ab_bounds(:,:)
695 integer,
intent(in) :: idim
700 bc%pml%width = bc%ab_width
719 call parse_variable(namespace,
'MaxwellABPMLReflectionError', 1.0e-16_real64, bc%pml%refl_error,
unit_one)
727 class(
mesh_t),
intent(in) :: mesh
728 type(namespace_t),
intent(in) :: namespace
729 class(
space_t),
intent(in) :: space
731 integer :: err, idim, idim2
732 real(real64),
allocatable :: tmp(:)
733 logical :: mask_check, pml_check, medium_check
734 character(1) :: dim_label(3)
742 medium_check = .false.
744 dim_label = (/
'x',
'y',
'z'/)
754 medium_check = .
true.
759 safe_allocate(tmp(1:mesh%np))
765 safe_deallocate_a(tmp)
766 else if (pml_check)
then
767 safe_allocate(tmp(1:mesh%np))
772 call write_files(
"maxwell_sigma_e-"//dim_label(idim), tmp)
777 call write_files(
"maxwell_sigma_m-"//dim_label(idim), tmp)
782 call write_files(
"maxwell_sigma_pml_a_e-"//dim_label(idim), tmp)
784 safe_deallocate_a(tmp)
787 if (medium_check)
then
788 safe_allocate(tmp(1:mesh%np))
793 call write_files(
"maxwell_ep"//dim_label(idim), tmp)
797 call write_files(
"maxwell_mu"//dim_label(idim), tmp)
801 call write_files(
"maxwell_c"//dim_label(idim), tmp)
806 call write_files(
"maxwell_aux_ep-"//dim_label(idim)//
"-"//dim_label(idim2), tmp)
811 call write_files(
"maxwell_aux_mu-"//dim_label(idim)//
"-"//dim_label(idim2), tmp)
815 safe_deallocate_a(tmp)
824 real(real64),
intent(in) :: pml_func(:)
826 real(real64),
intent(inout) :: io_func(:)
830 do ip_in = 1, bc%pml%points_number
831 ip = bc%pml%points_map(ip_in)
832 io_func(ip) = pml_func(ip_in)
838 real(real64),
intent(in) :: mask_func(:,:)
840 real(real64),
intent(inout) :: io_func(:)
841 integer,
intent(in) :: idim
845 do ip_in = 1, bc%mask_points_number(idim)
846 ip = bc%mask_points_map(ip_in, idim)
847 io_func(ip) = mask_func(ip_in, idim)
853 real(real64),
intent(in) :: medium_func(:)
855 real(real64),
intent(inout) :: io_func(:)
856 integer,
intent(in) :: idim
860 do ip_in = 1, bc%medium(idim)%points_number
861 ip = bc%medium(idim)%points_map(ip_in)
862 io_func(ip) = medium_func(ip_in)
868 character(len=*),
intent(in) :: filename
869 real(real64),
intent(in) :: tmp(:)
892 class(
mesh_t),
intent(in) :: mesh
893 real(real64),
intent(in) :: bounds(:,:)
895 integer :: ip, ip_in, ip_in_max, point_info, idim
907 if ((point_info == 1) .and. (abs(mesh%x_t(ip, idim)) >= bounds(1, idim)))
then
911 if (ip_in > ip_in_max) ip_in_max = ip_in
912 bc%mask_points_number(idim) = ip_in
915 safe_allocate(bc%mask(1:ip_in_max, 1:idim))
916 safe_allocate(bc%mask_points_map(1:ip_in_max, 1:idim))
924 if ((point_info == 1) .and. (abs(mesh%x_t(ip, idim)) >= bounds(1, idim)))
then
926 bc%mask_points_map(ip_in, idim) = ip
939 class(
mesh_t),
intent(in) :: mesh
940 real(real64),
intent(in) :: bounds(:,:)
942 integer :: ip, ip_in, point_info
952 if (point_info == 1)
then
956 bc%pml%points_number = ip_in
957 safe_allocate(bc%pml%points_map(1:ip_in))
958 safe_allocate(bc%pml%points_map_inv(1:mesh%np))
959 bc%pml%points_map_inv = 0
963 if (point_info == 1)
then
965 bc%pml%points_map(ip_in) = ip
966 bc%pml%points_map_inv(ip) = ip_in
978 class(
mesh_t),
intent(in) :: mesh
979 real(real64),
intent(in) :: bounds(:,:)
981 integer :: ip, ip_in, point_info
991 if (point_info == 1)
then
995 bc%constant_points_number = ip_in
996 safe_allocate(bc%constant_points_map(1:ip_in))
997 safe_allocate(bc%constant_rs_state(1:ip_in, 1:3))
1003 if (point_info == 1)
then
1005 bc%constant_points_map(ip_in) = ip
1011 call accel_write_buffer(bc%buff_constant_points_map, bc%constant_points_number, bc%constant_points_map)
1022 class(
mesh_t),
intent(in) :: mesh
1023 real(real64),
intent(in) :: bounds(:,:)
1025 integer :: ip, ip_in, point_info
1037 if (point_info == 1)
then
1041 bc%plane_wave%points_number = ip_in
1042 safe_allocate(bc%plane_wave%points_map(1:ip_in))
1048 if (point_info == 1)
then
1050 bc%plane_wave%points_map(ip_in) = ip
1056 call accel_write_buffer(bc%plane_wave%buff_map, bc%plane_wave%points_number, bc%plane_wave%points_map)
1067 class(
mesh_t),
intent(in) :: mesh
1068 real(real64),
intent(in) :: bounds(:,:)
1070 integer :: ip, ip_in, ip_in_max, point_info, idim
1078 if (bc%bc_type(idim) == mxll_bc_zero)
then
1083 if ((point_info == 1) .and. (abs(mesh%x(idim, ip)) >= bounds(1, idim)))
then
1087 if (ip_in > ip_in_max) ip_in_max = ip_in
1090 bc%zero_points_number = ip_in
1091 safe_allocate(bc%zero(1:ip_in_max,3))
1092 safe_allocate(bc%zero_points_map(1:ip_in_max, 1:3))
1095 if (bc%bc_type(idim) == mxll_bc_zero)
then
1100 if ((point_info == 1) .and. (abs(mesh%x_t(ip, idim)) >= bounds(1, idim)))
then
1102 bc%zero_points_map(ip_in, idim) = ip
1116 class(
mesh_t),
intent(in) :: mesh
1117 real(real64),
intent(in) :: bounds(:,:)
1119 integer :: ip, ip_in, ip_in_max, ip_bd, ip_bd_max, point_info, boundary_info, idim
1125 bc%medium(:)%points_number = 0
1126 bc%medium(:)%bdry_number = 0
1138 if ((point_info == 1) .and. (abs(mesh%x_t(ip, idim)) >= bounds(1, idim)))
then
1141 if ((boundary_info == 1) .and. (abs(mesh%x_t(ip, idim)) >= bounds(1, idim)))
then
1145 bc%medium(idim)%points_number = ip_in
1146 bc%medium(idim)%bdry_number = ip_bd
1147 ip_in_max = max(ip_in_max, ip_in)
1148 ip_bd_max = max(ip_bd_max, ip_bd)
1152 safe_allocate(bc%medium(idim)%points_map(1:ip_in_max))
1153 safe_allocate(bc%medium(idim)%bdry_map(1:ip_bd_max))
1163 if ((point_info == 1) .and. (abs(mesh%x_t(ip, idim)) >= bounds(1, idim)))
then
1165 bc%medium(idim)%points_map(ip_in) = ip
1167 if ((boundary_info == 1) .and. (abs(mesh%x_t(ip, idim)) >= bounds(1, idim)))
then
1169 bc%medium(idim)%bdry_map(ip_bd) = ip
1183 class(
space_t),
intent(in) :: space
1190 safe_allocate(bc%pml%kappa(1:bc%pml%points_number, 1:space%dim))
1191 safe_allocate(bc%pml%sigma_e(1:bc%pml%points_number, 1:space%dim))
1192 safe_allocate(bc%pml%sigma_m(1:bc%pml%points_number, 1:space%dim))
1193 safe_allocate(bc%pml%a(1:bc%pml%points_number, 1:space%dim))
1194 safe_allocate(bc%pml%b(1:bc%pml%points_number, 1:space%dim))
1195 safe_allocate(bc%pml%c(1:bc%pml%points_number, 1:3))
1196 safe_allocate(bc%pml%mask(1:bc%pml%points_number))
1197 safe_allocate(bc%pml%conv_plus(1:bc%pml%points_number, 1:3, 1:3))
1198 safe_allocate(bc%pml%conv_minus(1:bc%pml%points_number, 1:3, 1:3))
1199 safe_allocate(bc%pml%conv_plus_old(1:bc%pml%points_number, 1:3, 1:3))
1200 safe_allocate(bc%pml%conv_minus_old(1:bc%pml%points_number, 1:3, 1:3))
1201 safe_allocate(bc%pml%aux_ep(1:bc%pml%points_number, 1:3, 1:3))
1202 safe_allocate(bc%pml%aux_mu(1:bc%pml%points_number, 1:3, 1:3))
1204 bc%pml%kappa =
m_one
1211 bc%pml%conv_plus =
m_z0
1212 bc%pml%conv_minus =
m_z0
1213 bc%pml%conv_plus_old =
m_z0
1214 bc%pml%conv_minus_old =
m_z0
1222 int(bc%pml%points_number, int64)*space%dim*space%dim)
1224 int(bc%pml%points_number, int64)*space%dim*space%dim)
1226 int(bc%pml%points_number, int64)*space%dim*space%dim)
1231 call accel_write_buffer(bc%pml%buff_conv_plus, bc%pml%points_number, space%dim, space%dim, bc%pml%conv_plus)
1232 call accel_write_buffer(bc%pml%buff_conv_minus, bc%pml%points_number, space%dim, space%dim, bc%pml%conv_minus)
1233 call accel_write_buffer(bc%pml%buff_conv_plus_old, bc%pml%points_number, space%dim, space%dim, bc%pml%conv_plus_old)
1245 class(
space_t),
intent(in) :: space
1246 type(
grid_t),
intent(in) :: gr
1247 real(real64),
intent(in) :: c_factor
1248 real(real64),
optional,
intent(in) :: dt
1250 integer :: ip, ip_in, idim
1251 real(real64) :: width(3)
1252 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
1253 real(real64),
allocatable :: tmp(:), tmp_grad(:,:)
1257 safe_allocate(tmp(gr%np_part))
1258 safe_allocate(tmp_grad(gr%np, 1:space%dim))
1264 width(1:3) = (/ bc%pml%width, bc%pml%width, bc%pml%width /)
1267 do ip_in = 1, bc%pml%points_number
1268 ip = bc%pml%points_map(ip_in)
1269 ddv(1:3) = abs(gr%x(1:3, ip)) - bc%bc_bounds(1, 1:3)
1270 do idim = 1, space%dim
1271 if (ddv(idim) >=
m_zero)
then
1272 gg = (ddv(idim)/bc%pml%width)**bc%pml%power
1273 hh = (
m_one-ddv(idim)/bc%pml%width)**bc%pml%power
1275 ss_max = -(bc%pml%power +
m_one)*
p_c*c_factor*
p_ep*
log(bc%pml%refl_error)/(
m_two * bc%pml%width)
1286 bc%pml%sigma_e(ip_in, idim) = ss_e
1287 bc%pml%sigma_m(ip_in, idim) = ss_m
1288 bc%pml%a(ip_in, idim) = aa_e
1289 bc%pml%b(ip_in, idim) = bb_e
1290 bc%pml%kappa(ip_in, idim) = kk
1291 bc%pml%mask(ip_in) = bc%pml%mask(ip_in) * (
m_one -
sin(ddv(idim)*
m_pi/(
m_two*(width(idim))))**2)
1293 bc%pml%kappa(ip_in, idim) =
m_one
1294 bc%pml%sigma_e(ip_in, idim) =
m_zero
1295 bc%pml%sigma_m(ip_in, idim) =
m_zero
1296 bc%pml%a(ip_in, idim) =
m_zero
1297 bc%pml%b(ip_in, idim) =
m_zero
1298 bc%pml%mask(ip_in) =
m_one
1304 do idim = 1, space%dim
1306 do ip_in = 1, bc%pml%points_number
1307 ip = bc%pml%points_map(ip_in)
1308 tmp(ip) =
p_ep / bc%pml%kappa(ip_in, idim)
1311 do ip_in = 1, bc%pml%points_number
1312 ip = bc%pml%points_map(ip_in)
1313 bc%pml%aux_ep(ip_in, :, idim) = tmp_grad(ip, :)/(
m_four*
p_ep*bc%pml%kappa(ip_in, idim))
1318 do idim = 1, space%dim
1320 tmp =
p_mu/c_factor**2
1321 do ip_in = 1, bc%pml%points_number
1322 ip = bc%pml%points_map(ip_in)
1323 tmp(ip) =
p_mu/c_factor**2 / bc%pml%kappa(ip_in, idim)
1326 do ip_in = 1, bc%pml%points_number
1327 ip = bc%pml%points_map(ip_in)
1328 bc%pml%aux_mu(ip_in, :, idim) = tmp_grad(ip, :)/(
m_four*
p_mu/c_factor**2 * bc%pml%kappa(ip_in, idim))
1333 do idim = 1, space%dim
1334 do ip_in = 1, bc%pml%points_number
1335 bc%pml%c(ip_in, idim) =
p_c*c_factor/bc%pml%kappa(ip_in, idim)
1338 safe_deallocate_a(tmp)
1339 safe_deallocate_a(tmp_grad)
1346 call accel_write_buffer(bc%pml%buff_conv_plus, bc%pml%points_number, space%dim, space%dim, bc%pml%conv_plus)
1347 call accel_write_buffer(bc%pml%buff_conv_minus, bc%pml%points_number, space%dim, space%dim, bc%pml%conv_minus)
1350 bc%pml%parameters_initialized = .
true.
1359 class(
space_t),
intent(in) :: space
1360 type(
grid_t),
intent(in) :: gr
1361 real(real64),
intent(in) :: c_factor
1362 real(real64),
intent(in) :: dt
1364 integer :: ip_in, ip, idir
1365 real(real64) :: ddv(1:space%dim), kappa, sigma, alpha
1369 do ip_in = 1, bc%pml%points_number
1370 ip = bc%pml%points_map(ip_in)
1371 ddv(1:3) = abs(gr%x(1:3, ip)) - bc%bc_bounds(1, 1:3)
1372 do idir = 1, space%dim
1373 if (ddv(idir) >=
m_zero)
then
1374 sigma = (ddv(idir)/bc%pml%width)**bc%pml%power * &
1380 bc%pml%b(ip_in, idir) =
exp(-(alpha + sigma/kappa)/
p_ep*dt)
1382 bc%pml%c(ip_in, idir) =
m_zero
1384 bc%pml%c(ip_in, idir) =
m_one/(kappa + kappa**2*alpha/sigma) * &
1385 (bc%pml%b(ip_in, idir) - 1)
1388 bc%pml%b(ip_in, idir) =
m_zero
1389 bc%pml%c(ip_in, idir) =
m_zero
1404 class(
mesh_t),
intent(in) :: mesh
1405 real(real64),
intent(in) :: bounds(:,:)
1407 integer :: ip, ip_in, idim, ip_in_max
1408 real(real64) :: ddv(3), tmp(3), width(3)
1409 real(real64),
allocatable :: mask(:)
1415 ip_in_max = maxval(bc%mask_points_number(:))
1417 safe_allocate(mask(1:mesh%np))
1421 width(1:3) = bounds(2, 1:3) - bounds(1, 1:3)
1427 ddv(1:3) = abs(mesh%x(1:3, ip)) - bounds(1, 1:3)
1428 do idim = 1, mesh%box%dim
1429 if (ddv(idim) >=
m_zero)
then
1430 if (ddv(idim) <= width(idim))
then
1436 mask(ip) = mask(ip) * tmp(idim)
1440 do idim = 1, mesh%box%dim
1441 do ip_in = 1, bc%mask_points_number(idim)
1442 ip = bc%mask_points_map(ip_in, idim)
1443 bc%mask(ip_in,idim) = mask(ip)
1447 safe_deallocate_a(mask)
1455 subroutine bc_mxll_generate_medium(bc, space, gr, bounds, ep_factor, mu_factor, sigma_e_factor, sigma_m_factor)
1457 class(
space_t),
intent(in) :: space
1458 type(
grid_t),
intent(in) :: gr
1459 real(real64),
intent(in) :: bounds(:,:)
1460 real(real64),
intent(in) :: ep_factor
1461 real(real64),
intent(in) :: mu_factor
1462 real(real64),
intent(in) :: sigma_e_factor
1463 real(real64),
intent(in) :: sigma_m_factor
1465 integer :: ip, ipp, ip_in, ip_in_max, ip_bd, idim, point_info
1466 integer :: medium_points_number(3)
1467 real(real64) :: dd, dd_min, dd_max, xx(3), xxp(3)
1468 real(real64),
allocatable :: tmp(:), tmp_grad(:,:)
1474 ip_in_max = max(bc%medium(1)%points_number, bc%medium(2)%points_number, bc%medium(3)%points_number)
1475 medium_points_number(:) = [bc%medium(1)%points_number, bc%medium(2)%points_number, bc%medium(3)%points_number]
1476 dd_max = max(2*gr%spacing(1), 2*gr%spacing(2), 2*gr%spacing(3))
1477 safe_allocate(tmp(gr%np_part))
1478 safe_allocate(tmp_grad(1:gr%np_part,1:space%dim))
1482 bc%medium(idim)%points_number = medium_points_number(idim)
1483 bc%medium(idim)%aux_ep =
m_zero
1484 bc%medium(idim)%aux_mu =
m_zero
1485 bc%medium(idim)%c =
p_c
1489 do ip = 1, gr%np_part
1491 if ((point_info /= 0) .and. (abs(gr%x_t(ip, idim)) <= bounds(1, idim)))
then
1494 do ip_bd = 1, bc%medium(idim)%bdry_number
1495 ipp = bc%medium(idim)%bdry_map(ip_bd)
1496 xxp(:) = gr%x(:, ipp)
1497 dd = norm2(xx(1:3) - xxp(1:3))
1498 if (dd < dd_min) dd_min = dd
1504 do ip_in = 1, bc%medium(idim)%points_number
1505 ip = bc%medium(idim)%points_map(ip_in)
1506 bc%medium(idim)%aux_ep(ip_in, :) = &
1514 do ip = 1, gr%np_part
1516 if ((point_info == 1) .and. (abs(gr%x_t(ip, idim)) <= bounds(1, idim)))
then
1519 do ip_bd = 1, bc%medium(idim)%bdry_number
1520 ipp = bc%medium(idim)%bdry_map(ip_bd)
1521 xxp(:) = gr%x(:, ipp)
1522 dd = norm2(xx(1:3) - xxp(1:3))
1523 if (dd < dd_min) dd_min = dd
1529 do ip_in = 1, bc%medium(idim)%points_number
1530 ip = bc%medium(idim)%points_map(ip_in)
1531 bc%medium(idim)%aux_mu(ip_in, :) = &
1538 do ip_in = 1, bc%medium(idim)%points_number
1539 ip = bc%medium(idim)%points_map(ip_in)
1542 do ip_bd = 1, bc%medium(idim)%bdry_number
1543 ipp = bc%medium(idim)%bdry_map(ip_bd)
1544 xxp(:) = gr%x(:, ipp)
1545 dd = norm2(xx(1:3) - xxp(1:3))
1546 if (dd < dd_min) dd_min = dd
1548 bc%medium(idim)%ep(ip_in) =
p_ep * (
m_one + ep_factor &
1552 bc%medium(idim)%sigma_e(ip_in) = (
m_one + sigma_e_factor &
1554 bc%medium(idim)%sigma_m(ip_in) = (
m_one + sigma_m_factor &
1556 bc%medium(idim)%c(ip_in) =
m_one /
sqrt(bc%medium(idim)%ep(ip_in) * bc%medium(idim)%mu(ip_in))
1560 safe_deallocate_a(tmp)
1561 safe_deallocate_a(tmp_grad)
1570 class(
mesh_t),
intent(in) :: mesh
1572 real(real64),
intent(in) :: bounds(:,:)
1580 st%surface(1, 1)%spacing =
m_half*(mesh%spacing(2) + mesh%spacing(3))
1581 st%surface(1, 1)%origin(:) =
m_zero
1582 st%surface(1, 1)%origin(1) = -bounds(1, 1)
1583 st%surface(1, 1)%n(:) =
m_zero
1584 st%surface(1, 1)%n(1) = -
m_one
1585 st%surface(1, 1)%u(:) =
m_zero
1586 st%surface(1, 1)%u(2) = -
m_one
1587 st%surface(1, 1)%v(:) =
m_zero
1588 st%surface(1, 1)%v(3) =
m_one
1589 st%surface(1, 1)%nu = -int(bounds(1, 2)/mesh%spacing(2))
1590 st%surface(1, 1)%mu = int(bounds(1, 2)/mesh%spacing(2))
1591 st%surface(1, 1)%nv = -int(bounds(1, 3)/mesh%spacing(3))
1592 st%surface(1, 1)%mv = int(bounds(1, 3)/mesh%spacing(3))
1595 st%surface(2, 1)%spacing =
m_half*(mesh%spacing(2) + mesh%spacing(3))
1596 st%surface(2, 1)%origin(:) =
m_zero
1597 st%surface(2, 1)%origin(1) = bounds(1, 1)
1598 st%surface(2, 1)%n(:) =
m_zero
1599 st%surface(2, 1)%n(1) =
m_one
1600 st%surface(2, 1)%u(:) =
m_zero
1601 st%surface(2, 1)%u(2) =
m_one
1602 st%surface(2, 1)%v(:) =
m_zero
1603 st%surface(2, 1)%v(3) =
m_one
1604 st%surface(2, 1)%nu = -int(bounds(1, 2)/mesh%spacing(2))
1605 st%surface(2, 1)%mu = int(bounds(1, 2)/mesh%spacing(2))
1606 st%surface(2, 1)%nv = -int(bounds(1, 3)/mesh%spacing(3))
1607 st%surface(2, 1)%mv = int(bounds(1, 3)/mesh%spacing(3))
1610 st%surface(1, 2)%spacing =
m_half*(mesh%spacing(1) + mesh%spacing(3))
1611 st%surface(1, 2)%origin(:) =
m_zero
1612 st%surface(1, 2)%origin(2) = -bounds(1, 2)
1613 st%surface(1, 2)%n(:) =
m_zero
1614 st%surface(1, 2)%n(2) = -
m_one
1615 st%surface(1, 2)%u(:) =
m_zero
1616 st%surface(1, 2)%u(1) =
m_one
1617 st%surface(1, 2)%v(:) =
m_zero
1618 st%surface(1, 2)%v(3) =
m_one
1619 st%surface(1, 2)%nu = -int(bounds(1, 1)/mesh%spacing(1))
1620 st%surface(1, 2)%mu = int(bounds(1, 1)/mesh%spacing(1))
1621 st%surface(1, 2)%nv = -int(bounds(1, 3)/mesh%spacing(3))
1622 st%surface(1, 2)%mv = int(bounds(1, 3)/mesh%spacing(3))
1625 st%surface(2, 2)%spacing =
m_half*(mesh%spacing(1) + mesh%spacing(3))
1626 st%surface(2, 2)%origin(:) =
m_zero
1627 st%surface(2, 2)%origin(2) = bounds(1, 2)
1628 st%surface(2, 2)%n(:) =
m_zero
1629 st%surface(2, 2)%n(2) =
m_one
1630 st%surface(2, 2)%u(:) =
m_zero
1631 st%surface(2, 2)%u(1) =
m_one
1632 st%surface(2, 2)%v(:) =
m_zero
1633 st%surface(2, 2)%v(3) = -
m_one
1634 st%surface(2, 2)%nu = -int(bounds(1, 1)/mesh%spacing(1))
1635 st%surface(2, 2)%mu = int(bounds(1, 1)/mesh%spacing(1))
1636 st%surface(2, 2)%nv = -int(bounds(1, 3)/mesh%spacing(3))
1637 st%surface(2, 2)%mv = int(bounds(1, 3)/mesh%spacing(3))
1640 st%surface(1, 3)%spacing =
m_half*(mesh%spacing(1) + mesh%spacing(2))
1641 st%surface(1, 3)%origin(:) =
m_zero
1642 st%surface(1, 3)%origin(3) = -bounds(1, 3)
1643 st%surface(1, 3)%n(:) =
m_zero
1644 st%surface(1, 3)%n(3) = -
m_one
1645 st%surface(1, 3)%u(:) =
m_zero
1646 st%surface(1, 3)%u(1) =
m_one
1647 st%surface(1, 3)%v(:) =
m_zero
1648 st%surface(1, 3)%v(2) = -
m_one
1649 st%surface(1, 3)%nu = -int(bounds(1, 1)/mesh%spacing(1))
1650 st%surface(1, 3)%mu = int(bounds(1, 1)/mesh%spacing(1))
1651 st%surface(1, 3)%nv = -int(bounds(1, 2)/mesh%spacing(2))
1652 st%surface(1, 3)%mv = int(bounds(1, 2)/mesh%spacing(2))
1655 st%surface(2, 3)%spacing =
m_half*(mesh%spacing(1) + mesh%spacing(2))
1656 st%surface(2, 3)%origin(:) =
m_zero
1657 st%surface(2, 3)%origin(3) = bounds(1, 3)
1658 st%surface(2, 3)%n(:) =
m_zero
1659 st%surface(2, 3)%n(3) =
m_one
1660 st%surface(2, 3)%u(:) =
m_zero
1661 st%surface(2, 3)%u(1) =
m_one
1662 st%surface(2, 3)%v(:) =
m_zero
1663 st%surface(2, 3)%v(2) =
m_one
1664 st%surface(2, 3)%nu = -int(bounds(1, 1)/mesh%spacing(1))
1665 st%surface(2, 3)%mu = int(bounds(1, 1)/mesh%spacing(1))
1666 st%surface(2, 3)%nv = -int(bounds(1, 2)/mesh%spacing(2))
1667 st%surface(2, 3)%mv = int(bounds(1, 2)/mesh%spacing(2))
1677 class(
mesh_t),
intent(in) :: mesh
1678 integer,
intent(in) :: ip
1679 real(real64),
intent(in) :: bounds(:,:)
1680 integer,
intent(out) :: point_info
1682 real(real64) :: rr, dd, xx(3), width(3)
1686 width(1:3) = bounds(2, 1:3) - bounds(1, 1:3)
1688 xx(1:mesh%box%dim) = mesh%x(1:mesh%box%dim, ip)
1690 if (bc%ab_user_def)
then
1692 dd = bc%ab_ufn(ip) - bounds(1, 1)
1694 if (bc%ab_ufn(ip) < bounds(2, 1))
then
1701 select type (box => mesh%box)
1703 rr = norm2(xx - box%center)
1704 dd = rr - bounds(1, 1)
1706 if (dd < width(1))
then
1713 if (all(abs(xx(1:3) - box%center) <= bounds(2, 1:3)))
then
1714 if (any(abs(xx(1:3) - box%center) > bounds(1, 1:3)))
then
1733 class(
mesh_t),
intent(in) :: mesh
1734 integer,
intent(in) :: ip
1735 real(real64),
intent(in) :: bounds(:,:)
1736 integer,
intent(out) :: boundary_info
1738 real(real64) :: xx(3)
1743 xx(1:mesh%box%dim) = mesh%x(1:mesh%box%dim, ip)
1744 if (
is_close(abs(xx(1)), bounds(1, 1)) .and. (all(abs(xx(2:3)) <= bounds(1, 2:3))) .or. &
1745 is_close(abs(xx(2)), bounds(1, 2)) .and. (all(abs(xx(1:3:2)) <= bounds(1, 1:3:2))) .or. &
1746 is_close(abs(xx(3)), bounds(1, 3)) .and. (all(abs(xx(1:2)) <= bounds(1, 1:2))))
then
1756 class(
mesh_t),
intent(in) :: mesh
1758 real(real64),
intent(in) :: bounds(:,:)
1760 integer :: ip, ip_in, ip_bd, point_info
1761 real(real64) :: xx(mesh%box%dim)
1772 if (all(abs(xx) <= bounds(2,1:mesh%box%dim)))
then
1773 if (any(abs(xx) > bounds(1,1:mesh%box%dim)))
then
1781 if (point_info == 0)
then
1787 st%inner_points_number = ip_in
1788 safe_allocate(st%inner_points_map(1:ip_in))
1789 safe_allocate(st%inner_points_mask(1:mesh%np))
1790 st%boundary_points_number = ip_bd
1791 safe_allocate(st%boundary_points_map(1:ip_bd))
1792 safe_allocate(st%boundary_points_mask(1:mesh%np))
1793 st%inner_points_mask = .false.
1794 st%boundary_points_mask = .false.
1801 if (all(abs(xx) <= bounds(2,1:mesh%box%dim)))
then
1802 if (any(abs(xx) > bounds(1,1:mesh%box%dim)))
then
1810 if (point_info == 0)
then
1812 st%inner_points_map(ip_in) = ip
1813 st%inner_points_mask(ip) = .
true.
1816 st%boundary_points_map(ip_bd) = ip
1817 st%boundary_points_mask(ip) = .
true.
1823 call accel_write_buffer(st%buff_inner_points_map, st%inner_points_number, st%inner_points_map)
1825 call accel_write_buffer(st%buff_boundary_points_map, st%boundary_points_number, st%boundary_points_map)
1835 class(
mesh_t),
intent(in) :: mesh
1837 real(real64),
intent(in) :: bounds(:,:)
1839 integer :: ix, ix_max, iix, iy, iy_max, iiy, iz, iz_max, iiz, idx1, idx2, nn_max
1840 integer(int64) :: ip_global
1841 integer,
allocatable :: nn(:,:,:,:)
1842 real(real64) :: rr(3), delta(3), vec(2), min_1(3), max_1(3), min_2(3), max_2(3)
1848 st%surface_grid_rows_number(1) = 3
1849 ix_max = st%surface_grid_rows_number(1)
1850 st%surface_grid_rows_number(2) = 3
1851 iy_max = st%surface_grid_rows_number(2)
1852 st%surface_grid_rows_number(3) = 3
1853 iz_max = st%surface_grid_rows_number(3)
1855 delta(1) =
m_two * abs(bounds(1,1)) / real(ix_max, real64)
1856 delta(2) =
m_two * abs(bounds(1,2)) / real(iy_max, real64)
1857 delta(3) =
m_two * abs(bounds(1,3)) / real(iz_max, real64)
1859 st%surface_grid_element(1) = delta(2) * delta(3)
1860 st%surface_grid_element(2) = delta(1) * delta(3)
1861 st%surface_grid_element(3) = delta(1) * delta(2)
1863 safe_allocate(nn(1:2, 1:3, 1:3, 1:3))
1865 st%surface_grid_center(1, 1, :, :) = -int(bounds(1,1))
1868 rr(2) = -bounds(1,2) + delta(2)/
m_two + (iy-1) * delta(2)
1869 rr(3) = -bounds(1,3) + delta(3)/
m_two + (iz-1) * delta(3)
1870 st%surface_grid_center(1, 2, iy, iz) = int(rr(2))
1871 st%surface_grid_center(1, 3, iy, iz) = int(rr(3))
1874 st%surface_grid_center(2, 1, :, :) = int(bounds(1,1))
1877 rr(2) = -bounds(1,2) + delta(2)/
m_two + (iy-1) * delta(2)
1878 rr(3) = -bounds(1,3) + delta(3)/
m_two + (iz-1) * delta(3)
1879 st%surface_grid_center(2, 2, iy, iz) = int(rr(2))
1880 st%surface_grid_center(2, 3, iy, iz) = int(rr(3))
1884 st%surface_grid_center(1, 2, :, :) = -int(bounds(1,2))
1887 rr(1) = -bounds(1,1) + delta(1)/
m_two + (ix-1) * delta(1)
1888 rr(3) = -bounds(1,3) + delta(3)/
m_two + (iz-1) * delta(3)
1889 st%surface_grid_center(1, 1, ix, iz) = int(rr(1))
1890 st%surface_grid_center(1, 3, ix, iz) = int(rr(3))
1893 st%surface_grid_center(2, 2, :, :) = int(bounds(1,2))
1896 rr(1) = -bounds(1,2) + delta(1)/
m_two + (ix-1) * delta(1)
1897 rr(3) = -bounds(1,3) + delta(3)/
m_two + (iz-1) * delta(3)
1898 st%surface_grid_center(2, 1, ix, iz) = int(rr(1))
1899 st%surface_grid_center(2, 3, ix, iz) = int(rr(3))
1903 st%surface_grid_center(1, 3, :, :) = -int(bounds(1,3))
1906 rr(1) = -bounds(1,1) + delta(1)/
m_two + (ix-1) * delta(1)
1907 rr(2) = -bounds(1,2) + delta(2)/
m_two + (iy-1) * delta(2)
1908 st%surface_grid_center(1, 1, ix, iy) = int(rr(1))
1909 st%surface_grid_center(1, 2, ix, iy) = int(rr(2))
1912 st%surface_grid_center(2, 3, :, :) = int(bounds(1,3))
1915 rr(1) = -bounds(1,2) + delta(1)/
m_two + (ix-1) * delta(1)
1916 rr(2) = -bounds(1,2) + delta(2)/
m_two + (iy-1) * delta(2)
1917 st%surface_grid_center(2, 1, ix, iy) = int(rr(1))
1918 st%surface_grid_center(2, 2, ix, iy) = int(rr(2))
1922 st%surface_grid_points_number(:,:,:) = 0
1928 min_1(iy) = -bounds(1,2) + (iy-1) * delta(2)
1929 max_1(iy) = -bounds(1,2) + iy * delta(2)
1930 min_2(iz) = -bounds(1,3) + (iz-1) * delta(3)
1931 max_2(iz) = -bounds(1,3) + iz * delta(3)
1934 do iiy = mesh%idx%nr(1,2), mesh%idx%nr(2,2)
1935 do iiz = mesh%idx%nr(1,3), mesh%idx%nr(2,3)
1936 vec(1) = iiy * mesh%spacing(2)
1937 vec(2) = iiz * mesh%spacing(3)
1939 if (idx1 /= 0 .and. idx2 /= 0)
then
1940 st%surface_grid_points_number(1, idx1, idx2) = st%surface_grid_points_number(1, idx1, idx2) + 1
1941 if (nn_max < st%surface_grid_points_number(1, idx1, idx2))
then
1942 nn_max = st%surface_grid_points_number(1, idx1, idx2)
1950 min_1(ix) = -bounds(1,1) + (ix-1) * delta(1)
1951 max_1(ix) = -bounds(1,1) + ix * delta(1)
1952 min_2(iz) = -bounds(1,3) + (iz-1) * delta(3)
1953 max_2(iz) = -bounds(1,3) + iz * delta(3)
1956 do iix = mesh%idx%nr(1, 1), mesh%idx%nr(2, 1)
1957 do iiz = mesh%idx%nr(1, 3), mesh%idx%nr(2, 3)
1958 vec(1) = iix * mesh%spacing(1)
1959 vec(2) = iiz * mesh%spacing(3)
1961 if (idx1 /= 0 .and. idx2 /= 0)
then
1962 st%surface_grid_points_number(2,idx1,idx2) = st%surface_grid_points_number(2,idx1,idx2)+1
1963 if (nn_max < st%surface_grid_points_number(2, idx1, idx2))
then
1964 nn_max = st%surface_grid_points_number(2, idx1, idx2)
1972 min_1(ix) = -bounds(1,1) + (ix-1) * delta(1)
1973 max_1(ix) = -bounds(1,1) + ix * delta(1)
1974 min_2(iy) = -bounds(1,2) + (iy-1) * delta(2)
1975 max_2(iy) = -bounds(1,2) + iy * delta(2)
1978 do iix = mesh%idx%nr(1,1), mesh%idx%nr(2,1)
1979 do iiy = mesh%idx%nr(1,2), mesh%idx%nr(2,2)
1980 vec(1) = iix * mesh%spacing(1)
1981 vec(2) = iiy * mesh%spacing(2)
1983 if (idx1 /= 0 .and. idx2 /= 0)
then
1984 st%surface_grid_points_number(3, idx1, idx2) = st%surface_grid_points_number(3, idx1, idx2) + 1
1985 if (nn_max < st%surface_grid_points_number(3, idx1, idx2))
then
1986 nn_max = st%surface_grid_points_number(3, idx1, idx2)
1993 safe_allocate(st%surface_grid_points_map(1:2, 1:st%dim, 1:ix_max, 1:iy_max, 1:nn_max))
1999 min_1(iy) = -bounds(1,2) + (iy-1) * delta(2)
2000 max_1(iy) = -bounds(1,2) + iy * delta(2)
2001 min_2(iz) = -bounds(1,3) + (iz-1) * delta(3)
2002 max_2(iz) = -bounds(1,3) + iz * delta(3)
2005 do iiy = mesh%idx%nr(1,2), mesh%idx%nr(2,2)
2006 do iiz = mesh%idx%nr(1,3), mesh%idx%nr(2,3)
2007 vec(1) = iiy * mesh%spacing(2)
2008 vec(2) = iiz * mesh%spacing(3)
2010 if (idx1 /= 0 .and. idx2 /= 0)
then
2011 nn(1, 1, idx1, idx2) = nn(1, 1, idx1, idx2) + 1
2012 rr(1) = -bounds(1, 1)
2013 rr(2) = iiy * mesh%spacing(2)
2014 rr(3) = iiz * mesh%spacing(3)
2015 iix = int(-bounds(1,1)/mesh%spacing(1))
2017 st%surface_grid_points_map(1, 1, idx1, idx2, nn(1, 1, idx1, idx2)) = ip_global
2018 nn(2, 1, idx1, idx2) = nn(2, 1, idx1, idx2) + 1
2020 rr(2) = iiy * mesh%spacing(2)
2021 rr(3) = iiz * mesh%spacing(3)
2022 iix = int(bounds(1,1)/mesh%spacing(1))
2024 st%surface_grid_points_map(2, 1, idx1, idx2, nn(2, 1, idx1, idx2)) = ip_global
2031 min_1(ix) = -bounds(1,1) + (ix-1) * delta(1)
2032 max_1(ix) = -bounds(1,1) + ix * delta(1)
2033 min_2(iz) = -bounds(1,3) + (iz-1) * delta(3)
2034 max_2(iz) = -bounds(1,3) + iz * delta(3)
2037 do iix = mesh%idx%nr(1,1), mesh%idx%nr(2,1)
2038 do iiz = mesh%idx%nr(1,3), mesh%idx%nr(2,3)
2039 vec(1) = iix * mesh%spacing(1)
2040 vec(2) = iiz * mesh%spacing(3)
2042 if (idx1 /= 0 .and. idx2 /= 0)
then
2043 nn(1, 2, idx1, idx2) = nn(1, 2, idx1, idx2) + 1
2044 rr(1) = iix * mesh%spacing(1)
2045 rr(2) = -bounds(1, 2)
2046 rr(3) = iiz * mesh%spacing(3)
2047 iiy = int(-bounds(1,2)/mesh%spacing(2))
2049 st%surface_grid_points_map(1, 2, idx1, idx2, nn(1, 2, idx1, idx2)) = ip_global
2050 nn(2, 2, idx1, idx2) = nn(2, 2, idx1, idx2) + 1
2051 rr(1) = iix * mesh%spacing(1)
2053 rr(3) = iiz * mesh%spacing(3)
2054 iiy = int(bounds(1,2)/mesh%spacing(2))
2056 st%surface_grid_points_map(2, 2, idx1, idx2, nn(2, 2, idx1, idx2)) = ip_global
2063 min_1(ix) = -bounds(1,1) + (ix-1) * delta(1)
2064 max_1(ix) = -bounds(1,1) + ix * delta(1)
2065 min_2(iy) = -bounds(1,2) + (iy-1) * delta(2)
2066 max_2(iy) = -bounds(1,2) + iy * delta(2)
2069 do iix = mesh%idx%nr(1,1), mesh%idx%nr(2,1)
2070 do iiy = mesh%idx%nr(1,2), mesh%idx%nr(2,2)
2071 vec(1) = iix * mesh%spacing(1)
2072 vec(2) = iiy * mesh%spacing(2)
2074 if (idx1 /= 0 .and. idx2 /= 0)
then
2075 nn(1, 3, idx1, idx2) = nn(1, 3, idx1, idx2) + 1
2076 rr(1) = iix * mesh%spacing(1)
2077 rr(2) = iiy * mesh%spacing(2)
2078 rr(3) = -bounds(1,3)
2079 iiz = int(-bounds(1,3)/mesh%spacing(3))
2081 st%surface_grid_points_map(1, 3, idx1, idx2, nn(1, 3, idx1, idx2)) = ip_global
2082 nn(2, 3, idx1, idx2) = nn(2, 3, idx1, idx2) + 1
2083 rr(1) = iix * mesh%spacing(1)
2084 rr(2) = iiy * mesh%spacing(2)
2086 iiz = int(bounds(1,3)/mesh%spacing(3))
2088 st%surface_grid_points_map(2, 3, idx1, idx2, nn(2, 3, idx1, idx2)) = ip_global
2093 safe_deallocate_a(nn)
2101 real(real64),
intent(in) :: vec(:)
2102 real(real64),
intent(in) :: min_1(:)
2103 real(real64),
intent(in) :: max_1(:)
2104 real(real64),
intent(in) :: min_2(:)
2105 real(real64),
intent(in) :: max_2(:)
2106 integer,
intent(out) :: index_1
2107 integer,
intent(out) :: index_2
2109 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
2112 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
2115 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
2118 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
2121 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
2124 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
2127 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
2130 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
2133 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)
subroutine, public accel_free_buffer(this, async)
integer, parameter, public accel_mem_read_write
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)
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, public bc_mxll_generate_pml_parameters(bc, space, gr, c_factor, dt)
subroutine bc_mxll_generate_mask(bc, mesh, bounds)
subroutine maxwell_plane_waves_points_mapping(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
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public messages_input_error(namespace, var, details, row, column)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Some general things and nomenclature:
logical function, public parse_is_defined(namespace, name)
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), parameter, public type_cmplx
type(type_t), parameter, public type_integer
type(type_t), parameter, public type_float
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.