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