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