private LabelingPositionList RedoAV() { LabelingPositionList lps_local = new LabelingPositionList(this.LabelingPositions.Count); lps_local.AddRange(this.LabelingPositions); AVEngine av = new AVEngine(mt, this.ProjectDataCopy.AVGlobalParameters); LabelingPosition l; Vector3 rmp; int natom, nmol; for (Int32 i = 0; i < lps_local.Count; i++) { l = lps_local[i]; if (l.AVData.AVType == AVSimlationType.None) { continue; } nmol = sr.Molecules.FindIndex(l.Molecule); natom = Array.BinarySearch <Int32>(mt.OriginalAtomID, molstart[nmol], molnatoms[nmol], l.AVData.AtomID); if (l.AVData.AVType == AVSimlationType.SingleDyeR) { av.Calculate1R(l.AVData.L, l.AVData.W, l.AVData.R, natom); } else if (l.AVData.AVType == AVSimlationType.ThreeDyeR) { av.Calculate3R(l.AVData.L, l.AVData.W, l.AVData.R1, l.AVData.R2, l.AVData.R3, natom); } rmp = Matrix3.Transpose(sr.Rotation[nmol]) * (av.Rmp - sr.Translation[nmol] + sr.Molecules[0].CM - sr.Molecules[nmol].CM) + sr.Molecules[nmol].CM; l.X = rmp.X; l.Y = rmp.Y; l.Z = rmp.Z; lps_local[i] = l; } return(lps_local); }
public override SimulationResult Simulate() { // initial energy Elast = ForceAndTorque(); CheckForClashes(true); Elast += Eclash; int ntotal = 0; // current number of iterations int nsuccessfull = 0; // number of successfull iterations //const int nsuccessfull_max = 2000; // required number of successfull iterations between snapshots // simulate: main loop do { nsuccessfull += this.Iterate() ? 1 : 0; ntotal++; } while (nsuccessfull < this.SimulationParameters.MaxIterations);//while (ntotal < this.SimulationParameters.MaxIterations && nsuccessfull < nsuccessfull_max); // save result SimulationResult sr = new SimulationResult(); for (int i = 0; i < translation.Length; i++) { this.rotation[i] = Matrix3.RepairRotation(rotation[i]); } sr.E = ForceAndTorque(); CheckForClashes(true); sr.E += Eclash; sr.ParentStructure = _originalstate.InternalNumber; sr.Eclash = Eclash; sr.Ebond = Ebond; sr.Converged = (ntotal < this.SimulationParameters.MaxIterations); sr.SimulationMethod = _originalstate.SimulationMethod | SimulationMethods.MetropolisSampling; sr.Translation = new Vector3[translation.Length]; sr.Rotation = new Matrix3[translation.Length]; for (int i = 0; i < translation.Length; i++) { sr.Translation[i] = Matrix3.Transpose(rotation[0]) * (translation[i] - translation[0]) - _molecules[i].CM + _molecules[0].CM; this.rotation[i] = Matrix3.RepairRotation(rotation[i]); sr.Rotation[i] = Matrix3.RepairRotation(Matrix3.Transpose(rotation[0]) * rotation[i]); } sr.Molecules = _molecules; sr.CalculateBestFitTranslation(false); return(sr); }
/// <summary> /// Do one iteration /// </summary> /// <param name="normF">Sum of F*F</param> /// <param name="normT">Sum of T*T</param> /// <param name="K">Kinetic energy</param> /// <returns>Potential energy (before the iteration)</returns> private double Iterate(out double normF, out double normT, out double K) { double E, theta, thetaw, abst, absw; Molecule m; Vector3 force_i, torque_i, tmpt, v, w; Matrix3 tmpr; E = ForceAndTorque(); CheckForClashes(true); E += Eclash; normF = 0; normT = 0.0; K = 0.0; for (int i = 0; i < Nmolecules; i++) { m = _molecules[i]; tmpt = translationm1[i]; tmpr = rotation[i] * Matrix3.Transpose(rotationm1[i]); translationm1[i] = translation[i]; rotationm1[i] = rotation[i]; force_i = force[i]; normF += force_i * force_i; torque_i = torque[i]; normT += torque_i * torque_i; translation[i] = translation[i] * (2.0 - viscosity) - tmpt * (1.0 - viscosity) + force_i * (dt * dt / m.Mass); v = (translation[i] - tmpt) * 0.5 * rdt; K += 0.5 * m.Mass * (v * v); abst = torque_i.Normalize(); theta = dt * dt * abst / m.SimpleI; thetaw = Matrix3.AngleAndAxis(tmpr, out w); rotation[i] = Matrix3.Rotation(torque_i, theta) * Matrix3.Rotation(w, -thetaw * viscosity) * tmpr * rotation[i]; absw = thetaw * rdt; K += 0.5 * m.SimpleI * absw * absw; } return(E); }
// two molecules private Boolean CheckForClashes(int im1, int im2) { Molecule m1 = _molecules[im1]; Molecule m2 = _molecules[im2]; Vector3 dcm = translation[im1] - translation[im2], rc1, rc2; // check clusters Vector3[] rc2cache = new Vector3[m2.AtomClusters.Length]; double sumr, dsq, dx2, dy2, dz2; Vector3 sumrv; AtomCluster c1, c2; Matrix3 rot1to2 = Matrix3.Transpose(rotation[im2]) * rotation[im1]; Matrix3 rot2to1 = Matrix3.Transpose(rot1to2); Vector3 dcm1t = Matrix3.Transpose(rotation[im1]) * dcm; Vector3 dcm2t = Matrix3.Transpose(rotation[im2]) * dcm; int[] c2tocheck = new int[m2.AtomClusters.Length]; int j2, n2tocheck; int[] mustbechecked1 = new int[m1.AtomClusters.Length]; int[] mustbechecked2 = new int[m2.AtomClusters.Length]; // check if we can skip some of m2 n2tocheck = 0; for (int j = 0; j < m2.AtomClusters.Length; j++) { c2 = m2.AtomClusters[j]; rc2 = rot2to1 * c2 - dcm1t; dx2 = rc2.X * rc2.X; dy2 = rc2.Y * rc2.Y; dz2 = rc2.Z * rc2.Z; sumrv = m1.MaxRadius + c2.ClusterRadius; if ((dy2 + dz2 <= sumrv.X * sumrv.X) && (dx2 + dz2 <= sumrv.Y * sumrv.Y) && (dx2 + dy2 <= sumrv.Z * sumrv.Z)) { rc2cache[n2tocheck] = c2; c2tocheck[n2tocheck++] = j; } } for (int i = 0; i < m1.AtomClusters.Length; i++) { c1 = m1.AtomClusters[i]; rc1 = rot1to2 * c1 + dcm2t; // if completely out of reach, skip the check dx2 = rc1.X * rc1.X; dy2 = rc1.Y * rc1.Y; dz2 = rc1.Z * rc1.Z; sumrv = m2.MaxRadius + c1.ClusterRadius; if ((dy2 + dz2 > sumrv.X * sumrv.X) || (dx2 + dz2 > sumrv.Y * sumrv.Y) || (dx2 + dy2 > sumrv.Z * sumrv.Z)) { continue; } // otherwise check selected clusters from m2 for (int j = 0; j < n2tocheck; j++) { j2 = c2tocheck[j]; rc2 = rc2cache[j]; c2 = m2.AtomClusters[j2]; dsq = Vector3.SquareNormDiff(rc1, rc2); sumr = c1.ClusterRadius + c2.ClusterRadius; if (dsq < sumr * sumr) // clusters overlap, check all atoms { mustbechecked1[i] = 1; mustbechecked2[j2] = 1; // clash |= CheckForClashes(c1, c2, im1, im2, dcm); // => replaced with unmanaged } } } // this runs in m1's coordinate system! Vector3 fclash = new Vector3(), tclash1 = new Vector3(), tclash2 = new Vector3(); double dEClash = FpsNativeWrapper.CheckForClashes(FpsNativeWrapper.Aligned16(m1.XYZvdwRVectorArray), FpsNativeWrapper.Aligned16(m2.XYZvdwRVectorArray), m1.AtomClusters, m2.AtomClusters, m1.AtomClusters.Length, m2.AtomClusters.Length, mustbechecked1, mustbechecked2, rot2to1, -dcm1t, kclash, ref fclash, ref tclash1, ref tclash2); force[im1] += rotation[im1] * fclash; force[im2] -= rotation[im1] * fclash; torque[im1] += rotation[im1] * tclash1; torque[im2] += rotation[im1] * tclash2; Eclash += dEClash; return(dEClash > 1.0e-8); }
public override SimulationResult Simulate() { double E, K, Etot, theta, abst, normF, normT; Molecule m; Vector3 tnorm; // select dt and do the first time step E = ForceAndTorque(); CheckForClashes(true); E = E + Eclash; dt = dr4dt / Math.Sqrt(2.0 * Math.Max(E, Nmolecules) / minmass) * SimulationParameters.TimeStepFactor; rdt = 1.0 / dt; Etot_last = E; double Mtot = 0.0, ktot = 0.0; for (int i = 0; i < Nmolecules; i++) { Mtot += _molecules[i].Mass; } for (int i = 0; i < kplus.Length; i++) { ktot += Math.Max(kplus[i], kminus[i]); } viscosity_per_dt = SimulationParameters.ViscosityFactor * 2.0 * dt * Math.Sqrt(ktot / Mtot); viscosity = viscosity_per_dt * dt; viscosity = Math.Max(minviscosity, viscosity); viscosity = Math.Min(maxviscosity, viscosity); for (int i = 0; i < Nmolecules; i++) { m = _molecules[i]; translationm1[i] = translation[i]; rotationm1[i] = rotation[i]; translation[i] += force[i] * (0.5 / m.Mass) * dt * dt; abst = Vector3.Abs(torque[i]); tnorm = torque[i] * (1.0 / abst); theta = 0.5 * dt * dt * abst / m.SimpleI; rotation[i] *= Matrix3.Rotation(tnorm, theta); } // main loop int niter = 0, maxniter; optimize_selected_now = (SimulationParameters.OptimizeSelected == OptimizeSelected.Selected || SimulationParameters.OptimizeSelected == OptimizeSelected.SelectedThenAll); if (SimulationParameters.OptimizeSelected == OptimizeSelected.SelectedThenAll) { maxniter = SimulationParameters.MaxIterations / 2; } else { maxniter = SimulationParameters.MaxIterations; } do { E = Iterate(out normF, out normT, out K); Etot = E + K; niter++; if ((niter << 28) == 0 || Eclash > 10.0 || Etot > Etot_last + maxdE) { Cleanup(ref Etot); } Etot_last = Etot; }while (((normF > SimulationParameters.FTolerance) || (normT > SimulationParameters.TTolerance) || (K > SimulationParameters.KTolerance * Nmolecules)) && (niter < maxniter)); // repeat if selected then all if (SimulationParameters.OptimizeSelected == OptimizeSelected.SelectedThenAll) { dt = dr4dt / Math.Sqrt(2.0 * Math.Max(E, Nmolecules) / minmass) * SimulationParameters.TimeStepFactor; rdt = 1.0 / dt; viscosity = SimulationParameters.ViscosityFactor * 2.0 * dt * Math.Sqrt(ktot / Mtot); viscosity = Math.Max(minviscosity, viscosity); viscosity = Math.Min(maxviscosity, viscosity); niter = 0; optimize_selected_now = false; do { E = Iterate(out normF, out normT, out K); Etot = E + K; niter++; if ((niter << 28) == 0 || Eclash > 10.0 || Etot > Etot_last + maxdE) { Cleanup(ref Etot); } Etot_last = Etot; }while (((normF > SimulationParameters.FTolerance) || (normT > SimulationParameters.TTolerance) || (K > SimulationParameters.KTolerance * Nmolecules)) && (niter < maxniter)); } SimulationResult sr = new SimulationResult(); sr.E = E; sr.Eclash = Eclash; sr.Ebond = Ebond; sr.Converged = (niter < SimulationParameters.MaxIterations); sr.Translation = new Vector3[Nmolecules]; sr.Rotation = new Matrix3[Nmolecules]; sr.ParentStructure = _originalstate.InternalNumber; sr.SimulationMethod = _originalstate.SimulationMethod | SimulationMethods.Docking; for (int i = 0; i < Nmolecules; i++) { sr.Translation[i] = Matrix3.Transpose(rotation[0]) * (translation[i] - translation[0]) - _molecules[i].CM + _molecules[0].CM; sr.Rotation[i] = Matrix3.RepairRotation(Matrix3.Transpose(rotation[0]) * rotation[i]); } sr.Molecules = _molecules; sr.CalculateBestFitTranslation(false); return(sr); }