Octopus
maxwell_boundary_op.F90
Go to the documentation of this file.
1!! Copyright (C) 2019 R. Jestaedt, H. Appel, F. Bonafe, M. Oliveira, N. Tancogne-Dejean
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17
18#include "global.h"
19
21 use accel_oct_m
25 use debug_oct_m
28 use global_oct_m
29 use grid_oct_m
30 use index_oct_m
31 use io_oct_m
33 use math_oct_m
35 use math_oct_m
38 use mesh_oct_m
40 use mpi_oct_m
42 use parser_oct_m
45 use string_oct_m
46 use types_oct_m
47 use unit_oct_m
50 use space_oct_m
52
53 implicit none
54
55 private
56 public :: &
59 bc_mxll_t, &
64
65 type pml_t
66 real(real64) :: width
67 integer :: points_number
68 integer, allocatable :: points_map(:)
69 integer, allocatable :: points_map_inv(:)
70 real(real64) :: power
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.
86 ! GPU buffers
87 type(accel_mem_t) :: buff_a, buff_b, buff_c, buff_conv_plus, buff_conv_minus, buff_map, buff_conv_plus_old
88 end type pml_t
89
90 type bc_mxll_t
91 integer :: bc_type(3)
92 integer :: bc_ab_type(3)
93 real(real64) :: bc_bounds(2, 3)
94 logical :: ab_user_def
95 real(real64), allocatable :: ab_ufn(:)
96
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(:,:)
102
103 integer :: der_bndry_mask_points_number
104 integer, allocatable :: der_bndry_mask_points_map(:)
105 real(real64), allocatable :: der_bndry_mask(:)
106
107 type(pml_t) :: pml
108 type(single_medium_box_t) :: medium(3)
109
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
114
115 integer :: mirror_points_number(3)
116 integer, allocatable :: mirror_points_map(:,:)
117
118 logical :: do_plane_waves = .false. !! look here afterwards
119 type(external_waves_t) :: plane_wave
120 logical :: plane_waves_dims(1:3) = .false.
121
122 real(real64) :: zero_width
123 integer :: zero_points_number(3)
124 integer, allocatable :: zero_points_map(:,:)
125 real(real64), allocatable :: zero(:,:)
126 end type bc_mxll_t
127
128 integer, public, parameter :: &
129 MXLL_BC_ZERO = 0, &
130 mxll_bc_constant = 1, &
131 mxll_bc_mirror_pec = 2, &
132 mxll_bc_mirror_pmc = 3, &
134 mxll_bc_periodic = 5, &
136
137 integer, parameter :: &
138 MXLL_PLANE_WAVES_NEGATIVE_SIDE = -1, &
140
141 integer, public, parameter :: &
142 MXLL_AB_NOT_ABSORBING = 0, &
143 mxll_ab_mask = 1, &
144 mxll_ab_cpml = 2, &
146
147contains
148
149 ! ---------------------------------------------------------
150 subroutine bc_mxll_init(bc, namespace, space, gr, st)
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
156
157 integer :: idim, nlines, icol, ncols, ab_shape_dim
158 real(real64) :: bounds(2, space%dim), ab_bounds(2, space%dim)
159 type(block_t) :: blk
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
167 push_sub(bc_mxll_init)
169 call profiling_in('BC_MXLL_INIT')
171 plane_waves_check = .false.
172 ab_mask_check = .false.
173 ab_pml_check = .false.
174 constant_check = .false.
175 zero_check = .false.
177 bc%ab_user_def = .false.
178 bc%bc_ab_type(:) = mxll_ab_not_absorbing ! default option
179
180 !%Variable MaxwellAbsorbingBoundaries
181 !%Type block
182 !%Section Maxwell
183 !%Description
184 !% Type of absorbing boundaries used for Maxwell propagation in each direction.
185 !%
186 !% Example:
187 !%
188 !% <tt>%MaxwellAbsorbingBoundaries
189 !% <br>&nbsp;&nbsp; cpml | cpml | cpml
190 !% <br>%</tt>
191 !%
192 !%Option not_absorbing 0
193 !% No absorbing boundaries.
194 !%Option mask 1
195 !% A mask equal to the wavefunctions mask is applied to the Maxwell states at the boundaries
196 !%Option cpml 2
197 !% Perfectly matched layer absorbing boundary
198 !%Option mask_zero 7
199 !% Absorbing boundary region is set to zero
200 !%End
202 if (parse_block(namespace, 'MaxwellAbsorbingBoundaries', blk) == 0) then
203 ! find out how many lines (i.e. states) the block has
204 nlines = parse_block_n(blk)
205 if (nlines /= 1) then
206 message(1) = 'MaxwellAbsorbingBounaries has to consist of one line!'
207 call messages_fatal(1, namespace=namespace)
208 end if
210 ncols = parse_block_cols(blk, 0)
211 if (ncols /= 3) then
212 message(1) = 'MaxwellAbsorbingBoundaries has to consist of three columns!'
213 call messages_fatal(1, namespace=namespace)
214 end if
216 do icol = 1, ncols
217 call parse_block_integer(blk, 0, icol-1, bc%bc_ab_type(icol))
218 end do
219
220 call parse_block_end(blk)
221 end if
222
223 do idim = 1, 3
224 if (bc%bc_ab_type(idim) == mxll_ab_mask) ab_mask_check = .true.
225 if (bc%bc_ab_type(idim) == mxll_ab_cpml) ab_pml_check = .true.
226 if (bc%bc_type(idim) == mxll_bc_constant) constant_check = .true.
227 if (bc%bc_type(idim) == mxll_bc_zero) zero_check = .true.
228 end do
229
230 if (ab_mask_check .or. ab_pml_check) then
231
232 call messages_print_with_emphasis(msg='Maxwell Absorbing Boundaries', namespace=namespace)
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."
237 call messages_info(4, namespace=namespace)
238
239 end if
240
241 do idim = 1, st%dim
242 select case (bc%bc_type(idim))
244 case (mxll_bc_zero, mxll_bc_mirror_pec, mxll_bc_mirror_pmc)
245
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)
248
250
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)
253
255
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.
260
261 case (mxll_bc_medium)
262 call bc_mxll_medium_init(gr, namespace, bounds, idim, ep_factor, mu_factor, sigma_e_factor, sigma_m_factor)
263 call maxwell_medium_points_mapping(bc, gr, bounds)
264 call bc_mxll_generate_medium(bc, space, gr, bounds, ep_factor, mu_factor, sigma_e_factor, sigma_m_factor)
265
266 end select
267
268 select type (box => gr%box)
269 type is (box_sphere_t)
270 ab_shape_dim = 1
271 if (space%is_periodic()) then
272 message(1) = "Sphere box shape can only work for non-periodic systems"
273 call messages_fatal(1, namespace=namespace)
274 end if
275 type is (box_parallelepiped_t)
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."
278 call messages_fatal(1, namespace=namespace)
279 end if
280
281 ab_shape_dim = space%dim
282 ab_bounds(1, idim) = bounds(1, idim)
283 ab_bounds(2, idim) = bounds(1, idim)
284 class default
285 message(1) = "Box shape for Maxwell propagation not supported yet"
286 call messages_fatal(1, namespace=namespace)
287 end select
288
289 if (bc%bc_ab_type(idim) /= mxll_ab_not_absorbing) then
290
291 call messages_print_var_option("MaxwellAbsorbingBoundaries", bc%bc_ab_type(idim), namespace=namespace)
292
293 select case (bc%bc_ab_type(idim))
294 case (mxll_ab_mask_zero)
295 if (bc%bc_type(idim) == mxll_bc_periodic) then
296 message(1) = "Zero absorbing boundary conditions do not work in periodic directions"
297 call messages_fatal(1, namespace=namespace)
298 end if
299
300 call bc_mxll_ab_bounds_init(bc, gr, namespace, ab_bounds, idim)
301 bc%zero_width = bc%ab_width
302
303 case (mxll_ab_mask)
304 call bc_mxll_ab_bounds_init(bc, gr, namespace, ab_bounds, idim)
305 bc%mask_width = bc%ab_width
306
307 case (mxll_ab_cpml)
308 call bc_mxll_pml_init(bc, gr, namespace, ab_bounds, idim)
309
310 case default
311 message(1) = "Absorbing boundary type not implemented for Maxwell propagation"
312 call messages_fatal(1, namespace=namespace)
313 end select
314
315 end if
316
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)
322 case default
323 bc%bc_bounds(:, idim) = bounds(:, idim)
324 end select
325
326 select type (box => gr%box)
327 type is (box_parallelepiped_t)
328 select case (bc%bc_ab_type(idim))
329 case (mxll_ab_cpml)
330 ab_type_str = "PML"
331 case (mxll_ab_mask)
332 ab_type_str = "Mask"
333 case (mxll_ab_mask_zero)
334 ab_type_str = "Zero"
335 case default
336 ab_type_str = ""
337 end select
338
339 if (bc%bc_ab_type(idim) == mxll_ab_cpml .or. bc%bc_ab_type(idim) == mxll_ab_mask .or. &
340 bc%bc_ab_type(idim) == mxll_ab_mask_zero) then
341 string = trim(ab_type_str)//" Absorbing Boundary"
342 write(string,'(2a, f10.3,3a)') trim(string), " in "//dims(idim)//' direction spans from: ', &
343 units_from_atomic(units_inp%length, ab_bounds(1, idim) ), ' [', &
344 trim(units_abbrev(units_inp%length)), ']'
345 write(message(1),'(a)') trim(string)
346
347 string = "to "
348 write(string,'(a,f10.3,3a)') trim(string),&
349 units_from_atomic(units_inp%length, ab_bounds(2, idim) ), ' [', &
350 trim(units_abbrev(units_inp%length)), ']'
351
352 write(message(2),'(a)') trim(string)
353 call messages_info(2, namespace=namespace)
354 end if
355
356 class default
357
358 write(message(1),'(a,es10.3,3a)') &
359 " Lower bound = ", units_from_atomic(units_inp%length, ab_bounds(1, idim) ),&
360 ' [', trim(units_abbrev(units_inp%length)), ']'
361 write(message(2),'(a,es10.3,3a)') &
362 " Upper bound = ", units_from_atomic(units_inp%length, ab_bounds(2, idim) ),&
363 ' [', trim(units_abbrev(units_inp%length)), ']'
364 call messages_info(2, namespace=namespace)
365
366 end select
367
368 end do
369
370 ! initialization of surfaces
371 call maxwell_surfaces_init(gr, st, bounds)
372
373 ! mapping of mask boundary points
374 if (ab_mask_check) then
375 call maxwell_mask_points_mapping(bc, gr, ab_bounds)
376 end if
377
378 ! mapping of pml boundary points
379 if (ab_pml_check) then
380 call maxwell_pml_points_mapping(bc, gr, ab_bounds)
381 end if
382
383 ! mapping of constant boundary points
384 if (constant_check) then
385 call maxwell_constant_points_mapping(bc, gr, bounds)
386 end if
387
388 ! mapping of plane waves boundary points
389 if (plane_waves_check) then
390 call maxwell_plane_waves_points_mapping(bc, gr, bounds, namespace)
391 call external_waves_init(bc%plane_wave, namespace)
392 end if
393
394 ! mapping of zero points
395 if (zero_check) then
396 call maxwell_zero_points_mapping(bc, gr, bounds)
397 end if
398
399 if (ab_mask_check) then
400 call bc_mxll_generate_mask(bc, gr, ab_bounds)
401 end if
402
403 if (ab_pml_check) then
404 call bc_mxll_generate_pml(bc, space)
405 end if
406
407 !call bc_generate_zero(bc, gr, ab_bounds)
408
409 if (debug%info) call bc_mxll_write_info(bc, gr, namespace, space)
410
411 if (ab_mask_check .or. ab_pml_check) then
412 call messages_print_with_emphasis(namespace=namespace)
413 end if
414
415 call profiling_out('BC_MXLL_INIT')
416
417 pop_sub(bc_mxll_init)
418 end subroutine bc_mxll_init
419
420 ! ---------------------------------------------------------
421 subroutine bc_mxll_end(bc)
422 type(bc_mxll_t), intent(inout) :: bc
423
424 integer :: idim
425
426 push_sub(bc_mxll_end)
427
428 safe_deallocate_a(bc%ab_ufn)
429
430 safe_deallocate_a(bc%mask_points_map)
431 safe_deallocate_a(bc%mask)
432
433 safe_deallocate_a(bc%der_bndry_mask)
434 safe_deallocate_a(bc%der_bndry_mask_points_map)
435
436 call pml_end(bc%pml)
437 do idim = 1, 3
438 call single_medium_box_end(bc%medium(idim))
439 end do
440
441 safe_deallocate_a(bc%constant_points_map)
442 safe_deallocate_a(bc%constant_rs_state)
443 if (accel_is_enabled()) then
444 call accel_release_buffer(bc%buff_constant_points_map)
445 end if
446
447 safe_deallocate_a(bc%mirror_points_map)
448
449 call external_waves_end(bc%plane_wave)
450
451 safe_deallocate_a(bc%zero_points_map)
452 safe_deallocate_a(bc%zero)
453
454 pop_sub(bc_mxll_end)
455 end subroutine bc_mxll_end
456
457 ! ---------------------------------------------------------
458 subroutine pml_end(pml)
459 type(pml_t), intent(inout) :: pml
460
461 push_sub(pml_end)
462
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)
478 if (accel_is_enabled()) then
479 call accel_release_buffer(pml%buff_map)
480 call accel_release_buffer(pml%buff_a)
481 call accel_release_buffer(pml%buff_b)
482 call accel_release_buffer(pml%buff_c)
483 call accel_release_buffer(pml%buff_conv_plus)
484 call accel_release_buffer(pml%buff_conv_minus)
485 call accel_release_buffer(pml%buff_conv_plus_old)
486 end if
487
488
489 pop_sub(pml_end)
490 end subroutine pml_end
491
492
493
494 ! ---------------------------------------------------------
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
504
505 real(real64) :: width
506
507 push_sub(bc_mxll_medium_init)
508
509 call profiling_in('BC_MXLL_MEDIUM_INIT')
510
511 !%Variable MediumWidth
512 !%Type float
513 !%Default 0.0 a.u.
514 !%Section Maxwell::Boundaries
515 !%Description
516 !% Width of the boundary region with medium
517 !%End
518 call parse_variable(namespace, 'MediumWidth', m_zero, width, units_inp%length)
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)
522
523 !%Variable MediumEpsilonFactor
524 !%Type float
525 !%Default 1.0.
526 !%Section Maxwell::Boundaries
527 !%Description
528 !% Linear medium electric susceptibility.
529 !%End
530 call parse_variable(namespace, 'MediumpsilonFactor', m_one, ep_factor, unit_one)
531
532 !%Variable MediumMuFactor
533 !%Type float
534 !%Default 1.0
535 !%Section Maxwell::Boundaries
536 !%Description
537 !% Linear medium magnetic susceptibility.
538 !%End
539 call parse_variable(namespace, 'MediumMuFactor', m_one, mu_factor, unit_one)
540
541 !%Variable MediumElectricSigma
542 !%Type float
543 !%Default 0.
544 !%Section Maxwell::Boundaries
545 !%Description
546 !% Electric conductivity of the linear medium.
547 !%End
548
549 call parse_variable(namespace, 'MediumElectricSigma', m_zero, sigma_e_factor, unit_one)
550 !%Variable MediumMagneticSigma
551 !%Type float
552 !%Default 0.
553 !%Section Maxwell::Boundaries
554 !%Description
555 !% Magnetic conductivity of the linear medium.
556 !%End
557 call parse_variable(namespace, 'MediumMagneticSigma', m_zero, sigma_m_factor, unit_one)
558
559 call profiling_out('BC_MXLL_MEDIUM_INIT')
560
561 pop_sub(bc_mxll_medium_init)
562 end subroutine bc_mxll_medium_init
563
564 ! ---------------------------------------------------------
565 subroutine bc_mxll_ab_bounds_init(bc, gr, namespace, ab_bounds, idim)
566 type(bc_mxll_t), intent(inout) :: bc
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
571
572 real(real64) :: default_width
573
574 push_sub(bc_mxll_ab_bounds_init)
575
576 !%Variable MaxwellABWidth
577 !%Type float
578 !%Section Maxwell::Boundaries
579 !%Description
580 !% Width of the region used to apply the absorbing boundaries. The default value is twice
581 !% the derivative order.
582 !%End
583
584 default_width = m_two * gr%der%order * maxval(gr%spacing(1:3))
585 call parse_variable(namespace, 'MaxwellABWidth', default_width, bc%ab_width, units_inp%length)
586
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
591 call messages_info(2, namespace=namespace)
592 end if
593
594 ab_bounds(1, idim) = ab_bounds(2, idim) - bc%ab_width
595
597 end subroutine bc_mxll_ab_bounds_init
598
599 ! ---------------------------------------------------------
600 subroutine bc_mxll_pml_init(bc, gr, namespace, ab_bounds, idim)
601 type(bc_mxll_t), intent(inout) :: bc
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
606
607 push_sub(bc_mxll_pml_init)
608
609 call bc_mxll_ab_bounds_init(bc, gr, namespace, ab_bounds, idim)
610 bc%pml%width = bc%ab_width
611
612 !%Variable MaxwellABPMLPower
613 !%Type float
614 !%Default 3.5
615 !%Section Maxwell::Boundaries
616 !%Description
617 !% Exponential of the polynomial profile for the non-physical conductivity of the PML.
618 !% Should be between 2 and 4
619 !%End
620 call parse_variable(namespace, 'MaxwellABPMLPower', 3.5_real64, bc%pml%power, unit_one)
621
622 !%Variable MaxwellABPMLReflectionError
623 !%Type float
624 !%Default 1.0e-16
625 !%Section Maxwell::Boundaries
626 !%Description
627 !% Tolerated reflection error for the PML
628 !%End
629 call parse_variable(namespace, 'MaxwellABPMLReflectionError', 1.0e-16_real64, bc%pml%refl_error, unit_one)
630
631 pop_sub(bc_mxll_pml_init)
632 end subroutine bc_mxll_pml_init
633
634 ! ---------------------------------------------------------
635 subroutine bc_mxll_write_info(bc, mesh, namespace, space)
636 type(bc_mxll_t), intent(in) :: bc
637 class(mesh_t), intent(in) :: mesh
638 type(namespace_t), intent(in) :: namespace
639 class(space_t), intent(in) :: space
640
641 integer :: err, idim, idim2
642 real(real64), allocatable :: tmp(:)
643 logical :: mask_check, pml_check, medium_check
644 character(1) :: dim_label(3)
645
646 push_sub(bc_mxll_write_info)
647
648 call profiling_in('BC_MXLL_WRITE_INFO')
649
650 mask_check = .false.
651 pml_check = .false.
652 medium_check = .false.
653
654 dim_label = (/'x', 'y', 'z'/)
655
656 do idim = 1, 3
657 if (bc%bc_ab_type(idim) == mxll_ab_mask) then
658 mask_check = .true.
659 end if
660 if (bc%bc_ab_type(idim) == mxll_ab_cpml) then
661 pml_check = .true.
662 end if
663 if (bc%bc_ab_type(idim) == mxll_bc_medium) then
664 medium_check = .true.
665 end if
666 end do
667
668 if (mask_check) then
669 safe_allocate(tmp(1:mesh%np))
670 do idim = 1, 3
671 tmp(:) = m_zero
672 call get_mask_io_function(bc%mask, bc, tmp, idim)
673 call write_files("maxwell_mask", tmp)
674 end do
675 safe_deallocate_a(tmp)
676 else if (pml_check) then
677 safe_allocate(tmp(1:mesh%np))
678 do idim = 1, 3
679 ! sigma for electric field dim = idim
680 tmp(:) = m_one
681 call get_pml_io_function(bc%pml%sigma_e(:, idim), bc, tmp)
682 call write_files("maxwell_sigma_e-"//dim_label(idim), tmp)
683
684 ! sigma for magnetic dim = idim
685 tmp(:) = m_zero
686 call get_pml_io_function(bc%pml%sigma_m(:, 1), bc, tmp)
687 call write_files("maxwell_sigma_m-"//dim_label(idim), tmp)
688
689 ! pml_a for electric field dim = idim
690 tmp(:) = m_zero
691 call get_pml_io_function(real(bc%pml%a(:, idim), real64), bc, tmp)
692 call write_files("maxwell_sigma_pml_a_e-"//dim_label(idim), tmp)
693 end do
694 safe_deallocate_a(tmp)
695 end if
696
697 if (medium_check) then
698 safe_allocate(tmp(1:mesh%np))
699 do idim = 1, 3
700 ! medium epsilon
701 tmp(:) = p_ep
702 call get_medium_io_function(bc%medium(idim)%ep, bc, tmp, idim)
703 call write_files("maxwell_ep"//dim_label(idim), tmp)
704 ! medium mu
705 tmp(:) = p_mu
706 call get_medium_io_function(bc%medium(idim)%mu, bc, tmp, idim)
707 call write_files("maxwell_mu"//dim_label(idim), tmp)
708 ! medium epsilon
709 tmp(:) = p_c
710 call get_medium_io_function(bc%medium(idim)%c, bc, tmp, idim)
711 call write_files("maxwell_c"//dim_label(idim), tmp)
712 do idim2 = 1, 3
713 ! medium epsilon aux field dim = idim
714 tmp(:) = m_zero
715 call get_medium_io_function(bc%medium(idim)%aux_ep(:, idim2), bc, tmp, idim)
716 call write_files("maxwell_aux_ep-"//dim_label(idim)//"-"//dim_label(idim2), tmp)
717
718 ! medium mu aux field dim = idim
719 tmp(:) = m_zero
720 call get_medium_io_function(bc%medium(idim)%aux_mu(:, idim2), bc, tmp, idim)
721 call write_files("maxwell_aux_mu-"//dim_label(idim)//"-"//dim_label(idim2), tmp)
722 end do
723 end do
724
725 safe_deallocate_a(tmp)
726 end if
727
728 call profiling_out('BC_MXLL_WRITE_INFO')
729
730 pop_sub(bc_mxll_write_info)
731 contains
732
733 subroutine get_pml_io_function(pml_func, bc, io_func)
734 real(real64), intent(in) :: pml_func(:)
735 type(bc_mxll_t), intent(in) :: bc
736 real(real64), intent(inout) :: io_func(:)
737
738 integer :: ip, ip_in
739
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)
743 end do
744
745 end subroutine get_pml_io_function
746
747 subroutine get_mask_io_function(mask_func, bc, io_func, idim)
748 real(real64), intent(in) :: mask_func(:,:)
749 type(bc_mxll_t), intent(in) :: bc
750 real(real64), intent(inout) :: io_func(:)
751 integer, intent(in) :: idim
752
753 integer :: ip, ip_in
754
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)
758 end do
759
760 end subroutine get_mask_io_function
761
762 subroutine get_medium_io_function(medium_func, bc, io_func, idim)
763 real(real64), intent(in) :: medium_func(:)
764 type(bc_mxll_t), intent(in) :: bc
765 real(real64), intent(inout) :: io_func(:)
766 integer, intent(in) :: idim
767
768 integer :: ip, ip_in
769
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)
773 end do
774
775 end subroutine get_medium_io_function
776
777 subroutine write_files(filename, tmp)
778 character(len=*), intent(in) :: filename
779 real(real64), intent(in) :: tmp(:)
780
781 call dio_function_output(io_function_fill_how("VTK"), "./td.general", trim(filename), namespace, space, mesh, tmp, &
782 unit_one, err)
783 call dio_function_output(io_function_fill_how("AxisX"), "./td.general", trim(filename), namespace, space, mesh, tmp, &
784 unit_one, err)
785 call dio_function_output(io_function_fill_how("AxisY"), "./td.general", trim(filename), namespace, space, mesh, tmp, &
786 unit_one, err)
787 call dio_function_output(io_function_fill_how("AxisZ"), "./td.general", trim(filename), namespace, space, mesh, tmp, &
788 unit_one, err)
789 call dio_function_output(io_function_fill_how("PlaneX"), "./td.general", trim(filename), namespace, space, mesh, tmp, &
790 unit_one, err)
791 call dio_function_output(io_function_fill_how("PlaneY"), "./td.general", trim(filename), namespace, space, mesh, tmp, &
792 unit_one, err)
793 call dio_function_output(io_function_fill_how("PlaneZ"), "./td.general", trim(filename), namespace, space, mesh, tmp, &
794 unit_one, err)
795 end subroutine write_files
796
797 end subroutine bc_mxll_write_info
798
799 ! ---------------------------------------------------------
800 subroutine maxwell_mask_points_mapping(bc, mesh, bounds)
801 type(bc_mxll_t), intent(inout) :: bc
802 class(mesh_t), intent(in) :: mesh
803 real(real64), intent(in) :: bounds(:,:)
804
805 integer :: ip, ip_in, ip_in_max, point_info, idim
806
808
809 call profiling_in('MAXWELL_MASK_POINTS_MAPPING')
810 ip_in_max = 1
811 do idim = 1, 3
812 if (bc%bc_ab_type(idim) == mxll_ab_mask) then
813 ! allocate mask points map
814 ip_in = 0
815 do ip = 1, mesh%np
816 call maxwell_box_point_info(bc, mesh, ip, bounds, point_info)
817 if ((point_info == 1) .and. (abs(mesh%x(ip, idim)) >= bounds(1, idim))) then
818 ip_in = ip_in + 1
819 end if
820 end do
821 if (ip_in > ip_in_max) ip_in_max = ip_in
822 bc%mask_points_number(idim) = ip_in
823 end if
824 end do
825 safe_allocate(bc%mask(1:ip_in_max, 1:idim))
826 safe_allocate(bc%mask_points_map(1:ip_in_max, 1:idim))
827
828 do idim = 1, 3
829 if (bc%bc_ab_type(idim) == mxll_ab_mask) then
830 ! mask points mapping
831 ip_in = 0
832 do ip = 1, mesh%np
833 call maxwell_box_point_info(bc, mesh, ip, bounds, point_info)
834 if ((point_info == 1) .and. (abs(mesh%x(ip, idim)) >= bounds(1, idim))) then
835 ip_in = ip_in + 1
836 bc%mask_points_map(ip_in, idim) = ip
837 end if
838 end do
839 end if
840 end do
841
842 call profiling_out('MAXWELL_MASK_POINTS_MAPPING')
844 end subroutine maxwell_mask_points_mapping
845
846 ! ---------------------------------------------------------
847 subroutine maxwell_pml_points_mapping(bc, mesh, bounds)
848 type(bc_mxll_t), intent(inout) :: bc
849 class(mesh_t), intent(in) :: mesh
850 real(real64), intent(in) :: bounds(:,:)
851
852 integer :: ip, ip_in, point_info
853
856 call profiling_in('MXWL_PML_POINTS_MAPPING')
857
858 ! allocate pml points map
859 ip_in = 0
860 do ip = 1, mesh%np
861 call maxwell_box_point_info(bc, mesh, ip, bounds, point_info)
862 if (point_info == 1) then
863 ip_in = ip_in + 1
864 end if
865 end do
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
870 ip_in = 0
871 do ip = 1, mesh%np
872 call maxwell_box_point_info(bc, mesh, ip, bounds, point_info)
873 if (point_info == 1) then
874 ip_in = ip_in + 1
875 bc%pml%points_map(ip_in) = ip
876 bc%pml%points_map_inv(ip) = ip_in
877 end if
878 end do
879
880 call profiling_out('MXWL_PML_POINTS_MAPPING')
881
883 end subroutine maxwell_pml_points_mapping
884
885 ! ---------------------------------------------------------
886 subroutine maxwell_constant_points_mapping(bc, mesh, bounds)
887 type(bc_mxll_t), intent(inout) :: bc
888 class(mesh_t), intent(in) :: mesh
889 real(real64), intent(in) :: bounds(:,:)
890
891 integer :: ip, ip_in, point_info
892
894
895 call profiling_in('MAXWELL_CONSTANT_POINTS_MAP')
896
897 ! allocate constant points map
898 ip_in = 0
899 do ip = 1, mesh%np
900 call maxwell_box_point_info(bc, mesh, ip, bounds, point_info)
901 if (point_info == 1) then
902 ip_in = ip_in + 1
903 end if
904 end do
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))
908
909 ! zero constant mapping
910 ip_in = 0
911 do ip = 1, mesh%np
912 call maxwell_box_point_info(bc, mesh, ip, bounds, point_info)
913 if (point_info == 1) then
914 ip_in = ip_in + 1
915 bc%constant_points_map(ip_in) = ip
916 end if
917 end do
918
919 if (accel_is_enabled()) then
920 call accel_create_buffer(bc%buff_constant_points_map, accel_mem_read_only, type_integer, bc%constant_points_number)
921 call accel_write_buffer(bc%buff_constant_points_map, bc%constant_points_number, bc%constant_points_map)
922 end if
923
924 call profiling_out('MAXWELL_CONSTANT_POINTS_MAP')
925
928
929 ! ---------------------------------------------------------
930 subroutine maxwell_plane_waves_points_mapping(bc, mesh, bounds, namespace)
931 type(bc_mxll_t), intent(inout) :: bc
932 class(mesh_t), intent(in) :: mesh
933 real(real64), intent(in) :: bounds(:,:)
934 type(namespace_t), intent(in) :: namespace
935
936 integer :: ip, ip_in, point_info
937
939
940 call profiling_in('MXLL_PW_POINTS_MAP')
941
942 bc%plane_waves_dims = (bc%bc_type(1:3) == mxll_bc_plane_waves)
943
944 ! allocate map
945 ip_in = 0
946 do ip = 1, mesh%np
947 call maxwell_box_point_info(bc, mesh, ip, bounds, point_info)
948 if (point_info == 1) then
949 ip_in = ip_in + 1
950 end if
951 end do
952 bc%plane_wave%points_number = ip_in
953 safe_allocate(bc%plane_wave%points_map(1:ip_in))
954
955 ! mapping
956 ip_in = 0
957 do ip = 1, mesh%np
958 call maxwell_box_point_info(bc, mesh, ip, bounds, point_info)
959 if (point_info == 1) then
960 ip_in = ip_in + 1
961 bc%plane_wave%points_map(ip_in) = ip
962 end if
963 end do
964
965 if (accel_is_enabled()) then
966 call accel_create_buffer(bc%plane_wave%buff_map, accel_mem_read_only, type_integer, bc%plane_wave%points_number)
967 call accel_write_buffer(bc%plane_wave%buff_map, bc%plane_wave%points_number, bc%plane_wave%points_map)
968 end if
969
970 call profiling_out('MXLL_PW_POINTS_MAP')
971
974
975 ! ---------------------------------------------------------
976 subroutine maxwell_zero_points_mapping(bc, mesh, bounds)
977 type(bc_mxll_t), intent(inout) :: bc
978 class(mesh_t), intent(in) :: mesh
979 real(real64), intent(in) :: bounds(:,:)
980
981 integer :: ip, ip_in, ip_in_max, point_info, idim
982
984
985 call profiling_in('MXLL_ZERO_POINTS_MAPPING')
986
987 ip_in_max = 0
988 do idim = 1, 3
989 if (bc%bc_type(idim) == mxll_bc_zero) then
990 ! allocate zero points map
991 ip_in = 0
992 do ip = 1, mesh%np
993 call maxwell_box_point_info(bc, mesh, ip, bounds, point_info)
994 if ((point_info == 1) .and. (abs(mesh%x(ip, idim)) >= bounds(1, idim))) then
995 ip_in = ip_in + 1
996 end if
997 end do
998 if (ip_in > ip_in_max) ip_in_max = ip_in
999 end if
1000 end do
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))
1004
1005 do idim = 1, 3
1006 if (bc%bc_type(idim) == mxll_bc_zero) then
1007 ! zero points mapping
1008 ip_in = 0
1009 do ip = 1, mesh%np
1010 call maxwell_box_point_info(bc, mesh, ip, bounds, point_info)
1011 if ((point_info == 1) .and. (abs(mesh%x(ip, idim)) >= bounds(1, idim))) then
1012 ip_in = ip_in + 1
1013 bc%zero_points_map(ip_in, idim) = ip
1014 end if
1015 end do
1016 end if
1017 end do
1018
1019 call profiling_out('MXLL_ZERO_POINTS_MAPPING')
1020
1022 end subroutine maxwell_zero_points_mapping
1024 ! ---------------------------------------------------------
1025 subroutine maxwell_medium_points_mapping(bc, mesh, bounds)
1026 type(bc_mxll_t), intent(inout) :: bc
1027 class(mesh_t), intent(in) :: mesh
1028 real(real64), intent(in) :: bounds(:,:)
1029
1030 integer :: ip, ip_in, ip_in_max, ip_bd, ip_bd_max, point_info, boundary_info, idim
1031
1033
1034 call profiling_in('MXLL_MEDIUM_POINTS_MAPPING')
1035
1036 ip_in_max = 0
1037 ip_bd_max = 0
1038 do idim = 1, 3
1039 if (bc%bc_type(idim) == mxll_bc_medium) then
1040 ! allocate pml points map
1041 ip_in = 0
1042 ip_bd = 0
1043 do ip = 1, mesh%np
1044 call maxwell_box_point_info(bc, mesh, ip, bounds, point_info)
1045 call maxwell_boundary_point_info(mesh, ip, bounds, boundary_info)
1046 if ((point_info == 1) .and. (abs(mesh%x(ip, idim)) >= bounds(1, idim))) then
1047 ip_in = ip_in + 1
1048 end if
1049 if ((boundary_info == 1) .and. (abs(mesh%x(ip, idim)) >= bounds(1, idim))) then
1050 ip_bd = ip_bd + 1
1051 end if
1052 end do
1053 bc%medium(idim)%points_number = ip_in
1054 bc%medium(idim)%bdry_number = ip_bd
1055 end if
1056 end do
1057 do idim = 1, 3
1058 safe_allocate(bc%medium(idim)%points_map(1:ip_in_max))
1059 safe_allocate(bc%medium(idim)%bdry_map(1:ip_bd_max))
1060 end do
1061
1062 ip_in = 0
1063 ip_bd = 0
1064 do idim = 1, 3
1065 if (bc%bc_type(idim) == mxll_bc_medium) then
1066 do ip = 1, mesh%np
1067 call maxwell_box_point_info(bc, mesh, ip, bounds, point_info)
1068 call maxwell_boundary_point_info(mesh, ip, bounds, boundary_info)
1069 if ((point_info == 1) .and. (abs(mesh%x(ip, idim)) >= bounds(1, idim))) then
1070 ip_in = ip_in + 1
1071 bc%medium(idim)%points_map(ip_in) = ip
1072 end if
1073 if ((boundary_info == 1) .and. (abs(mesh%x(ip, idim)) >= bounds(1, idim))) then
1074 ip_bd = ip_bd + 1
1075 bc%medium(idim)%bdry_map(ip_bd) = ip
1076 end if
1077 end do
1078 end if
1079 end do
1080
1081 call profiling_out('MXLL_MEDIUM_POINTS_MAPPING')
1082
1084 end subroutine maxwell_medium_points_mapping
1085
1086 ! ---------------------------------------------------------
1087 subroutine bc_mxll_generate_pml(bc, space)
1088 type(bc_mxll_t), intent(inout) :: bc
1089 class(space_t), intent(in) :: space
1090
1091
1092 push_sub(bc_mxll_generate_pml)
1093
1094 call profiling_in('BC_MXLL_GENERATE_PML')
1095
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))
1109
1110 bc%pml%kappa = m_one
1111 bc%pml%sigma_e = m_zero
1112 bc%pml%sigma_m = m_zero
1113 bc%pml%a = m_zero
1114 bc%pml%b = m_zero
1115 bc%pml%c = m_zero
1116 bc%pml%mask = m_one
1117 bc%pml%conv_plus = m_z0
1118 bc%pml%conv_minus = m_z0
1119 bc%pml%conv_plus_old = m_z0
1120 bc%pml%conv_minus_old = m_z0
1121
1122 if (accel_is_enabled()) then
1123 call accel_create_buffer(bc%pml%buff_map, accel_mem_read_only, type_integer, bc%pml%points_number)
1124 call accel_create_buffer(bc%pml%buff_a, accel_mem_read_only, type_float, int(bc%pml%points_number, int64)*space%dim)
1125 call accel_create_buffer(bc%pml%buff_b, accel_mem_read_only, type_float, int(bc%pml%points_number, int64)*space%dim)
1126 call accel_create_buffer(bc%pml%buff_c, accel_mem_read_only, type_float, int(bc%pml%points_number, int64)*space%dim)
1127 call accel_create_buffer(bc%pml%buff_conv_plus, accel_mem_read_write, type_cmplx, &
1128 int(bc%pml%points_number, int64)*space%dim*space%dim)
1129 call accel_create_buffer(bc%pml%buff_conv_minus, accel_mem_read_write, type_cmplx, &
1130 int(bc%pml%points_number, int64)*space%dim*space%dim)
1131 call accel_create_buffer(bc%pml%buff_conv_plus_old, accel_mem_read_write, type_cmplx, &
1132 int(bc%pml%points_number, int64)*space%dim*space%dim)
1133
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)
1140 end if
1141
1142 call profiling_out('BC_MXLL_GENERATE_PML')
1143
1144 pop_sub(bc_mxll_generate_pml)
1145 end subroutine bc_mxll_generate_pml
1146
1147
1148 ! ---------------------------------------------------------
1149 subroutine bc_mxll_generate_pml_parameters(bc, space, gr, c_factor, dt)
1150 type(bc_mxll_t), intent(inout) :: bc
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
1155
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(:,:)
1160
1161
1163 safe_allocate(tmp(gr%np_part))
1164 safe_allocate(tmp_grad(gr%np, 1:space%dim))
1165 ! here bounds are ab_bounds, for which ab_bounds(1,:) = bc%bounds(1,:)
1166 ! width is stored in bc%pml%width
1167 ! assuming that the width is the same in the 3 dimensions (only case implemented now), we can change the following line:
1168 ! width(1:3) = bounds(2, 1:3) - bounds(1, 1:3) !! original line
1169 ! by
1170 width(1:3) = (/ bc%pml%width, bc%pml%width, bc%pml%width /)
1171
1172 ! PML variables for all boundary points
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)
1182 ss_e = gg * ss_max
1183 ss_m = gg * ss_max
1184 ll_e = ss_e*kk
1185 ll_m = ss_m*kk
1186 bb_e = exp(-(ss_e/(p_ep))*dt)
1187 bb_m = exp(-(ss_m/(p_ep))*dt)
1188 aa_e = (bb_e - 1)
1189 aa_m = (bb_m - 1)
1190 if (abs(ll_e) < m_epsilon) aa_e = m_zero
1191 if (abs(ll_m) < m_epsilon) aa_m = m_zero
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)
1198 else
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
1205 end if
1206 end do
1207 end do
1208
1209 ! PML auxiliary epsilon for all boundary points
1210 do idim = 1, space%dim
1211 tmp = p_ep
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)
1215 end do
1216 call dderivatives_grad(gr%der, tmp, tmp_grad, set_bc = .false.)
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))
1220 end do
1221 end do
1222
1223 ! PML auxiliary mu
1224 do idim = 1, space%dim
1225 ! P_mu is proportional to 1/P_c**2, so we need to devide by c_factor
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)
1230 end do
1231 call dderivatives_grad(gr%der, tmp, tmp_grad, set_bc = .false.)
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))
1235 end do
1236 end do
1237
1238 ! PML auxiliary c for all boundary points
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)
1242 end do
1243 end do
1244 safe_deallocate_a(tmp)
1245 safe_deallocate_a(tmp_grad)
1246
1247 if (accel_is_enabled()) then
1248 call accel_write_buffer(bc%pml%buff_map, bc%pml%points_number, bc%pml%points_map)
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)
1254 end if
1255
1256 bc%pml%parameters_initialized = .true.
1257
1259
1260 end subroutine bc_mxll_generate_pml_parameters
1261
1262 ! ---------------------------------------------------------
1263 subroutine bc_mxll_initialize_pml_simple(bc, space, gr, c_factor, dt)
1264 type(bc_mxll_t), intent(inout) :: bc
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
1269
1270 integer :: ip_in, ip, idir
1271 real(real64) :: ddv(1:space%dim), kappa, sigma, alpha
1273
1274 ! PML variables for all boundary points
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 * &
1281 -(bc%pml%power + m_one)*p_c*c_factor*p_ep*log(bc%pml%refl_error)/(m_two * bc%pml%width)
1282 ! kappa and alpha could be set to different values, but these seem to be fine
1283 kappa = m_one
1284 ! non-zero values for alpha can be used to modify the low-frequency behavior
1285 alpha = m_zero
1286 bc%pml%b(ip_in, idir) = exp(-(alpha + sigma/kappa)/p_ep*dt)
1287 if (abs(sigma) < m_epsilon) then
1288 bc%pml%c(ip_in, idir) = m_zero
1289 else
1290 bc%pml%c(ip_in, idir) = m_one/(kappa + kappa**2*alpha/sigma) * &
1291 (bc%pml%b(ip_in, idir) - 1)
1292 end if
1293 else
1294 bc%pml%b(ip_in, idir) = m_zero
1295 bc%pml%c(ip_in, idir) = m_zero
1296 end if
1297 end do
1298 end do
1299 if (accel_is_enabled()) then
1300 call accel_write_buffer(bc%pml%buff_map, &
1301 bc%pml%points_number, bc%pml%points_map)
1302 call accel_write_buffer(bc%pml%buff_b, &
1303 int(bc%pml%points_number, int64)*space%dim, bc%pml%b)
1304 call accel_write_buffer(bc%pml%buff_c, &
1305 int(bc%pml%points_number, int64)*space%dim, bc%pml%c)
1306 end if
1308 end subroutine bc_mxll_initialize_pml_simple
1309
1310 ! ---------------------------------------------------------
1311 subroutine bc_mxll_generate_mask(bc, mesh, bounds)
1312 type(bc_mxll_t), intent(inout) :: bc
1313 class(mesh_t), intent(in) :: mesh
1314 real(real64), intent(in) :: bounds(:,:)
1315
1316 integer :: ip, ip_in, idim, ip_in_max
1317 real(real64) :: ddv(3), tmp(3), width(3)
1318 real(real64), allocatable :: mask(:)
1319
1320 push_sub(bc_mxll_generate_mask)
1321
1322 call profiling_in('BC_MXLL_GENERATE_MASK')
1323
1324 ip_in_max = maxval(bc%mask_points_number(:))
1325
1326 safe_allocate(mask(1:mesh%np))
1327
1328 mask(:) = m_one
1329
1330 width(1:3) = bounds(2, 1:3) - bounds(1, 1:3)
1331 tmp(:) = m_zero
1332
1333 do ip = 1, mesh%np
1334 tmp = m_one
1335 mask(ip) = m_one
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
1340 tmp(idim) = m_one - sin(ddv(idim) * m_pi / (m_two * (width(idim))))**2
1341 else
1342 tmp(idim) = m_one
1343 end if
1344 end if
1345 mask(ip) = mask(ip) * tmp(idim)
1346 end do
1347 end do
1348
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)
1353 end do
1354 end do
1355
1356 safe_deallocate_a(mask)
1357
1358 call profiling_out('BC_MXLL_GENERATE_MASK')
1359
1360 pop_sub(bc_mxll_generate_mask)
1361 end subroutine bc_mxll_generate_mask
1362
1363 ! ---------------------------------------------------------
1364 subroutine bc_mxll_generate_medium(bc, space, gr, bounds, ep_factor, mu_factor, sigma_e_factor, sigma_m_factor)
1365 type(bc_mxll_t), intent(inout) :: bc
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
1373
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(:,:)
1377
1378 push_sub(bc_mxll_generate_medium)
1379
1380 call profiling_in('BC_MXLL_GENERATE_MEDIUM')
1381
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))
1384
1385 do idim = 1, 3
1386 call single_medium_box_allocate(bc%medium(idim), ip_in_max)
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
1392
1393 tmp = p_ep
1394 do ip = 1, gr%np_part
1395 call maxwell_box_point_info(bc, gr, ip, bounds, point_info)
1396 if ((point_info /= 0) .and. (abs(gr%x(ip, idim)) <= bounds(1, idim))) then
1397 xx(:) = gr%x(ip, :)
1398 dd_min = m_huge
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
1404 end do
1405 tmp(ip) = p_ep * (m_one + ep_factor * m_one/(m_one + exp(-m_five/dd_max * (dd_min-m_two*dd_max))))
1406 end if
1407 end do
1408 call dderivatives_grad(gr%der, tmp, tmp_grad, set_bc = .false.)
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, :) = &
1412 tmp_grad(ip, :)/(m_four*p_ep*ep_factor * m_one/(m_one + exp(-m_five/dd_max-dd)))
1413 end do
1414 end do
1415
1416 do idim = 1, 3
1417 tmp = p_mu
1418 do ip = 1, gr%np_part
1419 call maxwell_box_point_info(bc, gr, ip, bounds, point_info)
1420 if ((point_info == 1) .and. (abs(gr%x(ip, idim)) <= bounds(1, idim))) then
1421 xx(:) = gr%x(ip, :)
1422 dd_min = m_huge
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
1428 end do
1429 tmp(ip) = p_mu * (m_one + mu_factor * m_one/(m_one + exp(-m_five/dd_max * (dd_min - m_two*dd_max))))
1430 end if
1431 end do
1432 call dderivatives_grad(gr%der, tmp, tmp_grad, set_bc = .false.)
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, :) = &
1436 tmp_grad(ip, :)/(m_four * p_mu * mu_factor * m_one/(m_one + exp(-m_five/dd_max-dd)))
1437 end do
1438 end do
1439
1440 do idim = 1, 3
1441 do ip_in = 1, bc%medium(idim)%points_number
1442 ip = bc%medium(idim)%points_map(ip_in)
1443 xx(:) = gr%x(ip, :)
1444 dd_min = m_huge
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
1450 end do
1451 bc%medium(idim)%ep(ip_in) = p_ep * (m_one + ep_factor &
1452 * m_one/(m_one + exp(-m_five / dd_max * (dd_min - m_two * dd_max))))
1453 bc%medium(idim)%mu(ip_in) = p_mu * (m_one + mu_factor &
1454 * m_one/(m_one + exp(-m_five / dd_max * (dd_min - m_two * dd_max))))
1455 bc%medium(idim)%sigma_e(ip_in) = (m_one + sigma_e_factor &
1456 * m_one/(m_one + exp(-m_five / dd_max * (dd_min - m_two * dd_max))))
1457 bc%medium(idim)%sigma_m(ip_in) = (m_one + sigma_m_factor &
1458 * m_one/(m_one + exp(-m_five / dd_max * (dd_min - m_two * dd_max))))
1459 bc%medium(idim)%c(ip_in) = m_one / sqrt(bc%medium(idim)%ep(ip_in) * bc%medium(idim)%mu(ip_in))
1460 end do
1461 end do
1462
1463 safe_deallocate_a(tmp)
1464 safe_deallocate_a(tmp_grad)
1465
1466 call profiling_out('BC_MXLL_GENERATE_MEDIUM')
1467
1469 end subroutine bc_mxll_generate_medium
1470
1471 ! ---------------------------------------------------------
1472 subroutine maxwell_surfaces_init(mesh, st, bounds)
1473 class(mesh_t), intent(in) :: mesh
1474 type(states_mxll_t), intent(inout) :: st
1475 real(real64), intent(in) :: bounds(:,:)
1476
1477
1478 push_sub(maxwell_surfaces_init)
1479
1480 call profiling_in('MAXWELL_SURFACES_INIT')
1481
1482 ! y-z surface at -x boundary
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))
1496
1497 ! y-z surface at +x boundary
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))
1511
1512 ! x-z surface at -y boundary
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))
1526
1527 ! x-z surface at +y boundary
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))
1541
1542 ! x-y surface at -z boundary
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))
1556
1557 ! x-y surface at +z boundary
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
1565 st%surface(2, 3)%v(:) = m_zero
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))
1571
1572 call profiling_out('MAXWELL_SURFACES_INIT')
1573
1574 pop_sub(maxwell_surfaces_init)
1575 end subroutine maxwell_surfaces_init
1576
1577 ! ---------------------------------------------------------
1578 subroutine maxwell_box_point_info(bc, mesh, ip, bounds, point_info)
1579 type(bc_mxll_t), intent(inout) :: bc
1580 class(mesh_t), intent(in) :: mesh
1581 integer, intent(in) :: ip
1582 real(real64), intent(in) :: bounds(:,:)
1583 integer, intent(out) :: point_info
1584
1585 real(real64) :: rr, dd, xx(3), width(3)
1586
1587 point_info = 0
1588
1589 width(1:3) = bounds(2, 1:3) - bounds(1, 1:3)
1590 xx = m_zero
1591 xx(1:mesh%box%dim) = mesh%x(ip, 1:mesh%box%dim)
1592
1593 if (bc%ab_user_def) then
1594
1595 dd = bc%ab_ufn(ip) - bounds(1, 1)
1596 if (dd > m_zero) then
1597 if (bc%ab_ufn(ip) < bounds(2, 1)) then
1598 point_info = 1
1599 end if
1600 end if
1601
1602 else ! bc%ab_user_def == .false.
1603
1604 select type (box => mesh%box)
1605 type is (box_sphere_t)
1606 rr = norm2(xx - box%center)
1607 dd = rr - bounds(1, 1)
1608 if (dd > m_zero) then
1609 if (dd < width(1)) then
1610 point_info = 1
1611 end if
1612 end if
1613
1614 type is (box_parallelepiped_t)
1615 ! Limits of boundary region
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
1618 point_info = 1
1619 else
1620 point_info = 0
1621 end if
1622 else
1623 point_info = -1
1624 end if
1625
1626 class default
1627 ! Other box shapes are not supported.
1628 assert(.false.)
1629 end select
1630 end if
1631
1632 end subroutine maxwell_box_point_info
1633
1634 ! ---------------------------------------------------------
1635 subroutine maxwell_boundary_point_info(mesh, ip, bounds, boundary_info)
1636 class(mesh_t), intent(in) :: mesh
1637 integer, intent(in) :: ip
1638 real(real64), intent(in) :: bounds(:,:)
1639 integer, intent(out) :: boundary_info
1640
1641 real(real64) :: xx(3)
1642
1643 boundary_info = 0
1644
1645 xx = m_zero
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
1650 boundary_info = 1
1651 else
1652 boundary_info = 0
1653 end if
1654
1655 end subroutine maxwell_boundary_point_info
1656
1657 ! ---------------------------------------------------------
1658 subroutine inner_and_outer_points_mapping(mesh, st, bounds)
1659 class(mesh_t), intent(in) :: mesh
1660 type(states_mxll_t), intent(inout) :: st
1661 real(real64), intent(in) :: bounds(:,:)
1662
1663 integer :: ip, ip_in, ip_bd, point_info
1664 real(real64) :: xx(mesh%box%dim)
1665
1667
1668 call profiling_in('IN_OUT_POINTS_MAP')
1669
1670 ! allocate inner and boundary points points map
1671 ip_in = 0
1672 ip_bd = 0
1673 do ip = 1, mesh%np
1674 xx = mesh%x(ip, :)
1675 if (all(abs(xx) <= bounds(2,1:mesh%box%dim))) then
1676 if (any(abs(xx) > bounds(1,1:mesh%box%dim))) then
1677 point_info = 1
1678 else
1679 point_info = 0
1680 end if
1681 else
1682 point_info = -1
1683 end if
1684 if (point_info == 0) then
1685 ip_in = ip_in + 1
1686 else
1687 ip_bd = ip_bd + 1
1688 end if
1689 end do
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.
1698
1699 ! inner and boundary points mapping
1700 ip_in = 0
1701 ip_bd = 0
1702 do ip = 1, mesh%np
1703 xx = mesh%x(ip, :)
1704 if (all(abs(xx) <= bounds(2,1:mesh%box%dim))) then
1705 if (any(abs(xx) > bounds(1,1:mesh%box%dim))) then
1706 point_info = 1
1707 else
1708 point_info = 0
1709 end if
1710 else
1711 point_info = -1
1712 end if
1713 if (point_info == 0) then
1714 ip_in = ip_in + 1
1715 st%inner_points_map(ip_in) = ip
1716 st%inner_points_mask(ip) = .true.
1717 else
1718 ip_bd = ip_bd + 1
1719 st%boundary_points_map(ip_bd) = ip
1720 st%boundary_points_mask(ip) = .true.
1721 end if
1722 end do
1723
1724 if (accel_is_enabled()) then
1725 call accel_create_buffer(st%buff_inner_points_map, accel_mem_read_only, type_integer, st%inner_points_number)
1726 call accel_write_buffer(st%buff_inner_points_map, st%inner_points_number, st%inner_points_map)
1727 call accel_create_buffer(st%buff_boundary_points_map, accel_mem_read_only, type_integer, st%boundary_points_number)
1728 call accel_write_buffer(st%buff_boundary_points_map, st%boundary_points_number, st%boundary_points_map)
1729 end if
1730
1731 call profiling_out('IN_OUT_POINTS_MAP')
1732
1734 end subroutine inner_and_outer_points_mapping
1735
1736 ! ---------------------------------------------------------
1737 subroutine surface_grid_points_mapping(mesh, st, bounds)
1738 class(mesh_t), intent(in) :: mesh
1739 type(states_mxll_t), intent(inout) :: st
1740 real(real64), intent(in) :: bounds(:,:)
1741
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)
1746
1748
1749 call profiling_in('SURF_GRID_POINTS_MAPPING')
1750
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)
1757
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)
1761
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)
1765
1766 safe_allocate(nn(1:2, 1:3, 1:3, 1:3))
1767
1768 st%surface_grid_center(1, 1, :, :) = -int(bounds(1,1))
1769 do iy = 1, iy_max
1770 do iz = 1, iz_max
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))
1775 end do
1776 end do
1777 st%surface_grid_center(2, 1, :, :) = int(bounds(1,1))
1778 do iy = 1, iy_max
1779 do iz = 1, iz_max
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))
1784 end do
1785 end do
1786
1787 st%surface_grid_center(1, 2, :, :) = -int(bounds(1,2))
1788 do ix = 1, ix_max
1789 do iz = 1, iz_max
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))
1794 end do
1795 end do
1796 st%surface_grid_center(2, 2, :, :) = int(bounds(1,2))
1797 do ix = 1, ix_max
1798 do iz = 1, iz_max
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))
1803 end do
1804 end do
1805
1806 st%surface_grid_center(1, 3, :, :) = -int(bounds(1,3))
1807 do ix = 1, ix_max
1808 do iy = 1, iy_max
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))
1813 end do
1814 end do
1815 st%surface_grid_center(2, 3, :, :) = int(bounds(1,3))
1816 do ix = 1, ix_max
1817 do iy = 1, iy_max
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))
1822 end do
1823 end do
1824
1825 st%surface_grid_points_number(:,:,:) = 0
1826
1827 nn_max = 0
1828
1829 do iy = 1, iy_max
1830 do iz = 1, iz_max
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)
1835 end do
1836 end do
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)
1841 call get_surface_indices(vec, min_1, max_1, min_2, max_2, idx1, idx2)
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)
1846 end if
1847 end if
1848 end do
1849 end do
1850
1851 do ix = 1, ix_max
1852 do iz = 1, iz_max
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)
1857 end do
1858 end do
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)
1863 call get_surface_indices(vec, min_1, max_1, min_2, max_2, idx1, idx2)
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)
1868 end if
1869 end if
1870 end do
1871 end do
1872
1873 do ix = 1, ix_max
1874 do iy = 1, iy_max
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)
1879 end do
1880 end do
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)
1885 call get_surface_indices(vec, min_1, max_1, min_2, max_2, idx1, idx2)
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)
1890 end if
1891 end if
1892 end do
1893 end do
1894
1895 ! originally there were three allocated of the same pointer here
1896 safe_allocate(st%surface_grid_points_map(1:2, 1:st%dim, 1:ix_max, 1:iy_max, 1:nn_max))
1897
1898 nn(:,:,:,:) = 0
1899
1900 do iy = 1, iy_max
1901 do iz = 1, iz_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)
1906 end do
1907 end do
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)
1912 call get_surface_indices(vec, min_1, max_1, min_2, max_2, idx1, idx2)
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))
1919 ip_global = mesh_global_index_from_coords(mesh, [iix, iiy, iiz])
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
1922 rr(1) = bounds(1,1)
1923 rr(2) = iiy * mesh%spacing(2)
1924 rr(3) = iiz * mesh%spacing(3)
1925 iix = int(bounds(1,1)/mesh%spacing(1))
1926 ip_global = mesh_global_index_from_coords(mesh, [iix, iiy, iiz])
1927 st%surface_grid_points_map(2, 1, idx1, idx2, nn(2, 1, idx1, idx2)) = ip_global
1928 end if
1929 end do
1930 end do
1931
1932 do ix = 1, ix_max
1933 do iz = 1, iz_max
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)
1938 end do
1939 end do
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)
1944 call get_surface_indices(vec, min_1, max_1, min_2, max_2, idx1, idx2)
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))
1951 ip_global = mesh_global_index_from_coords(mesh, [iix, iiy, iiz])
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)
1955 rr(2) = bounds(1,2)
1956 rr(3) = iiz * mesh%spacing(3)
1957 iiy = int(bounds(1,2)/mesh%spacing(2))
1958 ip_global = mesh_global_index_from_coords(mesh, [iix, iiy, iiz])
1959 st%surface_grid_points_map(2, 2, idx1, idx2, nn(2, 2, idx1, idx2)) = ip_global
1960 end if
1961 end do
1962 end do
1963
1964 do ix = 1, ix_max
1965 do iy = 1, iy_max
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)
1970 end do
1971 end do
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)
1976 call get_surface_indices(vec, min_1, max_1, min_2, max_2, idx1, idx2)
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))
1983 ip_global = mesh_global_index_from_coords(mesh, [iix, iiy, iiz])
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)
1988 rr(3) = bounds(1,3)
1989 iiz = int(bounds(1,3)/mesh%spacing(3))
1990 ip_global = mesh_global_index_from_coords(mesh, [iix, iiy, iiz])
1991 st%surface_grid_points_map(2, 3, idx1, idx2, nn(2, 3, idx1, idx2)) = ip_global
1992 end if
1993 end do
1994 end do
1995
1996 safe_deallocate_a(nn)
1997
1998 call profiling_out('SURF_GRID_POINTS_MAPPING')
1999
2001 contains
2002
2003 subroutine get_surface_indices(vec, min_1, max_1, min_2, max_2, index_1, index_2)
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
2011
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
2013 index_1 = 1
2014 index_2 = 1
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
2016 index_1 = 2
2017 index_2 = 1
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
2019 index_1 = 3
2020 index_2 = 1
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
2022 index_1 = 1
2023 index_2 = 2
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
2025 index_1 = 2
2026 index_2 = 2
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
2028 index_1 = 3
2029 index_2 = 2
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
2031 index_1 = 1
2032 index_2 = 3
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
2034 index_1 = 2
2035 index_2 = 3
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
2037 index_1 = 3
2038 index_2 = 3
2039 else
2040 index_1 = 0
2041 index_2 = 0
2042 end if
2043
2044 end subroutine get_surface_indices
2045
2046 end subroutine surface_grid_points_mapping
2047
2049
2050!! Local Variables:
2051!! mode: f90
2052!! coding: utf-8
2053!! End:
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
Definition: accel.F90:183
subroutine, public accel_release_buffer(this)
Definition: accel.F90:1246
pure logical function, public accel_is_enabled()
Definition: accel.F90:400
integer, parameter, public accel_mem_read_only
Definition: accel.F90:183
type(debug_t), save, public debug
Definition: debug.F90:154
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
Definition: global.F90:189
real(real64), parameter, public m_huge
Definition: global.F90:205
real(real64), parameter, public m_zero
Definition: global.F90:187
real(real64), parameter, public m_four
Definition: global.F90:191
real(real64), parameter, public m_pi
some mathematical constants
Definition: global.F90:185
real(real64), parameter, public p_mu
Definition: global.F90:228
real(real64), parameter, public p_ep
Definition: global.F90:227
complex(real64), parameter, public m_z0
Definition: global.F90:197
real(real64), parameter, public m_epsilon
Definition: global.F90:203
real(real64), parameter, public m_half
Definition: global.F90:193
real(real64), parameter, public p_c
Electron gyromagnetic ratio, see Phys. Rev. Lett. 130, 071801 (2023)
Definition: global.F90:223
real(real64), parameter, public m_one
Definition: global.F90:188
real(real64), parameter, public m_five
Definition: global.F90:192
This module implements the underlying real-space grid.
Definition: grid.F90:117
This module implements the index, used for the mesh points.
Definition: index.F90:122
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...
Definition: io.F90:114
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.
Definition: math.F90:115
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.
Definition: mesh.F90:118
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.
Definition: mesh.F90:916
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:930
character(len=512), private msg
Definition: messages.F90:165
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
Definition: messages.F90:624
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:160
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:420
Some general things and nomenclature:
Definition: par_vec.F90:171
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:618
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:623
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:552
type(type_t), public type_float
Definition: types.F90:133
type(type_t), public type_cmplx
Definition: types.F90:134
type(type_t), public type_integer
Definition: types.F90:135
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:132
character(len=20) pure function, public units_abbrev(this)
Definition: unit.F90:223
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.
Definition: box_sphere.F90:132
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:168
Describes mesh distribution to nodes.
Definition: mesh.F90:186
int true(void)