37 use,
intrinsic :: iso_fortran_env
73 type(space_t) :: space
74 real(real64) :: omega_p
75 real(real64) :: gamma_p
76 real(real64) :: strength_p
77 real(real64),
allocatable :: current_p(:,:)
78 real(real64),
allocatable :: e_field(:,:)
79 real(real64),
allocatable :: e_field_dt_half(:,:)
80 real(real64),
allocatable :: e_field_dt_full(:,:)
81 real(real64),
allocatable :: current_at_point(:,:)
82 real(real64),
allocatable :: selected_points_coordinate(:,:)
83 integer :: n_output_points
84 integer :: medium_type
86 type(multicomm_t) :: mc
87 type(c_ptr) :: write_handle
88 type(output_t) :: outp
89 logical :: from_scratch = .
true.
90 type(restart_t) :: restart_load
91 type(restart_t) :: restart_dump
111 procedure dispersive_medium_constructor
114 integer,
public,
parameter :: &
125 class(dispersive_medium_t),
pointer :: sys
126 type(namespace_t),
intent(in) :: namespace
127 type(mpi_grp_t),
intent(in) :: grp
145 class(dispersive_medium_t),
target,
intent(inout) :: this
146 type(namespace_t),
intent(in) :: namespace
147 type(mpi_grp_t),
intent(in) :: grp
149 integer :: nlines, ncols, idim, il
150 real(real64) :: pos(3)
157 this%namespace = namespace
158 this%space =
space_t(this%namespace)
159 call this%init_parallelization(grp)
161 if (this%space%dim /= 3)
then
177 call parse_variable(namespace,
'MediumDispersionType', drude_medium, this%medium_type)
223 if (
parse_block(namespace,
'MediumCurrentCoordinates', blk) == 0)
then
225 this%n_output_points = nlines
226 safe_allocate(this%selected_points_coordinate(1:nlines,1:3))
227 safe_allocate(this%current_at_point(1:nlines,1:3))
233 this%selected_points_coordinate(il,:) = pos(:)
234 this%current_at_point(il,:) =
m_zero
238 this%n_output_points = 1
239 safe_allocate(this%selected_points_coordinate(1,3))
240 safe_allocate(this%current_at_point(1,3))
241 this%selected_points_coordinate =
m_zero
242 this%current_at_point =
m_zero
248 call this%quantities%add(
quantity_t(
"current", updated_on_demand = .false.))
262 integer(int64) :: index_range(4)
269 index_range(1) = this%gr%np_global
272 index_range(4) = 100000
276 index_range, (/ 5000, 1, 1, 1 /))
280 this%mc, ierr, mesh=this%gr)
282 this%mc, ierr, mesh=this%gr)
284 safe_allocate(this%current_p(1:this%gr%np, 1:3))
285 safe_allocate(this%e_field(1:this%gr%np, 1:3))
286 this%e_field(:,:) =
m_zero
300 select type (interaction)
302 call interaction%init(this%gr, 3)
307 select type (prop => this%algo)
312 message(1) =
"The chosen propagator does not yet support interaction interpolation"
315 call interaction%init_interpolation(depth, interaction%label)
318 message(1) =
"Trying to initialize an unsupported interaction by a Dispersive medium."
332 select type (interaction)
334 call interaction%init_from_partner(partner%gr, partner%space, partner%namespace)
336 message(1) =
"Trying to initialize an unsupported interaction by a linear medium."
349 this%from_scratch = .
true.
350 this%current_p(:,:) =
m_zero
359 character(len=:),
allocatable,
intent(out) :: updated_quantities(:)
362 real(real64) :: k1(1:3), k2(1:3), k3(1:3), k4(1:3)
365 call profiling_in(trim(this%namespace%get())//
":"//trim(operation%id))
375 select type (algo => this%algo)
379 select case (operation%id)
384 safe_allocate(this%e_field_dt_half(1:this%gr%np, 1:3))
385 safe_allocate(this%e_field_dt_full(1:this%gr%np, 1:3))
388 safe_deallocate_a(this%e_field_dt_half)
389 safe_deallocate_a(this%e_field_dt_full)
392 call this%get_efield(this%iteration%value(), this%e_field)
393 call this%get_efield(this%iteration%value()+algo%dt/
m_two, this%e_field_dt_half)
394 call this%get_efield(this%iteration%value()+algo%dt, this%e_field_dt_full)
399 do ip = 1, this%gr%np
401 this%e_field(ip,idim), this%gamma_p, this%omega_p, this%strength_p)
404 this%e_field_dt_half(ip, idim), this%gamma_p, this%omega_p, this%strength_p)
407 this%e_field_dt_half(ip, idim), this%gamma_p, this%omega_p, this%strength_p)
410 this%e_field_dt_full(ip, idim), this%gamma_p, this%omega_p, this%strength_p)
412 this%current_p(ip, idim) = this%current_p(ip, idim) + algo%dt / 6.0_real64 * &
413 (k1(idim) +
m_two * (k2(idim) + k3(idim)) + k4(idim))
416 updated_quantities = [
"current"]
423 call profiling_out(trim(this%namespace%get())//
":"//trim(operation%id))
428 real(real64),
intent(in) :: current_p
429 real(real64),
intent(in) :: e_field
430 real(real64),
intent(in) :: gamma_p
431 real(real64),
intent(in) :: omega_p
432 real(real64),
intent(in) :: strength_p
433 real(real64) :: current_dot
435 current_dot = - gamma_p * current_p + strength_p *
p_ep * omega_p**2 * e_field
443 real(real64),
intent(in) :: tol
460 call profiling_in(trim(partner%namespace%get())//
":"//
"COPY_QUANTITY_INTER")
462 select type (interaction)
464 interaction%partner_field(:,:) = partner%current_p
465 call interaction%do_mapping()
467 message(1) =
"Unsupported interaction."
471 call profiling_out(trim(partner%namespace%get())//
":"//
"COPY_QUANTITY_INTER")
479 character(len=256) :: filename
485 call profiling_in(trim(this%namespace%get())//
":"//
"RESTART_WRITE")
487 if (.not. this%restart_dump%skip())
then
488 do idir = 1, this%space%dim
489 write(filename,
"(A,A)")
"current_p-",
index2axis(idir)
490 call this%restart_dump%write_mesh_function(trim(filename), this%gr, &
491 this%current_p(:, idir), err)
494 call iter%start(this%interactions)
495 do while (iter%has_next())
496 interaction => iter%get_next()
497 select type (interaction)
499 call interaction%write_restart(this%gr, this%space, this%restart_dump, err)
504 message(1) =
"Successfully wrote restart data for system "//trim(this%namespace%get())
510 call profiling_out(trim(this%namespace%get())//
":"//
"RESTART_WRITE")
519 character(len=256) :: filename
525 call profiling_in(trim(this%namespace%get())//
":"//
"RESTART_READ")
528 if (.not. this%restart_load%skip())
then
530 write(filename,
"(A,A)")
"current_p-",
index2axis(idir)
531 call this%restart_load%read_mesh_function(trim(filename), this%gr, &
532 this%current_p(:, idir), err)
535 call iter%start(this%interactions)
536 do while (iter%has_next())
537 interaction => iter%get_next()
538 select type (interaction)
540 call interaction%read_restart(this%gr, this%space, this%restart_load, err)
546 this%from_scratch = .false.
549 this%current_p(:, :) =
m_zero
553 call profiling_out(trim(this%namespace%get())//
":"//
"RESTART_READ")
565 this%kinetic_energy =
m_zero
575 integer :: first, id, idir
576 character(len=130) :: aux
582 select type (algo => this%algo)
585 if (this%iteration%counter() == 0)
then
588 first = this%iteration%counter() + 1
591 call io_mkdir(
'td.general', this%namespace)
593 trim(
io_workpath(
"td.general/current_at_points", this%namespace)))
596 if (this%iteration%counter() == 0)
then
599 '################################################################################')
612 do id = 1, this%n_output_points
614 write(aux,
'(a,i1,a,i1,a)')
'j(', id,
',', idir,
')'
624 do id = 1, this%n_output_points
631 '################################################################################')
636 if (first == 0)
call this%output_write()
649 real(real64) :: dmin, dtmp(3)
650 integer :: ip, pos_index, rankmin
655 select type (algo => this%algo)
657 do ip = 1, this%n_output_points
658 pos_index =
mesh_nearest_point(this%gr, this%selected_points_coordinate(ip,:), dmin, rankmin)
659 if (this%gr%mpi_grp%rank == rankmin)
then
660 dtmp(:) = this%current_p(pos_index,:)
662 if (this%gr%parallel_in_domains)
then
663 call this%gr%mpi_grp%bcast(dtmp(:), 3, mpi_double_precision, rankmin)
669 call profiling_out(trim(this%namespace%get())//
":"//
"OUTPUT_WRITE")
675 do ip = 1, this%n_output_points
676 dtmp = this%current_at_point(ip,1:3)
685 call profiling_out(trim(this%namespace%get())//
":"//
"OUTPUT_WRITE")
708 real(real64),
intent(in) :: time
709 real(real64),
contiguous,
intent(inout) :: efield(:, :)
712 real(real64),
allocatable :: efield_tmp(:, :)
716 safe_allocate(efield_tmp(1:this%gr%np, 1:3))
719 call iter%start(this%interactions)
720 do while (iter%has_next())
721 select type (interaction => iter%get_next())
723 call interaction%interpolate(time, efield_tmp)
727 safe_deallocate_a(efield_tmp)
738 safe_deallocate_a(this%current_p)
739 safe_deallocate_a(this%e_field)
740 safe_deallocate_a(this%selected_points_coordinate)
741 safe_deallocate_a(this%current_at_point)
real(real64) function current_derivative_dir(current_p, e_field, gamma_p, omega_p, strength_p)
constant times a vector plus a vector
Writes to the corresponding file and adds one to the iteration. Must be called after write_iter_init(...
This module defines the abstract interfact for algorithm factories.
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.
subroutine dispersive_medium_init_parallelization(this, grp)
logical function dispersive_medium_is_tolerance_reached(this, tol)
logical function dispersive_medium_do_algorithmic_operation(this, operation, updated_quantities)
subroutine dispersive_medium_init_interaction(this, interaction)
subroutine dispersive_medium_restart_write_data(this)
logical function dispersive_medium_restart_read_data(this)
subroutine dispersive_medium_finalize(this)
subroutine dispersive_medium_init_interaction_as_partner(partner, interaction)
subroutine, public dispersive_medium_init(this, namespace, grp)
The init routine is a module level procedure This has the advantage that different classes can have d...
class(dispersive_medium_t) function, pointer dispersive_medium_constructor(namespace, grp)
The factory routine (or constructor) allocates a pointer of the corresponding type and then calls the...
subroutine dispersive_medium_output_start(this)
subroutine dispersive_medium_update_kinetic_energy(this)
subroutine dispersive_medium_initialize(this)
subroutine dispersive_medium_get_efield(this, time, efield)
subroutine dispersive_medium_output_finish(this)
subroutine dispersive_medium_output_write(this)
subroutine dispersive_medium_copy_quantities_to_interaction(partner, interaction)
This module implements the field transfer.
real(real64), parameter, public m_two
real(real64), parameter, public m_zero
real(real64), parameter, public p_ep
real(real64), parameter, public m_one
This module implements the underlying real-space grid.
subroutine, public grid_init_stage_1(gr, namespace, space, grp, 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 mxll_e_field_to_matter
integer, parameter, public current_to_mxll_field
This module defines the abstract interaction_t class, and some auxiliary classes for interactions.
This module defines classes and functions for interaction partners.
character(len=max_path_len) function, public io_workpath(path, namespace)
construct path name from given name and namespace
subroutine, public io_mkdir(fname, namespace, parents)
This module defines a linear medium for use in classical electrodynamics calculations.
This module defines the meshes, which are used in Octopus.
integer function, public mesh_nearest_point(mesh, pos, dmin, rankmin)
Returns the index of the point which is nearest to a given vector position pos.
subroutine, public messages_not_implemented(feature, 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
Maxwell-field-to-matter interactions.
integer, parameter, public mxll_field_total
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.
character(len=algo_label_len), parameter, public store_current_status
character(len=algo_label_len), parameter, public rk4_finish
character(len=algo_label_len), parameter, public rk4_start
character(len=algo_label_len), parameter, public rk4_propagate
character(len=algo_label_len), parameter, public rk4_extrapolate
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)
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
character(len=20) pure function, public units_abbrev(this)
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
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
This module is intended to contain simple general-purpose utility functions and procedures.
character pure function, public index2axis(idir)
Explicit interfaces to C functions, defined in write_iter_low.cc.
subroutine, public write_iter_header(out, string)
subroutine, public write_iter_string(out, string)
subroutine, public write_iter_init(out, iter, factor, file)
Descriptor of one algorithmic operation.
Class to transfer a current to a Maxwell field.
dispersive medium for classical electrodynamics calculations
These class extend the list and list iterator to make an interaction list.
abstract interaction class
surrogate interaction class to avoid circular dependencies between modules.
This is defined even when running serial.
class to transfer a Maxwell electric field to a medium
Abstract class implementing propagators.
Implements the 4th order Runge Kutta propagator.
Systems (system_t) can expose quantities that can be used to calculate interactions with other system...
Abstract class for systems.