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
112 procedure dispersive_medium_constructor
115 integer,
public,
parameter :: &
126 class(dispersive_medium_t),
pointer :: sys
127 type(namespace_t),
intent(in) :: namespace
145 class(dispersive_medium_t),
target,
intent(inout) :: this
146 type(namespace_t),
intent(in) :: namespace
148 integer :: nlines, ncols, idim, il
149 real(real64) :: pos(3)
154 this%namespace = namespace
158 this%space =
space_t(this%namespace)
159 if (this%space%dim /= 3)
then
175 call parse_variable(namespace,
'MediumDispersionType', drude_medium, this%medium_type)
221 if (
parse_block(namespace,
'MediumCurrentCoordinates', blk) == 0)
then
223 this%n_output_points = nlines
224 safe_allocate(this%selected_points_coordinate(1:nlines,1:3))
225 safe_allocate(this%current_at_point(1:nlines,1:3))
231 this%selected_points_coordinate(il,:) = pos(:)
232 this%current_at_point(il,:) =
m_zero
236 this%n_output_points = 1
237 safe_allocate(this%selected_points_coordinate(1,3))
238 safe_allocate(this%current_at_point(1,3))
240 this%current_at_point =
m_zero
246 call this%quantities%add(
quantity_t(
"current", updated_on_demand = .false.))
258 integer(int64) :: index_range(4)
266 index_range(1) = this%gr%np_global
269 index_range(4) = 100000
273 index_range, (/ 5000, 1, 1, 1 /))
277 this%mc, ierr, mesh=this%gr)
279 this%mc, ierr, mesh=this%gr)
281 safe_allocate(this%current_p(1:this%gr%np, 1:3))
282 safe_allocate(this%e_field(1:this%gr%np, 1:3))
283 this%e_field(:,:) =
m_zero
297 select type (interaction)
299 call interaction%init(this%gr, 3)
304 select type (prop => this%algo)
309 message(1) =
"The chosen propagator does not yet support interaction interpolation"
312 call interaction%init_interpolation(depth, interaction%label)
315 message(1) =
"Trying to initialize an unsupported interaction by a Dispersive medium."
329 select type (interaction)
331 call interaction%init_from_partner(partner%gr, partner%space, partner%namespace)
333 message(1) =
"Trying to initialize an unsupported interaction by a linear medium."
346 this%from_scratch = .
true.
347 this%current_p(:,:) =
m_zero
356 character(len=:),
allocatable,
intent(out) :: updated_quantities(:)
359 real(real64) :: k1(1:3), k2(1:3), k3(1:3), k4(1:3)
362 call profiling_in(trim(this%namespace%get())//
":"//trim(operation%id))
372 select type (algo => this%algo)
376 select case (operation%id)
381 safe_allocate(this%e_field_dt_half(1:this%gr%np, 1:3))
382 safe_allocate(this%e_field_dt_full(1:this%gr%np, 1:3))
385 safe_deallocate_a(this%e_field_dt_half)
386 safe_deallocate_a(this%e_field_dt_full)
389 call this%get_efield(this%iteration%value(), this%e_field)
390 call this%get_efield(this%iteration%value()+algo%dt/
m_two, this%e_field_dt_half)
391 call this%get_efield(this%iteration%value()+algo%dt, this%e_field_dt_full)
396 do ip = 1, this%gr%np
398 this%e_field(ip,idim), this%gamma_p, this%omega_p, this%strength_p)
401 this%e_field_dt_half(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_full(ip, idim), this%gamma_p, this%omega_p, this%strength_p)
409 this%current_p(ip, idim) = this%current_p(ip, idim) + algo%dt / 6.0_real64 * &
410 (k1(idim) +
m_two * (k2(idim) + k3(idim)) + k4(idim))
413 updated_quantities = [
"current"]
420 call profiling_out(trim(this%namespace%get())//
":"//trim(operation%id))
425 real(real64),
intent(in) :: current_p
426 real(real64),
intent(in) :: e_field
427 real(real64),
intent(in) :: gamma_p
428 real(real64),
intent(in) :: omega_p
429 real(real64),
intent(in) :: strength_p
430 real(real64) :: current_dot
432 current_dot = - gamma_p * current_p + strength_p *
p_ep * omega_p**2 * e_field
440 real(real64),
intent(in) :: tol
457 call profiling_in(trim(partner%namespace%get())//
":"//
"COPY_QUANTITY_INTER")
459 select type (interaction)
461 interaction%partner_field(:,:) = partner%current_p
462 call interaction%do_mapping()
464 message(1) =
"Unsupported interaction."
468 call profiling_out(trim(partner%namespace%get())//
":"//
"COPY_QUANTITY_INTER")
476 character(len=256) :: filename
482 call profiling_in(trim(this%namespace%get())//
":"//
"RESTART_WRITE")
484 if (.not. this%restart_dump%skip())
then
485 do idir = 1, this%space%dim
486 write(filename,
"(A,A)")
"current_p-",
index2axis(idir)
487 call this%restart_dump%write_mesh_function(this%space, trim(filename), this%gr, &
488 this%current_p(:, idir), err)
491 call iter%start(this%interactions)
492 do while (iter%has_next())
493 interaction => iter%get_next()
494 select type (interaction)
496 call interaction%write_restart(this%gr, this%space, this%restart_dump, err)
501 message(1) =
"Successfully wrote restart data for system "//trim(this%namespace%get())
507 call profiling_out(trim(this%namespace%get())//
":"//
"RESTART_WRITE")
516 character(len=256) :: filename
522 call profiling_in(trim(this%namespace%get())//
":"//
"RESTART_READ")
525 if (.not. this%restart_load%skip())
then
527 write(filename,
"(A,A)")
"current_p-",
index2axis(idir)
528 call this%restart_load%read_mesh_function(this%space, trim(filename), this%gr, &
529 this%current_p(:, idir), err)
532 call iter%start(this%interactions)
533 do while (iter%has_next())
534 interaction => iter%get_next()
535 select type (interaction)
537 call interaction%read_restart(this%gr, this%space, this%restart_load, err)
543 this%from_scratch = .false.
546 this%current_p(:, :) =
m_zero
550 call profiling_out(trim(this%namespace%get())//
":"//
"RESTART_READ")
562 this%kinetic_energy =
m_zero
572 integer :: first, id, idir
573 character(len=130) :: aux
579 select type (algo => this%algo)
582 if (this%iteration%counter() == 0)
then
585 first = this%iteration%counter() + 1
588 call io_mkdir(
'td.general', this%namespace)
590 trim(
io_workpath(
"td.general/current_at_points", this%namespace)))
593 if (this%iteration%counter() == 0)
then
596 '################################################################################')
609 do id = 1, this%n_output_points
611 write(aux,
'(a,i1,a,i1,a)')
'j(', id,
',', idir,
')'
621 do id = 1, this%n_output_points
628 '################################################################################')
633 if (first == 0)
call this%output_write()
646 real(real64) :: dmin, dtmp(3)
647 integer :: ip, pos_index, rankmin
652 select type (algo => this%algo)
654 do ip = 1, this%n_output_points
655 pos_index =
mesh_nearest_point(this%gr, this%selected_points_coordinate(ip,:), dmin, rankmin)
656 if (this%gr%mpi_grp%rank == rankmin)
then
657 dtmp(:) = this%current_p(pos_index,:)
659 if (this%gr%parallel_in_domains)
then
660 call this%gr%mpi_grp%bcast(dtmp(:), 3, mpi_double_precision, rankmin)
666 call profiling_out(trim(this%namespace%get())//
":"//
"OUTPUT_WRITE")
672 do ip = 1, this%n_output_points
673 dtmp = this%current_at_point(ip,1:3)
682 call profiling_out(trim(this%namespace%get())//
":"//
"OUTPUT_WRITE")
705 real(real64),
intent(in) :: time
706 real(real64),
contiguous,
intent(inout) :: efield(:, :)
709 real(real64),
allocatable :: efield_tmp(:, :)
713 safe_allocate(efield_tmp(1:this%gr%np, 1:3))
716 call iter%start(this%interactions)
717 do while (iter%has_next())
718 select type (interaction => iter%get_next())
720 call interaction%interpolate(time, efield_tmp)
724 safe_deallocate_a(efield_tmp)
735 safe_deallocate_a(this%current_p)
736 safe_deallocate_a(this%e_field)
737 safe_deallocate_a(this%selected_points_coordinate)
738 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)
class(dispersive_medium_t) function, pointer dispersive_medium_constructor(namespace)
The factory routine (or constructor) allocates a pointer of the corresponding type and then calls the...
subroutine, public dispersive_medium_init(this, namespace)
The init routine is a module level procedure This has the advantage that different classes can have d...
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
complex(real64), parameter, public m_z0
real(real64), parameter, public m_one
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 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
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_init_parallelization(this, grp)
Basic functionality: copy the MPI group. This function needs to be implemented by extended types that...
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.
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 field to a medium
Abstract class implementing propagators.
Implements a 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.