QMCPACK
VirtualParticleSet.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) 2021 QMCPACK developers.
6 //
7 // File developed by: Ye Luo, yeluo@anl.gov, Argonne National Laboratory
8 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
9 //
10 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
11 //////////////////////////////////////////////////////////////////////////////////////
12 
13 
14 /** @file VirtualParticleSet.cpp
15  * A proxy class to the quantum ParticleSet
16  */
17 
18 #include "Configuration.h"
19 #include "VirtualParticleSet.h"
20 #include "Particle/DistanceTable.h"
23 #include "ResourceCollection.h"
24 
25 namespace qmcplusplus
26 {
27 
28 struct VPMultiWalkerMem : public Resource
29 {
30  /// multi walker reference particle
32 
33  VPMultiWalkerMem() : Resource("VPMultiWalkerMem") {}
34 
36 
37  std::unique_ptr<Resource> makeClone() const override { return std::make_unique<VPMultiWalkerMem>(*this); }
38 };
39 
40 VirtualParticleSet::VirtualParticleSet(const ParticleSet& p, int nptcl, size_t dt_count_limit)
41  : ParticleSet(p.getSimulationCell())
42 {
43  setName("virtual");
44 
45  //initialize local data structure
46  setSpinor(p.isSpinor());
47  TotalNum = nptcl;
48  R.resize(nptcl);
49  if (isSpinor())
50  spins.resize(nptcl);
51  coordinates_->resize(nptcl);
52 
53  //create distancetables
54  assert(dt_count_limit <= p.getNumDistTables());
55  if (dt_count_limit == 0)
56  dt_count_limit = p.getNumDistTables();
57  for (int i = 0; i < dt_count_limit; ++i)
59  addTable(p.getDistTable(i).get_origin());
60  else
62 }
63 
65 
67 {
68  return mw_mem_handle_.getResource().mw_refPctls;
69 }
70 
72 {
73  return mw_mem_handle_.getResource().mw_refPctls;
74 }
75 
77 {
78  collection.addResource(std::make_unique<VPMultiWalkerMem>());
79  ParticleSet::createResource(collection);
80 }
81 
84 {
85  auto& vp_leader = vp_list.getLeader();
86  vp_leader.mw_mem_handle_ = collection.lendResource<VPMultiWalkerMem>();
87 
88  auto p_list = RefVectorWithLeaderParticleSet(vp_list);
89  ParticleSet::acquireResource(collection, p_list);
90 }
91 
94 {
95  collection.takebackResource(vp_list.getLeader().mw_mem_handle_);
96  auto p_list = RefVectorWithLeaderParticleSet(vp_list);
97  ParticleSet::releaseResource(collection, p_list);
98 }
99 
100 
103  int id)
104 {
105  RefVectorWithLeader<const DistanceTableAB> dt_list(vp_list.getLeader().getDistTableAB(id));
106  dt_list.reserve(vp_list.size());
107  for (const VirtualParticleSet& vp : vp_list)
108  {
109  const auto& d_table = vp.getDistTableAB(id);
110  dt_list.push_back(d_table);
111  }
112  return dt_list;
113 }
114 
115 
116 const std::vector<QMCTraits::PosType> VirtualParticleSet::extractVPCoords(
118 {
119  std::vector<QMCTraits::PosType> coords_list;
120  for (const VirtualParticleSet& vp : vp_list)
121  for (int iat = 0; iat < vp.getTotalNum(); iat++)
122  coords_list.push_back(vp.R[iat]);
123 
124  return coords_list;
125 }
126 
127 
128 /// move virtual particles to new postions and update distance tables
130  int jel,
131  const std::vector<PosType>& deltaV,
132  bool sphere,
133  int iat)
134 {
135  if (sphere && iat < 0)
136  throw std::runtime_error(
137  "VirtualParticleSet::makeMoves is invoked incorrectly, the flag sphere=true requires iat specified!");
138  onSphere = sphere;
139  refPS = refp;
140  refPtcl = jel;
141  refSourcePtcl = iat;
142  assert(R.size() == deltaV.size());
143  for (size_t ivp = 0; ivp < R.size(); ivp++)
144  R[ivp] = refp.R[jel] + deltaV[ivp];
145  if (refp.isSpinor())
146  for (size_t ivp = 0; ivp < R.size(); ivp++)
147  spins[ivp] = refp.spins[jel]; //no spin deltas in this API
148  update();
149 }
150 
151 /// move virtual particles to new postions and update distance tables
153  int jel,
154  const std::vector<PosType>& deltaV,
155  const std::vector<RealType>& deltaS,
156  bool sphere,
157  int iat)
158 {
159  assert(refp.isSpinor());
160  if (sphere && iat < 0)
161  throw std::runtime_error(
162  "VirtualParticleSet::makeMovesWithSpin is invoked incorrectly, the flag sphere=true requires iat specified!");
163  onSphere = sphere;
164  refPS = refp;
165  refPtcl = jel;
166  refSourcePtcl = iat;
167  assert(R.size() == deltaV.size());
168  assert(spins.size() == deltaS.size());
169  for (size_t ivp = 0; ivp < R.size(); ivp++)
170  {
171  R[ivp] = refp.R[jel] + deltaV[ivp];
172  spins[ivp] = refp.spins[jel] + deltaS[ivp];
173  }
174  update();
175 }
176 
178  const RefVectorWithLeader<ParticleSet>& refp_list,
179  const RefVector<const std::vector<PosType>>& deltaV_list,
180  const RefVector<const NLPPJob<RealType>>& joblist,
181  bool sphere)
182 {
183  auto& vp_leader = vp_list.getLeader();
184  vp_leader.onSphere = sphere;
185  vp_leader.refPS = refp_list.getLeader();
186 
187  const size_t nVPs = countVPs(vp_list);
188  auto& mw_refPctls = vp_leader.getMultiWalkerRefPctls();
189  mw_refPctls.resize(nVPs);
190 
191  RefVectorWithLeader<ParticleSet> p_list(vp_leader);
192  p_list.reserve(vp_list.size());
193 
194  size_t ivp = 0;
195  for (int iw = 0; iw < vp_list.size(); iw++)
196  {
197  VirtualParticleSet& vp(vp_list[iw]);
198  const std::vector<PosType>& deltaV(deltaV_list[iw]);
199  const NLPPJob<RealType>& job(joblist[iw]);
200 
201  vp.onSphere = sphere;
202  vp.refPS = refp_list[iw];
203  vp.refPtcl = job.electron_id;
204  vp.refSourcePtcl = job.ion_id;
205  assert(vp.R.size() == deltaV.size());
206  for (size_t k = 0; k < vp.R.size(); k++, ivp++)
207  {
208  vp.R[k] = refp_list[iw].R[vp.refPtcl] + deltaV[k];
209  if (vp_leader.isSpinor())
210  vp.spins[k] = refp_list[iw].spins[vp.refPtcl]; //no spin deltas in this API
211  mw_refPctls[ivp] = vp.refPtcl;
212  }
213  p_list.push_back(vp);
214  }
215  assert(ivp == nVPs);
216 
217  mw_refPctls.updateTo();
218  ParticleSet::mw_update(p_list);
219 }
220 
222  const RefVectorWithLeader<ParticleSet>& refp_list,
223  const RefVector<const std::vector<PosType>>& deltaV_list,
224  const RefVector<const std::vector<RealType>>& deltaS_list,
225  const RefVector<const NLPPJob<RealType>>& joblist,
226  bool sphere)
227 {
228  auto& vp_leader = vp_list.getLeader();
229  if (!vp_leader.isSpinor())
230  throw std::runtime_error(
231  "VirtualParticleSet::mw_makeMovesWithSpin should not be called if particle sets aren't spionor types");
232  vp_leader.onSphere = sphere;
233  vp_leader.refPS = refp_list.getLeader();
234 
235  const size_t nVPs = countVPs(vp_list);
236  auto& mw_refPctls = vp_leader.getMultiWalkerRefPctls();
237  mw_refPctls.resize(nVPs);
238 
239  RefVectorWithLeader<ParticleSet> p_list(vp_leader);
240  p_list.reserve(vp_list.size());
241 
242  size_t ivp = 0;
243  for (int iw = 0; iw < vp_list.size(); iw++)
244  {
245  VirtualParticleSet& vp(vp_list[iw]);
246  const std::vector<PosType>& deltaV(deltaV_list[iw]);
247  const std::vector<RealType>& deltaS(deltaS_list[iw]);
248  const NLPPJob<RealType>& job(joblist[iw]);
249 
250  vp.onSphere = sphere;
251  vp.refPS = refp_list[iw];
252  vp.refPtcl = job.electron_id;
253  vp.refSourcePtcl = job.ion_id;
254  assert(vp.R.size() == deltaV.size());
255  assert(vp.spins.size() == deltaS.size());
256  assert(vp.R.size() == vp.spins.size());
257  for (size_t k = 0; k < vp.R.size(); k++, ivp++)
258  {
259  vp.R[k] = refp_list[iw].R[vp.refPtcl] + deltaV[k];
260  vp.spins[k] = refp_list[iw].spins[vp.refPtcl] + deltaS[k];
261  mw_refPctls[ivp] = vp.refPtcl;
262  }
263  p_list.push_back(vp);
264  }
265  assert(ivp == nVPs);
266 
267  mw_refPctls.updateTo();
268  ParticleSet::mw_update(p_list);
269 }
270 
271 } // namespace qmcplusplus
void resize(size_type n, Type_t val=Type_t())
Resize the container.
Definition: OhmmsVector.h:166
void setName(const std::string &aname)
Definition: ParticleSet.h:237
size_t addResource(std::unique_ptr< Resource > &&res, bool noprint=false)
std::optional< std::reference_wrapper< const ParticleSet > > refPS
ParticleSet this object refers to after makeMoves.
void takebackResource(ResourceHandle< RS > &res_handle)
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
std::unique_ptr< Resource > makeClone() const override
ParticleScalar spins
internal spin variables for dynamical spin calculations
Definition: ParticleSet.h:81
void createResource(ResourceCollection &collection) const
initialize a shared resource and hand it to a collection
if(c->rank()==0)
size_t TotalNum
total number of particles
Definition: ParticleSet.h:642
static void releaseResource(ResourceCollection &collection, const RefVectorWithLeader< VirtualParticleSet > &vp_list)
release external resource Note: use RAII ResourceCollectionTeamLock whenever possible ...
For distance tables of virtual particle (VP) sets constructed based on this table, whether full table is needed on host The corresponding DT of VP need to set MW_EVALUATE_RESULT_NO_TRANSFER_TO_HOST accordingly.
static void releaseResource(ResourceCollection &collection, const RefVectorWithLeader< ParticleSet > &p_list)
release external resource Note: use RAII ResourceCollectionTeamLock whenever possible ...
void makeMovesWithSpin(const ParticleSet &refp, int jel, const std::vector< PosType > &deltaV, const std::vector< RealType > &deltaS, bool sphere=false, int iat=-1)
move virtual particles to new postions and update distance tables
int refSourcePtcl
Reference source particle, used when onSphere=true.
A ParticleSet that handles virtual moves of a selected particle of a given physical ParticleSet Virtu...
void makeMoves(const ParticleSet &refp, int jel, const std::vector< PosType > &deltaV, bool sphere=false, int iat=-1)
move virtual particles to new postions and update distance tables
int getNumDistTables() const
Definition: ParticleSet.h:566
int refPtcl
Reference particle.
void createResource(ResourceCollection &collection) const
initialize a shared resource and hand it to a collection
void update(bool skipSK=false)
update the internal data
A proxy class to the quantum ParticleSet.
static void acquireResource(ResourceCollection &collection, const RefVectorWithLeader< VirtualParticleSet > &vp_list)
acquire external resource and assocaite it with the list of ParticleSet Note: use RAII ResourceCollec...
int addTable(const ParticleSet &psrc, DTModes modes=DTModes::ALL_OFF)
add a distance table
Specialized paritlce class for atomistic simulations.
Definition: ParticleSet.h:55
Vector< int, OffloadPinnedAllocator< int > > & getMultiWalkerRefPctls()
size_type size() const
return the current size
Definition: OhmmsVector.h:162
Vector< int, OffloadPinnedAllocator< int > > mw_refPctls
multi walker reference particle
ParticlePos R
Position.
Definition: ParticleSet.h:79
VPMultiWalkerMem(const VPMultiWalkerMem &)
static const std::vector< QMCTraits::PosType > extractVPCoords(const RefVectorWithLeader< const VirtualParticleSet > &vp_list)
Extract list of VP coordinates, flattened over all walkers.
static void mw_makeMoves(const RefVectorWithLeader< VirtualParticleSet > &vp_list, const RefVectorWithLeader< ParticleSet > &p_list, const RefVector< const std::vector< PosType >> &deltaV_list, const RefVector< const NLPPJob< RealType >> &joblist, bool sphere)
VirtualParticleSet(const ParticleSet &p, int nptcl, size_t dt_count_limit=0)
constructor
auto & getDistTable(int table_ID) const
get a distance table by table_ID
Definition: ParticleSet.h:190
static void acquireResource(ResourceCollection &collection, const RefVectorWithLeader< ParticleSet > &p_list)
acquire external resource and assocaite it with the list of ParticleSet Note: use RAII ResourceCollec...
std::unique_ptr< DynamicCoordinates > coordinates_
internal representation of R. It can be an SoA copy of R
Definition: ParticleSet.h:648
static void mw_makeMovesWithSpin(const RefVectorWithLeader< VirtualParticleSet > &vp_list, const RefVectorWithLeader< ParticleSet > &p_list, const RefVector< const std::vector< PosType >> &deltaV_list, const RefVector< const std::vector< RealType >> &deltaS_list, const RefVector< const NLPPJob< RealType >> &joblist, bool sphere)
std::vector< std::reference_wrapper< T > > RefVector
const int electron_id
Definition: NLPPJob.h:31
static RefVectorWithLeader< ParticleSet > RefVectorWithLeaderParticleSet(const RefVectorWithLeader< VirtualParticleSet > &vp_list)
static void mw_update(const RefVectorWithLeader< ParticleSet > &p_list, bool skipSK=false)
batched version of update
meta data for NLPP calculation of a pair of ion and electron This is not just meta data...
static size_t countVPs(const RefVectorWithLeader< const VirtualParticleSet > &vp_list)
ResourceHandle< RS > lendResource()
void setSpinor(bool is_spinor)
Definition: ParticleSet.h:257
const int ion_id
Definition: NLPPJob.h:30
bool onSphere
true, if virtual particles are on a sphere for NLPP
ResourceHandle< VPMultiWalkerMem > mw_mem_handle_
multi walker resource
static const RefVectorWithLeader< const DistanceTableAB > extractDTRefList(const RefVectorWithLeader< const VirtualParticleSet > &vp_list, int id)
Extract list of Distance Tables.
skip data transfer back to host after mw_evalaute full distance table.