source: src/Atom/atom_bondedparticle.cpp@ 69f38a

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 69f38a was d948b4, checked in by Frederik Heber <heber@…>, 12 years ago

atom_bondedparticle::addBond() returns no longer const bond::ptr.

  • this comes in the way when we want to set the bond degree right away.
  • also added convenience functions for addBond() and removedBond() that act on the current time step.
  • Property mode set to 100644
File size: 13.9 KB
RevLine 
[bcf653]1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
[0aa122]4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
[94d5ac6]5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
[bcf653]21 */
22
[6b919f8]23/*
24 * atom_bondedparticle.cpp
25 *
26 * Created on: Oct 19, 2009
27 * Author: heber
28 */
29
[bf3817]30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
[ad011c]35#include "CodePatterns/MemDebug.hpp"
[112b09]36
[f63e41]37#include <algorithm>
38#include <boost/bind.hpp>
39
[6b919f8]40#include "atom.hpp"
41#include "atom_bondedparticle.hpp"
[129204]42#include "Bond/bond.hpp"
[d557374]43#include "CodePatterns/Assert.hpp"
[ad011c]44#include "CodePatterns/Log.hpp"
45#include "CodePatterns/Verbose.hpp"
[3bdb6d]46#include "Element/element.hpp"
[db7e6d]47#include "WorldTime.hpp"
[6b919f8]48
49/** Constructor of class BondedParticle.
50 */
[70ff32]51BondedParticle::BondedParticle()
52{
[9d83b6]53 ListOfBonds.push_back(BondList());
[70ff32]54};
[6b919f8]55
56/** Destructor of class BondedParticle.
57 */
58BondedParticle::~BondedParticle()
59{
[5e2f80]60 removeAllBonds();
[6b919f8]61};
62
63/** Outputs the current atom::AdaptiveOrder and atom::MaxOrder to \a *file.
64 * \param *file output stream
65 */
[b453f9]66void BondedParticle::OutputOrder(ofstream *file) const
[6b919f8]67{
[735b1c]68 *file << getNr() << "\t" << (int)AdaptiveOrder << "\t" << (int)MaxOrder << endl;
[d760bb]69 //LOG(2, "Storing: " << getNr() << "\t" << (int)AdaptiveOrder << "\t" << MaxOrder << ".");
[6b919f8]70};
71
72/** Prints all bonds of this atom with total degree.
73 */
[4b5cf8]74void BondedParticle::OutputBondOfAtom(std::ostream &ost) const
[6b919f8]75{
[9d83b6]76 const BondList& ListOfBonds = getListOfBonds();
[4b5cf8]77 ost << "Atom " << getName() << "/" << getNr() << " with " << ListOfBonds.size() << " bonds: ";
[e138de]78 int TotalDegree = 0;
79 for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); ++Runner) {
[4b5cf8]80 ost << **Runner << "\t";
[e138de]81 TotalDegree += (*Runner)->BondDegree;
82 }
[4b5cf8]83 ost << " -- TotalDegree: " << TotalDegree;
[6b919f8]84};
85
[5309ba]86/** Output of atom::Nr along each bond partner per line.
87 * Only bonds are printed where atom::Nr is smaller than the one of the bond partner.
[1f1b23]88 * \param *AdjacencyFile output stream
89 */
90void BondedParticle::OutputBonds(ofstream * const BondFile) const
91{
[9d83b6]92 const BondList& ListOfBonds = getListOfBonds();
[1f1b23]93 for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); (++Runner))
[735b1c]94 if (getNr() < (*Runner)->GetOtherAtom(this)->getNr())
[52ed5b]95 *BondFile << getNr() << "\t" << (*Runner)->GetOtherAtom(this)->getNr() << "\n";
[1f1b23]96};
97
[b8d4a3]98/**
[db7e6d]99 * Adds a bond between this bonded particle and another. Returns present instance if this
[b8d4a3]100 * bond already exists.
101 *
[073a9e4]102 * @param _step time step to access
[db7e6d]103 * @param bonding partner
[d948b4]104 * @return pointer to created bond or to already present bonds
[b8d4a3]105 */
[d948b4]106bond::ptr BondedParticle::addBond(const unsigned int _step, BondedParticle* Partner)
[db7e6d]107{
108 const BondList &bondlist = getListOfBondsAtStep(_step);
109 for (BondList::const_iterator runner = bondlist.begin();
110 runner != bondlist.end();
111 runner++) {
112 if ((*runner)->Contains(Partner))
113 return *runner;
[b8d4a3]114 }
115
[7d82a5]116 bond::ptr newBond(new bond((atom*) this, (atom*) Partner, 1));
[073a9e4]117 RegisterBond(_step, newBond);
118 Partner->RegisterBond(_step, newBond);
[db7e6d]119
120 return newBond;
121}
122
[d948b4]123/**
124 * Adds a bond between this bonded particle and another. Returns present instance if this
125 * bond already exists.
126 *
127 * @param bonding partner
128 * @return pointer to created bond or to already present bonds
129 */
130bond::ptr BondedParticle::addBond(BondedParticle* Partner)
131{
132 addBond(WorldTime::getTime(), Partner);
133}
134
[7d82a5]135/** Helper function to find the time step to a given bond in \a Binder.
[f63e41]136 *
[7d82a5]137 * \param Binder bond to look for
138 * \return ListOfBonds::size() - not found, else - step containing \a Binder
[f63e41]139 */
[7d82a5]140unsigned int BondedParticle::findBondsStep(bond::ptr const Binder) const
141{
142
143 size_t _step = 0;
144 for (;_step < ListOfBonds.size();++_step) {
145 const BondList& ListOfBonds = getListOfBondsAtStep(_step);
146 if (std::find(ListOfBonds.begin(), ListOfBonds.end(), Binder) != ListOfBonds.end())
147 break;
148 }
149 return _step;
150}
151
152/** Helper function to find the iterator to a bond at a given time \a step to
153 * a given bond partner in \a Partner.
154 *
155 * \param _step time step to look at
156 * \param Partner bond partner to look for
157 * \return ListOfBonds::end() - not found, else - iterator pointing \a Binder
158 */
159BondList::const_iterator BondedParticle::findBondPartnerAtStep(
160 const unsigned int _step,
161 BondedParticle * const Partner) const
[f63e41]162{
163 const BondList& ListOfBonds = getListOfBondsAtStep(_step);
164 BondList::const_iterator iter = std::find_if(ListOfBonds.begin(), ListOfBonds.end(),
165 boost::bind(
166 static_cast<bool (bond::*)(const ParticleInfo * const) const>(&bond::Contains),
167 _1,
168 boost::cref(Partner)));
[7d82a5]169 return iter;
170}
171
172/** Removes a bond of this atom to a given \a Partner.
173 *
174 * @param _step time step
175 * @param Partner bond partner
176 */
177void BondedParticle::removeBond(const unsigned int _step, BondedParticle * const Partner)
178{
179 BondList::const_iterator iter = findBondPartnerAtStep(_step, Partner);
180 if (iter != getListOfBondsAtStep(_step).end()) {
181 // iter becomes invalid upon first unregister,
182 // hence store the bond someplace else first
183 bond::ptr const Binder = *iter;
184 UnregisterBond(_step, Binder);
185 Partner->UnregisterBond(_step, Binder);
[f63e41]186 } else
187 ELOG(1, "BondedParticle::removeBond() - I cannot find the bond in between "
188 +toString(getName())+" and "+toString(Partner->getName())+".");
189}
190
[d948b4]191/** Removes a bond of this atom to a given \a Partner.
192 *
193 * @param Partner bond partner
194 */
195void BondedParticle::removeBond(BondedParticle * const Partner)
196{
197 removeBond(WorldTime::getTime(), Partner);
198}
199
[db7e6d]200/** Removes a bond for this atom.
201 *
202 * @param Binder bond to remove
203 */
[7d82a5]204void BondedParticle::removeBond(bond::ptr &binder)
[db7e6d]205{
[7d82a5]206 if (binder != NULL) {
207 atom * const Other = binder->GetOtherAtom(this);
208 ASSERT( Other != NULL,
209 "BondedParticle::removeBonds() - cannot find bond partner for "
210 +toString(*binder)+".");
211 // find bond at step
212 unsigned int step = findBondsStep(binder);
213 if (step != ListOfBonds.size()) {
214 UnregisterBond(step, binder);
215 Other->UnregisterBond(step, binder);
216 binder.reset();
217 }
218 }
[b8d4a3]219}
220
[cc9119]221/** Removes all bonds in all timesteps and their instances, too.
[5e2f80]222 *
223 */
224void BondedParticle::removeAllBonds()
225{
226 for (size_t index = 0; index < ListOfBonds.size(); ++index)
[cc9119]227 removeAllBonds(index);
228}
229
230/** Removes all bonds for a given \a _step and their instances, too.
231 *
232 * @param _step time step to access
233 */
234void BondedParticle::removeAllBonds(const unsigned int _step)
235{
[7d82a5]236 //LOG(3,"INFO: Clearing all bonds of " << *this << ": " << ListOfBonds[_step]);
237 for (BondList::iterator iter = (ListOfBonds[_step]).begin();
238 !(ListOfBonds[_step]).empty();
239 iter = (ListOfBonds[_step]).begin()) {
240 //LOG(3,"INFO: Clearing bond (" << *iter << ") " << *(*iter) << " of list " << &ListOfBonds);
241 atom * const Other = (*iter)->GetOtherAtom(this);
242 ASSERT( Other != NULL,
243 "BondedParticle::removeAllBonds() - cannot find bond partner for "
244 +toString(**iter)+".");
245 Other->UnregisterBond(_step, *iter);
246 UnregisterBond(_step, *iter);
[5e2f80]247 }
248}
249
[6b919f8]250/** Puts a given bond into atom::ListOfBonds.
[073a9e4]251 * @param _step time step to access
[6b919f8]252 * \param *Binder bond to insert
253 */
[88c8ec]254bool BondedParticle::RegisterBond(const unsigned int _step, bond::ptr const Binder)
[6b919f8]255{
256 bool status = false;
257 if (Binder != NULL) {
[7d82a5]258 OBSERVE;
[6b919f8]259 if (Binder->Contains(this)) {
[d557374]260 //LOG(3,"INFO: Registering bond "<< *Binder << " with atom " << *this << " at step " << _step);
[5e2f80]261 if (ListOfBonds.size() <= _step)
262 ListOfBonds.resize(_step+1);
263 ListOfBonds[_step].push_back(Binder);
[74ec1f]264 if (WorldTime::getTime() == _step)
[2ad1ec]265 NOTIFY(AtomObservable::BondsAdded);
[6b919f8]266 status = true;
267 } else {
[47d041]268 ELOG(1, *Binder << " does not contain " << *this << ".");
[6b919f8]269 }
270 } else {
[47d041]271 ELOG(1, "Binder is " << Binder << ".");
[6b919f8]272 }
273 return status;
274};
275
276/** Removes a given bond from atom::ListOfBonds.
[7d82a5]277 *
278 * \warning This only removes this atom not its bond partner, i.e.
279 * both atoms need to call this function to fully empty a bond.
280 *
[9d83b6]281 * @param _step time step to access
[6b919f8]282 * \param *Binder bond to remove
283 */
[7d82a5]284bool BondedParticle::UnregisterBond(const unsigned int _step, bond::ptr const Binder)
[6b919f8]285{
286 bool status = false;
[7d82a5]287 if (Binder != NULL) {
288 if (Binder->Contains(this)) {
289 OBSERVE;
290 //LOG(0,"INFO: Unregistering bond "<< *Binder << " from list " << &ListOfBonds << " of atom " << *this << " at step " << step);
291#ifndef NDEBUG
292 BondList::const_iterator iter =
293 std::find(ListOfBonds[_step].begin(), ListOfBonds[_step].end(), Binder);
294 ASSERT( iter != ListOfBonds[_step].end(),
295 "BondedParticle::UnregisterBond() - "+toString(*Binder)+" not contained at "
296 +toString(_step));
297#endif
298 Binder->removeAtom(this);
299 ListOfBonds[_step].remove(Binder);
300 if (WorldTime::getTime() == _step)
301 NOTIFY(AtomObservable::BondsRemoved);
302 status = true;
303 } else {
304 ELOG(1, *Binder << " does not contain " << *this << ".");
305 }
[6b919f8]306 } else {
[7d82a5]307 ELOG(1, "Binder is " << Binder << ".");
[6b919f8]308 }
309 return status;
310};
311
[583081]312/** Removes all bonds of given \a _step with freeing memory.
313 *
314 * @param _step time step whose bonds to free
315 */
316void BondedParticle::ClearBondsAtStep(const unsigned int _step)
317{
[7d82a5]318 removeAllBonds(_step);
[583081]319}
320
[93c6e9]321/** Searches for the time step where the given bond \a *Binder is a bond of this particle.
322 *
323 * @param Binder bond to check
324 * @return >=0 - first time step where bond appears, -1 - bond not present in lists
325 */
[88c8ec]326int BondedParticle::ContainsBondAtStep(bond::ptr Binder) const
[93c6e9]327{
328 int step = -1;
329 int tempstep = 0;
330 for(std::vector<BondList>::const_iterator iter = ListOfBonds.begin();
331 iter != ListOfBonds.end();
332 ++iter,++tempstep) {
333 for (BondList::const_iterator bonditer = iter->begin();
334 bonditer != iter->end();
335 ++bonditer) {
336 if ((*bonditer) == Binder) {
337 step = tempstep;
338 break;
339 }
340 }
341 if (step != -1)
342 break;
343 }
344
345 return step;
346}
347
[6b919f8]348/** Corrects the bond degree by one at most if necessary.
[93c6e9]349 * \return number of corrections done
[6b919f8]350 */
[e138de]351int BondedParticle::CorrectBondDegree()
[6b919f8]352{
[db7e6d]353 OBSERVE;
[74ec1f]354 NOTIFY(AtomObservable::BondDegreeChanged);
[6b919f8]355 int NoBonds = 0;
356 int OtherNoBonds = 0;
357 int FalseBondDegree = 0;
358 atom *OtherWalker = NULL;
[7d82a5]359 bond::ptr CandidateBond;
[6b919f8]360
361 NoBonds = CountBonds();
[47d041]362 //LOG(3, "Walker " << *this << ": " << (int)this->type->NoValenceOrbitals << " > " << NoBonds << "?");
[83f176]363 if ((int)(getType()->getNoValenceOrbitals()) > NoBonds) { // we have a mismatch, check all bonding partners for mismatch
[9d83b6]364 const BondList& ListOfBonds = getListOfBonds();
[6b919f8]365 for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); (++Runner)) {
366 OtherWalker = (*Runner)->GetOtherAtom(this);
367 OtherNoBonds = OtherWalker->CountBonds();
[47d041]368 //LOG(3, "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << OtherNoBonds << "?");
[83f176]369 if ((int)(OtherWalker->getType()->getNoValenceOrbitals()) > OtherNoBonds) { // check if possible candidate
[9d83b6]370 const BondList& OtherListOfBonds = OtherWalker->getListOfBonds();
371 if ((CandidateBond == NULL) || (ListOfBonds.size() > OtherListOfBonds.size())) { // pick the one with fewer number of bonds first
[6b919f8]372 CandidateBond = (*Runner);
[47d041]373 //LOG(3, "New candidate is " << *CandidateBond << ".");
[6b919f8]374 }
375 }
376 }
377 if ((CandidateBond != NULL)) {
378 CandidateBond->BondDegree++;
[47d041]379 //LOG(2, "Increased bond degree for bond " << *CandidateBond << ".");
[6b919f8]380 } else {
[47d041]381 ELOG(2, "Could not find correct degree for atom " << *this << ".");
[6b919f8]382 FalseBondDegree++;
383 }
384 }
385 return FalseBondDegree;
386};
387
[5e2f80]388/** Sets the weight of all connected bonds to one.
389 */
390void BondedParticle::resetBondDegree()
391{
392 OBSERVE;
[74ec1f]393 NOTIFY(BondedParticle::BondDegreeChanged);
[5e2f80]394 for (std::vector<BondList>::iterator Runner = ListOfBonds.begin();
395 Runner != ListOfBonds.end();
396 ++Runner)
397 for (BondList::iterator BondRunner = (*Runner).begin();
398 BondRunner != (*Runner).end();
399 ++BondRunner)
400 (*BondRunner)->BondDegree = 1;
401};
402
[c0d9eb]403/** Counts the number of bonds weighted by bond::BondDegree.
404 * @param _step time step to access
405 * \param bonds times bond::BondDegree
406 */
407int BondedParticle::CountBonds() const
408{
409 int NoBonds = 0;
[9d83b6]410 const BondList& ListOfBonds = getListOfBonds();
[c0d9eb]411 for (BondList::const_iterator Runner = ListOfBonds.begin();
412 Runner != ListOfBonds.end();
413 (++Runner))
414 NoBonds += (*Runner)->BondDegree;
415 return NoBonds;
416};
417
[b70721]418/** Checks whether there is a bond between \a this atom and the given \a *BondPartner.
[073a9e4]419 * @param _step time step to access
[b70721]420 * \param *BondPartner atom to check for
421 * \return true - bond exists, false - bond does not exist
422 */
[073a9e4]423bool BondedParticle::IsBondedTo(const unsigned int _step, BondedParticle * const BondPartner) const
[b70721]424{
425 bool status = false;
426
[073a9e4]427 const BondList& ListOfBonds = getListOfBondsAtStep(_step);
428 for (BondList::const_iterator runner = ListOfBonds.begin();
429 runner != ListOfBonds.end();
430 runner++) {
[b70721]431 status = status || ((*runner)->Contains(BondPartner));
432 }
433 return status;
434};
435
[d74077]436std::ostream & BondedParticle::operator << (std::ostream &ost) const
437{
438 ParticleInfo::operator<<(ost);
439 ost << "," << getPosition();
440 return ost;
441}
442
443std::ostream & operator << (std::ostream &ost, const BondedParticle &a)
444{
445 a.ParticleInfo::operator<<(ost);
446 ost << "," << a.getPosition();
447 return ost;
448}
449
Note: See TracBrowser for help on using the repository browser.