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