예제 #1
0
void leap_frog(const data* dat, output_function output)
{
  int i;
  double dt = dat->eta * delta_t_factor;

  vector *a    = (vector*) malloc((dat->N)*sizeof(vector)),
         *a_1 = (vector*) malloc((dat->N)*sizeof(vector)),
         *r_p  = (vector*) malloc((dat->N)*sizeof(vector)), // r_(n+1/2), not initialized
         *r    = init_r(dat),                               // r_(n+1)
         *r_n  = (vector*) malloc((dat->N)*sizeof(vector)), // r_(n+3/2), not initialized
         *v    = init_v(dat);                               // v_(n+1)

  double time = 0;
  output(time, dt, dat, r, v);

  // initial step
  for (i = 0; i < dat->N; i++)
    // set r_(1/2)
    r_n[i] = vector_add(r[i], scalar_mult(0.5 * dt, v[i]));

  // regular timesteps
  while (time < dat->t_max)
  {
    // a_(n+1/2)
    accelerations(dat, r_n, a);
    adots(dat, r_n, v, a_1);
    for (i = 0; i < dat->N; i++)
    {
      // store previous values as r_(n+1/2)
      r_p[i] = r_n[i];
      // v_(n+1)
      vector_add_to(&v[i], scalar_mult(dt, a[i]));
      // r_(n+3/2)
      vector_add_to(&r_n[i], scalar_mult(dt, v[i]));
      // build r_(n+1)
      r[i] = scalar_mult(0.5, vector_add(r_p[i], r_n[i]));
    }
    dt = delta_t(dat, a, a_1);
    time += dt;
    output(time, dt, dat, r, v);
  }
  free(a); free(r_p); free(r); free(r_n); free(v);
}
예제 #2
0
static void update_shape(jigglystruct *js)
{
    vertex *vtx = js->shape->vertices;
    edge *e = js->shape->edges;
    vector zero;

    vector_init(zero, 0, 0, 0);

    /* sum all the vertex-vertex forces */
    while(e) {
        vector f;
        coord mag;
        vector_sub(e->left->vtx->v, e->right->vtx->v, f);
        mag = js->stable_distance - magnitude(f);
        vector_scale(f, mag);
        vector_add_to(e->left->vtx->f, f);
        vector_sub(zero, f, f);
        vector_add_to(e->right->vtx->f, f);
        e = e->next;
    }

    /* scale back the v-v force and add the spherical force
     * then add the result to the vertex velocity, damping
     * if necessary. Finally, move the vertex */
    while(vtx) {
        coord mag;
        vector to_sphere;
        vector_scale(vtx->f, js->hold_strength);
        vector_copy(to_sphere, vtx->v);
        mag = 1 - magnitude(to_sphere);
        vector_scale(to_sphere, mag * js->spherify_strength);
        vector_add_to(vtx->f, to_sphere);
        vector_add_to(vtx->vel, vtx->f);
        vector_init(vtx->f, 0, 0, 0);
        mag = magnitude2(vtx->vel);
        if(mag > js->damping_velocity)
            vector_scale(vtx->vel, js->damping_factor);
        vector_add_to(vtx->v, vtx->vel);
        vtx = vtx->next;
    }
}
예제 #3
0
static inline void vertex_calcnormal(vertex *vtx, jigglystruct *js)
{
    hedge *start = vtx->h, *h=start;

    vector_init(vtx->n, 0, 0, 0);
    do {
        vector u, v, norm;
        vector_sub(h->prev->vtx->v, vtx->v, u);
        vector_sub(h->next->vtx->v, vtx->v, v);
        cross(u, v, norm);
        vector_add_to(vtx->n, norm);
        h = partner(h)->next;
    } while(h != start);
    if(!js->spooky)
        normalize(vtx->n);
    else
        vector_scale(vtx->n, js->spooky);
}
예제 #4
0
void runge_kutta(const data* dat, output_function output)
{
  int i;
  double dt = dat->eta * delta_t_factor;

  vector *r   = init_r(dat),
         *v   = init_v(dat),
         *a   = (vector*) malloc((dat->N)*sizeof(vector)),
         *a_1 = (vector*) malloc((dat->N)*sizeof(vector));

  // temporary r vector for acceleration calculations
  vector *rt = (vector*) malloc((dat->N)*sizeof(vector));

  vector *a1 = (vector*) malloc((dat->N)*sizeof(vector)),
         *a2 = (vector*) malloc((dat->N)*sizeof(vector)),
         *a3 = (vector*) malloc((dat->N)*sizeof(vector)),
         *a4 = (vector*) malloc((dat->N)*sizeof(vector));

  vector *r1 = (vector*) malloc((dat->N)*sizeof(vector)),
         *r2 = (vector*) malloc((dat->N)*sizeof(vector)),
         *r3 = (vector*) malloc((dat->N)*sizeof(vector)),
         *r4 = (vector*) malloc((dat->N)*sizeof(vector));

  vector *v1 = (vector*) malloc((dat->N)*sizeof(vector)),
         *v2 = (vector*) malloc((dat->N)*sizeof(vector)),
         *v3 = (vector*) malloc((dat->N)*sizeof(vector)),
         *v4 = (vector*) malloc((dat->N)*sizeof(vector));

  double time = 0;
  while (time < dat->t_max)
  {
    accelerations(dat, r, a1);
    for (i = 0; i < dat->N; i++)
    {
      v1[i] = scalar_mult(dt, a1[i]);
      r1[i] = scalar_mult(dt, v[i]);
      // temp r for a2
      rt[i] = vector_add(r[i], scalar_mult(0.5, r1[i]));
    }
    accelerations(dat, rt, a2);
    for (i = 0; i < dat->N; i++)
    {
      v2[i] = scalar_mult(dt, a2[i]);
      r2[i] = scalar_mult(dt, vector_add(v[i], scalar_mult(0.5, v1[i])));
      // temp r for a3
      rt[i] = vector_add(r[i], scalar_mult(0.5, r2[i]));
    }
    accelerations(dat, rt, a3);
    for (i = 0; i < dat->N; i++)
    {
      v3[i] = scalar_mult(dt, a3[i]);
      r3[i] = scalar_mult(dt, vector_add(v[i], scalar_mult(0.5, v2[i])));
      // temp r for a3
      rt[i] = vector_add(r[i], scalar_mult(0.5, r3[i]));
    }
    accelerations(dat, rt, a4);
    for (i = 0; i < dat->N; i++)
    {
      v4[i] = scalar_mult(dt, a4[i]);
      r4[i] = scalar_mult(dt, vector_add(v[i], v3[i]));
      // calculate v_(n+1) and r_(n+1)
      vector_add_to(&v[i], vector_add(scalar_mult(1.0/6.0, v1[i]),
                           vector_add(scalar_mult(1.0/3.0, v2[i]),
                           vector_add(scalar_mult(1.0/3.0, v3[i]),
                                      scalar_mult(1.0/6.0, v4[i])))));
      vector_add_to(&r[i], vector_add(scalar_mult(1.0/6.0, r1[i]),
                           vector_add(scalar_mult(1.0/3.0, r2[i]),
                           vector_add(scalar_mult(1.0/3.0, r3[i]),
                                      scalar_mult(1.0/6.0, r4[i])))));
    }
    // increase time
    adots(dat, r, v, a_1);
    dt = delta_t(dat, a1, a_1); // a1 = a(t_n), a_1 = a'(t_n)
    time += dt;
    output(time, dt, dat, r, v);
  }
  free(r);  free(v);  free(a);  free(a_1);
  free(rt);
  free(r1); free(r2); free(r3); free(r4);
  free(v1); free(v2); free(v3); free(v4);
  free(a1); free(a2); free(a3); free(a4);
}