Octopus
dispersive_medium.F90
Go to the documentation of this file.
1!! Copyright (C) 2021 F. Bonafé
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
19#include "global.h"
20
26 use debug_oct_m
28 use global_oct_m
34 use io_oct_m
36 use grid_oct_m
37 use, intrinsic :: iso_fortran_env
42 use mesh_oct_m
43 use mpi_oct_m
48 use parser_oct_m
55 use space_oct_m
56 use system_oct_m
58 use unit_oct_m
59 use utils_oct_m
62
63 implicit none
64
65 private
66 public :: &
69
71 type, extends(system_t) :: dispersive_medium_t
72 private
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
85 type(grid_t) :: gr
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
92
93 contains
94 procedure :: init_interaction => dispersive_medium_init_interaction
95 procedure :: init_interaction_as_partner => dispersive_medium_init_interaction_as_partner
96 procedure :: initialize => dispersive_medium_initialize
97 procedure :: do_algorithmic_operation => dispersive_medium_do_algorithmic_operation
98 procedure :: is_tolerance_reached => dispersive_medium_is_tolerance_reached
99 procedure :: copy_quantities_to_interaction => dispersive_medium_copy_quantities_to_interaction
100 procedure :: restart_write_data => dispersive_medium_restart_write_data
101 procedure :: restart_read_data => dispersive_medium_restart_read_data
102 procedure :: update_kinetic_energy => dispersive_medium_update_kinetic_energy
103 procedure :: output_start => dispersive_medium_output_start
104 procedure :: output_write => dispersive_medium_output_write
105 procedure :: output_finish => dispersive_medium_output_finish
106 procedure :: get_efield => dispersive_medium_get_efield
108 end type dispersive_medium_t
109
110 interface dispersive_medium_t
111 procedure dispersive_medium_constructor
112 end interface dispersive_medium_t
113
114 integer, public, parameter :: &
115 DRUDE_MEDIUM = 0
117contains
118
119 ! ---------------------------------------------------------
124 function dispersive_medium_constructor(namespace, grp) result(sys)
125 class(dispersive_medium_t), pointer :: sys
126 type(namespace_t), intent(in) :: namespace
127 type(mpi_grp_t), intent(in) :: grp
128
130
131 allocate(sys)
132
133 call dispersive_medium_init(sys, namespace, grp)
134
137
138 ! ---------------------------------------------------------
143 ! ---------------------------------------------------------
144 subroutine dispersive_medium_init(this, namespace, 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
148
149 integer :: nlines, ncols, idim, il
150 real(real64) :: pos(3)
151 type(block_t) :: blk
152
153 push_sub(dispersive_medium_init)
154
155 call profiling_in('DISP_MEDIUM_INIT')
156
157 this%namespace = namespace
158 this%space = space_t(this%namespace)
159 call this%init_parallelization(grp)
160
161 if (this%space%dim /= 3) then
162 call messages_not_implemented('Linear medium for dimensions other than 3', namespace=namespace)
163 end if
164 call grid_init_stage_1(this%gr, this%namespace, this%space, this%grp, latt=lattice_vectors_t(namespace, this%space))
165
166 ! Parse electromagnetic properties of dispersive media...
167
168 !%Variable MediumDispersionType
169 !%Type integer
170 !%Default drude_medium
171 !%Section Maxwell::Medium
172 !%Description
173 !% Dispersion model used for the medium (only Drude model available for the moment).
174 !%Option drude_medium 0
175 !% Drude type of dispersion.
176 !%End
177 call parse_variable(namespace, 'MediumDispersionType', drude_medium, this%medium_type)
178 if (.not. varinfo_valid_option('MediumDispersionType', this%medium_type)) then
179 call messages_input_error(namespace, 'MediumDispersionType')
180 end if
182 ! Parse electromagnetic properties of Dispersive media...
183 !%Variable MediumPoleEnergy
184 !%Type float
185 !%Default 0
186 !%Section Maxwell::Medium
187 !%Description
188 !% Energy of the pole.
189 !%End
190 call parse_variable(namespace, 'MediumPoleEnergy', m_zero, this%omega_p, unit_one/units_inp%time)
192 !%Variable MediumPoleDamping
193 !%Type float
194 !%Default 0
195 !%Section Maxwell::Medium
196 !%Description
197 !% Damping factor (inverse relaxation time) of the medium.
198 !%End
199 call parse_variable(namespace, 'MediumPoleDamping', m_zero, this%gamma_p, unit_one/units_inp%time)
201 !%Variable MediumPoleStrength
202 !%Type float
203 !%Default 1.0
204 !%Section Maxwell::Medium
205 !%Description
206 !% Strength of the pole (unitless).
207 !%End
208 call parse_variable(namespace, 'MediumPoleStrength', m_one, this%strength_p, unit_one)
210 !%Variable MediumCurrentCoordinates
211 !%Type block
212 !%Section Maxwell::Output
213 !%Description
214 !% This allows to output phasor current vectors at particular points in space.
215 !%
216 !% <tt>%MediumCurrentCoordinates
217 !% <br>&nbsp;&nbsp; -1.0 | 2.0 | 4.0
218 !% <br>&nbsp;&nbsp; 0.0 | 1.0 | -2.0
219 !% <br>%</tt>
220 !%
221 !%End
222
223 if (parse_block(namespace, 'MediumCurrentCoordinates', blk) == 0) then
224 nlines = parse_block_n(blk)
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))
228 do il = 1, nlines
229 ncols = parse_block_cols(blk,0)
230 do idim = 1, 3
231 call parse_block_float(blk, il-1, idim-1, pos(idim), units_inp%length)
232 end do
233 this%selected_points_coordinate(il,:) = pos(:)
234 this%current_at_point(il,:) = m_zero
235 end do
236 call parse_block_end(blk)
237 else
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
243 end if
244
245 this%supported_interactions = [mxll_e_field_to_matter]
246 this%supported_interactions_as_partner = [current_to_mxll_field]
247
248 call this%quantities%add(quantity_t("current", updated_on_demand = .false.))
249
250 call dispersive_medium_init_parallelization(this, this%grp)
251
252 call profiling_out('DISP_MEDIUM_INIT')
253
255 end subroutine dispersive_medium_init
256
257 ! ---------------------------------------------------------
258 subroutine dispersive_medium_init_parallelization(this, grp)
259 class(dispersive_medium_t), intent(inout) :: this
260 type(mpi_grp_t), intent(in) :: grp
261
262 integer(int64) :: index_range(4)
263 integer :: ierr
264
266
267 ! store the ranges for these two indices (serves as initial guess
268 ! for parallelization strategy)
269 index_range(1) = this%gr%np_global ! Number of points in mesh
270 index_range(2) = 1 ! Number of states
271 index_range(3) = 1 ! Number of k-points
272 index_range(4) = 100000 ! Some large number
273
274 ! create index and domain communicators
275 call multicomm_init(this%mc, this%namespace, mpi_world, calc_mode_par, mpi_world%size, &
276 index_range, (/ 5000, 1, 1, 1 /))
277 call grid_init_stage_2(this%gr, this%namespace, this%space, this%mc)
278
279 call this%restart_dump%init(this%namespace, restart_td, restart_type_dump, &
280 this%mc, ierr, mesh=this%gr)
281 call this%restart_load%init(this%namespace, restart_td, restart_type_load, &
282 this%mc, ierr, mesh=this%gr)
283
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
287
290
291 ! ---------------------------------------------------------
292 subroutine dispersive_medium_init_interaction(this, interaction)
293 class(dispersive_medium_t), target, intent(inout) :: this
294 class(interaction_t), intent(inout) :: interaction
295
296 integer :: depth
297
299
300 select type (interaction)
302 call interaction%init(this%gr, 3)
303 interaction%type = mxll_field_total
304
305 ! set interpolation depth for interaction
306 ! interpolation depth depends on the propagator
307 select type (prop => this%algo)
308 type is (propagator_rk4_t)
309 ! TODO: should be five, two is only for backwards compatibility
310 depth = 2
311 class default
312 message(1) = "The chosen propagator does not yet support interaction interpolation"
313 call messages_fatal(1)
314 end select
315 call interaction%init_interpolation(depth, interaction%label)
316
317 class default
318 message(1) = "Trying to initialize an unsupported interaction by a Dispersive medium."
319 call messages_fatal(1)
320 end select
321
324
325 ! ---------------------------------------------------------
326 subroutine dispersive_medium_init_interaction_as_partner(partner, interaction)
327 class(dispersive_medium_t), intent(in) :: partner
328 class(interaction_surrogate_t), intent(inout) :: interaction
329
331
332 select type (interaction)
334 call interaction%init_from_partner(partner%gr, partner%space, partner%namespace)
335 class default
336 message(1) = "Trying to initialize an unsupported interaction by a linear medium."
337 call messages_fatal(1)
338 end select
339
342
343 ! ---------------------------------------------------------
344 subroutine dispersive_medium_initialize(this)
345 class(dispersive_medium_t), intent(inout) :: this
346
348
349 this%from_scratch = .true.
350 this%current_p(:,:) = m_zero
351
354
355 ! ---------------------------------------------------------
356 logical function dispersive_medium_do_algorithmic_operation(this, operation, updated_quantities) result(done)
357 class(dispersive_medium_t), intent(inout) :: this
358 class(algorithmic_operation_t), intent(in) :: operation
359 character(len=:), allocatable, intent(out) :: updated_quantities(:)
360
361 integer :: ip, idim
362 real(real64) :: k1(1:3), k2(1:3), k3(1:3), k4(1:3)
363
365 call profiling_in(trim(this%namespace%get())//":"//trim(operation%id))
366
367 ! calculation of the current using ADE
368 ! \partial_t J_P(t) = - \gamma_p * J_P(t) + \epsilon_0 \omega_p^2 E(t)
369 ! (Computational Electrodynamics, Taflov and Hagness, 3rd Ed., section 9.4.3, eq. 9.56c)
370 ! Analysis of Units:
371 ! [e/time^2*a0^2] = (1/time) * (e/time*a0^2) + (e^2/hbar*c) * (1/time)^2 * Ha / (e * a0)
372 ! [e/time^2*a0^2] = (e/time^2*a0^2) + (e/hbar*c) * 1/time^2 * Ha/a0, and [c]=a0/time, so [hbar*c]=Ha*a0
373 ! [e/time^2*a0^2] = (e/time^2*a0^2) + (e/time^2*a0^2)
374
375 select type (algo => this%algo)
376 class is (propagator_t)
377
378 done = .true.
379 select case (operation%id)
381 ! For the moment we do nothing
382
383 case (rk4_start)
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))
386
388 safe_deallocate_a(this%e_field_dt_half)
389 safe_deallocate_a(this%e_field_dt_full)
390
391 case (rk4_extrapolate)
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)
395
396 case (rk4_propagate)
397 do idim=1, 3
398 !$omp parallel do private(k1, k2, k3, k4)
399 do ip = 1, this%gr%np
400 k1(idim) = current_derivative_dir(this%current_p(ip, idim), &
401 this%e_field(ip,idim), this%gamma_p, this%omega_p, this%strength_p)
402
403 k2(idim) = current_derivative_dir(this%current_p(ip, idim) + algo%dt * k1(idim) / m_two, &
404 this%e_field_dt_half(ip, idim), this%gamma_p, this%omega_p, this%strength_p)
405
406 k3(idim) = current_derivative_dir(this%current_p(ip, idim) + algo%dt * k2(idim) / m_two, &
407 this%e_field_dt_half(ip, idim), this%gamma_p, this%omega_p, this%strength_p)
408
409 k4(idim) = current_derivative_dir(this%current_p(ip, idim) + algo%dt * k3(idim), &
410 this%e_field_dt_full(ip, idim), this%gamma_p, this%omega_p, this%strength_p)
411
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))
414 end do
415 end do
416 updated_quantities = ["current"]
417
418 case default
419 done = .false.
420 end select
421 end select
422
423 call profiling_out(trim(this%namespace%get())//":"//trim(operation%id))
425 contains
426
427 function current_derivative_dir(current_p, e_field, gamma_p, omega_p, strength_p) result(current_dot)
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
434
435 current_dot = - gamma_p * current_p + strength_p * p_ep * omega_p**2 * e_field
436 end function current_derivative_dir
437
440 ! ---------------------------------------------------------
441 logical function dispersive_medium_is_tolerance_reached(this, tol) result(converged)
442 class(dispersive_medium_t), intent(in) :: this
443 real(real64), intent(in) :: tol
444
446
447 ! this routine is never called at present, no reason to be here
448 assert(.false.)
449 converged = .false.
450
453
454 ! ---------------------------------------------------------
455 subroutine dispersive_medium_copy_quantities_to_interaction(partner, interaction)
456 class(dispersive_medium_t), intent(inout) :: partner
457 class(interaction_surrogate_t), intent(inout) :: interaction
458
460 call profiling_in(trim(partner%namespace%get())//":"//"COPY_QUANTITY_INTER")
461
462 select type (interaction)
464 interaction%partner_field(:,:) = partner%current_p
465 call interaction%do_mapping()
466 class default
467 message(1) = "Unsupported interaction."
468 call messages_fatal(1)
469 end select
470
471 call profiling_out(trim(partner%namespace%get())//":"//"COPY_QUANTITY_INTER")
474
475 ! ---------------------------------------------------------
477 class(dispersive_medium_t), intent(inout) :: this
478
479 character(len=256) :: filename
480 integer :: idir, err
481 type(interaction_iterator_t) :: iter
482 class(interaction_t), pointer :: interaction
483
485 call profiling_in(trim(this%namespace%get())//":"//"RESTART_WRITE")
486
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)
492 end do
493
494 call iter%start(this%interactions)
495 do while (iter%has_next())
496 interaction => iter%get_next()
497 select type (interaction)
498 class is (mxll_e_field_to_matter_t)
499 call interaction%write_restart(this%gr, this%space, this%restart_dump, err)
500 end select
501 end do
502
503 if (err == 0) then
504 message(1) = "Successfully wrote restart data for system "//trim(this%namespace%get())
505 call messages_info(1, namespace=this%namespace)
506 end if
507
508 end if
509
510 call profiling_out(trim(this%namespace%get())//":"//"RESTART_WRITE")
513
514 ! ---------------------------------------------------------
515 ! this function returns true if restart data could be read
516 logical function dispersive_medium_restart_read_data(this)
517 class(dispersive_medium_t), intent(inout) :: this
518
519 character(len=256) :: filename
520 integer :: idir, err
521 type(interaction_iterator_t) :: iter
522 class(interaction_t), pointer :: interaction
523
525 call profiling_in(trim(this%namespace%get())//":"//"RESTART_READ")
526
528 if (.not. this%restart_load%skip()) then
529 do idir = 1, 3
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)
533 end do
534
535 call iter%start(this%interactions)
536 do while (iter%has_next())
537 interaction => iter%get_next()
538 select type (interaction)
539 class is (mxll_e_field_to_matter_t)
540 call interaction%read_restart(this%gr, this%space, this%restart_load, err)
541 end select
542 end do
543
544 if (err == 0) then
546 this%from_scratch = .false.
547 else
548 ! set to 0 again in case this was read incompletely
549 this%current_p(:, :) = m_zero
550 end if
551 end if
552
553 call profiling_out(trim(this%namespace%get())//":"//"RESTART_READ")
556
557 ! ---------------------------------------------------------
559 class(dispersive_medium_t), intent(inout) :: this
560
562
563 ! TODO: evaluate proper energy associated with the current distribution
564 ! For Drude model: check Giuliani/Vignale book, section 4.6.1
565 this%kinetic_energy = m_zero
566
568
570
571 ! ---------------------------------------------------------
572 subroutine dispersive_medium_output_start(this)
573 class(dispersive_medium_t), intent(inout) :: this
574
575 integer :: first, id, idir
576 character(len=130) :: aux
577
579
580 call profiling_in("DISP_MEDIUM_OUTPUT_START")
581
582 select type (algo => this%algo)
583 class is (propagator_t)
584
585 if (this%iteration%counter() == 0) then
586 first = 0
587 else
588 first = this%iteration%counter() + 1
589 end if
590
591 call io_mkdir('td.general', this%namespace)
592 call write_iter_init(this%write_handle, first, units_from_atomic(units_out%time, algo%dt), &
593 trim(io_workpath("td.general/current_at_points", this%namespace)))
594
595 if (mpi_world%is_root()) then
596 if (this%iteration%counter() == 0) then
597 call write_iter_clear(this%write_handle)
598 call write_iter_string(this%write_handle,&
599 '################################################################################')
600 call write_iter_nl(this%write_handle)
601 call write_iter_string(this%write_handle,'# HEADER')
602 call write_iter_nl(this%write_handle)
603
604 ! first line
605 write(aux, '(a7,e20.12,3a)') '# dt = ', units_from_atomic(units_out%time, algo%dt), &
606 " [", trim(units_abbrev(units_out%time)), "]"
607 call write_iter_string(this%write_handle, aux)
608 call write_iter_nl(this%write_handle)
609
610 call write_iter_header_start(this%write_handle)
612 do id = 1, this%n_output_points
613 do idir = 1, 3
614 write(aux, '(a,i1,a,i1,a)') 'j(', id, ',', idir, ')'
615 call write_iter_header(this%write_handle, aux)
616 end do
617 end do
618
619 call write_iter_nl(this%write_handle)
620 call write_iter_header(this%write_handle, '# [' // trim(units_abbrev(units_out%time)) // ']')
621
622 !FIXME: this is not printing the proper unit to output yet, for some reason
623 aux = ' [' // trim(units_abbrev(unit_one/(units_out%time*units_out%length**2))) // ']'
624 do id = 1, this%n_output_points
625 do idir = 1, 3
626 call write_iter_header(this%write_handle, aux)
627 end do
628 end do
629 call write_iter_nl(this%write_handle)
630 call write_iter_string(this%write_handle,&
631 '################################################################################')
632 call write_iter_nl(this%write_handle)
633 end if
634 end if
635
636 if (first == 0) call this%output_write()
637
638 end select
639
640 call profiling_out("DISP_MEDIUM_OUTPUT_START")
641
643 end subroutine dispersive_medium_output_start
644
645 ! ---------------------------------------------------------
646 subroutine dispersive_medium_output_write(this)
647 class(dispersive_medium_t), intent(inout) :: this
648
649 real(real64) :: dmin, dtmp(3)
650 integer :: ip, pos_index, rankmin
651
653 call profiling_in(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
654
655 select type (algo => this%algo)
656 class is (propagator_t)
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,:)
661 end if
662 if (this%gr%parallel_in_domains) then
663 call this%gr%mpi_grp%bcast(dtmp(:), 3, mpi_double_precision, rankmin)
664 end if
665 this%current_at_point(ip,:) = units_from_atomic((unit_one/units_out%time)/(units_out%length**2), dtmp(:))
666 end do
668 if (.not. mpi_world%is_root()) then
669 call profiling_out(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
671 return ! only first node outputs
672 end if
673
674 call write_iter_start(this%write_handle)
675 do ip = 1, this%n_output_points
676 dtmp = this%current_at_point(ip,1:3)
677 call write_iter_double(this%write_handle, dtmp, 3)
678 end do
679
680 call write_iter_nl(this%write_handle)
681 call write_iter_flush(this%write_handle)
682
683 end select
684
685 call profiling_out(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
687 end subroutine dispersive_medium_output_write
688
689 ! ---------------------------------------------------------
690 subroutine dispersive_medium_output_finish(this)
691 class(dispersive_medium_t), intent(inout) :: this
692
693
695
696 call profiling_in("DISP_MEDIUM_OUTPUT_FINISH")
697
698 call write_iter_end(this%write_handle)
699
700 call profiling_out("DISP_MEDIUM_OUTPUT_FINISH")
701
704
705 ! ---------------------------------------------------------
706 subroutine dispersive_medium_get_efield(this, time, efield)
707 class(dispersive_medium_t), intent(inout) :: this
708 real(real64), intent(in) :: time
709 real(real64), contiguous, intent(inout) :: efield(:, :)
710
711 type(interaction_iterator_t) :: iter
712 real(real64), allocatable :: efield_tmp(:, :)
713
715
716 safe_allocate(efield_tmp(1:this%gr%np, 1:3))
717 efield = m_zero
718 ! interpolate efield from interaction
719 call iter%start(this%interactions)
720 do while (iter%has_next())
721 select type (interaction => iter%get_next())
722 class is (mxll_e_field_to_matter_t)
723 call interaction%interpolate(time, efield_tmp)
724 call lalg_axpy(this%gr%np, 3, m_one, efield_tmp, efield)
725 end select
726 end do
727 safe_deallocate_a(efield_tmp)
728
730 end subroutine dispersive_medium_get_efield
731
732 ! ---------------------------------------------------------
733 subroutine dispersive_medium_finalize(this)
734 type(dispersive_medium_t), intent(inout) :: this
735
737 call system_end(this)
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)
742 call multicomm_end(this%mc)
743 call grid_end(this%gr)
745 end subroutine dispersive_medium_finalize
746
748
749!! Local Variables:
750!! mode: f90
751!! coding: utf-8
752!! End:
real(real64) function current_derivative_dir(current_p, e_field, gamma_p, omega_p, strength_p)
constant times a vector plus a vector
Definition: lalg_basic.F90:173
Writes to the corresponding file and adds one to the iteration. Must be called after write_iter_init(...
Definition: write_iter.F90:163
This module defines the abstract interfact for algorithm factories.
This module implements the basic elements defining algorithms.
Definition: algorithm.F90:143
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
Definition: global.F90:202
real(real64), parameter, public m_zero
Definition: global.F90:200
real(real64), parameter, public p_ep
Definition: global.F90:246
real(real64), parameter, public m_one
Definition: global.F90:201
This module implements the underlying real-space grid.
Definition: grid.F90:119
subroutine, public grid_init_stage_1(gr, namespace, space, grp, symm, latt, n_sites, site_position)
First stage of the grid initialization.
Definition: grid.F90:197
subroutine, public grid_init_stage_2(gr, namespace, space, mc, qvector)
Second stage of the grid initialization.
Definition: grid.F90:463
subroutine, public grid_end(gr)
finalize a grid object
Definition: grid.F90:490
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.
Definition: io.F90:116
character(len=max_path_len) function, public io_workpath(path, namespace)
construct path name from given name and namespace
Definition: io.F90:318
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:361
This module defines a linear medium for use in classical electrodynamics calculations.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
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.
Definition: mesh.F90:386
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1068
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:691
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:272
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
subroutine, public multicomm_end(mc)
Definition: multicomm.F90:706
subroutine, public multicomm_init(mc, namespace, base_grp, mode_para, n_node, index_range, min_range)
create index and domain communicators
Definition: multicomm.F90:273
Maxwell-field-to-matter interactions.
integer, parameter, public mxll_field_total
this module contains the low-level part of the output system
Definition: output_low.F90:117
integer function, public parse_block(namespace, name, blk, check_varinfo_)
Definition: parser.F90:623
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:631
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
Definition: profiling.F90:554
This module implements the basic propagator framework.
Definition: propagator.F90:119
character(len=algo_label_len), parameter, public store_current_status
Definition: propagator.F90:176
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...
Definition: quantity.F90:140
Implementation details for regridding.
Definition: regridding.F90:172
integer, parameter, public restart_type_dump
Definition: restart.F90:184
integer, parameter, public restart_td
Definition: restart.F90:156
integer, parameter, public restart_type_load
Definition: restart.F90:184
This module implements the abstract system type.
Definition: system.F90:120
subroutine, public system_end(this)
Definition: system.F90:1152
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
character(len=20) pure function, public units_abbrev(this)
Definition: unit.F90:225
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.
Definition: utils.F90:120
character pure function, public index2axis(idir)
Definition: utils.F90:205
Explicit interfaces to C functions, defined in write_iter_low.cc.
Definition: write_iter.F90:116
subroutine, public write_iter_header(out, string)
Definition: write_iter.F90:249
subroutine, public write_iter_string(out, string)
Definition: write_iter.F90:265
subroutine, public write_iter_init(out, iter, factor, file)
Definition: write_iter.F90:229
Descriptor of one algorithmic operation.
Definition: algorithm.F90:165
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.
Definition: mpi.F90:144
class to transfer a Maxwell electric field to a medium
Abstract class implementing propagators.
Definition: propagator.F90:144
Implements the 4th order Runge Kutta propagator.
Systems (system_t) can expose quantities that can be used to calculate interactions with other system...
Definition: quantity.F90:173
Abstract class for systems.
Definition: system.F90:175
int true(void)