source: src/atom.cpp@ 3a9fe9

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 3a9fe9 was 5034e1, checked in by Frederik Heber <heber@…>, 16 years ago

First half of molecule_fragmentation.cpp refactoring.

  • Property mode set to 100644
File size: 18.2 KB
Line 
1/** \file atom.cpp
2 *
3 * Function implementations for the class atom.
4 *
5 */
6
7#include "atom.hpp"
8#include "bond.hpp"
9#include "config.hpp"
10#include "element.hpp"
11#include "memoryallocator.hpp"
12#include "parser.hpp"
13#include "vector.hpp"
14
15/************************************* Functions for class atom *************************************/
16
17/** Constructor of class atom.
18 */
19atom::atom()
20{
21 father = this; // generally, father is itself
22 previous = NULL;
23 next = NULL;
24 Ancestor = NULL;
25 type = NULL;
26 sort = NULL;
27 FixedIon = 0;
28 GraphNr = -1;
29 ComponentNr = NULL;
30 IsCyclic = false;
31 SeparationVertex = false;
32 LowpointNr = -1;
33 AdaptiveOrder = 0;
34 MaxOrder = false;
35 // set LCNode::Vector to our Vector
36 node = &x;
37};
38
39/** Constructor of class atom.
40 */
41atom::atom(atom *pointer)
42{
43 Name = NULL;
44 previous = NULL;
45 next = NULL;
46 father = pointer; // generally, father is itself
47 Ancestor = NULL;
48 GraphNr = -1;
49 ComponentNr = NULL;
50 IsCyclic = false;
51 SeparationVertex = false;
52 LowpointNr = -1;
53 AdaptiveOrder = 0;
54 MaxOrder = false;
55 type = pointer->type; // copy element of atom
56 x.CopyVector(&pointer->x); // copy coordination
57 v.CopyVector(&pointer->v); // copy velocity
58 FixedIon = pointer->FixedIon;
59 nr = -1;
60 sort = &nr;
61 node = &x;
62}
63
64
65/** Destructor of class atom.
66 */
67atom::~atom()
68{
69 Free<int>(&ComponentNr, "atom::~atom: *ComponentNr");
70 Free<char>(&Name, "atom::~atom: *Name");
71 Trajectory.R.clear();
72 Trajectory.U.clear();
73 Trajectory.F.clear();
74};
75
76
77/** Climbs up the father list until NULL, last is returned.
78 * \return true father, i.e. whose father points to itself, NULL if it could not be found or has none (added hydrogen)
79 */
80atom *atom::GetTrueFather()
81{
82 atom *walker = this;
83 do {
84 if (walker == walker->father) // top most father is the one that points on itself
85 break;
86 walker = walker->father;
87 } while (walker != NULL);
88 return walker;
89};
90
91/** Sets father to itself or its father in case of copying a molecule.
92 */
93void atom::CorrectFather()
94{
95 if (father->father == father) // same atom in copy's father points to itself
96 father = this; // set father to itself (copy of a whole molecule)
97 else
98 father = father->father; // set father to original's father
99
100};
101
102/** Check whether father is equal to given atom.
103 * \param *ptr atom to compare father to
104 * \param **res return value (only set if atom::father is equal to \a *ptr)
105 */
106void atom::EqualsFather ( atom *ptr, atom **res )
107{
108 if ( ptr == father )
109 *res = this;
110};
111
112/** Checks whether atom is within the given box.
113 * \param offset offset to box origin
114 * \param *parallelepiped box matrix
115 * \return true - is inside, false - is not
116 */
117bool atom::IsInParallelepiped(Vector offset, double *parallelepiped)
118{
119 return (node->IsInParallelepiped(offset, parallelepiped));
120};
121
122/** Output of a single atom.
123 * \param ElementNo cardinal number of the element
124 * \param AtomNo cardinal number among these atoms of the same element
125 * \param *out stream to output to
126 * \param *comment commentary after '#' sign
127 * \return true - \a *out present, false - \a *out is NULL
128 */
129bool atom::Output(ofstream *out, int ElementNo, int AtomNo, const char *comment) const
130{
131 if (out != NULL) {
132 *out << "Ion_Type" << ElementNo << "_" << AtomNo << "\t" << fixed << setprecision(9) << showpoint;
133 *out << x.x[0] << "\t" << x.x[1] << "\t" << x.x[2];
134 *out << "\t" << FixedIon;
135 if (v.Norm() > MYEPSILON)
136 *out << "\t" << scientific << setprecision(6) << v.x[0] << "\t" << v.x[1] << "\t" << v.x[2] << "\t";
137 if (comment != NULL)
138 *out << " # " << comment << endl;
139 else
140 *out << " # molecule nr " << nr << endl;
141 return true;
142 } else
143 return false;
144};
145bool atom::Output(ofstream *out, int *ElementNo, int *AtomNo, const char *comment)
146{
147 AtomNo[type->Z]++; // increment number
148 if (out != NULL) {
149 *out << "Ion_Type" << ElementNo[type->Z] << "_" << AtomNo[type->Z] << "\t" << fixed << setprecision(9) << showpoint;
150 *out << x.x[0] << "\t" << x.x[1] << "\t" << x.x[2];
151 *out << "\t" << FixedIon;
152 if (v.Norm() > MYEPSILON)
153 *out << "\t" << scientific << setprecision(6) << v.x[0] << "\t" << v.x[1] << "\t" << v.x[2] << "\t";
154 if (comment != NULL)
155 *out << " # " << comment << endl;
156 else
157 *out << " # molecule nr " << nr << endl;
158 return true;
159 } else
160 return false;
161};
162
163/** Output of a single atom as one lin in xyz file.
164 * \param *out stream to output to
165 * \return true - \a *out present, false - \a *out is NULL
166 */
167bool atom::OutputXYZLine(ofstream *out) const
168{
169 if (out != NULL) {
170 *out << type->symbol << "\t" << x.x[0] << "\t" << x.x[1] << "\t" << x.x[2] << "\t" << endl;
171 return true;
172 } else
173 return false;
174};
175
176/** Output of a single atom as one lin in xyz file.
177 * \param *out stream to output to
178 * \param *ElementNo array with ion type number in the config file this atom's element shall have
179 * \param *AtomNo array with atom number in the config file this atom shall have, is increase by one automatically
180 * \param step Trajectory time step to output
181 * \return true - \a *out present, false - \a *out is NULL
182 */
183bool atom::OutputTrajectory(ofstream *out, int *ElementNo, int *AtomNo, int step) const
184{
185 AtomNo[type->Z]++;
186 if (out != NULL) {
187 *out << "Ion_Type" << ElementNo[type->Z] << "_" << AtomNo[type->Z] << "\t" << fixed << setprecision(9) << showpoint;
188 *out << Trajectory.R.at(step).x[0] << "\t" << Trajectory.R.at(step).x[1] << "\t" << Trajectory.R.at(step).x[2];
189 *out << "\t" << FixedIon;
190 if (Trajectory.U.at(step).Norm() > MYEPSILON)
191 *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";
192 if (Trajectory.F.at(step).Norm() > MYEPSILON)
193 *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";
194 *out << "\t# Number in molecule " << nr << endl;
195 return true;
196 } else
197 return false;
198};
199
200/** Output of a single atom as one lin in xyz file.
201 * \param *out stream to output to
202 * \param step Trajectory time step to output
203 * \return true - \a *out present, false - \a *out is NULL
204 */
205bool atom::OutputTrajectoryXYZ(ofstream *out, int step) const
206{
207 if (out != NULL) {
208 *out << type->symbol << "\t";
209 *out << Trajectory.R.at(step).x[0] << "\t";
210 *out << Trajectory.R.at(step).x[1] << "\t";
211 *out << Trajectory.R.at(step).x[2] << endl;
212 return true;
213 } else
214 return false;
215};
216
217/** Prints all bonds of this atom from given global lists.
218 * \param *out stream to output to
219 * \param *NumberOfBondsPerAtom array with number of bonds per atomic index
220 * \param ***ListOfBondsPerAtom array per atomic index of array with pointer to bond
221 * \return true - \a *out present, false - \a *out is NULL
222 */
223bool atom::OutputBondOfAtom(ofstream *out, int *NumberOfBondsPerAtom, bond ***ListOfBondsPerAtom) const
224{
225 if (out != NULL) {
226#ifdef ADDHYDROGEN
227 if (type->Z != 1) { // regard only non-hydrogen
228#endif
229 *out << Verbose(4) << "Atom " << Name << "/" << nr << " with " << NumberOfBondsPerAtom[nr] << " bonds: ";
230 int TotalDegree = 0;
231 for (int j=0;j<NumberOfBondsPerAtom[nr];j++) {
232 *out << *ListOfBondsPerAtom[nr][j] << "\t";
233 TotalDegree += ListOfBondsPerAtom[nr][j]->BondDegree;
234 }
235 *out << " -- TotalDegree: " << TotalDegree << endl;
236#ifdef ADDHYDROGEN
237 }
238#endif
239 return true;
240 } else
241 return false;
242};
243
244ostream & operator << (ostream &ost, const atom &a)
245{
246 ost << "[" << a.Name << "|" << &a << "]";
247 return ost;
248};
249
250ostream & atom::operator << (ostream &ost)
251{
252 ost << "[" << Name << "|" << this << "]";
253 return ost;
254};
255
256/** Compares the indices of \a this atom with a given \a ptr.
257 * \param ptr atom to compare index against
258 * \return true - this one's is smaller, false - not
259 */
260bool atom::Compare(const atom &ptr)
261{
262 if (nr < ptr.nr)
263 return true;
264 else
265 return false;
266};
267
268/** Extends the trajectory STL vector to the new size.
269 * Does nothing if \a MaxSteps is smaller than current size.
270 * \param MaxSteps
271 */
272void atom::ResizeTrajectory(int MaxSteps)
273{
274 if (Trajectory.R.size() <= (unsigned int)(MaxSteps)) {
275 //cout << "Increasing size for trajectory array of " << keyword << " to " << (MaxSteps+1) << "." << endl;
276 Trajectory.R.resize(MaxSteps+1);
277 Trajectory.U.resize(MaxSteps+1);
278 Trajectory.F.resize(MaxSteps+1);
279 }
280};
281
282/** Copies a given trajectory step \a src onto another \a dest
283 * \param dest index of destination step
284 * \param src index of source step
285 */
286void atom::CopyStepOnStep(int dest, int src)
287{
288 if (dest == src) // self assignment check
289 return;
290
291 for (int n=NDIM;n--;) {
292 Trajectory.R.at(dest).x[n] = Trajectory.R.at(src).x[n];
293 Trajectory.U.at(dest).x[n] = Trajectory.U.at(src).x[n];
294 Trajectory.F.at(dest).x[n] = Trajectory.F.at(src).x[n];
295 }
296};
297
298/** Performs a velocity verlet update of the trajectory.
299 * Parameters are according to those in configuration class.
300 * \param NextStep index of sequential step to set
301 * \param *configuration pointer to configuration with parameters
302 * \param *Force matrix with forces
303 */
304void atom::VelocityVerletUpdate(int NextStep, config *configuration, ForceMatrix *Force)
305{
306 //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
307 for (int d=0; d<NDIM; d++) {
308 Trajectory.F.at(NextStep).x[d] = -Force->Matrix[0][nr][d+5]*(configuration->GetIsAngstroem() ? AtomicLengthToAngstroem : 1.);
309 Trajectory.R.at(NextStep).x[d] = Trajectory.R.at(NextStep-1).x[d];
310 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
311 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
312 }
313 // Update U
314 for (int d=0; d<NDIM; d++) {
315 Trajectory.U.at(NextStep).x[d] = Trajectory.U.at(NextStep-1).x[d];
316 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
317 }
318 // Update R (and F)
319// out << "Integrated position&velocity of step " << (NextStep) << ": (";
320// for (int d=0;d<NDIM;d++)
321// out << Trajectory.R.at(NextStep).x[d] << " "; // next step
322// out << ")\t(";
323// for (int d=0;d<NDIM;d++)
324// cout << Trajectory.U.at(NextStep).x[d] << " "; // next step
325// out << ")" << endl;
326};
327
328/** Sums up mass and kinetics.
329 * \param Step step to sum for
330 * \param *TotalMass pointer to total mass sum
331 * \param *TotalVelocity pointer to tota velocity sum
332 */
333void atom::SumUpKineticEnergy( int Step, double *TotalMass, Vector *TotalVelocity )
334{
335 *TotalMass += type->mass; // sum up total mass
336 for(int d=0;d<NDIM;d++) {
337 TotalVelocity->x[d] += Trajectory.U.at(Step).x[d]*type->mass;
338 }
339};
340
341/** Outputs the current atom::AdaptiveOrder and atom::MaxOrder to \a *file.
342 * \param *file output stream
343 */
344void atom::OutputOrder(ofstream *file)
345{
346 *file << nr << "\t" << (int)AdaptiveOrder << "\t" << (int)MaxOrder << endl;
347 //cout << Verbose(2) << "Storing: " << Walker->nr << "\t" << (int)Walker->AdaptiveOrder << "\t" << (int)Walker->MaxOrder << "." << endl;
348}
349
350/** Returns squared distance to a given vector.
351 * \param origin vector to calculate distance to
352 * \return distance squared
353 */
354double atom::DistanceSquaredToVector(Vector &origin)
355{
356 return origin.DistanceSquared(&x);
357};
358
359/** Adds kinetic energy of this atom to given temperature value.
360 * \param *temperature add on this value
361 * \param step given step of trajectory to add
362 */
363void atom::AddKineticToTemperature(double *temperature, int step) const
364{
365 for (int i=NDIM;i--;)
366 *temperature += type->mass * Trajectory.U.at(step).x[i]* Trajectory.U.at(step).x[i];
367};
368
369/** Returns distance to a given vector.
370 * \param origin vector to calculate distance to
371 * \return distance
372 */
373double atom::DistanceToVector(Vector &origin)
374{
375 return origin.Distance(&x);
376};
377
378bool operator < (atom &a, atom &b)
379{
380 return a.Compare(b);
381};
382
383/** Evaluates some constraint potential if atom moves from \a startstep at once to \endstep in trajectory.
384 * \param startstep trajectory begins at
385 * \param endstep trajectory ends at
386 * \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).
387 * \param *Force Force matrix to store result in
388 */
389void atom::EvaluateConstrainedForce(int startstep, int endstep, atom **PermutationMap, ForceMatrix *Force)
390{
391 double constant = 10.;
392 atom *Sprinter = PermutationMap[nr];
393 // set forces
394 for (int i=NDIM;i++;)
395 Force->Matrix[0][nr][5+i] += 2.*constant*sqrt(Trajectory.R.at(startstep).Distance(&Sprinter->Trajectory.R.at(endstep)));
396};
397
398/** Correct velocity against the summed \a CoGVelocity for \a step.
399 * \param *ActualTemp sum up actual temperature meanwhile
400 * \param Step MD step in atom::Tracjetory
401 * \param *CoGVelocity remnant velocity (i.e. vector sum of all atom velocities)
402 */
403void atom::CorrectVelocity(double *ActualTemp, int Step, Vector *CoGVelocity)
404{
405 for(int d=0;d<NDIM;d++) {
406 Trajectory.U.at(Step).x[d] -= CoGVelocity->x[d];
407 *ActualTemp += 0.5 * type->mass * Trajectory.U.at(Step).x[d] * Trajectory.U.at(Step).x[d];
408 }
409};
410
411/** Scales velocity of atom according to Woodcock thermostat.
412 * \param ScaleTempFactor factor to scale the velocities with (i.e. sqrt of energy scale factor)
413 * \param Step MD step to scale
414 * \param *ekin sum of kinetic energy
415 */
416void atom::Thermostat_Woodcock(double ScaleTempFactor, int Step, double *ekin)
417{
418 double *U = Trajectory.U.at(Step).x;
419 if (FixedIon == 0) // even FixedIon moves, only not by other's forces
420 for (int d=0; d<NDIM; d++) {
421 U[d] *= ScaleTempFactor;
422 *ekin += 0.5*type->mass * U[d]*U[d];
423 }
424};
425
426/** Scales velocity of atom according to Gaussian thermostat.
427 * \param Step MD step to scale
428 * \param *G
429 * \param *E
430 */
431void atom::Thermostat_Gaussian_init(int Step, double *G, double *E)
432{
433 double *U = Trajectory.U.at(Step).x;
434 double *F = Trajectory.F.at(Step).x;
435 if (FixedIon == 0) // even FixedIon moves, only not by other's forces
436 for (int d=0; d<NDIM; d++) {
437 *G += U[d] * F[d];
438 *E += U[d]*U[d]*type->mass;
439 }
440};
441
442/** Determines scale factors according to Gaussian thermostat.
443 * \param Step MD step to scale
444 * \param GE G over E ratio
445 * \param *ekin sum of kinetic energy
446 * \param *configuration configuration class with TempFrequency and TargetTemp
447 */
448void atom::Thermostat_Gaussian_least_constraint(int Step, double G_over_E, double *ekin, config *configuration)
449{
450 double *U = Trajectory.U.at(Step).x;
451 if (FixedIon == 0) // even FixedIon moves, only not by other's forces
452 for (int d=0; d<NDIM; d++) {
453 U[d] += configuration->Deltat/type->mass * ( (G_over_E) * (U[d]*type->mass) );
454 *ekin += type->mass * U[d]*U[d];
455 }
456};
457
458/** Scales velocity of atom according to Langevin thermostat.
459 * \param Step MD step to scale
460 * \param *r random number generator
461 * \param *ekin sum of kinetic energy
462 * \param *configuration configuration class with TempFrequency and TargetTemp
463 */
464void atom::Thermostat_Langevin(int Step, gsl_rng * r, double *ekin, config *configuration)
465{
466 double sigma = sqrt(configuration->TargetTemp/type->mass); // sigma = (k_b T)/m (Hartree/atomicmass = atomiclength/atomictime)
467 double *U = Trajectory.U.at(Step).x;
468 if (FixedIon == 0) { // even FixedIon moves, only not by other's forces
469 // throw a dice to determine whether it gets hit by a heat bath particle
470 if (((((rand()/(double)RAND_MAX))*configuration->TempFrequency) < 1.)) {
471 cout << Verbose(3) << "Particle " << *this << " was hit (sigma " << sigma << "): " << sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]) << " -> ";
472 // pick three random numbers from a Boltzmann distribution around the desired temperature T for each momenta axis
473 for (int d=0; d<NDIM; d++) {
474 U[d] = gsl_ran_gaussian (r, sigma);
475 }
476 cout << sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]) << endl;
477 }
478 for (int d=0; d<NDIM; d++)
479 *ekin += 0.5*type->mass * U[d]*U[d];
480 }
481};
482
483/** Scales velocity of atom according to Berendsen thermostat.
484 * \param Step MD step to scale
485 * \param ScaleTempFactor factor to scale energy (not velocity!) with
486 * \param *ekin sum of kinetic energy
487 * \param *configuration configuration class with TempFrequency and Deltat
488 */
489void atom::Thermostat_Berendsen(int Step, double ScaleTempFactor, double *ekin, config *configuration)
490{
491 double *U = Trajectory.U.at(Step).x;
492 if (FixedIon == 0) { // even FixedIon moves, only not by other's forces
493 for (int d=0; d<NDIM; d++) {
494 U[d] *= sqrt(1+(configuration->Deltat/configuration->TempFrequency)*(ScaleTempFactor-1));
495 *ekin += 0.5*type->mass * U[d]*U[d];
496 }
497 }
498};
499
500/** Initializes current run of NoseHoover thermostat.
501 * \param Step MD step to scale
502 * \param *delta_alpha additional sum of kinetic energy on return
503 */
504void atom::Thermostat_NoseHoover_init(int Step, double *delta_alpha)
505{
506 double *U = Trajectory.U.at(Step).x;
507 if (FixedIon == 0) { // even FixedIon moves, only not by other's forces
508 for (int d=0; d<NDIM; d++) {
509 *delta_alpha += U[d]*U[d]*type->mass;
510 }
511 }
512};
513
514/** Initializes current run of NoseHoover thermostat.
515 * \param Step MD step to scale
516 * \param *ekin sum of kinetic energy
517 * \param *configuration configuration class with TempFrequency and Deltat
518 */
519void atom::Thermostat_NoseHoover_scale(int Step, double *ekin, config *configuration)
520{
521 double *U = Trajectory.U.at(Step).x;
522 if (FixedIon == 0) { // even FixedIon moves, only not by other's forces
523 for (int d=0; d<NDIM; d++) {
524 U[d] += configuration->Deltat/type->mass * (configuration->alpha * (U[d] * type->mass));
525 *ekin += (0.5*type->mass) * U[d]*U[d];
526 }
527 }
528};
Note: See TracBrowser for help on using the repository browser.