⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lgbuild.h

📁 大型并行量子化学软件;支持密度泛函(DFT)。可以进行各种量子化学计算。支持CHARMM并行计算。非常具有应用价值。
💻 H
字号:
//// lgbuild.h --- definition of the local G matrix builder//// Copyright (C) 1996 Limit Point Systems, Inc.//// Author: Edward Seidl <seidl@janed.com>// Maintainer: LPS//// This file is part of the SC Toolkit.//// The SC Toolkit is free software; you can redistribute it and/or modify// it under the terms of the GNU Library General Public License as published by// the Free Software Foundation; either version 2, or (at your option)// any later version.//// The SC Toolkit is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU Library General Public License for more details.//// You should have received a copy of the GNU Library General Public License// along with the SC Toolkit; see the file COPYING.LIB.  If not, write to// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.//// The U.S. Government is granted a limited license as per AL 91-7.//#ifndef _chemistry_qc_scf_lgbuild_h#define _chemistry_qc_scf_lgbuild_h#ifdef __GNUC__#pragma interface#endif#undef SCF_CHECK_INTS#undef SCF_CHECK_BOUNDS#undef SCF_DONT_USE_BOUNDS#include <scconfig.h>#include <chemistry/qc/scf/gbuild.h>namespace sc {template<class T>class LocalGBuild : public GBuild<T> {  public:    double tnint;      protected:    MessageGrp *grp_;    TwoBodyInt *tbi_;    GaussianBasisSet *gbs_;    PetiteList *rpl_;    signed char * restrictxx pmax;    int threadno_;    int nthread_;    double accuracy_;      public:    LocalGBuild(T& t, const Ref<TwoBodyInt>& tbi, const Ref<PetiteList>& rpl,                const Ref<GaussianBasisSet>& bs, const Ref<MessageGrp>& g,                signed char *pm, double acc, int nt=1, int tn=0) :      GBuild<T>(t),      pmax(pm), nthread_(nt), threadno_(tn), accuracy_(acc)    {      grp_ = g.pointer();      tbi_ = tbi.pointer();      rpl_ = rpl.pointer();      gbs_ = bs.pointer();    }    ~LocalGBuild() {}    void run() {      int tol = (int) (log(accuracy_)/log(2.0));      int me=grp_->me();      int nproc = grp_->n();        // grab references for speed      GaussianBasisSet& gbs = *gbs_;      PetiteList& pl = *rpl_;      TwoBodyInt& tbi = *tbi_;      tbi.set_redundant(0);      const double *intbuf = tbi.buffer();      tnint=0;      sc_int_least64_t threadind=0;      sc_int_least64_t ijklind=0;      for (int i=0; i < gbs.nshell(); i++) {        if (!pl.in_p1(i))          continue;        int fi=gbs.shell_to_function(i);        int ni=gbs(i).nfunction();                for (int j=0; j <= i; j++) {          int oij = i_offset(i)+j;                    if (!pl.in_p2(oij))            continue;          int fj=gbs.shell_to_function(j);          int nj=gbs(j).nfunction();          int pmaxij = pmax[oij];          for (int k=0; k <= i; k++, ijklind++) {            if (ijklind%nproc != me)              continue;            threadind++;            if (threadind % nthread_ != threadno_)              continue;                        int fk=gbs.shell_to_function(k);            int nk=gbs(k).nfunction();            int pmaxijk=pmaxij, ptmp;            if ((ptmp=pmax[i_offset(i)+k]-1) > pmaxijk) pmaxijk=ptmp;            if ((ptmp=pmax[ij_offset(j,k)]-1) > pmaxijk) pmaxijk=ptmp;                    int okl = i_offset(k);            for (int l=0; l <= (k==i?j:k); l++,okl++) {              int pmaxijkl = pmaxijk;              if ((ptmp=pmax[okl]) > pmaxijkl) pmaxijkl=ptmp;              if ((ptmp=pmax[i_offset(i)+l]-1) > pmaxijkl) pmaxijkl=ptmp;              if ((ptmp=pmax[ij_offset(j,l)]-1) > pmaxijkl) pmaxijkl=ptmp;              int qijkl = pl.in_p4(oij,okl,i,j,k,l);              if (!qijkl)                continue;#ifdef SCF_CHECK_BOUNDS              double intbound = pow(2.0,double(tbi.log2_shell_bound(i,j,k,l)));              double pbound   = pow(2.0,double(pmaxijkl));              intbound *= qijkl;              GBuild<T>::contribution.set_bound(intbound, pbound);#else#  ifndef SCF_DONT_USE_BOUNDS              if (tbi.log2_shell_bound(i,j,k,l)+pmaxijkl < tol)                continue;#  endif#endif              //tim_enter_default();              tbi.compute_shell(i,j,k,l);              //tim_exit_default();              int e12 = (i==j);              int e34 = (k==l);              int e13e24 = (i==k) && (j==l);              int e_any = e12||e34||e13e24;                  int fl=gbs.shell_to_function(l);              int nl=gbs(l).nfunction();                   int ii,jj,kk,ll;              int I,J,K,L;              int index=0;              for (I=0, ii=fi; I < ni; I++, ii++) {                for (J=0, jj=fj; J <= (e12 ? I : nj-1); J++, jj++) {                  for (K=0, kk=fk; K <= (e13e24 ? I : nk-1); K++, kk++) {                    int lend = (e34 ? ((e13e24)&&(K==I) ? J : K)                                : ((e13e24)&&(K==I)) ? J : nl-1);                    for (L=0, ll=fl; L <= lend; L++, ll++, index++) {                      double pki_int = intbuf[index];                      if ((pki_int>0?pki_int:-pki_int) < 1.0e-15)                        continue;#ifdef SCF_CHECK_INTS                      if (isnan(pki_int))                        abort();#endif                                            if (qijkl > 1)                        pki_int *= qijkl;      if (e_any) {        int ij,kl;        double val;        if (jj == kk) {          /*           * if i=j=k or j=k=l, then this integral contributes           * to J, K1, and K2 of G(ij), so           * pkval = (ijkl) - 0.25 * ((ikjl)-(ilkj))           *       = 0.5 * (ijkl)           */          if (ii == jj || kk == ll) {            ij = i_offset(ii)+jj;            kl = i_offset(kk)+ll;            val = (ij==kl) ? 0.5*pki_int : pki_int;            GBuild<T>::contribution.cont5(ij,kl,val);          } else {            /*             * if j=k, then this integral contributes             * to J and K1 of G(ij)             *             * pkval = (ijkl) - 0.25 * (ikjl)             *       = 0.75 * (ijkl)             */            ij = i_offset(ii)+jj;            kl = i_offset(kk)+ll;            val = (ij==kl) ? 0.5*pki_int : pki_int;                        GBuild<T>::contribution.cont4(ij,kl,val);            /*             * this integral also contributes to K1 and K2 of             * G(il)             *             * pkval = -0.25 * ((ijkl)+(ikjl))             *       = -0.5 * (ijkl)             */            ij = ij_offset(ii,ll);            kl = ij_offset(kk,jj);            val = (ij==kl) ? 0.5*pki_int : pki_int;                        GBuild<T>::contribution.cont3(ij,kl,val);          }        } else if (ii == kk || jj == ll) {          /*           * if i=k or j=l, then this integral contributes           * to J and K2 of G(ij)           *           * pkval = (ijkl) - 0.25 * (ilkj)           *       = 0.75 * (ijkl)           */          ij = i_offset(ii)+jj;          kl = i_offset(kk)+ll;          val = (ij==kl) ? 0.5*pki_int : pki_int;          GBuild<T>::contribution.cont4(ij,kl,val);          /*           * this integral also contributes to K1 and K2 of           * G(ik)           *           * pkval = -0.25 * ((ijkl)+(ilkj))           *       = -0.5 * (ijkl)           */          ij = ij_offset(ii,kk);          kl = ij_offset(jj,ll);          val = (ij==kl) ? 0.5*pki_int : pki_int;          GBuild<T>::contribution.cont3(ij,kl,val);        } else {          /*           * This integral contributes to J of G(ij)           *           * pkval = (ijkl)           */          ij = i_offset(ii)+jj;          kl = i_offset(kk)+ll;          val = (ij==kl) ? 0.5*pki_int : pki_int;          GBuild<T>::contribution.cont1(ij,kl,val);          /*           * and to K1 of G(ik)           *           * pkval = -0.25 * (ijkl)           */          ij = ij_offset(ii,kk);          kl = ij_offset(jj,ll);          val = (ij==kl) ? 0.5*pki_int : pki_int;          GBuild<T>::contribution.cont2(ij,kl,val);          if ((ii != jj) && (kk != ll)) {            /*             * if i!=j and k!=l, then this integral also             * contributes to K2 of G(il)             *             * pkval = -0.25 * (ijkl)             *             * note: if we get here, then ik can't equal jl,             * so pkval wasn't multiplied by 0.5 above.             */            ij = ij_offset(ii,ll);            kl = ij_offset(kk,jj);            GBuild<T>::contribution.cont2(ij,kl,val);          }        }      } else { // !e_any        if (jj == kk) {          /*           * if j=k, then this integral contributes           * to J and K1 of G(ij)           *           * pkval = (ijkl) - 0.25 * (ikjl)           *       = 0.75 * (ijkl)           */          GBuild<T>::contribution.cont4(i_offset(ii)+jj,i_offset(kk)+ll,pki_int);          /*           * this integral also contributes to K1 and K2 of           * G(il)           *           * pkval = -0.25 * ((ijkl)+(ikjl))           *       = -0.5 * (ijkl)           */          GBuild<T>::contribution.cont3(ij_offset(ii,ll),ij_offset(kk,jj),pki_int);        } else if (ii == kk || jj == ll) {          /*           * if i=k or j=l, then this integral contributes           * to J and K2 of G(ij)           *           * pkval = (ijkl) - 0.25 * (ilkj)           *       = 0.75 * (ijkl)           */          GBuild<T>::contribution.cont4(i_offset(ii)+jj,i_offset(kk)+ll,pki_int);          /*           * this integral also contributes to K1 and K2 of           * G(ik)           *           * pkval = -0.25 * ((ijkl)+(ilkj))           *       = -0.5 * (ijkl)           */          GBuild<T>::contribution.cont3(ij_offset(ii,kk),ij_offset(jj,ll),pki_int);        } else {          /*           * This integral contributes to J of G(ij)           *           * pkval = (ijkl)           */          GBuild<T>::contribution.cont1(i_offset(ii)+jj,i_offset(kk)+ll,pki_int);          /*           * and to K1 of G(ik)           *           * pkval = -0.25 * (ijkl)           */          GBuild<T>::contribution.cont2(ij_offset(ii,kk),ij_offset(jj,ll),pki_int);          /*           * and to K2 of G(il)           *           * pkval = -0.25 * (ijkl)           */          GBuild<T>::contribution.cont2(ij_offset(ii,ll),ij_offset(kk,jj),pki_int);        }      }                    }                  }                }              }              tnint += (double) ni*nj*nk*nl;            }          }        }      }    }};}#endif// Local Variables:// mode: c++// c-file-style: "ETS"// End:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -