# 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: