(git:5e7fe52)
Loading...
Searching...
No Matches
optbas_frontier_orbitals_utils_unittest.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7! **************************************************************************************************
8!> \brief Unit tests for the frontier-orbital objective
9!> \par History
10!> 28.08.2026 created [Jan Wilhelm]
11!> \author Jan Wilhelm
12! **************************************************************************************************
14 USE kinds, ONLY: dp
18#include "./base/base_uses.f90"
19
20 IMPLICIT NONE
21
22 REAL(kind=dp), PARAMETER :: tolerance = 1.0e-12_dp
23 REAL(kind=dp), DIMENSION(4) :: candidate_eigenvalues, reference_eigenvalues
24 REAL(kind=dp), DIMENSION(4, 4) :: orbital_overlap
25 TYPE(frontier_orbitals_result_type) :: result, result_rotated
26
27 reference_eigenvalues = [-1.0_dp, -0.5_dp, 0.1_dp, 0.2_dp]
28 candidate_eigenvalues = reference_eigenvalues
29
30 ! Identical spaces have zero loss. A permutation/sign change inside equally weighted subspaces
31 ! leaves the trace objectives invariant.
32 orbital_overlap = 0.0_dp
33 orbital_overlap(1, 1) = 1.0_dp
34 orbital_overlap(2, 2) = 1.0_dp
35 orbital_overlap(3, 3) = 1.0_dp
36 orbital_overlap(4, 4) = 1.0_dp
38 orbital_overlap, reference_eigenvalues, candidate_eigenvalues, 2, &
39 10.0_dp, 0.1_dp, 0.2_dp, result)
40 CALL assert_close(result%loss_occupied_subspace, 0.0_dp, "identical occupied subspace")
41 CALL assert_close(result%loss_virtual_subspace, 0.0_dp, "identical virtual subspace")
42 CALL assert_close(result%empty_subspace_overlap, 1.0_dp, "identical empty subspace")
43 CALL assert_close(result%loss_empty_subspace, 0.0_dp, "identical empty-space loss")
44 CALL assert_close(result%virtual_subspace_similarity, 1.0_dp, &
45 "identical virtual-space similarity")
46
47 orbital_overlap = 0.0_dp
48 orbital_overlap(1, 2) = -1.0_dp
49 orbital_overlap(2, 1) = 1.0_dp
50 orbital_overlap(3, 4) = -1.0_dp
51 orbital_overlap(4, 3) = 1.0_dp
53 orbital_overlap, reference_eigenvalues, candidate_eigenvalues, 2, &
54 10.0_dp, 0.1_dp, 0.2_dp, result_rotated)
55 CALL assert_close(result_rotated%loss_occupied_subspace, result%loss_occupied_subspace, &
56 "occupied permutation/sign invariance")
57 CALL assert_close(result_rotated%loss_virtual_subspace, result%loss_virtual_subspace, &
58 "virtual permutation/sign invariance")
59
60 ! Orthogonal equal-rank and equally weighted spaces give unit normalized losses.
61 orbital_overlap = 0.0_dp
62 candidate_eigenvalues = reference_eigenvalues
64 orbital_overlap, reference_eigenvalues, candidate_eigenvalues, 2, &
65 10.0_dp, 0.1_dp, 0.2_dp, result)
66 CALL assert_close(result%loss_occupied_subspace, 1.0_dp, "orthogonal occupied normalization")
67 CALL assert_close(result%loss_virtual_subspace, 1.0_dp, "orthogonal virtual normalization")
68 CALL assert_close(result%empty_subspace_overlap, 0.0_dp, "orthogonal empty subspace")
69 CALL assert_close(result%loss_empty_subspace, 1.0_dp, "orthogonal empty-space loss")
70 CALL assert_close(result%virtual_subspace_similarity, 0.0_dp, &
71 "orthogonal virtual-space similarity")
72
73 ! A gap error equal to E_scale gives a unit gap loss.
74 candidate_eigenvalues(3:4) = candidate_eigenvalues(3:4) + 0.2_dp
76 orbital_overlap, reference_eigenvalues, candidate_eigenvalues, 2, &
77 10.0_dp, 0.1_dp, 0.2_dp, result)
78 CALL assert_close(result%loss_gap, 1.0_dp, "gap normalization")
79
80 ! The virtual-orbital weight is continuous and monotonic across the cutoff.
81 IF (.NOT. smooth_frontier_orbital_weight(0.999_dp, 1.0_dp, 0.1_dp) > &
82 smooth_frontier_orbital_weight(1.001_dp, 1.0_dp, 0.1_dp)) THEN
83 error stop "virtual-orbital weight is not monotonic"
84 END IF
85 CALL assert_close(smooth_frontier_orbital_weight(1.0_dp, 1.0_dp, 0.1_dp), &
86 0.5_dp, "cutoff midpoint")
87
88CONTAINS
89
90! **************************************************************************************************
91!> \brief ...
92!> \param actual ...
93!> \param expected ...
94!> \param description ...
95! **************************************************************************************************
96 SUBROUTINE assert_close(actual, expected, description)
97 REAL(kind=dp), INTENT(IN) :: actual, expected
98 CHARACTER(LEN=*), INTENT(IN) :: description
99
100 IF (abs(actual - expected) > tolerance) THEN
101 cpabort(trim(description))
102 END IF
103
104 END SUBROUTINE assert_close
105
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Utilities for frontier-orbital basis optimization.
pure real(kind=dp) function, public smooth_frontier_orbital_weight(energy_from_lumo, cutoff, smoothing)
Return the smooth energy-window weight for a virtual orbital.
pure subroutine, public compute_frontier_orbital_loss_function(orbital_overlap, eigenvalues_reference, eigenvalues_candidate, number_occupied_orbitals, virtual_cutoff, virtual_smoothing, gap_scale, objective_result)
Compute the frontier-orbital loss function.
program optbas_frontier_orbitals_utils_unittest
Unit tests for the frontier-orbital objective.
subroutine assert_close(actual, expected, description)
...