MPQC  3.0.0-alpha
ltbgrad.h
1 //
2 // ltbgrad.h --- definition of the local two-electron gradient builder
3 //
4 // Copyright (C) 1996 Limit Point Systems, Inc.
5 //
6 // Author: Edward Seidl <seidl@janed.com>
7 // Maintainer: LPS
8 //
9 // This file is part of the SC Toolkit.
10 //
11 // The SC Toolkit is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU Library General Public License as published by
13 // the Free Software Foundation; either version 2, or (at your option)
14 // any later version.
15 //
16 // The SC Toolkit is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU Library General Public License for more details.
20 //
21 // You should have received a copy of the GNU Library General Public License
22 // along with the SC Toolkit; see the file COPYING.LIB. If not, write to
23 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 //
25 // The U.S. Government is granted a limited license as per AL 91-7.
26 //
27 
28 #ifndef _chemistry_qc_scf_ltbgrad_h
29 #define _chemistry_qc_scf_ltbgrad_h
30 
31 #include <math.h>
32 
33 #include <util/misc/regtime.h>
34 #include <math/scmat/offset.h>
35 
36 #include <chemistry/qc/basis/tbint.h>
37 #include <chemistry/qc/basis/petite.h>
38 
39 #include <chemistry/qc/scf/tbgrad.h>
40 
41 namespace sc {
42 
43 template<class T>
44 class LocalTBGrad : public TBGrad<T> {
45  public:
46  double *tbgrad;
47 
48  protected:
49  MessageGrp *grp_;
50  TwoBodyDerivInt *tbi_;
51  GaussianBasisSet *gbs_;
52  PetiteList *rpl_;
53  Molecule *mol_;
54 
55  double pmax_;
56  double accuracy_;
57 
58  int threadno_;
59  int nthread_;
60 
61  public:
62  LocalTBGrad(T& t, const Ref<TwoBodyDerivInt>& tbdi, const Ref<PetiteList>& pl,
63  const Ref<GaussianBasisSet>& bs, const Ref<MessageGrp>& g,
64  double *tbg, double pm, double a, int nt = 1, int tn = 0,
65  double exchange_fraction = 1.0) :
66  TBGrad<T>(t,exchange_fraction),
67  tbgrad(tbg), pmax_(pm), accuracy_(a), threadno_(tn), nthread_(nt)
68  {
69  grp_ = g.pointer();
70  gbs_ = bs.pointer();
71  rpl_ = pl.pointer();
72  tbi_ = tbdi.pointer();
73  mol_ = gbs_->molecule().pointer();
74  }
75 
76  ~LocalTBGrad() {}
77 
78  void run() {
79  int me = grp_->me();
80  int nproc = grp_->n();
81 
82  // grab ref for convenience
83  GaussianBasisSet& gbs = *gbs_;
84  Molecule& mol = *mol_;
85  PetiteList& pl = *rpl_;
86  TwoBodyDerivInt& tbi = *tbi_;
87 
88  // create vector to hold skeleton gradient
89  double *tbint = new double[mol.natom()*3];
90  memset(tbint, 0, sizeof(double)*mol.natom()*3);
91 
92  // for bounds checking
93  int PPmax = (int) (log(6.0*pmax_*pmax_)/log(2.0));
94  int threshold = (int) (log(accuracy_)/log(2.0));
95 
96  int kindex=0;
97  int threadind=0;
98  for (int i=0; i < gbs.nshell(); i++) {
99  if (!pl.in_p1(i))
100  continue;
101 
102  int ni=gbs(i).nfunction();
103  int fi=gbs.shell_to_function(i);
104 
105  for (int j=0; j <= i; j++) {
106  int ij=i_offset(i)+j;
107  if (!pl.in_p2(ij))
108  continue;
109 
110  if (tbi.log2_shell_bound(i,j,-1,-1)+PPmax < threshold)
111  continue;
112 
113  int nj=gbs(j).nfunction();
114  int fj=gbs.shell_to_function(j);
115 
116  for (int k=0; k <= i; k++,kindex++) {
117  if (kindex%nproc != me)
118  continue;
119 
120  threadind++;
121  if (threadind % nthread_ != threadno_)
122  continue;
123 
124  int nk=gbs(k).nfunction();
125  int fk=gbs.shell_to_function(k);
126 
127  for (int l=0; l <= ((i==k)?j:k); l++) {
128  if (tbi.log2_shell_bound(i,j,k,l)+PPmax < threshold)
129  continue;
130 
131  int kl=i_offset(k)+l;
132  int qijkl;
133  if (!(qijkl=pl.in_p4(ij,kl,i,j,k,l)))
134  continue;
135 
136  int nl=gbs(l).nfunction();
137  int fl=gbs.shell_to_function(l);
138 
139  DerivCenters cent;
140  tbi.compute_shell(i,j,k,l,cent);
141 
142  const double * buf = tbi.buffer();
143 
144  double cscl, escl;
145 
146  this->set_scale(cscl, escl, i, j, k, l);
147 
148  int indijkl=0;
149  int nx=cent.n();
150  //if (cent.has_omitted_center()) nx--;
151  for (int x=0; x < nx; x++) {
152  int ix=cent.atom(x);
153  int io=cent.omitted_atom();
154  for (int ixyz=0; ixyz < 3; ixyz++) {
155  double tx = tbint[ixyz+ix*3];
156  double to = tbint[ixyz+io*3];
157 
158  for (int ip=0, ii=fi; ip < ni; ip++, ii++) {
159  for (int jp=0, jj=fj; jp < nj; jp++, jj++) {
160  for (int kp=0, kk=fk; kp < nk; kp++, kk++) {
161  for (int lp=0, ll=fl; lp < nl; lp++, ll++, indijkl++) {
162  double contrib;
163  double qint = buf[indijkl]*qijkl;
164 
165  contrib = cscl*qint*
166  TBGrad<T>::contribution.cont1(ij_offset(ii,jj),
167  ij_offset(kk,ll));
168 
169  tx += contrib;
170  to -= contrib;
171 
172  contrib = escl*qint*
173  TBGrad<T>::contribution.cont2(ij_offset(ii,kk),
174  ij_offset(jj,ll));
175 
176  tx += contrib;
177  to -= contrib;
178 
179  if (i!=j && k!=l) {
180  contrib = escl*qint*
181  TBGrad<T>::contribution.cont2(ij_offset(ii,ll),
182  ij_offset(jj,kk));
183 
184  tx += contrib;
185  to -= contrib;
186  }
187  }
188  }
189  }
190  }
191 
192  tbint[ixyz+ix*3] = tx;
193  tbint[ixyz+io*3] = to;
194  }
195  }
196  }
197  }
198  }
199  }
200 
201  CharacterTable ct = mol.point_group()->char_table();
203 
204  for (int alpha=0; alpha < mol.natom(); alpha++) {
205  double tbx = tbint[alpha*3+0];
206  double tby = tbint[alpha*3+1];
207  double tbz = tbint[alpha*3+2];
208 
209  for (int g=1; g < ct.order(); g++) {
210  so = ct.symm_operation(g);
211  int ap = pl.atom_map(alpha,g);
212 
213  tbx += tbint[ap*3+0]*so(0,0) + tbint[ap*3+1]*so(1,0) +
214  tbint[ap*3+2]*so(2,0);
215  tby += tbint[ap*3+0]*so(0,1) + tbint[ap*3+1]*so(1,1) +
216  tbint[ap*3+2]*so(2,1);
217  tbz += tbint[ap*3+0]*so(0,2) + tbint[ap*3+1]*so(1,2) +
218  tbint[ap*3+2]*so(2,2);
219  }
220  double scl = 1.0/(double)ct.order();
221  tbgrad[alpha*3+0] += tbx*scl;
222  tbgrad[alpha*3+1] += tby*scl;
223  tbgrad[alpha*3+2] += tbz*scl;
224  }
225 
226  delete[] tbint;
227  }
228 };
229 
230 }
231 
232 #endif
233 
234 // Local Variables:
235 // mode: c++
236 // c-file-style: "ETS"
237 // End:
sc::LocalTBGrad
Definition: ltbgrad.h:44
sc::CharacterTable
The CharacterTable class provides a workable character table for all of the non-cubic point groups.
Definition: pointgrp.h:321
sc::LocalTBGrad::run
void run()
This is called with the Thread is run from a ThreadGrp.
Definition: ltbgrad.h:78
sc::GaussianBasisSet::nshell
unsigned int nshell() const
Return the number of shells.
Definition: gaussbas.h:500
sc::Molecule
The Molecule class contains information about molecules.
Definition: molecule.h:149
sc::Molecule::point_group
const Ref< PointGroup > & point_group() const
Returns the PointGroup of the molecule.
sc::TwoBodyDerivInt::compute_shell
virtual void compute_shell(int sh0, int sh1, int sh2, int sh3, DerivCenters &dercenters)=0
Given for shell indices, this will cause the derivative integral shell set to be computed.
sc::SymmetryOperation
The SymmetryOperation class provides a 3 by 3 matrix representation of a symmetry operation,...
Definition: pointgrp.h:66
sc::Ref
A template class that maintains references counts.
Definition: ref.h:361
sc::DerivCenters::omitted_atom
int omitted_atom() const
Definition: dercent.h:86
sc::CharacterTable::order
int order() const
Returns the order of the point group.
Definition: pointgrp.h:368
sc::TBGrad
Definition: tbgrad.h:36
sc::Ref::pointer
T * pointer() const
Returns a pointer the reference counted object.
Definition: ref.h:413
sc::MessageGrp::me
int me()
Returns my processor number. In the range [0,n()).
Definition: message.h:194
sc::PetiteList
PetiteList is a petite list (see Dupuis & King, IJQC 11,613,(1977) ) that can be used for constructin...
Definition: petite.h:120
sc::MessageGrp::n
int n()
Returns the number of processors.
Definition: message.h:192
sc::TwoBodyDerivInt
This is an abstract base type for classes that compute geometric derivatives of the integrals involvi...
Definition: tbint.h:554
sc::TwoBodyDerivInt::buffer
const double * buffer() const
The computed shell-set of integrals will be put in the buffer returned by this member.
sc::GaussianBasisSet::molecule
Ref< Molecule > molecule() const
Return the Molecule object.
Definition: gaussbas.h:489
sc::DerivCenters::n
int n() const
The number of centers for which derivatives have been computed.
Definition: dercent.h:69
sc::TwoBodyDerivInt::log2_shell_bound
virtual int log2_shell_bound(int=-1, int=-1, int=-1, int=-1)=0
Return log base 2 of the maximum magnitude of any integral in a shell block.
sc::GaussianBasisSet
The GaussianBasisSet class is used describe a basis set composed of atomic gaussian orbitals.
Definition: gaussbas.h:141
sc::Molecule::natom
size_t natom() const
Returns the number of atoms in the molecule.
Definition: molecule.h:327
sc::GaussianBasisSet::shell_to_function
int shell_to_function(int i) const
Return the number of the first function in the given shell.
Definition: gaussbas.h:540
sc::CharacterTable::symm_operation
SymmetryOperation & symm_operation(int i)
Returns the i'th symmetry operation.
Definition: pointgrp.h:374
sc::DerivCenters
DerivCenters keeps track the centers that derivatives are taken with respect to.
Definition: dercent.h:42
sc::MessageGrp
The MessageGrp abstract class provides a mechanism for moving data and objects between nodes in a par...
Definition: message.h:120
sc
Contains all MPQC code up to version 3.
Definition: mpqcin.h:14
sc::DerivCenters::atom
int atom(int i) const
Definition: dercent.h:77

Generated at Sun Jan 26 2020 23:24:00 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.8.16.