ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/NVT.cpp
Revision: 658
Committed: Thu Jul 31 15:35:07 2003 UTC (20 years, 11 months ago) by tim
File size: 4156 byte(s)
Log Message:
 Added Z constraint.

File Contents

# Content
1 #include "Atom.hpp"
2 #include "SRI.hpp"
3 #include "AbstractClasses.hpp"
4 #include "SimInfo.hpp"
5 #include "ForceFields.hpp"
6 #include "Thermo.hpp"
7 #include "ReadWrite.hpp"
8 #include "Integrator.hpp"
9 #include "simError.h"
10
11
12 // Basic thermostating via Hoover, Phys.Rev.A, 1985, Vol. 31 (5) 1695-1697
13
14 template<typename T> NVT<T>::NVT ( SimInfo *theInfo, ForceFields* the_ff):
15 T( theInfo, the_ff )
16 {
17 chi = 0.0;
18 have_tau_thermostat = 0;
19 have_target_temp = 0;
20 }
21
22 template<typename T> void NVT<T>::moveA() {
23
24 int i, j;
25 DirectionalAtom* dAtom;
26 double Tb[3], ji[3];
27 double A[3][3], I[3][3];
28 double angle, mass;
29 double vel[3], pos[3], frc[3];
30
31 double instTemp;
32
33 instTemp = tStats->getTemperature();
34
35 // first evolve chi a half step
36
37 chi += dt2 * ( instTemp / targetTemp - 1.0) / (tauThermostat*tauThermostat);
38
39 for( i=0; i<nAtoms; i++ ){
40
41 atoms[i]->getVel( vel );
42 atoms[i]->getPos( pos );
43 atoms[i]->getFrc( frc );
44
45 mass = atoms[i]->getMass();
46
47 for (j=0; j < 3; j++) {
48 // velocity half step
49 vel[j] += dt2 * ((frc[j] / mass ) * eConvert - vel[j]*chi);
50 // position whole step
51 pos[j] += dt * vel[j];
52 }
53
54 atoms[i]->setVel( vel );
55 atoms[i]->setPos( pos );
56
57 if( atoms[i]->isDirectional() ){
58
59 dAtom = (DirectionalAtom *)atoms[i];
60
61 // get and convert the torque to body frame
62
63 dAtom->getTrq( Tb );
64 dAtom->lab2Body( Tb );
65
66 // get the angular momentum, and propagate a half step
67
68 dAtom->getJ( ji );
69
70 for (j=0; j < 3; j++)
71 ji[j] += dt2 * (Tb[j] * eConvert - ji[j]*chi);
72
73 // use the angular velocities to propagate the rotation matrix a
74 // full time step
75
76 dAtom->getA(A);
77 dAtom->getI(I);
78
79 // rotate about the x-axis
80 angle = dt2 * ji[0] / I[0][0];
81 this->rotate( 1, 2, angle, ji, A );
82
83 // rotate about the y-axis
84 angle = dt2 * ji[1] / I[1][1];
85 this->rotate( 2, 0, angle, ji, A );
86
87 // rotate about the z-axis
88 angle = dt * ji[2] / I[2][2];
89 this->rotate( 0, 1, angle, ji, A);
90
91 // rotate about the y-axis
92 angle = dt2 * ji[1] / I[1][1];
93 this->rotate( 2, 0, angle, ji, A );
94
95 // rotate about the x-axis
96 angle = dt2 * ji[0] / I[0][0];
97 this->rotate( 1, 2, angle, ji, A );
98
99 dAtom->setJ( ji );
100 dAtom->setA( A );
101 }
102 }
103 }
104
105 template<typename T> void NVT<T>::moveB( void ){
106 int i, j;
107 DirectionalAtom* dAtom;
108 double Tb[3], ji[3];
109 double vel[3], frc[3];
110 double mass;
111
112 double instTemp;
113
114 instTemp = tStats->getTemperature();
115 chi += dt2 * ( instTemp / targetTemp - 1.0) / (tauThermostat*tauThermostat);
116
117 for( i=0; i<nAtoms; i++ ){
118
119 atoms[i]->getVel( vel );
120 atoms[i]->getFrc( frc );
121
122 mass = atoms[i]->getMass();
123
124 // velocity half step
125 for (j=0; j < 3; j++)
126 vel[j] += dt2 * ((frc[j] / mass ) * eConvert - vel[j]*chi);
127
128 atoms[i]->setVel( vel );
129
130 if( atoms[i]->isDirectional() ){
131
132 dAtom = (DirectionalAtom *)atoms[i];
133
134 // get and convert the torque to body frame
135
136 dAtom->getTrq( Tb );
137 dAtom->lab2Body( Tb );
138
139 // get the angular momentum, and propagate a half step
140
141 dAtom->getJ( ji );
142
143 for (j=0; j < 3; j++)
144 ji[j] += dt2 * (Tb[j] * eConvert - ji[j]*chi);
145
146
147 dAtom->setJ( ji );
148 }
149 }
150 }
151
152 template<typename T> int NVT<T>::readyCheck() {
153
154 //check parent's readyCheck() first
155 if (T::readyCheck() == -1)
156 return -1;
157
158 // First check to see if we have a target temperature.
159 // Not having one is fatal.
160
161 if (!have_target_temp) {
162 sprintf( painCave.errMsg,
163 "NVT error: You can't use the NVT integrator without a targetTemp!\n"
164 );
165 painCave.isFatal = 1;
166 simError();
167 return -1;
168 }
169
170 // We must set tauThermostat.
171
172 if (!have_tau_thermostat) {
173 sprintf( painCave.errMsg,
174 "NVT error: If you use the constant temperature\n"
175 " integrator, you must set tauThermostat.\n");
176 painCave.isFatal = 1;
177 simError();
178 return -1;
179 }
180 return 1;
181 }