void ApplyThermostat () { RMat mc, mt; VecR vt, waB, wvB; real s1, s2, vFac; int n; s1 = s2 = 0.; DO_MOL { VSAdd (vt, mol[n].rv, 0.5 * deltaT, mol[n].ra); s1 += VDot (vt, mol[n].ra); s2 += VLenSq (vt); VSAdd (vt, mol[n].wv, 0.5 * deltaT, mol[n].wa); MVMulT (wvB, mol[n].rMatT.u, vt); MVMulT (waB, mol[n].rMatT.u, mol[n].wa); s1 += VWDot (mInert, wvB, waB); s2 += VWLenSq (mInert, wvB); } vFac = - s1 / s2; DO_MOL { VSAdd (vt, mol[n].rv, 0.5 * deltaT, mol[n].ra); VVSAdd (mol[n].ra, vFac, vt); VSAdd (vt, mol[n].wv, 0.5 * deltaT, mol[n].wa); VVSAdd (mol[n].wa, vFac, vt); } }
void InitAngVels () { Quat qe; VecR e; real f; int n; DO_MOL { VRand (&e); QSet (qe, e.x, e.y, e.z, 0.); QMul (mol[n].qv, mol[n].q, qe); f = 0.5 * velMag / sqrt (VWLenSq (mInert, e)); QScale (mol[n].qv, f); } }
void AdjustTemp () { real vFac; VecR w; int n; vvSum = 0.; DO_MOL vvSum += VLenSq (mol[n].rv); vFac = velMag / sqrt (vvSum / nMol); DO_MOL VScale (mol[n].rv, vFac); vvqSum = 0.; DO_MOL { ComputeAngVel (n, &w); vvqSum += VWLenSq (mInert, w); } vFac = velMag / sqrt (vvqSum / nMol); DO_MOL QScale (mol[n].qv, vFac); }
void EvalProps () { VecR w; int n; VZero (vSum); vvSum = 0.; DO_MOL { VVAdd (vSum, mol[n].rv); vvSum += VLenSq (mol[n].rv); } vvqSum = 0.; DO_MOL { ComputeAngVel (n, &w); vvqSum += VWLenSq (mInert, w); } vvSum += vvqSum; kinEnergy.val = 0.5 * vvSum / nMol; totEnergy.val = kinEnergy.val + uSum / nMol; }
void ApplyThermostat () { real s1, s2, vFac; VecR w; int n; s1 = s2 = 0.; DO_MOL { s1 += VDot (mol[n].rv, mol[n].ra); s2 += VLenSq (mol[n].rv); } DO_MOL { ComputeAngVel (n, &w); s1 += VDot (w, mol[n].torq); s2 += VWLenSq (mInert, w); } vFac = - s1 / s2; DO_MOL { VVSAdd (mol[n].ra, vFac, mol[n].rv); QSAdd (mol[n].qa, mol[n].qa, vFac, mol[n].qv); } }