QMCPACK
SPOSetInputInfo.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: Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
8 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
9 //
10 // File created by: Jaron T. Krogel, krogeljt@ornl.gov, Oak Ridge National Laboratory
11 //////////////////////////////////////////////////////////////////////////////////////
12 
13 
14 #include "SPOSetInputInfo.h"
15 #include "OhmmsData/AttributeSet.h"
17 #include <limits>
18 
19 namespace qmcplusplus
20 {
22 
24 const RealType rnone = std::numeric_limits<RealType>::max();
25 const std::string& snone = "none";
26 
27 
29 {
30  group = 0;
31  size = inone;
32  index_min = inone;
33  index_max = inone;
34  occ = snone;
35  ecut = rnone;
36  energy_min = rnone;
37  energy_max = rnone;
39 
44 
45  has_size = false;
46  has_index_range = false;
47  has_occ = false;
48  has_ecut = false;
49  has_energy_range = false;
50  has_indices = false;
51  has_energies = false;
52  has_index_info = false;
53  has_energy_info = false;
54 
55  legacy_request = false;
56 
57  all_indices_computed = false;
58 }
59 
60 
61 void SPOSetInputInfo::put(xmlNodePtr cur)
62 {
63  using namespace Units;
64 
65  reset();
66 
67  indices.clear();
68  energies.clear();
69 
70  std::string units_in = snone;
71 
72  OhmmsAttributeSet attrib;
73  attrib.add(group, "group");
74  attrib.add(size, "size");
75  attrib.add(index_min, "index_min");
76  attrib.add(index_max, "index_max");
77  attrib.add(occ, "occ");
78  attrib.add(ecut, "ecut");
79  attrib.add(energy_min, "energy_min");
80  attrib.add(energy_max, "energy_max");
81  attrib.add(units_in, "units");
82  attrib.put(cur);
83 
84  has_size = size != inone;
86  has_occ = occ != snone;
87  has_ecut = ecut != rnone;
89  has_indices = false;
90  has_energies = false;
91 
92  if (group < 0)
93  APP_ABORT("SPOSetInputInfo::put group must be positive");
94 
96  {
97  report();
98  if (units_in == snone)
99  APP_ABORT("SPOSetInputInfo::put ecut or energy range present, but units have not been provided");
100  units eunits = energy_unit(units_in);
101  if (has_ecut)
102  ecut = convert(ecut, eunits, Ha);
103  else if (has_energy_range)
104  {
105  energy_min = convert(energy_min, eunits, Ha);
106  energy_max = convert(energy_max, eunits, Ha);
107  }
108  }
109 
110  xmlNodePtr element = cur->xmlChildrenNode;
111  while (element != NULL)
112  {
113  std::string ename((const char*)element->name);
114  if (ename == "indices")
115  {
116  has_indices = true;
117  putContent(indices, element);
118  }
119  else if (ename == "energies")
120  {
121  has_energies = true;
122  units_in = snone;
123  OhmmsAttributeSet attrib;
124  attrib.add(matching_tol, "matching_tol");
125  attrib.add(units_in, "units");
126  attrib.put(element);
127  putContent(energies, element);
128  if (units_in == snone)
129  APP_ABORT("SPOSetInputInfo::put energies present, but units have not been provided");
130  units eunits = energy_unit(units_in);
131  if (matching_tol == rnone)
132  matching_tol = 1e-6;
133  else
134  matching_tol = convert(matching_tol, eunits, Ha);
135 
136  //convert_array(energies,eunits,Ha);
137  std::vector<double> entmp;
138  convert_array(entmp, eunits, Ha);
139 
140  sort(energies.begin(), energies.end());
141  }
142  element = element->next;
143  }
144 
147 
149 
151 
153 }
154 
155 
157 {
158  if (has_index_info)
159  {
160  lowest_index = std::numeric_limits<int>::max();
162  if (has_size)
163  {
165  highest_index = std::max(highest_index, size - 1);
166  }
167  if (has_index_range)
168  {
171  }
172  if (has_occ)
173  {
174  int imin = -1;
175  int imax = -1;
176  for (int i = 0; i < occ.size(); ++i)
177  if (occ[i] == '1')
178  {
179  if (imin == -1)
180  imin = i;
181  imax = i;
182  }
183  if (imin != -1)
185  if (imax != -1)
186  highest_index = std::max(highest_index, imax);
187  }
188  if (has_indices)
189  for (int i = 0; i < indices.size(); ++i)
190  {
191  int ind = indices[i];
193  highest_index = std::max(highest_index, ind);
194  }
195  }
196 }
197 
198 
200 {
201  if (has_energy_info)
202  {
205  if (has_ecut)
206  {
208  highest_energy = std::max(highest_energy, ecut);
209  }
210  if (has_energy_range)
211  {
214  }
215  if (has_energies)
216  for (int i = 0; i < energies.size(); ++i)
217  {
218  RealType en = energies[i];
220  highest_energy = std::max(highest_energy, en);
221  }
222  }
223 }
224 
225 
226 void SPOSetInputInfo::report(const std::string& pad)
227 {
228  app_log() << pad << "SPOSetInput report" << std::endl;
229  app_log() << pad << " has_size = " << has_size << std::endl;
230  app_log() << pad << " has_index_range = " << has_index_range << std::endl;
231  app_log() << pad << " has_occ = " << has_occ << std::endl;
232  app_log() << pad << " has_ecut = " << has_ecut << std::endl;
233  app_log() << pad << " has_energy_range = " << has_energy_range << std::endl;
234  app_log() << pad << " has_indices = " << has_indices << std::endl;
235  app_log() << pad << " has_energies = " << has_energies << std::endl;
236  app_log() << pad << " group = " << group << std::endl;
237  app_log() << pad << " size = " << size << std::endl;
238  app_log() << pad << " index_min = " << index_min << std::endl;
239  app_log() << pad << " index_max = " << index_max << std::endl;
240  app_log() << pad << " occ = " << occ << std::endl;
241  app_log() << pad << " ecut = " << ecut << std::endl;
242  app_log() << pad << " energy_min = " << energy_min << std::endl;
243  app_log() << pad << " energy_max = " << energy_max << std::endl;
244  app_log() << pad << " # of indices = " << indices.size() << std::endl;
245  app_log() << pad << " indices = \n ";
246  for (int i = 0; i < indices.size(); ++i)
247  app_log() << indices[i] << " ";
248  app_log() << std::endl;
249  app_log() << pad << " # of energies = " << energies.size() << std::endl;
250  app_log() << pad << " energies = \n ";
251  for (int i = 0; i < energies.size(); ++i)
252  app_log() << energies[i] << " ";
253  app_log() << std::endl;
254  app_log() << pad << " matching_tol = " << matching_tol << std::endl;
255  app_log() << pad << " lowest_index = " << lowest_index << std::endl;
256  app_log() << pad << " highest_index = " << highest_index << std::endl;
257  app_log() << pad << " lowest_energy = " << lowest_energy << std::endl;
258  app_log() << pad << " highest_energy = " << highest_energy << std::endl;
259  app_log() << pad << "end SPOSetInput report" << std::endl;
260  app_log().flush();
261 }
262 
263 
264 SPOSetInputInfo::indices_t& SPOSetInputInfo::get_indices(const std::vector<std::unique_ptr<SPOSetInfo>>& states_vec)
265 {
267  {
268  all_indices.clear();
269 
270  if (group >= states_vec.size())
271  APP_ABORT("SPOSetInputInfo::get_indices orbital group index is out of range");
272 
273  const SPOSetInfo& states = *states_vec[group];
274 
275  // ensure that state info has been properly intialized
276  bool energy_incomplete = states.partial() || !states.has_indices() || !states.has_energies();
277  if (has_energy_info && energy_incomplete)
278  APP_ABORT("SPOSetInputInfo::get_indices\n energies requested for sposet\n but state info is incomplete");
279 
280  occupations.clear();
281 
282  occupy_size();
284  occupy_occ();
285  occupy_indices();
286  occupy_ecut(states);
287  occupy_energy_range(states);
288  occupy_energies(states);
289 
290  sort(all_indices.begin(), all_indices.end());
291 
292  if (all_indices[all_indices.size() - 1] >= states.size())
293  APP_ABORT("SPOSetInputInfo::get_indices requested state indices outside the range of states");
294 
295  if (all_indices.size() == 0)
296  APP_ABORT("SPOSetInputInfo::get_indices no states matched request");
297 
298  all_indices_computed = true;
299  }
300 
301  return all_indices;
302 }
303 
304 
306 {
307  if (has_size)
308  {
309  indices_t ind;
310  for (int i = 0; i < size; ++i)
311  ind.push_back(i);
312  occupy("size", ind);
313  }
314 }
315 
317 {
318  if (has_index_range)
319  {
320  indices_t ind;
321  for (int i = index_min; i < index_max; ++i)
322  ind.push_back(i);
323  occupy("index_range", ind);
324  }
325 }
326 
328 {
329  if (has_indices)
330  occupy("indices", indices);
331 }
332 
334 {
335  if (has_occ)
336  {
337  indices_t ind;
338  for (int i = 0; i < occ.size(); ++i)
339  if (occ[i] == '1')
340  ind.push_back(i);
341  occupy("occ", ind);
342  }
343 }
344 
346 {
347  if (has_ecut)
348  {
349  indices_t ind;
350  for (int i = 0; i < states.size(); ++i)
351  {
352  const SPOInfo& state = *states[i];
353  if (state.energy < ecut)
354  ind.push_back(state.index);
355  }
356  occupy("ecut", ind);
357  }
358 }
359 
361 {
362  if (has_energy_range)
363  {
364  indices_t ind;
365  for (int i = 0; i < states.size(); ++i)
366  {
367  const SPOInfo& state = *states[i];
368  if (state.energy < energy_max && state.energy >= energy_min)
369  ind.push_back(state.index);
370  }
371  occupy("energy_range", ind);
372  }
373 }
374 
376 {
377  if (has_energies)
378  {
379  if (!states.energy_ordered())
380  APP_ABORT(
381  "SPOSetInputInfo::load_indices(energies)\n states are not energy ordered\n this is a developer error");
382  indices_t ind;
383  int i = 0;
384  for (int n = 0; n < energies.size(); ++n)
385  {
386  RealType e = energies[n];
387  bool found = false;
388  while (i < states.size())
389  {
390  const SPOInfo& state = *states[i];
391  while (std::abs(e - state.energy) < matching_tol)
392  {
393  ind.push_back(state.index);
394  i++;
395  found = true;
396  }
397  if (found)
398  break;
399  else
400  i++;
401  }
402  if (!found)
403  APP_ABORT("SPOSetInputInfo::load_indices(energies)\n energy eigenvalue not found");
404  }
405  occupy("energies", ind);
406  }
407 }
408 
409 
410 void SPOSetInputInfo::occupy(const std::string& loc, const indices_t& ind)
411 {
412  int imin = std::numeric_limits<int>::max();
413  int imax = std::numeric_limits<int>::min();
414  for (int i = 0; i < ind.size(); ++i)
415  {
416  int ival = ind[i];
417  imin = std::min(imin, ival);
418  imax = std::max(imax, ival);
419  }
420  if (imin < 0)
421  APP_ABORT("SPOSetInputInfo::occupy(" + loc + ")\n indices are negative");
422  for (int i = 0; i < ind.size(); ++i)
423  {
424  int iocc = ind[i];
425  if (iocc >= occupations.size())
426  {
427  int old_size = occupations.size();
428  occupations.resize(iocc + 1);
429  for (int j = old_size; j < occupations.size(); ++j)
430  occupations[j] = false;
431  }
432  if (occupations[iocc])
433  APP_ABORT("SPOSetInputInfo::occupy(" + loc + ")\n sposet request has overlapping index ranges");
434  all_indices.push_back(iocc);
435  occupations[iocc] = true;
436  }
437 }
438 
439 } // namespace qmcplusplus
QMCTraits::RealType RealType
bool has_indices() const
Definition: SPOSetInfo.cpp:87
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
QTBase::RealType RealType
Definition: Configuration.h:58
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
void convert(const PL &lat, const PV &pin, PV &pout)
std::ostream & app_log()
Definition: OutputManager.h:65
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
std::vector< int > indices_t
int index
original orbital index in the maximal basis
Definition: SPOInfo.h:37
RealType energy
energy of the orbital (in Hartree units)
Definition: SPOInfo.h:43
T min(T a, T b)
void occupy_ecut(const SPOSetInfo &states)
base class to describe a single orbital in an SPOSet
Definition: SPOInfo.h:23
void occupy_energies(const SPOSetInfo &states)
const std::string & snone
bool energy_ordered() const
Definition: SPOSetInfo.cpp:115
const int inone
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
void occupy_energy_range(const SPOSetInfo &states)
collection of orbital info for SPOSet instance or builder
Definition: SPOSetInfo.h:25
units energy_unit(const std::string &su)
convert from std::string to energy unit
#define APP_ABORT(msg)
Widely used but deprecated fatal error macros from legacy code.
Definition: AppAbort.h:27
void report(const std::string &pad="")
bool has_energies() const
Definition: SPOSetInfo.cpp:89
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
QMCTraits::RealType RealType
const RealType rnone
std::vector< bool > occupations
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
void occupy(const std::string &loc, const indices_t &ind)
void convert_array(array &values, units units_in, units units_out)
indices_t & get_indices(const std::vector< std::unique_ptr< SPOSetInfo >> &states_vec)