void TpsTestPeSurf2dMD::run(int nsteps) { for (int i=0; i<nsteps; i++) { verlet(_current_timeslice); } callbackOnRunCommand(); }
void advance(int nprt,int ndim,double dt,double mass, double *coord,double *veloc,double *accel, double *pkin ,double *ppot) { /* alloc aux space for forces */ double *force=(double*)malloc(ndim*nprt*sizeof(double)); /* compute forces & energies */ compute(nprt,ndim,mass,coord,veloc,force,pkin,ppot); /* move particles using Verlet's algorithm */ verlet(nprt,ndim,dt,mass,coord,veloc,accel,force); /* free aux space */ free(force); }
void VerletManager::onTick(float seconds){ if(solve){ verlet(seconds); for(int i=0; i<_numSolves; i++){ _constraintManager->solveConstraints(); constraints(); } _constraintManager->solveConstraints(); for(Verlet* v:verlets) v->onTick(seconds); // foreach(Verlet* v, verlets){ // v->verlet(seconds); // for(int i=0; i<_numSolves; i++){ // v->linkConstraint(); // v->pinConstraint(); // } // v->onTick(seconds); // } } }
int SolveStep::solve(double timestep, double time, std::string name, std::string method, std::string dimension) { /* Solves given system with given parametres using * given method * timestep: size of timestep * time: total simulation time * name: name of files where the position of the * particles are saved at some timesteps * method: verlet or RK4 * dimension: ly or AU * * Ditterent timers have not been used at the * same time.*/ clock_t start, finish; Distance d; //declaration and intialisation omp_set_num_threads(8); //parallelisation double limit = 60; //definition of bound system arma::Col<double> center(3), position(3); center.zeros(); double t = 0.; System newsystem = mysolarsystem_; int n = time/timestep; //file to store energy of the system std::ofstream energy("energy.m"); energy << "A = ["; //file to store energy of the bound system std::ofstream bound("BoundEnergy.m"); bound << "A = ["; //update the objects initial acceleration for (int i = 0 ; i < size() ; ++i) { Object &mainbody = newsystem.objectlist[i]; newsystem.acceleration(mainbody, i, 0.0,dimension); } // start = clock(); //start timer //start simulation for (int k = 0 ; k < n ; ++k) { t += timestep; //file to store position of particles name.append("t"); std::string filename = name; filename.append(".m"); std::ofstream fout(filename.c_str()); fout << "t = " << t << "\n A = ["; //variable needed for calculating intermediate steps double addtime = 0.0; //simulate all particles for one timestep #pragma omp parallel for private(i) for (int i = 0 ; i < size() ; ++i) { Object &mainbody = newsystem.objectlist[i]; System tempSystem = mysolarsystem_; double dt = timestep; int j = 0; double maxTimestep; //chose the smallest timestep if (mainbody.maxTimestep() < tempSystem.maxTimestep(i)) { maxTimestep = mainbody.maxTimestep(); } else { maxTimestep = tempSystem.maxTimestep(i); } //make sure to use small endough timesteps while(dt > maxTimestep) { dt = dt/2.0; j += 1; } //simulate timesteps for (int kk = 0 ; kk < std::pow(2,j); ++kk) { if (method == "rk4") { start = clock(); //start timer rk4Step(dt, i, mainbody, tempSystem, addtime, dimension); finish = clock(); //stop timer std::cout << "time one rk4 step: " << static_cast<double>(finish - start)/ static_cast<double>(CLOCKS_PER_SEC ) << " s" << std::endl; // mainbody.addToFile(name); addtime += dt; } else if(method == "verlet") { start = clock(); //start timer verlet(dt, i, mainbody, tempSystem, addtime, dimension); finish = clock(); //stop timer std::cout << "time one verlet step: " << static_cast<double>(finish - start)/ static_cast<double>(CLOCKS_PER_SEC ) << " s" << std::endl; // mainbody.addToFile(name); addtime += dt; } else { std::cout << "method must be 'verlet' or 'rk4'" << std::endl; } } mysolarsystem_ = newsystem; //save position to file for (int i = 0 ; i < size() ; ++i) { Object &mainbody = mysolarsystem_.objectlist[i]; position = mainbody.getPosition(); double dist = d.twoObjects(position,center) ; if(dist < limit) { fout << mainbody.getPosition()(0) << "\t\t" << mainbody.getPosition()(1) << "\t\t" << mainbody.getPosition()(2) << "\n"; } // else // { // mysolarsystem_.removeObject(i); // i-=1; // } } fout << "]; \n"; fout << "plot3(A(:,1), A(:,2),A(:,3), 'o')\n"; fout << "t = " << t ; fout.close(); } //write energy of the system to file bound << t << "\t\t" << mysolarsystem_.boundPotentialEnergy(limit) << "\t\t" << mysolarsystem_.boundKineticEnergi(limit) << "\n"; energy << t << "\t\t" << mysolarsystem_.potentialEnergy() << "\t\t" << mysolarsystem_.kineticEnergi() << "\n"; if (k % 100 == 0) { std::cout << t << std::endl; } } // finish = clock(); //stop timer // std::cout << "time: " << // static_cast<double>(finish - start)/ // static_cast<double>(CLOCKS_PER_SEC ) << " s" << std::endl; energy << "]; \n"; energy.close(); bound << "]; \n"; bound.close(); for (int i = 0 ; i < size() ; ++i) { Object &mainbody = mysolarsystem_.objectlist[i]; mysolarsystem_.acceleration(mainbody, i, 0.0,dimension); } //write final postition to file std::ofstream fout("end.m"); fout << "A = ["; for (int i = 0 ; i < size() ; ++i) { Object &mainbody = mysolarsystem_.objectlist[i]; fout << mainbody.getPosition()(0) << "\t\t" << mainbody.getPosition()(1) << "\t\t" << mainbody.getPosition()(2) << "\n"; } fout << "] \n"; fout.close(); return 0; }
int main() { // Floating point precision typedef double FLOAT; // Units typedef angstrom<FLOAT> x; // length typedef K<FLOAT> T; // temperature typedef u<FLOAT> m; // mass typedef angstrom_div_ps<FLOAT> v; // velocity typedef angstrom_div_ps2<FLOAT> a; // acceleration typedef u_mul_angstrom_div_ps2<FLOAT> f; // force typedef u_mul_angstrom2_div_ps2<FLOAT> e; // energy typedef ps<FLOAT> t; // time // Declarations auto mass = m(39.948); auto temp = T(100); auto epsilon = T(119.8); auto dx = x(5.26); auto sigma = x(3.405); auto dt = t(0.01); auto t_end = t(10); auto N = ARRAYLIST(size_t, 4, 4, 4); string molecule[4]; molecule[0] = "Ar"; molecule[1] = "Ar"; molecule[2] = "Ar"; molecule[3] = "Ar"; ofstream time_file; time_file.open("time.dat"); auto t0 = clock(); // Boltzmann velocity dirstribution Boltzmann<FLOAT> boltz(temp, mass); Gaussian<v> gauss(boltz.StandardDeviation()); auto boltz_vel = delegate(gauss, &Gaussian<v>::Distribution_mu_0); // Models typedef VMD<x,Vector<v,3>> pos; typedef VMD_Vel<x,v> vel; typedef Vector<a,3> va; typedef Array<va> acc; typedef PBC<pos,vel,acc,void,x,3>::CX pref; typedef PBC<pos,vel,acc,void,x,3>::CA aref; typedef LJ_Potential<3,x,a,m,f,e> Potential; typedef Delegate<void,pref&,aref&> LJ_Solver; typedef PBC<pos,vel,acc,LJ_Solver,x,3> Boundary; typedef Delegate<void,pos&> PeriodicBoundary; typedef Delegate<void,pos&,vel&,acc&> List; typedef VelocityVerlet<2,pos,vel,va,List> VerletModel; typedef Delegate<void,t&> VerletSolver; // Molecular dynamic model MD_Model<m,t,x,v,VerletSolver,PeriodicBoundary> model(mass, dt, "Argon centered cubic lattice"); // Lennard-Jones potenial Potential potential(sigma, mass, 0); auto LJ_acc = delegate(potential, &Potential::Acceleration<pref,aref>); // Periodic bounary condition Boundary pbc(LJ_acc); for(size_t i = 0; i < 3; i++) { pbc.origin[i] = -0.25*dx; pbc.range[i] = dx*(N[i]-0.25); } auto periodic_boundary = delegate(pbc, &Boundary::Boundary<pos>); model.boundary = &periodic_boundary; auto list = delegate(pbc, &Boundary::NeighbourList); auto dist_vec = delegate(static_cast<MinImage<x,3>&>(pbc), &MinImage<x,3>::Distance<x,x>); auto dist = delegate(&Euclidean::Length<Vector<x,3>>); auto unit_vec = delegate(&Euclidean::UnitVector<x,x,3>); potential.dist_vec = &dist_vec; potential.dist = &dist; potential.unit_vec = &unit_vec; // Verlet differential solver VerletModel verlet(static_cast<pos&>(model), static_cast<vel&>(model), list); auto verlet_solver = delegate(verlet, &VerletModel::Solve<t>); model.step = &verlet_solver; // Lattice configuration model.LatticeCenteredCubic(molecule, dx, N); model.SetVelocityDistribution(boltz_vel); auto data = static_cast<vel>(model); TimeStep<t,decltype(model)> time(model); // Task a and b /*time.Open("b.xyz"); time.Print(); time.Close();*/ // Task c auto step = delegate(model, &decltype(model)::Step<t,decltype(model)>); auto Time = time; /*Time.Open("c.xyz"); Run(Time, t_end, step); Time.Close();*/ // Task d auto boundary = delegate(model, &decltype(model)::Boundary<t,decltype(model)>); /**time.data = data; Time = time; Time.Open("d.xyz"); Run(Time, t_end, step, boundary); Time.Close();*/ // Task g potential = epsilon * Boltzmann<FLOAT>::kB; /**time.data = data; Time = time; Time.Open("g.xyz"); verlet = 0; // Initialize verlet solver t0 = clock(); Run(Time, t_end, step, boundary); time_file << (double)(clock()-t0)/CLOCKS_PER_SEC << " & "; Time.Close();*/ // Task h for(size_t i = 0; i < 3; i++) pbc[i] = (pbc.range[i]-pbc.origin[i])/(3*sigma); *time.data = data; Time = time; Time.Open("h.xyz"); verlet = 0; // Initialize verlet solver t0 = clock(); Run(Time, t_end, step, boundary); time_file << (double)(clock()-t0)/CLOCKS_PER_SEC << " \\\\ "; Time.Close(); time_file.close(); return 0; }
int main(void) { int N, n, i, j, t, g, T_EQ, T_RUN, bins; double h, f(), v_sq, N_U; double v_avg, vsq_avg, vavg_min, vavg_max, v_one; FILE* fout; fout = fopen("anharmonicpositionvelocity.txt", "w"); h = 0.02; T_EQ = 800; N_U = 1 / h; //User inputs parameters of program printf("How many molecules in the system? "); scanf("%d", &N); printf("How many timesteps? "); scanf("%d", &T_RUN); printf("Amongst how many bins should the velocities be distributed? "); scanf("%d", &bins); double x[N], v[N], vavg_array[T_RUN], bin_val[bins], v_bins[bins], width, gaussian[bins]; width = 6.0 / bins; //gives each particle in the system an initial velocity/displacement for(n = 0; n < N; n++) { v[n] = sin(2*M_PI*((double)n + 1.3) / (double)N); x[n] = 0; //fprintf(fout, "%f %f\n", x[n], v[n]); } //below loop puts the system into equilibrium for(t = 0; t <= T_EQ; t++) { for(j = 0; j < N_U; j++) { verlet(N, h, x, v, f); } } //runs the system and begins to record velocities for(t = 0; t < T_RUN; t++) { v_one = 0; v_sq = 0; //updates particles' positions and velocities N_U times per second for(i = 0; i < N_U; i++) { verlet(N, h, x, v, f); } //distributes all velocities into the bins CreateBins(N, bins, width, v, bin_val, v_bins); //computes <v^2> for each time step for(i = 0; i < N; i++) { v_sq += v[i] * v[i] / (double)N; } //computes the average of all <v^2> vsq_avg += v_sq/T_RUN; } double Norm = 0, AREA_GAUSS = 0, AREA_BINS = 0; //finds the normalization constant to fit the outputted data to a normalized gaussian curve for(i = 0; i <= bins; i++) Norm += width * v_bins[i]; fprintf(fout, "T = %f\nNormalization Constant = %f\n\n", vsq_avg, Norm); fprintf(fout, " v P(v) Gaussian Fit\n"); //Computes the gaussian fit for each bin based off <v^2> and prints normalized frequency data for(i = 0; i <= bins; i++) { gaussian[i] = ((1 / sqrt(2 * M_PI * vsq_avg)) * exp(-(bin_val[i] * bin_val[i]) / (2 * vsq_avg))); //calculates the area underneath each normalized function for every bin AREA_GAUSS += gaussian[i] * width; AREA_BINS += (v_bins[i] / Norm) * width; fprintf(fout, "%f %f %f\n", bin_val[i], v_bins[i] / Norm, gaussian[i]); } fprintf(fout, "\nArea under normalized velocity distribution = %f\n", AREA_BINS); fprintf(fout, "Area under gaussian distribution = %f\n", AREA_GAUSS); return 0; }