Line data Source code
1 : !!****m* ABINIT/m_nonlop
2 : !! NAME
3 : !! m_nonlop
4 : !!
5 : !! FUNCTION
6 : !!
7 : !! COPYRIGHT
8 : !! Copyright (C) 1998-2026 ABINIT group (MT, FDahm)
9 : !! This file is distributed under the terms of the
10 : !! GNU General Public License, see ~abinit/COPYING
11 : !! or http://www.gnu.org/copyleft/gpl.txt .
12 : !!
13 : !! SOURCE
14 :
15 : #if defined HAVE_CONFIG_H
16 : #include "config.h"
17 : #endif
18 :
19 : #include "abi_common.h"
20 :
21 : ! nvtx related macro definition
22 : #include "nvtx_macros.h"
23 :
24 : module m_nonlop
25 :
26 : use, intrinsic :: iso_c_binding, only: c_loc, c_associated
27 : use defs_basis
28 : use m_errors
29 : use m_abicore
30 : use m_xmpi
31 : use m_xomp
32 : use m_cgtools
33 : use m_gemm_nonlop
34 : use m_gemm_nonlop_gpu
35 : use m_gemm_nonlop_projectors
36 :
37 : use defs_abitypes, only : MPI_type
38 : use m_time, only : timab
39 : use m_fstrings, only : sjoin, itoa, ftoa
40 : use m_hamiltonian, only : gs_hamiltonian_type, KPRIME_H_K, K_H_KPRIME, K_H_K, KPRIME_H_KPRIME
41 : use m_pawcprj, only : pawcprj_type, pawcprj_alloc, pawcprj_free, pawcprj_copy
42 : use m_nonlop_pl, only : nonlop_pl
43 : use m_nonlop_ylm, only : nonlop_ylm
44 :
45 : #if defined HAVE_GPU_CUDA
46 : use m_manage_cuda
47 : #endif
48 : #if defined(HAVE_GPU_MARKERS)
49 : use m_nvtx_data
50 : #endif
51 :
52 : implicit none
53 :
54 : private
55 : !!***
56 :
57 : public :: nonlop
58 : integer,public,save :: nonlop_counter = 0
59 : !!***
60 :
61 : contains
62 : !!***
63 :
64 : !!****f* ABINIT/nonlop
65 : !! NAME
66 : !! nonlop
67 : !!
68 : !! FUNCTION
69 : !! This routine is a driver to compute:
70 : !! * Application of a nonlocal operator Vnl_k_k^prime in order to get:
71 : !! - contracted elements (energy, forces, stresses, ...), if signs=1
72 : !! - a function in reciprocal space (|out> = Vnl|in>), if signs=2
73 : !! * Optionally, in case of PAW calculation:
74 : !! - Application of the overlap matrix in reciprocal space (<in|S|in> or (I+S)|in>).
75 : !! - Application of (Vnl-lambda.S) in reciprocal space
76 : !! According to user's choice, the routine calls a subroutine, computing all quantities:
77 : !! - using Legendre Polynomials Pl (Norm-conserving psps only)
78 : !! - using Spherical Harmonics Ylm (N-conserving or PAW; compulsory for PAW)
79 : !! - using GPUs (N-conserving or PAW)
80 : !!
81 : !! INPUTS
82 : !! choice: chooses possible output:
83 : !! choice=0 => do nothing (only compute WF projected with NL projectors)
84 : !! =1 => non-local energy contribution
85 : !! =2 => 1st derivative(s) with respect to atomic position(s)
86 : !! =3 => 1st derivative(s) with respect to strain(s)
87 : !! =22=> mixed 2nd derivative(s) with respect to atomic pos. and q vector (at q=0)
88 : !! =25=> mixed 3rd derivative(s) with respect to atomic pos. and two q vectors (at q=0)
89 : !! =23=> 1st derivative(s) with respect to atomic pos. and
90 : !! 1st derivative(s) with respect to atomic pos. and strains
91 : !! =4 => 2nd derivative(s) with respect to 2 atomic pos.
92 : !! =24=> 1st derivative(s) with respect to atm. pos. and
93 : !! 2nd derivative(s) with respect to 2 atomic pos.
94 : !! =33=> mixed 2nd derivative(s) with respect to strain and q vector (at q=0)
95 : !! =5 => 1st derivative(s) with respect to k wavevector, typically
96 : !! sum_ij [ |p_i> D_ij <dp_j/dk| + |dp_i/dk> D_ij < p_j| ]
97 : !! =6 => 2nd derivative(s) with respect to 2 strains and
98 : !! mixed 2nd derivative(s) with respect to strains & atomic pos.
99 : !! =51 =>right 1st derivative(s) with respect to k wavevector, typically
100 : !! sum_ij [ |p_i> D_ij <dp_j/dk| ]
101 : !! =52 =>left 1st derivative(s) with respect to k wavevector, typically
102 : !! sum_ij [ |dp_i/dk> D_ij < p_j| ]
103 : !! =53 =>twist 1st derivative(s) with respect to k, typically
104 : !! sum_ij [ |dp_i/dk_(idir+1)> D_ij <dp_j//dk_(idir+2)|
105 : !! where idir, idir+1, idir+2 taken mod 3
106 : !! =54=> mixed 2nd derivative(s) with respect to atomic pos. and left k wavevector
107 : !! =55=> mixed 2nd derivative(s) with respect to strain and right k wavevector
108 : !! =7 => apply operator $\sum_i [ |p_i> <p_i| ],
109 : !! same as overlap operator with s_ij=identity (paw_opt==3 only)
110 : !! =8 => 2nd derivatives with respect to 2 k wavevectors
111 : !! =81=> partial 2nd derivatives with respect to 2 k wavevectors,
112 : !! full derivative with respect to k1, right derivative with respect to k2,
113 : !! (derivative with respect to k of choice 51), typically
114 : !! sum_ij [ |dp_i/dk1> D_ij <dp_j/dk2| + |p_i> D_ij < d2p_j/dk1dk2| ]
115 : !! Only choices 1,2,3,23,4,5,6 are compatible with useylm=0.
116 : !! Only choices 1,2,22,25,3,5,33,51,52,53,7,8,81 are compatible with signs=2
117 : !! cpopt=flag defining the status of cprjin%cp(:)=<Proj_i|Cnk> scalars (see below, side effects)
118 : !! [enl]=optional (if not present, use hamk%ekb); non-local coeffs connecting projectors
119 : !! see hamk%ekb description
120 : !! hamk <type(gs_hamiltonian_type)>=data defining the Hamiltonian at a given k (NL part involved here)
121 : !! | atindx1(natom)=index table for atoms, inverse of atindx
122 : !! | dimekb1,dimekb2=dimensions of ekb (see ham%ekb)
123 : !! | dimekbq=1 if enl factors do not contain a exp(-iqR) phase, 2 is they do
124 : !! | ekb(dimekb1,dimekb2,nspinor**2,dimekbq)=
125 : !! | ->NC psps (paw_opt=0): Kleinman-Bylander energies (hartree)
126 : !! | dimekb1=lmnmax, dimekb2=ntypat
127 : !! | ->PAW (paw_opt=1 or 4): Dij coeffs connecting projectors (ij symmetric)
128 : !! | dimekb1=cplex_ekb*lmnmax*(lmnmax+1)/2, dimekb2=natom
129 : !! | Complex numbers if cplex_ekb=2
130 : !! | ekb(:,:,1)= Dij^up-up, ekb(:,:,2)= Dij^dn-dn
131 : !! | ekb(:,:,3)= Dij^up-dn, ekb(:,:,4)= Dij^dn-up (only if nspinor=2)
132 : !! | ffnl_k(npw_k,dimffnl_k,lmnmax,ntypat)=nonlocal form factors at k
133 : !! | ffnl_kp(npw_kp,dimffnl_kp,lmnmax,ntypat)=nonlocal form factors at k^prime
134 : !! | gmet(3,3)=metric tensor for G vecs (in bohr**-2)
135 : !! | gprimd(3,3)=dimensional reciprocal space primitive translations
136 : !! | indlmn(6,i,ntypat)= array giving l,m,n,lm,ln,s for i=ln (useylm=0) or i=lmn (useylm=1)
137 : !! | istwf_k=option parameter that describes the storage of wfs at k
138 : !! | istwf_kp=option parameter that describes the storage of wfs at k^prime
139 : !! | lmnmax=max. number of (l,m,n) components over all types of atoms
140 : !! | matblk=dimension of the arrays ph3d_k and ph3d_kp
141 : !! | mgfft=maximum size of 1D FFTs
142 : !! | mpsang= 1+maximum angular momentum for nonlocal pseudopotentials
143 : !! | mpssoang= 1+max(spin*angular momentum) for nonlocal pseudopotentials
144 : !! | natom=number of atoms in cell
145 : !! | nattyp(ntypat)=number of atoms of each type
146 : !! | ngfft(18)=contain all needed information about 3D FFT
147 : !! ! kg_k(3,npw_k)=integer coords of planewaves in basis sphere, for k
148 : !! ! kg_kp(3,npw_kp)=integer coords of planewaves in basis sphere, for k^prime
149 : !! ! kpg_k(npw_k,:)= (k+G) components and related data
150 : !! ! kpg_kp(npw_kp,:)=(k^prime+G) components and related data,
151 : !! ! kpt(3)=k point in terms of recip. translations
152 : !! ! kptp(3)=k^prime point in terms of recip. translations
153 : !! | nloalg(3)=governs the choice of the algorithm for nonlocal operator
154 : !! ! npw_k=number of (k+G) planewaves
155 : !! ! npw_kp=number of (k^prime+G) planewaves
156 : !! | ntypat=number of types of atoms in cell
157 : !! | nspinor=total number of spinorial components of the wavefunctions
158 : !! | ph1d(2,3*(2*mgfft+1)*natom)=1D structure factors phase information
159 : !! | ph3d_k(2,npw_k,matblk)=3D structure factors, for each atom and (k+g) plane wave
160 : !! | ph3d_kp(2,npw_kp,matblk)=3-dim structure factors, for each atom and (k^prime+g) plane wave
161 : !! | phkxred(2,natom)=phase factors exp(2 pi k.xred)
162 : !! | phkpxred(2,natom)=phase factors exp(2 pi k^prime.xred)
163 : !! | sij(dimekb1,ntypat)=overlap matrix components (only if paw_opt=2, 3 or 4)
164 : !! | ucvol=unit cell volume (bohr^3)
165 : !! | gpu_option= GPU implementation to use, i.e. cuda, openMP, ... (0=not using GPU)
166 : !! | useylm=how the NL operator is to be applied: 1=using Ylm, 0=using Legendre polynomials
167 : !! [iatom_only]=optional. If present (and >0), only projectors related to atom of index iatom_only
168 : !! will be applied. (used fi to apply derivative of NL operator wrt an atomic displacement)
169 : !! idir=direction of the - atom to be moved in the case (choice=2,signs=2) or (choice=22,signs=2)
170 : !! - k point direction in the case (choice=5,51,or 52)
171 : !! for choice 53 signs=2, cross derivatives are in idir+1 and idir+2 directions (mod 3)
172 : !! - strain component (1:6) in the case (choice=3,signs=2) or (choice=6,signs=1)
173 : !! - strain component (1:9) in the case (choice=33,signs=2)
174 : !! - (1:9) components to specify the atom to be moved and the second q-gradient
175 : !! direction in the case (choice=25,signs=2)
176 : !! lambda=factor to be used when computing (Vln-lambda.S) - only for paw_opt=2
177 : !! Typically lambda is the eigenvalue (or its guess)
178 : !! mpi_enreg=information about MPI parallelization
179 : !! ndat=number of wavefunctions on which to apply nonlop
180 : !! nnlout=dimension of enlout (when signs=1 and choice>0):
181 : !! ==== if paw_opt=0, 1 or 2 ====
182 : !! choice nnlout | choice nnlout
183 : !! 1 1 | 51 6 (complex)
184 : !! 2 3*natom | 52 6 (complex)
185 : !! 3 6 | 53 6 (complex)
186 : !! 4 6*natom | 54 9*natom
187 : !! 23 6+3*natom | 55 36 (complex)
188 : !! 24 9*natom | 6 36+18*natom
189 : !! 5 3 | 8 6
190 : !! | 81 18 (complex)
191 : !! ==== if paw_opt=3 ====
192 : !! choice nnlout
193 : !! 1 1
194 : !! 2 3*natom
195 : !! 5 3
196 : !! 51 3
197 : !! 52 3
198 : !! 54 9*natom
199 : !! 55 36
200 : !! 7 1
201 : !! 8 6
202 : !! 81 9
203 : !! ==== if paw_opt=4 ====
204 : !! not available
205 : !! [only_SO]=optional, flag to calculate only the SO part in nonlop
206 : !! paw_opt= define the nonlocal operator concerned with:
207 : !! paw_opt=0 : Norm-conserving Vnl (use of Kleinman-Bylander ener.)
208 : !! paw_opt=1 : PAW nonlocal part of H (use of Dij coeffs)
209 : !! paw_opt=2 : PAW: (Vnl-lambda.Sij) (Sij=overlap matrix)
210 : !! paw_opt=3 : PAW overlap matrix (Sij)
211 : !! paw_opt=4 : both PAW nonlocal part of H (Dij) and overlap matrix (Sij)
212 : !! [qdir]= optional, direction of the q-gradient (only for choice=22, choice=25 and choice=33)
213 : !! [select_k]=optional, option governing the choice of k points to be used.
214 : !! hamk datastructure contains quantities needed to apply NL operator
215 : !! in reciprocal space between 2 kpoints, k and k^prime (equal in most cases);
216 : !! if select_k=1, <k^prime|Vnl|k> is applied [default]
217 : !! if select_k=2, <k|Vnl|k^prime> is applied
218 : !! if select_k=3, <k|Vnl|k> is applied
219 : !! if select_k=4, <k^prime|Vnl|k^prime> is applied
220 : !! signs= if 1, get contracted elements (energy, forces, stress, ...)
221 : !! if 2, applies the non-local operator to a function in reciprocal space
222 : !! tim_nonlop=timing code of the calling routine (can be set to 0 if not attributed)
223 : !! vectin(2,npwin*my_nspinor*ndat)=input cmplx wavefunction coefficients <G|Cnk>
224 : !! vectproj(2,nprojs,my_nspinor*ndat)=Optional, vector to be used instead of cprjin%cp when provided
225 : !!
226 : !! OUTPUT
227 : !! ==== if (signs==1) ====
228 : !! --If (paw_opt==0, 1 or 2)
229 : !! enlout(nnlout)= contribution to the non-local part of the following properties:
230 : !! if choice=1 : enlout(1) -> the energy
231 : !! if choice=2 : enlout(3*natom) -> 1st deriv. of energy wrt atm. pos (forces)
232 : !! if choice=3 : enlout(6) -> 1st deriv. of energy wrt strain (stresses)
233 : !! if choice=4 : enlout(6*natom) -> 2nd deriv. of energy wrt 2 atm. pos (dyn. mat.)
234 : !! if choice=23: enlout(6+3*natom) -> 1st deriv. of energy wrt atm. pos (forces) and
235 : !! 1st deriv. of energy wrt strain (stresses)
236 : !! if choice=24: enlout(9*natom) -> 1st deriv. of energy wrt atm. pos (forces) and
237 : !! 2nd deriv. of energy wrt 2 atm. pos (dyn. mat.)
238 : !! if choice=5 : enlout(3) -> 1st deriv. of energy wrt k
239 : !! if choice=51: enlout(3) -> 1st deriv. (right) of energy wrt k
240 : !! if choice=52: enlout(3) -> 1st deriv. (left) of energy wrt k
241 : !! if choice=53: enlout(3) -> 1st deriv. (twist) of energy wrt k
242 : !! if choice=54: enlout(18*natom) -> 2nd deriv. of energy wrt atm. pos and right k (Born eff. charge)
243 : !! if choice=55: enlout(36) -> 2nd deriv. of energy wrt strain and right k (piezoelastic tensor)
244 : !! if choice=6 : enlout(36+18*natom) -> 2nd deriv. of energy wrt 2 strains (elast. tensor) and
245 : !! 2nd deriv. of energy wrt to atm. pos and strain (internal strain)
246 : !! if choice=8 : enlout(6) -> 2nd deriv. of energy wrt 2 k
247 : !! if choice=81: enlout(9) -> 2nd deriv.of E: full derivative w.r.t. k1, right derivative w.r.t k2
248 : !! --If (paw_opt==3)
249 : !! if choice=1 : enlout(1) -> contribution to <c|S|c> (note: not including <c|c>)
250 : !! if choice=2 : enlout(3*natom) -> contribution to <c|dS/d_atm.pos|c>
251 : !! if choice=51: enlout(3) -> contribution to <c|d(right)S/d_k|c>
252 : !! if choice=52: enlout(3) -> contribution to <c|d(left)S/d_k|c>
253 : !! if choice=54: enlout(18*natom) -> 2nd deriv. of energy wrt atm. pos and right k (Born eff. charge)
254 : !! if choice=55: enlout(36) -> 2nd deriv. of energy wrt strain and right k (piezoelastic tensor)
255 : !! if choice=7 : enlout(1) -> contribution to <c|sum_i[p_i><p_i]|c>
256 : !! if choice=8 : enlout(6) -> contribution to <c|d2S/d_k1d_k2|c>
257 : !! if choice=81: enlout(9) -> contribution to <c|dS/d_k1[d(right)d_k2]|c>
258 : !! --If (paw_opt==4)
259 : !! not available
260 : !! ==== if (signs==2) ====
261 : !! --if (paw_opt=0)
262 : !! vectout(2,npwout*my_nspinor*ndat)=result of the application of the concerned operator
263 : !! or one of its derivatives to the input vect.
264 : !! if (choice=22) <G|d2V_nonlocal/d(atm. pos)dq|vect_in> (at q=0)
265 : !! if (choice=25) <G|d3V_nonlocal/d(atm. pos)dqdq|vect_in> (at q=0)
266 : !! if (choice=33) <G|d2V_nonlocal/d(strain)dq|vect_in> (at q=0)
267 : !! --if (paw_opt=0, 1 or 4)
268 : !! vectout(2,npwout*my_nspinor*ndat)=result of the application of the concerned operator
269 : !! or one of its derivatives to the input vect.:
270 : !! if (choice=1) <G|V_nonlocal|vect_in>
271 : !! if (choice=2) <G|dV_nonlocal/d(atm. pos)|vect_in>
272 : !! if (choice=3) <G|dV_nonlocal/d(strain)|vect_in>
273 : !! if (choice=5) <G|dV_nonlocal/d(k)|vect_in>
274 : !! if (choice=51) <G|d(right)V_nonlocal/d(k)|vect_in>
275 : !! if (choice=52) <G|d(left)V_nonlocal/d(k)|vect_in>
276 : !! if (choice=53) <G|d(twist)V_nonlocal/d(k)|vect_in>
277 : !! if (choice=8) <G|d2V_nonlocal/d(k)d(k)|vect_in>
278 : !! if (choice=81) <G|d[d(right)V_nonlocal/d(k)]/d(k)|vect_in>
279 : !! --if (paw_opt=2)
280 : !! vectout(2,npwout*my_nspinor*ndat)=final vector in reciprocal space:
281 : !! if (choice=1) <G|V_nonlocal-lambda.(I+S)|vect_in>
282 : !! if (choice=2) <G|d[V_nonlocal-lambda.(I+S)]/d(atm. pos)|vect_in>
283 : !! if (choice=3) <G|d[V_nonlocal-lambda.(I+S)]/d(strain)|vect_in>
284 : !! if (choice=5) <G|d[V_nonlocal-lambda.(I+S)]/d(k)|vect_in>
285 : !! if (choice=51) <G|d(right)[V_nonlocal-lambda.(I+S)]/d(k)|vect_in>
286 : !! if (choice=52) <G|d(left)[V_nonlocal-lambda.(I+S)]/d(k)|vect_in>
287 : !! if (choice=53) <G|d(twist)[V_nonlocal-lambda.(I+S)]/d(k)|vect_in>
288 : !! if (choice=8) <G|d2[V_nonlocal-lambda.(I+S)]/d(k)d(k)|vect_in>
289 : !! if (choice=81) <G|d[d(right[V_nonlocal-lambda.(I+S)]/d(k)]/d(k)|vect_in>
290 : !! --if (paw_opt=3 or 4)
291 : !! svectout(2,npwout*my_nspinor*ndat)=result of the application of Sij (overlap matrix)
292 : !! or one of its derivatives to the input vect.:
293 : !! if (choice=1) <G|I+S|vect_in>
294 : !! if (choice=2) <G|dS/d(atm. pos)|vect_in>
295 : !! if (choice=3) <G|dS/d(strain)|vect_in>
296 : !! if (choice=5) <G|dS/d(k)|vect_in>
297 : !! if (choice=51) <G|d(right)S/d(k)|vect_in>
298 : !! if (choice=52) <G|d(left)S/d(k)|vect_in>
299 : !! if (choice=53) <G|d(twist)S/d(k)|vect_in>
300 : !! if (choice=3) <G|d[V_nonlocal-lambda.(I+S)]/d(strain)|vect_in>
301 : !! if (choice=7) <G|sum_i[p_i><p_i]|vect_in>
302 : !! if (choice=8) <G|d2S/d(k)d(k)|vect_in>
303 : !! if (choice=81) <G|d[d(right)S/d(k)]/d(k)|vect_in>
304 : !!
305 : !! SIDE EFFECTS
306 : !! ==== ONLY IF useylm=1
307 : !! cprjin(natom,my_nspinor*ndat) <type(pawcprj_type)>=projected input wave function |in> on non-local projectors
308 : !! =<p_lmn|in> and derivatives
309 : !! Treatment depends on cpopt parameter:
310 : !! if cpopt=-1, <p_lmn|in> (and derivatives)
311 : !! are computed here (and not saved)
312 : !! if cpopt= 0, <p_lmn|in> are computed here and saved
313 : !! derivatives are eventually computed but not saved
314 : !! if cpopt= 1, <p_lmn|in> and first derivatives are computed here and saved
315 : !! other derivatives are eventually computed but not saved
316 : !! if cpopt= 2 <p_lmn|in> are already in memory;
317 : !! first (and 2nd) derivatives are computed here and not saved
318 : !! if cpopt= 3 <p_lmn|in> are already in memory;
319 : !! first derivatives are computed here and saved
320 : !! other derivatives are eventually computed but not saved
321 : !! if cpopt= 4 <p_lmn|in> and first derivatives are already in memory;
322 : !! other derivatives are not computed
323 : !! This option is not compatible with choice=4,24 or 6
324 : !! If useylm=0, must have cpopt=-1!
325 : !! Warning: for cpopt= 1 or 3, derivatives wrt strains do not contain
326 : !! the contribution due to the volume change;
327 : !! i.e. <dp_lmn/dEps|in> are incomplete.
328 : !!
329 : !! NOTES
330 : !! * See nonlop_pl and nonlop_ylm to have more comments...
331 : !! * In the case signs=1, the array vectout is not used.
332 : !!
333 : !! SOURCE
334 :
335 101619076 : subroutine nonlop(choice,cpopt,cprjin,enlout,hamk,idir,lambda,mpi_enreg,ndat,nnlout,&
336 50809538 : paw_opt,signs,svectout,tim_nonlop,vectin,vectout,&
337 203238152 : cprjin_left,enl,enl_ndat,enlout_im,iatom_only,ndat_left,only_SO,qdir,select_k,vectproj) !optional arguments
338 :
339 : !Arguments ------------------------------------
340 : !scalars
341 : integer,intent(in) :: choice,cpopt,idir,ndat,nnlout,paw_opt,signs,tim_nonlop
342 : integer,intent(in),optional :: iatom_only,only_SO,qdir,ndat_left,select_k
343 : type(MPI_type),intent(in) :: mpi_enreg
344 : type(gs_hamiltonian_type),intent(in),target :: hamk
345 : !arrays
346 : real(dp),intent(in) :: lambda(ndat)
347 : real(dp),contiguous, intent(in),target,optional :: enl(:,:,:,:),enl_ndat(:,:,:,:,:)
348 : real(dp),intent(inout),target :: vectin(:,:)
349 : real(dp),intent(out),target :: enlout(:),svectout(:,:)
350 : real(dp),intent(out),optional :: enlout_im(:)
351 : real(dp),intent(inout),target :: vectout(:,:)
352 : type(pawcprj_type),intent(inout),target :: cprjin(:,:)
353 : type(pawcprj_type),intent(inout),target,optional :: cprjin_left(:,:)
354 : real(dp),intent(inout), contiguous, optional :: vectproj(:,:,:)
355 :
356 : !Local variables-------------------------------
357 : !scalars
358 : integer :: dimenl1,dimenl2,dimenl2_,dimekbq,dimffnlin,dimffnlout,dimsij,iatm,iatom_only_,idat
359 : integer :: ii,ispden,ispinor,istwf_k,itypat,jspinor,matblk_,my_nspinor,n1,n2,n3,natom_,ncpgr_atm,ndat_left_
360 : integer :: nkpgin,nkpgout,npwin,npwout,ntypat_,only_SO_,select_k_,shift1,shift2,shift3
361 : logical :: atom_pert,force_recompute_ph3d,kpgin_allocated,kpgout_allocated, use_gemm_nonlop
362 : !character(len=500) :: msg
363 : !arrays
364 : integer :: nlmn_atm(1),nloalg_(3)
365 50809538 : integer,pointer :: kgin(:,:),kgout(:,:)
366 50809538 : integer, contiguous, pointer :: atindx1_(:),indlmn_(:,:,:),nattyp_(:)
367 : real(dp) :: tsec(2)
368 50809538 : real(dp), contiguous, pointer :: enl_ptr(:,:,:,:),enl_ndat_ptr(:,:,:,:,:)
369 50809538 : real(dp),pointer :: ffnlin(:,:,:,:),ffnlin_(:,:,:,:),ffnlout(:,:,:,:),ffnlout_(:,:,:,:)
370 50809538 : real(dp),pointer :: kpgin(:,:),kpgout(:,:)
371 : real(dp) :: kptin(3),kptout(3)
372 50809538 : real(dp),pointer :: ph3din(:,:,:),ph3din_(:,:,:),ph3dout(:,:,:),ph3dout_(:,:,:)
373 50809538 : real(dp),pointer :: phkxredin(:,:),phkxredin_(:,:),phkxredout(:,:),phkxredout_(:,:)
374 50809538 : real(dp), contiguous, pointer :: ph1d_(:,:),sij_(:,:)
375 50809538 : real(dp), contiguous, pointer :: enl__(:,:,:,:),enl_ndat_(:,:,:,:,:)
376 50809538 : type(pawcprj_type),pointer :: cprjin_(:,:)
377 : integer :: b0,b1,b2,b3,b4,e0,e1,e2,e3,e4
378 : integer :: proj_shift,ia,nlmn
379 : integer :: shift,shift_forces,shift_stress
380 : integer :: nnlout_forces,nnlout_stress
381 50809538 : real(dp), allocatable :: enlout_forces(:),enlout_stress(:)
382 : ! **********************************************************************
383 :
384 : DBG_ENTER("COLL")
385 :
386 : !Keep track of time spent in this routine (selection of different slots for different choices)
387 50809538 : call timab(220+tim_nonlop,1,tsec)
388 :
389 : ! Increment global counter
390 : !$OMP MASTER
391 50809538 : nonlop_counter = nonlop_counter + ndat
392 : !$OMP END MASTER
393 :
394 50809538 : only_SO_=0; if (present(only_SO)) only_SO_=only_SO
395 50809538 : my_nspinor=max(1,hamk%nspinor/mpi_enreg%nproc_spinor)
396 :
397 50809538 : force_recompute_ph3d=.false.
398 :
399 : ! Error(s) on incorrect input
400 50809538 : if (hamk%useylm==0) then
401 28937731 : if (paw_opt>0) then
402 0 : ABI_BUG('When paw_opt>0 you must use ylm version of nonlop! Set useylm 1.')
403 : end if
404 28937731 : if (cpopt/=-1) then
405 0 : ABI_BUG('If useylm=0, ie no PAW, then cpopt/=-1 is not allowed !')
406 : end if
407 28937731 : if (hamk%dimekbq/=1) then
408 0 : ABI_BUG('If useylm=0, ie no PAW, then dimekbq/=-1 is not allowed !')
409 : end if
410 28937731 : if (hamk%gpu_option/=ABI_GPU_DISABLED) then
411 0 : ABI_BUG('When gpu_option/=0 you must use ylm version of nonlop! Set useylm to 1.')
412 : end if
413 : end if
414 50809538 : if (hamk%gpu_option/=ABI_GPU_DISABLED.and.hamk%dimekbq/=1) then
415 0 : ABI_BUG('GPU version of nonlop not compatible with a exp(-iqR) phase!')
416 : end if
417 50809538 : if ((.not.associated(hamk%kg_k)).or.(.not.associated(hamk%kg_kp))) then
418 0 : ABI_BUG('kg_k/kg_kp should be associated!')
419 : end if
420 50809538 : if ((.not.associated(hamk%ffnl_k)).or.(.not.associated(hamk%ffnl_kp))) then
421 0 : ABI_BUG('ffnl_k/ffnl_kp should be associated!')
422 : end if
423 : !if (hamk%istwf_k/=hamk%istwf_kp) then
424 : ! ABI_BUG('istwf has to be the same for both k-points.')
425 : !end if
426 :
427 50809538 : if (present(enl) .and. present(enl_ndat)) then
428 0 : ABI_BUG("enl and enl_ndat cannot be specified concurrently !")
429 : end if
430 :
431 : !Select k-dependent objects according to select_k input parameter
432 50809538 : select_k_=KPRIME_H_K;if (present(select_k)) select_k_=select_k
433 : ! If both K-Kprime variant of each attribute of hamiltonian share the same
434 : ! address, we can assume select_k==K_H_K.
435 : if ( c_associated(c_loc(hamk%ffnl_k), c_loc(hamk%ffnl_kp)) &
436 81931562 : .and. c_associated(c_loc(hamk%kg_k), c_loc(hamk%kg_kp))) then
437 19687514 : if (associated(hamk%ph3d_k).and.associated(hamk%ph3d_kp)) then
438 19667122 : if (c_associated(c_loc(hamk%ph3d_k), c_loc(hamk%ph3d_kp))) then
439 19667122 : select_k_=K_H_K
440 : end if
441 : else
442 20392 : select_k_=K_H_K
443 : end if
444 : end if
445 50809538 : nkpgin=0;nkpgout=0;nullify(kpgin);nullify(kpgout)
446 50809538 : nullify(ph3din);nullify(ph3dout)
447 : !print *, "in nonlop with select_k:", select_k_
448 :
449 50809538 : if (select_k_==KPRIME_H_K) then
450 : ! ===== <k^prime|Vnl|k> =====
451 68614616 : kptin = hamk%kpt_k ; kptout = hamk%kpt_kp
452 9802088 : npwin=hamk%npw_fft_k ; npwout=hamk%npw_fft_kp
453 9802088 : kgin => hamk%kg_k ; kgout => hamk%kg_kp
454 9802088 : if (associated(hamk%kpg_k)) then
455 9802088 : kpgin => hamk%kpg_k ; nkpgin=size(kpgin,2)
456 : end if
457 9802088 : if (associated(hamk%kpg_kp)) then
458 9802088 : kpgout => hamk%kpg_kp ; nkpgout=size(kpgout,2)
459 : end if
460 9802088 : phkxredin => hamk%phkxred ; phkxredout => hamk%phkpxred
461 9802088 : ffnlin => hamk%ffnl_k ; ffnlout => hamk%ffnl_kp
462 9802088 : if (associated(hamk%ph3d_k )) ph3din => hamk%ph3d_k
463 9802088 : if (associated(hamk%ph3d_kp)) ph3dout => hamk%ph3d_kp
464 9802088 : force_recompute_ph3d=(.not.(associated(hamk%ph3d_k).and.associated(hamk%ph3d_kp)))
465 9802088 : istwf_k=hamk%istwf_k
466 41007450 : else if (select_k_==K_H_KPRIME) then
467 : ! ===== <k|Vnl|k^prime> =====
468 250292 : kptin = hamk%kpt_kp ; kptout = hamk%kpt_k
469 35756 : npwin=hamk%npw_fft_kp ; npwout=hamk%npw_fft_k
470 35756 : kgin => hamk%kg_kp ; kgout => hamk%kg_k
471 35756 : if (associated(hamk%kpg_kp)) then
472 35756 : kpgin => hamk%kpg_kp ; nkpgin=size(kpgin,2)
473 : end if
474 35756 : if (associated(hamk%kpg_k)) then
475 35756 : kpgout => hamk%kpg_k ; nkpgout=size(kpgout,2)
476 : end if
477 35756 : phkxredin => hamk%phkpxred ; phkxredout => hamk%phkxred
478 35756 : ffnlin => hamk%ffnl_kp ; ffnlout => hamk%ffnl_k
479 35756 : if (associated(hamk%ph3d_kp)) ph3din => hamk%ph3d_kp
480 35756 : if (associated(hamk%ph3d_k )) ph3dout => hamk%ph3d_k
481 35756 : force_recompute_ph3d=(.not.(associated(hamk%ph3d_kp).and.associated(hamk%ph3d_k)))
482 35756 : istwf_k=hamk%istwf_kp
483 40971694 : else if (select_k_==K_H_K) then
484 : ! ===== <k|Vnl|k> =====
485 138796616 : kptin = hamk%kpt_k ; kptout = hamk%kpt_k
486 19828088 : npwin=hamk%npw_fft_k ; npwout=hamk%npw_fft_k
487 19828088 : kgin => hamk%kg_k ; kgout => hamk%kg_k
488 19828088 : if (associated(hamk%kpg_k)) then
489 19578558 : kpgin => hamk%kpg_k ; nkpgin=size(kpgin,2)
490 : end if
491 19828088 : if (associated(hamk%kpg_k)) then
492 19578558 : kpgout => hamk%kpg_k ; nkpgout=size(kpgout,2)
493 : end if
494 19828088 : phkxredin => hamk%phkxred ; phkxredout => hamk%phkxred
495 19828088 : ffnlin => hamk%ffnl_k ; ffnlout => hamk%ffnl_k
496 19828088 : if (associated(hamk%ph3d_k)) ph3din => hamk%ph3d_k
497 19828088 : if (associated(hamk%ph3d_k)) ph3dout => hamk%ph3d_k
498 19828088 : force_recompute_ph3d=(.not.(associated(hamk%ph3d_k)))
499 19828088 : istwf_k=hamk%istwf_k
500 21143606 : else if (select_k_==KPRIME_H_KPRIME) then
501 : ! ===== <k^prime|Vnl|k^prime> =====
502 148005242 : kptin = hamk%kpt_kp ; kptout = hamk%kpt_kp
503 21143606 : npwin=hamk%npw_fft_kp ; npwout=hamk%npw_fft_kp
504 21143606 : kgin => hamk%kg_kp ; kgout => hamk%kg_kp
505 21143606 : if (associated(hamk%kpg_kp)) then
506 21143606 : kpgin => hamk%kpg_kp ; nkpgin=size(kpgin,2)
507 : end if
508 21143606 : if (associated(hamk%kpg_kp)) then
509 21143606 : kpgout => hamk%kpg_kp ; nkpgout=size(kpgout,2)
510 : end if
511 21143606 : phkxredin => hamk%phkpxred ; phkxredout => hamk%phkpxred
512 21143606 : ffnlin => hamk%ffnl_kp ; ffnlout => hamk%ffnl_kp
513 21143606 : if (associated(hamk%ph3d_kp)) ph3din => hamk%ph3d_kp
514 21143606 : if (associated(hamk%ph3d_kp)) ph3dout => hamk%ph3d_kp
515 21143606 : force_recompute_ph3d=(.not.(associated(hamk%ph3d_kp)))
516 21143606 : istwf_k=hamk%istwf_kp
517 : end if
518 :
519 50809538 : if (npwin==0.or.npwout==0) return
520 50809538 : dimffnlin=size(ffnlin,2);dimffnlout=size(ffnlout,2)
521 50809538 : kpgin_allocated=(.not.associated(kpgin))
522 50809538 : if (kpgin_allocated) then
523 499060 : ABI_MALLOC(kpgin,(npwin,0))
524 : end if
525 50809538 : kpgout_allocated=(.not.associated(kpgout))
526 50809538 : if (kpgout_allocated) then
527 499060 : ABI_MALLOC(kpgout,(npwout,0))
528 : end if
529 :
530 : !Check some sizes for safety
531 : !if (paw_opt==0.or.cpopt<2.or.((cpopt==2.or.cpopt==3).and.choice>1)) then
532 : !if (size(ffnlin,1)/=npwin.or.size(ffnlin,3)/=hamk%lmnmax) then
533 : ! ABI_BUG('Incorrect size for ffnlin!')
534 : !end if
535 50809538 : if(signs==2) then
536 48982968 : if (size(ffnlout,1)/=npwout.or.size(ffnlout,3)/=hamk%lmnmax) then
537 0 : ABI_BUG('Incorrect size for ffnlout!')
538 : end if
539 : end if
540 50809538 : if (associated(kpgin)) then
541 152428614 : if (size(kpgin) > 0 .and. size(kpgin,1)/=npwin) then
542 0 : ABI_BUG('Incorrect size for kpgin')
543 : end if
544 : end if
545 50809538 : if (associated(kpgout)) then
546 152428614 : if (size(kpgout) > 0 .and. size(kpgout,1)/=npwout) then
547 0 : ABI_BUG('Incorrect size for kpgout')
548 : end if
549 : end if
550 : !This test is OK only because explicit sizes are passed to nonlop_* routines
551 152428614 : if (size(vectin)<2*npwin*my_nspinor*ndat) then
552 : !FB: Allow the usage of nonlop from the "linalg" representation where
553 : !FB: the cg are distributed over the plane waves with npband > 1
554 : !FB: in case signs=1 & choice=1
555 51200 : if (signs==1 .and. choice==1) then
556 51200 : npwin = size(vectin,2)/ndat/my_nspinor
557 : else
558 0 : ABI_BUG('Incorrect size for vectin!')
559 : end if
560 : end if
561 50809538 : if(choice/=0.and.signs==2) then
562 48822162 : if(paw_opt/=3) then
563 : ! This test is OK only because explicit sizes are passed to nonlop_* routines
564 142582896 : ABI_CHECK_IGEQ(size(vectout), 2*npwout*my_nspinor*ndat, 'Incorrect size for vectout!')
565 : end if
566 48822162 : if(paw_opt>=3) then
567 31136925 : ABI_CHECK_IGEQ(size(svectout), 2*npwout*my_nspinor*ndat, 'Incorrect size for svectout!')
568 : end if
569 : end if
570 50809538 : if(cpopt>=0 .and. .not. present(vectproj)) then
571 26011137 : ABI_CHECK_IGEQ(size(cprjin), hamk%natom*my_nspinor*ndat, 'Incorrect size for cprjin!')
572 : end if
573 50809538 : ndat_left_ = 1
574 50809538 : if (present(ndat_left)) then
575 220960 : ndat_left_ = ndat_left
576 : end if
577 50809538 : if(present(cprjin_left)) then
578 662880 : if (size(cprjin_left)/=hamk%natom*my_nspinor*ndat*ndat_left_) then
579 0 : ABI_BUG('Incorrect size for cprjin_left!')
580 : end if
581 : end if
582 :
583 : !Non-local coefficients connecting projectors:
584 : !If enl is present in the arg list, use it; instead use hamk%ebk
585 50809538 : if (present(enl)) then
586 3239256 : enl_ptr => enl
587 3239256 : dimenl1=size(enl,1);dimenl2=size(enl,2);dimekbq=size(enl,4)
588 : else
589 47570282 : enl_ptr => hamk%ekb
590 47570282 : dimenl1=hamk%dimekb1;dimenl2=hamk%dimekb2;dimekbq=1
591 : end if
592 :
593 : ! If enl_ndat is present (meaning enl is absent), use it
594 50809538 : if (present(enl_ndat)) then
595 35756 : enl_ndat_ptr => enl_ndat
596 35756 : dimenl1=size(enl_ndat,1);dimenl2=size(enl_ndat,2);dimekbq=size(enl_ndat,5)
597 : else
598 50773782 : ABI_MALLOC(enl_ndat_ptr, (0,0,0,0,0))
599 : end if
600 :
601 :
602 : !A specific version of nonlop based on BLAS3 can be used
603 : !But there are several restrictions
604 :
605 50809538 : use_gemm_nonlop=.false.
606 50809538 : if (gemm_nonlop_use_gemm) then
607 13942 : use_gemm_nonlop=.true.
608 13942 : if(signs==2) then
609 : use_gemm_nonlop= ( use_gemm_nonlop .and. &
610 : & ( paw_opt /= 2 .and. &
611 : & hamk%useylm /= 0 .and.&
612 : & ((cpopt < 3 .and. (choice < 1 .or. choice == 7)) .or.&
613 11478 : & (choice==1 .or. choice==2 .or. choice==3 .or. choice==5 .or. choice==51))))
614 : !FIXME Derivatives of any kind not handled in CUDA GEMM nonlop
615 11478 : if(choice > 1 .and. choice/=7 .and. (hamk%gpu_option==ABI_GPU_LEGACY .or. hamk%gpu_option==ABI_GPU_KOKKOS)) use_gemm_nonlop=.false.
616 : end if
617 13942 : if(signs==1) then
618 : use_gemm_nonlop= ( use_gemm_nonlop .and. hamk%useylm/=0 .and. &
619 : ! Forces and stress (forstr)
620 : & ( ((choice >= 1 .and. choice <= 3) .or. choice == 23) ) .or. &
621 : ! Rho ij
622 : & choice == 0 .or.&
623 2464 : ( (choice == 54 .or. choice == 55 .or. choice == 4 .or. choice==6) ) )
624 : !FIXME forces and constraints computation not handled in CUDA GEMM nonlop
625 2464 : if(choice > 0 .and. (hamk%gpu_option==ABI_GPU_LEGACY .or. hamk%gpu_option==ABI_GPU_KOKKOS)) use_gemm_nonlop=.false.
626 : end if
627 : end if
628 50809538 : if(gemm_nonlop_gpu_option/=hamk%gpu_option .or. force_recompute_ph3d .or. my_nspinor/=hamk%nspinor) use_gemm_nonlop=.false.
629 :
630 :
631 : !In the case of a derivative with respect to an atomic displacement,
632 : !and if <g|dVnl/dR|c> is required (signs=2), we only need to compute the
633 : !derivatives of the projectors associated with the displaced atom.
634 50809538 : iatom_only_=-1;if (present(iatom_only)) iatom_only_=iatom_only
635 50809538 : atom_pert=((signs==2).and.(choice==2.or.choice==4.or.choice==22.or.choice==24.or.choice==25.or.choice==54))
636 50809538 : proj_shift=0
637 :
638 50809538 : if (iatom_only_>0 .and. atom_pert) then
639 : ! Handling atomic displacement with GEMM variant.
640 : ! Arrays are fully passed as argument as when treating all atoms.
641 : ! An atom offset computed below is passed to gemm_nonlop instead.
642 7087345 : if (use_gemm_nonlop) then
643 0 : iatm=1; proj_shift=0
644 0 : do itypat=1, hamk%ntypat
645 0 : nlmn=count(hamk%indlmn(3,:,itypat)>0)
646 0 : do ia=1,hamk%nattyp(itypat)
647 0 : if(iatm/=iatom_only_) then
648 0 : proj_shift = proj_shift + nlmn
649 0 : iatm = iatm + 1
650 : end if
651 : end do
652 0 : if(iatm==iatom_only) exit
653 : end do
654 : end if
655 : ! We consider only atom with index iatom_only
656 7087345 : iatm=hamk%atindx(iatom_only_);itypat=hamk%typat(iatom_only_)
657 7087345 : natom_=1 ; ntypat_=1 ; dimenl2_=1 ; matblk_=1
658 28349380 : nloalg_(:)=hamk%nloalg(:)
659 7087345 : ABI_MALLOC(atindx1_,(1))
660 7087345 : ABI_MALLOC(nattyp_,(1))
661 7087345 : atindx1_(1)=1 ; nattyp_(1)=1
662 : ! Store at the right place the 1d phases
663 7087345 : n1=hamk%ngfft(1);n2=hamk%ngfft(2);n3=hamk%ngfft(3)
664 21262035 : ABI_MALLOC(ph1d_,(2,(2*n1+1)+(2*n2+1)+(2*n3+1)))
665 7087345 : shift1=(iatm-1)*(2*n1+1)
666 695748508 : ph1d_(:,1:2*n1+1)=hamk%ph1d(:,1+shift1:2*n1+1+shift1)
667 7087345 : shift2=(iatm-1)*(2*n2+1)+hamk%natom*(2*n1+1)
668 694298932 : ph1d_(:,1+2*n1+1:2*n2+1+2*n1+1)=hamk%ph1d(:,1+shift2:2*n2+1+shift2)
669 7087345 : shift3=(iatm-1)*(2*n3+1)+hamk%natom*(2*n1+1+2*n2+1)
670 726848212 : ph1d_(:,1+2*n1+1+2*n2+1:2*n3+1+2*n2+1+2*n1+1)=hamk%ph1d(:,1+shift3:2*n3+1+shift3)
671 7087345 : ABI_MALLOC(phkxredin_,(2,1))
672 7087345 : ABI_MALLOC(phkxredout_,(2,1))
673 35436725 : phkxredin_(:,1)=phkxredin(:,iatm)
674 35436725 : phkxredout_(:,1)=phkxredout(:,iatm)
675 21262035 : ABI_MALLOC(ph3din_,(2,npwin,1))
676 21262035 : ABI_MALLOC(ph3dout_,(2,npwout,1))
677 7087345 : if (force_recompute_ph3d.or.hamk%matblk<hamk%natom) then
678 2606200 : nloalg_(2)=-abs(nloalg_(2)) !Will compute the 3D phase factors inside nonlop
679 : else
680 8019866661 : ph3din_(:,1:npwin,1)=ph3din(:,1:npwin,iatm)
681 7999920957 : ph3dout_(:,1:npwout,1)=ph3dout(:,1:npwout,iatm)
682 : end if
683 35436725 : ABI_MALLOC(ffnlin_,(npwin,dimffnlin,hamk%lmnmax,1))
684 35436725 : ABI_MALLOC(ffnlout_,(npwout,dimffnlout,hamk%lmnmax,1))
685 24447967013 : ffnlin_(:,:,:,1)=ffnlin(:,:,:,itypat)
686 30840355487 : ffnlout_(:,:,:,1)=ffnlout(:,:,:,itypat)
687 22639451 : ABI_MALLOC(cprjin_,(1,my_nspinor*ndat*((cpopt+5)/5)))
688 7087345 : if (cpopt>=0) then
689 640300 : nlmn_atm(1)=cprjin(iatm,1)%nlmn
690 640300 : ncpgr_atm=cprjin(iatm,1)%ncpgr
691 640300 : call pawcprj_alloc(cprjin_,ncpgr_atm,nlmn_atm)
692 1329008 : do idat=1,ndat
693 2017716 : do ispinor=1,my_nspinor
694 688708 : jspinor=ispinor+(idat-1)*my_nspinor
695 1377416 : call pawcprj_copy(cprjin(iatm:iatm,jspinor:jspinor),cprjin_(1:1,jspinor:jspinor))
696 : end do
697 : end do
698 : end if
699 7087345 : if (present(enl_ndat)) then
700 100944 : ABI_MALLOC(enl_ndat_,(size(enl_ndat_ptr,1),1,hamk%nspinor**2,size(enl_ndat_ptr,5),ndat))
701 82056 : do idat=1,ndat
702 212520 : do ii=1,size(enl_ndat_ptr,5)
703 326160 : do ispden=1,hamk%nspinor**2
704 260928 : if (dimenl2==hamk%natom .and. hamk%usepaw==1) then
705 9523872 : enl_ndat_(:,1,ispden,ii,idat)=enl_ndat_ptr(:,iatom_only_,ispden,idat,ii)
706 0 : else if (dimenl2==hamk%ntypat) then
707 0 : enl_ndat_(:,1,ispden,ii,idat)=enl_ndat_ptr(:,itypat,ispden,idat,ii)
708 : else
709 0 : enl_ndat_(:,1,ispden,ii,idat)=enl_ndat_ptr(:,1,ispden,idat,ii)
710 : end if
711 : end do
712 : end do
713 : end do
714 35352605 : else if (size(enl_ptr)>0) then
715 35352605 : ABI_MALLOC(enl__,(size(enl_ptr,1),1,hamk%nspinor**2,size(enl_ptr,4)))
716 14141042 : do ii=1,size(enl_ptr,4)
717 21947997 : do ispden=1,hamk%nspinor**2
718 14877476 : if (dimenl2==hamk%natom .and. hamk%usepaw==1) then
719 72225980 : enl__(:,1,ispden,ii)=enl_ptr(:,iatom_only_,ispden,ii)
720 7011063 : else if (dimenl2==hamk%ntypat) then
721 79000291 : enl__(:,1,ispden,ii)=enl_ptr(:,itypat,ispden,ii)
722 : else
723 0 : enl__(:,1,ispden,ii)=enl_ptr(:,1,ispden,ii)
724 : end if
725 : end do
726 : end do
727 : else
728 0 : ABI_MALLOC(enl__,(0,0,0,0))
729 : end if
730 7087345 : if (allocated(hamk%sij)) then
731 7087345 : dimsij=size(hamk%sij,1)
732 21262035 : ABI_MALLOC(sij_,(dimsij,1))
733 7087345 : if (size(hamk%sij,2)==hamk%ntypat) then
734 37133424 : sij_(:,1)=hamk%sij(:,itypat)
735 18823887 : else if (size(hamk%sij)>0) then
736 0 : sij_(:,1)=hamk%sij(:,1)
737 : end if
738 : end if
739 21262035 : ABI_MALLOC(indlmn_,(6,hamk%lmnmax,1))
740 327226577 : indlmn_(:,:,1)=hamk%indlmn(:,:,itypat)
741 :
742 : else
743 : ! Usual case: all atoms are processed
744 43722193 : natom_ =hamk%natom; ntypat_=hamk%ntypat
745 43722193 : dimenl2_=dimenl2 ; matblk_=hamk%matblk
746 174888772 : nloalg_(:) = hamk%nloalg(:)
747 43722193 : atindx1_ => hamk%atindx1
748 43722193 : nattyp_ => hamk%nattyp
749 43722193 : ph1d_ => hamk%ph1d
750 43722193 : phkxredin_ => phkxredin
751 43722193 : phkxredout_ => phkxredout
752 43722193 : ffnlin_ => ffnlin
753 43722193 : ffnlout_ => ffnlout
754 43722193 : cprjin_ => cprjin
755 :
756 43722193 : enl__ => enl_ptr
757 :
758 43722193 : if (present(enl_ndat)) then
759 18932 : if (.not. use_gemm_nonlop) then
760 : ! An issue with Intel 16 forces to do this conversion
761 132524 : ABI_MALLOC(enl_ndat_,(size(enl_ndat_ptr,1),natom_,hamk%nspinor**2,size(enl_ndat_ptr,5),ndat))
762 94346 : do idat=1,ndat
763 23020202 : enl_ndat_(:,:,:,:,idat)=enl_ndat_ptr(:,:,:,idat,:)
764 : end do
765 : else
766 0 : enl_ndat_ => enl_ndat_ptr
767 : end if
768 : end if
769 43722193 : sij_ => hamk%sij
770 43722193 : indlmn_ => hamk%indlmn
771 43722193 : if (force_recompute_ph3d) then
772 0 : nloalg_(2)=-abs(nloalg_(2)) !Will compute the 3D phase factors inside nonlop
773 0 : ABI_MALLOC(ph3din_,(2,npwin,hamk%matblk))
774 0 : ABI_MALLOC(ph3dout_,(2,npwout,hamk%matblk))
775 : else
776 43722193 : ph3din_ => ph3din
777 43722193 : ph3dout_ => ph3dout
778 : end if
779 :
780 : end if
781 :
782 50809538 : if(use_gemm_nonlop) then
783 :
784 13942 : if(hamk%gpu_option==ABI_GPU_DISABLED .or. hamk%gpu_option==ABI_GPU_OPENMP) then
785 :
786 : ! If forces and stresses are both asked, compute them separately if set to (choice=={2,3})
787 13942 : if(choice==23 .and. signs==1 .and. (gemm_nonlop_split_choice23 .or. hamk%gpu_option==ABI_GPU_DISABLED)) then
788 212 : nnlout_forces = 3*hamk%natom
789 212 : nnlout_stress = 6
790 636 : ABI_MALLOC(enlout_forces,(nnlout_forces*ndat))
791 636 : ABI_MALLOC(enlout_stress,(nnlout_stress*ndat))
792 : call gemm_nonlop(hamk%atindx1, 2,cpopt,cprjin,dimenl1,dimenl2,dimekbq,&
793 : dimffnlin,dimffnlout,enl_ptr,enl_ndat_ptr,enlout_forces,ffnlin,ffnlout,&
794 : hamk%gmet,hamk%gprimd,&
795 : idir,hamk%indlmn,istwf_k,kgin,kgout,kpgin,kpgout,kptin,kptout,lambda,&
796 : hamk%lmnmax,hamk%matblk,hamk%mgfft,mpi_enreg,&
797 : hamk%natom,hamk%nattyp,ndat,hamk%ngfft,nkpgin,nkpgout,nloalg_,&
798 : nnlout_forces,npwin,npwout,my_nspinor,hamk%nspinor,hamk%ntypat,only_SO_,paw_opt,&
799 : ph3din,ph3dout,signs,hamk%sij,svectout,&
800 : tim_nonlop,hamk%ucvol,hamk%useylm,vectin,vectout,proj_shift,select_k_,&
801 : iatom_only_,hamk%typat,hamk%usepaw,&
802 424 : vectproj=vectproj,gpu_option=hamk%gpu_option)
803 : call gemm_nonlop(hamk%atindx1, 3,cpopt,cprjin,dimenl1,dimenl2,dimekbq,&
804 : dimffnlin,dimffnlout,enl_ptr,enl_ndat_ptr,enlout_stress,ffnlin,ffnlout,&
805 : hamk%gmet,hamk%gprimd,&
806 : idir,hamk%indlmn,istwf_k,kgin,kgout,kpgin,kpgout,kptin,kptout,lambda,&
807 : hamk%lmnmax,hamk%matblk,hamk%mgfft,mpi_enreg,&
808 : hamk%natom,hamk%nattyp,ndat,hamk%ngfft,nkpgin,nkpgout,nloalg_,&
809 : nnlout_stress,npwin,npwout,my_nspinor,hamk%nspinor,hamk%ntypat,only_SO_,paw_opt,&
810 : ph3din,ph3dout,signs,hamk%sij,svectout,&
811 : tim_nonlop,hamk%ucvol,hamk%useylm,vectin,vectout,proj_shift,select_k_,&
812 : iatom_only_,hamk%typat,hamk%usepaw,&
813 424 : vectproj=vectproj,gpu_option=hamk%gpu_option)
814 980 : do idat=1,ndat
815 768 : shift = (idat-1)*nnlout
816 768 : shift_forces = (idat-1)*nnlout_forces
817 768 : shift_stress = (idat-1)*nnlout_stress
818 5376 : enlout(shift+1:shift+nnlout_stress) = enlout_stress(shift_stress+1:shift_stress+nnlout_stress)
819 13652 : enlout(shift+nnlout_stress+1:shift+nnlout_stress+nnlout_forces) = enlout_forces(shift_forces+1:shift_forces+nnlout_forces)
820 : end do
821 212 : ABI_FREE(enlout_forces)
822 212 : ABI_FREE(enlout_stress)
823 : else
824 : call gemm_nonlop(hamk%atindx1,choice,cpopt,cprjin,dimenl1,dimenl2,dimekbq,&
825 : dimffnlin,dimffnlout,enl_ptr,enl_ndat_ptr,enlout,ffnlin,ffnlout,hamk%gmet,hamk%gprimd,&
826 : idir,hamk%indlmn,istwf_k,kgin,kgout,kpgin,kpgout,kptin,kptout,lambda,&
827 : hamk%lmnmax,hamk%matblk,hamk%mgfft,mpi_enreg,&
828 : hamk%natom,hamk%nattyp,ndat,hamk%ngfft,nkpgin,nkpgout,nloalg_,&
829 : nnlout,npwin,npwout,my_nspinor,hamk%nspinor,hamk%ntypat,only_SO_,paw_opt,&
830 : ph3din,ph3dout,signs,hamk%sij,svectout,&
831 : tim_nonlop,hamk%ucvol,hamk%useylm,vectin,vectout,proj_shift,select_k_,&
832 : iatom_only_,hamk%typat,hamk%usepaw,&
833 26308 : vectproj=vectproj,gpu_option=hamk%gpu_option)
834 : end if
835 :
836 : else if (hamk%gpu_option==ABI_GPU_LEGACY .or. hamk%gpu_option==ABI_GPU_KOKKOS) then
837 :
838 : #if defined HAVE_GPU_CUDA
839 : call gemm_nonlop_gpu(atindx1_, choice, cpopt, cprjin_, dimenl1, dimenl2_, dimekbq, &
840 : dimffnlin, dimffnlout, &
841 : enl_ptr, ffnlin, ffnlout, indlmn_, istwf_k, &
842 : lambda, hamk%lmnmax, matblk_, &
843 : mpi_enreg, natom_, nattyp_, ndat, nkpgin, nkpgout, &
844 : nnlout, npwin, npwout, my_nspinor, hamk%nspinor, ntypat_, paw_opt, &
845 : ph3din, ph3dout, sij_, svectout, &
846 : hamk%ucvol, hamk%useylm, vectin, vectout, select_k_, &
847 : hamk%gpu_option,vectproj=vectproj)
848 : #endif
849 :
850 : end if
851 :
852 : else
853 :
854 : #ifdef HAVE_OPENMP_OFFLOAD
855 : if(hamk%gpu_option==ABI_GPU_OPENMP) then
856 : if(xomp_target_is_present(c_loc(vectin))) then
857 : !$OMP TARGET UPDATE FROM(vectin)
858 : end if
859 : end if
860 : #endif
861 :
862 : !$omp parallel do default(shared), &
863 : !$omp& firstprivate(ndat,npwin,my_nspinor,choice,signs,paw_opt,npwout,cpopt,nnlout,enl__), &
864 : !$omp& private(b0,b1,b2,b3,b4,e0,e1,e2,e3,e4)
865 : !!$omp& schedule(static), if(hamk%gpu_option==ABI_GPU_DISABLED)
866 105284647 : do idat=1, ndat
867 54489051 : if(present(enl_ndat)) enl__ => enl_ndat_(:,:,:,:,idat)
868 : !vectin_idat => vectin(:,1+npwin*my_nspinor*(idat-1):npwin*my_nspinor*idat)
869 54489051 : b0 = 1+npwin*my_nspinor*(idat-1)
870 54489051 : e0 = npwin*my_nspinor*idat
871 54489051 : if (choice/=0.and.signs==2.and.paw_opt/=3) then
872 : !vectout_idat => vectout(:,1+npwout*my_nspinor*(idat-1):npwout*my_nspinor*idat)
873 49294683 : b1 = 1+npwout*my_nspinor*(idat-1)
874 49294683 : e1 = npwout*my_nspinor*idat
875 : else
876 : !vectout_idat => vectout
877 5194368 : b1 = lbound(vectout,dim=2)
878 10098560 : e1 = ubound(vectout,dim=2)
879 : end if
880 54489051 : if (choice/=0.and.signs==2.and.paw_opt>=3) then
881 : !svectout_idat => svectout(:,1+npwout*my_nspinor*(idat-1):npwout*my_nspinor*idat)
882 11780917 : b2 = 1+npwout*my_nspinor*(idat-1)
883 11780917 : e2 = npwout*my_nspinor*idat
884 : else
885 : !svectout_idat => svectout
886 42708134 : b2 = lbound(svectout,dim=2)
887 81733092 : e2 = ubound(svectout,dim=2)
888 : end if
889 :
890 54489051 : if (cpopt>=0) then
891 : !cprjin_idat => cprjin_(:,my_nspinor*(idat-1)+1:my_nspinor*(idat))
892 11645205 : b3 = my_nspinor*(idat-1)+1
893 11645205 : e3 = my_nspinor*(idat)
894 : else
895 : !cprjin_idat => cprjin_
896 42843846 : b3 = lbound(cprjin_,dim=2)
897 42843846 : e3 = ubound(cprjin_,dim=2)
898 : end if
899 54489051 : if (nnlout>0) then
900 : !enlout_idat => enlout((idat-1)*nnlout+1:(idat*nnlout))
901 49519234 : b4 = (idat-1)*nnlout*ndat_left_+1
902 49519234 : e4 = (idat*nnlout*ndat_left_)
903 : else
904 : !enlout_idat => enlout
905 4969817 : b4 = lbound(enlout,dim=1)
906 6681169 : e4 = ubound(enlout,dim=1)
907 : end if
908 :
909 : ! Legendre Polynomials version
910 105284647 : if (hamk%useylm==0) then
911 : call nonlop_pl(choice,dimenl1,dimenl2_,dimffnlin,dimffnlout,enl__,&
912 : & enlout(b4:e4),ffnlin_,ffnlout_,hamk%gmet,hamk%gprimd,idir,indlmn_,hamk%ispin_gbt,istwf_k,&
913 : & kgin,kgout,kpgin,kpgout,kptin,kptout,hamk%lmnmax,matblk_,hamk%mgfft,&
914 : & mpi_enreg,hamk%mpsang,hamk%mpssoang,natom_,nattyp_,hamk%ngfft,&
915 : & nkpgin,nkpgout,nloalg_,npwin,npwout,my_nspinor,hamk%nspinor,&
916 : & ntypat_,only_SO_,phkxredin_,phkxredout_,ph1d_,ph3din_,ph3dout_,signs,hamk%spinaxis,hamk%ucvol,hamk%use_gbt,&
917 29457648 : & vectin(:,b0:e0),vectout(:,b1:e1))
918 : ! Spherical Harmonics version
919 25031403 : else if (hamk%gpu_option==ABI_GPU_DISABLED .or. hamk%gpu_option==ABI_GPU_OPENMP) then
920 25031403 : if (present(cprjin_left).and.present(enlout_im)) then
921 : call nonlop_ylm(atindx1_,choice,cpopt,cprjin_(:,b3:e3),dimenl1,dimenl2_,dimekbq,&
922 : & dimffnlin,dimffnlout,enl__,enlout(b4:e4),ffnlin_,ffnlout_,hamk%gprimd,idir,&
923 : & indlmn_,istwf_k,kgin,kgout,kpgin,kpgout,kptin,kptout,lambda(idat),&
924 : & hamk%lmnmax,matblk_,hamk%mgfft,mpi_enreg,natom_,nattyp_,hamk%ngfft,&
925 : & nkpgin,nkpgout,nloalg_,nnlout,npwin,npwout,my_nspinor,hamk%nspinor,&
926 : & ntypat_,paw_opt,phkxredin_,phkxredout_,ph1d_,ph3din_,ph3dout_,signs,sij_,&
927 : & svectout(:,b2:e2),hamk%ucvol,vectin(:,b0:e0),vectout(:,b1:e1),qdir=qdir,&
928 220960 : cprjin_left=cprjin_left,enlout_im=enlout_im,ndat_left=ndat_left_)
929 : else
930 : call nonlop_ylm(atindx1_,choice,cpopt,cprjin_(:,b3:e3),dimenl1,dimenl2_,dimekbq,&
931 : & dimffnlin,dimffnlout,enl__,enlout(b4:e4),ffnlin_,ffnlout_,hamk%gprimd,idir,&
932 : & indlmn_,istwf_k,kgin,kgout,kpgin,kpgout,kptin,kptout,lambda(idat),&
933 : & hamk%lmnmax,matblk_,hamk%mgfft,mpi_enreg,natom_,nattyp_,hamk%ngfft,&
934 : & nkpgin,nkpgout,nloalg_,nnlout,npwin,npwout,my_nspinor,hamk%nspinor,&
935 : & ntypat_,paw_opt,phkxredin_,phkxredout_,ph1d_,ph3din_,ph3dout_,signs,sij_,&
936 24810443 : & svectout(:,b2:e2),hamk%ucvol,vectin(:,b0:e0),vectout(:,b1:e1),qdir=qdir)
937 : end if
938 : ! GPU version
939 : else
940 : call nonlop_gpu(atindx1_,choice,cpopt,cprjin(:,b3:e3),dimenl1,dimenl2_,&
941 : & dimffnlin,dimffnlout,enl__,enlout(b4:e4),ffnlin_,ffnlout_,hamk%gprimd,idir,&
942 : & indlmn_,istwf_k,kgin,kgout,kpgin,kpgout,kptin,kptout,lambda(idat),&
943 : & hamk%lmnmax,matblk_,hamk%mgfft,mpi_enreg,natom_,nattyp_,hamk%ngfft,&
944 : & nkpgin,nkpgout,nloalg_,nnlout,npwin,npwout,my_nspinor,hamk%nspinor,&
945 : & ntypat_,paw_opt,phkxredin_,phkxredout_,ph1d_,ph3din_,ph3dout_,signs,sij_,&
946 0 : & svectout(:,b2:e2),hamk%ucvol,vectin(:,b0:e0),vectout(:,b1:e1))
947 : end if
948 :
949 : end do
950 : !$omp end parallel do
951 :
952 : #ifdef HAVE_OPENMP_OFFLOAD
953 : if(hamk%gpu_option==ABI_GPU_OPENMP) then
954 : if(signs==2 .and. (paw_opt <= 2 .or. paw_opt == 4) .and. xomp_target_is_present(c_loc(vectout))) then
955 : !$OMP TARGET UPDATE TO(vectout)
956 : end if
957 : if(signs==2 .and. paw_opt>=3 .and. xomp_target_is_present(c_loc(svectout))) then
958 : !$OMP TARGET UPDATE TO(svectout)
959 : end if
960 : end if
961 : #endif
962 :
963 : end if
964 :
965 : !Release temporary storage
966 50809538 : if (iatom_only_>0.and.atom_pert) then
967 7087345 : if (cpopt>=0) then
968 640300 : call pawcprj_free(cprjin_)
969 : end if
970 7087345 : ABI_FREE(atindx1_)
971 7087345 : ABI_FREE(nattyp_)
972 7087345 : ABI_FREE(ph1d_)
973 7087345 : ABI_FREE(ph3din_)
974 7087345 : ABI_FREE(ph3dout_)
975 7087345 : ABI_FREE(phkxredin_)
976 7087345 : ABI_FREE(phkxredout_)
977 7087345 : ABI_FREE(ffnlin_)
978 7087345 : ABI_FREE(ffnlout_)
979 7087345 : if (present(enl_ndat)) then
980 16824 : ABI_FREE(enl_ndat_)
981 : else
982 7070521 : ABI_FREE(enl__)
983 : end if
984 7087345 : ABI_FREE(indlmn_)
985 7087345 : ABI_FREE(cprjin_)
986 7087345 : if (allocated(hamk%sij)) then
987 7087345 : ABI_FREE(sij_)
988 : end if
989 : else
990 43722193 : if (force_recompute_ph3d) then
991 0 : ABI_FREE(ph3din_)
992 0 : ABI_FREE(ph3dout_)
993 : end if
994 :
995 43722193 : if (present(enl_ndat) .and. .not. use_gemm_nonlop) then
996 18932 : ABI_FREE(enl_ndat_)
997 : end if
998 :
999 : end if
1000 :
1001 50809538 : if (kpgin_allocated) then
1002 249530 : ABI_FREE(kpgin)
1003 : end if
1004 50809538 : if (kpgout_allocated) then
1005 249530 : ABI_FREE(kpgout)
1006 : end if
1007 50809538 : if (.not. present(enl_ndat)) then
1008 50773782 : ABI_FREE(enl_ndat_ptr)
1009 : end if
1010 :
1011 50809538 : call timab(220+tim_nonlop,2,tsec)
1012 :
1013 : DBG_EXIT("COLL")
1014 :
1015 50809538 : end subroutine nonlop
1016 : !!***
1017 :
1018 : !!****f* ABINIT/nonlop_gpu
1019 : !! NAME
1020 : !! nonlop_gpu
1021 : !!
1022 : !! FUNCTION
1023 : !! Compute application of a nonlocal operator, using GPU (NVidia Cuda)
1024 : !! This routine is an interface to Cuda Kernel gpu_nonlop.cu
1025 : !!
1026 : !! INPUTS
1027 : !! atindx1(natom)=index table for atoms, inverse of atindx
1028 : !! choice: chooses possible output:
1029 : !! choice=0 => do nothing (only compute WF projected with NL projectors)
1030 : !! =1 => a non-local energy contribution
1031 : !! =2 => a gradient with respect to atomic position(s)
1032 : !! =3 => a gradient with respect to strain(s)
1033 : !! =23=> a gradient with respect to atm. pos. and strain(s)
1034 : !! cpopt=flag defining the status of cprjin%cp(:)=<Proj_i|Cnk> scalars (see below, side effects)
1035 : !! dimenl1,dimenl2=dimensions of enl (see enl)
1036 : !! dimffnlin=second dimension of ffnlin (1+number of derivatives)
1037 : !! dimffnlout=second dimension of ffnlout (1+number of derivatives)
1038 : !! enl(dimenl1,dimenl2,nspinortot**2)=
1039 : !! ->Norm conserving : ==== when paw_opt=0 ====
1040 : !! (Real) Kleinman-Bylander energies (hartree)
1041 : !! dimenl1=lmnmax - dimenl2=ntypat
1042 : !! ->PAW : ==== when paw_opt=1, 2 or 4 ====
1043 : !! (Real or complex, hermitian) Dij coefs to connect projectors
1044 : !! dimenl1=cplex_enl*lmnmax*(lmnmax+1)/2 - dimenl2=natom
1045 : !! ffnlin(npwin,dimffnlin,lmnmax,ntypat)=nonlocal form factors to be used
1046 : !! for the application of the nonlocal operator to the |in> vector
1047 : !! ffnlout(npwout,dimffnlout,lmnmax,ntypat)=nonlocal form factors to be used
1048 : !! for the application of the nonlocal operator to the |out> vector
1049 : !! gprimd(3,3)=dimensional reciprocal space primitive translations
1050 : !! idir=direction of the - atom to be moved in the case (choice=2,signs=2),
1051 : !! - k point direction in the case (choice=5,signs=2)
1052 : !! for choice 53, twisted derivative involves idir+1 and idir+2 (mod 3)
1053 : !! - strain component (1:6) in the case (choice=3,signs=2) or (choice=6,signs=1)
1054 : !! indlmn(6,i,ntypat)= array giving l,m,n,lm,ln,s for i=lmn
1055 : !! istwf_k=option parameter that describes the storage of wfs
1056 : !! kgin(3,npwin)=integer coords of planewaves in basis sphere, for the |in> vector
1057 : !! kgout(3,npwout)=integer coords of planewaves in basis sphere, for the |out> vector
1058 : !! kpgin(npw,npkgin)= (k+G) components and related data, for the |in> vector
1059 : !! kpgout(npw,nkpgout)=(k+G) components and related data, for the |out> vector
1060 : !! kptin(3)=k point in terms of recip. translations, for the |in> vector
1061 : !! kptout(3)=k point in terms of recip. translations, for the |out> vector
1062 : !! lambda=factor to be used when computing (Vln-lambda.S) - only for paw_opt=2
1063 : !! Typically lambda is the eigenvalue (or its guess)
1064 : !! lmnmax=max. number of (l,m,n) components over all types of atoms
1065 : !! matblk=dimension of the arrays ph3din and ph3dout
1066 : !! mgfft=maximum size of 1D FFTs
1067 : !! mpi_enreg=information about MPI parallelization
1068 : !! natom=number of atoms in cell
1069 : !! nattyp(ntypat)=number of atoms of each type
1070 : !! ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
1071 : !! nkpgin,nkpgout=second sizes of arrays kpgin/kpgout
1072 : !! nloalg(3)=governs the choice of the algorithm for nonlocal operator
1073 : !! nnlout=dimension of enlout (when signs=1 and choice>0):
1074 : !! ==== if paw_opt=0, 1 or 2 ====
1075 : !! choice=1=>nnlout=1 choice=2=>nnlout=3*natom choice=3=>nnlout=6
1076 : !! ==== if paw_opt=3 ====
1077 : !! choice=1 =>nnlout=1
1078 : !! ==== if paw_opt=4 ====
1079 : !! not available
1080 : !! npwin=number of planewaves for given k point, for the |in> vector
1081 : !! npwout=number of planewaves for given k point, for the |out> vector
1082 : !! nspinor=number of spinorial components of the wavefunctions (on current proc)
1083 : !! nspinortot=number of spinorial components of the wavefunctions on current proc
1084 : !! ntypat=number of types of atoms in cell
1085 : !! paw_opt= define the nonlocal operator concerned with:
1086 : !! paw_opt=0 : Norm-conserving Vnl (use of Kleinman-Bylander ener.)
1087 : !! paw_opt=1 : PAW nonlocal part of H (use of Dij coeffs)
1088 : !! paw_opt=2 : PAW: (Vnl-lambda.Sij) (Sij=overlap matrix)
1089 : !! paw_opt=3 : PAW overlap matrix (Sij)
1090 : !! paw_opt=4 : both PAW nonlocal part of H (Dij) and overlap matrix (Sij)
1091 : !! phkxredin(2,natom)=phase factors exp(2 pi kptin.xred)
1092 : !! phkxredout(2,natom)=phase factors exp(2 pi kptout.xred)
1093 : !! ph1d(2,3*(2*mgfft+1)*natom)=1D structure factors phase information
1094 : !! ph3din(2,npwin,matblk)=3D structure factors, for each atom and plane wave (in)
1095 : !! ph3dout(2,npwout,matblk)=3-dim structure factors, for each atom and plane wave (out)
1096 : !! signs= if 1, get contracted elements (energy, forces, stress, ...)
1097 : !! if 2, applies the non-local operator to a function in reciprocal space
1098 : !! sij(dimenl1,ntypat*(paw_opt/3))=overlap matrix components (only if paw_opt=2, 3 or 4)
1099 : !! ucvol=unit cell volume (bohr^3)
1100 : !! vectin(2,npwin*nspinor)=input cmplx wavefunction coefficients <G|Cnk>
1101 : !! [cprjin_left(natom,nspinor)]=The projected input wave function <p_nlm|in_left>
1102 : !! for the left wavefunction. Data are assumed to be in memory, they are NOT recalculated here.
1103 : !! Only signs==1 and choice==1 are supported.
1104 : !!
1105 : !! OUTPUT
1106 : !! ==== if (signs==1) ====
1107 : !! --If (paw_opt==0, 1 or 2)
1108 : !! enlout(nnlout)= contribution to the non-local part of the following properties:
1109 : !! if choice=1 : enlout(1) -> the energy
1110 : !! if choice=2 : enlout(1:3*natom) -> the forces
1111 : !! if choice=3 : enlout(1:6) -> the stresses
1112 : !! if choice=23: enlout(1:6+3*natom) -> the forces and the stresses
1113 : !! --If (paw_opt==3)
1114 : !! if choice=1 : enlout(nnlout)= contribution to <c|S|c> (nnlout=1)
1115 : !! --If (paw_opt==4)
1116 : !! not available
1117 : !! ==== if (signs==2) ====
1118 : !! --if (paw_opt=0, 1 or 4)
1119 : !! vectout(2,npwout*nspinor)=result of the application of the concerned operator
1120 : !! or one of its derivatives to the input vect.:
1121 : !! if (choice=1) <G|V_nonlocal|vect_start>
1122 : !! if (choice=2) <G|dV_nonlocal/d(atm coord)|vect_start>
1123 : !! if (choice=3) <G|dV_nonlocal/d(strain)|vect_start>
1124 : !! if (paw_opt=2)
1125 : !! vectout(2,npwout*nspinor)=final vector in reciprocal space:
1126 : !! if (choice=1) <G|V_nonlocal-lambda.(I+S)|vect_start>
1127 : !! if (choice=2) <G|d[V_nonlocal-lambda.(I+S)]/d(atm coord)|vect_start>
1128 : !! if (choice=3) <G|d[V_nonlocal-lambda.(I+S)]/d(strain)|vect_start>
1129 : !! --if (paw_opt=3 or 4)
1130 : !! svectout(2,npwout*nspinor)=result of the application of Sij (overlap matrix)
1131 : !! or one of its derivatives to the input vect.:
1132 : !! if (choice=1) <G|I+S|vect_start>
1133 : !! if (choice=2) <G|dS/d(atm coord)|vect_start>
1134 : !! if (choice=3) <G|dS/d(strain)|vect_start>
1135 : !!
1136 : !! SIDE EFFECTS
1137 : !! cprjin(natom,nspinor) <type(pawcprj_type)>=projected input wave function |in> on non-local projectors
1138 : !! =<p_lmn|in> and derivatives
1139 : !! Treatment depends on cpopt parameter:
1140 : !! if cpopt=-1, <p_lmn|in> (and derivatives)
1141 : !! are computed here (and not saved)
1142 : !! if cpopt= 0, <p_lmn|in> are computed here and saved
1143 : !! derivatives are eventually computed but not saved
1144 : !! if cpopt= 1, <p_lmn|in> and first derivatives are computed here and saved
1145 : !! other derivatives are eventually computed but not saved
1146 : !!
1147 : !! TODO
1148 : !! * Implementation for spinorial wave functions (nspinor=2)
1149 : !! * Implementation for response function (phonons, ddk, elastic tensor, ...)
1150 : !!
1151 : !! SOURCE
1152 :
1153 :
1154 0 : subroutine nonlop_gpu(atindx1,choice,cpopt,cprjin,dimenl1,dimenl2,dimffnlin,dimffnlout,&
1155 0 : & enl,enlout,ffnlin,ffnlout,gprimd,idir,indlmn,istwf_k,&
1156 0 : & kgin,kgout,kpgin,kpgout,kptin,kptout,lambda,lmnmax,matblk,mgfft,&
1157 0 : & mpi_enreg,natom,nattyp,ngfft,nkpgin,nkpgout,nloalg,nnlout,&
1158 0 : & npwin,npwout,nspinor,nspinortot,ntypat,paw_opt,phkxredin,phkxredout,ph1d,&
1159 0 : & ph3din,ph3dout,signs,sij,svectout,ucvol,vectin,vectout)
1160 :
1161 : !Arguments ------------------------------------
1162 : !scalars
1163 : integer,intent(in) :: choice,cpopt,dimenl1,dimenl2,dimffnlin,dimffnlout,idir
1164 : integer,intent(in) :: istwf_k,lmnmax,matblk,mgfft,natom,nkpgin,nkpgout,nnlout
1165 : integer,intent(in) :: npwin,npwout,nspinor,nspinortot,ntypat,paw_opt,signs
1166 : real(dp),intent(in) :: lambda,ucvol
1167 : type(MPI_type),intent(in) :: mpi_enreg
1168 : !arrays
1169 : integer,intent(in) :: atindx1(natom),indlmn(6,lmnmax,ntypat),kgin(3,npwin)
1170 : integer,intent(in) :: kgout(3,npwout),nattyp(ntypat),ngfft(18),nloalg(3)
1171 : real(dp),intent(in) :: enl(dimenl1,dimenl2,nspinortot**2)
1172 : real(dp),intent(in) :: ffnlin(npwin,dimffnlin,lmnmax,ntypat)
1173 : real(dp),intent(in) :: ffnlout(npwout,dimffnlout,lmnmax,ntypat) !,gmet(3,3)
1174 : real(dp),intent(in) :: gprimd(3,3),kpgin(npwin,nkpgin),kpgout(npwout,nkpgout)
1175 : real(dp),intent(in) :: kptin(3),kptout(3),ph1d(2,3*(2*mgfft+1)*natom)
1176 : real(dp),intent(in) :: phkxredin(2,natom),phkxredout(2,natom)
1177 : real(dp),intent(in) :: sij(dimenl1,ntypat*((paw_opt+1)/3))
1178 : real(dp),intent(inout) :: ph3din(2,npwin,matblk),ph3dout(2,npwout,matblk)
1179 : real(dp),intent(inout) :: vectin(:,:)
1180 : real(dp),intent(out) :: enlout(:)
1181 : real(dp),intent(out),target :: svectout(:,:)
1182 : real(dp),intent(out),target :: vectout (:,:)
1183 : type(pawcprj_type),intent(inout) :: cprjin(:,:)
1184 :
1185 : !Local variables-------------------------------
1186 : !scalars
1187 : integer :: ia,iatom,ilmn,iproj,ispinor,itypat,signs_
1188 : real(dp) :: doti
1189 : character(len=500) :: msg
1190 : !arrays
1191 0 : real(dp),allocatable :: proj(:,:)
1192 0 : real(dp),pointer :: svectout_(:,:),vectout_(:,:)
1193 : ! **********************************************************************
1194 :
1195 : DBG_ENTER("COLL")
1196 :
1197 : !Error on bad choice
1198 0 : if ((choice<0 .or. (choice>3.and.choice/=7)).and. choice/=23 .and. choice/=24) then
1199 0 : write(msg,'(a,i0,a)')'Does not presently support this choice=',choice,'.'
1200 0 : ABI_BUG(msg)
1201 : end if
1202 0 : if (cpopt<-1.or.cpopt>2) then
1203 0 : ABI_BUG('Bad value for cpopt !')
1204 : end if
1205 0 : if (nspinor==2) then
1206 0 : ABI_ERROR('nspinor=2 (spinorial WF) not yet allowed !')
1207 : end if
1208 :
1209 0 : if ((cpopt==0).or.(cpopt==1).or.(cpopt==2)) then
1210 0 : ABI_MALLOC(proj,(2,lmnmax*natom))
1211 0 : proj=zero;
1212 : end if
1213 :
1214 : !Workaround to get choice=1/signs=1 working
1215 0 : if (choice==1.and.signs==1) then
1216 0 : signs_=2
1217 0 : ABI_MALLOC(vectout_,(2,npwin*nspinor))
1218 0 : ABI_MALLOC(svectout_,(2,npwin*nspinor*(paw_opt/3)))
1219 : else
1220 0 : signs_=signs;vectout_=>vectout;svectout_=>svectout
1221 : end if
1222 :
1223 : !if cpot==2, the projections are already in memory
1224 0 : if (cpopt>=2) then
1225 : iproj=0
1226 0 : do ispinor=1,nspinor
1227 : iatom=0
1228 0 : do itypat=1,ntypat
1229 0 : do ia=1,nattyp(itypat)
1230 0 : iatom=iatom+1
1231 0 : do ilmn=1,cprjin(iatom,1)%nlmn
1232 0 : iproj=iproj+1
1233 0 : proj(:,iproj)=cprjin(iatom,1)%cp(:,ilmn)
1234 : end do
1235 : end do
1236 : end do
1237 : end do
1238 : end if
1239 :
1240 : #if defined HAVE_GPU_CUDA
1241 : call gpu_nonlop(atindx1,choice,cpopt,proj,dimenl1,dimenl2,dimffnlin,dimffnlout,&
1242 : & enl,enlout,ffnlin,ffnlout,gprimd,idir,indlmn,istwf_k,&
1243 : & kgin,kgout,kpgin,kpgout,kptin,kptout,lambda,lmnmax,matblk,mgfft,&
1244 : & mpi_enreg%me_g0_fft,natom,nattyp,ngfft,nkpgin,nkpgout,nloalg,nnlout,&
1245 : & npwin,npwout,nspinor,ntypat,paw_opt,phkxredin,phkxredout,ph1d,&
1246 : & ph3din,ph3dout,signs_,sij,svectout_,pi,ucvol,vectin,vectout_)
1247 : #else
1248 : ABI_UNUSED(nnlout)
1249 : #endif
1250 :
1251 0 : if (choice==1.and.signs==1) then
1252 0 : if (paw_opt/=3) then
1253 0 : call dotprod_g(enlout(1),doti,istwf_k,npwin*nspinor,1,vectin,vectout_,mpi_enreg%me_g0_fft,mpi_enreg%comm_spinorfft)
1254 : else
1255 0 : call dotprod_g(enlout(1),doti,istwf_k,npwin*nspinor,1,vectin,svectout_,mpi_enreg%me_g0_fft,mpi_enreg%comm_spinorfft)
1256 : end if
1257 0 : ABI_FREE(vectout_)
1258 0 : ABI_FREE(svectout_)
1259 : else
1260 0 : nullify(vectout_,svectout_)
1261 : end if
1262 :
1263 0 : if ((cpopt==0).or.(cpopt==1)) then
1264 : iproj=0
1265 0 : do ispinor=1,nspinor
1266 : iatom=0
1267 0 : do itypat=1,ntypat
1268 0 : do ia=1,nattyp(itypat)
1269 0 : iatom=iatom+1;cprjin(iatom,1)%nlmn=count(indlmn(3,:,itypat)>0)
1270 0 : do ilmn=1,cprjin(iatom,1)%nlmn
1271 0 : iproj=iproj+1;cprjin(iatom,1)%cp(:,ilmn)=proj(:,iproj)
1272 : end do
1273 : end do
1274 : end do
1275 : end do
1276 : end if
1277 :
1278 0 : if (allocated(proj)) then
1279 0 : ABI_FREE(proj)
1280 : end if
1281 :
1282 : DBG_EXIT("COLL")
1283 :
1284 : !Fake statements to satisfy ABI rules
1285 : #if ! defined HAVE_GPU_CUDA
1286 : if (.false.) then
1287 : write(std_out,*) atindx1,enl,ffnlin,ffnlout,gprimd
1288 : write(std_out,*) idir,istwf_k,kgin,kgout,kpgin,kpgout
1289 : write(std_out,*) kptin,kptout,lambda,mpi_enreg%me
1290 : write(std_out,*) ngfft,nloalg,ph1d,ph3din,ph3dout
1291 : write(std_out,*) phkxredin,phkxredout,signs,sij
1292 : write(std_out,*) ucvol,vectin
1293 : end if
1294 : #endif
1295 :
1296 0 : end subroutine nonlop_gpu
1297 : !!***
1298 :
1299 : end module m_nonlop
1300 : !!***
|