00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "QMCMolecule.h"
00014 #include "Lebedev-Laikov.h"
00015 #include "MathFunctions.h"
00016 #include <iomanip>
00017
00018 QMCMolecule::QMCMolecule()
00019 {
00020 Natoms = 0;
00021 }
00022
00023 void QMCMolecule::initialize(int nAtoms, int GridLevel)
00024 {
00025 Natoms = nAtoms;
00026 gridLevel = GridLevel;
00027 }
00028
00029 int QMCMolecule::getNumberAtoms()
00030 {
00031 return Natoms;
00032 }
00033
00034 int QMCMolecule::getNuclearCharge()
00035 {
00036 int sum = 0;
00037 for(int i=0; i<Natoms; i++)
00038 {
00039 sum += Zeff(i);
00040 }
00041 return sum;
00042 }
00043
00044 QMCMolecule QMCMolecule::operator=( const QMCMolecule & rhs )
00045 {
00046 Natoms = rhs.Natoms;
00047 Atom_Labels = rhs.Atom_Labels;
00048 Atom_Positions = rhs.Atom_Positions;
00049 Z = rhs.Z;
00050
00051 gridLevel = rhs.gridLevel;
00052 Zeff = rhs.Zeff;
00053 usesPsuedo = rhs.usesPsuedo;
00054 Vlocal = rhs.Vlocal;
00055 Vnonlocal = rhs.Vnonlocal;
00056 grid = rhs.grid;
00057 gridWeights = rhs.gridWeights;
00058 gridLegendre = rhs.gridLegendre;
00059
00060 return *this;
00061 }
00062
00063 int QMCMolecule::findClosestNucleusIndex(Array2D<double> & riA, int e)
00064 {
00065
00066 int closest_nucleus_index = 0;
00067 double closest_nucleus_distance = 1e100;
00068
00069 for(int nucleus=0; nucleus<getNumberAtoms(); nucleus++)
00070 {
00071 if( riA(e,nucleus) < closest_nucleus_distance )
00072 {
00073 closest_nucleus_distance = riA(e,nucleus);
00074 closest_nucleus_index = nucleus;
00075 }
00076 }
00077
00078 return closest_nucleus_index;
00079 }
00080
00081 istream& operator >>(istream &strm, QMCMolecule &rhs)
00082 {
00083 rhs.Atom_Labels.allocate(rhs.Natoms);
00084 rhs.Atom_Positions.allocate(rhs.Natoms,3);
00085 rhs.Z.allocate(rhs.Natoms);
00086 rhs.usesPsuedo.allocate(rhs.Natoms);
00087
00088 for(int i=0; i<rhs.Natoms; i++)
00089 {
00090 strm >> rhs.Atom_Labels(i);
00091 rhs.Atom_Labels(i) =
00092 StringManipulation::toFirstUpperRestLower(rhs.Atom_Labels(i));
00093
00094 if(rhs.Atom_Labels(i) == "&"){
00095 cerr << "ERROR: End of geometry section reached prematurely. We were expecting " << rhs.Natoms
00096 << " atoms, but we only got " << i << ".\n";
00097 exit(1);
00098 }
00099
00100 strm >> rhs.Z(i);
00101 strm >> rhs.Atom_Positions(i,0);
00102 strm >> rhs.Atom_Positions(i,1);
00103 strm >> rhs.Atom_Positions(i,2);
00104 rhs.usesPsuedo(i) = false;
00105 }
00106
00107 rhs.Zeff = rhs.Z;
00108 return strm;
00109 }
00110
00111 void QMCMolecule::readGeometry(string runfile)
00112 {
00113 if(Natoms == 0) return;
00114
00115 ifstream input_file(runfile.c_str());
00116
00117 if(!input_file)
00118 {
00119 cerr << "ERROR: Could not open " << runfile << "!" << endl;
00120 exit(1);
00121 }
00122
00123 string temp_string;
00124 input_file >> temp_string;
00125 while((temp_string != "&geometry") && (input_file.eof() != 1))
00126 {
00127 input_file >> temp_string;
00128 }
00129
00130 if(temp_string == "&geometry") input_file >> *this;
00131
00132
00133 list<string> nuclei;
00134 nuclei.push_back( Atom_Labels(0) );
00135 for( int i=0; i<Atom_Labels.dim1(); i++ )
00136 {
00137 bool found = false;
00138 for( list<string>::iterator it=nuclei.begin(); it!=nuclei.end(); ++it )
00139 {
00140 if( *it == Atom_Labels(i) )
00141 {
00142 found = true;
00143 }
00144 }
00145
00146 if( !found )
00147 {
00148 nuclei.push_back( Atom_Labels(i) );
00149 }
00150 }
00151
00152 NucleiTypes.allocate( (int)nuclei.size() );
00153 int Position = 0;
00154 for( list<string>::iterator it=nuclei.begin(); it!=nuclei.end(); ++it )
00155 {
00156 NucleiTypes(Position) = *it;
00157 Position++;
00158 }
00159 }
00160
00161 int QMCMolecule::readPsuedoPotential(string runfile)
00162 {
00163 if(Natoms == 0) return 0;
00164
00165 ifstream input_file(runfile.c_str());
00166
00167 if(!input_file)
00168 {
00169 cerr << "ERROR: Could not open " << runfile << "!" << endl;
00170 exit(1);
00171 }
00172
00173 string temp_string;
00174 input_file >> temp_string;
00175 while((temp_string != "&psuedopotential") && (input_file.eof() != 1))
00176 {
00177 input_file >> temp_string;
00178 }
00179
00180
00181 if(input_file.eof() == 1) return 0;
00182
00183 int gridSizes[32] = {6,14,26,38,50,74,86,110,
00184 146,170,194,230,266,302,350,434,
00185 590,770,974,1202,1454,1730,2030,2354,
00186 2702,3074,3470,3890,4334,4802,5294,5810};
00187 LDGRID functions[32] = {&LD0006,&LD0014,&LD0026,&LD0038,&LD0050,&LD0074,&LD0086,&LD0110,
00188 &LD0146,&LD0170,&LD0194,&LD0230,&LD0266,&LD0302,&LD0350,&LD0434,
00189 &LD0590,&LD0770,&LD0974,&LD1202,&LD1454,&LD1730,&LD2030,&LD2354,
00190 &LD2702,&LD3074,&LD3470,&LD3890,&LD4334,&LD4802,&LD5294,&LD5810};
00191
00192 grid.allocate(Natoms);
00193 gridWeights.allocate(Natoms);
00194 gridLegendre.allocate(Natoms);
00195 psuedoTitle.allocate(Natoms,2);
00196 Vlocal.allocate(Natoms);
00197 Vnonlocal.allocate(Natoms);
00198
00199
00200
00201
00202
00203 string item;
00204 stringstream itemSS;
00205 Array1D<string> ppTypes(Natoms);
00206 for(int i=0; i<Natoms; i++)
00207 {
00208 input_file >> ws;
00209 getline(input_file,item);
00210 stringstream lineSS(item);
00211 lineSS >> item;
00212 ppTypes[i] = item;
00213 lineSS >> ws;
00214
00215 psuedoTitle(i,0) = item;
00216 psuedoTitle(i,1) = "";
00217
00218 if(lineSS.eof()){
00219
00220
00221 int matched = -1;
00222 for(int j=0; j<i; j++){
00223 if(ppTypes(j) == item){
00224 matched = j;
00225 usesPsuedo(i) = usesPsuedo(j);
00226 Zeff(i) = Zeff(j);
00227 Vlocal(i) = Vlocal(j);
00228 Vnonlocal(i) = Vnonlocal(j);
00229 grid(i) = grid(j);
00230 gridWeights(i) = gridWeights(j);
00231 gridLegendre(i) = gridLegendre(j);
00232 break;
00233 }
00234 }
00235 if(matched >= 0){
00236 continue;
00237 } else {
00238 clog << "Error: Psuedopotential " << i << " didn't list a type, and didn't match a type.\n";
00239 exit(1);
00240 }
00241 }
00242
00243 lineSS >> item;
00244 psuedoTitle(i,1) = item;
00245 StringManipulation::toAllUpper(item);
00246 if(item != "GEN" && item != "NONE"){
00247
00248
00249 clog << "Error: psuedopotential for " << psuedoTitle(i,0)
00250 << " has unknown type " << item << ".\n";
00251 exit(1);
00252 }
00253
00254 int elec_removed = 0;
00255 int numl = 0;
00256 int vloc_size = 0;
00257 if(item == "NONE")
00258 {
00259 Vlocal(i).allocate(0,0);
00260 Vnonlocal(i).allocate(0);
00261 continue;
00262 }
00263
00264 usesPsuedo(i) = true;
00265
00266 lineSS >> item;
00267 elec_removed = atoi(item.c_str());
00268 Zeff(i) = Z(i) - elec_removed;
00269
00270 lineSS >> item;
00271 numl = atoi(item.c_str());
00272
00273 input_file >> item;
00274 vloc_size = atoi(item.c_str());
00275
00276 Vlocal(i).allocate(vloc_size,3);
00277 for(int vloc=0; vloc<vloc_size; vloc++)
00278 {
00279 input_file >> item;
00280 (Vlocal(i))(vloc,0) = atof(item.c_str());
00281 input_file >> item;
00282 (Vlocal(i))(vloc,1) = atof(item.c_str());
00283 input_file >> item;
00284 (Vlocal(i))(vloc,2) = atof(item.c_str());
00285 }
00286
00287
00288 Vnonlocal(i).allocate(numl);
00289 for(int l=0; l<numl; l++)
00290 {
00291 input_file >> item;
00292 int vnloc_size = atoi(item.c_str());
00293
00294 (Vnonlocal(i))(l).allocate(vnloc_size,3);
00295 for(int vnloc=0; vnloc<vnloc_size; vnloc++)
00296 {
00297 input_file >> item;
00298 (Vnonlocal(i))(l)(vnloc,0) = atof(item.c_str());
00299 input_file >> item;
00300 (Vnonlocal(i))(l)(vnloc,1) = atof(item.c_str());
00301 input_file >> item;
00302 (Vnonlocal(i))(l)(vnloc,2) = atof(item.c_str());
00303 }
00304 }
00305
00306 int grSize = gridSizes[gridLevel];
00307
00308
00309
00310
00311
00312 Array1D<double> x(grSize+1);
00313 Array1D<double> y(grSize+1);
00314 Array1D<double> z(grSize+1);
00315 Array1D<double> w(grSize+1);
00316 x = 0.0;
00317 y = 0.0;
00318 w = 0.0;
00319 z = 0.0;
00320
00321 grid(i).allocate(grSize,3);
00322 gridWeights(i).allocate(grSize);
00323 gridLegendre(i).allocate(numl,grSize);
00324
00325 (functions[gridLevel])(x.array(),y.array(),z.array(),w.array());
00326
00327 for(int gp=0; gp<grSize; gp++)
00328 {
00329 (grid(i))(gp,0) = x[gp+1];
00330 (grid(i))(gp,1) = y[gp+1];
00331 (grid(i))(gp,2) = z[gp+1];
00332 (gridWeights(i))(gp) = w[gp+1];
00333 for(int l=0; l<numl; l++)
00334 (gridLegendre(i))(l,gp) = MathFunctions::legendre(l,z[gp+1]);
00335 }
00336 }
00337
00338 int usePsuedo = 0;
00339 for(int i=0; i<Natoms; i++){
00340 if(usesPsuedo(i)){
00341 usePsuedo = 1;
00342 cout << "On atom " << i << ": replacing " << (Z(i)-Zeff(i)) << " electrons with the " << psuedoTitle(i,0) << " ecp"
00343 << " using " << grid(i).dim1() << " grid points." << endl;
00344
00345
00346
00347
00348
00349 }
00350 }
00351 return usePsuedo;
00352 }
00353
00354 Array2D<double> QMCMolecule::getGrid(int nuc, double r, bool translate)
00355 {
00356
00357
00358
00359
00360
00361 Array2D<double> gNuc = grid(nuc);
00362 gNuc *= r;
00363
00364
00365 if(!translate) return gNuc;
00366
00367 double x0 = Atom_Positions(nuc,0);
00368 double y0 = Atom_Positions(nuc,1);
00369 double z0 = Atom_Positions(nuc,2);
00370 for(int gr=0; gr<gNuc.dim1(); gr++){
00371 gNuc(gr,0) = gNuc(gr,0) + x0;
00372 gNuc(gr,1) = gNuc(gr,1) + y0;
00373 gNuc(gr,2) = gNuc(gr,2) + z0;
00374 }
00375 return gNuc;
00376 }
00377
00378 double QMCMolecule::evaluatePotential(Array2D<double> & V, double r)
00379 {
00380 double v = 0.0;
00381 int ngauss = V.dim1();
00382 for(int g=0; g<ngauss; g++)
00383 {
00384 double coeff = V(g,0);
00385 double n = V(g,1);
00386 double zeta = V(g,2);
00387
00388
00389
00390
00391
00392 v += coeff * pow(r,n-2) * exp(-1.0*zeta*r*r);
00393 }
00394 return v;
00395 }
00396
00397 ostream& operator <<(ostream& strm, QMCMolecule& rhs)
00398 {
00399 strm << "&geometry" << endl;
00400 strm.unsetf(ios::fixed);
00401 strm.unsetf(ios::scientific);
00402 for(int i=0; i<rhs.Natoms; i++)
00403 {
00404 strm << setw(5) << left << rhs.Atom_Labels(i);
00405 strm << setw(5) << rhs.Z(i);
00406 for(int j=0; j<3; j++)
00407 {
00408 if(rhs.Atom_Positions(i,j) < 0.0) strm << " -";
00409 else strm << " ";
00410 strm << setw(20) << left << fabs(rhs.Atom_Positions(i,j));
00411 }
00412 strm << endl;
00413 }
00414 strm << "&" << endl;
00415 strm << right;
00416
00417 bool printPsuedo = false;
00418 for(int i=0; i<rhs.Natoms; i++)
00419 if(rhs.usesPsuedo(i)) printPsuedo = true;
00420 if(!printPsuedo) return strm;
00421
00422 strm << "&psuedopotential" << endl;
00423 for(int i=0; i<rhs.Natoms; i++){
00424 strm << rhs.psuedoTitle(i,0);
00425 strm << " " << rhs.psuedoTitle(i,1);
00426
00427 if(!rhs.usesPsuedo(i) ||
00428 rhs.psuedoTitle(i,1) == ""){
00429 strm << endl;
00430 continue;
00431 }
00432
00433
00434 strm << " " << (rhs.Z(i) - rhs.Zeff(i));
00435
00436 int numl = rhs.Vnonlocal(i).dim1();
00437 strm << " " << numl;
00438 strm << endl;
00439
00440 int numG = rhs.Vlocal(i).dim1();
00441 strm << setw(5) << numG << endl;
00442 for(int ng=0; ng<numG; ng++)
00443 strm << setw(20) << (rhs.Vlocal(i))(ng,0)
00444 << setw(5) << (rhs.Vlocal(i))(ng,1)
00445 << setw(20) << (rhs.Vlocal(i))(ng,2) << endl;
00446
00447 for(int l=0; l<numl; l++){
00448 numG = (rhs.Vnonlocal(i))(l).dim1();
00449 strm << setw(5) << numG << endl;
00450 for(int ng=0; ng<numG; ng++)
00451 strm << setw(20) << ((rhs.Vnonlocal(i))(l))(ng,0)
00452 << setw(5) << ((rhs.Vnonlocal(i))(l))(ng,1)
00453 << setw(20) << ((rhs.Vnonlocal(i))(l))(ng,2) << endl;
00454 }
00455 }
00456 strm << "&" << endl;
00457 return strm;
00458 }
00459
00460
00461