QMCPACK
ECPComponentBuilder.1.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: Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
8 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
9 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
10 //
11 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
12 //////////////////////////////////////////////////////////////////////////////////////
13 
14 
17 #include "Numerics/Transform2GridFunctor.h"
19 
20 namespace qmcplusplus
21 {
23 {
24  std::unique_ptr<mGridType> grid_semilocal;
25  RealType rmax = pp_nonloc->Rmax;
26  cur = cur->children;
27  while (cur != NULL)
28  {
29  std::string cname((const char*)cur->name);
30  if (cname == "grid")
31  {
32  grid_semilocal = createGrid(cur);
33  rmax = grid_semilocal->rmax();
34  }
35  else if (cname == "vps")
36  {
37  //should be able to overwrite rmax
38  int l = angMon[getXMLAttributeValue(cur, "l")];
39  Lmax = std::max(l, Lmax);
40  xmlNodePtr cur1 = cur->children;
41  while (cur1 != NULL)
42  {
43  std::string cname1((const char*)cur1->name);
44  if (cname1 == "basisGroup")
45  {
46  pp_nonloc->add(l, createVrWithBasisGroup(cur1, grid_semilocal.get()));
47  }
48  cur1 = cur1->next;
49  }
50  NumNonLocal++;
51  }
52  cur = cur->next;
53  }
54  pp_nonloc->lmax = Lmax;
55  pp_nonloc->Rmax = rmax;
56 }
57 
59 {
60  //todo rcut should be reset if necessary
61  using InFuncType = GaussianTimesRN<RealType>;
62  InFuncType a;
63  a.putBasisGroup(cur);
64  bool ignore = true;
65  const RealType eps = 1e-4;
66  mRealType rout = agrid->rmax() * 2;
67  while (ignore && rout > agrid->rmax())
68  {
69  ignore = (std::abs(a.f(rout)) < eps);
70  rout -= 0.01;
71  }
72  rout += 0.01;
73  app_log() << " cutoff for non-local pseudopotential = " << agrid->rmax() << std::endl;
74  app_log() << " calculated cutoff for " << eps << " = " << rout << std::endl;
75  int ng = agrid->size();
76  //all ways reset grid. Ye Luo
77  std::unique_ptr<GridType> agrid_new;
78  //if(agrid->GridTag != LINEAR_1DGRID)// || rout > agrid->rmax())
79  {
80  RealType ri = 0.0;
81  RealType rf = std::max(rout, agrid->rmax());
82  agrid_new = std::make_unique<LinearGrid<RealType>>();
83  agrid_new->set(ri, rf, ng);
84  app_log() << " Reset the grid for SemiLocal component to a LinearGrid. " << std::endl;
85  }
86  std::vector<RealType> v(ng);
87  for (int ig = 0; ig < ng; ig++)
88  {
89  v[ig] = a.f((*agrid_new)[ig]);
90  }
91  v[ng - 1] = 0.0;
92  RadialPotentialType* app = new RadialPotentialType(std::move(agrid_new), v);
93  app->spline();
94  return app;
95 }
96 
97 /** build a Local Pseudopotential
98  *
99  * For numerical stability, the radial function of the local pseudopotential is stored
100  * as \f$rV(r)/Z_{eff}/Z_{e}\f$ for the distance r and \f$Z_e = -1\f$.
101  * The coulomb factor $Z_{e}Z_{eff}/r$ is applied by LocalECPotential
102  * (see LocalECPotential::evaluate).
103  */
105 {
106  if (pp_loc)
107  return; //something is wrong
108 
109  std::string vFormat("V");
110  const std::string v_str(getXMLAttributeValue(cur, "format"));
111  if (!v_str.empty())
112  vFormat = v_str;
113 
114  int vPowerCorrection = 1;
115  if (vFormat == "r*V")
116  {
117  app_log() << " Local pseudopotential format = r*V" << std::endl;
118  vPowerCorrection = 0;
119  }
120  else
121  {
122  app_log() << " Local pseudopotential format = V" << std::endl;
123  }
124  using InFuncType = GaussianTimesRN<RealType>;
125  std::unique_ptr<GridType> grid_local;
126  std::unique_ptr<mGridType> grid_local_inp;
127  InFuncType vr;
128  bool bareCoulomb = true;
129  cur = cur->children;
130  while (cur != NULL)
131  {
132  std::string cname((const char*)cur->name);
133  if (cname == "grid")
134  {
135  grid_local_inp = createGrid(cur, true);
136  }
137  else if (cname == "basisGroup")
138  {
139  vr.putBasisGroup(cur, vPowerCorrection);
140  bareCoulomb = false;
141  }
142  cur = cur->next;
143  }
144  if (grid_local_inp == nullptr)
145  {
146  if (grid_global == nullptr)
147  myComm->barrier_and_abort("ECPComponentBuilder::buildLocal Missing grid information. ");
148  grid_local = std::make_unique<LinearGrid<RealType>>();
149  grid_local->set(grid_global->rmin(), grid_global->rmax(), grid_global->size());
150  }
151  else
152  {
153  grid_local = std::make_unique<LinearGrid<RealType>>();
154  grid_local->set(grid_local_inp->rmin(), grid_local_inp->rmax(), grid_local_inp->size());
155  }
156  if (grid_local->GridTag == CUSTOM_1DGRID)
157  myComm->barrier_and_abort("ECPComponentBuilder::buildLocal Custom grid is used. Need to recast to the linear grid");
158  else
159  {
160  std::vector<RealType> v;
161  if (bareCoulomb)
162  {
163  app_log() << " Bare Coulomb potential is used." << std::endl;
164  grid_local->set(0.0, 1., 3);
165  v.resize(3);
166  for (int ig = 0; ig < 3; ig++)
167  v[ig] = 1.0;
168  pp_loc = std::make_unique<RadialPotentialType>(std::move(grid_local), v);
169  pp_loc->spline(0, 0.0, 2, 0.0);
170  }
171  else
172  {
173  app_log() << " Guassian basisGroup is used: base power " << vr.basePower << std::endl;
174  const RealType eps = 1e-12; //numeric_limits<RealType>::epsilon();//1e-12;
175  RealType zinv = 1.0 / Zeff;
176  RealType r = 10.;
177  bool ignore = true;
178  int last = grid_local->size() - 1;
179  while (ignore && last)
180  {
181  r = (*grid_local)[last];
182  ignore = (std::abs(zinv * vr.f(r)) < eps);
183  --last;
184  }
185  if (last == 0)
186  myComm->barrier_and_abort("ECPComponentBuilder::buildLocal. Illegal Local Pseudopotential");
187  //Add the reset values here
188  int ng = static_cast<int>(r / 1e-3) + 1;
189  app_log() << " Use a Linear Grid: [0," << r << "] Number of points = " << ng << std::endl;
190  grid_local->set(0.0, r, ng);
191  v.resize(ng);
192  for (int ig = 1; ig < ng - 1; ig++)
193  {
194  double r = (*grid_local)[ig];
195  v[ig] = 1.0 - zinv * vr.f(r);
196  }
197  v[0] = 2.0 * v[1] - v[2];
198  v[ng - 1] = 1.0;
199  pp_loc = std::make_unique<RadialPotentialType>(std::move(grid_local), v);
200  pp_loc->spline(); //use the fixed conditions
201  }
202  }
203 }
204 
205 std::unique_ptr<ECPComponentBuilder::mGridType> ECPComponentBuilder::createGrid(xmlNodePtr cur, bool useLinear)
206 {
207  mRealType ri = 1e-6;
208  mRealType rf = 100.0;
209  mRealType ascale = -1.0e0;
210  mRealType astep = -1.0;
211  //mRealType astep = 1.25e-2;
212  int npts = 1001;
213  std::string gridType("log");
214  std::string gridID("global");
215  OhmmsAttributeSet radAttrib;
216  radAttrib.add(gridType, "type");
217  radAttrib.add(gridID, "grid_id");
218  radAttrib.add(gridID, "grid_def");
219  radAttrib.add(gridID, "name");
220  radAttrib.add(gridID, "id");
221  radAttrib.add(npts, "npts");
222  radAttrib.add(ri, "ri");
223  radAttrib.add(rf, "rf");
224  radAttrib.add(ascale, "ascale");
225  radAttrib.add(astep, "astep");
226  radAttrib.add(ascale, "scale");
227  radAttrib.add(astep, "step");
228  radAttrib.put(cur);
229  auto git = grid_inp.find(gridID);
230  if (git != grid_inp.end())
231  {
232  return (*git).second->makeClone(); //use the same grid
233  }
234  //overwrite the grid type to linear starting at 0.0
235  if (useLinear)
236  {
237  gridType = "linear";
238  ri = 0.0;
239  }
240  std::unique_ptr<mGridType> agrid;
241  if (gridType == "log")
242  {
243  if (ascale > 0.0)
244  {
245  app_log() << " Log grid scale=" << ascale << " step=" << astep << " npts=" << npts << std::endl;
246  agrid = std::make_unique<LogGridZero<mRealType>>();
247  agrid->set(astep, ascale, npts);
248  }
249  else
250  {
251  if (ri < std::numeric_limits<mRealType>::epsilon())
252  {
253  ri = std::numeric_limits<mRealType>::epsilon();
254  }
255  agrid = std::make_unique<LogGrid<mRealType>>();
256  agrid->set(ri, rf, npts);
257  }
258  }
259  else if (gridType == "linear")
260  {
261  agrid = std::make_unique<LinearGrid<mRealType>>();
262  if (astep > 0.0)
263  {
264  npts = static_cast<int>((rf - ri) / astep) + 1;
265  }
266  agrid->set(ri, rf, npts);
267  app_log() << " Linear grid ri=" << ri << " rf=" << rf << " npts = " << npts << std::endl;
268  }
269  else
270  //accept numerical data
271  {
272  xmlNodePtr cur1 = cur->children;
273  while (cur1 != NULL)
274  {
275  std::string cname((const char*)cur1->name);
276  if (cname == "data")
277  {
278  std::vector<double> gIn(npts);
279  putContent(gIn, cur1);
280  agrid = std::make_unique<NumericalGrid<mRealType>>(gIn);
281  app_log() << " Numerical grid npts = " << gIn.size() << std::endl;
282  }
283  cur1 = cur1->next;
284  }
285  }
286  return agrid;
287 }
288 
289 } // namespace qmcplusplus
void buildLocal(xmlNodePtr cur)
build a Local Pseudopotential
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
QTBase::RealType RealType
Definition: Configuration.h:58
std::map< std::string, int > angMon
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
std::ostream & app_log()
Definition: OutputManager.h:65
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
bool putBasisGroup(xmlNodePtr cur, int baseOff=0)
process cur xmlnode
void spline(int imin, value_type yp1, int imax, value_type ypn) override
Evaluate the 2nd derivative on the grid points.
std::unique_ptr< NonLocalECPComponent > pp_nonloc
An abstract base class to implement a One-Dimensional grid.
std::unique_ptr< mGridType > grid_global
Communicate * myComm
pointer to Communicate
Definition: MPIObjectBase.h:62
Declaration of a builder class for an ECP component for an ionic type.
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
std::map< std::string, std::unique_ptr< mGridType > > grid_inp
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...
LocalECPotential::RadialPotentialType RadialPotentialType
bool putContent(T &a, xmlNodePtr cur)
replaces a&#39;s value with the first "element" in the "string" returned by XMLNodeString{cur}.
Definition: libxmldefs.h:88
int size() const
returns the size of the grid
T rmax() const
return the last grid point
void barrier_and_abort(const std::string &msg) const
void add(PDT &aparam, const std::string &aname, std::vector< PDT > candidate_values={}, TagStatus status=TagStatus::OPTIONAL)
add a new attribute
Definition: AttributeSet.h:42
RadialPotentialType * createVrWithBasisGroup(xmlNodePtr cur, mGridType *agrid)
std::unique_ptr< mGridType > createGrid(xmlNodePtr cur, bool useLinear=false)