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