// // csgrads2pdm.cc // based on csgrad.cc // // Copyright (C) 1996 Limit Point Systems, Inc. // // Author: Ida Nielsen // 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 #include #include #include #include #include using namespace sc; CSGradS2PDM::CSGradS2PDM(int mythread_a, int nthread_a, int me_a, int nproc_a, const Ref &lock_a, const Ref &basis_a, const Ref &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; imolecule()->natom(); for (int i=0; inshell(); 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; Qshell(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