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: John R. Gergely, University of Illinois at Urbana-Champaign
8 // Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
9 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
10 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
11 // Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
12 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
13 //
14 // File created by: John R. Gergely, University of Illinois at Urbana-Champaign
15 //////////////////////////////////////////////////////////////////////////////////////
16
17
18 #include "ForceBase.h"
19 #include "Particle/DistanceTableData.h"
20 #include "Message/Communicate.h"
21 #include "Utilities/ProgressReportEngine.h"
22 #include "Numerics/MatrixOperators.h"
23 #include "Numerics/DeterminantOperators.h"
24 #include "OhmmsData/AttributeSet.h"
25
26
27 namespace qmcplusplus
28 {
ForceBase(ParticleSet & ions,ParticleSet & elns)29 ForceBase::ForceBase(ParticleSet& ions, ParticleSet& elns) : FirstForceIndex(-1), tries(0), addionion(true), Ions(ions)
30 {
31 ReportEngine PRE("ForceBase", "ForceBase");
32 FirstTime = true;
33 Nnuc = ions.getTotalNum();
34 Nel = elns.getTotalNum();
35 //Determines if ion-ion force will be added to electron-ion force in derived force estimators.
36 //If false, forces_IonIon=0.0 .
37 addionion = true;
38 pairName = elns.getName() + "-" + ions.getName();
39 forces.resize(Nnuc);
40 forces = 0.0;
41 forces_IonIon.resize(Nnuc);
42 forces_IonIon = 0.0;
43 }
44
addObservablesF(QMCTraits::PropertySetType & plist)45 void ForceBase::addObservablesF(QMCTraits::PropertySetType& plist)
46 {
47 if (FirstForceIndex < 0)
48 FirstForceIndex = plist.size();
49 for (int iat = 0; iat < Nnuc; iat++)
50 {
51 for (int x = 0; x < OHMMS_DIM; x++)
52 {
53 std::ostringstream obsName;
54 obsName << prefix << "_" << iat << "_" << x;
55 plist.add(obsName.str());
56 }
57 }
58 }
59
addObservablesStress(QMCTraits::PropertySetType & plist)60 void ForceBase::addObservablesStress(QMCTraits::PropertySetType& plist)
61 {
62 if (FirstForceIndex < 0)
63 FirstForceIndex = plist.size();
64 for (int i = 0; i < OHMMS_DIM; i++)
65 for (int j = i; j < OHMMS_DIM; j++)
66 {
67 std::ostringstream obsName;
68 obsName << prefix << "_" << i << "_" << j;
69 plist.add(obsName.str());
70 }
71 }
72
registerObservablesF(std::vector<observable_helper * > & h5list,hid_t gid) const73 void ForceBase::registerObservablesF(std::vector<observable_helper*>& h5list, hid_t gid) const
74 {
75 std::vector<int> ndim(2);
76 ndim[0] = Nnuc;
77 ndim[1] = OHMMS_DIM;
78 observable_helper* h5o = new observable_helper(prefix);
79 h5o->set_dimensions(ndim, FirstForceIndex);
80 h5o->open(gid);
81 h5list.push_back(h5o);
82 }
83
setObservablesF(QMCTraits::PropertySetType & plist)84 void ForceBase::setObservablesF(QMCTraits::PropertySetType& plist)
85 {
86 int index = FirstForceIndex;
87 for (int iat = 0; iat < Nnuc; iat++)
88 {
89 for (int x = 0; x < OHMMS_DIM; x++)
90 {
91 plist[index] = forces[iat][x];
92 index++;
93 }
94 }
95 }
96
setObservablesStress(QMCTraits::PropertySetType & plist)97 void ForceBase::setObservablesStress(QMCTraits::PropertySetType& plist)
98 {
99 int index = FirstForceIndex;
100 for (int iat = 0; iat < OHMMS_DIM; iat++)
101 {
102 for (int jat = iat; jat < OHMMS_DIM; jat++)
103 {
104 plist[index] = stress(iat, jat);
105 index++;
106 }
107 }
108 }
109
110
setParticleSetF(QMCTraits::PropertySetType & plist,int offset)111 void ForceBase::setParticleSetF(QMCTraits::PropertySetType& plist, int offset)
112 {
113 int index = FirstForceIndex + offset;
114 for (int iat = 0; iat < Nnuc; iat++)
115 {
116 for (int x = 0; x < OHMMS_DIM; x++)
117 {
118 plist[index] = forces[iat][x];
119 index++;
120 }
121 }
122 }
123
setParticleSetStress(QMCTraits::PropertySetType & plist,int offset)124 void ForceBase::setParticleSetStress(QMCTraits::PropertySetType& plist, int offset)
125 {
126 int index = FirstForceIndex + offset;
127 for (int iat = 0; iat < OHMMS_DIM; iat++)
128 {
129 for (int jat = iat; jat < OHMMS_DIM; jat++)
130 {
131 plist[index] = stress(iat, jat);
132 index++;
133 }
134 }
135 }
136
BareForce(ParticleSet & ions,ParticleSet & elns)137 BareForce::BareForce(ParticleSet& ions, ParticleSet& elns) : ForceBase(ions, elns), d_ei_ID(elns.addTable(ions))
138 {
139 myName = "HF_Force_Base";
140 prefix = "HFBase";
141 }
142
resetTargetParticleSet(ParticleSet & P)143 void BareForce::resetTargetParticleSet(ParticleSet& P) {}
144
makeClone(ParticleSet & qp,TrialWaveFunction & psi)145 OperatorBase* BareForce::makeClone(ParticleSet& qp, TrialWaveFunction& psi) { return new BareForce(*this); }
146
addObservables(PropertySetType & plist,BufferType & collectables)147 void BareForce::addObservables(PropertySetType& plist, BufferType& collectables)
148 {
149 addObservablesF(plist);
150 myIndex = FirstForceIndex;
151 }
152
evaluate(ParticleSet & P)153 BareForce::Return_t BareForce::evaluate(ParticleSet& P)
154 {
155 forces = forces_IonIon;
156 const auto& d_ab = P.getDistTable(d_ei_ID);
157 const ParticleSet::Scalar_t* restrict Zat = Ions.Z.first_address();
158 const ParticleSet::Scalar_t* restrict Qat = P.Z.first_address();
159 //Loop over distinct eln-ion pairs
160 for (int jat = 0; jat < d_ab.targets(); jat++)
161 {
162 const auto& ab_dist = d_ab.getDistRow(jat);
163 const auto& ab_displ = d_ab.getDisplRow(jat);
164 for (int iat = 0; iat < d_ab.sources(); iat++)
165 {
166 real_type rinv = 1.0 / ab_dist[iat];
167 real_type r3zz = Qat[jat] * Zat[iat] * rinv * rinv * rinv;
168 forces[iat] += r3zz * ab_displ[iat];
169 }
170 }
171 tries++;
172 return 0.0;
173 }
174
put(xmlNodePtr cur)175 bool BareForce::put(xmlNodePtr cur)
176 {
177 std::string ionionforce("yes");
178 OhmmsAttributeSet attr;
179 attr.add(prefix, "name");
180 attr.add(ionionforce, "addionion");
181 attr.put(cur);
182 addionion = (ionionforce == "yes" || ionionforce == "true");
183 return true;
184 }
185
InitVarReduction(real_type rcut,int _m,int numFuncs)186 void ForceBase::InitVarReduction(real_type rcut, int _m, int numFuncs)
187 {
188 m = _m;
189 Rcut = rcut;
190 std::vector<real_type> h(numFuncs);
191 Matrix<real_type> S(numFuncs, numFuncs);
192 ck.resize(numFuncs, 0.0);
193 real_type R2jp1 = Rcut * Rcut;
194 real_type R2m = 1.0;
195 for (int i = 0; i < m; i++)
196 R2m *= Rcut;
197 for (int j = 1; j <= numFuncs; j++)
198 {
199 h[j - 1] = R2jp1 / real_type(j + 1);
200 real_type R2k = Rcut;
201 for (int k = 1; k <= numFuncs; k++)
202 {
203 S(k - 1, j - 1) = R2m * R2k * R2jp1 / (real_type)(m + k + j + 1);
204 S(k - 1, j - 1) = std::pow(Rcut, (m + k + j + 1)) / (m + k + j + 1.0);
205 R2k *= Rcut;
206 }
207 R2jp1 *= Rcut;
208 }
209 // fprintf (stderr, "Sij = \n");
210 // for (int i=0; i<numFuncs; i++) {
211 // for (int j=0; j<numFuncs; j++)
212 // fprintf (stderr, " %12.6f ", S(i,j));
213 // fprintf (stderr, "\n");
214 // }
215 invert_matrix(S, false);
216 for (int i = 0; i < numFuncs; i++)
217 {
218 for (int j = 0; j < numFuncs; j++)
219 ck[i] += S(i, j) * h[j];
220 }
221 FILE* fout = fopen("g_r.dat", "w");
222 for (double r = 0.0; r < Rcut; r += 0.001)
223 fprintf(fout, "%1.10f %1.10e\n", r, g(r));
224 fclose(fout);
225 app_log() << "Initialized variance reduction coefs.\n";
226 }
227
228 } // namespace qmcplusplus
229