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