00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _chemistry_qc_dft_functional_h
00029 #define _chemistry_qc_dft_functional_h
00030
00031 #ifdef __GNUC__
00032 #pragma interface
00033 #endif
00034
00035 #include <util/state/state.h>
00036 #include <math/scmat/vector3.h>
00037 #include <chemistry/qc/wfn/wfn.h>
00038
00040 struct PointInputData {
00041 enum {X=0, Y=1, Z=2};
00042 enum {XX=0, YX=1, YY=2, ZX=3, ZY=4, ZZ=5};
00043 struct SpinData {
00044 double rho;
00045
00046 double rho_13;
00047
00048 double del_rho[3];
00049
00050 double gamma;
00051
00052
00053 double hes_rho[6];
00054
00055 double lap_rho;
00056 };
00057 SpinData a, b;
00058
00059
00060 double gamma_ab;
00061
00062 const SCVector3 &r;
00063
00064
00065 void compute_derived(int spin_polarized, int need_gradient);
00066
00067 PointInputData(const SCVector3& r_): r(r_) {}
00068 };
00069
00071 struct PointOutputData {
00072
00073 double energy;
00074
00075
00076 double df_drho_a;
00077 double df_drho_b;
00078
00079
00080 double df_dgamma_aa;
00081 double df_dgamma_bb;
00082 double df_dgamma_ab;
00083
00084 void zero(){energy=df_drho_a=df_drho_b=df_dgamma_aa=df_dgamma_bb=df_dgamma_ab=0.0;}
00085
00086 };
00087
00089 class DenFunctional: virtual public SavableState {
00090 protected:
00091 int spin_polarized_;
00092 int compute_potential_;
00093 double a0_;
00094
00095 void do_fd_point(PointInputData&id,double&in,double&out,
00096 double lower_bound, double upper_bound);
00097 public:
00098 DenFunctional();
00099 DenFunctional(const Ref<KeyVal> &);
00100 DenFunctional(StateIn &);
00101 ~DenFunctional();
00102 void save_data_state(StateOut &);
00103
00104
00105
00106 virtual void set_spin_polarized(int i);
00107
00108
00109 virtual void set_compute_potential(int i);
00110
00111
00112
00113 virtual int need_density_gradient();
00114
00115
00116 virtual int need_density_hessian();
00117
00118 virtual void point(const PointInputData&, PointOutputData&) = 0;
00119 void gradient(const PointInputData&, PointOutputData&,
00120 double *gradient, int acenter,
00121 GaussianBasisSet *basis,
00122 const double *dmat_a, const double *dmat_b,
00123 int ncontrib_, const int *contrib_,
00124 int ncontrib_bf_, const int *contrib_bf_,
00125 const double *bs_values, const double *bsg_values,
00126 const double *bsh_values);
00127
00128 double a0() const { return a0_; }
00129
00130 void fd_point(const PointInputData&, PointOutputData&);
00131 int test(const PointInputData &);
00132 int test();
00133 };
00134
00135
00138 class NElFunctional: public DenFunctional {
00139 public:
00140 NElFunctional();
00141 NElFunctional(const Ref<KeyVal> &);
00142 NElFunctional(StateIn &);
00143 ~NElFunctional();
00144 void save_data_state(StateOut &);
00145
00146 void point(const PointInputData&, PointOutputData&);
00147 };
00148
00151 class SumDenFunctional: public DenFunctional {
00152 protected:
00153 int n_;
00154 Ref<DenFunctional> *funcs_;
00155 double *coefs_;
00156 public:
00157 SumDenFunctional();
00158 SumDenFunctional(const Ref<KeyVal> &);
00159 SumDenFunctional(StateIn &);
00160 ~SumDenFunctional();
00161 void save_data_state(StateOut &);
00162
00163 void set_spin_polarized(int);
00164 void set_compute_potential(int);
00165 int need_density_gradient();
00166
00167 void point(const PointInputData&, PointOutputData&);
00168
00169 void print(std::ostream& =ExEnv::out()) const;
00170 };
00171
00244 class StdDenFunctional: public SumDenFunctional {
00245 protected:
00246 char *name_;
00247 void init_arrays(int n);
00248 public:
00249 StdDenFunctional();
00253 StdDenFunctional(const Ref<KeyVal> &);
00254 StdDenFunctional(StateIn &);
00255 ~StdDenFunctional();
00256 void save_data_state(StateOut &);
00257
00258 void print(std::ostream& =ExEnv::out()) const;
00259 };
00260
00262 class LSDACFunctional: public DenFunctional {
00263 protected:
00264 public:
00265 LSDACFunctional();
00266 LSDACFunctional(const Ref<KeyVal> &);
00267 LSDACFunctional(StateIn &);
00268 ~LSDACFunctional();
00269 void save_data_state(StateOut &);
00270
00271 void point(const PointInputData&, PointOutputData&);
00272 virtual
00273 void point_lc(const PointInputData&, PointOutputData&,
00274 double &ec_local, double &decrs, double &deczeta) = 0;
00275
00276 };
00277
00278
00287 class PBECFunctional: public DenFunctional {
00288 protected:
00289 Ref<LSDACFunctional> local_;
00290 double gamma;
00291 double beta;
00292 void init_constants();
00293 double rho_deriv(double rho_a, double rho_b, double mdr,
00294 double ec_local, double ec_local_dra);
00295 double gab_deriv(double rho, double phi, double mdr, double ec_local);
00296 public:
00297 PBECFunctional();
00298 PBECFunctional(const Ref<KeyVal> &);
00299 PBECFunctional(StateIn &);
00300 ~PBECFunctional();
00301 void save_data_state(StateOut &);
00302 int need_density_gradient();
00303 void point(const PointInputData&, PointOutputData&);
00304 void set_spin_polarized(int);
00305
00306 };
00307
00318 class PW91CFunctional: public DenFunctional {
00319 protected:
00320 Ref<LSDACFunctional> local_;
00321 double a;
00322 double b;
00323 double c;
00324 double d;
00325 double alpha;
00326 double c_c0;
00327 double c_x;
00328 double nu;
00329 void init_constants();
00330 double limit_df_drhoa(double rhoa, double gamma,
00331 double ec, double decdrhoa);
00332
00333 public:
00334 PW91CFunctional();
00335 PW91CFunctional(const Ref<KeyVal> &);
00336 PW91CFunctional(StateIn &);
00337 ~PW91CFunctional();
00338 void save_data_state(StateOut &);
00339 int need_density_gradient();
00340
00341 void point(const PointInputData&, PointOutputData&);
00342 void set_spin_polarized(int);
00343
00344 };
00345
00352 class P86CFunctional: public DenFunctional {
00353 protected:
00354 double a_;
00355 double C1_;
00356 double C2_;
00357 double C3_;
00358 double C4_;
00359 double C5_;
00360 double C6_;
00361 double C7_;
00362 void init_constants();
00363 public:
00364 P86CFunctional();
00365 P86CFunctional(const Ref<KeyVal> &);
00366 P86CFunctional(StateIn &);
00367 ~P86CFunctional();
00368 void save_data_state(StateOut &);
00369 int need_density_gradient();
00370 void point(const PointInputData&, PointOutputData&);
00371
00372 };
00373
00374
00375
00376
00377 class NewP86CFunctional: public DenFunctional {
00378 protected:
00379 double a_;
00380 double C1_;
00381 double C2_;
00382 double C3_;
00383 double C4_;
00384 double C5_;
00385 double C6_;
00386 double C7_;
00387 void init_constants();
00388 double rho_deriv(double rho_a, double rho_b, double mdr);
00389 double gab_deriv(double rho_a, double rho_b, double mdr);
00390
00391 public:
00392 NewP86CFunctional();
00393 NewP86CFunctional(const Ref<KeyVal> &);
00394 NewP86CFunctional(StateIn &);
00395 ~NewP86CFunctional();
00396 void save_data_state(StateOut &);
00397 int need_density_gradient();
00398 void point(const PointInputData&, PointOutputData&);
00399 };
00400
00404 class SlaterXFunctional: public DenFunctional {
00405 protected:
00406 public:
00407 SlaterXFunctional();
00408 SlaterXFunctional(const Ref<KeyVal> &);
00409 SlaterXFunctional(StateIn &);
00410 ~SlaterXFunctional();
00411 void save_data_state(StateOut &);
00412 void point(const PointInputData&, PointOutputData&);
00413 };
00414
00422 class VWNLCFunctional: public LSDACFunctional {
00423 protected:
00424 double Ap_, Af_, A_alpha_;
00425 double x0p_mc_, bp_mc_, cp_mc_, x0f_mc_, bf_mc_, cf_mc_;
00426 double x0p_rpa_, bp_rpa_, cp_rpa_, x0f_rpa_, bf_rpa_, cf_rpa_;
00427 double x0_alpha_mc_, b_alpha_mc_, c_alpha_mc_;
00428 double x0_alpha_rpa_, b_alpha_rpa_, c_alpha_rpa_;
00429 void init_constants();
00430
00431 double F(double x, double A, double x0, double b, double c);
00432 double dFdr_s(double x, double A, double x0, double b, double c);
00433 public:
00434 VWNLCFunctional();
00435 VWNLCFunctional(const Ref<KeyVal> &);
00436 VWNLCFunctional(StateIn &);
00437 ~VWNLCFunctional();
00438 void save_data_state(StateOut &);
00439
00440 virtual
00441 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &);
00442 };
00443
00446 class VWN1LCFunctional: public VWNLCFunctional {
00447 protected:
00448 double x0p_, bp_, cp_, x0f_, bf_, cf_;
00449 public:
00451 VWN1LCFunctional();
00453 VWN1LCFunctional(int use_rpa);
00459 VWN1LCFunctional(const Ref<KeyVal> &);
00460 VWN1LCFunctional(StateIn &);
00461 ~VWN1LCFunctional();
00462 void save_data_state(StateOut &);
00463
00464 void point_lc(const PointInputData&, PointOutputData&,
00465 double &, double &, double &);
00466 };
00467
00470 class VWN2LCFunctional: public VWNLCFunctional {
00471 protected:
00472 public:
00474 VWN2LCFunctional();
00476 VWN2LCFunctional(const Ref<KeyVal> &);
00477 VWN2LCFunctional(StateIn &);
00478 ~VWN2LCFunctional();
00479 void save_data_state(StateOut &);
00480
00481 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &);
00482 };
00483
00484
00487 class VWN3LCFunctional: public VWNLCFunctional {
00488 protected:
00489 int monte_carlo_prefactor_;
00490 int monte_carlo_e0_;
00491 public:
00492 VWN3LCFunctional(int mcp = 1, int mce0 = 1);
00493 VWN3LCFunctional(const Ref<KeyVal> &);
00494 VWN3LCFunctional(StateIn &);
00495 ~VWN3LCFunctional();
00496 void save_data_state(StateOut &);
00497
00498 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &);
00499 };
00500
00503 class VWN4LCFunctional: public VWNLCFunctional {
00504 protected:
00505 int monte_carlo_prefactor_;
00506 public:
00507 VWN4LCFunctional();
00508 VWN4LCFunctional(const Ref<KeyVal> &);
00509 VWN4LCFunctional(StateIn &);
00510 ~VWN4LCFunctional();
00511 void save_data_state(StateOut &);
00512
00513 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &);
00514 };
00515
00518 class VWN5LCFunctional: public VWNLCFunctional {
00519 protected:
00520 public:
00521 VWN5LCFunctional();
00522 VWN5LCFunctional(const Ref<KeyVal> &);
00523 VWN5LCFunctional(StateIn &);
00524 ~VWN5LCFunctional();
00525 void save_data_state(StateOut &);
00526
00527 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &);
00528 };
00529
00535 class PW92LCFunctional: public LSDACFunctional {
00536 protected:
00537 double F(double x, double A, double alpha_1, double beta_1, double beta_2,
00538 double beta_3, double beta_4, double p);
00539 double dFdr_s(double x, double A, double alpha_1, double beta_1, double beta_2,
00540 double beta_3, double beta_4, double p);
00541 public:
00542 PW92LCFunctional();
00543 PW92LCFunctional(const Ref<KeyVal> &);
00544 PW92LCFunctional(StateIn &);
00545 ~PW92LCFunctional();
00546 void save_data_state(StateOut &);
00547
00548 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &);
00549 };
00550
00556 class PZ81LCFunctional: public LSDACFunctional {
00557 protected:
00558 double Fec_rsgt1(double rs, double beta_1, double beta_2, double gamma);
00559 double dFec_rsgt1_drho(double rs, double beta_1, double beta_2, double gamma,
00560 double &dec_drs);
00561 double Fec_rslt1(double rs, double A, double B, double C, double D);
00562 double dFec_rslt1_drho(double rs, double A, double B, double C, double D,
00563 double &dec_drs);
00564 public:
00565 PZ81LCFunctional();
00566 PZ81LCFunctional(const Ref<KeyVal> &);
00567 PZ81LCFunctional(StateIn &);
00568 ~PZ81LCFunctional();
00569 void save_data_state(StateOut &);
00570
00571 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &);
00572 };
00573
00575 class XalphaFunctional: public DenFunctional {
00576 protected:
00577 double alpha_;
00578 double factor_;
00579 public:
00580 XalphaFunctional();
00581 XalphaFunctional(const Ref<KeyVal> &);
00582 XalphaFunctional(StateIn &);
00583 ~XalphaFunctional();
00584 void save_data_state(StateOut &);
00585
00586 void point(const PointInputData&, PointOutputData&);
00587
00588 void print(std::ostream& =ExEnv::out()) const;
00589 };
00590
00595 class Becke88XFunctional: public DenFunctional {
00596 protected:
00597 double beta_;
00598 double beta6_;
00599 public:
00600 Becke88XFunctional();
00601 Becke88XFunctional(const Ref<KeyVal> &);
00602 Becke88XFunctional(StateIn &);
00603 ~Becke88XFunctional();
00604 void save_data_state(StateOut &);
00605
00606 int need_density_gradient();
00607
00608 void point(const PointInputData&, PointOutputData&);
00609 };
00610
00619 class LYPCFunctional: public DenFunctional {
00620 protected:
00621 double a_;
00622 double b_;
00623 double c_;
00624 double d_;
00625 void init_constants();
00626 public:
00627 LYPCFunctional();
00628 LYPCFunctional(const Ref<KeyVal> &);
00629 LYPCFunctional(StateIn &);
00630 ~LYPCFunctional();
00631 void save_data_state(StateOut &);
00632
00633 int need_density_gradient();
00634
00635 void point(const PointInputData&, PointOutputData&);
00636 };
00637
00642 class PW86XFunctional: public DenFunctional {
00643 protected:
00644 double a_;
00645 double b_;
00646 double c_;
00647 double m_;
00648 void init_constants();
00649 public:
00650 PW86XFunctional();
00651 PW86XFunctional(const Ref<KeyVal> &);
00652 PW86XFunctional(StateIn &);
00653 ~PW86XFunctional();
00654 void save_data_state(StateOut &);
00655
00656 int need_density_gradient();
00657
00658 void point(const PointInputData&, PointOutputData&);
00659 };
00660
00676 class PBEXFunctional: public DenFunctional {
00677 protected:
00678 double mu;
00679 double kappa;
00680 void spin_contrib(const PointInputData::SpinData &,
00681 double &mpw, double &dmpw_dr, double &dmpw_dg);
00682 void init_constants();
00683 public:
00684 PBEXFunctional();
00685 PBEXFunctional(const Ref<KeyVal> &);
00686 PBEXFunctional(StateIn &);
00687 ~PBEXFunctional();
00688 void save_data_state(StateOut &);
00689
00690 int need_density_gradient();
00691
00692 void point(const PointInputData&, PointOutputData&);
00693 };
00694
00705 class PW91XFunctional: public DenFunctional {
00706 protected:
00707 double a;
00708 double b;
00709 double c;
00710 double d;
00711 double a_x;
00712 void spin_contrib(const PointInputData::SpinData &,
00713 double &mpw, double &dmpw_dr, double &dmpw_dg);
00714 void init_constants();
00715 public:
00716 PW91XFunctional();
00717 PW91XFunctional(const Ref<KeyVal> &);
00718 PW91XFunctional(StateIn &);
00719 ~PW91XFunctional();
00720 void save_data_state(StateOut &);
00721
00722 int need_density_gradient();
00723
00724 void point(const PointInputData&, PointOutputData&);
00725 };
00726
00731 class mPW91XFunctional: public DenFunctional {
00732 protected:
00733 double b;
00734 double beta;
00735 double c;
00736 double d;
00737 double a_x;
00738 double x_d_coef;
00739
00740 void spin_contrib(const PointInputData::SpinData &,
00741 double &mpw, double &dmpw_dr, double &dmpw_dg);
00742 public:
00743 enum Func { B88, PW91, mPW91 };
00744
00746 mPW91XFunctional();
00749 mPW91XFunctional(Func variant);
00768 mPW91XFunctional(const Ref<KeyVal> &);
00769 mPW91XFunctional(StateIn &);
00770 ~mPW91XFunctional();
00771 void save_data_state(StateOut &);
00772
00773 int need_density_gradient();
00774
00775 void point(const PointInputData&, PointOutputData&);
00776
00777 void init_constants(Func);
00778 };
00779
00784 class G96XFunctional: public DenFunctional {
00785 protected:
00786 double b_;
00787 void init_constants();
00788 public:
00789 G96XFunctional();
00790 G96XFunctional(const Ref<KeyVal> &);
00791 G96XFunctional(StateIn &);
00792 ~G96XFunctional();
00793 void save_data_state(StateOut &);
00794
00795 int need_density_gradient();
00796
00797 void point(const PointInputData&, PointOutputData&);
00798 };
00799
00800 #endif
00801
00802
00803
00804
00805