MADNESS 0.10.1
correlationfactor.h
Go to the documentation of this file.
1/*
2 This file is part of MADNESS.
3
4 Copyright (C) 2007,2010 Oak Ridge National Laboratory
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 For more information please contact:
21
22 Robert J. Harrison
23 Oak Ridge National Laboratory
24 One Bethel Valley Road
25 P.O. Box 2008, MS-6367
26
27 email: harrisonrj@ornl.gov
28 tel: 865-241-3937
29 fax: 865-572-0680
30*/
31
32/*!
33 \file apps/chem/correlationfactor.h
34 \brief class for regularizing singular potentials in the molecular
35 Hamilton operator
36
37 \par Introduction
38
39 The correlation factors are intended to represent the cusps (nuclear or
40 electronic) in the molecular wave function. Their commutator over the
41 kinetic energy operator give a potential operator that cancels the
42 singular potential
43
44 [T, f12] = U + 1/r12
45 R^-1[T, R] = U_nuc - sum_A Z_A/r1A
46
47 The regularized potentials U and U_nuc contain two terms each, a local
48 potential, (denoted U2), and a potential that is multiplied with the
49 derivative operator \nabla (denoted U1)
50
51 U = U1 . (\nabla_1 - \nabla_2) + U2
52 U_nuc = U1 . \nabla + U2
53
54 with
55
56 U2 = (\nabla^2 f12)
57 U2 = R^{-1}(\nabla^2 R)
58
59 \vec U1 = (\vec \nabla f12)
60 \vec U1 = R^{-1}(\vec \nabla R)
61
62 To construct a nuclear correlation factor write:
63
64 std::shared_ptr<NuclearCorrelationFactor> nuclear_correlation
65 = create_nuclear_correlation_factor(world,*calc);
66
67 where calc is an SCF calculation which holds the molecule and the
68 nuclear_corrfac parameter name.
69*/
70
71
72#ifndef MADNESS_CHEM_NUCLEARCORRELATIONFACTOR_H_
73#define MADNESS_CHEM_NUCLEARCORRELATIONFACTOR_H_
74
75#include <madness/mra/mra.h>
79
80namespace madness {
81
82/// ABC for the nuclear correlation factors
84public:
87 typedef std::shared_ptr< FunctionFunctorInterface<double,3> > functorT;
88
89 /// ctor
90
91 /// @param[in] world the world
92 /// @param[in] mol molecule with the sites of the nuclei
94 : world(world), vtol(FunctionDefaults<3>::get_thresh()*0.1)
95 , eprec(mol.get_eprec()), molecule(mol) {}
96
97 /// virtual destructor
99
100 /// initialize the regularized potentials U1 and U2
101 void initialize(const double vtol1) {
102
103 // set threshold for projections
104 vtol=vtol1;
105
106 // Discard any previous set. initialize() is called again on every
107 // protocol step, and U1(axis) reads U1_function[axis] -- i.e. the FIRST
108 // three entries. Appending therefore left the accessor pinned to the
109 // functions built on the first call: at the initial (loosest) threshold,
110 // and at the initial k. With a pinned k that is a silent loss of
111 // precision for the rest of the ladder; with k varying across the
112 // protocol it is a tensor conformance failure.
113 U1_function.clear();
114
115 // construct the potential functions
116 // keep tighter threshold for orthogonalization
117 for (int axis=0; axis<3; ++axis) {
120 .functor(U1f).truncate_on_project());
121 U1_function.back().set_thresh(FunctionDefaults<3>::get_thresh());
122 }
123
124 // U2 is the term -S"/S - Z/r
125 functorT U2f=functorT(new U2_functor(this));
127 .functor(U2f).truncate_on_project();
129
130 // U3 is the term SA'/SA . SB'/SB
131 functorT U3f=functorT(new U3_functor(this));
133 .functor(U3f).truncate_on_project();
137 }
138
139 virtual corrfactype type() const = 0;
140
141 /// apply the regularized potential U_nuc on a given function rhs
143
144 // the purely local part
145 real_function_3d result=(U2()*rhs).truncate();
146
147 // the part with the derivative operators
148 result.compress();
149 for (int axis=0; axis<3; ++axis) {
151 const real_function_3d Drhs=D(rhs).truncate();
152 result+=U1(axis)*Drhs;
153 }
154
155 result.truncate();
156 return result;
157 }
158
159 /// return the nuclear correlation factor
160 virtual real_function_3d function() const {
161 functorT Rf=functorT(new R_functor(this,1));
163 .functor(Rf).truncate_on_project();
164 return r;
165 }
166
167 /// return the square of the nuclear correlation factor
168 virtual real_function_3d square() const {
169 R_functor r(this,2);
171 .functor(r).truncate_on_project();
172 return R2;
173 }
174
175 /// return the square of the nuclear correlation factor multiplied with
176 /// the derivative of the nuclear potential for the specified atom
177
178 /// @return R^2 * \frac{\partial Z_A/r_{1A}}{\partial X_A}
179 virtual real_function_3d square_times_V_derivative(const int iatom, const int axis) const {
182 .functor(func).truncate_on_project();
183 return R2;
184 }
185
186 /// return the inverse nuclear correlation factor
187 virtual real_function_3d inverse() const {
188 R_functor r(this,-1);
190 .functor(r).truncate_on_project();
191 return R_inverse;
192 }
193
194 /// return the U1 term of the correlation function
195 virtual const real_function_3d U1(const int axis) const {
196 return U1_function[axis];
197 }
198
199 /// return the U1 functions in a vector
200 std::vector<real_function_3d> U1vec() const {
201 std::vector<real_function_3d> uvec(3);
202 uvec[0]=U1_function[0];
203 uvec[1]=U1_function[1];
204 uvec[2]=U1_function[2];
205 return uvec;
206 }
207
208 /// return the U2 term of the correlation function
209 virtual const real_function_3d U2() const {return U2_function;}
210
211private:
212
213 /// the world
215
216 /// the threshold for initial projection
217 double vtol;
218
219 /// smoothing of the potential/step function
220 double eprec;
221
222 /// the molecule
224
225protected:
226 /// the three components of the U1 potential
227 std::vector<real_function_3d> U1_function;
228
229 /// the purely local U2 potential, having absorbed the nuclear pot V_nuc
231
232private:
233 /// the correlation factor S wrt a given atom
234
235 /// @param[in] r the distance of the req'd coord to the nucleus
236 /// @param[in] Z the nuclear charge
237 /// @return the nuclear correlation factor S_A(r_1A)
238 virtual double S(const double& r, const double& Z) const = 0;
239
240 /// the partial derivative of correlation factor S' wrt the cartesian coordinates
241
242 /// @param[in] vr1A the vector of the req'd coord to the nucleus
243 /// @param[in] Z the nuclear charge
244 /// @return the gradient of the nuclear correlation factor S'_A(r_1A)
245 virtual coord_3d Sp(const coord_3d& vr1A, const double& Z) const = 0;
246
247 /// the regularized potential wrt a given atom wrt the cartesian coordinate
248
249 /// S" is the Cartesian Laplacian applied on the NCF. Note the difference
250 /// to Srr_div_S, which is the second derivative wrt the distance rho.
251 /// this is: -S"/S - Z/r
252 /// @param[in] r the distance of the req'd coord to the nucleus
253 /// @param[in] Z the nuclear charge
254 /// @return the Laplacian of the nuclear correlation factor divided
255 /// by the correlation factor minus the nuclear potential
256 virtual double Spp_div_S(const double& r, const double& Z) const = 0;
257
258public:
259
260 /// first derivative of the NCF with respect to the relative distance rho
261 /// \f[
262 /// \frac{\partial S(\rho)}{\partial \rho} \frac{1}{S(\rho)}
263 /// \f]
264 /// where the distance of the electron to the nucleus A is given by
265 /// \f[
266 /// \rho = |\vec r - \vec R_A |
267 /// \f]
268 virtual double Sr_div_S(const double& r, const double& Z) const = 0;
269
270 /// second derivative of the NCF with respect to the relative distance rho
271 /// \f[
272 /// \frac{\partial^2 S(\rho)}{\partial \rho^2} \frac{1}{S(\rho)}
273 /// \f]
274 /// where the distance of the electron to the nucleus A is given by
275 /// \f[
276 /// \rho = |\vec r - \vec R_A |
277 /// \f]
278 virtual double Srr_div_S(const double& r, const double& Z) const = 0;
279
280 /// third derivative of the NCF with respect to the relative distance rho
281 /// \f[
282 /// \frac{\partial^3 S(\rho)}{\partial \rho^3} \frac{1}{S(\rho)}
283 /// \f]
284 /// where the distance of the electron to the nucleus A is given by
285 /// \f[
286 /// \rho = |\vec r - \vec R_A |
287 /// \f]
288 virtual double Srrr_div_S(const double& r, const double& Z) const = 0;
289
290 /// derivative of the U2 potential wrt nuclear coordinate X (spherical part)
291
292 /// need to reimplement this for all derived classes due to the
293 /// range for r -> 0, where the singular terms cancel. With
294 /// \f[
295 /// \rho = \left| \vec r- \vec R_A \right|
296 /// \f]
297 /// returns the term in the parenthesis without the the derivative of rho
298 /// \f[
299 /// \frac{\partial U_2}{\partial X_A} = \frac{\partial \rho}{\partial X}
300 /// \left(-\frac{1}{2}\frac{S''' S - S'' S'}{S^2} + \frac{1}{\rho^2}\frac{S'}{S}
301 /// - \frac{1}{\rho} \frac{S''S - S'^2}{S^2} + \frac{Z_A}{\rho^2}\right)
302 /// \f]
303 virtual double U2X_spherical(const double& r, const double& Z, const double& rcut) const {
304 if (world.rank()==0) {
305 print("you can't compute the Hessian matrix");
306 print("U2X_spherical is not implemented for the nuclear correlation factor");
307 }
308 MADNESS_EXCEPTION("do more implementation work",1);
309 }
310
311public:
312
313 /// smoothed unit vector for the computation of the U1 potential
314
315 /// note the identity for exchanging nuclear and electronic coordinates
316 /// (there is a sign change, unlike for the smoothed potential)
317 /// \f[
318 /// \vec n = \frac{\partial \rho}{\partial x} = -\frac{\partial \rho}{\partial X}
319 /// \f]
320 /// \f[
321 /// \vec n = \left\{\frac{x \mathrm{erf}\left(\frac{r}{s}\right)}{r},
322 /// \frac{y \mathrm{erf}\left(\frac{r}{s}\right)}{r},
323 /// \frac{z \mathrm{erf}\left(\frac{r}{s}\right)}{r}\right\}
324 /// \f]
325 coord_3d smoothed_unitvec(const coord_3d& xyz, double smoothing=0.0) const {
326#if 0
327
329 // TODO:need to test this
330 // reduce the smoothing for the unitvector
331 //if (not (this->type()==None or this->type()==Two)) smoothing=sqrt(smoothing);
333 const double r=xyz.normf();
334 const double rs=r/smoothing;
335 if (r<1.e-4) {
336 const double sqrtpi=sqrt(constants::pi);
337 double erfrs_div_r=2.0/(smoothing*sqrtpi)-2.0/3.0*rs*rs/(sqrtpi*smoothing);
338 return erfrs_div_r*xyz;
339 } else if (r<6.0) {
340 return erf(rs)/r*xyz;
341 } else {
342 return 1.0/r*xyz;
343 }
344
345
346
347#else
348 if (smoothing==0.0) smoothing=eprec;
349 // TODO:need to test this
350 // reduce the smoothing for the unitvector
351 //if (not (this->type()==None or this->type()==Two)) smoothing=sqrt(smoothing);
352 const double r=xyz.normf();
353 const double cutoff=smoothing;
354 if (r>cutoff) {
355 return 1.0/r*xyz;
356 } else {
357 const double xi=r/cutoff;
358 const double xi2=xi*xi;
359 const double xi3=xi*xi*xi;
360// const double nu21=0.5+1./32.*(45.*xi - 50.*xi3 + 21.*xi*xi*xi*xi*xi);
361 const double nu22=0.5 + 1./64.*(105* xi - 175 *xi3 + 147* xi2*xi3 - 45* xi3*xi3*xi);
362// const double nu40=0.5 + 1./128.*(225 *xi - 350 *xi3 + 189*xi2*xi3);
363 const double kk=2.*nu22-1.0;
364 return kk/r*xyz;
365 }
366
367#endif
368 }
369
370 /// derivative of smoothed unit vector wrt the *electronic* coordinate
371
372 /// note the sign change for exchanging nuclear and electronic coordinates
373 /// \f[
374 /// \frac{\partial \vec n}{\partial x} = -\frac{\partial \vec n}{\partial X}
375 /// \f]
376 /// the derivative wrt x is given by
377 /// \f[
378 /// \frac{\partial\vec n}{\partial x} =
379 /// \left\{\frac{\left(r^2-x^2\right) \mathrm{erf}\left(\frac{r}{s}\right)}{r^3}
380 /// +\frac{2 x^2 e^{-\frac{r^2}{s^2}}}{\sqrt{\pi } r^2 s},
381 /// x y \left(\frac{2 e^{-\frac{r^2}{s^2}}}{\sqrt{\pi } r^2 s}
382 /// -\frac{\mathrm{erf}\left(\frac{r}{s}\right)}{r^3}\right),
383 /// x z \left(\frac{2 e^{-\frac{r^2}{s^2}}}{\sqrt{\pi } r^2 s}
384 /// -\frac{\mathrm{erf}\left(\frac{r}{s}\right)}{r^3}\right)\right\}
385 /// \f]
387 double smoothing=0.0) const {
388
389 const double r=xyz.normf();
390 coord_3d result;
391 if (smoothing==0.0) smoothing=eprec;
392
393#if 1
394 // TODO:need to test this
395 // reduce the smoothing for the unitvector
396 //if (not (this->type()==None or this->type()==Two)) smoothing=sqrt(smoothing);
398
399 const double rs=r/smoothing;
400 const static double sqrtpi=sqrt(constants::pi);
402
403 if (r<1.e-4) {
404 // series expansion
405 double p=-4.0/(3.0*sqrtpis3) + 4.0*rs*rs/(5.0*sqrtpis3);
406
407 double erfrs_div_r=2.0/(smoothing*sqrtpi)-2.0/3.0*rs*rs/(sqrtpi*smoothing);
408 result=xyz*xyz[axis]*p;
409 result[axis]+=erfrs_div_r;
410
411 } else if (r<6.0) {
412 const double erfrs_div_r=erf(rs)/r;
413 const double term1=2.0*exp(-rs*rs)/(sqrtpi*r*r*smoothing);
414 result=xyz*xyz[axis]*(term1-erfrs_div_r/(r*r));
415 result[axis]+=erfrs_div_r;
416#else
417 if (r<smoothing) {
418 double r2=r*r;
419 double s2=smoothing*smoothing;
420 double s7=s2*s2*s2*smoothing;
421 double x2=xyz[axis]*xyz[axis];
422
423 double fac_offdiag=-(((135. *r2*r2 - 294.* r2 *s2
424 + 175.*s2*s2))/(16.* s7));
425 double fac_diag=-((45.* r2*r2*r2 - 147.* r2*r2* s2
426 + 175.* r2*s2*s2 - 105.* s2*s2*s2 + 270.* r2*r2* x2
427 - 588.* r2* s2* x2 + 350.*s2* s2 *x2)/(32.* s7));
428
429 result[0]=fac_offdiag*xyz[0]*xyz[axis];
430 result[1]=fac_offdiag*xyz[1]*xyz[axis];
431 result[2]=fac_offdiag*xyz[2]*xyz[axis];
432 result[axis]=fac_diag;
433
434#endif
435 } else {
436 result=xyz*(-xyz[axis]/(r*r*r));
437 result[axis]+=1/r;
438 }
439 return result;
440 }
441
442
443 class R_functor : public FunctionFunctorInterface<double,3> {
446 public:
448 : ncf(ncf), exponent(e) {}
449 double operator()(const coord_3d& xyz) const {
450 double result=1.0;
451 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
452 const Atom& atom=ncf->molecule.get_atom(i);
453 const coord_3d vr1A=xyz-atom.get_coords();
454 const double r=vr1A.normf();
455 result*=ncf->S(r,atom.q);
456 }
457 if (exponent==-1) return 1.0/result;
458 else if (exponent==2) return result*result;
459 else if (exponent==1) return result;
460 else {
461 return std::pow(result,double(exponent));
462 }
463
464 }
465 std::vector<coord_3d> special_points() const {
466 return ncf->molecule.get_all_coords_vec();
467 }
468 };
469
470 /// functor for the local part of the U1 potential -- NOTE THE SIGN
471
472 /// U1 = -S'/S
473 class U1_functor : public FunctionFunctorInterface<double,3> {
474
476 const int axis;
477
478 public:
480 : ncf(ncf), axis(axis) {}
481
482 double operator()(const coord_3d& xyz) const {
483 double result=0.0;
484 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
485 const Atom& atom=ncf->molecule.get_atom(i);
486 const coord_3d vr1A=xyz-atom.get_coords();
487 const double r=vr1A.normf();
488 const double& Z=atom.q;
489// result-=(ncf->Sp(vr1A,Z)[axis]/ncf->S(r,Z));
490 result-=ncf->Sr_div_S(r,Z)*ncf->smoothed_unitvec(vr1A)[axis];
491 }
492 return result;
493 }
494 std::vector<coord_3d> special_points() const {
495 return ncf->molecule.get_all_coords_vec();
496 }
497 };
498
499 /// U1 functor for a specific atom
500
501 /// NOTE THE SIGN !!
502 /// this is
503 /// \f[
504 /// -\frac{\partial \rho}{\partial X_A}\frac{\partial S}{\partial \rho}\frac{1}{S}
505 /// \f]
507
509 const size_t iatom;
510 const int axis;
511
512 public:
514 const int axis) : ncf(ncf), iatom(atom), axis(axis) {}
515
516 double operator()(const coord_3d& xyz) const {
517 const Atom& atom=ncf->molecule.get_atom(iatom);
518 const coord_3d vr1A=xyz-atom.get_coords();
519 const double r=vr1A.normf();
520 const double& Z=atom.q;
521 return ncf->Sr_div_S(r,Z)*ncf->smoothed_unitvec(vr1A)[axis];
522 }
523
524 std::vector<coord_3d> special_points() const {
525 std::vector< madness::Vector<double,3> > c(1);
526 const Atom& atom=ncf->molecule.get_atom(iatom);
527 c[0][0]=atom.x;
528 c[0][1]=atom.y;
529 c[0][2]=atom.z;
530 return c;
531 }
532 };
533
534
535 /// functor for a local U1 dot U1 potential
536
537 /// \f[
538 /// U1\dot U1 = \frac{\left(S^r_A S^r_B\right)}{S_A S_B} n_A \cdot n_B
539 /// \f]
540 /// with positive sign!
542
544
545 public:
547
548 double operator()(const coord_3d& xyz) const {
549 std::vector<double> Sr_div_S(ncf->molecule.natom());
550 std::vector<coord_3d> unitvec(ncf->molecule.natom());
551 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
552 const Atom& atom=ncf->molecule.get_atom(i);
553 const coord_3d vr1A=xyz-atom.get_coords();
554 const double r=vr1A.normf();
555 Sr_div_S[i]=ncf->Sr_div_S(r,atom.q);
556 unitvec[i]=ncf->smoothed_unitvec(vr1A);
557 }
558
559 double result=0.0;
560 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
561 for (size_t j=0; j<ncf->molecule.natom(); ++j) {
562 double tmp=Sr_div_S[i]*Sr_div_S[j];
563 if (i!=j) tmp*=inner(unitvec[i],unitvec[j]);
564 result+=tmp;
565 }
566 }
567
568
569 return result;
570 }
571 std::vector<coord_3d> special_points() const {
572 return ncf->molecule.get_all_coords_vec();
573 }
574 };
575
576
577 class U2_functor : public FunctionFunctorInterface<double,3> {
579 public:
581 double operator()(const coord_3d& xyz) const {
582 double result=0.0;
583 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
584 const Atom& atom=ncf->molecule.get_atom(i);
585 const coord_3d vr1A=xyz-atom.get_coords();
586 const double r=vr1A.normf();
587 result+=ncf->Spp_div_S(r,atom.q);
588 }
589 return result;
590 }
591 std::vector<coord_3d> special_points() const {
592 return ncf->molecule.get_all_coords_vec();
593 }
594 };
595
596 class U3_functor : public FunctionFunctorInterface<double,3> {
598 public:
600 double operator()(const coord_3d& xyz) const {
601 std::vector<coord_3d> all_terms(ncf->molecule.natom());
602 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
603 const Atom& atom=ncf->molecule.get_atom(i);
604 const coord_3d vr1A=xyz-atom.get_coords();
605 const double r=vr1A.normf();
606// all_terms[i]=ncf->Sp(vr1A,atom.q)*(1.0/ncf->S(r,atom.q));
607 all_terms[i]=ncf->Sr_div_S(r,atom.q)*ncf->smoothed_unitvec(vr1A);
608 }
609
610 double result=0.0;
611 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
612 for (size_t j=0; j<i; ++j) {
613 result+=all_terms[i][0]*all_terms[j][0]
614 +all_terms[i][1]*all_terms[j][1]
615 +all_terms[i][2]*all_terms[j][2];
616 }
617 }
618
619 return -1.0*result;
620 }
621 std::vector<coord_3d> special_points() const {
622 return ncf->molecule.get_all_coords_vec();
623 }
624 };
625
626 /// U2 functor for a specific atom
628
630 const size_t iatom;
631
632 public:
634 : ncf(ncf), iatom(atom) {}
635
636 double operator()(const coord_3d& xyz) const {
637 const Atom& atom=ncf->molecule.get_atom(iatom);
638 const coord_3d vr1A=xyz-atom.get_coords();
639 const double r=vr1A.normf();
640 return ncf->Spp_div_S(r,atom.q);
641 }
642
643 std::vector<coord_3d> special_points() const {
644 std::vector< madness::Vector<double,3> > c(1);
645 const Atom& atom=ncf->molecule.get_atom(iatom);
646 c[0][0]=atom.x;
647 c[0][1]=atom.y;
648 c[0][2]=atom.z;
649 return c;
650 }
651 };
652
653 /// U3 functor for a specific atom
655
657 const size_t iatom;
658
659 public:
661 : ncf(ncf), iatom(atom) {}
662
663 double operator()(const coord_3d& xyz) const {
664 const Atom& atomA=ncf->molecule.get_atom(iatom);
665 const coord_3d vr1A=xyz-atomA.get_coords();
666 const double rA=vr1A.normf();
667 const coord_3d nA=ncf->smoothed_unitvec(vr1A);
668 double Sr_div_SA=ncf->Sr_div_S(rA,atomA.q);
669
670 double result=0.0;
671 // sum over B
672 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
673 if (i==iatom) continue; // restricted sum
674
675 const Atom& atomB=ncf->molecule.get_atom(i);
676 const coord_3d vr1B=xyz-atomB.get_coords();
677 const double rB=vr1B.normf();
678 const coord_3d nB=ncf->smoothed_unitvec(vr1B);
679 double Sr_div_SB=ncf->Sr_div_S(rB,atomB.q);
680
681 double dot=nA[0]*nB[0] + nA[1]*nB[1] + nA[2]*nB[2];
682 result+=Sr_div_SB*Sr_div_SA*dot;
683 }
684 return -0.5*result;
685 }
686
687 std::vector<coord_3d> special_points() const {
688 std::vector< madness::Vector<double,3> > c(1);
689 const Atom& atom=ncf->molecule.get_atom(iatom);
690 c[0][0]=atom.x;
691 c[0][1]=atom.y;
692 c[0][2]=atom.z;
693 return c;
694 }
695 };
696
700 const size_t iatom;
701 public:
703 const Molecule& mol, const size_t iatom1)
704 : ncf(ncf), molecule(mol), iatom(iatom1) {}
705 double operator()(const coord_3d& xyz) const {
706 double result=1.0;
707 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
708 const Atom& atom=ncf->molecule.get_atom(i);
709 const coord_3d vr1A=xyz-atom.get_coords();
710 const double r=vr1A.normf();
711 result*=ncf->S(r,atom.q);
712 }
714 iatom, xyz[0], xyz[1], xyz[2]);
715 return result*result*V;
716
717 }
718 std::vector<coord_3d> special_points() const {
719 return ncf->molecule.get_all_coords_vec();
720 }
721 };
722
723
727 const size_t iatom;
728 const int axis;
729 public:
733 double operator()(const coord_3d& xyz) const {
734 double result=1.0;
735 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
736 const Atom& atom=ncf->molecule.get_atom(i);
737 const coord_3d vr1A=xyz-atom.get_coords();
738 const double r=vr1A.normf();
739 result*=ncf->S(r,atom.q);
740 }
742 iatom, axis, xyz[0], xyz[1], xyz[2]);
743 return result*result*Vprime;
744
745 }
746 std::vector<coord_3d> special_points() const {
747 return ncf->molecule.get_all_coords_vec();
748 }
749 };
750
751 /// compute the derivative of R wrt the displacement of atom A, coord axis
752 class RX_functor : public FunctionFunctorInterface<double,3> {
755 const int derivativeaxis; /// direction of the derivative operator
756 const int exponent; /// 1 or 2 -> R^X or R^X R
757
758 public:
760 const int daxis, const int exponent) : ncf(ncf), thisatom(atom1),
762 MADNESS_ASSERT((exponent==1) or (exponent==2) or (exponent==-1));
763 }
764
765 RX_functor(const NuclearCorrelationFactor* ncf, const int iatom,
766 const int daxis, const int exponent) : ncf(ncf),
767 thisatom(ncf->molecule.get_atom(iatom)),
769 MADNESS_ASSERT((exponent==1) or (exponent==2) or (exponent==-1));
770 }
771
772 double operator()(const coord_3d& xyz) const {
773
774 // compute the R term
775 double result=1.0;
776 if ((exponent==1) or (exponent==2)) {
777 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
778 const Atom& atom=ncf->molecule.get_atom(i);
779 const coord_3d vr1A=xyz-atom.get_coords();
780 const double r=vr1A.normf();
781 result*=ncf->S(r,atom.q);
782 }
783 if (exponent==2) result=result*result;
784 }
785
786 // compute the derivative term
787 {
789 const double r=vr1A.normf();
790 const double& Z=thisatom.q;
791 const double S1=-ncf->Sr_div_S(r,Z) // note the sign
792 *ncf->smoothed_unitvec(vr1A)[derivativeaxis];
793 result*=S1;
794 }
795 return result;
796 }
797
798 std::vector<coord_3d> special_points() const {
799 return ncf->molecule.get_all_coords_vec();
800 }
801
802 };
803
804
805 /// compute the derivative of U1 wrt the displacement of atom A, coord axis
806 class U1X_functor : public FunctionFunctorInterface<double,3> {
809 const int U1axis; /// U1x/U1y/U1z potential?
810 const int derivativeaxis; /// direction of the derivative operator
811 public:
813 const int U1axis, const int daxis) : ncf(ncf), thisatom(atom1),
815 double lo=1.0/thisatom.q;
817 }
818
819 U1X_functor(const NuclearCorrelationFactor* ncf, const int iatom,
820 const int U1axis, const int daxis) : ncf(ncf),
821 thisatom(ncf->molecule.get_atom(iatom)),
823 double lo=1.0/thisatom.q;
825 }
826
827 double operator()(const coord_3d& xyz) const {
829 const double r=vr1A.normf();
830 const double& Z=thisatom.q;
831 const double S1=ncf->Sr_div_S(r,Z);
832 const double S2=ncf->Srr_div_S(r,Z);
833
834 // note the sign change smoothed_unitvec due to the
835 // change in the derivative variable x: electronic -> nuclear
836 const double drhodx=-ncf->smoothed_unitvec(vr1A)[derivativeaxis];
837 return drhodx*(S2-S1*S1)*ncf->smoothed_unitvec(vr1A)[U1axis]
838 -S1*(ncf->dsmoothed_unitvec(vr1A,derivativeaxis)[U1axis]);
839 }
840
841 std::vector<coord_3d> special_points() const {
842 std::vector< madness::Vector<double,3> > c(1);
843 c[0][0]=thisatom.x;
844 c[0][1]=thisatom.y;
845 c[0][2]=thisatom.z;
846 return c;
847 }
848
849 };
850
851
852 /// compute the derivative of U2 wrt the displacement of atom A
853 class U2X_functor : public FunctionFunctorInterface<double,3> {
855 const int iatom;
856 const int axis;
857 public:
859 const int axis) : ncf(ncf), iatom(atom1), axis(axis) {
860 const Atom& atom=ncf->molecule.get_atom(iatom);
861 double lo=1.0/atom.q;
863 }
864
865 double operator()(const coord_3d& xyz) const {
866 const Atom& atom=ncf->molecule.get_atom(iatom);
867 const coord_3d vr1A=xyz-atom.get_coords();
868 const double r=vr1A.normf();
869 const double& Z=atom.q;
870 const double rcut=ncf->molecule.get_rcut()[iatom];
871
872 // note the sign change due to the change in the derivative
873 // variable x: electronic -> nuclear in drho/dx
874 const double drhodx=-ncf->smoothed_unitvec(vr1A)[axis];
875 return drhodx*ncf->U2X_spherical(r,Z,rcut);
876 }
877
878 std::vector<coord_3d> special_points() const {
879 std::vector< madness::Vector<double,3> > c(1);
880 const Atom& atom=ncf->molecule.get_atom(iatom);
881 c[0][0]=atom.x;
882 c[0][1]=atom.y;
883 c[0][2]=atom.z;
884 return c;
885 }
886 };
887
888
889 /// compute the derivative of U3 wrt the displacement of atom A, coord axis
890
891 /// \f[
892 /// U_3^{X_A} = -\sum_{B\neq A}\left(\frac{\vec S_A'}{S_A}\right)^X\cdot\left(\frac{\vec S_B'}{S_B}\right)
893 /// \f]
894 /// with
895 /// \f[
896 /// \left(\frac{\vec S_A'}{S_A}\right)^X =
897 /// \frac{\partial \rho}{\partial X}\left(\frac{S''_A}{S_A}
898 /// -\left(\frac{S'_A}{S_A}\right)^2\right)\vec n_{1A}
899 /// + \left(\frac{S'_A}{S_A}\right)\frac{\partial \vec n_{1A}}{\partial X}
900 /// \f]
901 class U3X_functor : public FunctionFunctorInterface<double,3> {
903 const size_t iatom;
904 const int axis;
905 public:
907 const int axis) : ncf(ncf), iatom(iatom), axis(axis) {}
908
909 double operator()(const coord_3d& xyz) const {
910 const Atom& atomA=ncf->molecule.get_atom(iatom);
911 const coord_3d vr1A=xyz-atomA.get_coords();
912 const double r1A=vr1A.normf();
913 const double& ZA=atomA.q;
914
915 double S1A=ncf->Sr_div_S(r1A,ZA);
916 double S2A=ncf->Srr_div_S(r1A,ZA);
917 double termA=S2A-S1A*S1A;
918
919 // unit vector \vec n_A = \vec r_{1A}/r_{1A}
920 const coord_3d nA=ncf->smoothed_unitvec(vr1A);
921 // derivative of the unit vector \frac{\partial \vec n_A}{\partial X}
922 const coord_3d dnA=ncf->dsmoothed_unitvec(vr1A,axis)*(-1.0);
923 // \frac{\partial \rho}{\partial X}
924 const double drhodx=-nA[axis];
925
926 double term=0.0;
927 for (size_t jatom=0; jatom<ncf->molecule.natom(); ++jatom) {
928 if (iatom==jatom) continue; // restricted sum B \neq A
929
930 const Atom& atomB=ncf->molecule.get_atom(jatom);
931 const coord_3d vr1B=xyz-atomB.get_coords();
932 const double r1B=vr1B.normf();
933 const double& ZB=atomB.q;
934
935 double S1B=ncf->Sr_div_S(r1B,ZB);
936 const coord_3d nB=ncf->smoothed_unitvec(vr1B);
937
938 double dot=0.0; // n_A.n_B
939 double ddot=0.0; // n'_A.n_B
940 for (int i=0; i<3; ++i) {
941 ddot+=dnA[i]*nB[i];
942 dot+=nA[i]*nB[i];
943 }
945
946 }
947
948 return term;
949 }
950
951 std::vector<coord_3d> special_points() const {
952 return ncf->molecule.get_all_coords_vec();
953 }
954 };
955
956};
957
958
959/// A nuclear correlation factor class
960
961/// The nuclear correlation factor is given by
962/// \[f
963/// R = \prod S_A ; S_A=exp(-Z_A r_{1A}) + ( 1 - exp(-r_{1A}^2) )
964/// \]f
966public:
967 /// ctor
968
969 /// @param[in] world the world
970 /// @param[in] mol molecule with the sites of the nuclei
973
974 if (world.rank()==0) {
975 print("constructed nuclear correlation factor of the form");
976 print(" R = Prod_A S_A");
977 print(" S_A = exp(-Z_A r_{1A}) + (1 - exp(-Z_A^2*r_{1A}^2))");
978 print("with eprec ",mol.get_eprec());
979 print("which is of Gaussian-Slater type\n");
980 }
981
982 }
983
985
986private:
987
988 /// the nuclear correlation factor
989 double S(const double& r, const double& Z) const {
990 const double rho=r*Z;
991 return exp(-rho)+(1.0-exp(-(rho*rho)));
992 }
993
994 /// radial part first derivative of the nuclear correlation factor
995 coord_3d Sp(const coord_3d& vr1A, const double& Z) const {
996
997 const double r=sqrt(vr1A[0]*vr1A[0] +
998 vr1A[1]*vr1A[1] + vr1A[2]*vr1A[2]);
999
1000 const double eA=exp(-Z*r);
1001 const double gA=exp(-Z*Z*r*r);
1003 return term;
1004 }
1005
1006 /// second derivative of the nuclear correlation factor
1007
1008 /// -1/2 S"/S - Z/r
1009 double Spp_div_S(const double& r, const double& Z) const {
1010 const double rho=Z*r;
1011 if (rho<1.e-4) {
1012 return Z*Z*(-3.5 - 4.0*rho + 6.0*rho*rho + 12.0*rho*rho*rho);
1013 } else {
1014 const double e=exp(-rho);
1015 const double g=exp(-rho*rho);
1016 const double term1=-Z/r*(1.0-g);
1017 const double term2=-g*Z*Z*(3.0-2.0*Z*Z*r*r) - Z*Z/2.0*e;
1018 const double S_inv=exp(-rho)+(1.0-exp(-(rho*rho)));
1019 return (term1+term2)/S_inv;
1020 }
1021 }
1022
1023 double Sr_div_S(const double& r, const double& Z) const {
1024 const double Zr=r*Z;
1025 const double eA=exp(-Zr);
1026 const double gA=exp(-Zr*Zr);
1027 const double num=Z*(2.0*Zr*gA-eA);
1028 const double denom=1.0+eA-gA;
1029 return num/denom;
1030 }
1031
1032 double Srr_div_S(const double& r, const double& Z) const {
1033 const double Zr=r*Z;
1034 const double eA=exp(-Zr);
1035 const double gA=exp(-Zr*Zr);
1036 const double num=Z*Z*(eA+gA*(2.0-4.0*Zr*Zr));
1037 const double denom=1.0+eA-gA;
1038 return num/denom;
1039 }
1040
1041 double Srrr_div_S(const double& r, const double& Z) const {
1042 const double Zr=r*Z;
1043 const double eA=exp(-Zr);
1044 const double gA=exp(-Zr*Zr);
1045 const double num=Z*Z*Z*(-eA - 12.0*gA*Zr + 8.0*gA*Zr*Zr*Zr);
1046 const double denom=1.0+eA-gA;
1047 return num/denom;
1048
1049 }
1050
1051 /// derivative of the U2 potential wrt X (scalar part)
1052
1053 /// with
1054 /// \f[
1055 /// \rho = \left| \vec r- \vec R_A \right|
1056 /// \f]
1057 /// returns the term in the parenthesis without the the derivative of rho
1058 /// \f[
1059 /// \frac{\partial U_2}{\partial X_A} = \frac{\partial \rho}{\partial X}
1060 /// \left(-\frac{1}{2}\frac{S''' S - S'' S'}{S^2} + \frac{1}{\rho^2}\frac{S'}{S}
1061 /// - \frac{1}{\rho} \frac{S''S - S'^2}{S^2} + \frac{Z_A}{\rho^2}\right)
1062 /// \f]
1063 double U2X_spherical(const double& r, const double& Z, const double& rcut) const {
1064
1065 double result=0.0;
1066 if (r*Z<1.e-4) {
1067 const double ZZ=Z*Z;
1068 const double ZZZ=ZZ*Z;
1069 const double Z4=ZZ*ZZ;
1070 const double r0=-4.0*ZZZ;
1071 const double r1=12.0*Z4;
1072 const double r2=36*Z4*Z;
1073 const double r3=-67.0/6.0*Z4*ZZ;
1074 result=(r0 + r*r1 + r*r*r2 + r*r*r*r3);
1075
1076 } else {
1077 const double S1=Sr_div_S(r,Z);
1078 const double S2=Srr_div_S(r,Z);
1079 const double S3=Srrr_div_S(r,Z);
1080 const double term1=-0.5*(S3-S1*S2);
1081 const double term2=(S1+Z)/(r*r);
1082 const double term3=(S2-S1*S1)/r;
1083 result=term1+term2-term3;
1084 }
1085 return result;
1086 }
1087
1088
1089};
1090
1091/// A nuclear correlation factor class
1092
1093/// The nuclear correlation factor is given by
1094/// \[f
1095/// R = \prod S_A ; S_A=exp(-Z_A r_{1A}) + ( 1 - exp(-r_{1A}^2) )
1096/// \]f
1098public:
1099 /// ctor
1100
1101 /// @param[in] world the world
1102 /// @param[in] mol molecule with the sites of the nuclei
1103 GradientalGaussSlater(World& world, const Molecule& mol, const double a)
1105
1106 if (world.rank()==0) {
1107 print("constructed nuclear correlation factor of the form");
1108 print(" R = Prod_A S_A");
1109 print(" S_A = 1/sqrt{Z} exp(-Z_A r_{1A}) + (1 - exp(-a^2*Z_A^2*r_{1A}^2))");
1110 print(" a = ",a);
1111 print("with eprec ",mol.get_eprec());
1112 print("which is of Gradiental Gaussian-Slater type\n");
1113 }
1114
1115 }
1116
1118
1119private:
1120
1121 const double a;
1122
1123 /// the nuclear correlation factor
1124 double S(const double& r, const double& Z) const {
1125 const double rho=r*Z;
1126 return 1/sqrt(Z) * exp(-rho)+(1.0-exp(-(a*a*rho*rho)));
1127 }
1128
1129 /// radial part first derivative of the nuclear correlation factor
1130 coord_3d Sp(const coord_3d& vr1A, const double& Z) const {
1131
1132 const double r=sqrt(vr1A[0]*vr1A[0] +
1133 vr1A[1]*vr1A[1] + vr1A[2]*vr1A[2]);
1134
1135 const double rho=Z*r;
1136 const double sqrtz=sqrt(Z);
1137 const double term=-exp(-rho)*sqrtz + 2.0*a*a*exp(-a*a*rho*rho)*Z*rho;
1138 return term*smoothed_unitvec(vr1A);
1139 }
1140
1141 /// second derivative of the nuclear correlation factor
1142
1143 /// -1/2 S"/S - Z/r
1144 double Spp_div_S(const double& r, const double& Z) const {
1145 const double rho=Z*r;
1146 const double sqrtz=sqrt(Z);
1147 if (rho<1.e-4) {
1148 const double zfivehalf=Z*Z*sqrtz;
1149 const double a2=a*a;
1150 const double a4=a2*a2;
1151 return -0.5*Z*Z
1152 - 3. *a2 * zfivehalf
1153 - 4.* a2 *rho* zfivehalf
1154 - 2. *a2 * rho*rho*zfivehalf
1155 + 5. *a4 *rho*rho*zfivehalf
1156 + 3. *a4 *rho*rho*Z*Z*Z
1157 -0.5 *a2 *rho*rho*rho*zfivehalf
1158 +5.5 *a4 *rho*rho*rho*zfivehalf
1159 +7. *a4 *rho*rho*rho*Z*Z*Z;
1160 } else {
1161 const double e=exp(-rho);
1162 const double g=exp(-a*a*rho*rho);
1163 const double poly=(2.0-6.0*a*a*rho + 4.0*a*a*a*a*rho*rho*rho);
1164 const double num=Z*(-2.0 - e*r*sqrtz + g*poly);
1165 const double denom=2.0*r*(1.0-g+e/sqrtz);
1166 return num/denom;
1167 }
1168 }
1169
1170 double Sr_div_S(const double& r, const double& Z) const {
1171 const double rZ=r*Z;
1172 const double e=exp(-rZ);
1173 const double g=exp(-a*a*rZ*rZ);
1174 const double sqrtz=sqrt(Z);
1175 const double num=-sqrtz*e + 2.0*a*a*g*Z*rZ;
1176 const double denom=1.0-g+e/sqrtz;
1177 return num/denom;
1178 }
1179
1180 double Srr_div_S(const double& r, const double& Z) const {
1181 const double rZ=r*Z;
1182 const double e=exp(-rZ);
1183 const double g=exp(-a*a*rZ*rZ);
1184 const double sqrtz=sqrt(Z);
1185 const double num=e*Z*sqrtz + g*(2.0*a*a - 4.0*power<4>(a)*rZ*rZ)*Z*Z;
1186 const double denom=1.0-g+e/sqrtz;
1187 return num/denom;
1188 }
1189
1190 double Srrr_div_S(const double& r, const double& Z) const {
1191 const double rZ=r*Z;
1192 const double e=exp(-rZ);
1193 const double g=exp(-a*a*rZ*rZ);
1194 const double sqrtz=sqrt(Z);
1195 const double num=e*power<3>(Z) + (12.0*power<4>(a)*g*rZ
1196 -8.0*power<6>(a)*g*power<3>(rZ))*sqrtz*power<3>(Z);
1197 const double denom=e+sqrtz-g*sqrtz;
1198 return -num/denom;
1199 }
1200
1201 double U2X_spherical(const double& r, const double& Z, const double& rcut) const {
1202
1203 double result=0.0;
1204 if (r*Z<1.e-4) {
1205 const double sqrtz=sqrt(Z);
1206 const double Z2=Z*Z;
1207 const double Z4=Z2*Z2;
1208 const double Z5=Z4*Z;
1209 const double Z6=Z5*Z;
1210 const double Z7=Z6*Z;
1211 const double a2=a*a;
1212 const double a4=a2*a2;
1213
1214 const double r0=-4.* a2* sqrt(Z7);
1215 const double r1=2.* (-2.* a2* Z*sqrt(Z7)+ 5.* a4* Z*sqrt(Z7) + 3.* a4 *Z5) *r;
1216 const double r2=1.5 * (-a2* sqrtz*Z5 + 11.* a4* sqrtz*Z5 + 14.*a4* Z6)* r*r;
1217 const double r3=1./6.* (-a2* sqrtz*Z6 + 66.* a4*sqrtz*Z6 - 84.* a2*a4* sqrtz*Z6 +
1218 180. *a4* Z7 - 156.*a2*a4* Z7 - 72.* a2*a4*sqrtz*Z7) *r*r*r;
1219 result=(r0 + r1 + r2 + r3);
1220
1221 } else {
1222 const double S1=Sr_div_S(r,Z);
1223 const double S2=Srr_div_S(r,Z);
1224 const double S3=Srrr_div_S(r,Z);
1225 const double term1=-0.5*(S3-S1*S2);
1226 const double term2=(S1+Z)/(r*r);
1227 const double term3=(S2-S1*S1)/r;
1228 result=term1+term2-term3;
1229 }
1230 return result;
1231 }
1232};
1233
1234
1235/// A nuclear correlation factor class
1236
1237/// The nuclear correlation factor is given by
1238/// \[f
1239/// R = \prod S_A ; S_A= -Z_A r_{1A} exp(-Z_A r_{1A}) + 1
1240/// \]f
1242public:
1243 /// ctor
1244
1245 /// @param[in] world the world
1246 /// @param[in] mol molecule with the sites of the nuclei
1247 LinearSlater(World& world, const Molecule& mol, const double a)
1248 : NuclearCorrelationFactor(world,mol), a_(1.0) {
1249
1250 if (a!=0.0) a_=a;
1251
1252 if (world.rank()==0) {
1253 print("constructed nuclear correlation factor of the form");
1254 print(" S_A = -Z_A r_{1A} exp(-Z_A r_{1A}) + 1");
1255 print(" a = ",a_);
1256 print("with eprec ",mol.get_eprec());
1257 print("which is of linear Slater type\n");
1258 }
1259 }
1260
1262
1263private:
1264
1265 /// the length scale parameter a
1266 double a_;
1267
1268 double a_param() const {return 1.0;}
1269
1270 /// the nuclear correlation factor
1271 double S(const double& r, const double& Z) const {
1272 const double rho=r*Z;
1273 const double b=a_param();
1274 return (-rho)*exp(-b*rho)+1.0;
1275 }
1276
1277 /// radial part first derivative of the nuclear correlation factor
1278 coord_3d Sp(const coord_3d& vr1A, const double& Z) const {
1279
1280 const double b=a_param();
1281 const double r=sqrt(vr1A[0]*vr1A[0] +
1282 vr1A[1]*vr1A[1] + vr1A[2]*vr1A[2]);
1283
1284 const double ebrz=exp(-b*r*Z);
1286 return term;
1287 }
1288
1289 /// second derivative of the nuclear correlation factor
1290
1291 /// -1/2 S"/S - Z/r
1292 double Spp_div_S(const double& r, const double& Z) const {
1293
1294 const double b=a_param();
1295 const double rho=Z*r;
1296 if (rho<1.e-4) {
1297 const double O0=1.0- 3.0* b;
1298 const double O1=Z - 4.0*b*Z + 3.0*b*b*Z;
1299 const double O2=Z*Z - 5.0*b*Z*Z + 6.5*b*b*Z*Z - 5.0/3.0*b*b*b*Z*Z;
1300 return Z*Z*(O0 + O1*r + O2*r*r);
1301
1302 } else {
1303 const double ebrz=exp(-b*rho);
1304 const double num=Z* (ebrz - 1.0 + 0.5*ebrz*rho* (2.0 + b*(b*rho-4.0)));
1305 const double denom=r*(rho*ebrz-1.0);
1306 return -num/denom;
1307 }
1308 }
1309
1310 double Sr_div_S(const double& r, const double& Z) const {
1311 const double& a=a_param();
1312 const double earz=exp(-a*r*Z);
1313 return Z*earz*(a*r*Z-1.0)/(1.0-r*Z*earz);
1314 }
1315
1316 double Srr_div_S(const double& r, const double& Z) const {
1317 const double& a=a_param();
1318 const double earz=exp(-a*r*Z);
1319 return a*Z*Z*earz*(a*r*Z-2.0)/(-1.0+r*Z*earz);
1320 }
1321
1322 double Srrr_div_S(const double& r, const double& Z) const {
1323 const double& a=a_param();
1324 const double earz=exp(-a*r*Z);
1325 return a*a*Z*Z*Z*earz*(a*r*Z-3.0)/(1.0-r*Z*earz);
1326 }
1327
1328};
1329
1330
1331/// A nuclear correlation factor class
1333public:
1334 /// ctor
1335
1336 /// @param[in] world the world
1337 /// @param[in] mol molecule with the sites of the nuclei
1338 Slater(World& world, const Molecule& mol, const double a)
1339 : NuclearCorrelationFactor(world,mol), a_(1.5) {
1340
1341 if (a!=0.0) a_=a;
1342 eprec_=mol.get_eprec();
1343
1344 if (world.rank()==0) {
1345 print("\nconstructed nuclear correlation factor of the form");
1346 print(" S_A = 1/(a-1) exp(-a Z_A r_{1A}) + 1");
1347 print(" a = ",a_);
1348 print("with eprec ",eprec_);
1349 print("which is of Slater type\n");
1350 }
1351 }
1352
1354
1355private:
1356
1357 /// the length scale parameter
1358 double a_;
1359 double eprec_;
1360
1361 double a_param() const {return a_;}
1362 double eprec_param() const {return eprec_;}
1363
1364 /// first derivative of the correlation factor wrt (r-R_A)
1365
1366 /// \f[
1367 /// Sr_div_S = \frac{1}{S(r)}\frac{\partial S(r)}{\partial r}
1368 /// \f]
1369 double Sr_div_S(const double& r, const double& Z) const {
1370 const double& a=a_param();
1371 return -a*Z/(1.0+(a-1.0)*exp(a*r*Z));
1372 }
1373
1374 /// second derivative of the correlation factor wrt (r-R_A)
1375
1376 /// \f[
1377 /// result = \frac{1}{S(r)}\frac{\partial^2 S(r)}{\partial r^2}
1378 /// \f]
1379 double Srr_div_S(const double& r, const double& Z) const {
1380 const double& a=a_param();
1381 const double aZ=a*Z;
1382 return aZ*aZ/(1.0+(a-1.0)*exp(r*aZ));
1383 }
1384
1385 /// third derivative of the correlation factor wrt (r-R_A)
1386
1387 /// \f[
1388 /// result = \frac{1}{S(r)}\frac{\partial^3 S(r)}{\partial r^3}
1389 /// \f]
1390 double Srrr_div_S(const double& r, const double& Z) const {
1391 const double& a=a_param();
1392 const double aZ=a*Z;
1393 return -aZ*aZ*aZ/(1.0+(a-1.0)*exp(r*aZ));
1394 }
1395
1396 /// the nuclear correlation factor
1397 double S(const double& r, const double& Z) const {
1398 const double a=a_param();
1399 //const double eprec=eprec_param();
1400 return 1.0+1.0/(a-1.0) * exp(-a*Z*r);
1401
1402// return 1.0 + 0.5/(a-1.0) *
1403// (exp(-a*r*Z + 0.5*a*a*Z*Z*eprec) * erfc((-r+a*eprec*Z)/sqrt(2*eprec))
1404// + exp(-a*r*Z + 0.5*a*Z*(4.0*r+a*eprec*Z)) * erfc((r+a*eprec*Z)/sqrt(2*eprec)));
1405 }
1406
1407 /// radial part first derivative of the nuclear correlation factor
1408 coord_3d Sp(const coord_3d& vr1A, const double& Z) const {
1409 const double a=a_param();
1410 const double r=vr1A.normf();
1411 return -(a*exp(-a*Z*r)*Z)/(a-1.0)*smoothed_unitvec(vr1A);
1412 }
1413
1414 /// second derivative of the nuclear correlation factor
1415 double Spp_div_S(const double& r, const double& Z) const {
1416 const double a=a_param();
1417
1418 if (r*Z<1.e-4) {
1419 const double O0=1.0-(1.5*a);
1420 const double O1=(a-1.0)*(a-1.0)*Z;
1421 const double O2=(1.0/12.0 * (a-1.0)*(12.0+a*(5*a-18.0)))*Z*Z;
1422 return Z*Z*(O0 + O1*r + O2*r*r);
1423
1424 } else {
1425 const double earz=exp(-a*r*Z);
1426 const double num=Z*(-earz + a*earz - (a-1.0) - 0.5*a*a*r*Z*earz);
1427 const double denom=(r*earz + (a-1.0) * r);
1428 return num/denom;
1429 }
1430 }
1431
1432
1433 /// derivative of the U2 potential wrt X (scalar part)
1434
1435 /// with
1436 /// \f[
1437 /// \rho = \left| \vec r- \vec R_A \right|
1438 /// \f]
1439 /// returns the term in the parenthesis without the the derivative of rho
1440 /// \f[
1441 /// \frac{\partial U_2}{\partial X_A} = \frac{\partial \rho}{\partial X}
1442 /// \left(-\frac{1}{2}\frac{S''' S - S'' S'}{S^2} + \frac{1}{\rho^2}\frac{S'}{S}
1443 /// - \frac{1}{\rho} \frac{S''S - S'^2}{S^2} + \frac{Z_A}{\rho^2}\right)
1444 /// \f]
1445 double U2X_spherical(const double& r, const double& Z, const double& rcut) const {
1446 const double a=a_param();
1447
1448 double result=0.0;
1449 if (r*Z<1.e-4) {
1450 const double ZZ=Z*Z;
1451 const double ZZZ=ZZ*Z;
1452 const double a2=a*a;
1453 const double a4=a2*a2;
1454 const double r0=ZZZ*(1. - 2.* a + a2);
1455 const double r1=ZZ*ZZ/6.* (12.0 - 30.* a + 23. *a2 - 5.*a*a2);
1456 const double r2=1./8.*ZZ*ZZZ* (24. - 72.*a + 74.*a2 - 29.*a2*a + 3.*a4);
1457 const double r3=1./60.*ZZZ*ZZZ* (240. - 840.*a + 1080.*a2 - 610.*a2*a
1458 + 137.*a2*a2 - 7.*a4*a);
1459 result=(r0 + r*r1 + r*r*r2 + r*r*r*r3);
1460
1461 } else {
1462 const double S1=Sr_div_S(r,Z);
1463 const double S2=Srr_div_S(r,Z);
1464 const double S3=Srrr_div_S(r,Z);
1465 const double term1=-0.5*(S3-S1*S2);
1466 const double term2=(S1+Z)/(r*r);
1467 const double term3=(S2-S1*S1)/r;
1468 result=term1+term2-term3;
1469 }
1470 return result;
1471 }
1472
1473};
1474
1475
1477public:
1478 /// ctor
1479
1480 /// @param[in] world the world
1481 /// @param[in] mol molecule with the sites of the nuclei
1482 poly4erfc(World& world, const Molecule& mol, const double aa)
1483 : NuclearCorrelationFactor(world,mol), a(1.0) {
1484
1485 if (aa!=0.0) a=aa;
1486 eprec_=mol.get_eprec();
1487
1488 if (world.rank()==0) {
1489 print("\nconstructed nuclear correlation factor of the form");
1490 print(" S_A = 1 + (a0 + a1 arZ + a2 (arZ)^2 + a3 (arZ)^3 + a4 (arZ)^4) erfc(arZ)");
1491 print(" a = ",a);
1492 print("with eprec ",eprec_);
1493 print("which is of poly4erfc type\n");
1494 }
1495 //const double pi32=std::pow(constants::pi,1.5);
1496 //const double sqrtpi=sqrt(constants::pi);
1497 //const double Pi=constants::pi;
1498
1499 if (a==0.5) {
1500 a0=0.5083397721116242769;
1501 a1=-2.4430795355664112811;
1502 a2=3.569312300653802680;
1503 a3=-1.9812471972342746507;
1504 a4=0.3641705622093696564;
1505 } else if (a==1.0) {
1506 a0=0.20265985404508529127;
1507 a1=-0.9739826967339938056;
1508 a2=1.4229779953809877198;
1509 a3=-0.7898639647077711196;
1510 a4=0.14518390461225107425;
1511
1512 } else {
1513 print("invalid parameter a for poly4erfc: only 0.5 and 1.0 implemented");
1514 MADNESS_EXCEPTION("stupid you",1);
1515 }
1516 }
1517
1519
1520private:
1521
1522 /// the length scale parameter
1523 double a;
1524 double a0, a1, a2, a3, a4;
1525 double eprec_;
1526
1527 double a_param() const {return a;}
1528 double eprec_param() const {return eprec_;}
1529
1530 /// first derivative of the correlation factor wrt (r-R_A)
1531
1532 /// \f[
1533 /// Sr_div_S = \frac{1}{S(r)}\frac{\partial S(r)}{\partial r}
1534 /// \f]
1535 double Sr_div_S(const double& r, const double& Z) const {
1536 const double x=r*Z;
1537
1538 double result=0.0;
1539 if (a==0.5) {
1540 if (x<1.0) {
1541 result=(-17.97663543396820624361586474 + x*(32.78290319470982346841067868 +
1542 x*(-18.158574783628271659713638233 +
1543 x*(2.472138984374094343735335913 +
1544 x*(0.5516975358315341628276502285 +
1545 x*(-0.008573693952875097234391220137 +
1546 x*(-0.05596791202351071993748992739 +
1547 (0.002673799219133696315436690424 +
1548 0.0013386538660557369902632289083*x)*x)))))))/
1549 (17.976635433967702922140233083 + x*
1550 (-13.062204300852085089323266568 +
1551 x*(16.397871971437618641239835027 + x*(-5.383337491559214163188757918 + 1.*x))));
1552 } else if (x<2.0) {
1553 result=(-16.53370050883888159389958126 + x*(30.04151304875517461538549269 +
1554 x*(-16.692529697855029750948871179 +
1555 x*(2.50341008323651011875249567 +
1556 x*(0.3106921665634860719234742532 +
1557 x*(0.08721948207311506458903445571 +
1558 x*(-0.10041387133168708232852057948 +
1559 (0.02000987266876476192949541524 - 0.0012508983745483161308604975792*x)*
1560 x)))))))/
1561 (16.532205048243702951212522516 + x*
1562 (-11.89273747187279634240347945 +
1563 x*(15.157537549656745468895369276 + x*(-4.9102960292797655978798640519 + 1.*x))));
1564 } else if (x<5.0) {
1565 result=(-2352.191894900273554810118278 + x*(5782.846962269399174183661793 +
1566 x*(-5653.246084369776756298278851 +
1567 x*(2948.18046377483570925427449 +
1568 x*(-913.4583247839311453090142452 +
1569 x*(174.39391722588915386106331206 +
1570 x*(-20.22035127074332315930567933 +
1571 (1.3107321165711966663791114988 - 0.03655666729452579098523876463*x)*x))
1572 )))))/
1573 (886.4859678528423041797649741 + x*(269.17746130370931387996124706 +
1574 x*(-130.21383548057958115685397713 + x*(37.644499985765056273193347388 + 1.*x))));
1575 } else if (x<10) {
1576 result=(2.2759176275121988686860433041 + x*(-1.8014283464827425541637211503 +
1577 x*(0.60570955276433317373251991152 +
1578 x*(-0.11235368819003308411943926239 +
1579 x*(0.01243211635244600976892077538 +
1580 x*(-0.0008211800260491381826149891865 +
1581 x*(0.000029973534470203049782417744015 +
1582 (-4.6423722605763162431293872646e-7 -
1583 1.3224615425412157194986675329e-10*x)*x)))))))/
1584 (1039.800013929971888016478838 + x*(-702.5378531848183775210948787 +
1585 x*(183.17476380259879599459789974 + x*(-21.74106003575315304073197254 + 1.*x))));
1586 } else {
1587 result=0.0;
1588 }
1589 } else if (a==1.0) {
1590 if (x<1.0) {
1591 result=(-1.6046958001953006847027538457 + x*(5.948945186367159977879486279 +
1592 x*(-6.884321742840291285733040882 +
1593 x*(2.296896506418919905405783368 +
1594 x*(0.616939354810622973212914089 +
1595 x*(-0.13679830198890803519235207564 +
1596 x*(-0.3356576872066501398893403439 +
1597 (0.14876798925798674488426727928 - 0.016049886728185297028755535226*x)*x
1598 )))))))/
1599 (1.6046957999975126909719683196 + x*
1600 (-0.8234878506688316215458988304 +
1601 x*(3.4607641859010551501639903314 + x*(-1.8955210085531557309609670978 + 1.*x))));
1602 } else if (x<2.0) {
1603 result=(-7.143856421301985019580778813 + x*(33.35568129248075086686087865 +
1604 x*(-60.0412343766569246898209957 +
1605 x*(55.46407913315151830247939138 +
1606 x*(-28.7874770749840240158264326 +
1607 x*(8.379317837934083469035061852 +
1608 x*(-1.2103278392957399092107317741 +
1609 (0.04275186003977071121074860478 + 0.005247730112126140726731063205*x)*x
1610 )))))))/
1611 (5.4509691924562038998044993827 + x*
1612 (-2.2732931206867811068721699796 +
1613 x*(4.1530634219989859344450742259 + x*(-2.0183662125874366044951391259 + 1.*x))));
1614 } else if (x<5.0) {
1615 result=(-0.4869290414611847276899694883 + x*(1.0513417728218375522016338562 +
1616 x*(-0.9694851629317255156038942437 +
1617 x*(0.5007460889402078102011673774 +
1618 x*(-0.15897436623286639052954575417 +
1619 x*(0.03185042477631079356985872518 +
1620 x*(-0.003940899912654543218183049969 +
1621 (0.0002757919409481032696079686825 -
1622 8.369138363906178282041501561e-6*x)*x)))))))/
1623 (30.81121613134246115634780413 + x*(-49.989974505724725146933397436 +
1624 x*(31.455643953462635691568128729 + x*(-8.992097794824270871044305786 + 1.*x))));
1625 } else {
1626 result=0.0;
1627 }
1628 }
1629 return result*Z;
1630 }
1631
1632 /// second derivative of the correlation factor wrt (r-R_A)
1633
1634 /// \f[
1635 /// result = \frac{1}{S(r)}\frac{\partial^2 S(r)}{\partial r^2}
1636 /// \f]
1637 double Srr_div_S(const double& r, const double& Z) const {
1638 MADNESS_EXCEPTION("no Srr_div_S in Slater2 yet",0);
1639 return 0.0;
1640 }
1641
1642 /// third derivative of the correlation factor wrt (r-R_A)
1643
1644 /// \f[
1645 /// result = \frac{1}{S(r)}\frac{\partial^3 S(r)}{\partial r^3}
1646 /// \f]
1647 double Srrr_div_S(const double& r, const double& Z) const {
1648 MADNESS_EXCEPTION("no Srrr_div_S in Slater2 yet",0);
1649 return 0.0;
1650 }
1651
1652 /// the nuclear correlation factor
1653 double S(const double& r, const double& Z) const {
1654 const double arZ=a*r*Z;
1655 const double arZ2=a*a*r*r*Z*Z;
1656
1657 return 1.0 + (a0 +a1* arZ+ a2 * arZ2 + a3*arZ*arZ2 + + a4*arZ2*arZ2) *erfc( a*r*Z);
1658 }
1659
1660 /// radial part first derivative of the nuclear correlation factor
1661 coord_3d Sp(const coord_3d& vr1A, const double& Z) const {
1662 MADNESS_EXCEPTION("no Sp in Slater2 yet",0);
1663 return smoothed_unitvec(vr1A);;
1664 }
1665
1666 /// second derivative of the nuclear correlation factor
1667 double Spp_div_S(const double& r, const double& Z) const {
1668 const double x=r*Z;
1669 double result=0.0;
1670 if (a==0.5) {
1671 if (x<1.0) {
1672 result=(-37.75186842343823465059 + x*(21.3476988467348903615 +
1673 x*(0.014608707333424946750026 +
1674 x*(-3.704945314726273312722 +
1675 x*(0.08808104845382944292252 +
1676 x*(0.3362428305409206967066 +
1677 x*(-0.02288039625102549092766 +
1678 (-0.017240056622850307571001 + 0.002412740490618117536527*x)*x)))))))/
1679 (17.595611361287293183447 + x*(-12.421065066789808273295 +
1680 x*(15.957564552156320207938 + x*(-5.0239100389132464317907 + 1.*x))));
1681 } else if (x<2.0) {
1682 result=(-35.46082798344982189328 + x*(20.3565414350879797493 +
1683 x*(-0.3046488975234456455871 +
1684 x*(-3.298067641731523613442 +
1685 x*(-0.10712268902574947466554 +
1686 x*(0.4829111116912435121877 +
1687 x*(-0.10089023589818206760275 +
1688 (0.0013899828749998182176948 + 0.0008305150868988335610678*x)*x)))))))/
1689 (16.526499668833810286111 + x*(-11.79820182874024593006 +
1690 x*(15.115407083582433322342 + x*(-4.8449266197426825174319 + 1.*x))));
1691 } else if (x<5.0) {
1692 result=(-414.5311559516023264104 + x*(615.8720414166440747539 +
1693 x*(-422.5938440932793094888 + x*
1694 (159.72497494584873155352 +
1695 x*(-35.6790348104188081907 +
1696 x*(4.658777521872728594702 +
1697 x*(-0.328305094433759490678 +
1698 (0.009162754689309596905172 + 0.00005047926659010755662873*x)*x)))))))/
1699 (112.7044543272820830484 + x*(-56.072518762714727894479 +
1700 x*(28.188843903409059322224 + x*(-6.519554545057610040741 + 1.*x))));
1701 } else if (x<10.0) {
1702 result=(-146.68256559112012287314 + x*(188.52807059353309478385 +
1703 x*(-82.07176992590032524431 + x*
1704 (18.107697718347802322776 +
1705 x*(-2.3221393933622638466979 +
1706 x*(0.18681223946803275939642 +
1707 x*(-0.009601011427143648072501 +
1708 (0.00028623295732553770894583 - 3.77364531155112782235e-6*x)*x)))))))/
1709 (633.1319105785227043552 + x*(-574.29230199331494406798 +
1710 x*(171.872612865808639376 + x*(-21.906495121260483674385 + 1.*x))));
1711 } else {
1712 result=-1.0/x;
1713 }
1714 } else if (a==1.0) {
1715 if (x<1.0) {
1716 result=(-8.85288955131414420808 + x*(11.359434597010419928515 +
1717 x*(-2.982094072176256165405 + x*
1718 (-4.924201512880445076103 +
1719 x*(0.6773928043289287907009 +
1720 x*(2.061680233090141287213 +
1721 x*(-0.5528612000728412913713 +
1722 (-0.3024276764350212595121 + 0.10765958646570631264003*x)*x)))))))/
1723 (1.6731803922436094206275 + x*(-0.8242052614481793487834 +
1724 x*(3.5912910648514747558597 + x*(-1.9146644266104277222142 + 1.*x))));
1725 } else if (x<2.0) {
1726 result=(-8.538839434207355205544 + x*(-37.85611260277589742674 +
1727 x*(155.08466711228234382211 + x*
1728 (-241.1247881821171613212 +
1729 x*(199.33293375918859716585 +
1730 x*(-96.80750216221383928113 +
1731 x*(27.71704080319043943288 +
1732 (-4.354251431065185902435 + 0.2906781051124817624589*x)*x)))))))/
1733 (2.2233877901091612794108 + x*(3.2084406367698851844258 +
1734 x*(1.021615116328133792993 + x*(-0.9819667717342250528772 + 1.*x))));
1735 } else if (x<5.0) {
1736 result=(-7.338671998425412491091 + x*(18.593867285988629508481 +
1737 x*(-19.15344657249203844577 + x*
1738 (10.072359942912659732126 +
1739 x*(-2.99771628023376895151 +
1740 x*(0.5324416109232007541639 +
1741 x*(-0.05993976172902101376555 +
1742 (0.003887110757665478374745 - 0.00011079212872583089652945*x)*x)))))))/
1743 (13.273604111590967002999 + x*(-28.012330064250556933961 +
1744 x*(22.161347591665727407914 + x*(-7.617582259533338164664 + 1.*x))));
1745 } else if (x<10) {
1746 result=(132.78397650676876308801 + x*(-78.01898251977413923271 +
1747 x*(15.292039515801252996504 + x*
1748 (-1.000000154745351328125 +
1749 x*(1.950300262619412492847e-8 +
1750 x*(-1.6337541591423364318692e-9 +
1751 x*(8.771557330523968791519e-11 +
1752 (-2.7388800346031121159372e-12 + 3.7894572289998844980568e-14*x)*x))))))
1753 )/(-4.724326520908917985827e-6 + x*
1754 (-132.78397108375581258096 + x*(78.01897976124964688489 +
1755 x*(-15.292038699709498552356 + 1.*x))));
1756 } else {
1757 result=-1.0/x;
1758 }
1759 }
1760 return result*Z*Z;
1761 }
1762
1763
1764 /// derivative of the U2 potential wrt X (scalar part)
1765
1766 /// with
1767 /// \f[
1768 /// \rho = \left| \vec r- \vec R_A \right|
1769 /// \f]
1770 /// returns the term in the parenthesis without the the derivative of rho
1771 /// \f[
1772 /// \frac{\partial U_2}{\partial X_A} = \frac{\partial \rho}{\partial X}
1773 /// \left(-\frac{1}{2}\frac{S''' S - S'' S'}{S^2} + \frac{1}{\rho^2}\frac{S'}{S}
1774 /// - \frac{1}{\rho} \frac{S''S - S'^2}{S^2} + \frac{Z_A}{\rho^2}\right)
1775 /// \f]
1776 double U2X_spherical(const double& r, const double& Z, const double& rcut) const {
1777 MADNESS_EXCEPTION("no U2X_spherical in Slater2 yet",0);
1778 return 0.0;
1779 }
1780
1781};
1782
1783
1784
1785/// A nuclear correlation factor class
1786
1787/// should reduce to quartic for N=4
1788/// @tparam N the exponent of the polynomial
1789template<std::size_t N>
1791public:
1792 /// ctor
1793
1794 /// @param[in] world the world
1795 /// @param[in] mol molecule with the sites of the nuclei
1796 Polynomial(World& world, const Molecule& mol, const double a)
1798
1799 /// length scale parameter a, default chosen that linear terms in U2 vanish
1800 a_=(2. + (-2. + sqrt(-1. + N))*N)/(-2. + N);
1801
1802 if (a!=0.0) a_=a;
1803
1804 if (world.rank()==0) {
1805 print("constructed nuclear correlation factor of the form");
1806 print(" R = Prod_A S_A");
1807 print(" S_A = 1 + a (r/b -1)^N if r<b, with b= (N*a)/((1+a) Z)");
1808 print(" = 1 else ");
1809 print("with eprec ",mol.get_eprec());
1810 print("which is of polynomial type with exponent N = ",N);
1811 }
1812 }
1813
1815
1816private:
1817
1818 /// length scale parameter a, default chosen that linear terms in U2 vanish
1819 double a_;
1820
1821 double a_param() const {return a_;}
1822
1823 /// the cutoff
1824 static double b_param(const double& a) {return N*a/(1.0+a);}
1825
1826 /// the nuclear correlation factor
1827 double S(const double& r, const double& Z) const {
1828
1829 const double rho=r*Z;
1830 const double a=Polynomial<N>::a_param();
1831 const double b=Polynomial<N>::b_param(a);
1832
1833 if (rho<b) {
1834 const double arg=-1.0 + rho/b;
1835 return 1.0 + power<N>(-1.0) * a*power<N>(arg);
1836 } else {
1837 return 1.0;
1838 }
1839
1840 }
1841
1842 /// radial part first derivative of the nuclear correlation factor
1843 coord_3d Sp(const coord_3d& vr1A, const double& Z) const {
1844
1845 const double r=vr1A.normf();
1846 const double rho=r*Z;
1847 const double a=Polynomial<N>::a_param();
1848 const double b=Polynomial<N>::b_param(a);
1849
1850 if (rho<b) {
1851 return power<N>(-1.)*(1.+a)* Z* power<N-1>(-1.+rho/b)*smoothed_unitvec(vr1A);
1852 }
1853 return coord_3d(0.0);
1854 }
1855
1856 /// second derivative of the nuclear correlation factor
1857
1858 /// -1/2 S"/S - Z/r
1859 double Spp_div_S(const double& r, const double& Z) const {
1860
1861 const double rho=r*Z;
1862 const double a=Polynomial<N>::a_param();
1863 const double b=Polynomial<N>::b_param(a);
1864
1865 if (rho<1.e-6) {
1866 const double ap1=1.0+a;
1867 const double c0=((3. *(1. + a) - (3. + a) * N))/(2.* a*N);
1868 const double c1=((2.* ap1*ap1 - ap1* (3. + a)*N + N*N)*Z)/(a*a*N*N);
1869 const double c2=((30.*ap1*ap1*ap1- ap1*ap1* (55 + 18* a)*N +
1870 30 *ap1 *N*N + (-5 + a* (8 + a)) *N*N*N)* Z*Z)/(12 *a*a*a*N*N*N);
1871 return Z*Z*(c0 + c1*r + c2*r*r);
1872
1873 } else if (rho<b) {
1874
1875 const double num=Z* (2 + (power<N>(-1)* a* power<N>(-1 + rho/b)
1876 * (-2 *a*N*N + (1 + a) *N* (1 + a *(-3 + N) + N)* rho +
1877 2 *(1 + a)*(1+a)* rho*rho))/power<2>(a* N - (1 + a)*rho));
1878
1879 const double denom=2.* (r + power<N>(-1) *a* r* power<N>(-1 + rho/b));
1880 return -num/denom;
1881
1882 } else {
1883 return -Z*Z/rho;
1884 }
1885 }
1886
1887 double Sr_div_S(const double& r, const double& Z) const {
1888 const double rho=r*Z;
1889 const double a=Polynomial<N>::a_param();
1890 const double b=Polynomial<N>::b_param(a);
1891
1892 if (rho<b) {
1893 const double negn= power<N>(-1.0);
1894 const double num=(negn*(1 + a)*Z*power<N-1>(-1 + ((1 + a)*r*Z)/(a*N)));
1895 const double denom=(1 + negn*a*power<N>(-1 + ((1 + a)*r*Z)/(a*N)));
1896 return num/denom;
1897 } else {
1898 return 0.0;
1899 }
1900
1901 }
1902
1903 double Srr_div_S(const double& r, const double& Z) const {
1904 const double rho=r*Z;
1905 const double a=Polynomial<N>::a_param();
1906 const double b=Polynomial<N>::b_param(a);
1907
1908 if (rho<b) {
1909 const double negn= power<N>(-1.0);
1910 return (negn*power<2>(1 + a)*(-1 + N)*power<2>(Z)*power<N-2>(-1 + ((1 + a)*r*Z)/(a*N)))/
1911 (a*N*(1 + negn*a*power<N>(-1 + ((1 + a)*r*Z)/(a*N))));
1912 } else {
1913 return 0.0;
1914 }
1915 }
1916
1917 double Srrr_div_S(const double& r, const double& Z) const {
1918 const double rho=r*Z;
1919 const double a=Polynomial<N>::a_param();
1920 const double b=Polynomial<N>::b_param(a);
1921
1922 if (rho<b) {
1923 const double negn= power<N>(-1.0);
1924 return (negn*power<3>(1 + a)*(-2 + N)*(-1 + N)*power<3>(Z)*power<N-3>(-1 + ((1 + a)*r*Z)/(a*N)))/
1925 (power<2>(a*N)*(1 + negn*a*power<N>(-1 + ((1 + a)*r*Z)/(a*N))));
1926 } else {
1927 return 0.0;
1928 }
1929 }
1930
1931 double U2X_spherical(const double& r, const double& Z, const double& rcut) const {
1932 const double a=a_param();
1933 const double aopt=(2. + (-2. + sqrt(-1. + N))*N)/(-2. + N);
1934 if (fabs(a-aopt)>1.e-10) {
1935 MADNESS_EXCEPTION("U2X_spherical for polynomial ncf only with aopt",1);
1936 }
1937
1938 double result=0.0;
1939 if (r*Z<1.e-4) {
1940 const double rn=sqrt(N-1);
1941 const double r0=0.0;
1942 const double r1=((2.*(-8. + 9.*rn) + N*(25. + 10.*rn + N))*r*power<4>(Z))/
1943 (6.*power<2>(-2 + N)*rn);
1944 const double r2=((-4*(17 + 9*rn) + N*(92 + 80*rn +
1945 N*(-29 - 33*rn + N*(4 + 7*rn + N))))*power<5>(Z))/
1946 (8.*power<3>(-2 + N)*(-1 + N)*rn);
1947 result=(r0 + r*r1 + r*r*r2);
1948
1949 } else {
1950 const double S1=Sr_div_S(r,Z);
1951 const double S2=Srr_div_S(r,Z);
1952 const double S3=Srrr_div_S(r,Z);
1953 const double term1=-0.5*(S3-S1*S2);
1954 const double term2=(S1+Z)/(r*r);
1955 const double term3=(S2-S1*S1)/r;
1956 result=term1+term2-term3;
1957 }
1958 return result;
1959 }
1960
1961};
1962
1964
1965public:
1966 /// ctor
1967
1968 /// @param[in] world the world
1969 /// @param[in] mol molecule with the sites of the nuclei
1971 const std::shared_ptr<PotentialManager> pot, const double fac)
1972 : NuclearCorrelationFactor(world,mol), potentialmanager(pot),
1973 eprec(mol.get_eprec()), fac(fac) {
1974
1975 if (world.rank()==0) {
1976 print("constructed nuclear correlation factor of the form");
1977 print(" R = ",fac);
1978 print("with eprec ",mol.get_eprec());
1979 print("which means it's (nearly) a conventional calculation\n");
1980 }
1981
1982 // add the missing -Z/r part to U2!
1983 }
1984
1985 corrfactype type() const {return None;}
1986
1987 /// return the U2 term of the correlation function
1988
1989 /// overloading to avoid inconsistent state of U2, which needs the
1990 /// nuclear potential
1991 const real_function_3d U2() const {
1992
1993// if (not U2_function.is_initialized()) {
1994 MADNESS_ASSERT(potentialmanager->vnuclear().is_initialized());
1995// }
1996 return potentialmanager->vnuclear();
1997 }
1998
1999 /// apply the regularized potential U_nuc on a given function rhs
2000
2001 /// overload the base class method for efficiency
2003 return (U2()*rhs).truncate();
2004 }
2005
2006
2007private:
2008
2009 /// underlying potential (=molecule)
2010 std::shared_ptr<PotentialManager> potentialmanager;
2011 double eprec;
2012
2013 /// the factor of the correlation factor: R=fac;
2014 const double fac;
2015
2016 double Sr_div_S(const double& r, const double& Z) const {return 0.0;}
2017
2018 double Srr_div_S(const double& r, const double& Z) const {return 0.0;}
2019
2020 double Srrr_div_S(const double& r, const double& Z) const {return 0.0;}
2021
2022 /// the nuclear correlation factor
2023 double S(const double& r, const double& Z) const {
2024 return fac;
2025 }
2026
2027 /// radial part first derivative of the nuclear correlation factor
2028 coord_3d Sp(const coord_3d& vr1A, const double& Z) const {
2029 return coord_3d(0.0);
2030 }
2031
2032 /// second derivative of the nuclear correlation factor
2033 double Spp_div_S(const double& r, const double& Z) const {
2034 double rcut= 1.0 / smoothing_parameter(Z, eprec);
2035 return - Z * smoothed_potential(r*rcut)*rcut;
2036 }
2037
2038 double U2X_spherical(const double& r, const double& Z, const double& rcut) const {
2039 // factor -1 from the definition of the dsmoothed_potential as -1/r^2
2040 return -Z*dsmoothed_potential(r * rcut) * (rcut * rcut);
2041 }
2042
2043};
2044
2045
2046/// this ncf has no information about itself, only U2 and U1 assigned
2048
2049public:
2050 /// ctor
2051
2052 /// @param[in] world the world
2053 /// @param[in] mol molecule with the sites of the nuclei
2055 const std::vector<real_function_3d>& U1)
2057
2058 U2_function=U2;
2059 U1_function=U1;
2060
2061 if (world.rank()==0) {
2062 print("constructed ad hoc nuclear correlation factor");
2063 }
2064 }
2065
2066 corrfactype type() const {return Adhoc;}
2067
2068private:
2069
2070 double Sr_div_S(const double& r, const double& Z) const {
2071 MADNESS_EXCEPTION("no Sr_div_S() in AdhocNuclearCorrelationFactor",0);
2072 return 0.0;
2073 }
2074
2075 double Srr_div_S(const double& r, const double& Z) const {
2076 MADNESS_EXCEPTION("no Srr_div_S() in AdhocNuclearCorrelationFactor",0);
2077 return 0.0;
2078 }
2079
2080 double Srrr_div_S(const double& r, const double& Z) const {
2081 MADNESS_EXCEPTION("no Srrr_div_S() in AdhocNuclearCorrelationFactor",0);
2082 return 0.0;
2083 }
2084
2085 /// the nuclear correlation factor
2086 double S(const double& r, const double& Z) const {
2087 MADNESS_EXCEPTION("no S() in AdhocNuclearCorrelationFactor",0);
2088 return 0.0;
2089 }
2090
2091 /// radial part first derivative of the nuclear correlation factor
2092 coord_3d Sp(const coord_3d& vr1A, const double& Z) const {
2093 MADNESS_EXCEPTION("no Sp() in AdhocNuclearCorrelationFactor",0);
2094 return coord_3d(0.0);
2095 }
2096
2097 /// second derivative of the nuclear correlation factor
2098 double Spp_div_S(const double& r, const double& Z) const {
2099 MADNESS_EXCEPTION("no Spp_div_S() in AdhocNuclearCorrelationFactor",0);
2100 return 0.0;
2101 }
2102};
2103
2104
2105std::shared_ptr<NuclearCorrelationFactor>
2107 const Molecule& molecule,
2108 const std::shared_ptr<PotentialManager> pm,
2109 const std::string inputline);
2110
2111std::shared_ptr<NuclearCorrelationFactor>
2113 const Molecule& molecule,
2114 const std::shared_ptr<PotentialManager> pm,
2115 const std::pair<std::string,double>& ncf);
2116
2117}
2118
2119
2120#endif /* NUCLEARCORRELATIONFACTOR_H_ */
Declaration of utility class and functions for atom.
this ncf has no information about itself, only U2 and U1 assigned
Definition correlationfactor.h:2047
double Spp_div_S(const double &r, const double &Z) const
second derivative of the nuclear correlation factor
Definition correlationfactor.h:2098
double Sr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:2070
coord_3d Sp(const coord_3d &vr1A, const double &Z) const
radial part first derivative of the nuclear correlation factor
Definition correlationfactor.h:2092
corrfactype type() const
Definition correlationfactor.h:2066
double Srr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:2075
AdhocNuclearCorrelationFactor(World &world, const real_function_3d U2, const std::vector< real_function_3d > &U1)
ctor
Definition correlationfactor.h:2054
double S(const double &r, const double &Z) const
the nuclear correlation factor
Definition correlationfactor.h:2086
double Srrr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:2080
Definition molecule.h:60
double y
Definition molecule.h:62
double x
Definition molecule.h:62
double z
Definition molecule.h:62
madness::Vector< double, 3 > get_coords() const
Definition molecule.h:106
double q
Coordinates and charge in atomic units.
Definition molecule.h:62
Implements derivatives operators with variety of boundary conditions on simulation domain.
Definition derivative.h:329
FunctionDefaults holds default paramaters as static class members.
Definition funcdefaults.h:100
Abstract base class interface required for functors used as input to Functions.
Definition function_interface.h:68
void set_length_scale(double lo)
adapt the special level to resolve the smallest length scale
Definition function_interface.h:80
double thresh() const
Returns value of truncation threshold. No communication.
Definition mra.h:677
void set_thresh(double value, bool fence=true)
Sets the value of the truncation threshold. Optional global fence.
Definition mra.h:687
Function< T, NDIM > & truncate(double tol=0.0, bool fence=true)
Truncate the function with optional fence. Compresses with fence if not compressed.
Definition mra.h:712
const Function< T, NDIM > & compress(bool fence=true) const
Compresses the function, transforming into wavelet basis. Possible non-blocking comm.
Definition mra.h:858
A nuclear correlation factor class.
Definition correlationfactor.h:965
GaussSlater(World &world, const Molecule &mol)
ctor
Definition correlationfactor.h:971
double Srr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1032
double S(const double &r, const double &Z) const
the nuclear correlation factor
Definition correlationfactor.h:989
double U2X_spherical(const double &r, const double &Z, const double &rcut) const
derivative of the U2 potential wrt X (scalar part)
Definition correlationfactor.h:1063
double Srrr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1041
double Spp_div_S(const double &r, const double &Z) const
second derivative of the nuclear correlation factor
Definition correlationfactor.h:1009
corrfactype type() const
Definition correlationfactor.h:984
coord_3d Sp(const coord_3d &vr1A, const double &Z) const
radial part first derivative of the nuclear correlation factor
Definition correlationfactor.h:995
double Sr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1023
A nuclear correlation factor class.
Definition correlationfactor.h:1097
double Srr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1180
double S(const double &r, const double &Z) const
the nuclear correlation factor
Definition correlationfactor.h:1124
coord_3d Sp(const coord_3d &vr1A, const double &Z) const
radial part first derivative of the nuclear correlation factor
Definition correlationfactor.h:1130
double U2X_spherical(const double &r, const double &Z, const double &rcut) const
derivative of the U2 potential wrt nuclear coordinate X (spherical part)
Definition correlationfactor.h:1201
const double a
Definition correlationfactor.h:1121
double Srrr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1190
double Spp_div_S(const double &r, const double &Z) const
second derivative of the nuclear correlation factor
Definition correlationfactor.h:1144
double Sr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1170
GradientalGaussSlater(World &world, const Molecule &mol, const double a)
ctor
Definition correlationfactor.h:1103
corrfactype type() const
Definition correlationfactor.h:1117
A nuclear correlation factor class.
Definition correlationfactor.h:1241
LinearSlater(World &world, const Molecule &mol, const double a)
ctor
Definition correlationfactor.h:1247
double Srr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1316
coord_3d Sp(const coord_3d &vr1A, const double &Z) const
radial part first derivative of the nuclear correlation factor
Definition correlationfactor.h:1278
double S(const double &r, const double &Z) const
the nuclear correlation factor
Definition correlationfactor.h:1271
double Sr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1310
double a_param() const
Definition correlationfactor.h:1268
double a_
the length scale parameter a
Definition correlationfactor.h:1266
double Srrr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1322
corrfactype type() const
Definition correlationfactor.h:1261
double Spp_div_S(const double &r, const double &Z) const
second derivative of the nuclear correlation factor
Definition correlationfactor.h:1292
Definition molecule.h:129
double atomic_attraction_potential(int iatom, double x, double y, double z) const
nuclear attraction potential for a specific atom in the molecule
Definition molecule.cc:1112
double get_eprec() const
Definition molecule.h:489
double nuclear_attraction_potential_derivative(int atom, int axis, double x, double y, double z) const
Definition molecule.cc:1125
compute the derivative of R wrt the displacement of atom A, coord axis
Definition correlationfactor.h:752
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:753
const Atom & thisatom
Definition correlationfactor.h:754
const int derivativeaxis
Definition correlationfactor.h:755
RX_functor(const NuclearCorrelationFactor *ncf, const Atom &atom1, const int daxis, const int exponent)
1 or 2 -> R^X or R^X R
Definition correlationfactor.h:759
std::vector< coord_3d > special_points() const
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:798
double operator()(const coord_3d &xyz) const
Definition correlationfactor.h:772
const int exponent
direction of the derivative operator
Definition correlationfactor.h:756
RX_functor(const NuclearCorrelationFactor *ncf, const int iatom, const int daxis, const int exponent)
Definition correlationfactor.h:765
Definition correlationfactor.h:443
R_functor(const NuclearCorrelationFactor *ncf, const int e=1)
Definition correlationfactor.h:447
std::vector< coord_3d > special_points() const
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:465
int exponent
Definition correlationfactor.h:445
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:444
double operator()(const coord_3d &xyz) const
Definition correlationfactor.h:449
compute the derivative of U1 wrt the displacement of atom A, coord axis
Definition correlationfactor.h:806
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:807
const int U1axis
Definition correlationfactor.h:809
U1X_functor(const NuclearCorrelationFactor *ncf, const int iatom, const int U1axis, const int daxis)
Definition correlationfactor.h:819
U1X_functor(const NuclearCorrelationFactor *ncf, const Atom &atom1, const int U1axis, const int daxis)
direction of the derivative operator
Definition correlationfactor.h:812
double operator()(const coord_3d &xyz) const
Definition correlationfactor.h:827
const Atom & thisatom
Definition correlationfactor.h:808
const int derivativeaxis
U1x/U1y/U1z potential?
Definition correlationfactor.h:810
std::vector< coord_3d > special_points() const
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:841
U1 functor for a specific atom.
Definition correlationfactor.h:506
double operator()(const coord_3d &xyz) const
Definition correlationfactor.h:516
const size_t iatom
Definition correlationfactor.h:509
U1_atomic_functor(const NuclearCorrelationFactor *ncf, const size_t atom, const int axis)
Definition correlationfactor.h:513
const int axis
Definition correlationfactor.h:510
std::vector< coord_3d > special_points() const
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:524
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:508
functor for a local U1 dot U1 potential
Definition correlationfactor.h:541
std::vector< coord_3d > special_points() const
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:571
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:543
U1_dot_U1_functor(const NuclearCorrelationFactor *ncf)
Definition correlationfactor.h:546
double operator()(const coord_3d &xyz) const
Definition correlationfactor.h:548
functor for the local part of the U1 potential – NOTE THE SIGN
Definition correlationfactor.h:473
double operator()(const coord_3d &xyz) const
Definition correlationfactor.h:482
std::vector< coord_3d > special_points() const
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:494
const int axis
Definition correlationfactor.h:476
U1_functor(const NuclearCorrelationFactor *ncf, const int axis)
Definition correlationfactor.h:479
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:475
compute the derivative of U2 wrt the displacement of atom A
Definition correlationfactor.h:853
const int iatom
Definition correlationfactor.h:855
const int axis
Definition correlationfactor.h:856
std::vector< coord_3d > special_points() const
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:878
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:854
U2X_functor(const NuclearCorrelationFactor *ncf, const int &atom1, const int axis)
Definition correlationfactor.h:858
double operator()(const coord_3d &xyz) const
Definition correlationfactor.h:865
U2 functor for a specific atom.
Definition correlationfactor.h:627
const size_t iatom
Definition correlationfactor.h:630
double operator()(const coord_3d &xyz) const
Definition correlationfactor.h:636
std::vector< coord_3d > special_points() const
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:643
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:629
U2_atomic_functor(const NuclearCorrelationFactor *ncf, const size_t atom)
Definition correlationfactor.h:633
Definition correlationfactor.h:577
std::vector< coord_3d > special_points() const
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:591
double operator()(const coord_3d &xyz) const
Definition correlationfactor.h:581
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:578
U2_functor(const NuclearCorrelationFactor *ncf)
Definition correlationfactor.h:580
compute the derivative of U3 wrt the displacement of atom A, coord axis
Definition correlationfactor.h:901
U3X_functor(const NuclearCorrelationFactor *ncf, const size_t iatom, const int axis)
Definition correlationfactor.h:906
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:902
const int axis
Definition correlationfactor.h:904
const size_t iatom
Definition correlationfactor.h:903
double operator()(const coord_3d &xyz) const
Definition correlationfactor.h:909
std::vector< coord_3d > special_points() const
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:951
U3 functor for a specific atom.
Definition correlationfactor.h:654
const size_t iatom
Definition correlationfactor.h:657
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:656
double operator()(const coord_3d &xyz) const
Definition correlationfactor.h:663
std::vector< coord_3d > special_points() const
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:687
U3_atomic_functor(const NuclearCorrelationFactor *ncf, const int atom)
Definition correlationfactor.h:660
Definition correlationfactor.h:596
std::vector< coord_3d > special_points() const
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:621
double operator()(const coord_3d &xyz) const
Definition correlationfactor.h:600
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:597
U3_functor(const NuclearCorrelationFactor *ncf)
Definition correlationfactor.h:599
double operator()(const coord_3d &xyz) const
Definition correlationfactor.h:733
const Molecule & molecule
Definition correlationfactor.h:726
const size_t iatom
Definition correlationfactor.h:727
std::vector< coord_3d > special_points() const
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:746
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:725
square_times_V_derivative_functor(const NuclearCorrelationFactor *ncf, const Molecule &molecule1, const size_t atom1, const int axis1)
Definition correlationfactor.h:730
std::vector< coord_3d > special_points() const
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:718
const size_t iatom
Definition correlationfactor.h:700
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:698
square_times_V_functor(const NuclearCorrelationFactor *ncf, const Molecule &mol, const size_t iatom1)
Definition correlationfactor.h:702
const Molecule & molecule
Definition correlationfactor.h:699
double operator()(const coord_3d &xyz) const
Definition correlationfactor.h:705
ABC for the nuclear correlation factors.
Definition correlationfactor.h:83
double eprec
smoothing of the potential/step function
Definition correlationfactor.h:220
std::shared_ptr< FunctionFunctorInterface< double, 3 > > functorT
Definition correlationfactor.h:87
virtual const real_function_3d U2() const
return the U2 term of the correlation function
Definition correlationfactor.h:209
virtual real_function_3d square() const
return the square of the nuclear correlation factor
Definition correlationfactor.h:168
double vtol
the threshold for initial projection
Definition correlationfactor.h:217
virtual double Srrr_div_S(const double &r, const double &Z) const =0
virtual real_function_3d function() const
return the nuclear correlation factor
Definition correlationfactor.h:160
coord_3d smoothed_unitvec(const coord_3d &xyz, double smoothing=0.0) const
smoothed unit vector for the computation of the U1 potential
Definition correlationfactor.h:325
const Molecule & molecule
the molecule
Definition correlationfactor.h:223
virtual real_function_3d apply_U(const real_function_3d &rhs) const
apply the regularized potential U_nuc on a given function rhs
Definition correlationfactor.h:142
virtual real_function_3d inverse() const
return the inverse nuclear correlation factor
Definition correlationfactor.h:187
virtual double Spp_div_S(const double &r, const double &Z) const =0
the regularized potential wrt a given atom wrt the cartesian coordinate
World & world
the world
Definition correlationfactor.h:214
real_function_3d U2_function
the purely local U2 potential, having absorbed the nuclear pot V_nuc
Definition correlationfactor.h:230
virtual ~NuclearCorrelationFactor()
virtual destructor
Definition correlationfactor.h:98
virtual double U2X_spherical(const double &r, const double &Z, const double &rcut) const
derivative of the U2 potential wrt nuclear coordinate X (spherical part)
Definition correlationfactor.h:303
virtual double S(const double &r, const double &Z) const =0
the correlation factor S wrt a given atom
virtual real_function_3d square_times_V_derivative(const int iatom, const int axis) const
Definition correlationfactor.h:179
void initialize(const double vtol1)
initialize the regularized potentials U1 and U2
Definition correlationfactor.h:101
virtual coord_3d Sp(const coord_3d &vr1A, const double &Z) const =0
the partial derivative of correlation factor S' wrt the cartesian coordinates
virtual const real_function_3d U1(const int axis) const
return the U1 term of the correlation function
Definition correlationfactor.h:195
NuclearCorrelationFactor(World &world, const Molecule &mol)
ctor
Definition correlationfactor.h:93
std::vector< real_function_3d > U1_function
the three components of the U1 potential
Definition correlationfactor.h:227
virtual corrfactype type() const =0
std::vector< real_function_3d > U1vec() const
return the U1 functions in a vector
Definition correlationfactor.h:200
coord_3d dsmoothed_unitvec(const coord_3d &xyz, const int axis, double smoothing=0.0) const
derivative of smoothed unit vector wrt the electronic coordinate
Definition correlationfactor.h:386
virtual double Srr_div_S(const double &r, const double &Z) const =0
corrfactype
Definition correlationfactor.h:85
@ Two
Definition correlationfactor.h:86
@ LinearSlater
Definition correlationfactor.h:85
@ GradientalGaussSlater
Definition correlationfactor.h:85
@ poly4erfc
Definition correlationfactor.h:86
@ Slater
Definition correlationfactor.h:86
@ Adhoc
Definition correlationfactor.h:86
@ GaussSlater
Definition correlationfactor.h:85
@ None
Definition correlationfactor.h:85
@ Polynomial
Definition correlationfactor.h:86
virtual double Sr_div_S(const double &r, const double &Z) const =0
A nuclear correlation factor class.
Definition correlationfactor.h:1790
double a_
length scale parameter a, default chosen that linear terms in U2 vanish
Definition correlationfactor.h:1819
Polynomial(World &world, const Molecule &mol, const double a)
ctor
Definition correlationfactor.h:1796
coord_3d Sp(const coord_3d &vr1A, const double &Z) const
radial part first derivative of the nuclear correlation factor
Definition correlationfactor.h:1843
double Spp_div_S(const double &r, const double &Z) const
second derivative of the nuclear correlation factor
Definition correlationfactor.h:1859
double S(const double &r, const double &Z) const
the nuclear correlation factor
Definition correlationfactor.h:1827
double Srrr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1917
double U2X_spherical(const double &r, const double &Z, const double &rcut) const
derivative of the U2 potential wrt nuclear coordinate X (spherical part)
Definition correlationfactor.h:1931
corrfactype type() const
Definition correlationfactor.h:1814
double a_param() const
Definition correlationfactor.h:1821
double Srr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1903
static double b_param(const double &a)
the cutoff
Definition correlationfactor.h:1824
double Sr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1887
Definition correlationfactor.h:1963
double Srrr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:2020
double eprec
Definition correlationfactor.h:2011
corrfactype type() const
Definition correlationfactor.h:1985
std::shared_ptr< PotentialManager > potentialmanager
underlying potential (=molecule)
Definition correlationfactor.h:2010
real_function_3d apply_U(const real_function_3d &rhs) const
apply the regularized potential U_nuc on a given function rhs
Definition correlationfactor.h:2002
double Srr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:2018
const double fac
the factor of the correlation factor: R=fac;
Definition correlationfactor.h:2014
double U2X_spherical(const double &r, const double &Z, const double &rcut) const
derivative of the U2 potential wrt nuclear coordinate X (spherical part)
Definition correlationfactor.h:2038
double S(const double &r, const double &Z) const
the nuclear correlation factor
Definition correlationfactor.h:2023
double Sr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:2016
coord_3d Sp(const coord_3d &vr1A, const double &Z) const
radial part first derivative of the nuclear correlation factor
Definition correlationfactor.h:2028
PseudoNuclearCorrelationFactor(World &world, const Molecule &mol, const std::shared_ptr< PotentialManager > pot, const double fac)
ctor
Definition correlationfactor.h:1970
double Spp_div_S(const double &r, const double &Z) const
second derivative of the nuclear correlation factor
Definition correlationfactor.h:2033
const real_function_3d U2() const
return the U2 term of the correlation function
Definition correlationfactor.h:1991
A nuclear correlation factor class.
Definition correlationfactor.h:1332
double eprec_param() const
Definition correlationfactor.h:1362
corrfactype type() const
Definition correlationfactor.h:1353
double a_param() const
Definition correlationfactor.h:1361
double Srr_div_S(const double &r, const double &Z) const
second derivative of the correlation factor wrt (r-R_A)
Definition correlationfactor.h:1379
coord_3d Sp(const coord_3d &vr1A, const double &Z) const
radial part first derivative of the nuclear correlation factor
Definition correlationfactor.h:1408
double Spp_div_S(const double &r, const double &Z) const
second derivative of the nuclear correlation factor
Definition correlationfactor.h:1415
Slater(World &world, const Molecule &mol, const double a)
ctor
Definition correlationfactor.h:1338
double eprec_
Definition correlationfactor.h:1359
double Sr_div_S(const double &r, const double &Z) const
first derivative of the correlation factor wrt (r-R_A)
Definition correlationfactor.h:1369
double Srrr_div_S(const double &r, const double &Z) const
third derivative of the correlation factor wrt (r-R_A)
Definition correlationfactor.h:1390
double U2X_spherical(const double &r, const double &Z, const double &rcut) const
derivative of the U2 potential wrt X (scalar part)
Definition correlationfactor.h:1445
double S(const double &r, const double &Z) const
the nuclear correlation factor
Definition correlationfactor.h:1397
double a_
the length scale parameter
Definition correlationfactor.h:1358
constexpr T normf() const
Calculate the 2-norm of the vector elements.
Definition vector.h:421
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
Definition correlationfactor.h:1476
double Srrr_div_S(const double &r, const double &Z) const
third derivative of the correlation factor wrt (r-R_A)
Definition correlationfactor.h:1647
double a
the length scale parameter
Definition correlationfactor.h:1523
double Spp_div_S(const double &r, const double &Z) const
second derivative of the nuclear correlation factor
Definition correlationfactor.h:1667
poly4erfc(World &world, const Molecule &mol, const double aa)
ctor
Definition correlationfactor.h:1482
double a0
Definition correlationfactor.h:1524
double eprec_
Definition correlationfactor.h:1525
coord_3d Sp(const coord_3d &vr1A, const double &Z) const
radial part first derivative of the nuclear correlation factor
Definition correlationfactor.h:1661
corrfactype type() const
Definition correlationfactor.h:1518
double U2X_spherical(const double &r, const double &Z, const double &rcut) const
derivative of the U2 potential wrt X (scalar part)
Definition correlationfactor.h:1776
double a_param() const
Definition correlationfactor.h:1527
double eprec_param() const
Definition correlationfactor.h:1528
double Srr_div_S(const double &r, const double &Z) const
second derivative of the correlation factor wrt (r-R_A)
Definition correlationfactor.h:1637
double Sr_div_S(const double &r, const double &Z) const
first derivative of the correlation factor wrt (r-R_A)
Definition correlationfactor.h:1535
double S(const double &r, const double &Z) const
the nuclear correlation factor
Definition correlationfactor.h:1653
char * p(char *buf, const char *name, int k, int initial_level, double thresh, int order)
Definition derivatives.cc:72
static double lo
Definition dirac-hatom.cc:23
Tensor< typename Tensor< T >::scalar_type > arg(const Tensor< T > &t)
Return a new tensor holding the argument of each element of t (complex types only)
Definition tensor.h:2643
static const double rcut
Definition hatom_sf_dirac.cc:19
static const double eprec
Definition hatom_sf_dirac.cc:18
static double Z2(const coord_3d &r)
Definition helium_mp2.cc:124
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition madness_exception.h:119
#define MADNESS_ASSERT(condition)
Assert a condition that should be free of side-effects since in release builds this might be a no-op.
Definition madness_exception.h:134
void print(const tensorT &t)
Definition mcpfit.cc:140
static double dsmoothed_potential(double r)
Derivative of the regularized 1/r potential.
Definition mentity.cc:223
static double smoothed_potential(double r)
Regularized 1/r potential.
Definition mentity.cc:206
static double smoothing_parameter(double Z, double eprec)
Returns radius for smoothing nuclear potential with energy precision eprec.
Definition mentity.cc:192
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 DFParameters.h:10
std::shared_ptr< NuclearCorrelationFactor > create_nuclear_correlation_factor(World &world, const Molecule &molecule, const std::shared_ptr< PotentialManager > potentialmanager, const std::string inputline)
create and return a new nuclear correlation factor
Definition correlationfactor.cc:45
int power< 4 >(int base)
Definition power.h:68
static double r2(const coord_3d &x)
Definition smooth.h:45
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:335
Function< TENSOR_RESULT_TYPE(T, R), NDIM > dot(World &world, const std::vector< Function< T, NDIM > > &a, const std::vector< Function< R, NDIM > > &b, bool fence=true, bool do_make_redundant=true, double tol=0.0)
Multiplies and sums two vectors of functions r = \sum_i a[i] * b[i].
Definition vmra.h:1645
int power< 5 >(int base)
Definition power.h:73
std::shared_ptr< FunctionFunctorInterface< double, 3 > > func(new opT(g))
constexpr Vector< T, N > unitvec(const Vector< T, N > &r, const double eps=1.e-6)
Construct a unit-Vector that has the same direction as r.
Definition vector.h:768
FunctionFactory< double, 3 > real_factory_3d
Definition functypedefs.h:108
void print(const T &t, const Ts &... ts)
Print items to std::cout (items separated by spaces) and terminate with a new line.
Definition print.h:227
NDIM const Function< R, NDIM > & g
Definition mra.h:2622
int power< 2 >(int base)
Definition power.h:58
int power< 3 >(int base)
Definition power.h:63
Function< T, CCPairFunction< T, NDIM >::LDIM > inner(const CCPairFunction< T, NDIM > &c, const Function< T, CCPairFunction< T, NDIM >::LDIM > &f, const std::tuple< int, int, int > v1, const std::tuple< int, int, int > v2)
Definition ccpairfunction.h:993
Vector< double, 3 > coord_3d
Definition funcplot.h:1042
static XNonlinearSolver< std::vector< Function< T, NDIM > >, T, vector_function_allocator< T, NDIM > > nonlinear_vector_solver(World &world, const long nvec)
Definition nonlinsol.h:371
int power< 6 >(int base)
Definition power.h:78
static const double b
Definition nonlinschro.cc:119
static const double a
Definition nonlinschro.cc:118
Declaration of molecule-related classes and functions.
static const double c
Definition relops.cc:10
static double Z
Definition rk.cc:35
static const double thresh
Definition rk.cc:45
const double xi
Exponent for delta function approx.
Definition siam_example.cc:60
Definition test_ar.cc:204
Definition dirac-hatom.cc:112
static double V(const coordT &r)
Definition tdse.cc:288
void e()
Definition test_sig.cc:75
double aa
Definition testbsh.cc:68
#define N
Definition testconv.cc:37
std::size_t axis
Definition testpdiff.cc:59
const double a2
Definition vnucso.cc:86
const double R2
Definition vnucso.cc:84
const double a1
Definition vnucso.cc:85