예제 #1
0
파일: rotation.c 프로젝트: adolfom/espresso
/** convert a dipole moment to quaternions and dipolar strength  */
int convert_dip_to_quat(double dip[3], double quat[4], double *dipm)
{
  double dm;
  // Calculate magnitude of dipole moment
  dm = sqrt(dip[0]*dip[0] + dip[1]*dip[1] + dip[2]*dip[2]);
  *dipm = dm;
  convert_quatu_to_quat(dip,quat);

  return 0;
}
// Setup the virtual_sites_relative properties of a particle so that the given virtaul particle will follow the given real particle
int vs_relate_to(int part_num, int relate_to)
{
    // Get the data for the particle we act on and the one we wnat to relate
    // it to.
    Particle  p_current,p_relate_to;
    if ((get_particle_data(relate_to,&p_relate_to)!=ES_OK) || 
        (get_particle_data(part_num,&p_current)!=ES_OK)) {
      char *errtxt = runtime_error(128 + 3*ES_INTEGER_SPACE);
      ERROR_SPRINTF(errtxt, "Could not retrieve particle data for the given id");
      return ES_ERROR;
    }
    
    // get teh distance between the particles
    double d[3];
    get_mi_vector(d, p_current.r.p,p_relate_to.r.p);
    
    // Set the particle id of the particle we want to relate to and the distnace
    if (set_particle_vs_relative(part_num, relate_to, sqrt(sqrlen(d))) == ES_ERROR) {
      char *errtxt = runtime_error(128 + 3*ES_INTEGER_SPACE);
      ERROR_SPRINTF(errtxt, "setting the vs_relative attributes failed");
      return ES_ERROR;
    }
    
    
    // Check, if the distance between virtual and non-virtual particles is larger htan minimum global cutoff
    // If so, warn user
    double l=sqrt(sqrlen(d));
    if (l>min_global_cut) {
      char *errtxt = runtime_error(300 + 3*ES_INTEGER_SPACE);
      ERROR_SPRINTF(errtxt, "Warning: The distance between virtual and non-virtual particle (%f) is\nlarger than the minimum global cutoff (%f). This may lead to incorrect simulations\nunder certain conditions. Use \"setmd min_global_cut\" to increase the minimum cutoff.\n",l,min_global_cut);
      return ES_ERROR;
    }

    // Now, calculate the quaternions which specify the angle between 
    // the director of the particel we relate to and the vector
    // (paritlce_we_relate_to - this_particle)
    double quat[4];
    // The vs_relative implemnation later obtains the direcotr by multiplying
    // the quaternions representing the orientation of the real particle
    // with those in the virtual particle. The re quulting quaternion is then
    // converted to a director.
    // Whe have quat_(real particle) *quat_(virtual particle) 
    // = quat_(obtained from desired director)
    // Resolving this for the quat_(virtaul particle)

    //Normalize desired director
    int i;
    for (i=0;i<3;i++)
     d[i]/=l;

    // Obtain quaternions from desired director
    double quat_director[4];
    convert_quatu_to_quat(d, quat_director);

    // Define quat as described above:
    double x=0;
    for (i=0;i<4;i++)
     x+=p_relate_to.r.quat[i]*p_relate_to.r.quat[i];

    quat[0]=0;
    for (i=0;i<4;i++)
     quat[0] +=p_relate_to.r.quat[i]*quat_director[i];
    
    quat[1] =-quat_director[0] *p_relate_to.r.quat[1] 
       +quat_director[1] *p_relate_to.r.quat[0]
       +quat_director[2] *p_relate_to.r.quat[3]
       -quat_director[3] *p_relate_to.r.quat[2];
    quat[2] =p_relate_to.r.quat[1] *quat_director[3] 
      + p_relate_to.r.quat[0] *quat_director[2] 
      - p_relate_to.r.quat[3] *quat_director[1] 
      - p_relate_to.r.quat[2] * quat_director[0];
    quat[3] =quat_director[3] *p_relate_to.r.quat[0]
      - p_relate_to.r.quat[3] *quat_director[0] 
      + p_relate_to.r.quat[2] * quat_director[1] 
      - p_relate_to.r.quat[1] *quat_director[2];
    for (i=0;i<4;i++)
     quat[i]/=x;
   
   
   // Verify result
   double qtemp[4];
   multiply_quaternions(p_relate_to.r.quat,quat,qtemp);
   for (i=0;i<4;i++)
     if (fabs(qtemp[i]-quat_director[i])>1E-9)
       fprintf(stderr, "vs_relate_to: component %d: %f instead of %f\n",
	       i, qtemp[i], quat_director[i]);


   // Save the quaternions in the particle
   if (set_particle_quat(part_num, quat) == ES_ERROR) {
     char *errtxt = runtime_error(128 + 3*ES_INTEGER_SPACE);
     ERROR_SPRINTF(errtxt, "set particle position first");

     return ES_ERROR;
   }
   
   return ES_OK;
}
예제 #3
0
// Setup the virtual_sites_relative properties of a particle so that the given virtaul particle will follow the given real particle
int vs_relate_to(int part_num, int relate_to)
{
    // Get the data for the particle we act on and the one we wnat to relate
    // it to.
    Particle  p_current,p_relate_to;
    if ((get_particle_data(relate_to,&p_relate_to)!=TCL_OK) || 
        (get_particle_data(part_num,&p_current)!=TCL_OK)) {
         printf("Could not retrieve particle data for the given id.\n");
          return TCL_ERROR;
    }
    
    // get teh distance between the particles
    double d[3];
    get_mi_vector(d, p_current.r.p,p_relate_to.r.p);
    
    // Set the particle id of the particle we want to relate to and the distnace
    if (set_particle_vs_relative(part_num, relate_to, sqrt(sqrlen(d))) == TCL_ERROR) {
      printf("setting the vs_relative attributes failed.\n");
      return TCL_ERROR;
    }

    // Now, calculate the quaternions which specify the angle between 
    // the director of the particel we relate to and the vector
    // (paritlce_we_relate_to - this_particle)
    double quat[4];
    // The vs_relative implemnation later obtains the direcotr by multiplying
    // the quaternions representing the orientation of the real particle
    // with those in the virtual particle. The re quulting quaternion is then
    // converted to a director.
    // Whe have quat_(real particle) *quat_(virtual particle) 
    // = quat_(obtained from desired director)
    // Resolving this for the quat_(virtaul particle)

    //Normalize desired director
    double l=sqrt(sqrlen(d));
    int i;
    for (i=0;i<3;i++)
     d[i]/=l;

    // Obtain quaternions from desired director
    double quat_director[4];
    convert_quatu_to_quat(d, quat_director);

    // Define quat as described above:
    double x=0;
    for (i=0;i<4;i++)
     x+=p_relate_to.r.quat[i]*p_relate_to.r.quat[i];

    quat[0]=0;
    for (i=0;i<4;i++)
     quat[0] +=p_relate_to.r.quat[i]*quat_director[i];
    
    quat[1] =-quat_director[0] *p_relate_to.r.quat[1] 
       +quat_director[1] *p_relate_to.r.quat[0]
       +quat_director[2] *p_relate_to.r.quat[3]
       -quat_director[3] *p_relate_to.r.quat[2];
    quat[2] =p_relate_to.r.quat[1] *quat_director[3] 
      + p_relate_to.r.quat[0] *quat_director[2] 
      - p_relate_to.r.quat[3] *quat_director[1] 
      - p_relate_to.r.quat[2] * quat_director[0];
    quat[3] =quat_director[3] *p_relate_to.r.quat[0]
      - p_relate_to.r.quat[3] *quat_director[0] 
      + p_relate_to.r.quat[2] * quat_director[1] 
      - p_relate_to.r.quat[1] *quat_director[2];
    for (i=0;i<4;i++)
     quat[i]/=x;
   
   
   // Verify result
   double qtemp[4];
   multiply_quaternions(p_relate_to.r.quat,quat,qtemp);
   for (i=0;i<4;i++)
    if (fabs(qtemp[i]-quat_director[i])>1E-9)
     printf("Component %d: %f instead of %f\n",i,qtemp[i],quat_director[i]);


   // Save the quaternions in the particle
   if (set_particle_quat(part_num, quat) == TCL_ERROR) {
     printf("set particle position first\n");

     return TCL_ERROR;
   }
   
   return TCL_OK;
}