source: src/Atom/atom_bondedparticle.cpp@ 31021ab

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

REFACTOR: PowerSetGenerator now creates all orders in one go, not limited to one by one increments.

  • atom_bondedparticle's MaxOrder is not a bool but an int containing the desired final order set by CheckOrderAtSite and compared to AdaptiveOrder to obtain its old meaning.
  • UniqueFragments now contains a vector of n Graphs to place n-body fragments in that are later combined. Also, cleaned up a lot of old functions and merged stuff into cstor. FreeAllOrdersList() and CombineAllOrderListIntoOne() have been adapted accordingly.
  • Fragmentation::FragmentBOSSANOVA now uses fully again FragmentLowerOrdersList which now has the above n slots to place n-body fragments in and which is passed by ref to UniqueFragments.
  • SPFragmentGenerator now always stores the current fragment, only in a specific slot in UniqueFragment's Graphs, and it recurses if there are enough SP levels and plces left.
  • FIX: BondsPerShortestPath properly prints and informs about resetting the path list.
  • We checked extra that BondFragments come out exactly as before (same order because of the Graph being a map naturally). The only difference is the OrderAtSite file which now has more than 0/1 values in the second entry.
  • Property mode set to 100644
File size: 13.4 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" << 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::ptr newBond(new bond((atom*) this, (atom*) Partner, 1));
117 RegisterBond(_step, newBond);
118 Partner->RegisterBond(_step, newBond);
119
120 return newBond;
121}
122
123/** Helper function to find the time step to a given bond in \a Binder.
124 *
125 * \param Binder bond to look for
126 * \return ListOfBonds::size() - not found, else - step containing \a Binder
127 */
128unsigned int BondedParticle::findBondsStep(bond::ptr const Binder) const
129{
130
131 size_t _step = 0;
132 for (;_step < ListOfBonds.size();++_step) {
133 const BondList& ListOfBonds = getListOfBondsAtStep(_step);
134 if (std::find(ListOfBonds.begin(), ListOfBonds.end(), Binder) != ListOfBonds.end())
135 break;
136 }
137 return _step;
138}
139
140/** Helper function to find the iterator to a bond at a given time \a step to
141 * a given bond partner in \a Partner.
142 *
143 * \param _step time step to look at
144 * \param Partner bond partner to look for
145 * \return ListOfBonds::end() - not found, else - iterator pointing \a Binder
146 */
147BondList::const_iterator BondedParticle::findBondPartnerAtStep(
148 const unsigned int _step,
149 BondedParticle * const Partner) const
150{
151 const BondList& ListOfBonds = getListOfBondsAtStep(_step);
152 BondList::const_iterator iter = std::find_if(ListOfBonds.begin(), ListOfBonds.end(),
153 boost::bind(
154 static_cast<bool (bond::*)(const ParticleInfo * const) const>(&bond::Contains),
155 _1,
156 boost::cref(Partner)));
157 return iter;
158}
159
160/** Removes a bond of this atom to a given \a Partner.
161 *
162 * @param _step time step
163 * @param Partner bond partner
164 */
165void BondedParticle::removeBond(const unsigned int _step, BondedParticle * const Partner)
166{
167 BondList::const_iterator iter = findBondPartnerAtStep(_step, Partner);
168 if (iter != getListOfBondsAtStep(_step).end()) {
169 // iter becomes invalid upon first unregister,
170 // hence store the bond someplace else first
171 bond::ptr const Binder = *iter;
172 UnregisterBond(_step, Binder);
173 Partner->UnregisterBond(_step, Binder);
174 } else
175 ELOG(1, "BondedParticle::removeBond() - I cannot find the bond in between "
176 +toString(getName())+" and "+toString(Partner->getName())+".");
177}
178
179/** Removes a bond for this atom.
180 *
181 * @param Binder bond to remove
182 */
183void BondedParticle::removeBond(bond::ptr &binder)
184{
185 if (binder != NULL) {
186 atom * const Other = binder->GetOtherAtom(this);
187 ASSERT( Other != NULL,
188 "BondedParticle::removeBonds() - cannot find bond partner for "
189 +toString(*binder)+".");
190 // find bond at step
191 unsigned int step = findBondsStep(binder);
192 if (step != ListOfBonds.size()) {
193 UnregisterBond(step, binder);
194 Other->UnregisterBond(step, binder);
195 binder.reset();
196 }
197 }
198}
199
200/** Removes all bonds in all timesteps and their instances, too.
201 *
202 */
203void BondedParticle::removeAllBonds()
204{
205 for (size_t index = 0; index < ListOfBonds.size(); ++index)
206 removeAllBonds(index);
207}
208
209/** Removes all bonds for a given \a _step and their instances, too.
210 *
211 * @param _step time step to access
212 */
213void BondedParticle::removeAllBonds(const unsigned int _step)
214{
215 //LOG(3,"INFO: Clearing all bonds of " << *this << ": " << ListOfBonds[_step]);
216 for (BondList::iterator iter = (ListOfBonds[_step]).begin();
217 !(ListOfBonds[_step]).empty();
218 iter = (ListOfBonds[_step]).begin()) {
219 //LOG(3,"INFO: Clearing bond (" << *iter << ") " << *(*iter) << " of list " << &ListOfBonds);
220 atom * const Other = (*iter)->GetOtherAtom(this);
221 ASSERT( Other != NULL,
222 "BondedParticle::removeAllBonds() - cannot find bond partner for "
223 +toString(**iter)+".");
224 Other->UnregisterBond(_step, *iter);
225 UnregisterBond(_step, *iter);
226 }
227}
228
229/** Puts a given bond into atom::ListOfBonds.
230 * @param _step time step to access
231 * \param *Binder bond to insert
232 */
233bool BondedParticle::RegisterBond(const unsigned int _step, bond::ptr const Binder)
234{
235 bool status = false;
236 if (Binder != NULL) {
237 OBSERVE;
238 if (Binder->Contains(this)) {
239 //LOG(3,"INFO: Registering bond "<< *Binder << " with atom " << *this << " at step " << _step);
240 if (ListOfBonds.size() <= _step)
241 ListOfBonds.resize(_step+1);
242 ListOfBonds[_step].push_back(Binder);
243 if (WorldTime::getTime() == _step)
244 NOTIFY(AtomObservable::BondsAdded);
245 status = true;
246 } else {
247 ELOG(1, *Binder << " does not contain " << *this << ".");
248 }
249 } else {
250 ELOG(1, "Binder is " << Binder << ".");
251 }
252 return status;
253};
254
255/** Removes a given bond from atom::ListOfBonds.
256 *
257 * \warning This only removes this atom not its bond partner, i.e.
258 * both atoms need to call this function to fully empty a bond.
259 *
260 * @param _step time step to access
261 * \param *Binder bond to remove
262 */
263bool BondedParticle::UnregisterBond(const unsigned int _step, bond::ptr const Binder)
264{
265 bool status = false;
266 if (Binder != NULL) {
267 if (Binder->Contains(this)) {
268 OBSERVE;
269 //LOG(0,"INFO: Unregistering bond "<< *Binder << " from list " << &ListOfBonds << " of atom " << *this << " at step " << step);
270#ifndef NDEBUG
271 BondList::const_iterator iter =
272 std::find(ListOfBonds[_step].begin(), ListOfBonds[_step].end(), Binder);
273 ASSERT( iter != ListOfBonds[_step].end(),
274 "BondedParticle::UnregisterBond() - "+toString(*Binder)+" not contained at "
275 +toString(_step));
276#endif
277 Binder->removeAtom(this);
278 ListOfBonds[_step].remove(Binder);
279 if (WorldTime::getTime() == _step)
280 NOTIFY(AtomObservable::BondsRemoved);
281 status = true;
282 } else {
283 ELOG(1, *Binder << " does not contain " << *this << ".");
284 }
285 } else {
286 ELOG(1, "Binder is " << Binder << ".");
287 }
288 return status;
289};
290
291/** Removes all bonds of given \a _step with freeing memory.
292 *
293 * @param _step time step whose bonds to free
294 */
295void BondedParticle::ClearBondsAtStep(const unsigned int _step)
296{
297 removeAllBonds(_step);
298}
299
300/** Searches for the time step where the given bond \a *Binder is a bond of this particle.
301 *
302 * @param Binder bond to check
303 * @return >=0 - first time step where bond appears, -1 - bond not present in lists
304 */
305int BondedParticle::ContainsBondAtStep(bond::ptr Binder) const
306{
307 int step = -1;
308 int tempstep = 0;
309 for(std::vector<BondList>::const_iterator iter = ListOfBonds.begin();
310 iter != ListOfBonds.end();
311 ++iter,++tempstep) {
312 for (BondList::const_iterator bonditer = iter->begin();
313 bonditer != iter->end();
314 ++bonditer) {
315 if ((*bonditer) == Binder) {
316 step = tempstep;
317 break;
318 }
319 }
320 if (step != -1)
321 break;
322 }
323
324 return step;
325}
326
327/** Corrects the bond degree by one at most if necessary.
328 * \return number of corrections done
329 */
330int BondedParticle::CorrectBondDegree()
331{
332 OBSERVE;
333 NOTIFY(AtomObservable::BondDegreeChanged);
334 int NoBonds = 0;
335 int OtherNoBonds = 0;
336 int FalseBondDegree = 0;
337 atom *OtherWalker = NULL;
338 bond::ptr CandidateBond;
339
340 NoBonds = CountBonds();
341 //LOG(3, "Walker " << *this << ": " << (int)this->type->NoValenceOrbitals << " > " << NoBonds << "?");
342 if ((int)(getType()->getNoValenceOrbitals()) > NoBonds) { // we have a mismatch, check all bonding partners for mismatch
343 const BondList& ListOfBonds = getListOfBonds();
344 for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); (++Runner)) {
345 OtherWalker = (*Runner)->GetOtherAtom(this);
346 OtherNoBonds = OtherWalker->CountBonds();
347 //LOG(3, "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << OtherNoBonds << "?");
348 if ((int)(OtherWalker->getType()->getNoValenceOrbitals()) > OtherNoBonds) { // check if possible candidate
349 const BondList& OtherListOfBonds = OtherWalker->getListOfBonds();
350 if ((CandidateBond == NULL) || (ListOfBonds.size() > OtherListOfBonds.size())) { // pick the one with fewer number of bonds first
351 CandidateBond = (*Runner);
352 //LOG(3, "New candidate is " << *CandidateBond << ".");
353 }
354 }
355 }
356 if ((CandidateBond != NULL)) {
357 CandidateBond->BondDegree++;
358 //LOG(2, "Increased bond degree for bond " << *CandidateBond << ".");
359 } else {
360 ELOG(2, "Could not find correct degree for atom " << *this << ".");
361 FalseBondDegree++;
362 }
363 }
364 return FalseBondDegree;
365};
366
367/** Sets the weight of all connected bonds to one.
368 */
369void BondedParticle::resetBondDegree()
370{
371 OBSERVE;
372 NOTIFY(BondedParticle::BondDegreeChanged);
373 for (std::vector<BondList>::iterator Runner = ListOfBonds.begin();
374 Runner != ListOfBonds.end();
375 ++Runner)
376 for (BondList::iterator BondRunner = (*Runner).begin();
377 BondRunner != (*Runner).end();
378 ++BondRunner)
379 (*BondRunner)->BondDegree = 1;
380};
381
382/** Counts the number of bonds weighted by bond::BondDegree.
383 * @param _step time step to access
384 * \param bonds times bond::BondDegree
385 */
386int BondedParticle::CountBonds() const
387{
388 int NoBonds = 0;
389 const BondList& ListOfBonds = getListOfBonds();
390 for (BondList::const_iterator Runner = ListOfBonds.begin();
391 Runner != ListOfBonds.end();
392 (++Runner))
393 NoBonds += (*Runner)->BondDegree;
394 return NoBonds;
395};
396
397/** Checks whether there is a bond between \a this atom and the given \a *BondPartner.
398 * @param _step time step to access
399 * \param *BondPartner atom to check for
400 * \return true - bond exists, false - bond does not exist
401 */
402bool BondedParticle::IsBondedTo(const unsigned int _step, BondedParticle * const BondPartner) const
403{
404 bool status = false;
405
406 const BondList& ListOfBonds = getListOfBondsAtStep(_step);
407 for (BondList::const_iterator runner = ListOfBonds.begin();
408 runner != ListOfBonds.end();
409 runner++) {
410 status = status || ((*runner)->Contains(BondPartner));
411 }
412 return status;
413};
414
415std::ostream & BondedParticle::operator << (std::ostream &ost) const
416{
417 ParticleInfo::operator<<(ost);
418 ost << "," << getPosition();
419 return ost;
420}
421
422std::ostream & operator << (std::ostream &ost, const BondedParticle &a)
423{
424 a.ParticleInfo::operator<<(ost);
425 ost << "," << a.getPosition();
426 return ost;
427}
428
Note: See TracBrowser for help on using the repository browser.