source: src/atom.cpp@ c75de1

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 c75de1 was 4455f4, checked in by Frederik Heber <heber@…>, 16 years ago

Huge Refactoring: class atom split up into several inherited classes.

  • Property mode set to 100644
File size: 24.5 KB
RevLine 
[14de469]1/** \file atom.cpp
[1907a7]2 *
[14de469]3 * Function implementations for the class atom.
[1907a7]4 *
[14de469]5 */
6
[357fba]7#include "atom.hpp"
[e41951]8#include "bond.hpp"
[4a7776a]9#include "config.hpp"
[f66195]10#include "element.hpp"
[266237]11#include "lists.hpp"
[29812d]12#include "memoryallocator.hpp"
[ccd9f5]13#include "parser.hpp"
[f66195]14#include "vector.hpp"
[1907a7]15
[14de469]16/************************************* Functions for class atom *************************************/
17
[4455f4]18/** Constructor of class AtomInfo.
19 */
20AtomInfo::AtomInfo() : type(NULL) {};
21
22/** Destructor of class AtomInfo.
23 */
24AtomInfo::~AtomInfo()
25{
26};
27
28/** Constructor of class TrajectoryParticleInfo.
29 */
30TrajectoryParticleInfo::TrajectoryParticleInfo() : FixedIon(0) {};
31
32/** Destructor of class TrajectoryParticleInfo.
33 */
34TrajectoryParticleInfo::~TrajectoryParticleInfo()
35{
36 Trajectory.R.clear();
37 Trajectory.U.clear();
38 Trajectory.F.clear();
39};
40
41/** Constructor of class TrajectoryParticle.
42 */
43TrajectoryParticle::TrajectoryParticle()
44{
45};
46
47/** Destructor of class TrajectoryParticle.
48 */
49TrajectoryParticle::~TrajectoryParticle()
50{
51};
52
53/** Constructor of class GraphNodeInfo.
54 */
55GraphNodeInfo::GraphNodeInfo() : GraphNr(-1), ComponentNr(NULL), LowpointNr(-1), SeparationVertex(false), IsCyclic(false), Ancestor(NULL) {};
56
57/** Destructor of class GraphNodeInfo.
58 */
59GraphNodeInfo::~GraphNodeInfo()
60{
61 Free<int>(&ComponentNr, "atom::~atom: *ComponentNr");
62};
63
64/** Constructor of class GraphNode.
65 */
66GraphNode::GraphNode()
67{
68};
69
70/** Destructor of class GraphNode.
71 */
72GraphNode::~GraphNode()
73{
74};
75
76/** Constructor of class BondedParticleInfo.
77 */
78BondedParticleInfo::BondedParticleInfo() : AdaptiveOrder(0), MaxOrder(false) {};
79
80/** Destructor of class BondedParticleInfo.
81 */
82BondedParticleInfo::~BondedParticleInfo()
83{
84};
85
86/** Constructor of class BondedParticle.
87 */
88BondedParticle::BondedParticle(){};
89
90/** Destructor of class BondedParticle.
91 */
92BondedParticle::~BondedParticle()
93{
94 BondList::const_iterator Runner;
95 while (!ListOfBonds.empty()) {
96 Runner = ListOfBonds.begin();
97 removewithoutcheck(*Runner);
98 }
99};
100
[14de469]101/** Constructor of class atom.
102 */
[1907a7]103atom::atom()
[14de469]104{
[357fba]105 father = this; // generally, father is itself
[14de469]106 previous = NULL;
107 next = NULL;
[4455f4]108 sort = &nr;
109
[357fba]110 // set LCNode::Vector to our Vector
111 node = &x;
[14de469]112};
113
[2319ed]114/** Constructor of class atom.
115 */
116atom::atom(atom *pointer)
117{
118 previous = NULL;
119 next = NULL;
[89c8b2]120 father = pointer; // generally, father is itself
[4455f4]121
[2319ed]122 type = pointer->type; // copy element of atom
123 x.CopyVector(&pointer->x); // copy coordination
124 v.CopyVector(&pointer->v); // copy velocity
125 FixedIon = pointer->FixedIon;
126 sort = &nr;
[89c8b2]127 node = &x;
[2319ed]128}
129
130
[14de469]131/** Destructor of class atom.
132 */
[1907a7]133atom::~atom()
[14de469]134{
[266237]135 unlink(this);
[14de469]136};
137
138
139/** Climbs up the father list until NULL, last is returned.
140 * \return true father, i.e. whose father points to itself, NULL if it could not be found or has none (added hydrogen)
141 */
142atom *atom::GetTrueFather()
143{
144 atom *walker = this;
145 do {
146 if (walker == walker->father) // top most father is the one that points on itself
147 break;
148 walker = walker->father;
149 } while (walker != NULL);
150 return walker;
151};
152
[e65246]153/** Sets father to itself or its father in case of copying a molecule.
154 */
155void atom::CorrectFather()
156{
157 if (father->father == father) // same atom in copy's father points to itself
158 father = this; // set father to itself (copy of a whole molecule)
159 else
160 father = father->father; // set father to original's father
161
162};
163
164/** Check whether father is equal to given atom.
165 * \param *ptr atom to compare father to
166 * \param **res return value (only set if atom::father is equal to \a *ptr)
167 */
168void atom::EqualsFather ( atom *ptr, atom **res )
169{
170 if ( ptr == father )
171 *res = this;
172};
173
[e9f8f9]174/** Checks whether atom is within the given box.
175 * \param offset offset to box origin
176 * \param *parallelepiped box matrix
177 * \return true - is inside, false - is not
178 */
179bool atom::IsInParallelepiped(Vector offset, double *parallelepiped)
180{
181 return (node->IsInParallelepiped(offset, parallelepiped));
182};
183
[266237]184/** Counts the number of bonds weighted by bond::BondDegree.
185 * \param bonds times bond::BondDegree
186 */
[4455f4]187int BondedParticle::CountBonds() const
[266237]188{
189 int NoBonds = 0;
190 for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); (++Runner))
191 NoBonds += (*Runner)->BondDegree;
192 return NoBonds;
193};
194
[14de469]195/** Output of a single atom.
196 * \param ElementNo cardinal number of the element
197 * \param AtomNo cardinal number among these atoms of the same element
198 * \param *out stream to output to
[1907a7]199 * \param *comment commentary after '#' sign
[e41951]200 * \return true - \a *out present, false - \a *out is NULL
[14de469]201 */
[fcd7b6]202bool atom::Output(ofstream *out, int ElementNo, int AtomNo, const char *comment) const
[14de469]203{
204 if (out != NULL) {
205 *out << "Ion_Type" << ElementNo << "_" << AtomNo << "\t" << fixed << setprecision(9) << showpoint;
[943d02]206 *out << x.x[0] << "\t" << x.x[1] << "\t" << x.x[2];
207 *out << "\t" << FixedIon;
208 if (v.Norm() > MYEPSILON)
209 *out << "\t" << scientific << setprecision(6) << v.x[0] << "\t" << v.x[1] << "\t" << v.x[2] << "\t";
[437922]210 if (comment != NULL)
211 *out << " # " << comment << endl;
[e9f8f9]212 else
213 *out << " # molecule nr " << nr << endl;
214 return true;
215 } else
216 return false;
217};
[fcd7b6]218bool atom::Output(ofstream *out, int *ElementNo, int *AtomNo, const char *comment)
[e9f8f9]219{
220 AtomNo[type->Z]++; // increment number
221 if (out != NULL) {
222 *out << "Ion_Type" << ElementNo[type->Z] << "_" << AtomNo[type->Z] << "\t" << fixed << setprecision(9) << showpoint;
223 *out << x.x[0] << "\t" << x.x[1] << "\t" << x.x[2];
224 *out << "\t" << FixedIon;
225 if (v.Norm() > MYEPSILON)
226 *out << "\t" << scientific << setprecision(6) << v.x[0] << "\t" << v.x[1] << "\t" << v.x[2] << "\t";
227 if (comment != NULL)
228 *out << " # " << comment << endl;
[437922]229 else
230 *out << " # molecule nr " << nr << endl;
[14de469]231 return true;
232 } else
233 return false;
234};
235
236/** Output of a single atom as one lin in xyz file.
237 * \param *out stream to output to
[e41951]238 * \return true - \a *out present, false - \a *out is NULL
[14de469]239 */
240bool atom::OutputXYZLine(ofstream *out) const
241{
242 if (out != NULL) {
243 *out << type->symbol << "\t" << x.x[0] << "\t" << x.x[1] << "\t" << x.x[2] << "\t" << endl;
244 return true;
245 } else
246 return false;
247};
248
[fcd7b6]249/** Output of a single atom as one lin in xyz file.
250 * \param *out stream to output to
[e41951]251 * \param *ElementNo array with ion type number in the config file this atom's element shall have
252 * \param *AtomNo array with atom number in the config file this atom shall have, is increase by one automatically
253 * \param step Trajectory time step to output
254 * \return true - \a *out present, false - \a *out is NULL
[fcd7b6]255 */
256bool atom::OutputTrajectory(ofstream *out, int *ElementNo, int *AtomNo, int step) const
257{
258 AtomNo[type->Z]++;
259 if (out != NULL) {
260 *out << "Ion_Type" << ElementNo[type->Z] << "_" << AtomNo[type->Z] << "\t" << fixed << setprecision(9) << showpoint;
261 *out << Trajectory.R.at(step).x[0] << "\t" << Trajectory.R.at(step).x[1] << "\t" << Trajectory.R.at(step).x[2];
262 *out << "\t" << FixedIon;
263 if (Trajectory.U.at(step).Norm() > MYEPSILON)
264 *out << "\t" << scientific << setprecision(6) << Trajectory.U.at(step).x[0] << "\t" << Trajectory.U.at(step).x[1] << "\t" << Trajectory.U.at(step).x[2] << "\t";
265 if (Trajectory.F.at(step).Norm() > MYEPSILON)
266 *out << "\t" << scientific << setprecision(6) << Trajectory.F.at(step).x[0] << "\t" << Trajectory.F.at(step).x[1] << "\t" << Trajectory.F.at(step).x[2] << "\t";
267 *out << "\t# Number in molecule " << nr << endl;
268 return true;
269 } else
270 return false;
271};
272
[681a8a]273/** Output of a single atom as one lin in xyz file.
274 * \param *out stream to output to
[e41951]275 * \param step Trajectory time step to output
276 * \return true - \a *out present, false - \a *out is NULL
[681a8a]277 */
278bool atom::OutputTrajectoryXYZ(ofstream *out, int step) const
279{
280 if (out != NULL) {
281 *out << type->symbol << "\t";
282 *out << Trajectory.R.at(step).x[0] << "\t";
283 *out << Trajectory.R.at(step).x[1] << "\t";
284 *out << Trajectory.R.at(step).x[2] << endl;
285 return true;
286 } else
287 return false;
288};
289
[4455f4]290/** Outputs the MPQC configuration line for this atom.
291 * \param *out output stream
292 * \param *center center of molecule subtracted from position
293 * \param *AtomNo pointer to atom counter that is increased by one
294 */
295void atom::OutputMPQCLine(ofstream *out, Vector *center, int *AtomNo = NULL) const
296{
297 *out << "\t\t" << type->symbol << " [ " << x.x[0]-center->x[0] << "\t" << x.x[1]-center->x[1] << "\t" << x.x[2]-center->x[2] << " ]" << endl;
298 if (AtomNo != NULL)
299 *AtomNo++;
300};
301
302ostream & operator << (ostream &ost, const ParticleInfo &a)
303{
304 ost << "[" << a.Name << "|" << &a << "]";
305 return ost;
306};
307
308ostream & ParticleInfo::operator << (ostream &ost)
309{
310 ost << "[" << Name << "|" << this << "]";
311 return ost;
312};
313
314/** Compares the indices of \a this atom with a given \a ptr.
315 * \param ptr atom to compare index against
316 * \return true - this one's is smaller, false - not
317 */
318bool atom::Compare(const atom &ptr)
319{
320 if (nr < ptr.nr)
321 return true;
322 else
323 return false;
324};
325
326/** Returns squared distance to a given vector.
327 * \param origin vector to calculate distance to
328 * \return distance squared
329 */
330double atom::DistanceSquaredToVector(Vector &origin)
331{
332 return origin.DistanceSquared(&x);
333};
334
335/** Returns distance to a given vector.
336 * \param origin vector to calculate distance to
337 * \return distance
338 */
339double atom::DistanceToVector(Vector &origin)
340{
341 return origin.Distance(&x);
342};
343
344/** Initialises the component number array.
345 * Size is set to atom::ListOfBonds.size()+1 (last is th encode end by -1)
346 */
347void atom::InitComponentNr()
348{
349 if (ComponentNr != NULL)
350 Free(&ComponentNr);
351 ComponentNr = Malloc<int>(ListOfBonds.size()+1, "atom::InitComponentNumbers: *ComponentNr");
352 for (int i=ListOfBonds.size()+1;i--;)
353 ComponentNr[i] = -1;
354};
355
356
357bool operator < (atom &a, atom &b)
358{
359 return a.Compare(b);
360};
361
[266237]362/** Output graph info of this atom.
363 * \param *out output stream
364 */
[4455f4]365void GraphNode::OutputGraphInfo(ofstream *out) const
[266237]366{
367 *out << Verbose(2) << "Atom " << Name << " is " << ((SeparationVertex) ? "a" : "not a") << " separation vertex, components are ";
368 OutputComponentNumber(out);
369 *out << " with Lowpoint " << LowpointNr << " and Graph Nr. " << GraphNr << "." << endl;
370};
371
372/** Output a list of flags, stating whether the bond was visited or not.
373 * Note, we make use of the last entry of the ComponentNr always being -1 if allocated.
374 * \param *out output stream for debugging
375 */
[4455f4]376void GraphNode::OutputComponentNumber(ofstream *out) const
[266237]377{
378 if (ComponentNr != NULL) {
379 for (int i=0; ComponentNr[i] != -1; i++)
380 *out << ComponentNr[i] << " ";
381 }
382};
383
[4455f4]384/** Outputs the current atom::AdaptiveOrder and atom::MaxOrder to \a *file.
385 * \param *file output stream
386 */
387void BondedParticle::OutputOrder(ofstream *file)
388{
389 *file << nr << "\t" << (int)AdaptiveOrder << "\t" << (int)MaxOrder << endl;
390 //cout << Verbose(2) << "Storing: " << nr << "\t" << (int)AdaptiveOrder << "\t" << (int)MaxOrder << "." << endl;
391};
[266237]392
393/** Prints all bonds of this atom with total degree.
[e41951]394 * \param *out stream to output to
395 * \return true - \a *out present, false - \a *out is NULL
396 */
[4455f4]397bool BondedParticle::OutputBondOfAtom(ofstream *out) const
[e41951]398{
399 if (out != NULL) {
[4455f4]400 *out << Verbose(4) << "Atom " << Name << "/" << nr << " with " << ListOfBonds.size() << " bonds: ";
401 int TotalDegree = 0;
402 for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); ++Runner) {
403 *out << **Runner << "\t";
404 TotalDegree += (*Runner)->BondDegree;
[e41951]405 }
[4455f4]406 *out << " -- TotalDegree: " << TotalDegree << endl;
[e41951]407 return true;
408 } else
409 return false;
410};
411
[266237]412/** Output of atom::nr along with all bond partners.
413 * \param *AdjacencyFile output stream
414 */
[4455f4]415void BondedParticle::OutputAdjacency(ofstream *AdjacencyFile) const
[266237]416{
417 *AdjacencyFile << nr << "\t";
418 for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); (++Runner))
419 *AdjacencyFile << (*Runner)->GetOtherAtom(this)->nr << "\t";
420 *AdjacencyFile << endl;
421};
422
423/** Puts a given bond into atom::ListOfBonds.
424 * \param *Binder bond to insert
425 */
[4455f4]426bool BondedParticle::RegisterBond(bond *Binder)
[266237]427{
428 bool status = false;
429 if (Binder != NULL) {
430 if (Binder->Contains(this)) {
431 ListOfBonds.push_back(Binder);
432 status = true;
433 } else {
434 cout << Verbose(1) << "ERROR: " << *Binder << " does not contain " << *this << "." << endl;
435 }
436 } else {
437 cout << Verbose(1) << "ERROR: Binder is " << Binder << "." << endl;
438 }
439 return status;
440};
441
442/** Removes a given bond from atom::ListOfBonds.
443 * \param *Binder bond to remove
444 */
[4455f4]445bool BondedParticle::UnregisterBond(bond *Binder)
[266237]446{
447 bool status = false;
448 if (Binder != NULL) {
449 if (Binder->Contains(this)) {
450 ListOfBonds.remove(Binder);
451 status = true;
452 } else {
453 cout << Verbose(1) << "ERROR: " << *Binder << " does not contain " << *this << "." << endl;
454 }
455 } else {
456 cout << Verbose(1) << "ERROR: Binder is " << Binder << "." << endl;
457 }
458 return status;
459};
460
461/** Removes all bonds from atom::ListOfBonds.
462 * \note Does not do any memory de-allocation.
463 */
[4455f4]464void BondedParticle::UnregisterAllBond()
[266237]465{
466 ListOfBonds.clear();
467};
468
469/** Corrects the bond degree by one at most if necessary.
470 * \param *out output stream for debugging
471 */
[4455f4]472int BondedParticle::CorrectBondDegree(ofstream *out)
[266237]473{
474 int NoBonds = 0;
475 int OtherNoBonds = 0;
476 int FalseBondDegree = 0;
477 atom *OtherWalker = NULL;
478 bond *CandidateBond = NULL;
479
480 *out << Verbose(3) << "Walker " << *this << ": " << (int)this->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
481 NoBonds = CountBonds();
482 if ((int)(type->NoValenceOrbitals) > NoBonds) { // we have a mismatch, check all bonding partners for mismatch
483 for (BondList::const_iterator Runner = ListOfBonds.begin(); Runner != ListOfBonds.end(); (++Runner)) {
484 OtherWalker = (*Runner)->GetOtherAtom(this);
485 OtherNoBonds = OtherWalker->CountBonds();
486 *out << Verbose(3) << "OtherWalker " << *OtherWalker << ": " << (int)OtherWalker->type->NoValenceOrbitals << " > " << NoBonds << "?" << endl;
487 if ((int)(OtherWalker->type->NoValenceOrbitals) > NoBonds) { // check if possible candidate
488 if ((CandidateBond == NULL) || (ListOfBonds.size() > OtherWalker->ListOfBonds.size())) { // pick the one with fewer number of bonds first
489 CandidateBond = (*Runner);
490 *out << Verbose(3) << "New candidate is " << *CandidateBond << "." << endl;
491 }
492 }
493 }
494 if ((CandidateBond != NULL)) {
495 CandidateBond->BondDegree++;
496 *out << Verbose(2) << "Increased bond degree for bond " << *CandidateBond << "." << endl;
497 } else {
498 *out << Verbose(2) << "Could not find correct degree for atom " << *this << "." << endl;
499 FalseBondDegree++;
500 }
501 }
502 return FalseBondDegree;
503};
504
[4455f4]505/** Adds kinetic energy of this atom to given temperature value.
506 * \param *temperature add on this value
507 * \param step given step of trajectory to add
508 */
509void TrajectoryParticle::AddKineticToTemperature(double *temperature, int step) const
[14de469]510{
[4455f4]511 for (int i=NDIM;i--;)
512 *temperature += type->mass * Trajectory.U.at(step).x[i]* Trajectory.U.at(step).x[i];
[14de469]513};
514
[4455f4]515/** Evaluates some constraint potential if atom moves from \a startstep at once to \endstep in trajectory.
516 * \param startstep trajectory begins at
517 * \param endstep trajectory ends at
518 * \param **PermutationMap if atom switches places with some other atom, there is no translation but a permutaton noted here (not in the trajectories of each).
519 * \param *Force Force matrix to store result in
520 */
521void TrajectoryParticle::EvaluateConstrainedForce(int startstep, int endstep, atom **PermutationMap, ForceMatrix *Force)
[055861]522{
[4455f4]523 double constant = 10.;
524 TrajectoryParticle *Sprinter = PermutationMap[nr];
525 // set forces
526 for (int i=NDIM;i++;)
527 Force->Matrix[0][nr][5+i] += 2.*constant*sqrt(Trajectory.R.at(startstep).Distance(&Sprinter->Trajectory.R.at(endstep)));
[055861]528};
529
[4455f4]530/** Correct velocity against the summed \a CoGVelocity for \a step.
531 * \param *ActualTemp sum up actual temperature meanwhile
532 * \param Step MD step in atom::Tracjetory
533 * \param *CoGVelocity remnant velocity (i.e. vector sum of all atom velocities)
[1907a7]534 */
[4455f4]535void TrajectoryParticle::CorrectVelocity(double *ActualTemp, int Step, Vector *CoGVelocity)
[14de469]536{
[4455f4]537 for(int d=0;d<NDIM;d++) {
538 Trajectory.U.at(Step).x[d] -= CoGVelocity->x[d];
539 *ActualTemp += 0.5 * type->mass * Trajectory.U.at(Step).x[d] * Trajectory.U.at(Step).x[d];
540 }
[14de469]541};
542
[4a7776a]543/** Extends the trajectory STL vector to the new size.
544 * Does nothing if \a MaxSteps is smaller than current size.
[4455f4]545 * \param MaxSteps
[4a7776a]546 */
[4455f4]547void TrajectoryParticle::ResizeTrajectory(int MaxSteps)
[4a7776a]548{
549 if (Trajectory.R.size() <= (unsigned int)(MaxSteps)) {
550 //cout << "Increasing size for trajectory array of " << keyword << " to " << (MaxSteps+1) << "." << endl;
551 Trajectory.R.resize(MaxSteps+1);
552 Trajectory.U.resize(MaxSteps+1);
553 Trajectory.F.resize(MaxSteps+1);
554 }
555};
556
557/** Copies a given trajectory step \a src onto another \a dest
558 * \param dest index of destination step
[4455f4]559 * \param src index of source step
[4a7776a]560 */
[4455f4]561void TrajectoryParticle::CopyStepOnStep(int dest, int src)
[4a7776a]562{
563 if (dest == src) // self assignment check
564 return;
565
566 for (int n=NDIM;n--;) {
567 Trajectory.R.at(dest).x[n] = Trajectory.R.at(src).x[n];
568 Trajectory.U.at(dest).x[n] = Trajectory.U.at(src).x[n];
569 Trajectory.F.at(dest).x[n] = Trajectory.F.at(src).x[n];
570 }
571};
572
573/** Performs a velocity verlet update of the trajectory.
574 * Parameters are according to those in configuration class.
575 * \param NextStep index of sequential step to set
576 * \param *configuration pointer to configuration with parameters
[4455f4]577 * \param *Force matrix with forces
[4a7776a]578 */
[4455f4]579void TrajectoryParticle::VelocityVerletUpdate(int NextStep, config *configuration, ForceMatrix *Force)
[4a7776a]580{
581 //a = configuration.Deltat*0.5/walker->type->mass; // (F+F_old)/2m = a and thus: v = (F+F_old)/2m * t = (F + F_old) * a
582 for (int d=0; d<NDIM; d++) {
583 Trajectory.F.at(NextStep).x[d] = -Force->Matrix[0][nr][d+5]*(configuration->GetIsAngstroem() ? AtomicLengthToAngstroem : 1.);
584 Trajectory.R.at(NextStep).x[d] = Trajectory.R.at(NextStep-1).x[d];
585 Trajectory.R.at(NextStep).x[d] += configuration->Deltat*(Trajectory.U.at(NextStep-1).x[d]); // s(t) = s(0) + v * deltat + 1/2 a * deltat^2
586 Trajectory.R.at(NextStep).x[d] += 0.5*configuration->Deltat*configuration->Deltat*(Trajectory.F.at(NextStep).x[d]/type->mass); // F = m * a and s = 0.5 * F/m * t^2 = F * a * t
587 }
588 // Update U
589 for (int d=0; d<NDIM; d++) {
590 Trajectory.U.at(NextStep).x[d] = Trajectory.U.at(NextStep-1).x[d];
591 Trajectory.U.at(NextStep).x[d] += configuration->Deltat * (Trajectory.F.at(NextStep).x[d]+Trajectory.F.at(NextStep-1).x[d]/type->mass); // v = F/m * t
592 }
593 // Update R (and F)
594// out << "Integrated position&velocity of step " << (NextStep) << ": (";
595// for (int d=0;d<NDIM;d++)
596// out << Trajectory.R.at(NextStep).x[d] << " "; // next step
597// out << ")\t(";
598// for (int d=0;d<NDIM;d++)
599// cout << Trajectory.U.at(NextStep).x[d] << " "; // next step
600// out << ")" << endl;
601};
602
603/** Sums up mass and kinetics.
604 * \param Step step to sum for
605 * \param *TotalMass pointer to total mass sum
[4455f4]606 * \param *TotalVelocity pointer to tota velocity sum
[4a7776a]607 */
[4455f4]608void TrajectoryParticle::SumUpKineticEnergy( int Step, double *TotalMass, Vector *TotalVelocity )
[4a7776a]609{
610 *TotalMass += type->mass; // sum up total mass
611 for(int d=0;d<NDIM;d++) {
612 TotalVelocity->x[d] += Trajectory.U.at(Step).x[d]*type->mass;
613 }
614};
615
616/** Scales velocity of atom according to Woodcock thermostat.
617 * \param ScaleTempFactor factor to scale the velocities with (i.e. sqrt of energy scale factor)
618 * \param Step MD step to scale
619 * \param *ekin sum of kinetic energy
620 */
[4455f4]621void TrajectoryParticle::Thermostat_Woodcock(double ScaleTempFactor, int Step, double *ekin)
[4a7776a]622{
623 double *U = Trajectory.U.at(Step).x;
624 if (FixedIon == 0) // even FixedIon moves, only not by other's forces
625 for (int d=0; d<NDIM; d++) {
626 U[d] *= ScaleTempFactor;
627 *ekin += 0.5*type->mass * U[d]*U[d];
628 }
629};
630
631/** Scales velocity of atom according to Gaussian thermostat.
632 * \param Step MD step to scale
633 * \param *G
634 * \param *E
635 */
[4455f4]636void TrajectoryParticle::Thermostat_Gaussian_init(int Step, double *G, double *E)
[4a7776a]637{
638 double *U = Trajectory.U.at(Step).x;
639 double *F = Trajectory.F.at(Step).x;
640 if (FixedIon == 0) // even FixedIon moves, only not by other's forces
641 for (int d=0; d<NDIM; d++) {
642 *G += U[d] * F[d];
643 *E += U[d]*U[d]*type->mass;
644 }
645};
646
647/** Determines scale factors according to Gaussian thermostat.
648 * \param Step MD step to scale
649 * \param GE G over E ratio
650 * \param *ekin sum of kinetic energy
651 * \param *configuration configuration class with TempFrequency and TargetTemp
652 */
[4455f4]653void TrajectoryParticle::Thermostat_Gaussian_least_constraint(int Step, double G_over_E, double *ekin, config *configuration)
[4a7776a]654{
655 double *U = Trajectory.U.at(Step).x;
656 if (FixedIon == 0) // even FixedIon moves, only not by other's forces
657 for (int d=0; d<NDIM; d++) {
658 U[d] += configuration->Deltat/type->mass * ( (G_over_E) * (U[d]*type->mass) );
659 *ekin += type->mass * U[d]*U[d];
660 }
661};
662
663/** Scales velocity of atom according to Langevin thermostat.
664 * \param Step MD step to scale
665 * \param *r random number generator
666 * \param *ekin sum of kinetic energy
667 * \param *configuration configuration class with TempFrequency and TargetTemp
668 */
[4455f4]669void TrajectoryParticle::Thermostat_Langevin(int Step, gsl_rng * r, double *ekin, config *configuration)
[4a7776a]670{
671 double sigma = sqrt(configuration->TargetTemp/type->mass); // sigma = (k_b T)/m (Hartree/atomicmass = atomiclength/atomictime)
672 double *U = Trajectory.U.at(Step).x;
673 if (FixedIon == 0) { // even FixedIon moves, only not by other's forces
674 // throw a dice to determine whether it gets hit by a heat bath particle
675 if (((((rand()/(double)RAND_MAX))*configuration->TempFrequency) < 1.)) {
676 cout << Verbose(3) << "Particle " << *this << " was hit (sigma " << sigma << "): " << sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]) << " -> ";
677 // pick three random numbers from a Boltzmann distribution around the desired temperature T for each momenta axis
678 for (int d=0; d<NDIM; d++) {
679 U[d] = gsl_ran_gaussian (r, sigma);
680 }
681 cout << sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]) << endl;
682 }
683 for (int d=0; d<NDIM; d++)
684 *ekin += 0.5*type->mass * U[d]*U[d];
685 }
686};
687
688/** Scales velocity of atom according to Berendsen thermostat.
689 * \param Step MD step to scale
690 * \param ScaleTempFactor factor to scale energy (not velocity!) with
691 * \param *ekin sum of kinetic energy
692 * \param *configuration configuration class with TempFrequency and Deltat
693 */
[4455f4]694void TrajectoryParticle::Thermostat_Berendsen(int Step, double ScaleTempFactor, double *ekin, config *configuration)
[4a7776a]695{
696 double *U = Trajectory.U.at(Step).x;
697 if (FixedIon == 0) { // even FixedIon moves, only not by other's forces
698 for (int d=0; d<NDIM; d++) {
699 U[d] *= sqrt(1+(configuration->Deltat/configuration->TempFrequency)*(ScaleTempFactor-1));
700 *ekin += 0.5*type->mass * U[d]*U[d];
701 }
702 }
703};
704
705/** Initializes current run of NoseHoover thermostat.
706 * \param Step MD step to scale
707 * \param *delta_alpha additional sum of kinetic energy on return
708 */
[4455f4]709void TrajectoryParticle::Thermostat_NoseHoover_init(int Step, double *delta_alpha)
[4a7776a]710{
711 double *U = Trajectory.U.at(Step).x;
712 if (FixedIon == 0) { // even FixedIon moves, only not by other's forces
713 for (int d=0; d<NDIM; d++) {
714 *delta_alpha += U[d]*U[d]*type->mass;
715 }
716 }
717};
718
719/** Initializes current run of NoseHoover thermostat.
720 * \param Step MD step to scale
721 * \param *ekin sum of kinetic energy
722 * \param *configuration configuration class with TempFrequency and Deltat
723 */
[4455f4]724void TrajectoryParticle::Thermostat_NoseHoover_scale(int Step, double *ekin, config *configuration)
[4a7776a]725{
726 double *U = Trajectory.U.at(Step).x;
727 if (FixedIon == 0) { // even FixedIon moves, only not by other's forces
728 for (int d=0; d<NDIM; d++) {
729 U[d] += configuration->Deltat/type->mass * (configuration->alpha * (U[d] * type->mass));
730 *ekin += (0.5*type->mass) * U[d]*U[d];
731 }
732 }
733};
Note: See TracBrowser for help on using the repository browser.