/** 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; }
/** 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; }
/** 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; }
/** 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; }
/* 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]; } }
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; }
/**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 }
/** 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; }
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); } } } }
/** 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; }
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++; } } }
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"); }
/// 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; }
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; }
/** 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 }
/** 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; }
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););
/** 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 }
/** 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; }
/** 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; }
// 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; } } } } }
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; } }
/* 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 }
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); }
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; }
/* 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 }
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; }
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 } } }