source: src/Atom/atom.cpp@ aadea2

Last change on this file since aadea2 was 88bb6b, checked in by Frederik Heber <heber@…>, 11 years ago

FIX: atom::clone() does not register pointer as father anymore.

  • otherwise during fill we always generate lots of "sons" (which was meant in another context, namely when generating fragment molecules in the same system that related to original molecule via the "father").
  • Property mode set to 100644
File size: 8.0 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
5 * Copyright (C) 2013 Frederik Heber. All rights reserved.
6 *
7 *
8 * This file is part of MoleCuilder.
9 *
10 * MoleCuilder is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * MoleCuilder is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24/** \file atom.cpp
25 *
26 * Function implementations for the class atom.
27 *
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35#include "CodePatterns/MemDebug.hpp"
36
37#include "atom.hpp"
38#include "AtomObserver.hpp"
39#include "Bond/bond.hpp"
40#include "CodePatterns/Log.hpp"
41#include "config.hpp"
42#include "Element/element.hpp"
43#include "LinearAlgebra/Vector.hpp"
44#include "World.hpp"
45#include "WorldTime.hpp"
46#include "molecule.hpp"
47#include "Shapes/Shape.hpp"
48
49#include <iomanip>
50#include <iostream>
51
52/************************************* Functions for class atom *************************************/
53
54
55atom::atom() :
56 father(this),
57 sort(&Nr),
58 mol(0)
59{
60 // sign on to global atom change tracker
61 AtomObserver::getInstance().AtomInserted(this);
62}
63
64atom::atom(atom *pointer) :
65 ParticleInfo(*pointer),
66 AtomInfo(*pointer),
67 father(pointer),
68 sort(&Nr),
69 mol(0)
70{
71 AtomicPosition = pointer->AtomicPosition; // copy trajectory of coordination
72 AtomicVelocity = pointer->AtomicVelocity; // copy trajectory of velocity
73 AtomicForce = pointer->AtomicForce;
74 // sign on to global atom change tracker
75 AtomObserver::getInstance().AtomInserted(this);
76};
77
78atom *atom::clone(){
79 atom *res = new atom(this);
80 res->father = res;
81 World::getInstance().registerAtom(res);
82 return res;
83}
84
85
86/** Destructor of class atom.
87 */
88atom::~atom()
89{
90 removeFromMolecule();
91 // sign off from global atom change tracker
92 AtomObserver::getInstance().AtomRemoved(this);
93}
94
95
96void atom::UpdateSteps()
97{
98 LOG(4,"atom::UpdateSteps() called.");
99 // append to position, velocity and force vector
100 AtomInfo::AppendTrajectoryStep();
101 // append to ListOfBonds vector
102 BondedParticleInfo::AppendTrajectoryStep();
103}
104
105atom *atom::GetTrueFather()
106{
107 const atom *father = const_cast<const atom *>(this)->GetTrueFather();
108 return const_cast<atom *>(father);
109}
110
111const atom *atom::GetTrueFather() const
112{
113 if(father == this){ // top most father is the one that points on itself
114 return this;
115 }
116 else if(!father) {
117 return 0;
118 }
119 else {
120 return father->GetTrueFather();
121 }
122};
123
124/** Sets father to itself or its father in case of copying a molecule.
125 */
126void atom::CorrectFather()
127{
128 if (father->father != father) // same atom in copy's father points to itself
129// father = this; // set father to itself (copy of a whole molecule)
130// else
131 father = father->father; // set father to original's father
132
133};
134
135void atom::EqualsFather ( const atom *ptr, const atom **res ) const
136{
137 if ( ptr == father )
138 *res = this;
139};
140
141bool atom::isFather(const atom *ptr){
142 return ptr==father;
143}
144
145bool atom::OutputIndexed(ofstream * const out, const int ElementNo, const int AtomNo, const char *comment) const
146{
147 if (out != NULL) {
148 *out << "Ion_Type" << ElementNo << "_" << AtomNo << "\t" << fixed << setprecision(9) << showpoint;
149 *out << at(0) << "\t" << at(1) << "\t" << at(2);
150 *out << "\t" << (int)(getFixedIon());
151 if (getAtomicVelocity().Norm() > MYEPSILON)
152 *out << "\t" << scientific << setprecision(6) << getAtomicVelocity()[0] << "\t" << getAtomicVelocity()[1] << "\t" << getAtomicVelocity()[2] << "\t";
153 if (comment != NULL)
154 *out << " # " << comment << endl;
155 else
156 *out << " # molecule nr " << getNr() << endl;
157 return true;
158 } else
159 return false;
160};
161
162bool atom::OutputArrayIndexed(ostream * const out,const enumeration<const element*> &elementLookup, int *AtomNo, const char *comment) const
163{
164 AtomNo[getType()->getAtomicNumber()]++; // increment number
165 if (out != NULL) {
166 const element *elemental = getType();
167 ASSERT(elementLookup.there.find(elemental)!=elementLookup.there.end(),"Type of this atom was not in the formula upon enumeration");
168 *out << "Ion_Type" << elementLookup.there.find(elemental)->second << "_" << AtomNo[elemental->getAtomicNumber()] << "\t" << fixed << setprecision(9) << showpoint;
169 *out << at(0) << "\t" << at(1) << "\t" << at(2);
170 *out << "\t" << getFixedIon();
171 if (getAtomicVelocity().Norm() > MYEPSILON)
172 *out << "\t" << scientific << setprecision(6) << getAtomicVelocity()[0] << "\t" << getAtomicVelocity()[1] << "\t" << getAtomicVelocity()[2] << "\t";
173 if (comment != NULL)
174 *out << " # " << comment << endl;
175 else
176 *out << " # molecule nr " << getNr() << endl;
177 return true;
178 } else
179 return false;
180};
181
182bool atom::Compare(const atom &ptr) const
183{
184 if (getNr() < ptr.getNr())
185 return true;
186 else
187 return false;
188};
189
190double atom::DistanceSquaredToVector(const Vector &origin) const
191{
192 return DistanceSquared(origin);
193};
194
195double atom::DistanceToVector(const Vector &origin) const
196{
197 return distance(origin);
198};
199
200void atom::InitComponentNr()
201{
202 if (ComponentNr != NULL)
203 delete[](ComponentNr);
204 const BondList& ListOfBonds = getListOfBonds();
205 ComponentNr = new int[ListOfBonds.size()+1];
206 for (int i=ListOfBonds.size()+1;i--;)
207 ComponentNr[i] = -1;
208};
209
210void atom::resetGraphNr(){
211 GraphNr=-1;
212}
213
214std::ostream & atom::operator << (std::ostream &ost) const
215{
216 ParticleInfo::operator<<(ost);
217 ost << "," << getPosition();
218 return ost;
219}
220
221std::ostream & operator << (std::ostream &ost, const atom &a)
222{
223 a.ParticleInfo::operator<<(ost);
224 ost << "," << a.getPosition();
225 return ost;
226}
227
228bool operator < (atom &a, atom &b)
229{
230 return a.Compare(b);
231};
232
233World *atom::getWorld(){
234 return world;
235}
236
237void atom::setWorld(World* _world){
238 world = _world;
239}
240
241bool atom::changeId(atomId_t newId){
242 // first we move ourselves in the world
243 // the world lets us know if that succeeded
244 if(world->changeAtomId(id,newId,this)){
245 OBSERVE;
246 id = newId;
247 NOTIFY(IndexChanged);
248 return true;
249 }
250 else{
251 return false;
252 }
253}
254
255void atom::setId(atomId_t _id) {
256 id=_id;
257}
258
259atomId_t atom::getId() const {
260 return id;
261}
262
263void atom::setMolecule(molecule *_mol){
264 // take this atom from the old molecule
265 removeFromMolecule();
266 mol = _mol;
267 if ((mol) && (!mol->containsAtom(this)))
268 mol->insert(this);
269}
270
271void atom::unsetMolecule()
272{
273 // take this atom from the old molecule
274 ASSERT(!mol->containsAtom(this),
275 "atom::unsetMolecule() - old molecule "+toString(mol)+" still contains us!");
276 mol = NULL;
277}
278
279molecule* atom::getMolecule() const {
280 return mol;
281}
282
283void atom::removeFromMolecule(){
284 if(mol){
285 if(mol->containsAtom(this)){
286 mol->erase(this);
287 }
288 mol=0;
289 }
290}
291
292bool atom::changeNr(const int newNr)
293{
294 if ((mol) && (mol->changeAtomNr(getNr(),newNr,this))) {
295 return true;
296 } else{
297 return false;
298 }
299}
300
301int atom::getNr() const{
302 return ParticleInfo::getNr();
303}
304
305atom* NewAtom(atomId_t _id){
306 atom * res = new atom();
307 // extent trajectory to current time step
308 const size_t CurrentTime = WorldTime::getTime();
309 for (size_t step = res->getTrajectorySize(); step <= CurrentTime; ++step)
310 res->UpdateSteps();
311 res->setId(_id);
312 return res;
313}
314
315void DeleteAtom(atom* atom){
316 delete atom;
317}
318
319bool compareAtomElements(atom* atom1,atom* atom2){
320 return atom1->getType()->getAtomicNumber() < atom2->getType()->getAtomicNumber();
321}
Note: See TracBrowser for help on using the repository browser.