source: src/Atom/atom_bondedparticle.cpp@ 440ac3

Action_Thermostats Add_AtomRandomPerturbation Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests AutomationFragmentation_failures Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_ChronosMutex Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion GeometryObjects Gui_displays_atomic_force_velocity IndependentFragmentGrids_IntegrationTest JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix PartialCharges_OrthogonalSummation PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks RotateToPrincipalAxisSystem_UndoRedo StoppableMakroAction TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes stable
Last change on this file since 440ac3 was a1c8fa, checked in by Frederik Heber <heber@…>, 8 years ago

FIX: BondedParticleInfo::MaxOrder and ::AdapativeOrder are now stored per trajectory step.

  • adapted uses in AdaptivityMap and Fragmentation as members are now protected.
  • Property mode set to 100644
File size: 13.2 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/*
25 * atom_bondedparticle.cpp
26 *
27 * Created on: Oct 19, 2009
28 * Author: heber
29 */
30
31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36#include "CodePatterns/MemDebug.hpp"
37
38#include <algorithm>
39#include <boost/bind.hpp>
40
41#include "atom.hpp"
42#include "atom_bondedparticle.hpp"
43#include "Bond/bond.hpp"
44#include "CodePatterns/Assert.hpp"
45#include "CodePatterns/Log.hpp"
46#include "CodePatterns/Verbose.hpp"
47#include "Element/element.hpp"
48#include "WorldTime.hpp"
49
50/** Constructor of class BondedParticle.
51 */
52BondedParticle::BondedParticle()
53{
54 ListOfBonds.insert( std::make_pair(0, emptyList) );
55};
56
57/** Destructor of class BondedParticle.
58 */
59BondedParticle::~BondedParticle()
60{
61 for(BondTrajectory_t::iterator iter = ListOfBonds.begin(); !ListOfBonds.empty();
62 iter = ListOfBonds.begin()) {
63 removeAllBonds(iter->first);
64 ListOfBonds.erase(iter);
65 }
66};
67
68/** Outputs the current atom::AdaptiveOrder and atom::MaxOrder to \a *file.
69 * \param *file output stream
70 */
71void BondedParticle::OutputOrder(ofstream *file) const
72{
73 *file << getNr() << "\t" << (int)getAdaptiveOrder() << "\t" << (int)getMaxOrder() << endl;
74 //LOG(2, "Storing: " << getNr() << "\t" << (int)getAdaptiveOrder() << "\t" << getMaxOrder() << ".");
75};
76
77/** Prints all bonds of this atom with total degree.
78 */
79void BondedParticle::OutputBondOfAtom(std::ostream &ost) const
80{
81 const BondList& ListOfBonds = getListOfBonds();
82 ost << "Atom " << getName() << "/" << getNr() << " with " << ListOfBonds.size() << " bonds: ";
83 int TotalDegree = 0;
84 for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); ++Runner) {
85 ost << **Runner << "\t";
86 TotalDegree += (*Runner)->getDegree();
87 }
88 ost << " -- TotalDegree: " << TotalDegree;
89};
90
91/** Output of atom::Nr along each bond partner per line.
92 * Only bonds are printed where atom::Nr is smaller than the one of the bond partner.
93 * \param *AdjacencyFile output stream
94 */
95void BondedParticle::OutputBonds(ofstream * const BondFile) const
96{
97 const BondList& ListOfBonds = getListOfBonds();
98 for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); (++Runner))
99 if (getNr() < (*Runner)->GetOtherAtom(this)->getNr())
100 *BondFile << getNr() << "\t" << (*Runner)->GetOtherAtom(this)->getNr() << "\n";
101};
102
103/**
104 * Adds a bond between this bonded particle and another. Returns present instance if this
105 * bond already exists.
106 *
107 * @param _step time step to access
108 * @param bonding partner
109 * @return pointer to created bond or to already present bonds
110 */
111bond::ptr BondedParticle::addBond(const unsigned int _step, BondedParticle* const Partner)
112{
113 const BondList &bondlist = getListOfBondsAtStep(_step);
114 for (BondList::const_iterator runner = bondlist.begin();
115 runner != bondlist.end();
116 runner++) {
117 if ((*runner)->Contains(Partner))
118 return *runner;
119 }
120
121 bond::ptr newBond(new bond((atom*) this, (atom*) Partner, 1));
122 RegisterBond(_step, newBond);
123 Partner->RegisterBond(_step, newBond);
124
125 return newBond;
126}
127
128/**
129 * Returns aan already present bond between this bonded particle and another.
130 *
131 * @param _step time step to access
132 * @param bonding partner
133 * @return pointer to already present bonds or containing NULL
134 */
135bond::ptr BondedParticle::getBondAtStep(
136 const unsigned int _step,
137 const BondedParticle* const Partner) const
138{
139 const BondList &bondlist = getListOfBondsAtStep(_step);
140 for (BondList::const_iterator runner = bondlist.begin();
141 runner != bondlist.end();
142 runner++) {
143 if ((*runner)->Contains(Partner))
144 return *runner;
145 }
146 return bond::ptr();
147}
148
149/**
150 * Adds a bond between this bonded particle and another. Returns present instance if this
151 * bond already exists.
152 *
153 * @param bonding partner
154 * @return pointer to created bond or to already present bonds
155 */
156bond::ptr BondedParticle::addBond(BondedParticle* const Partner)
157{
158 return addBond(WorldTime::getTime(), Partner);
159}
160
161/**
162 * Returns an already present bond between this bonded particle and another.
163 *
164 * @param bonding partner
165 * @return pointer to already present bonds or containing NULL
166 */
167bond::ptr BondedParticle::getBond(const BondedParticle* const Partner) const
168{
169 return getBondAtStep(WorldTime::getTime(), Partner);
170}
171
172/** Helper function to find the time step to a given bond in \a Binder.
173 *
174 * \param Binder bond to look for
175 * \return ListOfBonds::size() - not found, else - step containing \a Binder
176 */
177unsigned int BondedParticle::findBondsStep(bond::ptr const Binder) const
178{
179
180 size_t _step = 0;
181 for (;_step < ListOfBonds.size();++_step) {
182 const BondList& ListOfBonds = getListOfBondsAtStep(_step);
183 if (std::find(ListOfBonds.begin(), ListOfBonds.end(), Binder) != ListOfBonds.end())
184 break;
185 }
186 return _step;
187}
188
189/** Helper function to find the iterator to a bond at a given time \a step to
190 * a given bond partner in \a Partner.
191 *
192 * \param _step time step to look at
193 * \param Partner bond partner to look for
194 * \return ListOfBonds::end() - not found, else - iterator pointing \a Binder
195 */
196BondList::const_iterator BondedParticle::findBondPartnerAtStep(
197 const unsigned int _step,
198 BondedParticle * const Partner) const
199{
200 const BondList& ListOfBonds = getListOfBondsAtStep(_step);
201 BondList::const_iterator iter = std::find_if(ListOfBonds.begin(), ListOfBonds.end(),
202 boost::bind(
203 static_cast<bool (bond::*)(const ParticleInfo * const) const>(&bond::Contains),
204 _1,
205 boost::cref(Partner)));
206 return iter;
207}
208
209/** Removes a bond of this atom to a given \a Partner.
210 *
211 * @param _step time step
212 * @param Partner bond partner
213 */
214void BondedParticle::removeBond(const unsigned int _step, BondedParticle * const Partner)
215{
216 BondList::const_iterator iter = findBondPartnerAtStep(_step, Partner);
217 if (iter != getListOfBondsAtStep(_step).end()) {
218 // iter becomes invalid upon first unregister,
219 // hence store the bond someplace else first
220 bond::ptr const Binder = *iter;
221 UnregisterBond(_step, Binder);
222 Partner->UnregisterBond(_step, Binder);
223 } else
224 ELOG(1, "BondedParticle::removeBond() - I cannot find the bond in between "
225 +toString(getName())+" and "+toString(Partner->getName())+".");
226}
227
228/** Removes a bond of this atom to a given \a Partner.
229 *
230 * @param Partner bond partner
231 */
232void BondedParticle::removeBond(BondedParticle * const Partner)
233{
234 removeBond(WorldTime::getTime(), Partner);
235}
236
237/** Removes a bond for this atom.
238 *
239 * @param Binder bond to remove
240 */
241void BondedParticle::removeBond(bond::ptr &binder)
242{
243 if (binder != NULL) {
244 atom * const Other = binder->GetOtherAtom(this);
245 ASSERT( Other != NULL,
246 "BondedParticle::removeBonds() - cannot find bond partner for "
247 +toString(*binder)+".");
248 // find bond at step
249 unsigned int step = findBondsStep(binder);
250 if (step != ListOfBonds.size()) {
251 UnregisterBond(step, binder);
252 Other->UnregisterBond(step, binder);
253 binder.reset();
254 }
255 }
256}
257
258/** Removes all bonds in current timestep and their instances, too.
259 *
260 */
261void BondedParticle::removeAllBonds()
262{
263 removeAllBonds(WorldTime::getTime());
264}
265
266/** Removes all bonds for a given \a _step and their instances, too.
267 *
268 * @param _step time step to access
269 */
270void BondedParticle::removeAllBonds(const unsigned int _step)
271{
272 //LOG(3,"INFO: Clearing all bonds of " << *this << ": " << ListOfBonds[_step]);
273 BondTrajectory_t::iterator listiter = ListOfBonds.find(_step);
274 if (listiter != ListOfBonds.end())
275 for (BondList::iterator iter = listiter->second.begin();
276 !listiter->second.empty();
277 iter = listiter->second.begin()) {
278 //LOG(3,"INFO: Clearing bond (" << *iter << ") " << *(*iter) << " of list " << &ListOfBonds);
279 atom * const Other = (*iter)->GetOtherAtom(this);
280 ASSERT( Other != NULL,
281 "BondedParticle::removeAllBonds() - cannot find bond partner for "
282 +toString(**iter)+".");
283 Other->UnregisterBond(_step, *iter);
284 UnregisterBond(_step, *iter);
285 }
286}
287
288/** Puts a given bond into atom::ListOfBonds.
289 * @param _step time step to access
290 * \param *Binder bond to insert
291 */
292bool BondedParticle::RegisterBond(const unsigned int _step, bond::ptr const Binder)
293{
294 bool status = false;
295 if (Binder != NULL) {
296 OBSERVE;
297 if (Binder->Contains(this)) {
298 //LOG(3,"INFO: Registering bond "<< *Binder << " with atom " << *this << " at step " << _step);
299 std::pair< BondTrajectory_t::iterator, bool> inserter =
300 ListOfBonds.insert( std::make_pair( _step, BondList(1, Binder)) );
301 if (!inserter.second)
302 inserter.first->second.push_back(Binder);
303 if (WorldTime::getTime() == _step)
304 NOTIFY(AtomObservable::BondsAdded);
305 status = true;
306 } else {
307 ELOG(1, *Binder << " does not contain " << *this << ".");
308 }
309 } else {
310 ELOG(1, "Binder is " << Binder << ".");
311 }
312 return status;
313};
314
315/** Removes a given bond from atom::ListOfBonds.
316 *
317 * \warning This only removes this atom not its bond partner, i.e.
318 * both atoms need to call this function to fully empty a bond.
319 *
320 * @param _step time step to access
321 * \param *Binder bond to remove
322 */
323bool BondedParticle::UnregisterBond(const unsigned int _step, bond::ptr const Binder)
324{
325 bool status = false;
326 if (Binder != NULL) {
327 if (Binder->Contains(this)) {
328 OBSERVE;
329 //LOG(0,"INFO: Unregistering bond "<< *Binder << " from list " << &ListOfBonds << " of atom " << *this << " at step " << step);
330 BondTrajectory_t::iterator listiter = ListOfBonds.find(_step);
331 if (listiter != ListOfBonds.end()) {
332#ifndef NDEBUG
333 BondList::const_iterator iter =
334 std::find(listiter->second.begin(), listiter->second.end(), Binder);
335 ASSERT( iter != listiter->second.end(),
336 "BondedParticle::UnregisterBond() - "+toString(*Binder)+" not contained at "
337 +toString(_step));
338#endif
339 Binder->removeAtom(this);
340 listiter->second.remove(Binder);
341 if (WorldTime::getTime() == _step)
342 NOTIFY(AtomObservable::BondsRemoved);
343 status = true;
344 }
345 } else {
346 ELOG(1, *Binder << " does not contain " << *this << ".");
347 }
348 } else {
349 ELOG(1, "Binder is " << Binder << ".");
350 }
351 return status;
352};
353
354/** Removes all bonds of given \a _step with freeing memory.
355 *
356 * @param _step time step whose bonds to free
357 */
358void BondedParticle::ClearBondsAtStep(const unsigned int _step)
359{
360 removeAllBonds(_step);
361}
362
363/** Searches for the time step where the given bond \a *Binder is a bond of this particle.
364 *
365 * @param Binder bond to check
366 * @return >=0 - first time step where bond appears, -1 - bond not present in lists
367 */
368int BondedParticle::ContainsBondAtStep(const bond::ptr Binder) const
369{
370 int step = -1;
371 for(BondTrajectory_t::const_iterator listiter = ListOfBonds.begin();
372 listiter != ListOfBonds.end();
373 ++listiter) {
374 for (BondList::const_iterator bonditer = listiter->second.begin();
375 bonditer != listiter->second.end();
376 ++bonditer) {
377 if ((*bonditer) == Binder) {
378 step = listiter->first;
379 break;
380 }
381 }
382 if (step != -1)
383 break;
384 }
385
386 return step;
387}
388
389/** Counts the number of bonds weighted by bond::BondDegree.
390 * @param _step time step to access
391 * \param bonds times bond::BondDegree
392 */
393int BondedParticle::CountBonds() const
394{
395 int NoBonds = 0;
396 const BondList& ListOfBonds = getListOfBonds();
397 for (BondList::const_iterator Runner = ListOfBonds.begin();
398 Runner != ListOfBonds.end();
399 (++Runner))
400 NoBonds += (*Runner)->getDegree();
401 return NoBonds;
402};
403
404/** Checks whether there is a bond between \a this atom and the given \a *BondPartner.
405 * @param _step time step to access
406 * \param *BondPartner atom to check for
407 * \return true - bond exists, false - bond does not exist
408 */
409bool BondedParticle::IsBondedTo(const unsigned int _step, const BondedParticle * const BondPartner) const
410{
411 bool status = false;
412
413 const BondList& ListOfBonds = getListOfBondsAtStep(_step);
414 for (BondList::const_iterator runner = ListOfBonds.begin();
415 runner != ListOfBonds.end();
416 runner++) {
417 status = status || ((*runner)->Contains(BondPartner));
418 }
419 return status;
420};
421
422std::ostream & BondedParticle::operator << (std::ostream &ost) const
423{
424 ParticleInfo::operator<<(ost);
425 ost << "," << getPosition();
426 return ost;
427}
428
429std::ostream & operator << (std::ostream &ost, const BondedParticle &a)
430{
431 a.ParticleInfo::operator<<(ost);
432 ost << "," << a.getPosition();
433 return ost;
434}
435
Note: See TracBrowser for help on using the repository browser.