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
00039 namespace sc {
00040
00042 struct PointInputData {
00043 enum {X=0, Y=1, Z=2};
00044 enum {XX=0, YX=1, YY=2, ZX=3, ZY=4, ZZ=5};
00045 struct SpinData {
00046 double rho;
00047
00048 double rho_13;
00049
00050 double del_rho[3];
00051
00052 double gamma;
00053
00054
00055 double hes_rho[6];
00056
00057 double lap_rho;
00058 };
00059 SpinData a, b;
00060
00061
00062 double gamma_ab;
00063
00064 const SCVector3 &r;
00065
00066
00067 void compute_derived(int spin_polarized, int need_gradient);
00068
00069 PointInputData(const SCVector3& r_): r(r_) {}
00070 };
00071
00073 struct PointOutputData {
00074
00075 double energy;
00076
00077
00078 double df_drho_a;
00079 double df_drho_b;
00080
00081
00082 double df_dgamma_aa;
00083 double df_dgamma_bb;
00084 double df_dgamma_ab;
00085
00086 void zero(){energy=df_drho_a=df_drho_b=df_dgamma_aa=df_dgamma_bb=df_dgamma_ab=0.0;}
00087
00088 };
00089
00091 class DenFunctional: virtual public SavableState {
00092 protected:
00093 int spin_polarized_;
00094 int compute_potential_;
00095 double a0_;
00096
00097 void do_fd_point(PointInputData&id,double&in,double&out,
00098 double lower_bound, double upper_bound);
00099 public:
00100 DenFunctional();
00101 DenFunctional(const Ref<KeyVal> &);
00102 DenFunctional(StateIn &);
00103 ~DenFunctional();
00104 void save_data_state(StateOut &);
00105
00106
00107
00108 virtual void set_spin_polarized(int i);
00109
00110
00111 virtual void set_compute_potential(int i);
00112
00113
00114
00115 virtual int need_density_gradient();
00116
00117
00118 virtual int need_density_hessian();
00119
00120 virtual void point(const PointInputData&, PointOutputData&) = 0;
00121 void gradient(const PointInputData&, PointOutputData&,
00122 double *gradient, int acenter,
00123 GaussianBasisSet *basis,
00124 const double *dmat_a, const double *dmat_b,
00125 int ncontrib_, const int *contrib_,
00126 int ncontrib_bf_, const int *contrib_bf_,
00127 const double *bs_values, const double *bsg_values,
00128 const double *bsh_values);
00129
00130 double a0() const { return a0_; }
00131
00132 void fd_point(const PointInputData&, PointOutputData&);
00133 int test(const PointInputData &);
00134 int test();
00135 };
00136
00137
00140 class NElFunctional: public DenFunctional {
00141 public:
00142 NElFunctional();
00143 NElFunctional(const Ref<KeyVal> &);
00144 NElFunctional(StateIn &);
00145 ~NElFunctional();
00146 void save_data_state(StateOut &);
00147
00148 void point(const PointInputData&, PointOutputData&);
00149 };
00150
00153 class SumDenFunctional: public DenFunctional {
00154 protected:
00155 int n_;
00156 Ref<DenFunctional> *funcs_;
00157 double *coefs_;
00158 public:
00159 SumDenFunctional();
00160 SumDenFunctional(const Ref<KeyVal> &);
00161 SumDenFunctional(StateIn &);
00162 ~SumDenFunctional();
00163 void save_data_state(StateOut &);
00164
00165 void set_spin_polarized(int);
00166 void set_compute_potential(int);
00167 int need_density_gradient();
00168
00169 void point(const PointInputData&, PointOutputData&);
00170
00171 void print(std::ostream& =ExEnv::out0()) const;
00172 };
00173
00246 class StdDenFunctional: public SumDenFunctional {
00247 protected:
00248 char *name_;
00249 void init_arrays(int n);
00250 public:
00251 StdDenFunctional();
00256 StdDenFunctional(const Ref<KeyVal> &);
00257 StdDenFunctional(StateIn &);
00258 ~StdDenFunctional();
00259 void save_data_state(StateOut &);
00260
00261 void print(std::ostream& =ExEnv::out0()) const;
00262 };
00263
00265 class LSDACFunctional: public DenFunctional {
00266 protected:
00267 public:
00268 LSDACFunctional();
00269 LSDACFunctional(const Ref<KeyVal> &);
00270 LSDACFunctional(StateIn &);
00271 ~LSDACFunctional();
00272 void save_data_state(StateOut &);
00273
00274 void point(const PointInputData&, PointOutputData&);
00275 virtual
00276 void point_lc(const PointInputData&, PointOutputData&,
00277 double &ec_local, double &decrs, double &deczeta) = 0;
00278
00279 };
00280
00281
00290 class PBECFunctional: public DenFunctional {
00291 protected:
00292 Ref<LSDACFunctional> local_;
00293 double gamma;
00294 double beta;
00295 void init_constants();
00296 double rho_deriv(double rho_a, double rho_b, double mdr,
00297 double ec_local, double ec_local_dra);
00298 double gab_deriv(double rho, double phi, double mdr, double ec_local);
00299 public:
00300 PBECFunctional();
00301 PBECFunctional(const Ref<KeyVal> &);
00302 PBECFunctional(StateIn &);
00303 ~PBECFunctional();
00304 void save_data_state(StateOut &);
00305 int need_density_gradient();
00306 void point(const PointInputData&, PointOutputData&);
00307 void set_spin_polarized(int);
00308
00309 };
00310
00321 class PW91CFunctional: public DenFunctional {
00322 protected:
00323 Ref<LSDACFunctional> local_;
00324 double a;
00325 double b;
00326 double c;
00327 double d;
00328 double alpha;
00329 double c_c0;
00330 double c_x;
00331 double nu;
00332 void init_constants();
00333 double limit_df_drhoa(double rhoa, double gamma,
00334 double ec, double decdrhoa);
00335
00336 public:
00337 PW91CFunctional();
00338 PW91CFunctional(const Ref<KeyVal> &);
00339 PW91CFunctional(StateIn &);
00340 ~PW91CFunctional();
00341 void save_data_state(StateOut &);
00342 int need_density_gradient();
00343
00344 void point(const PointInputData&, PointOutputData&);
00345 void set_spin_polarized(int);
00346
00347 };
00348
00355 class P86CFunctional: public DenFunctional {
00356 protected:
00357 double a_;
00358 double C1_;
00359 double C2_;
00360 double C3_;
00361 double C4_;
00362 double C5_;
00363 double C6_;
00364 double C7_;
00365 void init_constants();
00366 public:
00367 P86CFunctional();
00368 P86CFunctional(const Ref<KeyVal> &);
00369 P86CFunctional(StateIn &);
00370 ~P86CFunctional();
00371 void save_data_state(StateOut &);
00372 int need_density_gradient();
00373 void point(const PointInputData&, PointOutputData&);
00374
00375 };
00376
00377
00378
00379
00380 class NewP86CFunctional: public DenFunctional {
00381 protected:
00382 double a_;
00383 double C1_;
00384 double C2_;
00385 double C3_;
00386 double C4_;
00387 double C5_;
00388 double C6_;
00389 double C7_;
00390 void init_constants();
00391 double rho_deriv(double rho_a, double rho_b, double mdr);
00392 double gab_deriv(double rho_a, double rho_b, double mdr);
00393
00394 public:
00395 NewP86CFunctional();
00396 NewP86CFunctional(const Ref<KeyVal> &);
00397 NewP86CFunctional(StateIn &);
00398 ~NewP86CFunctional();
00399 void save_data_state(StateOut &);
00400 int need_density_gradient();
00401 void point(const PointInputData&, PointOutputData&);
00402 };
00403
00407 class SlaterXFunctional: public DenFunctional {
00408 protected:
00409 public:
00410 SlaterXFunctional();
00411 SlaterXFunctional(const Ref<KeyVal> &);
00412 SlaterXFunctional(StateIn &);
00413 ~SlaterXFunctional();
00414 void save_data_state(StateOut &);
00415 void point(const PointInputData&, PointOutputData&);
00416 };
00417
00425 class VWNLCFunctional: public LSDACFunctional {
00426 protected:
00427 double Ap_, Af_, A_alpha_;
00428 double x0p_mc_, bp_mc_, cp_mc_, x0f_mc_, bf_mc_, cf_mc_;
00429 double x0p_rpa_, bp_rpa_, cp_rpa_, x0f_rpa_, bf_rpa_, cf_rpa_;
00430 double x0_alpha_mc_, b_alpha_mc_, c_alpha_mc_;
00431 double x0_alpha_rpa_, b_alpha_rpa_, c_alpha_rpa_;
00432 void init_constants();
00433
00434 double F(double x, double A, double x0, double b, double c);
00435 double dFdr_s(double x, double A, double x0, double b, double c);
00436 public:
00437 VWNLCFunctional();
00438 VWNLCFunctional(const Ref<KeyVal> &);
00439 VWNLCFunctional(StateIn &);
00440 ~VWNLCFunctional();
00441 void save_data_state(StateOut &);
00442
00443 virtual
00444 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &);
00445 };
00446
00449 class VWN1LCFunctional: public VWNLCFunctional {
00450 protected:
00451 double x0p_, bp_, cp_, x0f_, bf_, cf_;
00452 public:
00454 VWN1LCFunctional();
00456 VWN1LCFunctional(int use_rpa);
00462 VWN1LCFunctional(const Ref<KeyVal> &);
00463 VWN1LCFunctional(StateIn &);
00464 ~VWN1LCFunctional();
00465 void save_data_state(StateOut &);
00466
00467 void point_lc(const PointInputData&, PointOutputData&,
00468 double &, double &, double &);
00469 };
00470
00473 class VWN2LCFunctional: public VWNLCFunctional {
00474 protected:
00475 public:
00477 VWN2LCFunctional();
00479 VWN2LCFunctional(const Ref<KeyVal> &);
00480 VWN2LCFunctional(StateIn &);
00481 ~VWN2LCFunctional();
00482 void save_data_state(StateOut &);
00483
00484 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &);
00485 };
00486
00487
00490 class VWN3LCFunctional: public VWNLCFunctional {
00491 protected:
00492 int monte_carlo_prefactor_;
00493 int monte_carlo_e0_;
00494 public:
00495 VWN3LCFunctional(int mcp = 1, int mce0 = 1);
00496 VWN3LCFunctional(const Ref<KeyVal> &);
00497 VWN3LCFunctional(StateIn &);
00498 ~VWN3LCFunctional();
00499 void save_data_state(StateOut &);
00500
00501 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &);
00502 };
00503
00506 class VWN4LCFunctional: public VWNLCFunctional {
00507 protected:
00508 int monte_carlo_prefactor_;
00509 public:
00510 VWN4LCFunctional();
00511 VWN4LCFunctional(const Ref<KeyVal> &);
00512 VWN4LCFunctional(StateIn &);
00513 ~VWN4LCFunctional();
00514 void save_data_state(StateOut &);
00515
00516 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &);
00517 };
00518
00521 class VWN5LCFunctional: public VWNLCFunctional {
00522 protected:
00523 public:
00524 VWN5LCFunctional();
00525 VWN5LCFunctional(const Ref<KeyVal> &);
00526 VWN5LCFunctional(StateIn &);
00527 ~VWN5LCFunctional();
00528 void save_data_state(StateOut &);
00529
00530 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &);
00531 };
00532
00538 class PW92LCFunctional: public LSDACFunctional {
00539 protected:
00540 double F(double x, double A, double alpha_1, double beta_1, double beta_2,
00541 double beta_3, double beta_4, double p);
00542 double dFdr_s(double x, double A, double alpha_1, double beta_1, double beta_2,
00543 double beta_3, double beta_4, double p);
00544 public:
00545 PW92LCFunctional();
00546 PW92LCFunctional(const Ref<KeyVal> &);
00547 PW92LCFunctional(StateIn &);
00548 ~PW92LCFunctional();
00549 void save_data_state(StateOut &);
00550
00551 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &);
00552 };
00553
00559 class PZ81LCFunctional: public LSDACFunctional {
00560 protected:
00561 double Fec_rsgt1(double rs, double beta_1, double beta_2, double gamma);
00562 double dFec_rsgt1_drho(double rs, double beta_1, double beta_2, double gamma,
00563 double &dec_drs);
00564 double Fec_rslt1(double rs, double A, double B, double C, double D);
00565 double dFec_rslt1_drho(double rs, double A, double B, double C, double D,
00566 double &dec_drs);
00567 public:
00568 PZ81LCFunctional();
00569 PZ81LCFunctional(const Ref<KeyVal> &);
00570 PZ81LCFunctional(StateIn &);
00571 ~PZ81LCFunctional();
00572 void save_data_state(StateOut &);
00573
00574 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &);
00575 };
00576
00578 class XalphaFunctional: public DenFunctional {
00579 protected:
00580 double alpha_;
00581 double factor_;
00582 public:
00583 XalphaFunctional();
00584 XalphaFunctional(const Ref<KeyVal> &);
00585 XalphaFunctional(StateIn &);
00586 ~XalphaFunctional();
00587 void save_data_state(StateOut &);
00588
00589 void point(const PointInputData&, PointOutputData&);
00590
00591 void print(std::ostream& =ExEnv::out0()) const;
00592 };
00593
00598 class Becke88XFunctional: public DenFunctional {
00599 protected:
00600 double beta_;
00601 double beta6_;
00602 public:
00603 Becke88XFunctional();
00604 Becke88XFunctional(const Ref<KeyVal> &);
00605 Becke88XFunctional(StateIn &);
00606 ~Becke88XFunctional();
00607 void save_data_state(StateOut &);
00608
00609 int need_density_gradient();
00610
00611 void point(const PointInputData&, PointOutputData&);
00612 };
00613
00622 class LYPCFunctional: public DenFunctional {
00623 protected:
00624 double a_;
00625 double b_;
00626 double c_;
00627 double d_;
00628 void init_constants();
00629 public:
00630 LYPCFunctional();
00631 LYPCFunctional(const Ref<KeyVal> &);
00632 LYPCFunctional(StateIn &);
00633 ~LYPCFunctional();
00634 void save_data_state(StateOut &);
00635
00636 int need_density_gradient();
00637
00638 void point(const PointInputData&, PointOutputData&);
00639 };
00640
00645 class PW86XFunctional: public DenFunctional {
00646 protected:
00647 double a_;
00648 double b_;
00649 double c_;
00650 double m_;
00651 void init_constants();
00652 public:
00653 PW86XFunctional();
00654 PW86XFunctional(const Ref<KeyVal> &);
00655 PW86XFunctional(StateIn &);
00656 ~PW86XFunctional();
00657 void save_data_state(StateOut &);
00658
00659 int need_density_gradient();
00660
00661 void point(const PointInputData&, PointOutputData&);
00662 };
00663
00679 class PBEXFunctional: public DenFunctional {
00680 protected:
00681 double mu;
00682 double kappa;
00683 void spin_contrib(const PointInputData::SpinData &,
00684 double &mpw, double &dmpw_dr, double &dmpw_dg);
00685 void init_constants();
00686 public:
00687 PBEXFunctional();
00688 PBEXFunctional(const Ref<KeyVal> &);
00689 PBEXFunctional(StateIn &);
00690 ~PBEXFunctional();
00691 void save_data_state(StateOut &);
00692
00693 int need_density_gradient();
00694
00695 void point(const PointInputData&, PointOutputData&);
00696 };
00697
00708 class PW91XFunctional: public DenFunctional {
00709 protected:
00710 double a;
00711 double b;
00712 double c;
00713 double d;
00714 double a_x;
00715 void spin_contrib(const PointInputData::SpinData &,
00716 double &mpw, double &dmpw_dr, double &dmpw_dg);
00717 void init_constants();
00718 public:
00719 PW91XFunctional();
00720 PW91XFunctional(const Ref<KeyVal> &);
00721 PW91XFunctional(StateIn &);
00722 ~PW91XFunctional();
00723 void save_data_state(StateOut &);
00724
00725 int need_density_gradient();
00726
00727 void point(const PointInputData&, PointOutputData&);
00728 };
00729
00734 class mPW91XFunctional: public DenFunctional {
00735 protected:
00736 double b;
00737 double beta;
00738 double c;
00739 double d;
00740 double a_x;
00741 double x_d_coef;
00742
00743 void spin_contrib(const PointInputData::SpinData &,
00744 double &mpw, double &dmpw_dr, double &dmpw_dg);
00745 public:
00746 enum Func { B88, PW91, mPW91 };
00747
00749 mPW91XFunctional();
00752 mPW91XFunctional(Func variant);
00771 mPW91XFunctional(const Ref<KeyVal> &);
00772 mPW91XFunctional(StateIn &);
00773 ~mPW91XFunctional();
00774 void save_data_state(StateOut &);
00775
00776 int need_density_gradient();
00777
00778 void point(const PointInputData&, PointOutputData&);
00779
00780 void init_constants(Func);
00781 };
00782
00787 class G96XFunctional: public DenFunctional {
00788 protected:
00789 double b_;
00790 void init_constants();
00791 public:
00792 G96XFunctional();
00793 G96XFunctional(const Ref<KeyVal> &);
00794 G96XFunctional(StateIn &);
00795 ~G96XFunctional();
00796 void save_data_state(StateOut &);
00797
00798 int need_density_gradient();
00799
00800 void point(const PointInputData&, PointOutputData&);
00801 };
00802
00803 }
00804
00805 #endif
00806
00807
00808
00809
00810