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