/*--- leap: takes a leapfrog step ---*/ double leap(CHAIN * C, double h) { double dTdP[C->N-1][3], dUdQ[C->N-1][3], du1[C->N-1][3], du2[C->N-1][3], T, a1, a0, U, Pt = -(C->E); //set up to calculate Q_1/2 T = calc_T(C); a0 = 1/(2.0*(T + Pt)); calc_dT(C,dTdP); mat_scalar_mult(C->N-1,3,dTdP,h*a0,dTdP); //multiplied dTdP by scalar a mat_add(C->N-1,3,C->R,dTdP,C->R); //this has updated C->R to equal Q_1/2 //calculate P_1 calc_dU1(C,du1); calc_dU2(C,du2); mat_add(C->N-1,3,du1,du2,dUdQ); U = calc_U(C); mat_scalar_mult(C->N-1,3,dUdQ, -h/U ,dUdQ); //multiplied dUdQ by scalar -h/U mat_add(C->N-1,3,C->W,dUdQ,C->W); //this has updated C->W to equal P_1 //set up to calculate Q_1 T = calc_T(C); a1 = 1/(2.0*(T + Pt)); calc_dT(C,dTdP); mat_scalar_mult(C->N-1,3,dTdP,h*a1,dTdP); //multiplied dTdP by scalar a mat_add(C->N-1,3,C->R,dTdP,C->R); //this has updated C->R to equal Q_1/2 return h/2.0 * (a1 + a0); //returns update for time value, so use t += leap(C,h); }
int main(int argc, char* argv[]) { struct marsopts opts = init(argc, argv); Agraph_t* g = agread(opts.fin, (Agdisc_t*)NULL); Agnode_t* n; mat z; init_graph(g); z = mars(g, opts); mat_scalar_mult(z, opts.scale); if(opts.viewer) { viewer(argc, argv); } else { for(n = agfstnode(g); n; n = agnxtnode(g,n)) { int id = getid(n); char* s = pos_to_str(&z->m[mindex(id, 0, z)], z->c); agset(n,"pos",s); free(s); } agwrite(g, opts.fout); } mat_free(z); clean_up(g); agclose(g); return 0; }