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