Octopus
test.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
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
20#include "global.h"
21
22module test_oct_m
23 use accel_oct_m
24 use batch_oct_m
27 use box_oct_m
32 use clock_oct_m
34 use debug_oct_m
42 use global_oct_m
43 use grid_oct_m
49 use iihash_oct_m
51 use iso_c_binding
52 use io_csv_oct_m
53 use io_oct_m
55 use, intrinsic :: iso_fortran_env
61 use mesh_oct_m
69 use mpi_oct_m
76 use parser_oct_m
82 use sihash_oct_m
84 use space_oct_m
85 use sphash_oct_m
94 use types_oct_m
95 use v_ks_oct_m
99
100 ! TODO(Alex) Issue 951. Migrate the test implementations to separate modules in $OCTOPUS_ROOT/test_integrations/
101 ! Test implementation modules
104
105 implicit none
106
107 !Auxiliary quantities needed by the linear solver
108 real(real64), target :: shift_aux
109 type(preconditioner_t) :: prec_aux
110
111 public :: test_run
112
113contains
114
118 subroutine test_run(namespace)
119 type(namespace_t), intent(in) :: namespace
120
121 type(test_parameters_t) :: param
122 integer :: test_mode
123
124 push_sub(test_run)
125
126 call messages_obsolete_variable(namespace, 'WhichTest', 'TestMode')
127
128 call param%init_from_file(namespace)
129
130 !%Variable TestMode
131 !%Type integer
132 !%Default hartree
133 !%Section Calculation Modes::Test
134 !%Description
135 !% Decides what kind of test should be performed.
136 !%Option hartree 1
137 !% Tests the Poisson solvers used to calculate the Hartree potential.
138 !%Option derivatives 2
139 !% Tests and benchmarks the implementation of the finite-difference operators, used to calculate derivatives.
140 !%Option orthogonalization 3
141 !% Tests the implementation of the orthogonalization routines.
142 !%Option interpolation 4
143 !% Test the interpolation routines.
144 !%Option ion_interaction 5
145 !% Tests the ion-ion interaction routines.
146 !%Option projector 6
147 !% Tests the code that applies the nonlocal part of the pseudopotentials
148 !% in case of spin-orbit coupling
149 !%Option dft_u 7
150 !% Tests the DFT+U part of the code for projections on the basis.
151 !%Option hamiltonian_apply 8
152 !% Tests the application of the Hamiltonian, or a part of it
153 !%Option density_calc 9
154 !% Calculation of the density.
155 !%Option exp_apply 10
156 !% Tests the exponential of the Hamiltonian
157 !%Option boundaries 11
158 !% Tests the boundaries conditions
159 !%Option subspace_diag 12
160 !% Tests the subspace diagonalization
161 !%Option batch_ops 13
162 !% Tests the batch operations
163 !%Option clock 18
164 !% Tests for clock
165 !%Option linear_solver 19
166 !% Tests the linear solvers
167 !%Option cgal 20
168 !% Tests for cgal interface
169 !%Option dense_eigensolver 21
170 !% Tests for dense eigensolvers (especially parallel ones)
171 !%Option grid_interpolation 22
172 !% Tests for grid interpolation and multigrid methods.
173 !%Option iihash 23
174 !% Tests for the integer-integer hash table.
175 !%Option sihash 24
176 !% Tests for the string-integer hash table.
177 !%Option sphash 25
178 !% Tests for the string-polymorphic hash table.
179 !%Option mpiwrappers 26
180 !% Tests for the MPI wrappers with large integer displacements.
181 !%Option regridding 27
182 !% Tests the regridding between two different grids.
183 !%Option helmholtz_decomposition 28
184 !% Test for the Helmholtz decomposition subroutines
185 !%Option vecpot_analytical 29
186 !% Tests analytically the vector potential from B field.
187 !%Option current_density 30
188 !% Tests the different contributions to the total electronic current density
189 !%Option mixing_tests 31
190 !% Unit test for the mixing
191 !%Option optimizers 32
192 !% Tests for the optimizers, using standard test functions
193 !%Option weighted_kmeans 33
194 !% Tests weighted kmeans algorithm, for assignment of centroids at clustered
195 !% around regions of high weight.
196 !%Option csv_input 34
197 !% Tests the reading of csv files in various dimensions
198 !%Option composition_chebyshev 35
199 !% Tests the chebyshev filtering and the related composition rule
200 !%Option lalg_adv 36
201 !% Tests for the advanced linear algebra routines
202 !%Option isdf_serial 37
203 !% Tests construction of interoperable separable density fit vectors using the
204 !% serial reference implementation.
205 !%Option isdf 38
206 !% Tests construction of interoperable separable density fit vectors.
207 !%Option centroids_t 39
208 !% Test centroids type methods
209 !%End
210
211 call parse_variable(namespace, 'TestMode', option__testmode__hartree, test_mode)
212
213 call messages_print_with_emphasis(msg="Test mode", namespace=namespace)
214 call messages_print_var_option("TestMode", test_mode, namespace=namespace)
215 call messages_print_var_option("TestType", param%type, namespace=namespace)
216 call messages_print_var_value("TestRepetitions", param%repetitions, namespace=namespace)
217 call messages_print_var_value("TestMinBlockSize", param%min_blocksize, namespace=namespace)
218 call messages_print_var_value("TestMaxBlockSize", param%max_blocksize, namespace=namespace)
219 call messages_print_with_emphasis(namespace=namespace)
220
221 select case (test_mode)
222 case (option__testmode__hartree)
223 call test_hartree(param, namespace)
224 case (option__testmode__derivatives)
225 call test_derivatives(param, namespace)
226 case (option__testmode__orthogonalization)
227 call test_orthogonalization(param, namespace)
228 case (option__testmode__interpolation)
229 call test_interpolation(param, namespace)
230 case (option__testmode__ion_interaction)
231 call test_ion_interaction(namespace)
232 case (option__testmode__projector)
233 call test_projector(param, namespace)
234 case (option__testmode__dft_u)
235 call test_dft_u(param, namespace)
236 case (option__testmode__hamiltonian_apply)
237 call test_hamiltonian(param, namespace)
238 case (option__testmode__density_calc)
239 call test_density_calc(param, namespace)
240 case (option__testmode__exp_apply)
241 call test_exponential(param, namespace)
242 case (option__testmode__boundaries)
243 call test_boundaries(param, namespace)
244 case (option__testmode__subspace_diag)
245 call test_subspace_diagonalization(param, namespace)
246 case (option__testmode__batch_ops)
247 call test_batch_ops(param, namespace)
248 case (option__testmode__clock)
249 call test_clock()
250 case (option__testmode__linear_solver)
251 call test_linear_solver(namespace)
252 case (option__testmode__cgal)
253 call test_cgal()
254 case (option__testmode__dense_eigensolver)
256 case (option__testmode__grid_interpolation)
258 case (option__testmode__iihash)
259 call test_iihash()
260 case (option__testmode__sihash)
261 call test_sihash()
262 case (option__testmode__sphash)
263 call test_sphash(namespace)
264 case (option__testmode__mpiwrappers)
265 call test_mpiwrappers()
266 case (option__testmode__regridding)
267 call test_regridding(namespace)
268 case (option__testmode__helmholtz_decomposition)
269 call test_helmholtz_decomposition(namespace)
270 case (option__testmode__vecpot_analytical)
271 call test_vecpot_analytical(namespace)
272 case (option__testmode__current_density)
273 call test_current_density(namespace)
274 case (option__testmode__mixing_tests)
275 call mix_tests_run()
276 case (option__testmode__optimizers)
277 call test_optimizers(namespace)
278 case (option__testmode__weighted_kmeans)
279 call test_weighted_kmeans(namespace)
280 case (option__testmode__csv_input)
281 call test_csv_input(namespace)
282 case (option__testmode__composition_chebyshev)
283 call test_composition_chebyshev(namespace)
284 case (option__testmode__lalg_adv)
285 call test_exponential_matrix(namespace)
286 case (option__testmode__isdf_serial)
287 call test_isdf(namespace, serial=.true.)
288 case (option__testmode__isdf)
289 call test_isdf(namespace)
290 end select
291
292 pop_sub(test_run)
293 end subroutine test_run
294
295 ! ---------------------------------------------------------
296 subroutine test_hartree(param, namespace)
297 type(test_parameters_t), intent(in) :: param
298 type(namespace_t), intent(in) :: namespace
299
300 type(electrons_t), pointer :: sys
301
302 push_sub(test_hartree)
303
304 call calc_mode_par%set_parallelization(p_strategy_states, default = .false.)
305
306 sys => electrons_t(namespace, int(option__calculationmode__dummy, int32))
307 call sys%init_parallelization(mpi_world)
308 call poisson_test(sys%hm%psolver, sys%space, sys%gr, sys%ions%latt, namespace, param%repetitions)
309 safe_deallocate_p(sys)
310
311 pop_sub(test_hartree)
312 end subroutine test_hartree
313
314 ! ---------------------------------------------------------
315 subroutine test_helmholtz_decomposition(namespace)
316 type(namespace_t), intent(in) :: namespace
317
318 type(electrons_t), pointer :: sys
319 type(helmholtz_decomposition_t) :: helmholtz
320
322
323 ! First of all we have to initialize the grid and the poisson solver
324 call calc_mode_par%set_parallelization(p_strategy_states, default = .false.)
325
326 sys => electrons_t(namespace, int(option__calculationmode__dummy, int32))
327 call sys%init_parallelization(mpi_world)
328
329 call helmholtz%init(namespace, sys%gr, sys%mc, sys%space)
330
331 ! Then we have to initialize the exact fields
332 write(message(1),'(a)') "Helmholtz decomposition: beginning Hertzian dipole test"
333 call messages_info(1, namespace=namespace)
334 call hertzian_dipole_test(helmholtz, sys%gr, sys%namespace, sys%space)
335
336 write(message(1),'(a)') "Helmholtz decomposition: beginning Gaussian test"
337 call messages_info(1, namespace=namespace)
338 call gaussian_test(helmholtz, sys%gr, sys%namespace, sys%space)
339
340 safe_deallocate_p(sys)
341
343 end subroutine test_helmholtz_decomposition
344
345 ! ---------------------------------------------------------
346 subroutine test_linear_solver(namespace)
347 use, intrinsic :: iso_c_binding, only: c_ptr
348 type(namespace_t), intent(in) :: namespace
349
350 type(electrons_t), pointer :: sys
351 real(real64), allocatable :: rho(:), x(:), center(:)
352 real(real64) :: rr, alpha, beta, res
353 integer :: ip, iter
354 integer, target :: prefactor = -1
355
356 real(real64), parameter :: threshold = 1.e-7_real64
357
358 push_sub(test_linear_solver)
359
360 call calc_mode_par%set_parallelization(p_strategy_states, default = .false.)
361
362 sys => electrons_t(namespace, int(option__calculationmode__dummy, int32))
363 call sys%init_parallelization(mpi_world)
364
365 ! We need to set up some auxiliary quantities called by the linear solver
366 call mesh_init_mesh_aux(sys%gr)
367 ! Shift of the linear equation
368 shift_aux = 0.25_real64
369 ! Preconditioner used for the QMR algorithm
370 call preconditioner_init(prec_aux, namespace, sys%gr, sys%mc, sys%space)
371
372 ! Here we put a Gaussian as the right-hand side of the linear solver
373 ! Values are taken from the poisson_test routine
374 alpha = m_four * sys%gr%spacing(1)
375 beta = m_one / (alpha**sys%space%dim * sqrt(m_pi)**sys%space%dim)
376 ! The Gaussian is centered around the origin
377 safe_allocate(center(1:sys%space%dim))
378 center = m_zero
379
380 safe_allocate(rho(1:sys%gr%np))
381 rho = m_zero
382 do ip = 1, sys%gr%np
383 call mesh_r(sys%gr, ip, rr, origin = center(:))
384 rho(ip) = beta*exp(-(rr/alpha)**2)
385 end do
386
387 safe_allocate(x(1:sys%gr%np))
388
389 !Test the CG linear solver
390 x = m_zero
391 iter = 1000
392
393 call dconjugate_gradients(sys%gr%np, x, rho, dshifted_laplacian_op, dmf_dotp_aux, iter, res, &
394 threshold, userdata=[c_loc(sys%gr%der),c_loc(shift_aux),c_loc(prefactor)])
395 write(message(1),'(a,i6,a)') "Info: CG converged with ", iter, " iterations."
396 write(message(2),'(a,e14.6)') "Info: The residue is ", res
397 write(message(3),'(a,e14.6)') "Info: Norm solution CG ", dmf_nrm2(sys%gr, x)
398 call messages_info(3, namespace=namespace)
399
400 call preconditioner_end(prec_aux)
401 safe_deallocate_a(x)
402 safe_deallocate_a(rho)
403 safe_deallocate_p(sys)
404
405 pop_sub(test_linear_solver)
406 end subroutine test_linear_solver
407
408 ! ---------------------------------------------------------
409 subroutine test_projector(param, namespace)
410 type(test_parameters_t), intent(in) :: param
411 type(namespace_t), intent(in) :: namespace
412
413 type(electrons_t), pointer :: sys
414 type(wfs_elec_t) :: epsib
415 integer :: itime
416 complex(real64), allocatable :: psi(:, :)
417
418 push_sub(test_projector)
419
420 call calc_mode_par%set_parallelization(p_strategy_states, default = .false.)
421
422 call messages_write('Info: Testing the nonlocal part of the pseudopotential with SOC')
423 call messages_new_line()
424 call messages_new_line()
425 call messages_info(namespace=namespace)
426
427 sys => electrons_t(namespace, int(option__calculationmode__dummy, int32))
428 call sys%init_parallelization(mpi_world)
429
430 call states_elec_allocate_wfns(sys%st, sys%gr, wfs_type = type_cmplx)
431 call test_batch_set_gaussian(sys%st%group%psib(1, 1), sys%gr)
432
433 ! Initialize external potential
434 call hamiltonian_elec_epot_generate(sys%hm, sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st)
435
436 call sys%st%group%psib(1, 1)%copy_to(epsib)
437
438 call batch_set_zero(epsib)
439
440 do itime = 1, param%repetitions
441 call zproject_psi_batch(sys%gr, sys%gr%der%boundaries, sys%hm%ep%proj, &
442 sys%hm%ep%natoms, 2, sys%st%group%psib(1, 1), epsib)
443 end do
444
445 safe_allocate(psi(1:sys%gr%np, 1:sys%st%d%dim))
446 do itime = 1, epsib%nst
447 call batch_get_state(epsib, itime, sys%gr%np, psi)
448 write(message(1),'(a,i1,3x, f12.6)') "Norm state ", itime, zmf_nrm2(sys%gr, 2, psi)
449 call messages_info(1, namespace=sys%namespace)
450 end do
451 safe_deallocate_a(psi)
452
453 call epsib%end()
454 call states_elec_deallocate_wfns(sys%st)
455 safe_deallocate_p(sys)
456
457 pop_sub(test_projector)
458 end subroutine test_projector
459
460 ! ---------------------------------------------------------
461 subroutine test_dft_u(param, namespace)
462 type(test_parameters_t), intent(in) :: param
463 type(namespace_t), intent(in) :: namespace
464
465 type(electrons_t), pointer :: sys
466 type(wfs_elec_t) :: epsib, epsib2
467 integer :: itime, ist
468 type(orbitalbasis_t) :: basis
469 real(real64), allocatable :: ddot(:,:,:), dweight(:,:)
470 complex(real64), allocatable :: zdot(:,:,:), zweight(:,:)
471 logical :: skipSOrbitals, useAllOrbitals
472
473 push_sub(test_dft_u)
474
475 call calc_mode_par%unset_parallelization(p_strategy_states)
476 call calc_mode_par%unset_parallelization(p_strategy_kpoints)
477 call calc_mode_par%set_parallelization(p_strategy_domains, default = .true.)
478
479 call messages_write('Info: Testing some DFT+U routines')
480 call messages_new_line()
481 call messages_new_line()
482 call messages_info(namespace=namespace)
483
484 sys => electrons_t(namespace, int(option__calculationmode__dummy, int32))
485 call sys%init_parallelization(mpi_world)
486
487 call states_elec_allocate_wfns(sys%st, sys%gr)
488 call test_batch_set_gaussian(sys%st%group%psib(1, 1), sys%gr)
489 if (sys%st%pack_states) call sys%st%pack()
490
491 call sys%st%group%psib(1, 1)%copy_to(epsib2, copy_data = .true.)
492
493 ! We set the phase of the batch if needed
494 if (.not. sys%hm%phase%is_allocated()) then
495 call sys%st%group%psib(1, 1)%copy_to(epsib, copy_data = .true.)
496 else
497 call sys%st%group%psib(1, 1)%copy_to(epsib)
498 call sys%hm%phase%apply_to(sys%gr, sys%gr%np, &
499 .false., epsib, src=sys%st%group%psib(1, 1))
500 epsib2%has_phase = .true.
501 end if
502
503 ! Initialize the orbital basis
504 call orbitalbasis_init(basis, sys%namespace, sys%space%periodic_dim)
505
506 ! Parsed in src/hamiltonian/lda_u.F90
507 call parse_variable(namespace, 'UseAllAtomicOrbitals', .false., useallorbitals)
508 call parse_variable(namespace, 'SkipSOrbitals', .true.,skipsorbitals)
509
510 if (states_are_real(sys%st)) then
511 call dorbitalbasis_build(basis, sys%namespace, sys%ions, sys%gr, sys%st%d%kpt, sys%st%d%dim, &
512 skipsorbitals, useallorbitals, verbose=.false.)
513 safe_allocate(dweight(1:basis%orbsets(1)%norbs, 1:epsib%nst_linear))
514 safe_allocate(ddot(1:sys%st%d%dim, 1:basis%orbsets(1)%norbs, 1:epsib%nst))
515 else
516 call zorbitalbasis_build(basis, sys%namespace, sys%ions, sys%gr, sys%st%d%kpt, sys%st%d%dim, &
517 skipsorbitals, useallorbitals, verbose=.false.)
518 call orbitalset_update_phase(basis%orbsets(1), sys%space%dim, sys%st%d%kpt, sys%kpoints, (sys%st%d%ispin==spin_polarized))
519 safe_allocate(zweight(1:basis%orbsets(1)%norbs, 1:epsib%nst_linear))
520 safe_allocate(zdot(1:sys%st%d%dim, 1:basis%orbsets(1)%norbs, 1:epsib%nst))
521
522 !We set the phase of the orbitals if needed
523 if (sys%hm%phase%is_allocated()) then
524 call orbitalset_update_phase(basis%orbsets(1), sys%space%dim, sys%st%d%kpt, sys%kpoints, &
525 (sys%st%d%ispin==spin_polarized))
526 end if
527 end if
528
529 do itime = 1, param%repetitions
530 call batch_set_zero(epsib2)
531 if (states_are_real(sys%st)) then
532 dweight = m_one
533 ddot = m_zero
534 call dorbitalset_get_coeff_batch(basis%orbsets(1), sys%st%d%dim, sys%st%group%psib(1, 1), ddot)
535 call dorbitalset_add_to_batch(basis%orbsets(1), sys%st%d%dim, epsib2, dweight)
536 else
537 zweight = m_one
538 zdot = m_zero
539 call zorbitalset_get_coeff_batch(basis%orbsets(1), sys%st%d%dim, epsib, zdot)
540 call zorbitalset_add_to_batch(basis%orbsets(1), sys%st%d%dim, epsib2, zweight)
541 end if
542 end do
543
544 if (epsib%is_packed()) then
545 call epsib%do_unpack(force = .true.)
546 end if
547
548 do ist = 1, epsib%nst
549 if (states_are_real(sys%st)) then
550 write(message(1),'(a,i2,3x,e13.6)') "Dotp state ", ist, ddot(1,1,ist)
551 else
552 write(message(1),'(a,i2,2(3x,e13.6))') "Dotp state ", ist, zdot(1,1,ist)
553 end if
554 call messages_info(1)
555 end do
557
558 call test_prints_info_batch(sys%st, sys%gr, epsib2)
559
560 safe_deallocate_a(dweight)
561 safe_deallocate_a(zweight)
562 safe_deallocate_a(ddot)
563 safe_deallocate_a(zdot)
564
565 call epsib%end()
566 call epsib2%end()
567 call orbitalbasis_end(basis)
568 call states_elec_deallocate_wfns(sys%st)
569 safe_deallocate_p(sys)
570
571 pop_sub(test_dft_u)
572 end subroutine test_dft_u
573
574 ! ---------------------------------------------------------
575 subroutine test_hamiltonian(param, namespace)
576 type(test_parameters_t), intent(in) :: param
577 type(namespace_t), intent(in) :: namespace
578
579 type(electrons_t), pointer :: sys
580 type(hamiltonian_elec_t) :: hm_copy
581 type(wfs_elec_t) :: hpsib, hpsib_copy, hpsib_diff
582 integer :: itime, terms
583 integer :: ist
584 logical :: copy_before_apply
585 real(real64), allocatable :: norm_hpsib(:), norm_diff(:)
586 real(real64) :: max_rel_diff
587 real(real64), parameter :: hamiltonian_copy_rel_tol = 1.0e-12_real64
588
589 push_sub(test_hamiltonian)
590
591 !%Variable TestHamiltonianApply
592 !%Type integer
593 !%Default term_all
594 !%Section Calculation Modes::Test
595 !%Description
596 !% Decides which part of the Hamiltonian is applied.
597 !%Option term_all 0
598 !% Apply the full Hamiltonian.
599 !%Option term_kinetic 1
600 !% Apply only the kinetic operator
601 !%Option term_local_potential 2
602 !% Apply only the local potential.
603 !%Option term_non_local_potential 4
604 !% Apply only the non_local potential.
605 !%End
606 call parse_variable(namespace, 'TestHamiltonianApply', option__testhamiltonianapply__term_all, terms)
607 if (terms == 0) terms = huge(1)
608
609 !%Variable TestHamiltonianCopyBeforeApply
610 !%Type logical
611 !%Default no
612 !%Section Calculation Modes::Test
613 !%Description
614 !% If set to yes, the Hamiltonian is copied with hamiltonian_elec_copy
615 !% and the copied Hamiltonian is used for application.
616 !%End
617 call parse_variable(namespace, 'TestHamiltonianCopyBeforeApply', .false., copy_before_apply)
618 call messages_print_var_value('TestHamiltonianCopyBeforeApply', copy_before_apply, namespace=namespace)
619
620
621 call calc_mode_par%set_parallelization(p_strategy_states, default = .false.)
622
623 call messages_write('Info: Testing the application of the Hamiltonian')
624 call messages_new_line()
625 call messages_new_line()
626 call messages_info(namespace=namespace)
627
628 sys => electrons_t(namespace, int(option__calculationmode__dummy, int32))
629 call sys%init_parallelization(mpi_world)
630
631 call states_elec_allocate_wfns(sys%st, sys%gr)
632 call test_batch_set_gaussian(sys%st%group%psib(1, 1), sys%gr)
633
634 ! Initialize external potential
635 if (sys%st%pack_states .and. sys%hm%apply_packed()) call sys%st%pack()
636 call hamiltonian_elec_epot_generate(sys%hm, sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st)
637 call density_calc(sys%st, sys%gr, sys%st%rho)
638 call v_ks_calc(sys%ks, sys%namespace, sys%space, sys%hm, sys%st, sys%ions, sys%ext_partners)
639
640 if (copy_before_apply) then
641 call hamiltonian_elec_copy(hm_copy, sys%hm)
642 end if
643
644 call boundaries_set(sys%gr%der%boundaries, sys%gr, sys%st%group%psib(1, 1))
645
646 call sys%st%group%psib(1, 1)%copy_to(hpsib)
647 if (copy_before_apply) call sys%st%group%psib(1, 1)%copy_to(hpsib_copy)
648
649 if (sys%hm%apply_packed()) then
650 call sys%st%group%psib(1, 1)%do_pack()
651 call hpsib%do_pack(copy = .false.)
652 if (copy_before_apply) call hpsib_copy%do_pack(copy = .false.)
653 end if
654
655 do itime = 1, param%repetitions
656 if (states_are_real(sys%st)) then
657 call dhamiltonian_elec_apply_batch(sys%hm, sys%namespace, sys%gr, sys%st%group%psib(1, 1), hpsib, &
658 terms = terms, set_bc = .false.)
659 if (copy_before_apply) then
660 call dhamiltonian_elec_apply_batch(hm_copy, sys%namespace, sys%gr, sys%st%group%psib(1, 1), hpsib_copy, &
661 terms = terms, set_bc = .false.)
662 end if
663 else
664 call zhamiltonian_elec_apply_batch(sys%hm, sys%namespace, sys%gr, sys%st%group%psib(1, 1), hpsib, &
665 terms = terms, set_bc = .false.)
666 if (copy_before_apply) then
667 call zhamiltonian_elec_apply_batch(hm_copy, sys%namespace, sys%gr, sys%st%group%psib(1, 1), hpsib_copy, &
668 terms = terms, set_bc = .false.)
669 end if
670 end if
671 end do
672
673 if (hpsib%is_packed()) then
674 call hpsib%do_unpack(force = .true.)
675 end if
676 if (copy_before_apply .and. hpsib_copy%is_packed()) then
677 call hpsib_copy%do_unpack(force = .true.)
678 end if
679
680 if (copy_before_apply) then
681 call hpsib_copy%copy_to(hpsib_diff, copy_data = .true.)
682 call batch_axpy(sys%gr%np, -1.0_real64, hpsib, hpsib_diff)
683
684 safe_allocate(norm_hpsib(1:hpsib%nst))
685 safe_allocate(norm_diff(1:hpsib_diff%nst))
686 call mesh_batch_nrm2(sys%gr, hpsib, norm_hpsib)
687 call mesh_batch_nrm2(sys%gr, hpsib_diff, norm_diff)
688
689 max_rel_diff = maxval(norm_diff / max(norm_hpsib, tiny(1.0_real64)))
690 write(message(1),'(a,e23.16)') 'Hamiltonian copy max relative difference ', max_rel_diff
691 call messages_info(1, namespace=namespace)
692
693 do ist = 1, hpsib%nst
694 if (norm_diff(ist) > hamiltonian_copy_rel_tol*max(norm_hpsib(ist), tiny(1.0_real64))) then
695 write(message(1),'(a,i6)') 'Hamiltonian copy mismatch for state ', ist
696 call messages_fatal(1, namespace=namespace)
697 end if
698 end do
699
700 safe_deallocate_a(norm_hpsib)
701 safe_deallocate_a(norm_diff)
702 call hpsib_diff%end(copy = .false.)
703 end if
704
705 call test_prints_info_batch(sys%st, sys%gr, hpsib)
706
707 if (copy_before_apply) then
708 call hamiltonian_elec_end(hm_copy)
709 call hpsib_copy%end(copy = .false.)
710 ! check that original hm still works after teardown of copy
711 if (sys%hm%apply_packed()) then
712 call hpsib%do_pack(copy = .false.)
713 end if
714 if (states_are_real(sys%st)) then
715 call dhamiltonian_elec_apply_batch(sys%hm, sys%namespace, sys%gr, sys%st%group%psib(1, 1), hpsib, &
716 terms = terms, set_bc = .false.)
717 else
718 call zhamiltonian_elec_apply_batch(sys%hm, sys%namespace, sys%gr, sys%st%group%psib(1, 1), hpsib, &
719 terms = terms, set_bc = .false.)
720 end if
721 end if
722 call hpsib%end(copy = .false.)
723 call states_elec_deallocate_wfns(sys%st)
724 safe_deallocate_p(sys)
725
726 pop_sub(test_hamiltonian)
727 end subroutine test_hamiltonian
728
729
730 ! ---------------------------------------------------------
731 subroutine test_density_calc(param, namespace)
732 type(test_parameters_t), intent(in) :: param
733 type(namespace_t), intent(in) :: namespace
734
735 type(electrons_t), pointer :: sys
736 integer :: itime
737
738 push_sub(test_density_calc)
739
740 call calc_mode_par%set_parallelization(p_strategy_states, default = .false.)
741
742 call messages_write('Info: Testing density calculation')
743 call messages_new_line()
744 call messages_new_line()
745 call messages_info(namespace=namespace)
746
747 sys => electrons_t(namespace, int(option__calculationmode__dummy, int32))
748 call sys%init_parallelization(mpi_world)
749
750 call states_elec_allocate_wfns(sys%st, sys%gr)
751 call test_batch_set_gaussian(sys%st%group%psib(1, 1), sys%gr)
752 if (sys%st%pack_states) call sys%st%pack()
753
754 do itime = 1, param%repetitions
755 call density_calc(sys%st, sys%gr, sys%st%rho)
756 end do
757
758 write(message(1),'(a,3x, f12.6)') "Norm density ", dmf_nrm2(sys%gr, sys%st%rho(:,1))
759 call messages_info(1, namespace=namespace)
760
761 call states_elec_deallocate_wfns(sys%st)
762 safe_deallocate_p(sys)
763
764 pop_sub(test_density_calc)
765 end subroutine test_density_calc
766
767
768 ! ---------------------------------------------------------
769 subroutine test_boundaries(param, namespace)
770 type(test_parameters_t), intent(in) :: param
771 type(namespace_t), intent(in) :: namespace
772
773 type(electrons_t), pointer :: sys
774 integer :: itime
775
776 push_sub(test_density_calc)
777
778 call calc_mode_par%set_parallelization(p_strategy_states, default = .false.)
779
780 call messages_write('Info: Testing boundary conditions')
781 call messages_new_line()
782 call messages_new_line()
783 call messages_info(namespace=namespace)
784
785 sys => electrons_t(namespace, int(option__calculationmode__dummy, int32))
786 call sys%init_parallelization(mpi_world)
787
788 call states_elec_allocate_wfns(sys%st, sys%gr)
789 call test_batch_set_gaussian(sys%st%group%psib(1, 1), sys%gr)
790 if (sys%st%pack_states) call sys%st%pack()
791
792 do itime = 1, param%repetitions
793 call boundaries_set(sys%gr%der%boundaries, sys%gr, sys%st%group%psib(1, 1))
794 end do
795
796 call test_prints_info_batch(sys%st, sys%gr, sys%st%group%psib(1, 1))
797
798 call states_elec_deallocate_wfns(sys%st)
799 safe_deallocate_p(sys)
800
801 pop_sub(test_density_calc)
802 end subroutine test_boundaries
803
804 ! ---------------------------------------------------------
808 subroutine test_composition_chebyshev(namespace)
809 type(namespace_t), intent(in) :: namespace
810
811 type(electrons_t), pointer :: sys
812 type(chebyshev_filter_bounds_t), pointer :: bounds
813 integer, allocatable :: degree(:)
814 integer :: degree_n
815 type(wfs_elec_t) :: psib
816
818
819 call calc_mode_par%set_parallelization(p_strategy_states, default = .false.)
820
821 call messages_write('Info: Testing Chebyshev filtering and its composition rule')
822 call messages_new_line()
823 call messages_new_line()
824 call messages_info(namespace=namespace)
825
826 sys => electrons_t(namespace, int(option__calculationmode__dummy, int32))
827 call sys%init_parallelization(mpi_world)
828
829 call states_elec_allocate_wfns(sys%st, sys%gr)
830
831 if (sys%st%pack_states .and. sys%hm%apply_packed()) call sys%st%pack()
832 call hamiltonian_elec_epot_generate(sys%hm, sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st)
833 call density_calc(sys%st, sys%gr, sys%st%rho)
834 call v_ks_calc(sys%ks, sys%namespace, sys%space, sys%hm, sys%st, sys%ions, sys%ext_partners)
835
836 bounds => chebyshev_filter_bounds_t(-1.0_real64, 1.0_real64)
837 safe_allocate(degree(1:sys%st%group%nblocks))
838
839 !%Variable TestCompositionOrder
840 !%Type integer
841 !%Section Calculation Modes::Test
842 !%Description
843 !% Specifies the value of m for the test of the composition rule
844 !% $T_{2n}(x) = 2*T_n(x)^2-1$.
845 !%
846 !%End
847 call parse_variable(namespace, 'TestCompositionOrder', 2, degree_n)
848
849 !Initialization
850 call test_batch_set_gaussian(sys%st%group%psib(1, 1), sys%gr)
851 call messages_new_line()
852 call messages_write('Info: Result for the original vector')
853 call messages_info(namespace=namespace)
854 call test_prints_info_batch(sys%st, sys%gr, sys%st%group%psib(1, 1))
855
856 ! Direct evaluation of mxn-th order Chebyshev filtering
857 degree = 2*degree_n
858 if (states_are_real(sys%st)) then
859 call dchebyshev_filter(namespace, sys%gr, sys%st, sys%hm, degree, bounds, 1, normalize=.false.)
860 else
861 call zchebyshev_filter(namespace, sys%gr, sys%st, sys%hm, degree, bounds, 1, normalize=.false.)
862 end if
863
865 call messages_write('Info: Result after calling 2n-th order filtering')
866 call messages_info(namespace=namespace)
867 call test_prints_info_batch(sys%st, sys%gr, sys%st%group%psib(1, 1))
868
869 ! Composition rule: m-th order Chebyshev filtering followed by n-th order filtering
870 call test_batch_set_gaussian(sys%st%group%psib(1, 1), sys%gr)
871 call sys%st%group%psib(1, 1)%copy_to(psib, copy_data=.true.)
872 degree = degree_n
873 if (states_are_real(sys%st)) then
874 call dchebyshev_filter(namespace, sys%gr, sys%st, sys%hm, degree, bounds, 1, normalize=.false.)
875 call dchebyshev_filter(namespace, sys%gr, sys%st, sys%hm, degree, bounds, 1, normalize=.false.)
876 else
877 call zchebyshev_filter(namespace, sys%gr, sys%st, sys%hm, degree, bounds, 1, normalize=.false.)
878 call zchebyshev_filter(namespace, sys%gr, sys%st, sys%hm, degree, bounds, 1, normalize=.false.)
879 end if
880 call batch_scal(sys%gr%np, m_two, sys%st%group%psib(1, 1))
881 call batch_axpy(sys%gr%np, -m_one, psib, sys%st%group%psib(1, 1))
882
883 call messages_new_line()
884 call messages_write('Info: Result using the composition rule')
885 call messages_info(namespace=namespace)
886 call test_prints_info_batch(sys%st, sys%gr, sys%st%group%psib(1, 1))
887
888
889 safe_deallocate_a(degree)
890 safe_deallocate_p(bounds)
891
892 call psib%end()
893 call states_elec_deallocate_wfns(sys%st)
894 safe_deallocate_p(sys)
895
897 end subroutine test_composition_chebyshev
898
899
900
901 ! ---------------------------------------------------------
902 subroutine test_exponential(param, namespace)
903 type(test_parameters_t), intent(in) :: param
904 type(namespace_t), intent(in) :: namespace
905
906 type(electrons_t), pointer :: sys
907 type(exponential_t) :: te
908 integer :: itime
909
910 push_sub(test_exponential)
911
912 call calc_mode_par%set_parallelization(p_strategy_states, default = .false.)
913
914 call messages_write('Info: Testing exponential')
915 call messages_new_line()
916 call messages_new_line()
917 call messages_info(namespace=namespace)
918
919 sys => electrons_t(namespace, int(option__calculationmode__dummy, int32))
920 call sys%init_parallelization(mpi_world)
921
922 call states_elec_allocate_wfns(sys%st, sys%gr, wfs_type=type_cmplx)
923 call test_batch_set_gaussian(sys%st%group%psib(1, 1), sys%gr)
924
925 ! Initialize external potential
926 if (sys%st%pack_states .and. sys%hm%apply_packed()) call sys%st%pack()
927 call hamiltonian_elec_epot_generate(sys%hm, sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st)
928 call density_calc(sys%st, sys%gr, sys%st%rho)
929 call v_ks_calc(sys%ks, sys%namespace, sys%space, sys%hm, sys%st, sys%ions, sys%ext_partners)
930
931 call exponential_init(te, namespace)
932
933 if (sys%hm%apply_packed()) then
934 call sys%st%group%psib(1, 1)%do_pack()
935 end if
936
937 do itime = 1, param%repetitions
938 call te%apply_batch(sys%namespace, sys%gr, sys%hm, sys%st%group%psib(1, 1), 1e-3_real64)
939 end do
940
941 call test_prints_info_batch(sys%st, sys%gr, sys%st%group%psib(1, 1))
942
943 call states_elec_deallocate_wfns(sys%st)
944 safe_deallocate_p(sys)
945
946 pop_sub(test_exponential)
947 end subroutine test_exponential
948
949
950 ! ---------------------------------------------------------
951 subroutine test_subspace_diagonalization(param, namespace)
952 type(test_parameters_t), intent(in) :: param
953 type(namespace_t), intent(in) :: namespace
954
955 type(electrons_t), pointer :: sys
956 integer :: itime
957 type(subspace_t) :: sdiag
958 real(real64), allocatable :: diff(:)
959
961
962 call calc_mode_par%set_parallelization(p_strategy_states, default = .false.)
963
964 call messages_write('Info: Testing subspace diagonalization')
965 call messages_new_line()
966 call messages_new_line()
967 call messages_info(namespace=namespace)
968
969 sys => electrons_t(namespace, int(option__calculationmode__dummy, int32))
970 call sys%init_parallelization(mpi_world)
971
972 call states_elec_allocate_wfns(sys%st, sys%gr)
973 call test_batch_set_gaussian(sys%st%group%psib(1, 1), sys%gr)
974
975 if (sys%st%pack_states .and. sys%hm%apply_packed()) call sys%st%pack()
976 call hamiltonian_elec_epot_generate(sys%hm, sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st)
977 call density_calc(sys%st, sys%gr, sys%st%rho)
978 call v_ks_calc(sys%ks, sys%namespace, sys%space, sys%hm, sys%st, sys%ions, sys%ext_partners)
979
980 call sdiag%init(sys%namespace, sys%st)
981
982 safe_allocate(diff(1:sys%st%nst))
983
984 do itime = 1, param%repetitions
985 if (states_are_real(sys%st)) then
986 call dsubspace_diag(sdiag, sys%namespace, sys%gr, sys%st, sys%hm, 1, sys%st%eigenval(:, 1), diff)
987 else
988 call zsubspace_diag(sdiag, sys%namespace, sys%gr, sys%st, sys%hm, 1, sys%st%eigenval(:, 1), diff)
989 end if
990 end do
991
992 safe_deallocate_a(diff)
993
994 call test_prints_info_batch(sys%st, sys%gr, sys%st%group%psib(1, 1))
995
996 call states_elec_deallocate_wfns(sys%st)
997 safe_deallocate_p(sys)
998
1000 end subroutine test_subspace_diagonalization
1001
1002
1003 ! ---------------------------------------------------------
1004 subroutine test_batch_ops(param, namespace)
1005 type(test_parameters_t), intent(in) :: param
1006 type(namespace_t), intent(in) :: namespace
1007
1008 type(electrons_t), pointer :: sys
1009 integer :: itime, ops, ops_default, ist, jst, nst, ip
1010 type(wfs_elec_t) :: xx, yy, zz
1011 real(real64), allocatable :: tmp(:)
1012 real(real64), allocatable :: ddotv(:)
1013 complex(real64), allocatable :: zdotv(:)
1014 real(real64), allocatable :: ddot(:,:), df(:,:), dweight(:), dpoints(:,:,:)
1015 complex(real64), allocatable :: zdot(:,:), zf(:,:), zweight(:), zpoints(:,:,:)
1016 real(real64), allocatable :: dff_mf(:)
1017 complex(real64), allocatable :: zff_mf(:)
1018 integer :: sp, block_size, size
1019
1020
1021 push_sub(test_batch_ops)
1022
1023 !%Variable TestBatchOps
1024 !%Type flag
1025 !%Default all
1026 !%Section Calculation Modes::Test
1027 !%Description
1028 !% Decides which part of the Hamiltonian is applied.
1029 !%Option ops_axpy bit(1)
1030 !% Tests batch_axpy operation
1031 !%Option ops_scal bit(2)
1032 !% Tests batch_scal operation
1033 !%Option ops_nrm2 bit(3)
1034 !% Tests batch_nrm2 operation
1035 !%Option ops_dotp_matrix bit(4)
1036 !% Tests X(mesh_batch_dotp_matrix)
1037 !%Option ops_dotp_self bit(5)
1038 !% Tests X(mesh_batch_dotp_self)
1039 !%Option ops_dotp_vector bit(6)
1040 !% Tests X(mesh_batch_dotp_vector)
1041 !%Option ops_ax_function_py bit(7)
1042 !% Tests X(batch_ax_function_py)
1043 !%Option ops_get_points bit(8)
1044 !% Tests batch_get_points and batch_set_points
1045 !%End
1046 ops_default = &
1047 option__testbatchops__ops_axpy + &
1048 option__testbatchops__ops_scal + &
1049 option__testbatchops__ops_nrm2 + &
1050 option__testbatchops__ops_dotp_matrix + &
1051 option__testbatchops__ops_dotp_self + &
1052 option__testbatchops__ops_dotp_vector + &
1053 option__testbatchops__ops_ax_function_py + &
1054 option__testbatchops__ops_get_points
1055
1056 call parse_variable(namespace, 'TestBatchOps', ops_default, ops)
1057
1058 call calc_mode_par%set_parallelization(p_strategy_states, default = .false.)
1059
1060 call messages_write('Info: Testing batch operations')
1061 call messages_new_line()
1062 call messages_new_line()
1063 call messages_info(namespace=namespace)
1064
1065 sys => electrons_t(namespace, int(option__calculationmode__dummy, int32))
1066 call sys%init_parallelization(mpi_world)
1067
1068 call states_elec_allocate_wfns(sys%st, sys%gr)
1069 call test_batch_set_gaussian(sys%st%group%psib(1, 1), sys%gr)
1070 if (sys%st%pack_states) call sys%st%pack()
1071
1072 if (bitand(ops, option__testbatchops__ops_axpy) /= 0) then
1073 message(1) = 'Info: Testing axpy'
1074 call messages_info(1, namespace=sys%namespace)
1075
1076 call sys%st%group%psib(1, 1)%copy_to(xx, copy_data = .true.)
1077 call sys%st%group%psib(1, 1)%copy_to(yy, copy_data = .true.)
1078
1079 do itime = 1, param%repetitions
1080 call batch_axpy(sys%gr%np, 0.1_real64, xx, yy)
1081 end do
1082 call test_prints_info_batch(sys%st, sys%gr, yy, string = "axpy")
1083
1084 call xx%end()
1085 call yy%end()
1086
1087 call sys%st%group%psib(1, 1)%copy_to(xx, copy_data = .true.)
1088 call sys%st%group%psib(1, 1)%copy_to(yy, copy_data = .true.)
1089 do itime = 1, param%repetitions
1090 call batch_axpby(sys%gr%np, 0.1_real64, xx, 0.2_real64, yy)
1091 end do
1092 call test_prints_info_batch(sys%st, sys%gr, yy, string = "axpby")
1093
1094 call xx%end()
1095 call yy%end()
1096 end if
1097
1098 if (bitand(ops, option__testbatchops__ops_scal) /= 0) then
1099 message(1) = 'Info: Testing scal'
1100 call messages_info(1, namespace=sys%namespace)
1101
1102 call sys%st%group%psib(1, 1)%copy_to(xx, copy_data = .true.)
1103
1104 do itime = 1, param%repetitions
1105 call batch_scal(sys%gr%np, 0.1_real64, xx)
1106 end do
1107 call test_prints_info_batch(sys%st, sys%gr, xx, string="scal")
1108 call xx%end()
1109
1110 call sys%st%group%psib(1, 1)%copy_to(xx, copy_data = .true.)
1111 call sys%st%group%psib(1, 1)%copy_to(yy, copy_data = .false.)
1112 do itime = 1, param%repetitions
1113 call batch_scal2v(sys%gr%np, 0.1_real64, xx, yy)
1114 end do
1115 call test_prints_info_batch(sys%st, sys%gr, yy, string="scal2v")
1116
1117 call xx%end()
1118 call yy%end()
1119 call sys%st%group%psib(1, 1)%copy_to(xx, copy_data = .true.)
1120 call sys%st%group%psib(1, 1)%copy_to(yy, copy_data = .true.)
1121 call sys%st%group%psib(1, 1)%copy_to(zz, copy_data = .false.)
1122
1123 do itime = 1, param%repetitions
1124 call batch_pointwise_mul(sys%gr%np, xx, yy, zz)
1125 end do
1126 call test_prints_info_batch(sys%st, sys%gr, zz, string="hadamard")
1127 call xx%end()
1128 call yy%end()
1129 call zz%end()
1130
1131 call sys%st%group%psib(1, 1)%copy_to(xx, copy_data = .true.)
1132 call sys%st%group%psib(1, 1)%copy_to(yy, copy_data = .false.)
1133 if (states_are_real(sys%st)) then
1134 safe_allocate(dff_mf(1:sys%gr%np))
1135 do ip = 1, sys%gr%np
1136 dff_mf(ip) = 0.01_real64 + 0.001_real64*real(sys%gr%x(1, ip), real64)
1137 end do
1138
1139 do itime = 1, param%repetitions
1140 call batch_mul_mf(sys%gr%np, dff_mf, xx, yy)
1141 end do
1142 else
1143 safe_allocate(zff_mf(1:sys%gr%np))
1144 do ip = 1, sys%gr%np
1145 zff_mf(ip) = cmplx(0.01_real64 + 0.001_real64*real(sys%gr%x(1, ip), real64), 0.02_real64, real64)
1146 end do
1147
1148 do itime = 1, param%repetitions
1149 call batch_mul_mf(sys%gr%np, zff_mf, xx, yy)
1150 end do
1151 end if
1152
1153 call test_prints_info_batch(sys%st, sys%gr, yy, string="mul_mf")
1154
1155
1156 safe_deallocate_a(dff_mf)
1157 safe_deallocate_a(zff_mf)
1158
1159 call xx%end()
1160 call yy%end()
1161 end if
1162
1163 if (bitand(ops, option__testbatchops__ops_nrm2) /= 0) then
1164 message(1) = 'Info: Testing nrm2'
1165 call messages_info(1, namespace=sys%namespace)
1166
1167 call sys%st%group%psib(1, 1)%copy_to(xx, copy_data = .true.)
1168 call sys%st%group%psib(1, 1)%copy_to(yy, copy_data = .true.)
1169
1170 safe_allocate(tmp(1:xx%nst))
1171
1172 do itime = 1, param%repetitions
1173 call mesh_batch_nrm2(sys%gr, yy, tmp)
1174 end do
1175 do itime = 1, xx%nst
1176 write(message(1),'(a,i1,3x,e23.16)') "Nrm2 norm state ", itime, tmp(itime)
1177 call messages_info(1, namespace=sys%namespace)
1178 end do
1179
1180 safe_deallocate_a(tmp)
1181
1182 call xx%end()
1183 call yy%end()
1184 end if
1185
1186 if (bitand(ops, option__testbatchops__ops_dotp_matrix) /= 0) then
1187
1188 message(1) = 'Info: Testing dotp_matrix'
1189 call messages_info(1, namespace=sys%namespace)
1190
1191 call sys%st%group%psib(1, 1)%copy_to(xx, copy_data = .true.)
1192 call sys%st%group%psib(1, 1)%copy_to(yy, copy_data = .true.)
1193
1194 nst = sys%st%group%psib(1, 1)%nst
1195
1196 if (states_are_real(sys%st)) then
1197 safe_allocate(ddot(1:nst, 1:nst))
1198 do itime = 1, param%repetitions
1199 call dmesh_batch_dotp_matrix(sys%gr, xx, yy, ddot)
1200 end do
1201
1202 do ist = 1, nst
1203 do jst = 1, nst
1204 write(message(jst), '(a,2i3,3x,e23.16)') 'Dotp_matrix states', ist, jst, ddot(ist,jst)
1205 end do
1206 call messages_info(nst, namespace=sys%namespace)
1207 end do
1208 safe_deallocate_a(ddot)
1209 else
1210 safe_allocate(zdot(1:nst, 1:nst))
1211 do itime = 1, param%repetitions
1212 call zmesh_batch_dotp_matrix(sys%gr, xx, yy, zdot)
1213 end do
1214
1215 do ist = 1, nst
1216 do jst = 1, nst
1217 write(message(jst), '(a,2i3,3x,2(e23.16,1x))') 'Dotp_matrix states', ist, jst, zdot(ist,jst)
1218 end do
1219 call messages_info(nst, namespace=sys%namespace)
1220 end do
1221 safe_deallocate_a(zdot)
1222 end if
1223
1224 call xx%end()
1225 call yy%end()
1226 end if
1227
1228 if (bitand(ops, option__testbatchops__ops_dotp_vector) /= 0) then
1229
1230 message(1) = 'Info: Testing dotp_vector'
1231 call messages_info(1, namespace=sys%namespace)
1232
1233 call sys%st%group%psib(1, 1)%copy_to(xx, copy_data = .true.)
1234 call sys%st%group%psib(1, 1)%copy_to(yy, copy_data = .true.)
1235
1236 nst = sys%st%group%psib(1, 1)%nst
1237
1238 if (states_are_real(sys%st)) then
1239 safe_allocate(ddotv(1:nst))
1240 do itime = 1, param%repetitions
1241 call dmesh_batch_dotp_vector(sys%gr, xx, yy, ddotv)
1242 end do
1243
1244 do ist = 1, nst
1245 write(message(ist), '(a,i3,3x,e23.16)') 'Dotp_vector state', ist, ddotv(ist)
1246 end do
1247 call messages_info(nst, namespace=sys%namespace)
1248 safe_deallocate_a(ddotv)
1249 else
1250 safe_allocate(zdotv(1:nst))
1251 do itime = 1, param%repetitions
1252 call zmesh_batch_dotp_vector(sys%gr, xx, yy, zdotv)
1253 end do
1254
1255 do ist = 1, nst
1256 write(message(ist), '(a,i3,3x,2(e23.16,1x))') 'Dotp_vector state', ist, zdotv(ist)
1257 end do
1258 call messages_info(nst, namespace=sys%namespace)
1259 safe_deallocate_a(zdotv)
1260 end if
1261
1262 call xx%end()
1263 call yy%end()
1264 end if
1265
1266 if (bitand(ops, option__testbatchops__ops_dotp_self) /= 0) then
1267
1268 message(1) = 'Info: Testing dotp_self'
1269 call messages_info(1, namespace=sys%namespace)
1270
1271 call sys%st%group%psib(1, 1)%copy_to(xx, copy_data = .true.)
1272
1273 nst = sys%st%group%psib(1, 1)%nst
1274
1275 if (states_are_real(sys%st)) then
1276 safe_allocate(ddot(1:nst, 1:nst))
1277 do itime = 1, param%repetitions
1278 call dmesh_batch_dotp_self(sys%gr, xx, ddot)
1279 end do
1280
1281 do ist = 1, nst
1282 do jst = 1, nst
1283 write(message(jst), '(a,2i3,3x,e23.16)') 'Dotp_self states', ist, jst, ddot(ist,jst)
1284 end do
1285 call messages_info(nst, namespace=sys%namespace)
1286 end do
1287 safe_deallocate_a(ddot)
1288 else
1289 safe_allocate(zdot(1:nst, 1:nst))
1290 do itime = 1, param%repetitions
1291 call zmesh_batch_dotp_self(sys%gr, xx, zdot)
1292 end do
1293
1294 do ist = 1, nst
1295 do jst = 1, nst
1296 write(message(jst), '(a,2i3,3x,2(e23.16,1x))') 'Dotp_self states', ist, jst, zdot(ist,jst)
1297 end do
1298 call messages_info(nst, namespace=sys%namespace)
1299 end do
1300 safe_deallocate_a(zdot)
1301 end if
1302
1303 call xx%end()
1304 end if
1305
1306 if (bitand(ops, option__testbatchops__ops_ax_function_py) /= 0) then
1307 message(1) = 'Info: Testing ax_function_py'
1308 call messages_info(1, namespace=sys%namespace)
1309
1310 call sys%st%group%psib(1, 1)%copy_to(yy, copy_data = .true.)
1311
1312 if (states_are_real(sys%st)) then
1313 safe_allocate(df(sys%gr%np, sys%st%d%dim))
1314 safe_allocate(dweight(1:sys%st%group%psib(1, 1)%nst_linear))
1315 dweight = 0.1_real64
1316 call batch_get_state(sys%st%group%psib(1, 1), 1, sys%gr%np, df)
1317
1318 do itime = 1, param%repetitions
1319 call dbatch_ax_function_py(sys%gr%np, dweight, df, yy)
1320 end do
1321 safe_deallocate_a(df)
1322 safe_deallocate_a(dweight)
1323 else
1324 safe_allocate(zf(sys%gr%np, sys%st%d%dim))
1325 safe_allocate(zweight(1:sys%st%group%psib(1, 1)%nst_linear))
1326 zweight = cmplx(0.1_real64, m_zero, real64)
1327 call batch_get_state(sys%st%group%psib(1, 1), 1, sys%gr%np, zf)
1328
1329 do itime = 1, param%repetitions
1330 call zbatch_ax_function_py(sys%gr%np, zweight, zf, yy)
1331 end do
1332 safe_deallocate_a(zf)
1333 end if
1334 call test_prints_info_batch(sys%st, sys%gr, yy, string = "ax_function_py")
1335
1336 call yy%end()
1337 end if
1338
1339 if (bitand(ops, option__testbatchops__ops_get_points) /= 0) then
1340 ! The blocking over grid points mimics the actual use in the code
1341
1342 if (.not. accel_is_enabled()) then
1343
1344 call sys%st%group%psib(1, 1)%copy_to(yy)
1345
1346 if (states_are_real(sys%st)) then
1347
1348 block_size = max(40, cpu_hardware%l2%size/(2 * sizeof_real64 * sys%st%nst))
1349
1350 safe_allocate(dpoints(1:sys%st%nst, 1:sys%st%d%dim, 1:block_size))
1351
1352 do itime = 1, param%repetitions
1353 do sp = 1, sys%gr%np, block_size
1354 size = min(block_size, sys%gr%np - sp + 1)
1355 call batch_get_points(sys%st%group%psib(1, 1), sp, sp + size - 1, dpoints)
1356 call batch_set_points(yy, sp, sp + size - 1, dpoints)
1357 end do
1358 end do
1359 safe_deallocate_a(dpoints)
1360
1361 else
1362
1363 block_size = max(20, cpu_hardware%l2%size/(2 * sizeof_complex64 * sys%st%nst))
1364
1365 safe_allocate(zpoints(1:sys%st%nst, 1:sys%st%d%dim, 1:block_size))
1366
1367 do itime = 1, param%repetitions
1368 do sp = 1, sys%gr%np, block_size
1369 size = min(block_size, sys%gr%np - sp + 1)
1370 call batch_get_points(sys%st%group%psib(1, 1), sp, sp + size - 1, zpoints)
1371 call batch_set_points(yy, sp, sp + size - 1, zpoints)
1372 end do
1373 end do
1374 safe_deallocate_a(dpoints)
1375
1376 end if
1377
1378 call test_prints_info_batch(sys%st, sys%gr, yy, string = "get_points")
1379
1380 call yy%end()
1381 end if
1382 end if
1383
1384 call states_elec_deallocate_wfns(sys%st)
1385 safe_deallocate_p(sys)
1386
1387 pop_sub(test_batch_ops)
1388 end subroutine test_batch_ops
1389
1390! ---------------------------------------------------------
1391 subroutine test_derivatives(param, namespace)
1392 type(test_parameters_t), intent(in) :: param
1393 type(namespace_t), intent(in) :: namespace
1394
1395 type(electrons_t), pointer :: sys
1396
1397 push_sub(test_derivatives)
1398
1399 sys => electrons_t(namespace, int(option__calculationmode__dummy, int32))
1400 call sys%init_parallelization(mpi_world)
1401
1402 message(1) = 'Info: Testing the finite-differences derivatives.'
1403 message(2) = ''
1404 call messages_info(2, namespace=namespace)
1405
1406 if (param%type == option__testtype__all .or. param%type == option__testtype__real) then
1407 call dderivatives_test(sys%gr%der, sys%namespace, param%repetitions, param%min_blocksize, param%max_blocksize)
1408 end if
1409
1410 if (param%type == option__testtype__all .or. param%type == option__testtype__complex) then
1411 call zderivatives_test(sys%gr%der, sys%namespace, param%repetitions, param%min_blocksize, param%max_blocksize)
1412 end if
1413
1414 if (sys%space%dim > 1) then
1415 call derivatives_advanced_benchmark(sys%gr%der, sys%namespace)
1416 end if
1417
1418 safe_deallocate_p(sys)
1419
1420 pop_sub(test_derivatives)
1421 end subroutine test_derivatives
1422
1423 ! ---------------------------------------------------------
1424
1425 subroutine test_orthogonalization(param, namespace)
1426 type(test_parameters_t), intent(in) :: param
1427 type(namespace_t), intent(in) :: namespace
1428
1429 type(electrons_t), pointer :: sys
1430 integer :: itime
1431
1432 push_sub(test_orthogonalization)
1433
1434 call calc_mode_par%set_parallelization(p_strategy_states, default = .false.)
1435 call calc_mode_par%set_scalapack_compat()
1436
1437 sys => electrons_t(namespace, int(option__calculationmode__dummy, int32))
1438 call sys%init_parallelization(mpi_world)
1439
1440 message(1) = 'Info: Testing orthogonalization.'
1441 message(2) = ''
1442 call messages_info(2, namespace=namespace)
1443
1444 if (param%type == option__testtype__all .or. param%type == option__testtype__real) then
1445 message(1) = 'Info: Real wave-functions.'
1446 call messages_info(1, namespace=namespace)
1447 do itime = 1, param%repetitions
1448 call dstates_elec_calc_orth_test(sys%st, sys%namespace, sys%gr, sys%kpoints)
1449 end do
1450 end if
1451
1452 if (param%type == option__testtype__all .or. param%type == option__testtype__complex) then
1453 message(1) = 'Info: Complex wave-functions.'
1454 call messages_info(1, namespace=namespace)
1455 do itime = 1, param%repetitions
1456 call zstates_elec_calc_orth_test(sys%st, sys%namespace, sys%gr, sys%kpoints)
1457 end do
1458 end if
1459
1460 safe_deallocate_p(sys)
1461
1462 pop_sub(test_orthogonalization)
1463 end subroutine test_orthogonalization
1464
1465 ! ---------------------------------------------------------
1466
1467 subroutine test_interpolation(param, namespace)
1468 type(test_parameters_t), intent(in) :: param
1469 type(namespace_t), intent(in) :: namespace
1470
1471 type(electrons_t), pointer :: sys
1472
1473 push_sub(test_interpolation)
1474
1475 sys => electrons_t(namespace, int(option__calculationmode__dummy, int32))
1476 call sys%init_parallelization(mpi_world)
1477
1478 if (param%type == option__testtype__all .or. param%type == option__testtype__real) then
1479 call messages_write('Info: Testing real interpolation routines')
1480 call messages_new_line()
1481 call messages_new_line()
1482 call messages_info(namespace=namespace)
1483
1484 call dmesh_interpolation_test(sys%gr)
1485 end if
1487 if (param%type == option__testtype__all .or. param%type == option__testtype__complex) then
1488 call messages_new_line()
1489 call messages_write('Info: Testing complex interpolation routines')
1490 call messages_new_line()
1491 call messages_new_line()
1492 call messages_info(namespace=namespace)
1493
1494 call zmesh_interpolation_test(sys%gr)
1495 end if
1496
1497 safe_deallocate_p(sys)
1498
1499 pop_sub(test_interpolation)
1500 end subroutine test_interpolation
1501
1502
1503 ! ---------------------------------------------------------
1504
1505 subroutine test_ion_interaction(namespace)
1506 type(namespace_t), intent(in) :: namespace
1507
1508 type(electrons_t), pointer :: sys
1509
1510 push_sub(test_ion_interaction)
1511
1512 sys => electrons_t(namespace, int(option__calculationmode__dummy, int32))
1513 call sys%init_parallelization(mpi_world)
1514
1515 call ion_interaction_test(sys%space, sys%ions%latt, sys%ions%atom, sys%ions%natoms, sys%ions%pos, &
1516 sys%gr%box%bounding_box_l, namespace, sys%mc)
1517
1518 safe_deallocate_p(sys)
1519
1521 end subroutine test_ion_interaction
1522
1523 ! ---------------------------------------------------------
1524
1525 subroutine test_prints_info_batch(st, gr, psib, string)
1526 type(states_elec_t), intent(in) :: st
1527 type(grid_t), intent(in) :: gr
1528 class(batch_t), intent(inout) :: psib
1529 character(*), optional, intent(in) :: string
1530
1531 integer :: itime
1532 complex(real64), allocatable :: zpsi(:, :)
1533 real(real64), allocatable :: dpsi(:, :)
1534
1535 character(80) :: string_
1536
1537 string_ = optional_default(string, "")
1538
1539 push_sub(test_prints_info_batch)
1540
1541 if (states_are_real(st)) then
1542 safe_allocate(dpsi(1:gr%np, 1:st%d%dim))
1543 else
1544 safe_allocate(zpsi(1:gr%np, 1:st%d%dim))
1545 end if
1546
1547 do itime = 1, psib%nst
1548 if (states_are_real(st)) then
1549 call batch_get_state(psib, itime, gr%np, dpsi)
1550 write(message(1),'(a,i2,3x,e23.16)') "Norm state "//trim(string_)//" ", itime, dmf_nrm2(gr, st%d%dim, dpsi)
1551 else
1552 call batch_get_state(psib, itime, gr%np, zpsi)
1553 write(message(1),'(a,i2,3x,e23.16)') "Norm state "//trim(string_)//" ", itime, zmf_nrm2(gr, st%d%dim, zpsi)
1554 end if
1555 call messages_info(1)
1556 end do
1557
1558 if (states_are_real(st)) then
1559 safe_deallocate_a(dpsi)
1560 else
1561 safe_deallocate_a(zpsi)
1562 end if
1563
1564 pop_sub(test_prints_info_batch)
1565
1566 end subroutine test_prints_info_batch
1567
1568
1569 ! ---------------------------------------------------------
1570 subroutine test_clock()
1571
1572 type(iteration_counter_t) :: clock, other_clock
1573
1574 push_sub(test_clock)
1575
1576 ! Clock operations
1577 write(message(1),'(a)') " Operation Counter Time Global step"
1578 call messages_info(1)
1579
1580 clock = clock_t(time_step=m_two, initial_iteration=2)
1581 call write_clock("initialization")
1582
1583 clock = clock + 5
1584 call write_clock("addition (+5)")
1585
1586 clock = clock - 3
1587 call write_clock("subtraction (-3)")
1588
1589 call clock%reset()
1590 call write_clock("reset (=0)")
1591
1592 call clock%set(clock_t(time_step=m_four, initial_iteration=1))
1593 call write_clock("set (=2)")
1594
1595 ! Clock comparisons:
1596 write(message(1),'(a)') " Clock comparisons:"
1597 call messages_info(1)
1598
1599 other_clock = clock_t(time_step=m_one, initial_iteration=5)
1601 call write_condition_result("4 < 5", clock < other_clock)
1602 call write_condition_result("4 <= 5", clock <= other_clock)
1603 call write_condition_result("4 > 5", clock > other_clock)
1604 call write_condition_result("4 >= 5", clock >= other_clock)
1605 call write_condition_result("4 == 5", clock == other_clock)
1606 call write_condition_result("4 /= 5", clock /= other_clock)
1607
1608 pop_sub(test_clock)
1609 contains
1610 subroutine write_clock(operation)
1611 character(len=*), intent(in) :: operation
1612
1613 write(message(1),'(a17,1x,i6,1x,f10.1,1x,i16)') operation, clock%counter(), clock%value(), clock%global_step()
1614 call messages_info(1)
1615 end subroutine write_clock
1616
1617 subroutine write_condition_result(condition, result)
1618 character(len=*), intent(in) :: condition
1619 logical, intent(in) :: result
1621 write(message(1),'(a10," = ",i1," (",l1,")")') condition, abs(transfer(result, 0)), result
1622 call messages_info(1)
1623 end subroutine write_condition_result
1624
1625 end subroutine test_clock
1626
1627
1628 ! ---------------------------------------------------------
1629 subroutine test_cgal()
1630
1631 type(cgal_polyhedra_t) :: cgal_poly
1632
1633 push_sub(test_cgal)
1634
1635 call cgal_polyhedron_init(cgal_poly, "28-cgal.02-X.off", verbose = .true.)
1636
1637 if (cgal_polyhedron_point_inside(cgal_poly, 30._real64, 10._real64, 30._real64)) then
1638 message(1) = "cgal_polyhedron_point_inside"
1639 call messages_info(1)
1640 end if
1641
1642 call cgal_polyhedron_end(cgal_poly)
1643
1644 pop_sub(test_cgal)
1645 end subroutine test_cgal
1646
1647
1648 ! ---------------------------------------------------------
1649 subroutine test_dense_eigensolver()
1650 integer :: N, ii, jj, N_list(4), i_N
1651 real(real64), allocatable :: matrix(:, :), eigenvectors(:, :), eigenvalues(:), test(:)
1652 real(real64), allocatable :: differences(:)
1653
1654 push_sub(test_dense_eigensolver)
1655
1656 n_list = [15, 32, 100, 500]
1657
1658 do i_n = 1, 4
1659 n = n_list(i_n)
1660 safe_allocate(matrix(1:n, 1:n))
1661 safe_allocate(eigenvectors(1:n, 1:n))
1662 safe_allocate(eigenvalues(1:n))
1663 safe_allocate(test(1:n))
1664 safe_allocate(differences(1:n))
1666
1667 ! set up symmetrix matrix
1668 do jj = 1, n
1669 do ii = 1, n
1670 matrix(ii, jj) = ii * jj
1671 end do
1672 end do
1673
1674 ! parallel solver
1675 eigenvectors(1:n, 1:n) = matrix(1:n, 1:n)
1676 call lalg_eigensolve_parallel(n, eigenvectors, eigenvalues)
1677
1678 do ii = 1, n
1679 test(:) = matmul(matrix, eigenvectors(:, ii)) - eigenvalues(ii) * eigenvectors(:, ii)
1680 differences(ii) = sum(abs(test)) / sum(abs(eigenvectors(:, ii)))
1681 end do
1682 write(message(1), "(A, I3, A, E13.6)") "Parallel solver - N: ", n, &
1683 ", average difference: ", sum(differences)/n
1684 call messages_info(1)
1685
1686 ! serial solver
1687 eigenvectors(1:n, 1:n) = matrix(1:n, 1:n)
1688 call lalg_eigensolve(n, eigenvectors, eigenvalues)
1689
1690 do ii = 1, n
1691 test(:) = matmul(matrix, eigenvectors(:, ii)) - eigenvalues(ii) * eigenvectors(:, ii)
1692 differences(ii) = sum(abs(test)) / sum(abs(eigenvectors(:, ii)))
1693 end do
1694 write(message(1), "(A, I3, A, E13.6)") "Serial solver - N: ", n, &
1695 ", average difference: ", sum(differences)/n
1696 call messages_info(1)
1697
1698 safe_deallocate_a(matrix)
1699 safe_deallocate_a(eigenvectors)
1700 safe_deallocate_a(eigenvalues)
1701 safe_deallocate_a(test)
1702 safe_deallocate_a(differences)
1703 end do
1704
1706 end subroutine test_dense_eigensolver
1707
1708 subroutine test_batch_set_gaussian(psib, mesh)
1709 class(batch_t), intent(inout) :: psib
1710 class(mesh_t), intent(in) :: mesh
1711
1712 real(real64), allocatable :: dff(:)
1713 complex(real64), allocatable :: zff(:)
1714 integer :: ist, ip
1715 real(real64) :: da, db, dc
1716 complex(real64) :: za, zb, zc
1717
1718 push_sub(test_batch_set_gaussian)
1719
1720 ! use a similar function as in the derivatives test
1721 da = m_one/mesh%box%bounding_box_l(1)
1722 db = 10.0_real64
1723 dc = 100.0_real64
1725 if (type_is_complex(psib%type())) then
1726 ! we make things more "complex"
1727 za = da + m_zi*0.01_real64
1728 zb = db*exp(m_zi*0.345_real64)
1729 zc = dc - m_zi*50.0_real64
1730
1731 safe_allocate(zff(1:mesh%np))
1732 do ist = 1, psib%nst_linear
1733 za = za * ist
1734 zb = zb / ist
1735 do ip = 1, mesh%np
1736 zff(ip) = zb*exp(-za*sum(mesh%x(:, ip)**2)) + zc
1737 end do
1738 call batch_set_state(psib, ist, mesh%np, zff)
1739 end do
1740 call zmesh_batch_normalize(mesh, psib)
1741 safe_deallocate_a(zff)
1742 else
1743 safe_allocate(dff(1:mesh%np))
1744 do ist = 1, psib%nst_linear
1745 da = da * ist
1746 db = db / ist
1747 do ip = 1, mesh%np
1748 dff(ip) = db*exp(-da*sum(mesh%x(:, ip)**2)) + dc
1749 end do
1750 call batch_set_state(psib, ist, mesh%np, dff)
1751 end do
1752 call dmesh_batch_normalize(mesh, psib)
1753 safe_deallocate_a(dff)
1754 end if
1755
1757 end subroutine test_batch_set_gaussian
1758
1759 ! ---------------------------------------------------------
1760 subroutine test_grid_interpolation()
1761 type(electrons_t), pointer :: sys
1762 type(multigrid_t) :: mgrid
1763
1764 push_sub(test_grid_interpolation)
1765
1766 sys => electrons_t(global_namespace, int(option__calculationmode__dummy, int32))
1767 call sys%init_parallelization(mpi_world)
1768
1769 call multigrid_init(mgrid, global_namespace, sys%space, sys%gr, sys%gr%der, &
1770 sys%gr%stencil, sys%mc, nlevels=3)
1771
1772 call multigrid_test_interpolation(mgrid, sys%space)
1773
1774 call multigrid_end(mgrid)
1775
1776 safe_deallocate_p(sys)
1777
1779 end subroutine test_grid_interpolation
1780
1781 subroutine test_iihash()
1782
1783 type(iihash_t) :: h
1784 integer :: value
1785 logical :: found
1786
1787 call iihash_init(h)
1788 call iihash_insert(h, 1,5)
1789 call iihash_insert(h, 3,7)
1790
1791 value = iihash_lookup(h, 1, found)
1792 write(message(1),*) 'hash[1] :', found, value
1793 call messages_info()
1794
1795 value = iihash_lookup(h, 2, found)
1796 write(message(1),*) 'hash[2] :', found, value
1797 call messages_info()
1798
1799 value = iihash_lookup(h, 3, found)
1800 write(message(1),*) 'hash[3] :', found, value
1801 call messages_info()
1802
1804
1805 end subroutine test_iihash
1806
1807 subroutine test_sihash()
1808 type(sihash_t) :: h
1809 type(sihash_iterator_t) :: it
1810
1811 integer :: counter
1812 integer :: value, sum
1813 logical :: found
1814
1815 call sihash_init(h)
1816 call sihash_insert(h, "one",5)
1817 call sihash_insert(h, "three",7)
1818 call sihash_insert(h, "the answer", 42)
1819
1820 value = sihash_lookup(h, "one", found)
1821 write(message(1),*) 'hash["one"]: ', found, value
1822 call messages_info()
1823
1824 value = sihash_lookup(h, "two", found)
1825 write(message(1),*) 'hash["two"]: ', found, value
1826 call messages_info()
1827
1828 value = sihash_lookup(h, "three", found)
1829 write(message(1),*) 'hash["three"]: ', found, value
1830 call messages_info()
1831
1832 sum = 0
1833 counter = 1
1834 call it%start(h)
1835
1836 do while (it%has_next())
1837 value = it%get_next()
1838 sum = sum + value
1839 write(message(1),'(I3,A,I5)') counter,': hash[...] = ',value
1840 call messages_info()
1841 counter = counter + 1
1842 end do
1843 write(message(1),*) 'counter = ', counter
1844 write(message(2),*) 'sum = ', sum
1845 call messages_info(2)
1846
1847
1848 call sihash_end(h)
1849
1850 end subroutine test_sihash
1851
1852
1853 subroutine test_sphash(namespace)
1854 type(namespace_t), intent(in) :: namespace
1856 type(sphash_t) :: h
1857 type(sphash_iterator_t) :: it
1858
1859 logical :: found
1860
1861
1862 type(iteration_counter_t) :: clock_1
1863 type(iteration_counter_t), allocatable :: clock_2
1864 type(space_t) :: space_1
1865
1866 class(*), pointer :: value
1867
1868 integer :: count_clock, count_space
1869
1870 safe_allocate(clock_2)
1871
1872 clock_1 = clock_t(1.d-5, 1)
1873 clock_2 = clock_t(2.d-5, 2)
1874 space_1 = space_t(namespace)
1875
1877 call sphash_insert(h, "one", clock_1)
1878 call sphash_insert(h, "two", space_1)
1879 call sphash_insert(h, "three", clock_2, clone=.true.)
1880
1881 value => sphash_lookup(h, "one", found)
1882 select type(value)
1883 type is (iteration_counter_t)
1884 write(message(1),*) 'hash["one"]: ', found, value%counter()
1885 call messages_info()
1886 type is (space_t)
1887 write(message(1),*) 'hash["one"]: ', found, value%short_info()
1888 call messages_info()
1889 class default
1890 write(message(1),*) 'wrong type. found = ', found
1891 call messages_info()
1892 end select
1893
1894 value => sphash_lookup(h, "two", found)
1895 select type(value)
1896 type is (iteration_counter_t)
1897 write(message(1),*) 'hash["two"]: ', found, value%counter()
1898 call messages_info()
1899 type is (space_t)
1900 write(message(1),*) 'hash["two"]: ', found, value%short_info()
1901 call messages_info()
1902 class default
1903 write(message(1),*) 'wrong type. found = ',found
1904 call messages_info()
1905 end select
1906
1907 safe_deallocate_a(clock_2)
1908
1909 value => sphash_lookup(h, "three", found)
1910 select type(value)
1911 type is (iteration_counter_t)
1912 write(message(1),*) 'hash["three"]: ', found, value%counter()
1913 call messages_info()
1914 type is (space_t)
1915 write(message(1),*) 'hash["three"]: ', found, value%short_info()
1916 call messages_info()
1917 class default
1918 write(message(1),*) 'wrong type. found = ',found
1919 call messages_info()
1920 end select
1921
1922 count_clock = 0
1923 count_space = 0
1924
1925 call it%start(h)
1926
1927 do while (it%has_next())
1928 value => it%get_next()
1929 select type(value)
1930 type is (iteration_counter_t)
1931 count_clock = count_clock + 1
1932 type is (space_t)
1933 count_space = count_space + 1
1934 end select
1935 end do
1936
1937 write(message(1), *) 'Count_clock = ', count_clock
1938 write(message(2), *) 'Count_space = ', count_space
1939 call messages_info(2)
1940
1941 call sphash_end(h)
1942
1943 end subroutine test_sphash
1944
1945 ! ---------------------------------------------------------
1946 subroutine test_regridding(namespace)
1947 type(namespace_t), intent(in) :: namespace
1949 type(electrons_t), pointer :: sysA, sysB
1950 type(regridding_t), pointer :: regridding
1951 real(real64), allocatable :: ff_A(:), ff_A_reference(:), ff_B(:), ff_B_reference(:), diff_A(:), diff_B(:)
1952 real(real64) :: norm_ff, norm_diff
1953 integer :: ip, ierr
1954
1955 push_sub(test_regridding)
1956
1957 sysa => electrons_t(namespace_t("A", namespace), int(option__calculationmode__dummy, int32))
1958 sysb => electrons_t(namespace_t("B", namespace), int(option__calculationmode__dummy, int32))
1959
1960 call calc_mode_par%set_parallelization(p_strategy_states, default=.true.)
1961 call sysa%init_parallelization(mpi_world)
1962 call sysb%init_parallelization(mpi_world)
1963
1964
1965 safe_allocate(ff_a(1:sysa%gr%np))
1966 safe_allocate(ff_a_reference(1:sysa%gr%np))
1967 safe_allocate(diff_a(1:sysa%gr%np))
1968 safe_allocate(ff_b(1:sysb%gr%np))
1969 safe_allocate(ff_b_reference(1:sysb%gr%np))
1970 safe_allocate(diff_b(1:sysb%gr%np))
1971
1972 do ip = 1, sysa%gr%np
1973 ff_a_reference(ip) = values(sysa%gr%x(:, ip))
1974 end do
1975 do ip = 1, sysb%gr%np
1976 ff_b_reference(ip) = values(sysb%gr%x(:, ip))
1977 end do
1978
1979 ! forward mapping A->B
1980 regridding => regridding_t(sysb%gr, sysa%gr, sysa%space, sysa%namespace)
1981 call regridding%do_transfer(ff_b, ff_a_reference)
1982 safe_deallocate_p(regridding)
1983
1984 ! check that mapped function is exactly the same for the points that are available on both grids
1985 do ip = 1, sysb%gr%np
1986 if (abs(ff_b(ip)) <= m_epsilon) then
1987 ff_b_reference(ip) = m_zero
1988 diff_b(ip) = m_zero
1989 else
1990 diff_b(ip) = abs(ff_b_reference(ip) - ff_b(ip))
1991 end if
1992 end do
1993 norm_ff = dmf_nrm2(sysb%gr, ff_b_reference)
1994 norm_diff = dmf_nrm2(sysb%gr, diff_b)
1995
1996 write(message(1),'(a, E14.6)') "Forward: difference of reference to mapped function (rel.): ", &
1997 norm_diff/norm_ff
1998 call messages_info(1, namespace=namespace)
1999
2000 call dio_function_output(io_function_fill_how('AxisX'), ".", "forward_reference", namespace, sysb%space, &
2001 sysb%gr, ff_b_reference, unit_one, ierr)
2002 call dio_function_output(io_function_fill_how('AxisX'), ".", "forward_mapped", namespace, sysb%space, &
2003 sysb%gr, ff_b, unit_one, ierr)
2004 call dio_function_output(io_function_fill_how('AxisX'), ".", "forward_original", namespace, sysa%space, &
2005 sysa%gr, ff_a_reference, unit_one, ierr)
2006
2007 ! backward mapping B->A
2008 regridding => regridding_t(sysa%gr, sysb%gr, sysb%space, sysb%namespace)
2009 call regridding%do_transfer(ff_a, ff_b_reference)
2010 safe_deallocate_p(regridding)
2011
2012 do ip = 1, sysa%gr%np
2013 if (abs(ff_a(ip)) <= m_epsilon) then
2014 ff_a_reference(ip) = m_zero
2015 diff_a(ip) = m_zero
2016 else
2017 diff_a(ip) = abs(ff_a_reference(ip) - ff_a(ip))
2018 end if
2019 end do
2020 norm_ff = dmf_nrm2(sysa%gr, ff_a_reference)
2021 norm_diff = dmf_nrm2(sysa%gr, diff_a)
2022
2023 write(message(1),'(a, E14.6)') "Backward: difference of reference to mapped function (rel.): ", &
2024 norm_diff/norm_ff
2025 call messages_info(1, namespace=namespace)
2026
2027 call dio_function_output(io_function_fill_how('AxisX'), ".", "backward_reference", namespace, sysa%space, &
2028 sysa%gr, ff_a_reference, unit_one, ierr)
2029 call dio_function_output(io_function_fill_how('AxisX'), ".", "backward_mapped", namespace, sysa%space, &
2030 sysa%gr, ff_a, unit_one, ierr)
2031 call dio_function_output(io_function_fill_how('AxisX'), ".", "backward_original", namespace, sysb%space, &
2032 sysb%gr, ff_b_reference, unit_one, ierr)
2033
2034 safe_deallocate_a(ff_a)
2035 safe_deallocate_a(ff_a_reference)
2036 safe_deallocate_a(ff_b)
2037 safe_deallocate_a(ff_b_reference)
2038 safe_deallocate_a(diff_a)
2039 safe_deallocate_a(diff_b)
2040 safe_deallocate_p(sysa)
2041 safe_deallocate_p(sysb)
2042
2043 call messages_info(1, namespace=namespace)
2044
2045 pop_sub(test_regridding)
2046 contains
2047 real(real64) function values(xx)
2048 real(real64), intent(in) :: xx(:)
2049 real(real64) :: xx0(1:size(xx, dim=1))
2050 real(real64), parameter :: aa = m_half
2051 real(real64), parameter :: bb = m_four
2052
2053 ! no push_sub/pop_sub because this function is called often
2054 xx0(:) = m_one
2055 values = bb * exp(-aa*sum((xx-xx0)**2))
2056 end function values
2057 end subroutine test_regridding
2058
2064 subroutine test_vecpot_analytical(namespace)
2065 type(namespace_t), intent(in) :: namespace
2066
2067 class(maxwell_t), pointer :: maxwell_system
2068
2069 real(real64), allocatable :: magnetic_field(:,:)
2070 real(real64), allocatable :: vector_potential_mag(:,:)
2071 real(real64), allocatable :: vector_potential_analytical(:,:)
2072 real(real64), allocatable :: delta(:,:)
2073 real(real64) :: exp_factor
2074 real(real64) :: xx
2075 real(real64) :: yy
2076 real(real64) :: zz
2077 real(real64) :: sigma
2078 integer :: ip, j, ierr, nn
2079 integer(int64) :: out_how
2080 character(len=MAX_PATH_LEN) :: fname, fname2, fname3
2081
2082 out_how = 32
2083 maxwell_system => maxwell_t(namespace)
2084 sigma = maxwell_system%gr%box%bounding_box_l(1)/10_real64 ! this is exponential width
2085 call maxwell_system%init_parallelization(mpi_world)
2086
2087 safe_allocate(magnetic_field(1:maxwell_system%gr%np_part, 1:3))
2088 safe_allocate(vector_potential_mag(1:maxwell_system%gr%np_part, 1:3))
2089 safe_allocate(vector_potential_analytical(1:maxwell_system%gr%np_part, 1:3))
2090 safe_allocate(delta(1:maxwell_system%gr%np, 1:3))
2091
2092 !%Variable TestVectorPotentialType
2093 !%Type integer
2094 !%Default bounded
2095 !%Section Calculation Modes::Test
2096 !%Description
2097 !% Select whether bounded or unbounded type will be used for vector potential tests
2098 !%Option bounded 1
2099 !% Analytical Vector Potential formulation is bounded by spatial gaussian
2100 !%Option unbounded 2
2101 !% Analytical Vector Potential is not bounded
2102 !%End
2103 call parse_variable(namespace, 'TestVectorPotentialType', option__testvectorpotentialtype__bounded, nn)
2104
2105 select case (nn)
2106 case (option__testvectorpotentialtype__bounded) ! bounded input
2107 do ip = 1, maxwell_system%gr%np_part
2108 xx = maxwell_system%gr%x(1, ip)
2109 yy = maxwell_system%gr%x(2, ip)
2110 zz = maxwell_system%gr%x(3, ip)
2111 exp_factor = exp((-xx**2 - yy**2 - zz**2)*1/(2*sigma**2))
2112 magnetic_field(ip, 1) = exp_factor*yy*(1 - (-xx**2 + yy**2)/(3*sigma**2) - zz**2/(3*sigma**2))
2113 magnetic_field(ip, 2) = exp_factor * xx * (1 + (-xx**2 + yy**2)/(3*sigma**2) - zz**2/(3*sigma**2))
2114 magnetic_field(ip, 3) = exp_factor * 2 * xx * yy * zz * 1/(3*sigma**2)
2115
2116 vector_potential_analytical(ip, 1) = m_third * xx * zz * exp_factor
2117 vector_potential_analytical(ip, 2) = - m_third * yy * zz * exp_factor
2118 vector_potential_analytical(ip, 3) = m_third * (-xx**2 + yy**2) * exp_factor
2119 end do
2120 case (option__testvectorpotentialtype__unbounded) ! unbounded input,
2121 ! TODO this unit test requires implementation of BCs for Helmholtz decomposition
2122 do ip = 1, maxwell_system%gr%np_part
2123 magnetic_field(ip, 1) = maxwell_system%gr%x(2, ip)
2124 magnetic_field(ip, 2) = maxwell_system%gr%x(1, ip)
2125 magnetic_field(ip, 3) = m_zero
2126
2127 vector_potential_analytical(ip, 1) = m_third * maxwell_system%gr%x(1, ip) * maxwell_system%gr%x(3, ip)
2128 vector_potential_analytical(ip, 2) = - m_third * maxwell_system%gr%x(2, ip) * maxwell_system%gr%x(3, ip)
2129 vector_potential_analytical(ip, 3) = - m_third * (maxwell_system%gr%x(1, ip)**2 - maxwell_system%gr%x(2, ip)**2)
2130 end do
2131 end select
2132 call maxwell_system%helmholtz%get_vector_potential(namespace, vector_potential_mag, magnetic_field)
2133
2134 do j = 1, 3
2135 delta(:,:) = m_zero
2136 do ip = 1, maxwell_system%gr%np
2137 delta(ip,j) = vector_potential_analytical(ip, j) - vector_potential_mag(ip, j)
2138 end do
2139 end do
2140
2141 do j = 1, 3
2142 write(message(j),*) 'j, norm2(delta)', j, norm2(delta(:,j))
2143 end do
2144 call messages_info(3)
2145
2146 write(fname, '(a)') 'deviation_from_analytical_formulation' ! use messages later
2147 call io_function_output_vector(out_how , './' , trim(fname), namespace, maxwell_system%space, maxwell_system%gr, &
2148 delta, unit_one, ierr)
2149 write(fname2, '(a)') 'vector_potential_analytical'
2150 call io_function_output_vector(out_how , './' , trim(fname2), namespace, maxwell_system%space, maxwell_system%gr, &
2151 vector_potential_analytical, unit_one, ierr)
2152 write(fname3, '(a)') 'vector_potential_mag'
2153 call io_function_output_vector(out_how , './' , trim(fname3), namespace, maxwell_system%space, maxwell_system%gr, &
2154 vector_potential_mag, unit_one, ierr)
2155
2156 safe_deallocate_a(magnetic_field)
2157 safe_deallocate_a(vector_potential_mag)
2158 safe_deallocate_a(vector_potential_analytical)
2159 safe_deallocate_a(delta)
2160 safe_deallocate_p(maxwell_system)
2161
2162 end subroutine test_vecpot_analytical
2163
2164 ! ---------------------------------------------------------
2165 subroutine multigrid_test_interpolation(mgrid, space)
2166 type(multigrid_t), intent(in) :: mgrid
2167 class(space_t), intent(in) :: space
2168
2169 real(real64), allocatable :: guess0(:), res0(:), guess1(:)
2170 type(mesh_t), pointer :: mesh0, mesh1
2171 real(real64) :: delta, xx(3,2), alpha, beta, rr
2172 integer :: nn, ip, ierr
2173
2175
2176 message(1) = 'Info: Testing the grid interpolation.'
2177 message(2) = ''
2178 call messages_info(2)
2179
2180 mesh0 => mgrid%level(0)%mesh
2181 mesh1 => mgrid%level(1)%mesh
2182
2183 safe_allocate(guess0(1:mesh0%np_part))
2184 safe_allocate(res0(1:mesh0%np_part))
2185 safe_allocate(guess1(1:mesh1%np_part))
2186
2187 alpha = m_four*mesh0%spacing(1)
2188 beta = m_one / (alpha**space%dim * sqrt(m_pi)**space%dim)
2189
2190 ! Set the centers of the Gaussians by hand
2191 xx(1, 1) = m_one
2192 xx(2, 1) = -m_half
2193 xx(3, 1) = m_two
2194 xx(1, 2) = -m_two
2195 xx(2, 2) = m_zero
2196 xx(3, 2) = -m_one
2197 xx = xx * alpha
2198
2199 ! Density as sum of Gaussians
2200 guess0 = m_zero
2201 do nn = 1, 2
2202 do ip = 1, mesh0%np
2203 call mesh_r(mesh0, ip, rr, origin = xx(:, nn))
2204 guess0(ip) = guess0(ip) + (-1)**nn * beta*exp(-(rr/alpha)**2)
2205 end do
2206 end do
2207
2208 call dio_function_output (io_function_fill_how('AxisX'), ".", "interpolation_target", global_namespace, &
2209 space, mesh0, guess0, unit_one, ierr)
2210 call dio_function_output (io_function_fill_how('AxisZ'), ".", "interpolation_target", global_namespace, &
2211 space, mesh0, guess0, unit_one, ierr)
2212 call dio_function_output (io_function_fill_how('PlaneZ'), ".", "interpolation_target", global_namespace, &
2213 space, mesh0, guess0, unit_one, ierr)
2214
2215 ! We start by testing the interpolation scheme. For this, we generate a function on the fine grid
2216 ! and we inject it on the coarse grid. Then we interpolate it back to the fine grid and we compare
2217 ! This allows for testing the quality of the interpolation scheme
2218
2219 ! move to level 1
2220 call dmultigrid_fine2coarse(mgrid%level(1)%tt, mgrid%level(0)%der, mesh1, guess0, guess1, injection)
2221 ! back to level 0
2222 call dmultigrid_coarse2fine(mgrid%level(1)%tt, mgrid%level(1)%der, mesh0, guess1, res0)
2223
2224 call dio_function_output (io_function_fill_how('AxisX'), ".", "interpolation_result", global_namespace, &
2225 space, mesh0, res0, unit_one, ierr)
2226 call dio_function_output (io_function_fill_how('AxisZ'), ".", "interpolation_result", global_namespace, &
2227 space, mesh0, res0, unit_one, ierr)
2228 call dio_function_output (io_function_fill_how('PlaneZ'), ".", "interpolation_result", global_namespace, &
2229 space, mesh0, res0, unit_one, ierr)
2230
2231 delta = dmf_nrm2(mesh0, guess0(1:mesh0%np)-res0(1:mesh0%np))
2232 write(message(1),'(a,e13.6)') 'Interpolation test (abs.) = ', delta
2233
2234 ! Now we test if the restriction+interpolation combination returns the original result or not
2235 ! This allows to test if restriction and interpolation are adjoint operators or not.
2236
2237 ! move to level 1
2238 call dmultigrid_fine2coarse(mgrid%level(1)%tt, mgrid%level(0)%der, mesh1, guess0, guess1, fullweight)
2239 ! back to level 0
2240 call dmultigrid_coarse2fine(mgrid%level(1)%tt, mgrid%level(1)%der, mesh0, guess1, res0)
2241
2242 call dio_function_output (io_function_fill_how('AxisX'), ".", "restriction_result", global_namespace, &
2243 space, mesh0, res0, unit_one, ierr)
2244 call dio_function_output (io_function_fill_how('AxisZ'), ".", "restriction_result", global_namespace, &
2245 space, mesh0, res0, unit_one, ierr)
2246 call dio_function_output (io_function_fill_how('PlaneZ'), ".", "restriction_result", global_namespace, &
2247 space, mesh0, res0, unit_one, ierr)
2248
2249 delta = dmf_nrm2(mesh0, guess0(1:mesh0%np)-res0(1:mesh0%np))
2250 write(message(2),'(a,e13.6)') 'Restriction test (abs.) = ', delta
2251 call messages_info(2)
2252
2253 safe_deallocate_a(guess0)
2254 safe_deallocate_a(res0)
2255 safe_deallocate_a(guess1)
2256
2258 end subroutine multigrid_test_interpolation
2259
2262 subroutine test_current_density(namespace)
2263 type(namespace_t), intent(in) :: namespace
2264 type(electrons_t), pointer :: sys
2265
2266 type(current_t) :: current
2267 character(len=MAX_PATH_LEN) :: fname
2268 integer :: ierr, ip, idir
2269 integer(int64) :: out_how
2270 real(real64), allocatable :: current_para_ref(:,:), current_dia_ref(:,:), current_mag_ref(:,:), delta(:)
2271 real(real64) :: xx(3), rr, a0, mag_curr, sin_thet, sin_phi, cos_phi, vec_pot_slope
2272 complex(real64) :: alpha
2273
2274 sys => electrons_t(namespace, int(option__calculationmode__dummy, int32))
2275 call sys%init_parallelization(mpi_world)
2276
2277 alpha = (0.0_real64, 0.5_real64)
2278 a0 = m_one
2279 vec_pot_slope = 0.4_real64 ! units of B field
2280
2281 call states_elec_allocate_wfns(sys%st, sys%gr, wfs_type = type_cmplx)
2282 call set_hydrogen_states(sys%st%group%psib(1, 1), sys%gr, namespace, alpha, a0)
2283
2284 call current_init(current, namespace)
2285
2286 call hamiltonian_elec_epot_generate(sys%hm, sys%namespace, sys%space, sys%gr, sys%ions, sys%ext_partners, sys%st)
2287
2288 safe_allocate(sys%hm%hm_base%vector_potential(1:3, 1:sys%gr%np))
2289
2290 sys%hm%hm_base%vector_potential = m_zero
2291 do ip = 1, sys%gr%np
2292 xx = sys%gr%x(1:3, ip)
2293 sys%hm%hm_base%vector_potential(2, ip) = vec_pot_slope * xx(1) / p_c ! vector potential is here devided by c_0
2294 end do
2295
2296 call states_elec_allocate_current(sys%st, sys%space, sys%gr)
2297 call density_calc(sys%st, sys%gr, sys%st%rho)
2298 ! paramagnetic + diamagnetic current densities
2299 call current_calculate(current, namespace, sys%gr, sys%hm, sys%space, sys%st)
2300
2301 safe_allocate(current_para_ref(1:sys%gr%np,1:3))
2302 safe_allocate(current_dia_ref(1:sys%gr%np,1:3))
2303 safe_allocate(current_mag_ref(1:sys%gr%np,1:3))
2304 safe_allocate(delta(1:sys%gr%np))
2305
2306 ! analytic paramagnetic
2307 current_para_ref(:,:) = m_zero
2308 do ip = 1, sys%gr%np
2309 call mesh_r(sys%gr, ip, rr)
2310 xx = sys%gr%x(1:3, ip)
2311 if (rr > r_small) then
2312 current_para_ref(ip,1:3) = - (psi_2s(rr, a0) * dr_psi_1s(rr, a0) - &
2313 psi_1s(rr, a0) * dr_psi_2s(rr, a0) ) * aimag(alpha) / (1 + abs(alpha)**2) * xx(1:3) / rr
2314 end if
2315 end do
2316
2317 write(fname, '(a)') 'current_para'
2318 out_how = io_function_fill_how("PlaneZ")
2319 call io_function_output_vector(out_how , './' , trim(fname), namespace, sys%space, sys%gr, &
2320 sys%st%current_para(:,:,1), unit_one, ierr)
2321
2322 write(fname, '(a)') 'current_para-ref'
2323 out_how = io_function_fill_how("PlaneZ")
2324 call io_function_output_vector(out_how , './' , trim(fname), namespace, sys%space, sys%gr, &
2325 current_para_ref(:,:), unit_one, ierr)
2326
2327 do idir = 1, 3
2328 delta = m_zero
2329 delta(:) = current_para_ref(1:sys%gr%np, idir) - sys%st%current_para(1:sys%gr%np, idir, 1)
2330 write(message(idir),*) 'idir =',idir,', norm2(delta paramagnetic)',norm2(delta)
2331 end do
2332 call messages_info(3)
2333
2334 ! analytic diamagnetic
2335 current_dia_ref(:,:) = m_zero
2336 do ip = 1, sys%gr%np
2337 call mesh_r(sys%gr, ip, rr)
2338 current_dia_ref(ip,1:3) = - sys%hm%hm_base%vector_potential(1:3,ip) *&
2339 m_one / (1 + abs(alpha)**2) * abs(lc_hydrogen_state(rr, alpha, a0))**2
2340 end do
2341
2342 write(fname, '(a)') 'current_dia'
2343 out_how = io_function_fill_how("PlaneZ")
2344 call io_function_output_vector(out_how , './' , trim(fname), namespace, sys%space, sys%gr, &
2345 sys%st%current_dia(:,:,1), unit_one, ierr)
2346
2347 write(fname, '(a)') 'current_dia-ref'
2348 out_how = io_function_fill_how("PlaneZ")
2349 call io_function_output_vector(out_how , './' , trim(fname), namespace, sys%space, sys%gr, &
2350 current_dia_ref(:,:), unit_one, ierr)
2351
2352 do idir = 1, 3
2353 delta = m_zero
2354 delta(:) = current_dia_ref(1:sys%gr%np, idir) - sys%st%current_dia(1:sys%gr%np, idir, 1)
2355 write(message(idir),*) 'idir =',idir,', norm2(delta diamagnetic)',norm2(delta)
2356 end do
2357 call messages_info(3)
2358
2359 ! magnetization current
2360 call current_calculate_mag(sys%gr%der, sys%st)
2361
2362 ! analytic magnetization
2363 current_mag_ref(:,:) = m_zero
2364 do ip = 1, sys%gr%np
2365 call mesh_r(sys%gr, ip, rr)
2366 xx = sys%gr%x(1:3, ip)
2367 if (norm2(xx(1:2)) > r_small .and. rr > r_small) then
2368 sin_thet = norm2(xx(1:2)) / rr
2369 sin_phi = xx(2) / norm2(xx(1:2))
2370 cos_phi = xx(1) / norm2(xx(1:2))
2371 mag_curr = m_two * (psi_1s(rr,a0)*dr_psi_1s(rr,a0) + real(alpha)*(psi_1s(rr,a0)*dr_psi_2s(rr,a0) &
2372 + dr_psi_1s(rr,a0)*psi_2s(rr,a0)) + abs(alpha)**2 * psi_2s(rr,a0)*dr_psi_2s(rr,a0))
2373 ! minus signs are reversed because of the charge of the electron
2374 current_mag_ref(ip,1) = m_half * mag_curr * sin_thet * sin_phi / (1+abs(alpha)**2)
2375 current_mag_ref(ip,2) = -m_half * mag_curr * sin_thet * cos_phi / (1+abs(alpha)**2)
2376 endif
2377 end do
2378
2379 write(fname, '(a)') 'current_mag'
2380 out_how = io_function_fill_how("PlaneZ")
2381 call io_function_output_vector(out_how , './' , trim(fname), namespace, sys%space, sys%gr, &
2382 sys%st%current_mag(:,:,1), unit_one, ierr)
2383
2384 write(fname, '(a)') 'current_mag-ref'
2385 out_how = io_function_fill_how("PlaneZ")
2386 call io_function_output_vector(out_how , './' , trim(fname), namespace, sys%space, sys%gr, &
2387 current_mag_ref(:,:), unit_one, ierr)
2388
2389 do idir = 1, 3
2390 delta = m_zero
2391 delta(:) = current_mag_ref(1:sys%gr%np, idir) - sys%st%current_mag(1:sys%gr%np, idir, 1)
2392 write(message(idir),*) 'idir =',idir,', norm2(delta magnetization)',norm2(delta)
2393 end do
2394 call messages_info(3)
2395
2396 safe_deallocate_a(current_para_ref)
2397 safe_deallocate_a(current_dia_ref)
2398 safe_deallocate_a(current_mag_ref)
2399 safe_deallocate_a(delta)
2400 safe_deallocate_p(sys)
2401
2402 end subroutine test_current_density
2403
2404
2405 subroutine set_hydrogen_states(psib, mesh, namespace, alpha, a0)
2406 class(batch_t), intent(inout) :: psib
2407 class(mesh_t), intent(in) :: mesh
2408 type(namespace_t), intent(in) :: namespace
2409 complex(real64), intent(in) :: alpha
2410 real(real64), intent(in) :: a0
2411
2412 complex(real64), allocatable :: zff(:)
2413 integer :: ip
2414 real(real64) :: rr
2415
2416 push_sub(set_hydrogen_states)
2417
2418 ! psi = phi_{1s} + \alpha \phi_{2s}
2419 safe_allocate(zff(1:mesh%np))
2420 if (type_is_complex(psib%type())) then
2421 do ip = 1, mesh%np
2422 call mesh_r(mesh, ip, rr)
2423 zff(ip) = m_one / sqrt(1 + abs(alpha)**2) * lc_hydrogen_state(rr, alpha, a0)
2424 call batch_set_state(psib, 1, mesh%np, zff)
2425 end do
2426 safe_deallocate_a(zff)
2427 else
2428 write(message(1),*) "States should be complex for the linear combination of hydrogenic states to work"
2429 call messages_info(1, namespace=namespace)
2430 end if
2431
2432 pop_sub(set_hydrogen_states)
2433 end subroutine set_hydrogen_states
2434
2435 complex(real64) function lc_hydrogen_state(rr, alpha, a0)
2436 real(real64), intent(in) :: a0, rr
2437 complex(real64), intent(in) :: alpha
2438
2439 lc_hydrogen_state = psi_1s(rr, a0) + alpha * psi_2s(rr, a0)
2440 end function lc_hydrogen_state
2441
2442 ! phi_{1s} = R_{10}(r)Y_{00}(\theta, \phi) = 1/(2\sqrt(\pi)) * 2 a0^{-3/2} * \exp(-r/a0)
2443 real(real64) function psi_1s(rr, a0)
2444 real(real64), intent(in) :: a0, rr
2445
2446 psi_1s = a0**(-m_three/m_two) * exp(-rr / a0) / sqrt(m_pi)
2447 end function psi_1s
2448
2449 ! phi_{2s} = R_{20}(r)Y_{00}(\theta, \phi) = 1/(2\sqrt(\pi)) * \sqrt(2) a0^{-3/2} (1 - r/(2a0)) \exp(-r/(2a0))
2450 real(real64) function psi_2s(rr, a0)
2451 real(real64), intent(in) :: a0, rr
2452
2453 psi_2s = sqrt(m_two) * a0**(-m_three/m_two) * (m_one - rr/(m_two * a0)) * exp(-rr/(m_two * a0)) &
2454 / (m_two * sqrt(m_pi))
2455 end function psi_2s
2456
2457 real(real64) function dr_psi_1s(rr, a0)
2458 real(real64), intent(in) :: a0, rr
2459
2460 dr_psi_1s = -(m_one / a0) * psi_1s(rr, a0)
2461 end function dr_psi_1s
2462
2463 real(real64) function dr_psi_2s(rr, a0)
2464 real(real64), intent(in) :: a0, rr
2465
2466 dr_psi_2s = -(m_half / a0) * psi_2s(rr, a0) - &
2467 a0**(-m_five/m_two) * exp(-rr/(m_two * a0)) / (sqrt(m_two) * m_two * sqrt(m_pi))
2468 end function dr_psi_2s
2469
2470
2471 subroutine test_csv_input(namespace)
2472 type(namespace_t), intent(in) :: namespace
2473
2474 integer :: ierr
2475 integer(int64) :: i, j, k
2476 integer(int64) :: dims(3)
2477 character(len=MAX_PATH_LEN) :: fname
2478
2479 real(real64), allocatable :: ff(:)
2480
2481 push_sub(test_csv_input)
2482
2483 !%Variable TestCSVFileName
2484 !%Type string
2485 !%Section Calculation Modes::Test
2486 !%Description
2487 !% The file name of the csv file to be read
2488 !%End
2489 call parse_variable(namespace, 'TestCSVFileName', "", fname)
2490
2491 message(1) = "Attempting to probe "//trim(fname)
2492 call messages_info(1, namespace=namespace)
2493
2494 call io_csv_get_info(fname, dims, ierr)
2495 if (ierr == 0) then
2496 message(1) = "Probing successful."
2497 write(message(2), '("found dimensions: ",3I20)') dims
2498 call messages_info(2, namespace=namespace)
2499 else
2500 write(message(1),'("Probing failed. ierr = ",I5)') ierr
2501 call messages_fatal(1, namespace=namespace)
2502 end if
2503
2504 safe_allocate(ff(1:dims(1)*dims(2)*dims(3)))
2505
2506 message(1) = "Attempting to read "//trim(fname)
2507 call messages_info(1, namespace=namespace)
2508
2509 call dread_csv(fname, dims(1)*dims(2)*dims(3), ff, ierr)
2510 if (ierr == 0) then
2511 message(1) = "Reading successful."
2512 call messages_info(1, namespace=namespace)
2513
2514 do k=1, min(4_int64, dims(3))
2515 do j=1, min(4_int64, dims(2))
2516 write(message(j), '("data ",2I5, 1X, 4F8.2)') k, j, &
2517 (ff(i + dims(1)*(j-1) + dims(1)* dims(2)*(k-1)), i=1, min(4_int64, dims(1)))
2518 end do
2519 write(message(int(j, int32)), '("")')
2520 call messages_info(int(j, int32), namespace=namespace)
2521 end do
2522
2523 else
2524 message(1) = "Reading failed."
2525 call messages_fatal(1, namespace=namespace)
2526 end if
2527
2528 safe_deallocate_a(ff)
2529
2531 end subroutine test_csv_input
2532
2533end module test_oct_m
2534
2535!! Local Variables:
2536!! mode: f90
2537!! coding: utf-8
2538!! End:
batchified version of the BLAS axpy routine:
Definition: batch_ops.F90:159
batchified multiplication by mesh function with optional conjugation:
Definition: batch_ops.F90:254
batchified scale with optional conjugation:
Definition: batch_ops.F90:181
scale a batch by a constant or vector
Definition: batch_ops.F90:167
There are several ways how to call batch_set_state and batch_get_state:
Definition: batch_ops.F90:218
Prints out to iunit a message in the form: ["InputVariable" = value] where "InputVariable" is given b...
Definition: messages.F90:182
double exp(double __x) __attribute__((__nothrow__
double sqrt(double __x) __attribute__((__nothrow__
pure logical function, public accel_is_enabled()
Definition: accel.F90:402
This module implements batches of mesh functions.
Definition: batch.F90:135
This module implements common operations on batches of mesh functions.
Definition: batch_ops.F90:118
subroutine, public dbatch_ax_function_py(np, aa, psi, yy)
This routine performs a set of axpy operations adding the same function psi to all functions of a bat...
Definition: batch_ops.F90:1173
subroutine, public batch_set_zero(this, np, async)
fill all mesh functions of the batch with zero
Definition: batch_ops.F90:265
subroutine, public zbatch_ax_function_py(np, aa, psi, yy)
This routine performs a set of axpy operations adding the same function psi to all functions of a bat...
Definition: batch_ops.F90:3021
Module implementing boundary conditions in Octopus.
Definition: boundaries.F90:124
Module, implementing a factory for boxes.
This module handles the calculation mode.
integer, parameter, public p_strategy_kpoints
parallelization in k-points
integer, parameter, public p_strategy_domains
parallelization in domains
type(calc_mode_par_t), public calc_mode_par
Singleton instance of parallel calculation mode.
integer, parameter, public p_strategy_states
parallelization in states
subroutine, public cgal_polyhedron_init(cgal_poly, fname, verbose)
logical function, public cgal_polyhedron_point_inside(cgal_poly, xq, yq, zq)
subroutine, public cgal_polyhedron_end(cgal_poly)
pure real(real64) function center(this)
Center of the filter interval.
This module implements a calculator for the density and defines related functions.
Definition: density.F90:122
subroutine, public density_calc(st, gr, density, istin)
Computes the density from the orbitals in st.
Definition: density.F90:619
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
This module provides unit tests for the derivatives.
subroutine, public zderivatives_test(this, namespace, repetitions, min_blocksize, max_blocksize)
unit test for derivatives
subroutine, public dderivatives_test(this, namespace, repetitions, min_blocksize, max_blocksize)
unit test for derivatives
subroutine, public derivatives_advanced_benchmark(this, namespace)
Further unit tests design to challenge numerical stability of the finite differences.
subroutine, public zchebyshev_filter(namespace, mesh, st, hm, degree, bounds, ik, normalize)
Chebyshev Filter.
subroutine, public dchebyshev_filter(namespace, mesh, st, hm, degree, bounds, ik, normalize)
Chebyshev Filter.
integer, parameter, public spin_polarized
subroutine, public exponential_init(te, namespace, full_batch)
real(real64), parameter, public m_two
Definition: global.F90:202
real(real64), parameter, public m_zero
Definition: global.F90:200
real(real64), parameter, public m_four
Definition: global.F90:204
real(real64), parameter, public m_pi
some mathematical constants
Definition: global.F90:198
complex(real64), parameter, public m_zi
Definition: global.F90:214
real(real64), parameter, public m_epsilon
Definition: global.F90:216
real(real64), parameter, public m_half
Definition: global.F90:206
real(real64), parameter, public m_one
Definition: global.F90:201
This module implements the underlying real-space grid.
Definition: grid.F90:119
subroutine, public zhamiltonian_elec_apply_batch(hm, namespace, mesh, psib, hpsib, terms, set_bc)
subroutine, public hamiltonian_elec_end(hm)
subroutine, public hamiltonian_elec_epot_generate(this, namespace, space, gr, ions, ext_partners, st, time)
subroutine, public hamiltonian_elec_copy(hm_out, hm_in)
Deep-copy a hamiltonian_elec_t snapshot.
subroutine, public dhamiltonian_elec_apply_batch(hm, namespace, mesh, psib, hpsib, terms, set_bc)
type(hardware_t), public cpu_hardware
Global instance of CPU hardware specification.
Definition: hardware.F90:61
integer, parameter, public sizeof_real64
Number of bytes to store a variable of type real(real64)
Definition: hardware.F90:55
integer, parameter, public sizeof_complex64
Number of bytes to store a variable of type complex(real64)
Definition: hardware.F90:58
The Helmholtz decomposition is intended to contain "only mathematical" functions and procedures to co...
Test suit for the Helmholtz decomposition module.
subroutine, public gaussian_test(helmholtz, sys_grid, namespace, space)
subroutine, public hertzian_dipole_test(helmholtz, sys_grid, namespace, space)
This module implements a simple hash table for non-negative integer keys and integer values.
Definition: iihash.F90:127
subroutine, public iihash_end(h)
Free a hash table.
Definition: iihash.F90:186
subroutine, public iihash_insert(h, key, val)
Insert a (key, val) pair into the hash table h.
Definition: iihash.F90:208
integer function, public iihash_lookup(h, key, found)
Look up a value in the hash table h. If found is present, it indicates if key could be found in the t...
Definition: iihash.F90:233
subroutine, public iihash_init(h)
Initialize a hash table h.
Definition: iihash.F90:163
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.
integer(int64) function, public io_function_fill_how(where)
Use this function to quickly plot functions for debugging purposes: call dio_function_output(io_funct...
Definition: io.F90:116
subroutine, public ion_interaction_test(space, latt, atom, natoms, pos, lsize, namespace, mc)
This modules takes care of testing some linear algebra routines.
subroutine, public test_exponential_matrix(namespace)
Unit tests for the exponential of a matrix.
Computes and , suitable as an operator callback for iterative solvers (CG, QMR, etc....
subroutine, public dshifted_laplacian_op(x, lx, userdata)
Computes the shifted Laplacian operator: .
This module defines functions over batches of mesh functions.
Definition: mesh_batch.F90:118
subroutine, public dmesh_batch_dotp_matrix(mesh, aa, bb, dot, reduce)
Calculate the overlap matrix of two batches.
Definition: mesh_batch.F90:273
subroutine, public dmesh_batch_dotp_self(mesh, aa, dot, reduce)
calculate the overlap matrix of a batch with itself
Definition: mesh_batch.F90:536
subroutine, public mesh_batch_nrm2(mesh, aa, nrm2, reduce)
Calculate the norms (norm2, not the square!) of a batch of mesh functions.
Definition: mesh_batch.F90:179
subroutine, public zmesh_batch_dotp_vector(mesh, aa, bb, dot, reduce, cproduct)
calculate the vector of dot-products of mesh functions between two batches
subroutine, public zmesh_batch_dotp_matrix(mesh, aa, bb, dot, reduce)
Calculate the overlap matrix of two batches.
subroutine, public zmesh_batch_normalize(mesh, psib, norm)
Normalize a batch.
subroutine, public zmesh_batch_dotp_self(mesh, aa, dot, reduce)
calculate the overlap matrix of a batch with itself
subroutine, public dmesh_batch_normalize(mesh, psib, norm)
Normalize a batch.
subroutine, public dmesh_batch_dotp_vector(mesh, aa, bb, dot, reduce, cproduct)
calculate the vector of dot-products of mesh functions between two batches
Definition: mesh_batch.F90:650
This module defines various routines, operating on mesh functions.
real(real64) function, public dmf_dotp_aux(f1, f2)
dot product between two vectors (mesh functions)
subroutine, public mesh_init_mesh_aux(mesh)
Initialise a pointer to the grid/mesh, that is globally exposed, such that low level mesh operations ...
subroutine, public zmesh_interpolation_test(mesh)
subroutine, public dmesh_interpolation_test(mesh)
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
pure subroutine, public mesh_r(mesh, ip, rr, origin, coords)
return the distance to the origin for a given grid point
Definition: mesh.F90:342
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
Definition: messages.F90:898
character(len=512), private msg
Definition: messages.F90:167
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1000
subroutine, public messages_new_line()
Definition: messages.F90:1089
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 modules takes care of testing optimizers using standard test functions.
subroutine, public test_optimizers(namespace)
Unit tests for different optimizers.
This module implements unit tests for the mixing methods.
Definition: mix_tests.F90:117
subroutine, public mix_tests_run()
Definition: mix_tests.F90:139
type(mpi_grp_t), public mpi_world
Definition: mpi.F90:272
subroutine, public test_mpiwrappers
Definition: mpi_test.F90:130
This module handles the communicators for the various parallelization strategies.
Definition: multicomm.F90:147
subroutine, public multigrid_end(mgrid)
Definition: multigrid.F90:516
subroutine, public multigrid_init(mgrid, namespace, space, mesh, der, stencil, mc, nlevels)
Definition: multigrid.F90:187
type(namespace_t), public global_namespace
Definition: namespace.F90:135
subroutine, public orbitalbasis_end(this)
subroutine, public zorbitalbasis_build(this, namespace, ions, mesh, kpt, ndim, skip_s_orb, use_all_orb, verbose)
This routine is an interface for constructing the orbital basis.
subroutine, public dorbitalbasis_build(this, namespace, ions, mesh, kpt, ndim, skip_s_orb, use_all_orb, verbose)
This routine is an interface for constructing the orbital basis.
subroutine, public orbitalbasis_init(this, namespace, periodic_dim)
subroutine, public dorbitalset_add_to_batch(os, ndim, psib, weight)
Definition: orbitalset.F90:865
subroutine, public zorbitalset_add_to_batch(os, ndim, psib, weight)
subroutine, public orbitalset_update_phase(os, dim, kpt, kpoints, spin_polarized, vec_pot, vec_pot_var, kpt_max)
Build the phase correction to the global phase in case the orbital crosses the border of the simulato...
Definition: orbitalset.F90:286
subroutine, public dorbitalset_get_coeff_batch(os, ndim, psib, dot, reduce)
Definition: orbitalset.F90:590
subroutine, public zorbitalset_get_coeff_batch(os, ndim, psib, dot, reduce)
subroutine, public poisson_test(this, space, mesh, latt, namespace, repetitions)
This routine checks the Hartree solver selected in the input file by calculating numerically and anal...
subroutine, public preconditioner_end(this)
subroutine, public preconditioner_init(this, namespace, gr, mc, space)
subroutine, public zproject_psi_batch(mesh, bnd, pj, npj, dim, psib, ppsib)
To optimize the application of the non-local operator in parallel, the projectors are applied in step...
Definition: projector.F90:1258
Implementation details for regridding.
Definition: regridding.F90:172
This module implements a simple hash table for string valued keys and integer values using the C++ ST...
Definition: sihash.F90:120
subroutine, public sihash_insert(h, key, val)
Insert a (key, val) pair into the hash table h.
Definition: sihash.F90:205
subroutine, public sihash_init(h)
Initialize a hash table h with size entries. Since we use separate chaining, the number of entries in...
Definition: sihash.F90:164
integer function, public sihash_lookup(h, key, found)
Look up a value in the hash table h. If found is present, it indicates if key could be found in the t...
Definition: sihash.F90:231
subroutine, public sihash_end(h)
Free a hash table.
Definition: sihash.F90:185
This module is intended to contain "only mathematical" functions and procedures.
Definition: solvers.F90:117
This module implements a simple hash table for string valued keys and integer values using the C++ ST...
Definition: sphash.F90:120
subroutine, public sphash_init(h)
Initialize a hash table h with size entries. Since we use separate chaining, the number of entries in...
Definition: sphash.F90:223
subroutine, public sphash_insert(h, key, val, clone)
Insert a (key, val) pair into the hash table h. If clone=.true., the object will be copied.
Definition: sphash.F90:293
subroutine, public sphash_end(h)
Free a hash table.
Definition: sphash.F90:249
class(*) function, pointer, public sphash_lookup(h, key, found)
Look up a value in the hash table h. If found is present, it indicates if key could be found in the t...
Definition: sphash.F90:325
pure logical function, public states_are_real(st)
subroutine, public zstates_elec_calc_orth_test(st, namespace, mesh, kpoints)
subroutine, public dstates_elec_calc_orth_test(st, namespace, mesh, kpoints)
This module handles spin dimensions of the states and the k-point distribution.
subroutine, public states_elec_deallocate_wfns(st)
Deallocates the KS wavefunctions defined within a states_elec_t structure.
subroutine, public states_elec_allocate_wfns(st, mesh, wfs_type, skip, packed)
Allocates the KS wavefunctions defined within a states_elec_t structure.
subroutine, public dsubspace_diag(this, namespace, mesh, st, hm, ik, eigenval, diff, nonortho)
Diagonalises the Hamiltonian in the subspace defined by the states.
Definition: subspace.F90:299
subroutine, public zsubspace_diag(this, namespace, mesh, st, hm, ik, eigenval, diff, nonortho)
Diagonalises the Hamiltonian in the subspace defined by the states.
Definition: subspace.F90:770
Integration tests for ISDF.
Definition: test_isdf.F90:116
subroutine, public test_isdf(namespace, serial)
Set up an electron system, compute some optimal centroid positions, and use these to build a set of I...
Definition: test_isdf.F90:158
subroutine, public test_weighted_kmeans(namespace)
Test weighted kmeans algorithm for a finite system.
This module implements a unit-test like runmode for Octopus.
Definition: test.F90:117
real(real64) function psi_2s(rr, a0)
Definition: test.F90:2546
subroutine test_sihash()
Definition: test.F90:1903
subroutine test_cgal()
Definition: test.F90:1725
subroutine test_helmholtz_decomposition(namespace)
Definition: test.F90:411
subroutine test_hartree(param, namespace)
Definition: test.F90:392
subroutine test_derivatives(param, namespace)
Definition: test.F90:1487
subroutine test_subspace_diagonalization(param, namespace)
Definition: test.F90:1047
subroutine, public test_run(namespace)
Components and integration test runner.
Definition: test.F90:214
subroutine test_density_calc(param, namespace)
Definition: test.F90:827
subroutine test_iihash()
Definition: test.F90:1877
real(real64) function psi_1s(rr, a0)
Definition: test.F90:2539
subroutine test_current_density(namespace)
Here we test the different contributions to the total electronic current density.
Definition: test.F90:2358
subroutine test_batch_set_gaussian(psib, mesh)
Definition: test.F90:1804
subroutine test_regridding(namespace)
Definition: test.F90:2042
subroutine test_sphash(namespace)
Definition: test.F90:1949
subroutine test_hamiltonian(param, namespace)
Definition: test.F90:671
subroutine test_dense_eigensolver()
Definition: test.F90:1745
subroutine test_interpolation(param, namespace)
Definition: test.F90:1563
subroutine multigrid_test_interpolation(mgrid, space)
Definition: test.F90:2261
subroutine test_ion_interaction(namespace)
Definition: test.F90:1601
subroutine test_boundaries(param, namespace)
Definition: test.F90:865
subroutine test_orthogonalization(param, namespace)
Definition: test.F90:1521
real(real64) function dr_psi_2s(rr, a0)
Definition: test.F90:2559
subroutine test_batch_ops(param, namespace)
Definition: test.F90:1100
complex(real64) function lc_hydrogen_state(rr, alpha, a0)
Definition: test.F90:2531
subroutine test_projector(param, namespace)
Definition: test.F90:505
subroutine test_dft_u(param, namespace)
Definition: test.F90:557
subroutine test_prints_info_batch(st, gr, psib, string)
Definition: test.F90:1621
subroutine test_composition_chebyshev(namespace)
Test the composition rule for Chebyshev polynomials.
Definition: test.F90:904
real(real64) function dr_psi_1s(rr, a0)
Definition: test.F90:2553
subroutine test_linear_solver(namespace)
Definition: test.F90:442
subroutine test_grid_interpolation()
Definition: test.F90:1856
subroutine set_hydrogen_states(psib, mesh, namespace, alpha, a0)
Definition: test.F90:2501
subroutine test_exponential(param, namespace)
Definition: test.F90:998
subroutine test_csv_input(namespace)
Definition: test.F90:2567
subroutine test_vecpot_analytical(namespace)
Here, analytical formulation for vector potential and B field are used. Ref: Sangita Sen and Erik I....
Definition: test.F90:2160
subroutine test_clock()
Definition: test.F90:1666
type(type_t), public type_cmplx
Definition: types.F90:136
logical pure function, public type_is_complex(this)
Definition: types.F90:182
This module defines the unit system, used for input and output.
type(unit_t), public unit_one
some special units required for particular quantities
subroutine, public v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, calc_eigenval, time, calc_energy, calc_current, force_semilocal)
Definition: v_ks.F90:754
Class defining batches of mesh functions.
Definition: batch.F90:161
Class describing the electron system.
Definition: electrons.F90:220
Description of the grid, containing information on derivatives, stencil, and symmetries.
Definition: grid.F90:171
This class implements the iteration counter used by the multisystem algorithms. As any iteration coun...
Describes mesh distribution to nodes.
Definition: mesh.F90:187
contains the information of the meshes and provides the transfer functions
Definition: regridding.F90:198
The states_elec_t class contains all electronic wave functions.
batches of electronic states
Definition: wfs_elec.F90:141
int true(void)
subroutine write_clock(operation)
Definition: test.F90:1706
subroutine write_condition_result(condition, result)
Definition: test.F90:1713
real(real64) function values(xx)
Definition: test.F90:2143