Ejemplo n.º 1
0
int set_particle_torque_lab(int part, double torque_lab[3])
{
  int pnode;
  if (!particle_node)
    build_particle_node();

  if (part < 0 || part > max_seen_particle)
    return ES_ERROR;
  pnode = particle_node[part];

  if (pnode == -1)
    return ES_ERROR;

  /* Internal functions require the body coordinates
     so we need to convert to these from the lab frame */

  double A[9];
  double torque[3];
  Particle particle;

  get_particle_data(part, &particle);
  define_rotation_matrix(&particle, A);

  torque[0] = A[0 + 3*0]*torque_lab[0] + A[0 + 3*1]*torque_lab[1] + A[0 + 3*2]*torque_lab[2];
  torque[1] = A[1 + 3*0]*torque_lab[0] + A[1 + 3*1]*torque_lab[1] + A[1 + 3*2]*torque_lab[2];
  torque[2] = A[2 + 3*0]*torque_lab[0] + A[2 + 3*1]*torque_lab[1] + A[2 + 3*2]*torque_lab[2];

  mpi_send_torque(pnode, part, torque);
  return ES_OK;
}
Ejemplo n.º 2
0
void convert_vec_space_to_body(Particle *p, double *v,double* res)
{
  double A[9];
  define_rotation_matrix(p, A);

  res[0] = A[0 + 3*0]*v[0] + A[0 + 3*1]*v[1] + A[0 + 3*2]*v[2];
  res[1] = A[1 + 3*0]*v[0] + A[1 + 3*1]*v[1] + A[1 + 3*2]*v[2];
  res[2] = A[2 + 3*0]*v[0] + A[2 + 3*1]*v[1] + A[2 + 3*2]*v[2];
}
Ejemplo n.º 3
0
void convert_vel_space_to_body(Particle *p, double *vel_body)
{
  double A[9];
  define_rotation_matrix(p, A);

  vel_body[0] = A[0 + 3*0]*p->m.v[0] + A[0 + 3*1]*p->m.v[1] + A[0 + 3*2]*p->m.v[2];
  vel_body[1] = A[1 + 3*0]*p->m.v[0] + A[1 + 3*1]*p->m.v[1] + A[1 + 3*2]*p->m.v[2];
  vel_body[2] = A[2 + 3*0]*p->m.v[0] + A[2 + 3*1]*p->m.v[1] + A[2 + 3*2]*p->m.v[2];
}
Ejemplo n.º 4
0
void convert_torques_body_to_space(Particle *p, double *torque)
{
  double A[9];
  define_rotation_matrix(p, A);

  torque[0] = A[0 + 3*0]*p->f.torque[0] + A[1 + 3*0]*p->f.torque[1] + A[2 + 3*0]*p->f.torque[2];
  torque[1] = A[0 + 3*1]*p->f.torque[0] + A[1 + 3*1]*p->f.torque[1] + A[2 + 3*1]*p->f.torque[2];
  torque[2] = A[0 + 3*2]*p->f.torque[0] + A[1 + 3*2]*p->f.torque[1] + A[2 + 3*2]*p->f.torque[2];
}
Ejemplo n.º 5
0
void convert_omega_body_to_space(Particle *p, double *omega)
{
  double A[9];
  define_rotation_matrix(p, A);

  omega[0] = A[0 + 3*0]*p->m.omega[0] + A[1 + 3*0]*p->m.omega[1] + A[2 + 3*0]*p->m.omega[2];
  omega[1] = A[0 + 3*1]*p->m.omega[0] + A[1 + 3*1]*p->m.omega[1] + A[2 + 3*1]*p->m.omega[2];
  omega[2] = A[0 + 3*2]*p->m.omega[0] + A[1 + 3*2]*p->m.omega[1] + A[2 + 3*2]*p->m.omega[2];
}
Ejemplo n.º 6
0
/** convert the torques to the body-fixed frames before the integration loop */
void convert_initial_torques()
{
  Particle *p;
  Cell *cell;
  int c,i, np;
  double tx, ty, tz;

  INTEG_TRACE(fprintf(stderr,"%d: convert_initial_torques:\n",this_node));
  for (c = 0; c < local_cells.n; c++) {
    cell = local_cells.cell[c];
    p  = cell->part;
    np = cell->n;
    for(i = 0; i < np; i++) {
#ifdef ROTATION_PER_PARTICLE
      if (!p[i].p.rotation)
       continue;
#endif
      double A[9];
      define_rotation_matrix(&p[i], A);

      tx = A[0 + 3*0]*p[i].f.torque[0] + A[0 + 3*1]*p[i].f.torque[1] + A[0 + 3*2]*p[i].f.torque[2];
      ty = A[1 + 3*0]*p[i].f.torque[0] + A[1 + 3*1]*p[i].f.torque[1] + A[1 + 3*2]*p[i].f.torque[2];
      tz = A[2 + 3*0]*p[i].f.torque[0] + A[2 + 3*1]*p[i].f.torque[1] + A[2 + 3*2]*p[i].f.torque[2];

      if ( thermo_switch & THERMO_LANGEVIN ) {
      
	friction_thermo_langevin_rotation(&p[i]);
	p[i].f.torque[0]+= tx;
	p[i].f.torque[1]+= ty;
	p[i].f.torque[2]+= tz;
      } else {
	p[i].f.torque[0] = tx;
	p[i].f.torque[1] = ty;
	p[i].f.torque[2] = tz;
      }

#ifdef ROTATION_PER_PARTICLE
      if (!(p[i].p.rotation & 2))
        p[i].f.torque[0]=0;
      
      if (!(p[i].p.rotation & 4))
        p[i].f.torque[1]=0;
      
      if (!(p[i].p.rotation & 8))
        p[i].f.torque[2]=0;
      
#endif

      ONEPART_TRACE(if(p[i].p.identity==check_id) fprintf(stderr,"%d: OPT: SCAL f = (%.3e,%.3e,%.3e) v_old = (%.3e,%.3e,%.3e)\n",this_node,p[i].f.f[0],p[i].f.f[1],p[i].f.f[2],p[i].m.v[0],p[i].m.v[1],p[i].m.v[2]));
    }
  }
}
Ejemplo n.º 7
0
int observable_calc_particle_angular_momentum(observable* self) {
  double* A = self->last_value;
  IntList* ids;
  if (!sortPartCfg()) {
    char *errtxt = runtime_error(128);
    ERROR_SPRINTF(errtxt,"{094 could not sort partCfg} ");
    return -1;
  }
  ids=(IntList*) self->container;
  for ( int i = 0; i<ids->n; i++ ) {
    if (ids->e[i] >= n_part)
      return 1;

    #ifdef ROTATION

    double RMat[9];
    double omega[3];
    define_rotation_matrix(&partCfg[ids->e[i]], RMat);
    omega[0] = RMat[0 + 3*0]*partCfg[ids->e[i]].m.omega[0] + RMat[1 + 3*0]*partCfg[ids->e[i]].m.omega[1] + RMat[2 + 3*0]*partCfg[ids->e[i]].m.omega[2];
    omega[1] = RMat[0 + 3*1]*partCfg[ids->e[i]].m.omega[0] + RMat[1 + 3*1]*partCfg[ids->e[i]].m.omega[1] + RMat[2 + 3*1]*partCfg[ids->e[i]].m.omega[2];
    omega[2] = RMat[0 + 3*2]*partCfg[ids->e[i]].m.omega[0] + RMat[1 + 3*2]*partCfg[ids->e[i]].m.omega[1] + RMat[2 + 3*2]*partCfg[ids->e[i]].m.omega[2];

    A[3*i + 0] = omega[0];
    A[3*i + 1] = omega[1];
    A[3*i + 2] = omega[2];

    #else

    A[3*i + 0] = 0.0;
    A[3*i + 1] = 0.0;
    A[3*i + 2] = 0.0;

    #endif
  }
  return 0;
}
Ejemplo n.º 8
0
/** convert the torques to the body-fixed frames and propagate angular velocities */
void convert_torques_propagate_omega()
{
  Particle *p;
  Cell *cell;
  int c,i, np, times;
  double dt2, tx, ty, tz;

  dt2 = time_step*0.5;
  INTEG_TRACE(fprintf(stderr,"%d: convert_torques_propagate_omega:\n",this_node));
  for (c = 0; c < local_cells.n; c++) {
    cell = local_cells.cell[c];
    p  = cell->part;
    np = cell->n;
    for(i = 0; i < np; i++) {
      double A[9];
      define_rotation_matrix(&p[i], A);

      tx = A[0 + 3*0]*p[i].f.torque[0] + A[0 + 3*1]*p[i].f.torque[1] + A[0 + 3*2]*p[i].f.torque[2];
      ty = A[1 + 3*0]*p[i].f.torque[0] + A[1 + 3*1]*p[i].f.torque[1] + A[1 + 3*2]*p[i].f.torque[2];
      tz = A[2 + 3*0]*p[i].f.torque[0] + A[2 + 3*1]*p[i].f.torque[1] + A[2 + 3*2]*p[i].f.torque[2];

      
      if ( thermo_switch & THERMO_LANGEVIN ) {
      #ifdef THERMOSTAT_IGNORE_NON_VIRTUAL
       if (!ifParticleIsVirtual(&p[i]))
       #endif
       {
	friction_thermo_langevin_rotation(&p[i]);

	p[i].f.torque[0]+= tx;
	p[i].f.torque[1]+= ty;
	p[i].f.torque[2]+= tz;
       }
      } else {
	p[i].f.torque[0] = tx;
	p[i].f.torque[1] = ty;
	p[i].f.torque[2] = tz;
      }
    
      ONEPART_TRACE(if(p[i].p.identity==check_id) fprintf(stderr,"%d: OPT: SCAL f = (%.3e,%.3e,%.3e) v_old = (%.3e,%.3e,%.3e)\n",this_node,p[i].f.f[0],p[i].f.f[1],p[i].f.f[2],p[i].m.v[0],p[i].m.v[1],p[i].m.v[2]));
    
#ifdef ROTATIONAL_INERTIA
	  p[i].m.omega[0]+= dt2*p[i].f.torque[0]/p[i].p.rinertia[0]/I[0];
	  p[i].m.omega[1]+= dt2*p[i].f.torque[1]/p[i].p.rinertia[1]/I[1];
	  p[i].m.omega[2]+= dt2*p[i].f.torque[2]/p[i].p.rinertia[2]/I[2];
#else
	  p[i].m.omega[0]+= dt2*p[i].f.torque[0]/I[0];
	  p[i].m.omega[1]+= dt2*p[i].f.torque[1]/I[1];
	  p[i].m.omega[2]+= dt2*p[i].f.torque[2]/I[2];
#endif
	  /* if the tensor of inertia is isotrpic, the following refinement is not needed.
	     Otherwise repeat this loop 2-3 times depending on the required accuracy */
	  for(times=0;times<=5;times++) { 
	    double Wd[3];

#ifdef ROTATIONAL_INERTIA
	    Wd[0] = (p[i].m.omega[1]*p[i].m.omega[2]*(I[1]-I[2]))/I[0]/p[i].p.rinertia[0];
	    Wd[1] = (p[i].m.omega[2]*p[i].m.omega[0]*(I[2]-I[0]))/I[1]/p[i].p.rinertia[1]; 
	    Wd[2] = (p[i].m.omega[0]*p[i].m.omega[1]*(I[0]-I[1]))/I[2]/p[i].p.rinertia[2];
#else
	    Wd[0] = (p[i].m.omega[1]*p[i].m.omega[2]*(I[1]-I[2]))/I[0];
	    Wd[1] = (p[i].m.omega[2]*p[i].m.omega[0]*(I[2]-I[0]))/I[1]; 
	    Wd[2] = (p[i].m.omega[0]*p[i].m.omega[1]*(I[0]-I[1]))/I[2];
#endif
 
	    p[i].m.omega[0]+= dt2*Wd[0];
	    p[i].m.omega[1]+= dt2*Wd[1];
	    p[i].m.omega[2]+= dt2*Wd[2];
	  }
	
      
      ONEPART_TRACE(if(p[i].p.identity==check_id) fprintf(stderr,"%d: OPT: PV_2 v_new = (%.3e,%.3e,%.3e)\n",this_node,p[i].m.v[0],p[i].m.v[1],p[i].m.v[2]));
      
    }
  }
}
Ejemplo n.º 9
0
/** convert the torques to the body-fixed frames and propagate angular velocities */
void convert_torques_propagate_omega()
{
  Particle *p;
  Cell *cell;
  int np;
  double tx, ty, tz;

  INTEG_TRACE(fprintf(stderr,"%d: convert_torques_propagate_omega:\n",this_node));

#if defined(LB_GPU) && defined(ENGINE)
  if (lattice_switch & LATTICE_LB_GPU) {
    copy_v_cs_from_GPU();
  }
#endif

  for (int c = 0; c < local_cells.n; c++)
  {
    cell = local_cells.cell[c];
    p  = cell->part;
    np = cell->n;
    for(int i = 0; i < np; i++)
    {
#ifdef ROTATION_PER_PARTICLE
      if (!p[i].p.rotation)
        continue;
#endif
      double A[9];
      define_rotation_matrix(&p[i], A);

      tx = A[0 + 3*0]*p[i].f.torque[0] + A[0 + 3*1]*p[i].f.torque[1] + A[0 + 3*2]*p[i].f.torque[2];
      ty = A[1 + 3*0]*p[i].f.torque[0] + A[1 + 3*1]*p[i].f.torque[1] + A[1 + 3*2]*p[i].f.torque[2];
      tz = A[2 + 3*0]*p[i].f.torque[0] + A[2 + 3*1]*p[i].f.torque[1] + A[2 + 3*2]*p[i].f.torque[2];

      if ( thermo_switch & THERMO_LANGEVIN )
      {
#if defined (VIRTUAL_SITES) && defined(THERMOSTAT_IGNORE_NON_VIRTUAL)
        if (!ifParticleIsVirtual(&p[i]))
#endif
        {
          friction_thermo_langevin_rotation(&p[i]);

          p[i].f.torque[0]+= tx;
          p[i].f.torque[1]+= ty;
          p[i].f.torque[2]+= tz;
        }
      }
      else
      {
        p[i].f.torque[0] = tx;
        p[i].f.torque[1] = ty;
        p[i].f.torque[2] = tz;
      }

#ifdef ROTATION_PER_PARTICLE
      if (!(p[i].p.rotation & 2))
        p[i].f.torque[0]=0;
      
      if (!(p[i].p.rotation & 4))
        p[i].f.torque[1]=0;
      
      if (!(p[i].p.rotation & 8))
        p[i].f.torque[2]=0;
      
#endif

        


#if defined(ENGINE) && (defined(LB) || defined(LB_GPU))
      double omega_swim[3] = {0, 0, 0};
      double omega_swim_body[3] = {0, 0, 0};
      if ( p[i].swim.swimming && lattice_switch != 0 )
      {
        double dip[3];
        double diff[3];
        double cross[3];
        double l_diff, l_cross;

        dip[0]   = p[i].swim.dipole_length * p[i].r.quatu[0];
        dip[1]   = p[i].swim.dipole_length * p[i].r.quatu[1];
        dip[2]   = p[i].swim.dipole_length * p[i].r.quatu[2];

        diff[0]  = ( p[i].swim.v_center[0] - p[i].swim.v_source[0] );
        diff[1]  = ( p[i].swim.v_center[1] - p[i].swim.v_source[1] );
        diff[2]  = ( p[i].swim.v_center[2] - p[i].swim.v_source[2] );

        cross[0] = diff[1]*dip[2] - diff[2]*dip[1];
        cross[1] = diff[0]*dip[2] - diff[2]*dip[0];
        cross[2] = diff[0]*dip[1] - diff[1]*dip[0];

        l_diff   = sqrt(diff[0]*diff[0] + diff[1]*diff[1] + diff[2]*diff[2]);
        l_cross  = sqrt(cross[0]*cross[0] + cross[1]*cross[1] + cross[2]*cross[2]);

        if ( l_cross > 0 && p[i].swim.dipole_length > 0 )
        {
          omega_swim[0]      = l_diff * cross[0] / ( l_cross * p[i].swim.dipole_length );
          omega_swim[1]      = l_diff * cross[1] / ( l_cross * p[i].swim.dipole_length );
          omega_swim[2]      = l_diff * cross[2] / ( l_cross * p[i].swim.dipole_length );

          omega_swim_body[0] = A[0 + 3*0]*omega_swim[0] + A[0 + 3*1]*omega_swim[1] + A[0 + 3*2]*omega_swim[2];
          omega_swim_body[1] = A[1 + 3*0]*omega_swim[0] + A[1 + 3*1]*omega_swim[1] + A[1 + 3*2]*omega_swim[2];
          omega_swim_body[2] = A[2 + 3*0]*omega_swim[0] + A[2 + 3*1]*omega_swim[1] + A[2 + 3*2]*omega_swim[2];

          p[i].f.torque[0]  += p[i].swim.rotational_friction * ( omega_swim_body[0] - p[i].m.omega[0] );
          p[i].f.torque[1]  += p[i].swim.rotational_friction * ( omega_swim_body[1] - p[i].m.omega[1] );
          p[i].f.torque[2]  += p[i].swim.rotational_friction * ( omega_swim_body[2] - p[i].m.omega[2] );
        }
      }
#endif

      ONEPART_TRACE(if(p[i].p.identity==check_id) fprintf(stderr,"%d: OPT: SCAL f = (%.3e,%.3e,%.3e) v_old = (%.3e,%.3e,%.3e)\n",this_node,p[i].f.f[0],p[i].f.f[1],p[i].f.f[2],p[i].m.v[0],p[i].m.v[1],p[i].m.v[2]));

#ifdef ROTATIONAL_INERTIA
      p[i].m.omega[0]+= time_step_half*p[i].f.torque[0]/p[i].p.rinertia[0]/I[0];
      p[i].m.omega[1]+= time_step_half*p[i].f.torque[1]/p[i].p.rinertia[1]/I[1];
      p[i].m.omega[2]+= time_step_half*p[i].f.torque[2]/p[i].p.rinertia[2]/I[2];
#else
      p[i].m.omega[0]+= time_step_half*p[i].f.torque[0]/I[0];
      p[i].m.omega[1]+= time_step_half*p[i].f.torque[1]/I[1];
      p[i].m.omega[2]+= time_step_half*p[i].f.torque[2]/I[2];
#endif
      /* if the tensor of inertia is isotropic, the following refinement is not needed.
         Otherwise repeat this loop 2-3 times depending on the required accuracy */
      for(int times=0; times <= 5; times++)
      { 
        double Wd[3];

#ifdef ROTATIONAL_INERTIA
        Wd[0] = (p[i].m.omega[1]*p[i].m.omega[2]*(I[1]-I[2]))/I[0]/p[i].p.rinertia[0];
        Wd[1] = (p[i].m.omega[2]*p[i].m.omega[0]*(I[2]-I[0]))/I[1]/p[i].p.rinertia[1]; 
        Wd[2] = (p[i].m.omega[0]*p[i].m.omega[1]*(I[0]-I[1]))/I[2]/p[i].p.rinertia[2];
#else
        Wd[0] = (p[i].m.omega[1]*p[i].m.omega[2]*(I[1]-I[2]))/I[0];
        Wd[1] = (p[i].m.omega[2]*p[i].m.omega[0]*(I[2]-I[0]))/I[1]; 
        Wd[2] = (p[i].m.omega[0]*p[i].m.omega[1]*(I[0]-I[1]))/I[2];
#endif

        p[i].m.omega[0]+= time_step_half*Wd[0];
        p[i].m.omega[1]+= time_step_half*Wd[1];
        p[i].m.omega[2]+= time_step_half*Wd[2];
      }

      ONEPART_TRACE(if(p[i].p.identity==check_id) fprintf(stderr,"%d: OPT: PV_2 v_new = (%.3e,%.3e,%.3e)\n",this_node,p[i].m.v[0],p[i].m.v[1],p[i].m.v[2]));

    }
  }
}