void ComputeSiteForces () { VecR dr, shift; real fcVal, rr, rrCut, rri, rri3, uVal; int j1, j2, m1, m2, ms1, ms2, n, typeSum; rrCut = Sqr (rCut); for (n = 0; n < nMol * sitesMol; n ++) VZero (site[n].f); uSum = 0.; for (m1 = 0; m1 < nMol - 1; m1 ++) { for (m2 = m1 + 1; m2 < nMol; m2 ++) { VSub (dr, mol[m1].r, mol[m2].r); VZero (shift); VShiftAll (dr); VVAdd (dr, shift); rr = VLenSq (dr); if (rr < rrCut) { ms1 = m1 * sitesMol; ms2 = m2 * sitesMol; for (j1 = 0; j1 < sitesMol; j1 ++) { for (j2 = 0; j2 < sitesMol; j2 ++) { typeSum = mSite[j1].typeF + mSite[j2].typeF; if (mSite[j1].typeF == mSite[j2].typeF || typeSum == 5) { VSub (dr, site[ms1 + j1].r, site[ms2 + j2].r); VVAdd (dr, shift); rr = VLenSq (dr); rri = 1. / rr; switch (typeSum) { case 2: rri3 = Cube (rri); uVal = 4. * rri3 * (rri3 - 1.); fcVal = 48. * rri3 * (rri3 - 0.5) * rri; break; case 4: uVal = 4. * bCon * sqrt (rri); fcVal = uVal * rri; break; case 5: uVal = -2. * bCon * sqrt (rri); fcVal = uVal * rri; break; case 6: uVal = bCon * sqrt (rri); fcVal = uVal * rri; break; } VVSAdd (site[ms1 + j1].f, fcVal, dr); VVSAdd (site[ms2 + j2].f, - fcVal, dr); uSum += uVal; } } } } } } }
void EvalRdf () { VecR dr, shift; real deltaR, normFac, rr; int j1, j2, k, m1, m2, ms1, ms2, n, rdfType, typeSum; if (countRdf == 0) { for (k = 0; k < 3; k ++) { for (n = 0; n < sizeHistRdf; n ++) histRdf[k][n] = 0.; } } deltaR = rangeRdf / sizeHistRdf; for (m1 = 0; m1 < nMol - 1; m1 ++) { for (m2 = m1 + 1; m2 < nMol; m2 ++) { VSub (dr, mol[m1].r, mol[m2].r); VZero (shift); VShiftAll (dr); VVAdd (dr, shift); rr = VLenSq (dr); if (rr < Sqr (rangeRdf)) { ms1 = m1 * sitesMol; ms2 = m2 * sitesMol; for (j1 = 0; j1 < sitesMol; j1 ++) { for (j2 = 0; j2 < sitesMol; j2 ++) { typeSum = mSite[j1].typeRdf + mSite[j2].typeRdf; if (typeSum >= 2) { VSub (dr, site[ms1 + j1].r, site[ms2 + j2].r); VVAdd (dr, shift); rr = VLenSq (dr); if (rr < Sqr (rangeRdf)) { n = sqrt (rr) / deltaR; if (typeSum == 2) rdfType = 0; else if (typeSum == 3) rdfType = 1; else rdfType = 2; ++ histRdf[rdfType][n]; } } } } } } } ++ countRdf; if (countRdf == limitRdf) { normFac = VProd (region) / (2. * M_PI * Cube (deltaR) * Sqr (nMol) * countRdf); for (k = 0; k < 3; k ++) { for (n = 0; n < sizeHistRdf; n ++) histRdf[k][n] *= normFac / Sqr (n - 0.5); } PrintRdf (stdout); countRdf = 0; } }
void ComputeForces () { VecR dr; real fcVal, rr, rrCut, rri, rri3; int j1, j2, n; rrCut = Sqr (rCut); DO_MOL VZero (mol[n].ra); uSum = 0.; virSum = 0.; for (j1 = 0; j1 < nMol - 1; j1 ++) { for (j2 = j1 + 1; j2 < nMol; j2 ++) { VSub (dr, mol[j1].r, mol[j2].r); VWrapAll (dr); rr = VLenSq (dr); if (rr < rrCut) { rri = 1. / rr; rri3 = Cube (rri); fcVal = 48. * rri3 * (rri3 - 0.5) * rri; VVSAdd (mol[j1].ra, fcVal, dr); VVSAdd (mol[j2].ra, - fcVal, dr); uSum += 4. * rri3 * (rri3 - 1.) + 1.; virSum += fcVal * rr; } } } }
void SingleEvent () { real vvSum; int n; NextEvent (); if (evIdB < MOL_LIMIT) { ProcessCollision (); EvalFreePath (); ++ collCount; } else if (evIdB >= MOL_LIMIT + 100) { ProcessCellCrossing (); ++ crossCount; } else if (evIdB == MOL_LIMIT + 6) { UpdateSystem (); nextSumTime += intervalSum; ScheduleEvent (0, MOL_LIMIT + 6, nextSumTime); VZero (vSum); vvSum = 0.; DO_MOL { VVAdd (vSum, mol[n].rv); vvSum += VLenSq (mol[n].rv); } kinEnVal = vvSum * 0.5 / nMol; PrintSummary (stdout); }
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 SingleEvent () { real vvSum; real sp; int n; NextEvent (); if (evIdB < MOL_LIMIT) { ProcessCollision (); ++ collCount; } else if (evIdB < MOL_LIMIT + NDIM * 2 || evIdB >= MOL_LIMIT + 100) { ProcessCellCrossing (); ++ crossCount; } else if (evIdB == MOL_LIMIT + 6) { UpdateSystem (); nextSumTime += intervalSum; ScheduleEvent (0, MOL_LIMIT + 6, nextSumTime); VZero (vSum); vvSum = 0.; sp = 0.; DO_MOL { VVAdd (vSum, mol[n].rv); vvSum += VLenSq (mol[n].rv); sp += VDot (mol[n].r, gravField); } kinEnVal = vvSum * 0.5 / nMol; totEnVal = kinEnVal - sp / nMol; PrintSummary (stdout); } else if (evIdB == MOL_LIMIT + 7) {
void AdjustTemp () { real vFac; int n; VZero (vSum); DO_MOL VVAdd (vSum, mol[n].rv); DO_MOL VVSAdd (mol[n].rv, - 1. / nMol, vSum); vvSum = 0.; DO_MOL vvSum += VLenSq (mol[n].rv); vFac = velMag / sqrt (vvSum / nMol); DO_MOL VScale (mol[n].rv, vFac); vvsSum = 0.; DO_MOL vvsSum += mInert * VLenSq (mol[n].sv); vFac = velMag / sqrt (1.5 * vvsSum / nMol); DO_MOL VScale (mol[n].sv, vFac); }
void ApplyThermostat () { real s1, s2, vFac; int n; s1 = s2 = 0.; DO_MOL { s1 += VDot (mol[n].rv, mol[n].ra); s2 += VLenSq (mol[n].rv); } DO_MOL { s1 += mInert * VDot (mol[n].sv, mol[n].sa); s2 += mInert * VLenSq (mol[n].sv); } vFac = - s1 / s2; DO_MOL VVSAdd (mol[n].ra, vFac, mol[n].rv); DO_MOL VVSAdd (mol[n].sa, vFac, mol[n].sv); }
void ComputeForcesDipoleF () { VecR vc, vn, vs; real fMult, gr, gs, gu, pc, ps, sumC, sumS, t, w; int n, nvv, nx, ny, nz; gu = 2. * M_PI * dipoleInt / Cube (region.x); gr = 4. * M_PI * gu / region.x; gs = 2. * gu; EvalSinCos (); w = Sqr (M_PI / (region.x * alpha)); for (nz = 0; nz <= fSpaceLimit; nz ++) { for (ny = - fSpaceLimit; ny <= fSpaceLimit; ny ++) { for (nx = - fSpaceLimit; nx <= fSpaceLimit; nx ++) { VSet (vn, nx, ny, nz); nvv = VLenSq (vn); if (nvv == 0 || nvv > Sqr (fSpaceLimit)) continue; fMult = 2. * exp (- w * nvv) / nvv; if (nz == 0) fMult *= 0.5; sumC = sumS = 0.; DO_MOL { VSet (vc, tCos[abs (nx)][n].x, tCos[abs (ny)][n].y, tCos[nz][n].z); VSet (vs, tSin[abs (nx)][n].x, tSin[abs (ny)][n].y, tSin[nz][n].z); if (nx < 0) vs.x = - vs.x; if (ny < 0) vs.y = - vs.y; pc = vc.x * vc.y * vc.z - vc.x * vs.y * vs.z - vs.x * vc.y * vs.z - vs.x * vs.y * vc.z; ps = vs.x * vc.y * vc.z + vc.x * vs.y * vc.z + vc.x * vc.y * vs.z - vs.x * vs.y * vs.z; sumC += VDot (vn, mol[n].s) * pc; sumS += VDot (vn, mol[n].s) * ps; } DO_MOL { VSet (vc, tCos[abs (nx)][n].x, tCos[abs (ny)][n].y, tCos[nz][n].z); VSet (vs, tSin[abs (nx)][n].x, tSin[abs (ny)][n].y, tSin[nz][n].z); if (nx < 0) vs.x = - vs.x; if (ny < 0) vs.y = - vs.y; pc = vc.x * vc.y * vc.z - vc.x * vs.y * vs.z - vs.x * vc.y * vs.z - vs.x * vs.y * vc.z; ps = vs.x * vc.y * vc.z + vc.x * vs.y * vc.z + vc.x * vc.y * vs.z - vs.x * vs.y * vs.z; t = gr * fMult * VDot (vn, mol[n].s) * (sumC * ps - sumS * pc); VVSAdd (mol[n].ra, t, vn); t = gs * fMult * (sumC * pc + sumS * ps); VVSAdd (mol[n].sa, - t, vn); } uSum += gu * fMult * (Sqr (sumC) + Sqr (sumS)); } } } }
void EvalProps () { VecR w; int n; VZero (vSum); vvSum = 0.; DO_MOL { VVAdd (vSum, mol[n].rv); vvSum += VLenSq (mol[n].rv); } vvsSum = 0.; DO_MOL vvsSum += mInert * VLenSq (mol[n].sv); vvSum += vvsSum; kinEnergy.val = 0.5 * vvSum / nMol; totEnergy.val = kinEnergy.val + uSum / nMol; VZero (w); DO_MOL VVAdd (w, mol[n].s); dipoleOrder.val = VLen (w) / nMol; }
void ComputeDipoleAccel () { real t; int n; DO_MOL { t = VDot (mol[n].sa, mol[n].s) + mInert * VLenSq (mol[n].sv); VVSAdd (mol[n].sa, - t, mol[n].s); VScale (mol[n].sa, 1. / mInert); } }
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 EvalRdf () { VecR dr; real deltaR, normFac, rr, sr1, sr2, ss; int j1, j2, k, n; if (countRdf == 0) { for (k = 0; k < 3; k ++) { for (n = 0; n < sizeHistRdf; n ++) histRdf[k][n] = 0.; } } deltaR = rangeRdf / sizeHistRdf; for (j1 = 0; j1 < nMol - 1; j1 ++) { for (j2 = j1 + 1; j2 < nMol; j2 ++) { VSub (dr, mol[j1].r, mol[j2].r); VWrapAll (dr); rr = VLenSq (dr); if (rr < Sqr (rangeRdf)) { ss = VDot (mol[j1].s, mol[j2].s); sr1 = VDot (mol[j1].s, dr); sr2 = VDot (mol[j2].s, dr); n = sqrt (rr) / deltaR; ++ histRdf[0][n]; histRdf[1][n] += ss; histRdf[2][n] += 3. * sr1 * sr2 / rr - ss; } } } ++ countRdf; if (countRdf == limitRdf) { normFac = VProd (region) / (2. * M_PI * Cube (deltaR) * Sqr (nMol) * countRdf); for (k = 0; k < 3; k ++) { for (n = 0; n < sizeHistRdf; n ++) histRdf[k][n] *= normFac / Sqr (n - 0.5); } PrintRdf (stdout); countRdf = 0; } }
void ComputeForcesDipoleR () { VecR dr, w; real a1, a2, a3, alpha2, d, irPi, rr, rrCut, rri, sr1, sr2, ss, t; int j1, j2, n; rrCut = Sqr (0.5 * region.x); irPi = 1. / sqrt (M_PI); alpha2 = Sqr (alpha); DO_MOL VZero (mol[n].sa); for (j1 = 0; j1 < nMol - 1; j1 ++) { for (j2 = j1 + 1; j2 < nMol; j2 ++) { VSub (dr, mol[j1].r, mol[j2].r); VWrapAll (dr); rr = VLenSq (dr); if (rr < rrCut) { d = sqrt (rr); rri = 1. / rr; t = 2. * dipoleInt * alpha * exp (- alpha2 * rr) * rri * irPi; a1 = dipoleInt * erfc (alpha * d) * rri / d + t; a2 = 3. * a1 * rri + 2. * alpha2 * t; a3 = 5. * a2 * rri + 4. * Sqr (alpha2) * t; ss = VDot (mol[j1].s, mol[j2].s); sr1 = VDot (mol[j1].s, dr); sr2 = VDot (mol[j2].s, dr); VSSAdd (w, sr2, mol[j1].s, sr1, mol[j2].s); t = (a2 * ss - a3 * sr1 * sr2); VSSAdd (w, t, dr, a2, w); VVAdd (mol[j1].ra, w); VVSub (mol[j2].ra, w); VVSAdd (mol[j1].sa, - a1, mol[j2].s); VVSAdd (mol[j1].sa, a2 * sr2, dr); VVSAdd (mol[j2].sa, - a1, mol[j1].s); VVSAdd (mol[j2].sa, a2 * sr1, dr); uSum += a1 * ss - a2 * sr1 * sr2; } } } uSum -= 2. * dipoleInt * Cube (alpha) * nMol * irPi / 3.; }
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); } }