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