00001
00002 #include <util/misc/exenv.h>
00003
00004 #undef SCF_CHECK_BOUNDS
00005
00006 #ifdef SCF_CHECK_BOUNDS
00007 #define CHECK(ival,pval,ij,kl,con) check(ival,pval,ij,kl,con)
00008 #else
00009 #define CHECK(ival,pval,ij,kl,con)
00010 #endif
00011
00012 class LocalCLHFContribution {
00013 private:
00014 double * const gmat;
00015 double * const pmat;
00016
00017 double ibound_;
00018 double pbound_;
00019
00020 public:
00021 LocalCLHFContribution(double *g, double *p) : gmat(g), pmat(p) {}
00022 ~LocalCLHFContribution() {}
00023
00024 void set_bound(double i, double p) { ibound_ = i; pbound_ = p; }
00025 void check(double ival, double pval, int ij, int kl, const char *contrib)
00026 {
00027 int bad = 0;
00028 if ( 1.000001 * ibound_ < (ival > 0 ? ival : -ival)) {
00029 ExEnv::err() << "BAD INTEGRAL BOUND" << std::endl;
00030 ExEnv::err() << " bound = " << ibound_ << std::endl;
00031 ExEnv::err() << " value = " << ival << std::endl;
00032 bad = 1;
00033 }
00034 if ( 1.000001 * pbound_ < (pval > 0 ? pval : -pval)) {
00035 ExEnv::err() << "BAD DENSITY BOUND" << std::endl;
00036 ExEnv::err() << " bound = " << pbound_ << std::endl;
00037 ExEnv::err() << " value = " << pval << std::endl;
00038 bad = 1;
00039 }
00040 if (bad) {
00041 ExEnv::err() << " ij = " << ij << std::endl;
00042 ExEnv::err() << " kl = " << kl << std::endl;
00043 ExEnv::err() << " cont = " << contrib << std::endl;
00044 abort();
00045 }
00046 }
00047
00048 inline void cont1(int ij, int kl, double val) {
00049 gmat[ij] += val*pmat[kl]; CHECK(val,pmat[kl],ij,kl,"cont1a");
00050 gmat[kl] += val*pmat[ij]; CHECK(val,pmat[ij],ij,kl,"cont1b");
00051 }
00052
00053 inline void cont2(int ij, int kl, double val) {
00054 val *= -0.25;
00055 gmat[ij] += val*pmat[kl]; CHECK(4*val,0.25*pmat[kl],ij,kl,"cont2a");
00056 gmat[kl] += val*pmat[ij]; CHECK(4*val,0.25*pmat[ij],ij,kl,"cont2b");
00057 }
00058
00059 inline void cont3(int ij, int kl, double val) {
00060 val *= -0.5;
00061 gmat[ij] += val*pmat[kl]; CHECK(2*val,0.5*pmat[kl],ij,kl,"cont3a");
00062 gmat[kl] += val*pmat[ij]; CHECK(2*val,0.5*pmat[ij],ij,kl,"cont3b");
00063 }
00064
00065 inline void cont4(int ij, int kl, double val) {
00066 val *= 0.75;
00067 gmat[ij] += val*pmat[kl]; CHECK(4./3.*val,0.75*pmat[kl],ij,kl,"cont4a");
00068 gmat[kl] += val*pmat[ij]; CHECK(4./3.*val,0.75*pmat[ij],ij,kl,"cont4b");
00069 }
00070
00071 inline void cont5(int ij, int kl, double val) {
00072 val *= 0.5;
00073 gmat[ij] += val*pmat[kl]; CHECK(2*val,0.5*pmat[kl],ij,kl,"cont5a");
00074 gmat[kl] += val*pmat[ij]; CHECK(2*val,0.5*pmat[ij],ij,kl,"cont5b");
00075 }
00076 };
00077
00078 class LocalCLHFEnergyContribution {
00079 private:
00080 double * const pmat;
00081
00082 public:
00083 double ec;
00084 double ex;
00085
00086 void set_bound(double,double) {}
00087
00088 LocalCLHFEnergyContribution(double *p) : pmat(p) {
00089 ec=ex=0;
00090 }
00091 ~LocalCLHFEnergyContribution() {}
00092
00093 inline void cont1(int ij, int kl, double val) {
00094 ec += val*pmat[ij]*pmat[kl];
00095 }
00096
00097 inline void cont2(int ij, int kl, double val) {
00098 ex -= 0.25*val*pmat[ij]*pmat[kl];
00099 }
00100
00101 inline void cont3(int ij, int kl, double val) {
00102 ex -= 0.5*val*pmat[ij]*pmat[kl];
00103 }
00104
00105 inline void cont4(int ij, int kl, double val) {
00106 ec += val*pmat[ij]*pmat[kl];
00107 ex -= 0.25*val*pmat[ij]*pmat[kl];
00108 }
00109
00110 inline void cont5(int ij, int kl, double val) {
00111 ec += val*pmat[ij]*pmat[kl];
00112 ex -= 0.5*val*pmat[ij]*pmat[kl];
00113 }
00114 };
00115
00116 class LocalCLHFGradContribution {
00117 private:
00118 double * const pmat;
00119
00120 public:
00121 LocalCLHFGradContribution(double *p) : pmat(p) {}
00122 ~LocalCLHFGradContribution() {}
00123
00124 inline double cont1(int ij, int kl) {
00125 return pmat[ij]*pmat[kl];
00126 }
00127
00128 inline double cont2(int ij, int kl) {
00129 return pmat[ij]*pmat[kl];
00130 }
00131 };