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

📄 csgrads2pdm.cc

📁 大型并行量子化学软件;支持密度泛函(DFT)。可以进行各种量子化学计算。支持CHARMM并行计算。非常具有应用价值。
💻 CC
字号:
//// csgrads2pdm.cc// based on csgrad.cc//// Copyright (C) 1996 Limit Point Systems, Inc.//// Author: Ida Nielsen <ida@kemi.aau.dk>// 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.//#ifdef __GNUC__#pragma implementation#endif#include <stdlib.h>#include <math.h>#include <limits.h>#include <util/misc/formio.h>#include <util/group/message.h>#include <chemistry/qc/mbpt/csgrads2pdm.h>#include <chemistry/qc/mbpt/distsh.h>using namespace sc;CSGradS2PDM::CSGradS2PDM(int mythread_a, int nthread_a,                         int me_a, int nproc_a,                         const Ref<ThreadLock> &lock_a,                         const Ref<GaussianBasisSet> &basis_a,                         const Ref<TwoBodyDerivInt> &tbintder_a,                         const double *PHF_a, const double *P2AO_a,                         int tol_a, int debug_a, int dynamic_a){  mythread = mythread_a;  nthread = nthread_a;  me = me_a;  nproc = nproc_a;  lock = lock_a;  basis = basis_a;  tbintder = tbintder_a;  PHF = PHF_a;  P2AO = P2AO_a;  tol = tol_a;  debug = debug_a;  dynamic = dynamic_a;  int natom = basis->molecule()->natom();  ginter = new double*[natom];  ginter[0] = new double[natom*3];  hf_ginter = new double*[natom];  hf_ginter[0] = new double[natom*3];  for (int i=0; i<natom; i++) {    ginter[i] = &ginter[0][i*3];    hf_ginter[i] = &hf_ginter[0][i*3];    for (int j=0; j<3; j++) {      ginter[i][j] = 0.0;      hf_ginter[i][j] = 0.0;      }    }}CSGradS2PDM::~CSGradS2PDM(){  delete[] ginter[0];  delete[] ginter;  delete[] hf_ginter[0];  delete[] hf_ginter;}voidCSGradS2PDM::accum_contrib(double **sum, double **contribs){  int natom = basis->molecule()->natom();  for (int i=0; i<natom; i++) {    for (int j=0; j<3; j++) {      sum[i][j] += contribs[i][j];      }    }}voidCSGradS2PDM::accum_mp2_contrib(double **ginter_a){  accum_contrib(ginter_a, ginter);}voidCSGradS2PDM::accum_hf_contrib(double **hf_ginter_a){  accum_contrib(hf_ginter_a, hf_ginter);}//////////////////////////////////////////////////////////////// Compute (in the AO basis) the contribution to the gradient // from the separable part of the two particle density matrix//////////////////////////////////////////////////////////////voidCSGradS2PDM::run(){                 int P, Q, R, S;  int QP, SR;  int p, q, r;  int np, nq, nr, ns;  int p_offset, q_offset, r_offset, s_offset;  int bf1, bf2, bf3, bf4;  int xyz;  int derset;  int nshell = basis->nshell();  int nbasis = basis->nbasis();  double *grad_ptr1, *grad_ptr2;  double *hf_grad_ptr1, *hf_grad_ptr2;  double tmpval;  const double *phf_pq, *phf_pr, *phf_ps, *phf_qr, *phf_qs, *phf_rs;  const double *p2ao_pq, *p2ao_pr, *p2ao_ps, *p2ao_qr, *p2ao_qs, *p2ao_rs;  double k_QP, k_SR, k_QPSR; // factors needed since we loop over nonredund                             // shell quartets but do redund integrals within                             // shell quartets when applicable  double gamma_factor; // factor multiplying integrals; needed because we                       // loop over nonredund shell quarters but do redund                       // integrals within shell quartets when applicable  double *gammasym_pqrs; // symmetrized sep. 2PDM  double *gammasym_ptr;  double *hf_gammasym_pqrs; // HF only versions of gammsym  double *hf_gammasym_ptr;  const double *integral_ptr;  int nfuncmax = basis->max_nfunction_in_shell();  const double *intderbuf = tbintder->buffer();  gammasym_pqrs = new double[nfuncmax*nfuncmax*nfuncmax*nfuncmax];  hf_gammasym_pqrs = new double[nfuncmax*nfuncmax*nfuncmax*nfuncmax];  DerivCenters der_centers;  int index = 0;  int threadindex = 0;  for (Q=0; Q<nshell; Q++) {    nq = basis->shell(Q).nfunction();    q_offset = basis->shell_to_function(Q);    for (S=0; S<=Q; S++) {      ns = basis->shell(S).nfunction();      s_offset = basis->shell_to_function(S);      for (R=0; R<=S; R++) {        nr = basis->shell(R).nfunction();        r_offset = basis->shell_to_function(R);        k_SR = (R == S ? 0.5 : 1.0);        SR = S*(S+1)/2 + R;        for (P=0; P<=(S==Q ? R:Q); P++) {          // If integral derivative is 0, skip to next P          if (tbintder->log2_shell_bound(P,Q,R,S) < tol) continue;          if (index++%nproc == me && threadindex++%nthread == mythread) {            np = basis->shell(P).nfunction();            p_offset = basis->shell_to_function(P);            k_QP = (P == Q ? 0.5 : 1.0);            QP = Q*(Q+1)/2 + P;            k_QPSR = (QP == SR ? 0.5 : 1.0);            gamma_factor = k_QP*k_SR*k_QPSR;            // Evaluate derivative integrals            tbintder->compute_shell(P,Q,R,S,der_centers);            //////////////////////////////            // Symmetrize sep. 2PDM            //////////////////////////////            gammasym_ptr = gammasym_pqrs;            hf_gammasym_ptr = hf_gammasym_pqrs;            for (bf1=0; bf1<np; bf1++) {              p = p_offset + bf1;              phf_pq =  &PHF [p*nbasis + q_offset];              p2ao_pq = &P2AO[p*nbasis + q_offset];              for (bf2=0; bf2<nq; bf2++) {                q = q_offset + bf2;                phf_pr =  &PHF [p*nbasis + r_offset];                p2ao_pr = &P2AO[p*nbasis + r_offset];                phf_qr =  &PHF [q*nbasis + r_offset];                p2ao_qr = &P2AO[q*nbasis + r_offset];                for (bf3=0; bf3<nr; bf3++) {                  r = r_offset + bf3;                  phf_ps =  &PHF [p*nbasis + s_offset];                  phf_qs =  &PHF [q*nbasis + s_offset];                  phf_rs =  &PHF [r*nbasis + s_offset];                  p2ao_ps = &P2AO[p*nbasis + s_offset];                  p2ao_qs = &P2AO[q*nbasis + s_offset];                  p2ao_rs = &P2AO[r*nbasis + s_offset];                  for (bf4=0; bf4<ns; bf4++) {                    *gammasym_ptr++ = gamma_factor*(                                          4**phf_pq*(*phf_rs + *p2ao_rs)                                        + 4**phf_rs**p2ao_pq                                        - *phf_qs*(*phf_pr + *p2ao_pr)                                        - *phf_qr*(*phf_ps + *p2ao_ps)                                        - *phf_ps**p2ao_qr                                        - *phf_pr**p2ao_qs);                    *hf_gammasym_ptr++ = gamma_factor*(                                          4**phf_pq*(*phf_rs)                                        - *phf_qs*(*phf_pr)                                        - *phf_qr*(*phf_ps));                    phf_ps++;                    phf_qs++;                    phf_rs++;                    p2ao_ps++;                    p2ao_qs++;                    p2ao_rs++;                    } // exit bf4 loop                  phf_pr++;                  p2ao_pr++;                  phf_qr++;                  p2ao_qr++;                  }   // exit bf3 loop                phf_pq++;                p2ao_pq++;                }     // exit bf2 loop              }       // exit bf1 loop            ///////////////////////////////////////////////////////////            // Contract symmetrized sep 2PDM with integral derivatives            ///////////////////////////////////////////////////////////            integral_ptr = intderbuf;            for (derset=0; derset<der_centers.n(); derset++) {              for (xyz=0; xyz<3; xyz++) {                grad_ptr1 = &ginter[der_centers.atom(derset)][xyz];                hf_grad_ptr1 = &hf_ginter[der_centers.atom(derset)][xyz];                if (der_centers.has_omitted_center()) {                  grad_ptr2 = &ginter[der_centers.omitted_atom()][xyz];                  hf_grad_ptr2 = &hf_ginter[der_centers.omitted_atom()][xyz];                  }                gammasym_ptr = gammasym_pqrs;                hf_gammasym_ptr = hf_gammasym_pqrs;                for (bf1=0; bf1<np; bf1++) {                  for (bf2=0; bf2<nq; bf2++) {                    for (bf3=0; bf3<nr; bf3++) {                      for (bf4=0; bf4<ns; bf4++) {                        double intval = *integral_ptr++;                        tmpval = intval * *gammasym_ptr++;                        *grad_ptr1 += tmpval;                        *grad_ptr2 -= tmpval;                        tmpval = intval * *hf_gammasym_ptr++;                        *hf_grad_ptr1 += tmpval;                        *hf_grad_ptr2 -= tmpval;                        } // exit bf4 loop                      }   // exit bf3 loop                    }     // exit bf2 loop                  }       // exit bf1 loop                }         // exit xyz loop              }           // exit derset loop            } // exit "if"          }   // exit P loop        }     // exit R loop      }       // exit S loop    }         // exit Q loop  delete[] gammasym_pqrs;  delete[] hf_gammasym_pqrs;}////////////////////////////////////////////////////////////////////////////// Local Variables:// mode: c++// c-file-style: "CLJ-CONDENSED"// End:

⌨️ 快捷键说明

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