source: src/atom.cpp@ 1a6bda

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 1a6bda was 9df680, checked in by Frederik Heber <heber@…>, 14 years ago

FIX: FillVoidWithMolecule() now centers filler molecule at its center of gravity.

  • this is the only sensible option if we later rotate the molecule.
  • atom::clone() reduced a lot, as copy constructors contains it all.
  • FillVoidWithMolecule() - filler is now selected to reside entirely within the domain. Otherwise, we seg'fault on save on exit, as one of the father atoms for all copied atoms is missing and hence, we cannot look at its additional...Data for various parsers.
  • new function molecule::removeAtomsInMolecule() which destroys all the molecule's atoms.

TESTFIXES:

  • Filling/3: filled water box has changed due to different center of water molecules.
  • Property mode set to 100644
File size: 11.7 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/** \file atom.cpp
9 *
10 * Function implementations for the class atom.
11 *
12 */
13
14// include config.h
15#ifdef HAVE_CONFIG_H
16#include <config.h>
17#endif
18
19#include "CodePatterns/MemDebug.hpp"
20
21#include "atom.hpp"
22#include "bond.hpp"
23#include "config.hpp"
24#include "element.hpp"
25#include "lists.hpp"
26#include "parser.hpp"
27#include "LinearAlgebra/Vector.hpp"
28#include "World.hpp"
29#include "molecule.hpp"
30#include "Shapes/Shape.hpp"
31
32#include <iomanip>
33#include <iostream>
34
35/************************************* Functions for class atom *************************************/
36
37
38/** Constructor of class atom.
39 */
40atom::atom() :
41 father(this),
42 sort(&nr),
43 mol(0)
44{};
45
46/** Constructor of class atom.
47 */
48atom::atom(atom *pointer) :
49 ParticleInfo(pointer),
50 father(pointer),
51 sort(&nr),
52 mol(0)
53{
54 setType(pointer->getType()); // copy element of atom
55 setPosition(pointer->getPosition()); // copy coordination
56 AtomicVelocity = pointer->AtomicVelocity; // copy velocity
57 FixedIon = pointer->FixedIon;
58};
59
60atom *atom::clone(){
61 atom *res = new atom(this);
62 World::getInstance().registerAtom(res);
63 return res;
64}
65
66
67/** Destructor of class atom.
68 */
69atom::~atom()
70{
71 removeFromMolecule();
72 for(BondList::iterator iter=ListOfBonds.begin(); iter!=ListOfBonds.end();){
73 // deleting the bond will invalidate the iterator !!!
74 bond *bond =*(iter++);
75 delete(bond);
76 }
77};
78
79
80/** Climbs up the father list until NULL, last is returned.
81 * \return true father, i.e. whose father points to itself, NULL if it could not be found or has none (added hydrogen)
82 */
83atom *atom::GetTrueFather()
84{
85 if(father == this){ // top most father is the one that points on itself
86 return this;
87 }
88 else if(!father) {
89 return 0;
90 }
91 else {
92 return father->GetTrueFather();
93 }
94};
95
96/** Sets father to itself or its father in case of copying a molecule.
97 */
98void atom::CorrectFather()
99{
100 if (father->father == father) // same atom in copy's father points to itself
101 father = this; // set father to itself (copy of a whole molecule)
102 else
103 father = father->father; // set father to original's father
104
105};
106
107/** Check whether father is equal to given atom.
108 * \param *ptr atom to compare father to
109 * \param **res return value (only set if atom::father is equal to \a *ptr)
110 */
111void atom::EqualsFather ( const atom *ptr, const atom **res ) const
112{
113 if ( ptr == father )
114 *res = this;
115};
116
117bool atom::isFather(const atom *ptr){
118 return ptr==father;
119}
120
121/** Checks whether atom is within the given box.
122 * \param offset offset to box origin
123 * \param *parallelepiped box matrix
124 * \return true - is inside, false - is not
125 */
126bool atom::IsInShape(const Shape& shape) const
127{
128 return shape.isInside(getPosition());
129};
130
131/** Counts the number of bonds weighted by bond::BondDegree.
132 * \param bonds times bond::BondDegree
133 */
134int BondedParticle::CountBonds() const
135{
136 int NoBonds = 0;
137 for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); (++Runner))
138 NoBonds += (*Runner)->BondDegree;
139 return NoBonds;
140};
141
142/** Output of a single atom with given numbering.
143 * \param ElementNo cardinal number of the element
144 * \param AtomNo cardinal number among these atoms of the same element
145 * \param *out stream to output to
146 * \param *comment commentary after '#' sign
147 * \return true - \a *out present, false - \a *out is NULL
148 */
149bool atom::OutputIndexed(ofstream * const out, const int ElementNo, const int AtomNo, const char *comment) const
150{
151 if (out != NULL) {
152 *out << "Ion_Type" << ElementNo << "_" << AtomNo << "\t" << fixed << setprecision(9) << showpoint;
153 *out << at(0) << "\t" << at(1) << "\t" << at(2);
154 *out << "\t" << FixedIon;
155 if (AtomicVelocity.Norm() > MYEPSILON)
156 *out << "\t" << scientific << setprecision(6) << AtomicVelocity[0] << "\t" << AtomicVelocity[1] << "\t" << AtomicVelocity[2] << "\t";
157 if (comment != NULL)
158 *out << " # " << comment << endl;
159 else
160 *out << " # molecule nr " << nr << endl;
161 return true;
162 } else
163 return false;
164};
165
166/** Output of a single atom with numbering from array according to atom::type.
167 * \param *ElementNo cardinal number of the element
168 * \param *AtomNo cardinal number among these atoms of the same element
169 * \param *out stream to output to
170 * \param *comment commentary after '#' sign
171 * \return true - \a *out present, false - \a *out is NULL
172 */
173bool atom::OutputArrayIndexed(ostream * const out,const enumeration<const element*> &elementLookup, int *AtomNo, const char *comment) const
174{
175 AtomNo[getType()->getAtomicNumber()]++; // increment number
176 if (out != NULL) {
177 const element *elemental = getType();
178 ASSERT(elementLookup.there.find(elemental)!=elementLookup.there.end(),"Type of this atom was not in the formula upon enumeration");
179 *out << "Ion_Type" << elementLookup.there.find(elemental)->second << "_" << AtomNo[elemental->getAtomicNumber()] << "\t" << fixed << setprecision(9) << showpoint;
180 *out << at(0) << "\t" << at(1) << "\t" << at(2);
181 *out << "\t" << FixedIon;
182 if (AtomicVelocity.Norm() > MYEPSILON)
183 *out << "\t" << scientific << setprecision(6) << AtomicVelocity[0] << "\t" << AtomicVelocity[1] << "\t" << AtomicVelocity[2] << "\t";
184 if (comment != NULL)
185 *out << " # " << comment << endl;
186 else
187 *out << " # molecule nr " << nr << endl;
188 return true;
189 } else
190 return false;
191};
192
193/** Output of a single atom as one lin in xyz file.
194 * \param *out stream to output to
195 * \return true - \a *out present, false - \a *out is NULL
196 */
197bool atom::OutputXYZLine(ofstream *out) const
198{
199 if (out != NULL) {
200 *out << getType()->getSymbol() << "\t" << at(0) << "\t" << at(1) << "\t" << at(2) << "\t" << endl;
201 return true;
202 } else
203 return false;
204};
205
206/** Output of a single atom as one lin in xyz file.
207 * \param *out stream to output to
208 * \param *ElementNo array with ion type number in the config file this atom's element shall have
209 * \param *AtomNo array with atom number in the config file this atom shall have, is increase by one automatically
210 * \param step Trajectory time step to output
211 * \return true - \a *out present, false - \a *out is NULL
212 */
213bool atom::OutputTrajectory(ofstream * const out, const enumeration<const element*> &elementLookup, int *AtomNo, const int step) const
214{
215 AtomNo[getType()->getAtomicNumber()]++;
216 if (out != NULL) {
217 const element *elemental = getType();
218 ASSERT(elementLookup.there.find(elemental)!=elementLookup.there.end(),"Type of this atom was not in the formula upon enumeration");
219 *out << "Ion_Type" << elementLookup.there.find(elemental)->second << "_" << AtomNo[getType()->getAtomicNumber()] << "\t" << fixed << setprecision(9) << showpoint;
220 *out << Trajectory.R.at(step)[0] << "\t" << Trajectory.R.at(step)[1] << "\t" << Trajectory.R.at(step)[2];
221 *out << "\t" << FixedIon;
222 if (Trajectory.U.at(step).Norm() > MYEPSILON)
223 *out << "\t" << scientific << setprecision(6) << Trajectory.U.at(step)[0] << "\t" << Trajectory.U.at(step)[1] << "\t" << Trajectory.U.at(step)[2] << "\t";
224 if (Trajectory.F.at(step).Norm() > MYEPSILON)
225 *out << "\t" << scientific << setprecision(6) << Trajectory.F.at(step)[0] << "\t" << Trajectory.F.at(step)[1] << "\t" << Trajectory.F.at(step)[2] << "\t";
226 *out << "\t# Number in molecule " << nr << endl;
227 return true;
228 } else
229 return false;
230};
231
232/** Output of a single atom as one lin in xyz file.
233 * \param *out stream to output to
234 * \param step Trajectory time step to output
235 * \return true - \a *out present, false - \a *out is NULL
236 */
237bool atom::OutputTrajectoryXYZ(ofstream * const out, const int step) const
238{
239 if (out != NULL) {
240 *out << getType()->getSymbol() << "\t";
241 *out << Trajectory.R.at(step)[0] << "\t";
242 *out << Trajectory.R.at(step)[1] << "\t";
243 *out << Trajectory.R.at(step)[2] << endl;
244 return true;
245 } else
246 return false;
247};
248
249/** Outputs the MPQC configuration line for this atom.
250 * \param *out output stream
251 * \param *center center of molecule subtracted from position
252 * \param *AtomNo pointer to atom counter that is increased by one
253 */
254void atom::OutputMPQCLine(ostream * const out, const Vector *center) const
255{
256 Vector recentered(getPosition());
257 recentered -= *center;
258 *out << "\t\t" << getType()->getSymbol() << " [ " << recentered[0] << "\t" << recentered[1] << "\t" << recentered[2] << " ]" << endl;
259};
260
261/** Compares the indices of \a this atom with a given \a ptr.
262 * \param ptr atom to compare index against
263 * \return true - this one's is smaller, false - not
264 */
265bool atom::Compare(const atom &ptr) const
266{
267 if (nr < ptr.nr)
268 return true;
269 else
270 return false;
271};
272
273/** Returns squared distance to a given vector.
274 * \param origin vector to calculate distance to
275 * \return distance squared
276 */
277double atom::DistanceSquaredToVector(const Vector &origin) const
278{
279 return DistanceSquared(origin);
280};
281
282/** Returns distance to a given vector.
283 * \param origin vector to calculate distance to
284 * \return distance
285 */
286double atom::DistanceToVector(const Vector &origin) const
287{
288 return distance(origin);
289};
290
291/** Initialises the component number array.
292 * Size is set to atom::ListOfBonds.size()+1 (last is th encode end by -1)
293 */
294void atom::InitComponentNr()
295{
296 if (ComponentNr != NULL)
297 delete[](ComponentNr);
298 ComponentNr = new int[ListOfBonds.size()+1];
299 for (int i=ListOfBonds.size()+1;i--;)
300 ComponentNr[i] = -1;
301};
302
303void atom::resetGraphNr(){
304 GraphNr=-1;
305}
306
307std::ostream & atom::operator << (std::ostream &ost) const
308{
309 ParticleInfo::operator<<(ost);
310 ost << "," << getPosition();
311 return ost;
312}
313
314std::ostream & operator << (std::ostream &ost, const atom &a)
315{
316 a.ParticleInfo::operator<<(ost);
317 ost << "," << a.getPosition();
318 return ost;
319}
320
321bool operator < (atom &a, atom &b)
322{
323 return a.Compare(b);
324};
325
326World *atom::getWorld(){
327 return world;
328}
329
330void atom::setWorld(World* _world){
331 world = _world;
332}
333
334bool atom::changeId(atomId_t newId){
335 // first we move ourselves in the world
336 // the world lets us know if that succeeded
337 if(world->changeAtomId(id,newId,this)){
338 id = newId;
339 return true;
340 }
341 else{
342 return false;
343 }
344}
345
346void atom::setId(atomId_t _id) {
347 id=_id;
348}
349
350atomId_t atom::getId() const {
351 return id;
352}
353
354/** Makes the atom be contained in the new molecule \a *_mol.
355 * Uses atom::removeFromMolecule() to delist from old molecule.
356 * \param *_mol pointer to new molecule
357 */
358void atom::setMolecule(molecule *_mol){
359 // take this atom from the old molecule
360 removeFromMolecule();
361 mol = _mol;
362 if(!mol->containsAtom(this)){
363 mol->insert(this);
364 }
365}
366
367/** Returns pointer to the molecule which atom belongs to.
368 * \return containing molecule
369 */
370molecule* atom::getMolecule() const {
371 return mol;
372}
373
374/** Erases the atom in atom::mol's list of atoms and sets it to zero.
375 */
376void atom::removeFromMolecule(){
377 if(mol){
378 if(mol->containsAtom(this)){
379 mol->erase(this);
380 }
381 mol=0;
382 }
383}
384
385double atom::getMass() const{
386 return getType()->getMass();
387}
388
389int atom::getNr() const{
390 return nr;
391}
392
393atom* NewAtom(atomId_t _id){
394 atom * res =new atom();
395 res->setId(_id);
396 return res;
397}
398
399void DeleteAtom(atom* atom){
400 delete atom;
401}
402
403bool compareAtomElements(atom* atom1,atom* atom2){
404 return atom1->getType()->getNumber() < atom2->getType()->getNumber();
405}
Note: See TracBrowser for help on using the repository browser.