Пример #1
0
/** Computes the three body angle interaction energy (see \ref tclcommand_inter, \ref tclcommand_analyze). 
    @param p_mid        Pointer to first particle.
    @param p_left        Pointer to second/middle particle.
    @param p_right        Pointer to third particle.
    @param iaparams  bond type number of the angle interaction (see \ref tclcommand_inter).
    @param _energy   return energy pointer.
    @return 0.
*/
inline int angle_cosine_energy(Particle *p_mid, Particle *p_left, Particle *p_right,
			     Bonded_ia_parameters *iaparams, double *_energy)
{
  double cosine, vec1[3], vec2[3],  d1i, d2i, dist2;
  int j;

  cosine=0.0;
  /* vector from p_mid to p_left */
  get_mi_vector(vec1, p_mid->r.p, p_left->r.p);
  dist2 = sqrlen(vec1);
  d1i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec1[j] *= d1i;
  /* vector from p_right to p_mid */
  get_mi_vector(vec2, p_right->r.p, p_mid->r.p);
  dist2 = sqrlen(vec2);
  d2i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec2[j] *= d2i;
  /* scalar produvt of vec1 and vec2 */
  cosine = scalar(vec1, vec2);
  if ( cosine >  TINY_COS_VALUE)  cosine = TINY_COS_VALUE;
  if ( cosine < -TINY_COS_VALUE)  cosine = -TINY_COS_VALUE;
  /* bond angle energy */

  *_energy = iaparams->p.angle_cosine.bend*(cosine*iaparams->p.angle_cosine.cos_phi0 - sqrt(1-SQR(cosine))*iaparams->p.angle_cosine.sin_phi0+1);

  return 0;
}
Пример #2
0
/** Computes the three body angle interaction force and adds this
    force to the particle forces (see \ref tclcommand_inter). 
    @param p_mid     Pointer to second/middle particle.
    @param p_left    Pointer to first/left particle.
    @param p_right   Pointer to third/right particle.
    @param iaparams  bond type number of the angle interaction (see \ref tclcommand_inter).
    @param force1 returns force of particle 1
    @param force2 returns force of particle 2
    @return 0
*/
inline int calc_angle_harmonic_force(Particle *p_mid, Particle *p_left, Particle *p_right,
			      Bonded_ia_parameters *iaparams, double force1[3], double force2[3])
{
  double cosine, vec1[3], vec2[3], d1i, d2i, dist2,  fac, f1=0.0, f2=0.0;
  int j;

  cosine=0.0;
  /* vector from p_left to p_mid */
  get_mi_vector(vec1, p_mid->r.p, p_left->r.p);
  dist2 = sqrlen(vec1);
  d1i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec1[j] *= d1i;
  /* vector from p_mid to p_right */
  get_mi_vector(vec2, p_right->r.p, p_mid->r.p);
  dist2 = sqrlen(vec2);
  d2i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec2[j] *= d2i;
  /* scalar produvt of vec1 and vec2 */
  cosine = scalar(vec1, vec2);
  fac    = iaparams->p.angle_harmonic.bend;

  {
    double phi,sinphi;
    if ( cosine >  TINY_COS_VALUE) cosine = TINY_COS_VALUE;
    if ( cosine < -TINY_COS_VALUE)  cosine = -TINY_COS_VALUE;
    phi =  acos(-cosine);

    sinphi = sin(phi);
    if ( sinphi < TINY_SIN_VALUE ) sinphi = TINY_SIN_VALUE;
    fac *= (phi - iaparams->p.angle_harmonic.phi0)/sinphi;

#ifdef CONFIGTEMP
  extern double configtemp[2];
  if (p_left->p.configtemp) {
    configtemp[0] += SQR(fac*sinphi*d1i);
    configtemp[1] -= iaparams->p.angle_harmonic.bend*(1+cosine/sinphi*(phi - iaparams->p.angle_harmonic.phi0))*SQR(d1i);
  }
  if (p_mid->p.configtemp) {
    configtemp[0] += SQR(fac*sinphi) * (1./sqrlen(vec1) + 1./sqrlen(vec2) - 2*cosine*d1i*d2i);
    configtemp[1] -= iaparams->p.angle_harmonic.bend*((1/sqrlen(vec1)+1/sqrlen(vec2)-cosine*d1i*d2i)
      +cosine/sinphi * (1./sqrlen(vec1)+1./sqrlen(vec2)-d1i*d2i/cosine) *(phi - iaparams->p.angle_harmonic.phi0));
  }
  if (p_right->p.configtemp) {
    configtemp[0] += SQR(fac*sinphi*d2i);
    configtemp[1] -= iaparams->p.angle_harmonic.bend*(1+cosine/sinphi*(phi - iaparams->p.angle_harmonic.phi0))*SQR(d2i);
  }

#endif

  }
  for(j=0;j<3;j++) {
    f1               = fac * (cosine * vec1[j] - vec2[j]) * d1i;
    f2               = fac * (cosine * vec2[j] - vec1[j]) * d2i;

    force1[j] = (f1-f2);
    force2[j] = -f1;
  }

  return 0;
}
Пример #3
0
/** Computes the three body angle interaction force and adds this
    force to the particle forces (see \ref tclcommand_inter). 
    @param p_mid     Pointer to second/middle particle.
    @param p_left    Pointer to first/left particle.
    @param p_right   Pointer to third/right particle.
    @param iaparams  bond type number of the angle interaction (see \ref tclcommand_inter).
    @param force1 returns force of particle 1
    @param force2 returns force of particle 2
    @return 0
*/
inline int calc_angle_cosine_force(Particle *p_mid, Particle *p_left, Particle *p_right,
			      Bonded_ia_parameters *iaparams, double force1[3], double force2[3])
{
  double cosine, vec1[3], vec2[3], d1i, d2i, dist2,  fac, f1=0.0, f2=0.0;
  int j;

  cosine=0.0;
  /* vector from p_left to p_mid */
  get_mi_vector(vec1, p_mid->r.p, p_left->r.p);
  dist2 = sqrlen(vec1);
  d1i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec1[j] *= d1i;
  /* vector from p_mid to p_right */
  get_mi_vector(vec2, p_right->r.p, p_mid->r.p);
  dist2 = sqrlen(vec2);
  d2i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec2[j] *= d2i;
  /* scalar produvt of vec1 and vec2 */
  cosine = scalar(vec1, vec2);
  fac    = iaparams->p.angle_cosine.bend;

  if ( cosine >  TINY_COS_VALUE ) cosine = TINY_COS_VALUE;
  if ( cosine < -TINY_COS_VALUE)  cosine = -TINY_COS_VALUE;
  fac *= iaparams->p.angle_cosine.sin_phi0 * (cosine/sqrt(1-SQR(cosine))) + iaparams->p.angle_cosine.cos_phi0;
  
  for(j=0;j<3;j++) {
    f1               = fac * (cosine * vec1[j] - vec2[j]) * d1i;
    f2               = fac * (cosine * vec2[j] - vec1[j]) * d2i;

    force1[j] = (f1-f2);
    force2[j] = -f1;
  }
  return 0;
}
inline int calc_area_force_local_complicated(Particle *p1, Particle *p2, Particle *p3,
         Bonded_ia_parameters *iaparams, double force1[3], double force2[3], double force3[3]) // more complicated approach
{
 int k; 
 double A, aa, uh[3], vh[3], rh[3], hn;
 double uu[3],vv[3];

 get_mi_vector(uu, p2->r.p, p1->r.p);
 get_mi_vector(vv, p3->r.p, p1->r.p);

 for(k=0;k<3;k++) rh[k]=1.0/3.0 *(uu[k]+vv[k]);
 for(k=0;k<3;k++) uh[k]=rh[k]-uu[k];
 for(k=0;k<3;k++) vh[k]=rh[k]-vv[k];

 A=area_triangle_new(uu,vv);
 //printf("area %e uu %e %e %e vv %e %e %e\n", A, uu[0], uu[1], uu[2], vv[0], vv[1], vv[2]);
 aa=(A - iaparams->p.area_force_local.A0_l)/iaparams->p.area_force_local.A0_l;

 hn=normr(rh);
 for(k=0;k<3;k++) {
  force1[k] =  iaparams->p.area_force_local.ka_l * aa * rh[k]/hn;
 }
 hn=normr(uh);
 for(k=0;k<3;k++) {
  force2[k] =  iaparams->p.area_force_local.ka_l * aa * uh[k]/hn;
 }
 hn=normr(vh);
 for(k=0;k<3;k++) {
  force3[k] =  iaparams->p.area_force_local.ka_l * aa * vh[k]/hn;
 }
  return 0;
}
Пример #5
0
/** Computes the three body angle interaction energy (see \ref tclcommand_inter, \ref tclcommand_analyze). 
    @param p_mid        Pointer to first particle.
    @param p_left        Pointer to second/middle particle.
    @param p_right        Pointer to third particle.
    @param iaparams  bond type number of the angle interaction (see \ref tclcommand_inter).
    @param _energy   return energy pointer.
    @return 0.
*/
inline int angle_harmonic_energy(Particle *p_mid, Particle *p_left, Particle *p_right,
			     Bonded_ia_parameters *iaparams, double *_energy)
{
  double cosine, vec1[3], vec2[3],  d1i, d2i, dist2;
  int j;

  cosine=0.0;
  /* vector from p_mid to p_left */
  get_mi_vector(vec1, p_mid->r.p, p_left->r.p);
  dist2 = sqrlen(vec1);
  d1i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec1[j] *= d1i;
  /* vector from p_right to p_mid */
  get_mi_vector(vec2, p_right->r.p, p_mid->r.p);
  dist2 = sqrlen(vec2);
  d2i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec2[j] *= d2i;
  /* scalar produvt of vec1 and vec2 */
  cosine = scalar(vec1, vec2);
  if ( cosine >  TINY_COS_VALUE)  cosine = TINY_COS_VALUE;
  if ( cosine < -TINY_COS_VALUE)  cosine = -TINY_COS_VALUE;
  /* bond angle energy */
  {
    double phi;
    phi =  acos(-cosine);
    *_energy = 0.5*iaparams->p.angle_harmonic.bend*SQR(phi - iaparams->p.angle_harmonic.phi0);
  }
  return 0;
}
Пример #6
0
/* The force on each particle due to a three-body bonded potential
   is computed. */
inline void calc_angle_cossquare_3body_forces(Particle *p_mid, Particle *p_left,
        Particle *p_right, Bonded_ia_parameters *iaparams,
        double force1[3], double force2[3], double force3[3]) {

    int j;
    double pot_dep;
    double cos_phi;
    double sin_phi;
    double vec31[3];
    double vec21[3];
    double vec12[3]; // espresso convention
    double vec21_sqr;
    double vec31_sqr;
    double vec21_magn;
    double vec31_magn;
    double fj[3];
    double fk[3];
    double fac;

    get_mi_vector(vec12, p_mid->r.p, p_left->r.p);
    for(j = 0; j < 3; j++)
        vec21[j] = -vec12[j];

    get_mi_vector(vec31, p_right->r.p, p_mid->r.p);
    vec21_sqr = sqrlen(vec21);
    vec21_magn = sqrt(vec21_sqr);
    vec31_sqr = sqrlen(vec31);
    vec31_magn = sqrt(vec31_sqr);
    cos_phi = scalar(vec21, vec31) / (vec21_magn * vec31_magn);
    sin_phi = sqrt(1.0 - SQR(cos_phi));

    /* uncomment this block if interested in the angle
    if(cos_phi < -1.0) cos_phi = -TINY_COS_VALUE;
    if(cos_phi >  1.0) cos_phi =  TINY_COS_VALUE;
    phi = acos(cos_phi);
    */
    {
        double K, cos_phi0;
        K = iaparams->p.angle_cossquare.bend;
        cos_phi0 = iaparams->p.angle_cossquare.cos_phi0;

        // potential dependent term [dU/dphi = K * (sin_phi * cos_phi0 - cos_phi * sin_phi)]
        pot_dep = K * (sin_phi * cos_phi0 - cos_phi * sin_phi);
    }

    fac = pot_dep / sin_phi;

    for(j = 0; j < 3; j++) {
        fj[j] = vec31[j] / (vec21_magn * vec31_magn) - cos_phi * vec21[j] / vec21_sqr;
        fk[j] = vec21[j] / (vec21_magn * vec31_magn) - cos_phi * vec31[j] / vec31_sqr;
    }

    // note that F1 = -(F2 + F3)
    for(j = 0; j < 3; j++) {
        force1[j] = force1[j] - fac * (fj[j] + fk[j]);
        force2[j] = force2[j] + fac * fj[j];
        force3[j] = force3[j] + fac * fk[j];
    }
}
Пример #7
0
int calc_angledist_force(Particle *p_mid, Particle *p_left,
				  Particle *p_right,
                                  Bonded_ia_parameters *iaparams,
				  double force1[3], double force2[3])
{
  double cosine=0.0, vec1[3], vec2[3], d1i=0.0, d2i=0.0, dist2, fac=0.0, f1=0.0, f2=0.0;
  int j;

  /* vector from p_left to p_mid */
  get_mi_vector(vec1, p_mid->r.p, p_left->r.p);
  dist2 = sqrlen(vec1);
  d1i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec1[j] *= d1i;
  /* vector from p_mid to p_right */
  get_mi_vector(vec2, p_right->r.p, p_mid->r.p);
  dist2 = sqrlen(vec2);
  d2i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec2[j] *= d2i;
  /* scalar product of vec1 and vec2 */
  cosine = scalar(vec1, vec2);
  fac    = iaparams->p.angledist.bend;

#ifdef BOND_ANGLEDIST_HARMONIC
  {
    double phi,sinphi;
    /* NOTE: The angledist is ONLY implemented for the HARMONIC case */
    double phi0 = calc_angledist_param(p_mid, p_left, p_right, iaparams);

      if ( cosine >  TINY_COS_VALUE) cosine =  TINY_COS_VALUE;
    if ( cosine < -TINY_COS_VALUE) cosine = -TINY_COS_VALUE;
    phi =  acos(-cosine);
    sinphi = sin(phi);
    if ( sinphi < TINY_SIN_VALUE ) sinphi = TINY_SIN_VALUE;
    fac *= (phi - phi0)/sinphi;
    //    fprintf(stdout,"\n force:  z_pmid=%f, phi0=%f  phi=%f fac=%f",p_mid->r.p[2],phi0*180.0/PI,phi*180.0/PI,fac);
  }
#endif

#ifdef BOND_ANGLEDIST_COSINE
  #error angledist ONLY implemented for harmonic case!
#endif
#ifdef BOND_ANGLEDIST_COSSQUARE
  #error angledist ONLY implemented for harmonic case!
#endif

  for(j=0;j<3;j++) {
    f1               = fac * (cosine * vec1[j] - vec2[j]) * d1i;
    f2               = fac * (cosine * vec2[j] - vec1[j]) * d2i;

    force1[j] = (f1-f2);
    force2[j] = -f1;
  }
  return 0;
}
Пример #8
0
/**Compute positional corrections*/
void compute_pos_corr_vec(int *repeat_)
{
  Bonded_ia_parameters *ia_params;
  int i, j, k, c, np, cnt=-1;
  Cell *cell;
  Particle *p, *p1, *p2;
  double r_ij_t[3], r_ij[3], r_ij_dot, G, pos_corr, r_ij2;

  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++) {
      p1 = &p[i];
      k=0;
      while(k<p1->bl.n) {
	ia_params = &bonded_ia_params[p1->bl.e[k++]];
	if( ia_params->type == BONDED_IA_RIGID_BOND ) {
	  cnt++;
	  p2 = local_particles[p1->bl.e[k++]];
	  if (!p2) {
	    char *errtxt = runtime_error(128 + 2*ES_INTEGER_SPACE);
	    ERROR_SPRINTF(errtxt,"{051 rigid bond broken between particles %d and %d (particles not stored on the same node)} ",
		    p1->p.identity, p1->bl.e[k-1]);
	    return;
	  }

	  get_mi_vector(r_ij  , p1->r.p    , p2->r.p    );
	  r_ij2 = sqrlen(r_ij);
	  if(fabs(1.0 - r_ij2/ia_params->p.rigid_bond.d2) > ia_params->p.rigid_bond.p_tol) {
            get_mi_vector(r_ij_t, p1->r.p_old, p2->r.p_old);
	    r_ij_dot = scalar(r_ij_t, r_ij);
	    G = 0.50*(ia_params->p.rigid_bond.d2 - r_ij2 )/r_ij_dot;
#ifdef MASS
	    G /= (PMASS(*p1)+PMASS(*p2));
#else
	    G /= 2;
#endif
	    for (j=0;j<3;j++) {
	      pos_corr = G*r_ij_t[j];
	      p1->f.f[j] += pos_corr*PMASS(*p2);
	      p2->f.f[j] -= pos_corr*PMASS(*p1);
	    }
	    /*Increase the 'repeat' flag by one */
	      *repeat_ = *repeat_ + 1;
	  }
	}
	else
	  /* skip bond partners of nonrigid bond */
          k+=ia_params->num;
      } //while loop
    } //for i loop
  } //for c loop
}
Пример #9
0
/** Computes the three body overlapped angle interaction force.
    Adds this force to the particle forces in forces.hpp (see \ref tclcommand_inter). 
    @param p_mid     Pointer to second/middle particle.
    @param p_left    Pointer to first/left particle.
    @param p_right   Pointer to third/right particle.
    @param iaparams  bond type number of the angle interaction (see \ref tclcommand_inter).
    @param force1 returns force of particle 1
    @param force2 returns force of particle 2
    @return 0
    Needs feature OVERLAPPED compiled in (see \ref config.hpp). 
*/
inline int calc_overlap_angle_force(Particle *p_mid, Particle *p_left, 
				  Particle *p_right, Bonded_ia_parameters *iaparams,
				  double force1[3], double force2[3])
{
  double cosine, vec1[3], vec2[3], d1i, d2i, dist2,  fac, f1=0.0, f2=0.0;
  int j; 
  
  int ig;
  double ev;
  double prob=0.; 
  double Apart=0.;

  cosine=0.0;
  /* vector from p_left to p_mid */
  get_mi_vector(vec1, p_mid->r.p, p_left->r.p);
  dist2 = sqrlen(vec1);
  d1i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec1[j] *= d1i;
  /* vector from p_mid to p_right */
  get_mi_vector(vec2, p_right->r.p, p_mid->r.p);
  dist2 = sqrlen(vec2);
  d2i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec2[j] *= d2i;
  /* scalar produvt of vec1 and vec2 */
  /* Notice: cosine = - costheta */
  cosine = scalar(vec1, vec2);

  if ( cosine >  TINY_COS_VALUE ) cosine = TINY_COS_VALUE;
  if ( cosine < -TINY_COS_VALUE)  cosine = -TINY_COS_VALUE;

  /* compute fac = - dU/d(costheta) */
  /* prob = sum_(i=1,N) [ a_i * exp(-(costheta -b_i)^2/c_i^2))] */
  /* Apart = sum_(i=1,N) [ a_i * exp(-(costheta -b_i)^2/c_i^2)) * (costheta-b_i) / c_i^2] */
  /* fac = -2.0 * ( Apart / prob ) */

  for(ig=0; ig<iaparams->p.overlap.noverlaps; ig++) {
        ev = (-cosine - iaparams->p.overlap.para_b[ig]) / iaparams->p.overlap.para_c[ig];
        prob = prob + iaparams->p.overlap.para_a[ig] * exp (-1.0*ev*ev);
        Apart = Apart + iaparams->p.overlap.para_a[ig] * exp (-1.0*ev*ev) * (-cosine-iaparams->p.overlap.para_b[ig]) / (iaparams->p.overlap.para_c[ig] * iaparams->p.overlap.para_c[ig]);
  }
  fac = -2. * ( Apart / prob);

  /* compute force */
  for(j=0;j<3;j++) {
    f1               = fac * (cosine * vec1[j] - vec2[j]) * d1i;
    f2               = fac * (cosine * vec2[j] - vec1[j]) * d2i;

    force1[j] = (f1-f2);
    force2[j] = -f1;
  }
  return 0;
}
Пример #10
0
void nsq_calculate_virials()
{
  Particle *partl, *partg;
  Particle *pt1, *pt2;
  int p, p2, npl, npg, c;
  double d[3], dist2, dist;

  npl   = local->n;
  partl = local->part;

  /* calculate bonded interactions and non bonded node-node */
  for (p = 0; p < npl; p++) {
    pt1 = &partl[p];
    add_kinetic_virials(pt1,0);
    add_bonded_virials(pt1);
#ifdef BOND_ANGLE
    add_three_body_bonded_stress(pt1);
#endif

    /* other particles, same node */
    for (p2 = p + 1; p2 < npl; p2++) {
      pt2 = &partl[p2];
      get_mi_vector(d, pt1->r.p, pt2->r.p);
      dist2 = sqrlen(d);
      dist = sqrt(dist2);
#ifdef EXCLUSIONS
      if (do_nonbonded(pt1, pt2))
#endif
	add_non_bonded_pair_virials(pt1, pt2, d, dist, dist2);
    }

    /* calculate with my ghosts */
    for (c = 0; c < me_do_ghosts.n; c++) {
      npg   = me_do_ghosts.cell[c]->n;
      partg = me_do_ghosts.cell[c]->part;

      for (p2 = 0; p2 < npg; p2++) {
	pt2 = &partg[p2];
	get_mi_vector(d, pt1->r.p, pt2->r.p);
	dist2 = sqrlen(d);
	dist = sqrt(dist2);
#ifdef EXCLUSIONS
	if (do_nonbonded(pt1, pt2))
#endif
	  add_non_bonded_pair_virials(pt1, pt2, d, dist, dist2);
      }
    }
  }
}
Пример #11
0
/** Computes the three body angle interaction force and adds this
    force to the particle forces (see \ref tclcommand_inter). 
    @param p_mid     Pointer to second/middle particle.
    @param p_left    Pointer to first/left particle.
    @param p_right   Pointer to third/right particle.
    @param iaparams  bond type number of the angle interaction (see \ref tclcommand_inter).
    @param force1 returns force of particle 1
    @param force2 returns force of particle 2
    @return 0
*/
inline int calc_angle_force(Particle *p_mid, Particle *p_left, Particle *p_right,
			      Bonded_ia_parameters *iaparams, double force1[3], double force2[3])
{
  double cosine, vec1[3], vec2[3], d1i, d2i, dist2,  fac, f1=0.0, f2=0.0;
  int j;

  cosine=0.0;
  /* vector from p_left to p_mid */
  get_mi_vector(vec1, p_mid->r.p, p_left->r.p);
  dist2 = sqrlen(vec1);
  d1i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec1[j] *= d1i;
  /* vector from p_mid to p_right */
  get_mi_vector(vec2, p_right->r.p, p_mid->r.p);
  dist2 = sqrlen(vec2);
  d2i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec2[j] *= d2i;
  /* scalar produvt of vec1 and vec2 */
  cosine = scalar(vec1, vec2);
  fac    = iaparams->p.angle.bend;

#ifdef BOND_ANGLE_HARMONIC
  {
    double phi,sinphi;
    if ( cosine >  TINY_COS_VALUE) cosine = TINY_COS_VALUE;
    if ( cosine < -TINY_COS_VALUE)  cosine = -TINY_COS_VALUE;
    phi =  acos(-cosine);
    sinphi = sin(phi);
    if ( sinphi < TINY_SIN_VALUE ) sinphi = TINY_SIN_VALUE;
    fac *= (phi - iaparams->p.angle.phi0)/sinphi;
  }
#endif
#ifdef BOND_ANGLE_COSINE
  if ( cosine >  TINY_COS_VALUE ) cosine = TINY_COS_VALUE;
  if ( cosine < -TINY_COS_VALUE)  cosine = -TINY_COS_VALUE;
  fac *= iaparams->p.angle.sin_phi0 * (cosine/sqrt(1-SQR(cosine))) + iaparams->p.angle.cos_phi0;
#endif
#ifdef BOND_ANGLE_COSSQUARE
  fac *= iaparams->p.angle.cos_phi0 + cosine;
#endif
  for(j=0;j<3;j++) {
    f1               = fac * (cosine * vec1[j] - vec2[j]) * d1i;
    f2               = fac * (cosine * vec2[j] - vec1[j]) * d2i;

    force1[j] = (f1-f2);
    force2[j] = -f1;
  }
  return 0;
}
Пример #12
0
void nbhood(double pt[3], double r, IntList *il, int planedims[3] )
{
  double d[3];
  int i,j;
  double r2;

  r2 = r*r;

  init_intlist(il);
 
  updatePartCfg(WITHOUT_BONDS);

  for (i = 0; i<n_part; i++) {
    if ( (planedims[0] + planedims[1] + planedims[2]) == 3 ) {
      get_mi_vector(d, pt, partCfg[i].r.p);
    } else {
      /* Calculate the in plane distance */
      for ( j= 0 ; j < 3 ; j++ ) {
	d[j] = planedims[j]*(partCfg[i].r.p[j]-pt[j]);
      }
    }

    if (sqrlen(d) < r2) {
      realloc_intlist(il, il->n + 1);
      il->e[il->n] = partCfg[i].p.identity;
      il->n++;
    }
  }
}
Пример #13
0
void print_bond_len()
{
  int i, k, c, np;
  Cell *cell;
  Particle *p;
  Bonded_ia_parameters *b_ia;
  double r_ij[3];
  printf("%d: ", 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++) {
       k=0;
       while(k<p[i].bl.n)
       {
             b_ia = &bonded_ia_params[p[i].bl.e[k]];
	     if(b_ia->type == BONDED_IA_RIGID_BOND)
             {
	       Particle *p2 = local_particles[p[i].bl.e[k++]];
           if (!p2) {
           runtimeErrorMsg() <<"rigid bond broken between particles " << p[i].p.identity << " and " << p[i].bl.e[k-1] << " (particles not stored on the same node)";
		 return;
	       }

	       get_mi_vector(r_ij, p[i].r.p , p2->r.p);
	       printf(" bl (%d %d): %f\t", p[i].p.identity, p2->p.identity,sqrlen(r_ij));
             }
	     else
	       k += b_ia->num;
       } //while k loop
    } //for i loop
  }// for c loop
  printf("\n");
}
Пример #14
0
/// Calculate angle that p1--p2 makes with wall constraint
static double calc_pwangle(Particle *p1, Particle *p2, Bonded_ia_parameters *iaparams, int *constr)
{
  int j;
  double dist,di,cosine,phi;
  double vec[3];

  /* vector from p1 to p2 */
  get_mi_vector(vec, p2->r.p, p1->r.p);
  dist = sqrlen(vec);
  di = 1.0/sqrt(dist);
  for(j=0;j<3;j++) vec[j] *= di;
  /*
  fprintf(stdout,"Normalised: p1= %9.6f %9.6f %9.6f   p1= %9.6f %9.6f %9.6f   vec= %9.6f %9.6f %9.6f\n",p1->r.p[0],p1->r.p[1],p1->r.p[2],p2->r.p[0],p2->r.p[1],p2->r.p[2],vec[0],vec[1],vec[2]);
  */
  /* vectors are normalised so cosine is just cos(angle_between_vec1_and_vec2)
   * Wall is closest wall to particle
   */

  cosine = scalar(vec, constraints[*constr].c.wal.n);
  if ( cosine >  TINY_COS_VALUE)  cosine =  TINY_COS_VALUE;
  if ( cosine < -TINY_COS_VALUE)  cosine = -TINY_COS_VALUE;
  phi=acos(cosine);

  /*
  fprintf(stdout,"Angle with wall 0=%f  ",(acos(scalar(vec, constraints[0].c.wal.n)))*180.0/PI);
  fprintf(stdout,"Angle with wall 1=%f  ",(acos(scalar(vec, constraints[1].c.wal.n)))*180.0/PI);
  fprintf(stdout,"dxy=%f  dz=%f  angle=%f\n",sqrt(vec[0]*vec[0]+vec[1]*vec[1]),vec[2],atan(sqrt(vec[0]*vec[0]+vec[1]*vec[1])/vec[2])*180.0/PI);
  fprintf(stdout,"Angle with closest wall %d=%f  ",*constr,(acos(scalar(vec, constraints[*constr].c.wal.n)))*180.0/PI);
  */
  return phi;
}
Пример #15
0
int angledist_energy(Particle *p_mid, Particle *p_left, Particle *p_right, 
		     Bonded_ia_parameters *iaparams, double *_energy)
{
  int j;
  double cosine=0.0, d1i, d2i, dist1, dist2;
  double vec1[3], vec2[3];

  //  if (phi0 < PI) {
  //    fprintf(stdout,"\nIn angledist_energy:  z_p_mid=%f, phi0=%f\n",p_mid->r.p[2],phi0*180.0/PI);
  //  }

  /* vector from p_mid to p_left */
  get_mi_vector(vec1, p_mid->r.p, p_left->r.p);
  dist1 = sqrlen(vec1);
  d1i = 1.0 / sqrt(dist1);
  for(j=0;j<3;j++) vec1[j] *= d1i;
  /* vector from p_right to p_mid */
  get_mi_vector(vec2, p_right->r.p, p_mid->r.p);
  dist2 = sqrlen(vec2);
  d2i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec2[j] *= d2i;
  /* scalar produvt of vec1 and vec2 */
  cosine = scalar(vec1, vec2);
  if ( cosine >  TINY_COS_VALUE)  cosine = TINY_COS_VALUE;
  if ( cosine < -TINY_COS_VALUE)  cosine = -TINY_COS_VALUE;

#ifdef BOND_ANGLEDIST_HARMONIC
  {
    double phi;
    double phi0=calc_angledist_param(p_mid, p_left, p_right, iaparams);
    phi =  acos(-cosine);
    *_energy = 0.5*iaparams->p.angledist.bend*SQR(phi - phi0);
    //    fprintf(stdout,"\n energy:  z_pmid=%f  bend=%f  phi0=%f  phi=%f energy=%f",p_mid->r.p[2],iaparams->p.angledist.bend,phi0*180.0/PI,phi*180.0/PI,0.5*iaparams->p.angledist.bend*SQR(phi - phi0));

  }
#endif
#ifdef BOND_ANGLEDIST_COSINE
  #error angledist ONLY implemented for harmonic case!
#endif
#ifdef BOND_ANGLEDIST_COSSQUARE
  #error angledist ONLY implemented for harmonic case!
#endif
  return 0;
}
Пример #16
0
/** Velocity correction vectors are computed*/
void compute_vel_corr_vec(int *repeat_)
{
  Bonded_ia_parameters *ia_params;
  int i, j, k, c, np;
  Cell *cell;
  Particle *p, *p1, *p2;
  double v_ij[3], r_ij[3], K, vel_corr;

  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++) {
        p1 = &p[i];
        k=0;
	while(k<p1->bl.n)
	  {
	    ia_params = &bonded_ia_params[p1->bl.e[k++]];
	    if( ia_params->type == BONDED_IA_RIGID_BOND )
	      {
		p2 = local_particles[p1->bl.e[k++]];
		if (!p2) {
		  char *errtxt = runtime_error(128 + 2*ES_INTEGER_SPACE);
		  ERROR_SPRINTF(errtxt,"{054 rigid bond broken between particles %d and %d (particles not stored on the same node)} ",
			  p1->p.identity, p1->bl.e[k-1]);
		  return;
		}

		vecsub(p1->m.v, p2->m.v, v_ij);
                get_mi_vector(r_ij, p1->r.p, p2->r.p);
		if(fabs(scalar(v_ij, r_ij)) > ia_params->p.rigid_bond.v_tol)
	        {
		  K = scalar(v_ij, r_ij)/ia_params->p.rigid_bond.d2;
#ifdef MASS
		  K /= (PMASS(*p1) + PMASS(*p2));
#else
		  K /= 2.0;
#endif
		for (j=0;j<3;j++)
		  {
		    vel_corr = K*r_ij[j];
		    p1->f.f[j] -= vel_corr*PMASS(*p2);
		    p2->f.f[j] += vel_corr*PMASS(*p1);
		  }
		  *repeat_ = *repeat_ + 1 ;
		}
	      }
	    else
	      k += ia_params->num;
	  } //while loop
      } //for i loop
    } //for c loop
}
Пример #17
0
/** Computes the three body overlapped angle interaction energy (see \ref tclcommand_inter, \ref tclcommand_analyze). 
    @param p_mid        Pointer to first particle.
    @param p_left        Pointer to second/middle particle.
    @param p_right        Pointer to third particle.
    @param iaparams  bond type number of the angle interaction (see \ref tclcommand_inter).
    @param _energy   return energy pointer.
    @return 0.
    Needs feature OVERLAPPED compiled in (see \ref config.hpp). 
*/
inline int overlap_angle_energy(Particle *p_mid, Particle *p_left, 
			      Particle *p_right, Bonded_ia_parameters *iaparams,
			      double *_energy)
{
  double cosine, vec1[3], vec2[3],  d1i, d2i, dist2;
  int j;

  int ig;
  double ev;
  double prob=0.; 

  cosine=0.0;
  /* vector from p_mid to p_left */
  get_mi_vector(vec1, p_mid->r.p, p_left->r.p);
  dist2 = sqrlen(vec1);
  d1i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec1[j] *= d1i;
  /* vector from p_right to p_mid */
  get_mi_vector(vec2, p_right->r.p, p_mid->r.p);
  dist2 = sqrlen(vec2);
  d2i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec2[j] *= d2i;
  /* scalar produvt of vec1 and vec2 */
  /* Notice: cosine = - costheta */
  cosine = scalar(vec1, vec2);

  if ( cosine >  TINY_COS_VALUE)  cosine = TINY_COS_VALUE;
  if ( cosine < -TINY_COS_VALUE)  cosine = -TINY_COS_VALUE;

  /* compute overlapped cosangl energy */
  /*prob = sum_(i=1,N) [ a_i * exp(-(costheta -b_i)^2/c_i^2))] */
  /*pot  = -1.0 * Log { prob } */
  for(ig=0; ig<iaparams->p.overlap.noverlaps; ig++) {
        ev = (-cosine - iaparams->p.overlap.para_b[ig]) / iaparams->p.overlap.para_c[ig];
        prob = prob + iaparams->p.overlap.para_a[ig] * exp (-1.0*ev*ev);
   }
  *_energy = - log (prob);

  return 0;

}
Пример #18
0
int does_line_go_through_cube(double pos1[3], double pos2[3], double range_start[3], double range[3], int sign[3], double entry[3], double exit[3],int *facein, int *faceout)
     /* p1 and p2 are two particle positions
        there is a cube in the simulation box with one vertex at range_start and the opposite vertex at range_start + range
        this routine calculates where the line connecting p1 and p2 enters and exits this cube
	these points are returned in the variables entry and exit
	the function returns a 0 if the line does not pass through the cube and 1 if it does
     */
{

  double centre[3];             /* centre of the cube */
  double vect2centre1[3];       /* vectors from centre of cube to pos1 and pos2 */
  double vect2centre2[3];
  int i;

  int doesntenter = 0;          /* boolean that indicates whether we have already determined that the line does not enter the cube at all */
  double intersection1 = 0.0, intersection2 = 0.0;
  int found_entry = 0;          /* boolean that indicates whether we have determined where the line enters */
  int found_exit = 0;           /* boolean that indicates whether we have determined where the line exits */
  int i1, i2;
  int inside1, inside2;

   /* find centre of analyzed cube */
  for (i=0;i<3;i++) {
    centre[i] = range_start[i] + range[i]/2.0;
  }

  /* find vectors connecting two particles to centre */
  get_mi_vector(vect2centre1,pos1,centre);
  get_mi_vector(vect2centre2,pos2,centre);

  *facein = -1;
  *faceout = -1;

  /* check if particles are inside cube */
  inside1 = 1;
  inside2 = 1;
  for (i=0;i<3;i++) {
    if (fabs(vect2centre1[i])>range[i]/2.0) inside1 = 0;
    if (fabs(vect2centre2[i])>range[i]/2.0) inside2 = 0;
  }
  PTENSOR_TRACE(fprintf(stderr,"%d: does_line_go_through_cube: Particle1 inside cube = %d Particle2 inside cube = %d \n",this_node,inside1,inside2););
Пример #19
0
/** Velocity correction vectors are computed*/
void compute_vel_corr_vec(int *repeat_)
{
  Bonded_ia_parameters *ia_params;
  int i, j, k, c, np;
  Cell *cell;
  Particle *p, *p1, *p2;
  double v_ij[3], r_ij[3], K, vel_corr;

  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++) {
        p1 = &p[i];
        k=0;
	while(k<p1->bl.n)
	  {
	    ia_params = &bonded_ia_params[p1->bl.e[k++]];
	    if( ia_params->type == BONDED_IA_RIGID_BOND )
	      {
		p2 = local_particles[p1->bl.e[k++]];
        if (!p2) {
            runtimeErrorMsg() <<"rigid bond broken between particles " << p1->p.identity << " and " << p1->bl.e[k-1] << " (particles not stored on the same node)";
		  return;
		}

		vecsub(p1->m.v, p2->m.v, v_ij);
                get_mi_vector(r_ij, p1->r.p, p2->r.p);
		if(fabs(scalar(v_ij, r_ij)) > ia_params->p.rigid_bond.v_tol)
	        {
		  K = scalar(v_ij, r_ij)/ia_params->p.rigid_bond.d2;
#ifdef MASS
		  K /= ((*p1).p.mass + (*p2).p.mass);
#else
		  K /= 2.0;
#endif
		for (j=0;j<3;j++)
		  {
		    vel_corr = K*r_ij[j];
		    p1->f.f[j] -= vel_corr*(*p2).p.mass;
		    p2->f.f[j] += vel_corr*(*p1).p.mass;
		  }
		  *repeat_ = *repeat_ + 1 ;
		}
	      }
	    else
	      k += ia_params->num;
	  } //while loop
      } //for i loop
    } //for c loop
}
Пример #20
0
/** Computes the three body angle interaction energy (see \ref tclcommand_inter, \ref tclcommand_analyze). 
    @param p_mid        Pointer to first particle.
    @param p_left        Pointer to second/middle particle.
    @param p_right        Pointer to third particle.
    @param iaparams  bond type number of the angle interaction (see \ref tclcommand_inter).
    @param _energy   return energy pointer.
    @return 0.
*/
inline int angle_energy(Particle *p_mid, Particle *p_left, Particle *p_right,
			     Bonded_ia_parameters *iaparams, double *_energy)
{
  double cosine, vec1[3], vec2[3],  d1i, d2i, dist2;
  int j;

  cosine=0.0;
  /* vector from p_mid to p_left */
  get_mi_vector(vec1, p_mid->r.p, p_left->r.p);
  dist2 = sqrlen(vec1);
  d1i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec1[j] *= d1i;
  /* vector from p_right to p_mid */
  get_mi_vector(vec2, p_right->r.p, p_mid->r.p);
  dist2 = sqrlen(vec2);
  d2i = 1.0 / sqrt(dist2);
  for(j=0;j<3;j++) vec2[j] *= d2i;
  /* scalar produvt of vec1 and vec2 */
  cosine = scalar(vec1, vec2);
  if ( cosine >  TINY_COS_VALUE)  cosine = TINY_COS_VALUE;
  if ( cosine < -TINY_COS_VALUE)  cosine = -TINY_COS_VALUE;
  /* bond angle energy */
#ifdef BOND_ANGLE_HARMONIC
  {
    double phi;
    phi =  acos(-cosine);
    *_energy = 0.5*iaparams->p.angle.bend*SQR(phi - iaparams->p.angle.phi0);
  }
#endif
#ifdef BOND_ANGLE_COSINE
  *_energy = iaparams->p.angle.bend*(cosine*iaparams->p.angle.cos_phi0 - sqrt(1-SQR(cosine))*iaparams->p.angle.sin_phi0+1);
#endif
#ifdef BOND_ANGLE_COSSQUARE
  *_energy = 0.5*iaparams->p.angle.bend*SQR(cosine + iaparams->p.angle.cos_phi0);
#endif
  return 0;
}
Пример #21
0
/** Calculates the dihedral angle between particle quadruple p1, p2,
p3 and p4. The dihedral angle is the angle between the planes
specified by the particle triples (p1,p2,p3) and (p2,p3,p4). 
Vectors a, b and c are the bond vectors between consequtive particles.
If the a,b or b,c are parallel the dihedral angle is not defined in which
case the routine returns phi=-1. Calling functions should check for that
(Written by: Arijit Maitra) */
inline void calc_dihedral_angle(Particle *p1, Particle *p2, Particle *p3, Particle *p4, 
				  double a[3], double b[3], double c[3], 
				  double aXb[3], double *l_aXb, double bXc[3], double *l_bXc, 
				  double *cosphi, double *phi)
{
  int i;

  get_mi_vector(a, p2->r.p, p1->r.p);
  get_mi_vector(b, p3->r.p, p2->r.p);
  get_mi_vector(c, p4->r.p, p3->r.p);

  /* calculate vector product a X b and b X c */
  vector_product(a, b, aXb);
  vector_product(b, c, bXc);

  /* calculate the unit vectors */
  *l_aXb = sqrt(sqrlen(aXb));
  *l_bXc = sqrt(sqrlen(bXc));

  /* catch case of undefined dihedral angle */
   if ( *l_aXb <= TINY_LENGTH_VALUE || *l_bXc <= TINY_LENGTH_VALUE ) { *phi = -1.0; *cosphi = 0; return;}

  for (i=0;i<3;i++) {
    aXb[i] /= *l_aXb;
    bXc[i] /= *l_bXc;
  }

  *cosphi = scalar(aXb, bXc);

  if ( fabs(fabs(*cosphi)-1)  < TINY_SIN_VALUE  ) *cosphi = dround(*cosphi);

  /* Calculate dihedral angle */
  *phi = acos(*cosphi);
  if( scalar(aXb, c) < 0.0 ) *phi = (2.0*PI) - *phi;

}
Пример #22
0
// Distribute forces that have accumulated on virtual particles to the 
// associated real particles
void distribute_mol_force()
{
  // Iterate over all the particles in the local cells
  Particle *p;
  int i, np, c;
  Cell *cell;
  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++) {
      // We only care about virtual particles
      if (ifParticleIsVirtual(&p[i])) {
       update_mol_pos_particle(&p[i]);

       // First obtain the real particle responsible for this virtual particle:
       Particle *p_real = vs_relative_get_real_particle(&p[i]);

       // Get distance vector pointing from real to virtual particle, respecting periodic boundary i
       // conditions
       double d[3];
       get_mi_vector(d,p[i].r.p,p_real->r.p);

       // The rules for transfering forces are:
       // F_realParticle +=F_virtualParticle
       // T_realParticle +=f_realParticle \times (r_virtualParticle-r_realParticle)
       
       // Calculate torque to be added on real particle
       double tmp[3];
       vector_product(d,p[i].f.f,tmp);

       // Add forces and torques
       int j;
//       printf("Particle %d gets torque from %f %f %f of particle %d\n",p_real->p.identity, p[i].f.f[0], p[i].f.f[1],p[i].f.f[2], p[i].p.identity);
       for (j=0;j<3;j++) {
         p_real->f.torque[j]+=tmp[j];
//	 printf("%f ",tmp[j]);
	 p_real->f.f[j]+=p[i].f.f[j];
	 // Clear forces on virtual particle
	 p[i].f.f[j]=0;

       }
      }
    }
  }
}
Пример #23
0
void calc_wallrdfyz(double *g, int bin, double rmin, double rmax, int rbins)
{
  double bin_width = (rmax-rmin) / (double)rbins;
  double inv_bin_width = 1.0 / bin_width;

  // initially set all counts to 0
  for(int i = 0; i < rbins; ++i) g[i] = 0.0;

  // number of samples gathered
  int cnt = 0;

  // loop over all distinct particle pairs in the bin
  for (int i = 0; i < wallstuff_part_in_bin[bin].n; ++i) {
    for (int j = i + 1; j < wallstuff_part_in_bin[bin].n; ++j) {
      int p = wallstuff_part_in_bin[bin].e[i];
      int q = wallstuff_part_in_bin[bin].e[j];

      // minimum image vector between the two particles
      double diff[3];
      get_mi_vector(diff, partCfg[p].r.p, partCfg[q].r.p);
      double dist = sqrt(SQR(diff[1]) + SQR(diff[2]));

      // binning
      int ind = (int) ((dist - rmin)*inv_bin_width);
      if (ind >=0 && ind < rbins) {
        g[ind]++;
      }
      cnt++;
    }
  }

  // normalization
  // the width of the slice we look at
  double width = wallstuff_boundaries.e[bin+1] - wallstuff_boundaries.e[bin];
  // average density of particles
  double av_density = cnt/(width*box_l[1]*box_l[2]);

  for(int i = 0; i < rbins; ++i) {
    double r_in  =     i*bin_width + rmin; 
    double r_out = (i+1)*bin_width + rmin;
    double bin_volume = PI*(r_out*r_out - r_in*r_in)*width;
    // normalize first to density, and then to relative density
    g[i] = (g[i]/bin_volume) / av_density;
  }
}
Пример #24
0
/* but p_com is a real particle */
void calc_mol_pos(Particle *p_com,double r_com[3]){
   int i,j,mol_id;
   double M=0;
   double vec12[3];
   Particle *p;
#ifdef VIRTUAL_SITES_DEBUG
   int count=0;
#endif
   for (i=0;i<3;i++){
      r_com[i]=0.0;
   }
   mol_id=p_com->p.mol_id;
   for (i=0;i<topology[mol_id].part.n;i++){
      p=local_particles[topology[mol_id].part.e[i]];
      #ifdef VIRTUAL_SITES_DEBUG
      if (p==NULL){
          ostringstream msg;
          msg <<"Particle does not exist in calc_mol_pos! id= " << topology[mol_id].part.e[i] << "\n";
          runtimeError(msg);
         return;
      }
      #endif
      if (ifParticleIsVirtual(p)) continue;
      get_mi_vector(vec12,p->r.p, p_com->r.p);
      for (j=0;j<3;j++){
          r_com[j] += PMASS(*p)*vec12[j];
      }
      M+=PMASS(*p);
#ifdef VIRTUAL_SITES_DEBUG
      count++;
#endif
   }
   for (j=0;j<3;j++){
      r_com[j] /= M;
      r_com[j] += p_com->r.p[j];
   }
#ifdef VIRTUAL_SITES_DEBUG
   if (count!=topology[mol_id].part.n-1){
       ostringstream msg;
       msg <<"There is more than one COM in calc_mol_pos! mol_id= " << mol_id << "\n";
       runtimeError(msg);
      return;
   }
#endif
}
Пример #25
0
void get_mol_dist_vector_from_molid_cfg(int mol_id1,int mol_id2,double dist[3]){
   Particle *p1_com,*p2_com;
   p1_com=get_mol_com_particle_from_molid_cfg(mol_id1);
   p2_com=get_mol_com_particle_from_molid_cfg(mol_id2);
   #ifdef VIRTUAL_SITES_DEBUG
   if(p1_com==NULL){
      fprintf(stderr,"No com found in get_mol_dist_vector_from_molid_cfg for mol id=%i\n",mol_id1);
      dist[0]=dist[1]=dist[2]=0.0;
      return;
   }
   if(p2_com==NULL){
      fprintf(stderr,"No com found in get_mol_dist_vector_from_molid_cfg for mol id=%i\n",mol_id2);
      dist[0]=dist[1]=dist[2]=0.0;
      return;
   }
   #endif
   get_mi_vector(dist,p1_com->r.p, p2_com->r.p);
}
Пример #26
0
double distto(double p[3], int pid)
{
  int i;
  double d[3];
  double mindist;

  updatePartCfg(WITHOUT_BONDS);

  /* larger than possible */
  mindist=SQR(box_l[0] + box_l[1] + box_l[2]);
  for (i=0; i<n_part; i++) {
    if (pid != partCfg[i].p.identity) {
      get_mi_vector(d, p, partCfg[i].r.p);
      mindist = dmin(mindist, sqrlen(d));
    }
  }
  return sqrt(mindist);
}
// Rigid body conribution to scalar pressure and stress tensor
void vs_relative_pressure_and_stress_tensor(double* pressure, double* stress_tensor)
{
  // Division by 3 volume is somewhere else. (pressure.cpp after all presure calculations)


  // Iterate over all the particles in the local cells
  Particle *p;
  int i, np, c;
  Cell *cell;
  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++) {
      // We only care about virtual particles
      if (!ifParticleIsVirtual(&p[i]))
        continue;

      update_mol_pos_particle(&p[i]);

      // First obtain the real particle responsible for this virtual particle:
      Particle *p_real = vs_relative_get_real_particle(&p[i]);

      // Get distance vector pointing from real to virtual particle, respecting periodic boundary i
      // conditions
      double d[3];
      get_mi_vector(d,p_real->r.p,p[i].r.p);

      // Stress tensor conribution
      for (int k =0; k<3;k++)
       for (int l =0;l<3;l++)
        stress_tensor[k*3+l] +=p[i].f.f[k] *d[l];
      
      // Pressure = 1/3 trace of stress tensor
      // but the 1/3 is applied somewhere else.
      *pressure +=(p[i].f.f[0] *d[0] +p[i].f.f[1] *d[1] +p[i].f.f[2] *d[2]);

    }
  }
 *pressure/=0.5*time_step*time_step;
 for (i=0;i<9;i++)
  stress_tensor[i]/=0.5*time_step*time_step;

}
Пример #28
0
/* but p_com is a real particle */
void calc_mol_pos(Particle *p_com,double r_com[3]){
   int i,j,mol_id;
   double M=0;
   double vec12[3];
   Particle *p;
#ifdef VIRTUAL_SITES_DEBUG
   int count=0;
#endif
   for (i=0;i<3;i++){
      r_com[i]=0.0;
   }
   mol_id=p_com->p.mol_id;
   for (i=0;i<topology[mol_id].part.n;i++){
      p=local_particles[topology[mol_id].part.e[i]];
      #ifdef VIRTUAL_SITES_DEBUG
      if (p==NULL){
         char *errtxt = runtime_error(128 + 3*ES_INTEGER_SPACE);
         ERROR_SPRINTF(errtxt,"Particle does not exist in calc_mol_pos! id=%i\n",topology[mol_id].part.e[i]);
         return;
      }
      #endif
      if (ifParticleIsVirtual(p)) continue;
      get_mi_vector(vec12,p->r.p, p_com->r.p);
      for (j=0;j<3;j++){
          r_com[j] += PMASS(*p)*vec12[j];
      }
      M+=PMASS(*p);
#ifdef VIRTUAL_SITES_DEBUG
      count++;
#endif
   }
   for (j=0;j<3;j++){
      r_com[j] /= M;
      r_com[j] += p_com->r.p[j];
   }
#ifdef VIRTUAL_SITES_DEBUG
   if (count!=topology[mol_id].part.n-1){
      char *errtxt = runtime_error(128 + 3*ES_INTEGER_SPACE);
      ERROR_SPRINTF(errtxt,"There is more than one COM in calc_mol_pos! mol_id=%i\n",mol_id);
      return;
   }
#endif
}
Пример #29
0
int observable_calc_interacts_with (observable* self) {
  double* A = self->last_value;
  iw_params *params=(iw_params*) self->container;
  IntList* ids1;
  IntList* ids2;
  int i,j;
//  double dx,dy,dz;
  double dist2;
  double cutoff2=params->cutoff*params->cutoff;
  double pos1[3], pos2[3], dist[3];
  ids1=params->ids1;
  ids2=params->ids2;
  if (!sortPartCfg()) {
    char *errtxt = runtime_error(128);
    ERROR_SPRINTF(errtxt,"{094 could not sort partCfg} ");
    return -1;
  }
  for ( i = 0; i<ids1->n; i++ ) {
    if (ids1->e[i] >= n_part)
      return 1;
    pos1[0]=partCfg[ids1->e[i]].r.p[0];
    pos1[1]=partCfg[ids1->e[i]].r.p[1];
    pos1[2]=partCfg[ids1->e[i]].r.p[2];
    for ( j = 0; j<ids2->n; j++ ) {
      if (ids2->e[j] >= n_part)
        return 1;
      if (ids2->e[j] == ids1->e[i]) // do not count self-interaction :-)
        continue;
      A[i] = 0;
      pos2[0]=partCfg[ids2->e[j]].r.p[0];
      pos2[1]=partCfg[ids2->e[j]].r.p[1];
      pos2[2]=partCfg[ids2->e[j]].r.p[2];
      get_mi_vector(dist,pos1,pos2);
      dist2= dist[0]*dist[0] + dist[1]*dist[1] + dist[2]*dist[2];
      if(dist2<cutoff2) {
        A[i] = 1;
	break;
	// interaction found for i, go for next
      }
    }
  }
  return 0;
}
Пример #30
0
void calc_force_between_mol(int mol_id1,int mol_id2,double force[3]){
  int i,j;
  Particle *p1,*p2;
  double vec12[3],dist2,dist;
#ifdef ADRESS
  int l;
  double weight;
  double temp_force[3]={0,0,0};
#endif
  force[0]=force[1]=force[2]=0.0;
  for (i=0;i<topology[mol_id1].part.n;i++){
    p1=&partCfg[topology[mol_id1].part.e[i]];
    for (j=0;j<topology[mol_id2].part.n;j++){
      p2=&partCfg[topology[mol_id2].part.e[j]];
      
      get_mi_vector(vec12,p1->r.p, p2->r.p);
      dist2=sqrlen(vec12);
      dist=sqrt(dist2);
#ifdef ADRESS
      for(l=0;l<3;l++)
	temp_force[l]=0;
#ifdef EXCLUSIONS
      if(do_nonbonded(p1,p2))
#endif
	{
	  calc_non_bonded_pair_force_from_partcfg_simple(p1,p2,vec12,dist,dist2,temp_force);
	  weight = adress_non_bonded_force_weight(p1,p2);
	  for(l=0;l<3;l++)
	    force[l] += weight*temp_force[l];
	}
#else
#ifdef EXCLUSIONS
      if(do_nonbonded(p1,p2))
#endif
	calc_non_bonded_pair_force_from_partcfg_simple(p1,p2,vec12,dist,dist2,force);
#endif
      
    }
  }
  
}