Beispiel #1
0
Datei: fdgl.hpp Projekt: EQ4/lad
/** Spring force with a directional force to align with flow direction. */
static const Vector
edge_force(const Vector& dir, const Vector& hpos, const Vector& tpos)
{
	return vec_add(dir, spring_force(hpos, tpos, EDGE_LEN, EDGE_K));
}
Beispiel #2
0
void get_forces(struct chain_param *chain_pm, struct monomer *monomers, Float ***velcs_df, int n_step, VSLStreamStatePtr rngstream)
{
  extern int n_proc, num_proc;
  extern int num_x;
  extern int max_x, max_y, max_z;
  extern int wall_flag;

  int mon_proc;
  int num_beads, Nbead;
  int i, j;
  int n1, n2;
  int s_type = 1;    /* spring type : 0 = FENE, 1=WLC */
  int ev_type = 1;   /* ev type: 0=HS, 1=WCA, 2=Gaussian */
  int maxsize[DIMS];
  int max_N_flag=0;
  double send_buffer[2*DIMS+1];
  char filename[80];
  FILE *stream;

  maxsize[0]=max_x;
  maxsize[1]=max_y;
  maxsize[2]=max_z;

  num_beads = chain_pm->num_beads;
  Nbead = chain_pm->num_beads / chain_pm->Nchain;

  for(j=0; j<DIMS; j++) 
    monomers[0].force[j] = monomers[0].f_ext[j];
  for(n1=1; n1<num_beads; n1++)
    for(j=0; j<DIMS; j++) 
      monomers[n1].force[j] = 0.0;

  /* Calculate spring and exc. vol. forces if # of beads > 1 */
  if(num_beads > 1) {
    spring_force(chain_pm, monomers);  /* 0 = FENE, 1=WLC */

    /*excluded volume forces */
    if(num_beads < 200)
      ev_force(monomers[0].radius, chain_pm, monomers);
    else {
      for(n1=0; n1<num_beads; n1++)
        if(monomers[n1].list[0] >= MAX_N-1) max_N_flag = 1;

      if(max_N_flag == 1)
        ev_force(monomers[0].radius, chain_pm, monomers);
      else ev_force_nlist(monomers[0].radius, chain_pm, monomers);
    }
  }

  for(n1=0; n1<num_beads; n1++)
    for(j=0; j<DIMS; j++) {
      monomers[n1].force[j] *= chain_pm->monmass;
      monomers[n1].f_int[j] = monomers[n1].force[j];
    }

  /*hydrodynamic and fluctuation forces */
  hi_force(monomers, velcs_df, chain_pm->fric, chain_pm->MD_steps, chain_pm->dt, num_beads, chain_pm->monmass, rngstream);
  
  if(wall_flag > 0)
    wall_force(chain_pm, monomers);

  /* send forces and fluid_vel back to proc 0 then broadcast from 0 */

  for(n1=0; n1< num_beads; n1++) { 
    mon_proc = (int)(monomers[n1].pos[0]/num_x);
    send_buffer[0]=n1;
    for(i=0; i<DIMS; i++) {
      send_buffer[i+1]=monomers[n1].force[i];
      send_buffer[i+DIMS+1]=monomers[n1].fluid_vel[i];
    }

    vector_copy(send_buffer, 2*DIMS+1, n_proc, mon_proc, 0);

    for(i=0; i<DIMS; i++) {
      monomers[(int)send_buffer[0]].force[i]=send_buffer[i+1];
      monomers[(int)send_buffer[0]].fluid_vel[i]=send_buffer[i+1+DIMS];
    }

  }
  sync_procs();

  for(n1=0; n1< num_beads; n1++) {
    broad_cast(monomers[n1].force, DIMS, 0);
    broad_cast(monomers[n1].fluid_vel, DIMS, 0);
  }
}
Beispiel #3
0
void settle_sheet(
  tectonic_sheet *ts,
  size_t iterations,
  float dt,
  float equilibrium_distance,
  float spring_constant,
  int hold_edges
) {
  size_t iter, i, j;
  size_t idx, idx_a, idx_b, idx_c;
  size_t pw, ph;
  pw = sheet_pwidth(ts);
  ph = sheet_pheight(ts);
  vector *a, *b, *c; // the points of the current triangle
  vector *f; // the force on the current point
  vector tmp; // vector used for intermediate calculations
  for (iter = 0; iter < iterations; ++iter) {
    // First pass: compute forces by iterating over triangles in the sheet:
    for (i = 0; i < ts->width; ++i) {
      for (j = 0; j < ts->height; ++j) {
        idx_a = sheet_pidx_a(ts, i, j);
        idx_b = sheet_pidx_b(ts, i, j);
        idx_c = sheet_pidx_c(ts, i, j);
        a = &(ts->points[idx_a]);
        b = &(ts->points[idx_b]);
        c = &(ts->points[idx_c]);
        if (i % 2 == j % 2) { // if this triangle points up
          // All six forces on all three corners of this triangle:
          // a <- b
          f = &(ts->forces[idx_a]);
          spring_force(b, a, &tmp, equilibrium_distance, spring_constant);
          vadd_to(f, &tmp);

          // a <- c
          spring_force(c, a, &tmp, equilibrium_distance, spring_constant);
          vadd_to(f, &tmp);

          // b <- a
          f = &(ts->forces[idx_b]);
          spring_force(a, b, &tmp, equilibrium_distance, spring_constant);
          vadd_to(f, &tmp);

          // b <- c
          spring_force(c, b, &tmp, equilibrium_distance, spring_constant);
          vadd_to(f, &tmp);

          // c <- a
          f = &(ts->forces[idx_c]);
          spring_force(a, c, &tmp, equilibrium_distance, spring_constant);
          vadd_to(f, &tmp);

          // c <- b
          spring_force(b, c, &tmp, equilibrium_distance, spring_constant);
          vadd_to(f, &tmp);
        } else if (i == 0 && (j % 2 == 1)) {
          // Both forces on our a <-> b edge:
          // a <- b
          f = &(ts->forces[idx_a]);
          spring_force(b, a, &tmp, equilibrium_distance, spring_constant);
          vadd_to(f, &tmp);

          // b <- a
          f = &(ts->forces[idx_b]);
          spring_force(a, b, &tmp, equilibrium_distance, spring_constant);
          vadd_to(f, &tmp);
        } else if ((i == ts->width - 1) && (j % 2 == 0) ) {
          // Both forces on our a <-> c edge:
          // a <- c
          f = &(ts->forces[idx_a]);
          spring_force(c, a, &tmp, equilibrium_distance, spring_constant);
          vadd_to(f, &tmp);

          // c <- a
          f = &(ts->forces[idx_c]);
          spring_force(a, c, &tmp, equilibrium_distance, spring_constant);
          vadd_to(f, &tmp);
        }
      }
    }
    // Second pass: apply forces (iterating over points this time)
    for (i = 0; i < pw; ++i) {
      for (j = 0; j < ph; ++j) {
        idx = sheet_pidx(ts, i, j);
        f = &(ts->forces[idx]);
        if (
          hold_edges
        &&
          (i == 0 || i == pw - 1 || j == 0 || j == ph - 1)
        ) {
          vzero(f);
          continue;
        }
        vscale(f, dt);
        vadd_to(&(ts->points[idx]), f);
        vzero(f);
      }
    }
  }
}