Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

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 #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         // rho^(1/3)
00048         double rho_13;
00049 
00050         double del_rho[3];
00051         // gamma = (del rho).(del rho)
00052         double gamma;
00053 
00054         // hessian of rho
00055         double hes_rho[6];
00056         // del^2 rho
00057         double lap_rho;
00058     };
00059     SpinData a, b;
00060 
00061     // gamma_ab = (del rho_a).(del rho_b)
00062     double gamma_ab;
00063 
00064     const SCVector3 &r;
00065 
00066     // fill in derived quantities
00067     void compute_derived(int spin_polarized, int need_gradient);
00068 
00069     PointInputData(const SCVector3& r_): r(r_) {}
00070 };
00071 
00073 struct PointOutputData {
00074     // energy at r
00075     double energy;
00076 
00077     // derivative of functional wrt density
00078     double df_drho_a;
00079     double df_drho_b;
00080 
00081     // derivative of functional wrt density gradient
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_;  // for ACM functionals
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     // Set to zero if dens_alpha == dens_beta everywhere.
00107     // The default is false.
00108     virtual void set_spin_polarized(int i);
00109     // Set to nonzero if the potential should be computed.
00110     // The default is false.
00111     virtual void set_compute_potential(int i);
00112 
00113     // Must return 1 if the density gradient must also be provided.
00114     // The default implementation returns 0.
00115     virtual int need_density_gradient();
00116     // Must return 1 if the density hessian must also be provided.
00117     // The default implementation returns 0.
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 // The Perdew 1986 (P86) Correlation Functional computes energies and densities
00379 //    using the designated local correlation functional.
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 // Local Variables:
00808 // mode: c++
00809 // c-file-style: "CLJ"
00810 // End:

Generated at Tue Jun 14 10:27:56 2005 for MPQC 2.2.3 using the documentation package Doxygen 1.4.3-20050530.