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
451
452 double operator()(const coord_3d& xyz) const override {
453 double result=1.0;
454 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
455 const Atom& atom=ncf->molecule.get_atom(i);
456 const coord_3d vr1A=xyz-atom.get_coords();
457 const double r=vr1A.normf();
458 result*=ncf->S(r,atom.q);
459 }
460 if (exponent==-1) return 1.0/result;
461 else if (exponent==2) return result*result;
462 else if (exponent==1) return result;
463 else {
464 return std::pow(result,double(exponent));
465 }
466
467 }
468 std::vector<coord_3d> special_points() const override {
469 return ncf->molecule.get_all_coords_vec();
470 }
471 };
472
473 /// functor for the local part of the U1 potential -- NOTE THE SIGN
474
475 /// U1 = -S'/S
476 class U1_functor : public FunctionFunctorInterface<double,3> {
477
479 const int axis;
480
481 public:
483 : ncf(ncf), axis(axis) {}
484
485
487
488 double operator()(const coord_3d& xyz) const override {
489 double result=0.0;
490 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
491 const Atom& atom=ncf->molecule.get_atom(i);
492 const coord_3d vr1A=xyz-atom.get_coords();
493 const double r=vr1A.normf();
494 const double& Z=atom.q;
495// result-=(ncf->Sp(vr1A,Z)[axis]/ncf->S(r,Z));
496 result-=ncf->Sr_div_S(r,Z)*ncf->smoothed_unitvec(vr1A)[axis];
497 }
498 return result;
499 }
500 std::vector<coord_3d> special_points() const override {
501 return ncf->molecule.get_all_coords_vec();
502 }
503 };
504
505 /// U1 functor for a specific atom
506
507 /// NOTE THE SIGN !!
508 /// this is
509 /// \f[
510 /// -\frac{\partial \rho}{\partial X_A}\frac{\partial S}{\partial \rho}\frac{1}{S}
511 /// \f]
513
515 const size_t iatom;
516 const int axis;
517
518 public:
520 const int axis) : ncf(ncf), iatom(atom), axis(axis) {}
522 double operator()(const coord_3d& xyz) const override {
523 const Atom& atom=ncf->molecule.get_atom(iatom);
524 const coord_3d vr1A=xyz-atom.get_coords();
525 const double r=vr1A.normf();
526 const double& Z=atom.q;
527 return ncf->Sr_div_S(r,Z)*ncf->smoothed_unitvec(vr1A)[axis];
528 }
529
530 std::vector<coord_3d> special_points() const override {
531 std::vector< madness::Vector<double,3> > c(1);
532 const Atom& atom=ncf->molecule.get_atom(iatom);
533 c[0][0]=atom.x;
534 c[0][1]=atom.y;
535 c[0][2]=atom.z;
536 return c;
537 }
538 };
539
540
541 /// functor for a local U1 dot U1 potential
542
543 /// \f[
544 /// U1\dot U1 = \frac{\left(S^r_A S^r_B\right)}{S_A S_B} n_A \cdot n_B
545 /// \f]
546 /// with positive sign!
548
550
551 public:
553
555 double operator()(const coord_3d& xyz) const override {
556 std::vector<double> Sr_div_S(ncf->molecule.natom());
557 std::vector<coord_3d> unitvec(ncf->molecule.natom());
558 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
559 const Atom& atom=ncf->molecule.get_atom(i);
560 const coord_3d vr1A=xyz-atom.get_coords();
561 const double r=vr1A.normf();
562 Sr_div_S[i]=ncf->Sr_div_S(r,atom.q);
563 unitvec[i]=ncf->smoothed_unitvec(vr1A);
564 }
565
566 double result=0.0;
567 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
568 for (size_t j=0; j<ncf->molecule.natom(); ++j) {
569 double tmp=Sr_div_S[i]*Sr_div_S[j];
570 if (i!=j) tmp*=inner(unitvec[i],unitvec[j]);
571 result+=tmp;
572 }
573 }
574
575
576 return result;
577 }
578 std::vector<coord_3d> special_points() const override {
579 return ncf->molecule.get_all_coords_vec();
580 }
581 };
582
583
584 class U2_functor : public FunctionFunctorInterface<double,3> {
586 public:
588
590 double operator()(const coord_3d& xyz) const override {
591 double result=0.0;
592 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
593 const Atom& atom=ncf->molecule.get_atom(i);
594 const coord_3d vr1A=xyz-atom.get_coords();
595 const double r=vr1A.normf();
596 result+=ncf->Spp_div_S(r,atom.q);
597 }
598 return result;
599 }
600 std::vector<coord_3d> special_points() const override {
601 return ncf->molecule.get_all_coords_vec();
602 }
603 };
604
605 class U3_functor : public FunctionFunctorInterface<double,3> {
607 public:
609
611 double operator()(const coord_3d& xyz) const override {
612 std::vector<coord_3d> all_terms(ncf->molecule.natom());
613 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
614 const Atom& atom=ncf->molecule.get_atom(i);
615 const coord_3d vr1A=xyz-atom.get_coords();
616 const double r=vr1A.normf();
617// all_terms[i]=ncf->Sp(vr1A,atom.q)*(1.0/ncf->S(r,atom.q));
618 all_terms[i]=ncf->Sr_div_S(r,atom.q)*ncf->smoothed_unitvec(vr1A);
619 }
620
621 double result=0.0;
622 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
623 for (size_t j=0; j<i; ++j) {
624 result+=all_terms[i][0]*all_terms[j][0]
625 +all_terms[i][1]*all_terms[j][1]
626 +all_terms[i][2]*all_terms[j][2];
627 }
628 }
629
630 return -1.0*result;
631 }
632 std::vector<coord_3d> special_points() const override {
633 return ncf->molecule.get_all_coords_vec();
634 }
635 };
636
637 /// U2 functor for a specific atom
639
641 const size_t iatom;
642
643 public:
645 : ncf(ncf), iatom(atom) {}
646
648 double operator()(const coord_3d& xyz) const override {
649 const Atom& atom=ncf->molecule.get_atom(iatom);
650 const coord_3d vr1A=xyz-atom.get_coords();
651 const double r=vr1A.normf();
652 return ncf->Spp_div_S(r,atom.q);
653 }
654
655 std::vector<coord_3d> special_points() const override {
656 std::vector< madness::Vector<double,3> > c(1);
657 const Atom& atom=ncf->molecule.get_atom(iatom);
658 c[0][0]=atom.x;
659 c[0][1]=atom.y;
660 c[0][2]=atom.z;
661 return c;
662 }
663 };
664
665 /// U3 functor for a specific atom
667
669 const size_t iatom;
670
671 public:
673 : ncf(ncf), iatom(atom) {}
674
676 double operator()(const coord_3d& xyz) const override {
677 const Atom& atomA=ncf->molecule.get_atom(iatom);
678 const coord_3d vr1A=xyz-atomA.get_coords();
679 const double rA=vr1A.normf();
680 const coord_3d nA=ncf->smoothed_unitvec(vr1A);
681 double Sr_div_SA=ncf->Sr_div_S(rA,atomA.q);
682
683 double result=0.0;
684 // sum over B
685 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
686 if (i==iatom) continue; // restricted sum
687
688 const Atom& atomB=ncf->molecule.get_atom(i);
689 const coord_3d vr1B=xyz-atomB.get_coords();
690 const double rB=vr1B.normf();
691 const coord_3d nB=ncf->smoothed_unitvec(vr1B);
692 double Sr_div_SB=ncf->Sr_div_S(rB,atomB.q);
693
694 double dot=nA[0]*nB[0] + nA[1]*nB[1] + nA[2]*nB[2];
695 result+=Sr_div_SB*Sr_div_SA*dot;
696 }
697 return -0.5*result;
698 }
699
700 std::vector<coord_3d> special_points() const override {
701 std::vector< madness::Vector<double,3> > c(1);
702 const Atom& atom=ncf->molecule.get_atom(iatom);
703 c[0][0]=atom.x;
704 c[0][1]=atom.y;
705 c[0][2]=atom.z;
706 return c;
707 }
708 };
709
713 const size_t iatom;
714 public:
716 const Molecule& mol, const size_t iatom1)
717 : ncf(ncf), molecule(mol), iatom(iatom1) {}
718
720 double operator()(const coord_3d& xyz) const override {
721 double result=1.0;
722 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
723 const Atom& atom=ncf->molecule.get_atom(i);
724 const coord_3d vr1A=xyz-atom.get_coords();
725 const double r=vr1A.normf();
726 result*=ncf->S(r,atom.q);
727 }
729 iatom, xyz[0], xyz[1], xyz[2]);
730 return result*result*V;
731
732 }
733 std::vector<coord_3d> special_points() const override {
734 return ncf->molecule.get_all_coords_vec();
735 }
736 };
737
738
742 const size_t iatom;
743 const int axis;
744 public:
748
750 double operator()(const coord_3d& xyz) const override {
751 double result=1.0;
752 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
753 const Atom& atom=ncf->molecule.get_atom(i);
754 const coord_3d vr1A=xyz-atom.get_coords();
755 const double r=vr1A.normf();
756 result*=ncf->S(r,atom.q);
757 }
759 iatom, axis, xyz[0], xyz[1], xyz[2]);
760 return result*result*Vprime;
761
762 }
763 std::vector<coord_3d> special_points() const override {
764 return ncf->molecule.get_all_coords_vec();
765 }
766 };
767
768 /// compute the derivative of R wrt the displacement of atom A, coord axis
769 class RX_functor : public FunctionFunctorInterface<double,3> {
772 const int derivativeaxis; /// direction of the derivative operator
773 const int exponent; /// 1 or 2 -> R^X or R^X R
774
775 public:
777 const int daxis, const int exponent) : ncf(ncf), thisatom(atom1),
779 MADNESS_ASSERT((exponent==1) or (exponent==2) or (exponent==-1));
780 }
781
782 RX_functor(const NuclearCorrelationFactor* ncf, const int iatom,
783 const int daxis, const int exponent) : ncf(ncf),
784 thisatom(ncf->molecule.get_atom(iatom)),
786 MADNESS_ASSERT((exponent==1) or (exponent==2) or (exponent==-1));
787 }
788
790 double operator()(const coord_3d& xyz) const override {
791
792 // compute the R term
793 double result=1.0;
794 if ((exponent==1) or (exponent==2)) {
795 for (size_t i=0; i<ncf->molecule.natom(); ++i) {
796 const Atom& atom=ncf->molecule.get_atom(i);
797 const coord_3d vr1A=xyz-atom.get_coords();
798 const double r=vr1A.normf();
799 result*=ncf->S(r,atom.q);
800 }
801 if (exponent==2) result=result*result;
802 }
803
804 // compute the derivative term
805 {
807 const double r=vr1A.normf();
808 const double& Z=thisatom.q;
809 const double S1=-ncf->Sr_div_S(r,Z) // note the sign
810 *ncf->smoothed_unitvec(vr1A)[derivativeaxis];
811 result*=S1;
812 }
813 return result;
814 }
815
816 std::vector<coord_3d> special_points() const override {
817 return ncf->molecule.get_all_coords_vec();
818 }
819
820 };
821
822
823 /// compute the derivative of U1 wrt the displacement of atom A, coord axis
824 class U1X_functor : public FunctionFunctorInterface<double,3> {
827 const int U1axis; /// U1x/U1y/U1z potential?
828 const int derivativeaxis; /// direction of the derivative operator
829 public:
831 const int U1axis, const int daxis) : ncf(ncf), thisatom(atom1),
833 double lo=1.0/thisatom.q;
835 }
836
837 U1X_functor(const NuclearCorrelationFactor* ncf, const int iatom,
838 const int U1axis, const int daxis) : ncf(ncf),
839 thisatom(ncf->molecule.get_atom(iatom)),
841 double lo=1.0/thisatom.q;
843 }
844
846
847 double operator()(const coord_3d& xyz) const override {
849 const double r=vr1A.normf();
850 const double& Z=thisatom.q;
851 const double S1=ncf->Sr_div_S(r,Z);
852 const double S2=ncf->Srr_div_S(r,Z);
853
854 // note the sign change smoothed_unitvec due to the
855 // change in the derivative variable x: electronic -> nuclear
856 const double drhodx=-ncf->smoothed_unitvec(vr1A)[derivativeaxis];
857 return drhodx*(S2-S1*S1)*ncf->smoothed_unitvec(vr1A)[U1axis]
858 -S1*(ncf->dsmoothed_unitvec(vr1A,derivativeaxis)[U1axis]);
859 }
860
861 std::vector<coord_3d> special_points() const override {
862 std::vector< madness::Vector<double,3> > c(1);
863 c[0][0]=thisatom.x;
864 c[0][1]=thisatom.y;
865 c[0][2]=thisatom.z;
866 return c;
867 }
868
869 };
870
871
872 /// compute the derivative of U2 wrt the displacement of atom A
873 class U2X_functor : public FunctionFunctorInterface<double,3> {
875 const int iatom;
876 const int axis;
877 public:
879 const int axis) : ncf(ncf), iatom(atom1), axis(axis) {
880 const Atom& atom=ncf->molecule.get_atom(iatom);
881 double lo=1.0/atom.q;
883 }
884
886 double operator()(const coord_3d& xyz) const override {
887 const Atom& atom=ncf->molecule.get_atom(iatom);
888 const coord_3d vr1A=xyz-atom.get_coords();
889 const double r=vr1A.normf();
890 const double& Z=atom.q;
891 const double rcut=ncf->molecule.get_rcut()[iatom];
892
893 // note the sign change due to the change in the derivative
894 // variable x: electronic -> nuclear in drho/dx
895 const double drhodx=-ncf->smoothed_unitvec(vr1A)[axis];
896 return drhodx*ncf->U2X_spherical(r,Z,rcut);
897 }
898
899 std::vector<coord_3d> special_points() const override {
900 std::vector< madness::Vector<double,3> > c(1);
901 const Atom& atom=ncf->molecule.get_atom(iatom);
902 c[0][0]=atom.x;
903 c[0][1]=atom.y;
904 c[0][2]=atom.z;
905 return c;
906 }
907 };
908
909
910 /// compute the derivative of U3 wrt the displacement of atom A, coord axis
911
912 /// \f[
913 /// 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)
914 /// \f]
915 /// with
916 /// \f[
917 /// \left(\frac{\vec S_A'}{S_A}\right)^X =
918 /// \frac{\partial \rho}{\partial X}\left(\frac{S''_A}{S_A}
919 /// -\left(\frac{S'_A}{S_A}\right)^2\right)\vec n_{1A}
920 /// + \left(\frac{S'_A}{S_A}\right)\frac{\partial \vec n_{1A}}{\partial X}
921 /// \f]
922 class U3X_functor : public FunctionFunctorInterface<double,3> {
924 const size_t iatom;
925 const int axis;
926 public:
928 const int axis) : ncf(ncf), iatom(iatom), axis(axis) {}
929
931 double operator()(const coord_3d& xyz) const override {
932 const Atom& atomA=ncf->molecule.get_atom(iatom);
933 const coord_3d vr1A=xyz-atomA.get_coords();
934 const double r1A=vr1A.normf();
935 const double& ZA=atomA.q;
936
937 double S1A=ncf->Sr_div_S(r1A,ZA);
938 double S2A=ncf->Srr_div_S(r1A,ZA);
939 double termA=S2A-S1A*S1A;
940
941 // unit vector \vec n_A = \vec r_{1A}/r_{1A}
942 const coord_3d nA=ncf->smoothed_unitvec(vr1A);
943 // derivative of the unit vector \frac{\partial \vec n_A}{\partial X}
944 const coord_3d dnA=ncf->dsmoothed_unitvec(vr1A,axis)*(-1.0);
945 // \frac{\partial \rho}{\partial X}
946 const double drhodx=-nA[axis];
947
948 double term=0.0;
949 for (size_t jatom=0; jatom<ncf->molecule.natom(); ++jatom) {
950 if (iatom==jatom) continue; // restricted sum B \neq A
951
952 const Atom& atomB=ncf->molecule.get_atom(jatom);
953 const coord_3d vr1B=xyz-atomB.get_coords();
954 const double r1B=vr1B.normf();
955 const double& ZB=atomB.q;
956
957 double S1B=ncf->Sr_div_S(r1B,ZB);
958 const coord_3d nB=ncf->smoothed_unitvec(vr1B);
959
960 double dot=0.0; // n_A.n_B
961 double ddot=0.0; // n'_A.n_B
962 for (int i=0; i<3; ++i) {
963 ddot+=dnA[i]*nB[i];
964 dot+=nA[i]*nB[i];
965 }
967
968 }
969
970 return term;
971 }
972
973 std::vector<coord_3d> special_points() const override {
974 return ncf->molecule.get_all_coords_vec();
975 }
976 };
977
978};
979
980
981/// A nuclear correlation factor class
982
983/// The nuclear correlation factor is given by
984/// \[f
985/// R = \prod S_A ; S_A=exp(-Z_A r_{1A}) + ( 1 - exp(-r_{1A}^2) )
986/// \]f
988public:
989 /// ctor
990
991 /// @param[in] world the world
992 /// @param[in] mol molecule with the sites of the nuclei
995
996 if (world.rank()==0) {
997 print("constructed nuclear correlation factor of the form");
998 print(" R = Prod_A S_A");
999 print(" S_A = exp(-Z_A r_{1A}) + (1 - exp(-Z_A^2*r_{1A}^2))");
1000 print("with eprec ",mol.get_eprec());
1001 print("which is of Gaussian-Slater type\n");
1002 }
1003
1004 }
1005
1007
1008private:
1009
1010 /// the nuclear correlation factor
1011 double S(const double& r, const double& Z) const {
1012 const double rho=r*Z;
1013 return exp(-rho)+(1.0-exp(-(rho*rho)));
1014 }
1015
1016 /// radial part first derivative of the nuclear correlation factor
1017 coord_3d Sp(const coord_3d& vr1A, const double& Z) const {
1018
1019 const double r=sqrt(vr1A[0]*vr1A[0] +
1020 vr1A[1]*vr1A[1] + vr1A[2]*vr1A[2]);
1021
1022 const double eA=exp(-Z*r);
1023 const double gA=exp(-Z*Z*r*r);
1025 return term;
1026 }
1027
1028 /// second derivative of the nuclear correlation factor
1029
1030 /// -1/2 S"/S - Z/r
1031 double Spp_div_S(const double& r, const double& Z) const {
1032 const double rho=Z*r;
1033 if (rho<1.e-4) {
1034 return Z*Z*(-3.5 - 4.0*rho + 6.0*rho*rho + 12.0*rho*rho*rho);
1035 } else {
1036 const double e=exp(-rho);
1037 const double g=exp(-rho*rho);
1038 const double term1=-Z/r*(1.0-g);
1039 const double term2=-g*Z*Z*(3.0-2.0*Z*Z*r*r) - Z*Z/2.0*e;
1040 const double S_inv=exp(-rho)+(1.0-exp(-(rho*rho)));
1041 return (term1+term2)/S_inv;
1042 }
1043 }
1044
1045 double Sr_div_S(const double& r, const double& Z) const {
1046 const double Zr=r*Z;
1047 const double eA=exp(-Zr);
1048 const double gA=exp(-Zr*Zr);
1049 const double num=Z*(2.0*Zr*gA-eA);
1050 const double denom=1.0+eA-gA;
1051 return num/denom;
1052 }
1053
1054 double Srr_div_S(const double& r, const double& Z) const {
1055 const double Zr=r*Z;
1056 const double eA=exp(-Zr);
1057 const double gA=exp(-Zr*Zr);
1058 const double num=Z*Z*(eA+gA*(2.0-4.0*Zr*Zr));
1059 const double denom=1.0+eA-gA;
1060 return num/denom;
1061 }
1062
1063 double Srrr_div_S(const double& r, const double& Z) const {
1064 const double Zr=r*Z;
1065 const double eA=exp(-Zr);
1066 const double gA=exp(-Zr*Zr);
1067 const double num=Z*Z*Z*(-eA - 12.0*gA*Zr + 8.0*gA*Zr*Zr*Zr);
1068 const double denom=1.0+eA-gA;
1069 return num/denom;
1070
1071 }
1072
1073 /// derivative of the U2 potential wrt X (scalar part)
1074
1075 /// with
1076 /// \f[
1077 /// \rho = \left| \vec r- \vec R_A \right|
1078 /// \f]
1079 /// returns the term in the parenthesis without the the derivative of rho
1080 /// \f[
1081 /// \frac{\partial U_2}{\partial X_A} = \frac{\partial \rho}{\partial X}
1082 /// \left(-\frac{1}{2}\frac{S''' S - S'' S'}{S^2} + \frac{1}{\rho^2}\frac{S'}{S}
1083 /// - \frac{1}{\rho} \frac{S''S - S'^2}{S^2} + \frac{Z_A}{\rho^2}\right)
1084 /// \f]
1085 double U2X_spherical(const double& r, const double& Z, const double& rcut) const {
1086
1087 double result=0.0;
1088 if (r*Z<1.e-4) {
1089 const double ZZ=Z*Z;
1090 const double ZZZ=ZZ*Z;
1091 const double Z4=ZZ*ZZ;
1092 const double r0=-4.0*ZZZ;
1093 const double r1=12.0*Z4;
1094 const double r2=36*Z4*Z;
1095 const double r3=-67.0/6.0*Z4*ZZ;
1096 result=(r0 + r*r1 + r*r*r2 + r*r*r*r3);
1097
1098 } else {
1099 const double S1=Sr_div_S(r,Z);
1100 const double S2=Srr_div_S(r,Z);
1101 const double S3=Srrr_div_S(r,Z);
1102 const double term1=-0.5*(S3-S1*S2);
1103 const double term2=(S1+Z)/(r*r);
1104 const double term3=(S2-S1*S1)/r;
1105 result=term1+term2-term3;
1106 }
1107 return result;
1108 }
1109
1110
1111};
1112
1113/// A nuclear correlation factor class
1114
1115/// The nuclear correlation factor is given by
1116/// \[f
1117/// R = \prod S_A ; S_A=exp(-Z_A r_{1A}) + ( 1 - exp(-r_{1A}^2) )
1118/// \]f
1120public:
1121 /// ctor
1122
1123 /// @param[in] world the world
1124 /// @param[in] mol molecule with the sites of the nuclei
1125 GradientalGaussSlater(World& world, const Molecule& mol, const double a)
1127
1128 if (world.rank()==0) {
1129 print("constructed nuclear correlation factor of the form");
1130 print(" R = Prod_A S_A");
1131 print(" S_A = 1/sqrt{Z} exp(-Z_A r_{1A}) + (1 - exp(-a^2*Z_A^2*r_{1A}^2))");
1132 print(" a = ",a);
1133 print("with eprec ",mol.get_eprec());
1134 print("which is of Gradiental Gaussian-Slater type\n");
1135 }
1136
1137 }
1138
1140
1141private:
1142
1143 const double a;
1144
1145 /// the nuclear correlation factor
1146 double S(const double& r, const double& Z) const {
1147 const double rho=r*Z;
1148 return 1/sqrt(Z) * exp(-rho)+(1.0-exp(-(a*a*rho*rho)));
1149 }
1150
1151 /// radial part first derivative of the nuclear correlation factor
1152 coord_3d Sp(const coord_3d& vr1A, const double& Z) const {
1153
1154 const double r=sqrt(vr1A[0]*vr1A[0] +
1155 vr1A[1]*vr1A[1] + vr1A[2]*vr1A[2]);
1156
1157 const double rho=Z*r;
1158 const double sqrtz=sqrt(Z);
1159 const double term=-exp(-rho)*sqrtz + 2.0*a*a*exp(-a*a*rho*rho)*Z*rho;
1160 return term*smoothed_unitvec(vr1A);
1161 }
1162
1163 /// second derivative of the nuclear correlation factor
1164
1165 /// -1/2 S"/S - Z/r
1166 double Spp_div_S(const double& r, const double& Z) const {
1167 const double rho=Z*r;
1168 const double sqrtz=sqrt(Z);
1169 if (rho<1.e-4) {
1170 const double zfivehalf=Z*Z*sqrtz;
1171 const double a2=a*a;
1172 const double a4=a2*a2;
1173 return -0.5*Z*Z
1174 - 3. *a2 * zfivehalf
1175 - 4.* a2 *rho* zfivehalf
1176 - 2. *a2 * rho*rho*zfivehalf
1177 + 5. *a4 *rho*rho*zfivehalf
1178 + 3. *a4 *rho*rho*Z*Z*Z
1179 -0.5 *a2 *rho*rho*rho*zfivehalf
1180 +5.5 *a4 *rho*rho*rho*zfivehalf
1181 +7. *a4 *rho*rho*rho*Z*Z*Z;
1182 } else {
1183 const double e=exp(-rho);
1184 const double g=exp(-a*a*rho*rho);
1185 const double poly=(2.0-6.0*a*a*rho + 4.0*a*a*a*a*rho*rho*rho);
1186 const double num=Z*(-2.0 - e*r*sqrtz + g*poly);
1187 const double denom=2.0*r*(1.0-g+e/sqrtz);
1188 return num/denom;
1189 }
1190 }
1191
1192 double Sr_div_S(const double& r, const double& Z) const {
1193 const double rZ=r*Z;
1194 const double e=exp(-rZ);
1195 const double g=exp(-a*a*rZ*rZ);
1196 const double sqrtz=sqrt(Z);
1197 const double num=-sqrtz*e + 2.0*a*a*g*Z*rZ;
1198 const double denom=1.0-g+e/sqrtz;
1199 return num/denom;
1200 }
1201
1202 double Srr_div_S(const double& r, const double& Z) const {
1203 const double rZ=r*Z;
1204 const double e=exp(-rZ);
1205 const double g=exp(-a*a*rZ*rZ);
1206 const double sqrtz=sqrt(Z);
1207 const double num=e*Z*sqrtz + g*(2.0*a*a - 4.0*power<4>(a)*rZ*rZ)*Z*Z;
1208 const double denom=1.0-g+e/sqrtz;
1209 return num/denom;
1210 }
1211
1212 double Srrr_div_S(const double& r, const double& Z) const {
1213 const double rZ=r*Z;
1214 const double e=exp(-rZ);
1215 const double g=exp(-a*a*rZ*rZ);
1216 const double sqrtz=sqrt(Z);
1217 const double num=e*power<3>(Z) + (12.0*power<4>(a)*g*rZ
1218 -8.0*power<6>(a)*g*power<3>(rZ))*sqrtz*power<3>(Z);
1219 const double denom=e+sqrtz-g*sqrtz;
1220 return -num/denom;
1221 }
1222
1223 double U2X_spherical(const double& r, const double& Z, const double& rcut) const {
1224
1225 double result=0.0;
1226 if (r*Z<1.e-4) {
1227 const double sqrtz=sqrt(Z);
1228 const double Z2=Z*Z;
1229 const double Z4=Z2*Z2;
1230 const double Z5=Z4*Z;
1231 const double Z6=Z5*Z;
1232 const double Z7=Z6*Z;
1233 const double a2=a*a;
1234 const double a4=a2*a2;
1235
1236 const double r0=-4.* a2* sqrt(Z7);
1237 const double r1=2.* (-2.* a2* Z*sqrt(Z7)+ 5.* a4* Z*sqrt(Z7) + 3.* a4 *Z5) *r;
1238 const double r2=1.5 * (-a2* sqrtz*Z5 + 11.* a4* sqrtz*Z5 + 14.*a4* Z6)* r*r;
1239 const double r3=1./6.* (-a2* sqrtz*Z6 + 66.* a4*sqrtz*Z6 - 84.* a2*a4* sqrtz*Z6 +
1240 180. *a4* Z7 - 156.*a2*a4* Z7 - 72.* a2*a4*sqrtz*Z7) *r*r*r;
1241 result=(r0 + r1 + r2 + r3);
1242
1243 } else {
1244 const double S1=Sr_div_S(r,Z);
1245 const double S2=Srr_div_S(r,Z);
1246 const double S3=Srrr_div_S(r,Z);
1247 const double term1=-0.5*(S3-S1*S2);
1248 const double term2=(S1+Z)/(r*r);
1249 const double term3=(S2-S1*S1)/r;
1250 result=term1+term2-term3;
1251 }
1252 return result;
1253 }
1254};
1255
1256
1257/// A nuclear correlation factor class
1258
1259/// The nuclear correlation factor is given by
1260/// \[f
1261/// R = \prod S_A ; S_A= -Z_A r_{1A} exp(-Z_A r_{1A}) + 1
1262/// \]f
1264public:
1265 /// ctor
1266
1267 /// @param[in] world the world
1268 /// @param[in] mol molecule with the sites of the nuclei
1269 LinearSlater(World& world, const Molecule& mol, const double a)
1270 : NuclearCorrelationFactor(world,mol), a_(1.0) {
1271
1272 if (a!=0.0) a_=a;
1273
1274 if (world.rank()==0) {
1275 print("constructed nuclear correlation factor of the form");
1276 print(" S_A = -Z_A r_{1A} exp(-Z_A r_{1A}) + 1");
1277 print(" a = ",a_);
1278 print("with eprec ",mol.get_eprec());
1279 print("which is of linear Slater type\n");
1280 }
1281 }
1282
1284
1285private:
1286
1287 /// the length scale parameter a
1288 double a_;
1289
1290 double a_param() const {return 1.0;}
1291
1292 /// the nuclear correlation factor
1293 double S(const double& r, const double& Z) const {
1294 const double rho=r*Z;
1295 const double b=a_param();
1296 return (-rho)*exp(-b*rho)+1.0;
1297 }
1298
1299 /// radial part first derivative of the nuclear correlation factor
1300 coord_3d Sp(const coord_3d& vr1A, const double& Z) const {
1301
1302 const double b=a_param();
1303 const double r=sqrt(vr1A[0]*vr1A[0] +
1304 vr1A[1]*vr1A[1] + vr1A[2]*vr1A[2]);
1305
1306 const double ebrz=exp(-b*r*Z);
1308 return term;
1309 }
1310
1311 /// second derivative of the nuclear correlation factor
1312
1313 /// -1/2 S"/S - Z/r
1314 double Spp_div_S(const double& r, const double& Z) const {
1315
1316 const double b=a_param();
1317 const double rho=Z*r;
1318 if (rho<1.e-4) {
1319 const double O0=1.0- 3.0* b;
1320 const double O1=Z - 4.0*b*Z + 3.0*b*b*Z;
1321 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;
1322 return Z*Z*(O0 + O1*r + O2*r*r);
1323
1324 } else {
1325 const double ebrz=exp(-b*rho);
1326 const double num=Z* (ebrz - 1.0 + 0.5*ebrz*rho* (2.0 + b*(b*rho-4.0)));
1327 const double denom=r*(rho*ebrz-1.0);
1328 return -num/denom;
1329 }
1330 }
1331
1332 double Sr_div_S(const double& r, const double& Z) const {
1333 const double& a=a_param();
1334 const double earz=exp(-a*r*Z);
1335 return Z*earz*(a*r*Z-1.0)/(1.0-r*Z*earz);
1336 }
1337
1338 double Srr_div_S(const double& r, const double& Z) const {
1339 const double& a=a_param();
1340 const double earz=exp(-a*r*Z);
1341 return a*Z*Z*earz*(a*r*Z-2.0)/(-1.0+r*Z*earz);
1342 }
1343
1344 double Srrr_div_S(const double& r, const double& Z) const {
1345 const double& a=a_param();
1346 const double earz=exp(-a*r*Z);
1347 return a*a*Z*Z*Z*earz*(a*r*Z-3.0)/(1.0-r*Z*earz);
1348 }
1349
1350};
1351
1352
1353/// A nuclear correlation factor class
1355public:
1356 /// ctor
1357
1358 /// @param[in] world the world
1359 /// @param[in] mol molecule with the sites of the nuclei
1360 Slater(World& world, const Molecule& mol, const double a)
1361 : NuclearCorrelationFactor(world,mol), a_(1.5) {
1362
1363 if (a!=0.0) a_=a;
1364 eprec_=mol.get_eprec();
1365
1366 if (world.rank()==0) {
1367 print("\nconstructed nuclear correlation factor of the form");
1368 print(" S_A = 1/(a-1) exp(-a Z_A r_{1A}) + 1");
1369 print(" a = ",a_);
1370 print("with eprec ",eprec_);
1371 print("which is of Slater type\n");
1372 }
1373 }
1374
1376
1377private:
1378
1379 /// the length scale parameter
1380 double a_;
1381 double eprec_;
1382
1383 double a_param() const {return a_;}
1384 double eprec_param() const {return eprec_;}
1385
1386 /// first derivative of the correlation factor wrt (r-R_A)
1387
1388 /// \f[
1389 /// Sr_div_S = \frac{1}{S(r)}\frac{\partial S(r)}{\partial r}
1390 /// \f]
1391 double Sr_div_S(const double& r, const double& Z) const {
1392 const double& a=a_param();
1393 return -a*Z/(1.0+(a-1.0)*exp(a*r*Z));
1394 }
1395
1396 /// second derivative of the correlation factor wrt (r-R_A)
1397
1398 /// \f[
1399 /// result = \frac{1}{S(r)}\frac{\partial^2 S(r)}{\partial r^2}
1400 /// \f]
1401 double Srr_div_S(const double& r, const double& Z) const {
1402 const double& a=a_param();
1403 const double aZ=a*Z;
1404 return aZ*aZ/(1.0+(a-1.0)*exp(r*aZ));
1405 }
1406
1407 /// third derivative of the correlation factor wrt (r-R_A)
1408
1409 /// \f[
1410 /// result = \frac{1}{S(r)}\frac{\partial^3 S(r)}{\partial r^3}
1411 /// \f]
1412 double Srrr_div_S(const double& r, const double& Z) const {
1413 const double& a=a_param();
1414 const double aZ=a*Z;
1415 return -aZ*aZ*aZ/(1.0+(a-1.0)*exp(r*aZ));
1416 }
1417
1418 /// the nuclear correlation factor
1419 double S(const double& r, const double& Z) const {
1420 const double a=a_param();
1421 //const double eprec=eprec_param();
1422 return 1.0+1.0/(a-1.0) * exp(-a*Z*r);
1423
1424// return 1.0 + 0.5/(a-1.0) *
1425// (exp(-a*r*Z + 0.5*a*a*Z*Z*eprec) * erfc((-r+a*eprec*Z)/sqrt(2*eprec))
1426// + exp(-a*r*Z + 0.5*a*Z*(4.0*r+a*eprec*Z)) * erfc((r+a*eprec*Z)/sqrt(2*eprec)));
1427 }
1428
1429 /// radial part first derivative of the nuclear correlation factor
1430 coord_3d Sp(const coord_3d& vr1A, const double& Z) const {
1431 const double a=a_param();
1432 const double r=vr1A.normf();
1433 return -(a*exp(-a*Z*r)*Z)/(a-1.0)*smoothed_unitvec(vr1A);
1434 }
1435
1436 /// second derivative of the nuclear correlation factor
1437 double Spp_div_S(const double& r, const double& Z) const {
1438 const double a=a_param();
1439
1440 if (r*Z<1.e-4) {
1441 const double O0=1.0-(1.5*a);
1442 const double O1=(a-1.0)*(a-1.0)*Z;
1443 const double O2=(1.0/12.0 * (a-1.0)*(12.0+a*(5*a-18.0)))*Z*Z;
1444 return Z*Z*(O0 + O1*r + O2*r*r);
1445
1446 } else {
1447 const double earz=exp(-a*r*Z);
1448 const double num=Z*(-earz + a*earz - (a-1.0) - 0.5*a*a*r*Z*earz);
1449 const double denom=(r*earz + (a-1.0) * r);
1450 return num/denom;
1451 }
1452 }
1453
1454
1455 /// derivative of the U2 potential wrt X (scalar part)
1456
1457 /// with
1458 /// \f[
1459 /// \rho = \left| \vec r- \vec R_A \right|
1460 /// \f]
1461 /// returns the term in the parenthesis without the the derivative of rho
1462 /// \f[
1463 /// \frac{\partial U_2}{\partial X_A} = \frac{\partial \rho}{\partial X}
1464 /// \left(-\frac{1}{2}\frac{S''' S - S'' S'}{S^2} + \frac{1}{\rho^2}\frac{S'}{S}
1465 /// - \frac{1}{\rho} \frac{S''S - S'^2}{S^2} + \frac{Z_A}{\rho^2}\right)
1466 /// \f]
1467 double U2X_spherical(const double& r, const double& Z, const double& rcut) const {
1468 const double a=a_param();
1469
1470 double result=0.0;
1471 if (r*Z<1.e-4) {
1472 const double ZZ=Z*Z;
1473 const double ZZZ=ZZ*Z;
1474 const double a2=a*a;
1475 const double a4=a2*a2;
1476 const double r0=ZZZ*(1. - 2.* a + a2);
1477 const double r1=ZZ*ZZ/6.* (12.0 - 30.* a + 23. *a2 - 5.*a*a2);
1478 const double r2=1./8.*ZZ*ZZZ* (24. - 72.*a + 74.*a2 - 29.*a2*a + 3.*a4);
1479 const double r3=1./60.*ZZZ*ZZZ* (240. - 840.*a + 1080.*a2 - 610.*a2*a
1480 + 137.*a2*a2 - 7.*a4*a);
1481 result=(r0 + r*r1 + r*r*r2 + r*r*r*r3);
1482
1483 } else {
1484 const double S1=Sr_div_S(r,Z);
1485 const double S2=Srr_div_S(r,Z);
1486 const double S3=Srrr_div_S(r,Z);
1487 const double term1=-0.5*(S3-S1*S2);
1488 const double term2=(S1+Z)/(r*r);
1489 const double term3=(S2-S1*S1)/r;
1490 result=term1+term2-term3;
1491 }
1492 return result;
1493 }
1494
1495};
1496
1497
1499public:
1500 /// ctor
1501
1502 /// @param[in] world the world
1503 /// @param[in] mol molecule with the sites of the nuclei
1504 poly4erfc(World& world, const Molecule& mol, const double aa)
1505 : NuclearCorrelationFactor(world,mol), a(1.0) {
1506
1507 if (aa!=0.0) a=aa;
1508 eprec_=mol.get_eprec();
1509
1510 if (world.rank()==0) {
1511 print("\nconstructed nuclear correlation factor of the form");
1512 print(" S_A = 1 + (a0 + a1 arZ + a2 (arZ)^2 + a3 (arZ)^3 + a4 (arZ)^4) erfc(arZ)");
1513 print(" a = ",a);
1514 print("with eprec ",eprec_);
1515 print("which is of poly4erfc type\n");
1516 }
1517 //const double pi32=std::pow(constants::pi,1.5);
1518 //const double sqrtpi=sqrt(constants::pi);
1519 //const double Pi=constants::pi;
1520
1521 if (a==0.5) {
1522 a0=0.5083397721116242769;
1523 a1=-2.4430795355664112811;
1524 a2=3.569312300653802680;
1525 a3=-1.9812471972342746507;
1526 a4=0.3641705622093696564;
1527 } else if (a==1.0) {
1528 a0=0.20265985404508529127;
1529 a1=-0.9739826967339938056;
1530 a2=1.4229779953809877198;
1531 a3=-0.7898639647077711196;
1532 a4=0.14518390461225107425;
1533
1534 } else {
1535 print("invalid parameter a for poly4erfc: only 0.5 and 1.0 implemented");
1536 MADNESS_EXCEPTION("stupid you",1);
1537 }
1538 }
1539
1541
1542private:
1543
1544 /// the length scale parameter
1545 double a;
1546 double a0, a1, a2, a3, a4;
1547 double eprec_;
1548
1549 double a_param() const {return a;}
1550 double eprec_param() const {return eprec_;}
1551
1552 /// first derivative of the correlation factor wrt (r-R_A)
1553
1554 /// \f[
1555 /// Sr_div_S = \frac{1}{S(r)}\frac{\partial S(r)}{\partial r}
1556 /// \f]
1557 double Sr_div_S(const double& r, const double& Z) const {
1558 const double x=r*Z;
1559
1560 double result=0.0;
1561 if (a==0.5) {
1562 if (x<1.0) {
1563 result=(-17.97663543396820624361586474 + x*(32.78290319470982346841067868 +
1564 x*(-18.158574783628271659713638233 +
1565 x*(2.472138984374094343735335913 +
1566 x*(0.5516975358315341628276502285 +
1567 x*(-0.008573693952875097234391220137 +
1568 x*(-0.05596791202351071993748992739 +
1569 (0.002673799219133696315436690424 +
1570 0.0013386538660557369902632289083*x)*x)))))))/
1571 (17.976635433967702922140233083 + x*
1572 (-13.062204300852085089323266568 +
1573 x*(16.397871971437618641239835027 + x*(-5.383337491559214163188757918 + 1.*x))));
1574 } else if (x<2.0) {
1575 result=(-16.53370050883888159389958126 + x*(30.04151304875517461538549269 +
1576 x*(-16.692529697855029750948871179 +
1577 x*(2.50341008323651011875249567 +
1578 x*(0.3106921665634860719234742532 +
1579 x*(0.08721948207311506458903445571 +
1580 x*(-0.10041387133168708232852057948 +
1581 (0.02000987266876476192949541524 - 0.0012508983745483161308604975792*x)*
1582 x)))))))/
1583 (16.532205048243702951212522516 + x*
1584 (-11.89273747187279634240347945 +
1585 x*(15.157537549656745468895369276 + x*(-4.9102960292797655978798640519 + 1.*x))));
1586 } else if (x<5.0) {
1587 result=(-2352.191894900273554810118278 + x*(5782.846962269399174183661793 +
1588 x*(-5653.246084369776756298278851 +
1589 x*(2948.18046377483570925427449 +
1590 x*(-913.4583247839311453090142452 +
1591 x*(174.39391722588915386106331206 +
1592 x*(-20.22035127074332315930567933 +
1593 (1.3107321165711966663791114988 - 0.03655666729452579098523876463*x)*x))
1594 )))))/
1595 (886.4859678528423041797649741 + x*(269.17746130370931387996124706 +
1596 x*(-130.21383548057958115685397713 + x*(37.644499985765056273193347388 + 1.*x))));
1597 } else if (x<10) {
1598 result=(2.2759176275121988686860433041 + x*(-1.8014283464827425541637211503 +
1599 x*(0.60570955276433317373251991152 +
1600 x*(-0.11235368819003308411943926239 +
1601 x*(0.01243211635244600976892077538 +
1602 x*(-0.0008211800260491381826149891865 +
1603 x*(0.000029973534470203049782417744015 +
1604 (-4.6423722605763162431293872646e-7 -
1605 1.3224615425412157194986675329e-10*x)*x)))))))/
1606 (1039.800013929971888016478838 + x*(-702.5378531848183775210948787 +
1607 x*(183.17476380259879599459789974 + x*(-21.74106003575315304073197254 + 1.*x))));
1608 } else {
1609 result=0.0;
1610 }
1611 } else if (a==1.0) {
1612 if (x<1.0) {
1613 result=(-1.6046958001953006847027538457 + x*(5.948945186367159977879486279 +
1614 x*(-6.884321742840291285733040882 +
1615 x*(2.296896506418919905405783368 +
1616 x*(0.616939354810622973212914089 +
1617 x*(-0.13679830198890803519235207564 +
1618 x*(-0.3356576872066501398893403439 +
1619 (0.14876798925798674488426727928 - 0.016049886728185297028755535226*x)*x
1620 )))))))/
1621 (1.6046957999975126909719683196 + x*
1622 (-0.8234878506688316215458988304 +
1623 x*(3.4607641859010551501639903314 + x*(-1.8955210085531557309609670978 + 1.*x))));
1624 } else if (x<2.0) {
1625 result=(-7.143856421301985019580778813 + x*(33.35568129248075086686087865 +
1626 x*(-60.0412343766569246898209957 +
1627 x*(55.46407913315151830247939138 +
1628 x*(-28.7874770749840240158264326 +
1629 x*(8.379317837934083469035061852 +
1630 x*(-1.2103278392957399092107317741 +
1631 (0.04275186003977071121074860478 + 0.005247730112126140726731063205*x)*x
1632 )))))))/
1633 (5.4509691924562038998044993827 + x*
1634 (-2.2732931206867811068721699796 +
1635 x*(4.1530634219989859344450742259 + x*(-2.0183662125874366044951391259 + 1.*x))));
1636 } else if (x<5.0) {
1637 result=(-0.4869290414611847276899694883 + x*(1.0513417728218375522016338562 +
1638 x*(-0.9694851629317255156038942437 +
1639 x*(0.5007460889402078102011673774 +
1640 x*(-0.15897436623286639052954575417 +
1641 x*(0.03185042477631079356985872518 +
1642 x*(-0.003940899912654543218183049969 +
1643 (0.0002757919409481032696079686825 -
1644 8.369138363906178282041501561e-6*x)*x)))))))/
1645 (30.81121613134246115634780413 + x*(-49.989974505724725146933397436 +
1646 x*(31.455643953462635691568128729 + x*(-8.992097794824270871044305786 + 1.*x))));
1647 } else {
1648 result=0.0;
1649 }
1650 }
1651 return result*Z;
1652 }
1653
1654 /// second derivative of the correlation factor wrt (r-R_A)
1655
1656 /// \f[
1657 /// result = \frac{1}{S(r)}\frac{\partial^2 S(r)}{\partial r^2}
1658 /// \f]
1659 double Srr_div_S(const double& r, const double& Z) const {
1660 MADNESS_EXCEPTION("no Srr_div_S in Slater2 yet",0);
1661 return 0.0;
1662 }
1663
1664 /// third derivative of the correlation factor wrt (r-R_A)
1665
1666 /// \f[
1667 /// result = \frac{1}{S(r)}\frac{\partial^3 S(r)}{\partial r^3}
1668 /// \f]
1669 double Srrr_div_S(const double& r, const double& Z) const {
1670 MADNESS_EXCEPTION("no Srrr_div_S in Slater2 yet",0);
1671 return 0.0;
1672 }
1673
1674 /// the nuclear correlation factor
1675 double S(const double& r, const double& Z) const {
1676 const double arZ=a*r*Z;
1677 const double arZ2=a*a*r*r*Z*Z;
1678
1679 return 1.0 + (a0 +a1* arZ+ a2 * arZ2 + a3*arZ*arZ2 + + a4*arZ2*arZ2) *erfc( a*r*Z);
1680 }
1681
1682 /// radial part first derivative of the nuclear correlation factor
1683 coord_3d Sp(const coord_3d& vr1A, const double& Z) const {
1684 MADNESS_EXCEPTION("no Sp in Slater2 yet",0);
1685 return smoothed_unitvec(vr1A);;
1686 }
1687
1688 /// second derivative of the nuclear correlation factor
1689 double Spp_div_S(const double& r, const double& Z) const {
1690 const double x=r*Z;
1691 double result=0.0;
1692 if (a==0.5) {
1693 if (x<1.0) {
1694 result=(-37.75186842343823465059 + x*(21.3476988467348903615 +
1695 x*(0.014608707333424946750026 +
1696 x*(-3.704945314726273312722 +
1697 x*(0.08808104845382944292252 +
1698 x*(0.3362428305409206967066 +
1699 x*(-0.02288039625102549092766 +
1700 (-0.017240056622850307571001 + 0.002412740490618117536527*x)*x)))))))/
1701 (17.595611361287293183447 + x*(-12.421065066789808273295 +
1702 x*(15.957564552156320207938 + x*(-5.0239100389132464317907 + 1.*x))));
1703 } else if (x<2.0) {
1704 result=(-35.46082798344982189328 + x*(20.3565414350879797493 +
1705 x*(-0.3046488975234456455871 +
1706 x*(-3.298067641731523613442 +
1707 x*(-0.10712268902574947466554 +
1708 x*(0.4829111116912435121877 +
1709 x*(-0.10089023589818206760275 +
1710 (0.0013899828749998182176948 + 0.0008305150868988335610678*x)*x)))))))/
1711 (16.526499668833810286111 + x*(-11.79820182874024593006 +
1712 x*(15.115407083582433322342 + x*(-4.8449266197426825174319 + 1.*x))));
1713 } else if (x<5.0) {
1714 result=(-414.5311559516023264104 + x*(615.8720414166440747539 +
1715 x*(-422.5938440932793094888 + x*
1716 (159.72497494584873155352 +
1717 x*(-35.6790348104188081907 +
1718 x*(4.658777521872728594702 +
1719 x*(-0.328305094433759490678 +
1720 (0.009162754689309596905172 + 0.00005047926659010755662873*x)*x)))))))/
1721 (112.7044543272820830484 + x*(-56.072518762714727894479 +
1722 x*(28.188843903409059322224 + x*(-6.519554545057610040741 + 1.*x))));
1723 } else if (x<10.0) {
1724 result=(-146.68256559112012287314 + x*(188.52807059353309478385 +
1725 x*(-82.07176992590032524431 + x*
1726 (18.107697718347802322776 +
1727 x*(-2.3221393933622638466979 +
1728 x*(0.18681223946803275939642 +
1729 x*(-0.009601011427143648072501 +
1730 (0.00028623295732553770894583 - 3.77364531155112782235e-6*x)*x)))))))/
1731 (633.1319105785227043552 + x*(-574.29230199331494406798 +
1732 x*(171.872612865808639376 + x*(-21.906495121260483674385 + 1.*x))));
1733 } else {
1734 result=-1.0/x;
1735 }
1736 } else if (a==1.0) {
1737 if (x<1.0) {
1738 result=(-8.85288955131414420808 + x*(11.359434597010419928515 +
1739 x*(-2.982094072176256165405 + x*
1740 (-4.924201512880445076103 +
1741 x*(0.6773928043289287907009 +
1742 x*(2.061680233090141287213 +
1743 x*(-0.5528612000728412913713 +
1744 (-0.3024276764350212595121 + 0.10765958646570631264003*x)*x)))))))/
1745 (1.6731803922436094206275 + x*(-0.8242052614481793487834 +
1746 x*(3.5912910648514747558597 + x*(-1.9146644266104277222142 + 1.*x))));
1747 } else if (x<2.0) {
1748 result=(-8.538839434207355205544 + x*(-37.85611260277589742674 +
1749 x*(155.08466711228234382211 + x*
1750 (-241.1247881821171613212 +
1751 x*(199.33293375918859716585 +
1752 x*(-96.80750216221383928113 +
1753 x*(27.71704080319043943288 +
1754 (-4.354251431065185902435 + 0.2906781051124817624589*x)*x)))))))/
1755 (2.2233877901091612794108 + x*(3.2084406367698851844258 +
1756 x*(1.021615116328133792993 + x*(-0.9819667717342250528772 + 1.*x))));
1757 } else if (x<5.0) {
1758 result=(-7.338671998425412491091 + x*(18.593867285988629508481 +
1759 x*(-19.15344657249203844577 + x*
1760 (10.072359942912659732126 +
1761 x*(-2.99771628023376895151 +
1762 x*(0.5324416109232007541639 +
1763 x*(-0.05993976172902101376555 +
1764 (0.003887110757665478374745 - 0.00011079212872583089652945*x)*x)))))))/
1765 (13.273604111590967002999 + x*(-28.012330064250556933961 +
1766 x*(22.161347591665727407914 + x*(-7.617582259533338164664 + 1.*x))));
1767 } else if (x<10) {
1768 result=(132.78397650676876308801 + x*(-78.01898251977413923271 +
1769 x*(15.292039515801252996504 + x*
1770 (-1.000000154745351328125 +
1771 x*(1.950300262619412492847e-8 +
1772 x*(-1.6337541591423364318692e-9 +
1773 x*(8.771557330523968791519e-11 +
1774 (-2.7388800346031121159372e-12 + 3.7894572289998844980568e-14*x)*x))))))
1775 )/(-4.724326520908917985827e-6 + x*
1776 (-132.78397108375581258096 + x*(78.01897976124964688489 +
1777 x*(-15.292038699709498552356 + 1.*x))));
1778 } else {
1779 result=-1.0/x;
1780 }
1781 }
1782 return result*Z*Z;
1783 }
1784
1785
1786 /// derivative of the U2 potential wrt X (scalar part)
1787
1788 /// with
1789 /// \f[
1790 /// \rho = \left| \vec r- \vec R_A \right|
1791 /// \f]
1792 /// returns the term in the parenthesis without the the derivative of rho
1793 /// \f[
1794 /// \frac{\partial U_2}{\partial X_A} = \frac{\partial \rho}{\partial X}
1795 /// \left(-\frac{1}{2}\frac{S''' S - S'' S'}{S^2} + \frac{1}{\rho^2}\frac{S'}{S}
1796 /// - \frac{1}{\rho} \frac{S''S - S'^2}{S^2} + \frac{Z_A}{\rho^2}\right)
1797 /// \f]
1798 double U2X_spherical(const double& r, const double& Z, const double& rcut) const {
1799 MADNESS_EXCEPTION("no U2X_spherical in Slater2 yet",0);
1800 return 0.0;
1801 }
1802
1803};
1804
1805
1806
1807/// A nuclear correlation factor class
1808
1809/// should reduce to quartic for N=4
1810/// @tparam N the exponent of the polynomial
1811template<std::size_t N>
1813public:
1814 /// ctor
1815
1816 /// @param[in] world the world
1817 /// @param[in] mol molecule with the sites of the nuclei
1818 Polynomial(World& world, const Molecule& mol, const double a)
1820
1821 /// length scale parameter a, default chosen that linear terms in U2 vanish
1822 a_=(2. + (-2. + sqrt(-1. + N))*N)/(-2. + N);
1823
1824 if (a!=0.0) a_=a;
1825
1826 if (world.rank()==0) {
1827 print("constructed nuclear correlation factor of the form");
1828 print(" R = Prod_A S_A");
1829 print(" S_A = 1 + a (r/b -1)^N if r<b, with b= (N*a)/((1+a) Z)");
1830 print(" = 1 else ");
1831 print("with eprec ",mol.get_eprec());
1832 print("which is of polynomial type with exponent N = ",N);
1833 }
1834 }
1835
1837
1838private:
1839
1840 /// length scale parameter a, default chosen that linear terms in U2 vanish
1841 double a_;
1842
1843 double a_param() const {return a_;}
1844
1845 /// the cutoff
1846 static double b_param(const double& a) {return N*a/(1.0+a);}
1847
1848 /// the nuclear correlation factor
1849 double S(const double& r, const double& Z) const {
1850
1851 const double rho=r*Z;
1852 const double a=Polynomial<N>::a_param();
1853 const double b=Polynomial<N>::b_param(a);
1854
1855 if (rho<b) {
1856 const double arg=-1.0 + rho/b;
1857 return 1.0 + power<N>(-1.0) * a*power<N>(arg);
1858 } else {
1859 return 1.0;
1860 }
1861
1862 }
1863
1864 /// radial part first derivative of the nuclear correlation factor
1865 coord_3d Sp(const coord_3d& vr1A, const double& Z) const {
1866
1867 const double r=vr1A.normf();
1868 const double rho=r*Z;
1869 const double a=Polynomial<N>::a_param();
1870 const double b=Polynomial<N>::b_param(a);
1871
1872 if (rho<b) {
1873 return power<N>(-1.)*(1.+a)* Z* power<N-1>(-1.+rho/b)*smoothed_unitvec(vr1A);
1874 }
1875 return coord_3d(0.0);
1876 }
1877
1878 /// second derivative of the nuclear correlation factor
1879
1880 /// -1/2 S"/S - Z/r
1881 double Spp_div_S(const double& r, const double& Z) const {
1882
1883 const double rho=r*Z;
1884 const double a=Polynomial<N>::a_param();
1885 const double b=Polynomial<N>::b_param(a);
1886
1887 if (rho<1.e-6) {
1888 const double ap1=1.0+a;
1889 const double c0=((3. *(1. + a) - (3. + a) * N))/(2.* a*N);
1890 const double c1=((2.* ap1*ap1 - ap1* (3. + a)*N + N*N)*Z)/(a*a*N*N);
1891 const double c2=((30.*ap1*ap1*ap1- ap1*ap1* (55 + 18* a)*N +
1892 30 *ap1 *N*N + (-5 + a* (8 + a)) *N*N*N)* Z*Z)/(12 *a*a*a*N*N*N);
1893 return Z*Z*(c0 + c1*r + c2*r*r);
1894
1895 } else if (rho<b) {
1896
1897 const double num=Z* (2 + (power<N>(-1)* a* power<N>(-1 + rho/b)
1898 * (-2 *a*N*N + (1 + a) *N* (1 + a *(-3 + N) + N)* rho +
1899 2 *(1 + a)*(1+a)* rho*rho))/power<2>(a* N - (1 + a)*rho));
1900
1901 const double denom=2.* (r + power<N>(-1) *a* r* power<N>(-1 + rho/b));
1902 return -num/denom;
1903
1904 } else {
1905 return -Z*Z/rho;
1906 }
1907 }
1908
1909 double Sr_div_S(const double& r, const double& Z) const {
1910 const double rho=r*Z;
1911 const double a=Polynomial<N>::a_param();
1912 const double b=Polynomial<N>::b_param(a);
1913
1914 if (rho<b) {
1915 const double negn= power<N>(-1.0);
1916 const double num=(negn*(1 + a)*Z*power<N-1>(-1 + ((1 + a)*r*Z)/(a*N)));
1917 const double denom=(1 + negn*a*power<N>(-1 + ((1 + a)*r*Z)/(a*N)));
1918 return num/denom;
1919 } else {
1920 return 0.0;
1921 }
1922
1923 }
1924
1925 double Srr_div_S(const double& r, const double& Z) const {
1926 const double rho=r*Z;
1927 const double a=Polynomial<N>::a_param();
1928 const double b=Polynomial<N>::b_param(a);
1929
1930 if (rho<b) {
1931 const double negn= power<N>(-1.0);
1932 return (negn*power<2>(1 + a)*(-1 + N)*power<2>(Z)*power<N-2>(-1 + ((1 + a)*r*Z)/(a*N)))/
1933 (a*N*(1 + negn*a*power<N>(-1 + ((1 + a)*r*Z)/(a*N))));
1934 } else {
1935 return 0.0;
1936 }
1937 }
1938
1939 double Srrr_div_S(const double& r, const double& Z) const {
1940 const double rho=r*Z;
1941 const double a=Polynomial<N>::a_param();
1942 const double b=Polynomial<N>::b_param(a);
1943
1944 if (rho<b) {
1945 const double negn= power<N>(-1.0);
1946 return (negn*power<3>(1 + a)*(-2 + N)*(-1 + N)*power<3>(Z)*power<N-3>(-1 + ((1 + a)*r*Z)/(a*N)))/
1947 (power<2>(a*N)*(1 + negn*a*power<N>(-1 + ((1 + a)*r*Z)/(a*N))));
1948 } else {
1949 return 0.0;
1950 }
1951 }
1952
1953 double U2X_spherical(const double& r, const double& Z, const double& rcut) const {
1954 const double a=a_param();
1955 const double aopt=(2. + (-2. + sqrt(-1. + N))*N)/(-2. + N);
1956 if (fabs(a-aopt)>1.e-10) {
1957 MADNESS_EXCEPTION("U2X_spherical for polynomial ncf only with aopt",1);
1958 }
1959
1960 double result=0.0;
1961 if (r*Z<1.e-4) {
1962 const double rn=sqrt(N-1);
1963 const double r0=0.0;
1964 const double r1=((2.*(-8. + 9.*rn) + N*(25. + 10.*rn + N))*r*power<4>(Z))/
1965 (6.*power<2>(-2 + N)*rn);
1966 const double r2=((-4*(17 + 9*rn) + N*(92 + 80*rn +
1967 N*(-29 - 33*rn + N*(4 + 7*rn + N))))*power<5>(Z))/
1968 (8.*power<3>(-2 + N)*(-1 + N)*rn);
1969 result=(r0 + r*r1 + r*r*r2);
1970
1971 } else {
1972 const double S1=Sr_div_S(r,Z);
1973 const double S2=Srr_div_S(r,Z);
1974 const double S3=Srrr_div_S(r,Z);
1975 const double term1=-0.5*(S3-S1*S2);
1976 const double term2=(S1+Z)/(r*r);
1977 const double term3=(S2-S1*S1)/r;
1978 result=term1+term2-term3;
1979 }
1980 return result;
1981 }
1982
1983};
1984
1986
1987public:
1988 /// ctor
1989
1990 /// @param[in] world the world
1991 /// @param[in] mol molecule with the sites of the nuclei
1993 const std::shared_ptr<PotentialManager> pot, const double fac)
1994 : NuclearCorrelationFactor(world,mol), potentialmanager(pot),
1995 eprec(mol.get_eprec()), fac(fac) {
1996
1997 if (world.rank()==0) {
1998 print("constructed nuclear correlation factor of the form");
1999 print(" R = ",fac);
2000 print("with eprec ",mol.get_eprec());
2001 print("which means it's (nearly) a conventional calculation\n");
2002 }
2003
2004 // add the missing -Z/r part to U2!
2005 }
2006
2007 corrfactype type() const {return None;}
2008
2009 /// return the U2 term of the correlation function
2010
2011 /// overloading to avoid inconsistent state of U2, which needs the
2012 /// nuclear potential
2013 const real_function_3d U2() const {
2014
2015// if (not U2_function.is_initialized()) {
2016 MADNESS_ASSERT(potentialmanager->vnuclear().is_initialized());
2017// }
2018 return potentialmanager->vnuclear();
2019 }
2020
2021 /// apply the regularized potential U_nuc on a given function rhs
2022
2023 /// overload the base class method for efficiency
2025 return (U2()*rhs).truncate();
2026 }
2027
2028
2029private:
2030
2031 /// underlying potential (=molecule)
2032 std::shared_ptr<PotentialManager> potentialmanager;
2033 double eprec;
2034
2035 /// the factor of the correlation factor: R=fac;
2036 const double fac;
2037
2038 double Sr_div_S(const double& r, const double& Z) const {return 0.0;}
2039
2040 double Srr_div_S(const double& r, const double& Z) const {return 0.0;}
2041
2042 double Srrr_div_S(const double& r, const double& Z) const {return 0.0;}
2043
2044 /// the nuclear correlation factor
2045 double S(const double& r, const double& Z) const {
2046 return fac;
2047 }
2048
2049 /// radial part first derivative of the nuclear correlation factor
2050 coord_3d Sp(const coord_3d& vr1A, const double& Z) const {
2051 return coord_3d(0.0);
2052 }
2053
2054 /// second derivative of the nuclear correlation factor
2055 double Spp_div_S(const double& r, const double& Z) const {
2056 double rcut= 1.0 / smoothing_parameter(Z, eprec);
2057 return - Z * smoothed_potential(r*rcut)*rcut;
2058 }
2059
2060 double U2X_spherical(const double& r, const double& Z, const double& rcut) const {
2061 // factor -1 from the definition of the dsmoothed_potential as -1/r^2
2062 return -Z*dsmoothed_potential(r * rcut) * (rcut * rcut);
2063 }
2064
2065};
2066
2067
2068/// this ncf has no information about itself, only U2 and U1 assigned
2070
2071public:
2072 /// ctor
2073
2074 /// @param[in] world the world
2075 /// @param[in] mol molecule with the sites of the nuclei
2077 const std::vector<real_function_3d>& U1)
2079
2080 U2_function=U2;
2081 U1_function=U1;
2082
2083 if (world.rank()==0) {
2084 print("constructed ad hoc nuclear correlation factor");
2085 }
2086 }
2087
2088 corrfactype type() const {return Adhoc;}
2089
2090private:
2091
2092 double Sr_div_S(const double& r, const double& Z) const {
2093 MADNESS_EXCEPTION("no Sr_div_S() in AdhocNuclearCorrelationFactor",0);
2094 return 0.0;
2095 }
2096
2097 double Srr_div_S(const double& r, const double& Z) const {
2098 MADNESS_EXCEPTION("no Srr_div_S() in AdhocNuclearCorrelationFactor",0);
2099 return 0.0;
2100 }
2101
2102 double Srrr_div_S(const double& r, const double& Z) const {
2103 MADNESS_EXCEPTION("no Srrr_div_S() in AdhocNuclearCorrelationFactor",0);
2104 return 0.0;
2105 }
2106
2107 /// the nuclear correlation factor
2108 double S(const double& r, const double& Z) const {
2109 MADNESS_EXCEPTION("no S() in AdhocNuclearCorrelationFactor",0);
2110 return 0.0;
2111 }
2112
2113 /// radial part first derivative of the nuclear correlation factor
2114 coord_3d Sp(const coord_3d& vr1A, const double& Z) const {
2115 MADNESS_EXCEPTION("no Sp() in AdhocNuclearCorrelationFactor",0);
2116 return coord_3d(0.0);
2117 }
2118
2119 /// second derivative of the nuclear correlation factor
2120 double Spp_div_S(const double& r, const double& Z) const {
2121 MADNESS_EXCEPTION("no Spp_div_S() in AdhocNuclearCorrelationFactor",0);
2122 return 0.0;
2123 }
2124};
2125
2126
2127std::shared_ptr<NuclearCorrelationFactor>
2129 const Molecule& molecule,
2130 const std::shared_ptr<PotentialManager> pm,
2131 const std::string inputline);
2132
2133std::shared_ptr<NuclearCorrelationFactor>
2135 const Molecule& molecule,
2136 const std::shared_ptr<PotentialManager> pm,
2137 const std::pair<std::string,double>& ncf);
2138
2139}
2140
2141
2142#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:2069
double Spp_div_S(const double &r, const double &Z) const
second derivative of the nuclear correlation factor
Definition correlationfactor.h:2120
double Sr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:2092
coord_3d Sp(const coord_3d &vr1A, const double &Z) const
radial part first derivative of the nuclear correlation factor
Definition correlationfactor.h:2114
corrfactype type() const
Definition correlationfactor.h:2088
double Srr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:2097
AdhocNuclearCorrelationFactor(World &world, const real_function_3d U2, const std::vector< real_function_3d > &U1)
ctor
Definition correlationfactor.h:2076
double S(const double &r, const double &Z) const
the nuclear correlation factor
Definition correlationfactor.h:2108
double Srrr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:2102
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:987
GaussSlater(World &world, const Molecule &mol)
ctor
Definition correlationfactor.h:993
double Srr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1054
double S(const double &r, const double &Z) const
the nuclear correlation factor
Definition correlationfactor.h:1011
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:1085
double Srrr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1063
double Spp_div_S(const double &r, const double &Z) const
second derivative of the nuclear correlation factor
Definition correlationfactor.h:1031
corrfactype type() const
Definition correlationfactor.h:1006
coord_3d Sp(const coord_3d &vr1A, const double &Z) const
radial part first derivative of the nuclear correlation factor
Definition correlationfactor.h:1017
double Sr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1045
A nuclear correlation factor class.
Definition correlationfactor.h:1119
double Srr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1202
double S(const double &r, const double &Z) const
the nuclear correlation factor
Definition correlationfactor.h:1146
coord_3d Sp(const coord_3d &vr1A, const double &Z) const
radial part first derivative of the nuclear correlation factor
Definition correlationfactor.h:1152
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:1223
const double a
Definition correlationfactor.h:1143
double Srrr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1212
double Spp_div_S(const double &r, const double &Z) const
second derivative of the nuclear correlation factor
Definition correlationfactor.h:1166
double Sr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1192
GradientalGaussSlater(World &world, const Molecule &mol, const double a)
ctor
Definition correlationfactor.h:1125
corrfactype type() const
Definition correlationfactor.h:1139
A nuclear correlation factor class.
Definition correlationfactor.h:1263
LinearSlater(World &world, const Molecule &mol, const double a)
ctor
Definition correlationfactor.h:1269
double Srr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1338
coord_3d Sp(const coord_3d &vr1A, const double &Z) const
radial part first derivative of the nuclear correlation factor
Definition correlationfactor.h:1300
double S(const double &r, const double &Z) const
the nuclear correlation factor
Definition correlationfactor.h:1293
double Sr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1332
double a_param() const
Definition correlationfactor.h:1290
double a_
the length scale parameter a
Definition correlationfactor.h:1288
double Srrr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1344
corrfactype type() const
Definition correlationfactor.h:1283
double Spp_div_S(const double &r, const double &Z) const
second derivative of the nuclear correlation factor
Definition correlationfactor.h:1314
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:495
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:769
double operator()(const coord_3d &xyz) const override
Definition correlationfactor.h:790
std::vector< coord_3d > special_points() const override
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:816
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:770
const Atom & thisatom
Definition correlationfactor.h:771
const int derivativeaxis
Definition correlationfactor.h:772
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:776
const int exponent
direction of the derivative operator
Definition correlationfactor.h:773
RX_functor(const NuclearCorrelationFactor *ncf, const int iatom, const int daxis, const int exponent)
Definition correlationfactor.h:782
Definition correlationfactor.h:443
R_functor(const NuclearCorrelationFactor *ncf, const int e=1)
Definition correlationfactor.h:447
double operator()(const coord_3d &xyz) const override
Definition correlationfactor.h:452
int exponent
Definition correlationfactor.h:445
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:444
std::vector< coord_3d > special_points() const override
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:468
compute the derivative of U1 wrt the displacement of atom A, coord axis
Definition correlationfactor.h:824
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:825
const int U1axis
Definition correlationfactor.h:827
U1X_functor(const NuclearCorrelationFactor *ncf, const int iatom, const int U1axis, const int daxis)
Definition correlationfactor.h:837
U1X_functor(const NuclearCorrelationFactor *ncf, const Atom &atom1, const int U1axis, const int daxis)
direction of the derivative operator
Definition correlationfactor.h:830
double operator()(const coord_3d &xyz) const override
Definition correlationfactor.h:847
const Atom & thisatom
Definition correlationfactor.h:826
const int derivativeaxis
U1x/U1y/U1z potential?
Definition correlationfactor.h:828
std::vector< coord_3d > special_points() const override
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:861
U1 functor for a specific atom.
Definition correlationfactor.h:512
double operator()(const coord_3d &xyz) const override
Definition correlationfactor.h:522
const size_t iatom
Definition correlationfactor.h:515
std::vector< coord_3d > special_points() const override
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:530
U1_atomic_functor(const NuclearCorrelationFactor *ncf, const size_t atom, const int axis)
Definition correlationfactor.h:519
const int axis
Definition correlationfactor.h:516
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:514
functor for a local U1 dot U1 potential
Definition correlationfactor.h:547
double operator()(const coord_3d &xyz) const override
Definition correlationfactor.h:555
std::vector< coord_3d > special_points() const override
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:578
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:549
U1_dot_U1_functor(const NuclearCorrelationFactor *ncf)
Definition correlationfactor.h:552
functor for the local part of the U1 potential – NOTE THE SIGN
Definition correlationfactor.h:476
std::vector< coord_3d > special_points() const override
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:500
const int axis
Definition correlationfactor.h:479
U1_functor(const NuclearCorrelationFactor *ncf, const int axis)
Definition correlationfactor.h:482
double operator()(const coord_3d &xyz) const override
Definition correlationfactor.h:488
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:478
compute the derivative of U2 wrt the displacement of atom A
Definition correlationfactor.h:873
const int iatom
Definition correlationfactor.h:875
const int axis
Definition correlationfactor.h:876
std::vector< coord_3d > special_points() const override
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:899
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:874
U2X_functor(const NuclearCorrelationFactor *ncf, const int &atom1, const int axis)
Definition correlationfactor.h:878
double operator()(const coord_3d &xyz) const override
Definition correlationfactor.h:886
U2 functor for a specific atom.
Definition correlationfactor.h:638
const size_t iatom
Definition correlationfactor.h:641
double operator()(const coord_3d &xyz) const override
Definition correlationfactor.h:648
std::vector< coord_3d > special_points() const override
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:655
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:640
U2_atomic_functor(const NuclearCorrelationFactor *ncf, const size_t atom)
Definition correlationfactor.h:644
Definition correlationfactor.h:584
double operator()(const coord_3d &xyz) const override
Definition correlationfactor.h:590
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:585
std::vector< coord_3d > special_points() const override
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:600
U2_functor(const NuclearCorrelationFactor *ncf)
Definition correlationfactor.h:587
compute the derivative of U3 wrt the displacement of atom A, coord axis
Definition correlationfactor.h:922
std::vector< coord_3d > special_points() const override
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:973
U3X_functor(const NuclearCorrelationFactor *ncf, const size_t iatom, const int axis)
Definition correlationfactor.h:927
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:923
const int axis
Definition correlationfactor.h:925
const size_t iatom
Definition correlationfactor.h:924
double operator()(const coord_3d &xyz) const override
Definition correlationfactor.h:931
U3 functor for a specific atom.
Definition correlationfactor.h:666
const size_t iatom
Definition correlationfactor.h:669
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:668
double operator()(const coord_3d &xyz) const override
Definition correlationfactor.h:676
std::vector< coord_3d > special_points() const override
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:700
U3_atomic_functor(const NuclearCorrelationFactor *ncf, const int atom)
Definition correlationfactor.h:672
Definition correlationfactor.h:605
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:606
U3_functor(const NuclearCorrelationFactor *ncf)
Definition correlationfactor.h:608
double operator()(const coord_3d &xyz) const override
Definition correlationfactor.h:611
std::vector< coord_3d > special_points() const override
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:632
std::vector< coord_3d > special_points() const override
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:763
const Molecule & molecule
Definition correlationfactor.h:741
const size_t iatom
Definition correlationfactor.h:742
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:740
square_times_V_derivative_functor(const NuclearCorrelationFactor *ncf, const Molecule &molecule1, const size_t atom1, const int axis1)
Definition correlationfactor.h:745
double operator()(const coord_3d &xyz) const override
Definition correlationfactor.h:750
const size_t iatom
Definition correlationfactor.h:713
const NuclearCorrelationFactor * ncf
Definition correlationfactor.h:711
square_times_V_functor(const NuclearCorrelationFactor *ncf, const Molecule &mol, const size_t iatom1)
Definition correlationfactor.h:715
double operator()(const coord_3d &xyz) const override
Definition correlationfactor.h:720
std::vector< coord_3d > special_points() const override
Override this to return list of special points to be refined more deeply.
Definition correlationfactor.h:733
const Molecule & molecule
Definition correlationfactor.h:712
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:1812
double a_
length scale parameter a, default chosen that linear terms in U2 vanish
Definition correlationfactor.h:1841
Polynomial(World &world, const Molecule &mol, const double a)
ctor
Definition correlationfactor.h:1818
coord_3d Sp(const coord_3d &vr1A, const double &Z) const
radial part first derivative of the nuclear correlation factor
Definition correlationfactor.h:1865
double Spp_div_S(const double &r, const double &Z) const
second derivative of the nuclear correlation factor
Definition correlationfactor.h:1881
double S(const double &r, const double &Z) const
the nuclear correlation factor
Definition correlationfactor.h:1849
double Srrr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1939
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:1953
corrfactype type() const
Definition correlationfactor.h:1836
double a_param() const
Definition correlationfactor.h:1843
double Srr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1925
static double b_param(const double &a)
the cutoff
Definition correlationfactor.h:1846
double Sr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:1909
Definition correlationfactor.h:1985
double Srrr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:2042
double eprec
Definition correlationfactor.h:2033
corrfactype type() const
Definition correlationfactor.h:2007
std::shared_ptr< PotentialManager > potentialmanager
underlying potential (=molecule)
Definition correlationfactor.h:2032
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:2024
double Srr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:2040
const double fac
the factor of the correlation factor: R=fac;
Definition correlationfactor.h:2036
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:2060
double S(const double &r, const double &Z) const
the nuclear correlation factor
Definition correlationfactor.h:2045
double Sr_div_S(const double &r, const double &Z) const
Definition correlationfactor.h:2038
coord_3d Sp(const coord_3d &vr1A, const double &Z) const
radial part first derivative of the nuclear correlation factor
Definition correlationfactor.h:2050
PseudoNuclearCorrelationFactor(World &world, const Molecule &mol, const std::shared_ptr< PotentialManager > pot, const double fac)
ctor
Definition correlationfactor.h:1992
double Spp_div_S(const double &r, const double &Z) const
second derivative of the nuclear correlation factor
Definition correlationfactor.h:2055
const real_function_3d U2() const
return the U2 term of the correlation function
Definition correlationfactor.h:2013
A nuclear correlation factor class.
Definition correlationfactor.h:1354
double eprec_param() const
Definition correlationfactor.h:1384
corrfactype type() const
Definition correlationfactor.h:1375
double a_param() const
Definition correlationfactor.h:1383
double Srr_div_S(const double &r, const double &Z) const
second derivative of the correlation factor wrt (r-R_A)
Definition correlationfactor.h:1401
coord_3d Sp(const coord_3d &vr1A, const double &Z) const
radial part first derivative of the nuclear correlation factor
Definition correlationfactor.h:1430
double Spp_div_S(const double &r, const double &Z) const
second derivative of the nuclear correlation factor
Definition correlationfactor.h:1437
Slater(World &world, const Molecule &mol, const double a)
ctor
Definition correlationfactor.h:1360
double eprec_
Definition correlationfactor.h:1381
double Sr_div_S(const double &r, const double &Z) const
first derivative of the correlation factor wrt (r-R_A)
Definition correlationfactor.h:1391
double Srrr_div_S(const double &r, const double &Z) const
third derivative of the correlation factor wrt (r-R_A)
Definition correlationfactor.h:1412
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:1467
double S(const double &r, const double &Z) const
the nuclear correlation factor
Definition correlationfactor.h:1419
double a_
the length scale parameter
Definition correlationfactor.h:1380
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:1498
double Srrr_div_S(const double &r, const double &Z) const
third derivative of the correlation factor wrt (r-R_A)
Definition correlationfactor.h:1669
double a
the length scale parameter
Definition correlationfactor.h:1545
double Spp_div_S(const double &r, const double &Z) const
second derivative of the nuclear correlation factor
Definition correlationfactor.h:1689
poly4erfc(World &world, const Molecule &mol, const double aa)
ctor
Definition correlationfactor.h:1504
double a0
Definition correlationfactor.h:1546
double eprec_
Definition correlationfactor.h:1547
coord_3d Sp(const coord_3d &vr1A, const double &Z) const
radial part first derivative of the nuclear correlation factor
Definition correlationfactor.h:1683
corrfactype type() const
Definition correlationfactor.h:1540
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:1798
double a_param() const
Definition correlationfactor.h:1549
double eprec_param() const
Definition correlationfactor.h:1550
double Srr_div_S(const double &r, const double &Z) const
second derivative of the correlation factor wrt (r-R_A)
Definition correlationfactor.h:1659
double Sr_div_S(const double &r, const double &Z) const
first derivative of the correlation factor wrt (r-R_A)
Definition correlationfactor.h:1557
double S(const double &r, const double &Z) const
the nuclear correlation factor
Definition correlationfactor.h:1675
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
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)
Multiplies and sums two vectors of functions r = \sum_i a[i] * b[i]; see dot_sparse for screening.
Definition vmra.h:1809
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:336
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:2620
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