Esempio n. 1
0
        public static Matrix3 RepairRotation(Matrix3 R)
        {
            Vector3 u;
            Double  theta = Matrix3.AngleAndAxis(R, out u);
            Double  absu  = Vector3.Abs(u);

            u = u * (1.0 / absu);
            return(Matrix3.Rotation(u, theta));
        }
Esempio n. 2
0
        private bool Iterate()
        {
            // random subunit
            int i = _rnd.Next(this.translation.Length);

            // save initial state
            this.translationm1[i] = this.translation[i];
            this.rotationm1[i]    = this.rotation[i];

            // random translation
            double translationstep = 0.05;

            this.translation[i].X += RandomNorm() * translationstep;
            this.translation[i].Y += RandomNorm() * translationstep;
            this.translation[i].Z += RandomNorm() * translationstep;

            // random rotation
            double rotationstep = 0.0017; // ~0.1° in rad

            // random rotation axis (anisotropic, normalized)
            double phi, rxy;
            double z0 = -1.0 + 2.0 * _rnd.NextDouble();

            rxy = Math.Sqrt(1 - z0 * z0);
            phi = _rnd.NextDouble() * 2.0 * Math.PI;
            Vector3 u = new Vector3(Math.Cos(phi) * rxy, Math.Sin(phi) * rxy, z0);

            // rotation matrix
            Matrix3 rot = Matrix3.Rotation(u, RandomNorm() * rotationstep);

            this.rotation[i] = rot * this.rotation[i];

            // recalculate "energy"
            double E = ForceAndTorque();

            CheckForClashes(true);
            E += Eclash;

            // accept or reject
            double recipr_kT = this.SimulationParameters.rkT;
            bool   accepted  = E < Elast || _rnd.NextDouble() < Math.Exp((Elast - E) * recipr_kT);

            // revert to previous state if rejected
            if (!accepted)
            {
                this.translation[i] = this.translationm1[i];
                this.rotation[i]    = this.rotationm1[i];
            }
            else
            {
                Elast = E;
            }

            return(accepted);
        }
Esempio n. 3
0
        // calculate <R>
        public Double AveragedDistance(Vector3[] r1, Vector3[] r2, Double translation,
                                       Boolean FRETAveraged, Boolean shuffle, Double R0, Random rnd)
        {
            Vector3 rrand;
            Matrix3 Urand;
            Double  t, uz, uxy, uphi, Emean, Rmean, R06 = Math.Pow(R0, 6.0);

            if (shuffle)
            {
                // random translation of 1
                uz    = -1.0 + rnd.NextDouble() * 2.0;
                uxy   = Math.Sqrt(1.0 - uz * uz);
                uphi  = rnd.NextDouble() * 2.0 * Math.PI;
                rrand = new Vector3(uxy * Math.Cos(uphi), uxy * Math.Sin(uphi), uz);
                rrand = rrand * translation;

                // random rotation of 2
                uz    = -1.0 + rnd.NextDouble() * 2.0;
                uxy   = Math.Sqrt(1.0 - uz * uz);
                uphi  = rnd.NextDouble() * 2.0 * Math.PI;
                Urand = Matrix3.Rotation(new Vector3(uxy * Math.Cos(uphi), uxy * Math.Sin(uphi), uz),
                                         2.0 * Math.PI * rnd.NextDouble());
            }
            else
            {
                rrand = new Vector3();
                Urand = Matrix3.E;
            }

            if (FRETAveraged)
            {
                Emean = 0.0;
                for (Int32 j = 0; j < _nsamples; j++)
                {
                    t = Vector3.SquareNormDiff(r1[rnd.Next(r1.Length - 1)] + rrand,
                                               Urand * r2[rnd.Next(r2.Length - 1)]);
                    Emean += 1.0 / (1.0 + t * t * t / R06);
                }
                Emean /= ((Double)_nsamples);
                Rmean  = R0 * Math.Pow((1.0 / Emean - 1.0), 1.0 / 6.0);
            }
            else
            {
                Rmean = 0.0;
                for (Int32 j = 0; j < _nsamples; j++)
                {
                    Rmean += Math.Sqrt(Vector3.SquareNormDiff(r1[rnd.Next(r1.Length - 1)] + rrand,
                                                              Urand * r2[rnd.Next(r2.Length - 1)]));
                }
                Rmean /= ((Double)NSamples);
            }
            return(Rmean);
        }
Esempio n. 4
0
        /// <summary>
        /// Randomly redistributes subunits until no clashes are detected
        /// </summary>
        public override double SetState()
        {
            Vector3 tshake;
            Vector3 ushake;
            double  angleshake, uz, uxy, uphi;
            Matrix3 rotshake;
            int     lastshaked;

            PrepareSimulation();
            _originalstate = new SimulationResult()
            {
                InternalNumber = -1
            };

            for (int i = 0; i < _molecules.Count; i++)
            {
                translation[i] = new Vector3(0.0, 0.0, 0.0);
                rotation[i]    = Matrix3.E;
            }
            do
            {
                for (int i = 1; i < _molecules.Count; i++)
                {
                    lastshaked = 0;
                    if (!_molecules[i].Selected)
                    {
                        tshake          = (new Vector3(_rnd.NextDouble(), _rnd.NextDouble(), _rnd.NextDouble()) + (-0.5)) * 10.0;
                        translation[i] += tshake;
                        lastshaked      = i;
                        uz              = -1.0 + _rnd.NextDouble() * 2.0;
                        uxy             = Math.Sqrt(1.0 - uz * uz);
                        uphi            = _rnd.NextDouble() * 2.0 * Math.PI;
                        ushake          = new Vector3(uxy * Math.Cos(uphi), uxy * Math.Sin(uphi), uz);
                        angleshake      = 2.0 * Math.PI * _rnd.NextDouble();
                        rotshake        = Matrix3.Rotation(ushake, angleshake);
                        rotation[i]     = rotshake * rotation[i];
                    }
                    else
                    {
                        translation[i] = translation[lastshaked] + _molecules[i].CM - _molecules[lastshaked].CM;
                        rotation[i]    = rotation[lastshaked];
                    }
                }
            }while (CheckForClashes(false));
            return(ForceAndTorque());
        }
Esempio n. 5
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);
        }
Esempio n. 6
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);
        }