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); }
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); }