예제 #1
0
        static public void VelocityVerlet(DPDSim sim)
        {
            var N_sites = sim.site_ids.Length;

            double dt      = sim.delta_t;
            double h_dt_sq = 0.5 * (dt * dt);

            //
            // Advance positions.
            //
            for (var site_i = 0; site_i < N_sites; site_i++)
            {
                var s = site_i * 3;

                //
                // Calculate new positions
                //
                sim.r[s + 0] += dt * sim.v[s + 0] + h_dt_sq * sim.f[s + 0];
                sim.r[s + 1] += dt * sim.v[s + 1] + h_dt_sq * sim.f[s + 1];
                sim.r[s + 2] += dt * sim.v[s + 2] + h_dt_sq * sim.f[s + 2];

                //
                // Wrap new positions to periodic boundary
                //
                sim.r[s + 0] -= sim.cell[0] * Math.Round(sim.r[s + 0] / sim.cell[0], MidpointRounding.AwayFromZero);
                sim.r[s + 1] -= sim.cell[1] * Math.Round(sim.r[s + 1] / sim.cell[1], MidpointRounding.AwayFromZero);
                sim.r[s + 2] -= sim.cell[2] * Math.Round(sim.r[s + 2] / sim.cell[2], MidpointRounding.AwayFromZero);

                //
                // Store current velocities and forces
                //
                sim.v_[s + 0] = sim.v[s + 0];
                sim.v_[s + 1] = sim.v[s + 1];
                sim.v_[s + 2] = sim.v[s + 2];

                sim.f_[s + 0] = sim.f[s + 0];
                sim.f_[s + 1] = sim.f[s + 1];
                sim.f_[s + 2] = sim.f[s + 2];

                //
                // Calculate temporary velocity prediction
                //
                sim.v[s + 0] += sim.lambda * dt * sim.f[s + 0];
                sim.v[s + 1] += sim.lambda * dt * sim.f[s + 1];
                sim.v[s + 2] += sim.lambda * dt * sim.f[s + 2];

                //
                // Zero force array; force routines treat it as an accumulator.
                //
                sim.f[s + 0] = 0.0;
                sim.f[s + 1] = 0.0;
                sim.f[s + 2] = 0.0;
            }

            //
            // Get new forces for these positions and temporary velocity prediction
            //
            if (sim.i_am_dumb == 1)
            {
                Forces.DoNonbondedSlow(sim);
            }
            else
            {
                Forces.DoNonbondedFast(sim);
            }

            Forces.DoBonds(sim);
            Forces.DoAngles(sim);

            //
            // At this point we have:
            // sim->v_ == original velocities for this step, sim->v == velocity prediction.
            // sim->f_ == original forces for this step, sim->f == forces at new positions and predicted velocities.
            //

            //
            // Correct the velocities using the two force arrays.
            //
            sim.kinetic_energy = 0.0;
            for (var site_i = 0; site_i < N_sites; site_i++)
            {
                var s = site_i * 3;

                sim.v[s + 0] = sim.v_[s + 0] + 0.5 * dt * (sim.f_[s + 0] + sim.f[s + 0]);
                sim.v[s + 1] = sim.v_[s + 1] + 0.5 * dt * (sim.f_[s + 1] + sim.f[s + 1]);
                sim.v[s + 2] = sim.v_[s + 2] + 0.5 * dt * (sim.f_[s + 2] + sim.f[s + 2]);

                //
                // Add kinetic contribution to the pressure tensor.
                //
                double pvx = 0.5 * (sim.v_[s + 0] + sim.v[s + 0]);
                double pvy = 0.5 * (sim.v_[s + 1] + sim.v[s + 1]);
                double pvz = 0.5 * (sim.v_[s + 2] + sim.v[s + 2]);

                sim.pressure[0] += pvx * pvx;
                sim.pressure[1] += pvx * pvy;
                sim.pressure[2] += pvx * pvz;

                sim.pressure[3] += pvy * pvx;
                sim.pressure[4] += pvy * pvy;
                sim.pressure[5] += pvy * pvz;

                sim.pressure[6] += pvz * pvx;
                sim.pressure[7] += pvz * pvy;
                sim.pressure[8] += pvz * pvz;

                sim.kinetic_energy += 0.5 * ((sim.v[s + 0] * sim.v[s + 0]) + (sim.v[s + 1] * sim.v[s + 1]) + (sim.v[s + 2] * sim.v[s + 2]));
            }

            //
            // Divide all pressure tensor elements by sim volume for correct units
            //
            double volume = sim.cell[0] * sim.cell[1] * sim.cell[2];

            for (var i = 0; i < 9; i++)
            {
                sim.pressure[i] /= volume;
            }
        }
예제 #2
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("Pass in simulation definition file as first parameter!");
                System.Environment.Exit(-1);
            }

            DPDSim sim = new DPDSim();

            //
            // Load DPD sim data
            //

            try
            {
                using (StreamReader f = File.OpenText(args[0]))
                {
                    DPDIO.LoadSim(f, sim);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                DPDError("Unable to open input file '{0}'", args[0]);
            }

            //
            // Print initial system info
            //

            Console.WriteLine("Friction coefficient is {0} ( as sigma = {1} )", sim.fric, sim.sigma);
            Console.WriteLine("Bead density is {0} per cubic Rc", ((double)sim.site_ids.Length) / (sim.cell[0] * sim.cell[1] * sim.cell[2]));

            {
                sim.ClearEnergyAndPressure();

                if (sim.i_am_dumb == 1)
                {
                    Forces.DoNonbondedSlow(sim);
                }
                else
                {
                    Forces.DoNonbondedFast(sim);
                }

                Forces.DoBonds(sim);
                Forces.DoAngles(sim);

                DPDIO.PrintSimInfo(sim, 0.0);
            }

            //
            // Main integration loop
            //

            var time_start = DateTime.Now;

            for ( ; sim.step_no <= sim.max_steps; sim.step_no++)
            {
                sim.ClearEnergyAndPressure();

                Integrator.VelocityVerlet(sim);

                if (sim.step_no % sim.save_every == 0)
                {
                    save_checkpoint_and_trajectory(sim);
                }
                if (sim.step_no % sim.print_every == 0)
                {
                    DPDIO.PrintSimInfo(sim, (DateTime.Now - time_start).TotalSeconds);
                }
            }

            //
            // Final information
            //

            Console.WriteLine("");
            Console.WriteLine("Final information:");
            Console.WriteLine("");

            DPDIO.PrintSimInfo(sim, (DateTime.Now - time_start).TotalSeconds);
            save_checkpoint_and_trajectory(sim);
        }