MADNESS 0.10.1
gth_pseudopotential.h
Go to the documentation of this file.
1/// \file gth_pseudopotential.cc
2/// \brief GTH pseudopotential functionality
3/// \defgroup moldft The molecular density functional and Hartree-Fock code
4
5#ifndef MADNESS_CHEM_GTH_PSEUDOPOTENTIAL_H__INCLUDED
6#define MADNESS_CHEM_GTH_PSEUDOPOTENTIAL_H__INCLUDED
7
8#include <madness/mra/mra.h>
9#include <madness/external/tinyxml/tinyxml.h>
10
14
15namespace madness {
16
17typedef Tensor<double> tensorT;
18
19double get_charge_from_file(const std::string filename, unsigned int atype);
20
21/*template <typename Q, int NDIM>
22struct function_real2complex_op
23{
24 typedef std::complex<Q> resultT;
25 Tensor<resultT> operator()(const Key<NDIM>& key, const Tensor<Q>& t) const
26 {
27 Tensor<resultT> result(t.ndim(), t.dims());
28 BINARY_OPTIMIZED_ITERATOR(const Q, t, resultT, result, *_p1 = resultT(*_p0,0.0););
29 return result;
30 }
31 template <typename Archive>
32 void serialize(Archive& ar) {}
33};
34
35Function<std::complex<double>,3> function_real2complex(const Function<double,3>& r)
36{
37 return unary_op_coeffs(r, function_real2complex_op<double,3>());
38}*/
39
40class VLocalFunctor : public FunctionFunctorInterface<double,3> {
41private:
42 double Zeff, zi, C1, C2, C3, C4;
44 std::vector<coord_3d> specialpts;
45
46public:
47 using FunctionFunctorInterface<double,3>::operator();
48
49 VLocalFunctor(double Zeff, double zi,
50 double C1, double C2, double C3, double C4, const coord_3d& center)
51 : Zeff(Zeff), zi(zi), C1(C1), C2(C2),
52 C3(C3), C4(C4), center(center) {
53 specialpts.push_back(center);
54 }
55
56 double operator()(const coord_3d& r) const final {
57 const double x = r[0]-center[0]; const double y = r[1]-center[1]; const double z = r[2]-center[2];
58 double rr = std::sqrt(x*x + y*y + z*z);
59 double rs = rr/zi;
60 double rs2 = rs*rs; double rs4 = rs2*rs2; double rs6 = rs2*rs4;
61 return -(Zeff/rr)*erf(rs/std::sqrt(2.0))
62 + std::exp(-0.5*rs2)*
63 (C1 + C2*rs2 + C3*rs4 + C4*rs6);
64 }
65
66 std::vector<coord_3d> special_points() const final {return specialpts;}
67
69 return 6;
70 }
71};
72
73class ProjRLMFunctor : public FunctionFunctorInterface<double,3> {
74private:
75 double alpha; // radius
76 int l, m; // i = 1,2,3 and m = 0,1,2,3 and l = 0,1,2,3 (angular momentum) (i just used in constructor)
78 std::vector<coord_3d> specialpts;
79 // gamma of half-integers starting and 1 (which means 1/2)
80 /*const double gamma_data[17] = {1.0, 0.0, 1.0/2.0, 0.0, 3.0/4.0, 0.0, 15.0/8.0, 0.0, 105.0/16.0, 0.0,
81 945.0/32.0, 0.0, 10395.0/64.0, 0.0, 135135.0/128.0, 0.0, 2027025.0/256.0};*/
82 double sqrtPI;
83 int itmp, itmp2;
84 double t1;
85
86public:
87
88 using FunctionFunctorInterface<double,3>::operator();
89
90 virtual bool supports_vectorized() const final {return false;}
91
92 static const double gamma_data[17];
93
94 ProjRLMFunctor(double alpha, int l, int m, int i, const coord_3d& center)
95 : alpha(alpha), l(l), m(m), center(center) {
96 specialpts.push_back(coord_3d(0.0));
97 sqrtPI = std::sqrt(constants::pi);
98 itmp = 2*l + (4*i-1);
99 itmp2 = 2*(i-1);
100 t1 = 1./std::pow(alpha, 0.5*(double)itmp)/std::sqrt(gamma_data[itmp-1]*sqrtPI);
101 }
102
103 double operator()(const coord_3d& r) const final {
104 double x = r[0]-center[0]; double y = r[1]-center[1]; double z = r[2]-center[2];
105 double rsq = x*x + y*y + z*z;
106
107 if (rsq > 40.0) return 0.0;
108
109 double rr = std::sqrt(rsq);
110 double rval = t1;
111 const double PI = constants::pi;
112 // Radial part
113 if (itmp2 == 0) {
114 rval *= std::sqrt(2);
115 }
116 else if (itmp2 == 1) {
117 rval *= rr*std::sqrt(2);
118 }
119 else if (itmp2 == 2) {
120 rval *= rsq*std::sqrt(2);
121 }
122 else if (itmp2 == 3) {
123 rval *= rr*rsq*std::sqrt(2);
124 }
125 else if (itmp2 == 4) {
126 rval *= rsq*rsq*std::sqrt(2);
127 }
128 else if (itmp2 == 5) {
129 rval *= rr*rsq*rsq*std::sqrt(2);
130 }
131 else if (itmp2 == 6) {
132 rval *= rsq*rsq*rsq*std::sqrt(2);
133 }
134 else if (itmp2 == 7) {
135 rval *= rr*rsq*rsq*rsq*std::sqrt(2);
136 }
137 // Angular part
138 if (l == 0) {
139 rval *= (1./2.)*std::sqrt(1./PI);
140 } else if (l == 1) {
141 if (m == 0) {
142 rval *= std::sqrt(3./4./PI)*x;
143 }
144 else if (m == 1) {
145 rval *= std::sqrt(3./4./PI)*y;
146 }
147 else if (m == 2) {
148 rval *= std::sqrt(3./4./PI)*z;
149 }
150 else {
151 MADNESS_EXCEPTION("m out of range for l = 1", 0);
152 }
153 } else if (l == 2) {
154 if (m == 0) {
155 rval *= (1./4.)*std::sqrt(5./PI)*(-x*x - y*y + 2*z*z);
156 }
157 else if (m == 1) {
158 rval *= (1./2.)*std::sqrt(15./PI)*(y*z);
159 }
160 else if (m == 2) {
161 rval *= (1./2.)*std::sqrt(15./PI)*(x*z);
162 }
163 else if (m == 3) {
164 rval *= (1./2.)*std::sqrt(15./PI)*(x*y);
165 }
166 else if (m == 4) {
167 rval *= (1./4.)*std::sqrt(15./PI)*(x*x - y*y);
168 }
169 else {
170 MADNESS_EXCEPTION("m out of range for l = 2", 0);
171 }
172 }
173 rval *= std::exp(-0.5*(rsq/alpha/alpha));
174 return rval;
175 }
176
177 virtual bool screened(const coord_3d& c1, const coord_3d& c2) const final {
178 double ftol = 1e-12;
179
180 double x1 = c1[0]; double y1 = c1[1]; double z1 = c1[2];
181 double x2 = c2[0]; double y2 = c2[1]; double z2 = c2[2];
182
183 // if center is inside box, then return false
184 // otherwise, look for the closest point and check
185 bool inside = (center[0] >= x1) && (center[0] <= x2) &&
186 (center[1] >= y1) && (center[1] <= y2) &&
187 (center[2] >= z1) && (center[2] <= z2);
188 if (inside) {
189 return false;
190 }
191 else {
192 //printf("GTH_pseudopotential: (point not inside)\n");
193 //print(" c1: ", c1, " c2: ", c2);
194 double minr = 1e10;
195 int ii = -1; int jj = -1; int kk = -1;
196 for (int i = 0; i <= 1; i++) {
197 for (int j = 0; j <= 1; j++) {
198 for (int k = 0; k <= 1; k++) {
199 double x = (i == 0) ? c1[0] : c2[0];
200 double y = (j == 0) ? c1[1] : c2[1];
201 double z = (k == 0) ? c1[2] : c2[2];
202 coord_3d rr = coord_3d{x, y, z} - center;
203 double rsq = rr[0]*rr[0]+rr[1]*rr[1]+rr[2]*rr[2];
204 // print("current minr: ", minr, " point: ", {x,y,z}, " center: ", center, " p: ", {x,y,z}, " rsq: ", rsq);
205 if (minr > rsq) {
206 minr = rsq;
207 ii = i; jj = j; kk = k;
208 }
209 }
210 }
211 }
212 //print("ii: ", ii, "jj: ", jj, "kk: ", kk);
213 //printf("\n");
214 if ((ii < 0) || (jj < 0) || (kk < 0)) MADNESS_EXCEPTION("GTH_Pseudopotential: failed to find suitable minimum point\n", 0);
215 double x = (ii == 0) ? c1[0] : c2[0];
216 double y = (jj == 0) ? c1[1] : c2[1];
217 double z = (kk == 0) ? c1[2] : c2[2];
218 double fval = this->operator()({x, y, z});
219 if (fabs(fval) < ftol) return true;
220 else return false;
221 }
222 }
223
224 virtual void operator()(const Vector<double*,3>& xvals, double* MADNESS_RESTRICT fvals, int npts) const final {
225
226 double* x = new double[npts];
227 double* y = new double[npts];
228 double* z = new double[npts];
229 double* rsq = new double[npts];
230 double* rr = new double[npts];
231
232 double* x1 = xvals[0]; double* x2 = xvals[1]; double* x3 = xvals[2];
233 for (int i = 0; i < npts; i++) {
234 x[i] = x1[i]-center[0];
235 y[i] = x2[i]-center[1];
236 z[i] = x3[i]-center[2];
237 rsq[i] = x[i]*x[i] + y[i]*y[i] + z[i]*z[i];
238 rr[i] = std::sqrt(rsq[i]);
239 fvals[i] = t1;
240 }
241
242 const double PI = constants::pi;
243
244 // Radial part
245 if (itmp2 == 0) {
246 for (int i = 0; i < npts; i++) {
247 fvals[i] *= std::sqrt(2);
248 }
249 }
250 else if (itmp2 == 1) {
251 for (int i = 0; i < npts; i++) {
252 fvals[i] *= rr[i]*std::sqrt(2);
253 }
254 }
255 else if (itmp2 == 2) {
256 for (int i = 0; i < npts; i++) {
257 fvals[i] *= rsq[i]*std::sqrt(2);
258 }
259 }
260 else if (itmp2 == 3) {
261 for (int i = 0; i < npts; i++) {
262 fvals[i] *= rr[i]*rsq[i]*std::sqrt(2);
263 }
264 }
265 else if (itmp2 == 4) {
266 for (int i = 0; i < npts; i++) {
267 fvals[i] *= rsq[i]*rsq[i]*std::sqrt(2);
268 }
269 }
270 else if (itmp2 == 5) {
271 for (int i = 0; i < npts; i++) {
272 fvals[i] *= rr[i]*rsq[i]*rsq[i]*std::sqrt(2);
273 }
274 }
275 else if (itmp2 == 6) {
276 for (int i = 0; i < npts; i++) {
277 fvals[i] *= rsq[i]*rsq[i]*rsq[i]*std::sqrt(2);
278 }
279 }
280 else if (itmp2 == 7) {
281 for (int i = 0; i < npts; i++) {
282 fvals[i] *= rr[i]*rsq[i]*rsq[i]*rsq[i];
283 }
284 }
285 // Angular part
286 if (l == 0) {
287 for (int i = 0; i < npts; i++) {
288 fvals[i] *= (1./2.)*std::sqrt(1./PI)*std::exp(-0.5*(rsq[i]/alpha/alpha));
289 }
290 } else if (l == 1) {
291 if (m == 0) {
292 for (int i = 0; i < npts; i++) {
293 fvals[i] *= std::sqrt(3./4./PI)*x[i]*std::exp(-0.5*(rsq[i]/alpha/alpha));
294 }
295 }
296 else if (m == 1) {
297 for (int i = 0; i < npts; i++) {
298 fvals[i] *= std::sqrt(3./4./PI)*y[i]*std::exp(-0.5*(rsq[i]/alpha/alpha));
299 }
300 }
301 else if (m == 2) {
302 for (int i = 0; i < npts; i++) {
303 fvals[i] *= std::sqrt(3./4./PI)*z[i]*std::exp(-0.5*(rsq[i]/alpha/alpha));
304 }
305 }
306 else {
307 MADNESS_EXCEPTION("m out of range for l = 1", 0);
308 }
309 } else if (l == 2) {
310 if (m == 0) {
311 for (int i = 0; i < npts; i++) {
312 fvals[i] *= (1./4.)*std::sqrt(5./PI)*(-x[i]*x[i] - y[i]*y[i] + 2*z[i]*z[i])*std::exp(-0.5*(rsq[i]/alpha/alpha));
313 }
314 }
315 else if (m == 1) {
316 for (int i = 0; i < npts; i++) {
317 fvals[i] *= (1./2.)*std::sqrt(15./PI)*(y[i]*z[i])*std::exp(-0.5*(rsq[i]/alpha/alpha));
318 }
319 }
320 else if (m == 2) {
321 for (int i = 0; i < npts; i++) {
322 fvals[i] *= (1./2.)*std::sqrt(15./PI)*(x[i]*z[i])*std::exp(-0.5*(rsq[i]/alpha/alpha));
323 }
324 }
325 else if (m == 3) {
326 for (int i = 0; i < npts; i++) {
327 fvals[i] *= (1./2.)*std::sqrt(15./PI)*(x[i]*y[i])*std::exp(-0.5*(rsq[i]/alpha/alpha));
328 }
329 }
330 else if (m == 4) {
331 for (int i = 0; i < npts; i++) {
332 fvals[i] *= (1./4.)*std::sqrt(15./PI)*(x[i]*x[i] - y[i]*y[i])*std::exp(-0.5*(rsq[i]/alpha/alpha));
333 }
334 }
335 else {
336 MADNESS_EXCEPTION("m out of range for l = 2", 0);
337 }
338 }
339 //for (int i = 0; i < npts; i++) {
340 // fvals[i] *= std::exp(-0.5*(rsq[i]/alpha/alpha));
341 //}
342
343 delete [] x;
344 delete [] y;
345 delete [] z;
346 delete [] rsq;
347 delete [] rr;
348 }
349
350 std::vector<coord_3d> special_points() const final {return specialpts;}
351
353 return 6;
354 }
355};
356
358private:
359 int maxL;
362
363public:
366
367 real_function_3d nlmproj(World& world, int l, int m, int i) {
368 // real_function_3d f1 = (m < 2*l+1) ?
369 // real_factory_3d(world).functor(real_functor_3d(new ProjRLMFunctor(radii(l), l, m, i, center))).
370 // truncate_on_project().nofence().truncate_mode(0) : real_factory_3d(world);
371
373 if (m < 2*l+1) {
374 auto functor = real_functor_3d(new ProjRLMFunctor(radii(l), l, m, i, center));
375 f1 = real_factory_3d(world).functor(functor).truncate_on_project().nofence().truncate_mode(0);
376 }
377 else {
378 f1 = real_factory_3d(world);
379 }
380
381 return f1;
382 }
383
384 ProjRLMFunctor nlmproj_functor(World& world, int l, int m, int i) {
385 return ProjRLMFunctor(radii(l), l, m, i, center);
386 }
387};
388
389template <typename Q>
391private:
392public:
394 std::array<real_tensor,118> localp;
395 std::array<real_tensor,118> radii;
396 std::array<real_tensor,118> hlij;
397 std::array<real_tensor,118> klij;
399 std::vector<unsigned int> atoms_with_projectors;
400
401
402public:
404
406 // Load info from file
407 load_pseudo_from_file(world, "gth.xml");
408 atoms_with_projectors.clear();
409
410 // fill list with atoms-with-projectors (i.e. not H or He)
411 for (size_t iatom = 0; iatom < molecule.natom(); iatom++) {
412 Atom atom = molecule.get_atom(iatom);
413
414 //make sure this is actually a pseudo-atom
415 if (!atom.pseudo_atom) continue;
416
417 unsigned int atype = atom.atomic_number;
418 if (radii[atype-1].dim(0) > 0)
419 atoms_with_projectors.push_back(iatom);
420 }
421
422 vlocalp = real_factory_3d(world);
424 for (size_t iatom = 0; iatom < molecule.natom(); iatom++) {
425 // Get atom and its associated GTH tensors
426 Atom atom = molecule.get_atom(iatom);
427
428 //make sure this is actually a pseudo-atom
429 if (!atom.pseudo_atom) continue;
430
431 coord_3d center = atom.get_coords();
432 unsigned int atype = atom.atomic_number;
433 // do local part
434 real_tensor atom_localp = localp[atype-1];
435 real_function_3d temp = real_factory_3d(world).functor(
436 real_functor_3d(new
437 VLocalFunctor(atom_localp[0], atom_localp[1], atom_localp[2], atom_localp[3], atom_localp[4], atom_localp[5], center))).
438 truncate_mode(0).truncate_on_project();
439 temp.compress();
440 //vlocalp += temp;
441 vlocalp.gaxpy(1.0, temp, 1.0, true);
442 }
443 }
444
446 return vlocalp;
447 }
448
449 void reproject(int k, double thresh) {
451 }
452
453 void load_pseudo_from_file(World& world, const std::string filename) {
454 bool debug = true;
455
456 TiXmlDocument doc(filename);
457 if (!doc.LoadFile()) {
458 MADNESS_EXCEPTION("Failed to load GTH pseudopotential file", 0);
459 }
460
461 for (size_t iatom = 0; iatom < molecule.natom(); iatom++) {
462 Atom atom = molecule.get_atom(iatom);
463 unsigned int atype = atom.atomic_number;
464 if (debug && world.rank() == 0) {printf("atom atomic_number = %d\n", atype);}
465
466 bool success = false;
467 for (TiXmlElement* node=doc.FirstChildElement(); node && !success; node=node->NextSiblingElement()) {
468 if (strcmp(node->Value(),"name") == 0) {
469 std::string name = node->GetText();
470 if (debug && world.rank() == 0) std::cout << "Loading pseudopotential file " << name << std::endl;
471 }
472 else if (strcmp(node->Value(), "atom") == 0) {
473 const char* symbol = node->Attribute("symbol");
474 unsigned int atn = symbol_to_atomic_number(symbol);
475 if (atype == atn) {
476 success = true;
477 if (debug && world.rank() == 0) std::cout << " found atomic pseudopotential " << symbol << std::endl;
478 int lmax = -1;
479 node->Attribute("lmax", &lmax);
480 if (debug && world.rank() == 0) std::cout << " maximum L is " << lmax << std::endl;
481 real_tensor t_radii((long)lmax+1);
482 real_tensor t_hlij((long)lmax+1, (long)3, (long)3);
483 real_tensor t_klij((long)lmax+1, (long)3, (long)3);
484 // local part
485 TiXmlElement* xmlVLocal = node->FirstChildElement();
486 real_tensor t_localp((long)6);
487 double zeff = 0.0; xmlVLocal->Attribute("Zeff", &zeff); t_localp[0] = zeff;
488 double lradius = 0.0; xmlVLocal->Attribute("radius", &lradius); t_localp(1) = lradius;
489 double C1 = 0.0; xmlVLocal->Attribute("C1", &C1); t_localp[2] = C1;
490 double C2 = 0.0; xmlVLocal->Attribute("C2", &C2); t_localp[3] = C2;
491 double C3 = 0.0; xmlVLocal->Attribute("C3", &C3); t_localp[4] = C3;
492 double C4 = 0.0; xmlVLocal->Attribute("C4", &C4); t_localp[5] = C4;
493 // loop through nonlocal part
494 for (TiXmlElement* xmlLnlproj = xmlVLocal->NextSiblingElement();
495 xmlLnlproj; xmlLnlproj=xmlLnlproj->NextSiblingElement()) {
496 int lvalue = -1; xmlLnlproj->Attribute("l", &lvalue);
497 double radius = 0.0; xmlLnlproj->Attribute("radius", &radius); t_radii[lvalue] = radius;
498 double h00 = 0.0; xmlLnlproj->Attribute("h00", &h00); t_hlij(lvalue, 0, 0) = h00;
499 double h11 = 0.0; xmlLnlproj->Attribute("h11", &h11); t_hlij(lvalue, 1, 1) = h11;
500 double h22 = 0.0; xmlLnlproj->Attribute("h22", &h22); t_hlij(lvalue, 2, 2) = h22;
501 double k00 = 0.0; xmlLnlproj->Attribute("k00", &k00); t_klij(lvalue, 0, 0) = k00;
502 double k11 = 0.0; xmlLnlproj->Attribute("k11", &k11); t_klij(lvalue, 1, 1) = k11;
503 double k22 = 0.0; xmlLnlproj->Attribute("k22", &k22); t_klij(lvalue, 2, 2) = k22;
504 }
505 // off-diagonal elements
506 if (lmax >= 0) {
507 t_hlij(0, 0, 1) = -1./2.*std::sqrt(3./5.)*t_hlij(0, 1, 1);
508 t_hlij(0, 1, 0) = t_hlij(0, 0, 1);
509 t_hlij(0, 0, 2) = 1./2.*std::sqrt(5./21.)*t_hlij(0, 2, 2);
510 t_hlij(0, 2, 0) = t_hlij(0, 0, 2);
511 t_hlij(0, 1, 2) = -1./2.*std::sqrt(100./63.)*t_hlij(0, 2, 2);
512 t_hlij(0, 2, 1) = t_hlij(0, 1, 2);
513 } if (lmax >= 1) {
514 t_hlij(1, 0, 1) = -1./2.*std::sqrt(5./7.)*t_hlij(1, 1, 1);
515 t_hlij(1, 1, 0) = t_hlij(1, 0, 1);
516 t_hlij(1, 0, 2) = 1./6.*std::sqrt(35./11.)*t_hlij(1, 2, 2);
517 t_hlij(1, 2, 0) = t_hlij(1, 0, 2);
518 t_hlij(1, 1, 2) = -1./6.*14./std::sqrt(11.)*t_hlij(1, 2, 2);
519 t_hlij(1, 2, 1) = t_hlij(1, 1, 2);
520 } if (lmax >= 2) {
521 t_hlij(2, 0, 1) = -1./2.*std::sqrt(7./9.)*t_hlij(2, 1, 1);
522 t_hlij(2, 1, 0) = t_hlij(2, 0, 1);
523 t_hlij(2, 0, 2) = 1./2.*std::sqrt(63./143.)*t_hlij(2, 2, 2);
524 t_hlij(2, 2, 0) = t_hlij(2, 0, 2);
525 t_hlij(2, 1, 2) = -1./2.*18./std::sqrt(143.)*t_hlij(2, 2, 2);
526 t_hlij(2, 2, 1) = t_hlij(2, 1, 2);
527 }
528
529 // Copy to main array
530 localp[atype-1] = t_localp;
531 radii[atype-1] = t_radii;
532 hlij[atype-1] = t_hlij;
533 klij[atype-1] = t_klij;
534 }
535 }
536 }
537 }
538 }
539
540
541 std::vector<Function<Q,3> > apply_potential(World& world, const real_function_3d& potential, const std::vector<Function<Q,3> >& psi, const tensorT & occ, Q & enl) {
543 double vtol = 1e-2*thresh;
544 std::vector<Function<Q,3> > vpsi = mul_sparse(world,(potential), psi, vtol);
545
546 unsigned int norbs = psi.size();
547 unsigned int natoms = atoms_with_projectors.size();
548
549 // NEW (VECTORIZED) ... hopefully
550 vector_real_function_3d localproj;
551 int lidx = 0;
552 unsigned int maxLL = 0;
553 // loop through all of the atom types in the molecule and get the maximum L value
554 // we need this because we are going to create a fixed sized tensor to store
555 // mapping between a linear index and (ias=which atom, i=which projector, l=angular momentum,
556 // m=angular momentum projection)
557 for (unsigned int iatom = 0; iatom < natoms; iatom++) {
558 // Get atom and its associated GTH tensors
560 unsigned int atype = atom.atomic_number;
561 real_tensor& atom_radii = radii[atype-1];
562 if (atom_radii.dim(0) > 0)
563 maxLL = std::max(maxLL,(unsigned int)atom_radii.dim(0)-1);
564 }
565
566 // Pilm_lookup is a mapping between a linear index and (ias,i,l,m)
567 Tensor<int> Pilm_lookup((unsigned int) natoms, (unsigned long) 3, (unsigned long) maxLL+1, (unsigned long) 2*maxLL+1);
568 for (unsigned int iatom = 0; iatom < natoms; iatom++) {
569 // Get atom and its associated GTH tensors
571 coord_3d center = atom.get_coords();
572 unsigned int atype = atom.atomic_number;
573 real_tensor& atom_radii = radii[atype-1];
574 //real_tensor& atom_hlij = hlij[atype-1];
575
576 // Create function stores for projectors
577 ProjRLMStore prlmstore(atom_radii, center);
578 for (unsigned int j = 1; j <= 3; j++) {
579 for (unsigned int l = 0; l <= maxLL; l++) {
580 for (unsigned int m = 0; m < 2*maxLL+1; m++) {
581 Pilm_lookup(iatom, j-1, l, m) = lidx++;
582 if (m < 2*l+1) localproj.push_back(prlmstore.nlmproj(world,l,m,j));
583 else localproj.push_back(real_factory_3d(world));
584 }
585 }
586 }
587 // Somehow this scares me ... thread-safety of the container localproj (???)
588 world.gop.fence();
589 }
590 truncate(world, localproj, FunctionDefaults<3>::get_thresh());
591 compress(world, localproj);
592 //truncate(world, psi, FunctionDefaults<3>::get_thresh());
593 compress(world, psi);
594 //truncate(world, vpsi, FunctionDefaults<3>::get_thresh());
595 compress(world, vpsi);
596
597 Tensor<Q> Pilm = matrix_inner(world, localproj, psi);
598 Pilm = Pilm.reshape(natoms, 3, maxLL+1, 2*maxLL+1, norbs);
599
600 Tensor<Q> Qilm((unsigned int) natoms, (unsigned long) 3, (unsigned long) maxLL+1, (unsigned long) 2*maxLL+1, (unsigned int) norbs);
601 for (unsigned int iorb=0; iorb<psi.size(); iorb++) {
602 for (unsigned int iatom = 0; iatom < natoms; iatom++) {
603 // Get atom and its associated GTH tensors
605 unsigned int atype = atom.atomic_number;
606 real_tensor& atom_radii = radii[atype-1];
607 real_tensor& atom_hlij = hlij[atype-1];
608 int maxL = atom_radii.dim(0)-1;
609 for (unsigned int i = 1; i <= 3; i++) {
610 for (int l = 0; l <= maxL; l++) {
611 for (int m = 0; m < 2*l+1; m++) {
612 Q s = 0.0;
613 for (unsigned int j = 1; j <= 3; j++) {
614 s += atom_hlij(l,i-1,j-1)*Pilm(iatom, j-1,l,m,iorb);
615 }
616 Qilm(iatom, i-1,l,m,iorb) = s;
617 }
618 }
619 }
620 }
621 }
622 Qilm = Qilm.reshape(natoms*3*(maxLL+1)*(2*maxLL+1),norbs);
623
624 double vtol2 = 1e-4*thresh;
625 double trantol = vtol2 / std::min(30.0, double(localproj.size()));
626 vector_real_function_3d dpsi = transform(world, localproj, Qilm, trantol, true);
627
628 // calculate non-local energy
629 tensorT nlmat = matrix_inner(world, dpsi, psi, true);
630 int nocc = occ.size();
631 enl = 0.0;
632 for(int i = 0;i < nocc;++i){
633 enl += occ[i] * nlmat(i, i);
634 }
635
636 //debug printing
637 /*tensorT lmat = matrix_inner(world, vpsi, psi, true);
638 Q el = 0.0;
639 for(int i = 0;i < nocc;++i){
640 el += occ[i] * lmat(i, i);
641 std::cout << "nloc/loc " << i << " " << occ[i] << " " << nlmat(i,i) << " "<< lmat(i,i) << std::endl;
642 }
643
644 if(world.rank() == 0){
645 printf("\n enl, el, epot %16.8f %16.8f %16.8f\n", enl, el, enl+el);
646 }*/
647
648 gaxpy(world, 1.0, vpsi, 1.0, dpsi);
649
650 return vpsi;
651 }
652
653 std::vector<Function<Q,3> > apply_potential_simple(World& world, const real_function_3d& potential, const std::vector<Function<Q,3> >& psi, const tensorT & occ, Q & enl) {
655 double vtol = 1e-2*thresh;
656 std::vector<Function<Q,3> > vpsi = mul_sparse(world,(potential), psi, vtol);
657
658 //unsigned int norbs = psi.size();
659 unsigned int natoms = atoms_with_projectors.size();
660
661 for (unsigned int iatom = 0; iatom < natoms; iatom++) {
663 unsigned int atype = atom.atomic_number;
664 real_tensor& atom_radii = radii[atype-1];
665 real_tensor& atom_hlij = hlij[atype-1];
666 coord_3d center = atom.get_coords();
667 ProjRLMStore prlmstore(atom_radii, center);
668 unsigned int maxLL = atom_radii.dim(0)-1;
669 for (unsigned int l = 0; l <= maxLL; l++) {
670 for (unsigned int m = 0; m < 2*l+1; m++) {
671 for (unsigned int i = 1; i <= 3; i++) {
672 real_function_3d fproji = prlmstore.nlmproj(world,l,m,i);
673 for (unsigned int j = 1; j <= 3; j++) {
674 real_function_3d fprojj = prlmstore.nlmproj(world,l,m,j);
675 for (unsigned int iorb = 0; iorb < psi.size(); iorb++) {
676 double val = atom_hlij(l,i-1,j-1)*(fprojj.inner(psi[iorb]));
677 if (std::abs(val) > vtol*1e-2) {
678 vpsi[iorb] += val*fproji;
679 }
680 }
681 }
682 }
683 }
684 }
685 }
686 return vpsi;
687 }
688};
689
690
691
692
693}
694
695#endif // MADNESS_CHEM_GTH_PSEUDOPOTENTIAL_H__INCLUDED
double potential(const coord_3d &r)
Definition 3dharmonic.cc:132
Definition molecule.h:60
unsigned int atomic_number
Atomic number.
Definition molecule.h:63
madness::Vector< double, 3 > get_coords() const
Definition molecule.h:106
bool pseudo_atom
Indicates if this atom uses a pseudopotential.
Definition molecule.h:65
long dim(int i) const
Returns the size of dimension i.
Definition basetensor.h:147
long size() const
Returns the number of elements in the tensor.
Definition basetensor.h:138
FunctionDefaults holds default paramaters as static class members.
Definition funcdefaults.h:101
static const double & get_thresh()
Returns the default threshold.
Definition funcdefaults.h:183
Abstract base class interface required for functors used as input to Functions.
Definition function_interface.h:68
Function< T, NDIM > & gaxpy(const T &alpha, const Function< Q, NDIM > &other, const R &beta, bool fence=true)
Inplace, general bi-linear operation in wavelet basis. No communication except for optional fence.
Definition mra.h:1156
const Function< T, NDIM > & compress(bool fence=true) const
Compresses the function, transforming into wavelet basis. Possible non-blocking comm.
Definition mra.h:886
Definition gth_pseudopotential.h:390
std::vector< Function< Q, 3 > > apply_potential(World &world, const real_function_3d &potential, const std::vector< Function< Q, 3 > > &psi, const tensorT &occ, Q &enl)
Definition gth_pseudopotential.h:541
void make_pseudo_potential(World &world)
Definition gth_pseudopotential.h:405
std::array< real_tensor, 118 > klij
Definition gth_pseudopotential.h:397
void reproject(int k, double thresh)
Definition gth_pseudopotential.h:449
real_function_3d vlocalp
Definition gth_pseudopotential.h:398
std::vector< unsigned int > atoms_with_projectors
Definition gth_pseudopotential.h:399
GTHPseudopotential(World &world, Molecule molecule)
Definition gth_pseudopotential.h:403
std::array< real_tensor, 118 > hlij
Definition gth_pseudopotential.h:396
std::array< real_tensor, 118 > localp
Definition gth_pseudopotential.h:394
std::vector< Function< Q, 3 > > apply_potential_simple(World &world, const real_function_3d &potential, const std::vector< Function< Q, 3 > > &psi, const tensorT &occ, Q &enl)
Definition gth_pseudopotential.h:653
void load_pseudo_from_file(World &world, const std::string filename)
Definition gth_pseudopotential.h:453
std::array< real_tensor, 118 > radii
Definition gth_pseudopotential.h:395
real_function_3d vlocalpot()
Definition gth_pseudopotential.h:445
Molecule molecule
Definition gth_pseudopotential.h:393
Definition molecule.h:129
const Atom & get_atom(unsigned int i) const
Definition molecule.cc:502
size_t natom() const
Definition molecule.h:463
Definition gth_pseudopotential.h:73
int itmp
Definition gth_pseudopotential.h:83
static const double gamma_data[17]
Definition gth_pseudopotential.h:92
std::vector< coord_3d > special_points() const final
Override this to return list of special points to be refined more deeply.
Definition gth_pseudopotential.h:350
double t1
Definition gth_pseudopotential.h:84
double alpha
Definition gth_pseudopotential.h:75
std::vector< coord_3d > specialpts
Definition gth_pseudopotential.h:78
ProjRLMFunctor(double alpha, int l, int m, int i, const coord_3d &center)
Definition gth_pseudopotential.h:94
double operator()(const coord_3d &r) const final
Definition gth_pseudopotential.h:103
virtual void operator()(const Vector< double *, 3 > &xvals, double *MADNESS_RESTRICT fvals, int npts) const final
Definition gth_pseudopotential.h:224
virtual bool screened(const coord_3d &c1, const coord_3d &c2) const final
Definition gth_pseudopotential.h:177
Level special_level() const final
Override this to change the minimum level of refinement at special points (default is 6)
Definition gth_pseudopotential.h:352
int l
Definition gth_pseudopotential.h:76
double sqrtPI
Definition gth_pseudopotential.h:82
virtual bool supports_vectorized() const final
Does the interface support a vectorized operator()?
Definition gth_pseudopotential.h:90
int m
Definition gth_pseudopotential.h:76
int itmp2
Definition gth_pseudopotential.h:83
coord_3d center
Definition gth_pseudopotential.h:77
Definition gth_pseudopotential.h:357
coord_3d center
Definition gth_pseudopotential.h:361
real_function_3d nlmproj(World &world, int l, int m, int i)
Definition gth_pseudopotential.h:367
ProjRLMStore(const real_tensor &radii, const coord_3d &center)
Definition gth_pseudopotential.h:364
real_tensor radii
Definition gth_pseudopotential.h:360
ProjRLMFunctor nlmproj_functor(World &world, int l, int m, int i)
Definition gth_pseudopotential.h:384
int maxL
Definition gth_pseudopotential.h:359
Tensor< T > reshape(int ndimnew, const long *d)
Returns new view/tensor reshaping size/number of dimensions to conforming tensor.
Definition tensor.h:1385
Definition gth_pseudopotential.h:40
double C3
Definition gth_pseudopotential.h:42
double C1
Definition gth_pseudopotential.h:42
double C4
Definition gth_pseudopotential.h:42
double operator()(const coord_3d &r) const final
Definition gth_pseudopotential.h:56
double Zeff
Definition gth_pseudopotential.h:42
double zi
Definition gth_pseudopotential.h:42
double C2
Definition gth_pseudopotential.h:42
coord_3d center
Definition gth_pseudopotential.h:43
Level special_level() const final
Override this to change the minimum level of refinement at special points (default is 6)
Definition gth_pseudopotential.h:68
std::vector< coord_3d > special_points() const final
Override this to return list of special points to be refined more deeply.
Definition gth_pseudopotential.h:66
std::vector< coord_3d > specialpts
Definition gth_pseudopotential.h:44
VLocalFunctor(double Zeff, double zi, double C1, double C2, double C3, double C4, const coord_3d &center)
Definition gth_pseudopotential.h:49
void fence(bool debug=false)
Synchronizes all processes in communicator AND globally ensures no pending AM or tasks.
Definition worldgop.cc:177
A parallel world class.
Definition world.h:134
ProcessID rank() const
Returns the process rank in this World (same as MPI_Comm_rank()).
Definition world.h:344
WorldGopInterface & gop
Global operations.
Definition world.h:216
double(* f1)(const coord_3d &)
Definition derivatives.cc:55
static bool debug
Definition dirac-hatom.cc:16
double psi(const Vector< double, 3 > &r)
Definition hatom_energy.cc:78
#define final(a, b, c)
Definition lookup3.c:153
#define MADNESS_RESTRICT
Definition mTxmq.h:37
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition madness_exception.h:119
Main include file for MADNESS and defines Function interface.
constexpr double pi
Mathematical constant .
Definition constants.h:48
Namespace for all elements and tools of MADNESS.
Definition DFConvergence.h:9
static const char * filename
Definition legendre.cc:96
std::vector< Function< TENSOR_RESULT_TYPE(T, R), NDIM > > transform(World &world, const std::vector< Function< T, NDIM > > &v, const Tensor< R > &c, bool fence=true)
Transforms a vector of functions according to new[i] = sum[j] old[j]*c[j,i].
Definition vmra.h:758
void truncate(World &world, std::vector< Function< T, NDIM > > &v, double tol=0.0, bool fence=true)
Truncates a vector of functions.
Definition vmra.h:336
Tensor< double > tensorT
Definition distpm.cc:21
void compress(World &world, const std::vector< Function< T, NDIM > > &v, bool fence=true)
Compress a vector of functions.
Definition vmra.h:150
std::shared_ptr< FunctionFunctorInterface< double, 3 > > real_functor_3d
Definition functypedefs.h:122
std::vector< real_function_3d > vector_real_function_3d
Definition functypedefs.h:94
unsigned int symbol_to_atomic_number(const std::string &symbol)
Definition atomutil.cc:173
int Level
Definition key.h:59
FunctionFactory< double, 3 > real_factory_3d
Definition functypedefs.h:108
double get_charge_from_file(const std::string filename, unsigned int atype)
Definition gth_pseudopotential.cc:8
Function< TENSOR_RESULT_TYPE(L, R), NDIM > mul_sparse(const Function< L, NDIM > &left, const Function< R, NDIM > &right, double tol, bool fence=true, bool do_make_redundant=true)
Sparse multiplication; the scalar interface redirects to the vector one in vmra.h.
Definition mra.h:1977
Vector< double, 3 > coord_3d
Definition funcplot.h:1042
Function< T, NDIM > project(const Function< T, NDIM > &other, int k=FunctionDefaults< NDIM >::get_k(), double thresh=FunctionDefaults< NDIM >::get_thresh(), bool fence=true)
Definition mra.h:2651
std::string name(const FuncType &type, const int ex=-1)
Definition ccpairfunction.h:28
void matrix_inner(DistributedMatrix< T > &A, const std::vector< Function< T, NDIM > > &f, const std::vector< Function< T, NDIM > > &g, bool sym=false)
Definition distpm.cc:46
void gaxpy(const double a, ScalarResult< T > &left, const double b, const T &right, const bool fence=true)
the result type of a macrotask must implement gaxpy
Definition macrotaskq.h:244
static long abs(long a)
Definition tensor.h:219
double Q(double a)
Definition relops.cc:20
static const double PI
Definition relops.cc:12
static const double m
Definition relops.cc:9
static const double thresh
Definition rk.cc:45
static const long k
Definition rk.cc:44
void e()
Definition test_sig.cc:75
static const int truncate_mode
Definition testcosine.cc:14
const auto npts
Definition testgconv.cc:52