|
MPQC
3.0.0-alpha
|
00001 // 00002 // functional.h --- definition of the dft functional 00003 // 00004 // Copyright (C) 1997 Limit Point Systems, Inc. 00005 // 00006 // Author: Curtis Janssen <cljanss@limitpt.com> 00007 // Maintainer: LPS 00008 // 00009 // This file is part of the SC Toolkit. 00010 // 00011 // The SC Toolkit is free software; you can redistribute it and/or modify 00012 // it under the terms of the GNU Library General Public License as published by 00013 // the Free Software Foundation; either version 2, or (at your option) 00014 // any later version. 00015 // 00016 // The SC Toolkit is distributed in the hope that it will be useful, 00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 // GNU Library General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU Library General Public License 00022 // along with the SC Toolkit; see the file COPYING.LIB. If not, write to 00023 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 00024 // 00025 // The U.S. Government is granted a limited license as per AL 91-7. 00026 // 00027 00028 #ifndef _chemistry_qc_dft_functional_h 00029 #define _chemistry_qc_dft_functional_h 00030 00031 #include <util/state/state.h> 00032 #include <math/scmat/vector3.h> 00033 #include <chemistry/qc/wfn/wfn.h> 00034 #include <chemistry/qc/wfn/density.h> 00035 00036 namespace sc { 00037 00039 struct PointInputData { 00040 enum {X=BatchElectronDensity::X, 00041 Y=BatchElectronDensity::Y, 00042 Z=BatchElectronDensity::Z}; 00043 enum {XX=BatchElectronDensity::XX, 00044 YX=BatchElectronDensity::YX, 00045 YY=BatchElectronDensity::YY, 00046 ZX=BatchElectronDensity::ZX, 00047 ZY=BatchElectronDensity::ZY, 00048 ZZ=BatchElectronDensity::ZZ}; 00049 struct SpinData { 00050 double rho; 00051 // rho^(1/3) 00052 double rho_13; 00053 00054 double del_rho[3]; 00055 // gamma = (del rho).(del rho) 00056 double gamma; 00057 00058 // hessian of rho 00059 double hes_rho[6]; 00060 // del^2 rho 00061 double lap_rho; 00062 }; 00063 SpinData a, b; 00064 00065 // gamma_ab = (del rho_a).(del rho_b) 00066 double gamma_ab; 00067 00068 const SCVector3 &r; 00069 00070 // fill in derived quantities 00071 void compute_derived(int spin_polarized, 00072 int need_gradient, 00073 int need_hessian); 00074 00075 PointInputData(const SCVector3& r_): r(r_) {} 00076 }; 00077 00079 struct PointOutputData { 00080 // energy at r 00081 double energy; 00082 00083 // derivative of functional wrt density 00084 double df_drho_a; 00085 double df_drho_b; 00086 00087 // derivative of functional wrt density gradient 00088 double df_dgamma_aa; 00089 double df_dgamma_bb; 00090 double df_dgamma_ab; 00091 00092 void zero(){energy=df_drho_a=df_drho_b=df_dgamma_aa=df_dgamma_bb=df_dgamma_ab=0.0;} 00093 00094 }; 00095 00097 class DenFunctional: virtual public SavableState { 00098 protected: 00099 int spin_polarized_; 00100 int compute_potential_; 00101 double a0_; // for ACM functionals 00102 00103 void do_fd_point(PointInputData&id,double&in,double&out, 00104 double lower_bound, double upper_bound); 00105 public: 00106 DenFunctional(); 00107 DenFunctional(const Ref<KeyVal> &); 00108 DenFunctional(StateIn &); 00109 virtual ~DenFunctional(); 00110 void save_data_state(StateOut &); 00111 00112 // Set to zero if dens_alpha == dens_beta everywhere. 00113 // The default is false. 00114 virtual void set_spin_polarized(int i); 00115 // Set to nonzero if the potential should be computed. 00116 // The default is false. 00117 virtual void set_compute_potential(int i); 00118 00119 // Must return 1 if the density gradient must also be provided. 00120 // The default implementation returns 0. 00121 virtual int need_density_gradient(); 00122 // Must return 1 if the density hessian must also be provided. 00123 // The default implementation returns 0. 00124 virtual int need_density_hessian(); 00125 00126 virtual void point(const PointInputData&, PointOutputData&) = 0; 00127 void gradient(const PointInputData&, PointOutputData&, 00128 double *gradient, int acenter, 00129 GaussianBasisSet *basis, 00130 const double *dmat_a, const double *dmat_b, 00131 int ncontrib, const int *contrib, 00132 int ncontrib_bf, const int *contrib_bf, 00133 const double *bs_values, const double *bsg_values, 00134 const double *bsh_values); 00135 00137 virtual double a0() const; 00138 00139 void fd_point(const PointInputData&, PointOutputData&); 00140 int test(const PointInputData &); 00141 int test(); 00142 }; 00143 00144 00147 class NElFunctional: public DenFunctional { 00148 public: 00149 NElFunctional(); 00150 NElFunctional(const Ref<KeyVal> &); 00151 NElFunctional(StateIn &); 00152 ~NElFunctional(); 00153 void save_data_state(StateOut &); 00154 00155 void point(const PointInputData&, PointOutputData&); 00156 }; 00157 00160 class SumDenFunctional: public DenFunctional { 00161 protected: 00162 int n_; 00163 Ref<DenFunctional> *funcs_; 00164 double *coefs_; 00165 public: 00166 SumDenFunctional(); 00194 SumDenFunctional(const Ref<KeyVal> &); 00195 SumDenFunctional(StateIn &); 00196 ~SumDenFunctional(); 00197 void save_data_state(StateOut &); 00198 00199 void set_spin_polarized(int); 00200 void set_compute_potential(int); 00201 int need_density_gradient(); 00202 00203 void point(const PointInputData&, PointOutputData&); 00204 00205 void print(std::ostream& =ExEnv::out0()) const; 00206 00209 double a0() const; 00210 }; 00211 00284 class StdDenFunctional: public SumDenFunctional { 00285 protected: 00286 std::string name_; 00287 void init_arrays(int n); 00288 public: 00289 StdDenFunctional(); 00294 StdDenFunctional(const Ref<KeyVal> &); 00295 StdDenFunctional(StateIn &); 00296 ~StdDenFunctional(); 00297 void save_data_state(StateOut &); 00298 00299 void print(std::ostream& =ExEnv::out0()) const; 00300 }; 00301 00303 class LSDACFunctional: public DenFunctional { 00304 protected: 00305 public: 00306 LSDACFunctional(); 00307 LSDACFunctional(const Ref<KeyVal> &); 00308 LSDACFunctional(StateIn &); 00309 ~LSDACFunctional(); 00310 void save_data_state(StateOut &); 00311 00312 void point(const PointInputData&, PointOutputData&); 00313 virtual 00314 void point_lc(const PointInputData&, PointOutputData&, 00315 double &ec_local, double &decrs, double &deczeta) = 0; 00316 00317 }; 00318 00319 00328 class PBECFunctional: public DenFunctional { 00329 protected: 00330 Ref<LSDACFunctional> local_; 00331 double gamma; 00332 double beta; 00333 void init_constants(); 00334 double rho_deriv(double rho_a, double rho_b, double mdr, 00335 double ec_local, double ec_local_dra); 00336 double gab_deriv(double rho, double phi, double mdr, double ec_local); 00337 public: 00338 PBECFunctional(); 00339 PBECFunctional(const Ref<KeyVal> &); 00340 PBECFunctional(StateIn &); 00341 ~PBECFunctional(); 00342 void save_data_state(StateOut &); 00343 int need_density_gradient(); 00344 void point(const PointInputData&, PointOutputData&); 00345 void set_spin_polarized(int); 00346 00347 }; 00348 00359 class PW91CFunctional: public DenFunctional { 00360 protected: 00361 Ref<LSDACFunctional> local_; 00362 double a; 00363 double b; 00364 double c; 00365 double d; 00366 double alpha; 00367 double c_c0; 00368 double c_x; 00369 double nu; 00370 void init_constants(); 00371 double limit_df_drhoa(double rhoa, double gamma, 00372 double ec, double decdrhoa); 00373 00374 public: 00375 PW91CFunctional(); 00376 PW91CFunctional(const Ref<KeyVal> &); 00377 PW91CFunctional(StateIn &); 00378 ~PW91CFunctional(); 00379 void save_data_state(StateOut &); 00380 int need_density_gradient(); 00381 00382 void point(const PointInputData&, PointOutputData&); 00383 void set_spin_polarized(int); 00384 00385 }; 00386 00393 class P86CFunctional: public DenFunctional { 00394 protected: 00395 double a_; 00396 double C1_; 00397 double C2_; 00398 double C3_; 00399 double C4_; 00400 double C5_; 00401 double C6_; 00402 double C7_; 00403 void init_constants(); 00404 public: 00405 P86CFunctional(); 00406 P86CFunctional(const Ref<KeyVal> &); 00407 P86CFunctional(StateIn &); 00408 ~P86CFunctional(); 00409 void save_data_state(StateOut &); 00410 int need_density_gradient(); 00411 void point(const PointInputData&, PointOutputData&); 00412 00413 }; 00414 00415 00416 // The Perdew 1986 (P86) Correlation Functional computes energies and densities 00417 // using the designated local correlation functional. 00418 class NewP86CFunctional: public DenFunctional { 00419 protected: 00420 double a_; 00421 double C1_; 00422 double C2_; 00423 double C3_; 00424 double C4_; 00425 double C5_; 00426 double C6_; 00427 double C7_; 00428 void init_constants(); 00429 double rho_deriv(double rho_a, double rho_b, double mdr); 00430 double gab_deriv(double rho_a, double rho_b, double mdr); 00431 00432 public: 00433 NewP86CFunctional(); 00434 NewP86CFunctional(const Ref<KeyVal> &); 00435 NewP86CFunctional(StateIn &); 00436 ~NewP86CFunctional(); 00437 void save_data_state(StateOut &); 00438 int need_density_gradient(); 00439 void point(const PointInputData&, PointOutputData&); 00440 }; 00441 00445 class SlaterXFunctional: public DenFunctional { 00446 protected: 00447 public: 00448 SlaterXFunctional(); 00449 SlaterXFunctional(const Ref<KeyVal> &); 00450 SlaterXFunctional(StateIn &); 00451 ~SlaterXFunctional(); 00452 void save_data_state(StateOut &); 00453 void point(const PointInputData&, PointOutputData&); 00454 }; 00455 00463 class VWNLCFunctional: public LSDACFunctional { 00464 protected: 00465 double Ap_, Af_, A_alpha_; 00466 double x0p_mc_, bp_mc_, cp_mc_, x0f_mc_, bf_mc_, cf_mc_; 00467 double x0p_rpa_, bp_rpa_, cp_rpa_, x0f_rpa_, bf_rpa_, cf_rpa_; 00468 double x0_alpha_mc_, b_alpha_mc_, c_alpha_mc_; 00469 double x0_alpha_rpa_, b_alpha_rpa_, c_alpha_rpa_; 00470 void init_constants(); 00471 00472 double F(double x, double A, double x0, double b, double c); 00473 double dFdr_s(double x, double A, double x0, double b, double c); 00474 public: 00475 VWNLCFunctional(); 00476 VWNLCFunctional(const Ref<KeyVal> &); 00477 VWNLCFunctional(StateIn &); 00478 ~VWNLCFunctional(); 00479 void save_data_state(StateOut &); 00480 00481 virtual 00482 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &); 00483 }; 00484 00487 class VWN1LCFunctional: public VWNLCFunctional { 00488 protected: 00489 double x0p_, bp_, cp_, x0f_, bf_, cf_; 00490 public: 00492 VWN1LCFunctional(); 00494 VWN1LCFunctional(int use_rpa); 00500 VWN1LCFunctional(const Ref<KeyVal> &); 00501 VWN1LCFunctional(StateIn &); 00502 ~VWN1LCFunctional(); 00503 void save_data_state(StateOut &); 00504 00505 void point_lc(const PointInputData&, PointOutputData&, 00506 double &, double &, double &); 00507 }; 00508 00511 class VWN2LCFunctional: public VWNLCFunctional { 00512 protected: 00513 public: 00515 VWN2LCFunctional(); 00517 VWN2LCFunctional(const Ref<KeyVal> &); 00518 VWN2LCFunctional(StateIn &); 00519 ~VWN2LCFunctional(); 00520 void save_data_state(StateOut &); 00521 00522 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &); 00523 }; 00524 00525 00528 class VWN3LCFunctional: public VWNLCFunctional { 00529 protected: 00530 int monte_carlo_prefactor_; 00531 int monte_carlo_e0_; 00532 public: 00533 VWN3LCFunctional(int mcp = 1, int mce0 = 1); 00534 VWN3LCFunctional(const Ref<KeyVal> &); 00535 VWN3LCFunctional(StateIn &); 00536 ~VWN3LCFunctional(); 00537 void save_data_state(StateOut &); 00538 00539 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &); 00540 }; 00541 00544 class VWN4LCFunctional: public VWNLCFunctional { 00545 protected: 00546 int monte_carlo_prefactor_; 00547 public: 00548 VWN4LCFunctional(); 00549 VWN4LCFunctional(const Ref<KeyVal> &); 00550 VWN4LCFunctional(StateIn &); 00551 ~VWN4LCFunctional(); 00552 void save_data_state(StateOut &); 00553 00554 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &); 00555 }; 00556 00559 class VWN5LCFunctional: public VWNLCFunctional { 00560 protected: 00561 public: 00562 VWN5LCFunctional(); 00563 VWN5LCFunctional(const Ref<KeyVal> &); 00564 VWN5LCFunctional(StateIn &); 00565 ~VWN5LCFunctional(); 00566 void save_data_state(StateOut &); 00567 00568 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &); 00569 }; 00570 00576 class PW92LCFunctional: public LSDACFunctional { 00577 protected: 00578 double F(double x, double A, double alpha_1, double beta_1, double beta_2, 00579 double beta_3, double beta_4, double p); 00580 double dFdr_s(double x, double A, double alpha_1, double beta_1, double beta_2, 00581 double beta_3, double beta_4, double p); 00582 public: 00583 PW92LCFunctional(); 00584 PW92LCFunctional(const Ref<KeyVal> &); 00585 PW92LCFunctional(StateIn &); 00586 ~PW92LCFunctional(); 00587 void save_data_state(StateOut &); 00588 00589 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &); 00590 }; 00591 00597 class PZ81LCFunctional: public LSDACFunctional { 00598 protected: 00599 double Fec_rsgt1(double rs, double beta_1, double beta_2, double gamma); 00600 double dFec_rsgt1_drho(double rs, double beta_1, double beta_2, double gamma, 00601 double &dec_drs); 00602 double Fec_rslt1(double rs, double A, double B, double C, double D); 00603 double dFec_rslt1_drho(double rs, double A, double B, double C, double D, 00604 double &dec_drs); 00605 public: 00606 PZ81LCFunctional(); 00607 PZ81LCFunctional(const Ref<KeyVal> &); 00608 PZ81LCFunctional(StateIn &); 00609 ~PZ81LCFunctional(); 00610 void save_data_state(StateOut &); 00611 00612 void point_lc(const PointInputData&, PointOutputData&, double &, double &, double &); 00613 }; 00614 00616 class XalphaFunctional: public DenFunctional { 00617 protected: 00618 double alpha_; 00619 double factor_; 00620 public: 00621 XalphaFunctional(); 00622 XalphaFunctional(const Ref<KeyVal> &); 00623 XalphaFunctional(StateIn &); 00624 ~XalphaFunctional(); 00625 void save_data_state(StateOut &); 00626 00627 void point(const PointInputData&, PointOutputData&); 00628 00629 void print(std::ostream& =ExEnv::out0()) const; 00630 }; 00631 00636 class Becke88XFunctional: public DenFunctional { 00637 protected: 00638 double beta_; 00639 double beta6_; 00640 public: 00641 Becke88XFunctional(); 00642 Becke88XFunctional(const Ref<KeyVal> &); 00643 Becke88XFunctional(StateIn &); 00644 ~Becke88XFunctional(); 00645 void save_data_state(StateOut &); 00646 00647 int need_density_gradient(); 00648 00649 void point(const PointInputData&, PointOutputData&); 00650 }; 00651 00660 class LYPCFunctional: public DenFunctional { 00661 protected: 00662 double a_; 00663 double b_; 00664 double c_; 00665 double d_; 00666 void init_constants(); 00667 public: 00668 LYPCFunctional(); 00669 LYPCFunctional(const Ref<KeyVal> &); 00670 LYPCFunctional(StateIn &); 00671 ~LYPCFunctional(); 00672 void save_data_state(StateOut &); 00673 00674 int need_density_gradient(); 00675 00676 void point(const PointInputData&, PointOutputData&); 00677 }; 00678 00683 class PW86XFunctional: public DenFunctional { 00684 protected: 00685 double a_; 00686 double b_; 00687 double c_; 00688 double m_; 00689 void init_constants(); 00690 public: 00691 PW86XFunctional(); 00692 PW86XFunctional(const Ref<KeyVal> &); 00693 PW86XFunctional(StateIn &); 00694 ~PW86XFunctional(); 00695 void save_data_state(StateOut &); 00696 00697 int need_density_gradient(); 00698 00699 void point(const PointInputData&, PointOutputData&); 00700 }; 00701 00717 class PBEXFunctional: public DenFunctional { 00718 protected: 00719 double mu; 00720 double kappa; 00721 void spin_contrib(const PointInputData::SpinData &, 00722 double &mpw, double &dmpw_dr, double &dmpw_dg); 00723 void init_constants(); 00724 public: 00725 PBEXFunctional(); 00726 PBEXFunctional(const Ref<KeyVal> &); 00727 PBEXFunctional(StateIn &); 00728 ~PBEXFunctional(); 00729 void save_data_state(StateOut &); 00730 00731 int need_density_gradient(); 00732 00733 void point(const PointInputData&, PointOutputData&); 00734 }; 00735 00746 class PW91XFunctional: public DenFunctional { 00747 protected: 00748 double a; 00749 double b; 00750 double c; 00751 double d; 00752 double a_x; 00753 void spin_contrib(const PointInputData::SpinData &, 00754 double &mpw, double &dmpw_dr, double &dmpw_dg); 00755 void init_constants(); 00756 public: 00757 PW91XFunctional(); 00758 PW91XFunctional(const Ref<KeyVal> &); 00759 PW91XFunctional(StateIn &); 00760 ~PW91XFunctional(); 00761 void save_data_state(StateOut &); 00762 00763 int need_density_gradient(); 00764 00765 void point(const PointInputData&, PointOutputData&); 00766 }; 00767 00772 class mPW91XFunctional: public DenFunctional { 00773 protected: 00774 double b; 00775 double beta; 00776 double c; 00777 double d; 00778 double a_x; 00779 double x_d_coef; 00780 00781 void spin_contrib(const PointInputData::SpinData &, 00782 double &mpw, double &dmpw_dr, double &dmpw_dg); 00783 public: 00784 enum Func { B88, PW91, mPW91 }; 00785 00787 mPW91XFunctional(); 00790 mPW91XFunctional(Func variant); 00809 mPW91XFunctional(const Ref<KeyVal> &); 00810 mPW91XFunctional(StateIn &); 00811 ~mPW91XFunctional(); 00812 void save_data_state(StateOut &); 00813 00814 int need_density_gradient(); 00815 00816 void point(const PointInputData&, PointOutputData&); 00817 00818 void init_constants(Func); 00819 }; 00820 00825 class G96XFunctional: public DenFunctional { 00826 protected: 00827 double b_; 00828 void init_constants(); 00829 public: 00830 G96XFunctional(); 00831 G96XFunctional(const Ref<KeyVal> &); 00832 G96XFunctional(StateIn &); 00833 ~G96XFunctional(); 00834 void save_data_state(StateOut &); 00835 00836 int need_density_gradient(); 00837 00838 void point(const PointInputData&, PointOutputData&); 00839 }; 00840 00841 } 00842 00843 #endif 00844 00845 // Local Variables: 00846 // mode: c++ 00847 // c-file-style: "CLJ" 00848 // End: