Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
        // 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);
        }
Beispiel #5
0
        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);
        }