MPQC  3.0.0-alpha
src/lib/chemistry/qc/dft/functional.h
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:

Generated at Sat Jul 7 2012 11:52:44 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.8.0.