QMCPACK
StressPBC.cpp
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) 2020 QMCPACK developers
6 //
7 // File developed by: Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
8 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
9 // Yubo Paul Yang, yyang173@illinois.edu, University of Illinois Urbana-Champaign
10 //
11 // File created by: Raymond Clay III, j.k.rofling@gmail.com, Lawrence Livermore National Laboratory
12 //////////////////////////////////////////////////////////////////////////////////////
13 
14 
15 #include "StressPBC.h"
16 #include "DistanceTable.h"
17 #include "Message/Communicate.h"
21 #include "OhmmsData/ParameterSet.h"
22 #include "OhmmsData/AttributeSet.h"
25 
26 namespace qmcplusplus
27 {
29  : ForceBase(ions, elns),
30  Psi(Psi0),
31  PtclTarg(elns),
32  PtclA(ions),
33  ei_table_index(elns.addTable(ions)),
34  ee_table_index(elns.addTable(elns)),
35  ii_table_index(ions.addTable(ions)),
36  firstTimeStress(true)
37 {
38  ReportEngine PRE("StressPBC", "StressPBC");
39  name_ = "StressPBC";
40  prefix_ = "StressPBC";
41  //This sets up the long range breakups.
43  stress_eI_const = 0.0;
44  stress_ee_const = 0.0;
45  if (firstTimeStress)
46  { // calculate constants
48  firstTimeStress = false;
49  }
50  RealType vinv = -1. / PtclTarg.getLattice().Volume;
51  app_log() << "\n====ion-ion stress ====\n" << stress_ion_ion_ * vinv << std::endl;
52  app_log() << "\n e-e const = " << stress_ee_const * vinv << std::endl;
53  app_log() << "\n e-I const = " << stress_eI_const * vinv << std::endl;
54 }
55 
57 {
58  SpeciesSet& tspeciesA(PtclA.getSpeciesSet());
59  SpeciesSet& tspeciesB(P.getSpeciesSet());
60  int ChargeAttribIndxA = tspeciesA.addAttribute("charge");
61  int ChargeAttribIndxB = tspeciesB.addAttribute("charge");
63  NptclB = P.getTotalNum();
64  NumSpeciesA = tspeciesA.TotalNum;
65  NumSpeciesB = tspeciesB.TotalNum;
66  //Store information about charges and number of each species
67  Zat.resize(NptclA);
68  Zspec.resize(NumSpeciesA);
69  Qat.resize(NptclB);
70  Qspec.resize(NumSpeciesB);
71  NofSpeciesA.resize(NumSpeciesA);
72  NofSpeciesB.resize(NumSpeciesB);
73  for (int spec = 0; spec < NumSpeciesA; spec++)
74  {
75  Zspec[spec] = tspeciesA(ChargeAttribIndxA, spec);
76  NofSpeciesA[spec] = PtclA.groupsize(spec);
77  }
78  for (int spec = 0; spec < NumSpeciesB; spec++)
79  {
80  Qspec[spec] = tspeciesB(ChargeAttribIndxB, spec);
81  NofSpeciesB[spec] = P.groupsize(spec);
82  }
83 
84  for (int spec = 0; spec < NumSpeciesA; spec++) {}
85  for (int iat = 0; iat < NptclA; iat++)
86  Zat[iat] = Zspec[PtclA.GroupID[iat]];
87  for (int iat = 0; iat < NptclB; iat++)
88  Qat[iat] = Qspec[P.GroupID[iat]];
89 
91 }
92 
94 {
96  const StructFact& RhoKA(PtclA.getSK());
97  const StructFact& RhoKB(P.getSK());
98 
99  for (int i = 0; i < NumSpeciesA; i++)
100  {
102  esum = 0.0;
103  for (int j = 0; j < NumSpeciesB; j++)
104  esum += Qspec[j] *
105  AA->evaluateStress(P.getSimulationCell().getKLists().kshell, RhoKA.rhok_r[i], RhoKA.rhok_i[i],
106  RhoKB.rhok_r[j], RhoKB.rhok_i[j]);
107  res += Zspec[i] * esum;
108  }
109 
110  return res;
111 }
112 
114 {
115  const auto& d_ab = P.getDistTableAB(ei_table_index);
117  //Loop over distinct eln-ion pairs
118  for (int jpart = 0; jpart < NptclB; jpart++)
119  {
120  const auto& drijs = d_ab.getDisplRow(jpart);
121  const auto& rijs = d_ab.getDistRow(jpart);
122  const RealType e = Qat[jpart];
123  for (int iat = 0; iat < NptclA; iat++)
124  {
125  res += Zat[iat] * e * AA->evaluateSR_dstrain(drijs[iat], rijs[iat]);
126  }
127  }
128  return res;
129 }
130 
132 {
133  const auto& d_aa = P.getDistTableAA(itabSelf);
134 
136  for (int ipart = 0; ipart < NptclB; ipart++)
137  {
139  const auto& drijs = d_aa.getDisplRow(ipart);
140  const auto& rijs = d_aa.getDistRow(ipart);
141  for (int jpart = 0; jpart < ipart; jpart++)
142  {
143  esum += P.Z[jpart] * AA->evaluateSR_dstrain(drijs[jpart], rijs[jpart]);
144  }
145  stress_aa += P.Z[ipart] * esum;
146  }
147 
148  return stress_aa;
149 }
150 
152 {
153  int NumSpecies = P.getSpeciesSet().TotalNum;
155  const StructFact& PtclRhoK(P.getSK());
156  int ChargeAttribIndx = P.getSpeciesSet().getAttribute("charge");
157 
158  std::vector<int> NofSpecies;
159  std::vector<int> Zmyspec;
160  NofSpecies.resize(NumSpecies);
161  Zmyspec.resize(NumSpecies);
162 
163  for (int spec = 0; spec < NumSpecies; spec++)
164  {
165  Zmyspec[spec] = P.getSpeciesSet()(ChargeAttribIndx, spec);
166  NofSpecies[spec] = P.groupsize(spec);
167  }
168 
170  for (int spec1 = 0; spec1 < NumSpecies; spec1++)
171  {
172  RealType Z1 = Zmyspec[spec1];
173  for (int spec2 = spec1; spec2 < NumSpecies; spec2++)
174  {
176  AA->evaluateStress(P.getSimulationCell().getKLists().kshell, PtclRhoK.rhok_r[spec1], PtclRhoK.rhok_i[spec1],
177  PtclRhoK.rhok_r[spec2], PtclRhoK.rhok_i[spec2]);
178  if (spec2 == spec1)
179  temp *= 0.5;
180  stress_aa += Z1 * Zmyspec[spec2] * temp;
181  } //spec2
182  } //spec1
183 
184  return stress_aa;
185 }
186 
188 {
189  int nelns = PtclTarg.getTotalNum();
190  int nions = PtclA.getTotalNum();
191 
193 
194  SymTensor<mRealType, OHMMS_DIM> Consts = 0.0;
195  SymTensor<mRealType, OHMMS_DIM> vs_k0 = AA->evaluateSR_k0_dstrain();
196  mRealType v1; //single particle energy
197  for (int i = 0; i < nelns; ++i)
198  {
199  v1 = 0.0;
200  for (int s = 0; s < NumSpeciesA; s++)
201  v1 += NofSpeciesA[s] * Zspec[s];
202  Consts += -.5 * Qat[i] * vs_k0 * v1;
203  }
204  for (int i = 0; i < nions; ++i)
205  {
206  v1 = 0.0;
207  for (int s = 0; s < NumSpeciesB; s++)
208  v1 += NofSpeciesB[s] * Qspec[s];
209  Consts += -.5 * Zat[i] * vs_k0 * v1;
210  }
211 
212  return SymTensor<RealType, OHMMS_DIM>(Consts);
213 }
214 
216 {
217  SymTensor<RealType, OHMMS_DIM> tmpconsts = 0.0; // constant term
218 
219  int NumSpecies = P.getSpeciesSet().TotalNum;
220  int NumCenters = P.getTotalNum();
221  RealType v1; //single particle energy
222 
223  int ChargeAttribIndx = P.getSpeciesSet().getAttribute("charge");
224 
225  std::vector<int> NofSpecies;
226  std::vector<int> Zmyspec;
227  NofSpecies.resize(NumSpecies);
228  Zmyspec.resize(NumSpecies);
229 
230  for (int spec = 0; spec < NumSpecies; spec++)
231  {
232  Zmyspec[spec] = P.getSpeciesSet()(ChargeAttribIndx, spec);
233  NofSpecies[spec] = P.groupsize(spec);
234  }
235 
236  SymTensor<RealType, OHMMS_DIM> vl_r0 = AA->evaluateLR_r0_dstrain();
237  for (int ipart = 0; ipart < NumCenters; ipart++)
238  {
239  tmpconsts += -.5 * P.Z[ipart] * P.Z[ipart] * vl_r0;
240  }
241  // if(report)
242  app_log() << " PBCAA self-interaction term \n" << tmpconsts << std::endl;
243  //Compute Madelung constant: this is not correct for general cases
245  for (int ks = 0; ks < AA->Fk.size(); ks++)
246  MC0 += AA->dFk_dstrain[ks];
247  MC0 = 0.5 * (MC0 - vl_r0);
248  //Neutraling background term
249  SymTensor<RealType, OHMMS_DIM> vs_k0 = AA->evaluateSR_k0_dstrain(); //v_s(k=0)
250  for (int ipart = 0; ipart < NumCenters; ipart++)
251  {
252  v1 = 0.0;
253  for (int spec = 0; spec < NumSpecies; spec++)
254  v1 += -.5 * P.Z[ipart] * NofSpecies[spec] * Zmyspec[spec];
255  tmpconsts += v1 * vs_k0;
256  }
257  // if(report)
258  app_log() << " PBCAA total constant \n" << tmpconsts << std::endl;
259  return tmpconsts;
260 }
261 
263 {
264  const RealType vinv(-1.0 / P.getLattice().Volume);
265  stress_ = 0.0;
266  stress_ee_ = 0.0;
267  stress_ei_ = 0.0;
268  stress_kin_ = 0.0;
269 
270  stress_ei_ += vinv * evaluateLR_AB(PtclTarg);
271  stress_ei_ += vinv * evaluateSR_AB(PtclTarg);
272  stress_ei_ += vinv * stress_eI_const;
273 
274  stress_ee_ += vinv * evaluateLR_AA(PtclTarg);
276  stress_ee_ += vinv * stress_ee_const;
277 
278 
280 
282  if (add_ion_ion_)
283  stress_ += vinv * stress_ion_ion_;
284 
285  return 0.0;
286 }
287 
289 {
290  WaveFunctionComponent::HessVector grad_grad_psi;
291  Psi.evaluateHessian(P, grad_grad_psi);
292  SymTensor<RealType, OHMMS_DIM> kinetic_tensor;
293  Tensor<ComplexType, OHMMS_DIM> complex_ktensor;
294 
295  for (int iat = 0; iat < P.getTotalNum(); iat++)
296  {
297  const RealType minv(1.0 / P.Mass[iat]);
298  complex_ktensor += outerProduct(P.G[iat], P.G[iat]) * static_cast<ParticleSet::SingleParticleValue>(minv);
299  complex_ktensor += grad_grad_psi[iat] * minv;
300  }
301 
302  for (int i = 0; i < OHMMS_DIM; i++)
303  for (int j = i; j < OHMMS_DIM; j++)
304  {
305  kinetic_tensor(i, j) = complex_ktensor(i, j).real();
306  }
307  return kinetic_tensor;
308 }
309 
310 bool StressPBC::put(xmlNodePtr cur)
311 {
312  std::string ionionforce("yes");
313  OhmmsAttributeSet attr;
314  attr.add(prefix_, "name");
315  attr.add(ionionforce, "add_ion_ion_");
316  attr.put(cur);
317  add_ion_ion_ = (ionionforce == "yes") || (ionionforce == "true");
318  app_log() << "add ion-ion stress = " << add_ion_ion_ << std::endl;
319  return true;
320 }
321 
322 std::unique_ptr<OperatorBase> StressPBC::makeClone(ParticleSet& qp, TrialWaveFunction& psi)
323 {
324  std::unique_ptr<StressPBC> tmp = std::make_unique<StressPBC>(PtclA, qp, psi);
325  tmp->firstTimeStress = firstTimeStress;
326  tmp->stress_ion_ion_ = stress_ion_ion_;
327  tmp->stress_ee_const = stress_ee_const;
328  tmp->stress_eI_const = stress_eI_const;
329  tmp->add_ion_ion_ = add_ion_ion_;
330  return tmp;
331 }
332 } // namespace qmcplusplus
static std::unique_ptr< LRHandlerType > getDerivHandler(ParticleSet &ref)
This returns a force/stress optimized LR handler. If non existent, it creates one.
std::unique_ptr< OperatorBase > makeClone(ParticleSet &qp, TrialWaveFunction &psi) final
Definition: StressPBC.cpp:322
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
const DistanceTableAA & getDistTableAA(int table_ID) const
get a distance table by table_ID and dyanmic_cast to DistanceTableAA
int NumSpeciesB
number of species of B particle set
Definition: StressPBC.h:47
SymTensor< Real, OHMMS_DIM > stress_ee_
Definition: ForceBase.h:91
size_t getTotalNum() const
Definition: ParticleSet.h:493
void evaluateHessian(ParticleSet &P, HessVector &all_grad_grad_psi)
evaluate the hessian w.r.t.
std::ostream & app_log()
Definition: OutputManager.h:65
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
EwaldHandler3D::mRealType mRealType
SymTensor< RealType, OHMMS_DIM > evaluateSR_AB(ParticleSet &P_target)
Definition: StressPBC.cpp:113
std::vector< int > NofSpeciesA
number of particles per species of A
Definition: StressPBC.h:54
SymTensor< RealType, OHMMS_DIM > evaluateKineticSymTensor(ParticleSet &P)
Definition: StressPBC.cpp:288
SymTensor< RealType, OHMMS_DIM > stress_eI_const
Definition: StressPBC.h:29
int NptclA
number of particles of A (classical, e.g. ions)
Definition: StressPBC.h:49
Calculates the structure-factor for a particle set.
Definition: StructFact.h:39
std::string prefix_
Definition: ForceBase.h:96
int addAttribute(const std::string &aname)
for a new attribute, allocate the data, !More often used to get the index of a species ...
Definition: SpeciesSet.cpp:45
QTFull::ValueType SingleParticleValue
Definition: Configuration.h:97
#define OHMMS_DIM
Definition: config.h:64
SymTensor< Real, OHMMS_DIM > stress_kin_
Definition: ForceBase.h:93
ParticleIndex GroupID
Species ID.
Definition: ParticleSet.h:77
for(int i=0;i< size_test;++i) CHECK(Approx(gauss_random_vals[offset_for_rs+i])
const DistanceTableAB & getDistTableAB(int table_ID) const
get a distance table by table_ID and dyanmic_cast to DistanceTableAB
SymTensor< RealType, OHMMS_DIM > stress_ee_const
Definition: StressPBC.h:28
int NumSpeciesA
number of species of A particle set
Definition: StressPBC.h:45
std::vector< RealType > Zat
Zat[iat] charge for the iat-th particle of A.
Definition: StressPBC.h:58
const auto & getSimulationCell() const
Definition: ParticleSet.h:250
std::string name_
name of this object
Definition: OperatorBase.h:527
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
bool add_ion_ion_
Determines if ion-ion force will be added to electron-ion force in derived force estimators. If false, forces_ion_ion_=0.0.
Definition: ForceBase.h:84
ParticleSet & PtclA
Definition: StressPBC.h:36
Tensor<T,D> class for D by D tensor.
Definition: OhmmsTinyMeta.h:32
Final class and should not be derived.
std::vector< RealType > Qat
Qat[iat] charge for the iat-th particle of B.
Definition: StressPBC.h:60
Tensor< typename BinaryReturn< T1, T2, OpMultiply >::Type_t, D > outerProduct(const TinyVector< T1, D > &lhs, const TinyVector< T2, D > &rhs)
Definition: TinyVector.h:211
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
std::vector< RealType > Zspec
Zspec[spec] charge for the spec-th species of A.
Definition: StressPBC.h:62
std::unique_ptr< LRHandlerType > AA
long-range Handler
Definition: StressPBC.h:38
declaration of ProgressReportEngine
ParticleGradient G
gradients of the particles
Definition: ParticleSet.h:83
Return_t evaluate(ParticleSet &P) override
Evaluate the local energy contribution of this component.
Definition: StressPBC.cpp:262
int groupsize(int igroup) const
return the size of a group
Definition: ParticleSet.h:527
ParticleSet & PtclTarg
source particle set
Definition: StressPBC.h:35
TrialWaveFunction & Psi
Definition: StressPBC.h:32
void initBreakup(ParticleSet &P)
Definition: StressPBC.cpp:56
SymTensor< RealType, OHMMS_DIM > evaluateSR_AA(ParticleSet &P, int itabSelf)
Definition: StressPBC.cpp:131
SymTensor< RealType, OHMMS_DIM > evaluateLR_AB(ParticleSet &P)
Definition: StressPBC.cpp:93
const StructFact & getSK() const
return Structure Factor
Definition: ParticleSet.h:216
std::vector< RealType > Qspec
Qspec[spec] charge for the spec-th species of B.
Definition: StressPBC.h:64
StressPBC(ParticleSet &ions, ParticleSet &elns, TrialWaveFunction &Psi)
Definition: StressPBC.cpp:28
bool put(xmlNodePtr cur) override
Read the input parameter.
Definition: StressPBC.cpp:310
SymTensor< RealType, OHMMS_DIM > evalConsts_AB()
Definition: StressPBC.cpp:187
ParticleScalar Z
charge of each particle
Definition: ParticleSet.h:89
std::vector< int > NofSpeciesB
number of particles per species of B
Definition: StressPBC.h:56
SpeciesSet & getSpeciesSet()
retrun the SpeciesSet of this particle set
Definition: ParticleSet.h:231
Declaration of a TrialWaveFunction.
FullPrecRealType Return_t
type of return value of evaluate
Definition: OperatorBase.h:64
Define determinant operators.
Class to represent a many-body trial wave function.
int getAttribute(const std::string &aname) const
When a name species does not exist, return attribute.size()
Definition: SpeciesSet.cpp:60
ParticleScalar Mass
mass of each particle
Definition: ParticleSet.h:87
SymTensor< Real, OHMMS_DIM > stress_ion_ion_
Definition: ForceBase.h:90
SymTensor< Real, OHMMS_DIM > stress_
Definition: ForceBase.h:94
const auto & getLattice() const
Definition: ParticleSet.h:251
OrbitalSetTraits< ValueType >::HessVector HessVector
int NptclB
number of particles of B (quantum, e.g. electrons)
Definition: StressPBC.h:51
Declaration of WaveFunctionComponent.
Custom container for set of attributes for a set of species.
Definition: SpeciesSet.h:33
SymTensor< RealType, OHMMS_DIM > evaluateLR_AA(ParticleSet &P)
Definition: StressPBC.cpp:151
void CalculateIonIonStress()
Definition: StressPBC.h:105
SymTensor< Real, OHMMS_DIM > stress_ei_
Definition: ForceBase.h:92
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
const int ee_table_index
e-e table ID
Definition: StressPBC.h:42
SymTensor< RealType, OHMMS_DIM > evalConsts_AA(ParticleSet &P)
Definition: StressPBC.cpp:215
unsigned TotalNum
The number of species.
Definition: SpeciesSet.h:41
const int ei_table_index
locator of the distance table
Definition: StressPBC.h:40