QMCPACK
InitMolecularSystem Class Reference
+ Inheritance diagram for InitMolecularSystem:
+ Collaboration diagram for InitMolecularSystem:

Public Member Functions

 InitMolecularSystem (ParticleSetPool &pset, const char *aname="mosystem")
 
bool get (std::ostream &os) const override
 write to a std::ostream More...
 
bool put (std::istream &is) override
 read from std::istream More...
 
bool put (xmlNodePtr cur) override
 read from an xmlNode More...
 
void reset () override
 reset member data More...
 
void initAtom (ParticleSet *ions, ParticleSet *els)
 initialize els for an atom More...
 
void initMolecule (ParticleSet *ions, ParticleSet *els)
 initialize els position for a molecule More...
 
void initWithVolume (ParticleSet *ions, ParticleSet *els)
 initialize els for the systems with a mixed boundary More...
 
- Public Member Functions inherited from OhmmsElementBase
 OhmmsElementBase (const char *aname="none")
 constructor with a name More...
 
virtual ~OhmmsElementBase ()
 destructor More...
 
const std::string & getName () const
 return the name More...
 
void setName (const std::string &aname)
 set name More...
 
void setIOMode (int imode)
 set iomode More...
 
virtual bool add (xmlNodePtr parent)
 add a xmlNode to the children list of parent More...
 
void put (const std::string &s)
 read from string More...
 
virtual void begin_node (std::ostream &os) const
 write the start of a node More...
 
virtual void end_node (std::ostream &os) const
 write the end of a node More...
 

Private Attributes

ParticleSetPoolptclPool
 pointer to ParticleSetPool More...
 

Additional Inherited Members

- Public Types inherited from OhmmsElementBase
enum  { useLIBXML = 0, useLIBXMLPP, usePLAIN }
 enumeration to choose the xml parser More...
 
- Protected Attributes inherited from OhmmsElementBase
int myIOMode
 the type of IO mode: default is useLIBXML More...
 
std::string myName
 the name of the node, corresponds to the xml tag More...
 

Detailed Description

Definition at line 30 of file InitMolecularSystem.h.

Constructor & Destructor Documentation

◆ InitMolecularSystem()

InitMolecularSystem ( ParticleSetPool pset,
const char *  aname = "mosystem" 
)

Definition at line 32 of file InitMolecularSystem.cpp.

33  : OhmmsElementBase(aname), ptclPool(pset)
34 {}
OhmmsElementBase(const char *aname="none")
constructor with a name
ParticleSetPool & ptclPool
pointer to ParticleSetPool

Member Function Documentation

◆ get()

bool get ( std::ostream &  ) const
overridevirtual

write to a std::ostream

Implements OhmmsElementBase.

Definition at line 272 of file InitMolecularSystem.cpp.

272 { return true; }

◆ initAtom()

void initAtom ( ParticleSet ions,
ParticleSet els 
)

initialize els for an atom

Definition at line 73 of file InitMolecularSystem.cpp.

References ParticleSet::getTotalNum(), qmcplusplus::makeGaussRandom(), ParticleSet::R, and qmcplusplus::sqrt().

Referenced by InitMolecularSystem::initMolecule().

74 {
75  //3N-dimensional Gaussian
76  ParticleSet::ParticlePos chi(els->getTotalNum());
77  makeGaussRandom(chi);
78  RealType q = std::sqrt(static_cast<RealType>(els->getTotalNum())) * 0.5;
79  int nel(els->getTotalNum()), items(0);
80  while (nel)
81  {
82  els->R[items] = ions->R[0] + q * chi[items];
83  --nel;
84  ++items;
85  }
86 }
void makeGaussRandom(std::vector< TinyVector< T, D >> &a)
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
QMCTraits::RealType RealType
ParticleAttrib< SingleParticlePos > ParticlePos
Definition: Configuration.h:92

◆ initMolecule()

void initMolecule ( ParticleSet ions,
ParticleSet els 
)

initialize els position for a molecule

Use the valence of each ionic species on a sphere

Definition at line 95 of file InitMolecularSystem.cpp.

References ParticleSet::addTable(), ParticleSet::applyBC(), qmcplusplus::Cartesian, ParticleSet::first(), DistanceTableAA::getDistances(), ParticleSet::getDistTableAA(), ParticleSet::getLattice(), ParticleSet::getSpeciesSet(), ParticleSet::getTotalNum(), ParticleSet::GroupID, ParticleSet::groups(), InitMolecularSystem::initAtom(), ParticleSet::last(), qmcplusplus::makeSphereRandom(), omptarget::min(), ParticleSet::R, qmcplusplus::SUPERCELL_OPEN, and ParticleSet::update().

Referenced by InitMolecularSystem::put().

96 {
97  if (ions->getTotalNum() == 1)
98  return initAtom(ions, els);
99 
100  const int d_ii_ID = ions->addTable(*ions);
101  ions->update();
102  const ParticleSet::ParticleIndex& grID(ions->GroupID);
103  SpeciesSet& Species(ions->getSpeciesSet());
104  int Centers = ions->getTotalNum();
105  std::vector<int> Qtot(Centers), Qcore(Centers), Qval(Centers, 0);
106  //use charge as the core electrons first
107  int icharge = Species.addAttribute("charge");
108  //Assign default core charge
109  for (int iat = 0; iat < Centers; iat++)
110  Qtot[iat] = static_cast<int>(Species(icharge, grID[iat]));
111  //cutoff radius (Bohr) this a random choice
112  RealType cutoff = 4.0;
113  ParticleSet::ParticlePos chi(els->getTotalNum());
114  //makeGaussRandom(chi);
115  makeSphereRandom(chi);
116  // the upper limit of the electron index with spin up
117  const int numUp = els->last(0);
118  // the upper limit of the electron index with spin down. Pay attention to the no spin down electron case.
119  const int numDown = els->last(els->groups() > 1 ? 1 : 0) - els->first(0);
120  // consumer counter of random numbers chi
121  int random_number_counter = 0;
122  int nup_tot = 0, ndown_tot = numUp;
123  std::vector<LoneElectron> loneQ;
124  RealType rmin = cutoff;
126 
127  const auto& dist = ions->getDistTableAA(d_ii_ID).getDistances();
128  // Step 1. Distribute even Q[iat] of atomic center iat. If Q[iat] is odd, put Q[iat]-1 and save the lone electron.
129  for (size_t iat = 0; iat < Centers; iat++)
130  {
131  cm += ions->R[iat];
132  for (size_t jat = iat + 1; jat < Centers; ++jat)
133  {
134  rmin = std::min(rmin, dist[jat][iat]);
135  }
136  //use 40% of the minimum bond
137  RealType sep = rmin * 0.4;
138  int v2 = Qtot[iat] / 2;
139  if (Qtot[iat] > v2 * 2)
140  {
141  loneQ.push_back(LoneElectron(iat, sep));
142  }
143  for (int k = 0; k < v2; k++)
144  {
145  // initialize electron positions in pairs
146  if (nup_tot < numUp)
147  els->R[nup_tot++] = ions->R[iat] + sep * chi[random_number_counter++];
148  if (ndown_tot < numDown)
149  els->R[ndown_tot++] = ions->R[iat] + sep * chi[random_number_counter++];
150  }
151  }
152 
153  // Step 2. Distribute the electrons left alone
154  // mmorales: changed order of spin assignment to help with spin
155  // imbalances in molecules at large distances.
156  // Not guaranteed to work, but should help in most cases
157  // as long as atoms in molecules are defined sequencially
158  std::vector<LoneElectron>::iterator it(loneQ.begin());
159  std::vector<LoneElectron>::iterator it_end(loneQ.end());
160  while (it != it_end && nup_tot != numUp && ndown_tot != numDown)
161  {
162  if (nup_tot < numUp)
163  {
164  els->R[nup_tot++] = ions->R[(*it).ID] + (*it).BondLength * chi[random_number_counter++];
165  ++it;
166  }
167  if (ndown_tot < numDown && it != it_end)
168  {
169  els->R[ndown_tot++] = ions->R[(*it).ID] + (*it).BondLength * chi[random_number_counter++];
170  ++it;
171  }
172  }
173 
174  // Step 3. Handle more than neutral electrons
175  //extra electrons around the geometric center
176  RealType cnorm = 1.0 / static_cast<RealType>(Centers);
177  RealType sep = rmin * 2;
178  cm = cnorm * cm;
179  if (nup_tot < numUp)
180  while (nup_tot < numUp)
181  els->R[nup_tot++] = cm + sep * chi[random_number_counter++];
182  if (ndown_tot < numDown)
183  while (ndown_tot < numDown)
184  els->R[ndown_tot++] = cm + sep * chi[random_number_counter++];
185 
186  // safety check. all the random numbers should have been consumed once and only once.
187  if (random_number_counter != chi.size())
188  throw std::runtime_error("initMolecule unexpected random number consumption. Please report a bug!");
189 
190  //put all the electrons in a unit box
191  if (els->getLattice().SuperCellEnum != SUPERCELL_OPEN)
192  {
193  els->R.setUnit(PosUnit::Cartesian);
194  els->applyBC(els->R);
195  els->update(false);
196  }
197 }
ParticleLayout::SingleParticlePos SingleParticlePos
Definition: Configuration.h:87
ParticleAttrib< Index_t > ParticleIndex
Definition: Configuration.h:90
T min(T a, T b)
void makeSphereRandom(ParticleAttrib< TinyVector< T, 3 >> &a)
QMCTraits::RealType RealType
void initAtom(ParticleSet *ions, ParticleSet *els)
initialize els for an atom
ParticleAttrib< SingleParticlePos > ParticlePos
Definition: Configuration.h:92

◆ initWithVolume()

void initWithVolume ( ParticleSet ions,
ParticleSet els 
)

initialize els for the systems with a mixed boundary

Use the bound of the ionic systems and uniform random positions within a reduced box

Definition at line 213 of file InitMolecularSystem.cpp.

References qmcplusplus::abs(), qmcplusplus::app_log(), ParticleSet::applyBC(), qmcplusplus::Cartesian, ParticleSet::getLattice(), ParticleSet::getTotalNum(), qmcplusplus::Lattice, qmcplusplus::lower_bound(), qmcplusplus::makeUniformRandom(), omptarget::min(), OHMMS_DIM, ParticleSet::R, CrystalLattice< T, D >::set(), ParticleAttrib< T, Alloc >::setUnit(), and qmcplusplus::upper_bound().

Referenced by InitMolecularSystem::put().

214 {
217 
218  ParticleSet::ParticlePos Ru(ions->getTotalNum());
219  Ru.setUnit(PosUnit::Lattice);
220  ions->applyBC(ions->R, Ru);
221 
222  for (int iat = 0; iat < Ru.size(); iat++)
223  {
224  start = lower_bound(Ru[iat], start);
225  end = upper_bound(Ru[iat], end);
226  }
227 
229  Tensor<RealType, OHMMS_DIM> newbox(ions->getLattice().R);
230 
231  RealType buffer = 2.0; //buffer 2 bohr
232  for (int idim = 0; idim < OHMMS_DIM; ++idim)
233  {
234  //if(ions->getLattice().BoxBConds[idim])
235  //{
236  // start[idim]=0.0;
237  // end[idim]=1.0;
238  // shift[idim]=0.0;
239  //}
240  //else
241  {
242  RealType buffer_r = buffer * ions->getLattice().OneOverLength[idim];
243  start[idim] = std::max((RealType)0.0, (start[idim] - buffer_r));
244  end[idim] = std::min((RealType)1.0, (end[idim] + buffer_r));
245  shift[idim] = start[idim] * ions->getLattice().Length[idim];
246  if (std::abs(end[idim] = start[idim]) < buffer)
247  { //handle singular case
248  start[idim] = std::max(0.0, start[idim] - buffer_r / 2.0);
249  end[idim] = std::min(1.0, end[idim] + buffer_r / 2.0);
250  }
251 
252  newbox(idim, idim) = (end[idim] - start[idim]) * ions->getLattice().Length[idim];
253  }
254  }
255 
256  ParticleSet::ParticleLayout slattice(ions->getLattice());
257  slattice.set(newbox);
258 
259  app_log() << " InitMolecularSystem::initWithVolume " << std::endl;
260  app_log() << " Effective Lattice shifted by " << shift << std::endl;
261  app_log() << newbox << std::endl;
262 
263  Ru.resize(els->getTotalNum());
264  makeUniformRandom(Ru);
265  for (int iat = 0; iat < Ru.size(); ++iat)
266  els->R[iat] = slattice.toCart(Ru[iat]) + shift;
267  els->R.setUnit(PosUnit::Cartesian);
268 }
void makeUniformRandom(ParticleAttrib< TinyVector< T, D >> &a)
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
std::ostream & app_log()
Definition: OutputManager.h:65
CrystalLattice< OHMMS_PRECISION, OHMMS_DIM > ParticleLayout
Definition: Configuration.h:79
#define OHMMS_DIM
Definition: config.h:64
T min(T a, T b)
TinyVector< T, 3 > lower_bound(const TinyVector< T, 3 > &a, const TinyVector< T, 3 > &b)
helper function to determine the lower bound of a domain (need to move up)
TinyVector< T, 3 > upper_bound(const TinyVector< T, 3 > &a, const TinyVector< T, 3 > &b)
helper function to determine the upper bound of a domain (need to move up)
QMCTraits::RealType RealType
ParticleAttrib< SingleParticlePos > ParticlePos
Definition: Configuration.h:92

◆ put() [1/2]

bool put ( std::istream &  )
overridevirtual

read from std::istream

Implements OhmmsElementBase.

Definition at line 270 of file InitMolecularSystem.cpp.

Referenced by ParticleSetPool::randomize(), and QMCMain::validateXML().

270 { return true; }

◆ put() [2/2]

bool put ( xmlNodePtr  cur)
overridevirtual

read from an xmlNode

Implements OhmmsElementBase.

Definition at line 36 of file InitMolecularSystem.cpp.

References OhmmsAttributeSet::add(), qmcplusplus::app_log(), ERRORMSG, ParticleSetPool::getParticleSet(), InitMolecularSystem::initMolecule(), InitMolecularSystem::initWithVolume(), qmcplusplus::makeUniformRandom(), InitMolecularSystem::ptclPool, OhmmsAttributeSet::put(), and ParticleSet::spins.

37 {
38  std::string target("e"), source("i"), volume("no");
39  OhmmsAttributeSet hAttrib;
40  hAttrib.add(target, "target");
41  hAttrib.add(source, "source");
42  hAttrib.add(volume, "use_volume");
43  hAttrib.put(cur);
44  ParticleSet* els = ptclPool.getParticleSet(target);
45  if (els == 0)
46  {
47  ERRORMSG("No target particle " << target << " exists.")
48  return false;
49  }
50  ParticleSet* ions = ptclPool.getParticleSet(source);
51  if (ions == 0)
52  {
53  ERRORMSG("No source particle " << source << " exists.")
54  return false;
55  }
56 
57  app_log() << "<init source=\"" << source << "\" target=\"" << target << "\">" << std::endl;
58 
59  if (volume == "yes")
60  initWithVolume(ions, els);
61  else
62  initMolecule(ions, els);
63 
64  makeUniformRandom(els->spins);
65  els->spins *= 2 * M_PI;
66 
67  app_log() << "</init>" << std::endl;
68  app_log().flush();
69 
70  return true;
71 }
void makeUniformRandom(ParticleAttrib< TinyVector< T, D >> &a)
#define ERRORMSG(msg)
Definition: OutputManager.h:86
std::ostream & app_log()
Definition: OutputManager.h:65
if(c->rank()==0)
bool put(xmlNodePtr cur)
assign attributes to the set
Definition: AttributeSet.h:55
ParticleSet * getParticleSet(const std::string &pname)
get a named ParticleSet
class to handle a set of attributes of an xmlNode
Definition: AttributeSet.h:24
void initWithVolume(ParticleSet *ions, ParticleSet *els)
initialize els for the systems with a mixed boundary
void initMolecule(ParticleSet *ions, ParticleSet *els)
initialize els position for a molecule
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
ParticleSetPool & ptclPool
pointer to ParticleSetPool

◆ reset()

void reset ( )
overridevirtual

reset member data

Implements OhmmsElementBase.

Definition at line 274 of file InitMolecularSystem.cpp.

274 {}

Member Data Documentation

◆ ptclPool

ParticleSetPool& ptclPool
private

pointer to ParticleSetPool

QMCHamiltonian needs to know which ParticleSet object is used as an input object for the evaluations. Any number of ParticleSet can be used to describe a QMCHamiltonian.

Definition at line 62 of file InitMolecularSystem.h.

Referenced by InitMolecularSystem::put().


The documentation for this class was generated from the following files: