source: ThirdParty/mpqc_open/src/lib/chemistry/qc/basis/sobasis.cc

Candidate_v1.6.1
Last change on this file was 860145, checked in by Frederik Heber <heber@…>, 8 years ago

Merge commit '0b990dfaa8c6007a996d030163a25f7f5fc8a7e7' as 'ThirdParty/mpqc_open'

  • Property mode set to 100644
File size: 9.1 KB
Line 
1//
2// sobasis.cc --- implementation of the Integral class
3//
4// Copyright (C) 1998 Limit Point Systems, Inc.
5//
6// Author: Curtis Janssen <cljanss@limitpt.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#ifdef __GNUC__
29#pragma implementation
30#endif
31
32#include <string.h>
33
34#include <util/misc/formio.h>
35#include <math/symmetry/pointgrp.h>
36#include <chemistry/qc/basis/petite.h>
37#include <chemistry/qc/basis/sobasis.h>
38
39using namespace std;
40using namespace sc;
41
42SOBasis::SOBasis(const Ref<GaussianBasisSet> &basis, const Ref<Integral>&integral)
43{
44 int i,j,k;
45
46 basis_ = basis;
47
48 Ref<Molecule> mol = basis_->molecule();
49
50 CharacterTable ct = mol->point_group()->char_table();
51 nirrep_ = ct.nirrep();
52
53 // count the number of so shells
54 nshell_ = 0;
55 for (i=0; i<mol->nunique(); i++) {
56 nshell_ += basis_->nshell_on_center(mol->unique(i));
57 }
58
59 // map each ao shell to an so shell
60 int *aoshell_to_soshell = new int[basis_->nshell()];
61 int soshell = 0;
62 for (i=0; i<mol->nunique(); i++) {
63 for (j=0; j<basis_->nshell_on_center(mol->unique(i)); j++) {
64 for (k=0; k<mol->nequivalent(i); k++) {
65 int aoshell = basis_->shell_on_center(mol->equivalent(i,k),j);
66 aoshell_to_soshell[aoshell] = soshell;
67 }
68 soshell++;
69 }
70 }
71
72 ncomp_ = new int[nirrep_];
73 for (i=0; i<nirrep_; i++) {
74 ncomp_[i] = ct.gamma(i).degeneracy();
75 if (ncomp_[i] != 1) {
76 ExEnv::out0()
77 << "WARNING: SOBasis not tested for degenerate point groups"
78 << endl;
79 }
80 }
81
82 naofunc_ = new int[nshell_];
83 memset(naofunc_, 0, sizeof(int)*nshell_);
84
85 nfunc_ = new int*[nshell_];
86 funcoff_ = new int*[nshell_];
87 for (i=0; i<nshell_; i++) {
88 nfunc_[i] = new int[nirrep_];
89 funcoff_[i] = new int[nirrep_];
90 for (j=0; j<nirrep_; j++) {
91 nfunc_[i][j] = 0;
92 }
93 }
94
95 Ref<PetiteList> petite = new PetiteList(basis_, integral);
96
97 int nblocks = petite->nblocks();
98 SO_block *soblocks = petite->aotoso_info();
99
100 trans_ = new SOTransform[nshell_];
101 for (i=0; i<nblocks; i++) {
102 for (j=0; j<soblocks[i].len; j++) {
103 if (soblocks[i].so[j].length == 0) continue;
104 int bfn0 = soblocks[i].so[j].cont[0].bfn;
105 int aoshell0 = basis_->function_to_shell(bfn0);
106 int soshell0 = aoshell_to_soshell[aoshell0];
107 int atom0 = basis_->shell_to_center(aoshell0);
108 int nequiv0 = mol->nequivalent(mol->atom_to_unique(atom0));
109 trans_[soshell0].set_naoshell(nequiv0);
110 }
111 }
112
113 int nfuncall = 0;
114 for (i=0; i<nblocks; i++) {
115 int irrep = ct.which_irrep(i);
116 for (j=0; j<soblocks[i].len; j++) {
117 if (soblocks[i].so[j].length == 0) continue;
118 int bfn0 = soblocks[i].so[j].cont[0].bfn;
119 int aoshell0 = basis_->function_to_shell(bfn0);
120 int soshell0 = aoshell_to_soshell[aoshell0];
121 int sofunc = nfunc_[soshell0][irrep];
122
123 int naofunc = basis_->shell(aoshell0).nfunction();
124 if (naofunc_[soshell0] && (naofunc_[soshell0] != naofunc)) {
125 ExEnv::errn() << "ERROR: SOBasis: mismatch in naofunc" << endl;
126 abort();
127 }
128 naofunc_[soshell0] = naofunc;
129
130 nfunc_[soshell0][irrep]++;
131 nfuncall++;
132
133 for (k=0; k<soblocks[i].so[j].length; k++) {
134 int bfn = soblocks[i].so[j].cont[k].bfn;
135 double coef = soblocks[i].so[j].cont[k].coef;
136 int aoshell = basis_->function_to_shell(bfn);
137 int aoshellfunc = bfn - basis_->shell_to_function(aoshell);
138 int soshell = aoshell_to_soshell[aoshell];
139
140 if (soshell != soshell0) {
141 ExEnv::outn() << "ERROR: SOBasis: shell changed" << endl;
142 abort();
143 }
144
145 trans_[soshell].add_transform(aoshell,irrep, coef,aoshellfunc,sofunc);
146 }
147 }
148 }
149
150 if (nfuncall != basis_->nbasis()) {
151 ExEnv::out0() << "ERROR: SOBasis: miscounted number of functions"
152 << endl;
153 print();
154 abort();
155 }
156
157 delete[] soblocks;
158 delete[] aoshell_to_soshell;
159
160 for (i=0; i<nshell_; i++) {
161 funcoff_[i][0] = 0;
162 for (j=1; j<nirrep_; j++) {
163 funcoff_[i][j] = funcoff_[i][j-1] + nfunc_[i][j-1];
164 }
165 }
166
167 func_ = new int[nshell_];
168 irrep_ = new int[basis_->nbasis()];
169 func_within_irrep_ = new int[basis_->nbasis()];
170 nfunc_in_irrep_ = new int[nirrep_];
171
172 for (i=0; i<nirrep_; i++) nfunc_in_irrep_[i] = 0;
173
174 if (nshell_) {
175 func_[0] = 0;
176 for (i=1; i<nshell_; i++) {
177 func_[i] = func_[i-1] + nfunction(i-1);
178 }
179 int ibasis_ = 0;
180 for (i=0; i<nshell_; i++) {
181 for (j=0; j<nirrep_; j++) {
182 for (k=0; k<nfunc_[i][j]; k++,ibasis_++) {
183 irrep_[ibasis_] = j;
184 func_within_irrep_[ibasis_] = nfunc_in_irrep_[j]++;
185 }
186 }
187 }
188 }
189}
190
191SOBasis::~SOBasis()
192{
193 for (int i=0; i<nshell_; i++) {
194 delete[] nfunc_[i];
195 delete[] funcoff_[i];
196 }
197 delete[] nfunc_;
198 delete[] funcoff_;
199 delete[] naofunc_;
200 delete[] ncomp_;
201 delete[] trans_;
202 delete[] func_;
203 delete[] irrep_;
204 delete[] func_within_irrep_;
205 delete[] nfunc_in_irrep_;
206}
207
208int
209SOBasis::max_nfunction_in_shell() const
210{
211 int maxn = 0;
212 for (int i=0; i<nshell_; i++) {
213 int n = nfunction(i);
214 if (n > maxn) maxn = n;
215 }
216 return maxn;
217}
218
219int
220SOBasis::nfunction(int ishell) const
221{
222 int n=0;
223 for (int i=0; i<nirrep_; i++) {
224 n += nfunc_[ishell][i];
225 }
226 return n;
227}
228
229void
230SOBasis::print(ostream &o) const
231{
232 int i,j,k;
233
234 ExEnv::out0()
235 << indent << "SOBasis:" << endl
236 << incindent
237 << basis_
238 << indent << "nshell(SO) = " << nshell_ << endl
239 << indent << "nirrep = " << nirrep_ << endl;
240
241 ExEnv::out0() << indent << "ncomp = [";
242 for (i=0; i<nirrep_; i++) ExEnv::out0() << " " << ncomp_[i];
243 ExEnv::out0() << " ]" << endl;
244
245 ExEnv::out0() << indent << "nfunc:" << endl;
246 for (i=0; i<nshell_; i++) {
247 ExEnv::out0() << indent << " " << i << ":";
248 for (j=0; j<nirrep_; j++) ExEnv::out0() << " " << nfunc_[i][j];
249 ExEnv::out0() << endl;
250 }
251
252 ExEnv::out0() << indent << "transform:" << endl;
253 ExEnv::out0() << incindent;
254 for (i=0; i<nshell_; i++) {
255 if (i>0) ExEnv::out0() << endl;
256 for (j=0; j<trans_[i].naoshell; j++) {
257 for (k=0; k<trans_[i].aoshell[j].nfunc; k++) {
258 ExEnv::out0() << indent
259 << scprintf("SO(%3d %2d %d [%2d]) += % 12.8f * AO(%3d %2d)",
260 i,
261 trans_[i].aoshell[j].func[k].sofunc,
262 trans_[i].aoshell[j].func[k].irrep,
263 function_offset_within_shell(
264 i, trans_[i].aoshell[j].func[k].irrep)
265 + trans_[i].aoshell[j].func[k].sofunc,
266 trans_[i].aoshell[j].func[k].coef,
267 trans_[i].aoshell[j].aoshell,
268 trans_[i].aoshell[j].func[k].aofunc
269 )
270 << endl;
271 }
272 }
273 }
274 ExEnv::out0() << decindent;
275
276 ExEnv::out0() << decindent;
277}
278
279/////////////////////////////////////////////////////////////////////////////
280
281SOTransform::SOTransform()
282{
283 naoshell_allocated = 0;
284 naoshell = 0;
285 aoshell = 0;
286}
287
288SOTransform::~SOTransform()
289{
290 delete[] aoshell;
291}
292
293void
294SOTransform::set_naoshell(int n)
295{
296 naoshell = 0;
297 delete[] aoshell;
298 naoshell_allocated = n;
299 aoshell = new SOTransformShell[n];
300}
301
302void
303SOTransform::add_transform(int aoshellnum, int irrep,
304 double coef, int aofunc, int sofunc)
305{
306 int i;
307 for (i=0; i<naoshell; i++) {
308 if (aoshell[i].aoshell == aoshellnum) break;
309 }
310 if (i>=naoshell_allocated) {
311 ExEnv::outn() << "ERROR: SOTransform: add_transform allocation too small"
312 << endl;
313 abort();
314 }
315 aoshell[i].add_func(irrep,coef,aofunc,sofunc);
316 aoshell[i].aoshell = aoshellnum;
317 if (i==naoshell) naoshell++;
318}
319
320/////////////////////////////////////////////////////////////////////////////
321
322SOTransformShell::SOTransformShell()
323{
324 nfunc = 0;
325 func = 0;
326}
327
328SOTransformShell::~SOTransformShell()
329{
330 delete[] func;
331}
332
333void
334SOTransformShell::add_func(int irrep, double coef, int aofunc, int sofunc)
335{
336 SOTransformFunction *newfunc = new SOTransformFunction[nfunc+1];
337 for (int i=0; i<nfunc; i++) newfunc[i] = func[i];
338 delete[] func;
339 func = newfunc;
340 func[nfunc].irrep = irrep;
341 func[nfunc].coef = coef;
342 func[nfunc].aofunc = aofunc;
343 func[nfunc].sofunc = sofunc;
344 nfunc++;
345}
346
347/////////////////////////////////////////////////////////////////////////////
348
349// Local Variables:
350// mode: c++
351// c-file-style: "CLJ-CONDENSED"
352// End:
Note: See TracBrowser for help on using the repository browser.