source: molecuilder/src/atom_trajectoryparticle.cpp@ 2e2a70

Last change on this file since 2e2a70 was 2e2a70, checked in by Frederik Heber <heber@…>, 16 years ago

Refactored atom.cpp into multiple files.

After the class atom was refactored into multiple base classes that are inherited, these base classes are also all put into separate files. This is basically a preparatory step for the like-wise refactoring of class molecule into inherited base classes and splitting up (that is there done already). Finally, we will also separate the relations, i.e. not have "atom.hpp" included everywhere and use class atom, but rather the subclasses such as TrajectoryParticle and its header files only.
Signed-off-by: Frederik Heber <heber@…>

  • Property mode set to 100644
File size: 9.6 KB
Line 
1/*
2 * atom_trajectoryparticle.cpp
3 *
4 * Created on: Oct 19, 2009
5 * Author: heber
6 */
7
8#include "atom.hpp"
9#include "atom_trajectoryparticle.hpp"
10#include "config.hpp"
11#include "element.hpp"
12#include "parser.hpp"
13#include "verbose.hpp"
14
15/** Constructor of class TrajectoryParticle.
16 */
17TrajectoryParticle::TrajectoryParticle()
18{
19};
20
21/** Destructor of class TrajectoryParticle.
22 */
23TrajectoryParticle::~TrajectoryParticle()
24{
25};
26
27
28/** Adds kinetic energy of this atom to given temperature value.
29 * \param *temperature add on this value
30 * \param step given step of trajectory to add
31 */
32void TrajectoryParticle::AddKineticToTemperature(double *temperature, int step) const
33{
34 for (int i=NDIM;i--;)
35 *temperature += type->mass * Trajectory.U.at(step).x[i]* Trajectory.U.at(step).x[i];
36};
37
38/** Evaluates some constraint potential if atom moves from \a startstep at once to \endstep in trajectory.
39 * \param startstep trajectory begins at
40 * \param endstep trajectory ends at
41 * \param **PermutationMap if atom switches places with some other atom, there is no translation but a permutaton noted here (not in the trajectories of ea
42 * \param *Force Force matrix to store result in
43 */
44void TrajectoryParticle::EvaluateConstrainedForce(int startstep, int endstep, atom **PermutationMap, ForceMatrix *Force)
45{
46 double constant = 10.;
47 TrajectoryParticle *Sprinter = PermutationMap[nr];
48 // set forces
49 for (int i=NDIM;i++;)
50 Force->Matrix[0][nr][5+i] += 2.*constant*sqrt(Trajectory.R.at(startstep).Distance(&Sprinter->Trajectory.R.at(endstep)));
51};
52
53/** Correct velocity against the summed \a CoGVelocity for \a step.
54 * \param *ActualTemp sum up actual temperature meanwhile
55 * \param Step MD step in atom::Tracjetory
56 * \param *CoGVelocity remnant velocity (i.e. vector sum of all atom velocities)
57 */
58void TrajectoryParticle::CorrectVelocity(double *ActualTemp, int Step, Vector *CoGVelocity)
59{
60 for(int d=0;d<NDIM;d++) {
61 Trajectory.U.at(Step).x[d] -= CoGVelocity->x[d];
62 *ActualTemp += 0.5 * type->mass * Trajectory.U.at(Step).x[d] * Trajectory.U.at(Step).x[d];
63 }
64};
65
66/** Extends the trajectory STL vector to the new size.
67 * Does nothing if \a MaxSteps is smaller than current size.
68 * \param MaxSteps
69 */
70void TrajectoryParticle::ResizeTrajectory(int MaxSteps)
71{
72 if (Trajectory.R.size() <= (unsigned int)(MaxSteps)) {
73 //cout << "Increasing size for trajectory array of " << keyword << " to " << (MaxSteps+1) << "." << endl;
74 Trajectory.R.resize(MaxSteps+1);
75 Trajectory.U.resize(MaxSteps+1);
76 Trajectory.F.resize(MaxSteps+1);
77 }
78};
79
80/** Copies a given trajectory step \a src onto another \a dest
81 * \param dest index of destination step
82 * \param src index of source step
83 */
84void TrajectoryParticle::CopyStepOnStep(int dest, int src)
85{
86 if (dest == src) // self assignment check
87 return;
88
89 for (int n=NDIM;n--;) {
90 Trajectory.R.at(dest).x[n] = Trajectory.R.at(src).x[n];
91 Trajectory.U.at(dest).x[n] = Trajectory.U.at(src).x[n];
92 Trajectory.F.at(dest).x[n] = Trajectory.F.at(src).x[n];
93 }
94};
95
96/** Performs a velocity verlet update of the trajectory.
97 * Parameters are according to those in configuration class.
98 * \param NextStep index of sequential step to set
99 * \param *configuration pointer to configuration with parameters
100 * \param *Force matrix with forces
101 */
102void TrajectoryParticle::VelocityVerletUpdate(int NextStep, config *configuration, ForceMatrix *Force)
103{
104 //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
105 for (int d=0; d<NDIM; d++) {
106 Trajectory.F.at(NextStep).x[d] = -Force->Matrix[0][nr][d+5]*(configuration->GetIsAngstroem() ? AtomicLengthToAngstroem : 1.);
107 Trajectory.R.at(NextStep).x[d] = Trajectory.R.at(NextStep-1).x[d];
108 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
109 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 =
110 }
111 // Update U
112 for (int d=0; d<NDIM; d++) {
113 Trajectory.U.at(NextStep).x[d] = Trajectory.U.at(NextStep-1).x[d];
114 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
115 }
116 // Update R (and F)
117// out << "Integrated position&velocity of step " << (NextStep) << ": (";
118// for (int d=0;d<NDIM;d++)
119// out << Trajectory.R.at(NextStep).x[d] << " "; // next step
120// out << ")\t(";
121// for (int d=0;d<NDIM;d++)
122// cout << Trajectory.U.at(NextStep).x[d] << " "; // next step
123// out << ")" << endl;
124};
125
126/** Sums up mass and kinetics.
127 * \param Step step to sum for
128 * \param *TotalMass pointer to total mass sum
129 * \param *TotalVelocity pointer to tota velocity sum
130 */
131void TrajectoryParticle::SumUpKineticEnergy( int Step, double *TotalMass, Vector *TotalVelocity )
132{
133 *TotalMass += type->mass; // sum up total mass
134 for(int d=0;d<NDIM;d++) {
135 TotalVelocity->x[d] += Trajectory.U.at(Step).x[d]*type->mass;
136 }
137};
138
139/** Scales velocity of atom according to Woodcock thermostat.
140 * \param ScaleTempFactor factor to scale the velocities with (i.e. sqrt of energy scale factor)
141 * \param Step MD step to scale
142 * \param *ekin sum of kinetic energy
143 */
144void TrajectoryParticle::Thermostat_Woodcock(double ScaleTempFactor, int Step, double *ekin)
145{
146 double *U = Trajectory.U.at(Step).x;
147 if (FixedIon == 0) // even FixedIon moves, only not by other's forces
148 for (int d=0; d<NDIM; d++) {
149 U[d] *= ScaleTempFactor;
150 *ekin += 0.5*type->mass * U[d]*U[d];
151 }
152};
153
154/** Scales velocity of atom according to Gaussian thermostat.
155 * \param Step MD step to scale
156 * \param *G
157 * \param *E
158 */
159void TrajectoryParticle::Thermostat_Gaussian_init(int Step, double *G, double *E)
160{
161 double *U = Trajectory.U.at(Step).x;
162 double *F = Trajectory.F.at(Step).x;
163 if (FixedIon == 0) // even FixedIon moves, only not by other's forces
164 for (int d=0; d<NDIM; d++) {
165 *G += U[d] * F[d];
166 *E += U[d]*U[d]*type->mass;
167 }
168};
169
170/** Determines scale factors according to Gaussian thermostat.
171 * \param Step MD step to scale
172 * \param GE G over E ratio
173 * \param *ekin sum of kinetic energy
174 * \param *configuration configuration class with TempFrequency and TargetTemp
175 */
176void TrajectoryParticle::Thermostat_Gaussian_least_constraint(int Step, double G_over_E, double *ekin, config *configuration)
177{
178 double *U = Trajectory.U.at(Step).x;
179 if (FixedIon == 0) // even FixedIon moves, only not by other's forces
180 for (int d=0; d<NDIM; d++) {
181 U[d] += configuration->Deltat/type->mass * ( (G_over_E) * (U[d]*type->mass) );
182 *ekin += type->mass * U[d]*U[d];
183 }
184};
185
186/** Scales velocity of atom according to Langevin thermostat.
187 * \param Step MD step to scale
188 * \param *r random number generator
189 * \param *ekin sum of kinetic energy
190 * \param *configuration configuration class with TempFrequency and TargetTemp
191 */
192void TrajectoryParticle::Thermostat_Langevin(int Step, gsl_rng * r, double *ekin, config *configuration)
193{
194 double sigma = sqrt(configuration->TargetTemp/type->mass); // sigma = (k_b T)/m (Hartree/atomicmass = atomiclength/atomictime)
195 double *U = Trajectory.U.at(Step).x;
196 if (FixedIon == 0) { // even FixedIon moves, only not by other's forces
197 // throw a dice to determine whether it gets hit by a heat bath particle
198 if (((((rand()/(double)RAND_MAX))*configuration->TempFrequency) < 1.)) {
199 cout << Verbose(3) << "Particle " << *this << " was hit (sigma " << sigma << "): " << sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]) << " -> ";
200 // pick three random numbers from a Boltzmann distribution around the desired temperature T for each momenta axis
201 for (int d=0; d<NDIM; d++) {
202 U[d] = gsl_ran_gaussian (r, sigma);
203 }
204 cout << sqrt(U[0]*U[0]+U[1]*U[1]+U[2]*U[2]) << endl;
205 }
206 for (int d=0; d<NDIM; d++)
207 *ekin += 0.5*type->mass * U[d]*U[d];
208 }
209};
210
211/** Scales velocity of atom according to Berendsen thermostat.
212 * \param Step MD step to scale
213 * \param ScaleTempFactor factor to scale energy (not velocity!) with
214 * \param *ekin sum of kinetic energy
215 * \param *configuration configuration class with TempFrequency and Deltat
216 */
217void TrajectoryParticle::Thermostat_Berendsen(int Step, double ScaleTempFactor, double *ekin, config *configuration)
218{
219 double *U = Trajectory.U.at(Step).x;
220 if (FixedIon == 0) { // even FixedIon moves, only not by other's forces
221 for (int d=0; d<NDIM; d++) {
222 U[d] *= sqrt(1+(configuration->Deltat/configuration->TempFrequency)*(ScaleTempFactor-1));
223 *ekin += 0.5*type->mass * U[d]*U[d];
224 }
225 }
226};
227
228/** Initializes current run of NoseHoover thermostat.
229 * \param Step MD step to scale
230 * \param *delta_alpha additional sum of kinetic energy on return
231 */
232void TrajectoryParticle::Thermostat_NoseHoover_init(int Step, double *delta_alpha)
233{
234 double *U = Trajectory.U.at(Step).x;
235 if (FixedIon == 0) { // even FixedIon moves, only not by other's forces
236 for (int d=0; d<NDIM; d++) {
237 *delta_alpha += U[d]*U[d]*type->mass;
238 }
239 }
240};
241
242/** Initializes current run of NoseHoover thermostat.
243 * \param Step MD step to scale
244 * \param *ekin sum of kinetic energy
245 * \param *configuration configuration class with TempFrequency and Deltat
246 */
247void TrajectoryParticle::Thermostat_NoseHoover_scale(int Step, double *ekin, config *configuration)
248{
249 double *U = Trajectory.U.at(Step).x;
250 if (FixedIon == 0) { // even FixedIon moves, only not by other's forces
251 for (int d=0; d<NDIM; d++) {
252 U[d] += configuration->Deltat/type->mass * (configuration->alpha * (U[d] * type->mass));
253 *ekin += (0.5*type->mass) * U[d]*U[d];
254 }
255 }
256};
Note: See TracBrowser for help on using the repository browser.