38
38
using namespace sc;
41
R12IntEvalInfo::compute_multipole_ints(RefSymmSCMatrix& MX, RefSymmSCMatrix& MY, RefSymmSCMatrix& MZ,
42
RefSymmSCMatrix& MXX, RefSymmSCMatrix& MYY, RefSymmSCMatrix& MZZ)
41
R12IntEvalInfo::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
Ref<PetiteList> pl = ref_->integral()->petite_list();
45
int nshell = bs_->nshell();
47
// Have to convert scf_vec_ to unblocked form, get_subblock, and convert back to blocked form
48
// because get_subblock doesn't like blocked matrices
49
RefSCDimension aodim = pl->AO_basisdim();
52
int nmo = scf_vec_.rowdim().n();
53
int blksize[1]; blksize[0] = nmo;
54
modim = new SCDimension(nmo,1,blksize,"Sorted MO dimension");
56
RefSCMatrix unblvec(modim,aodim,bs_->matrixkit());
57
unblvec->convert(scf_vec_.pointer());
58
RefSCMatrix subblock = unblvec.get_subblock(nfzc_,nocc_-1,0,bs_->nbasis()-1);
59
RefSCDimension occactdim;
61
int blksize[1]; blksize[0] = nocc_ - nfzc_;
62
occactdim = new SCDimension(nocc_-nfzc_,1,blksize,"Active occupied MO dimension");
63
occactdim->blocks()->set_subdim(0,new SCDimension(nocc_-nfzc_,"occact MO dim"));
65
RefSCMatrix OccAct_Vec(occactdim,aodim,bs_->so_matrixkit());
66
OccAct_Vec->convert(subblock.pointer());
70
Ref<OneBodyInt> m1_ints = integral_->dipole(0);
72
// form AO dipole moment matrices
73
RefSymmSCMatrix mx(pl->AO_basisdim(), bs_->so_matrixkit());
74
RefSymmSCMatrix my(pl->AO_basisdim(), bs_->so_matrixkit());
75
RefSymmSCMatrix mz(pl->AO_basisdim(), bs_->so_matrixkit());
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();
53
RefSCMatrix vec1t = space1->coefs().t();
54
RefSCMatrix vec2 = space2->coefs();
56
Ref<Integral> localints = space1->integral()->clone();
57
localints->set_basis(bs1,bs2);
59
Ref<OneBodyInt> m1_ints = localints->dipole(0);
60
Ref<OneBodyInt> m2_ints = localints->quadrupole(0);
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);
79
for(int sh1=0; sh1<nshell1; sh1++) {
80
int bf1_offset = bs1->shell_to_function(sh1);
81
int nbf1 = bs1->shell(sh1).nfunction();
80
for(int sh1=0; sh1<nshell; sh1++) {
81
int bf1_offset = bs_->shell_to_function(sh1);
82
int nbf1 = bs_->shell(sh1).nfunction();
83
for(int sh2=0; sh2<=sh1; sh2++) {
84
int bf2_offset = bs_->shell_to_function(sh2);
85
int nbf2 = bs_->shell(sh2).nfunction();
89
for(int sh2=0; sh2<=sh2max; sh2++) {
90
int bf2_offset = bs2->shell_to_function(sh2);
91
int nbf2 = bs2->shell(sh2).nfunction();
87
93
m1_ints->compute_shell(sh1,sh2);
88
94
const double *m1intsptr = m1_ints->buffer();
96
m2_ints->compute_shell(sh1,sh2);
97
const double *m2intsptr = m2_ints->buffer();
89
99
int bf1_index = bf1_offset;
90
for(int bf1=0; bf1<nbf1; bf1++, bf1_index++, m1intsptr+=3*nbf2) {
100
for(int bf1=0; bf1<nbf1; bf1++, bf1_index++, m1intsptr+=3*nbf2, m2intsptr+=6*nbf2) {
91
101
int bf2_index = bf2_offset;
92
102
const double *ptr1 = m1intsptr;
103
const double *ptr2 = m2intsptr;
105
if (bs1_eq_bs2 && sh1 == sh2)
98
109
for(int bf2=0; bf2<=bf2max; bf2++, bf2_index++) {
99
111
mx.set_element(bf1_index, bf2_index, *(ptr1++));
100
112
my.set_element(bf1_index, bf2_index, *(ptr1++));
101
113
mz.set_element(bf1_index, bf2_index, *(ptr1++));
115
mxx.set_element(bf1_index, bf2_index, *(ptr2++));
117
myy.set_element(bf1_index, bf2_index, *(ptr2++));
119
mzz.set_element(bf1_index, bf2_index, *(ptr2++));
107
126
// and clean up a bit
130
// Symmetrize matrices, if necessary
133
const int nbasis = bs1->nbasis();
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);
110
148
// finally, transform
111
MX = bs_->so_matrixkit()->symmmatrix(occactdim);
112
MY = bs_->so_matrixkit()->symmmatrix(occactdim);
113
MZ = bs_->so_matrixkit()->symmmatrix(occactdim);
117
MX.accumulate_transform(OccAct_Vec,mx);
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;
156
// and clean up a bit
119
MY.accumulate_transform(OccAct_Vec,my);
121
MZ.accumulate_transform(OccAct_Vec,mz);
124
// same for quadrupole integrals
125
Ref<OneBodyInt> m2_ints = integral_->quadrupole(0);
126
RefSymmSCMatrix mxx(pl->AO_basisdim(), bs_->so_matrixkit());
127
RefSymmSCMatrix myy(pl->AO_basisdim(), bs_->so_matrixkit());
128
RefSymmSCMatrix mzz(pl->AO_basisdim(), bs_->so_matrixkit());
133
for(int sh1=0; sh1<nshell; sh1++) {
134
int bf1_offset = bs_->shell_to_function(sh1);
135
int nbf1 = bs_->shell(sh1).nfunction();
136
for(int sh2=0; sh2<=sh1; sh2++) {
137
int bf2_offset = bs_->shell_to_function(sh2);
138
int nbf2 = bs_->shell(sh2).nfunction();
140
m2_ints->compute_shell(sh1,sh2);
141
const double *m2intsptr = m2_ints->buffer();
142
int bf1_index = bf1_offset;
143
for(int bf1=0; bf1<nbf1; bf1++, bf1_index++, m2intsptr+=6*nbf2) {
144
int bf2_index = bf2_offset;
145
const double *ptr2 = m2intsptr;
151
for(int bf2=0; bf2<=bf2max; bf2++, bf2_index++) {
152
mxx.set_element(bf1_index, bf2_index, *(ptr2++));
154
myy.set_element(bf1_index, bf2_index, *(ptr2++));
156
mzz.set_element(bf1_index, bf2_index, *(ptr2++));
161
// and clean up a bit
166
MXX = bs_->so_matrixkit()->symmmatrix(occactdim);
167
MYY = bs_->so_matrixkit()->symmmatrix(occactdim);
168
MZZ = bs_->so_matrixkit()->symmmatrix(occactdim);
172
MXX.accumulate_transform(OccAct_Vec,mxx);
174
MYY.accumulate_transform(OccAct_Vec,myy);
176
MZZ.accumulate_transform(OccAct_Vec,mzz);
180
MX.print("mu(X) in active occupied MO basis");
181
MY.print("mu(Y) in active occupied MO basis");
182
MZ.print("mu(Z) in active occupied MO basis");
183
MXX.print("mu(XX) in active occupied MO basis");
184
MYY.print("mu(YY) in active occupied MO basis");
185
MZZ.print("mu(ZZ) in active occupied MO basis");
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)");
176
R12IntEvalInfo::compute_overlap_ints(const Ref<MOIndexSpace>& space1, const Ref<MOIndexSpace>& space2,
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();
187
RefSCMatrix vec1t = space1->coefs().t();
188
RefSCMatrix vec2 = space2->coefs();
190
Ref<Integral> localints = space1->integral()->clone();
191
localints->set_basis(bs1,bs2);
193
Ref<OneBodyInt> ov_ints = localints->overlap();
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);
202
for(int sh1=0; sh1<nshell1; sh1++) {
203
int bf1_offset = bs1->shell_to_function(sh1);
204
int nbf1 = bs1->shell(sh1).nfunction();
212
for(int sh2=0; sh2<=sh2max; sh2++) {
213
int bf2_offset = bs2->shell_to_function(sh2);
214
int nbf2 = bs2->shell(sh2).nfunction();
216
ov_ints->compute_shell(sh1,sh2);
217
const double *ovintsptr = ov_ints->buffer();
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;
224
if (bs1_eq_bs2 && sh1 == sh2)
228
for(int bf2=0; bf2<=bf2max; bf2++, bf2_index++) {
230
s.set_element(bf1_index, bf2_index, *(ptr++));
237
// and clean up a bit
240
// Symmetrize matrices, if necessary
243
const int nbasis = bs1->nbasis();
245
for(int bf1=0; bf1<nbasis; bf1++)
246
for(int bf2=0; bf2<=bf1; bf2++) {
247
s(bf2,bf1) = s(bf1,bf2);
253
// finally, transform
254
S = vec1t * s * vec2;
256
// and clean up a bit
260
// S.print("Overlap");
193
264
///////////////////////////////////////////////////////////////