source: src/lib/chemistry/qc/mbptr12/multipole_ints.cc@ 5d30c1

Last change on this file since 5d30c1 was 5d30c1, checked in by Frederik Heber <heber@…>, 13 years ago

Initial commit based on 3.0.0alpha (here claimed as 2.4).

  • simply added all files.
  • Property mode set to 100644
File size: 7.2 KB
Line 
1//
2// multipole_ints.cc
3//
4// Copyright (C) 2003 Edward Valeev
5//
6// Author: Edward Valeev <edward.valeev@chemistry.gatech.edu>
7// Maintainer: EV
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#ifdef __GNUC__
29#pragma implementation
30#endif
31
32#include <stdexcept>
33#include <math/scmat/blocked.h>
34#include <chemistry/qc/basis/petite.h>
35#include <chemistry/qc/mbptr12/vxb_eval_info.h>
36
37using namespace std;
38using namespace sc;
39
40void
41R12IntEvalInfo::compute_multipole_ints(const Ref<MOIndexSpace>& space1, const Ref<MOIndexSpace>& space2,
42 RefSCMatrix& MX, RefSCMatrix& MY, RefSCMatrix& MZ,
43 RefSCMatrix& MXX, RefSCMatrix& MYY, RefSCMatrix& MZZ)
44{
45 if (!space1->integral()->equiv(space2->integral()))
46 throw ProgrammingError("two MOIndexSpaces use incompatible Integral factories");
47 const Ref<GaussianBasisSet> bs1 = space1->basis();
48 const Ref<GaussianBasisSet> bs2 = space2->basis();
49 const bool bs1_eq_bs2 = (bs1 == bs2);
50 int nshell1 = bs1->nshell();
51 int nshell2 = bs2->nshell();
52
53 RefSCMatrix vec1t = space1->coefs().t();
54 RefSCMatrix vec2 = space2->coefs();
55
56 Ref<Integral> localints = space1->integral()->clone();
57 localints->set_basis(bs1,bs2);
58
59 Ref<OneBodyInt> m1_ints = localints->dipole(0);
60 Ref<OneBodyInt> m2_ints = localints->quadrupole(0);
61
62 // form AO moment matrices
63 RefSCDimension aodim1 = vec1t.coldim();
64 RefSCDimension aodim2 = vec2.rowdim();
65 Ref<SCMatrixKit> aokit = bs1->so_matrixkit();
66 RefSCMatrix mx(aodim1, aodim2, aokit);
67 RefSCMatrix my(aodim1, aodim2, aokit);
68 RefSCMatrix mz(aodim1, aodim2, aokit);
69 RefSCMatrix mxx(aodim1, aodim2, aokit);
70 RefSCMatrix myy(aodim1, aodim2, aokit);
71 RefSCMatrix mzz(aodim1, aodim2, aokit);
72 mx.assign(0.0);
73 my.assign(0.0);
74 mz.assign(0.0);
75 mxx.assign(0.0);
76 myy.assign(0.0);
77 mzz.assign(0.0);
78
79 for(int sh1=0; sh1<nshell1; sh1++) {
80 int bf1_offset = bs1->shell_to_function(sh1);
81 int nbf1 = bs1->shell(sh1).nfunction();
82
83 int sh2max;
84 if (bs1_eq_bs2)
85 sh2max = sh1;
86 else
87 sh2max = nshell2-1;
88
89 for(int sh2=0; sh2<=sh2max; sh2++) {
90 int bf2_offset = bs2->shell_to_function(sh2);
91 int nbf2 = bs2->shell(sh2).nfunction();
92
93 m1_ints->compute_shell(sh1,sh2);
94 const double *m1intsptr = m1_ints->buffer();
95
96 m2_ints->compute_shell(sh1,sh2);
97 const double *m2intsptr = m2_ints->buffer();
98
99 int bf1_index = bf1_offset;
100 for(int bf1=0; bf1<nbf1; bf1++, bf1_index++, m1intsptr+=3*nbf2, m2intsptr+=6*nbf2) {
101 int bf2_index = bf2_offset;
102 const double *ptr1 = m1intsptr;
103 const double *ptr2 = m2intsptr;
104 int bf2max;
105 if (bs1_eq_bs2 && sh1 == sh2)
106 bf2max = bf1;
107 else
108 bf2max = nbf2-1;
109 for(int bf2=0; bf2<=bf2max; bf2++, bf2_index++) {
110
111 mx.set_element(bf1_index, bf2_index, *(ptr1++));
112 my.set_element(bf1_index, bf2_index, *(ptr1++));
113 mz.set_element(bf1_index, bf2_index, *(ptr1++));
114
115 mxx.set_element(bf1_index, bf2_index, *(ptr2++));
116 ptr2 += 2;
117 myy.set_element(bf1_index, bf2_index, *(ptr2++));
118 ptr2++;
119 mzz.set_element(bf1_index, bf2_index, *(ptr2++));
120
121 }
122 }
123 }
124 }
125
126 // and clean up a bit
127 m1_ints = 0;
128 m2_ints = 0;
129
130 // Symmetrize matrices, if necessary
131 if (bs1_eq_bs2) {
132
133 const int nbasis = bs1->nbasis();
134
135 for(int bf1=0; bf1<nbasis; bf1++)
136 for(int bf2=0; bf2<=bf1; bf2++) {
137 mx(bf2,bf1) = mx(bf1,bf2);
138 my(bf2,bf1) = my(bf1,bf2);
139 mz(bf2,bf1) = mz(bf1,bf2);
140 mxx(bf2,bf1) = mxx(bf1,bf2);
141 myy(bf2,bf1) = myy(bf1,bf2);
142 mzz(bf2,bf1) = mzz(bf1,bf2);
143 }
144
145 }
146
147
148 // finally, transform
149 MX = vec1t * mx * vec2;
150 MY = vec1t * my * vec2;
151 MZ = vec1t * mz * vec2;
152 MXX = vec1t * mxx * vec2;
153 MYY = vec1t * myy * vec2;
154 MZZ = vec1t * mzz * vec2;
155
156 // and clean up a bit
157 mx = 0;
158 my = 0;
159 mz = 0;
160 mxx = 0;
161 myy = 0;
162 mzz = 0;
163
164 //if (debug_ > 1) {
165 // MX.print("mu(X)");
166 // MY.print("mu(Y)");
167 // MZ.print("mu(Z)");
168 // MXX.print("mu(XX)");
169 // MYY.print("mu(YY)");
170 // MZZ.print("mu(ZZ)");
171 //}
172}
173
174
175void
176R12IntEvalInfo::compute_overlap_ints(const Ref<MOIndexSpace>& space1, const Ref<MOIndexSpace>& space2,
177 RefSCMatrix& S)
178{
179 if (!space1->integral()->equiv(space2->integral()))
180 throw ProgrammingError("two MOIndexSpaces use incompatible Integral factories");
181 const Ref<GaussianBasisSet> bs1 = space1->basis();
182 const Ref<GaussianBasisSet> bs2 = space2->basis();
183 const bool bs1_eq_bs2 = (bs1 == bs2);
184 int nshell1 = bs1->nshell();
185 int nshell2 = bs2->nshell();
186
187 RefSCMatrix vec1t = space1->coefs().t();
188 RefSCMatrix vec2 = space2->coefs();
189
190 Ref<Integral> localints = space1->integral()->clone();
191 localints->set_basis(bs1,bs2);
192
193 Ref<OneBodyInt> ov_ints = localints->overlap();
194
195 // form AO moment matrices
196 RefSCDimension aodim1 = vec1t.coldim();
197 RefSCDimension aodim2 = vec2.rowdim();
198 Ref<SCMatrixKit> aokit = bs1->so_matrixkit();
199 RefSCMatrix s(aodim1, aodim2, aokit);
200 s.assign(0.0);
201
202 for(int sh1=0; sh1<nshell1; sh1++) {
203 int bf1_offset = bs1->shell_to_function(sh1);
204 int nbf1 = bs1->shell(sh1).nfunction();
205
206 int sh2max;
207 if (bs1_eq_bs2)
208 sh2max = sh1;
209 else
210 sh2max = nshell2-1;
211
212 for(int sh2=0; sh2<=sh2max; sh2++) {
213 int bf2_offset = bs2->shell_to_function(sh2);
214 int nbf2 = bs2->shell(sh2).nfunction();
215
216 ov_ints->compute_shell(sh1,sh2);
217 const double *ovintsptr = ov_ints->buffer();
218
219 int bf1_index = bf1_offset;
220 for(int bf1=0; bf1<nbf1; bf1++, bf1_index++, ovintsptr+=nbf2) {
221 int bf2_index = bf2_offset;
222 const double *ptr = ovintsptr;
223 int bf2max;
224 if (bs1_eq_bs2 && sh1 == sh2)
225 bf2max = bf1;
226 else
227 bf2max = nbf2-1;
228 for(int bf2=0; bf2<=bf2max; bf2++, bf2_index++) {
229
230 s.set_element(bf1_index, bf2_index, *(ptr++));
231
232 }
233 }
234 }
235 }
236
237 // and clean up a bit
238 ov_ints = 0;
239
240 // Symmetrize matrices, if necessary
241 if (bs1_eq_bs2) {
242
243 const int nbasis = bs1->nbasis();
244
245 for(int bf1=0; bf1<nbasis; bf1++)
246 for(int bf2=0; bf2<=bf1; bf2++) {
247 s(bf2,bf1) = s(bf1,bf2);
248 }
249
250 }
251
252
253 // finally, transform
254 S = vec1t * s * vec2;
255
256 // and clean up a bit
257 s = 0;
258
259 //if (debug_ > 1) {
260 // S.print("Overlap");
261 //}
262}
263
264///////////////////////////////////////////////////////////////
265
266// Local Variables:
267// mode: c++
268// c-file-style: "CLJ"
269// End:
Note: See TracBrowser for help on using the repository browser.