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
41 use mesh_oct_m
42 use mpi_oct_m
47 use parser_oct_m
54 use space_oct_m
55 use system_oct_m
57 use unit_oct_m
58 use utils_oct_m
61
62 implicit none
63
64 private
65 public :: &
68
70 type, extends(system_t) :: dispersive_medium_t
71 private
72 type(space_t) :: space
73 real(real64) :: omega_p
74 real(real64) :: gamma_p
75 real(real64) :: strength_p
76 real(real64), allocatable :: current_p(:,:)
77 real(real64), allocatable :: e_field(:,:)
78 real(real64), allocatable :: e_field_dt_half(:,:)
79 real(real64), allocatable :: e_field_dt_full(:,:)
80 real(real64), allocatable :: current_at_point(:,:)
81 real(real64), allocatable :: selected_points_coordinate(:,:)
82 integer :: n_output_points
83 integer :: medium_type
84 type(grid_t) :: gr
85 type(multicomm_t) :: mc
86 type(c_ptr) :: write_handle
87 type(output_t) :: outp
88 logical :: from_scratch = .true.
89 type(restart_t) :: restart_load
90 type(restart_t) :: restart_dump
91
92 contains
93 procedure :: init_interaction => dispersive_medium_init_interaction
94 procedure :: init_interaction_as_partner => dispersive_medium_init_interaction_as_partner
95 procedure :: initialize => dispersive_medium_initialize
96 procedure :: do_algorithmic_operation => dispersive_medium_do_algorithmic_operation
97 procedure :: is_tolerance_reached => dispersive_medium_is_tolerance_reached
98 procedure :: copy_quantities_to_interaction => dispersive_medium_copy_quantities_to_interaction
99 procedure :: restart_write_data => dispersive_medium_restart_write_data
100 procedure :: restart_read_data => dispersive_medium_restart_read_data
101 procedure :: update_kinetic_energy => dispersive_medium_update_kinetic_energy
102 procedure :: output_start => dispersive_medium_output_start
103 procedure :: output_write => dispersive_medium_output_write
104 procedure :: output_finish => dispersive_medium_output_finish
105 procedure :: init_parallelization => dispersive_medium_init_parallelization
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
116
117contains
118
119 ! ---------------------------------------------------------
124 function dispersive_medium_constructor(namespace) result(sys)
125 class(dispersive_medium_t), pointer :: sys
126 type(namespace_t), intent(in) :: namespace
127
129
130 allocate(sys)
131
132 call dispersive_medium_init(sys, namespace)
133
136
137 ! ---------------------------------------------------------
142 ! ---------------------------------------------------------
143 subroutine dispersive_medium_init(this, namespace)
144 class(dispersive_medium_t), target, intent(inout) :: this
145 type(namespace_t), intent(in) :: namespace
146
147 integer :: nlines, ncols, idim, il
148 real(real64) :: pos(3)
149 type(block_t) :: blk
150
151 push_sub(dispersive_medium_init)
152
153 this%namespace = namespace
154
155 call profiling_in('DISP_MEDIUM_INIT')
156
157 this%space = space_t(this%namespace)
158 if (this%space%is_periodic()) then
159 call messages_not_implemented('Linear medium for periodic systems', namespace=namespace)
160 end if
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)
166 ! Parse electromagnetic properties of dispersive media...
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)
209
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
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 profiling_out('DISP_MEDIUM_INIT')
251
253 end subroutine dispersive_medium_init
254
255 ! ---------------------------------------------------------
256 subroutine dispersive_medium_init_parallelization(this, grp)
257 class(dispersive_medium_t), intent(inout) :: this
258 type(mpi_grp_t), intent(in) :: grp
259
260 integer(int64) :: index_range(4)
261 integer :: ierr
262
264
265 call system_init_parallelization(this, grp)
266 ! store the ranges for these two indices (serves as initial guess
267 ! for parallelization strategy)
268 index_range(1) = this%gr%np_global ! Number of points in mesh
269 index_range(2) = 1 ! Number of states
270 index_range(3) = 1 ! Number of k-points
271 index_range(4) = 100000 ! Some large number
272
273 ! create index and domain communicators
274 call multicomm_init(this%mc, this%namespace, mpi_world, calc_mode_par, mpi_world%size, &
275 index_range, (/ 5000, 1, 1, 1 /))
276 call grid_init_stage_2(this%gr, this%namespace, this%space, this%mc)
277
278 call restart_init(this%restart_dump, this%namespace, restart_td, restart_type_dump, &
279 this%mc, ierr, mesh=this%gr)
280 call restart_init(this%restart_load, this%namespace, restart_td, restart_type_load, &
281 this%mc, ierr, mesh=this%gr)
282
283 safe_allocate(this%current_p(1:this%gr%np, 1:3))
284 safe_allocate(this%e_field(1:this%gr%np, 1:3))
285 this%e_field(:,:) = m_zero
286
289
290 ! ---------------------------------------------------------
291 subroutine dispersive_medium_init_interaction(this, interaction)
292 class(dispersive_medium_t), target, intent(inout) :: this
293 class(interaction_t), intent(inout) :: interaction
294
295 integer :: depth
296
298
299 select type (interaction)
301 call interaction%init(this%gr, 3)
302 interaction%type = mxll_field_total
303
304 ! set interpolation depth for interaction
305 ! interpolation depth depends on the propagator
306 select type (prop => this%algo)
307 type is (propagator_rk4_t)
308 ! TODO: should be five, two is only for backwards compatibility
309 depth = 2
310 class default
311 message(1) = "The chosen propagator does not yet support interaction interpolation"
312 call messages_fatal(1)
313 end select
314 call interaction%init_interpolation(depth, interaction%label)
315
316 class default
317 message(1) = "Trying to initialize an unsupported interaction by a Dispersive medium."
318 call messages_fatal(1)
319 end select
320
323
324 ! ---------------------------------------------------------
325 subroutine dispersive_medium_init_interaction_as_partner(partner, interaction)
326 class(dispersive_medium_t), intent(in) :: partner
327 class(interaction_surrogate_t), intent(inout) :: interaction
328
330
331 select type (interaction)
333 call interaction%init_from_partner(partner%gr, partner%space, partner%namespace)
334 class default
335 message(1) = "Trying to initialize an unsupported interaction by a linear medium."
336 call messages_fatal(1)
337 end select
338
341
342 ! ---------------------------------------------------------
343 subroutine dispersive_medium_initialize(this)
344 class(dispersive_medium_t), intent(inout) :: this
345
347
348 this%from_scratch = .true.
349 this%current_p(:,:) = m_zero
350
352 end subroutine dispersive_medium_initialize
353
354 ! ---------------------------------------------------------
355 logical function dispersive_medium_do_algorithmic_operation(this, operation, updated_quantities) result(done)
356 class(dispersive_medium_t), intent(inout) :: this
357 class(algorithmic_operation_t), intent(in) :: operation
358 character(len=:), allocatable, intent(out) :: updated_quantities(:)
359
360 integer :: ip, idim
361 real(real64) :: k1(1:3), k2(1:3), k3(1:3), k4(1:3)
362
364 call profiling_in(trim(this%namespace%get())//":"//trim(operation%id))
365
366 ! calculation of the current using ADE
367 ! \partial_t J_P(t) = - \gamma_p * J_P(t) + \epsilon_0 \omega_p^2 E(t)
368 ! (Computational Electrodynamics, Taflov and Hagness, 3rd Ed., section 9.4.3, eq. 9.56c)
369 ! Analysis of Units:
370 ! [e/time^2*a0^2] = (1/time) * (e/time*a0^2) + (e^2/hbar*c) * (1/time)^2 * Ha / (e * a0)
371 ! [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
372 ! [e/time^2*a0^2] = (e/time^2*a0^2) + (e/time^2*a0^2)
373
374 select type (algo => this%algo)
375 class is (propagator_t)
376
377 done = .true.
378 select case (operation%id)
380 ! For the moment we do nothing
381
382 case (rk4_start)
383 safe_allocate(this%e_field_dt_half(1:this%gr%np, 1:3))
384 safe_allocate(this%e_field_dt_full(1:this%gr%np, 1:3))
385
386 case (rk4_finish)
387 safe_deallocate_a(this%e_field_dt_half)
388 safe_deallocate_a(this%e_field_dt_full)
389
390 case (rk4_extrapolate)
391 call this%get_efield(this%iteration%value(), this%e_field)
392 call this%get_efield(this%iteration%value()+algo%dt/m_two, this%e_field_dt_half)
393 call this%get_efield(this%iteration%value()+algo%dt, this%e_field_dt_full)
394
395 case (rk4_propagate)
396 do idim=1, 3
397 !$omp parallel do private(k1, k2, k3, k4)
398 do ip = 1, this%gr%np
399 k1(idim) = current_derivative_dir(this%current_p(ip, idim), &
400 this%e_field(ip,idim), this%gamma_p, this%omega_p, this%strength_p)
401
402 k2(idim) = current_derivative_dir(this%current_p(ip, idim) + algo%dt * k1(idim) / m_two, &
403 this%e_field_dt_half(ip, idim), this%gamma_p, this%omega_p, this%strength_p)
404
405 k3(idim) = current_derivative_dir(this%current_p(ip, idim) + algo%dt * k2(idim) / m_two, &
406 this%e_field_dt_half(ip, idim), this%gamma_p, this%omega_p, this%strength_p)
407
408 k4(idim) = current_derivative_dir(this%current_p(ip, idim) + algo%dt * k3(idim), &
409 this%e_field_dt_full(ip, idim), this%gamma_p, this%omega_p, this%strength_p)
410
411 this%current_p(ip, idim) = this%current_p(ip, idim) + algo%dt / 6.0_real64 * &
412 (k1(idim) + m_two * (k2(idim) + k3(idim)) + k4(idim))
413 end do
414 end do
415 updated_quantities = ["current"]
416
417 case default
418 done = .false.
419 end select
420 end select
421
422 call profiling_out(trim(this%namespace%get())//":"//trim(operation%id))
424 contains
425
426 function current_derivative_dir(current_p, e_field, gamma_p, omega_p, strength_p) result(current_dot)
427 real(real64), intent(in) :: current_p
428 real(real64), intent(in) :: e_field
429 real(real64), intent(in) :: gamma_p
430 real(real64), intent(in) :: omega_p
431 real(real64), intent(in) :: strength_p
432 real(real64) :: current_dot
433
434 current_dot = - gamma_p * current_p + strength_p * p_ep * omega_p**2 * e_field
435 end function current_derivative_dir
438
439 ! ---------------------------------------------------------
440 logical function dispersive_medium_is_tolerance_reached(this, tol) result(converged)
441 class(dispersive_medium_t), intent(in) :: this
442 real(real64), intent(in) :: tol
443
445
446 ! this routine is never called at present, no reason to be here
447 assert(.false.)
448 converged = .false.
449
452
453 ! ---------------------------------------------------------
454 subroutine dispersive_medium_copy_quantities_to_interaction(partner, interaction)
455 class(dispersive_medium_t), intent(inout) :: partner
456 class(interaction_surrogate_t), intent(inout) :: interaction
457
459 call profiling_in(trim(partner%namespace%get())//":"//"COPY_QUANTITY_INTER")
460
461 select type (interaction)
463 interaction%partner_field(:,:) = partner%current_p
464 call interaction%do_mapping()
465 class default
466 message(1) = "Unsupported interaction."
467 call messages_fatal(1)
468 end select
469
470 call profiling_out(trim(partner%namespace%get())//":"//"COPY_QUANTITY_INTER")
473
474 ! ---------------------------------------------------------
476 class(dispersive_medium_t), intent(inout) :: this
477
478 character(len=256) :: filename
479 integer :: idir, err
480 type(interaction_iterator_t) :: iter
481 class(interaction_t), pointer :: interaction
482
484 call profiling_in(trim(this%namespace%get())//":"//"RESTART_WRITE")
485
486 if (.not. restart_skip(this%restart_dump)) then
487 do idir = 1, this%space%dim
488 write(filename, "(A,A)") "current_p-", index2axis(idir)
489 call restart_write_mesh_function(this%restart_dump, this%space, trim(filename), this%gr, &
490 this%current_p(:, idir), err)
491 end do
492
493 call iter%start(this%interactions)
494 do while (iter%has_next())
495 interaction => iter%get_next()
496 select type (interaction)
497 class is (mxll_e_field_to_matter_t)
498 call interaction%write_restart(this%gr, this%space, this%restart_dump, err)
499 end select
500 end do
501
502 if (err == 0) then
503 message(1) = "Successfully wrote restart data for system "//trim(this%namespace%get())
504 call messages_info(1, namespace=this%namespace)
505 end if
506
507 end if
508
509 call profiling_out(trim(this%namespace%get())//":"//"RESTART_WRITE")
512
513 ! ---------------------------------------------------------
514 ! this function returns true if restart data could be read
515 logical function dispersive_medium_restart_read_data(this)
516 class(dispersive_medium_t), intent(inout) :: this
517
518 character(len=256) :: filename
519 integer :: idir, err
520 type(interaction_iterator_t) :: iter
521 class(interaction_t), pointer :: interaction
522
524 call profiling_in(trim(this%namespace%get())//":"//"RESTART_READ")
525
527 if (.not. restart_skip(this%restart_load)) then
528 do idir = 1, 3
529 write(filename, "(A,A)") "current_p-", index2axis(idir)
530 call restart_read_mesh_function(this%restart_load, this%space, trim(filename), this%gr, &
531 this%current_p(:, idir), err)
532 end do
534 call iter%start(this%interactions)
535 do while (iter%has_next())
536 interaction => iter%get_next()
537 select type (interaction)
538 class is (mxll_e_field_to_matter_t)
539 call interaction%read_restart(this%gr, this%space, this%restart_load, err)
540 end select
541 end do
542
543 if (err == 0) then
545 this%from_scratch = .false.
546 else
547 ! set to 0 again in case this was read incompletely
548 this%current_p(:, :) = m_zero
549 end if
550 end if
551
552 call profiling_out(trim(this%namespace%get())//":"//"RESTART_READ")
555
556 ! ---------------------------------------------------------
558 class(dispersive_medium_t), intent(inout) :: this
559
561
562 ! TODO: evaluate proper energy associated with the current distribution
563 ! For Drude model: check Giuliani/Vignale book, section 4.6.1
564 this%kinetic_energy = m_zero
565
567
569
570 ! ---------------------------------------------------------
571 subroutine dispersive_medium_output_start(this)
572 class(dispersive_medium_t), intent(inout) :: this
573
574 integer :: first, id, idir
575 character(len=130) :: aux
576
578
579 call profiling_in("DISP_MEDIUM_OUTPUT_START")
580
581 select type (algo => this%algo)
582 class is (propagator_t)
583
584 if (this%iteration%counter() == 0) then
585 first = 0
586 else
587 first = this%iteration%counter() + 1
588 end if
589
590 call io_mkdir('td.general', this%namespace)
591 call write_iter_init(this%write_handle, first, units_from_atomic(units_out%time, algo%dt), &
592 trim(io_workpath("td.general/current_at_points", this%namespace)))
593
594 if (mpi_grp_is_root(mpi_world)) then
595 if (this%iteration%counter() == 0) then
596 call write_iter_clear(this%write_handle)
597 call write_iter_string(this%write_handle,&
598 '################################################################################')
599 call write_iter_nl(this%write_handle)
600 call write_iter_string(this%write_handle,'# HEADER')
601 call write_iter_nl(this%write_handle)
602
603 ! first line
604 write(aux, '(a7,e20.12,3a)') '# dt = ', units_from_atomic(units_out%time, algo%dt), &
605 " [", trim(units_abbrev(units_out%time)), "]"
606 call write_iter_string(this%write_handle, aux)
607 call write_iter_nl(this%write_handle)
609 call write_iter_header_start(this%write_handle)
610
611 do id = 1, this%n_output_points
612 do idir = 1, 3
613 write(aux, '(a,i1,a,i1,a)') 'j(', id, ',', idir, ')'
614 call write_iter_header(this%write_handle, aux)
615 end do
616 end do
617
618 call write_iter_nl(this%write_handle)
619 call write_iter_header(this%write_handle, '# [' // trim(units_abbrev(units_out%time)) // ']')
620
621 !FIXME: this is not printing the proper unit to output yet, for some reason
622 aux = ' [' // trim(units_abbrev(unit_one/(units_out%time*units_out%length**2))) // ']'
623 do id = 1, this%n_output_points
624 do idir = 1, 3
625 call write_iter_header(this%write_handle, aux)
626 end do
627 end do
628 call write_iter_nl(this%write_handle)
629 call write_iter_string(this%write_handle,&
630 '################################################################################')
631 call write_iter_nl(this%write_handle)
632 end if
633 end if
634
635 if (first == 0) call this%output_write()
636
637 end select
638
639 call profiling_out("DISP_MEDIUM_OUTPUT_START")
640
642 end subroutine dispersive_medium_output_start
643
644 ! ---------------------------------------------------------
645 subroutine dispersive_medium_output_write(this)
646 class(dispersive_medium_t), intent(inout) :: this
647
648 real(real64) :: dmin, dtmp(3)
649 integer :: ip, pos_index, rankmin
652 call profiling_in(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
653
654 select type (algo => this%algo)
655 class is (propagator_t)
656 do ip = 1, this%n_output_points
657 pos_index = mesh_nearest_point(this%gr, this%selected_points_coordinate(ip,:), dmin, rankmin)
658 if (this%gr%mpi_grp%rank == rankmin) then
659 dtmp(:) = this%current_p(pos_index,:)
660 end if
661 if (this%gr%parallel_in_domains) then
662 call this%gr%mpi_grp%bcast(dtmp(:), 3, mpi_double_precision, rankmin)
663 end if
664 this%current_at_point(ip,:) = units_from_atomic((unit_one/units_out%time)/(units_out%length**2), dtmp(:))
665 end do
666
667 if (.not. mpi_grp_is_root(mpi_world)) then
668 call profiling_out(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
670 return ! only first node outputs
671 end if
672
673 call write_iter_start(this%write_handle)
674 do ip = 1, this%n_output_points
675 dtmp = this%current_at_point(ip,1:3)
676 call write_iter_double(this%write_handle, dtmp, 3)
677 end do
678
679 call write_iter_nl(this%write_handle)
680 call write_iter_flush(this%write_handle)
681
682 end select
683
684 call profiling_out(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
686 end subroutine dispersive_medium_output_write
687
688 ! ---------------------------------------------------------
689 subroutine dispersive_medium_output_finish(this)
690 class(dispersive_medium_t), intent(inout) :: this
691
692
694
695 call profiling_in("DISP_MEDIUM_OUTPUT_FINISH")
696
697 call write_iter_end(this%write_handle)
698
699 call profiling_out("DISP_MEDIUM_OUTPUT_FINISH")
700
703
704 ! ---------------------------------------------------------
705 subroutine dispersive_medium_get_efield(this, time, efield)
706 class(dispersive_medium_t), intent(inout) :: this
707 real(real64), intent(in) :: time
708 real(real64), contiguous, intent(inout) :: efield(:, :)
709
710 type(interaction_iterator_t) :: iter
711 real(real64), allocatable :: efield_tmp(:, :)
712
714
715 safe_allocate(efield_tmp(1:this%gr%np, 1:3))
716 efield = m_z0
717 ! interpolate efield from interaction
718 call iter%start(this%interactions)
719 do while (iter%has_next())
720 select type (interaction => iter%get_next())
721 class is (mxll_e_field_to_matter_t)
722 call interaction%interpolate(time, efield_tmp)
723 call lalg_axpy(this%gr%np, 3, m_one, efield_tmp, efield)
724 end select
725 end do
726 safe_deallocate_a(efield_tmp)
727
729 end subroutine dispersive_medium_get_efield
730
731 ! ---------------------------------------------------------
732 subroutine dispersive_medium_finalize(this)
733 type(dispersive_medium_t), intent(inout) :: this
734
736 call system_end(this)
737 safe_deallocate_a(this%current_p)
738 safe_deallocate_a(this%e_field)
739 safe_deallocate_a(this%selected_points_coordinate)
740 safe_deallocate_a(this%current_at_point)
741 call multicomm_end(this%mc)
742 call grid_end(this%gr)
744 end subroutine dispersive_medium_finalize
745
747
748!! Local Variables:
749!! mode: f90
750!! coding: utf-8
751!! 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:171
Writes to the corresponding file and adds one to the iteration. Must be called after write_iter_init(...
Definition: write_iter.F90:167
This module defines the abstract interfact for algorithm factories.
This module implements the basic elements defining algorithms.
Definition: algorithm.F90:141
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
Definition: global.F90:190
real(real64), parameter, public m_zero
Definition: global.F90:188
real(real64), parameter, public p_ep
Definition: global.F90:228
complex(real64), parameter, public m_z0
Definition: global.F90:198
real(real64), parameter, public m_one
Definition: global.F90:189
This module implements the underlying real-space grid.
Definition: grid.F90:117
subroutine, public grid_init_stage_1(gr, namespace, space, symm, latt, n_sites, site_position)
First stage of the grid initialization.
Definition: grid.F90:194
subroutine, public grid_init_stage_2(gr, namespace, space, mc, qvector)
Second stage of the grid initialization.
Definition: grid.F90:465
subroutine, public grid_end(gr)
finalize a grid object
Definition: grid.F90:493
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:114
character(len=max_path_len) function, public io_workpath(path, namespace)
Definition: io.F90:270
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:311
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:118
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:380
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1113
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:414
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:713
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:616
logical function mpi_grp_is_root(grp)
Is the current MPI process of grpcomm, root.
Definition: mpi.F90:430
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:266
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:145
subroutine, public multicomm_end(mc)
Definition: multicomm.F90:889
subroutine, public multicomm_init(mc, namespace, base_grp, mode_para, n_node, index_range, min_range)
create index and domain communicators
Definition: multicomm.F90:264
integer, parameter, public mxll_field_total
this module contains the low-level part of the output system
Definition: output_low.F90:115
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
This module implements the basic propagator framework.
Definition: propagator.F90:117
character(len=algo_label_len), parameter, public store_current_status
Definition: propagator.F90:169
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:138
Implementation details for regridding.
Definition: regridding.F90:170
subroutine, public restart_init(restart, namespace, data_type, type, mc, ierr, mesh, dir, exact)
Initializes a restart object.
Definition: restart.F90:516
integer, parameter, public restart_type_dump
Definition: restart.F90:245
logical pure function, public restart_skip(restart)
Returns true if the restart information should neither be read nor written. This might happen because...
Definition: restart.F90:969
integer, parameter, public restart_td
Definition: restart.F90:200
integer, parameter, public restart_type_load
Definition: restart.F90:245
This module implements the abstract system type.
Definition: system.F90:118
subroutine, public system_init_parallelization(this, grp)
Basic functionality: copy the MPI group. This function needs to be implemented by extended types that...
Definition: system.F90:1236
subroutine, public system_end(this)
Definition: system.F90:1145
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_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:118
character pure function, public index2axis(idir)
Definition: utils.F90:202
Explicit interfaces to C functions, defined in write_iter_low.cc.
Definition: write_iter.F90:114
Descriptor of one algorithmic operation.
Definition: algorithm.F90:163
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:142
class to transfer a Maxwell field to a medium
Abstract class implementing propagators.
Definition: propagator.F90:138
Implements a 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:171
Abstract class for systems.
Definition: system.F90:172
int true(void)