Main Page   Class Hierarchy   Compound List   File List   Compound Members   Related Pages  

ltbgrad.h

00001 //
00002 // ltbgrad.h --- definition of the local two-electron gradient builder
00003 //
00004 // Copyright (C) 1996 Limit Point Systems, Inc.
00005 //
00006 // Author: Edward Seidl <seidl@janed.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_scf_ltbgrad_h
00029 #define _chemistry_qc_scf_ltbgrad_h
00030 
00031 #ifdef __GNUC__
00032 #pragma interface
00033 #endif
00034 
00035 #include <math.h>
00036 
00037 #include <util/misc/timer.h>
00038 #include <math/scmat/offset.h>
00039 
00040 #include <chemistry/qc/basis/tbint.h>
00041 #include <chemistry/qc/basis/petite.h>
00042 
00043 #include <chemistry/qc/scf/tbgrad.h>
00044   
00045 template<class T>
00046 class LocalTBGrad : public TBGrad<T> {
00047   public:
00048     double *tbgrad;
00049 
00050   protected:
00051     MessageGrp *grp_;
00052     TwoBodyDerivInt *tbi_;
00053     GaussianBasisSet *gbs_;
00054     PetiteList *rpl_;
00055     Molecule *mol_;
00056 
00057     double pmax_;
00058     double accuracy_;
00059 
00060     int threadno_;
00061     int nthread_;
00062 
00063   public:
00064     LocalTBGrad(T& t, const Ref<TwoBodyDerivInt>& tbdi, const Ref<PetiteList>& pl,
00065                 const Ref<GaussianBasisSet>& bs, const Ref<MessageGrp>& g,
00066                 double *tbg, double pm, double a, int nt = 1, int tn = 0,
00067                 double exchange_fraction = 1.0) :
00068       TBGrad<T>(t,exchange_fraction),
00069       tbgrad(tbg), pmax_(pm), accuracy_(a), threadno_(tn), nthread_(nt)
00070     {
00071       grp_ = g.pointer();
00072       gbs_ = bs.pointer();
00073       rpl_ = pl.pointer();
00074       tbi_ = tbdi.pointer();
00075       mol_ = gbs_->molecule().pointer();
00076     }
00077 
00078     ~LocalTBGrad() {}
00079     
00080     void run() {
00081       int me = grp_->me();
00082       int nproc = grp_->n();
00083       
00084       // grab ref for convenience
00085       GaussianBasisSet& gbs = *gbs_;
00086       Molecule& mol = *mol_;
00087       PetiteList& pl = *rpl_;
00088       TwoBodyDerivInt& tbi = *tbi_;
00089       
00090       // create vector to hold skeleton gradient
00091       double *tbint = new double[mol.natom()*3];
00092       memset(tbint, 0, sizeof(double)*mol.natom()*3);
00093 
00094       // for bounds checking
00095       int PPmax = (int) (log(6.0*pmax_*pmax_)/log(2.0));
00096       int threshold = (int) (log(accuracy_)/log(2.0));
00097   
00098       int kindex=0;
00099       int threadind=0;
00100       for (int i=0; i < gbs.nshell(); i++) {
00101         if (!pl.in_p1(i))
00102           continue;
00103     
00104         int ni=gbs(i).nfunction();
00105         int fi=gbs.shell_to_function(i);
00106     
00107         for (int j=0; j <= i; j++) {
00108           int ij=i_offset(i)+j;
00109           if (!pl.in_p2(ij))
00110             continue;
00111       
00112           if (tbi.log2_shell_bound(i,j,-1,-1)+PPmax < threshold)
00113             continue;
00114       
00115           int nj=gbs(j).nfunction();
00116           int fj=gbs.shell_to_function(j);
00117     
00118           for (int k=0; k <= i; k++,kindex++) {
00119             if (kindex%nproc != me)
00120               continue;
00121             
00122             threadind++;
00123             if (threadind % nthread_ != threadno_)
00124               continue;
00125             
00126             int nk=gbs(k).nfunction();
00127             int fk=gbs.shell_to_function(k);
00128     
00129             for (int l=0; l <= ((i==k)?j:k); l++) {
00130               if (tbi.log2_shell_bound(i,j,k,l)+PPmax < threshold)
00131                 continue;
00132           
00133               int kl=i_offset(k)+l;
00134               int qijkl;
00135               if (!(qijkl=pl.in_p4(ij,kl,i,j,k,l)))
00136                 continue;
00137           
00138               int nl=gbs(l).nfunction();
00139               int fl=gbs.shell_to_function(l);
00140 
00141               DerivCenters cent;
00142               tbi.compute_shell(i,j,k,l,cent);
00143 
00144               const double * buf = tbi.buffer();
00145           
00146               double cscl, escl;
00147 
00148               set_scale(cscl, escl, i, j, k, l);
00149 
00150               int indijkl=0;
00151               int nx=cent.n();
00152               //if (cent.has_omitted_center()) nx--;
00153               for (int x=0; x < nx; x++) {
00154                 int ix=cent.atom(x);
00155                 int io=cent.omitted_atom();
00156                 for (int ixyz=0; ixyz < 3; ixyz++) {
00157                   double tx = tbint[ixyz+ix*3];
00158                   double to = tbint[ixyz+io*3];
00159                   
00160                   for (int ip=0, ii=fi; ip < ni; ip++, ii++) {
00161                     for (int jp=0, jj=fj; jp < nj; jp++, jj++) {
00162                       for (int kp=0, kk=fk; kp < nk; kp++, kk++) {
00163                         for (int lp=0, ll=fl; lp < nl; lp++, ll++, indijkl++) {
00164                           double contrib;
00165                           double qint = buf[indijkl]*qijkl;
00166 
00167                           contrib = cscl*qint*
00168                             TBGrad<T>::contribution.cont1(ij_offset(ii,jj),
00169                                                ij_offset(kk,ll));
00170 
00171                           tx += contrib;
00172                           to -= contrib;
00173 
00174                           contrib = escl*qint*
00175                             TBGrad<T>::contribution.cont2(ij_offset(ii,kk),
00176                                                ij_offset(jj,ll));
00177 
00178                           tx += contrib;
00179                           to -= contrib;
00180 
00181                           if (i!=j && k!=l) {
00182                             contrib = escl*qint*
00183                               TBGrad<T>::contribution.cont2(ij_offset(ii,ll),
00184                                                  ij_offset(jj,kk));
00185 
00186                             tx += contrib;
00187                             to -= contrib;
00188                           }
00189                         }
00190                       }
00191                     }
00192                   }
00193 
00194                   tbint[ixyz+ix*3] = tx;
00195                   tbint[ixyz+io*3] = to;
00196                 }
00197               }
00198             }
00199           }
00200         }
00201       }
00202       
00203       CharacterTable ct = mol.point_group()->char_table();
00204       SymmetryOperation so;
00205 
00206       for (int alpha=0; alpha < mol.natom(); alpha++) {
00207         double tbx = tbint[alpha*3+0];
00208         double tby = tbint[alpha*3+1];
00209         double tbz = tbint[alpha*3+2];
00210         
00211         for (int g=1; g < ct.order(); g++) {
00212           so = ct.symm_operation(g);
00213           int ap = pl.atom_map(alpha,g);
00214 
00215           tbx += tbint[ap*3+0]*so(0,0) + tbint[ap*3+1]*so(1,0) +
00216                  tbint[ap*3+2]*so(2,0);
00217           tby += tbint[ap*3+0]*so(0,1) + tbint[ap*3+1]*so(1,1) +
00218                  tbint[ap*3+2]*so(2,1);
00219           tbz += tbint[ap*3+0]*so(0,2) + tbint[ap*3+1]*so(1,2) +
00220                  tbint[ap*3+2]*so(2,2);
00221         }
00222         double scl = 1.0/(double)ct.order();
00223         tbgrad[alpha*3+0] += tbx*scl;
00224         tbgrad[alpha*3+1] += tby*scl;
00225         tbgrad[alpha*3+2] += tbz*scl;
00226       }
00227     
00228       delete[] tbint;
00229     }
00230 };
00231 
00232 #endif
00233 
00234 // Local Variables:
00235 // mode: c++
00236 // c-file-style: "ETS"
00237 // End:

Generated at Thu Oct 4 18:08:45 2001 for MPQC 2.0.0 using the documentation package Doxygen 1.2.5.