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 :: init_parallelization => dispersive_medium_init_parallelization
107 procedure :: get_efield => dispersive_medium_get_efield
109 end type dispersive_medium_t
110
111 interface dispersive_medium_t
112 procedure dispersive_medium_constructor
113 end interface dispersive_medium_t
114
115 integer, public, parameter :: &
116 DRUDE_MEDIUM = 0
117
118contains
119
120 ! ---------------------------------------------------------
125 function dispersive_medium_constructor(namespace) result(sys)
126 class(dispersive_medium_t), pointer :: sys
127 type(namespace_t), intent(in) :: namespace
128
130
131 allocate(sys)
132
133 call dispersive_medium_init(sys, namespace)
134
137
138 ! ---------------------------------------------------------
143 ! ---------------------------------------------------------
144 subroutine dispersive_medium_init(this, namespace)
145 class(dispersive_medium_t), target, intent(inout) :: this
146 type(namespace_t), intent(in) :: namespace
147
148 integer :: nlines, ncols, idim, il
149 real(real64) :: pos(3)
150 type(block_t) :: blk
151
152 push_sub(dispersive_medium_init)
153
154 this%namespace = namespace
155
156 call profiling_in('DISP_MEDIUM_INIT')
157
158 this%space = space_t(this%namespace)
159 if (this%space%dim /= 3) then
160 call messages_not_implemented('Linear medium for dimensions other than 3', namespace=namespace)
161 end if
162 call grid_init_stage_1(this%gr, this%namespace, this%space, latt=lattice_vectors_t(namespace, this%space))
163
164 ! Parse electromagnetic properties of dispersive media...
165
166 !%Variable MediumDispersionType
167 !%Type integer
168 !%Default drude_medium
169 !%Section Maxwell::Medium
170 !%Description
171 !% Dispersion model used for the medium (only Drude model available for the moment).
172 !%Option drude_medium 0
173 !% Drude type of dispersion.
174 !%End
175 call parse_variable(namespace, 'MediumDispersionType', drude_medium, this%medium_type)
176 if (.not. varinfo_valid_option('MediumDispersionType', this%medium_type)) then
177 call messages_input_error(namespace, 'MediumDispersionType')
178 end if
180 ! Parse electromagnetic properties of Dispersive media...
181 !%Variable MediumPoleEnergy
182 !%Type float
183 !%Default 0
184 !%Section Maxwell::Medium
185 !%Description
186 !% Energy of the pole.
187 !%End
188 call parse_variable(namespace, 'MediumPoleEnergy', m_zero, this%omega_p, unit_one/units_inp%time)
190 !%Variable MediumPoleDamping
191 !%Type float
192 !%Default 0
193 !%Section Maxwell::Medium
194 !%Description
195 !% Damping factor (inverse relaxation time) of the medium.
196 !%End
197 call parse_variable(namespace, 'MediumPoleDamping', m_zero, this%gamma_p, unit_one/units_inp%time)
199 !%Variable MediumPoleStrength
200 !%Type float
201 !%Default 1.0
202 !%Section Maxwell::Medium
203 !%Description
204 !% Strength of the pole (unitless).
205 !%End
206 call parse_variable(namespace, 'MediumPoleStrength', m_one, this%strength_p, unit_one)
207
208 !%Variable MediumCurrentCoordinates
209 !%Type block
210 !%Section Maxwell::Output
211 !%Description
212 !% This allows to output phasor current vectors at particular points in space.
213 !%
214 !% <tt>%MediumCurrentCoordinates
215 !% <br>&nbsp;&nbsp; -1.0 | 2.0 | 4.0
216 !% <br>&nbsp;&nbsp; 0.0 | 1.0 | -2.0
217 !% <br>%</tt>
218 !%
219 !%End
221 if (parse_block(namespace, 'MediumCurrentCoordinates', blk) == 0) then
222 nlines = parse_block_n(blk)
223 this%n_output_points = nlines
224 safe_allocate(this%selected_points_coordinate(1:nlines,1:3))
225 safe_allocate(this%current_at_point(1:nlines,1:3))
226 do il = 1, nlines
227 ncols = parse_block_cols(blk,0)
228 do idim = 1, 3
229 call parse_block_float(blk, il-1, idim-1, pos(idim), units_inp%length)
230 end do
231 this%selected_points_coordinate(il,:) = pos(:)
232 this%current_at_point(il,:) = m_zero
233 end do
234 call parse_block_end(blk)
235 else
236 this%n_output_points = 1
237 safe_allocate(this%selected_points_coordinate(1,3))
238 safe_allocate(this%current_at_point(1,3))
239 this%selected_points_coordinate = m_zero
240 this%current_at_point = m_zero
241 end if
242
243 this%supported_interactions = [mxll_e_field_to_matter]
244 this%supported_interactions_as_partner = [current_to_mxll_field]
245
246 call this%quantities%add(quantity_t("current", updated_on_demand = .false.))
247
248 call profiling_out('DISP_MEDIUM_INIT')
249
251 end subroutine dispersive_medium_init
252
253 ! ---------------------------------------------------------
254 subroutine dispersive_medium_init_parallelization(this, grp)
255 class(dispersive_medium_t), intent(inout) :: this
256 type(mpi_grp_t), intent(in) :: grp
257
258 integer(int64) :: index_range(4)
259 integer :: ierr
260
262
263 call system_init_parallelization(this, grp)
264 ! store the ranges for these two indices (serves as initial guess
265 ! for parallelization strategy)
266 index_range(1) = this%gr%np_global ! Number of points in mesh
267 index_range(2) = 1 ! Number of states
268 index_range(3) = 1 ! Number of k-points
269 index_range(4) = 100000 ! Some large number
270
271 ! create index and domain communicators
272 call multicomm_init(this%mc, this%namespace, mpi_world, calc_mode_par, mpi_world%size, &
273 index_range, (/ 5000, 1, 1, 1 /))
274 call grid_init_stage_2(this%gr, this%namespace, this%space, this%mc)
275
276 call this%restart_dump%init(this%namespace, restart_td, restart_type_dump, &
277 this%mc, ierr, mesh=this%gr)
278 call this%restart_load%init(this%namespace, restart_td, restart_type_load, &
279 this%mc, ierr, mesh=this%gr)
280
281 safe_allocate(this%current_p(1:this%gr%np, 1:3))
282 safe_allocate(this%e_field(1:this%gr%np, 1:3))
283 this%e_field(:,:) = m_zero
284
287
288 ! ---------------------------------------------------------
289 subroutine dispersive_medium_init_interaction(this, interaction)
290 class(dispersive_medium_t), target, intent(inout) :: this
291 class(interaction_t), intent(inout) :: interaction
292
293 integer :: depth
294
296
297 select type (interaction)
299 call interaction%init(this%gr, 3)
300 interaction%type = mxll_field_total
301
302 ! set interpolation depth for interaction
303 ! interpolation depth depends on the propagator
304 select type (prop => this%algo)
305 type is (propagator_rk4_t)
306 ! TODO: should be five, two is only for backwards compatibility
307 depth = 2
308 class default
309 message(1) = "The chosen propagator does not yet support interaction interpolation"
310 call messages_fatal(1)
311 end select
312 call interaction%init_interpolation(depth, interaction%label)
313
314 class default
315 message(1) = "Trying to initialize an unsupported interaction by a Dispersive medium."
316 call messages_fatal(1)
317 end select
318
321
322 ! ---------------------------------------------------------
323 subroutine dispersive_medium_init_interaction_as_partner(partner, interaction)
324 class(dispersive_medium_t), intent(in) :: partner
325 class(interaction_surrogate_t), intent(inout) :: interaction
326
328
329 select type (interaction)
331 call interaction%init_from_partner(partner%gr, partner%space, partner%namespace)
332 class default
333 message(1) = "Trying to initialize an unsupported interaction by a linear medium."
334 call messages_fatal(1)
335 end select
336
339
340 ! ---------------------------------------------------------
341 subroutine dispersive_medium_initialize(this)
342 class(dispersive_medium_t), intent(inout) :: this
343
345
346 this%from_scratch = .true.
347 this%current_p(:,:) = m_zero
348
350 end subroutine dispersive_medium_initialize
351
352 ! ---------------------------------------------------------
353 logical function dispersive_medium_do_algorithmic_operation(this, operation, updated_quantities) result(done)
354 class(dispersive_medium_t), intent(inout) :: this
355 class(algorithmic_operation_t), intent(in) :: operation
356 character(len=:), allocatable, intent(out) :: updated_quantities(:)
357
358 integer :: ip, idim
359 real(real64) :: k1(1:3), k2(1:3), k3(1:3), k4(1:3)
360
362 call profiling_in(trim(this%namespace%get())//":"//trim(operation%id))
363
364 ! calculation of the current using ADE
365 ! \partial_t J_P(t) = - \gamma_p * J_P(t) + \epsilon_0 \omega_p^2 E(t)
366 ! (Computational Electrodynamics, Taflov and Hagness, 3rd Ed., section 9.4.3, eq. 9.56c)
367 ! Analysis of Units:
368 ! [e/time^2*a0^2] = (1/time) * (e/time*a0^2) + (e^2/hbar*c) * (1/time)^2 * Ha / (e * a0)
369 ! [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
370 ! [e/time^2*a0^2] = (e/time^2*a0^2) + (e/time^2*a0^2)
371
372 select type (algo => this%algo)
373 class is (propagator_t)
374
375 done = .true.
376 select case (operation%id)
378 ! For the moment we do nothing
379
380 case (rk4_start)
381 safe_allocate(this%e_field_dt_half(1:this%gr%np, 1:3))
382 safe_allocate(this%e_field_dt_full(1:this%gr%np, 1:3))
383
385 safe_deallocate_a(this%e_field_dt_half)
386 safe_deallocate_a(this%e_field_dt_full)
387
388 case (rk4_extrapolate)
389 call this%get_efield(this%iteration%value(), this%e_field)
390 call this%get_efield(this%iteration%value()+algo%dt/m_two, this%e_field_dt_half)
391 call this%get_efield(this%iteration%value()+algo%dt, this%e_field_dt_full)
392
393 case (rk4_propagate)
394 do idim=1, 3
395 !$omp parallel do private(k1, k2, k3, k4)
396 do ip = 1, this%gr%np
397 k1(idim) = current_derivative_dir(this%current_p(ip, idim), &
398 this%e_field(ip,idim), this%gamma_p, this%omega_p, this%strength_p)
399
400 k2(idim) = current_derivative_dir(this%current_p(ip, idim) + algo%dt * k1(idim) / m_two, &
401 this%e_field_dt_half(ip, idim), this%gamma_p, this%omega_p, this%strength_p)
402
403 k3(idim) = current_derivative_dir(this%current_p(ip, idim) + algo%dt * k2(idim) / m_two, &
404 this%e_field_dt_half(ip, idim), this%gamma_p, this%omega_p, this%strength_p)
405
406 k4(idim) = current_derivative_dir(this%current_p(ip, idim) + algo%dt * k3(idim), &
407 this%e_field_dt_full(ip, idim), this%gamma_p, this%omega_p, this%strength_p)
408
409 this%current_p(ip, idim) = this%current_p(ip, idim) + algo%dt / 6.0_real64 * &
410 (k1(idim) + m_two * (k2(idim) + k3(idim)) + k4(idim))
411 end do
412 end do
413 updated_quantities = ["current"]
414
415 case default
416 done = .false.
417 end select
418 end select
419
420 call profiling_out(trim(this%namespace%get())//":"//trim(operation%id))
422 contains
423
424 function current_derivative_dir(current_p, e_field, gamma_p, omega_p, strength_p) result(current_dot)
425 real(real64), intent(in) :: current_p
426 real(real64), intent(in) :: e_field
427 real(real64), intent(in) :: gamma_p
428 real(real64), intent(in) :: omega_p
429 real(real64), intent(in) :: strength_p
430 real(real64) :: current_dot
431
432 current_dot = - gamma_p * current_p + strength_p * p_ep * omega_p**2 * e_field
433 end function current_derivative_dir
434
437 ! ---------------------------------------------------------
438 logical function dispersive_medium_is_tolerance_reached(this, tol) result(converged)
439 class(dispersive_medium_t), intent(in) :: this
440 real(real64), intent(in) :: tol
441
443
444 ! this routine is never called at present, no reason to be here
445 assert(.false.)
446 converged = .false.
447
450
451 ! ---------------------------------------------------------
452 subroutine dispersive_medium_copy_quantities_to_interaction(partner, interaction)
453 class(dispersive_medium_t), intent(inout) :: partner
454 class(interaction_surrogate_t), intent(inout) :: interaction
455
457 call profiling_in(trim(partner%namespace%get())//":"//"COPY_QUANTITY_INTER")
458
459 select type (interaction)
461 interaction%partner_field(:,:) = partner%current_p
462 call interaction%do_mapping()
463 class default
464 message(1) = "Unsupported interaction."
465 call messages_fatal(1)
466 end select
467
468 call profiling_out(trim(partner%namespace%get())//":"//"COPY_QUANTITY_INTER")
471
472 ! ---------------------------------------------------------
474 class(dispersive_medium_t), intent(inout) :: this
475
476 character(len=256) :: filename
477 integer :: idir, err
478 type(interaction_iterator_t) :: iter
479 class(interaction_t), pointer :: interaction
480
482 call profiling_in(trim(this%namespace%get())//":"//"RESTART_WRITE")
483
484 if (.not. this%restart_dump%skip()) then
485 do idir = 1, this%space%dim
486 write(filename, "(A,A)") "current_p-", index2axis(idir)
487 call this%restart_dump%write_mesh_function(this%space, trim(filename), this%gr, &
488 this%current_p(:, idir), err)
489 end do
490
491 call iter%start(this%interactions)
492 do while (iter%has_next())
493 interaction => iter%get_next()
494 select type (interaction)
495 class is (mxll_e_field_to_matter_t)
496 call interaction%write_restart(this%gr, this%space, this%restart_dump, err)
497 end select
498 end do
499
500 if (err == 0) then
501 message(1) = "Successfully wrote restart data for system "//trim(this%namespace%get())
502 call messages_info(1, namespace=this%namespace)
503 end if
504
505 end if
506
507 call profiling_out(trim(this%namespace%get())//":"//"RESTART_WRITE")
510
511 ! ---------------------------------------------------------
512 ! this function returns true if restart data could be read
513 logical function dispersive_medium_restart_read_data(this)
514 class(dispersive_medium_t), intent(inout) :: this
515
516 character(len=256) :: filename
517 integer :: idir, err
518 type(interaction_iterator_t) :: iter
519 class(interaction_t), pointer :: interaction
520
522 call profiling_in(trim(this%namespace%get())//":"//"RESTART_READ")
523
525 if (.not. this%restart_load%skip()) then
526 do idir = 1, 3
527 write(filename, "(A,A)") "current_p-", index2axis(idir)
528 call this%restart_load%read_mesh_function(this%space, trim(filename), this%gr, &
529 this%current_p(:, idir), err)
530 end do
531
532 call iter%start(this%interactions)
533 do while (iter%has_next())
534 interaction => iter%get_next()
535 select type (interaction)
536 class is (mxll_e_field_to_matter_t)
537 call interaction%read_restart(this%gr, this%space, this%restart_load, err)
538 end select
539 end do
540
541 if (err == 0) then
543 this%from_scratch = .false.
544 else
545 ! set to 0 again in case this was read incompletely
546 this%current_p(:, :) = m_zero
547 end if
548 end if
549
550 call profiling_out(trim(this%namespace%get())//":"//"RESTART_READ")
553
554 ! ---------------------------------------------------------
556 class(dispersive_medium_t), intent(inout) :: this
557
559
560 ! TODO: evaluate proper energy associated with the current distribution
561 ! For Drude model: check Giuliani/Vignale book, section 4.6.1
562 this%kinetic_energy = m_zero
563
565
567
568 ! ---------------------------------------------------------
569 subroutine dispersive_medium_output_start(this)
570 class(dispersive_medium_t), intent(inout) :: this
571
572 integer :: first, id, idir
573 character(len=130) :: aux
574
576
577 call profiling_in("DISP_MEDIUM_OUTPUT_START")
578
579 select type (algo => this%algo)
580 class is (propagator_t)
581
582 if (this%iteration%counter() == 0) then
583 first = 0
584 else
585 first = this%iteration%counter() + 1
586 end if
587
588 call io_mkdir('td.general', this%namespace)
589 call write_iter_init(this%write_handle, first, units_from_atomic(units_out%time, algo%dt), &
590 trim(io_workpath("td.general/current_at_points", this%namespace)))
591
592 if (mpi_world%is_root()) then
593 if (this%iteration%counter() == 0) then
594 call write_iter_clear(this%write_handle)
595 call write_iter_string(this%write_handle,&
596 '################################################################################')
597 call write_iter_nl(this%write_handle)
598 call write_iter_string(this%write_handle,'# HEADER')
599 call write_iter_nl(this%write_handle)
600
601 ! first line
602 write(aux, '(a7,e20.12,3a)') '# dt = ', units_from_atomic(units_out%time, algo%dt), &
603 " [", trim(units_abbrev(units_out%time)), "]"
604 call write_iter_string(this%write_handle, aux)
605 call write_iter_nl(this%write_handle)
606
607 call write_iter_header_start(this%write_handle)
609 do id = 1, this%n_output_points
610 do idir = 1, 3
611 write(aux, '(a,i1,a,i1,a)') 'j(', id, ',', idir, ')'
612 call write_iter_header(this%write_handle, aux)
613 end do
614 end do
615
616 call write_iter_nl(this%write_handle)
617 call write_iter_header(this%write_handle, '# [' // trim(units_abbrev(units_out%time)) // ']')
618
619 !FIXME: this is not printing the proper unit to output yet, for some reason
620 aux = ' [' // trim(units_abbrev(unit_one/(units_out%time*units_out%length**2))) // ']'
621 do id = 1, this%n_output_points
622 do idir = 1, 3
623 call write_iter_header(this%write_handle, aux)
624 end do
625 end do
626 call write_iter_nl(this%write_handle)
627 call write_iter_string(this%write_handle,&
628 '################################################################################')
629 call write_iter_nl(this%write_handle)
630 end if
631 end if
632
633 if (first == 0) call this%output_write()
634
635 end select
636
637 call profiling_out("DISP_MEDIUM_OUTPUT_START")
638
640 end subroutine dispersive_medium_output_start
641
642 ! ---------------------------------------------------------
643 subroutine dispersive_medium_output_write(this)
644 class(dispersive_medium_t), intent(inout) :: this
645
646 real(real64) :: dmin, dtmp(3)
647 integer :: ip, pos_index, rankmin
648
650 call profiling_in(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
651
652 select type (algo => this%algo)
653 class is (propagator_t)
654 do ip = 1, this%n_output_points
655 pos_index = mesh_nearest_point(this%gr, this%selected_points_coordinate(ip,:), dmin, rankmin)
656 if (this%gr%mpi_grp%rank == rankmin) then
657 dtmp(:) = this%current_p(pos_index,:)
658 end if
659 if (this%gr%parallel_in_domains) then
660 call this%gr%mpi_grp%bcast(dtmp(:), 3, mpi_double_precision, rankmin)
661 end if
662 this%current_at_point(ip,:) = units_from_atomic((unit_one/units_out%time)/(units_out%length**2), dtmp(:))
663 end do
665 if (.not. mpi_world%is_root()) then
666 call profiling_out(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
668 return ! only first node outputs
669 end if
670
671 call write_iter_start(this%write_handle)
672 do ip = 1, this%n_output_points
673 dtmp = this%current_at_point(ip,1:3)
674 call write_iter_double(this%write_handle, dtmp, 3)
675 end do
676
677 call write_iter_nl(this%write_handle)
678 call write_iter_flush(this%write_handle)
679
680 end select
681
682 call profiling_out(trim(this%namespace%get())//":"//"OUTPUT_WRITE")
684 end subroutine dispersive_medium_output_write
685
686 ! ---------------------------------------------------------
687 subroutine dispersive_medium_output_finish(this)
688 class(dispersive_medium_t), intent(inout) :: this
689
690
692
693 call profiling_in("DISP_MEDIUM_OUTPUT_FINISH")
694
695 call write_iter_end(this%write_handle)
696
697 call profiling_out("DISP_MEDIUM_OUTPUT_FINISH")
698
701
702 ! ---------------------------------------------------------
703 subroutine dispersive_medium_get_efield(this, time, efield)
704 class(dispersive_medium_t), intent(inout) :: this
705 real(real64), intent(in) :: time
706 real(real64), contiguous, intent(inout) :: efield(:, :)
707
708 type(interaction_iterator_t) :: iter
709 real(real64), allocatable :: efield_tmp(:, :)
710
712
713 safe_allocate(efield_tmp(1:this%gr%np, 1:3))
714 efield = m_z0
715 ! interpolate efield from interaction
716 call iter%start(this%interactions)
717 do while (iter%has_next())
718 select type (interaction => iter%get_next())
719 class is (mxll_e_field_to_matter_t)
720 call interaction%interpolate(time, efield_tmp)
721 call lalg_axpy(this%gr%np, 3, m_one, efield_tmp, efield)
722 end select
723 end do
724 safe_deallocate_a(efield_tmp)
725
727 end subroutine dispersive_medium_get_efield
728
729 ! ---------------------------------------------------------
730 subroutine dispersive_medium_finalize(this)
731 type(dispersive_medium_t), intent(inout) :: this
732
734 call system_end(this)
735 safe_deallocate_a(this%current_p)
736 safe_deallocate_a(this%e_field)
737 safe_deallocate_a(this%selected_points_coordinate)
738 safe_deallocate_a(this%current_at_point)
739 call multicomm_end(this%mc)
740 call grid_end(this%gr)
742 end subroutine dispersive_medium_finalize
743
745
746!! Local Variables:
747!! mode: f90
748!! coding: utf-8
749!! 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:169
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)
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:192
real(real64), parameter, public m_zero
Definition: global.F90:190
real(real64), parameter, public p_ep
Definition: global.F90:232
complex(real64), parameter, public m_z0
Definition: global.F90:200
real(real64), parameter, public m_one
Definition: global.F90:191
This module implements the underlying real-space grid.
Definition: grid.F90:119
subroutine, public grid_init_stage_1(gr, namespace, space, 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:473
subroutine, public grid_end(gr)
finalize a grid object
Definition: grid.F90:501
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:317
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:360
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:384
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1097
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:416
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:697
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:600
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:697
subroutine, public multicomm_init(mc, namespace, base_grp, mode_para, n_node, index_range, min_range)
create index and domain communicators
Definition: multicomm.F90:266
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:621
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
Definition: profiling.F90:625
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:171
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:183
integer, parameter, public restart_td
Definition: restart.F90:156
integer, parameter, public restart_type_load
Definition: restart.F90:183
This module implements the abstract system type.
Definition: system.F90:120
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:1240
subroutine, public system_end(this)
Definition: system.F90:1149
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
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 field to a medium
Abstract class implementing propagators.
Definition: propagator.F90:140
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:173
Abstract class for systems.
Definition: system.F90:174
int true(void)