fcdft 1.1.2__tar.gz → 1.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fcdft-1.1.2 → fcdft-1.1.4}/MANIFEST.in +1 -0
- {fcdft-1.1.2/fcdft.egg-info → fcdft-1.1.4}/PKG-INFO +1 -1
- fcdft-1.1.4/fcdft/__init__.py +1 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/df/df_jk.py +65 -2
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/df/grad/rks.py +27 -19
- fcdft-1.1.4/fcdft/dft/gen_grid.py +88 -0
- fcdft-1.1.4/fcdft/gto/mole.py +110 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/lib/CMakeLists.txt +1 -0
- fcdft-1.1.4/fcdft/lib/df/CMakeLists.txt +8 -0
- fcdft-1.1.4/fcdft/lib/df/nr_contract_k.c +13 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/lib/dft/quadrature.c +6 -2
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/lib/fcdft_helper.c +5928 -6134
- fcdft-1.1.4/fcdft/lib/pbe/poisson.c +152 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/lib/pbe_helper.c +6281 -6659
- fcdft-1.1.4/fcdft/solvent/AMGX.json +32 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/solvent/_attach_solvent.py +5 -1
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/solvent/calculus_helper.py +39 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/solvent/grad/pbe.py +27 -12
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/solvent/pbe.py +17 -12
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/solvent/solver.py +67 -3
- fcdft-1.1.4/fcdft/tools/__init__.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/wbl/rks.py +11 -7
- {fcdft-1.1.2 → fcdft-1.1.4/fcdft.egg-info}/PKG-INFO +1 -1
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft.egg-info/SOURCES.txt +6 -0
- fcdft-1.1.2/fcdft/__init__.py +0 -1
- fcdft-1.1.2/fcdft/lib/pbe/poisson.c +0 -81
- {fcdft-1.1.2 → fcdft-1.1.4}/AUTHORS +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/LICENSE +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/README.md +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/df/__init__.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/df/grad/__init__.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/df/grad/uks.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/dft/__init__.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/dft/numint.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/grad/__init__.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/grad/lifcdft.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/grad/rks.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/grad/uks.py +0 -0
- {fcdft-1.1.2/fcdft/hessian → fcdft-1.1.4/fcdft/gto}/__init__.py +0 -0
- {fcdft-1.1.2/fcdft/jellium → fcdft-1.1.4/fcdft/hessian}/__init__.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/hessian/lifcdft.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/hessian/numhess.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/hessian/thermo.py +0 -0
- {fcdft-1.1.2/fcdft/lifcdft → fcdft-1.1.4/fcdft/jellium}/__init__.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/jellium/jellium.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/lib/__init__.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/lib/dft/CMakeLists.txt +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/lib/dft/nr_numint.c +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/lib/dft/nr_numint.h +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/lib/fcdft_helper.pyx +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/lib/misc.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/lib/pbe/CMakeLists.txt +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/lib/pbe/boundary_condition.c +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/lib/pbe/boundary_condition.h +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/lib/pbe/constant.h +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/lib/pbe_helper.pyx +0 -0
- {fcdft-1.1.2/fcdft/solvent → fcdft-1.1.4/fcdft/lifcdft}/__init__.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/lifcdft/lifcdft.py +0 -0
- {fcdft-1.1.2/fcdft/solvent/grad → fcdft-1.1.4/fcdft/solvent}/__init__.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/solvent/boundary.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/solvent/esp.py +0 -0
- {fcdft-1.1.2/fcdft/tools → fcdft-1.1.4/fcdft/solvent/grad}/__init__.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/solvent/ions.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/solvent/radii.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/tools/addons.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/tools/molden.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/wbl/__init__.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/wbl/abscissas.npy +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/wbl/uks.py +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft/wbl/weights.npy +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft.egg-info/dependency_links.txt +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/fcdft.egg-info/top_level.txt +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/setup.cfg +0 -0
- {fcdft-1.1.2 → fcdft-1.1.4}/setup.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '1.1.4'
|
|
@@ -4,6 +4,12 @@ from pyscf.df import df_jk
|
|
|
4
4
|
from pyscf import lib
|
|
5
5
|
from pyscf.lib import logger
|
|
6
6
|
from fcdft import wbl
|
|
7
|
+
import ctypes
|
|
8
|
+
import os
|
|
9
|
+
import fcdft
|
|
10
|
+
from pyscf.lib.numpy_helper import _dgemm
|
|
11
|
+
|
|
12
|
+
libdf = lib.load_library(os.path.join(fcdft.__path__[0], 'lib', 'libdf'))
|
|
7
13
|
|
|
8
14
|
def density_fit(mf, auxbasis=None, with_df=None, only_dfj=False):
|
|
9
15
|
from pyscf import df
|
|
@@ -128,13 +134,71 @@ def get_j(dfobj, dm, hermi=0, direct_scf_tol=1e-13):
|
|
|
128
134
|
logger.timer(dfobj, 'df-vj', *t0)
|
|
129
135
|
return numpy.asarray(vj).reshape(dm_shape)
|
|
130
136
|
|
|
137
|
+
# numpy.einsum replaced by custom dgemm for computational efficiency.
|
|
138
|
+
def get_jk(dfobj, dm, hermi=0, with_j=True, with_k=True, direct_scf_tol=1e-13):
|
|
139
|
+
assert (with_j or with_k)
|
|
140
|
+
if (not with_k and not dfobj.mol.incore_anyway and
|
|
141
|
+
# 3-center integral tensor is not initialized
|
|
142
|
+
dfobj._cderi is None):
|
|
143
|
+
return get_j(dfobj, dm, hermi, direct_scf_tol), None
|
|
144
|
+
|
|
145
|
+
t0 = t1 = (logger.process_clock(), logger.perf_counter())
|
|
146
|
+
log = logger.Logger(dfobj.stdout, dfobj.verbose)
|
|
147
|
+
|
|
148
|
+
dms = numpy.asarray(dm)
|
|
149
|
+
dm_shape = dms.shape
|
|
150
|
+
nao = dm_shape[-1]
|
|
151
|
+
dms = dms.reshape(-1,nao,nao)
|
|
152
|
+
nset = dms.shape[0]
|
|
153
|
+
vj = 0
|
|
154
|
+
vk = numpy.zeros_like(dms)
|
|
155
|
+
|
|
156
|
+
fdrv = libdf.nr_mapdm1
|
|
157
|
+
|
|
158
|
+
if numpy.iscomplexobj(dms):
|
|
159
|
+
if with_j:
|
|
160
|
+
vj = numpy.zeros_like(dms)
|
|
161
|
+
max_memory = dfobj.max_memory - lib.current_memory()[0]
|
|
162
|
+
blksize = max(4, int(min(dfobj.blockdim, max_memory*.22e6/8/nao**2)))
|
|
163
|
+
buf = numpy.empty((blksize,nao,nao))
|
|
164
|
+
for eri1 in dfobj.loop(blksize):
|
|
165
|
+
naux, nao_pair = eri1.shape
|
|
166
|
+
eri1 = lib.unpack_tril(eri1, out=buf)
|
|
167
|
+
if with_j:
|
|
168
|
+
tmp = numpy.tensordot(eri1, dms.real, axes=([1,2],[2,1]))
|
|
169
|
+
vj.real += numpy.tensordot(tmp.T, eri1, axes=([1],[0]))
|
|
170
|
+
tmp = numpy.tensordot(eri1, dms.imag, axes=([1,2],[2,1]))
|
|
171
|
+
vj.imag += numpy.tensordot(tmp.T, eri1, axes=([1],[0]))
|
|
172
|
+
buf2 = numpy.empty((naux,nao,nao), dtype=numpy.float64, order='C')
|
|
173
|
+
for k in range(nset):
|
|
174
|
+
dmsRe = numpy.asarray(dms[k].real, dtype=numpy.float64, order='C')
|
|
175
|
+
dmsIm = numpy.asarray(dms[k].imag, dtype=numpy.float64, order='C')
|
|
176
|
+
fdrv(buf2.ctypes.data_as(ctypes.c_void_p),
|
|
177
|
+
eri1.ctypes.data_as(ctypes.c_void_p),
|
|
178
|
+
dmsRe.ctypes.data_as(ctypes.c_void_p),
|
|
179
|
+
ctypes.c_int(nao), ctypes.c_int(naux))
|
|
180
|
+
vk[k].real += numpy.tensordot(buf2, eri1, axes=([0,2],[0,1]))
|
|
181
|
+
fdrv(buf2.ctypes.data_as(ctypes.c_void_p),
|
|
182
|
+
eri1.ctypes.data_as(ctypes.c_void_p),
|
|
183
|
+
dmsIm.ctypes.data_as(ctypes.c_void_p),
|
|
184
|
+
ctypes.c_int(nao), ctypes.c_int(naux))
|
|
185
|
+
vk[k].imag += numpy.tensordot(buf2, eri1, axes=([0,2],[0,1]))
|
|
186
|
+
t1 = log.timer_debug1('jk', *t1)
|
|
187
|
+
if with_j: vj = vj.reshape(dm_shape)
|
|
188
|
+
if with_k: vk = vk.reshape(dm_shape)
|
|
189
|
+
logger.timer(dfobj, 'df vj and vk', *t0)
|
|
190
|
+
return vj, vk
|
|
191
|
+
|
|
192
|
+
else:
|
|
193
|
+
return df_jk.get_jk(dfobj, dm, hermi, with_j, with_k, direct_scf_tol)
|
|
194
|
+
|
|
131
195
|
class _DFHF(df_jk._DFHF):
|
|
132
196
|
def get_jk(self, mol=None, dm=None, hermi=0, with_j=True, with_k=True, omega=None):
|
|
133
197
|
if dm is None: dm = self.make_rdm1()
|
|
134
198
|
if not with_k:
|
|
135
199
|
return get_j(self.with_df, dm, hermi, self.direct_scf_tol), None
|
|
136
200
|
else:
|
|
137
|
-
return
|
|
201
|
+
return get_jk(self.with_df, dm, hermi, with_j, with_k, self.direct_scf_tol)
|
|
138
202
|
|
|
139
203
|
def nuc_grad_method(self):
|
|
140
204
|
from fcdft.df.grad import rks, uks
|
|
@@ -152,4 +216,3 @@ class _DFHF(df_jk._DFHF):
|
|
|
152
216
|
|
|
153
217
|
def to_gpu(self):
|
|
154
218
|
raise NotImplementedError
|
|
155
|
-
|
|
@@ -15,7 +15,7 @@ LINEAR_DEP_THRESHOLD = LINEAR_DEP_THR
|
|
|
15
15
|
|
|
16
16
|
def get_jk(mf_grad, mol=None, dm=None, hermi=0, with_j=True, with_k=True,
|
|
17
17
|
decompose_j2c='CD', lindep=LINEAR_DEP_THRESHOLD):
|
|
18
|
-
"""Copied from pyscf.df.grad.rhf and
|
|
18
|
+
"""Copied from pyscf.df.grad.rhf and some parts modified to handle complex density matrices."""
|
|
19
19
|
assert (with_j or with_k)
|
|
20
20
|
if not with_k:
|
|
21
21
|
return get_j (mf_grad, mol=mol, dm=dm, hermi=hermi), None
|
|
@@ -57,7 +57,7 @@ def get_jk(mf_grad, mol=None, dm=None, hermi=0, with_j=True, with_k=True,
|
|
|
57
57
|
vk = numpy.zeros((nset,3,nao,nao), dtype=numpy.complex128)
|
|
58
58
|
get_int3c_ip1 = df_rhf_grad._int3c_wrapper(mol, auxmol, 'int3c2e_ip1', 's1')
|
|
59
59
|
max_memory = mf_grad.max_memory - lib.current_memory()[0]
|
|
60
|
-
blksize = int(min(max(max_memory * .5e6/8 / (nao**2*3), 20), naux,
|
|
60
|
+
blksize = int(min(max(max_memory * .5e6/8 / (nao**2*3), 20), naux, 80)) # 240 -> 80 for handling complex128
|
|
61
61
|
ao_ranges = df_rhf_grad.balance_partition(aux_loc, blksize)
|
|
62
62
|
fmmm = _ao2mo.libao2mo.AO2MOmmm_bra_nr_s1 # MO output index slower than AO output index; input AOs are asymmetric
|
|
63
63
|
fdrv = _ao2mo.libao2mo.AO2MOnr_e2_drv # comp and aux indices are slower
|
|
@@ -74,10 +74,11 @@ def get_jk(mf_grad, mol=None, dm=None, hermi=0, with_j=True, with_k=True,
|
|
|
74
74
|
vj[i,1] += numpy.dot (rhoj[i,p0:p1], int3c[1].reshape (p1-p0, -1)).reshape (nao, nao).T
|
|
75
75
|
vj[i,2] += numpy.dot (rhoj[i,p0:p1], int3c[2].reshape (p1-p0, -1)).reshape (nao, nao).T
|
|
76
76
|
t2 = logger.timer_debug1 (mf_grad, "df grad einsum rho_P (P|mn') rho_P", *t2)
|
|
77
|
+
tmp = numpy.empty ((3,p1-p0,nocc[i],nao), dtype=numpy.complex128)
|
|
77
78
|
tmpRe = numpy.empty ((3,p1-p0,nocc[i],nao), dtype=numpy.float64)
|
|
78
79
|
tmpIm = numpy.empty ((3,p1-p0,nocc[i],nao), dtype=numpy.float64)
|
|
79
80
|
orbolRe = numpy.asarray(orbol[i].real, order='F')
|
|
80
|
-
orbolIm = numpy.asarray(orbol[i].imag, order='F')
|
|
81
|
+
orbolIm = numpy.asarray(orbol[i].imag, order='F')
|
|
81
82
|
fdrv(ftrans, fmmm, # lib.einsum ('xpmn,mi->xpin', int3c, orbol[i])
|
|
82
83
|
tmpRe.ctypes.data_as(ctypes.c_void_p),
|
|
83
84
|
int3c.ctypes.data_as(ctypes.c_void_p),
|
|
@@ -85,6 +86,7 @@ def get_jk(mf_grad, mol=None, dm=None, hermi=0, with_j=True, with_k=True,
|
|
|
85
86
|
ctypes.c_int (3*(p1-p0)), ctypes.c_int (nao),
|
|
86
87
|
(ctypes.c_int*4)(0, nocc[i], 0, nao),
|
|
87
88
|
null, ctypes.c_int(0))
|
|
89
|
+
orbolRe = None
|
|
88
90
|
fdrv(ftrans, fmmm, # lib.einsum ('xpmn,mi->xpin', int3c, orbol[i])
|
|
89
91
|
tmpIm.ctypes.data_as(ctypes.c_void_p),
|
|
90
92
|
int3c.ctypes.data_as(ctypes.c_void_p),
|
|
@@ -92,11 +94,13 @@ def get_jk(mf_grad, mol=None, dm=None, hermi=0, with_j=True, with_k=True,
|
|
|
92
94
|
ctypes.c_int (3*(p1-p0)), ctypes.c_int (nao),
|
|
93
95
|
(ctypes.c_int*4)(0, nocc[i], 0, nao),
|
|
94
96
|
null, ctypes.c_int(0))
|
|
95
|
-
tmp = tmpRe + 1.0j * tmpIm
|
|
97
|
+
# tmp = tmpRe + 1.0j * tmpIm
|
|
98
|
+
orbolIm = None
|
|
99
|
+
tmp.real, tmp.imag = tmpRe, tmpIm
|
|
100
|
+
tmpRe = tmpIm = None
|
|
96
101
|
t2 = logger.timer_debug1 (mf_grad, "df grad einsum (P|mn') u_mi = dg_Pin", *t2)
|
|
97
102
|
rhok = get_rhok (i, p0, p1)
|
|
98
|
-
|
|
99
|
-
vk[i] += numpy.tensordot(tmp, rhok, axes=([1,2], [0,1]))
|
|
103
|
+
vk[i] += numpy.tensordot(tmp, rhok, axes=([1,2],[0,1]))
|
|
100
104
|
t2 = logger.timer_debug1 (mf_grad, "df grad einsum D_Pim dg_Pin = v_ij", *t2)
|
|
101
105
|
rhok = tmp = None
|
|
102
106
|
int3c = None
|
|
@@ -117,10 +121,10 @@ def get_jk(mf_grad, mol=None, dm=None, hermi=0, with_j=True, with_k=True,
|
|
|
117
121
|
max_memory = mf_grad.max_memory - lib.current_memory()[0]
|
|
118
122
|
# blksize = int(min(max(max_memory * .5e6/8 / (nao*max (nocc)), 20), naux))
|
|
119
123
|
# In principe, all occupation numbers are non-zero for open quantum systems.
|
|
120
|
-
blksize = int(min(max(max_memory * .5e6/8 / (nao*nao), 20), naux))
|
|
124
|
+
blksize = int(min(max(max_memory * .5e6/8 / (nao*nao), 20), naux) / 3) # Divided by 3 for handling complex128
|
|
121
125
|
rhok_oo = []
|
|
122
126
|
for i, j in product (range (nset), repeat=2):
|
|
123
|
-
tmp = numpy.empty ((naux,nocc[i],nocc[j]), numpy.complex128)
|
|
127
|
+
tmp = numpy.empty ((naux,nocc[i],nocc[j]), dtype=numpy.complex128)
|
|
124
128
|
for p0, p1 in lib.prange(0, naux, blksize):
|
|
125
129
|
rhok = get_rhok (i, p0, p1).reshape ((p1-p0)*nocc[i], nao)
|
|
126
130
|
tmp[p0:p1] = lib.dot (rhok, orbol[j]).reshape (p1-p0, nocc[i], nocc[j])
|
|
@@ -150,8 +154,9 @@ def get_jk(mf_grad, mol=None, dm=None, hermi=0, with_j=True, with_k=True,
|
|
|
150
154
|
# Here, the sparse matrix int3c is transformed into the smaller MO
|
|
151
155
|
# basis. The latter approach is obviously more performant.
|
|
152
156
|
for i in range (nset):
|
|
153
|
-
|
|
154
|
-
|
|
157
|
+
buf = numpy.empty((3, p1-p0, nocc[i], nao), dtype=numpy.complex128)
|
|
158
|
+
bufRe = numpy.empty((3, p1-p0, nocc[i], nao), dtype=numpy.float64)
|
|
159
|
+
bufIm = numpy.empty((3, p1-p0, nocc[i], nao), dtype=numpy.float64)
|
|
155
160
|
orbolRe = numpy.asarray(orbol[i].real, order='F')
|
|
156
161
|
orbolIm = numpy.asarray(orbol[i].imag, order='F')
|
|
157
162
|
fdrv(ftrans, fmmm, # lib.einsum ('pmn,ni->pim', int3c, orbol[i])
|
|
@@ -168,14 +173,18 @@ def get_jk(mf_grad, mol=None, dm=None, hermi=0, with_j=True, with_k=True,
|
|
|
168
173
|
ctypes.c_int (3*(p1-p0)), ctypes.c_int (nao),
|
|
169
174
|
(ctypes.c_int*4)(0, nocc[i], 0, nao),
|
|
170
175
|
null, ctypes.c_int(0))
|
|
171
|
-
buf = bufRe
|
|
176
|
+
buf.real, buf.imag = bufRe, bufIm
|
|
172
177
|
for j in range (nset): # lib.einsum ('pim,mj->pij', buf, orbor[j])
|
|
173
178
|
int3c_ij = lib.dot (buf.reshape (-1, nao), orbor[j])
|
|
174
179
|
int3c_ij = int3c_ij.reshape (3, p1-p0, nocc[i], nocc[j])
|
|
175
180
|
rhok_oo_ij = rhok_oo[(i*nset)+j][p0:p1]
|
|
176
181
|
vkaux[i,j,:,p0:p1] += lib.einsum('xpij,pij->xp', int3c_ij,
|
|
177
182
|
rhok_oo_ij)
|
|
183
|
+
int3c = None
|
|
178
184
|
t2 = logger.timer_debug1 (mf_grad, "df grad vk aux (P'|mn) eval", *t2)
|
|
185
|
+
orbol = orbor = None
|
|
186
|
+
buf = bufRe = bufIm = orbolRe = orbolIm = None
|
|
187
|
+
dm_tril = None
|
|
179
188
|
int3c = tmp = None
|
|
180
189
|
t1 = logger.timer_debug1 (mf_grad, "df grad vj and vk aux (P'|mn) eval", *t1)
|
|
181
190
|
|
|
@@ -185,8 +194,9 @@ def get_jk(mf_grad, mol=None, dm=None, hermi=0, with_j=True, with_k=True,
|
|
|
185
194
|
for i, j in product (range (nset), repeat=2):
|
|
186
195
|
k = (i*nset) + j
|
|
187
196
|
l = (j*nset) + i
|
|
188
|
-
|
|
189
|
-
|
|
197
|
+
tmp = numpy.zeros((naux,naux), dtype=numpy.complex128)
|
|
198
|
+
for p0, p1 in lib.prange(0, nao, blksize):
|
|
199
|
+
tmp += numpy.tensordot(rhok_oo[k][:,p0:p1,:], rhok_oo[l][:,:,p0:p1], axes=([1,2], [2,1]))
|
|
190
200
|
vkaux[i,j] -= lib.einsum('xpq,pq->xp', int2c_e1, tmp)
|
|
191
201
|
t1 = logger.timer_debug1 (mf_grad, "df grad vj and vk aux (P'|Q) eval", *t1)
|
|
192
202
|
|
|
@@ -233,7 +243,7 @@ def get_j(mf_grad, mol=None, dm=None, hermi=0):
|
|
|
233
243
|
|
|
234
244
|
aux_loc = auxmol.ao_loc
|
|
235
245
|
max_memory = mf_grad.max_memory - lib.current_memory()[0]
|
|
236
|
-
blksize = int(min(max(max_memory * .5e6/8 / (nao**2*3), 20), naux,
|
|
246
|
+
blksize = int(min(max(max_memory * .5e6/8 / (nao**2*3), 20), naux, 80)) # 240 -> 80 for handling complex128
|
|
237
247
|
ao_ranges = df_rhf_grad.balance_partition(aux_loc, blksize)
|
|
238
248
|
|
|
239
249
|
# (ij|P), (nao, nao, naux)
|
|
@@ -241,8 +251,7 @@ def get_j(mf_grad, mol=None, dm=None, hermi=0):
|
|
|
241
251
|
for shl0, shl1, nL in ao_ranges:
|
|
242
252
|
int3c = get_int3c_s1((0, nbas, 0, nbas, shl0, shl1)) # (i,j|P)
|
|
243
253
|
p0, p1 = aux_loc[shl0], aux_loc[shl1]
|
|
244
|
-
|
|
245
|
-
rhoj[:,p0:p1] = numpy.tensordot(dms, int3c, axes=([1,2], [0,1]))
|
|
254
|
+
rhoj[:,p0:p1] = lib.einsum('ijp,aij->ap', int3c, dms)
|
|
246
255
|
int3c = None
|
|
247
256
|
|
|
248
257
|
# (P|Q), (naux, naux)
|
|
@@ -255,8 +264,7 @@ def get_j(mf_grad, mol=None, dm=None, hermi=0):
|
|
|
255
264
|
for shl0, shl1, nL in ao_ranges:
|
|
256
265
|
int3c = get_int3c_ip1((0, nbas, 0, nbas, shl0, shl1))
|
|
257
266
|
p0, p1 = aux_loc[shl0], aux_loc[shl1]
|
|
258
|
-
|
|
259
|
-
vj += numpy.tensordot(rhoj[:,p0:p1], int3c, axes=([1], [3]))
|
|
267
|
+
vj += lib.einsum('xijp,ap->axij', int3c, rhoj[:,p0:p1])
|
|
260
268
|
int3c = None
|
|
261
269
|
|
|
262
270
|
if mf_grad.auxbasis_response:
|
|
@@ -298,7 +306,7 @@ def _cho_solve_rhojk (mf_grad, mol, auxmol, orbol, orbor,
|
|
|
298
306
|
f_rhok = lib.H5TmpFile()
|
|
299
307
|
t1 = (logger.process_clock (), logger.perf_counter ())
|
|
300
308
|
max_memory = mf_grad.max_memory - lib.current_memory()[0]
|
|
301
|
-
blksize = max_memory * .5e6/8 / (naux*nao)
|
|
309
|
+
blksize = max_memory * .5e6/8 / (naux*nao) / 3 # Divided by 3 for handling complex128 safely (complex + buffer)
|
|
302
310
|
mol_ao_ranges = df_rhf_grad.balance_partition(ao_loc, blksize)
|
|
303
311
|
nsteps = len(mol_ao_ranges)
|
|
304
312
|
t2 = t1
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import numpy
|
|
2
|
+
from pyscf.dft import gen_grid
|
|
3
|
+
from pyscf.dft import radi
|
|
4
|
+
from pyscf.lib import logger
|
|
5
|
+
from fcdft.gto.mole import split_mol
|
|
6
|
+
import ipdb
|
|
7
|
+
|
|
8
|
+
# Grid for equilibrium DFT object.
|
|
9
|
+
|
|
10
|
+
def get_partition(mol, atom_slice, *args, **kwargs):
|
|
11
|
+
mol1, mol2 = split_mol(mol, atom_slice)
|
|
12
|
+
coords1, weights1 = gen_grid.get_partition(mol1, *args, **kwargs)
|
|
13
|
+
coords2, weights2 = gen_grid.get_partition(mol2, *args, **kwargs)
|
|
14
|
+
coords_all = [coords1, coords2]
|
|
15
|
+
weights_all = [weights1, weights2]
|
|
16
|
+
return coords_all, weights_all
|
|
17
|
+
|
|
18
|
+
class Grids(gen_grid.Grids):
|
|
19
|
+
_keys = {'atom_slice'}
|
|
20
|
+
|
|
21
|
+
def __init__(self, mol, atom_slice):
|
|
22
|
+
gen_grid.Grids.__init__(self, mol)
|
|
23
|
+
self.atom_slice = atom_slice
|
|
24
|
+
|
|
25
|
+
def build(self, mol=None, with_non0tab=False, sort_grids=True, **kwargs):
|
|
26
|
+
if mol is None: mol = self.mol
|
|
27
|
+
if self.verbose >= logger.WARN:
|
|
28
|
+
self.check_sanity()
|
|
29
|
+
atom_grids_tab = self.gen_atomic_grids(
|
|
30
|
+
mol, self.atom_grid, self.radi_method, self.level, self.prune, **kwargs)
|
|
31
|
+
self.coords, self.weights = self.get_partition(
|
|
32
|
+
mol, self.atom_slice, atom_grids_tab, self.radii_adjust, self.atomic_radii, self.becke_scheme)
|
|
33
|
+
mol1, mol2 = split_mol(mol, self.atom_slice)
|
|
34
|
+
mol = [mol1, mol2]
|
|
35
|
+
atm_idx1 = numpy.empty(self.coords[0].shape[0], dtype=numpy.int32)
|
|
36
|
+
atm_idx2 = numpy.empty(self.coords[1].shape[0], dtype=numpy.int32)
|
|
37
|
+
atm_idx = [atm_idx1, atm_idx2]
|
|
38
|
+
quad_weights1 = numpy.empty(self.coords[0].shape[0])
|
|
39
|
+
quad_weights2 = numpy.empty(self.coords[1].shape[0])
|
|
40
|
+
quadrature_weights = [quad_weights1, quad_weights2]
|
|
41
|
+
for i in range(2):
|
|
42
|
+
p0 = p1 = 0
|
|
43
|
+
for ia in range(mol[i].natm):
|
|
44
|
+
r, vol = atom_grids_tab[mol[i].atom_symbol(ia)]
|
|
45
|
+
p0, p1 = p1, p1 + vol.size
|
|
46
|
+
atm_idx[i][p0:p1] = ia
|
|
47
|
+
quadrature_weights[i][p0:p1] = vol
|
|
48
|
+
self.atm_idx = atm_idx
|
|
49
|
+
self.quadrature_weights = quadrature_weights
|
|
50
|
+
if sort_grids:
|
|
51
|
+
for i in range(2):
|
|
52
|
+
idx = gen_grid.arg_group_grids(mol[i], self.coords[i])
|
|
53
|
+
self.coords[i] = self.coords[i][idx]
|
|
54
|
+
self.weights[i] = self.weights[i][idx]
|
|
55
|
+
self.atm_idx[i] = self.atm_idx[i][idx]
|
|
56
|
+
self.quadrature_weights[i] = self.quadrature_weights[i][idx]
|
|
57
|
+
# ??
|
|
58
|
+
if self.alignment > 1:
|
|
59
|
+
padding = gen_grid._padding_size(self.size, self.alignment)
|
|
60
|
+
logger.debug(self, 'Padding %d grids', padding)
|
|
61
|
+
if padding > 0:
|
|
62
|
+
self.coords = numpy.vstack(
|
|
63
|
+
[self.coords, numpy.repeat([[1e-4]*3], padding, axis=0)])
|
|
64
|
+
self.weights = numpy.hstack([self.weights, numpy.zeros(padding)])
|
|
65
|
+
self.atm_idx = numpy.hstack([self.atm_idx, numpy.full(padding, -1, dtype=numpy.int32)])
|
|
66
|
+
self.quadrature_weights = numpy.hstack([self.quadrature_weights, numpy.zeros(padding)])
|
|
67
|
+
if with_non0tab:
|
|
68
|
+
non0tab = []
|
|
69
|
+
for i in range(2):
|
|
70
|
+
non0tab.append(self.make_mask(mol[i], self.coords[i]))
|
|
71
|
+
self.non0tab = non0tab
|
|
72
|
+
self.screen_index = self.non0tab
|
|
73
|
+
else:
|
|
74
|
+
self.screen_index = self.non0tab = None
|
|
75
|
+
logger.info(self, 'tot grids = %d', len(self.weights[0]) + len(self.weights[1]))
|
|
76
|
+
return self
|
|
77
|
+
|
|
78
|
+
def kernel(self, **kwargs):
|
|
79
|
+
self.dump_flags()
|
|
80
|
+
return self.build(**kwargs)
|
|
81
|
+
|
|
82
|
+
def get_partition(self, mol, atom_slice, atom_grids_tab=None,
|
|
83
|
+
radii_adjust=None, atomic_radii=radi.BRAGG_RADII,
|
|
84
|
+
becke_scheme=gen_grid.original_becke, concat=True):
|
|
85
|
+
if atom_grids_tab is None:
|
|
86
|
+
atom_grids_tab = self.gen_atomic_grids(mol)
|
|
87
|
+
return get_partition(mol, atom_slice, atom_grids_tab, radii_adjust, atomic_radii,
|
|
88
|
+
becke_scheme, concat=concat)
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
from pyscf.gto.mole import Mole
|
|
2
|
+
from pyscf.lib import logger
|
|
3
|
+
|
|
4
|
+
# def split_env(mol, atm, bas, env, atom_id):
|
|
5
|
+
# symbols = [mol.atom_symbol(i) for i in range(mol.natm)]
|
|
6
|
+
# sym1 = symbols[:atom_id]
|
|
7
|
+
# from pyscf.gto.mole import make_bas_env
|
|
8
|
+
# len_env = 0
|
|
9
|
+
# for symb, basis_add in mol._basis.items():
|
|
10
|
+
# if symb in sym1:
|
|
11
|
+
# _, env0 = make_bas_env(basis_add, 0, 0)
|
|
12
|
+
# len_env += len(env0)
|
|
13
|
+
|
|
14
|
+
# env1, env2 = [numpy.zeros(PTR_ENV_START)], [numpy.zeros(PTR_ENV_START)]
|
|
15
|
+
# env1.append(env[PTR_ENV_START:PTR_ENV_START+4*atom_id])
|
|
16
|
+
# env2.append(env[PTR_ENV_START+4*atom_id:PTR_ENV_START+4*len(atm)])
|
|
17
|
+
# env1, env2 = env[:len_env], env[len_env:]
|
|
18
|
+
# idx = numpy.where(bas[:,0] == atom_id)[0][0]
|
|
19
|
+
# bas1, bas2 = bas[:idx].copy(), bas[idx:].copy()
|
|
20
|
+
# off = len(env1)
|
|
21
|
+
# natm_off = atom_id
|
|
22
|
+
# atm1, atm2 = atm[:atom_id].copy(), atm[atom_id:].copy()
|
|
23
|
+
# atm2[:,PTR_COORD] -= off
|
|
24
|
+
# atm2[:,PTR_ZETA ] -= off
|
|
25
|
+
# bas2[:,ATOM_OF ] -= natm_off
|
|
26
|
+
# bas2[:,PTR_EXP ] -= off
|
|
27
|
+
# bas2[:,PTR_COEFF] -= off
|
|
28
|
+
# return atm1, bas1, env1, atm2, bas2, env2
|
|
29
|
+
|
|
30
|
+
def conc_mol(mol1, mol2):
|
|
31
|
+
from pyscf.gto import mole
|
|
32
|
+
mol = mole.conc_mol(mol1, mol2)
|
|
33
|
+
if mol1.basis == mol2.basis:
|
|
34
|
+
mol.basis = mol1.basis
|
|
35
|
+
return mol
|
|
36
|
+
|
|
37
|
+
def split_mol(mol, atom_id):
|
|
38
|
+
'''Split the molecule into two Mole objects.
|
|
39
|
+
Reverse of conc_mol in pyscf.gto.mole
|
|
40
|
+
'''
|
|
41
|
+
if not mol._built:
|
|
42
|
+
logger.warn(mol, 'Warning: object %s not initialized. Initializing %s',
|
|
43
|
+
mol, mol)
|
|
44
|
+
mol.build()
|
|
45
|
+
|
|
46
|
+
# TODO: mol.stdout for logger
|
|
47
|
+
mol1, mol2 = Mole(), Mole()
|
|
48
|
+
mol1.basis = mol2.basis = mol.basis
|
|
49
|
+
mol1.verbose = mol2.verbose = mol.verbose
|
|
50
|
+
mol1.stdout = mol2.stdout = mol.stdout
|
|
51
|
+
mol1.output = mol2.output = mol.output
|
|
52
|
+
mol1.max_memory = mol2.max_memory = mol.max_memory
|
|
53
|
+
mol1.spin = mol2.spin = 0
|
|
54
|
+
mol1.symmetry = mol2.symmetry = False
|
|
55
|
+
mol1.symmetry_subgroup = mol2.symmetry_subgroup = None
|
|
56
|
+
mol1.cart = mol2.cart = mol.cart
|
|
57
|
+
mol1._atom = mol._atom[:atom_id]
|
|
58
|
+
mol2._atom = mol._atom[atom_id:]
|
|
59
|
+
mol1.unit = mol2.unit = 'Bohr'
|
|
60
|
+
mol1.build(), mol2.build()
|
|
61
|
+
|
|
62
|
+
return mol1, mol2
|
|
63
|
+
|
|
64
|
+
if __name__=='__main__':
|
|
65
|
+
from pyscf import gto
|
|
66
|
+
mol1 = gto.M(
|
|
67
|
+
atom='''
|
|
68
|
+
C -1.1367537947 0.1104289172 2.4844663896
|
|
69
|
+
C -1.1385831318 0.1723328088 3.8772156394
|
|
70
|
+
C 0.0819843127 0.0788096973 1.7730802291
|
|
71
|
+
H -2.0846565855 0.1966185690 4.4236084687
|
|
72
|
+
C 0.0806058727 0.2041086872 4.5921211233
|
|
73
|
+
C 1.2993389981 0.1104289172 2.4844663896
|
|
74
|
+
H 2.2526138470 0.0865980845 1.9483127672
|
|
75
|
+
C 1.2994126658 0.1723829840 3.8783367991
|
|
76
|
+
H 2.2453411518 0.1966879024 4.4251589385
|
|
77
|
+
H -2.0869454458 0.0863720324 1.9432143952
|
|
78
|
+
C 0.0810980584 0.2676328718 6.0213144069
|
|
79
|
+
N 0.0819851974 0.3199013851 7.1972568519
|
|
80
|
+
S 0.0000000000 0.0000000000 0.0000000000
|
|
81
|
+
H 1.3390319419 -0.0095801980 -0.2157234144''',
|
|
82
|
+
charge=0, basis='6-31g**', verbose=5)
|
|
83
|
+
mol2 = gto.M(
|
|
84
|
+
atom='''
|
|
85
|
+
C -0.8476079365 0.0026700202 -3.5281035617
|
|
86
|
+
C -2.0218283577 -0.2604683627 -2.8073958219
|
|
87
|
+
C 0.3353012600 0.2642432684 -2.8231212050
|
|
88
|
+
H -2.9520951875 -0.4549635668 -3.3338745954
|
|
89
|
+
H 1.2611570861 0.4600128780 -3.3568350109
|
|
90
|
+
C -2.0073245682 -0.2604462093 -1.4139657047
|
|
91
|
+
C 0.3383704802 0.2619859179 -1.4285927349
|
|
92
|
+
H -2.9349818456 -0.4420746761 -0.8791308006
|
|
93
|
+
H 1.2732326220 0.4430128273 -0.9060391242
|
|
94
|
+
C -0.8293545128 0.0002996322 -0.6916543989
|
|
95
|
+
C -0.8192397451 -0.0006201775 0.7937732451
|
|
96
|
+
C -1.5616839183 -0.9482725602 1.5218647171
|
|
97
|
+
C -0.0671411632 0.9462610490 1.5129186979
|
|
98
|
+
C -1.5541603792 -0.9481485004 2.9180008413
|
|
99
|
+
C -0.0558307025 0.9446630867 2.9090260355
|
|
100
|
+
C -0.8001707945 -0.0022152441 3.6187748549
|
|
101
|
+
H -2.1295491966 -1.7060626237 0.9896596517
|
|
102
|
+
H 0.4930453218 1.7050509252 0.9740007250
|
|
103
|
+
H -2.1296311282 -1.6947234290 3.4583587491
|
|
104
|
+
H 0.5267024257 1.6907508988 3.4424644381
|
|
105
|
+
H -0.7929373074 -0.0027907562 4.7049223527
|
|
106
|
+
S -0.9353266992 -0.0162143726 -5.3112847893
|
|
107
|
+
H 0.3533301599 0.3018611373 -5.5386460312''',
|
|
108
|
+
charge=0, basis='6-31g**', verbose=5)
|
|
109
|
+
mol = gto.conc_mol(mol1, mol2)
|
|
110
|
+
_mol1, _mol2 = split_mol(mol, 14)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#include <stdlib.h>
|
|
2
|
+
#include <stdio.h>
|
|
3
|
+
#include <stdint.h>
|
|
4
|
+
#include <omp.h>
|
|
5
|
+
#include "cblas.h"
|
|
6
|
+
|
|
7
|
+
void nr_mapdm1(double *buf, double *eri, double *dms, int nao, int naux) {
|
|
8
|
+
// vk shape: (nao, nao), (155,155)
|
|
9
|
+
// eri shape: (naux, nao, nao) (240,155,155)
|
|
10
|
+
// dms shape: (nao, nao) (155,155)
|
|
11
|
+
// buf shape: (naux, nao, nao) (240,155,155)
|
|
12
|
+
cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, naux*nao, nao, nao, 1.0, eri, nao, dms, nao, 0.0, buf, nao);
|
|
13
|
+
}
|
|
@@ -36,12 +36,16 @@ void roots_legendre(int n, double *abscissas, double *weights){
|
|
|
36
36
|
|
|
37
37
|
double occ_drv(double sampling, double moe_energy, double fermi, double broad, double smear) {
|
|
38
38
|
double dist = 1 / (exp((sampling - fermi)/smear) + 1);
|
|
39
|
-
|
|
39
|
+
double a = sampling - moe_energy;
|
|
40
|
+
double b = broad / 2.0;
|
|
41
|
+
return dist * broad / (a*a + b*b) / TWO_PI;
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
double occ_grad_drv(double sampling, double moe_energy, double fermi, double broad, double smear) {
|
|
43
45
|
double dist = 1 / (exp((sampling - fermi)/smear) + 1);
|
|
44
|
-
|
|
46
|
+
double a = sampling - moe_energy;
|
|
47
|
+
double b = broad / 2.0;
|
|
48
|
+
return dist * (1 - dist) * broad / (a*a + b*b) / TWO_PI / smear;
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
void fermi_level_drv(double *moe_energy, double *abscissas, double *weights, double fermi, double broad, double smear, double window, int pts, int nbas, double *mo_occ, double *mo_grad) {
|