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 :: initial_conditions => dispersive_medium_initial_conditions
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 this%quantities(current)%updated_on_demand = .false.
248
249 call profiling_out('DISP_MEDIUM_INIT')
250
252 end subroutine dispersive_medium_init
253
254 ! ---------------------------------------------------------
255 subroutine dispersive_medium_init_parallelization(this, grp)
256 class(dispersive_medium_t), intent(inout) :: this
257 type(mpi_grp_t), intent(in) :: grp
258
259 integer(int64) :: index_range(4)
260 integer :: ierr
261
263
264 call system_init_parallelization(this, grp)
265 ! store the ranges for these two indices (serves as initial guess
266 ! for parallelization strategy)
267 index_range(1) = this%gr%np_global ! Number of points in mesh
268 index_range(2) = 1 ! Number of states
269 index_range(3) = 1 ! Number of k-points
270 index_range(4) = 100000 ! Some large number
271
272 ! create index and domain communicators
273 call multicomm_init(this%mc, this%namespace, mpi_world, calc_mode_par, mpi_world%size, &
274 index_range, (/ 5000, 1, 1, 1 /))
275 call grid_init_stage_2(this%gr, this%namespace, this%space, this%mc)
276
277 call restart_init(this%restart_dump, this%namespace, restart_td, restart_type_dump, &
278 this%mc, ierr, mesh=this%gr)
279 call restart_init(this%restart_load, this%namespace, restart_td, restart_type_load, &
280 this%mc, ierr, mesh=this%gr)
281
282 safe_allocate(this%current_p(1:this%gr%np, 1:3))
283 safe_allocate(this%e_field(1:this%gr%np, 1:3))
284 this%e_field(:,:) = m_zero
285
288
289 ! ---------------------------------------------------------
290 subroutine dispersive_medium_init_interaction(this, interaction)
291 class(dispersive_medium_t), target, intent(inout) :: this
292 class(interaction_t), intent(inout) :: interaction
293
294 integer :: depth
295
297
298 select type (interaction)
300 call interaction%init(this%gr, 3)
301 interaction%type = mxll_field_total
302
303 ! set interpolation depth for interaction
304 ! interpolation depth depends on the propagator
305 select type (prop => this%algo)
306 type is (propagator_rk4_t)
307 ! TODO: should be five, two is only for backwards compatibility
308 depth = 2
309 class default
310 message(1) = "The chosen propagator does not yet support interaction interpolation"
311 call messages_fatal(1)
312 end select
313 call interaction%init_interpolation(depth, interaction%label)
314
315 class default
316 message(1) = "Trying to initialize an unsupported interaction by a Dispersive medium."
317 call messages_fatal(1)
318 end select
319
322
323 ! ---------------------------------------------------------
324 subroutine dispersive_medium_init_interaction_as_partner(partner, interaction)
325 class(dispersive_medium_t), intent(in) :: partner
326 class(interaction_surrogate_t), intent(inout) :: interaction
327
329
330 select type (interaction)
332 call interaction%init_from_partner(partner%gr, partner%space, partner%namespace)
333 class default
334 message(1) = "Trying to initialize an unsupported interaction by a linear medium."
335 call messages_fatal(1)
336 end select
337
340
341 ! ---------------------------------------------------------
343 class(dispersive_medium_t), intent(inout) :: this
344
346
347 this%from_scratch = .true.
348 this%current_p(:,:) = m_zero
349
352
353 ! ---------------------------------------------------------
354 logical function dispersive_medium_do_algorithmic_operation(this, operation, updated_quantities) result(done)
355 class(dispersive_medium_t), intent(inout) :: this
356 class(algorithmic_operation_t), intent(in) :: operation
357 integer, allocatable, intent(out) :: updated_quantities(:)
358
359 integer :: ip, idim
360 real(real64) :: k1(1:3), k2(1:3), k3(1:3), k4(1:3)
361
363 call profiling_in(trim(this%namespace%get())//":"//trim(operation%id))
364
365 ! calculation of the current using ADE
366 ! \partial_t J_P(t) = - \gamma_p * J_P(t) + \epsilon_0 \omega_p^2 E(t)
367 ! (Computational Electrodynamics, Taflov and Hagness, 3rd Ed., section 9.4.3, eq. 9.56c)
368 ! Analysis of Units:
369 ! [e/time^2*a0^2] = (1/time) * (e/time*a0^2) + (e^2/hbar*c) * (1/time)^2 * Ha / (e * a0)
370 ! [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
371 ! [e/time^2*a0^2] = (e/time^2*a0^2) + (e/time^2*a0^2)
372
373 select type (algo => this%algo)
374 class is (propagator_t)
375
376 done = .true.
377 select case (operation%id)
379 ! For the moment we do nothing
380
381 case (rk4_start)
382 safe_allocate(this%e_field_dt_half(1:this%gr%np, 1:3))
383 safe_allocate(this%e_field_dt_full(1:this%gr%np, 1:3))
384
385 case (rk4_finish)
386 safe_deallocate_a(this%e_field_dt_half)
387 safe_deallocate_a(this%e_field_dt_full)
388
389 case (rk4_extrapolate)
390 call this%get_efield(this%iteration%value(), this%e_field)
391 call this%get_efield(this%iteration%value()+algo%dt/m_two, this%e_field_dt_half)
392 call this%get_efield(this%iteration%value()+algo%dt, this%e_field_dt_full)
393
394 case (rk4_propagate)
395 do idim=1, 3
396 !$omp parallel do private(k1, k2, k3, k4)
397 do ip = 1, this%gr%np
398 k1(idim) = current_derivative_dir(this%current_p(ip, idim), &
399 this%e_field(ip,idim), this%gamma_p, this%omega_p, this%strength_p)
400
401 k2(idim) = current_derivative_dir(this%current_p(ip, idim) + algo%dt * k1(idim) / m_two, &
402 this%e_field_dt_half(ip, idim), this%gamma_p, this%omega_p, this%strength_p)
403
404 k3(idim) = current_derivative_dir(this%current_p(ip, idim) + algo%dt * k2(idim) / m_two, &
405 this%e_field_dt_half(ip, idim), this%gamma_p, this%omega_p, this%strength_p)
406
407 k4(idim) = current_derivative_dir(this%current_p(ip, idim) + algo%dt * k3(idim), &
408 this%e_field_dt_full(ip, idim), this%gamma_p, this%omega_p, this%strength_p)
409
410 this%current_p(ip, idim) = this%current_p(ip, idim) + algo%dt / 6.0_real64 * &
411 (k1(idim) + m_two * (k2(idim) + k3(idim)) + k4(idim))
412 end do
413 end do
414 updated_quantities = [current]
415
416 case default
417 done = .false.
418 end select
419 end select
420
421 call profiling_out(trim(this%namespace%get())//":"//trim(operation%id))
423 contains
424
425 function current_derivative_dir(current_p, e_field, gamma_p, omega_p, strength_p) result(current_dot)
426 real(real64), intent(in) :: current_p
427 real(real64), intent(in) :: e_field
428 real(real64), intent(in) :: gamma_p
429 real(real64), intent(in) :: omega_p
430 real(real64), intent(in) :: strength_p
431 real(real64) :: current_dot
432
433 current_dot = - gamma_p * current_p + strength_p * p_ep * omega_p**2 * e_field
434 end function current_derivative_dir
437
438 ! ---------------------------------------------------------
439 logical function dispersive_medium_is_tolerance_reached(this, tol) result(converged)
440 class(dispersive_medium_t), intent(in) :: this
441 real(real64), intent(in) :: tol
442
444
445 ! this routine is never called at present, no reason to be here
446 assert(.false.)
447 converged = .false.
448
451
452 ! ---------------------------------------------------------
453 subroutine dispersive_medium_copy_quantities_to_interaction(partner, interaction)
454 class(dispersive_medium_t), intent(inout) :: partner
455 class(interaction_surrogate_t), intent(inout) :: interaction
456
458 call profiling_in(trim(partner%namespace%get())//":"//"COPY_QUANTITY_INTER")
459
460 select type (interaction)
462 interaction%partner_field(:,:) = partner%current_p
463 call interaction%do_mapping()
464 class default
465 message(1) = "Unsupported interaction."
466 call messages_fatal(1)
467 end select
468
469 call profiling_out(trim(partner%namespace%get())//":"//"COPY_QUANTITY_INTER")
472
473 ! ---------------------------------------------------------
475 class(dispersive_medium_t), intent(inout) :: this
476
477 character(len=256) :: filename
478 integer :: idir, err
479 type(interaction_iterator_t) :: iter
480 class(interaction_t), pointer :: interaction
481
483 call profiling_in(trim(this%namespace%get())//":"//"RESTART_WRITE")
484
485 if (.not. restart_skip(this%restart_dump)) then
486 do idir = 1, this%space%dim
487 write(filename, "(A,A)") "current_p-", index2axis(idir)
488 call restart_write_mesh_function(this%restart_dump, this%space, trim(filename), this%gr, &
489 this%current_p(:, idir), err)
490 end do
491
492 call iter%start(this%interactions)
493 do while (iter%has_next())
494 interaction => iter%get_next()
495 select type (interaction)
496 class is (mxll_e_field_to_matter_t)
497 call interaction%write_restart(this%gr, this%space, this%restart_dump, err)
498 end select
499 end do
500
501 if (err == 0) then
502 message(1) = "Successfully wrote restart data for system "//trim(this%namespace%get())
503 call messages_info(1, namespace=this%namespace)
504 end if
505
506 end if
507
508 call profiling_out(trim(this%namespace%get())//":"//"RESTART_WRITE")
511
512 ! ---------------------------------------------------------
513 ! this function returns true if restart data could be read
514 logical function dispersive_medium_restart_read_data(this)
515 class(dispersive_medium_t), intent(inout) :: this
516
517 character(len=256) :: filename
518 integer :: idir, err
519 type(interaction_iterator_t) :: iter
520 class(interaction_t), pointer :: interaction
521
523 call profiling_in(trim(this%namespace%get())//":"//"RESTART_READ")
524
526 if (.not. restart_skip(this%restart_load)) then
527 do idir = 1, 3
528 write(filename, "(A,A)") "current_p-", index2axis(idir)
529 call restart_read_mesh_function(this%restart_load, this%space, trim(filename), this%gr, &
530 this%current_p(:, idir), err)
531 end do
533 call iter%start(this%interactions)
534 do while (iter%has_next())
535 interaction => iter%get_next()
536 select type (interaction)
537 class is (mxll_e_field_to_matter_t)
538 call interaction%read_restart(this%gr, this%space, this%restart_load, err)
539 end select
540 end do
541
542 if (err == 0) then
544 this%from_scratch = .false.
545 else
546 ! set to 0 again in case this was read incompletely
547 this%current_p(:, :) = m_zero
548 end if
549 end if
550
551 call profiling_out(trim(this%namespace%get())//":"//"RESTART_READ")
554
555 ! ---------------------------------------------------------
557 class(dispersive_medium_t), intent(inout) :: this
558
560
561 ! TODO: evaluate proper energy associated with the current distribution
562 ! For Drude model: check Giuliani/Vignale book, section 4.6.1
563 this%kinetic_energy = m_zero
564
566
568
569 ! ---------------------------------------------------------
570 subroutine dispersive_medium_output_start(this)
571 class(dispersive_medium_t), intent(inout) :: this
572
573 integer :: first, id, idir
574 character(len=130) :: aux
575
577
578 call profiling_in("DISP_MEDIUM_OUTPUT_START")
579
580 select type (algo => this%algo)
581 class is (propagator_t)
582
583 if (this%iteration%counter() == 0) then
584 first = 0
585 else
586 first = this%iteration%counter() + 1
587 end if
588
589 call io_mkdir('td.general', this%namespace)
590 call write_iter_init(this%write_handle, first, units_from_atomic(units_out%time, algo%dt), &
591 trim(io_workpath("td.general/current_at_points", this%namespace)))
592
593 if (mpi_grp_is_root(mpi_world)) then
594 if (this%iteration%counter() == 0) then
595 call write_iter_clear(this%write_handle)
596 call write_iter_string(this%write_handle,&
597 '################################################################################')
598 call write_iter_nl(this%write_handle)
599 call write_iter_string(this%write_handle,'# HEADER')
600 call write_iter_nl(this%write_handle)
601
602 ! first line
603 write(aux, '(a7,e20.12,3a)') '# dt = ', units_from_atomic(units_out%time, algo%dt), &
604 " [", trim(units_abbrev(units_out%time)), "]"
605 call write_iter_string(this%write_handle, aux)
606 call write_iter_nl(this%write_handle)
608 call write_iter_header_start(this%write_handle)
609
610 do id = 1, this%n_output_points
611 do idir = 1, 3
612 write(aux, '(a,i1,a,i1,a)') 'j(', id, ',', idir, ')'
613 call write_iter_header(this%write_handle, aux)
614 end do
615 end do
616
617 call write_iter_nl(this%write_handle)
618 call write_iter_header(this%write_handle, '# [' // trim(units_abbrev(units_out%time)) // ']')
619
620 !FIXME: this is not printing the proper unit to output yet, for some reason
621 aux = ' [' // trim(units_abbrev(unit_one/(units_out%time*units_out%length**2))) // ']'
622 do id = 1, this%n_output_points
623 do idir = 1, 3
624 call write_iter_header(this%write_handle, aux)
625 end do
626 end do
627 call write_iter_nl(this%write_handle)
628 call write_iter_string(this%write_handle,&
629 '################################################################################')
630 call write_iter_nl(this%write_handle)
631 end if
632 end if
633
634 if (first == 0) call this%output_write()
635
636 end select
637
638 call profiling_out("DISP_MEDIUM_OUTPUT_START")
639
641 end subroutine dispersive_medium_output_start
642
643 ! ---------------------------------------------------------
644 subroutine dispersive_medium_output_write(this)
645 class(dispersive_medium_t), intent(inout) :: this
646
647 real(real64) :: dmin, dtmp(3)
648 integer :: ip, pos_index, rankmin
651 call profiling_in(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
652
653 select type (algo => this%algo)
654 class is (propagator_t)
655 do ip = 1, this%n_output_points
656 pos_index = mesh_nearest_point(this%gr, this%selected_points_coordinate(ip,:), dmin, rankmin)
657 if (this%gr%mpi_grp%rank == rankmin) then
658 dtmp(:) = this%current_p(pos_index,:)
659 end if
660 if (this%gr%parallel_in_domains) then
661 call this%gr%mpi_grp%bcast(dtmp(:), 3, mpi_double_precision, rankmin)
662 end if
663 this%current_at_point(ip,:) = units_from_atomic((unit_one/units_out%time)/(units_out%length**2), dtmp(:))
664 end do
665
666 if (.not. mpi_grp_is_root(mpi_world)) then
667 call profiling_out(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
669 return ! only first node outputs
670 end if
671
672 call write_iter_start(this%write_handle)
673 do ip = 1, this%n_output_points
674 dtmp = this%current_at_point(ip,1:3)
675 call write_iter_double(this%write_handle, dtmp, 3)
676 end do
677
678 call write_iter_nl(this%write_handle)
679 call write_iter_flush(this%write_handle)
680
681 end select
682
683 call profiling_out(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
685 end subroutine dispersive_medium_output_write
686
687 ! ---------------------------------------------------------
688 subroutine dispersive_medium_output_finish(this)
689 class(dispersive_medium_t), intent(inout) :: this
690
691
693
694 call profiling_in("DISP_MEDIUM_OUTPUT_FINISH")
695
696 call write_iter_end(this%write_handle)
697
698 call profiling_out("DISP_MEDIUM_OUTPUT_FINISH")
699
702
703 ! ---------------------------------------------------------
704 subroutine dispersive_medium_get_efield(this, time, efield)
705 class(dispersive_medium_t), intent(inout) :: this
706 real(real64), intent(in) :: time
707 real(real64), contiguous, intent(inout) :: efield(:, :)
708
709 type(interaction_iterator_t) :: iter
710 real(real64), allocatable :: efield_tmp(:, :)
711
713
714 safe_allocate(efield_tmp(1:this%gr%np, 1:3))
715 efield = m_z0
716 ! interpolate efield from interaction
717 call iter%start(this%interactions)
718 do while (iter%has_next())
719 select type (interaction => iter%get_next())
720 class is (mxll_e_field_to_matter_t)
721 call interaction%interpolate(time, efield_tmp)
722 call lalg_axpy(this%gr%np, 3, m_one, efield_tmp, efield)
723 end select
724 end do
725 safe_deallocate_a(efield_tmp)
726
728 end subroutine dispersive_medium_get_efield
729
730 ! ---------------------------------------------------------
731 subroutine dispersive_medium_finalize(this)
732 type(dispersive_medium_t), intent(inout) :: this
733
735 call system_end(this)
736 safe_deallocate_a(this%current_p)
737 safe_deallocate_a(this%e_field)
738 safe_deallocate_a(this%selected_points_coordinate)
739 safe_deallocate_a(this%current_at_point)
740 call multicomm_end(this%mc)
741 call grid_end(this%gr)
743 end subroutine dispersive_medium_finalize
744
746
747!! Local Variables:
748!! mode: f90
749!! coding: utf-8
750!! 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:170
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_initial_conditions(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:189
real(real64), parameter, public m_zero
Definition: global.F90:187
real(real64), parameter, public p_ep
Definition: global.F90:227
complex(real64), parameter, public m_z0
Definition: global.F90:197
real(real64), parameter, public m_one
Definition: global.F90:188
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:313
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:354
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:1125
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
Definition: messages.F90:624
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:420
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:723
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:891
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 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:167
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:137
integer, parameter, public current
Definition: quantity.F90:146
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:514
integer, parameter, public restart_type_dump
Definition: restart.F90:225
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:967
integer, parameter, public restart_td
Definition: restart.F90:229
integer, parameter, public restart_type_load
Definition: restart.F90:225
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:1207
subroutine, public system_end(this)
Definition: system.F90:1116
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.
Abstract class for systems.
Definition: system.F90:172
int true(void)