QMCPACK
RMGParser.cpp
Go to the documentation of this file.
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) 2021 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Kevin Gasperich, kgasperich@anl.gov, Argonne National Laboratory
8 //
9 // File created by: Kevin Gasperich, kgasperich@anl.gov, Argonne National Laboratory
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 #include "RMGParser.h"
14 #include <fstream>
15 #include <iterator>
16 #include <algorithm>
17 #include <set>
18 #include <map>
19 
20 
22 
23 RMGParser::RMGParser(int argc, char** argv) : QMCGaussianParserBase(argc, argv) { PBC = true; }
24 
25 void RMGParser::getCell(const std::string& fname)
26 {
27  // from LCAOHDFParser (maybe put into base class?)
28  X.resize(3);
29  Y.resize(3);
30  Z.resize(3);
31 
32  hdf_archive hin;
33 
34  if (!hin.open(fname.c_str(), H5F_ACC_RDONLY))
35  {
36  std::cerr << "Could not open H5 file" << std::endl;
37  abort();
38  }
39  hin.push("supercell");
40  Matrix<double> LatticeVec(3, 3);
41  hin.read(LatticeVec, "primitive_vectors");
42  X[0] = LatticeVec[0][0];
43  X[1] = LatticeVec[0][1];
44  X[2] = LatticeVec[0][2];
45  Y[0] = LatticeVec[1][0];
46  Y[1] = LatticeVec[1][1];
47  Y[2] = LatticeVec[1][2];
48  Z[0] = LatticeVec[2][0];
49  Z[1] = LatticeVec[2][1];
50  Z[2] = LatticeVec[2][2];
51  hin.close();
52  std::cout << "Lattice parameters in Bohr:" << std::endl;
53  std::cout << X[0] << " " << X[1] << " " << X[2] << std::endl;
54  std::cout << Y[0] << " " << Y[1] << " " << Y[2] << std::endl;
55  std::cout << Z[0] << " " << Z[1] << " " << Z[2] << std::endl;
56 }
57 
58 void RMGParser::dumpPBC(const std::string& psi_tag, const std::string& ion_tag)
59 {
60  std::cout << " RMGParser::dumpPBC " << std::endl;
61  if (!Structure)
62  {
63  xmlDocPtr doc_p = xmlNewDoc((const xmlChar*)"1.0");
64  xmlNodePtr qm_root_p = xmlNewNode(NULL, BAD_CAST "qmcsystem");
65  if (PBC)
66  xmlAddChild(qm_root_p, createCell());
67  xmlAddChild(qm_root_p, createIonSet());
68  xmlAddChild(qm_root_p, createElectronSet(ion_tag));
69  xmlDocSetRootElement(doc_p, qm_root_p);
70  std::string fname = Title + ".structure.xml";
71  xmlSaveFormatFile(fname.c_str(), doc_p, 1);
72  xmlFreeDoc(doc_p);
73  Structure = true;
74  }
75  xmlDocPtr doc = xmlNewDoc((const xmlChar*)"1.0");
76  xmlNodePtr qm_root = xmlNewNode(NULL, BAD_CAST "qmcsystem");
77  {
78  //wavefunction
79  xmlNodePtr wfPtr = xmlNewNode(NULL, (const xmlChar*)"wavefunction");
80  xmlNewProp(wfPtr, (const xmlChar*)"name", (const xmlChar*)psi_tag.c_str());
81  xmlNewProp(wfPtr, (const xmlChar*)"target", (const xmlChar*)"e");
82  {
83  xmlNodePtr detsetPtr = xmlNewNode(NULL, (const xmlChar*)"determinantset");
84  xmlNewProp(detsetPtr, (const xmlChar*)"type", (const xmlChar*)"bspline");
85  xmlNewProp(detsetPtr, (const xmlChar*)"href", (const xmlChar*)h5file.c_str());
86  xmlNewProp(detsetPtr, (const xmlChar*)"source", (const xmlChar*)ion_tag.c_str());
87  // this just reproduces the behavior of pw2qmcpack
88  xmlNewProp(detsetPtr, (const xmlChar*)"sort", (const xmlChar*)"1");
89  xmlNewProp(detsetPtr, (const xmlChar*)"tilematrix", (const xmlChar*)"1 0 0 0 1 0 0 0 1");
90  xmlNewProp(detsetPtr, (const xmlChar*)"twistnum", (const xmlChar*)"0");
91  xmlNewProp(detsetPtr, (const xmlChar*)"version", (const xmlChar*)"0.10");
92  {
93  std::ostringstream up_size, down_size;
94  up_size << NumberOfAlpha;
95  down_size << NumberOfBeta;
96 
97  xmlNodePtr slaterdetPtr = xmlNewNode(NULL, (const xmlChar*)"slaterdeterminant");
98 
99  xmlNodePtr updetPtr = xmlNewNode(NULL, (const xmlChar*)"determinant");
100  xmlNewProp(updetPtr, (const xmlChar*)"id", (const xmlChar*)"updet");
101  xmlNewProp(updetPtr, (const xmlChar*)"size", (const xmlChar*)up_size.str().c_str());
102 
103  xmlNodePtr occUpPtr = xmlNewNode(NULL, (const xmlChar*)"occupation");
104  xmlNewProp(occUpPtr, (const xmlChar*)"mode", (const xmlChar*)"ground");
105  xmlNewProp(occUpPtr, (const xmlChar*)"spindataset", (const xmlChar*)"0");
106  xmlAddChild(updetPtr, occUpPtr);
107 
108 
109  xmlNodePtr downdetPtr = xmlNewNode(NULL, (const xmlChar*)"determinant");
110  xmlNewProp(downdetPtr, (const xmlChar*)"id", (const xmlChar*)"downdet");
111  xmlNewProp(downdetPtr, (const xmlChar*)"size", (const xmlChar*)down_size.str().c_str());
112 
113  xmlNodePtr occDownPtr = xmlNewNode(NULL, (const xmlChar*)"occupation");
114  xmlNewProp(occDownPtr, (const xmlChar*)"mode", (const xmlChar*)"ground");
115  if (NumberOfSpins == 2)
116  {
117  xmlNewProp(downdetPtr, (const xmlChar*)"ref", (const xmlChar*)"updet");
118  xmlNewProp(occDownPtr, (const xmlChar*)"spindataset", (const xmlChar*)"1");
119  }
120  else if (NumberOfSpins == 1)
121  {
122  xmlNewProp(occDownPtr, (const xmlChar*)"spindataset", (const xmlChar*)"0");
123  }
124  else
125  {
126  std::cerr << "Error: Number of spins should be 1 or 2. (" << NumberOfSpins << ")" << std::endl;
127  abort();
128  }
129  xmlAddChild(downdetPtr, occDownPtr);
130 
131  xmlAddChild(slaterdetPtr, updetPtr);
132  xmlAddChild(slaterdetPtr, downdetPtr);
133 
134  xmlAddChild(detsetPtr, slaterdetPtr);
135  }
136  xmlAddChild(wfPtr, detsetPtr);
137  if (addJastrow)
138  {
139  std::cout << R"(Adding Two-Body and One-Body jastrows with rcut="10" and size="10")" << std::endl;
140  if (NumberOfEls > 1)
141  {
142  xmlAddChild(wfPtr, createJ2());
143  }
144  xmlAddChild(wfPtr, createJ1());
145  if (NumberOfEls > 1)
146  {
147  std::cout << "Adding Three-Body jastrows with rcut=\"5\"" << std::endl;
148  xmlAddChild(wfPtr, createJ3());
149  }
150  }
151  }
152  xmlAddChild(qm_root, wfPtr);
153  }
154  xmlDocSetRootElement(doc, qm_root);
155  std::string fname = Title + ".wf" + WFS_name + ".xml";
156  xmlSaveFormatFile(fname.c_str(), doc, 1);
157  xmlFreeDoc(doc);
158 }
159 
160 void RMGParser::parse(const std::string& fname)
161 {
162  hdf_archive hin;
163 
164  if (!hin.open(fname.c_str(), H5F_ACC_RDONLY))
165  {
166  std::cerr << "Could not open H5 file" << std::endl;
167  abort();
168  }
169 
170  hin.push("application");
171  hin.read(CodeName, "code");
172  std::cout << "Converting Wavefunction from the " << CodeName << " Code" << std::endl;
173  hin.pop();
174 
175  hin.push("electrons");
176  std::vector<double> Nalpha_Nbeta(2);
177  hin.read(Nalpha_Nbeta, "number_of_electrons");
178  NumberOfAlpha = Nalpha_Nbeta[0];
179  NumberOfBeta = Nalpha_Nbeta[1];
181  std::cout << "Number of (alpha,beta) electrons: (" << NumberOfAlpha << ", " << NumberOfBeta << ")" << std::endl;
182 
183  hin.read(NumberOfSpins, "number_of_spins");
184  std::cout << "Number of spins: " << NumberOfSpins << std::endl;
185  hin.pop();
186 
187  hin.push("atoms");
188  hin.read(NumberOfAtoms, "number_of_atoms");
189  std::cout << "Number of atoms: " << NumberOfAtoms << std::endl;
190  getCell(fname);
191 
193  GroupName.resize(NumberOfAtoms);
194  Matrix<double> IonPos(NumberOfAtoms, 3);
195  //atomic numbers
196  std::vector<int> atomic_number;
197  std::vector<double> q;
198  ECP_names.clear();
199  //read atomic info
200  //MAP: (Atom Number, Species Index)
201  std::vector<int> idx(NumberOfAtoms);
202  std::map<int, int> AtomIndexmap;
203  hin.read(idx, "species_ids");
204  for (int i = 0; i < NumberOfAtoms; i++)
205  {
206  AtomIndexmap.insert(std::pair<int, int>(i, idx[i]));
207  }
208  for (int i = 0; i < NumberOfAtoms; i++)
209  {
210  std::string speciesName("species_");
211  speciesName = speciesName + std::to_string(AtomIndexmap[i]);
212  hin.push(speciesName);
213  int zint;
214  double z;
215  std::string Name;
216  std::string ecpName = "";
217  hin.read(zint, "atomic_number");
218  atomic_number.push_back(zint);
219  hin.read(z, "valence_charge");
220  q.push_back(z);
221  hin.read(Name, "name");
222  try
223  {
224  hin.read(ecpName, "pseudopotential");
225  ECP_names.push_back(ecpName);
226  ECP = true;
227  }
228  catch (...)
229  {
230  std::cerr << "WARNING: no ECP found for " << speciesName << ":" << Name << std::endl;
231  ECP_names.push_back(ecpName);
232  }
233  hin.pop();
234  }
235  hin.read(IonPos, "positions");
236 
237  SpeciesSet& species(IonSystem.getSpeciesSet());
238  for (int i = 0; i < NumberOfAtoms; i++)
239  {
240  IonSystem.R[i][0] = IonPos[i][0];
241  IonSystem.R[i][1] = IonPos[i][1];
242  IonSystem.R[i][2] = IonPos[i][2];
243  GroupName[i] = IonName[atomic_number[i]];
244  int speciesID = species.addSpecies(GroupName[i]);
245  IonSystem.GroupID[i] = speciesID;
246  species(AtomicNumberIndex, speciesID) = atomic_number[i];
247  species(IonChargeIndex, speciesID) = q[i];
248  }
249  hin.pop(); // atoms
250 
251 
252  // this is just a messy workaround to avoid modifying the behavior of convert4qmc
253  // if (PBC) then convert4qmc will try to print the first 3 elements of STwist_Coord
254  STwist_Coord.resize(3);
255  try
256  {
257  hin.push("Super_Twist");
258  Matrix<double> STVec(1, 3);
259  hin.read(STVec, "Coord");
260  hin.pop();
261  STwist_Coord[0] = STVec[0][0];
262  STwist_Coord[1] = STVec[0][1];
263  STwist_Coord[2] = STVec[0][2];
264  }
265  catch (...)
266  {
267  std::cout << "Could not find Super_Twist, using [0,0,0] (not yet implemented in basic RMG interface)" << std::endl;
268  STwist_Coord[0] = 0;
269  STwist_Coord[1] = 0;
270  STwist_Coord[2] = 0;
271  }
272 }
bool open(const std::filesystem::path &fname, unsigned flags=H5F_ACC_RDWR)
open a file
std::vector< double > Z
std::vector< double > X
void close()
close all the open groups and file
Definition: hdf_archive.cpp:38
void parse(const std::string &fname) override
Definition: RMGParser.cpp:160
class to handle hdf file
Definition: hdf_archive.h:51
void dumpPBC(const std::string &psi_tag, const std::string &ion_tag) override
Definition: RMGParser.cpp:58
std::vector< std::string > GroupName
ParticleIndex GroupID
Species ID.
Definition: ParticleSet.h:77
std::vector< double > STwist_Coord
ParticlePos R
Position.
Definition: ParticleSet.h:79
static std::map< int, std::string > IonName
xmlNodePtr createElectronSet(const std::string &ion_tag)
std::vector< double > Y
SpeciesSet & getSpeciesSet()
retrun the SpeciesSet of this particle set
Definition: ParticleSet.h:231
void create(const std::vector< int > &agroup)
create grouped particles
void push(const std::string &gname, bool createit=true)
push a group to the group stack
void read(T &data, const std::string &aname)
read the data from the group aname and check status runtime error is issued on I/O error ...
Definition: hdf_archive.h:306
int NumberOfSpins
Definition: RMGParser.h:29
Custom container for set of attributes for a set of species.
Definition: SpeciesSet.h:33
void getCell(const std::string &fname)
Definition: RMGParser.cpp:25
std::vector< std::string > ECP_names
Definition: RMGParser.h:28