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: Bryan Clark, bclark@Princeton.edu, Princeton University
8 //                    John R. Gergely,  University of Illinois at Urbana-Champaign
9 //                    Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
10 //                    Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
11 //                    Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
12 //                    Ye Luo, yeluo@anl.gov, Argonne National Laboratory
13 //                    Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
14 //
15 // File created by: Bryan Clark, bclark@Princeton.edu, Princeton University
16 //////////////////////////////////////////////////////////////////////////////////////
17 
18 
19 #include "DensityEstimator.h"
20 #include "OhmmsData/AttributeSet.h"
21 #include "LongRange/LRCoulombSingleton.h"
22 #include "Particle/DistanceTableData.h"
23 #include "Particle/MCWalkerConfiguration.h"
24 
25 namespace qmcplusplus
26 {
27 typedef LRCoulombSingleton::LRHandlerType LRHandlerType;
28 typedef LRCoulombSingleton::GridType GridType;
29 typedef LRCoulombSingleton::RadFunctorType RadFunctorType;
30 
DensityEstimator(ParticleSet & elns)31 DensityEstimator::DensityEstimator(ParticleSet& elns)
32 {
33   UpdateMode.set(COLLECTABLE, 1);
34   Periodic = (elns.Lattice.SuperCellEnum != SUPERCELL_OPEN);
35   for (int dim = 0; dim < OHMMS_DIM; ++dim)
36   {
37     density_max[dim] = elns.Lattice.Length[dim];
38     ScaleFactor[dim] = 1.0 / elns.Lattice.Length[dim];
39   }
40 }
41 
resetTargetParticleSet(ParticleSet & P)42 void DensityEstimator::resetTargetParticleSet(ParticleSet& P) {}
43 
evaluate(ParticleSet & P)44 DensityEstimator::Return_t DensityEstimator::evaluate(ParticleSet& P)
45 {
46   RealType wgt = tWalker->Weight;
47   if (Periodic)
48   {
49     for (int iat = 0; iat < P.getTotalNum(); ++iat)
50     {
51       PosType ru;
52       ru    = P.Lattice.toUnit(P.R[iat]);
53       int i = static_cast<int>(DeltaInv[0] * (ru[0] - std::floor(ru[0])));
54       int j = static_cast<int>(DeltaInv[1] * (ru[1] - std::floor(ru[1])));
55       int k = static_cast<int>(DeltaInv[2] * (ru[2] - std::floor(ru[2])));
56       P.Collectables[getGridIndex(i, j, k)] += wgt; //1.0;
57       //	P.Collectables[getGridIndexPotential(i,j,k)]-=1.0;
58     }
59   }
60   else
61   {
62     for (int iat = 0; iat < P.getTotalNum(); ++iat)
63     {
64       PosType ru;
65       for (int dim = 0; dim < OHMMS_DIM; dim++)
66       {
67         //ru[dim]=(P.R[iat][dim]-density_min[dim])/(density_max[dim]-density_min[dim]);
68         ru[dim] = (P.R[iat][dim] - density_min[dim]) * ScaleFactor[dim];
69       }
70       if (ru[0] > 0.0 && ru[1] > 0.0 && ru[2] > 0.0 && ru[0] < 1.0 && ru[1] < 1.0 && ru[2] < 1.0)
71       {
72         int i = static_cast<int>(DeltaInv[0] * (ru[0] - std::floor(ru[0])));
73         int j = static_cast<int>(DeltaInv[1] * (ru[1] - std::floor(ru[1])));
74         int k = static_cast<int>(DeltaInv[2] * (ru[2] - std::floor(ru[2])));
75         P.Collectables[getGridIndex(i, j, k)] += wgt; //1.0;
76         //	  P.Collectables[getGridIndexPotential(i,j,k)]-=1.0;
77       }
78     }
79   }
80   return 0.0;
81 }
82 
addEnergy(MCWalkerConfiguration & W,std::vector<RealType> & LocalEnergy)83 void DensityEstimator::addEnergy(MCWalkerConfiguration& W, std::vector<RealType>& LocalEnergy)
84 {
85   int nw = W.WalkerList.size();
86   int N  = W.getTotalNum();
87   if (Periodic)
88   {
89     for (int iw = 0; iw < nw; iw++)
90     {
91       Walker_t& w     = *W.WalkerList[iw];
92       RealType weight = w.Weight / nw;
93       for (int iat = 0; iat < N; iat++)
94       {
95         PosType ru;
96         ru = W.Lattice.toUnit(w.R[iat]);
97         // for (int dim=0; dim<OHMMS_DIM; dim++)
98         // {
99         //   ru[dim]=(w.R[iat][dim]-density_min[dim])*ScaleFactor[dim];
100         // }
101         int i = static_cast<int>(DeltaInv[0] * (ru[0] - std::floor(ru[0])));
102         int j = static_cast<int>(DeltaInv[1] * (ru[1] - std::floor(ru[1])));
103         int k = static_cast<int>(DeltaInv[2] * (ru[2] - std::floor(ru[2])));
104         W.Collectables[getGridIndex(i, j, k)] += weight;
105       }
106     }
107   }
108 }
109 
addObservables(PropertySetType & plist,BufferType & collectables)110 void DensityEstimator::addObservables(PropertySetType& plist, BufferType& collectables)
111 {
112   //current index
113   myIndex = collectables.current();
114   std::vector<RealType> tmp(NumGrids[OHMMS_DIM]);
115   collectables.add(tmp.begin(), tmp.end());
116   //potentialIndex=collectables.current();
117   //vector<RealType> tmp2(NumGrids[OHMMS_DIM]);
118   //collectables.add(tmp2.begin(),tmp2.end());
119 }
120 
registerCollectables(std::vector<observable_helper * > & h5desc,hid_t gid) const121 void DensityEstimator::registerCollectables(std::vector<observable_helper*>& h5desc, hid_t gid) const
122 {
123   int loc = h5desc.size();
124   std::vector<int> ng(OHMMS_DIM);
125   for (int i = 0; i < OHMMS_DIM; ++i)
126     ng[i] = NumGrids[i];
127   observable_helper* h5o = new observable_helper(myName);
128   h5o->set_dimensions(ng, myIndex);
129   h5o->open(gid);
130   h5desc.push_back(h5o);
131   //h5o=new observable_helper("Potential");
132   //h5o->set_dimensions(ng,potentialIndex);
133   //h5o->open(gid);
134   //h5desc.push_back(h5o);
135 }
136 
setObservables(PropertySetType & plist)137 void DensityEstimator::setObservables(PropertySetType& plist)
138 {
139   //std::copy(density.first_address(),density.last_address(),plist.begin()+myDebugIndex);
140 }
141 
setParticlePropertyList(PropertySetType & plist,int offset)142 void DensityEstimator::setParticlePropertyList(PropertySetType& plist, int offset)
143 {
144   //std::copy(density.first_address(),density.last_address(),plist.begin()+myDebugIndex+offset);
145 }
146 
147 /** check xml elements
148  *
149  * <estimator name="density" debug="no" delta="0.1 0.1 0.1"/>
150  */
put(xmlNodePtr cur)151 bool DensityEstimator::put(xmlNodePtr cur)
152 {
153   Delta = 0.1;
154   std::vector<double> delta;
155   std::string debug("no");
156   std::string potential("no");
157   OhmmsAttributeSet attrib;
158   attrib.add(debug, "debug");
159   attrib.add(potential, "potential");
160   attrib.add(density_min[0], "x_min");
161   attrib.add(density_min[1], "y_min");
162   attrib.add(density_min[2], "z_min");
163   attrib.add(density_max[0], "x_max");
164   attrib.add(density_max[1], "y_max");
165   attrib.add(density_max[2], "z_max");
166   attrib.add(Delta, "delta");
167   attrib.put(cur);
168   if (!Periodic)
169   {
170     for (int dim = 0; dim < OHMMS_DIM; ++dim)
171       ScaleFactor[dim] = 1.0 / (density_max[dim] - density_min[dim]);
172   }
173   resize();
174   return true;
175 }
176 
get(std::ostream & os) const177 bool DensityEstimator::get(std::ostream& os) const
178 {
179   os << myName << " bin =" << Delta << " bohrs " << std::endl;
180   return true;
181 }
182 
makeClone(ParticleSet & qp,TrialWaveFunction & psi)183 OperatorBase* DensityEstimator::makeClone(ParticleSet& qp, TrialWaveFunction& psi)
184 {
185   //default constructor is sufficient
186   return new DensityEstimator(*this);
187 }
188 
resize()189 void DensityEstimator::resize()
190 {
191   for (int i = 0; i < OHMMS_DIM; ++i)
192   {
193     DeltaInv[i] = 1.0 / Delta[i];
194     NumGrids[i] = static_cast<int>(DeltaInv[i]);
195     if (NumGrids[i] < 2)
196     {
197       APP_ABORT("DensityEstimator::resize invalid bin size");
198     }
199   }
200   app_log() << " DensityEstimator bin_size= " << NumGrids << " delta = " << Delta << std::endl;
201   NumGrids[OHMMS_DIM] = NumGrids[0] * NumGrids[1] * NumGrids[2];
202 }
203 
204 } // namespace qmcplusplus
205