QMCPACK
ECPComponentBuilder.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) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
8 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
9 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
10 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
11 //
12 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
13 //////////////////////////////////////////////////////////////////////////////////////
14 
15 
16 #include "ECPComponentBuilder.h"
18 #include "Numerics/Quadrature.h"
20 #include "Numerics/Transform2GridFunctor.h"
22 #include "Utilities/SimpleParser.h"
23 #include "Message/CommOperators.h"
25 #include <cmath>
26 #include "Utilities/qmc_common.h"
27 
28 
29 namespace qmcplusplus
30 {
31 ECPComponentBuilder::ECPComponentBuilder(const std::string& aname, Communicate* c, int nrule, int llocal, int srule)
32  : MPIObjectBase(c),
33  NumNonLocal(0),
34  Lmax(0),
35  Llocal(llocal),
36  Nrule(nrule),
37  Srule(srule),
38  AtomicNumber(0),
39  Zeff(0),
40  RcutMax(-1),
41  Species(aname)
42 {
43  angMon["s"] = 0;
44  angMon["p"] = 1;
45  angMon["d"] = 2;
46  angMon["f"] = 3;
47  angMon["g"] = 4;
48  angMon["h"] = 5;
49  angMon["i"] = 6;
50  angMon["j"] = 7;
51  angMon["k"] = 8;
52  angMon["0"] = 0;
53  angMon["1"] = 1;
54  angMon["2"] = 2;
55  angMon["3"] = 3;
56  angMon["4"] = 4;
57  angMon["5"] = 5;
58  angMon["6"] = 6;
59  angMon["7"] = 7;
60  angMon["8"] = 8;
61 }
62 
63 bool ECPComponentBuilder::parse(const std::string& fname, xmlNodePtr cur)
64 {
65  const std::string cutoff_str(getXMLAttributeValue(cur, "cutoff"));
66  if (!cutoff_str.empty())
67  RcutMax = std::stod(cutoff_str);
68 
69  return read_pp_file(fname);
70 }
71 
72 int ReadFileBuffer::get_file_length(std::ifstream* f) const
73 {
74  f->seekg(0, std::ios::end);
75  int len = f->tellg();
76  f->seekg(0, std::ios::beg);
77  return len;
78 }
79 
81 {
82  if (is_open)
83  {
84  if (myComm == NULL || myComm->rank() == 0)
85  {
86  delete fin;
87  fin = NULL;
88  }
89  delete[] cbuffer;
90  cbuffer = NULL;
91  is_open = false;
92  length = 0;
93  }
94 }
95 
96 bool ReadFileBuffer::open_file(const std::string& fname)
97 {
98  reset();
99 
100  if (myComm == NULL || myComm->rank() == 0)
101  {
102  fin = new std::ifstream(fname.c_str());
103  if (fin->is_open())
104  is_open = true;
105  }
106  if (myComm)
107  myComm->bcast(is_open);
108  return is_open;
109 }
110 
112 {
113  if (!is_open)
114  return false;
115 
116  if (myComm == NULL || myComm->rank() == 0)
117  {
119  }
120  if (myComm)
121  myComm->bcast(length);
122 
123  cbuffer = new char[length + 1];
124  cbuffer[length] = '\0';
125 
126  if (myComm == NULL || myComm->rank() == 0)
127  fin->read(cbuffer, length);
128 
129  if (myComm != NULL)
131 
132  return true;
133 }
134 
135 
136 bool ECPComponentBuilder::read_pp_file(const std::string& fname)
137 {
138  ReadFileBuffer buf(myComm);
139  bool okay = buf.open_file(fname);
140  if (!okay)
141  myComm->barrier_and_abort("ECPComponentBuilder::read_pp_file Missing PP file " + fname + "\n");
142 
143  okay = buf.read_contents();
144  if (!okay)
145  myComm->barrier_and_abort("ECPComponentBuilder::read_pp_file Unable to read PP file " + fname + "\n");
146 
147  xmlDocPtr m_doc = xmlReadMemory(buf.contents(), buf.length, NULL, NULL, 0);
148 
149  if (m_doc == NULL)
150  {
151  xmlFreeDoc(m_doc);
152  myComm->barrier_and_abort("ECPComponentBuilder::read_pp_file xml file " + fname + " is invalid");
153  }
154  // Check the document is of the right kind
155  xmlNodePtr cur = xmlDocGetRootElement(m_doc);
156  if (cur == NULL)
157  {
158  xmlFreeDoc(m_doc);
159  myComm->barrier_and_abort("Empty document");
160  }
161  bool success = put(cur);
162  xmlFreeDoc(m_doc);
163  return success;
164 }
165 
166 bool ECPComponentBuilder::put(xmlNodePtr cur)
167 {
168  // int nk=0;
169  //vector<RealType> kpts;
170  std::vector<xmlNodePtr> semiPtr;
171  cur = cur->children;
172  while (cur != NULL)
173  {
174  std::string cname((const char*)cur->name);
175  if (cname == "header")
176  {
177  Zeff = std::stoi(getXMLAttributeValue(cur, "zval"));
178  AtomicNumber = std::stoi(getXMLAttributeValue(cur, "atomic-number"));
179  }
180  else if (cname == "grid")
181  {
182  //capture the global grid
183  grid_global = createGrid(cur);
184  }
185  else if (cname == "L2")
186  {
187  buildL2(cur);
188  }
189  else if (cname == "semilocal")
190  {
191  semiPtr.push_back(cur); //save the pointer
192  }
193  else if (cname == "local")
194  {
195  buildLocal(cur);
196  }
197  cur = cur->next;
198  }
199  if (semiPtr.size())
200  {
201  if (!pp_nonloc)
202  pp_nonloc = std::make_unique<NonLocalECPComponent>();
203  if (pp_so == 0)
204  pp_so = std::make_unique<SOECPComponent>();
205  if (pp_loc)
206  {
207  for (int i = 0; i < semiPtr.size(); i++)
208  addSemiLocal(semiPtr[i]);
209  }
210  else
211  buildSemiLocalAndLocal(semiPtr);
212  }
213  if (pp_nonloc)
214  {
216  app_log() << " Non-local pseudopotential parameters" << std::endl;
217  pp_nonloc->print(app_log());
218  app_log() << " Maximum cutoff radius " << pp_nonloc->Rmax << std::endl;
219  }
220  return true;
221 }
222 
224 {
226  return;
228  return;
229  std::array<char, 12> fname;
230  std::snprintf(fname.data(), fname.size(), "%s.pp.dat", Species.c_str());
231  std::ofstream fout(fname.data());
232  fout.setf(std::ios::scientific, std::ios::floatfield);
233  fout.precision(12);
234  int nl = pp_nonloc ? pp_nonloc->nlpp_m.size() : 0;
235  RealType d = 1.7e-2;
236  RealType rt = 0.13 * d;
237  if (nl)
238  {
239  fout << "# Lmax = " << Lmax + 1 << " nonlocal L channels" << nl << std::endl;
240  fout << "# Units = bohr hartree " << std::endl;
241  fout << "# r -r*V/zeff Vnl ... " << std::endl;
242  while (rt < 5)
243  {
244  fout << rt << std::setw(25) << pp_loc->splint(rt);
245  for (int l = 0; l < nl; l++)
246  fout << std::setw(25) << pp_nonloc->nlpp_m[l]->splint(rt);
247  fout << std::endl;
248  rt += d;
249  }
250  }
251  else
252  {
253  fout << "# Units = bohr hartree " << std::endl;
254  fout << "# r -r*V/zeff " << std::endl;
255  while (rt < 5)
256  {
257  fout << rt << std::setw(25) << pp_loc->splint(rt) << std::endl;
258  ;
259  rt += d;
260  }
261  }
262 }
263 
265 {
266  app_log() << " Quadrature Nrule: " << rule << std::endl;
267  Quadrature3D<RealType> myRule(rule);
268  pp_nonloc->sgridxyz_m = myRule.xyz_m;
269  pp_nonloc->sgridweight_m = myRule.weight_m;
270  // Allocate storage for wave function ratios
271  pp_nonloc->resize_warrays(myRule.nk, NumNonLocal, Lmax);
272  if (pp_so)
273  { //added here bc must have nonlocal terms to have SO contributions
274  pp_so->sgridxyz_m_ = myRule.xyz_m;
275  pp_so->sgridweight_m_ = myRule.weight_m;
276  pp_so->resize_warrays(myRule.nk, NumSO, Srule);
277  }
278 }
279 
280 } // namespace qmcplusplus
void buildLocal(xmlNodePtr cur)
build a Local Pseudopotential
Base class for any object which needs to know about a MPI communicator.
Definition: MPIObjectBase.h:26
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
int rank() const
return the rank
Definition: Communicate.h:116
QTBase::RealType RealType
Definition: Configuration.h:58
Declaration of OutputManager class.
std::map< std::string, int > angMon
ECPComponentBuilder(const std::string &aname, Communicate *c, int nrule=-1, int llocal=-1, int srule=8)
constructor spin grid used for numerical integration.
std::ostream & app_log()
Definition: OutputManager.h:65
std::unique_ptr< NonLocalECPComponent > pp_nonloc
OutputManagerClass outputManager(Verbosity::HIGH)
Wrapping information on parallelism.
Definition: Communicate.h:68
bool open_file(const std::string &fname)
std::unique_ptr< mGridType > grid_global
std::unique_ptr< SOECPComponent > pp_so
Communicate * myComm
pointer to Communicate
Definition: MPIObjectBase.h:62
Declaration of a builder class for an ECP component for an ionic type.
bool io_node
true, print out file
Definition: qmc_common.h:39
std::unique_ptr< RadialPotentialType > pp_loc
std::string getXMLAttributeValue(const xmlNodePtr cur, const std::string_view name)
get the value string for attribute name if name is unfound in cur you get an empty string back this i...
int mpi_groups
number of mpi groups
Definition: qmc_common.h:33
bool parse(const std::string &fname, xmlNodePtr cur)
std::vector< PosType > xyz_m
Definition: Quadrature.h:43
bool read_pp_file(const std::string &fname)
std::vector< RealType > weight_m
Definition: Quadrature.h:44
void buildSemiLocalAndLocal(std::vector< xmlNodePtr > &semiPtr)
int get_file_length(std::ifstream *f) const
void bcast(T &)
QMCState qmc_common
a unique QMCState during a run
Definition: qmc_common.cpp:111
void barrier_and_abort(const std::string &msg) const
bool isActive(Verbosity level) const
std::unique_ptr< mGridType > createGrid(xmlNodePtr cur, bool useLinear=false)