37 CHARACTER(len=*),
INTENT(IN) :: filename
38 REAL(kind=
dp),
INTENT(IN) :: real_lattice(3, 3), recip_lattice(3, 3)
39 REAL(kind=
dp),
ALLOCATABLE,
INTENT(OUT) :: kpt(:, :)
40 INTEGER,
ALLOCATABLE,
INTENT(OUT) :: nnlist(:, :), nncell(:, :, :)
42 CHARACTER(len=1024) :: line
43 CHARACTER(len=64) :: block, marker
44 INTEGER :: i, ios, j, n, nexclude, nneigh, origin, &
45 shift(3),
TARGET, unit
46 INTEGER,
ALLOCATABLE :: counts(:)
47 LOGICAL :: have_real, have_recip
48 REAL(kind=
dp) :: lattice(3, 3)
52 CALL open_file(filename, unit_number=unit, file_status=
"OLD", file_action=
"READ")
54 CALL next_line(unit, line, ios)
56 IF (ios /= 0) cpabort(
"NNKP_FILE: read error.")
59 READ (line, *, iostat=ios) marker, block
63 IF (marker /=
"begin") cycle
64 SELECT CASE (trim(block))
65 CASE (
"real_lattice",
"recip_lattice")
67 CALL required_line(unit, line)
68 READ (line, *, iostat=ios) lattice(:, i)
69 IF (ios /= 0) cpabort(
"NNKP_FILE: invalid lattice vector.")
71 IF (.NOT. all(ieee_is_finite(lattice))) cpabort(
"NNKP_FILE: nonfinite lattice.")
72 IF (block ==
"real_lattice")
THEN
73 IF (have_real) cpabort(
"NNKP_FILE: duplicate real_lattice block.")
74 IF (maxval(abs(lattice - real_lattice)) > real_lattice_tol)
THEN
75 cpabort(
"NNKP_FILE: real lattice differs from the CP2K cell (Angstrom).")
79 IF (have_recip) cpabort(
"NNKP_FILE: duplicate recip_lattice block.")
80 IF (maxval(abs(lattice - recip_lattice)) > recip_lattice_tol)
THEN
81 cpabort(
"NNKP_FILE: reciprocal lattice differs from the CP2K cell.")
85 CALL end_block(unit, block)
87 IF (
ALLOCATED(kpt)) cpabort(
"NNKP_FILE: duplicate kpoints block.")
88 CALL required_line(unit, line)
89 READ (line, *, iostat=ios) n
90 IF (ios /= 0) cpabort(
"NNKP_FILE: invalid point count.")
91 IF (n < 1) cpabort(
"NNKP_FILE: point count must be positive.")
94 CALL required_line(unit, line)
95 READ (line, *, iostat=ios) kpt(:, i)
96 IF (ios /= 0) cpabort(
"NNKP_FILE: invalid k-point.")
98 IF (.NOT. all(ieee_is_finite(kpt))) cpabort(
"NNKP_FILE: nonfinite k-point.")
99 CALL end_block(unit, block)
101 IF (.NOT.
ALLOCATED(kpt)) cpabort(
"NNKP_FILE: kpoints must precede nnkpts.")
102 IF (
ALLOCATED(nnlist)) cpabort(
"NNKP_FILE: duplicate nnkpts block.")
103 CALL required_line(unit, line)
104 READ (line, *, iostat=ios) nneigh
105 IF (ios /= 0) cpabort(
"NNKP_FILE: invalid neighbour count.")
106 IF (nneigh < 1) cpabort(
"NNKP_FILE: neighbour count must be positive.")
108 ALLOCATE (nnlist(n, nneigh), nncell(3, n, nneigh), counts(n))
111 CALL required_line(unit, line)
112 READ (line, *, iostat=ios) origin,
TARGET, shift
113 IF (ios /= 0) cpabort(
"NNKP_FILE: invalid connection.")
114 IF (min(origin,
TARGET) < 1 .OR. max(origin,
TARGET) > n)
THEN
115 cpabort(
"NNKP_FILE: connection point index out of range.")
117 IF (counts(origin) == nneigh) cpabort(
"NNKP_FILE: too many neighbours for a point.")
118 DO j = 1, counts(origin)
119 IF (nnlist(origin, j) ==
TARGET .AND. all(nncell(:, origin, j) == shift))
THEN
120 cpabort(
"NNKP_FILE: duplicate connection.")
123 counts(origin) = counts(origin) + 1
124 nnlist(origin, counts(origin)) =
TARGET
125 nncell(:, origin, counts(origin)) = shift
127 IF (any(counts /= nneigh)) cpabort(
"NNKP_FILE: missing connections.")
129 CALL end_block(unit, block)
130 CASE (
"exclude_bands")
131 CALL required_line(unit, line)
132 READ (line, *, iostat=ios) nexclude
133 IF (ios /= 0) cpabort(
"NNKP_FILE: invalid exclude_bands count.")
134 IF (nexclude /= 0) cpabort(
"NNKP_FILE: specify band exclusions using CP2K EXCLUDE_BANDS.")
135 CALL end_block(unit, block)
139 CALL required_line(unit, line)
141 READ (line, *, iostat=ios) marker
142 IF (ios /= 0) cpabort(
"NNKP_FILE: invalid line in unused block.")
144 IF (marker ==
"end")
EXIT
149 IF (.NOT. have_real .OR. .NOT. have_recip) cpabort(
"NNKP_FILE: missing lattice blocks.")
150 IF (.NOT.
ALLOCATED(kpt) .OR. .NOT.
ALLOCATED(nnlist))
THEN
151 cpabort(
"NNKP_FILE: missing kpoints or nnkpts block.")
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
subroutine, public read_wannier90_nnkpts(filename, real_lattice, recip_lattice, kpt, nnlist, nncell)
Read and validate the cell, points, and directed connections of an nnkp file.