00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "QMCWavefunction.h"
00014 #include "QMCInput.h"
00015 #include <iomanip>
00016
00017 QMCWavefunction::QMCWavefunction()
00018 {
00019 Norbitals = 0;
00020 Nbasisfunc = 0;
00021 Nalpha = 0;
00022 Nbeta = 0;
00023 Ncharge = 0;
00024 Nelectrons = 0;
00025 Ndeterminants = 0;
00026 factor = 1.0;
00027 unusedIndicator = 0;
00028 trialFunctionType = "restricted";
00029 }
00030
00031 int QMCWavefunction::getNumberOrbitals()
00032 {
00033 return Norbitals;
00034 }
00035
00036 int QMCWavefunction::getNumberOrbitals(Array2D<int> & Occupation)
00037 {
00038 Array1D<int> count(Occupation.dim1());
00039 count = 0;
00040 for(int ci=0; ci<Occupation.dim1(); ci++)
00041 for(int o=0; o<Occupation.dim2(); o++)
00042 if(Occupation(ci,o) != unusedIndicator)
00043 count(ci) = count(ci) + 1;
00044
00045 for(int ci=0; ci<count.dim1(); ci++)
00046 if(count(ci) != count(0))
00047 {
00048 clog << "Error: number of orbitals doesn't match\n";
00049 clog << " count = " << count << endl;
00050 exit(0);
00051 }
00052
00053 return count(0);
00054 }
00055
00056 int QMCWavefunction::getNumberActiveOrbitals()
00057 {
00058 int Nactiveorbs = 0;
00059 for(int o=0; o<Norbitals; o++)
00060 {
00061 bool Aused = false;
00062 bool Bused = false;
00063 for(int ci=0; ci<Ndeterminants; ci++)
00064 {
00065 if(AlphaOccupation(ci,o) != unusedIndicator)
00066 Aused = true;
00067 if(BetaOccupation(ci,o) != unusedIndicator)
00068 Bused = true;
00069 }
00070 if(Aused || Bused) Nactiveorbs++;
00071 }
00072 return Nactiveorbs;
00073 }
00074
00075 int QMCWavefunction::getNumberActiveOrbitals(Array2D<int> & Occupation)
00076 {
00077 int Nactiveorbs = 0;
00078 for(int o=0; o<Norbitals; o++)
00079 {
00080 bool used = false;
00081 for(int ci=0; ci<Ndeterminants; ci++)
00082 {
00083 if(Occupation(ci,o) != unusedIndicator)
00084 used = true;
00085 }
00086 if(used) Nactiveorbs++;
00087 }
00088 return Nactiveorbs;
00089 }
00090
00091 int QMCWavefunction::getNumberBasisFunctions()
00092 {
00093 return Nbasisfunc;
00094 }
00095
00096 int QMCWavefunction::getNumberElectrons(bool isAlpha)
00097 {
00098 if(isAlpha)
00099 return Nalpha;
00100 else
00101 return Nbeta;
00102 }
00103
00104 int QMCWavefunction::getNumberElectrons()
00105 {
00106 return Nelectrons;
00107 }
00108
00109 int QMCWavefunction::getNumberDeterminants()
00110 {
00111 return Ndeterminants;
00112 }
00113
00114 void QMCWavefunction::scaleCoeffs(double scaleFactor)
00115 {
00116 factor *= scaleFactor;
00117 OrbitalCoeffs *= scaleFactor;
00118 }
00119
00120 int QMCWavefunction::getUnusedIndicator()
00121 {
00122 return unusedIndicator;
00123 }
00124
00125 void QMCWavefunction::sortOccupations(bool ordered)
00126 {
00127 int currentUnusedIndicator = getUnusedIndicator();
00128
00129 unusedIndicator = 0;
00130 if(ordered) unusedIndicator = -1;
00131
00132 for(int ci=0; ci<Ndeterminants; ci++)
00133 {
00134 int numOrbA = 0;
00135 int numOrbB = 0;
00136 for(int o=0; o<Norbitals; o++)
00137 {
00138 if(AlphaOccupation(ci,o) == currentUnusedIndicator)
00139 AlphaOccupation(ci,o) = unusedIndicator;
00140 else
00141 if(ordered)
00142 AlphaOccupation(ci,o) = numOrbA++;
00143 else
00144 AlphaOccupation(ci,o) = 1;
00145
00146 if(BetaOccupation(ci,o) == currentUnusedIndicator)
00147 BetaOccupation(ci,o) = unusedIndicator;
00148 else
00149 if(ordered)
00150 BetaOccupation(ci,o) = numOrbB++;
00151 else
00152 BetaOccupation(ci,o) = 1;
00153 }
00154 }
00155 }
00156
00157 void QMCWavefunction::unlinkOrbitals()
00158 {
00159
00160
00161
00162
00163 Array1D<bool> duplicateOrbital(Norbitals);
00164 int finalNorbitals = Norbitals;
00165 for(int o=0; o<Norbitals; o++)
00166 {
00167 bool alphaUses = false;
00168 bool betaUses = false;
00169 for(int ci=0; ci<Ndeterminants; ci++)
00170 {
00171 if(AlphaOccupation(ci,o) != unusedIndicator)
00172 alphaUses = true;
00173 if(BetaOccupation(ci,o) != unusedIndicator)
00174 betaUses = true;
00175 }
00176
00177
00178 if(alphaUses && betaUses)
00179 {
00180 duplicateOrbital(o) = true;
00181 finalNorbitals++;
00182 } else {
00183 duplicateOrbital(o) = false;
00184 }
00185 }
00186
00187
00188 if(finalNorbitals == Norbitals)
00189 return;
00190
00191 Array2D<qmcfloat> newOrbitalCoeffs(finalNorbitals,Nbasisfunc);
00192 Array2D<int> newAlphaOccupation(Ndeterminants, finalNorbitals);
00193 Array2D<int> newBetaOccupation(Ndeterminants, finalNorbitals);
00194
00195 int newIndex = Norbitals;
00196 for(int o=0; o<Norbitals; o++)
00197 {
00198 newOrbitalCoeffs.setRows(o,o,1,OrbitalCoeffs);
00199 if(duplicateOrbital(o))
00200 {
00201 newOrbitalCoeffs.setRows(newIndex,o,1,OrbitalCoeffs);
00202 for(int ci=0; ci<Ndeterminants; ci++)
00203 {
00204 newAlphaOccupation(ci,o) = AlphaOccupation(ci,o);
00205 newBetaOccupation(ci,o) = unusedIndicator;
00206 newAlphaOccupation(ci,newIndex) = unusedIndicator;
00207 newBetaOccupation(ci,newIndex) = BetaOccupation(ci,o);
00208 }
00209 newIndex++;
00210 } else {
00211 for(int ci=0; ci<Ndeterminants; ci++)
00212 {
00213 newAlphaOccupation(ci,o) = AlphaOccupation(ci,o);
00214 newBetaOccupation(ci,o) = BetaOccupation(ci,o);
00215 }
00216 }
00217 }
00218
00219 OrbitalCoeffs = newOrbitalCoeffs;
00220 AlphaOccupation = newAlphaOccupation;
00221 BetaOccupation = newBetaOccupation;
00222 Norbitals = finalNorbitals;
00223 }
00224
00225 void QMCWavefunction::unlinkDeterminants()
00226 {
00227 int finalNorbitals = 0;
00228 vector<int> unusedOrbitals;
00229 for(int o=0; o<Norbitals; o++)
00230 {
00231 bool used = false;
00232 for(int ci=0; ci<Ndeterminants; ci++)
00233 {
00234 if(AlphaOccupation(ci,o) != unusedIndicator ||
00235 BetaOccupation(ci,o) != unusedIndicator)
00236 {
00237 finalNorbitals++;
00238 used = true;
00239 }
00240 }
00241
00242 if(!used)
00243 unusedOrbitals.push_back(o);
00244 }
00245
00246
00247 finalNorbitals += unusedOrbitals.size();
00248
00249
00250 if(finalNorbitals == Norbitals)
00251 return;
00252
00253 Array2D<qmcfloat> newOrbitalCoeffs(finalNorbitals,Nbasisfunc);
00254 Array2D<int> newAlphaOccupation(Ndeterminants, finalNorbitals);
00255 Array2D<int> newBetaOccupation(Ndeterminants, finalNorbitals);
00256
00257 newAlphaOccupation = unusedIndicator;
00258 newBetaOccupation = unusedIndicator;
00259
00260 int newIndex = 0;
00261 for(int o=0; o<Norbitals; o++)
00262 for(int ci=0; ci<Ndeterminants; ci++)
00263 if(AlphaOccupation(ci,o) != unusedIndicator ||
00264 BetaOccupation(ci,o) != unusedIndicator)
00265 {
00266 newAlphaOccupation(ci,newIndex) = AlphaOccupation(ci,o);
00267 newBetaOccupation(ci,newIndex) = BetaOccupation(ci,o);
00268 newOrbitalCoeffs.setRows(newIndex,o,1,OrbitalCoeffs);
00269 newIndex++;
00270 }
00271
00272 if(finalNorbitals - newIndex != (int)(unusedOrbitals.size()))
00273 {
00274 clog << "Error: orbital counting went bad.\n";
00275 clog << " finalNorbitals = " << finalNorbitals << endl;
00276 clog << " newIndex = " << newIndex << endl;
00277 clog << " unusedOrbitals = " << unusedOrbitals.size() << endl;
00278 exit(0);
00279 }
00280 for(unsigned int o=0; o<unusedOrbitals.size(); o++)
00281 {
00282 newOrbitalCoeffs.setRows(newIndex,o,1,OrbitalCoeffs);
00283 newIndex++;
00284 }
00285
00286 OrbitalCoeffs = newOrbitalCoeffs;
00287 AlphaOccupation = newAlphaOccupation;
00288 BetaOccupation = newBetaOccupation;
00289 Norbitals = finalNorbitals;
00290 }
00291
00292 QMCWavefunction QMCWavefunction::operator=( const QMCWavefunction & rhs )
00293 {
00294 Norbitals = rhs.Norbitals;
00295 Nbasisfunc = rhs.Nbasisfunc;
00296 Nalpha = rhs.Nalpha;
00297 Nbeta = rhs.Nbeta;
00298 Nelectrons = rhs.Nelectrons;
00299 Ndeterminants = rhs.Ndeterminants;
00300 trialFunctionType = rhs.trialFunctionType;
00301 OrbitalCoeffs = rhs.OrbitalCoeffs;
00302 CI_coeffs = rhs.CI_coeffs;
00303 CI_constraints = rhs.CI_constraints;
00304 numCIIndependent = rhs.numCIIndependent;
00305 AlphaOccupation = rhs.AlphaOccupation;
00306 BetaOccupation = rhs.BetaOccupation;
00307 return *this;
00308 }
00309
00310 istream& operator >>(istream &strm,QMCWavefunction &rhs)
00311 {
00312 string temp_string;
00313
00314 if (rhs.trialFunctionType == "harmonicoscillator")
00315 {
00316 rhs.Nalpha = abs(rhs.Ncharge);
00317 rhs.Nbeta = 0;
00318 rhs.Nelectrons = rhs.Nalpha + rhs.Nbeta;
00319 return strm;
00320 }
00321
00322 int finalNorbitals = rhs.Norbitals;
00323 if (rhs.trialFunctionType == "restricted")
00324 {
00325 rhs.OrbitalCoeffs.allocate(rhs.Norbitals,
00326 rhs.Nbasisfunc);
00327
00328 for(int i=0; i<rhs.Norbitals; i++)
00329 for(int j=0; j<rhs.Nbasisfunc; j++)
00330 strm >> rhs.OrbitalCoeffs(i,j);
00331 }
00332
00333 else if (rhs.trialFunctionType == "unrestricted")
00334 {
00335 finalNorbitals *= 2;
00336 rhs.OrbitalCoeffs.allocate(finalNorbitals,
00337 rhs.Nbasisfunc);
00338
00339
00340 strm >> temp_string;
00341 strm >> temp_string;
00342 strm >> temp_string;
00343
00344 for(int i=0; i<rhs.Norbitals; i++)
00345 for(int j=0; j<rhs.Nbasisfunc; j++)
00346 strm >> rhs.OrbitalCoeffs(i,j);
00347
00348
00349 strm >> temp_string;
00350 strm >> temp_string;
00351 strm >> temp_string;
00352
00353 for(int i=rhs.Norbitals; i < finalNorbitals; i++)
00354 for(int j=0; j<rhs.Nbasisfunc; j++)
00355 strm >> rhs.OrbitalCoeffs(i,j);
00356 }
00357
00358 rhs.AlphaOccupation.allocate(rhs.Ndeterminants,finalNorbitals);
00359 rhs.AlphaOccupation = 0;
00360 rhs.BetaOccupation.allocate(rhs.Ndeterminants,finalNorbitals);
00361 rhs.BetaOccupation = 0;
00362
00363
00364 strm >> temp_string;
00365 strm >> temp_string;
00366
00367 for (int i=0; i<rhs.Ndeterminants; i++)
00368 for(int j=0; j<rhs.Norbitals; j++)
00369 strm >> rhs.AlphaOccupation(i,j);
00370
00371
00372 strm >> temp_string;
00373 strm >> temp_string;
00374
00375 for (int i=0; i<rhs.Ndeterminants; i++)
00376 {
00377 int start = finalNorbitals - rhs.Norbitals;
00378 for(int j=start; j<finalNorbitals; j++)
00379 strm >> rhs.BetaOccupation(i,j);
00380 }
00381
00382
00383 strm >> temp_string;
00384 strm >> temp_string;
00385
00386 rhs.CI_coeffs.allocate(rhs.Ndeterminants);
00387 rhs.CI_constraints.allocate(rhs.Ndeterminants);
00388 rhs.numCIIndependent = rhs.Ndeterminants;
00389 rhs.CI_constraints = -1;
00390 for(int i=0; i<rhs.Ndeterminants; i++)
00391 {
00392 string temp;
00393 strm >> temp;
00394
00395 if(temp.find('c') != string::npos)
00396 {
00397 int c;
00398 strm >> c;
00399
00400
00401
00402 rhs.CI_constraints(i) = c;
00403 rhs.numCIIndependent--;
00404 } else {
00405 rhs.CI_coeffs(i) = atof(temp.c_str());
00406 }
00407 }
00408
00409 for(int i=0; i<rhs.Ndeterminants; i++)
00410 if(rhs.CI_constraints(i) != -1)
00411 rhs.CI_coeffs(i) = rhs.CI_coeffs(rhs.CI_constraints(i));
00412
00413 if(rhs.Ncharge != 0)
00414 {
00415 cerr << "Error: molecular charges have not been included in QMcBeaver\n";
00416 }
00417
00418 rhs.Nalpha = 0;
00419 rhs.Nbeta = 0;
00420 for(int i=0; i<rhs.Norbitals; i++)
00421 {
00422 rhs.Nalpha += rhs.AlphaOccupation(0,i);
00423 rhs.Nbeta += rhs.BetaOccupation(0,i);
00424 }
00425
00426 rhs.Nelectrons = rhs.Nalpha + rhs.Nbeta;
00427
00428
00429 for(int ci=1; ci<rhs.Ndeterminants; ci++)
00430 {
00431 int numE = 0;
00432 for(int i=0; i<rhs.Norbitals; i++)
00433 {
00434 numE += rhs.AlphaOccupation(ci,i);
00435 numE += rhs.BetaOccupation(ci,i);
00436 }
00437 if(numE != rhs.Nelectrons)
00438 {
00439 clog << "Error: determinant " << (ci+1) << " has " << numE << " electrons.\n";
00440 clog << " It should have " << rhs.Nelectrons << " to be consistent with\n"
00441 << " the first determinant.\n";
00442 exit(0);
00443 }
00444 }
00445
00446 rhs.Norbitals = finalNorbitals;
00447 rhs.trialFunctionType = "restricted";
00448
00449 strm >> temp_string;
00450 if(temp_string != "&")
00451 {
00452 clog << "ERROR: there was some error in reading the wavefunction. WF = " << endl;
00453 clog << rhs << endl;
00454 exit(0);
00455 }
00456
00457 return strm;
00458 }
00459
00460 void QMCWavefunction::read(int charge, int numberOrbitals, int numberBasisFunctions,
00461 int numberDeterminants, string functionType, string runfile)
00462 {
00463 Norbitals = numberOrbitals;
00464 Nbasisfunc = numberBasisFunctions;
00465 Ndeterminants = numberDeterminants;
00466 Ncharge = charge;
00467 trialFunctionType = functionType;
00468
00469 ifstream input_file(runfile.c_str());
00470
00471 if(!input_file)
00472 {
00473 cerr << "ERROR: Could not open " << runfile << "!" << endl;
00474 exit(1);
00475 }
00476
00477 string temp_string;
00478 input_file >> temp_string;
00479 while((temp_string != "&wavefunction") && (input_file.eof() != 1))
00480 {
00481 input_file >> temp_string;
00482 }
00483 input_file >> *this;
00484
00485 if(getNumberElectrons(true) + getNumberElectrons(false) != getNumberElectrons()){
00486 cerr << "Error: We are expecting number alpha electrons " << getNumberElectrons(true) <<
00487 " + number beta electrons " << getNumberElectrons(false) << " to add up to the total " <<
00488 getNumberElectrons() << endl;
00489 }
00490
00491
00492
00493 if(globalInput.flags.optimize_Psi == 1 &&
00494 globalInput.flags.optimize_Orbitals == 1)
00495 {
00496 if(globalInput.flags.link_Orbital_parameters == 0)
00497 unlinkOrbitals();
00498
00499 if(globalInput.flags.link_Determinant_parameters == 0)
00500 unlinkDeterminants();
00501
00502 if(globalInput.flags.Norbitals != Norbitals)
00503 {
00504 clog << "Notice: the number of orbitals has increased from "
00505 << globalInput.flags.Norbitals << " to "
00506 << Norbitals << endl;
00507 globalInput.flags.Norbitals = Norbitals;
00508 }
00509 sortOccupations(true);
00510
00511 int numOR = getNumberOrbitals();
00512 int numORA= getNumberActiveOrbitals();
00513 int numBF = getNumberBasisFunctions();
00514 int numCI = getNumberDeterminants();
00515
00516 numORIndependent = numORA*numBF;
00517 OR_constraints.allocate(numORA*numBF);
00518
00519
00520 OR_constraints = -1;
00521
00522 int ai = 0;
00523 for(int o=0; o<numOR; o++)
00524 {
00525 bool orbitalUsed = false;
00526 for(int ci=0; ci<numCI; ci++)
00527 {
00528 if(AlphaOccupation(ci,o) != unusedIndicator ||
00529 BetaOccupation(ci,o) != unusedIndicator)
00530 {
00531 orbitalUsed = true;
00532 break;
00533 }
00534 }
00535
00536 if(!orbitalUsed) continue;
00537 int orbStart = ai;
00538
00539 for(int bf=0; bf<numBF; bf++)
00540 {
00541 if(globalInput.flags.constrain_Orbital_zeros == 1 &&
00542 fabs(OrbitalCoeffs(o,bf)) < 1e-8 )
00543 {
00544 numORIndependent--;
00545 OR_constraints(ai) = -2;
00546 } else if(globalInput.flags.constrain_Orbital_same == 1) {
00547
00548 for(int bfp=0; bfp<bf; bfp++)
00549 if(fabs(OrbitalCoeffs(o,bf) - OrbitalCoeffs(o,bfp)) < 1e-8)
00550 {
00551 OR_constraints(ai) = orbStart+bfp;
00552 numORIndependent--;
00553 break;
00554 }
00555 }
00556 ai++;
00557 }
00558 }
00559
00560 if(numORIndependent != OR_constraints.dim1())
00561 cout << "Notice: wavefunction went from " << OR_constraints.dim1()
00562 << " optimizable orbital parameters to " << numORIndependent << endl;
00563
00564 }
00565 else
00566 {
00567 sortOccupations(false);
00568 }
00569
00570 makeCoefficients(AlphaOccupation,
00571 OrbitalCoeffs,
00572 AlphaOrbitals,
00573 AlphaCoeffs,
00574 AlphaSwaps);
00575 makeCoefficients(BetaOccupation,
00576 OrbitalCoeffs,
00577 BetaOrbitals,
00578 BetaCoeffs,
00579 BetaSwaps);
00580 }
00581
00582 ostream& operator <<(ostream& strm, QMCWavefunction& rhs)
00583 {
00584 strm << "&wavefunction" << endl;
00585
00586 int wf_width = 25;
00587 int wf_precision = 12;
00588
00589
00590 if (rhs.trialFunctionType == "restricted")
00591 {
00592 for(int i=0; i<rhs.Norbitals; i++)
00593 {
00594 for(int j=0; j<rhs.Nbasisfunc; j++)
00595 {
00596 if( j%3 == 0 && j > 0 )
00597 strm << endl;
00598 strm.unsetf(ios::scientific);
00599 strm.unsetf(ios::fixed);
00600
00601 strm.precision(wf_precision);
00602 if(rhs.OrbitalCoeffs(i,j) < 0.0) strm << " -";
00603 else strm << " ";
00604 strm << setw(wf_width) << left << fabs(rhs.OrbitalCoeffs(i,j));
00605 }
00606 strm << endl << endl;
00607 }
00608 }
00609 else if (rhs.trialFunctionType == "unrestricted")
00610 {
00611 clog << "Warning: why is the wavefunction unrestricted?" << endl;
00612 }
00613 else if (rhs.trialFunctionType == "harmonicoscillator")
00614 {
00615 return strm;
00616 }
00617
00618 strm << "Alpha Occupation" << endl;
00619 for (int i=0; i<rhs.Ndeterminants; i++)
00620 {
00621 for (int j=0; j<rhs.Norbitals; j++)
00622 {
00623
00624 if(rhs.AlphaOccupation(i,j) == rhs.unusedIndicator)
00625 strm << setw(4) << 0;
00626 else
00627 strm << setw(4) << 1;
00628 }
00629 strm << endl;
00630 }
00631
00632 strm << endl << "Beta Occupation" << endl;
00633 for (int i=0; i<rhs.Ndeterminants; i++)
00634 {
00635 for (int j=0; j<rhs.Norbitals; j++)
00636 {
00637 strm.width(2);
00638 if(rhs.BetaOccupation(i,j) == rhs.unusedIndicator)
00639 strm << setw(4) << 0;
00640 else
00641 strm << setw(4) << 1;
00642 }
00643 strm << endl;
00644 }
00645
00646 strm << endl << "CI Coeffs" << endl;
00647 for (int i=0; i<rhs.Ndeterminants; i++)
00648 {
00649 if(rhs.CI_constraints(i) == -1)
00650 {
00651 strm.precision(wf_precision);
00652 if(rhs.CI_coeffs(i) < 0.0) strm << " -";
00653 else strm << " ";
00654 strm << setw(wf_width) << left << fabs(rhs.CI_coeffs(i)) << endl;
00655 } else {
00656 strm << " c " << rhs.CI_constraints(i) << endl;
00657 }
00658 }
00659 strm << endl;
00660
00661 strm << "&" << endl << endl;
00662 return strm;
00663 }
00664
00665 int QMCWavefunction::getNumberCIParameters()
00666 {
00667 if(globalInput.flags.optimize_CI == 0)
00668 return 0;
00669
00670
00671
00672
00673 return numCIIndependent;
00674 }
00675
00676 void QMCWavefunction::getCIParameters(Array1D<double> & params, int shift)
00677 {
00678 if(getNumberCIParameters() <= 0)
00679 return;
00680
00681 int ci = 0;
00682 for(int i=0; i<getNumberDeterminants(); i++)
00683 {
00684 if(CI_constraints(i) == -1)
00685 {
00686 params(ci + shift) = CI_coeffs(i);
00687 ci++;
00688 }
00689 }
00690 }
00691
00692 void QMCWavefunction::setCIParameters(Array1D<double> & params, int shift)
00693 {
00694 if(getNumberCIParameters() <= 0)
00695 return;
00696
00697 int ci = 0;
00698 for(int i=0; i<getNumberDeterminants(); i++)
00699 {
00700 if(CI_constraints(i) == -1)
00701 {
00702 CI_coeffs(i) = params(ci + shift);
00703 ci++;
00704 }
00705 }
00706 for(int i=0; i<getNumberDeterminants(); i++)
00707 {
00708 if(CI_constraints(i) != -1)
00709 CI_coeffs(i) = CI_coeffs(CI_constraints(i));
00710 }
00711 }
00712
00713 double QMCWavefunction::getCINorm()
00714 {
00715 return CI_coeffs.mag();
00716 }
00717
00718 void QMCWavefunction::normalizeCI()
00719 {
00720 double norm = CI_coeffs.mag();
00721 for(int ci=0; ci<Ndeterminants; ci++)
00722 CI_coeffs(ci) = CI_coeffs(ci)/norm;
00723 }
00724
00725 int QMCWavefunction::getNumberORParameters()
00726 {
00727 if(globalInput.flags.optimize_Orbitals == 0)
00728 return 0;
00729
00730 return numORIndependent;
00731 }
00732
00733 void QMCWavefunction::getORParameters(Array1D<double> & params, int shift)
00734 {
00735 if(globalInput.flags.optimize_Orbitals == 0)
00736 return;
00737
00738 int numOR = getNumberOrbitals();
00739 int numBF = getNumberBasisFunctions();
00740 int numCI = getNumberDeterminants();
00741
00742 int ai = shift;
00743 int ind = 0;
00744 for(int o=0; o<numOR; o++)
00745 {
00746 bool orbitalUsed = false;
00747 for(int ci=0; ci<numCI; ci++)
00748 {
00749 if(AlphaOccupation(ci,o) != unusedIndicator ||
00750 BetaOccupation(ci,o) != unusedIndicator)
00751 {
00752 orbitalUsed = true;
00753 break;
00754 }
00755 }
00756
00757 if(!orbitalUsed) continue;
00758
00759 for(int bf=0; bf<numBF; bf++)
00760 {
00761 if(OR_constraints(ind) == -1)
00762 {
00763 params(ai) = OrbitalCoeffs(o,bf);
00764 ai++;
00765 }
00766 ind++;
00767 }
00768 }
00769 }
00770
00771 void QMCWavefunction::setORParameters(Array1D<double> & params, int shift)
00772 {
00773 if(globalInput.flags.optimize_Orbitals == 0)
00774 return;
00775
00776 int numOR = getNumberOrbitals();
00777 int numBF = getNumberBasisFunctions();
00778 int numCI = getNumberDeterminants();
00779
00780 int ai = shift;
00781 Array1D<double> newParams(OR_constraints.dim1());
00782 int ind = 0;
00783 for(int o=0; o<numOR; o++)
00784 {
00785 bool orbitalUsed = false;
00786 for(int ci=0; ci<numCI; ci++)
00787 {
00788 if(AlphaOccupation(ci,o) != unusedIndicator ||
00789 BetaOccupation(ci,o) != unusedIndicator)
00790 {
00791 orbitalUsed = true;
00792 break;
00793 }
00794 }
00795
00796 if(!orbitalUsed) continue;
00797
00798 for(int bf=0; bf<numBF; bf++)
00799 {
00800 int c = OR_constraints(ind);
00801 if(c == -1)
00802 {
00803 OrbitalCoeffs(o,bf) = params(ai);
00804 ai++;
00805 } else if(c == -2) {
00806 OrbitalCoeffs(o,bf) = 0.0;
00807 } else {
00808 OrbitalCoeffs(o,bf) = newParams(c);
00809 }
00810 newParams(ind) = OrbitalCoeffs(o,bf);
00811 ind++;
00812 }
00813 }
00814
00815 makeCoefficients(AlphaOccupation,
00816 OrbitalCoeffs,
00817 AlphaOrbitals,
00818 AlphaCoeffs,
00819 AlphaSwaps);
00820 makeCoefficients(BetaOccupation,
00821 OrbitalCoeffs,
00822 BetaOrbitals,
00823 BetaCoeffs,
00824 BetaSwaps);
00825 }
00826
00827 Array2D<qmcfloat> * QMCWavefunction::getCoeff(bool isAlpha)
00828 {
00829 if(isAlpha)
00830 {
00831 return & AlphaCoeffs;
00832 } else {
00833 return & BetaCoeffs;
00834 }
00835 }
00836
00837 Array2D<int> * QMCWavefunction::getOccupations(bool isAlpha)
00838 {
00839 if(isAlpha)
00840 {
00841 return & AlphaOrbitals;
00842 } else {
00843 return & BetaOrbitals;
00844 }
00845 }
00846
00847 Array2D<int> * QMCWavefunction::getDeterminantSwaps(bool isAlpha)
00848 {
00849 if(isAlpha)
00850 {
00851 return & AlphaSwaps;
00852 } else {
00853 return & BetaSwaps;
00854 }
00855 }
00856
00857 void QMCWavefunction::makeCoefficients(Array2D<int> & TypeOccupations,
00858 Array2D<qmcfloat> & AllCoeffs,
00859 Array2D<int> & TypeIndices,
00860 Array2D<qmcfloat> & TypeCoeffs,
00861 Array2D<int> & TypeSwaps)
00862 {
00863 int numOR = getNumberOrbitals(TypeOccupations);
00864 int numAC = getNumberActiveOrbitals(TypeOccupations);
00865 int numCI = Ndeterminants;
00866
00867 TypeCoeffs.allocate(numAC,Nbasisfunc);
00868 TypeIndices.allocate(numCI,numOR);
00869
00870 int idxAct = 0;
00871 Array1D<int> count(numCI);
00872 count = 0;
00873 for(int o=0; o<AllCoeffs.dim1(); o++)
00874 {
00875 bool used = false;
00876 for(int ci=0; ci<numCI; ci++)
00877 if(TypeOccupations(ci,o) != unusedIndicator)
00878 {
00879 used = true;
00880 TypeIndices(ci,count(ci)) = idxAct;
00881 count(ci) = count(ci) + 1;
00882 }
00883
00884 if(used)
00885 {
00886 TypeCoeffs.setRows(idxAct,o,1,OrbitalCoeffs);
00887 idxAct++;
00888 }
00889 }
00890
00891 bool goodCI = true;
00892 for(int ci=0; ci<count.dim1(); ci++)
00893 if(count(ci) != numOR)
00894 goodCI = false;
00895
00896 if(idxAct != numAC || !goodCI)
00897 {
00898 clog << "Error: we failed to make the coefficient matrices\n"
00899 << " numCI = " << numCI << endl
00900 << " numOR = " << numOR << endl
00901 << " numAC = " << numAC << endl
00902 << "idxAct = " << idxAct << endl;
00903 if(!goodCI)
00904 clog << " CI count = \n" << count << endl;
00905 exit(0);
00906 }
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917 TypeSwaps.allocate(numCI,numOR);
00918 Array2D<int> IndexUpdater = TypeIndices;
00919 TypeSwaps = -1;
00920 for(int ci=1; ci<numCI; ci++)
00921 {
00922 int swap = 0;
00923 bool badSwap = false;
00924
00925
00926
00927
00928
00929
00930
00931
00932 do {
00933 badSwap = false;
00934 for(int o=0; o<numOR; o++)
00935 {
00936
00937
00938 if(IndexUpdater(ci,o) == IndexUpdater(ci-1,o))
00939 continue;
00940
00941
00942
00943 bool goodSwap = true;
00944 for(int o2=0; o2<numOR; o2++)
00945 if(o != o2 && IndexUpdater(ci,o) == IndexUpdater(ci-1,o2))
00946 {
00947 badSwap = true;
00948 goodSwap = false;
00949 break;
00950 }
00951
00952
00953 if(goodSwap)
00954 {
00955 IndexUpdater(ci-1,o) = IndexUpdater(ci,o);
00956 TypeSwaps(ci,swap) = o;
00957 swap++;
00958 }
00959 }
00960 } while(badSwap);
00961 }
00962 }