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