![]() |
ESPResSo 3.2.0-167-g2c9ead1-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 _LJCOS2_H 00022 #define _LJCOS2_H 00023 00024 /** \file ljcos2.h 00025 * Routines to calculate the lennard-jones with cosine tail energy and/or force 00026 * for a particle pair. Cosine tail is different from that in ljcos.h 00027 * Used for attractive tail/tail interactions in lipid bilayer calculations 00028 * \ref forces.c 00029 */ 00030 00031 #include "utils.h" 00032 #include "interaction_data.h" 00033 #include "particle_data.h" 00034 #include "mol_cut.h" 00035 #include "forcecap.h" 00036 00037 #ifdef LJCOS2 00038 #include <math.h> 00039 00040 int ljcos2_set_params(int part_type_a, int part_type_b, 00041 double eps, double sig, double offset, 00042 double w); 00043 00044 /** Calculate lj-cos2 force between particle p1 and p2 */ 00045 MDINLINE void add_ljcos2_pair_force(Particle *p1, Particle *p2, IA_parameters *ia_params, 00046 double d[3], double dist, double force[3]) 00047 { 00048 int j; 00049 double r_off, frac2, frac6, fac=0.0; 00050 if(CUTOFF_CHECK(dist < ia_params->LJCOS2_cut+ia_params->LJCOS2_offset)) { 00051 r_off = dist - ia_params->LJCOS2_offset; 00052 /* normal case: resulting force/energy smaller than capping. */ 00053 if(r_off > ia_params->LJCOS2_capradius) { 00054 if(r_off < ia_params->LJCOS2_rchange) { 00055 frac2 = SQR(ia_params->LJCOS2_sig/r_off); 00056 frac6 = frac2*frac2*frac2; 00057 fac = 48.0 * ia_params->LJCOS2_eps * frac6*(frac6 - 0.5) / (r_off*dist); 00058 } 00059 else if (r_off< ia_params->LJCOS2_rchange + ia_params->LJCOS2_w) { 00060 fac = -ia_params->LJCOS2_eps*M_PI/2/ia_params->LJCOS2_w/dist * sin(M_PI*(r_off-ia_params->LJCOS2_rchange)/ia_params->LJCOS2_w); 00061 } 00062 00063 for(j=0;j<3;j++) 00064 force[j] += fac * d[j]; 00065 00066 #ifdef LJ_WARN_WHEN_CLOSE 00067 if(fac*dist > 1000) fprintf(stderr,"%d: LJ-Warning: Pair (%d-%d) force=%f dist=%f\n", 00068 this_node,p1->p.identity,p2->p.identity,fac*dist,dist); 00069 #endif 00070 } 00071 /* capped part of lj-cos2 potential. */ 00072 else if(dist > 0.0) { 00073 frac2 = SQR(ia_params->LJCOS2_sig/ia_params->LJCOS2_capradius); 00074 frac6 = frac2*frac2*frac2; 00075 fac = 48.0 * ia_params->LJCOS2_eps * frac6*(frac6 - 0.5) / (ia_params->LJCOS2_capradius * dist); 00076 for(j=0;j<3;j++) 00077 /* vector d is rescaled to length LJCOS2_capradius */ 00078 force[j] += fac * d[j]; 00079 } 00080 /* this should not happen! */ 00081 else { 00082 LJ_TRACE(fprintf(stderr, "%d: Lennard-Jones warning: Particles id1=%d id2=%d exactly on top of each other\n",this_node,p1->p.identity,p2->p.identity)); 00083 00084 frac2 = SQR(ia_params->LJCOS2_sig/ia_params->LJCOS2_capradius); 00085 frac6 = frac2*frac2*frac2; 00086 fac = 48.0 * ia_params->LJCOS2_eps * frac6*(frac6 - 0.5) / ia_params->LJCOS2_capradius; 00087 00088 force[0] += fac * ia_params->LJCOS2_capradius; 00089 } 00090 00091 ONEPART_TRACE(if(p1->p.identity==check_id) fprintf(stderr,"%d: OPT: LJ f = (%.3e,%.3e,%.3e) with part id=%d at dist %f fac %.3e\n",this_node,p1->f.f[0],p1->f.f[1],p1->f.f[2],p2->p.identity,dist,fac)); 00092 ONEPART_TRACE(if(p2->p.identity==check_id) fprintf(stderr,"%d: OPT: LJ f = (%.3e,%.3e,%.3e) with part id=%d at dist %f fac %.3e\n",this_node,p2->f.f[0],p2->f.f[1],p2->f.f[2],p1->p.identity,dist,fac)); 00093 00094 LJ_TRACE(fprintf(stderr,"%d: LJ: Pair (%d-%d) dist=%.3f: force+-: (%.3e,%.3e,%.3e)\n", 00095 this_node,p1->p.identity,p2->p.identity,dist,fac*d[0],fac*d[1],fac*d[2])); 00096 } 00097 } 00098 00099 /** calculate lj-cos2 energy between particle p1 and p2. */ 00100 MDINLINE double ljcos2_pair_energy(Particle *p1, Particle *p2, IA_parameters *ia_params, 00101 double d[3], double dist) 00102 { 00103 double r_off, frac2, frac6; 00104 00105 if(CUTOFF_CHECK(dist < ia_params->LJCOS2_cut+ia_params->LJCOS2_offset)) { 00106 r_off = dist - ia_params->LJCOS2_offset; 00107 /* normal case: resulting force/energy smaller than capping. */ 00108 if(r_off > ia_params->LJCOS2_capradius) { 00109 if (r_off < ia_params->LJCOS2_rchange){ 00110 frac2 = SQR(ia_params->LJCOS2_sig/r_off); 00111 frac6 = frac2*frac2*frac2; 00112 return 4.0*ia_params->LJCOS2_eps*(SQR(frac6)-frac6); 00113 } 00114 else if (r_off < ia_params->LJCOS2_rchange + ia_params->LJCOS2_w){ 00115 return -ia_params->LJCOS2_eps/2 * (cos(M_PI*(r_off-ia_params->LJCOS2_rchange)/ia_params->LJCOS2_w)+1); 00116 } 00117 } 00118 /* capped part of lj-cos2 potential. */ 00119 else if(dist > 0.0) { 00120 frac2 = SQR(ia_params->LJCOS2_sig/ia_params->LJCOS2_capradius); 00121 frac6 = frac2*frac2*frac2; 00122 return 4.0*ia_params->LJCOS2_eps*(SQR(frac6)-frac6); 00123 } 00124 /* this should not happen! */ 00125 else { 00126 frac2 = SQR(ia_params->LJCOS2_sig/ia_params->LJCOS2_capradius); 00127 frac6 = frac2*frac2*frac2; 00128 return 4.0*ia_params->LJCOS2_eps*(SQR(frac6)-frac6); 00129 } 00130 } 00131 return 0.0; 00132 } 00133 00134 /** calculate ljcos2_capradius from force_cap */ 00135 void calc_ljcos2_cap_radii(); 00136 00137 #endif /* ifdef LJCOS2 */ 00138 #endif
1.7.5.1