Пример #1
0
        private static void ApplyAtomForces(Molecule molecule,
                                            UnitValue elapsedTime,
                                            ForceCalculatorResult forces,
                                            MoleculeDynamicsSimulationSettings settings)
        {
            var maxVelocity = 1e2;
            var dT          = settings.TimeStep.In(Unit.Second);

            foreach (var vertexForce in forces.ForceLookup)
            {
                var atom  = molecule.GetAtom(vertexForce.Key);
                var force = vertexForce.Value;
                if (settings.ForceRampUp && elapsedTime < settings.ForceRampUpPeriod)
                {
                    var quotient = elapsedTime.Value / settings.ForceRampUpPeriod.Value;
                    force *= quotient;//Math.Pow(10, (int)(-100*quotient));
                }
                if (force.Magnitude() < ForceLowerCutoff)
                {
                    continue;
                }
                atom.Velocity += settings.TimeStep * (force.To(Unit.Newton) / atom.Mass);
                if (atom.Velocity.Magnitude().In(Unit.MetersPerSecond) > maxVelocity)
                {
                    atom.Velocity *= maxVelocity / atom.Velocity.Magnitude().In(Unit.MetersPerSecond);
                }
                atom.Position += dT * atom.Velocity;
                if (settings.ResetAtomVelocityAfterEachTimestep)
                {
                    atom.Velocity = new UnitVector3D(Unit.MetersPerSecond, 0, 0, 0);
                }
                else
                {
                    atom.Velocity *= 1.0; // TODO: Scale velocity to maintain a specific total energy, matching the environement's temperature
                }
            }
        }
Пример #2
0
        private static void ApplyLonePairRepulsion(ForceCalculatorResult forces)
        {
            foreach (var lonePairForce in forces.LonePairForceLookup)
            {
                var orbital = lonePairForce.Key;
                var atom    = orbital.Atom;
                var force   = lonePairForce.Value;
                if (force.Magnitude() < ForceLowerCutoff)
                {
                    continue;
                }
                var displacementDirection = force.Normalize();
                var atomRadius            = atom.Radius.Value;

                var lonePairVector         = atom.Position.VectorTo(orbital.MaximumElectronDensityPosition);
                var displacementNormal     = displacementDirection.ProjectOnto(lonePairVector.Normalize());
                var tangentialDisplacement = (displacementDirection - displacementNormal).ToVector3D();
                var displacedLonePair      = orbital.MaximumElectronDensityPosition
                                             + atomRadius * tangentialDisplacement;
                lonePairVector = atom.Position.VectorTo(displacedLonePair);
                var scaling = 0.85 * atomRadius / lonePairVector.Magnitude();
                orbital.MaximumElectronDensityPosition = atom.Position + scaling * lonePairVector;
            }
        }