source: src/Atom/atom_atominfo.cpp@ 8d56a6

Candidate_v1.6.1 ChemicalSpaceEvaluator
Last change on this file since 8d56a6 was 8ac6d0e, checked in by Frederik Heber <frederik.heber@…>, 7 years ago

FIX: atominfo now provides correct TrajectoryUpdate notifications.

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