25 REAL(kind=
dp),
PARAMETER :: initial(6) = [1.0_dp, 2.0_dp, 3.0_dp, 4.0_dp, 5.0_dp, 6.0_dp]
26 REAL(kind=
dp),
DIMENSION(:),
POINTER :: gradient => null()
27 TYPE(
cell_type),
POINTER :: cell => null()
30 ALLOCATE (gradient(6))
32 CALL check_projections()
43 CHARACTER(LEN=4),
PARAMETER :: &
44 legacy(7) = [
"NONE",
" X",
" Y",
" Z",
" XY",
" XZ",
" YZ"], names(18) = [ &
45 CHARACTER(LEN=4) ::
"NONE",
"X",
"Y",
"Z",
"XY",
"XZ",
"YZ",
"a",
"AX",
"B",
"BX",
"BY", &
46 "C",
"CX",
"CY",
"CZ",
"none",
" z "]
47 CHARACTER(LEN=5),
PARAMETER :: &
48 invalid(5) = [character(len=5) ::
"AY",
"AZ",
"BZ",
"ALPHA",
"YX"]
49 INTEGER,
PARAMETER :: &
50 masks(18) = [0, 11, 22, 56, 31, 59, 62, 1, 1, 6, 2, 4, 56, 8, 16, 32, 0, 56]
52 CHARACTER(LEN=default_string_length) :: label, reason, tokens(6)
53 INTEGER :: i, mask, n, wanted
61 IF (mask /= masks(i)) error stop
"Incorrect constraint token mask"
62 IF (i <=
SIZE(legacy))
THEN
67 IF (mask /= 37) error stop
"Constraint components were not combined"
69 IF (mask /= 7) error stop
"Redundant constraint changed the mask"
71 IF (mask /= 15) error stop
"Partially overlapping constraint lost components"
76 DO WHILE (len_trim(label) > 0)
78 READ (label, *) tokens(n)
80 label = adjustl(label)
83 IF (mask /= wanted) error stop
"Constraint label round trip failed"
85 DO i = 1,
SIZE(invalid)
86 CALL parse_token(invalid(i), accepted, mask, reason)
87 IF (accepted .OR. len_trim(reason) == 0) error stop
"Invalid constraint token accepted"
93 IF (mask /= masks(i + 1)) error stop
"Incorrect 2D default constraint"
95 IF (mask /= masks(i + 1)) error stop
"Explicit 2D constraint changed"
97 IF (mask /=
mask_all) error stop
"Explicit 2D constraint superset changed"
104 SUBROUTINE check_projections()
105 REAL(KIND=
dp) :: a, normal(3), reference(6), root3
109 cell%orthorhombic = .false.
110 cell%hmat = reshape([2.0_dp, 0.0_dp, 0.0_dp, 1.0_dp, 2.0_dp, 0.0_dp, 1.0_dp, 2.0_dp, 2.0_dp], [3, 3])
114 [1.0_dp, 8.0_dp/5, 16.0_dp/5, 26.0_dp/9, 52.0_dp/9, 52.0_dp/9], .true., 0)
115 CALL check_projection(
cell_sym_triclinic, [0.0_dp, 2.0_dp, 0.0_dp, 4.0_dp, 5.0_dp, 0.0_dp], &
117 CALL check_projection(
cell_sym_triclinic, [0.0_dp, 8.0_dp/5, 16.0_dp/5, 0.0_dp, 0.0_dp, 0.0_dp], &
119 cell%hmat = reshape([2.0_dp, 0.0_dp, 0.0_dp, 0.0_dp, 2.0_dp, 0.0_dp, 0.0_dp, 0.0_dp, 2.0_dp], [3, 3])
120 cell%orthorhombic = .true.
121 CALL check_projection(
cell_sym_cubic, [10.0_dp/3, 0.0_dp, 10.0_dp/3, 0.0_dp, 0.0_dp, 10.0_dp/3], .false., 0)
122 CALL check_projection(
cell_sym_tetragonal_ab, [2.0_dp, 0.0_dp, 2.0_dp, 0.0_dp, 0.0_dp, 6.0_dp], .false., 0)
123 CALL check_projection(
cell_sym_tetragonal_ac, [3.5_dp, 0.0_dp, 3.0_dp, 0.0_dp, 0.0_dp, 3.5_dp], .false., 0)
124 CALL check_projection(
cell_sym_tetragonal_bc, [1.0_dp, 0.0_dp, 4.5_dp, 0.0_dp, 0.0_dp, 4.5_dp], .false., 0)
125 CALL check_projection(
cell_sym_monoclinic, [1.0_dp, 0.0_dp, 3.0_dp, 4.0_dp, 0.0_dp, 6.0_dp], .false., 0)
126 cell%hmat = reshape([1.0_dp, 0.0_dp, 0.0_dp, 0.5_dp, root3/2, 0.0_dp, 0.0_dp, 0.0_dp, 2.0_dp], [3, 3])
127 cell%orthorhombic = .false.
128 a = 1.0_dp + 0.75_dp*root3
131 cell%hmat(1, 2) = -0.5_dp
134 cell%hmat = reshape([1.0_dp, 0.0_dp, 0.0_dp, 0.5_dp, root3/2, 0.0_dp, &
135 0.5_dp, root3/6, sqrt(2.0_dp/3)], [3, 3])
137 reference = [1.0_dp, 0.5_dp, root3/2, 0.5_dp, root3/6, sqrt(2.0_dp/3)]
138 reference = reference*dot_product(reference, initial)/3.0_dp
140 cell%hmat(:, 3) = [0.0_dp, 0.0_dp, 2.0_dp]
142 normal = [-1.0_dp, 0.5_dp, root3/2]
144 reference(1:3) = initial(1:3) - normal*dot_product(normal, initial(1:3))/2.0_dp
145 reference(4:5) = 0.0_dp
149 cell%hmat(1, 1) = 2.0_dp
150 cell%hmat(2, 2) = 3.0_dp
151 cell%hmat(3, 3) = 4.0_dp
152 cell%orthorhombic = .true.
153 CALL check_projection(
cell_sym_orthorhombic, [1.0_dp, 0.0_dp, 3.0_dp, 0.0_dp, 0.0_dp, 6.0_dp], .false., 0)
154 CALL check_projection(
cell_sym_orthorhombic, [1.0_dp, 0.0_dp, 3.0_dp, 0.0_dp, 0.0_dp, 6.0_dp], .true., 0)
156 END SUBROUTINE check_projections
165 SUBROUTINE check_projection(symmetry, expected, keep_angles, mask)
166 INTEGER,
INTENT(IN) :: symmetry
167 REAL(KIND=
dp),
INTENT(IN) :: expected(6)
168 LOGICAL,
INTENT(IN) :: keep_angles
169 INTEGER,
INTENT(IN) :: mask
173 cell%symmetry_id = symmetry
177 IF (.NOT. all(abs(gradient - expected) <= 1.0e-12_dp))
THEN
178 print *,
"Incorrect cell projection: symmetry, mask, repetition:", symmetry, mask, repeat
182 END SUBROUTINE check_projection
187 SUBROUTINE check_guards()
188 INTEGER,
PARAMETER :: &
190 partial(12) = [1, 1, 1, 4, 2, 2, 2, 32, 1, 1, 1, 1], systems(12) = [
cell_sym_cubic, &
195 LOGICAL,
PARAMETER :: angle_conflict(8) = [.false., .false., .false., .false., .true., .true.&
196 , .true., .false.], &
197 pressure(8) = [.false., .false., .true., .true., .true., .false., .false., .false.]
201 DO i = 1,
SIZE(systems)
204 IF (
keep_symmetry_conflict(partial(i), systems(i)) .NEQV. (i <= 8)) error stop
"Incorrect symmetry conflict"
207 DO i = 1,
SIZE(masks)
208 IF (
keep_angles_conflict(masks(i), .false.) .NEQV. angle_conflict(i)) error stop
"Incorrect angle conflict"
210 IF (
pres_crit_shear_pinned(masks(i), .false., .false.) .NEQV. pressure(i)) error stop
"Incorrect pressure warning"
215 END SUBROUTINE check_guards
subroutine check_parser()
Check token masks, label round trips, rejections and 2D defaults.
program cell_opt_utils_test
Handles all functions related to the CELL.
subroutine, public cell_create(cell, hmat, periodic, tag)
allocates and initializes a cell
contains a functional that calculates the energy and its derivatives for the geometry optimizer
pure logical function, public keep_symmetry_conflict(mask, symmetry_id)
Whether a CONSTRAINT mask conflicts with the KEEP_SYMMETRY projection.
integer, parameter, public comp_cz
integer, parameter, public comp_bx
integer, parameter, public comp_ax
subroutine, public apply_cell_constraints(gradient, cell, keep_angles, keep_symmetry, constraint_id)
Apply cell constraints.
subroutine, public parse_cell_constraint(constraint_tokens, cell, explicit, mask)
Parses the tokens of the CONSTRAINT keyword into a cell component mask.
pure logical function, public pres_crit_shear_pinned(mask, orthorhombic, keep_angles)
Whether the masked pressure criterion is structurally off target.
integer, parameter, public comp_by
integer, parameter, public mask_b
integer, parameter, public mask_c
pure subroutine, public parse_token(token, accepted, token_mask, reject_reason)
Classify one CONSTRAINT token without aborting (decision half of the parser).
pure logical function, public keep_angles_conflict(mask, orthorhombic)
Whether a CONSTRAINT mask conflicts with the KEEP_ANGLES projection.
pure character(len=default_string_length) function, public cell_opt_constraint_label(mask)
Returns the label of the consolidated cell constraint mask.
integer, parameter, public mask_all
Handles all functions related to the CELL.
integer, parameter, public cell_sym_monoclinic
integer, parameter, public cell_sym_triclinic
integer, parameter, public cell_sym_tetragonal_ab
integer, parameter, public cell_sym_rhombohedral
subroutine, public cell_release(cell)
releases the given cell (see doc/ReferenceCounting.html)
integer, parameter, public cell_sym_tetragonal_ac
integer, parameter, public cell_sym_hexagonal_gamma_60
integer, parameter, public cell_sym_orthorhombic
integer, parameter, public cell_sym_none
integer, parameter, public cell_sym_hexagonal_gamma_120
integer, parameter, public cell_sym_monoclinic_gamma_ab
integer, parameter, public cell_sym_cubic
integer, parameter, public cell_sym_tetragonal_bc
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
Utilities for string manipulations.
subroutine, public remove_word(string)
remove a word from a string (words are separated by white spaces)
Type defining parameters related to the simulation cell.