示例#1
0
/** initialize the forces for a real particle */
inline void init_local_particle_force(Particle *part) {
  if ( thermo_switch & THERMO_LANGEVIN )
    friction_thermo_langevin(part);
  else {
    part->f.f[0] = 0;
    part->f.f[1] = 0;
    part->f.f[2] = 0;
  }

#ifdef EXTERNAL_FORCES
  if(part->p.ext_flag & PARTICLE_EXT_FORCE) {
    part->f.f[0] += part->p.ext_force[0];
    part->f.f[1] += part->p.ext_force[1];
    part->f.f[2] += part->p.ext_force[2];
  }
#endif

#ifdef ROTATION
  {
    double scale;
    /* set torque to zero */
    part->f.torque[0] = 0;
    part->f.torque[1] = 0;
    part->f.torque[2] = 0;

#ifdef EXTERNAL_FORCES
    if(part->p.ext_flag & PARTICLE_EXT_TORQUE) 
    {
      part->f.torque[0] += part->p.ext_torque[0];
      part->f.torque[1] += part->p.ext_torque[1];
      part->f.torque[2] += part->p.ext_torque[2];
    }
#endif

#ifdef ENGINE
    // apply a swimming force in the direction of
    // the particle's orientation axis
    if ( part->swim.swimming )
    {
      part->f.f[0] += part->swim.f_swim * part->r.quatu[0];
      part->f.f[1] += part->swim.f_swim * part->r.quatu[1];
      part->f.f[2] += part->swim.f_swim * part->r.quatu[2];
    }
#endif

    /* and rescale quaternion, so it is exactly of unit length */
    scale = sqrt( SQR(part->r.quat[0]) + SQR(part->r.quat[1]) +
          SQR(part->r.quat[2]) + SQR(part->r.quat[3]));
    part->r.quat[0]/= scale;
    part->r.quat[1]/= scale;
    part->r.quat[2]/= scale;
    part->r.quat[3]/= scale;
  }
#endif
}
示例#2
0
文件: forces.c 项目: roehm/cython
/** initialize the forces for a real particle */
MDINLINE void init_local_particle_force(Particle *part)
{
#ifdef ADRESS
  double new_weight;
  if (ifParticleIsVirtual(part)) {
    new_weight = adress_wf_vector(part->r.p);
#ifdef ADRESS_INIT
    double old_weight = part->p.adress_weight;
    
    if(new_weight>0 && old_weight==0){
      double rand_cm_pos[3], rand_cm_vel[3], rand_weight, new_pos, old_pos;
      int it, dim, this_mol_id=part->p.mol_id, rand_mol_id, rand_type;
      int n_ats_this_mol=topology[this_mol_id].part.n, n_ats_rand_mol;
      
      //look for a random explicit particle
      rand_type=-1;
      rand_weight=-1;
      rand_mol_id=-1;
      n_ats_rand_mol=-1;
      
      while(rand_type != part->p.type || rand_weight != 1 || n_ats_rand_mol != n_ats_this_mol){
	rand_mol_id = i_random(n_molecules);
	rand_type   = local_particles[(topology[rand_mol_id].part.e[0])]->p.type;
	rand_weight = local_particles[(topology[rand_mol_id].part.e[0])]->p.adress_weight;
	n_ats_rand_mol = topology[rand_mol_id].part.n;
	
	if(!ifParticleIsVirtual(local_particles[(topology[rand_mol_id].part.e[0])]))
	  fprintf(stderr,"No virtual site found on molecule %d, with %d total molecules.\n",rand_mol_id, n_molecules);
      }
      
      //store CM position and velocity
      for(dim=0;dim<3;dim++){
	rand_cm_pos[dim]=local_particles[(topology[rand_mol_id].part.e[0])]->r.p[dim];
	rand_cm_vel[dim]=local_particles[(topology[rand_mol_id].part.e[0])]->m.v[dim];
      }
      
      //assign new positions and velocities to the atoms
      for(it=0;it<n_ats_this_mol;it++){
	if (!ifParticleIsVirtual(local_particles[topology[rand_mol_id].part.e[it]])) {
	  for(dim=0;dim<3;dim++){
	    old_pos = local_particles[topology[this_mol_id].part.e[it]]->r.p[dim];
	    new_pos = local_particles[topology[rand_mol_id].part.e[it]]->r.p[dim]-rand_cm_pos[dim]+part->r.p[dim];
	    //MAKE SURE THEY ARE IN THE SAME BOX
	    while(new_pos-old_pos>box_l[dim]*0.5)
	      new_pos=new_pos-box_l[dim];
	    while(new_pos-old_pos<-box_l[dim]*0.5)
	      new_pos=new_pos+box_l[dim];
	    
	    local_particles[(topology[this_mol_id].part.e[it])]->r.p[dim] = new_pos;
	    local_particles[(topology[this_mol_id].part.e[it])]->m.v[dim] = local_particles[(topology[rand_mol_id].part.e[it])]->m.v[dim]-rand_cm_vel[dim]+part->m.v[dim];
	  }   
	}
      }
    }
#endif
    part->p.adress_weight=new_weight;
  }
#endif
  if ( thermo_switch & THERMO_LANGEVIN )
    friction_thermo_langevin(part);
  else {
    part->f.f[0] = 0;
    part->f.f[1] = 0;
    part->f.f[2] = 0;
  }

#ifdef EXTERNAL_FORCES   
  if(part->l.ext_flag & PARTICLE_EXT_FORCE) {
    part->f.f[0] += part->l.ext_force[0];
    part->f.f[1] += part->l.ext_force[1];
    part->f.f[2] += part->l.ext_force[2];
  }
#endif
  
#ifdef ROTATION
  {
    double scale;
    /* set torque to zero */
    part->f.torque[0] = 0;
    part->f.torque[1] = 0;
    part->f.torque[2] = 0;
    
    /* and rescale quaternion, so it is exactly of unit length */	
    scale = sqrt( SQR(part->r.quat[0]) + SQR(part->r.quat[1]) +
		  SQR(part->r.quat[2]) + SQR(part->r.quat[3]));
    part->r.quat[0]/= scale;
    part->r.quat[1]/= scale;
    part->r.quat[2]/= scale;
    part->r.quat[3]/= scale;
  }
#endif

#ifdef ADRESS
  /* #ifdef THERMODYNAMIC_FORCE */
  if(ifParticleIsVirtual(part))
    if(part->p.adress_weight > 0 && part->p.adress_weight < 1)
      add_thermodynamic_force(part);
  /* #endif */  
#endif
}