| [0b990d] | 1 | //
 | 
|---|
 | 2 | // aotoso.cc --- more symmetry stuff
 | 
|---|
 | 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 | #include <float.h>
 | 
|---|
 | 29 | 
 | 
|---|
 | 30 | #include <util/misc/formio.h>
 | 
|---|
 | 31 | 
 | 
|---|
 | 32 | #include <chemistry/qc/basis/basis.h>
 | 
|---|
 | 33 | #include <chemistry/qc/basis/integral.h>
 | 
|---|
 | 34 | #include <chemistry/qc/basis/shellrot.h>
 | 
|---|
 | 35 | #include <chemistry/qc/basis/petite.h>
 | 
|---|
 | 36 | #include <chemistry/qc/basis/f77sym.h>
 | 
|---|
 | 37 | 
 | 
|---|
 | 38 | using namespace std;
 | 
|---|
 | 39 | using namespace sc;
 | 
|---|
 | 40 | 
 | 
|---|
 | 41 | extern "C" {
 | 
|---|
 | 42 |   void
 | 
|---|
 | 43 |   F77_DGESVD(const char * JOBU, const char *JOBVT,
 | 
|---|
 | 44 |              int *M, int *N, double *A, int *LDA,
 | 
|---|
 | 45 |              double *S, double *U, int *LDU, double *VT, int *LDVT,
 | 
|---|
 | 46 |              double *WORK, int *LWORK, int *INFO );
 | 
|---|
 | 47 | }
 | 
|---|
 | 48 | 
 | 
|---|
 | 49 | ////////////////////////////////////////////////////////////////////////////
 | 
|---|
 | 50 | 
 | 
|---|
 | 51 | contribution::contribution()
 | 
|---|
 | 52 | {
 | 
|---|
 | 53 | }
 | 
|---|
 | 54 | 
 | 
|---|
 | 55 | contribution::~contribution()
 | 
|---|
 | 56 | {
 | 
|---|
 | 57 | }
 | 
|---|
 | 58 | 
 | 
|---|
 | 59 | contribution::contribution(int b, double c) : bfn(b), coef(c)
 | 
|---|
 | 60 | {
 | 
|---|
 | 61 | }
 | 
|---|
 | 62 | 
 | 
|---|
 | 63 | ////////////////////////////////////////////////////////////////////////////
 | 
|---|
 | 64 | 
 | 
|---|
 | 65 | SO::SO() : len(0), length(0), cont(0)
 | 
|---|
 | 66 | {
 | 
|---|
 | 67 | }
 | 
|---|
 | 68 | 
 | 
|---|
 | 69 | SO::SO(int l) : len(0), length(0), cont(0)
 | 
|---|
 | 70 | {
 | 
|---|
 | 71 |   set_length(l);
 | 
|---|
 | 72 | }
 | 
|---|
 | 73 | 
 | 
|---|
 | 74 | SO::~SO()
 | 
|---|
 | 75 | {
 | 
|---|
 | 76 |   set_length(0);
 | 
|---|
 | 77 | }
 | 
|---|
 | 78 | 
 | 
|---|
 | 79 | SO&
 | 
|---|
 | 80 | SO::operator=(const SO& so)
 | 
|---|
 | 81 | {
 | 
|---|
 | 82 |   set_length(so.length);
 | 
|---|
 | 83 |   length = so.length;
 | 
|---|
 | 84 |   for (int i=0; i < length; i++)
 | 
|---|
 | 85 |     cont[i] = so.cont[i];
 | 
|---|
 | 86 |   return *this;
 | 
|---|
 | 87 | }
 | 
|---|
 | 88 | 
 | 
|---|
 | 89 | void
 | 
|---|
 | 90 | SO::set_length(int l)
 | 
|---|
 | 91 | {
 | 
|---|
 | 92 |   len=l;
 | 
|---|
 | 93 |   length=l;
 | 
|---|
 | 94 |   if (cont) {
 | 
|---|
 | 95 |     delete[] cont;
 | 
|---|
 | 96 |     cont=0;
 | 
|---|
 | 97 |   }
 | 
|---|
 | 98 | 
 | 
|---|
 | 99 |   if (l)
 | 
|---|
 | 100 |     cont = new contribution[l];
 | 
|---|
 | 101 | }
 | 
|---|
 | 102 | 
 | 
|---|
 | 103 | void
 | 
|---|
 | 104 | SO::reset_length(int l)
 | 
|---|
 | 105 | {
 | 
|---|
 | 106 |   length=l;
 | 
|---|
 | 107 | 
 | 
|---|
 | 108 |   if (l <= len)
 | 
|---|
 | 109 |     return;
 | 
|---|
 | 110 |   
 | 
|---|
 | 111 |   l=l+10;
 | 
|---|
 | 112 |   
 | 
|---|
 | 113 |   contribution *newcont = new contribution[l];
 | 
|---|
 | 114 |   
 | 
|---|
 | 115 |   if (cont) {
 | 
|---|
 | 116 |     for (int i=0; i < len; i++)
 | 
|---|
 | 117 |       newcont[i] = cont[i];
 | 
|---|
 | 118 |     
 | 
|---|
 | 119 |     delete[] cont;
 | 
|---|
 | 120 |   }
 | 
|---|
 | 121 | 
 | 
|---|
 | 122 |   cont=newcont;
 | 
|---|
 | 123 |   len=l;
 | 
|---|
 | 124 | }
 | 
|---|
 | 125 | 
 | 
|---|
 | 126 | int
 | 
|---|
 | 127 | SO::equiv(const SO& so)
 | 
|---|
 | 128 | {
 | 
|---|
 | 129 |   int i;
 | 
|---|
 | 130 |       
 | 
|---|
 | 131 |   if (so.length != length)
 | 
|---|
 | 132 |     return 0;
 | 
|---|
 | 133 | 
 | 
|---|
 | 134 |   double c=0;
 | 
|---|
 | 135 |   for (i=0; i < length; i++) {
 | 
|---|
 | 136 |     if (cont[i].bfn != so.cont[i].bfn)
 | 
|---|
 | 137 |       return 0;
 | 
|---|
 | 138 |     c += cont[i].coef*so.cont[i].coef;
 | 
|---|
 | 139 |   }
 | 
|---|
 | 140 |       
 | 
|---|
 | 141 |   // if the overlap == 1.0, they're equal (SO's should have been
 | 
|---|
 | 142 |   // normalized by now)
 | 
|---|
 | 143 |   if (fabs(fabs(c)-1.0) < 1.0e-3)
 | 
|---|
 | 144 |     return 1;
 | 
|---|
 | 145 | 
 | 
|---|
 | 146 |   return 0;
 | 
|---|
 | 147 | }
 | 
|---|
 | 148 | 
 | 
|---|
 | 149 | ////////////////////////////////////////////////////////////////////////////
 | 
|---|
 | 150 | 
 | 
|---|
 | 151 | SO_block::SO_block() : len(0), so(0)
 | 
|---|
 | 152 | {
 | 
|---|
 | 153 | }
 | 
|---|
 | 154 | 
 | 
|---|
 | 155 | SO_block::SO_block(int l) : len(0), so(0)
 | 
|---|
 | 156 | {
 | 
|---|
 | 157 |   set_length(l);
 | 
|---|
 | 158 | }
 | 
|---|
 | 159 | 
 | 
|---|
 | 160 | SO_block::~SO_block()
 | 
|---|
 | 161 | {
 | 
|---|
 | 162 |   set_length(0);
 | 
|---|
 | 163 | }
 | 
|---|
 | 164 | 
 | 
|---|
 | 165 | void
 | 
|---|
 | 166 | SO_block::set_length(int l)
 | 
|---|
 | 167 | {
 | 
|---|
 | 168 |   len=l;
 | 
|---|
 | 169 |   if (so) {
 | 
|---|
 | 170 |     delete[] so;
 | 
|---|
 | 171 |     so=0;
 | 
|---|
 | 172 |   }
 | 
|---|
 | 173 | 
 | 
|---|
 | 174 |   if (l)
 | 
|---|
 | 175 |     so = new SO[l];
 | 
|---|
 | 176 | }
 | 
|---|
 | 177 | 
 | 
|---|
 | 178 | void
 | 
|---|
 | 179 | SO_block::reset_length(int l)
 | 
|---|
 | 180 | {
 | 
|---|
 | 181 |   if (len == l) return;
 | 
|---|
 | 182 | 
 | 
|---|
 | 183 |   SO *newso = new SO[l];
 | 
|---|
 | 184 |   
 | 
|---|
 | 185 |   if (so) {
 | 
|---|
 | 186 |     for (int i=0; i < len; i++)
 | 
|---|
 | 187 |       newso[i] = so[i];
 | 
|---|
 | 188 |     
 | 
|---|
 | 189 |     delete[] so;
 | 
|---|
 | 190 |   }
 | 
|---|
 | 191 | 
 | 
|---|
 | 192 |   so=newso;
 | 
|---|
 | 193 |   len=l;
 | 
|---|
 | 194 | }
 | 
|---|
 | 195 | 
 | 
|---|
 | 196 | int
 | 
|---|
 | 197 | SO_block::add(SO& s, int i)
 | 
|---|
 | 198 | {
 | 
|---|
 | 199 |   // first check to see if s is already here
 | 
|---|
 | 200 |   for (int j=0; j < ((i < len) ? i : len); j++)
 | 
|---|
 | 201 |     if (so[j].equiv(s))
 | 
|---|
 | 202 |       return 0;
 | 
|---|
 | 203 |       
 | 
|---|
 | 204 |   if (i >= len)
 | 
|---|
 | 205 |     reset_length(i+1);
 | 
|---|
 | 206 |   so[i] = s;
 | 
|---|
 | 207 | 
 | 
|---|
 | 208 |   return 1;
 | 
|---|
 | 209 | }
 | 
|---|
 | 210 | 
 | 
|---|
 | 211 | void
 | 
|---|
 | 212 | SO_block::print(const char *title)
 | 
|---|
 | 213 | {
 | 
|---|
 | 214 |   int i,j;
 | 
|---|
 | 215 |   ExEnv::out0() << indent << "SO block " << title << endl;
 | 
|---|
 | 216 |   for (i=0; i < len; i++) {
 | 
|---|
 | 217 |     ExEnv::out0() << indent << "SO " << i+1 << endl << indent;
 | 
|---|
 | 218 |     for (j=0; j < so[i].length; j++)
 | 
|---|
 | 219 |       ExEnv::out0() << scprintf(" %10d",so[i].cont[j].bfn);
 | 
|---|
 | 220 |     ExEnv::out0() << endl << indent;
 | 
|---|
 | 221 |     for (j=0; j < so[i].length; j++)
 | 
|---|
 | 222 |       ExEnv::out0() << scprintf(" %10.7f",so[i].cont[j].coef);
 | 
|---|
 | 223 |     ExEnv::out0() << endl;
 | 
|---|
 | 224 |   }
 | 
|---|
 | 225 | }
 | 
|---|
 | 226 | 
 | 
|---|
 | 227 | ////////////////////////////////////////////////////////////////////////////
 | 
|---|
 | 228 | 
 | 
|---|
 | 229 | struct lin_comb {
 | 
|---|
 | 230 |     int ns;
 | 
|---|
 | 231 |     int f0;
 | 
|---|
 | 232 |     int mapf0;
 | 
|---|
 | 233 |     double **c;
 | 
|---|
 | 234 | 
 | 
|---|
 | 235 |     lin_comb(int ins, int if0, int imf0) : ns(ins), f0(if0), mapf0(imf0) {
 | 
|---|
 | 236 |       int i;
 | 
|---|
 | 237 |       
 | 
|---|
 | 238 |       c = new double*[ns];
 | 
|---|
 | 239 |       for (i=0; i < ns; i++) {
 | 
|---|
 | 240 |         c[i] = new double[ns];
 | 
|---|
 | 241 |         memset(c[i],0,sizeof(double)*ns);
 | 
|---|
 | 242 |       }
 | 
|---|
 | 243 |     }
 | 
|---|
 | 244 | 
 | 
|---|
 | 245 |     ~lin_comb() {
 | 
|---|
 | 246 |       if (c) {
 | 
|---|
 | 247 |         for (int i=0; i < ns; i++)
 | 
|---|
 | 248 |           if (c[i])
 | 
|---|
 | 249 |             delete[] c[i];
 | 
|---|
 | 250 |         delete[] c;
 | 
|---|
 | 251 |         c=0;
 | 
|---|
 | 252 |       }
 | 
|---|
 | 253 |     }
 | 
|---|
 | 254 | 
 | 
|---|
 | 255 |     void print() const {
 | 
|---|
 | 256 |       int i;
 | 
|---|
 | 257 |       ExEnv::out0() << indent;
 | 
|---|
 | 258 |       for (i=0; i < ns; i++)
 | 
|---|
 | 259 |         ExEnv::out0() << scprintf(" %10d",mapf0+i);
 | 
|---|
 | 260 |       ExEnv::out0() << endl;
 | 
|---|
 | 261 |       
 | 
|---|
 | 262 |       for (i=0; i < ns; i++) {
 | 
|---|
 | 263 |         ExEnv::out0() << indent << scprintf("%2d",f0+i);
 | 
|---|
 | 264 |         for (int j=0; j < ns; j++)
 | 
|---|
 | 265 |           ExEnv::out0() << scprintf(" %10.7f",c[i][j]);
 | 
|---|
 | 266 |         ExEnv::out0() << endl;
 | 
|---|
 | 267 |       }
 | 
|---|
 | 268 |     }
 | 
|---|
 | 269 | };
 | 
|---|
 | 270 | 
 | 
|---|
 | 271 | ////////////////////////////////////////////////////////////////////////////
 | 
|---|
 | 272 | 
 | 
|---|
 | 273 | SO_block *
 | 
|---|
 | 274 | PetiteList::aotoso_info()
 | 
|---|
 | 275 | {
 | 
|---|
 | 276 |   int iuniq, i, j, d, ii, jj, g, s, c, ir;
 | 
|---|
 | 277 | 
 | 
|---|
 | 278 |   GaussianBasisSet& gbs = *gbs_.pointer();
 | 
|---|
 | 279 |   Molecule& mol = *gbs.molecule().pointer();
 | 
|---|
 | 280 | 
 | 
|---|
 | 281 |   // create the character table for the point group
 | 
|---|
 | 282 |   CharacterTable ct = mol.point_group()->char_table();
 | 
|---|
 | 283 |   SymmetryOperation so;
 | 
|---|
 | 284 | 
 | 
|---|
 | 285 |   if (c1_) {
 | 
|---|
 | 286 |     SO_block *SOs = new SO_block[1];
 | 
|---|
 | 287 |     SOs[0].set_length(gbs.nbasis());
 | 
|---|
 | 288 |     for (i=0; i < gbs.nbasis(); i++) {
 | 
|---|
 | 289 |       SOs[0].so[i].set_length(1);
 | 
|---|
 | 290 |       SOs[0].so[i].cont[0].bfn=i;
 | 
|---|
 | 291 |       SOs[0].so[i].cont[0].coef=1.0;
 | 
|---|
 | 292 |     }
 | 
|---|
 | 293 |     return SOs;
 | 
|---|
 | 294 |   }
 | 
|---|
 | 295 | 
 | 
|---|
 | 296 |   // ncomp is the number of symmetry blocks we have. for point groups with
 | 
|---|
 | 297 |   // complex E representations, this will be cut in two eventually
 | 
|---|
 | 298 |   int ncomp=0;
 | 
|---|
 | 299 |   for (i=0; i < nirrep_; i++)
 | 
|---|
 | 300 |     ncomp += ct.gamma(i).degeneracy();
 | 
|---|
 | 301 |   
 | 
|---|
 | 302 |   // saoelem is the current SO in a block
 | 
|---|
 | 303 |   int *saoelem = new int[ncomp];
 | 
|---|
 | 304 |   memset(saoelem,0,sizeof(int)*ncomp);
 | 
|---|
 | 305 | 
 | 
|---|
 | 306 |   int *whichir = new int[ncomp];
 | 
|---|
 | 307 |   int *whichcmp = new int[ncomp];
 | 
|---|
 | 308 |   for (i=ii=0; i < nirrep_; i++) {
 | 
|---|
 | 309 |     for (int j=0; j < ct.gamma(i).degeneracy(); j++,ii++) {
 | 
|---|
 | 310 |       whichir[ii] = i;
 | 
|---|
 | 311 |       whichcmp[ii] = j;
 | 
|---|
 | 312 |     }
 | 
|---|
 | 313 |   }
 | 
|---|
 | 314 |   
 | 
|---|
 | 315 |   // SOs is an array of SO_blocks which holds the redundant SO's
 | 
|---|
 | 316 |   SO_block *SOs = new SO_block[ncomp];
 | 
|---|
 | 317 | 
 | 
|---|
 | 318 |   for (i=0; i < ncomp; i++) {
 | 
|---|
 | 319 |     ir = whichir[i];
 | 
|---|
 | 320 |     int len = (ct.gamma(ir).complex()) ? nbf_in_ir_[ir]/2 : nbf_in_ir_[ir];
 | 
|---|
 | 321 |     SOs[i].set_length(len);
 | 
|---|
 | 322 |   }
 | 
|---|
 | 323 |   
 | 
|---|
 | 324 |   // loop over all unique shells
 | 
|---|
 | 325 |   for (iuniq=0; iuniq < gbs.molecule()->nunique(); iuniq++) {
 | 
|---|
 | 326 |     int nequiv = gbs.molecule()->nequivalent(iuniq);
 | 
|---|
 | 327 |     i = gbs.molecule()->unique(iuniq);
 | 
|---|
 | 328 |     for (s=0; s < gbs.nshell_on_center(i); s++) {
 | 
|---|
 | 329 |       int shell_i = gbs.shell_on_center(i,s);
 | 
|---|
 | 330 |       
 | 
|---|
 | 331 |       // test to see if there are any high am cartesian functions in this
 | 
|---|
 | 332 |       // shell.  for now don't allow symmetry with cartesian functions...I
 | 
|---|
 | 333 |       // just can't seem to get them working.
 | 
|---|
 | 334 |       for (c=0; c < gbs(i,s).ncontraction(); c++) {
 | 
|---|
 | 335 |         if (gbs(i,s).am(c) > 1 && gbs(i,s).is_cartesian(c)) {
 | 
|---|
 | 336 |           if (ng_ != nirrep_) {
 | 
|---|
 | 337 |             ExEnv::err0() << indent
 | 
|---|
 | 338 |                          << "PetiteList::aotoso: cannot yet handle"
 | 
|---|
 | 339 |                          << " symmetry for angular momentum >= 2\n";
 | 
|---|
 | 340 |             abort();
 | 
|---|
 | 341 |           }
 | 
|---|
 | 342 |         }
 | 
|---|
 | 343 |       }
 | 
|---|
 | 344 | 
 | 
|---|
 | 345 |       // the functions do not mix between contractions
 | 
|---|
 | 346 |       // so the contraction loop can be done outside the symmetry
 | 
|---|
 | 347 |       // operation loop
 | 
|---|
 | 348 |       int bfn_offset_in_shell = 0;
 | 
|---|
 | 349 |       for (c=0; c < gbs(i,s).ncontraction(); c++) {
 | 
|---|
 | 350 |         int nfuncuniq = gbs(i,s).nfunction(c);
 | 
|---|
 | 351 |         int nfuncall = nfuncuniq * nequiv;
 | 
|---|
 | 352 | 
 | 
|---|
 | 353 |         // allocate an array to store linear combinations of orbitals
 | 
|---|
 | 354 |         // this is destroyed by the SVD routine
 | 
|---|
 | 355 |         double **linorb = new double*[nfuncuniq];
 | 
|---|
 | 356 |         linorb[0] = new double[nfuncuniq*nfuncall];
 | 
|---|
 | 357 |         for (j=1; j<nfuncuniq; j++) {
 | 
|---|
 | 358 |           linorb[j] = &linorb[j-1][nfuncall];
 | 
|---|
 | 359 |         }
 | 
|---|
 | 360 | 
 | 
|---|
 | 361 |         // a copy of linorb
 | 
|---|
 | 362 |         double **linorbcop = new double*[nfuncuniq];
 | 
|---|
 | 363 |         linorbcop[0] = new double[nfuncuniq*nfuncall];
 | 
|---|
 | 364 |         for (j=1; j<nfuncuniq; j++) {
 | 
|---|
 | 365 |           linorbcop[j] = &linorbcop[j-1][nfuncall];
 | 
|---|
 | 366 |         }
 | 
|---|
 | 367 | 
 | 
|---|
 | 368 |         // allocate an array for the SVD routine
 | 
|---|
 | 369 |         double **u = new double*[nfuncuniq];
 | 
|---|
 | 370 |         u[0] = new double[nfuncuniq*nfuncuniq];
 | 
|---|
 | 371 |         for (j=1; j<nfuncuniq; j++) {
 | 
|---|
 | 372 |           u[j] = &u[j-1][nfuncuniq];
 | 
|---|
 | 373 |         }
 | 
|---|
 | 374 | 
 | 
|---|
 | 375 |         // loop through each irrep to form the linear combination
 | 
|---|
 | 376 |         // of orbitals of that symmetry
 | 
|---|
 | 377 |         int irnum = 0;
 | 
|---|
 | 378 |         for (ir=0; ir<ct.nirrep(); ir++) {
 | 
|---|
 | 379 |           int cmplx = (ct.complex() && ct.gamma(ir).complex());
 | 
|---|
 | 380 |           for (int comp=0; comp < ct.gamma(ir).degeneracy(); comp++) {
 | 
|---|
 | 381 |             memset(linorb[0], 0, nfuncuniq*nfuncall*sizeof(double));
 | 
|---|
 | 382 |             for (d=0; d < ct.gamma(ir).degeneracy(); d++) {
 | 
|---|
 | 383 |               // if this is a point group with a complex E representation,
 | 
|---|
 | 384 |               // then only do the first set of projections for E
 | 
|---|
 | 385 |               if (d && cmplx) break;
 | 
|---|
 | 386 | 
 | 
|---|
 | 387 |               // operate on each function in this contraction with each
 | 
|---|
 | 388 |               // symmetry operation to form symmetrized linear combinations
 | 
|---|
 | 389 |               // of orbitals
 | 
|---|
 | 390 | 
 | 
|---|
 | 391 |               for (g=0; g<ng_; g++) {
 | 
|---|
 | 392 |                 // the character
 | 
|---|
 | 393 |                 double ccdg = ct.gamma(ir).p(comp,d,g);
 | 
|---|
 | 394 | 
 | 
|---|
 | 395 |                 so = ct.symm_operation(g);
 | 
|---|
 | 396 |                 int equivatom = atom_map_[i][g];
 | 
|---|
 | 397 |                 int atomoffset
 | 
|---|
 | 398 |                   = gbs.molecule()->atom_to_unique_offset(equivatom);
 | 
|---|
 | 399 |         
 | 
|---|
 | 400 |                 ShellRotation rr
 | 
|---|
 | 401 |                   = ints_->shell_rotation(gbs(i,s).am(c),
 | 
|---|
 | 402 |                                           so,gbs(i,s).is_pure(c));
 | 
|---|
 | 403 | 
 | 
|---|
 | 404 |                 for (ii=0; ii < rr.dim(); ii++) {
 | 
|---|
 | 405 |                   for (jj=0; jj < rr.dim(); jj++) {
 | 
|---|
 | 406 |                     linorb[ii][atomoffset*nfuncuniq+jj] += ccdg * rr(ii,jj);
 | 
|---|
 | 407 |                   }
 | 
|---|
 | 408 |                 }
 | 
|---|
 | 409 |               }
 | 
|---|
 | 410 |             }
 | 
|---|
 | 411 |             // find the linearly independent SO's for this irrep/component
 | 
|---|
 | 412 |             memcpy(linorbcop[0], linorb[0], nfuncuniq*nfuncall*sizeof(double));
 | 
|---|
 | 413 |             double *singval = new double[nfuncuniq];
 | 
|---|
 | 414 |             double djunk=0; int ijunk=1;
 | 
|---|
 | 415 |             int lwork = 5*nfuncall;
 | 
|---|
 | 416 |             double *work = new double[lwork];
 | 
|---|
 | 417 |             int info;
 | 
|---|
 | 418 |             // solves At = V SIGMA Ut (since FORTRAN array layout is used)
 | 
|---|
 | 419 |             F77_DGESVD("N","A",&nfuncall,&nfuncuniq,linorb[0],&nfuncall,
 | 
|---|
 | 420 |                        singval, &djunk, &ijunk, u[0], &nfuncuniq,
 | 
|---|
 | 421 |                        work, &lwork, &info);
 | 
|---|
 | 422 |             // put the lin indep symm orbs into the so array
 | 
|---|
 | 423 |             for (j=0; j<nfuncuniq; j++) {
 | 
|---|
 | 424 |               if (singval[j] > 1.0e-6) {
 | 
|---|
 | 425 |                 SO tso;
 | 
|---|
 | 426 |                 tso.set_length(nfuncall);
 | 
|---|
 | 427 |                 int ll = 0, llnonzero = 0;
 | 
|---|
 | 428 |                 for (int k=0; k<nequiv; k++) {
 | 
|---|
 | 429 |                   for (int l=0; l<nfuncuniq; l++,ll++) {
 | 
|---|
 | 430 |                     double tmp = 0.0;
 | 
|---|
 | 431 |                     for (int m=0; m<nfuncuniq; m++) {
 | 
|---|
 | 432 |                       tmp += u[m][j] * linorbcop[m][ll] / singval[j];
 | 
|---|
 | 433 |                     }
 | 
|---|
 | 434 |                     if (fabs(tmp) > DBL_EPSILON) {
 | 
|---|
 | 435 |                       int equivatom = gbs.molecule()->equivalent(iuniq,k);
 | 
|---|
 | 436 |                       tso.cont[llnonzero].bfn
 | 
|---|
 | 437 |                         = l
 | 
|---|
 | 438 |                         + bfn_offset_in_shell
 | 
|---|
 | 439 |                         + gbs.shell_to_function(gbs.shell_on_center(equivatom,
 | 
|---|
 | 440 |                                                                     s));
 | 
|---|
 | 441 |                       tso.cont[llnonzero].coef = tmp;
 | 
|---|
 | 442 |                       llnonzero++;
 | 
|---|
 | 443 |                     }
 | 
|---|
 | 444 |                   }
 | 
|---|
 | 445 |                 }
 | 
|---|
 | 446 |                 tso.reset_length(llnonzero);
 | 
|---|
 | 447 |                 if (llnonzero == 0) {
 | 
|---|
 | 448 |                   ExEnv::errn() << "aotoso: internal error: no bfns in SO"
 | 
|---|
 | 449 |                                << endl;
 | 
|---|
 | 450 |                   abort();
 | 
|---|
 | 451 |                 }
 | 
|---|
 | 452 |                 if (SOs[irnum+comp].add(tso,saoelem[irnum+comp])) {
 | 
|---|
 | 453 |                   saoelem[irnum+comp]++;
 | 
|---|
 | 454 |                 }
 | 
|---|
 | 455 |                 else {
 | 
|---|
 | 456 |                   ExEnv::errn() << "aotoso: internal error: "
 | 
|---|
 | 457 |                                << "impossible duplicate SO"
 | 
|---|
 | 458 |                                << endl;
 | 
|---|
 | 459 |                   abort();
 | 
|---|
 | 460 |                 }
 | 
|---|
 | 461 |               }
 | 
|---|
 | 462 |             }
 | 
|---|
 | 463 |             delete[] singval;
 | 
|---|
 | 464 |             delete[] work;
 | 
|---|
 | 465 |           }
 | 
|---|
 | 466 |           irnum += ct.gamma(ir).degeneracy();
 | 
|---|
 | 467 |         }
 | 
|---|
 | 468 |         bfn_offset_in_shell += gbs(i,s).nfunction(c);
 | 
|---|
 | 469 | 
 | 
|---|
 | 470 |         delete[] linorb[0];
 | 
|---|
 | 471 |         delete[] linorb;
 | 
|---|
 | 472 |         delete[] linorbcop[0];
 | 
|---|
 | 473 |         delete[] linorbcop;
 | 
|---|
 | 474 |         delete[] u[0];
 | 
|---|
 | 475 |         delete[] u;
 | 
|---|
 | 476 |       }
 | 
|---|
 | 477 |     }
 | 
|---|
 | 478 |   }
 | 
|---|
 | 479 | 
 | 
|---|
 | 480 |   // Make sure all the nodes agree on what the symmetry orbitals are.
 | 
|---|
 | 481 |   // (All the above work for me > 0 is ignored.)
 | 
|---|
 | 482 |   Ref<MessageGrp> grp = MessageGrp::get_default_messagegrp();
 | 
|---|
 | 483 |   for (i=0; i<ncomp; i++) {
 | 
|---|
 | 484 |     int len = SOs[i].len;
 | 
|---|
 | 485 |     grp->bcast(len);
 | 
|---|
 | 486 |     SOs[i].reset_length(len);
 | 
|---|
 | 487 |     for (j=0; j<len; j++) {
 | 
|---|
 | 488 |       int solen = SOs[i].so[j].length;
 | 
|---|
 | 489 |       grp->bcast(solen);
 | 
|---|
 | 490 |       SOs[i].so[j].reset_length(solen);
 | 
|---|
 | 491 |       for (int k=0; k<solen; k++) {
 | 
|---|
 | 492 |         grp->bcast(SOs[i].so[j].cont[k].bfn);
 | 
|---|
 | 493 |         grp->bcast(SOs[i].so[j].cont[k].coef);
 | 
|---|
 | 494 |       }
 | 
|---|
 | 495 |     }
 | 
|---|
 | 496 |   }
 | 
|---|
 | 497 | 
 | 
|---|
 | 498 |   for (i=0; i < ncomp; i++) {
 | 
|---|
 | 499 |     ir = whichir[i];
 | 
|---|
 | 500 |     int scal = ct.gamma(ir).complex() ? 2 : 1;
 | 
|---|
 | 501 | 
 | 
|---|
 | 502 |     if (saoelem[i] < nbf_in_ir_[ir]/scal) {
 | 
|---|
 | 503 |       // if we found too few, there are big problems
 | 
|---|
 | 504 |       
 | 
|---|
 | 505 |       ExEnv::err0() << indent
 | 
|---|
 | 506 |            << scprintf("trouble making SO's for irrep %s\n",
 | 
|---|
 | 507 |                        ct.gamma(ir).symbol());
 | 
|---|
 | 508 |       ExEnv::err0() << indent
 | 
|---|
 | 509 |            << scprintf("  only found %d out of %d SO's\n",
 | 
|---|
 | 510 |                        saoelem[i], nbf_in_ir_[ir]/scal);
 | 
|---|
 | 511 |       SOs[i].print("");
 | 
|---|
 | 512 |       abort();
 | 
|---|
 | 513 | 
 | 
|---|
 | 514 |     } else if (saoelem[i] > nbf_in_ir_[ir]/scal) {
 | 
|---|
 | 515 |       // there are some redundant so's left...need to do something to get
 | 
|---|
 | 516 |       // the elements we want
 | 
|---|
 | 517 |       
 | 
|---|
 | 518 |       ExEnv::err0() << indent
 | 
|---|
 | 519 |            << scprintf("trouble making SO's for irrep %s\n",
 | 
|---|
 | 520 |                        ct.gamma(ir).symbol());
 | 
|---|
 | 521 |       ExEnv::err0() << indent
 | 
|---|
 | 522 |            << scprintf("  found %d SO's, but there should only be %d\n",
 | 
|---|
 | 523 |                        saoelem[i], nbf_in_ir_[ir]/scal);
 | 
|---|
 | 524 |       SOs[i].print("");
 | 
|---|
 | 525 |       abort();
 | 
|---|
 | 526 |     }
 | 
|---|
 | 527 |   }
 | 
|---|
 | 528 | 
 | 
|---|
 | 529 |   if (ct.complex()) {
 | 
|---|
 | 530 |     SO_block *nSOs = new SO_block[nblocks_];
 | 
|---|
 | 531 | 
 | 
|---|
 | 532 |     int in=0;
 | 
|---|
 | 533 | 
 | 
|---|
 | 534 |     for (i=ir=0; ir < nirrep_; ir++) {
 | 
|---|
 | 535 |       if (ct.gamma(ir).complex()) {
 | 
|---|
 | 536 |         nSOs[in].set_length(nbf_in_ir_[ir]);
 | 
|---|
 | 537 |         int k;
 | 
|---|
 | 538 |         for (k=0; k < SOs[i].len; k++)
 | 
|---|
 | 539 |           nSOs[in].add(SOs[i].so[k],k);
 | 
|---|
 | 540 |         i++;
 | 
|---|
 | 541 | 
 | 
|---|
 | 542 |         for (j=0; j < SOs[i].len; j++,k++)
 | 
|---|
 | 543 |           nSOs[in].add(SOs[i].so[j],k);
 | 
|---|
 | 544 | 
 | 
|---|
 | 545 |         i++;
 | 
|---|
 | 546 |         in++;
 | 
|---|
 | 547 |       } else {
 | 
|---|
 | 548 |         for (j=0; j < ct.gamma(ir).degeneracy(); j++,i++,in++) {
 | 
|---|
 | 549 |           nSOs[in].set_length(nbf_in_ir_[ir]);
 | 
|---|
 | 550 |           for (int k=0; k < SOs[i].len; k++)
 | 
|---|
 | 551 |             nSOs[in].add(SOs[i].so[k],k);
 | 
|---|
 | 552 |         }
 | 
|---|
 | 553 |       }
 | 
|---|
 | 554 |     }
 | 
|---|
 | 555 | 
 | 
|---|
 | 556 |     SO_block *tmp= SOs;
 | 
|---|
 | 557 |     SOs = nSOs;
 | 
|---|
 | 558 |     delete[] tmp;
 | 
|---|
 | 559 |   }
 | 
|---|
 | 560 | 
 | 
|---|
 | 561 |   delete[] saoelem;
 | 
|---|
 | 562 |   delete[] whichir;
 | 
|---|
 | 563 |   delete[] whichcmp;
 | 
|---|
 | 564 | 
 | 
|---|
 | 565 |   return SOs;
 | 
|---|
 | 566 | }
 | 
|---|
 | 567 | 
 | 
|---|
 | 568 | RefSCMatrix
 | 
|---|
 | 569 | PetiteList::aotoso()
 | 
|---|
 | 570 | {
 | 
|---|
 | 571 |   RefSCMatrix aoso(AO_basisdim(), SO_basisdim(), gbs_->so_matrixkit());
 | 
|---|
 | 572 |   aoso.assign(0.0);
 | 
|---|
 | 573 | 
 | 
|---|
 | 574 |   if (c1_) {
 | 
|---|
 | 575 |     aoso->unit();
 | 
|---|
 | 576 |     return aoso;
 | 
|---|
 | 577 |   }
 | 
|---|
 | 578 |   
 | 
|---|
 | 579 |   SO_block *sos = aotoso_info();
 | 
|---|
 | 580 |   
 | 
|---|
 | 581 |   BlockedSCMatrix *aosop = dynamic_cast<BlockedSCMatrix*>(aoso.pointer());
 | 
|---|
 | 582 | 
 | 
|---|
 | 583 |   for (int b=0; b < aosop->nblocks(); b++) {
 | 
|---|
 | 584 |     RefSCMatrix aosb = aosop->block(b);
 | 
|---|
 | 585 | 
 | 
|---|
 | 586 |     if (aosb.null())
 | 
|---|
 | 587 |       continue;
 | 
|---|
 | 588 |     
 | 
|---|
 | 589 |     SO_block& sob = sos[b];
 | 
|---|
 | 590 |     
 | 
|---|
 | 591 |     Ref<SCMatrixSubblockIter> iter =
 | 
|---|
 | 592 |       aosb->local_blocks(SCMatrixSubblockIter::Write);
 | 
|---|
 | 593 | 
 | 
|---|
 | 594 |     for (iter->begin(); iter->ready(); iter->next()) {
 | 
|---|
 | 595 |       if (dynamic_cast<SCMatrixRectBlock*>(iter->block())) {
 | 
|---|
 | 596 |         SCMatrixRectBlock *blk = dynamic_cast<SCMatrixRectBlock*>(iter->block());
 | 
|---|
 | 597 | 
 | 
|---|
 | 598 |         int jlen = blk->jend-blk->jstart;
 | 
|---|
 | 599 |     
 | 
|---|
 | 600 |         for (int j=0; j < sob.len; j++) {
 | 
|---|
 | 601 |           if (j < blk->jstart || j >= blk->jend)
 | 
|---|
 | 602 |             continue;
 | 
|---|
 | 603 |       
 | 
|---|
 | 604 |           SO& soj = sob.so[j];
 | 
|---|
 | 605 |       
 | 
|---|
 | 606 |           for (int i=0; i < soj.len; i++) {
 | 
|---|
 | 607 |             int ii=soj.cont[i].bfn;
 | 
|---|
 | 608 |             
 | 
|---|
 | 609 |             if (ii < blk->istart || ii >= blk->iend)
 | 
|---|
 | 610 |               continue;
 | 
|---|
 | 611 | 
 | 
|---|
 | 612 |             blk->data[(ii-blk->istart)*jlen+(j-blk->jstart)] =
 | 
|---|
 | 613 |               soj.cont[i].coef;
 | 
|---|
 | 614 |           }
 | 
|---|
 | 615 |         }
 | 
|---|
 | 616 |       } else {
 | 
|---|
 | 617 |         SCMatrixRectSubBlock *blk =
 | 
|---|
 | 618 |           dynamic_cast<SCMatrixRectSubBlock*>(iter->block());
 | 
|---|
 | 619 | 
 | 
|---|
 | 620 |         for (int j=0; j < sob.len; j++) {
 | 
|---|
 | 621 |           if (j < blk->jstart || j >= blk->jend)
 | 
|---|
 | 622 |             continue;
 | 
|---|
 | 623 |       
 | 
|---|
 | 624 |           SO& soj = sob.so[j];
 | 
|---|
 | 625 |       
 | 
|---|
 | 626 |           for (int i=0; i < soj.len; i++) {
 | 
|---|
 | 627 |             int ii=soj.cont[i].bfn;
 | 
|---|
 | 628 |         
 | 
|---|
 | 629 |             if (ii < blk->istart || ii >= blk->iend)
 | 
|---|
 | 630 |               continue;
 | 
|---|
 | 631 | 
 | 
|---|
 | 632 |             blk->data[ii*blk->istride+j] = soj.cont[i].coef;
 | 
|---|
 | 633 |           }
 | 
|---|
 | 634 |         }
 | 
|---|
 | 635 |       }
 | 
|---|
 | 636 |     }
 | 
|---|
 | 637 |   }
 | 
|---|
 | 638 |   
 | 
|---|
 | 639 |   delete[] sos;
 | 
|---|
 | 640 | 
 | 
|---|
 | 641 |   return aoso;
 | 
|---|
 | 642 | }
 | 
|---|
 | 643 | 
 | 
|---|
 | 644 | RefSCMatrix
 | 
|---|
 | 645 | PetiteList::sotoao()
 | 
|---|
 | 646 | {
 | 
|---|
 | 647 |   if (c1_)
 | 
|---|
 | 648 |     return aotoso();
 | 
|---|
 | 649 |   else if (nirrep_ == ng_) // subgroup of d2h
 | 
|---|
 | 650 |     return aotoso().t();
 | 
|---|
 | 651 |   else
 | 
|---|
 | 652 |     return aotoso().i();
 | 
|---|
 | 653 | }
 | 
|---|
 | 654 | 
 | 
|---|
 | 655 | RefSymmSCMatrix
 | 
|---|
 | 656 | PetiteList::to_SO_basis(const RefSymmSCMatrix& a)
 | 
|---|
 | 657 | {
 | 
|---|
 | 658 |   // SO basis is always blocked, so first make sure a is blocked
 | 
|---|
 | 659 |   RefSymmSCMatrix aomatrix = dynamic_cast<BlockedSymmSCMatrix*>(a.pointer());
 | 
|---|
 | 660 |   if (aomatrix.null()) {
 | 
|---|
 | 661 |     aomatrix = gbs_->so_matrixkit()->symmmatrix(AO_basisdim());
 | 
|---|
 | 662 |     aomatrix->convert(a);
 | 
|---|
 | 663 |   }
 | 
|---|
 | 664 | 
 | 
|---|
 | 665 |   // if C1, then do nothing
 | 
|---|
 | 666 |   if (c1_)
 | 
|---|
 | 667 |     return aomatrix.copy();
 | 
|---|
 | 668 |   
 | 
|---|
 | 669 |   RefSymmSCMatrix somatrix(SO_basisdim(), gbs_->so_matrixkit());
 | 
|---|
 | 670 |   somatrix.assign(0.0);
 | 
|---|
 | 671 |   somatrix->accumulate_transform(aotoso(), aomatrix,
 | 
|---|
 | 672 |                                  SCMatrix::TransposeTransform);
 | 
|---|
 | 673 | 
 | 
|---|
 | 674 |   return somatrix;
 | 
|---|
 | 675 | }
 | 
|---|
 | 676 | 
 | 
|---|
 | 677 | RefSymmSCMatrix
 | 
|---|
 | 678 | PetiteList::to_AO_basis(const RefSymmSCMatrix& somatrix)
 | 
|---|
 | 679 | {
 | 
|---|
 | 680 |   // if C1, then do nothing
 | 
|---|
 | 681 |   if (c1_)
 | 
|---|
 | 682 |     return somatrix.copy();
 | 
|---|
 | 683 |   
 | 
|---|
 | 684 |   RefSymmSCMatrix aomatrix(AO_basisdim(), gbs_->so_matrixkit());
 | 
|---|
 | 685 |   aomatrix.assign(0.0);
 | 
|---|
 | 686 | 
 | 
|---|
 | 687 |   if (nirrep_ == ng_) // subgroup of d2h
 | 
|---|
 | 688 |     aomatrix->accumulate_transform(aotoso(), somatrix);
 | 
|---|
 | 689 |   else
 | 
|---|
 | 690 |     aomatrix->accumulate_transform(aotoso().i(), somatrix,
 | 
|---|
 | 691 |                                    SCMatrix::TransposeTransform);
 | 
|---|
 | 692 | 
 | 
|---|
 | 693 |   return aomatrix;
 | 
|---|
 | 694 | }
 | 
|---|
 | 695 | 
 | 
|---|
 | 696 | RefSCMatrix
 | 
|---|
 | 697 | PetiteList::evecs_to_SO_basis(const RefSCMatrix& aoev)
 | 
|---|
 | 698 | {
 | 
|---|
 | 699 |   ExEnv::err0() << indent
 | 
|---|
 | 700 |        << "PetiteList::evecs_to_SO_basis: don't work yet\n";
 | 
|---|
 | 701 |   abort();
 | 
|---|
 | 702 |   
 | 
|---|
 | 703 |   RefSCMatrix aoevecs = dynamic_cast<BlockedSCMatrix*>(aoev.pointer());
 | 
|---|
 | 704 |   if (aoevecs.null()) {
 | 
|---|
 | 705 |     aoevecs = gbs_->so_matrixkit()->matrix(AO_basisdim(), AO_basisdim());
 | 
|---|
 | 706 |     aoevecs->convert(aoev);
 | 
|---|
 | 707 |   }
 | 
|---|
 | 708 | 
 | 
|---|
 | 709 |   RefSCMatrix soev =  aotoso().t() * aoevecs;
 | 
|---|
 | 710 |   soev.print("soev");
 | 
|---|
 | 711 | 
 | 
|---|
 | 712 |   RefSCMatrix soevecs(SO_basisdim(), SO_basisdim(), gbs_->so_matrixkit());
 | 
|---|
 | 713 |   soevecs->convert(soev);
 | 
|---|
 | 714 | 
 | 
|---|
 | 715 |   return soevecs;
 | 
|---|
 | 716 | }
 | 
|---|
 | 717 | 
 | 
|---|
 | 718 | RefSCMatrix
 | 
|---|
 | 719 | PetiteList::evecs_to_AO_basis(const RefSCMatrix& soevecs)
 | 
|---|
 | 720 | {
 | 
|---|
 | 721 |   // if C1, then do nothing
 | 
|---|
 | 722 |   if (c1_)
 | 
|---|
 | 723 |     return soevecs.copy();
 | 
|---|
 | 724 |   
 | 
|---|
 | 725 |   RefSCMatrix aoev = aotoso() * soevecs;
 | 
|---|
 | 726 | 
 | 
|---|
 | 727 |   return aoev;
 | 
|---|
 | 728 | }
 | 
|---|
 | 729 | 
 | 
|---|
 | 730 | /////////////////////////////////////////////////////////////////////////////
 | 
|---|
 | 731 | 
 | 
|---|
 | 732 | void
 | 
|---|
 | 733 | PetiteList::symmetrize(const RefSymmSCMatrix& skel,
 | 
|---|
 | 734 |                        const RefSymmSCMatrix& sym)
 | 
|---|
 | 735 | {
 | 
|---|
 | 736 |   GaussianBasisSet& gbs = *gbs_.pointer();
 | 
|---|
 | 737 | 
 | 
|---|
 | 738 |   // SO basis is always blocked, so first make sure skel is blocked
 | 
|---|
 | 739 |   RefSymmSCMatrix bskel = dynamic_cast<BlockedSymmSCMatrix*>(skel.pointer());
 | 
|---|
 | 740 |   if (bskel.null()) {
 | 
|---|
 | 741 |     bskel = gbs.so_matrixkit()->symmmatrix(AO_basisdim());
 | 
|---|
 | 742 |     bskel->convert(skel);
 | 
|---|
 | 743 |   }
 | 
|---|
 | 744 |   
 | 
|---|
 | 745 |   // if C1, then do nothing
 | 
|---|
 | 746 |   if (c1_) {
 | 
|---|
 | 747 |     sym.assign(bskel);
 | 
|---|
 | 748 |     return;
 | 
|---|
 | 749 |   }
 | 
|---|
 | 750 |   
 | 
|---|
 | 751 |   int b,c;
 | 
|---|
 | 752 | 
 | 
|---|
 | 753 |   CharacterTable ct = gbs.molecule()->point_group()->char_table();
 | 
|---|
 | 754 | 
 | 
|---|
 | 755 |   RefSCMatrix aoso = aotoso();
 | 
|---|
 | 756 |   BlockedSCMatrix *lu = dynamic_cast<BlockedSCMatrix*>(aoso.pointer());
 | 
|---|
 | 757 | 
 | 
|---|
 | 758 |   for (b=0; b < lu->nblocks(); b++) {
 | 
|---|
 | 759 |     if (lu->block(b).null())
 | 
|---|
 | 760 |       continue;
 | 
|---|
 | 761 |     
 | 
|---|
 | 762 |     int ir = ct.which_irrep(b);
 | 
|---|
 | 763 |   
 | 
|---|
 | 764 |     double skal = (double)ct.order()/(double)ct.gamma(ir).degeneracy();
 | 
|---|
 | 765 |     skal = sqrt(skal);
 | 
|---|
 | 766 |     lu->block(b).scale(skal);
 | 
|---|
 | 767 |   }
 | 
|---|
 | 768 | 
 | 
|---|
 | 769 |   sym.assign(0.0);
 | 
|---|
 | 770 |   sym.accumulate_transform(aoso,bskel,SCMatrix::TransposeTransform);
 | 
|---|
 | 771 |   aoso=0;
 | 
|---|
 | 772 | 
 | 
|---|
 | 773 |   BlockedSymmSCMatrix *la = dynamic_cast<BlockedSymmSCMatrix*>(sym.pointer());
 | 
|---|
 | 774 |   
 | 
|---|
 | 775 |   // loop through blocks and finish symmetrizing degenerate blocks
 | 
|---|
 | 776 |   for (b=0; b < la->nblocks(); b++) {
 | 
|---|
 | 777 |     if (la->block(b).null())
 | 
|---|
 | 778 |       continue;
 | 
|---|
 | 779 | 
 | 
|---|
 | 780 |     int ir=ct.which_irrep(b);
 | 
|---|
 | 781 | 
 | 
|---|
 | 782 |     if (ct.gamma(ir).degeneracy()==1)
 | 
|---|
 | 783 |       continue;
 | 
|---|
 | 784 | 
 | 
|---|
 | 785 |     if (ct.gamma(ir).complex()) {
 | 
|---|
 | 786 |       int nbf = nbf_in_ir_[ir]/2;
 | 
|---|
 | 787 |       
 | 
|---|
 | 788 |       RefSymmSCMatrix irrep = la->block(b).get_subblock(0, nbf-1);
 | 
|---|
 | 789 |       irrep.accumulate(la->block(b).get_subblock(nbf, 2*nbf-1));
 | 
|---|
 | 790 | 
 | 
|---|
 | 791 |       RefSCMatrix sub = la->block(b).get_subblock(nbf, 2*nbf-1, 0, nbf-1);
 | 
|---|
 | 792 |       RefSCMatrix subt = sub.t();
 | 
|---|
 | 793 |       subt.scale(-1.0);
 | 
|---|
 | 794 |       sub.accumulate(subt);
 | 
|---|
 | 795 |       subt=0;
 | 
|---|
 | 796 | 
 | 
|---|
 | 797 |       la->block(b).assign_subblock(irrep,  0, nbf-1);
 | 
|---|
 | 798 |       la->block(b).assign_subblock(irrep,nbf, 2*nbf-1);
 | 
|---|
 | 799 |       la->block(b).assign_subblock(sub, nbf, 2*nbf-1, 0, nbf-1);
 | 
|---|
 | 800 | 
 | 
|---|
 | 801 |     } else {
 | 
|---|
 | 802 |       RefSymmSCMatrix irrep = la->block(b).copy();
 | 
|---|
 | 803 |       for (c=1; c < ct.gamma(ir).degeneracy(); c++)
 | 
|---|
 | 804 |         irrep.accumulate(la->block(b+c));
 | 
|---|
 | 805 |       
 | 
|---|
 | 806 |       for (c=0; c < ct.gamma(ir).degeneracy(); c++)
 | 
|---|
 | 807 |         la->block(b+c).assign(irrep);
 | 
|---|
 | 808 | 
 | 
|---|
 | 809 |       b += ct.gamma(ir).degeneracy()-1;
 | 
|---|
 | 810 |     }
 | 
|---|
 | 811 |   }
 | 
|---|
 | 812 | }
 | 
|---|
 | 813 | 
 | 
|---|
 | 814 | /////////////////////////////////////////////////////////////////////////////
 | 
|---|
 | 815 | 
 | 
|---|
 | 816 | // Local Variables:
 | 
|---|
 | 817 | // mode: c++
 | 
|---|
 | 818 | // c-file-style: "ETS"
 | 
|---|
 | 819 | // End:
 | 
|---|