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

Generated at Thu Oct 4 18:08:44 2001 for MPQC 2.0.0 using the documentation package Doxygen 1.2.5.