93 void SwitchingFunction::registerKeywords(
Keywords& keys ){
94 keys.
add(
"compulsory",
"R_0",
"the value of R_0 in the switching function");
95 keys.
add(
"compulsory",
"D_0",
"0.0",
"the value of D_0 in the switching function");
96 keys.
add(
"optional",
"D_MAX",
"the value at which the switching function can be assumed equal to zero");
97 keys.
add(
"compulsory",
"NN",
"6",
"the value of n in the switching function (only needed for TYPE=RATIONAL)");
98 keys.
add(
"compulsory",
"MM",
"12",
"the value of m in the switching function (only needed for TYPE=RATIONAL)");
99 keys.
add(
"compulsory",
"A",
"the value of a in the switching funciton (only needed for TYPE=SMAP)");
100 keys.
add(
"compulsory",
"B",
"the value of b in the switching funciton (only needed for TYPE=SMAP)");
103 void SwitchingFunction::set(
const std::string & definition,std::string& errormsg){
104 vector<string> data=Tools::getWords(definition);
105 if( data.size()<1 ) errormsg=
"missing all input for switching function";
107 data.erase(data.begin());
110 dmax=std::numeric_limits<double>::max();
114 bool found_r0=Tools::parse(data,
"R_0",r0);
115 if(!found_r0) errormsg=
"R_0 is required";
117 Tools::parse(data,
"D_0",d0);
118 Tools::parse(data,
"D_MAX",dmax);
120 if(name==
"RATIONAL"){
124 Tools::parse(data,
"NN",nn);
125 Tools::parse(data,
"MM",mm);
126 }
else if(name==
"SMAP"){
128 Tools::parse(data,
"A",
a);
129 Tools::parse(data,
"B",b);
130 c=pow(2., static_cast<double>(
a)/static_cast<double>(b) ) - 1;
131 d = -
static_cast<double>(b) / static_cast<double>(
a);
132 }
else if(name==
"EXP") type=exponential;
133 else if(name==
"GAUSSIAN") type=gaussian;
134 else errormsg=
"cannot understand switching function type '"+name+
"'";
136 errormsg=
"found the following rogue keywords in switching function input : ";
137 for(
unsigned i=0;i<data.size();++i) errormsg = errormsg + data[i] +
" ";
141 std::string SwitchingFunction::description()
const {
142 std::ostringstream ostr;
143 ostr<<1./invr0<<
". Using ";
146 }
else if(type==exponential){
148 }
else if(type==gaussian){
150 }
else if(type==smap){
153 plumed_merror(
"Unknown switching function type");
155 ostr<<
" swiching function with parameters d0="<<d0;
157 ostr<<
" nn="<<nn<<
" mm="<<mm;
158 }
else if(type==smap){
159 ostr<<
" a="<<
a<<
" b="<<b;
164 double SwitchingFunction::calculate(
double distance,
double&dfunc)
const{
165 plumed_massert(init,
"you are trying to use an unset SwitchingFunction");
170 const double rdist = (distance-d0)*invr0;
177 double sx=c*pow( rdist,
a );
178 result=pow( 1.0 + sx, d );
179 dfunc=-b*sx/rdist*result/(1.0+sx);
180 }
else if(type==spline){
183 double rNdist=Tools::fastpow(rdist,nn-1);
184 double iden=1.0/(1+rNdist*rdist);
185 dfunc = -nn*rNdist*iden*iden;
190 dfunc=0.5*nn*(nn-mm)/mm;
192 double rNdist=Tools::fastpow(rdist,nn-1);
193 double rMdist=Tools::fastpow(rdist,mm-1);
194 double num = 1.-rNdist*rdist;
195 double iden = 1./(1.-rMdist*rdist);
196 double func = num*iden;
198 dfunc = ((-nn*rNdist*iden)+(func*(iden*mm)*rMdist));
201 }
else if(type==exponential){
204 }
else if(type==gaussian){
205 result=exp(-0.5*rdist*rdist);
207 }
else plumed_merror(
"Unknown switching function type");
217 SwitchingFunction::SwitchingFunction():
235 this->
dmax=d0+r0*pow(0.00001,1./(nn-mm));
void set(int nn, int mm, double r_0, double d_0)
void add(const std::string &t, const std::string &k, const std::string &d)
Add a new keyword of type t with name k and description d.
This class holds the keywords and their documentation.
enum PLMD::SwitchingFunction::@7 type