1{
2 lib,
3 stdenv,
4 fetchFromGitHub,
5 autoconf,
6 automake,
7 libtool,
8 python3,
9 perl,
10 gmpxx,
11 mpfr,
12 boost,
13 eigen,
14 gfortran,
15 cmake,
16 enableFMA ? stdenv.hostPlatform.fmaSupport,
17 enableFortran ? true,
18 enableSSE ? (!enableFortran) && stdenv.hostPlatform.isx86_64,
19
20 # Maximum angular momentum of basis functions
21 # 7 is required for def2/J auxiliary basis on 3d metals upwards
22 maxAm ? 7,
23
24 # ERI derivative order for 4-, 3- and 2-centre ERIs.
25 # 2nd derivatives are defaults and allow gradients Hessians with density fitting
26 # Setting them to zero disables derivatives.
27 eriDeriv ? 2,
28 eri3Deriv ? 2,
29 eri2Deriv ? 2,
30
31 # Angular momentum for derivatives of ERIs. Takes a list of length $DERIV_ORD+1.
32 # Starting from index 0, each index i specifies the supported angular momentum
33 # for the derivative order i, e.g. [6,5,4] supports ERIs for l=6, their first
34 # derivatives for l=5 and their second derivatives for l=4.
35 eriAm ? (builtins.genList (i: maxAm - 1 - i) (eriDeriv + 1)),
36 eri3Am ? (builtins.genList (i: maxAm - i) (eri2Deriv + 1)),
37 eri2Am ? (builtins.genList (i: maxAm - i) (eri2Deriv + 1)),
38
39 # Same as above for optimised code. Higher optimisations take a long time.
40 eriOptAm ? (builtins.genList (i: maxAm - 3 - i) (eriDeriv + 1)),
41 eri3OptAm ? (builtins.genList (i: maxAm - 3 - i) (eri2Deriv + 1)),
42 eri2OptAm ? (builtins.genList (i: maxAm - 3 - i) (eri2Deriv + 1)),
43
44 # One-Electron integrals of all kinds including multipole integrals.
45 # Libint does not build them and their derivatives by default.
46 enableOneBody ? false,
47 oneBodyDerivOrd ? 2,
48 multipoleOrd ? 4, # Maximum order of multipole integrals, 4=octopoles
49
50 # Whether to enable generic code if angular momentum is unsupported
51 enableGeneric ? true,
52
53 # Support integrals over contracted Gaussian
54 enableContracted ? true,
55
56 # Spherical harmonics/Cartesian orbital conventions
57 cartGaussOrd ? "standard", # Ordering of Cartesian basis functions, "standard" is CCA
58 shGaussOrd ? "standard", # Ordering of spherical harmonic basis functions. "standard" is -l to +l, "guassian" is 0, 1, -1, 2, -2, ...
59 shellSet ? "standard",
60 eri3PureSh ? false, # Transformation of 3-centre ERIs into spherical harmonics
61 eri2PureSh ? false, # Transformation of 2-centre ERIs into spherical harmonics
62}:
63
64# Check that Fortran bindings are not used together with SIMD real type
65assert (if enableFortran then !enableSSE else true);
66
67# Check that a possible angular momentum for basis functions is used
68assert (maxAm >= 1 && maxAm <= 8);
69
70# Check for valid derivative order in ERIs
71assert (eriDeriv >= 0 && eriDeriv <= 4);
72assert (eri2Deriv >= 0 && eri2Deriv <= 4);
73assert (eri3Deriv >= 0 && eri3Deriv <= 4);
74
75# Ensure valid arguments for generated angular momenta in ERI derivatives are used.
76assert (
77 builtins.length eriAm == eriDeriv + 1
78 && builtins.foldl' (a: b: a && b) true (builtins.map (a: a <= maxAm && a >= 0) eriAm)
79);
80assert (
81 builtins.length eri3Am == eriDeriv + 1
82 && builtins.foldl' (a: b: a && b) true (builtins.map (a: a <= maxAm && a >= 0) eri3Am)
83);
84assert (
85 builtins.length eri2Am == eriDeriv + 1
86 && builtins.foldl' (a: b: a && b) true (builtins.map (a: a <= maxAm && a >= 0) eri2Am)
87);
88
89# Ensure valid arguments for generated angular momenta in optimised ERI derivatives are used.
90assert (
91 builtins.length eriOptAm == eriDeriv + 1
92 && builtins.foldl' (a: b: a && b) true (builtins.map (a: a <= maxAm && a >= 0) eriOptAm)
93);
94assert (
95 builtins.length eri3OptAm == eriDeriv + 1
96 && builtins.foldl' (a: b: a && b) true (builtins.map (a: a <= maxAm && a >= 0) eri3OptAm)
97);
98assert (
99 builtins.length eri2OptAm == eriDeriv + 1
100 && builtins.foldl' (a: b: a && b) true (builtins.map (a: a <= maxAm && a >= 0) eri2OptAm)
101);
102
103# Ensure a valid derivative order for one-electron integrals
104assert (oneBodyDerivOrd >= 0 && oneBodyDerivOrd <= 4);
105
106# Check that valid basis shell orders are used, see https://github.com/evaleev/libint/wiki
107assert (
108 builtins.elem cartGaussOrd [
109 "standard"
110 "intv3"
111 "gamess"
112 "orca"
113 "bagel"
114 ]
115);
116assert (
117 builtins.elem shGaussOrd [
118 "standard"
119 "gaussian"
120 ]
121);
122assert (
123 builtins.elem shellSet [
124 "standard"
125 "orca"
126 ]
127);
128
129let
130 pname = "libint";
131 version = "2.11.1";
132
133 meta = {
134 description = "Library for the evaluation of molecular integrals of many-body operators over Gaussian functions";
135 homepage = "https://github.com/evaleev/libint";
136 license = with lib.licenses; [
137 lgpl3Only
138 gpl3Only
139 ];
140 maintainers = with lib.maintainers; [
141 markuskowa
142 sheepforce
143 ];
144 platforms = [ "x86_64-linux" ];
145 };
146
147 codeGen = stdenv.mkDerivation {
148 inherit pname version;
149
150 src = fetchFromGitHub {
151 owner = "evaleev";
152 repo = "libint";
153 rev = "v${version}";
154 hash = "sha256-oV/RWWfD0Kf2egI40fV8z2atG+4Cs+9+Wvy0euNNjtM=";
155 };
156
157 # Replace hardcoded "/bin/rm" with normal "rm"
158 postPatch = ''
159 for f in \
160 bin/ltmain.sh \
161 configure.ac \
162 src/bin/libint/Makefile \
163 src/lib/libint/Makefile.library \
164 tests/eri/Makefile \
165 tests/hartree-fock/Makefile \
166 tests/unit/Makefile; do
167 substituteInPlace $f --replace-warn "/bin/rm" "rm"
168 done
169 '';
170
171 nativeBuildInputs = [
172 autoconf
173 automake
174 libtool
175 mpfr
176 python3
177 perl
178 gmpxx
179 ]
180 ++ lib.optional enableFortran gfortran;
181
182 buildInputs = [
183 boost
184 eigen
185 ];
186
187 configureFlags = [
188 "--with-max-am=${builtins.toString maxAm}"
189 "--with-eri-max-am=${lib.concatStringsSep "," (builtins.map builtins.toString eriAm)}"
190 "--with-eri3-max-am=${lib.concatStringsSep "," (builtins.map builtins.toString eri3Am)}"
191 "--with-eri2-max-am=${lib.concatStringsSep "," (builtins.map builtins.toString eri2Am)}"
192 "--with-eri-opt-am=${lib.concatStringsSep "," (builtins.map builtins.toString eriOptAm)}"
193 "--with-eri3-opt-am=${lib.concatStringsSep "," (builtins.map builtins.toString eri3OptAm)}"
194 "--with-eri2-opt-am=${lib.concatStringsSep "," (builtins.map builtins.toString eri2OptAm)}"
195 "--with-cartgauss-ordering=${cartGaussOrd}"
196 "--with-shgauss-ordering=${shGaussOrd}"
197 "--with-shell-set=${shellSet}"
198 ]
199 ++ lib.optional enableFMA "--enable-fma"
200 ++ lib.optional (eriDeriv > 0) "--enable-eri=${builtins.toString eriDeriv}"
201 ++ lib.optional (eri2Deriv > 0) "--enable-eri2=${builtins.toString eri2Deriv}"
202 ++ lib.optional (eri3Deriv > 0) "--enable-eri3=${builtins.toString eri3Deriv}"
203 ++ lib.optionals enableOneBody [
204 "--enable-1body=${builtins.toString oneBodyDerivOrd}"
205 "--enable-1body-property-derivs"
206 ]
207 ++ lib.optional (multipoleOrd > 0) "--with-multipole-max-order=${builtins.toString multipoleOrd}"
208 ++ lib.optional enableGeneric "--enable-generic"
209 ++ lib.optional enableContracted "--enable-contracted-ints"
210 ++ lib.optional eri3PureSh "--enable-eri3-pure-sh"
211 ++ lib.optional eri2PureSh "--enable-eri2-pure-sh";
212
213 preConfigure = ''
214 ./autogen.sh
215 '';
216
217 makeFlags = [ "export" ];
218
219 installPhase = ''
220 mkdir -p $out
221 cp libint-${version}.tgz $out/.
222 '';
223
224 enableParallelBuilding = true;
225
226 inherit meta;
227 };
228
229 codeComp = stdenv.mkDerivation {
230 inherit pname version;
231
232 src = "${codeGen}/libint-${version}.tgz";
233
234 nativeBuildInputs = [
235 python3
236 cmake
237 ]
238 ++ lib.optional enableFortran gfortran;
239
240 buildInputs = [
241 boost
242 eigen
243 ];
244
245 # Default is just "double", but SSE2 is available on all x86_64 CPUs.
246 # AVX support is advertised, but does not work.
247 # Fortran interface is incompatible with changing the LIBINT2_REALTYPE.
248 cmakeFlags = [
249 "-DLIBINT2_SHGAUSS_ORDERING=${shGaussOrd}"
250 ]
251 ++ lib.optional enableFortran "-DENABLE_FORTRAN=ON"
252 ++ lib.optional enableSSE "-DLIBINT2_REALTYPE=libint2::simd::VectorSSEDouble";
253
254 # Can only build in the source-tree. A lot of preprocessing magic fails otherwise.
255 dontUseCmakeBuildDir = true;
256
257 inherit meta;
258 };
259
260in
261codeComp