![]() |
ESPResSo 3.2.0-11-g9950804-git
Extensible Simulation Package for Soft Matter Research
|
00001 /* 00002 Copyright (C) 2010,2012,2013 The ESPResSo project 00003 Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 00004 Max-Planck-Institute for Polymer Research, Theory Group 00005 00006 This file is part of ESPResSo. 00007 00008 ESPResSo is free software: you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation, either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 ESPResSo is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with this program. If not, see <http://www.gnu.org/licenses/>. 00020 */ 00021 #ifndef _FORCES_H 00022 #define _FORCES_H 00023 /** \file forces.h Force calculation. 00024 * 00025 * \todo Preprocessor switches for all forces (Default: everything is turned on). 00026 * \todo Implement more flexible thermostat, %e.g. which thermostat to use. 00027 * 00028 * For more information see forces.c . 00029 */ 00030 #include "utils.h" 00031 #include "thermostat.h" 00032 #ifdef MOLFORCES 00033 #include "topology.h" 00034 #endif 00035 #include "npt.h" 00036 #include "adresso.h" 00037 #include "virtual_sites.h" 00038 #include "metadynamics.h" 00039 00040 /* include the force files */ 00041 #include "p3m.h" 00042 #include "p3m-dipolar.h" 00043 #include "lj.h" 00044 #include "ljgen.h" 00045 #include "steppot.h" 00046 #include "hertzian.h" 00047 #include "gaussian.h" 00048 #include "bmhtf-nacl.h" 00049 #include "buckingham.h" 00050 #include "soft_sphere.h" 00051 #include "hat.h" 00052 #include "maggs.h" 00053 #include "tab.h" 00054 #include "overlap.h" 00055 #include "ljcos.h" 00056 #include "ljcos2.h" 00057 #include "ljangle.h" 00058 #include "gb.h" 00059 #include "fene.h" 00060 #include "object-in-fluid/stretching_force.h" 00061 #include "object-in-fluid/area_force_local.h" 00062 #include "object-in-fluid/area_force_global.h" 00063 #include "object-in-fluid/bending_force.h" 00064 #include "object-in-fluid/volume_force.h" 00065 #include "harmonic.h" 00066 #include "subt_lj.h" 00067 #include "angle.h" 00068 #include "angle_harmonic.h" 00069 #include "angle_cosine.h" 00070 #include "angle_cossquare.h" 00071 #include "angledist.h" 00072 #include "dihedral.h" 00073 #include "debye_hueckel.h" 00074 #include "endangledist.h" 00075 #include "reaction_field.h" 00076 #include "mmm1d.h" 00077 #include "mmm2d.h" 00078 #include "comforce.h" 00079 #include "comfixed.h" 00080 #include "molforces.h" 00081 #include "morse.h" 00082 #include "elc.h" 00083 #include "iccp3m.h" 00084 #include "collision.h" 00085 /* end of force files */ 00086 00087 /** \name Exported Functions */ 00088 /************************************************************/ 00089 /*@{*/ 00090 00091 /** Calculate forces. 00092 * 00093 * A short list, what the function is doing: 00094 * <ol> 00095 * <li> Initialize forces with: \ref friction_thermo_langevin (ghost forces with zero). 00096 * <li> Calculate bonded interaction forces:<br> 00097 * Loop all local particles (not the ghosts). 00098 * <ul> 00099 * <li> FENE 00100 * <li> ANGLE (cos bend potential) 00101 * </ul> 00102 * <li> Calculate non-bonded short range interaction forces:<br> 00103 * Loop all \ref IA_Neighbor::vList "verlet lists" of all \ref #cells. 00104 * <ul> 00105 * <li> Lennard-Jones. 00106 * <li> Buckingham. 00107 * <li> Real space part: Coulomb. 00108 * <li> Ramp. 00109 * </ul> 00110 * <li> Calculate long range interaction forces:<br> 00111 Uses <a href=P3M_calc_kspace_forces> P3M_calc_kspace_forces </a> 00112 * </ol> 00113 */ 00114 void force_calc(); 00115 00116 /** Set forces of all ghosts to zero 00117 */ 00118 void init_forces_ghosts(); 00119 00120 /** Check if forces are NAN 00121 */ 00122 void check_forces(); 00123 00124 00125 MDINLINE void calc_non_bonded_pair_force_parts(Particle *p1, Particle *p2, IA_parameters *ia_params,double d[3], 00126 double dist, double dist2, double force[3],double torgue1[3],double torgue2[3]) 00127 { 00128 #ifdef NO_INTRA_NB 00129 if (p1->p.mol_id==p2->p.mol_id) return; 00130 #endif 00131 /* lennard jones */ 00132 #ifdef LENNARD_JONES 00133 add_lj_pair_force(p1,p2,ia_params,d,dist, force); 00134 #endif 00135 /* lennard jones generic */ 00136 #ifdef LENNARD_JONES_GENERIC 00137 add_ljgen_pair_force(p1,p2,ia_params,d,dist, force); 00138 #endif 00139 /* Directional LJ */ 00140 #ifdef LJ_ANGLE 00141 /* The forces are propagated within the function */ 00142 add_ljangle_pair_force(p1,p2,ia_params,d,dist); 00143 #endif 00144 /* smooth step */ 00145 #ifdef SMOOTH_STEP 00146 add_SmSt_pair_force(p1,p2,ia_params,d,dist,dist2, force); 00147 #endif 00148 /* Hertzian force */ 00149 #ifdef HERTZIAN 00150 add_hertzian_pair_force(p1,p2,ia_params,d,dist,dist2, force); 00151 #endif 00152 /* Gaussian force */ 00153 #ifdef GAUSSIAN 00154 add_gaussian_pair_force(p1,p2,ia_params,d,dist,dist2, force); 00155 #endif 00156 /* BMHTF NaCl */ 00157 #ifdef BMHTF_NACL 00158 add_BMHTF_pair_force(p1,p2,ia_params,d,dist,dist2, force); 00159 #endif 00160 /* buckingham*/ 00161 #ifdef BUCKINGHAM 00162 add_buck_pair_force(p1,p2,ia_params,d,dist,force); 00163 #endif 00164 /* morse*/ 00165 #ifdef MORSE 00166 add_morse_pair_force(p1,p2,ia_params,d,dist,force); 00167 #endif 00168 /*soft-sphere potential*/ 00169 #ifdef SOFT_SPHERE 00170 add_soft_pair_force(p1,p2,ia_params,d,dist,force); 00171 #endif 00172 /*hat potential*/ 00173 #ifdef HAT 00174 add_hat_pair_force(p1,p2,ia_params,d,dist,force); 00175 #endif 00176 /* lennard jones cosine */ 00177 #ifdef LJCOS 00178 add_ljcos_pair_force(p1,p2,ia_params,d,dist,force); 00179 #endif 00180 /* lennard jones cosine */ 00181 #ifdef LJCOS2 00182 add_ljcos2_pair_force(p1,p2,ia_params,d,dist,force); 00183 #endif 00184 /* tabulated */ 00185 #ifdef TABULATED 00186 add_tabulated_pair_force(p1,p2,ia_params,d,dist,force); 00187 #endif 00188 /* Gay-Berne */ 00189 #ifdef GAY_BERNE 00190 add_gb_pair_force(p1,p2,ia_params,d,dist,force,torgue1,torgue2); 00191 #endif 00192 #ifdef INTER_RF 00193 add_interrf_pair_force(p1,p2,ia_params,d,dist, force); 00194 #endif 00195 #ifdef ADRESS 00196 #ifdef INTERFACE_CORRECTION 00197 add_adress_tab_pair_force(p1,p2,ia_params,d,dist,force); 00198 #endif 00199 #endif 00200 } 00201 00202 MDINLINE void calc_non_bonded_pair_force(Particle *p1,Particle *p2,IA_parameters *ia_params,double d[3],double dist,double dist2,double force[3],double t1[3],double t2[3]){ 00203 #ifdef MOL_CUT 00204 //You may want to put a correction factor and correction term for smoothing function else then theta 00205 if (checkIfParticlesInteractViaMolCut(p1,p2,ia_params)==1) 00206 #endif 00207 { 00208 calc_non_bonded_pair_force_parts(p1, p2, ia_params,d, dist, dist2,force,t1,t2); 00209 } 00210 } 00211 00212 MDINLINE void calc_non_bonded_pair_force_simple(Particle *p1,Particle *p2,double d[3],double dist,double dist2,double force[3]){ 00213 IA_parameters *ia_params = get_ia_param(p1->p.type,p2->p.type); 00214 double t1[3],t2[3]; 00215 #ifdef ADRESS 00216 int j; 00217 double force_weight=adress_non_bonded_force_weight(p1,p2); 00218 if (force_weight<ROUND_ERROR_PREC) return; 00219 #endif 00220 calc_non_bonded_pair_force(p1,p2,ia_params,d,dist,dist2,force,t1,t2); 00221 #ifdef ADRESS 00222 for (j=0;j<3;j++){ 00223 force[j]*=force_weight; 00224 } 00225 #endif 00226 } 00227 00228 MDINLINE void calc_non_bonded_pair_force_from_partcfg(Particle *p1,Particle *p2,IA_parameters *ia_params,double d[3],double dist,double dist2,double force[3],double t1[3],double t2[3]){ 00229 #ifdef MOL_CUT 00230 //You may want to put a correction factor and correction term for smoothing function else then theta 00231 if (checkIfParticlesInteractViaMolCut_partcfg(p1,p2,ia_params)==1) 00232 #endif 00233 { 00234 calc_non_bonded_pair_force_parts(p1, p2, ia_params,d, dist, dist2,force,t1,t2); 00235 } 00236 } 00237 00238 MDINLINE void calc_non_bonded_pair_force_from_partcfg_simple(Particle *p1,Particle *p2,double d[3],double dist,double dist2,double force[3]){ 00239 IA_parameters *ia_params = get_ia_param(p1->p.type,p2->p.type); 00240 double t1[3],t2[3]; 00241 calc_non_bonded_pair_force_from_partcfg(p1,p2,ia_params,d,dist,dist2,force,t1,t2); 00242 } 00243 00244 /** Calculate non bonded forces between a pair of particles. 00245 @param p1 pointer to particle 1. 00246 @param p2 pointer to particle 2. 00247 @param d vector between p1 and p2. 00248 @param dist distance between p1 and p2. 00249 @param dist2 distance squared between p1 and p2. */ 00250 MDINLINE void add_non_bonded_pair_force(Particle *p1, Particle *p2, 00251 double d[3], double dist, double dist2) 00252 { 00253 IA_parameters *ia_params = get_ia_param(p1->p.type,p2->p.type); 00254 double force[3] = { 0., 0., 0. }; 00255 double torque1[3] = { 0., 0., 0. }; 00256 double torque2[3] = { 0., 0., 0. }; 00257 int j; 00258 00259 00260 #ifdef COLLISION_DETECTION 00261 if (collision_params.mode > 0) 00262 detect_collision(p1,p2); 00263 #endif 00264 00265 #ifdef ADRESS 00266 double tmp,force_weight=adress_non_bonded_force_weight(p1,p2); 00267 if (force_weight<ROUND_ERROR_PREC) return; 00268 #endif 00269 00270 FORCE_TRACE(fprintf(stderr, "%d: interaction %d<->%d dist %f\n", this_node, p1->p.identity, p2->p.identity, dist)); 00271 00272 /***********************************************/ 00273 /* thermostat */ 00274 /***********************************************/ 00275 00276 #ifdef DPD 00277 /* DPD thermostat forces */ 00278 if ( thermo_switch & THERMO_DPD ) add_dpd_thermo_pair_force(p1,p2,d,dist,dist2); 00279 #endif 00280 00281 #ifdef INTER_DPD 00282 if ( thermo_switch == THERMO_INTER_DPD ) add_inter_dpd_pair_force(p1,p2,ia_params,d,dist,dist2); 00283 #endif 00284 00285 /***********************************************/ 00286 /* non bonded pair potentials */ 00287 /***********************************************/ 00288 00289 calc_non_bonded_pair_force(p1,p2,ia_params,d,dist,dist2,force,torque1,torque2); 00290 00291 /***********************************************/ 00292 /* short range electrostatics */ 00293 /***********************************************/ 00294 00295 #ifdef ELECTROSTATICS 00296 if (coulomb.method == COULOMB_DH) 00297 add_dh_coulomb_pair_force(p1,p2,d,dist,force); 00298 00299 if (coulomb.method == COULOMB_RF) 00300 add_rf_coulomb_pair_force(p1,p2,d,dist,force); 00301 #endif 00302 00303 /*********************************************************************/ 00304 /* everything before this contributes to the virial pressure in NpT, */ 00305 /* but nothing afterwards */ 00306 /*********************************************************************/ 00307 #ifdef NPT 00308 for (j = 0; j < 3; j++) 00309 if(integ_switch == INTEG_METHOD_NPT_ISO) 00310 nptiso.p_vir[j] += force[j] * d[j]; 00311 #endif 00312 00313 /***********************************************/ 00314 /* long range electrostatics */ 00315 /***********************************************/ 00316 00317 #ifdef ELECTROSTATICS 00318 00319 /* real space coulomb */ 00320 double q1q2 = p1->p.q*p2->p.q; 00321 if (!(iccp3m_initialized && iccp3m_cfg.set_flag)) { 00322 switch (coulomb.method) { 00323 #ifdef P3M 00324 case COULOMB_ELC_P3M: { 00325 if (q1q2) { 00326 p3m_add_pair_force(q1q2,d,dist2,dist,force); 00327 00328 // forces from the virtual charges 00329 // they go directly onto the particles, since they are not pairwise forces 00330 if (elc_params.dielectric_contrast_on) 00331 ELC_P3M_dielectric_layers_force_contribution(p1, p2, p1->f.f, p2->f.f); 00332 } 00333 break; 00334 } 00335 case COULOMB_P3M: { 00336 #ifdef NPT 00337 if (q1q2) { 00338 double eng = p3m_add_pair_force(q1q2,d,dist2,dist,force); 00339 if(integ_switch == INTEG_METHOD_NPT_ISO) 00340 nptiso.p_vir[0] += eng; 00341 } 00342 #else 00343 if (q1q2) p3m_add_pair_force(q1q2,d,dist2,dist,force); 00344 #endif 00345 break; 00346 } 00347 #endif 00348 case COULOMB_MMM1D: 00349 if (q1q2) add_mmm1d_coulomb_pair_force(q1q2,d,dist2,dist,force); 00350 break; 00351 case COULOMB_MMM2D: 00352 if (q1q2) add_mmm2d_coulomb_pair_force(q1q2,d,dist2,dist,force); 00353 break; 00354 case COULOMB_NONE: 00355 break; 00356 } 00357 } 00358 00359 #endif /*ifdef ELECTROSTATICS */ 00360 00361 00362 /***********************************************/ 00363 /* long range magnetostatics */ 00364 /***********************************************/ 00365 00366 00367 #ifdef DIPOLES 00368 /* real space magnetic dipole-dipole */ 00369 switch (coulomb.Dmethod) { 00370 #ifdef DP3M 00371 case DIPOLAR_MDLC_P3M: 00372 //fall trough 00373 case DIPOLAR_P3M: { 00374 #ifdef NPT 00375 double eng = dp3m_add_pair_force(p1,p2,d,dist2,dist,force); 00376 if(integ_switch == INTEG_METHOD_NPT_ISO) 00377 nptiso.p_vir[0] += eng; 00378 #else 00379 dp3m_add_pair_force(p1,p2,d,dist2,dist,force); 00380 #endif 00381 break; 00382 } 00383 #endif /*ifdef DP3M */ 00384 } 00385 #endif /* ifdef DIPOLES */ 00386 00387 /***********************************************/ 00388 /* add total nonbonded forces to particle */ 00389 /***********************************************/ 00390 00391 for (j = 0; j < 3; j++) { 00392 #ifdef ADRESS 00393 tmp=force_weight*force[j]; 00394 p1->f.f[j] += tmp; 00395 p2->f.f[j] -= tmp; 00396 #else 00397 p1->f.f[j] += force[j]; 00398 p2->f.f[j] -= force[j]; 00399 #endif 00400 #ifdef ROTATION 00401 p1->f.torque[j] += torque1[j]; 00402 p2->f.torque[j] += torque2[j]; 00403 #endif 00404 } 00405 } 00406 00407 /** Calculate bonded forces for one particle. 00408 @param p1 particle for which to calculate forces 00409 */ 00410 MDINLINE void add_bonded_force(Particle *p1) 00411 { 00412 double dx[3] = { 0., 0., 0. }; 00413 double force[3] = { 0., 0., 0. }; 00414 double force2[3] = { 0., 0., 0. }; 00415 double force3[3] = { 0., 0., 0. }; 00416 #ifdef ROTATION 00417 double torque1[3] = { 0., 0., 0. }; 00418 double torque2[3] = { 0., 0., 0. }; 00419 #endif 00420 char *errtxt; 00421 Particle *p2, *p3 = NULL, *p4 = NULL; 00422 Bonded_ia_parameters *iaparams; 00423 int i, j, type_num, type, n_partners, bond_broken; 00424 00425 #ifdef ADRESS 00426 double tmp, force_weight=1; 00427 //double tmp,force_weight=adress_bonded_force_weight(p1); 00428 //if (force_weight<ROUND_ERROR_PREC) return; 00429 #endif 00430 00431 i = 0; 00432 while(i<p1->bl.n) { 00433 type_num = p1->bl.e[i++]; 00434 iaparams = &bonded_ia_params[type_num]; 00435 type = iaparams->type; 00436 n_partners = iaparams->num; 00437 00438 /* fetch particle 2, which is always needed */ 00439 p2 = local_particles[p1->bl.e[i++]]; 00440 if (!p2) { 00441 errtxt = runtime_error(128 + 2*ES_INTEGER_SPACE); 00442 ERROR_SPRINTF(errtxt,"{078 bond broken between particles %d and %d (particles not stored on the same node)} ", 00443 p1->p.identity, p1->bl.e[i-1]); 00444 return; 00445 } 00446 00447 /* fetch particle 3 eventually */ 00448 if (n_partners >= 2) { 00449 p3 = local_particles[p1->bl.e[i++]]; 00450 if (!p3) { 00451 errtxt = runtime_error(128 + 3*ES_INTEGER_SPACE); 00452 ERROR_SPRINTF(errtxt,"{079 bond broken between particles %d, %d and %d (particles not stored on the same node)} ", 00453 p1->p.identity, p1->bl.e[i-2], p1->bl.e[i-1]); 00454 return; 00455 } 00456 } 00457 00458 /* fetch particle 4 eventually */ 00459 if (n_partners >= 3) { 00460 p4 = local_particles[p1->bl.e[i++]]; 00461 if (!p4) { 00462 errtxt = runtime_error(128 + 4*ES_INTEGER_SPACE); 00463 ERROR_SPRINTF(errtxt,"{080 bond broken between particles %d, %d, %d and %d (particles not stored on the same node)} ", 00464 p1->p.identity, p1->bl.e[i-3], p1->bl.e[i-2], p1->bl.e[i-1]); 00465 return; 00466 } 00467 } 00468 00469 if (n_partners == 1) { 00470 /* because of the NPT pressure calculation for pair forces, we need the 00471 1->2 distance vector here. For many body interactions this vector is not needed, 00472 and the pressure calculation not yet clear. */ 00473 get_mi_vector(dx, p1->r.p, p2->r.p); 00474 } 00475 00476 switch (type) { 00477 case BONDED_IA_FENE: 00478 bond_broken = calc_fene_pair_force(p1, p2, iaparams, dx, force); 00479 break; 00480 case BONDED_IA_HARMONIC: 00481 bond_broken = calc_harmonic_pair_force(p1, p2, iaparams, dx, force); 00482 break; 00483 case BONDED_IA_STRETCHING_FORCE: 00484 bond_broken = calc_stretching_force_pair_force(p1, p2, iaparams, dx, force); 00485 break; 00486 case BONDED_IA_AREA_FORCE_LOCAL: 00487 bond_broken = calc_area_force_local(p1, p2, p3, iaparams, force, force2, force3); 00488 break; 00489 #ifdef AREA_FORCE_GLOBAL 00490 case BONDED_IA_AREA_FORCE_GLOBAL: 00491 bond_broken = 0; 00492 break; 00493 #endif 00494 case BONDED_IA_BENDING_FORCE: 00495 bond_broken = calc_bending_force(p1, p2, p3, p4, iaparams, force, force2); 00496 break; 00497 #ifdef VOLUME_FORCE 00498 case BONDED_IA_VOLUME_FORCE: 00499 bond_broken = 0; 00500 break; 00501 #endif 00502 #ifdef LENNARD_JONES 00503 case BONDED_IA_SUBT_LJ: 00504 bond_broken = calc_subt_lj_pair_force(p1, p2, iaparams, dx, force); 00505 break; 00506 #endif 00507 #ifdef BOND_ANGLE_OLD 00508 /* the first case is not needed and should not be called */ 00509 case BONDED_IA_ANGLE_OLD: 00510 bond_broken = calc_angle_force(p1, p2, p3, iaparams, force, force2); 00511 break; 00512 #endif 00513 #ifdef BOND_ANGLE 00514 case BONDED_IA_ANGLE_HARMONIC: 00515 bond_broken = calc_angle_harmonic_force(p1, p2, p3, iaparams, force, force2); 00516 break; 00517 case BONDED_IA_ANGLE_COSINE: 00518 bond_broken = calc_angle_cosine_force(p1, p2, p3, iaparams, force, force2); 00519 break; 00520 case BONDED_IA_ANGLE_COSSQUARE: 00521 bond_broken = calc_angle_cossquare_force(p1, p2, p3, iaparams, force, force2); 00522 break; 00523 #endif 00524 #ifdef BOND_ANGLEDIST 00525 case BONDED_IA_ANGLEDIST: 00526 bond_broken = calc_angledist_force(p1, p2, p3, iaparams, force, force2); 00527 break; 00528 #endif 00529 #ifdef BOND_ENDANGLEDIST 00530 case BONDED_IA_ENDANGLEDIST: 00531 bond_broken = calc_endangledist_pair_force(p1, p2, iaparams, dx, force, force2); 00532 break; 00533 #endif 00534 case BONDED_IA_DIHEDRAL: 00535 bond_broken = calc_dihedral_force(p1, p2, p3, p4, iaparams, force, force2, force3); 00536 break; 00537 #ifdef BOND_CONSTRAINT 00538 case BONDED_IA_RIGID_BOND: 00539 //add_rigid_bond_pair_force(p1,p2, iaparams, force, force2); 00540 bond_broken = 0; 00541 force[0]=force[1]=force[2]=0.0; 00542 break; 00543 #endif 00544 #ifdef TABULATED 00545 case BONDED_IA_TABULATED: 00546 switch(iaparams->p.tab.type) { 00547 case TAB_BOND_LENGTH: 00548 bond_broken = calc_tab_bond_force(p1, p2, iaparams, dx, force); 00549 break; 00550 case TAB_BOND_ANGLE: 00551 bond_broken = calc_tab_angle_force(p1, p2, p3, iaparams, force, force2); 00552 break; 00553 case TAB_BOND_DIHEDRAL: 00554 bond_broken = calc_tab_dihedral_force(p1, p2, p3, p4, iaparams, force, force2, force3); 00555 break; 00556 default: 00557 errtxt = runtime_error(128 + ES_INTEGER_SPACE); 00558 ERROR_SPRINTF(errtxt,"{081 add_bonded_force: tabulated bond type of atom %d unknown\n", p1->p.identity); 00559 return; 00560 } 00561 break; 00562 #endif 00563 #ifdef OVERLAPPED 00564 case BONDED_IA_OVERLAPPED: 00565 switch(iaparams->p.overlap.type) { 00566 case OVERLAP_BOND_LENGTH: 00567 bond_broken = calc_overlap_bond_force(p1, p2, iaparams, dx, force); 00568 break; 00569 case OVERLAP_BOND_ANGLE: 00570 bond_broken = calc_overlap_angle_force(p1, p2, p3, iaparams, force, force2); 00571 break; 00572 case OVERLAP_BOND_DIHEDRAL: 00573 bond_broken = calc_overlap_dihedral_force(p1, p2, p3, p4, iaparams, force, force2, force3); 00574 break; 00575 default: 00576 errtxt = runtime_error(128 + ES_INTEGER_SPACE); 00577 ERROR_SPRINTF(errtxt,"{081 add_bonded_force: overlapped bond type of atom %d unknown\n", p1->p.identity); 00578 return; 00579 } 00580 break; 00581 #endif 00582 #ifdef BOND_VIRTUAL 00583 case BONDED_IA_VIRTUAL_BOND: 00584 bond_broken = 0; 00585 force[0]=force[1]=force[2]=0.0; 00586 break; 00587 #endif 00588 default : 00589 errtxt = runtime_error(128 + ES_INTEGER_SPACE); 00590 ERROR_SPRINTF(errtxt,"{082 add_bonded_force: bond type of atom %d unknown\n", p1->p.identity); 00591 return; 00592 } 00593 00594 switch (n_partners) { 00595 case 1: 00596 if (bond_broken) { 00597 char *errtext = runtime_error(128 + 2*ES_INTEGER_SPACE); 00598 ERROR_SPRINTF(errtext,"{083 bond broken between particles %d and %d} ", 00599 p1->p.identity, p2->p.identity); 00600 continue; 00601 } 00602 00603 #ifdef ADRESS 00604 force_weight = adress_bonded_force_weight(p1,p2); 00605 #endif 00606 00607 for (j = 0; j < 3; j++) { 00608 #ifdef ADRESS 00609 tmp=force_weight*force[j]; 00610 p1->f.f[j] += tmp; 00611 p2->f.f[j] -= tmp; 00612 #else // ADRESS 00613 00614 switch (type) { 00615 #ifdef BOND_ENDANGLEDIST 00616 case BONDED_IA_ENDANGLEDIST: 00617 p1->f.f[j] += force[j]; 00618 p2->f.f[j] += force2[j]; 00619 break; 00620 #endif // BOND_ENDANGLEDIST 00621 default: 00622 p1->f.f[j] += force[j]; 00623 p2->f.f[j] -= force[j]; 00624 #ifdef ROTATION 00625 p1->f.torque[j] += torque1[j]; 00626 p2->f.torque[j] += torque2[j]; 00627 #endif 00628 } 00629 #endif // NOT ADRESS 00630 00631 #ifdef NPT 00632 if(integ_switch == INTEG_METHOD_NPT_ISO) 00633 nptiso.p_vir[j] += force[j] * dx[j]; 00634 #endif 00635 } 00636 break; 00637 case 2: 00638 if (bond_broken) { 00639 char *errtext = runtime_error(128 + 3*ES_INTEGER_SPACE); 00640 ERROR_SPRINTF(errtext,"{084 bond broken between particles %d, %d and %d} ", 00641 p1->p.identity, p2->p.identity, p3->p.identity); 00642 continue; 00643 } 00644 00645 #ifdef ADRESS 00646 force_weight=adress_angle_force_weight(p1,p2,p3); 00647 #endif 00648 for (j = 0; j < 3; j++) { 00649 #ifdef ADRESS 00650 p1->f.f[j] += force_weight*force[j]; 00651 p2->f.f[j] += force_weight*force2[j]; 00652 p3->f.f[j] -= force_weight*(force[j] + force2[j]); 00653 #else 00654 switch (type) { 00655 case BONDED_IA_AREA_FORCE_LOCAL: 00656 p1->f.f[j] += force[j]; 00657 p2->f.f[j] += force2[j]; 00658 p3->f.f[j] += force3[j]; 00659 break; 00660 #ifdef AREA_FORCE_GLOBAL 00661 case BONDED_IA_AREA_FORCE_GLOBAL: 00662 break; 00663 #endif 00664 #ifdef VOLUME_FORCE 00665 case BONDED_IA_VOLUME_FORCE: 00666 break; 00667 #endif 00668 default: 00669 p1->f.f[j] += force[j]; 00670 p2->f.f[j] += force2[j]; 00671 p3->f.f[j] -= (force[j] + force2[j]); 00672 } 00673 #endif 00674 } 00675 break; 00676 case 3: 00677 if (bond_broken) { 00678 char *errtext = runtime_error(128 + 4*ES_INTEGER_SPACE); 00679 ERROR_SPRINTF(errtext,"{085 bond broken between particles %d, %d, %d and %d} ", 00680 p1->p.identity, p2->p.identity, p3->p.identity, p4->p.identity); 00681 continue; 00682 } 00683 #ifdef ADRESS 00684 force_weight=adress_dihedral_force_weight(p1,p2,p3,p4); 00685 #endif 00686 for (j = 0; j < 3; j++) { 00687 #ifdef ADRESS 00688 p1->f.f[j] += force_weight*force[j]; 00689 p2->f.f[j] += force_weight*force2[j]; 00690 p3->f.f[j] += force_weight*force3[j]; 00691 p4->f.f[j] -= force_weight*(force[j] + force2[j] + force3[j]); 00692 #else 00693 00694 switch (type) { 00695 case BONDED_IA_BENDING_FORCE: 00696 p1->f.f[j] -= (force[j]*0.5+force2[j]*0.5); 00697 p2->f.f[j] += force[j]; 00698 p3->f.f[j] -= (force[j]*0.5+force2[j]*0.5); 00699 p4->f.f[j] += force2[j]; 00700 break; 00701 default: 00702 p1->f.f[j] += force[j]; 00703 p2->f.f[j] += force2[j]; 00704 p3->f.f[j] += force3[j]; 00705 p4->f.f[j] -= (force[j] + force2[j] + force3[j]); 00706 } 00707 00708 #endif 00709 } 00710 break; 00711 } 00712 } 00713 } 00714 00715 /** add force to another. This is used when collecting ghost forces. */ 00716 MDINLINE void add_force(ParticleForce *F_to, ParticleForce *F_add) 00717 { 00718 int i; 00719 for (i = 0; i < 3; i++) 00720 F_to->f[i] += F_add->f[i]; 00721 #ifdef ROTATION 00722 for (i = 0; i < 3; i++) 00723 F_to->torque[i] += F_add->torque[i]; 00724 #endif 00725 } 00726 00727 MDINLINE void check_particle_force(Particle *part) 00728 { 00729 00730 int i; 00731 for (i=0; i< 3; i++) { 00732 if isnan(part->f.f[i]) { 00733 char *errtext = runtime_error(128); 00734 ERROR_SPRINTF(errtext,"{999 force on particle was NAN.} "); 00735 } 00736 } 00737 00738 #ifdef ROTATION 00739 for (i=0; i< 3; i++) { 00740 if isnan(part->f.torque[i]) { 00741 char *errtext = runtime_error(128); 00742 ERROR_SPRINTF(errtext,"{999 force on particle was NAN.} "); 00743 } 00744 } 00745 #endif 00746 } 00747 00748 /*@}*/ 00749 00750 #endif
1.7.5.1