Octopus
output_mxll.F90
Go to the documentation of this file.
1!! Copyright (C) 2019 F. Bonafe, R. Jestaedt, H. Appel
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
20#include "global.h"
21
23 use debug_oct_m
28 use global_oct_m
29 use grid_oct_m
31 use io_oct_m
33 use mesh_oct_m
36 use output_oct_m
38 use parser_oct_m
40 use space_oct_m
43 use string_oct_m
44 use unit_oct_m
46
47
48 implicit none
49
50 private
51 public :: &
54
55contains
56
57 ! ---------------------------------------------------------
58 subroutine output_mxll_init(outp, namespace, space)
59 type(output_t), intent(out) :: outp
60 type(namespace_t), intent(in) :: namespace
61 class(space_t), intent(in) :: space
62 integer :: what_i
63 push_sub(output_mxll_init)
64
65 !%Variable MaxwellOutput
66 !%Type block
67 !%Default none
68 !%Section Output
69 !%Description
70 !% Specifies what to print. The output files are written at the end of the run into the output directory for the
71 !% Maxwell run.
72 !% Time-dependent simulations print only per iteration, including always the last. The frequency of output per iteration
73 !% is set by <tt>OutputInterval</tt> and the directory is set by <tt>OutputIterDir</tt>.
74 !% Each option must be in a separate row. Optionally individual output formats and output intervals can be defined
75 !% for each row or they can be read separately from <tt>OutputFormat</tt> and <tt>MaxwellOutputInterval</tt> variables
76 !% in the input file.
77 !%
78 !% Example:
79 !% <br><br><tt>%MaxwellOutput
80 !% <br>&nbsp;&nbsp;electric_field
81 !% <br>&nbsp;&nbsp;magnetic_field
82 !% <br>%<br></tt>
83 !% This block supports all the formats of the <tt>Output</tt> block.
84 !% See <tt>Output</tt>.
85 !%Option electric_field 1
86 !% Output of the electric field
87 !%Option magnetic_field 2
88 !% Output of the magnetic field
89 !%Option trans_electric_field 3
90 !% Output of the transversal electric field
91 !%Option trans_magnetic_field 4
92 !% Output of the transversal magnetic field
93 !%Option long_electric_field 5
94 !% Output of the longitudinal electric field
95 !%Option long_magnetic_field 6
96 !% Output of the longitudinal magnetic field
97 !%Option div_electric_field 7
98 !% Output of the divergence of the electric field
99 !%Option div_magnetic_field 8
100 !% Output of the divergence of the magnetic field
101 !%Option poynting_vector 9
102 !% Output of the Maxwell Poynting vector
103 !%Option maxwell_energy_density 10
104 !% Output of the electromagnetic density
105 !%Option external_current 11
106 !% Output of the external Maxwell current
107 !%Option charge_density 12
108 !% Output of the charge density calculated by the divergence of the electric field.
109 !%Option orbital_angular_momentum 13
110 !% Output of the orbital angular momentum
111 !%Option vector_potential_mag 14
112 !% Output of the vector potential from magnetic field
113 !%Option magnetic_field_diff 15
114 !% Output of the magnetic field difference
115 !%Option total_current_mxll 16
116 !% Output of the total current density
117 !%End
118
119 !%Variable MaxwellOutputInterval
120 !%Type integer
121 !%Default 50
122 !%Section Output
123 !%Description
124 !% The output requested by variable <tt>MaxwellOutput</tt> is written
125 !% to the directory <tt>MaxwellOutputIterDir</tt>
126 !% when the iteration number is a multiple of the <tt>MaxwellOutputInterval</tt> variable.
127 !% Subdirectories are named Y.X, where Y is <tt>td</tt>, <tt>scf</tt>, or <tt>unocc</tt>, and
128 !% X is the iteration number. To use the working directory, specify <tt>"."</tt>
129 !% Must be >= 0. If it is 0, then no output is written.
130 !% This variable can also be defined inside the <tt>MaxwellOutput</tt> block.
131 !% See <tt>MaxwellOutput</tt>.
132 !%End
133
134 outp%what = .false.
135 call io_function_read_what_how_when(namespace, space, outp%what, outp%how, outp%output_interval, &
136 'MaxwellOutput', 'OutputFormat', 'MaxwellOutputInterval')
137
138 do what_i = lbound(outp%what, 1), ubound(outp%what, 1)
139 ! xyz format is not available for Maxwell
140 if (bitand(outp%how(what_i), option__outputformat__xyz) /= 0) then
141 message(1) = "OutputFormat = xyz is not compatible with Maxwell systems"
142 call messages_warning(1)
143 end if
144 end do
145
146
147
148 !%Variable MaxwellOutputIterDir
149 !%Default "output_iter"
150 !%Type string
151 !%Section Output
152 !%Description
153 !% The name of the directory where <tt>Octopus</tt> stores information
154 !% such as the density, forces, etc. requested by variable <tt>MaxwellOutput</tt>
155 !% in the format specified by <tt>OutputHow</tt>.
156 !% This information is written while iterating <tt>CalculationMode = maxwell</tt>
157 !% according to <tt>OutputInterval</tt>, and has nothing to do with the restart information.
158 !%End
159 call parse_variable(namespace, 'MaxwellOutputIterDir', "output_iter", outp%iter_dir)
160 if (any(outp%what) .and. maxval(outp%output_interval) > 0) then
161 call io_mkdir(outp%iter_dir, namespace)
162 end if
163 call add_last_slash(outp%iter_dir)
164
165 if (parse_is_defined(namespace, 'MaxwellRestartWriteInterval')) then
166 write(message(1), '(a)') 'Input variable MaxwellRestartWriteInterval is obsolete.'
167 write(message(2), '(a)') 'Restart files are now written in periods of the wallclock time'
168 write(message(3), '(a)') 'given by RestartWallTimePeriod, so you can simply delete this variable.'
169 call messages_fatal(3, only_root_writes=.true., namespace=namespace)
170 end if
171
172 if (outp%what(option__maxwelloutput__electric_field)) then
173 outp%wfs_list = trim("1-3")
174 end if
175
176 if (outp%what(option__maxwelloutput__magnetic_field)) then
177 outp%wfs_list = trim("1-3")
178 end if
179
180 if (outp%what(option__maxwelloutput__trans_electric_field)) then
181 outp%wfs_list = trim("1-3")
182 end if
183
184 if (outp%what(option__maxwelloutput__trans_magnetic_field)) then
185 outp%wfs_list = trim("1-3")
186 end if
187
188
189 pop_sub(output_mxll_init)
190 end subroutine output_mxll_init
191
192
193 ! ---------------------------------------------------------
194 subroutine output_mxll(outp, namespace, space, gr_mxll, st_mxll, hm_mxll, helmholtz, time, dir, gr_elec, st_elec, hm_elec)
195 type(output_t), intent(in) :: outp
196 type(namespace_t), intent(in) :: namespace
197 class(space_t), intent(in) :: space
198 type(states_mxll_t), intent(inout) :: st_mxll
199 type(hamiltonian_mxll_t), intent(in) :: hm_mxll
200 type(grid_t), intent(in) :: gr_mxll
201 type(helmholtz_decomposition_t), intent(inout) :: helmholtz
202 real(real64), intent(in) :: time
203 character(len=*), intent(in) :: dir
204 type(grid_t), optional, intent(inout) :: gr_elec
205 type(states_elec_t), optional, intent(inout) :: st_elec
206 type(hamiltonian_elec_t), optional, intent(in) :: hm_elec
207
208 push_sub(output_mxll)
209
210 if (any(outp%what)) then
211 message(1) = "Info: Writing output to " // trim(dir)
212 call messages_info(1, namespace=namespace)
213 call io_mkdir(dir, namespace)
214 end if
215
216 call output_states_mxll(outp, namespace, space, dir, st_mxll, gr_mxll)
217 call output_energy_density_mxll(outp, namespace, space, dir, st_mxll, gr_mxll)
218 call output_poynting_vector_orbital_angular_momentum(outp, namespace, space, dir, st_mxll, gr_mxll)
219 call output_transverse_rs_state(helmholtz, outp, namespace, space, dir, st_mxll, gr_mxll)
220 call output_longitudinal_rs_state(helmholtz, outp, namespace, space, dir, st_mxll, gr_mxll)
221 call output_vector_potential_mag(outp, helmholtz, namespace, gr_mxll, space, dir, st_mxll)
222 call output_divergence_rs_state(outp, namespace, space, dir, st_mxll, gr_mxll)
223 call output_external_current_density(outp, namespace, space, dir, st_mxll, gr_mxll, hm_mxll, time)
224 call output_total_current_mxll(outp, namespace, space, dir, st_mxll, gr_mxll, hm_mxll, time, st_mxll%ep, gr_mxll%np)
225 call output_charge_density_mxll(outp, namespace, space, dir, st_mxll, gr_mxll, hm_mxll)
226
227 if (present(hm_elec) .and. present(gr_elec) .and. present(st_elec)) then
228 call output_coupling_potentials(outp, namespace, dir, hm_elec, gr_elec)
229 call output_current_density(outp, namespace, dir, st_mxll, gr_mxll, hm_mxll, st_elec, gr_elec, hm_elec, time)
230 end if
231
232 pop_sub(output_mxll)
233 end subroutine output_mxll
234
235
236 ! ---------------------------------------------------------
237 subroutine output_states_mxll(outp, namespace, space, dir, st, mesh)
238 type(output_t), intent(in) :: outp
239 type(namespace_t), intent(in) :: namespace
240 class(space_t), intent(in) :: space
241 character(len=*), intent(in) :: dir
242 type(states_mxll_t), intent(in) :: st
243 class(mesh_t), intent(in) :: mesh
244
245 integer :: ierr
246 character(len=MAX_PATH_LEN) :: fname
247 type(unit_t) :: fn_unit
248 real(real64), allocatable :: dtmp(:,:)
249
250 push_sub(output_states_mxll)
251
252 ! Electric field
253 if (outp%what(option__maxwelloutput__electric_field)) then
254 fn_unit = units_out%energy/units_out%length
255 safe_allocate(dtmp(1:mesh%np, 1:space%dim))
256 call get_electric_field_state(st%rs_state, mesh, dtmp, st%ep, mesh%np)
257 fname = 'e_field'
258 call io_function_output_vector(outp%how(option__maxwelloutput__electric_field), dir, fname, namespace, space, &
259 mesh, dtmp, fn_unit, ierr)
260 safe_deallocate_a(dtmp)
261 end if
262
263 ! Magnetic field
264 if (outp%what(option__maxwelloutput__magnetic_field)) then
265 fn_unit = unit_one/units_out%length**2
266 safe_allocate(dtmp(1:mesh%np, 1:space%dim))
267 call get_magnetic_field_state(st%rs_state, mesh, st%rs_sign, dtmp, st%mu(1:mesh%np), mesh%np)
268 fname = 'b_field'
269 call io_function_output_vector(outp%how(option__maxwelloutput__magnetic_field), dir, fname, namespace, space, &
270 mesh, dtmp, fn_unit, ierr)
271 safe_deallocate_a(dtmp)
272 end if
273
274 pop_sub(output_states_mxll)
275 end subroutine output_states_mxll
276
277
278 !----------------------------------------------------------
279 subroutine output_energy_density_mxll(outp, namespace, space, dir, st, mesh) !< have to set unit output correctly
280 type(output_t), intent(in) :: outp
281 type(namespace_t), intent(in) :: namespace
282 class(space_t), intent(in) :: space
283 character(len=*), intent(in) :: dir
284 type(states_mxll_t), intent(in) :: st
285 class(mesh_t), intent(in) :: mesh
286
287 integer :: ierr
288 real(real64), allocatable :: energy_density(:), e_energy_density(:), b_energy_density(:)
291
292 ! Maxwell energy density
293 if (outp%what(option__maxwelloutput__maxwell_energy_density)) then
294 safe_allocate(energy_density(1:mesh%np))
295 safe_allocate(e_energy_density(1:mesh%np))
296 safe_allocate(b_energy_density(1:mesh%np))
297 ! calculate the energy density
298 call energy_density_calc(mesh, st, st%rs_state, energy_density, e_energy_density, b_energy_density)
299
300 call dio_function_output(outp%how(option__maxwelloutput__maxwell_energy_density), dir, "maxwell_energy_density", &
301 namespace, space, mesh, energy_density, units_out%energy/units_out%length**3, ierr)
302
303 safe_deallocate_a(energy_density)
304 safe_deallocate_a(e_energy_density)
305 safe_deallocate_a(b_energy_density)
306 end if
307
309 end subroutine output_energy_density_mxll
310
311
312 !----------------------------------------------------------
313 subroutine output_poynting_vector_orbital_angular_momentum(outp, namespace, space, dir, st, mesh)
314 type(output_t), intent(in) :: outp
315 type(namespace_t), intent(in) :: namespace
316 class(space_t), intent(in) :: space
317 character(len=*), intent(in) :: dir
318 type(states_mxll_t), intent(in) :: st
319 class(mesh_t), intent(in) :: mesh
320
321 integer :: ierr
322 character(len=MAX_PATH_LEN) :: fname
323 type(unit_t) :: fn_unit
324 real(real64), allocatable :: poynting_vector(:,:), oam(:,:)
325
327
328 if (outp%what(option__maxwelloutput__poynting_vector).or.outp%what(option__maxwelloutput__orbital_angular_momentum)) then
329
330 ! the Poynting vector is needed in both cases, so we compute it here first
331 fn_unit = units_out%energy/(units_out%time*units_out%length**2)
332 safe_allocate(poynting_vector(1:mesh%np, 1:space%dim))
333 call get_poynting_vector(mesh, st, st%rs_state, st%rs_sign, poynting_vector, st%ep, st%mu)
334
335 if(outp%what(option__maxwelloutput__poynting_vector)) then
336 fname = 'poynting_vector'
337 call io_function_output_vector(outp%how(option__maxwelloutput__poynting_vector), dir, fname, namespace, space, &
338 mesh, poynting_vector, fn_unit, ierr)
339 end if
340
341 if(outp%what(option__maxwelloutput__orbital_angular_momentum)) then
342 safe_allocate(oam(1:mesh%np, 1:space%dim))
343 call get_orbital_angular_momentum(mesh, poynting_vector, oam)
344 fname = 'orbital_angular_momentum'
345 call io_function_output_vector(outp%how(option__maxwelloutput__orbital_angular_momentum), dir, fname, namespace, space, &
346 mesh, oam, fn_unit, ierr)
347 safe_deallocate_a(oam)
348 end if
349
350 safe_deallocate_a(poynting_vector)
351 end if
352
355
356
357 ! add documentation to magnetic field subtraction order
358 subroutine output_vector_potential_mag(outp, helmholtz, namespace, gr, space, dir, st) !< have to set unit output correctly
359 type(output_t), intent(in) :: outp
360 type(helmholtz_decomposition_t), intent(inout) :: helmholtz
361 type(namespace_t), intent(in) :: namespace
362 type(grid_t), intent(in) :: gr
363 class(space_t), intent(in) :: space
364 character(len=*), intent(in) :: dir
365 type(states_mxll_t), intent(in) :: st
366
367 character(len=MAX_PATH_LEN) :: fname
368 integer :: ierr
369 type(unit_t) :: fn_unit
370 real(real64), allocatable :: dtmp(:,:),vtmp(:,:), mag_fromvec(:,:) , delta(:,:)
371
373
374 ! vector potential from magnetic field
375 if (outp%what(option__maxwelloutput__vector_potential_mag) .or. &
376 outp%what(option__maxwelloutput__magnetic_field_diff)) then
377
378 fn_unit = unit_one/units_out%length
379 safe_allocate(dtmp(1:gr%np_part, 1:space%dim))
380 safe_allocate(vtmp(1:gr%np_part, 1:space%dim))
381 call get_magnetic_field_state(st%rs_state, gr, st%rs_sign, dtmp, st%mu(1:gr%np), gr%np)
382 ! Get vector potential for magnetic field
383 call helmholtz%get_vector_potential(namespace, vtmp, trans_field=dtmp)
384
385 if (outp%what(option__maxwelloutput__vector_potential_mag)) then
386 message(1) = 'Vector potential is currently missing surface contributions'
387 message(2) = 'If in doubt, use magnetic_field_diff output which shows deviation of B field'
388 message(3) = 'Large B field deviations mean the calculated vector potential is unreliable'
389 call messages_warning(3)
390
391 fname = 'vector_potential_mag'
392 call io_function_output_vector(outp%how(option__maxwelloutput__vector_potential_mag), dir, fname, namespace, &
393 space, gr, vtmp, fn_unit, ierr)
394 end if
395
396 if (outp%what(option__maxwelloutput__magnetic_field_diff)) then
397 fn_unit = unit_one/units_out%length**2
398 safe_allocate(mag_fromvec(1:gr%np_part, 1:space%dim))
399 safe_allocate(delta(1:gr%np, 1:space%dim))
400 ! Get transverse field from vector potential
401 call helmholtz%get_trans_field(namespace, mag_fromvec, vector_potential=vtmp)
402 ! mag_fromvec is of size np_part, but should be used up to np
403 ! Due to how the Helmholtz decomposition works (see its documentation), we have to remove a stencil from dtmp
404 call helmholtz%apply_inner_stencil_mask(dtmp)
405 delta = dtmp(1:gr%np, 1:space%dim) - mag_fromvec(1:gr%np, 1:space%dim)
406 fname = 'magnetic_field_diff'
407 call io_function_output_vector(outp%how(option__maxwelloutput__magnetic_field_diff), dir, fname, namespace, &
408 space, gr, delta, fn_unit, ierr)
409 safe_deallocate_a(mag_fromvec)
410 safe_deallocate_a(delta)
411 end if
412
413 safe_deallocate_a(dtmp)
414 safe_deallocate_a(vtmp)
415 end if
416
418 end subroutine output_vector_potential_mag
419
420
421 !----------------------------------------------------------
422 subroutine output_transverse_rs_state(helmholtz, outp, namespace, space, dir, st, gr) !< have to set unit output correctly
423 type(helmholtz_decomposition_t), intent(inout) :: helmholtz
424 type(output_t), intent(in) :: outp
425 type(namespace_t), intent(in) :: namespace
426 class(space_t), intent(in) :: space
427 character(len=*), intent(in) :: dir
428 type(states_mxll_t), intent(inout) :: st ! needs to be inout as st%rs_state is passed to get_trans_field
429 type(grid_t), intent(in) :: gr
430
431 character(len=MAX_PATH_LEN) :: fname
432 integer :: ierr
433 type(unit_t) :: fn_unit
434 real(real64), allocatable :: dtmp(:,:)
435
437
438 if (outp%what(option__maxwelloutput__trans_electric_field) .or. outp%what(option__maxwelloutput__trans_magnetic_field)) then
439 call helmholtz%get_trans_field(namespace, st%rs_state_trans, total_field=st%rs_state)
440 end if
441
442 ! transverse component of the electric field
443 if (outp%what(option__maxwelloutput__trans_electric_field)) then
444 fn_unit = units_out%energy/units_out%length
445 safe_allocate(dtmp(1:gr%np, 1:space%dim))
446 call get_electric_field_state(st%rs_state_trans, gr, dtmp, st%ep(1:gr%np), gr%np)
447 fname = 'e_field_trans'
448 call io_function_output_vector(outp%how(option__maxwelloutput__trans_electric_field), dir, fname, namespace, space, &
449 gr, dtmp, fn_unit, ierr)
450 safe_deallocate_a(dtmp)
451 end if
452
453 ! transverse component of the magnetic field
454 if (outp%what(option__maxwelloutput__trans_magnetic_field)) then
455 fn_unit = unit_one/units_out%length**2
456 safe_allocate(dtmp(1:gr%np, 1:space%dim))
457 call get_magnetic_field_state(st%rs_state_trans, gr, st%rs_sign, dtmp, st%mu(1:gr%np), gr%np)
458 fname = 'b_field_trans'
459 call io_function_output_vector(outp%how(option__maxwelloutput__trans_magnetic_field), dir, fname, namespace, space, &
460 gr, dtmp, fn_unit, ierr)
461 safe_deallocate_a(dtmp)
462 end if
463
465 end subroutine output_transverse_rs_state
466
467
468 !----------------------------------------------------------
469 !This subroutine is left here, will be corrected and called in near future
470 subroutine output_longitudinal_rs_state(helmholtz, outp, namespace, space, dir, st, gr) !< have to set unit output correctly
471 type(helmholtz_decomposition_t), intent(inout) :: helmholtz
472 type(output_t), intent(in) :: outp
473 type(namespace_t), intent(in) :: namespace
474 class(space_t), intent(in) :: space
475 character(len=*), intent(in) :: dir
476 type(states_mxll_t), intent(inout) :: st ! needs to be inout as st%rs_state is passed to get_long_field
477 type(grid_t), intent(in) :: gr
478
479 character(len=MAX_PATH_LEN) :: fname
480 integer :: ierr
481 type(unit_t) :: fn_unit
482 real(real64), allocatable :: dtmp(:,:)
483
485
486 if (outp%what(option__maxwelloutput__long_electric_field) .or. outp%what(option__maxwelloutput__long_magnetic_field)) then
487 call helmholtz%get_long_field(namespace, st%rs_state_long, total_field=st%rs_state)
488 end if
489
490 ! longitudinal component of the electric field
491 if (outp%what(option__maxwelloutput__long_electric_field)) then
492 fn_unit = units_out%energy/units_out%length
493 safe_allocate(dtmp(1:gr%np, 1:space%dim))
494 call get_electric_field_state(st%rs_state_long, gr, dtmp, st%ep(1:gr%np), gr%np)
495 fname = 'e_field_long'
496 call io_function_output_vector(outp%how(option__maxwelloutput__long_electric_field), dir, fname, namespace, space, &
497 gr, dtmp, fn_unit, ierr)
498 safe_deallocate_a(dtmp)
499 end if
500
501 ! longitudinal component of the magnetic field
502 if (outp%what(option__maxwelloutput__long_magnetic_field)) then
503 fn_unit = unit_one/units_out%length**2
504 safe_allocate(dtmp(1:gr%np, 1:space%dim))
505 call get_magnetic_field_state(st%rs_state_long, gr, st%rs_sign, dtmp, st%mu(1:gr%np), gr%np)
506 fname = 'b_field_long'
507 call io_function_output_vector(outp%how(option__maxwelloutput__long_magnetic_field), dir, fname, namespace, space, &
508 gr, dtmp, fn_unit, ierr)
509 safe_deallocate_a(dtmp)
510 end if
511
513 end subroutine output_longitudinal_rs_state
514
515
516 !----------------------------------------------------------
517 subroutine output_divergence_rs_state(outp, namespace, space, dir, st, gr) !< have to set unit output correctly
518 type(output_t), intent(in) :: outp
519 type(namespace_t), intent(in) :: namespace
520 class(space_t), intent(in) :: space
521 character(len=*), intent(in) :: dir
522 type(states_mxll_t), intent(in) :: st
523 type(grid_t), intent(in) :: gr
524
525 integer :: ierr
526 type(unit_t) :: fn_unit
527 real(real64), allocatable :: dtmp_1(:,:), dtmp_2(:)
528
530
531 ! divergence of the electric field
532 if (outp%what(option__maxwelloutput__div_electric_field)) then
533 fn_unit = units_out%length**(-space%dim)
534 safe_allocate(dtmp_1(1:gr%np_part, 1:space%dim))
535 safe_allocate(dtmp_2(1:gr%np))
536 dtmp_1 = m_zero
537 call get_electric_field_state(st%rs_state, gr, dtmp_1(1:gr%np,:), st%ep(1:gr%np), gr%np)
538 call get_divergence_field(gr, dtmp_1, dtmp_2, .false.)
539 call dio_function_output(outp%how(option__maxwelloutput__div_electric_field), dir, "e_field_div", namespace, space, &
540 gr, dtmp_2, fn_unit, ierr)
541 safe_deallocate_a(dtmp_1)
542 safe_deallocate_a(dtmp_2)
543 end if
544
545 ! divergence of the magnetic field
546 if (outp%what(option__maxwelloutput__div_magnetic_field)) then
547 ! unit does not matter, should be zero
548 fn_unit = unit_one
549 safe_allocate(dtmp_1(1:gr%np_part, 1:space%dim))
550 safe_allocate(dtmp_2(1:gr%np))
551 dtmp_1 = m_zero
552 call get_magnetic_field_state(st%rs_state, gr, st%rs_sign, dtmp_1(1:gr%np,:), st%mu(1:gr%np), gr%np)
553 call get_divergence_field(gr, dtmp_1, dtmp_2, .false.)
554 call dio_function_output(outp%how(option__maxwelloutput__div_magnetic_field), dir, "b_field_div", namespace, space, &
555 gr, dtmp_2, fn_unit, ierr)
556 safe_deallocate_a(dtmp_1)
557 safe_deallocate_a(dtmp_2)
558 end if
559
561 end subroutine output_divergence_rs_state
562
563
564 !------------------------------------------------------------
565 subroutine output_coupling_potentials(outp, namespace, dir, hm, gr) !< have to set unit output correctly
566 type(output_t), intent(in) :: outp
567 type(namespace_t), intent(in) :: namespace
568 character(len=*), intent(in) :: dir
569 type(hamiltonian_elec_t), intent(in) :: hm
570 type(grid_t), intent(in) :: gr
571
572 message(1) = "Maxwell-matter coupling potentials not implemented yet."
573 call messages_fatal(1, namespace=namespace)
574
575 end subroutine output_coupling_potentials
576
577
578 !----------------------------------------------------------
579 subroutine output_current_density(outp, namespace, dir, st_mxll, gr_mxll, hm_mxll, st_elec, gr_elec, hm_elec, time)
580 type(output_t), intent(in) :: outp
581 type(namespace_t), intent(in) :: namespace
582 character(len=*), intent(in) :: dir
583 type(states_mxll_t), intent(in) :: st_mxll
584 type(grid_t), intent(in) :: gr_mxll
585 type(hamiltonian_mxll_t), intent(in) :: hm_mxll
586 type(states_elec_t), intent(in) :: st_elec
587 type(grid_t), intent(in) :: gr_elec
588 type(hamiltonian_elec_t), intent(in) :: hm_elec
589 real(real64), intent(in) :: time
590
591 message(1) = "Current density can not yet be calculated in a Maxwell propagation."
592 call messages_fatal(1, namespace=namespace)
593
594 end subroutine output_current_density
595
596
597 !----------------------------------------------------------
598 subroutine output_external_current_density(outp, namespace, space, dir, st, mesh, hm, time)
599 type(output_t), intent(in) :: outp
600 type(namespace_t), intent(in) :: namespace
601 class(space_t), intent(in) :: space
602 character(len=*), intent(in) :: dir
603 type(states_mxll_t), intent(in) :: st
604 class(mesh_t), intent(in) :: mesh
605 type(hamiltonian_mxll_t), intent(in) :: hm
606 real(real64), intent(in) :: time
607
608 character(len=MAX_PATH_LEN) :: fname
609 integer :: ierr
610 real(real64), allocatable :: dtmp(:,:)
611 type(unit_t) :: fn_unit
614
615 ! Maxwell current density
616 if (outp%what(option__maxwelloutput__external_current)) then
617 if (hm%current_density_ext_flag) then
618 fn_unit = (unit_one/units_out%time)/(units_out%length**2)
619 safe_allocate(dtmp(1:mesh%np, 1:space%dim))
620 call external_current_calculation(st, space, mesh, time, dtmp)
621 fname = 'external_current'
622 call io_function_output_vector(outp%how(option__maxwelloutput__external_current), dir, fname, namespace, space, &
623 mesh, dtmp, fn_unit, ierr)
624 safe_deallocate_a(dtmp)
625 end if
626 end if
627
630
631 subroutine output_total_current_mxll(outp, namespace, space, dir, st, mesh, hm, time, ep_field, np)
632 type(output_t), intent(in) :: outp
633 type(namespace_t), intent(in) :: namespace
634 class(space_t), intent(in) :: space
635 character(len=*), intent(in) :: dir
636 type(states_mxll_t), intent(in) :: st
637 class(mesh_t), intent(in) :: mesh
638 type(hamiltonian_mxll_t), intent(in) :: hm
639 real(real64), intent(in) :: time
640 real(real64), optional, intent(in) :: ep_field(:)
641 integer, optional, intent(in) :: np
642
643 real(real64), allocatable :: ctmp(:,:)
644 character(len=MAX_PATH_LEN) :: fname
645 integer :: ierr, ip, idim, np_, ff_dim
646 type(unit_t) :: fn_unit
647
649 safe_allocate(ctmp(1:mesh%np, 1:space%dim))
650 if (outp%what(option__maxwelloutput__total_current_mxll)) then
651 np_ = optional_default(np, mesh%np)
652 ff_dim = space%dim
653 if (present(ep_field)) then
654 do idim = 1, ff_dim
655 do ip = 1, np_
656 ctmp(ip, idim) = sqrt(m_two*ep_field(ip)) * real(st%rs_current_density_t1(ip, idim))
657 end do
658 end do
659 else
660 do idim = 1, ff_dim
661 do ip = 1, np_
662 ctmp(ip, idim) = sqrt(m_two*p_ep) * real(st%rs_current_density_t1(ip, idim))
663 end do
664 end do
665 end if
666
667 fn_unit = (unit_one/units_out%time)/(units_out%length**2)
668 fname = 'total_current_mxll'
669 call io_function_output_vector(outp%how(option__maxwelloutput__total_current_mxll), dir, fname, namespace, space, &
670 mesh, ctmp, fn_unit, ierr)
671 end if
672 safe_deallocate_a(ctmp)
675
676
677 !----------------------------------------------------------
678 subroutine output_charge_density_mxll(outp, namespace, space, dir, st, gr, hm) !< have to set unit output correctly
679 type(output_t), intent(in) :: outp
680 type(namespace_t), intent(in) :: namespace
681 class(space_t), intent(in) :: space
682 character(len=*), intent(in) :: dir
683 type(states_mxll_t), intent(in) :: st
684 type(grid_t), intent(in) :: gr
685 type(hamiltonian_mxll_t), intent(in) :: hm
686
687 integer :: ierr
688 type(unit_t) :: fn_unit
689 real(real64), allocatable :: dtmp_1(:,:), dtmp_2(:)
690
692
693 ! charge density calculated by the divergence of the electric field
694 if (outp%what(option__maxwelloutput__charge_density)) then
695 fn_unit = units_out%length**(-space%dim)
696 safe_allocate(dtmp_1(1:gr%np_part,1:space%dim))
697 safe_allocate(dtmp_2(1:gr%np))
698 call get_electric_field_state(st%rs_state, gr, dtmp_1, st%ep, gr%np)
699 call get_divergence_field(gr, dtmp_1, dtmp_2, .true.)
700 call dio_function_output(outp%how(option__maxwelloutput__charge_density), dir, "charge_density", namespace, space, &
701 gr, dtmp_2(:), fn_unit, ierr)
702 safe_deallocate_a(dtmp_1)
703 safe_deallocate_a(dtmp_2)
704 end if
705
707 end subroutine output_charge_density_mxll
708
709end module output_mxll_oct_m
710
711!! Local Variables:
712!! mode: f90
713!! coding: utf-8
714!! End:
subroutine, public energy_density_calc(mesh, st, rs_field, energy_dens, e_energy_dens, b_energy_dens, plane_waves_check, rs_field_plane_waves, energy_dens_plane_waves)
subroutine, public external_current_calculation(st, space, mesh, time, current)
real(real64), parameter, public m_two
Definition: global.F90:193
real(real64), parameter, public m_zero
Definition: global.F90:191
real(real64), parameter, public p_ep
Definition: global.F90:233
This module implements the underlying real-space grid.
Definition: grid.F90:119
The Helmholtz decomposition is intended to contain "only mathematical" functions and procedures to co...
subroutine, public io_function_read_what_how_when(namespace, space, what, how, output_interval, what_tag_in, how_tag_in, output_interval_tag_in, ignore_error)
subroutine, public dio_function_output(how, dir, fname, namespace, space, mesh, ff, unit, ierr, pos, atoms, grp, root)
Top-level IO routine for functions defined on the mesh.
Definition: io.F90:116
subroutine, public io_mkdir(fname, namespace, parents)
Definition: io.F90:360
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:525
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
this module contains the low-level part of the output system
Definition: output_low.F90:117
subroutine output_total_current_mxll(outp, namespace, space, dir, st, mesh, hm, time, ep_field, np)
subroutine output_states_mxll(outp, namespace, space, dir, st, mesh)
subroutine output_current_density(outp, namespace, dir, st_mxll, gr_mxll, hm_mxll, st_elec, gr_elec, hm_elec, time)
subroutine output_poynting_vector_orbital_angular_momentum(outp, namespace, space, dir, st, mesh)
subroutine output_external_current_density(outp, namespace, space, dir, st, mesh, hm, time)
subroutine, public output_mxll_init(outp, namespace, space)
subroutine output_coupling_potentials(outp, namespace, dir, hm, gr)
subroutine output_transverse_rs_state(helmholtz, outp, namespace, space, dir, st, gr)
subroutine output_energy_density_mxll(outp, namespace, space, dir, st, mesh)
subroutine output_longitudinal_rs_state(helmholtz, outp, namespace, space, dir, st, gr)
subroutine, public output_mxll(outp, namespace, space, gr_mxll, st_mxll, hm_mxll, helmholtz, time, dir, gr_elec, st_elec, hm_elec)
subroutine output_vector_potential_mag(outp, helmholtz, namespace, gr, space, dir, st)
subroutine output_divergence_rs_state(outp, namespace, space, dir, st, gr)
subroutine output_charge_density_mxll(outp, namespace, space, dir, st, gr, hm)
this module contains the output system
Definition: output.F90:117
logical function, public parse_is_defined(namespace, name)
Definition: parser.F90:455
subroutine, public get_orbital_angular_momentum(mesh, poynting_vector, orbital_angular_momentum)
subroutine, public get_electric_field_state(rs_state, mesh, electric_field, ep_field, np)
subroutine, public get_poynting_vector(mesh, st, rs_state, rs_sign, poynting_vector, ep_field, mu_field)
subroutine, public get_divergence_field(gr, field, field_div, charge_density)
subroutine, public get_magnetic_field_state(rs_state, mesh, rs_sign, magnetic_field, mu_field, np)
subroutine, public add_last_slash(str)
Adds a '/' in the end of the string, only if it missing. Useful for directories.
Definition: string.F90:163
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
type(unit_t), public unit_one
some special units required for particular quantities
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:171
Describes mesh distribution to nodes.
Definition: mesh.F90:187
output handler class
Definition: output_low.F90:166
The states_elec_t class contains all electronic wave functions.
int true(void)