void EvalSinCos () { VecR t, tt, u, w; int j, n; VSetAll (t, 2. * M_PI); VDiv (t, t, region); DO_MOL { VMul (tt, t, mol[n].r); VSetAll (tCos[0][n], 1.); VSetAll (tSin[0][n], 0.); VSet (tCos[1][n], cos (tt.x), cos (tt.y), cos (tt.z)); VSet (tSin[1][n], sin (tt.x), sin (tt.y), sin (tt.z)); VSCopy (u, 2., tCos[1][n]); VMul (tCos[2][n], u, tCos[1][n]); VMul (tSin[2][n], u, tSin[1][n]); VSetAll (tt, 1.); VVSub (tCos[2][n], tt); for (j = 3; j <= fSpaceLimit; j ++) { VMul (w, u, tCos[j - 1][n]); VSub (tCos[j][n], w, tCos[j - 2][n]); VMul (w, u, tSin[j - 1][n]); VSub (tSin[j][n], w, tSin[j - 2][n]); } } }
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 InitCoords () { VecR c, gap; int j, n, nx, ny, nz; VDiv (gap, region, initUcell); n = 0; for (nz = 0; nz < initUcell.z; nz ++) { for (ny = 0; ny < initUcell.y; ny ++) { for (nx = 0; nx < initUcell.x; nx ++) { VSet (c, nx + 0.25, ny + 0.25, nz + 0.25); VMul (c, c, gap); VVSAdd (c, -0.5, region); for (j = 0; j < 4; j ++) { mol[n].r = c; if (j != 3) { if (j != 0) mol[n].r.x += 0.5 * gap.x; if (j != 1) mol[n].r.y += 0.5 * gap.y; if (j != 2) mol[n].r.z += 0.5 * gap.z; } ++ n; } } } } }
void ComputeAngVel (int n, VecR *w) { Quat qt, qvt; qvt = mol[n].qv; qvt.u4 *= -1.; QMul (qt, qvt, mol[n].q); QScale (qt, 2.); VSet (*w, qt.u1, qt.u2, qt.u3); }
void InitAngVels () { real ang, angvFac; int n; angvFac = velMag / sqrt (1.5 * mInert); DO_MOL { ang = 2. * M_PI * RandR (); VSet (mol[n].sv, cos (ang), sin (ang), 0.); VScale (mol[n].sv, angvFac); } }
void DefineMol () { int j; for (j = 0; j < sitesMol; j ++) VZero (mSite[j].r); mSite[0].r.z = -0.0206; mSite[1].r.z = 0.0274; mSite[2].r.y = 0.240; mSite[2].r.z = 0.165; mSite[3].r.y = - mSite[2].r.y; mSite[3].r.z = mSite[2].r.z; VSet (mInert, 0.00980, 0.00340, 0.00640); bCon = 183.5; mSite[0].typeF = 1; mSite[1].typeF = 2; mSite[2].typeF = 3; mSite[3].typeF = 3; }
void InitCoords () { VecR c, gap; int n, nx, ny, nz; VDiv (gap, region, initUcell); n = 0; for (nz = 0; nz < initUcell.z; nz ++) { for (ny = 0; ny < initUcell.y; ny ++) { for (nx = 0; nx < initUcell.x; nx ++) { VSet (c, nx + 0.5, ny + 0.5, nz + 0.5); VMul (c, c, gap); VVSAdd (c, -0.5, region); mol[n].r = c; ++ n; } } } }