QMCPACK
SPOSetScanner.h
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: Ye Luo, yeluo@anl.gov, Argonne National Laboratory
8 //
9 // File created by: Ye Luo, yeluo@anl.gov, Argonne National Laboratory
10 //////////////////////////////////////////////////////////////////////////////////////
11 
12 
13 #ifndef QMCPLUSPLUS_SPOSET_SCANNER_H
14 #define QMCPLUSPLUS_SPOSET_SCANNER_H
15 
16 #include "Particle/ParticleSet.h"
19 #include "OhmmsData/AttributeSet.h"
20 
21 namespace qmcplusplus
22 {
23 /** a scanner for all the SPO sets.
24  */
26 {
27 public:
28  using PtclPool = std::map<std::string, const std::unique_ptr<ParticleSet>>;
35 
36  RealType myfabs(RealType s) { return std::fabs(s); }
37  template<typename T>
38  std::complex<T> myfabs(std::complex<T>& s)
39  {
40  return std::complex<T>(myfabs(s.real()), myfabs(s.imag()));
41  }
42  template<typename T>
44  {
45  return TinyVector<T, OHMMS_DIM>(myfabs(s[0]), myfabs(s[1]), myfabs(s[2]));
46  }
47 
52 
53  // construction/destruction
54  SPOSetScanner(const SPOSetMap& sposets_in, ParticleSet& targetPtcl, const PtclPool& psets)
55  : sposets(sposets_in), target(targetPtcl), ptcl_pool_(psets), ions(0){};
56  //~SPOSetScanner(){};
57 
58  // processing scanning
59  void put(xmlNodePtr cur)
60  {
61  app_log() << "Entering the SPO set scanner!" << std::endl;
62  // check in the source particle set and search for it in the pool.
63  std::string sourcePtcl("ion0");
64  OhmmsAttributeSet aAttrib;
65  aAttrib.add(sourcePtcl, "source");
66  aAttrib.put(cur);
67  auto pit(ptcl_pool_.find(sourcePtcl));
68  if (pit == ptcl_pool_.end())
69  app_log() << "Source particle set not found. Can not be used as reference point." << std::endl;
70  else
71  ions = pit->second.get();
72 
73  // scanning the SPO sets
74  xmlNodePtr cur_save = cur;
75  for (const auto& [name, sposet] : sposets)
76  {
77  app_log() << " Processing SPO " << sposet->getName() << std::endl;
78  // scanning the paths
79  cur = cur_save->children;
80  while (cur != NULL)
81  {
82  std::string trace_name("no name");
83  OhmmsAttributeSet aAttrib;
84  aAttrib.add(trace_name, "name");
85  aAttrib.put(cur);
86  std::string cname(getNodeName(cur));
87  std::string prefix(sposet->getName() + "_" + cname + "_" + trace_name);
88  if (cname == "path")
89  {
90  app_log() << " Scanning a " << cname << " called " << trace_name << " and writing to "
91  << prefix + "_v/g/l/report.dat" << std::endl;
92  auto spo = sposet->makeClone();
93  scan_path(cur, *spo, prefix);
94  }
95  else
96  {
97  if (cname != "text" && cname != "comment")
98  app_log() << " Unknown type of scanning " << cname << std::endl;
99  }
100  cur = cur->next;
101  }
102  }
103  app_log() << "Exiting the SPO set scanner!" << std::endl << std::endl;
104  }
105 
106  // scanning a path
107  void scan_path(xmlNodePtr cur, SPOSet& sposet, std::string prefix)
108  {
109  std::string file_name;
110  file_name = prefix + "_v.dat";
111  std::ofstream output_v(file_name.c_str());
112  file_name = prefix + "_g.dat";
113  std::ofstream output_g(file_name.c_str());
114  file_name = prefix + "_l.dat";
115  std::ofstream output_l(file_name.c_str());
116  file_name = prefix + "_report.dat";
117  std::ofstream output_report(file_name.c_str());
118 
119  int nknots(2);
120  int from_atom(-1);
121  int to_atom(-1);
122  TinyVector<double, OHMMS_DIM> from_pos(0.0, 0.0, 0.0);
123  TinyVector<double, OHMMS_DIM> to_pos(0.0, 0.0, 0.0);
124 
125  OhmmsAttributeSet aAttrib;
126  aAttrib.add(nknots, "nknots");
127  aAttrib.add(from_atom, "from_atom");
128  aAttrib.add(to_atom, "to_atom");
129  aAttrib.add(from_pos, "from_pos");
130  aAttrib.add(to_pos, "to_pos");
131  aAttrib.put(cur);
132 
133  // sanity check
134  if (nknots < 2)
135  nknots = 2;
136  // check out the reference atom coordinates
137  if (ions)
138  {
139  if (from_atom >= 0 && from_atom < ions->R.size())
140  from_pos = ions->R[from_atom];
141  if (to_atom >= 0 && to_atom < ions->R.size())
142  to_pos = ions->R[to_atom];
143  }
144 
145  // prepare a fake particle set
146  ValueVector SPO_v, SPO_l, SPO_v_avg, SPO_l_avg;
147  GradVector SPO_g, SPO_g_avg;
148  int OrbitalSize(sposet.size());
149  SPO_v.resize(OrbitalSize);
150  SPO_g.resize(OrbitalSize);
151  SPO_l.resize(OrbitalSize);
152  SPO_v_avg.resize(OrbitalSize);
153  SPO_g_avg.resize(OrbitalSize);
154  SPO_l_avg.resize(OrbitalSize);
155  SPO_v_avg = 0.0;
156  SPO_g_avg = 0.0;
157  SPO_l_avg = 0.0;
158  double Delta = 1.0 / (nknots - 1);
159  int elec_count = target.R.size();
160  auto R_saved = target.R;
161  ParticleSet::SingleParticlePos zero_pos(0.0, 0.0, 0.0);
162  for (int icount = 0, ind = 0; icount < nknots; icount++, ind++)
163  {
164  if (ind == elec_count)
165  ind = 0;
166  target.R[ind][0] = (to_pos[0] - from_pos[0]) * Delta * icount + from_pos[0];
167  target.R[ind][1] = (to_pos[1] - from_pos[1]) * Delta * icount + from_pos[1];
168  target.R[ind][2] = (to_pos[2] - from_pos[2]) * Delta * icount + from_pos[2];
169  target.makeMove(ind, zero_pos);
170  sposet.evaluateVGL(target, ind, SPO_v, SPO_g, SPO_l);
171  std::ostringstream o;
172  o << "x_y_z " << std::fixed << std::setprecision(7) << target.R[ind][0] << " " << target.R[ind][1] << " "
173  << target.R[ind][2];
174  output_v << o.str() << " : " << std::scientific << std::setprecision(12);
175  output_g << o.str() << " : " << std::scientific << std::setprecision(12);
176  output_l << o.str() << " : " << std::scientific << std::setprecision(12);
177  for (int iorb = 0; iorb < OrbitalSize; iorb++)
178  {
179  SPO_v_avg[iorb] += myfabs(SPO_v[iorb]);
180  SPO_g_avg[iorb] += myfabs(SPO_g[iorb]);
181  SPO_l_avg[iorb] += myfabs(SPO_l[iorb]);
182  output_v << SPO_v[iorb] << " ";
183  output_g << SPO_g[iorb][0] << " " << SPO_g[iorb][1] << " " << SPO_g[iorb][2] << " ";
184  output_l << SPO_l[iorb] << " ";
185  }
186  output_v << std::endl;
187  output_g << std::endl;
188  output_l << std::endl;
189  }
190  // restore the whole target.
191  target.R = R_saved;
192  target.update();
193 #ifdef QMC_COMPLEX
194  output_report << "# Report: Orb Value_avg I/R Gradients_avg Laplacian_avg" << std::endl;
195 #else
196  output_report << "# Report: Orb Value_avg Gradients_avg Laplacian_avg" << std::endl;
197 #endif
198  for (int iorb = 0; iorb < OrbitalSize; iorb++)
199  output_report << "\t" << iorb << " " << std::scientific
200  << SPO_v_avg[iorb] * static_cast<RealType>(1.0 / nknots) << " "
201 #ifdef QMC_COMPLEX
202  << SPO_v_avg[iorb].imag() / SPO_v_avg[iorb].real() << " "
203 #endif
204  << SPO_g_avg[iorb][0] * static_cast<RealType>(1.0 / nknots) << " "
205  << SPO_g_avg[iorb][1] * static_cast<RealType>(1.0 / nknots) << " "
206  << SPO_g_avg[iorb][2] * static_cast<RealType>(1.0 / nknots) << " "
207  << SPO_l_avg[iorb] * static_cast<RealType>(1.0 / nknots) << std::fixed << std::endl;
208  output_v.close();
209  output_g.close();
210  output_l.close();
211  output_report.close();
212  }
213 };
214 } // namespace qmcplusplus
215 
216 #endif
base class for Single-particle orbital sets
Definition: SPOSet.h:46
Fixed-size array.
Definition: OhmmsTinyMeta.h:30
OrbitalSetTraits< ValueType >::ValueVector ValueVector
Definition: SPOSetScanner.h:32
RealType myfabs(RealType s)
Definition: SPOSetScanner.h:36
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
QTBase::RealType RealType
Definition: Configuration.h:58
const SPOSetMap & sposets
Definition: SPOSetScanner.h:48
QMCTraits::RealType RealType
Definition: SPOSetScanner.h:30
std::ostream & app_log()
Definition: OutputManager.h:65
if(c->rank()==0)
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
QMCTraits::ValueType ValueType
Definition: SPOSetScanner.h:31
OrbitalSetTraits< ValueType >::HessVector HessVector
Definition: SPOSetScanner.h:34
int size() const
return the size of the orbital set Ye: this needs to be replaced by getOrbitalSetSize(); ...
Definition: SPOSet.h:75
void update(bool skipSK=false)
update the internal data
TinyVector< T, OHMMS_DIM > myfabs(TinyVector< T, OHMMS_DIM > &s)
Definition: SPOSetScanner.h:43
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
const PtclPool & ptcl_pool_
Definition: SPOSetScanner.h:50
QTBase::ValueType ValueType
Definition: Configuration.h:60
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
void scan_path(xmlNodePtr cur, SPOSet &sposet, std::string prefix)
a scanner for all the SPO sets.
Definition: SPOSetScanner.h:25
virtual void evaluateVGL(const ParticleSet &P, int iat, ValueVector &psi, GradVector &dpsi, ValueVector &d2psi)=0
evaluate the values, gradients and laplacians of this single-particle orbital set ...
ParticlePos R
Position.
Definition: ParticleSet.h:79
std::map< std::string, const std::unique_ptr< ParticleSet > > PtclPool
Definition: SPOSetScanner.h:28
void makeMove(Index_t iat, const SingleParticlePos &displ, bool maybe_accept=true)
move the iat-th particle to active_pos_
OrbitalSetTraits< ValueType >::GradVector GradVector
Definition: SPOSetScanner.h:33
std::map< std::string, const std::unique_ptr< const SPOSet > > SPOMap
Definition: SPOSet.h:57
SPOSetScanner(const SPOSetMap &sposets_in, ParticleSet &targetPtcl, const PtclPool &psets)
Definition: SPOSetScanner.h:54
trait class to handel a set of Orbitals
void put(xmlNodePtr cur)
Definition: SPOSetScanner.h:59
bool get(std::ostream &os) const override
dummy. For satisfying OhmmsElementBase.
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
std::string getNodeName(xmlNodePtr cur)
Definition: libxmldefs.cpp:15
std::complex< T > myfabs(std::complex< T > &s)
Definition: SPOSetScanner.h:38