Line data Source code
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 : ! **************************************************************************************************
9 : !> \brief Full Born-von-Karman AO operators at a frozen SCF potential.
10 : !> \author Thomas D. Kuehne, tkuehne@cp2k.org
11 : ! **************************************************************************************************
12 : MODULE qs_localizer_torus
13 : USE cell_types, ONLY: cell_type
14 : USE cp_dbcsr_api, ONLY: &
15 : dbcsr_add, dbcsr_create, dbcsr_desymmetrize, dbcsr_distribution_get, &
16 : dbcsr_distribution_new, dbcsr_distribution_release, dbcsr_distribution_type, &
17 : dbcsr_finalize, dbcsr_get_info, dbcsr_iterator_blocks_left, dbcsr_iterator_next_block, &
18 : dbcsr_iterator_start, dbcsr_iterator_stop, dbcsr_iterator_type, dbcsr_p_type, &
19 : dbcsr_put_block, dbcsr_release, dbcsr_set, dbcsr_type, dbcsr_type_antisymmetric, &
20 : dbcsr_type_no_symmetry, dbcsr_type_symmetric
21 : USE cp_dbcsr_cp2k_link, ONLY: cp_dbcsr_alloc_block_from_nbl
22 : USE cp_dbcsr_operations, ONLY: dbcsr_deallocate_matrix_set
23 : USE kinds, ONLY: dp
24 : USE kpoint_methods, ONLY: kpoint_init_cell_index,&
25 : rskp_transform
26 : USE kpoint_types, ONLY: kpoint_create,&
27 : kpoint_release,&
28 : kpoint_type
29 : USE mathconstants, ONLY: twopi
30 : USE message_passing, ONLY: mp_para_env_type
31 : USE qs_ao_translations, ONLY: ao_translation_matrices
32 : USE qs_environment_types, ONLY: get_qs_env,&
33 : qs_env_release,&
34 : qs_environment_type
35 : USE qs_finite_ao, ONLY: finite_ao_soc
36 : USE qs_gamma2kp, ONLY: create_kp_from_gamma
37 : USE qs_ks_types, ONLY: get_ks_env,&
38 : qs_ks_env_type
39 : USE qs_moments, ONLY: build_berry_kpoint_matrix
40 : USE qs_neighbor_list_types, ONLY: neighbor_list_set_p_type
41 : #include "./base/base_uses.f90"
42 :
43 : IMPLICIT NONE
44 : PRIVATE
45 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_localizer_torus'
46 : PUBLIC :: localizer_torus_operators, torus_translation_operators
47 : CONTAINS
48 :
49 : ! **************************************************************************************************
50 : !> \brief Lift scalar image operators and ordered Berry integrals to a full real-cell torus.
51 : !> \param qs_env Converged SCF environment, possibly symmetry reduced
52 : !> \param grid Gamma-centered property mesh, one in nonperiodic directions
53 : !> \param directions Oriented periodic directions
54 : !> \param do_soc Include physical-spin GTH SOC
55 : !> \param h Newly allocated scalar Hamiltonians on the torus
56 : !> \param s Newly allocated torus overlap
57 : !> \param cosines Newly allocated torus cosine matrices, in directions order
58 : !> \param sines Newly allocated sine matrices, indexed by lattice direction
59 : !> \param soc Newly allocated torus SOC components when requested
60 : !> \note No SCF weights or reconstructed occupied MOs enter. Keeping a real-cell AO basis
61 : !> also retains the standard physical time-reversal representation for the AII solver.
62 : ! **************************************************************************************************
63 16 : SUBROUTINE localizer_torus_operators(qs_env, grid, directions, do_soc, h, s, cosines, sines, soc)
64 : TYPE(qs_environment_type), POINTER :: qs_env
65 : INTEGER, INTENT(IN) :: grid(3), directions(:)
66 : LOGICAL, INTENT(IN) :: do_soc
67 : TYPE(dbcsr_p_type), POINTER :: h(:), s(:), cosines(:), sines(:), &
68 : soc(:, :)
69 :
70 : INTEGER :: axis, j, nimages
71 : LOGICAL :: do_kpoints
72 : TYPE(cell_type), POINTER :: cell
73 16 : TYPE(dbcsr_p_type), POINTER :: cb(:, :), sb(:, :)
74 : TYPE(kpoint_type), POINTER :: berry
75 : TYPE(mp_para_env_type), POINTER :: para_env
76 16 : TYPE(neighbor_list_set_p_type), POINTER :: all_pairs(:)
77 : TYPE(qs_environment_type), POINTER :: qp
78 :
79 16 : NULLIFY (qp, berry, cb, sb, soc)
80 0 : CPASSERT(SIZE(directions) >= 1 .AND. SIZE(directions) <= 3)
81 108 : CPASSERT(ALL(directions >= 1) .AND. ALL(directions <= 3))
82 54 : DO j = 1, SIZE(directions)
83 148 : CPASSERT(COUNT(directions == directions(j)) == 1)
84 : END DO
85 16 : CALL get_qs_env(qs_env, do_kpoints=do_kpoints)
86 16 : IF (do_kpoints) THEN
87 16 : qp => qs_env
88 : ELSE
89 0 : CALL create_kp_from_gamma(qs_env, qp)
90 : END IF
91 16 : CALL get_qs_env(qp, cell=cell, para_env=para_env, sab_all=all_pairs)
92 16 : CALL lift_electronic_operators(qp, grid, do_soc, h, s, soc)
93 134 : ALLOCATE (cosines(SIZE(directions)), sines(3))
94 16 : CALL kpoint_create(berry)
95 16 : CALL kpoint_init_cell_index(berry, all_pairs, para_env, nimages)
96 64 : DO axis = 1, 3
97 48 : ALLOCATE (sines(axis)%matrix)
98 48 : CALL dbcsr_create(sines(axis)%matrix, template=s(1)%matrix, name='TORUS SIN')
99 64 : CALL dbcsr_finalize(sines(axis)%matrix)
100 : END DO
101 54 : DO j = 1, SIZE(directions)
102 38 : axis = directions(j)
103 : CALL build_berry_kpoint_matrix(qp, cb, sb, twopi*cell%h_inv(axis, :)/REAL(grid(axis), dp), &
104 152 : ordered=.TRUE., ordered_kpoints=berry)
105 38 : ALLOCATE (cosines(j)%matrix)
106 38 : CALL dbcsr_create(cosines(j)%matrix, template=s(1)%matrix, name='TORUS COS')
107 38 : CALL lift_berry(cb, sb, berry%index_to_cell, grid, axis, cosines(j)%matrix, sines(axis)%matrix)
108 38 : CALL dbcsr_deallocate_matrix_set(cb)
109 54 : CALL dbcsr_deallocate_matrix_set(sb)
110 : END DO
111 16 : CALL kpoint_release(berry)
112 16 : IF (.NOT. do_kpoints) THEN
113 0 : CALL qs_env_release(qp)
114 0 : DEALLOCATE (qp)
115 : END IF
116 32 : END SUBROUTINE localizer_torus_operators
117 :
118 : ! **************************************************************************************************
119 : !> \brief Full AO torus with translated, periodized Gaussians instead of position coordinates.
120 : !> \param qs_env Converged SCF environment
121 : !> \param grid Full Gamma-centered property mesh
122 : !> \param shifts Cartesian translations in internal bohr
123 : !> \param do_soc Include post-SCF physical-spin GTH SOC
124 : !> \param h Newly allocated scalar torus Hamiltonians
125 : !> \param s Newly allocated torus metric
126 : !> \param translations Newly allocated nonsymmetric torus translation overlaps
127 : !> \param soc Newly allocated torus SOC components when requested
128 : ! **************************************************************************************************
129 6 : SUBROUTINE torus_translation_operators(qs_env, grid, shifts, do_soc, h, s, translations, soc)
130 : TYPE(qs_environment_type), POINTER :: qs_env
131 : INTEGER, INTENT(IN) :: grid(3)
132 : REAL(dp), INTENT(IN) :: shifts(:, :)
133 : LOGICAL, INTENT(IN) :: do_soc
134 : TYPE(dbcsr_p_type), POINTER :: h(:), s(:), translations(:), soc(:, :)
135 :
136 : INTEGER :: ir, it, r(3)
137 : LOGICAL :: do_kpoints
138 : REAL(dp), ALLOCATABLE :: displaced(:, :)
139 : TYPE(cell_type), POINTER :: cell
140 6 : TYPE(dbcsr_p_type), POINTER :: primitive_s(:, :), residues(:)
141 : TYPE(qs_environment_type), POINTER :: qp
142 :
143 6 : CALL get_qs_env(qs_env, do_kpoints=do_kpoints)
144 6 : IF (do_kpoints) THEN
145 4 : qp => qs_env
146 : ELSE
147 2 : CALL create_kp_from_gamma(qs_env, qp)
148 : END IF
149 6 : CALL get_qs_env(qp, cell=cell, matrix_s_kp=primitive_s)
150 6 : CALL lift_electronic_operators(qp, grid, do_soc, h, s, soc)
151 36 : ALLOCATE (translations(SIZE(shifts, 2)), displaced(3, SIZE(shifts, 2)))
152 12 : DO it = 1, SIZE(translations)
153 6 : ALLOCATE (translations(it)%matrix)
154 30 : CALL create_torus(primitive_s(1, 1)%matrix, PRODUCT(grid), translations(it)%matrix)
155 : END DO
156 38 : DO ir = 1, PRODUCT(grid)
157 14 : r = cell_coordinates(ir, grid)
158 28 : DO it = 1, SIZE(translations)
159 336 : displaced(:, it) = shifts(:, it) - MATMUL(cell%hmat, REAL(r, dp))
160 : END DO
161 14 : CALL ao_translation_matrices(qp, displaced, residues, periodic_grid=grid)
162 28 : DO it = 1, SIZE(translations)
163 28 : CALL lift_blocks(residues(it)%matrix, grid, r, 0, .FALSE., translations(it)%matrix)
164 : END DO
165 20 : CALL dbcsr_deallocate_matrix_set(residues)
166 : END DO
167 6 : IF (.NOT. do_kpoints) THEN
168 2 : CALL qs_env_release(qp)
169 2 : DEALLOCATE (qp)
170 : END IF
171 12 : END SUBROUTINE torus_translation_operators
172 :
173 : ! **************************************************************************************************
174 : !> \brief Common Hamiltonian, metric and physical-spin image lifting for the two AO-torus analyses.
175 : !> \param qp Environment with explicit real-space image matrices
176 : !> \param grid Property mesh
177 : !> \param do_soc Include post-SCF GTH SOC
178 : !> \param h Newly allocated scalar Hamiltonians
179 : !> \param s Newly allocated overlap
180 : !> \param soc Newly allocated SOC components, or null without SOC
181 : ! **************************************************************************************************
182 22 : SUBROUTINE lift_electronic_operators(qp, grid, do_soc, h, s, soc)
183 : TYPE(qs_environment_type), POINTER :: qp
184 : INTEGER, INTENT(IN) :: grid(3)
185 : LOGICAL, INTENT(IN) :: do_soc
186 : TYPE(dbcsr_p_type), POINTER :: h(:), s(:), soc(:, :)
187 :
188 : INTEGER :: axis, spin
189 22 : TYPE(dbcsr_p_type), POINTER :: hk(:, :), sk(:, :), vk(:, :)
190 : TYPE(kpoint_type), POINTER :: kpoints
191 22 : TYPE(neighbor_list_set_p_type), POINTER :: pairs(:)
192 : TYPE(qs_ks_env_type), POINTER :: ks_env
193 :
194 22 : NULLIFY (soc, vk)
195 22 : CALL get_qs_env(qp, ks_env=ks_env, matrix_ks_kp=hk, matrix_s_kp=sk, sab_orb=pairs)
196 22 : CALL get_ks_env(ks_env, kpoints=kpoints)
197 110 : ALLOCATE (h(SIZE(hk, 1)), s(1))
198 44 : DO spin = 1, SIZE(hk, 1)
199 22 : ALLOCATE (h(spin)%matrix)
200 44 : CALL lift_fourier(hk, spin, pairs, kpoints, grid, .FALSE., h(spin)%matrix)
201 : END DO
202 22 : ALLOCATE (s(1)%matrix)
203 22 : CALL lift_fourier(sk, 1, pairs, kpoints, grid, .FALSE., s(1)%matrix)
204 22 : IF (do_soc) THEN
205 14 : CALL finite_ao_soc(qp, vk)
206 70 : ALLOCATE (soc(3, 1))
207 56 : DO axis = 1, 3
208 42 : ALLOCATE (soc(axis, 1)%matrix)
209 56 : CALL lift_fourier(vk, axis, pairs, kpoints, grid, .TRUE., soc(axis, 1)%matrix)
210 : END DO
211 14 : CALL dbcsr_deallocate_matrix_set(vk)
212 : END IF
213 22 : END SUBROUTINE lift_electronic_operators
214 :
215 : ! **************************************************************************************************
216 : !> \brief Repeat the atom-block distribution; cell copies remain on the same MPI owners.
217 : !> \param source Primitive AO template
218 : !> \param copies Number of real cells
219 : !> \param matrix New full-storage torus matrix
220 : ! **************************************************************************************************
221 92 : SUBROUTINE create_torus(source, copies, matrix)
222 : TYPE(dbcsr_type), INTENT(IN) :: source
223 : INTEGER, INTENT(IN) :: copies
224 : TYPE(dbcsr_type), INTENT(OUT) :: matrix
225 :
226 : INTEGER :: n
227 92 : INTEGER, POINTER :: cols(:), ec(:), er(:), es(:), rows(:), &
228 92 : sizes(:)
229 : TYPE(dbcsr_distribution_type) :: distribution, expanded
230 :
231 92 : CALL dbcsr_get_info(source, distribution=distribution, row_blk_size=sizes)
232 92 : CALL dbcsr_distribution_get(distribution, row_dist=rows, col_dist=cols)
233 92 : n = SIZE(sizes)*copies
234 460 : ALLOCATE (es(n), er(n), ec(n))
235 184 : es = RESHAPE(SPREAD(sizes, 2, copies), [n])
236 184 : er = RESHAPE(SPREAD(rows, 2, copies), [n])
237 184 : ec = RESHAPE(SPREAD(cols, 2, copies), [n])
238 92 : CALL dbcsr_distribution_new(expanded, template=distribution, row_dist=er, col_dist=ec)
239 92 : CALL dbcsr_create(matrix, 'TORUS AO', expanded, dbcsr_type_no_symmetry, es, es)
240 92 : CALL dbcsr_distribution_release(expanded)
241 92 : DEALLOCATE (es, er, ec)
242 184 : END SUBROUTINE create_torus
243 :
244 : ! **************************************************************************************************
245 : !> \brief Inverse discrete Fourier transform of the existing CP2K image convention.
246 : !> \param images Primitive real-space matrices
247 : !> \param spin Component of images
248 : !> \param pairs SCF orbital neighbour list
249 : !> \param kpoints SCF image indexing, not the SCF k-points or weights
250 : !> \param grid Full Gamma-centered property mesh
251 : !> \param antisymmetric Whether images are real SOC components (before multiplication by i)
252 : !> \param matrix New real-cell torus matrix
253 : !> \note This reference assembly uses O(Nk**2) primitive-block operations, but never
254 : !> gathers a dense AO matrix. It intentionally shares rskp_transform conventions.
255 : ! **************************************************************************************************
256 86 : SUBROUTINE lift_fourier(images, spin, pairs, kpoints, grid, antisymmetric, matrix)
257 : TYPE(dbcsr_p_type), POINTER :: images(:, :)
258 : INTEGER, INTENT(IN) :: spin
259 : TYPE(neighbor_list_set_p_type), POINTER :: pairs(:)
260 : TYPE(kpoint_type), POINTER :: kpoints
261 : INTEGER, INTENT(IN) :: grid(3)
262 : LOGICAL, INTENT(IN) :: antisymmetric
263 : TYPE(dbcsr_type), INTENT(OUT) :: matrix
264 :
265 : INTEGER :: ik, ir, n, r(3)
266 : REAL(dp) :: k(3), phase
267 86 : TYPE(dbcsr_p_type), POINTER :: residues(:)
268 : TYPE(dbcsr_type) :: full_im, full_re, im, re
269 :
270 344 : n = PRODUCT(grid)
271 86 : CALL create_torus(images(spin, 1)%matrix, n, matrix)
272 86 : CALL dbcsr_create(re, template=images(spin, 1)%matrix, matrix_type=dbcsr_type_symmetric)
273 86 : CALL dbcsr_create(im, template=images(spin, 1)%matrix, matrix_type=dbcsr_type_antisymmetric)
274 86 : CALL cp_dbcsr_alloc_block_from_nbl(re, pairs)
275 86 : CALL cp_dbcsr_alloc_block_from_nbl(im, pairs)
276 86 : CALL dbcsr_create(full_re, template=re, matrix_type=dbcsr_type_no_symmetry)
277 86 : CALL dbcsr_create(full_im, template=re, matrix_type=dbcsr_type_no_symmetry)
278 682 : ALLOCATE (residues(n))
279 510 : DO ir = 1, n
280 424 : ALLOCATE (residues(ir)%matrix)
281 424 : CALL dbcsr_create(residues(ir)%matrix, template=full_re)
282 510 : CALL dbcsr_finalize(residues(ir)%matrix)
283 : END DO
284 510 : DO ik = 1, n
285 1696 : k = REAL(cell_coordinates(ik, grid), dp)/REAL(grid, dp)
286 424 : CALL dbcsr_set(re, 0.0_dp)
287 424 : CALL dbcsr_set(im, 0.0_dp)
288 424 : IF (antisymmetric) THEN
289 : ! build_core_ppnl already reverses the SOC integral for swapped atom blocks.
290 : ! Match the band SOC transform; is_complex would apply that sign a second time.
291 228 : CALL rskp_transform(im, re, images, spin, k, kpoints%cell_to_index, pairs)
292 228 : CALL dbcsr_desymmetrize(im, full_re)
293 228 : CALL dbcsr_desymmetrize(re, full_im)
294 : ELSE
295 196 : CALL rskp_transform(re, im, images, spin, k, kpoints%cell_to_index, pairs)
296 196 : CALL dbcsr_desymmetrize(re, full_re)
297 196 : CALL dbcsr_desymmetrize(im, full_im)
298 : END IF
299 3010 : DO ir = 1, n
300 2500 : r = cell_coordinates(ir, grid)
301 10000 : phase = twopi*DOT_PRODUCT(k, REAL(r, dp))
302 2500 : CALL dbcsr_add(residues(ir)%matrix, full_re, 1.0_dp, COS(phase)/REAL(n, dp))
303 2924 : CALL dbcsr_add(residues(ir)%matrix, full_im, 1.0_dp, SIN(phase)/REAL(n, dp))
304 : END DO
305 : END DO
306 510 : DO ir = 1, n
307 424 : r = cell_coordinates(ir, grid)
308 510 : CALL lift_blocks(residues(ir)%matrix, grid, r, 0, .FALSE., matrix)
309 : END DO
310 86 : CALL dbcsr_finalize(matrix)
311 86 : CALL dbcsr_deallocate_matrix_set(residues)
312 86 : CALL dbcsr_release(re)
313 86 : CALL dbcsr_release(im)
314 86 : CALL dbcsr_release(full_re)
315 86 : CALL dbcsr_release(full_im)
316 172 : END SUBROUTINE lift_fourier
317 :
318 : ! **************************************************************************************************
319 : !> \brief Lift ordered Berry integrals with the phase of every translated bra cell.
320 : !> \param cosmat Primitive ordered cosine integrals
321 : !> \param sinmat Primitive ordered sine integrals
322 : !> \param cells Integer image labels
323 : !> \param grid Torus dimensions
324 : !> \param axis Direction of the reciprocal torus coordinate
325 : !> \param cosine Full torus cosine
326 : !> \param sine Full torus sine
327 : ! **************************************************************************************************
328 38 : SUBROUTINE lift_berry(cosmat, sinmat, cells, grid, axis, cosine, sine)
329 : TYPE(dbcsr_p_type), INTENT(INOUT) :: cosmat(:, :), sinmat(:, :)
330 : INTEGER, INTENT(IN) :: cells(:, :), grid(3), axis
331 : TYPE(dbcsr_type), INTENT(INOUT) :: cosine, sine
332 :
333 : INTEGER :: ir
334 :
335 2140 : DO ir = 1, SIZE(cells, 2)
336 2102 : CALL lift_blocks(cosmat(1, ir)%matrix, grid, cells(:, ir), axis, .FALSE., cosine)
337 2102 : CALL lift_blocks(sinmat(1, ir)%matrix, grid, cells(:, ir), -axis, .TRUE., cosine)
338 2102 : CALL lift_blocks(cosmat(1, ir)%matrix, grid, cells(:, ir), axis, .TRUE., sine)
339 2140 : CALL lift_blocks(sinmat(1, ir)%matrix, grid, cells(:, ir), axis, .FALSE., sine)
340 : END DO
341 38 : CALL dbcsr_finalize(cosine)
342 38 : CALL dbcsr_finalize(sine)
343 38 : END SUBROUTINE lift_berry
344 :
345 : ! **************************************************************************************************
346 : !> \brief Translate primitive AO blocks onto the torus without changing MPI ownership.
347 : !> \param source Fully stored primitive matrix for one displacement
348 : !> \param grid Torus dimensions
349 : !> \param displacement Ket-cell displacement relative to the bra
350 : !> \param axis Zero for no phase, signed reciprocal direction otherwise
351 : !> \param sine Use sine rather than cosine of the translation phase
352 : !> \param destination Accumulated torus matrix
353 : ! **************************************************************************************************
354 17692 : SUBROUTINE lift_blocks(source, grid, displacement, axis, sine, destination)
355 : TYPE(dbcsr_type), INTENT(INOUT) :: source
356 : INTEGER, INTENT(IN) :: grid(3), displacement(3), axis
357 : LOGICAL, INTENT(IN) :: sine
358 : TYPE(dbcsr_type), INTENT(INOUT) :: destination
359 :
360 : INTEGER :: blocks, col, it, iu, row, t(3), u(3)
361 : LOGICAL :: transposed
362 : REAL(dp) :: factor, phase
363 8846 : REAL(dp), POINTER :: block(:, :)
364 : TYPE(dbcsr_iterator_type) :: iterator
365 :
366 8846 : CALL dbcsr_get_info(source, nblkrows_total=blocks)
367 8846 : CALL dbcsr_iterator_start(iterator, source)
368 20373 : DO WHILE (dbcsr_iterator_blocks_left(iterator))
369 11527 : CALL dbcsr_iterator_next_block(iterator, row, col, block, transposed=transposed)
370 11527 : CPASSERT(.NOT. transposed)
371 332070 : IF (ALL(block == 0.0_dp)) CYCLE
372 89655 : DO it = 1, PRODUCT(grid)
373 41741 : t = cell_coordinates(it, grid)
374 166964 : u = MODULO(t + displacement, grid)
375 41741 : iu = 1 + u(1) + grid(1)*(u(2) + grid(2)*u(3))
376 41741 : factor = 1.0_dp
377 41741 : IF (axis /= 0) THEN
378 39968 : phase = twopi*REAL(t(ABS(axis)), dp)/REAL(grid(ABS(axis)), dp)
379 39968 : IF (sine) THEN
380 19984 : factor = SIN(phase)
381 : ELSE
382 19984 : factor = COS(phase)
383 : END IF
384 39968 : IF (axis < 0) factor = -factor
385 : END IF
386 39968 : IF (factor == 0.0_dp) CYCLE
387 : CALL dbcsr_put_block(destination, row + (it - 1)*blocks, col + (iu - 1)*blocks, &
388 5361338 : factor*block, summation=.TRUE.)
389 : END DO
390 : END DO
391 8846 : CALL dbcsr_iterator_stop(iterator)
392 8846 : CALL dbcsr_finalize(destination)
393 8846 : END SUBROUTINE lift_blocks
394 :
395 : ! **************************************************************************************************
396 : !> \brief Zero-based cell coordinates with the first axis varying fastest.
397 : !> \param index One-based cell index
398 : !> \param grid Torus dimensions
399 : !> \return Integer lattice coordinates
400 : ! **************************************************************************************************
401 45103 : PURE FUNCTION cell_coordinates(index, grid) RESULT(r)
402 : INTEGER, INTENT(IN) :: index, grid(3)
403 : INTEGER :: r(3)
404 :
405 45103 : r(1) = MODULO(index - 1, grid(1))
406 45103 : r(2) = MODULO((index - 1)/grid(1), grid(2))
407 45103 : r(3) = (index - 1)/(grid(1)*grid(2))
408 45103 : END FUNCTION cell_coordinates
409 : END MODULE qs_localizer_torus
|