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(:,:)
104 type(single_medium_box_t) :: medium(3)
106 integer :: constant_points_number
107 integer,
allocatable :: constant_points_map(:)
108 complex(real64),
allocatable :: constant_rs_state(:,:)
109 type(accel_mem_t) :: buff_constant_points_map
111 integer :: mirror_points_number(3)
112 integer,
allocatable :: mirror_points_map(:,:)
114 logical :: do_plane_waves = .false.
115 type(external_waves_t) :: plane_wave
116 logical :: plane_waves_dims(1:3) = .false.
118 real(real64) :: zero_width
119 integer :: zero_points_number(3)
120 integer,
allocatable :: zero_points_map(:,:)
121 real(real64),
allocatable :: zero(:,:)
124 integer,
public,
parameter :: &
132 integer,
parameter :: &
133 MXLL_PLANE_WAVES_NEGATIVE_SIDE = -1, &
136 integer,
public,
parameter :: &
137 MXLL_AB_NOT_ABSORBING = 0, &
146 type(bc_mxll_t),
intent(inout) :: bc
147 type(namespace_t),
intent(in) :: namespace
148 class(space_t),
intent(in) :: space
149 type(grid_t),
intent(in) :: gr
150 type(states_mxll_t),
intent(inout) :: st
152 integer :: idim, nlines, icol, ncols, ab_shape_dim
153 real(real64) :: bounds(2, space%dim), ab_bounds(2, space%dim)
155 character(len=1024) :: string
156 character(len=50) :: ab_type_str
157 character(len=1),
dimension(3),
parameter :: dims = [
"x",
"y",
"z"]
158 logical :: plane_waves_check, ab_mask_check, ab_pml_check, plane_waves_set
159 logical :: constant_check, zero_check
160 real(real64) :: ep_factor, mu_factor, sigma_e_factor, sigma_m_factor
166 plane_waves_set = .false.
167 bc%bc_type(:) = mxll_bc_zero
168 bc%medium(:)%points_number = 0
169 bc%medium(:)%bdry_number = 0
199 if (
parse_block(namespace,
'MaxwellBoundaryConditions', blk) == 0)
then
204 if (nlines /= 1)
then
218 select case (bc%bc_type(icol))
224 string =
'PEC Mirror'
226 string =
'PMC Mirror'
228 string =
'Plane waves'
230 string =
'Medium boundary'
232 write(
message(1),
'(a)')
'Unknown Maxwell boundary condition'
235 write(
message(1),
'(a,I1,a,a)')
'Maxwell boundary condition in direction ', icol,
': ', trim(string)
237 if (plane_waves_set .and. .not. (
parse_is_defined(namespace,
'MaxwellIncidentWaves')))
then
238 write(
message(1),
'(a)')
'Input: Maxwell boundary condition option is set to "plane_waves".'
239 write(
message(2),
'(a)')
'Input: User defined Maxwell plane waves have to be defined!'
244 plane_waves_check = .false.
245 ab_mask_check = .false.
246 ab_pml_check = .false.
247 constant_check = .false.
250 bc%ab_user_def = .false.
251 bc%bc_ab_type(:) = mxll_ab_not_absorbing
275 if (
parse_block(namespace,
'MaxwellAbsorbingBoundaries', blk) == 0)
then
278 if (nlines /= 1)
then
279 message(1) =
'MaxwellAbsorbingBounaries has to consist of one line!'
285 message(1) =
'MaxwellAbsorbingBoundaries has to consist of three columns!'
300 if (bc%bc_type(idim) == mxll_bc_zero) zero_check = .
true.
303 if (ab_mask_check .or. ab_pml_check)
then
306 write(
message(1),
'(a)')
"Please keep in mind that"
307 write(
message(2),
'(a)')
"with larger ABWidth, comes great responsibility."
308 write(
message(3),
'(a)')
"AbsorbingBoundaries occupy space in the simulation box,"
309 write(
message(4),
'(a)')
"hence choose your Lsize wisely."
314 bounds(1, :) = (gr%idx%nr(2, :) - gr%idx%enlarge(:))*gr%spacing(:)
315 bounds(2, :) = gr%idx%nr(2, :) * gr%spacing(:)
317 select case (bc%bc_type(idim))
321 bounds(1, idim) = (gr%idx%nr(2, idim) - gr%idx%enlarge(idim))*gr%spacing(idim)
322 bounds(2, idim) = (gr%idx%nr(2, idim)) * gr%spacing(idim)
326 bounds(1, idim) = (gr%idx%nr(2, idim) - 2*gr%idx%enlarge(idim))*gr%spacing(idim)
327 bounds(2, idim) = (gr%idx%nr(2, idim)) * gr%spacing(idim)
331 bounds(1, idim) = (gr%idx%nr(2, idim) - 2*gr%idx%enlarge(idim))*gr%spacing(idim)
332 bounds(2, idim) = (gr%idx%nr(2, idim)) * gr%spacing(idim)
333 plane_waves_check = .
true.
334 bc%do_plane_waves = .
true.
337 call bc_mxll_medium_init(gr, namespace, bounds, idim, ep_factor, mu_factor, sigma_e_factor, sigma_m_factor)
343 select type (box => gr%box)
346 if (space%is_periodic())
then
347 message(1) =
"Sphere box shape can only work for non-periodic systems"
351 if (.not. box%axes%orthogonal)
then
352 message(1) =
"Maxwell propagation does not work for non-orthogonal grids."
356 ab_shape_dim = space%dim
357 ab_bounds(1, idim) = bounds(1, idim)
358 ab_bounds(2, idim) = bounds(1, idim)
360 message(1) =
"Box shape for Maxwell propagation not supported yet"
364 if (bc%bc_ab_type(idim) /= mxll_ab_not_absorbing)
then
368 select case (bc%bc_ab_type(idim))
371 bc%zero_width = bc%ab_width
375 bc%mask_width = bc%ab_width
381 message(1) =
"Absorbing boundary type not implemented for Maxwell propagation"
387 select case (bc%bc_ab_type(idim))
389 bounds(1, idim) = ab_bounds(1, idim)
390 bounds(2, idim) = bounds(2, idim)
391 bc%bc_bounds(:, idim) = bounds(:, idim)
393 bc%bc_bounds(:, idim) = bounds(:, idim)
396 select type (box => gr%box)
398 select case (bc%bc_ab_type(idim))
411 string = trim(ab_type_str)//
" Absorbing Boundary"
412 write(string,
'(2a, f10.3,3a)') trim(string),
" in "//dims(idim)//
' direction spans from: ', &
415 write(
message(1),
'(a)') trim(string)
418 write(string,
'(a,f10.3,3a)') trim(string),&
422 write(
message(2),
'(a)') trim(string)
428 write(
message(1),
'(a,es10.3,3a)') &
431 write(
message(2),
'(a,es10.3,3a)') &
444 if (ab_mask_check)
then
449 if (ab_pml_check)
then
454 if (constant_check)
then
455 bounds(1, :) = gr%idx%nr(2, :) * gr%spacing(:)
456 bounds(2, :) = gr%idx%nr(2, :) * gr%spacing(:)
459 bounds(1, idim) = (gr%idx%nr(2, idim) - 2*gr%idx%enlarge(idim))*gr%spacing(idim)
460 bounds(2, idim) = (gr%idx%nr(2, idim)) * gr%spacing(idim)
467 if (plane_waves_check)
then
468 bounds(1, :) = gr%idx%nr(2, :) * gr%spacing(:)
469 bounds(2, :) = gr%idx%nr(2, :) * gr%spacing(:)
472 bounds(1, idim) = (gr%idx%nr(2, idim) - 2*gr%idx%enlarge(idim))*gr%spacing(idim)
473 bounds(2, idim) = (gr%idx%nr(2, idim)) * gr%spacing(idim)
482 bounds(1, :) = gr%idx%nr(2, :) * gr%spacing(:)
483 bounds(2, :) = gr%idx%nr(2, :) * gr%spacing(:)
485 if (bc%bc_type(idim) == mxll_bc_zero)
then
486 bounds(1, idim) = (gr%idx%nr(2, idim) - gr%idx%enlarge(idim))*gr%spacing(idim)
487 bounds(2, idim) = (gr%idx%nr(2, idim)) * gr%spacing(idim)
493 if (ab_mask_check)
then
497 if (ab_pml_check)
then
505 if (ab_mask_check .or. ab_pml_check)
then
522 safe_deallocate_a(bc%ab_ufn)
524 safe_deallocate_a(bc%mask_points_map)
525 safe_deallocate_a(bc%mask)
532 safe_deallocate_a(bc%constant_points_map)
533 safe_deallocate_a(bc%constant_rs_state)
538 safe_deallocate_a(bc%mirror_points_map)
542 safe_deallocate_a(bc%zero_points_map)
543 safe_deallocate_a(bc%zero)
550 type(
pml_t),
intent(inout) :: pml
554 safe_deallocate_a(pml%points_map)
555 safe_deallocate_a(pml%points_map_inv)
556 safe_deallocate_a(pml%kappa)
557 safe_deallocate_a(pml%sigma_e)
558 safe_deallocate_a(pml%sigma_m)
559 safe_deallocate_a(pml%a)
560 safe_deallocate_a(pml%b)
561 safe_deallocate_a(pml%c)
562 safe_deallocate_a(pml%mask)
563 safe_deallocate_a(pml%aux_ep)
564 safe_deallocate_a(pml%aux_mu)
565 safe_deallocate_a(pml%conv_plus)
566 safe_deallocate_a(pml%conv_minus)
567 safe_deallocate_a(pml%conv_plus_old)
568 safe_deallocate_a(pml%conv_minus_old)
586 subroutine bc_mxll_medium_init(gr, namespace, bounds, idim, ep_factor, mu_factor, sigma_e_factor, sigma_m_factor)
587 type(
grid_t),
intent(in) :: gr
588 type(namespace_t),
intent(in) :: namespace
589 real(real64),
intent(inout) :: bounds(:,:)
590 integer,
intent(in) :: idim
591 real(real64),
intent(out) :: ep_factor
592 real(real64),
intent(out) :: mu_factor
593 real(real64),
intent(out) :: sigma_e_factor
594 real(real64),
intent(out) :: sigma_m_factor
596 real(real64) :: width
610 bounds(1,idim) = ( gr%idx%nr(2, idim) - gr%idx%enlarge(idim) ) * gr%spacing(idim)
611 bounds(1,idim) = bounds(1,idim) - width
612 bounds(2,idim) = ( gr%idx%nr(2, idim) ) * gr%spacing(idim)
658 type(
grid_t),
intent(in) :: gr
659 type(namespace_t),
intent(in) :: namespace
660 real(real64),
intent(inout) :: ab_bounds(:,:)
661 integer,
intent(in) :: idim
663 real(real64) :: default_width
675 default_width =
m_two * gr%der%order * maxval(gr%spacing(1:3))
678 if (bc%ab_width < default_width)
then
679 bc%ab_width = default_width
680 write(
message(1),
'(a)')
'Absorbing boundary width has to be larger or equal than twice the derivatives order times spacing!'
681 write(
message(2),
'(a,es10.3)')
'Absorbing boundary width is set to: ', default_width
685 ab_bounds(1, idim) = ab_bounds(2, idim) - bc%ab_width
693 type(
grid_t),
intent(in) :: gr
694 type(namespace_t),
intent(in) :: namespace
695 real(real64),
intent(inout) :: ab_bounds(:,:)
696 integer,
intent(in) :: idim
701 bc%pml%width = bc%ab_width
720 call parse_variable(namespace,
'MaxwellABPMLReflectionError', 1.0e-16_real64, bc%pml%refl_error,
unit_one)
728 class(
mesh_t),
intent(in) :: mesh
729 type(namespace_t),
intent(in) :: namespace
730 class(
space_t),
intent(in) :: space
732 integer :: err, idim, idim2
733 real(real64),
allocatable :: tmp(:)
734 logical :: mask_check, pml_check, medium_check
735 character(1) :: dim_label(3)
743 medium_check = .false.
745 dim_label = (/
'x',
'y',
'z'/)
755 medium_check = .
true.
760 safe_allocate(tmp(1:mesh%np))
766 safe_deallocate_a(tmp)
767 else if (pml_check)
then
768 safe_allocate(tmp(1:mesh%np))
773 call write_files(
"maxwell_sigma_e-"//dim_label(idim), tmp)
778 call write_files(
"maxwell_sigma_m-"//dim_label(idim), tmp)
783 call write_files(
"maxwell_sigma_pml_a_e-"//dim_label(idim), tmp)
785 safe_deallocate_a(tmp)
788 if (medium_check)
then
789 safe_allocate(tmp(1:mesh%np))
794 call write_files(
"maxwell_ep"//dim_label(idim), tmp)
798 call write_files(
"maxwell_mu"//dim_label(idim), tmp)
802 call write_files(
"maxwell_c"//dim_label(idim), tmp)
807 call write_files(
"maxwell_aux_ep-"//dim_label(idim)//
"-"//dim_label(idim2), tmp)
812 call write_files(
"maxwell_aux_mu-"//dim_label(idim)//
"-"//dim_label(idim2), tmp)
816 safe_deallocate_a(tmp)
825 real(real64),
intent(in) :: pml_func(:)
827 real(real64),
intent(inout) :: io_func(:)
831 do ip_in = 1, bc%pml%points_number
832 ip = bc%pml%points_map(ip_in)
833 io_func(ip) = pml_func(ip_in)
839 real(real64),
intent(in) :: mask_func(:,:)
841 real(real64),
intent(inout) :: io_func(:)
842 integer,
intent(in) :: idim
846 do ip_in = 1, bc%mask_points_number(idim)
847 ip = bc%mask_points_map(ip_in, idim)
848 io_func(ip) = mask_func(ip_in, idim)
854 real(real64),
intent(in) :: medium_func(:)
856 real(real64),
intent(inout) :: io_func(:)
857 integer,
intent(in) :: idim
861 do ip_in = 1, bc%medium(idim)%points_number
862 ip = bc%medium(idim)%points_map(ip_in)
863 io_func(ip) = medium_func(ip_in)
869 character(len=*),
intent(in) :: filename
870 real(real64),
intent(in) :: tmp(:)
893 class(
mesh_t),
intent(in) :: mesh
894 real(real64),
intent(in) :: bounds(:,:)
896 integer :: ip, ip_in, ip_in_max, point_info, idim
908 if ((point_info == 1) .and. (abs(mesh%x_t(ip, idim)) >= bounds(1, idim)))
then
912 if (ip_in > ip_in_max) ip_in_max = ip_in
913 bc%mask_points_number(idim) = ip_in
916 safe_allocate(bc%mask(1:ip_in_max, 1:idim))
917 safe_allocate(bc%mask_points_map(1:ip_in_max, 1:idim))
925 if ((point_info == 1) .and. (abs(mesh%x_t(ip, idim)) >= bounds(1, idim)))
then
927 bc%mask_points_map(ip_in, idim) = ip
940 class(
mesh_t),
intent(in) :: mesh
941 real(real64),
intent(in) :: bounds(:,:)
943 integer :: ip, ip_in, point_info
953 if (point_info == 1)
then
957 bc%pml%points_number = ip_in
958 safe_allocate(bc%pml%points_map(1:ip_in))
959 safe_allocate(bc%pml%points_map_inv(1:mesh%np))
960 bc%pml%points_map_inv = 0
964 if (point_info == 1)
then
966 bc%pml%points_map(ip_in) = ip
967 bc%pml%points_map_inv(ip) = ip_in
979 class(
mesh_t),
intent(in) :: mesh
980 real(real64),
intent(in) :: bounds(:,:)
982 integer :: ip, ip_in, point_info
992 if (point_info == 1)
then
996 bc%constant_points_number = ip_in
997 safe_allocate(bc%constant_points_map(1:ip_in))
998 safe_allocate(bc%constant_rs_state(1:ip_in, 1:3))
1004 if (point_info == 1)
then
1006 bc%constant_points_map(ip_in) = ip
1012 call accel_write_buffer(bc%buff_constant_points_map, bc%constant_points_number, bc%constant_points_map)
1023 class(
mesh_t),
intent(in) :: mesh
1024 real(real64),
intent(in) :: bounds(:,:)
1026 integer :: ip, ip_in, point_info
1038 if (point_info == 1)
then
1042 bc%plane_wave%points_number = ip_in
1043 safe_allocate(bc%plane_wave%points_map(1:ip_in))
1049 if (point_info == 1)
then
1051 bc%plane_wave%points_map(ip_in) = ip
1057 call accel_write_buffer(bc%plane_wave%buff_map, bc%plane_wave%points_number, bc%plane_wave%points_map)
1068 class(
mesh_t),
intent(in) :: mesh
1069 real(real64),
intent(in) :: bounds(:,:)
1071 integer :: ip, ip_in, ip_in_max, point_info, idim
1079 if (bc%bc_type(idim) == mxll_bc_zero)
then
1084 if ((point_info == 1) .and. (abs(mesh%x(idim, ip)) >= bounds(1, idim)))
then
1088 if (ip_in > ip_in_max) ip_in_max = ip_in
1091 bc%zero_points_number = ip_in
1092 safe_allocate(bc%zero(1:ip_in_max,3))
1093 safe_allocate(bc%zero_points_map(1:ip_in_max, 1:3))
1096 if (bc%bc_type(idim) == mxll_bc_zero)
then
1101 if ((point_info == 1) .and. (abs(mesh%x_t(ip, idim)) >= bounds(1, idim)))
then
1103 bc%zero_points_map(ip_in, idim) = ip
1117 class(
mesh_t),
intent(in) :: mesh
1118 real(real64),
intent(in) :: bounds(:,:)
1120 integer :: ip, ip_in, ip_in_max, ip_bd, ip_bd_max, point_info, boundary_info, idim
1126 bc%medium(:)%points_number = 0
1127 bc%medium(:)%bdry_number = 0
1139 if ((point_info == 1) .and. (abs(mesh%x_t(ip, idim)) >= bounds(1, idim)))
then
1142 if ((boundary_info == 1) .and. (abs(mesh%x_t(ip, idim)) >= bounds(1, idim)))
then
1146 bc%medium(idim)%points_number = ip_in
1147 bc%medium(idim)%bdry_number = ip_bd
1148 ip_in_max = max(ip_in_max, ip_in)
1149 ip_bd_max = max(ip_bd_max, ip_bd)
1153 safe_allocate(bc%medium(idim)%points_map(1:ip_in_max))
1154 safe_allocate(bc%medium(idim)%bdry_map(1:ip_bd_max))
1164 if ((point_info == 1) .and. (abs(mesh%x_t(ip, idim)) >= bounds(1, idim)))
then
1166 bc%medium(idim)%points_map(ip_in) = ip
1168 if ((boundary_info == 1) .and. (abs(mesh%x_t(ip, idim)) >= bounds(1, idim)))
then
1170 bc%medium(idim)%bdry_map(ip_bd) = ip
1184 class(
space_t),
intent(in) :: space
1191 safe_allocate(bc%pml%kappa(1:bc%pml%points_number, 1:space%dim))
1192 safe_allocate(bc%pml%sigma_e(1:bc%pml%points_number, 1:space%dim))
1193 safe_allocate(bc%pml%sigma_m(1:bc%pml%points_number, 1:space%dim))
1194 safe_allocate(bc%pml%a(1:bc%pml%points_number, 1:space%dim))
1195 safe_allocate(bc%pml%b(1:bc%pml%points_number, 1:space%dim))
1196 safe_allocate(bc%pml%c(1:bc%pml%points_number, 1:3))
1197 safe_allocate(bc%pml%mask(1:bc%pml%points_number))
1198 safe_allocate(bc%pml%conv_plus(1:bc%pml%points_number, 1:3, 1:3))
1199 safe_allocate(bc%pml%conv_minus(1:bc%pml%points_number, 1:3, 1:3))
1200 safe_allocate(bc%pml%conv_plus_old(1:bc%pml%points_number, 1:3, 1:3))
1201 safe_allocate(bc%pml%conv_minus_old(1:bc%pml%points_number, 1:3, 1:3))
1202 safe_allocate(bc%pml%aux_ep(1:bc%pml%points_number, 1:3, 1:3))
1203 safe_allocate(bc%pml%aux_mu(1:bc%pml%points_number, 1:3, 1:3))
1205 bc%pml%kappa =
m_one
1212 bc%pml%conv_plus =
m_z0
1213 bc%pml%conv_minus =
m_z0
1214 bc%pml%conv_plus_old =
m_z0
1215 bc%pml%conv_minus_old =
m_z0
1223 int(bc%pml%points_number, int64)*space%dim*space%dim)
1225 int(bc%pml%points_number, int64)*space%dim*space%dim)
1227 int(bc%pml%points_number, int64)*space%dim*space%dim)
1232 call accel_write_buffer(bc%pml%buff_conv_plus, bc%pml%points_number, space%dim, space%dim, bc%pml%conv_plus)
1233 call accel_write_buffer(bc%pml%buff_conv_minus, bc%pml%points_number, space%dim, space%dim, bc%pml%conv_minus)
1234 call accel_write_buffer(bc%pml%buff_conv_plus_old, bc%pml%points_number, space%dim, space%dim, bc%pml%conv_plus_old)
1246 class(
space_t),
intent(in) :: space
1247 type(
grid_t),
intent(in) :: gr
1248 real(real64),
intent(in) :: c_factor
1249 real(real64),
optional,
intent(in) :: dt
1251 integer :: ip, ip_in, idim
1252 real(real64) :: width(3)
1253 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
1254 real(real64),
allocatable :: tmp(:), tmp_grad(:,:)
1258 safe_allocate(tmp(gr%np_part))
1259 safe_allocate(tmp_grad(gr%np, 1:space%dim))
1265 width(1:3) = (/ bc%pml%width, bc%pml%width, bc%pml%width /)
1268 do ip_in = 1, bc%pml%points_number
1269 ip = bc%pml%points_map(ip_in)
1270 ddv(1:3) = abs(gr%x(1:3, ip)) - bc%bc_bounds(1, 1:3)
1271 do idim = 1, space%dim
1272 if (ddv(idim) >=
m_zero)
then
1273 gg = (ddv(idim)/bc%pml%width)**bc%pml%power
1274 hh = (
m_one-ddv(idim)/bc%pml%width)**bc%pml%power
1276 ss_max = -(bc%pml%power +
m_one)*
p_c*c_factor*
p_ep*
log(bc%pml%refl_error)/(
m_two * bc%pml%width)
1287 bc%pml%sigma_e(ip_in, idim) = ss_e
1288 bc%pml%sigma_m(ip_in, idim) = ss_m
1289 bc%pml%a(ip_in, idim) = aa_e
1290 bc%pml%b(ip_in, idim) = bb_e
1291 bc%pml%kappa(ip_in, idim) = kk
1292 bc%pml%mask(ip_in) = bc%pml%mask(ip_in) * (
m_one -
sin(ddv(idim)*
m_pi/(
m_two*(width(idim))))**2)
1294 bc%pml%kappa(ip_in, idim) =
m_one
1295 bc%pml%sigma_e(ip_in, idim) =
m_zero
1296 bc%pml%sigma_m(ip_in, idim) =
m_zero
1297 bc%pml%a(ip_in, idim) =
m_zero
1298 bc%pml%b(ip_in, idim) =
m_zero
1299 bc%pml%mask(ip_in) =
m_one
1305 do idim = 1, space%dim
1307 do ip_in = 1, bc%pml%points_number
1308 ip = bc%pml%points_map(ip_in)
1309 tmp(ip) =
p_ep / bc%pml%kappa(ip_in, idim)
1312 do ip_in = 1, bc%pml%points_number
1313 ip = bc%pml%points_map(ip_in)
1314 bc%pml%aux_ep(ip_in, :, idim) = tmp_grad(ip, :)/(
m_four*
p_ep*bc%pml%kappa(ip_in, idim))
1319 do idim = 1, space%dim
1321 tmp =
p_mu/c_factor**2
1322 do ip_in = 1, bc%pml%points_number
1323 ip = bc%pml%points_map(ip_in)
1324 tmp(ip) =
p_mu/c_factor**2 / bc%pml%kappa(ip_in, idim)
1327 do ip_in = 1, bc%pml%points_number
1328 ip = bc%pml%points_map(ip_in)
1329 bc%pml%aux_mu(ip_in, :, idim) = tmp_grad(ip, :)/(
m_four*
p_mu/c_factor**2 * bc%pml%kappa(ip_in, idim))
1334 do idim = 1, space%dim
1335 do ip_in = 1, bc%pml%points_number
1336 bc%pml%c(ip_in, idim) =
p_c*c_factor/bc%pml%kappa(ip_in, idim)
1339 safe_deallocate_a(tmp)
1340 safe_deallocate_a(tmp_grad)
1347 call accel_write_buffer(bc%pml%buff_conv_plus, bc%pml%points_number, space%dim, space%dim, bc%pml%conv_plus)
1348 call accel_write_buffer(bc%pml%buff_conv_minus, bc%pml%points_number, space%dim, space%dim, bc%pml%conv_minus)
1351 bc%pml%parameters_initialized = .
true.
1360 class(
space_t),
intent(in) :: space
1361 type(
grid_t),
intent(in) :: gr
1362 real(real64),
intent(in) :: c_factor
1363 real(real64),
intent(in) :: dt
1365 integer :: ip_in, ip, idir
1366 real(real64) :: ddv(1:space%dim), kappa, sigma, alpha
1370 do ip_in = 1, bc%pml%points_number
1371 ip = bc%pml%points_map(ip_in)
1372 ddv(1:3) = abs(gr%x(1:3, ip)) - bc%bc_bounds(1, 1:3)
1373 do idir = 1, space%dim
1374 if (ddv(idir) >=
m_zero)
then
1375 sigma = (ddv(idir)/bc%pml%width)**bc%pml%power * &
1381 bc%pml%b(ip_in, idir) =
exp(-(alpha + sigma/kappa)/
p_ep*dt)
1383 bc%pml%c(ip_in, idir) =
m_zero
1385 bc%pml%c(ip_in, idir) =
m_one/(kappa + kappa**2*alpha/sigma) * &
1386 (bc%pml%b(ip_in, idir) - 1)
1389 bc%pml%b(ip_in, idir) =
m_zero
1390 bc%pml%c(ip_in, idir) =
m_zero
1405 class(
mesh_t),
intent(in) :: mesh
1406 real(real64),
intent(in) :: bounds(:,:)
1408 integer :: ip, ip_in, idim, ip_in_max
1409 real(real64) :: ddv(3), tmp(3), width(3)
1410 real(real64),
allocatable :: mask(:)
1416 ip_in_max = maxval(bc%mask_points_number(:))
1418 safe_allocate(mask(1:mesh%np))
1422 width(1:3) = bounds(2, 1:3) - bounds(1, 1:3)
1428 ddv(1:3) = abs(mesh%x(1:3, ip)) - bounds(1, 1:3)
1429 do idim = 1, mesh%box%dim
1430 if (ddv(idim) >=
m_zero)
then
1431 if (ddv(idim) <= width(idim))
then
1437 mask(ip) = mask(ip) * tmp(idim)
1441 do idim = 1, mesh%box%dim
1442 do ip_in = 1, bc%mask_points_number(idim)
1443 ip = bc%mask_points_map(ip_in, idim)
1444 bc%mask(ip_in,idim) = mask(ip)
1448 safe_deallocate_a(mask)
1456 subroutine bc_mxll_generate_medium(bc, space, gr, bounds, ep_factor, mu_factor, sigma_e_factor, sigma_m_factor)
1458 class(
space_t),
intent(in) :: space
1459 type(
grid_t),
intent(in) :: gr
1460 real(real64),
intent(in) :: bounds(:,:)
1461 real(real64),
intent(in) :: ep_factor
1462 real(real64),
intent(in) :: mu_factor
1463 real(real64),
intent(in) :: sigma_e_factor
1464 real(real64),
intent(in) :: sigma_m_factor
1466 integer :: ip, ipp, ip_in, ip_in_max, ip_bd, idim, point_info
1467 integer :: medium_points_number(3)
1468 real(real64) :: dd, dd_min, dd_max, xx(3), xxp(3)
1469 real(real64),
allocatable :: tmp(:), tmp_grad(:,:)
1475 ip_in_max = max(bc%medium(1)%points_number, bc%medium(2)%points_number, bc%medium(3)%points_number)
1476 medium_points_number(:) = [bc%medium(1)%points_number, bc%medium(2)%points_number, bc%medium(3)%points_number]
1477 dd_max = max(2*gr%spacing(1), 2*gr%spacing(2), 2*gr%spacing(3))
1478 safe_allocate(tmp(gr%np_part))
1479 safe_allocate(tmp_grad(1:gr%np_part,1:space%dim))
1483 bc%medium(idim)%points_number = medium_points_number(idim)
1484 bc%medium(idim)%aux_ep =
m_zero
1485 bc%medium(idim)%aux_mu =
m_zero
1486 bc%medium(idim)%c =
p_c
1490 do ip = 1, gr%np_part
1492 if ((point_info /= 0) .and. (abs(gr%x_t(ip, idim)) <= bounds(1, idim)))
then
1495 do ip_bd = 1, bc%medium(idim)%bdry_number
1496 ipp = bc%medium(idim)%bdry_map(ip_bd)
1497 xxp(:) = gr%x(:, ipp)
1498 dd = norm2(xx(1:3) - xxp(1:3))
1499 if (dd < dd_min) dd_min = dd
1505 do ip_in = 1, bc%medium(idim)%points_number
1506 ip = bc%medium(idim)%points_map(ip_in)
1507 bc%medium(idim)%aux_ep(ip_in, :) = &
1515 do ip = 1, gr%np_part
1517 if ((point_info == 1) .and. (abs(gr%x_t(ip, idim)) <= bounds(1, idim)))
then
1520 do ip_bd = 1, bc%medium(idim)%bdry_number
1521 ipp = bc%medium(idim)%bdry_map(ip_bd)
1522 xxp(:) = gr%x(:, ipp)
1523 dd = norm2(xx(1:3) - xxp(1:3))
1524 if (dd < dd_min) dd_min = dd
1530 do ip_in = 1, bc%medium(idim)%points_number
1531 ip = bc%medium(idim)%points_map(ip_in)
1532 bc%medium(idim)%aux_mu(ip_in, :) = &
1539 do ip_in = 1, bc%medium(idim)%points_number
1540 ip = bc%medium(idim)%points_map(ip_in)
1543 do ip_bd = 1, bc%medium(idim)%bdry_number
1544 ipp = bc%medium(idim)%bdry_map(ip_bd)
1545 xxp(:) = gr%x(:, ipp)
1546 dd = norm2(xx(1:3) - xxp(1:3))
1547 if (dd < dd_min) dd_min = dd
1549 bc%medium(idim)%ep(ip_in) =
p_ep * (
m_one + ep_factor &
1553 bc%medium(idim)%sigma_e(ip_in) = (
m_one + sigma_e_factor &
1555 bc%medium(idim)%sigma_m(ip_in) = (
m_one + sigma_m_factor &
1557 bc%medium(idim)%c(ip_in) =
m_one /
sqrt(bc%medium(idim)%ep(ip_in) * bc%medium(idim)%mu(ip_in))
1561 safe_deallocate_a(tmp)
1562 safe_deallocate_a(tmp_grad)
1571 class(
mesh_t),
intent(in) :: mesh
1573 real(real64),
intent(in) :: bounds(:,:)
1581 st%surface(1, 1)%spacing =
m_half*(mesh%spacing(2) + mesh%spacing(3))
1582 st%surface(1, 1)%origin(:) =
m_zero
1583 st%surface(1, 1)%origin(1) = -bounds(1, 1)
1584 st%surface(1, 1)%n(:) =
m_zero
1585 st%surface(1, 1)%n(1) = -
m_one
1586 st%surface(1, 1)%u(:) =
m_zero
1587 st%surface(1, 1)%u(2) = -
m_one
1588 st%surface(1, 1)%v(:) =
m_zero
1589 st%surface(1, 1)%v(3) =
m_one
1590 st%surface(1, 1)%nu = -int(bounds(1, 2)/mesh%spacing(2))
1591 st%surface(1, 1)%mu = int(bounds(1, 2)/mesh%spacing(2))
1592 st%surface(1, 1)%nv = -int(bounds(1, 3)/mesh%spacing(3))
1593 st%surface(1, 1)%mv = int(bounds(1, 3)/mesh%spacing(3))
1596 st%surface(2, 1)%spacing =
m_half*(mesh%spacing(2) + mesh%spacing(3))
1597 st%surface(2, 1)%origin(:) =
m_zero
1598 st%surface(2, 1)%origin(1) = bounds(1, 1)
1599 st%surface(2, 1)%n(:) =
m_zero
1600 st%surface(2, 1)%n(1) =
m_one
1601 st%surface(2, 1)%u(:) =
m_zero
1602 st%surface(2, 1)%u(2) =
m_one
1603 st%surface(2, 1)%v(:) =
m_zero
1604 st%surface(2, 1)%v(3) =
m_one
1605 st%surface(2, 1)%nu = -int(bounds(1, 2)/mesh%spacing(2))
1606 st%surface(2, 1)%mu = int(bounds(1, 2)/mesh%spacing(2))
1607 st%surface(2, 1)%nv = -int(bounds(1, 3)/mesh%spacing(3))
1608 st%surface(2, 1)%mv = int(bounds(1, 3)/mesh%spacing(3))
1611 st%surface(1, 2)%spacing =
m_half*(mesh%spacing(1) + mesh%spacing(3))
1612 st%surface(1, 2)%origin(:) =
m_zero
1613 st%surface(1, 2)%origin(2) = -bounds(1, 2)
1614 st%surface(1, 2)%n(:) =
m_zero
1615 st%surface(1, 2)%n(2) = -
m_one
1616 st%surface(1, 2)%u(:) =
m_zero
1617 st%surface(1, 2)%u(1) =
m_one
1618 st%surface(1, 2)%v(:) =
m_zero
1619 st%surface(1, 2)%v(3) =
m_one
1620 st%surface(1, 2)%nu = -int(bounds(1, 1)/mesh%spacing(1))
1621 st%surface(1, 2)%mu = int(bounds(1, 1)/mesh%spacing(1))
1622 st%surface(1, 2)%nv = -int(bounds(1, 3)/mesh%spacing(3))
1623 st%surface(1, 2)%mv = int(bounds(1, 3)/mesh%spacing(3))
1626 st%surface(2, 2)%spacing =
m_half*(mesh%spacing(1) + mesh%spacing(3))
1627 st%surface(2, 2)%origin(:) =
m_zero
1628 st%surface(2, 2)%origin(2) = bounds(1, 2)
1629 st%surface(2, 2)%n(:) =
m_zero
1630 st%surface(2, 2)%n(2) =
m_one
1631 st%surface(2, 2)%u(:) =
m_zero
1632 st%surface(2, 2)%u(1) =
m_one
1633 st%surface(2, 2)%v(:) =
m_zero
1634 st%surface(2, 2)%v(3) = -
m_one
1635 st%surface(2, 2)%nu = -int(bounds(1, 1)/mesh%spacing(1))
1636 st%surface(2, 2)%mu = int(bounds(1, 1)/mesh%spacing(1))
1637 st%surface(2, 2)%nv = -int(bounds(1, 3)/mesh%spacing(3))
1638 st%surface(2, 2)%mv = int(bounds(1, 3)/mesh%spacing(3))
1641 st%surface(1, 3)%spacing =
m_half*(mesh%spacing(1) + mesh%spacing(2))
1642 st%surface(1, 3)%origin(:) =
m_zero
1643 st%surface(1, 3)%origin(3) = -bounds(1, 3)
1644 st%surface(1, 3)%n(:) =
m_zero
1645 st%surface(1, 3)%n(3) = -
m_one
1646 st%surface(1, 3)%u(:) =
m_zero
1647 st%surface(1, 3)%u(1) =
m_one
1648 st%surface(1, 3)%v(:) =
m_zero
1649 st%surface(1, 3)%v(2) = -
m_one
1650 st%surface(1, 3)%nu = -int(bounds(1, 1)/mesh%spacing(1))
1651 st%surface(1, 3)%mu = int(bounds(1, 1)/mesh%spacing(1))
1652 st%surface(1, 3)%nv = -int(bounds(1, 2)/mesh%spacing(2))
1653 st%surface(1, 3)%mv = int(bounds(1, 2)/mesh%spacing(2))
1656 st%surface(2, 3)%spacing =
m_half*(mesh%spacing(1) + mesh%spacing(2))
1657 st%surface(2, 3)%origin(:) =
m_zero
1658 st%surface(2, 3)%origin(3) = bounds(1, 3)
1659 st%surface(2, 3)%n(:) =
m_zero
1660 st%surface(2, 3)%n(3) =
m_one
1661 st%surface(2, 3)%u(:) =
m_zero
1662 st%surface(2, 3)%u(1) =
m_one
1663 st%surface(2, 3)%v(:) =
m_zero
1664 st%surface(2, 3)%v(2) =
m_one
1665 st%surface(2, 3)%nu = -int(bounds(1, 1)/mesh%spacing(1))
1666 st%surface(2, 3)%mu = int(bounds(1, 1)/mesh%spacing(1))
1667 st%surface(2, 3)%nv = -int(bounds(1, 2)/mesh%spacing(2))
1668 st%surface(2, 3)%mv = int(bounds(1, 2)/mesh%spacing(2))
1678 class(
mesh_t),
intent(in) :: mesh
1679 integer,
intent(in) :: ip
1680 real(real64),
intent(in) :: bounds(:,:)
1681 integer,
intent(out) :: point_info
1683 real(real64) :: rr, dd, xx(3), width(3)
1687 width(1:3) = bounds(2, 1:3) - bounds(1, 1:3)
1689 xx(1:mesh%box%dim) = mesh%x(1:mesh%box%dim, ip)
1691 if (bc%ab_user_def)
then
1693 dd = bc%ab_ufn(ip) - bounds(1, 1)
1695 if (bc%ab_ufn(ip) < bounds(2, 1))
then
1702 select type (box => mesh%box)
1704 rr = norm2(xx - box%center)
1705 dd = rr - bounds(1, 1)
1707 if (dd < width(1))
then
1714 if (all(abs(xx(1:3) - box%center) <= bounds(2, 1:3)))
then
1715 if (any(abs(xx(1:3) - box%center) > bounds(1, 1:3)))
then
1734 class(
mesh_t),
intent(in) :: mesh
1735 integer,
intent(in) :: ip
1736 real(real64),
intent(in) :: bounds(:,:)
1737 integer,
intent(out) :: boundary_info
1739 real(real64) :: xx(3)
1744 xx(1:mesh%box%dim) = mesh%x(1:mesh%box%dim, ip)
1745 if (
is_close(abs(xx(1)), bounds(1, 1)) .and. (all(abs(xx(2:3)) <= bounds(1, 2:3))) .or. &
1746 is_close(abs(xx(2)), bounds(1, 2)) .and. (all(abs(xx(1:3:2)) <= bounds(1, 1:3:2))) .or. &
1747 is_close(abs(xx(3)), bounds(1, 3)) .and. (all(abs(xx(1:2)) <= bounds(1, 1:2))))
then
1757 class(
mesh_t),
intent(in) :: mesh
1759 real(real64),
intent(in) :: bounds(:,:)
1761 integer :: ip, ip_in, ip_bd, point_info
1762 real(real64) :: xx(mesh%box%dim)
1773 if (all(abs(xx) <= bounds(2,1:mesh%box%dim)))
then
1774 if (any(abs(xx) > bounds(1,1:mesh%box%dim)))
then
1782 if (point_info == 0)
then
1788 st%inner_points_number = ip_in
1789 safe_allocate(st%inner_points_map(1:ip_in))
1790 safe_allocate(st%inner_points_mask(1:mesh%np))
1791 st%boundary_points_number = ip_bd
1792 safe_allocate(st%boundary_points_map(1:ip_bd))
1793 safe_allocate(st%boundary_points_mask(1:mesh%np))
1794 st%inner_points_mask = .false.
1795 st%boundary_points_mask = .false.
1802 if (all(abs(xx) <= bounds(2,1:mesh%box%dim)))
then
1803 if (any(abs(xx) > bounds(1,1:mesh%box%dim)))
then
1811 if (point_info == 0)
then
1813 st%inner_points_map(ip_in) = ip
1814 st%inner_points_mask(ip) = .
true.
1817 st%boundary_points_map(ip_bd) = ip
1818 st%boundary_points_mask(ip) = .
true.
1824 call accel_write_buffer(st%buff_inner_points_map, st%inner_points_number, st%inner_points_map)
1826 call accel_write_buffer(st%buff_boundary_points_map, st%boundary_points_number, st%boundary_points_map)
1836 class(
mesh_t),
intent(in) :: mesh
1838 real(real64),
intent(in) :: bounds(:,:)
1840 integer :: ix, ix_max, iix, iy, iy_max, iiy, iz, iz_max, iiz, idx1, idx2, nn_max
1841 integer(int64) :: ip_global
1842 integer,
allocatable :: nn(:,:,:,:)
1843 real(real64) :: rr(3), delta(3), vec(2), min_1(3), max_1(3), min_2(3), max_2(3)
1849 st%surface_grid_rows_number(1) = 3
1850 ix_max = st%surface_grid_rows_number(1)
1851 st%surface_grid_rows_number(2) = 3
1852 iy_max = st%surface_grid_rows_number(2)
1853 st%surface_grid_rows_number(3) = 3
1854 iz_max = st%surface_grid_rows_number(3)
1856 delta(1) =
m_two * abs(bounds(1,1)) / real(ix_max, real64)
1857 delta(2) =
m_two * abs(bounds(1,2)) / real(iy_max, real64)
1858 delta(3) =
m_two * abs(bounds(1,3)) / real(iz_max, real64)
1860 st%surface_grid_element(1) = delta(2) * delta(3)
1861 st%surface_grid_element(2) = delta(1) * delta(3)
1862 st%surface_grid_element(3) = delta(1) * delta(2)
1864 safe_allocate(nn(1:2, 1:3, 1:3, 1:3))
1866 st%surface_grid_center(1, 1, :, :) = -int(bounds(1,1))
1869 rr(2) = -bounds(1,2) + delta(2)/
m_two + (iy-1) * delta(2)
1870 rr(3) = -bounds(1,3) + delta(3)/
m_two + (iz-1) * delta(3)
1871 st%surface_grid_center(1, 2, iy, iz) = int(rr(2))
1872 st%surface_grid_center(1, 3, iy, iz) = int(rr(3))
1875 st%surface_grid_center(2, 1, :, :) = int(bounds(1,1))
1878 rr(2) = -bounds(1,2) + delta(2)/
m_two + (iy-1) * delta(2)
1879 rr(3) = -bounds(1,3) + delta(3)/
m_two + (iz-1) * delta(3)
1880 st%surface_grid_center(2, 2, iy, iz) = int(rr(2))
1881 st%surface_grid_center(2, 3, iy, iz) = int(rr(3))
1885 st%surface_grid_center(1, 2, :, :) = -int(bounds(1,2))
1888 rr(1) = -bounds(1,1) + delta(1)/
m_two + (ix-1) * delta(1)
1889 rr(3) = -bounds(1,3) + delta(3)/
m_two + (iz-1) * delta(3)
1890 st%surface_grid_center(1, 1, ix, iz) = int(rr(1))
1891 st%surface_grid_center(1, 3, ix, iz) = int(rr(3))
1894 st%surface_grid_center(2, 2, :, :) = int(bounds(1,2))
1897 rr(1) = -bounds(1,2) + delta(1)/
m_two + (ix-1) * delta(1)
1898 rr(3) = -bounds(1,3) + delta(3)/
m_two + (iz-1) * delta(3)
1899 st%surface_grid_center(2, 1, ix, iz) = int(rr(1))
1900 st%surface_grid_center(2, 3, ix, iz) = int(rr(3))
1904 st%surface_grid_center(1, 3, :, :) = -int(bounds(1,3))
1907 rr(1) = -bounds(1,1) + delta(1)/
m_two + (ix-1) * delta(1)
1908 rr(2) = -bounds(1,2) + delta(2)/
m_two + (iy-1) * delta(2)
1909 st%surface_grid_center(1, 1, ix, iy) = int(rr(1))
1910 st%surface_grid_center(1, 2, ix, iy) = int(rr(2))
1913 st%surface_grid_center(2, 3, :, :) = int(bounds(1,3))
1916 rr(1) = -bounds(1,2) + delta(1)/
m_two + (ix-1) * delta(1)
1917 rr(2) = -bounds(1,2) + delta(2)/
m_two + (iy-1) * delta(2)
1918 st%surface_grid_center(2, 1, ix, iy) = int(rr(1))
1919 st%surface_grid_center(2, 2, ix, iy) = int(rr(2))
1923 st%surface_grid_points_number(:,:,:) = 0
1929 min_1(iy) = -bounds(1,2) + (iy-1) * delta(2)
1930 max_1(iy) = -bounds(1,2) + iy * delta(2)
1931 min_2(iz) = -bounds(1,3) + (iz-1) * delta(3)
1932 max_2(iz) = -bounds(1,3) + iz * delta(3)
1935 do iiy = mesh%idx%nr(1,2), mesh%idx%nr(2,2)
1936 do iiz = mesh%idx%nr(1,3), mesh%idx%nr(2,3)
1937 vec(1) = iiy * mesh%spacing(2)
1938 vec(2) = iiz * mesh%spacing(3)
1940 if (idx1 /= 0 .and. idx2 /= 0)
then
1941 st%surface_grid_points_number(1, idx1, idx2) = st%surface_grid_points_number(1, idx1, idx2) + 1
1942 if (nn_max < st%surface_grid_points_number(1, idx1, idx2))
then
1943 nn_max = st%surface_grid_points_number(1, idx1, idx2)
1951 min_1(ix) = -bounds(1,1) + (ix-1) * delta(1)
1952 max_1(ix) = -bounds(1,1) + ix * delta(1)
1953 min_2(iz) = -bounds(1,3) + (iz-1) * delta(3)
1954 max_2(iz) = -bounds(1,3) + iz * delta(3)
1957 do iix = mesh%idx%nr(1, 1), mesh%idx%nr(2, 1)
1958 do iiz = mesh%idx%nr(1, 3), mesh%idx%nr(2, 3)
1959 vec(1) = iix * mesh%spacing(1)
1960 vec(2) = iiz * mesh%spacing(3)
1962 if (idx1 /= 0 .and. idx2 /= 0)
then
1963 st%surface_grid_points_number(2,idx1,idx2) = st%surface_grid_points_number(2,idx1,idx2)+1
1964 if (nn_max < st%surface_grid_points_number(2, idx1, idx2))
then
1965 nn_max = st%surface_grid_points_number(2, idx1, idx2)
1973 min_1(ix) = -bounds(1,1) + (ix-1) * delta(1)
1974 max_1(ix) = -bounds(1,1) + ix * delta(1)
1975 min_2(iy) = -bounds(1,2) + (iy-1) * delta(2)
1976 max_2(iy) = -bounds(1,2) + iy * delta(2)
1979 do iix = mesh%idx%nr(1,1), mesh%idx%nr(2,1)
1980 do iiy = mesh%idx%nr(1,2), mesh%idx%nr(2,2)
1981 vec(1) = iix * mesh%spacing(1)
1982 vec(2) = iiy * mesh%spacing(2)
1984 if (idx1 /= 0 .and. idx2 /= 0)
then
1985 st%surface_grid_points_number(3, idx1, idx2) = st%surface_grid_points_number(3, idx1, idx2) + 1
1986 if (nn_max < st%surface_grid_points_number(3, idx1, idx2))
then
1987 nn_max = st%surface_grid_points_number(3, idx1, idx2)
1994 safe_allocate(st%surface_grid_points_map(1:2, 1:st%dim, 1:ix_max, 1:iy_max, 1:nn_max))
2000 min_1(iy) = -bounds(1,2) + (iy-1) * delta(2)
2001 max_1(iy) = -bounds(1,2) + iy * delta(2)
2002 min_2(iz) = -bounds(1,3) + (iz-1) * delta(3)
2003 max_2(iz) = -bounds(1,3) + iz * delta(3)
2006 do iiy = mesh%idx%nr(1,2), mesh%idx%nr(2,2)
2007 do iiz = mesh%idx%nr(1,3), mesh%idx%nr(2,3)
2008 vec(1) = iiy * mesh%spacing(2)
2009 vec(2) = iiz * mesh%spacing(3)
2011 if (idx1 /= 0 .and. idx2 /= 0)
then
2012 nn(1, 1, idx1, idx2) = nn(1, 1, idx1, idx2) + 1
2013 rr(1) = -bounds(1, 1)
2014 rr(2) = iiy * mesh%spacing(2)
2015 rr(3) = iiz * mesh%spacing(3)
2016 iix = int(-bounds(1,1)/mesh%spacing(1))
2018 st%surface_grid_points_map(1, 1, idx1, idx2, nn(1, 1, idx1, idx2)) = ip_global
2019 nn(2, 1, idx1, idx2) = nn(2, 1, idx1, idx2) + 1
2021 rr(2) = iiy * mesh%spacing(2)
2022 rr(3) = iiz * mesh%spacing(3)
2023 iix = int(bounds(1,1)/mesh%spacing(1))
2025 st%surface_grid_points_map(2, 1, idx1, idx2, nn(2, 1, idx1, idx2)) = ip_global
2032 min_1(ix) = -bounds(1,1) + (ix-1) * delta(1)
2033 max_1(ix) = -bounds(1,1) + ix * delta(1)
2034 min_2(iz) = -bounds(1,3) + (iz-1) * delta(3)
2035 max_2(iz) = -bounds(1,3) + iz * delta(3)
2038 do iix = mesh%idx%nr(1,1), mesh%idx%nr(2,1)
2039 do iiz = mesh%idx%nr(1,3), mesh%idx%nr(2,3)
2040 vec(1) = iix * mesh%spacing(1)
2041 vec(2) = iiz * mesh%spacing(3)
2043 if (idx1 /= 0 .and. idx2 /= 0)
then
2044 nn(1, 2, idx1, idx2) = nn(1, 2, idx1, idx2) + 1
2045 rr(1) = iix * mesh%spacing(1)
2046 rr(2) = -bounds(1, 2)
2047 rr(3) = iiz * mesh%spacing(3)
2048 iiy = int(-bounds(1,2)/mesh%spacing(2))
2050 st%surface_grid_points_map(1, 2, idx1, idx2, nn(1, 2, idx1, idx2)) = ip_global
2051 nn(2, 2, idx1, idx2) = nn(2, 2, idx1, idx2) + 1
2052 rr(1) = iix * mesh%spacing(1)
2054 rr(3) = iiz * mesh%spacing(3)
2055 iiy = int(bounds(1,2)/mesh%spacing(2))
2057 st%surface_grid_points_map(2, 2, idx1, idx2, nn(2, 2, idx1, idx2)) = ip_global
2064 min_1(ix) = -bounds(1,1) + (ix-1) * delta(1)
2065 max_1(ix) = -bounds(1,1) + ix * delta(1)
2066 min_2(iy) = -bounds(1,2) + (iy-1) * delta(2)
2067 max_2(iy) = -bounds(1,2) + iy * delta(2)
2070 do iix = mesh%idx%nr(1,1), mesh%idx%nr(2,1)
2071 do iiy = mesh%idx%nr(1,2), mesh%idx%nr(2,2)
2072 vec(1) = iix * mesh%spacing(1)
2073 vec(2) = iiy * mesh%spacing(2)
2075 if (idx1 /= 0 .and. idx2 /= 0)
then
2076 nn(1, 3, idx1, idx2) = nn(1, 3, idx1, idx2) + 1
2077 rr(1) = iix * mesh%spacing(1)
2078 rr(2) = iiy * mesh%spacing(2)
2079 rr(3) = -bounds(1,3)
2080 iiz = int(-bounds(1,3)/mesh%spacing(3))
2082 st%surface_grid_points_map(1, 3, idx1, idx2, nn(1, 3, idx1, idx2)) = ip_global
2083 nn(2, 3, idx1, idx2) = nn(2, 3, idx1, idx2) + 1
2084 rr(1) = iix * mesh%spacing(1)
2085 rr(2) = iiy * mesh%spacing(2)
2087 iiz = int(bounds(1,3)/mesh%spacing(3))
2089 st%surface_grid_points_map(2, 3, idx1, idx2, nn(2, 3, idx1, idx2)) = ip_global
2094 safe_deallocate_a(nn)
2102 real(real64),
intent(in) :: vec(:)
2103 real(real64),
intent(in) :: min_1(:)
2104 real(real64),
intent(in) :: max_1(:)
2105 real(real64),
intent(in) :: min_2(:)
2106 real(real64),
intent(in) :: max_2(:)
2107 integer,
intent(out) :: index_1
2108 integer,
intent(out) :: index_2
2110 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
2113 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
2116 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
2119 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
2122 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
2125 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
2128 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
2131 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
2134 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), 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.