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