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