source: src/Atom/atom_bondedparticle.cpp@ ca09be

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 ca09be was 8cc22f, checked in by Frederik Heber <heber@…>, 11 years ago

Changed how trajectories are stored, not as vecor but as map.

  • Property mode set to 100644
File size: 12.3 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)AdaptiveOrder << "\t" << (int)MaxOrder << endl;
74 //LOG(2, "Storing: " << getNr() << "\t" << (int)AdaptiveOrder << "\t" << MaxOrder << ".");
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* 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 * Adds a bond between this bonded particle and another. Returns present instance if this
130 * bond already exists.
131 *
132 * @param bonding partner
133 * @return pointer to created bond or to already present bonds
134 */
135bond::ptr BondedParticle::addBond(BondedParticle* Partner)
136{
137 return addBond(WorldTime::getTime(), Partner);
138}
139
140/** Helper function to find the time step to a given bond in \a Binder.
141 *
142 * \param Binder bond to look for
143 * \return ListOfBonds::size() - not found, else - step containing \a Binder
144 */
145unsigned int BondedParticle::findBondsStep(bond::ptr const Binder) const
146{
147
148 size_t _step = 0;
149 for (;_step < ListOfBonds.size();++_step) {
150 const BondList& ListOfBonds = getListOfBondsAtStep(_step);
151 if (std::find(ListOfBonds.begin(), ListOfBonds.end(), Binder) != ListOfBonds.end())
152 break;
153 }
154 return _step;
155}
156
157/** Helper function to find the iterator to a bond at a given time \a step to
158 * a given bond partner in \a Partner.
159 *
160 * \param _step time step to look at
161 * \param Partner bond partner to look for
162 * \return ListOfBonds::end() - not found, else - iterator pointing \a Binder
163 */
164BondList::const_iterator BondedParticle::findBondPartnerAtStep(
165 const unsigned int _step,
166 BondedParticle * const Partner) const
167{
168 const BondList& ListOfBonds = getListOfBondsAtStep(_step);
169 BondList::const_iterator iter = std::find_if(ListOfBonds.begin(), ListOfBonds.end(),
170 boost::bind(
171 static_cast<bool (bond::*)(const ParticleInfo * const) const>(&bond::Contains),
172 _1,
173 boost::cref(Partner)));
174 return iter;
175}
176
177/** Removes a bond of this atom to a given \a Partner.
178 *
179 * @param _step time step
180 * @param Partner bond partner
181 */
182void BondedParticle::removeBond(const unsigned int _step, BondedParticle * const Partner)
183{
184 BondList::const_iterator iter = findBondPartnerAtStep(_step, Partner);
185 if (iter != getListOfBondsAtStep(_step).end()) {
186 // iter becomes invalid upon first unregister,
187 // hence store the bond someplace else first
188 bond::ptr const Binder = *iter;
189 UnregisterBond(_step, Binder);
190 Partner->UnregisterBond(_step, Binder);
191 } else
192 ELOG(1, "BondedParticle::removeBond() - I cannot find the bond in between "
193 +toString(getName())+" and "+toString(Partner->getName())+".");
194}
195
196/** Removes a bond of this atom to a given \a Partner.
197 *
198 * @param Partner bond partner
199 */
200void BondedParticle::removeBond(BondedParticle * const Partner)
201{
202 removeBond(WorldTime::getTime(), Partner);
203}
204
205/** Removes a bond for this atom.
206 *
207 * @param Binder bond to remove
208 */
209void BondedParticle::removeBond(bond::ptr &binder)
210{
211 if (binder != NULL) {
212 atom * const Other = binder->GetOtherAtom(this);
213 ASSERT( Other != NULL,
214 "BondedParticle::removeBonds() - cannot find bond partner for "
215 +toString(*binder)+".");
216 // find bond at step
217 unsigned int step = findBondsStep(binder);
218 if (step != ListOfBonds.size()) {
219 UnregisterBond(step, binder);
220 Other->UnregisterBond(step, binder);
221 binder.reset();
222 }
223 }
224}
225
226/** Removes all bonds in current timestep and their instances, too.
227 *
228 */
229void BondedParticle::removeAllBonds()
230{
231 removeAllBonds(WorldTime::getTime());
232}
233
234/** Removes all bonds for a given \a _step and their instances, too.
235 *
236 * @param _step time step to access
237 */
238void BondedParticle::removeAllBonds(const unsigned int _step)
239{
240 //LOG(3,"INFO: Clearing all bonds of " << *this << ": " << ListOfBonds[_step]);
241 BondTrajectory_t::iterator listiter = ListOfBonds.find(_step);
242 if (listiter != ListOfBonds.end())
243 for (BondList::iterator iter = listiter->second.begin();
244 !listiter->second.empty();
245 iter = listiter->second.begin()) {
246 //LOG(3,"INFO: Clearing bond (" << *iter << ") " << *(*iter) << " of list " << &ListOfBonds);
247 atom * const Other = (*iter)->GetOtherAtom(this);
248 ASSERT( Other != NULL,
249 "BondedParticle::removeAllBonds() - cannot find bond partner for "
250 +toString(**iter)+".");
251 Other->UnregisterBond(_step, *iter);
252 UnregisterBond(_step, *iter);
253 }
254}
255
256/** Puts a given bond into atom::ListOfBonds.
257 * @param _step time step to access
258 * \param *Binder bond to insert
259 */
260bool BondedParticle::RegisterBond(const unsigned int _step, bond::ptr const Binder)
261{
262 bool status = false;
263 if (Binder != NULL) {
264 OBSERVE;
265 if (Binder->Contains(this)) {
266 //LOG(3,"INFO: Registering bond "<< *Binder << " with atom " << *this << " at step " << _step);
267 std::pair< BondTrajectory_t::iterator, bool> inserter =
268 ListOfBonds.insert( std::make_pair( _step, BondList(1, Binder)) );
269 if (!inserter.second)
270 inserter.first->second.push_back(Binder);
271 if (WorldTime::getTime() == _step)
272 NOTIFY(AtomObservable::BondsAdded);
273 status = true;
274 } else {
275 ELOG(1, *Binder << " does not contain " << *this << ".");
276 }
277 } else {
278 ELOG(1, "Binder is " << Binder << ".");
279 }
280 return status;
281};
282
283/** Removes a given bond from atom::ListOfBonds.
284 *
285 * \warning This only removes this atom not its bond partner, i.e.
286 * both atoms need to call this function to fully empty a bond.
287 *
288 * @param _step time step to access
289 * \param *Binder bond to remove
290 */
291bool BondedParticle::UnregisterBond(const unsigned int _step, bond::ptr const Binder)
292{
293 bool status = false;
294 if (Binder != NULL) {
295 if (Binder->Contains(this)) {
296 OBSERVE;
297 //LOG(0,"INFO: Unregistering bond "<< *Binder << " from list " << &ListOfBonds << " of atom " << *this << " at step " << step);
298 BondTrajectory_t::iterator listiter = ListOfBonds.find(_step);
299 if (listiter != ListOfBonds.end()) {
300#ifndef NDEBUG
301 BondList::const_iterator iter =
302 std::find(listiter->second.begin(), listiter->second.end(), Binder);
303 ASSERT( iter != listiter->second.end(),
304 "BondedParticle::UnregisterBond() - "+toString(*Binder)+" not contained at "
305 +toString(_step));
306#endif
307 Binder->removeAtom(this);
308 listiter->second.remove(Binder);
309 if (WorldTime::getTime() == _step)
310 NOTIFY(AtomObservable::BondsRemoved);
311 status = true;
312 }
313 } else {
314 ELOG(1, *Binder << " does not contain " << *this << ".");
315 }
316 } else {
317 ELOG(1, "Binder is " << Binder << ".");
318 }
319 return status;
320};
321
322/** Removes all bonds of given \a _step with freeing memory.
323 *
324 * @param _step time step whose bonds to free
325 */
326void BondedParticle::ClearBondsAtStep(const unsigned int _step)
327{
328 removeAllBonds(_step);
329}
330
331/** Searches for the time step where the given bond \a *Binder is a bond of this particle.
332 *
333 * @param Binder bond to check
334 * @return >=0 - first time step where bond appears, -1 - bond not present in lists
335 */
336int BondedParticle::ContainsBondAtStep(bond::ptr Binder) const
337{
338 int step = -1;
339 for(BondTrajectory_t::const_iterator listiter = ListOfBonds.begin();
340 listiter != ListOfBonds.end();
341 ++listiter) {
342 for (BondList::const_iterator bonditer = listiter->second.begin();
343 bonditer != listiter->second.end();
344 ++bonditer) {
345 if ((*bonditer) == Binder) {
346 step = listiter->first;
347 break;
348 }
349 }
350 if (step != -1)
351 break;
352 }
353
354 return step;
355}
356
357/** Counts the number of bonds weighted by bond::BondDegree.
358 * @param _step time step to access
359 * \param bonds times bond::BondDegree
360 */
361int BondedParticle::CountBonds() const
362{
363 int NoBonds = 0;
364 const BondList& ListOfBonds = getListOfBonds();
365 for (BondList::const_iterator Runner = ListOfBonds.begin();
366 Runner != ListOfBonds.end();
367 (++Runner))
368 NoBonds += (*Runner)->getDegree();
369 return NoBonds;
370};
371
372/** Checks whether there is a bond between \a this atom and the given \a *BondPartner.
373 * @param _step time step to access
374 * \param *BondPartner atom to check for
375 * \return true - bond exists, false - bond does not exist
376 */
377bool BondedParticle::IsBondedTo(const unsigned int _step, BondedParticle * const BondPartner) const
378{
379 bool status = false;
380
381 const BondList& ListOfBonds = getListOfBondsAtStep(_step);
382 for (BondList::const_iterator runner = ListOfBonds.begin();
383 runner != ListOfBonds.end();
384 runner++) {
385 status = status || ((*runner)->Contains(BondPartner));
386 }
387 return status;
388};
389
390std::ostream & BondedParticle::operator << (std::ostream &ost) const
391{
392 ParticleInfo::operator<<(ost);
393 ost << "," << getPosition();
394 return ost;
395}
396
397std::ostream & operator << (std::ostream &ost, const BondedParticle &a)
398{
399 a.ParticleInfo::operator<<(ost);
400 ost << "," << a.getPosition();
401 return ost;
402}
403
Note: See TracBrowser for help on using the repository browser.