source: src/Atom/atom_bondedparticle.cpp@ 88c8ec

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

REFACTOR: Replaced all "bond *" appearances by bond::ptr.

  • this is preparatory for making bond::ptr a boost::shared_ptr of bond.
  • NOTE: We had to remove a const prefix at four or five places and forward declarations had to be replaced by the true inclusion of bond.hpp at tne or so files. Apart from that, the replacement has been very smooth.
  • Property mode set to 100644
File size: 11.6 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 *
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/>.
21 */
22
23/*
24 * atom_bondedparticle.cpp
25 *
26 * Created on: Oct 19, 2009
27 * Author: heber
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 <algorithm>
38#include <boost/bind.hpp>
39
40#include "atom.hpp"
41#include "atom_bondedparticle.hpp"
42#include "Bond/bond.hpp"
43#include "CodePatterns/Assert.hpp"
44#include "CodePatterns/Log.hpp"
45#include "CodePatterns/Verbose.hpp"
46#include "Element/element.hpp"
47#include "WorldTime.hpp"
48
49/** Constructor of class BondedParticle.
50 */
51BondedParticle::BondedParticle()
52{
53 ListOfBonds.push_back(BondList());
54};
55
56/** Destructor of class BondedParticle.
57 */
58BondedParticle::~BondedParticle()
59{
60 removeAllBonds();
61};
62
63/** Outputs the current atom::AdaptiveOrder and atom::MaxOrder to \a *file.
64 * \param *file output stream
65 */
66void BondedParticle::OutputOrder(ofstream *file) const
67{
68 *file << getNr() << "\t" << (int)AdaptiveOrder << "\t" << (int)MaxOrder << endl;
69 //LOG(2, "Storing: " << getNr() << "\t" << (int)AdaptiveOrder << "\t" << (int)MaxOrder << ".");
70};
71
72/** Prints all bonds of this atom with total degree.
73 */
74void BondedParticle::OutputBondOfAtom(std::ostream &ost) const
75{
76 const BondList& ListOfBonds = getListOfBonds();
77 ost << "Atom " << getName() << "/" << getNr() << " with " << ListOfBonds.size() << " bonds: ";
78 int TotalDegree = 0;
79 for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); ++Runner) {
80 ost << **Runner << "\t";
81 TotalDegree += (*Runner)->BondDegree;
82 }
83 ost << " -- TotalDegree: " << TotalDegree;
84};
85
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.
88 * \param *AdjacencyFile output stream
89 */
90void BondedParticle::OutputBonds(ofstream * const BondFile) const
91{
92 const BondList& ListOfBonds = getListOfBonds();
93 for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); (++Runner))
94 if (getNr() < (*Runner)->GetOtherAtom(this)->getNr())
95 *BondFile << getNr() << "\t" << (*Runner)->GetOtherAtom(this)->getNr() << "\n";
96};
97
98/**
99 * Adds a bond between this bonded particle and another. Returns present instance if this
100 * bond already exists.
101 *
102 * @param _step time step to access
103 * @param bonding partner
104 * @return const pointer to created bond or to already present bonds
105 */
106bond::ptr const BondedParticle::addBond(const unsigned int _step, BondedParticle* Partner)
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;
114 }
115
116 bond* newBond = new bond((atom*) this, (atom*) Partner, 1);
117 RegisterBond(_step, newBond);
118 Partner->RegisterBond(_step, newBond);
119
120 return newBond;
121}
122
123/** Removes a bond of this atom to a given \a Partner.
124 *
125 * @param _step time step
126 * @param Partner bond partner
127 */
128void BondedParticle::removeBond(const unsigned int _step, BondedParticle * const Partner)
129{
130 const BondList& ListOfBonds = getListOfBondsAtStep(_step);
131 BondList::const_iterator iter = std::find_if(ListOfBonds.begin(), ListOfBonds.end(),
132 boost::bind(
133 static_cast<bool (bond::*)(const ParticleInfo * const) const>(&bond::Contains),
134 _1,
135 boost::cref(Partner)));
136 if (iter != ListOfBonds.end()) {
137 delete *iter; //dstor takes care of unregistering and all
138 } else
139 ELOG(1, "BondedParticle::removeBond() - I cannot find the bond in between "
140 +toString(getName())+" and "+toString(Partner->getName())+".");
141}
142
143/** Removes a bond for this atom.
144 *
145 * @param Binder bond to remove
146 */
147void BondedParticle::removeBond(bond::ptr binder)
148{
149 UnregisterBond(binder);
150}
151
152/** Removes all bonds in all timesteps and their instances, too.
153 *
154 */
155void BondedParticle::removeAllBonds()
156{
157 for (size_t index = 0; index < ListOfBonds.size(); ++index)
158 removeAllBonds(index);
159}
160
161/** Removes all bonds for a given \a _step and their instances, too.
162 *
163 * @param _step time step to access
164 */
165void BondedParticle::removeAllBonds(const unsigned int _step)
166{
167 for (BondList::iterator iter = ListOfBonds[_step].begin();
168 !ListOfBonds[_step].empty();
169 iter = ListOfBonds[_step].begin()) {
170 delete (*iter);
171 // unregister/NOTIFY is done by bond::~bond()
172 }
173}
174
175/** Puts a given bond into atom::ListOfBonds.
176 * @param _step time step to access
177 * \param *Binder bond to insert
178 */
179bool BondedParticle::RegisterBond(const unsigned int _step, bond::ptr const Binder)
180{
181 OBSERVE;
182 bool status = false;
183 if (Binder != NULL) {
184 if (Binder->Contains(this)) {
185 //LOG(3,"INFO: Registering bond "<< *Binder << " with atom " << *this << " at step " << _step);
186 if (ListOfBonds.size() <= _step)
187 ListOfBonds.resize(_step+1);
188 ListOfBonds[_step].push_back(Binder);
189 if (WorldTime::getTime() == _step)
190 NOTIFY(AtomObservable::BondsAdded);
191 status = true;
192 } else {
193 ELOG(1, *Binder << " does not contain " << *this << ".");
194 }
195 } else {
196 ELOG(1, "Binder is " << Binder << ".");
197 }
198 return status;
199};
200
201/** Removes a given bond from atom::ListOfBonds.
202 * @param _step time step to access
203 * \param *Binder bond to remove
204 */
205bool BondedParticle::UnregisterBond(bond::ptr const Binder)
206{
207 OBSERVE;
208 bool status = false;
209 ASSERT(Binder != NULL, "BondedParticle::UnregisterBond() - Binder is NULL.");
210 const int step = ContainsBondAtStep(Binder);
211 if (step != -1) {
212 //LOG(0,"INFO: Unregistering bond "<< *Binder << " from list " << &ListOfBonds << " of atom " << *this << " at step " << step);
213 ListOfBonds[step].remove(Binder);
214 if (WorldTime::getTime() == step)
215 NOTIFY(AtomObservable::BondsRemoved);
216 status = true;
217 } else {
218 ELOG(1, *Binder << " does not contain " << *this << ".");
219 }
220 return status;
221};
222
223/** Removes all bonds from atom::ListOfBonds.
224 * \note Does not do any memory de-allocation.
225 */
226void BondedParticle::UnregisterAllBond(const unsigned int _step)
227{
228 OBSERVE;
229 NOTIFY(AtomObservable::BondsRemoved);
230 ListOfBonds[_step].clear();
231}
232
233/** Removes all bonds of given \a _step with freeing memory.
234 *
235 * @param _step time step whose bonds to free
236 */
237void BondedParticle::ClearBondsAtStep(const unsigned int _step)
238{
239 OBSERVE;
240 NOTIFY(AtomObservable::BondsRemoved);
241 //LOG(3,"INFO: Clearing all bonds of " << *this << ": " << ListOfBonds[_step]);
242 for (BondList::iterator iter = (ListOfBonds[_step]).begin();
243 !(ListOfBonds[_step]).empty();
244 iter = (ListOfBonds[_step]).begin()) {
245 //LOG(3,"INFO: Clearing bond (" << *iter << ") " << *(*iter) << " of list " << &ListOfBonds);
246 delete((*iter)); // will also unregister with us and remove from list
247 }
248}
249
250/** Searches for the time step where the given bond \a *Binder is a bond of this particle.
251 *
252 * @param Binder bond to check
253 * @return >=0 - first time step where bond appears, -1 - bond not present in lists
254 */
255int BondedParticle::ContainsBondAtStep(bond::ptr Binder) const
256{
257 int step = -1;
258 int tempstep = 0;
259 for(std::vector<BondList>::const_iterator iter = ListOfBonds.begin();
260 iter != ListOfBonds.end();
261 ++iter,++tempstep) {
262 for (BondList::const_iterator bonditer = iter->begin();
263 bonditer != iter->end();
264 ++bonditer) {
265 if ((*bonditer) == Binder) {
266 step = tempstep;
267 break;
268 }
269 }
270 if (step != -1)
271 break;
272 }
273
274 return step;
275}
276
277/** Corrects the bond degree by one at most if necessary.
278 * \return number of corrections done
279 */
280int BondedParticle::CorrectBondDegree()
281{
282 OBSERVE;
283 NOTIFY(AtomObservable::BondDegreeChanged);
284 int NoBonds = 0;
285 int OtherNoBonds = 0;
286 int FalseBondDegree = 0;
287 atom *OtherWalker = NULL;
288 bond::ptr CandidateBond = NULL;
289
290 NoBonds = CountBonds();
291 //LOG(3, "Walker " << *this << ": " << (int)this->type->NoValenceOrbitals << " > " << NoBonds << "?");
292 if ((int)(getType()->getNoValenceOrbitals()) > NoBonds) { // we have a mismatch, check all bonding partners for mismatch
293 const BondList& ListOfBonds = getListOfBonds();
294 for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); (++Runner)) {
295 OtherWalker = (*Runner)->GetOtherAtom(this);
296 OtherNoBonds = OtherWalker->CountBonds();
297 //LOG(3, "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << OtherNoBonds << "?");
298 if ((int)(OtherWalker->getType()->getNoValenceOrbitals()) > OtherNoBonds) { // check if possible candidate
299 const BondList& OtherListOfBonds = OtherWalker->getListOfBonds();
300 if ((CandidateBond == NULL) || (ListOfBonds.size() > OtherListOfBonds.size())) { // pick the one with fewer number of bonds first
301 CandidateBond = (*Runner);
302 //LOG(3, "New candidate is " << *CandidateBond << ".");
303 }
304 }
305 }
306 if ((CandidateBond != NULL)) {
307 CandidateBond->BondDegree++;
308 //LOG(2, "Increased bond degree for bond " << *CandidateBond << ".");
309 } else {
310 ELOG(2, "Could not find correct degree for atom " << *this << ".");
311 FalseBondDegree++;
312 }
313 }
314 return FalseBondDegree;
315};
316
317/** Sets the weight of all connected bonds to one.
318 */
319void BondedParticle::resetBondDegree()
320{
321 OBSERVE;
322 NOTIFY(BondedParticle::BondDegreeChanged);
323 for (std::vector<BondList>::iterator Runner = ListOfBonds.begin();
324 Runner != ListOfBonds.end();
325 ++Runner)
326 for (BondList::iterator BondRunner = (*Runner).begin();
327 BondRunner != (*Runner).end();
328 ++BondRunner)
329 (*BondRunner)->BondDegree = 1;
330};
331
332/** Counts the number of bonds weighted by bond::BondDegree.
333 * @param _step time step to access
334 * \param bonds times bond::BondDegree
335 */
336int BondedParticle::CountBonds() const
337{
338 int NoBonds = 0;
339 const BondList& ListOfBonds = getListOfBonds();
340 for (BondList::const_iterator Runner = ListOfBonds.begin();
341 Runner != ListOfBonds.end();
342 (++Runner))
343 NoBonds += (*Runner)->BondDegree;
344 return NoBonds;
345};
346
347/** Checks whether there is a bond between \a this atom and the given \a *BondPartner.
348 * @param _step time step to access
349 * \param *BondPartner atom to check for
350 * \return true - bond exists, false - bond does not exist
351 */
352bool BondedParticle::IsBondedTo(const unsigned int _step, BondedParticle * const BondPartner) const
353{
354 bool status = false;
355
356 const BondList& ListOfBonds = getListOfBondsAtStep(_step);
357 for (BondList::const_iterator runner = ListOfBonds.begin();
358 runner != ListOfBonds.end();
359 runner++) {
360 status = status || ((*runner)->Contains(BondPartner));
361 }
362 return status;
363};
364
365std::ostream & BondedParticle::operator << (std::ostream &ost) const
366{
367 ParticleInfo::operator<<(ost);
368 ost << "," << getPosition();
369 return ost;
370}
371
372std::ostream & operator << (std::ostream &ost, const BondedParticle &a)
373{
374 a.ParticleInfo::operator<<(ost);
375 ost << "," << a.getPosition();
376 return ost;
377}
378
Note: See TracBrowser for help on using the repository browser.