source: src/Atom/atom_atominfo.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: 17.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 * Copyright (C) 2014 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_atominfo.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 "CodePatterns/Verbose.hpp"
39
40#include "atom_atominfo.hpp"
41#include "CodePatterns/Log.hpp"
42#include "config.hpp"
43#include "Element/element.hpp"
44#include "Element/periodentafel.hpp"
45#include "Fragmentation/ForceMatrix.hpp"
46#include "World.hpp"
47#include "WorldTime.hpp"
48
49#include <iomanip>
50
51/** Constructor of class AtomInfo.
52 */
53AtomInfo::AtomInfo() :
54 AtomicElement(1),
55 FixedIon(false),
56 charge(0.)
57{
58 AtomicPosition.insert( std::make_pair(0, zeroVec) );
59 AtomicVelocity.insert( std::make_pair(0, zeroVec) );
60 AtomicForce.insert( std::make_pair(0, zeroVec) );
61}
62
63/** Copy constructor of class AtomInfo.
64 */
65AtomInfo::AtomInfo(const AtomInfo &_atom) :
66 AtomicPosition(_atom.AtomicPosition),
67 AtomicVelocity(_atom.AtomicVelocity),
68 AtomicForce(_atom.AtomicForce),
69 AtomicElement(_atom.AtomicElement),
70 FixedIon(_atom.FixedIon),
71 charge(_atom.charge)
72{
73}
74
75AtomInfo::AtomInfo(const VectorInterface &_v) :
76 AtomicElement(1),
77 FixedIon(false),
78 charge(0.)
79{
80 AtomicPosition.insert( std::make_pair(0, _v.getPosition()) );
81 AtomicVelocity.insert( std::make_pair(0, zeroVec) );
82 AtomicForce.insert( std::make_pair(0, zeroVec) );
83};
84
85/** Destructor of class AtomInfo.
86 */
87AtomInfo::~AtomInfo()
88{
89};
90
91void AtomInfo::AppendTrajectoryStep(const unsigned int _step)
92{
93 if (WorldTime::getTime() == _step)
94 NOTIFY(TrajectoryChanged);
95 AtomicPosition.insert( std::make_pair(_step, zeroVec) );
96 AtomicVelocity.insert( std::make_pair(_step, zeroVec) );
97 AtomicForce.insert( std::make_pair(_step, zeroVec) );
98 LOG(5,"AtomInfo::AppendTrajectoryStep() called, size is ("
99 << AtomicPosition.size() << ","
100 << AtomicVelocity.size() << ","
101 << AtomicForce.size() << ")");
102}
103
104void AtomInfo::removeTrajectoryStep(const unsigned int _step)
105{
106 if (WorldTime::getTime() == _step)
107 NOTIFY(TrajectoryChanged);
108 AtomicPosition.erase(_step);
109 AtomicVelocity.erase(_step);
110 AtomicForce.erase(_step);
111 LOG(5,"AtomInfo::removeTrajectoryStep() called, size is ("
112 << AtomicPosition.size() << ","
113 << AtomicVelocity.size() << ","
114 << AtomicForce.size() << ")");
115}
116
117const element *AtomInfo::getType() const
118{
119 const element *elem = World::getInstance().getPeriode()->FindElement(AtomicElement);
120 return elem;
121}
122
123const element &AtomInfo::getElement() const
124{
125 const element &elem = *World::getInstance().getPeriode()->FindElement(AtomicElement);
126 return elem;
127}
128
129atomicNumber_t AtomInfo::getElementNo() const
130{
131 return AtomicElement;
132}
133
134const double& AtomInfo::operator[](size_t i) const
135{
136 return atStep(i, WorldTime::getTime());
137}
138
139const double& AtomInfo::at(size_t i) const
140{
141 return atStep(i, WorldTime::getTime());
142}
143
144const double& AtomInfo::atStep(size_t i, unsigned int _step) const
145{
146 ASSERT(!AtomicPosition.empty(),
147 "AtomInfo::operator[]() - AtomicPosition is empty.");
148 VectorTrajectory_t::const_iterator iter =
149 AtomicPosition.lower_bound(_step);
150 return iter->second[i];
151}
152
153void AtomInfo::set(size_t i, const double value)
154{
155 OBSERVE;
156 NOTIFY(AtomObservable::PositionChanged);
157 VectorTrajectory_t::iterator iter = AtomicPosition.find(WorldTime::getTime());
158 if (iter != AtomicPosition.end()) {
159 iter->second[i] = value;
160 } else {
161 Vector newPos;
162 newPos[i] = value;
163#ifndef NDEBUG
164 std::pair<VectorTrajectory_t::iterator, bool> inserter =
165#endif
166 AtomicPosition.insert( std::make_pair(WorldTime::getTime(), newPos) );
167 ASSERT( inserter.second,
168 "AtomInfo::set() - time step "+toString(WorldTime::getTime())
169 +" present after all?");
170 }
171}
172
173/** Helps to determine whether the current step really exists or getPosition() has just
174 * delivered the one closest to it in the past.
175 *
176 * \param _step step to check
177 * \param true - step exists, false - step does not exist, getPosition() delivers closest
178 */
179bool AtomInfo::isStepPresent(const unsigned int _step) const
180{
181 VectorTrajectory_t::const_iterator iter =
182 AtomicPosition.find(_step);
183 return iter != AtomicPosition.end();
184}
185
186const Vector& AtomInfo::getPosition() const
187{
188 return getPositionAtStep(WorldTime::getTime());
189}
190
191const Vector& AtomInfo::getPositionAtStep(const unsigned int _step) const
192{
193 ASSERT(!AtomicPosition.empty(),
194 "AtomInfo::operator[]() - AtomicPosition is empty.");
195 VectorTrajectory_t::const_iterator iter =
196 AtomicPosition.lower_bound(_step);
197 return iter->second;
198}
199
200void AtomInfo::setType(const element* _type)
201{
202 if (_type->getAtomicNumber() != AtomicElement) {
203 OBSERVE;
204 NOTIFY(AtomObservable::ElementChanged);
205 AtomicElement = _type->getAtomicNumber();
206 }
207}
208
209void AtomInfo::setType(const int Z)
210{
211 const element *elem = World::getInstance().getPeriode()->FindElement(Z);
212 setType(elem);
213}
214
215const Vector& AtomInfo::getAtomicVelocity() const
216{
217 return getAtomicVelocityAtStep(WorldTime::getTime());
218}
219
220const Vector& AtomInfo::getAtomicVelocityAtStep(const unsigned int _step) const
221{
222 ASSERT(!AtomicVelocity.empty(),
223 "AtomInfo::operator[]() - AtomicVelocity is empty.");
224 VectorTrajectory_t::const_iterator iter =
225 AtomicVelocity.lower_bound(_step);
226 // special, we only interpolate between present time steps not into the future
227 if (_step > AtomicVelocity.begin()->first)
228 return zeroVec;
229 else
230 return iter->second;
231}
232
233void AtomInfo::setAtomicVelocity(const Vector &_newvelocity)
234{
235 setAtomicVelocityAtStep(WorldTime::getTime(), _newvelocity);
236}
237
238void AtomInfo::setAtomicVelocityAtStep(const unsigned int _step, const Vector &_newvelocity)
239{
240 OBSERVE;
241 VectorTrajectory_t::iterator iter = AtomicVelocity.find(_step);
242 if (iter != AtomicVelocity.end()) {
243 iter->second = _newvelocity;
244 } else {
245#ifndef NDEBUG
246 std::pair<VectorTrajectory_t::iterator, bool> inserter =
247#endif
248 AtomicVelocity.insert( std::make_pair(_step, _newvelocity) );
249 ASSERT( inserter.second,
250 "AtomInfo::set() - time step "+toString(_step)
251 +" present after all?");
252 }
253 if (WorldTime::getTime() == _step)
254 NOTIFY(AtomObservable::VelocityChanged);
255}
256
257const Vector& AtomInfo::getAtomicForce() const
258{
259 return getAtomicForceAtStep(WorldTime::getTime());
260}
261
262const Vector& AtomInfo::getAtomicForceAtStep(const unsigned int _step) const
263{
264 ASSERT(!AtomicForce.empty(),
265 "AtomInfo::operator[]() - AtomicForce is empty.");
266 VectorTrajectory_t::const_iterator iter =
267 AtomicForce.lower_bound(_step);
268 // special, we only interpolate between present time steps not into the future
269 if (_step > AtomicForce.begin()->first)
270 return zeroVec;
271 else
272 return iter->second;
273}
274
275void AtomInfo::setAtomicForce(const Vector &_newforce)
276{
277 setAtomicForceAtStep(WorldTime::getTime(), _newforce);
278}
279
280void AtomInfo::setAtomicForceAtStep(const unsigned int _step, const Vector &_newforce)
281{
282 OBSERVE;
283 VectorTrajectory_t::iterator iter = AtomicForce.find(_step);
284 if (iter != AtomicForce.end()) {
285 iter->second = _newforce;
286 } else {
287#ifndef NDEBUG
288 std::pair<VectorTrajectory_t::iterator, bool> inserter =
289#endif
290 AtomicForce.insert( std::make_pair(_step, _newforce) );
291 ASSERT( inserter.second,
292 "AtomInfo::set() - time step "+toString(_step)
293 +" present after all?");
294 }
295 if (WorldTime::getTime() == _step)
296 NOTIFY(AtomObservable::ForceChanged);
297}
298
299bool AtomInfo::getFixedIon() const
300{
301 return FixedIon;
302}
303
304void AtomInfo::setFixedIon(const bool _fixedion)
305{
306 OBSERVE;
307 NOTIFY(AtomObservable::PropertyChanged);
308 FixedIon = _fixedion;
309}
310
311void AtomInfo::setPosition(const Vector& _vector)
312{
313 setPositionAtStep(WorldTime::getTime(), _vector);
314}
315
316void AtomInfo::setPositionAtStep(unsigned int _step, const Vector& _vector)
317{
318 OBSERVE;
319 VectorTrajectory_t::iterator iter = AtomicPosition.find(_step);
320 if (iter != AtomicPosition.end()) {
321 iter->second = _vector;
322 } else {
323#ifndef NDEBUG
324 std::pair<VectorTrajectory_t::iterator, bool> inserter =
325#endif
326 AtomicPosition.insert( std::make_pair(_step, _vector) );
327 ASSERT( inserter.second,
328 "AtomInfo::set() - time step "+toString(_step)
329 +" present after all?");
330 }
331 if (WorldTime::getTime() == _step)
332 NOTIFY(AtomObservable::PositionChanged);
333}
334
335const VectorInterface& AtomInfo::operator+=(const Vector& b)
336{
337 setPosition(getPosition()+b);
338 return *this;
339}
340
341const VectorInterface& AtomInfo::operator-=(const Vector& b)
342{
343 setPosition(getPosition()-b);
344 return *this;
345}
346
347Vector const AtomInfo::operator+(const Vector& b) const
348{
349 Vector a(getPosition());
350 a += b;
351 return a;
352}
353
354Vector const AtomInfo::operator-(const Vector& b) const
355{
356 Vector a(getPosition());
357 a -= b;
358 return a;
359}
360
361double AtomInfo::distance(const Vector &point) const
362{
363 return getPosition().distance(point);
364}
365
366double AtomInfo::DistanceSquared(const Vector &y) const
367{
368 return getPosition().DistanceSquared(y);
369}
370
371double AtomInfo::distance(const VectorInterface &_atom) const
372{
373 return _atom.distance(getPosition());
374}
375
376double AtomInfo::DistanceSquared(const VectorInterface &_atom) const
377{
378 return _atom.DistanceSquared(getPosition());
379}
380
381VectorInterface &AtomInfo::operator=(const Vector& _vector)
382{
383 setPosition(_vector);
384 return *this;
385}
386
387void AtomInfo::ScaleAll(const double *factor)
388{
389 Vector temp(getPosition());
390 temp.ScaleAll(factor);
391 setPosition(temp);
392}
393
394void AtomInfo::ScaleAll(const Vector &factor)
395{
396 Vector temp(getPosition());
397 temp.ScaleAll(factor);
398 setPosition(temp);
399}
400
401void AtomInfo::Scale(const double factor)
402{
403 Vector temp(getPosition());
404 temp.Scale(factor);
405 setPosition(temp);
406}
407
408void AtomInfo::Zero()
409{
410 setPosition(zeroVec);
411}
412
413void AtomInfo::One(const double one)
414{
415 setPosition(Vector(one,one,one));
416}
417
418void AtomInfo::LinearCombinationOfVectors(const Vector &x1, const Vector &x2, const Vector &x3, const double * const factors)
419{
420 Vector newPos;
421 newPos.LinearCombinationOfVectors(x1,x2,x3,factors);
422 setPosition(newPos);
423}
424
425/**
426 * returns the kinetic energy of this atom at a given time step
427 */
428double AtomInfo::getKineticEnergy(const unsigned int _step) const
429{
430 return getMass() * getAtomicVelocityAtStep(_step).NormSquared();
431}
432
433Vector AtomInfo::getMomentum(const unsigned int _step) const
434{
435 return getMass() * getAtomicVelocityAtStep(_step);
436}
437
438/** Decrease the trajectory if given \a MaxSteps is smaller.
439 * Does nothing if \a MaxSteps is larger than current size.
440 *
441 * \param MaxSteps
442 */
443void AtomInfo::ResizeTrajectory(size_t MaxSteps)
444{
445 // mind the reverse ordering due to std::greater, latest time steps are at beginning
446 VectorTrajectory_t::iterator positer = AtomicPosition.lower_bound(MaxSteps);
447 if (positer != AtomicPosition.begin()) {
448 if (positer->first == MaxSteps)
449 --positer;
450 AtomicPosition.erase(AtomicPosition.begin(), positer);
451 }
452 VectorTrajectory_t::iterator veliter = AtomicVelocity.lower_bound(MaxSteps);
453 if (veliter != AtomicVelocity.begin()) {
454 if (veliter->first == MaxSteps)
455 --veliter;
456 AtomicVelocity.erase(AtomicVelocity.begin(), veliter);
457 }
458 VectorTrajectory_t::iterator forceiter = AtomicForce.lower_bound(MaxSteps);
459 if (forceiter != AtomicForce.begin()) {
460 if (forceiter->first == MaxSteps)
461 --forceiter;
462 AtomicForce.erase(AtomicForce.begin(), forceiter);
463 }
464}
465
466size_t AtomInfo::getTrajectorySize() const
467{
468 // mind greater comp for map here: first element is latest in time steps!
469 return AtomicPosition.begin()->first+1;
470}
471
472double AtomInfo::getMass() const
473{
474 return getType()->getMass();
475}
476
477/** Helper function to either insert or assign, depending on the element being
478 * present already.
479 *
480 * \param _trajectory vector of Vectors to assign
481 * \param dest step to insert/assign to
482 * \param _newvalue new Vector value
483 */
484void assignTrajectoryElement(
485 std::map<unsigned int, Vector, std::greater<unsigned int> > &_trajectory,
486 const unsigned int dest,
487 const Vector &_newvalue)
488{
489 std::pair<std::map<unsigned int, Vector, std::greater<unsigned int> >::iterator, bool> inserter =
490 _trajectory.insert( std::make_pair(dest, _newvalue) );
491 if (!inserter.second)
492 inserter.first->second = _newvalue;
493}
494
495/** Copies a given trajectory step \a src onto another \a dest
496 * \param dest index of destination step
497 * \param src index of source step
498 */
499void AtomInfo::CopyStepOnStep(const unsigned int dest, const unsigned int src)
500{
501 if (dest == src) // self assignment check
502 return;
503
504 if (WorldTime::getTime() == dest){
505 NOTIFY(AtomObservable::PositionChanged);
506 NOTIFY(AtomObservable::VelocityChanged);
507 NOTIFY(AtomObservable::ForceChanged);
508 }
509
510 VectorTrajectory_t::iterator positer = AtomicPosition.find(src);
511 ASSERT( positer != AtomicPosition.end(),
512 "AtomInfo::CopyStepOnStep() - step "
513 +toString(src)+" to copy from not present in AtomicPosition.");
514 VectorTrajectory_t::iterator veliter = AtomicVelocity.find(src);
515 ASSERT( veliter != AtomicVelocity.end(),
516 "AtomInfo::CopyStepOnStep() - step "
517 +toString(src)+" to copy from not present in AtomicVelocity.");
518 VectorTrajectory_t::iterator forceiter = AtomicForce.find(src);
519 ASSERT( forceiter != AtomicForce.end(),
520 "AtomInfo::CopyStepOnStep() - step "
521 +toString(src)+" to copy from not present in AtomicForce.");
522 assignTrajectoryElement(AtomicPosition, dest, positer->second);
523 assignTrajectoryElement(AtomicVelocity, dest, veliter->second);
524 assignTrajectoryElement(AtomicForce, dest, forceiter->second);
525};
526
527/** Performs a velocity verlet update of the position at \a NextStep from \a LastStep information only.
528 *
529 * We calculate \f$x(t + \delta t) = x(t) + v(t)* \delta t + .5 * \delta t * \delta t * F(t)/m \f$.
530 *
531 *
532 * \param NextStep index of sequential step to set
533 * \param Deltat time step width
534 * \param IsAngstroem whether the force's underlying unit of length is angstroem or bohr radii
535 */
536void AtomInfo::VelocityVerletUpdateX(int nr, const unsigned int NextStep, double Deltat, bool IsAngstroem)
537{
538 const unsigned int LastStep = NextStep == 0 ? 0 : NextStep-1;
539
540 LOG(2, "INFO: Particle that currently " << *this);
541 LOG(2, "INFO: Integrating position with mass=" << getMass() << " and Deltat="
542 << Deltat << " at NextStep=" << NextStep);
543
544 // update position
545 {
546 Vector tempVector = getPositionAtStep(LastStep);
547 LOG(4, "INFO: initial position from last step " << setprecision(4) << tempVector);
548 tempVector += Deltat*(getAtomicVelocityAtStep(LastStep)); // s(t) = s(0) + v * deltat + 1/2 a * deltat^2
549 LOG(4, "INFO: position with velocity " << getAtomicVelocityAtStep(LastStep) << " from last step " << tempVector);
550 tempVector += .5*Deltat*Deltat*(getAtomicForceAtStep(LastStep))*(1./getMass()); // F = m * a and s =
551 LOG(4, "INFO: position with force " << getAtomicForceAtStep(LastStep) << " from last step " << tempVector);
552 setPositionAtStep(NextStep, tempVector);
553 LOG(3, "INFO: Position at step " << NextStep << " set to " << tempVector);
554 }
555};
556
557/** Performs a velocity verlet update of the velocity at \a NextStep.
558 *
559 * \note forces at NextStep should have been calculated based on position at NextStep prior
560 * to calling this function.
561 *
562 * We calculate \f$v(t) = v(t - \delta t) + \delta _t * .5 * (F(t - \delta t) + F(t))/m \f$.
563 *
564 * Parameters are according to those in configuration class.
565 * \param NextStep index of sequential step to set
566 * \param Deltat time step width
567 * \param IsAngstroem whether the force's underlying unit of length is angstroem or bohr radii
568 */
569void AtomInfo::VelocityVerletUpdateU(int nr, const unsigned int NextStep, double Deltat, bool IsAngstroem)
570{
571 const unsigned int LastStep = NextStep == 0 ? 0 : NextStep-1;
572
573 LOG(2, "INFO: Particle that currently " << *this);
574 LOG(2, "INFO: Integrating velocity with mass=" << getMass() << " and Deltat="
575 << Deltat << " at NextStep=" << NextStep);
576
577 // Update U
578 {
579 Vector tempVector = getAtomicVelocityAtStep(LastStep);
580 LOG(4, "INFO: initial velocity from last step " << tempVector);
581 tempVector += Deltat * .5*(getAtomicForceAtStep(LastStep)+getAtomicForceAtStep(NextStep))*(1./getMass()); // v = F/m * t
582 LOG(4, "INFO: Velocity with force from last " << getAtomicForceAtStep(LastStep)
583 << " and present " << getAtomicForceAtStep(NextStep) << " step " << tempVector);
584 setAtomicVelocityAtStep(NextStep, tempVector);
585 LOG(3, "INFO: Velocity at step " << NextStep << " set to " << tempVector);
586 }
587};
588
589std::ostream & AtomInfo::operator << (std::ostream &ost) const
590{
591 return (ost << getPosition());
592}
593
594std::ostream & operator << (std::ostream &ost, const AtomInfo &a)
595{
596 const size_t terminalstep = a.getTrajectorySize()-1;
597 if (terminalstep) {
598 ost << "starts at "
599 << a.getPositionAtStep(0) << " and ends at "
600 << a.getPositionAtStep(terminalstep)
601 << " at time step " << terminalstep;
602 } else {
603 ost << "is at "
604 << a.getPositionAtStep(0) << " with a single time step only";
605 }
606 return ost;
607}
608
Note: See TracBrowser for help on using the repository browser.