68 integer,
parameter :: &
69 MEDIUM_PARALLELEPIPED = 1, &
75 type(space_t) :: space
76 real(real64) :: ep_factor
77 real(real64) :: mu_factor
78 real(real64) :: sigma_e_factor
79 real(real64) :: sigma_m_factor
80 integer :: edge_profile
81 type(output_t) :: outp
83 type(multicomm_t) :: mc
84 type(single_medium_box_t) :: medium_box
100 procedure linear_medium_constructor
111 class(linear_medium_t),
pointer :: sys
112 type(namespace_t),
intent(in) :: namespace
130 class(linear_medium_t),
target,
intent(inout) :: this
131 type(namespace_t),
intent(in) :: namespace
133 integer :: nlines, ncols,n_points, n_global_points
134 integer(int64) :: index_range(4)
135 integer,
allocatable :: tmp(:)
142 this%namespace = namespace
143 this%space =
space_t(this%namespace)
147 index_range(1) = this%gr%np_global
150 index_range(4) = 100000
154 index_range, (/ 5000, 1, 1, 1 /))
174 if (
parse_block(namespace,
'LinearMediumProperties', blk) == 0)
then
177 if (nlines /= 1)
then
188 write(
message(1),
'(a,es9.2)')
'Box epsilon factor: ', this%ep_factor
189 write(
message(2),
'(a,es9.2)')
'Box mu factor: ', this%mu_factor
190 write(
message(3),
'(a,es9.2)')
'Box electric sigma: ', this%sigma_e_factor
191 write(
message(4),
'(a,es9.2)')
'Box magnetic sigma: ', this%sigma_m_factor
198 message(1) =
'You must specify the properties of your linear medium through the LinearMediumProperties block.'
214 call parse_variable(namespace,
'LinearMediumEdgeProfile', option__linearmediumedgeprofile__edged, this%edge_profile)
215 if (this%edge_profile == option__linearmediumedgeprofile__edged)
then
216 write(
message(1),
'(a,a)')
'Box shape: ',
'edged'
217 else if (this%edge_profile == option__linearmediumedgeprofile__smooth)
then
218 write(
message(1),
'(a,a)')
'Box shape: ',
'smooth'
222 allocate(this%supported_interactions(0))
224 call this%quantities%add(
quantity_t(
"permitivity", updated_on_demand = .false., always_available = .
true.))
225 call this%quantities%add(
quantity_t(
"permeability", updated_on_demand = .false., always_available = .
true.))
226 call this%quantities%add(
quantity_t(
"E conductivity", updated_on_demand = .false., always_available = .
true.))
227 call this%quantities%add(
quantity_t(
"M conductivity", updated_on_demand = .false., always_available = .
true.))
234 this%outp%iter_dir, this%medium_box%points_map, this%medium_box%ep, &
235 this%medium_box%mu, this%medium_box%c)
237 if (this%medium_box%check_medium_points)
then
238 safe_allocate(tmp(1:this%gr%np))
240 write(
message(1),
'(a, a, a)')
'Check of points inside surface of medium ', trim(this%medium_box%filename),
":"
243 write(
message(1),
'(a, I8)')
'Number of points inside medium (normal coordinates):', &
244 this%medium_box%global_points_number
245 write(
message(2),
'(a, I8)')
'Number of points inside medium (rescaled coordinates):', n_global_points
248 safe_deallocate_a(tmp)
263 select type (interaction)
265 message(1) =
"Trying to initialize an unsupported interaction by a linear medium."
282 select type (interaction)
285 partner%gr, partner%space, partner%namespace)
288 medium_box_grid => partner%medium_box%to_grid(partner%gr)
291 call regridding%do_transfer(interaction%medium_box%aux_ep, medium_box_grid%aux_ep)
292 call regridding%do_transfer(interaction%medium_box%aux_mu, medium_box_grid%aux_mu)
293 call regridding%do_transfer(interaction%medium_box%ep, medium_box_grid%ep)
294 call regridding%do_transfer(interaction%medium_box%mu, medium_box_grid%mu)
295 call regridding%do_transfer(interaction%medium_box%c, medium_box_grid%c)
296 call regridding%do_transfer(interaction%medium_box%sigma_e, medium_box_grid%sigma_e)
297 call regridding%do_transfer(interaction%medium_box%sigma_m, medium_box_grid%sigma_m)
299 safe_deallocate_p(regridding)
300 safe_deallocate_p(medium_box_grid)
302 message(1) =
"Trying to initialize an unsupported interaction by a linear medium."
322 character(len=:),
allocatable,
intent(out) :: updated_quantities(:)
335 real(real64),
intent(in) :: tol
353 select type (interaction)
357 message(1) =
"Unsupported interaction."
369 integer :: restart_file_unit, ierr
375 message(1) =
"Linear medium system "//trim(this%namespace%get())//
" will only write a dummy restart file."
379 restart_file_unit = restart%open(
'restart_linear_medium')
380 if (restart%do_i_write())
write(restart_file_unit, *)
'Linear medium restart file'
381 call restart%close(restart_file_unit)
382 message(1) =
"Successfully wrote restart data for system "//trim(this%namespace%get())
385 message(1) =
"Could not write restart data for system "//trim(this%namespace%get())
400 integer :: restart_file_unit, ierr
405 restart_file_unit = restart%open(
'restart_linear_medium')
407 call restart%close(restart_file_unit)
416 message(1) =
"Successfully read restart data for system "//trim(this%namespace%get())
454 type(
grid_t),
intent(in) :: gr
456 integer :: ip, ip_in, ip_bd, idim
457 integer,
allocatable :: tmp_points_map(:), tmp_bdry_map(:)
458 real(real64) :: bounds(2,gr%box%dim), xx(gr%box%dim)
465 safe_allocate(tmp_points_map(1:gr%np))
466 safe_allocate(tmp_bdry_map(1:gr%np))
473 medium_box%global_points_number, tmp_points_map)
478 bounds(1,idim) = medium_box%center(idim) - medium_box%lsize(idim)/
m_two
479 bounds(2,idim) = medium_box%center(idim) + medium_box%lsize(idim)/
m_two
484 xx(1:3) = gr%x(1:3, ip)
488 tmp_points_map(ip_in) = ip
492 tmp_bdry_map(ip_bd) = ip
496 medium_box%points_number = ip_in
497 medium_box%bdry_number = ip_bd
499 safe_allocate(medium_box%bdry_map(1:medium_box%bdry_number))
500 medium_box%bdry_map = 0
501 medium_box%bdry_map = tmp_bdry_map(1:medium_box%bdry_number)
505 safe_allocate(medium_box%points_map(1:medium_box%points_number))
506 medium_box%points_map(:) = tmp_points_map(1:medium_box%points_number)
509 safe_deallocate_a(tmp_points_map)
510 safe_deallocate_a(tmp_bdry_map)
518 real(real64),
intent(in) :: xx(:)
519 real(real64),
intent(in) :: bounds(:,:)
522 if ((xx(1) >= bounds(1,1)) .and. (xx(1) <= bounds(2,1)) .and. &
523 (xx(2) >= bounds(1,2)) .and. (xx(2) <= bounds(2,2)) .and. &
524 (xx(3) >= bounds(1,3)) .and. (xx(3) <= bounds(2,3)) )
then
530 logical pure function check_point_on_bounds(xx, bounds) result (check)
531 real(real64),
intent(in) :: xx(:)
532 real(real64),
intent(in) :: bounds(:,:)
535 if (
is_close(xx(1), bounds(1,1)) .and. (xx(2) >= bounds(1,2) .and. xx(3) >= bounds(1,3)) &
536 .and. (xx(2) <= bounds(2,2) .and. xx(3) <= bounds(2,3)) .or. &
537 is_close(xx(2), bounds(1,2)) .and. (xx(1) >= bounds(1,1) .and. xx(3) >= bounds(1,3)) &
538 .and. (xx(1) <= bounds(2,1) .and. xx(3) <= bounds(2,3)) .or. &
539 is_close(xx(3), bounds(1,3)) .and. (xx(1) >= bounds(1,1) .and. xx(2) >= bounds(1,2)) &
540 .and. (xx(1) <= bounds(2,1) .and. xx(2) <= bounds(2,2)) .or. &
541 is_close(xx(1), bounds(2,1)) .and. (xx(2) >= bounds(1,2) .and. xx(3) >= bounds(1,3)) &
542 .and. (xx(2) <= bounds(2,2) .and. xx(3) <= bounds(2,3)) .or. &
543 is_close(xx(2), bounds(2,2)) .and. (xx(1) >= bounds(1,1) .and. xx(3) >= bounds(1,3)) &
544 .and. (xx(1) <= bounds(2,1) .and. xx(3) <= bounds(2,3)) .or. &
545 is_close(xx(3), bounds(2,3)) .and. (xx(1) >= bounds(1,1) .and. xx(2) >= bounds(1,2)) &
546 .and. (xx(1) <= bounds(2,1) .and. xx(2) <= bounds(2,2)) )
then
558 type(single_medium_box_t),
intent(inout) :: medium_box
559 type(grid_t),
intent(in) :: gr
561 integer :: ip, ip_in, ip_bd, ipp
562 real(real64) :: xx(gr%box%dim), xxp(gr%box%dim), dd, dd_max, dd_min
563 real(real64),
allocatable :: tmp(:), tmp_grad(:,:)
567 call profiling_in(
'GET_LIN_MEDIUM_EM_PROP')
569 safe_allocate(tmp(1:gr%np_part))
570 safe_allocate(tmp_grad(1:gr%np_part, 1:gr%box%dim))
571 dd_max = max(2*gr%spacing(1), 2*gr%spacing(2), 2*gr%spacing(3))
573 do ip_in = 1, medium_box%points_number
574 ip = medium_box%points_map(ip_in)
575 if (this%edge_profile == option__linearmediumedgeprofile__smooth)
then
576 assert(
allocated(medium_box%bdry_map))
578 xx(1:3) = gr%x(1:3, ip)
581 do ip_bd = 1, medium_box%bdry_number
582 ipp = medium_box%bdry_map(ip_bd)
583 xxp(1:3) = gr%x(1:3, ipp)
584 dd = norm2(xx(1:3) - xxp(1:3))
585 if (dd < dd_min) dd_min = dd
588 medium_box%ep(ip_in) = p_ep + ((p_ep * this%ep_factor - p_ep) &
589 * m_one/(m_one +
exp(-m_five/dd_max * (dd_min - m_two*dd_max))))
590 medium_box%mu(ip_in) = p_mu + ((p_mu * this%mu_factor - p_mu) &
591 * m_one/(m_one +
exp(-m_five/dd_max * (dd_min - m_two*dd_max))))
592 medium_box%c(ip_in) = m_one/
sqrt(medium_box%ep(ip_in)*medium_box%mu(ip_in))
593 medium_box%sigma_e(ip_in) = this%sigma_e_factor &
594 * m_one/(m_one +
exp(-m_five/dd_max * (dd_min - m_two*dd_max)))
595 medium_box%sigma_m(ip_in) = this%sigma_m_factor &
596 * m_one/(m_one +
exp(-m_five/dd_max * (dd_min - m_two*dd_max)))
598 else if (this%edge_profile == option__linearmediumedgeprofile__edged)
then
600 medium_box%ep(ip_in) = p_ep * this%ep_factor
601 medium_box%mu(ip_in) = p_mu * this%mu_factor
602 medium_box%c(ip_in) = m_one/
sqrt(medium_box%ep(ip_in)*medium_box%mu(ip_in))
603 medium_box%sigma_e(ip_in) = this%sigma_e_factor
604 medium_box%sigma_m(ip_in) = this%sigma_m_factor
610 do ip_in = 1, medium_box%points_number
611 ip = medium_box%points_map(ip_in)
612 tmp(ip)= medium_box%ep(ip_in)
614 call dderivatives_grad(gr%der, tmp, tmp_grad, set_bc = .false.)
615 do ip_in = 1, medium_box%points_number
616 ip = medium_box%points_map(ip_in)
617 medium_box%aux_ep(ip_in, :) = tmp_grad(ip, :)/(m_four * medium_box%ep(ip_in))
621 do ip_in = 1, medium_box%points_number
622 ip = medium_box%points_map(ip_in)
623 tmp(ip) = medium_box%mu(ip_in)
625 call dderivatives_grad(gr%der, tmp, tmp_grad, set_bc = .false.)
626 do ip_in = 1, medium_box%points_number
627 ip = medium_box%points_map(ip_in)
628 medium_box%aux_mu(ip_in, :) = tmp_grad(ip, :)/(m_four * medium_box%mu(ip_in))
633 safe_deallocate_a(tmp)
634 safe_deallocate_a(tmp_grad)
636 call profiling_out(
'GET_LIN_MEDIUM_EM_PROP')
644 character(len=256),
intent(in) :: filename
645 class(mesh_t),
intent(in) :: mesh
646 integer,
intent(out) :: n_points
647 integer,
intent(out) :: global_points_number
648 integer,
intent(inout) :: tmp_map(:)
649 real(real64),
optional,
intent(in) :: scale_factor
652 real(real64) :: xx(3)
653 type(cgal_polyhedra_t) :: cgal_poly
657 call profiling_in(
'GET_POINTS_MAP_FROM_FILE')
659 call cgal_polyhedron_init(cgal_poly, trim(filename), verbose = .false.)
663 if (
present(scale_factor))
then
664 xx(1:3) = scale_factor * mesh%x(1:3, ip)
666 xx(1:3) = mesh%x(1:3, ip)
668 if (cgal_polyhedron_point_inside(cgal_poly, xx(1), xx(2), xx(3)))
then
674 call cgal_polyhedron_end(cgal_poly)
676 call mpi_world%allreduce(ip_in, global_points_number, 1, mpi_integer, mpi_sum)
678 call profiling_out(
'GET_POINTS_MAP_FROM_FILE')
687 type(single_medium_box_t),
intent(inout) :: medium_box
688 type(namespace_t),
intent(in) :: namespace
690 integer :: nlines, ncols, idim
709 if (.not. varinfo_valid_option(
'LinearMediumBoxShape', medium_box%box_shape))
then
710 call messages_input_error(namespace,
'LinearMediumBoxShape')
713 select case (medium_box%box_shape)
729 if (parse_block(namespace,
'LinearMediumBoxSize', blk) == 0)
then
730 call messages_print_with_emphasis(msg=trim(
'Linear Medium box center and size:'), namespace=namespace)
732 nlines = parse_block_n(blk)
733 if (nlines /= 1)
then
734 call messages_input_error(namespace,
'LinearMediumBoxSize',
'should consist of one line')
736 ncols = parse_block_cols(blk, 0)
738 call messages_input_error(namespace,
'LinearMediumBoxSize',
'should consist of six columns')
741 call parse_block_float(blk, 0, idim-1, medium_box%center(idim))
742 call parse_block_float(blk, 0, idim+2, medium_box%lsize(idim))
744 write(message(1),
'(a,es9.2,a,es9.2,a,es9.2)')
'Box center: ', medium_box%center(1),
' | ',&
745 medium_box%center(2),
' | ', medium_box%center(3)
746 write(message(2),
'(a,es9.2,a,es9.2,a,es9.2)')
'Box size : ', medium_box%lsize(1),
' | ', &
747 medium_box%lsize(2),
' | ', medium_box%lsize(3)
748 write(message(3),
'(a)')
""
749 call messages_info(3)
750 call parse_block_end(blk)
752 call messages_print_with_emphasis(namespace=namespace)
754 message(1) =
"For parallelepiped box shapes, you must provide a LinearMediumBoxSize block."
755 call messages_fatal(1, namespace=namespace)
765 if (parse_is_defined(namespace,
'LinearMediumBoxFile'))
then
766 call parse_variable(namespace,
'LinearMediumBoxFile',
'mediumboxfile', medium_box%filename)
768 message(1) =
"When using box_file as the box shape, you must provide a filename through the LinearMediumBoxFile variable."
769 call messages_fatal(1, namespace=namespace)
781 call parse_variable(namespace,
'CheckPointsMediumFromFile', .false., medium_box%check_medium_points)
double exp(double __x) __attribute__((__nothrow__
double sqrt(double __x) __attribute__((__nothrow__
logical pure function check_point_on_bounds(xx, bounds)
logical pure function check_point_in_bounds(xx, bounds)
This module implements the basic elements defining algorithms.
This module handles the calculation mode.
type(calc_mode_par_t), public calc_mode_par
Singleton instance of parallel calculation mode.
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
real(real64), parameter, public m_two
real(real64), parameter, public m_zero
This module implements the underlying real-space grid.
subroutine, public grid_init_stage_1(gr, namespace, space, symm, latt, n_sites, site_position)
First stage of the grid initialization.
subroutine, public grid_init_stage_2(gr, namespace, space, mc, qvector)
Second stage of the grid initialization.
subroutine, public grid_end(gr)
finalize a grid object
integer, parameter, public linear_medium_to_em_field
This module defines the abstract interaction_t class, and some auxiliary classes for interactions.
This module defines a linear medium for use in classical electrodynamics calculations.
subroutine linear_medium_initialize(this)
logical function linear_medium_is_tolerance_reached(this, tol)
integer, parameter medium_parallelepiped
subroutine linear_medium_copy_quantities_to_interaction(partner, interaction)
subroutine linear_medium_restart_write_data(this)
class(linear_medium_t) function, pointer linear_medium_constructor(namespace)
The factory routine (or constructor) allocates a pointer of the corresponding type and then calls the...
logical function linear_medium_restart_read_data(this)
subroutine, public get_medium_box_points_map(medium_box, gr)
subroutine linear_medium_init_interaction(this, interaction)
subroutine, public medium_box_init(medium_box, namespace)
Parse and store geometry of medium box.
subroutine linear_medium_init_interaction_as_partner(partner, interaction)
subroutine linear_medium_update_kinetic_energy(this)
integer, parameter medium_box_file
logical function linear_medium_do_algorithmic_operation(this, operation, updated_quantities)
subroutine linear_medium_finalize(this)
subroutine get_points_map_from_file(filename, mesh, n_points, global_points_number, tmp_map, scale_factor)
Populate list of point indices for points inside the polyhedron.
subroutine, public linear_medium_init(this, namespace)
The init routine is a module level procedure This has the advantage that different classes can have d...
subroutine get_linear_medium_em_properties(this, medium_box, gr)
Evaluate electromagnetic properties of linear medium.
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.
This module defines the meshes, which are used in Octopus.
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
subroutine, public messages_warning(no_lines, all_nodes, namespace)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public messages_input_error(namespace, var, details, row, column)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
type(mpi_grp_t), public mpi_world
This module handles the communicators for the various parallelization strategies.
subroutine, public multicomm_end(mc)
subroutine, public multicomm_init(mc, namespace, base_grp, mode_para, n_node, index_range, min_range)
create index and domain communicators
subroutine, public output_linear_medium(outp, namespace, space, mesh, dir, points_map, ep, mu, cc)
subroutine, public output_linear_medium_init(outp, namespace, space)
this module contains the low-level part of the output system
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.
This module implements the basic propagator framework.
This module defines the quantity_t class and the IDs for quantities, which can be exposed by a system...
Implementation details for regridding.
integer, parameter, public restart_type_dump
integer, parameter, public restart_td
integer, parameter, public restart_type_load
This module implements the abstract system type.
subroutine, public system_end(this)
Descriptor of one algorithmic operation.
Description of the grid, containing information on derivatives, stencil, and symmetries.
abstract interaction class
surrogate interaction class to avoid circular dependencies between modules.
linear medium for classical electrodynamics
Systems (system_t) can expose quantities that can be used to calculate interactions with other system...
contains the information of the meshes and provides the transfer functions
restart_basic_t stores the basic information about a restart object.
Abstract class for systems.