/** Calculate non bonded energies between a pair of particles. @param p1 pointer to particle 1. @param p2 pointer to particle 2. @param d vector between p1 and p2. @param dist distance between p1 and p2. @param dist2 distance squared between p1 and p2. */ inline void add_non_bonded_pair_virials(Particle *p1, Particle *p2, double d[3], double dist, double dist2) { int p1molid, p2molid, k, l; double force[3] = {0, 0, 0}; calc_non_bonded_pair_force(p1, p2,d, dist, dist2, force); *obsstat_nonbonded(&virials, p1->p.type, p2->p.type) += d[0]*force[0] + d[1]*force[1] + d[2]*force[2]; /* stress tensor part */ for(k=0; k<3; k++) for(l=0; l<3; l++) obsstat_nonbonded(&p_tensor, p1->p.type, p2->p.type)[k*3 + l] += force[k]*d[l]; p1molid = p1->p.mol_id; p2molid = p2->p.mol_id; if ( p1molid == p2molid ) { *obsstat_nonbonded_intra(&virials_non_bonded, p1->p.type, p2->p.type) += d[0]*force[0] + d[1]*force[1] + d[2]*force[2]; for(k=0; k<3; k++) for(l=0; l<3; l++) obsstat_nonbonded_intra(&p_tensor_non_bonded, p1->p.type, p2->p.type)[k*3 + l] += force[k]*d[l]; } if ( p1molid != p2molid ) { *obsstat_nonbonded_inter(&virials_non_bonded, p1->p.type, p2->p.type) += d[0]*force[0] + d[1]*force[1] + d[2]*force[2]; for(k=0; k<3; k++) for(l=0; l<3; l++) obsstat_nonbonded_inter(&p_tensor_non_bonded, p1->p.type, p2->p.type)[k*3 + l] += force[k]*d[l]; } #ifdef ELECTROSTATICS /* real space coulomb */ if (coulomb.method != COULOMB_NONE) { switch (coulomb.method) { #ifdef P3M case COULOMB_P3M_GPU: case COULOMB_P3M: force[0] = 0.0; force[1] = 0.0; force[2] = 0.0; p3m_add_pair_force(p1->p.q*p2->p.q, d, dist2, dist, force); virials.coulomb[0] += p3m_pair_energy(p1->p.q*p2->p.q,d,dist2,dist); for (k = 0; k<3; k++) for (l = 0; l<3; l++) p_tensor.coulomb[k*3 + l] += force[k]*d[l]; break; #endif /* short range potentials, where we use the virial */ /***************************************************/ case COULOMB_DH: { double force[3] = {0, 0, 0}; add_dh_coulomb_pair_force(p1,p2,d,dist, force); for(k=0; k<3; k++) for(l=0; l<3; l++) p_tensor.coulomb[k*3 + l] += force[k]*d[l]; virials.coulomb[0] += force[0]*d[0] + force[1]*d[1] + force[2]*d[2]; break; } case COULOMB_RF: { double force[3] = {0, 0, 0}; add_rf_coulomb_pair_force(p1,p2,d,dist, force); for(k=0; k<3; k++) for(l=0; l<3; l++) p_tensor.coulomb[k*3 + l] += force[k]*d[l]; virials.coulomb[0] += force[0]*d[0] + force[1]*d[1] + force[2]*d[2]; break; } case COULOMB_INTER_RF: // this is done together with the other short range interactions break; default: fprintf(stderr,"calculating pressure for electrostatics method that doesn't have it implemented\n"); break; } } #endif /*ifdef ELECTROSTATICS */ #ifdef DIPOLES /* real space magnetic dipole-dipole */ if (coulomb.Dmethod != DIPOLAR_NONE) { fprintf(stderr,"calculating pressure for magnetostatics which doesn't have it implemented\n"); } #endif /*ifdef DIPOLES */ }
/** Add non bonded energies and short range coulomb between a pair of particles. @param p1 pointer to particle 1. @param p2 pointer to particle 2. @param d vector between p1 and p2. @param dist distance between p1 and p2. @param dist2 distance squared between p1 and p2. */ inline void add_non_bonded_pair_energy(Particle *p1, Particle *p2, double d[3], double dist, double dist2) { IA_parameters *ia_params = get_ia_param(p1->p.type,p2->p.type); #if defined(ELECTROSTATICS) || defined(DIPOLES) double ret = 0; #endif *obsstat_nonbonded(&energy, p1->p.type, p2->p.type) += calc_non_bonded_pair_energy(p1, p2, ia_params, d, dist, dist2); #ifdef ELECTROSTATICS if (coulomb.method != COULOMB_NONE) { /* real space coulomb */ switch (coulomb.method) { #ifdef P3M case COULOMB_P3M_GPU: case COULOMB_P3M: ret = p3m_pair_energy(p1->p.q*p2->p.q,d,dist2,dist); break; case COULOMB_ELC_P3M: ret = p3m_pair_energy(p1->p.q*p2->p.q,d,dist2,dist); if (elc_params.dielectric_contrast_on) ret += 0.5*ELC_P3M_dielectric_layers_energy_contribution(p1,p2); break; #endif case COULOMB_DH: ret = dh_coulomb_pair_energy(p1,p2,dist); break; case COULOMB_RF: ret = rf_coulomb_pair_energy(p1,p2,dist); break; case COULOMB_INTER_RF: //this is done above as interaction ret = 0; break; case COULOMB_MMM1D: ret = mmm1d_coulomb_pair_energy(p1,p2,d,dist2,dist); break; case COULOMB_MMM2D: ret = mmm2d_coulomb_pair_energy(p1->p.q*p2->p.q,d,dist2,dist); break; default : ret = 0.; } energy.coulomb[0] += ret; } #endif #ifdef DIPOLES if (coulomb.Dmethod != DIPOLAR_NONE) { //ret=0; switch (coulomb.Dmethod) { #ifdef DP3M case DIPOLAR_MDLC_P3M: //fall trough case DIPOLAR_P3M: ret = dp3m_pair_energy(p1,p2,d,dist2,dist); break; #endif default: ret=0; } energy.dipolar[0] += ret; } #endif }