1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Jordan E. Vincent, University of Illinois at Urbana-Champaign
8 //                    Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
9 //                    Miguel Morales, moralessilva2@llnl.gov, Lawrence Livermore National Laboratory
10 //                    Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
11 //                    Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
12 //
13 // File created by: Jordan E. Vincent, University of Illinois at Urbana-Champaign
14 //////////////////////////////////////////////////////////////////////////////////////
15 
16 
17 #include "GaussianFCHKParser.h"
18 #include <fstream>
19 #include <iterator>
20 #include <algorithm>
21 #include <set>
22 #include <map>
23 
24 
GaussianFCHKParser()25 GaussianFCHKParser::GaussianFCHKParser()
26 {
27   basisName  = "Gaussian-G2";
28   Normalized = "no";
29 }
30 
GaussianFCHKParser(int argc,char ** argv)31 GaussianFCHKParser::GaussianFCHKParser(int argc, char** argv) : QMCGaussianParserBase(argc, argv)
32 {
33   basisName  = "Gaussian-G2";
34   Normalized = "no";
35 }
36 
parse(const std::string & fname)37 void GaussianFCHKParser::parse(const std::string& fname)
38 {
39   std::ifstream fin(fname.c_str());
40   getwords(currentWords, fin); //1
41   Title = currentWords[0];
42   getwords(currentWords, fin); //2  SP RHF Gen
43   //if(currentWords[1]=="ROHF" || currentWords[1]=="UHF") {
44   if (currentWords[1] == "UHF")
45   {
46     // mmorales: this should be determined by the existence of "Beta MO", since
47     // there are many ways to get unrestricted runs without UHF (e.g. UMP2,UCCD,etc)
48     SpinRestricted = false;
49     //std::cout << " Spin Unrestricted Calculation (UHF). " << std::endl;
50   }
51   else
52   {
53     SpinRestricted = true;
54     //std::cout << " Spin Restricted Calculation (RHF). " << std::endl;
55   }
56   getwords(currentWords, fin); //3  Number of atoms
57   NumberOfAtoms = atoi(currentWords.back().c_str());
58   // TDB: THIS FIX SHOULD BE COMPATIBLE WITH MY OLD FCHK FILES
59   //getwords(currentWords,fin); //4 Charge
60   bool notfound = true;
61   while (notfound)
62   {
63     std::string aline;
64     getwords(currentWords, fin);
65     for (int i = 0; i < currentWords.size(); i++)
66     {
67       if ("Charge" == currentWords[i])
68       {
69         notfound = false;
70       }
71     }
72   }
73   getwords(currentWords, fin); //5 Multiplicity
74   SpinMultiplicity = atoi(currentWords.back().c_str());
75   getwords(currentWords, fin); //6 Number of electrons
76   NumberOfEls = atoi(currentWords.back().c_str());
77   getwords(currentWords, fin); //7 Number of alpha electrons
78   int nup = atoi(currentWords.back().c_str());
79   getwords(currentWords, fin); //8 Number of beta electrons
80   int ndown = atoi(currentWords.back().c_str());
81   //NumberOfAlpha=nup-ndown;
82   NumberOfAlpha = nup;
83   NumberOfBeta  = ndown;
84   getwords(currentWords, fin); //9 Number of basis functions
85   SizeOfBasisSet = atoi(currentWords.back().c_str());
86   getwords(currentWords, fin); //10 Number of independent functions
87   int NumOfIndOrb = atoi(currentWords.back().c_str());
88   std::cout << "Number of independent orbitals: " << NumOfIndOrb << std::endl;
89   numMO = NumOfIndOrb;
90   // TDB: THIS ADDITION SHOULD BE COMPATIBLE WITH MY OLD FCHK FILES
91   std::streampos pivottdb = fin.tellg();
92   int ng                  = 0;
93   notfound                = true;
94   while (notfound)
95   {
96     std::string aline;
97     getwords(currentWords, fin);
98     for (int i = 0; i < currentWords.size(); i++)
99     {
100       if ("contracted" == currentWords[i])
101       {
102         ng       = atoi(currentWords.back().c_str());
103         notfound = false;
104       }
105     }
106   }
107   // TDB: THIS FIX SHOULD BE COMPATIBLE WITH MY OLD FCHK FILES
108   // getwords(currentWords,fin); //Number of contracted shells
109   // getwords(currentWords,fin); //Number of contracted shells
110   // getwords(currentWords,fin); //Number of contracted shells
111   // int nx=atoi(currentWords.back().c_str()); //Number of exponents
112   int nx   = 0;
113   notfound = true;
114   while (notfound)
115   {
116     std::string aline;
117     getwords(currentWords, fin);
118     for (int i = 0; i < currentWords.size(); i++)
119     {
120       if ("primitive" == currentWords[i])
121       {
122         nx       = atoi(currentWords.back().c_str()); //Number of exponents
123         notfound = false;
124       }
125     }
126   }
127   //allocate everything here
128   IonSystem.create(NumberOfAtoms);
129   GroupName.resize(NumberOfAtoms);
130   gBound.resize(NumberOfAtoms + 1);
131   gShell.resize(ng);
132   gNumber.resize(ng);
133   gExp.resize(nx);
134   gC0.resize(nx);
135   gC1.resize(nx);
136   // TDB: THIS ADDITION SHOULD BE COMPATIBLE WITH MY OLD FCHK FILES
137   fin.seekg(pivottdb); //rewind it
138   getGeometry(fin);
139   std::cout << "Number of gaussians " << ng << std::endl;
140   std::cout << "Number of primitives " << nx << std::endl;
141   std::cout << "Number of atoms " << NumberOfAtoms << std::endl;
142   search(fin, "Shell types");
143   getGaussianCenters(fin);
144   std::cout << " Shell types reading: OK" << std::endl;
145   // mmorales: SizeOfBasisSet > numMO always, so leave it like this
146   EigVal_alpha.resize(SizeOfBasisSet);
147   EigVal_beta.resize(SizeOfBasisSet);
148   // mmorales HACK HACK HACK, look for a way to rewind w/o closing/opening a file
149   SpinRestricted = !(lookFor(fin, "Beta MO"));
150   fin.close();
151   fin.open(fname.c_str());
152   search(fin, "Alpha Orbital"); //search "Alpha Orbital Energies"
153                                 // only read NumOfIndOrb
154   getValues(fin, EigVal_alpha.begin(), EigVal_alpha.begin() + numMO);
155   std::cout << " Orbital energies reading: OK" << std::endl;
156   if (SpinRestricted)
157   {
158     EigVec.resize(2 * numMO * SizeOfBasisSet);
159     EigVal_beta = EigVal_alpha;
160     std::vector<value_type> etemp;
161     search(fin, "Alpha MO");
162     getValues(fin, EigVec.begin(), EigVec.begin() + SizeOfBasisSet * numMO);
163     copy(EigVec.begin(), EigVec.begin() + SizeOfBasisSet * numMO, EigVec.begin() + SizeOfBasisSet * numMO);
164     std::cout << " Orbital coefficients reading: OK" << std::endl;
165   }
166   else
167   {
168     EigVec.resize(2 * numMO * SizeOfBasisSet);
169     std::vector<value_type> etemp;
170     search(fin, "Beta Orbital");
171     getValues(fin, EigVal_beta.begin(), EigVal_beta.begin() + numMO);
172     std::cout << " Read Beta Orbital energies: OK" << std::endl;
173     search(fin, "Alpha MO");
174     getValues(fin, EigVec.begin(), EigVec.begin() + SizeOfBasisSet * numMO);
175     search(fin, "Beta MO");
176     getValues(fin, EigVec.begin() + numMO * SizeOfBasisSet, EigVec.begin() + 2 * numMO * SizeOfBasisSet);
177     std::cout << " Alpha and Beta Orbital coefficients reading: OK" << std::endl;
178   }
179   if (multideterminant)
180   {
181     std::ifstream ofile(outputFile.c_str());
182     if (ofile.fail())
183     {
184       std::cerr << "Failed to open output file from gaussian. \n";
185       exit(401);
186     }
187     int statesType          = 0;
188     std::streampos beginpos = ofile.tellg();
189     bool found              = lookFor(ofile, "SLATER DETERMINANT BASIS");
190     if (!found)
191     {
192       ofile.close();
193       ofile.open(outputFile.c_str());
194       ofile.seekg(beginpos);
195       found = lookFor(ofile, "Slater Determinants");
196       if (found)
197       {
198         statesType = 1;
199         ofile.close();
200         ofile.open(outputFile.c_str());
201         ofile.seekg(beginpos);
202         search(ofile, "Total number of active electrons");
203         getwords(currentWords, ofile);
204         ci_nstates = atoi(currentWords[5].c_str());
205         search(ofile, "Slater Determinants");
206       }
207       else
208       {
209         std::cerr << "Gaussian parser currently works for slater determinant basis only. Use SlaterDet in CAS() or "
210                      "improve parser.\n";
211         abort();
212       }
213     }
214     beginpos = ofile.tellg();
215     // mmorales: gaussian by default prints only 50 states
216     // if you want more you need to use, iop(5/33=1), but this prints
217     // a lot of things. So far, I don't know how to change this
218     // without modifying the source code, l510.F or utilam.F
219     found = lookFor(ofile, "Do an extra-iteration for final printing");
220     std::map<int, int> coeff2confg;
221     //   290 FORMAT(1X,7('(',I5,')',F10.7,1X)/(1X,7('(',I5,')',F10.7,1X)))
222     if (found)
223     {
224       // this is tricky, because output depends on diagonalizer used (Davidson or Lanczos) for now hope this works
225       std::streampos tmppos = ofile.tellg();
226       // long output with iop(5/33=1)
227       int coeffType = 0;
228       if (lookFor(ofile, "EIGENVECTOR USED TO COMPUTE DENSITY MATRICES SET"))
229       {
230         coeffType = 1;
231       }
232       else
233       {
234         // short list (50 states) with either Dav or Lanc
235         ofile.close();
236         ofile.open(outputFile.c_str());
237         ofile.seekg(tmppos); //rewind it
238         if (!lookFor(ofile, "EIGENVALUE "))
239         {
240           ofile.close();
241           ofile.open(outputFile.c_str());
242           ofile.seekg(tmppos); //rewind it
243           if (!lookFor(ofile, "Eigenvalue"))
244           {
245             std::cerr << "Failed to find CI voefficients.\n";
246             abort();
247           }
248         }
249       }
250       std::streampos strpos = ofile.tellg();
251       ofile.close();
252       ofile.open(outputFile.c_str());
253       ofile.seekg(beginpos); //rewind it
254       std::string aline;
255       int numCI;
256       if (lookFor(ofile, "NO OF BASIS FUNCTIONS", aline))
257       {
258         parsewords(aline.c_str(), currentWords);
259         numCI = atoi(currentWords[5].c_str());
260       }
261       else
262       {
263         ofile.close();
264         ofile.open(outputFile.c_str());
265         if (lookFor(ofile, "Number of configurations", aline))
266         {
267           parsewords(aline.c_str(), currentWords);
268           numCI = atoi(currentWords[3].c_str());
269         }
270         else
271         {
272           std::cerr << "Problems finding total number of configurations. \n";
273           abort();
274         }
275       }
276       std::cout << "Total number of CI configurations in file (w/o truncation): " << numCI << std::endl;
277       ofile.close();
278       ofile.open(outputFile.c_str());
279       ofile.seekg(strpos); //rewind it
280       int cnt = 0;
281       CIcoeff.clear();
282       CIalpha.clear();
283       CIbeta.clear();
284       if (coeffType == 0)
285       {
286         // short list
287         for (int i = 0; i < 7; i++)
288         {
289           int pos = 2;
290           std::string aline;
291           getline(ofile, aline, '\n');
292           //cout<<"aline: " <<aline << std::endl;
293           for (int i = 0; i < 7; i++)
294           {
295             //int q = atoi( (aline.substr(pos,pos+4)).c_str() );
296             //coeff2confg[q] = cnt++;
297             //CIcoeff.push_back( atof( (aline.substr(pos+6,pos+15)).c_str() ) );
298             //pos+=18;
299             int q          = atoi((aline.substr(pos, pos + 7)).c_str());
300             coeff2confg[q] = cnt++;
301             CIcoeff.push_back(atof((aline.substr(pos + 9, pos + 18)).c_str()));
302             pos += 21;
303             //cout<<"confg, coeff: " <<q <<"  " <<CIcoeff.back() << std::endl;
304           }
305         }
306         {
307           int pos = 2;
308           std::string aline;
309           getline(ofile, aline, '\n');
310           //int q = atoi( (aline.substr(pos,pos+4)).c_str() );
311           //coeff2confg[q] = cnt++;
312           //CIcoeff.push_back( atof( (aline.substr(pos+6,pos+15)).c_str() ) );
313           int q          = atoi((aline.substr(pos, pos + 7)).c_str());
314           coeff2confg[q] = cnt++;
315           CIcoeff.push_back(atof((aline.substr(pos + 9, pos + 18)).c_str()));
316           //cout<<"confg, coeff: " <<q <<"  " <<CIcoeff.back() << std::endl;
317         }
318       }
319       else
320       {
321         // long list
322         int nrows  = numCI / 5;
323         int nextra = numCI - nrows * 5;
324         int indx[5];
325         ofile.close();
326         ofile.open(outputFile.c_str());
327         ofile.seekg(strpos); //rewind it
328         for (int i = 0; i < nrows; i++)
329         {
330           getwords(currentWords, ofile);
331           if (currentWords.size() != 5)
332           {
333             std::cerr << "Error reading CI configurations-line: " << i << "\n";
334             abort();
335           }
336           for (int k = 0; k < 5; k++)
337             indx[k] = atoi(currentWords[k].c_str());
338           getwords(currentWords, ofile);
339           if (currentWords.size() != 6)
340           {
341             std::cerr << "Error reading CI configurations-line: " << i << "\n";
342             abort();
343           }
344           for (int k = 0; k < 5; k++)
345           {
346             // HACK HACK HACK - how is this done formally???
347             for (int j = 0; j < currentWords[k + 1].size(); j++)
348               if (currentWords[k + 1][j] == 'D')
349                 currentWords[k + 1][j] = 'E';
350             double ci = atof(currentWords[k + 1].c_str());
351             if (std::abs(ci) > ci_threshold)
352             {
353               coeff2confg[indx[k]] = cnt++;
354               CIcoeff.push_back(ci);
355               //cout<<"ind,cnt,c: " <<indx[k] <<"  " <<cnt-1 <<"  " <<CIcoeff.back() << std::endl;
356             }
357           }
358         }
359         if (nextra > 0)
360         {
361           getwords(currentWords, ofile);
362           if (currentWords.size() != nextra)
363           {
364             std::cerr << "Error reading CI configurations last line \n";
365             abort();
366           }
367           for (int k = 0; k < nextra; k++)
368             indx[k] = atoi(currentWords[k].c_str());
369           getwords(currentWords, ofile);
370           if (currentWords.size() != nextra + 1)
371           {
372             std::cerr << "Error reading CI configurations last line \n";
373             abort();
374           }
375           for (int k = 0; k < nextra; k++)
376           {
377             double ci = atof(currentWords[k + 1].c_str());
378             if (std::abs(ci) > ci_threshold)
379             {
380               coeff2confg[indx[k]] = cnt++;
381               CIcoeff.push_back(ci);
382             }
383           }
384         }
385       }
386       std::cout << "Found " << CIcoeff.size() << " coeffficients after truncation. \n";
387       if (statesType == 0)
388       {
389         ofile.close();
390         ofile.open(outputFile.c_str());
391         ofile.seekg(beginpos); //rewind it
392                                // this might not work, look for better entry point later
393         search(ofile, "Truncation Level=");
394         //cout<<"found Truncation Level=" << std::endl;
395         getwords(currentWords, ofile);
396         while (!ofile.eof() &&
397                (currentWords[0] != "no." || currentWords[1] != "active" || currentWords[2] != "orbitals"))
398         {
399           //        std::cout <<"1. " <<currentWords[0] << std::endl;
400           getwords(currentWords, ofile);
401         }
402         ci_nstates = atoi(currentWords[4].c_str());
403         getwords(currentWords, ofile);
404         // can choose specific irreps if I want...
405         while (currentWords[0] != "Configuration" || currentWords[2] != "Symmetry")
406         {
407           //        std::cout <<"2. " <<currentWords[0] << std::endl;
408           getwords(currentWords, ofile);
409         }
410         CIbeta.resize(CIcoeff.size());
411         CIalpha.resize(CIcoeff.size());
412         bool done = false;
413         // can choose specific irreps if I want...
414         while (currentWords[0] == "Configuration" && currentWords[2] == "Symmetry")
415         {
416           int pos                         = atoi(currentWords[1].c_str());
417           std::map<int, int>::iterator it = coeff2confg.find(pos);
418           //cout<<"3. configuration: " <<currentWords[1].c_str() << std::endl;
419           if (it != coeff2confg.end())
420           {
421             std::string alp(currentWords[4]);
422             std::string beta(currentWords[4]);
423             if (alp.size() != ci_nstates)
424             {
425               std::cerr << "Problem with ci string. \n";
426               abort();
427             }
428             for (int i = 0; i < alp.size(); i++)
429             {
430               if (alp[i] == 'a')
431                 alp[i] = '1';
432               if (alp[i] == 'b')
433                 alp[i] = '0';
434               if (beta[i] == 'a')
435                 beta[i] = '0';
436               if (beta[i] == 'b')
437                 beta[i] = '1';
438             }
439             if (done)
440             {
441               // check number of alpha/beta electrons
442               int n1 = 0;
443               for (int i = 0; i < alp.size(); i++)
444                 if (alp[i] == '1')
445                   n1++;
446               if (n1 != ci_nea)
447               {
448                 std::cerr << "Problems with alpha ci string: " << std::endl
449                           << alp << std::endl
450                           << currentWords[3] << std::endl;
451                 abort();
452               }
453               n1 = 0;
454               for (int i = 0; i < beta.size(); i++)
455                 if (beta[i] == '1')
456                   n1++;
457               if (n1 != ci_neb)
458               {
459                 std::cerr << "Problems with beta ci string: " << std::endl
460                           << beta << std::endl
461                           << currentWords[3] << std::endl;
462                 abort();
463               }
464             }
465             else
466             {
467               // count number of alpha/beta electrons
468               ci_nea = 0;
469               for (int i = 0; i < alp.size(); i++)
470                 if (alp[i] == '1')
471                   ci_nea++;
472               ci_neb = 0;
473               for (int i = 0; i < beta.size(); i++)
474                 if (beta[i] == '1')
475                   ci_neb++;
476               ci_nca = nup - ci_nea;
477               ci_ncb = ndown - ci_neb;
478             }
479             CIalpha[it->second] = alp;
480             CIbeta[it->second]  = beta;
481             //cout<<"alpha: " <<alp <<"  -   "  <<CIalpha[it->second] << std::endl;
482           }
483           getwords(currentWords, ofile);
484         }
485         //cout.flush();
486       }
487       else
488       {
489         // coefficient list obtained with iop(4/21=110)
490         ofile.close();
491         ofile.open(outputFile.c_str());
492         ofile.seekg(beginpos); //rewind it
493         bool first_alpha = true;
494         bool first_beta  = true;
495         std::string aline;
496         getline(ofile, aline, '\n');
497         CIbeta.resize(CIcoeff.size());
498         CIalpha.resize(CIcoeff.size());
499         for (int nst = 0; nst < numCI; nst++)
500         {
501           getwords(currentWords, ofile); // state number
502           int pos                         = atoi(currentWords[0].c_str());
503           std::map<int, int>::iterator it = coeff2confg.find(pos);
504           if (it != coeff2confg.end())
505           {
506             getwords(currentWords, ofile); // state number
507             if (first_alpha)
508             {
509               first_alpha = false;
510               ci_nea      = currentWords.size();
511               ci_nca      = nup - ci_nea;
512               std::cout << "nca, nea, nstates: " << ci_nca << "  " << ci_nea << "  " << ci_nstates << std::endl;
513             }
514             else
515             {
516               if (currentWords.size() != ci_nea)
517               {
518                 std::cerr << "Problems with alpha string: " << pos << std::endl;
519                 abort();
520               }
521             }
522             std::string alp(ci_nstates, '0');
523             for (int i = 0; i < currentWords.size(); i++)
524             {
525               //              std::cout <<"i, alpOcc: " <<i <<"  " <<atoi(currentWords[i].c_str())-1 << std::endl; std::cout.flush();
526               alp[atoi(currentWords[i].c_str()) - 1] = '1';
527             }
528             getwords(currentWords, ofile); // state number
529             if (first_beta)
530             {
531               first_beta = false;
532               ci_neb     = currentWords.size();
533               ci_ncb     = ndown - ci_neb;
534               std::cout << "ncb, neb, nstates: " << ci_ncb << "  " << ci_neb << "  " << ci_nstates << std::endl;
535             }
536             else
537             {
538               if (currentWords.size() != ci_neb)
539               {
540                 std::cerr << "Problems with beta string: " << pos << std::endl;
541                 abort();
542               }
543             }
544             std::string beta(ci_nstates, '0');
545             for (int i = 0; i < currentWords.size(); i++)
546             {
547               //              std::cout <<"i, alpOcc: " <<i <<"  " <<atoi(currentWords[i].c_str())-1 << std::endl; std::cout.flush();
548               beta[atoi(currentWords[i].c_str()) - 1] = '1';
549             }
550             CIalpha[it->second] = alp;
551             CIbeta[it->second]  = beta;
552             //cout<<"alpha: " <<alp << std::endl <<"beta: " <<beta << std::endl;
553             std::string aline1;
554             getline(ofile, aline1, '\n');
555           }
556           else
557           {
558             getwords(currentWords, ofile);
559             getwords(currentWords, ofile);
560             std::string aline1;
561             getline(ofile, aline1, '\n');
562           }
563         }
564       }
565       ofile.close();
566     }
567     else
568     {
569       std::cerr << "Could not find CI coefficients in gaussian output file. \n";
570       abort();
571     }
572     std::cout << " size of CIalpha,CIbeta: " << CIalpha.size() << "  " << CIbeta.size() << std::endl;
573   }
574 }
575 
getGeometry(std::istream & is)576 void GaussianFCHKParser::getGeometry(std::istream& is)
577 {
578   //atomic numbers
579   std::vector<int> atomic_number(NumberOfAtoms);
580   std::vector<double> q(NumberOfAtoms);
581   //read atomic numbers
582   search(is, "Atomic numbers"); //search for Atomic numbers
583   getValues(is, atomic_number.begin(), atomic_number.end());
584   std::streampos pivot = is.tellg();
585   //read effective nuclear charges
586   search(is, "Nuclear"); //search for Nuclear
587   getValues(is, q.begin(), q.end());
588   is.seekg(pivot); //rewind it
589   search(is, "coordinates");
590   std::vector<double> pos(NumberOfAtoms * OHMMS_DIM);
591   getValues(is, pos.begin(), pos.end());
592   SpeciesSet& species(IonSystem.getSpeciesSet());
593   for (int i = 0, ii = 0; i < NumberOfAtoms; i++)
594   {
595     IonSystem.R[i][0]                     = pos[ii++];
596     IonSystem.R[i][1]                     = pos[ii++];
597     IonSystem.R[i][2]                     = pos[ii++];
598     GroupName[i]                          = IonName[atomic_number[i]];
599     int speciesID                         = species.addSpecies(GroupName[i]);
600     IonSystem.GroupID[i]                  = speciesID;
601     species(AtomicNumberIndex, speciesID) = atomic_number[i];
602     species(IonChargeIndex, speciesID)    = q[i];
603   }
604 }
605 
getGaussianCenters(std::istream & is)606 void GaussianFCHKParser::getGaussianCenters(std::istream& is)
607 {
608   //map between Gaussian to Casino Shell notation
609   std::map<int, int> gsMap;
610   gsMap[0]  = 1;  //s
611   gsMap[-1] = 2;  //sp
612   gsMap[1]  = 3;  //p
613   gsMap[-2] = 4;  //d
614   gsMap[-3] = 5;  //f
615   gsMap[-4] = 6;  //g
616   gsMap[-5] = 7;  //l=5 h
617   gsMap[-6] = 8;  //l=6 h1??
618   gsMap[-7] = 9;  //l=7 h2??
619   gsMap[-8] = 10; //l=8 h3??
620   std::vector<int> n(gShell.size()), dn(NumberOfAtoms, 0);
621   bool SPshell(false);
622   getValues(is, n.begin(), n.end());
623   for (int i = 0; i < n.size(); i++)
624   {
625     gShell[i] = gsMap[n[i]];
626     if (n[i] == -1)
627       SPshell = true;
628   }
629   search(is, "Number");
630   getValues(is, gNumber.begin(), gNumber.end());
631   search(is, "Shell");
632   getValues(is, n.begin(), n.end());
633   for (int i = 0; i < n.size(); i++)
634     dn[n[i] - 1] += 1;
635   gBound[0] = 0;
636   for (int i = 0; i < NumberOfAtoms; i++)
637   {
638     gBound[i + 1] = gBound[i] + dn[i];
639   }
640   search(is, "Primitive");
641   getValues(is, gExp.begin(), gExp.end());
642   search(is, "Contraction");
643   getValues(is, gC0.begin(), gC0.end());
644   if (SPshell)
645   {
646     search(is, "P(S=P)");
647     getValues(is, gC1.begin(), gC1.end());
648   }
649 }
650