Example #1
0
double SwitchingFunction::calculate(double distance,double&dfunc)const{
  plumed_massert(init,"you are trying to use an unset SwitchingFunction");
  if(distance>dmax){
    dfunc=0.0;
    return 0.0;
  }
  const double rdist = (distance-d0)*invr0;
  double result;

  if(rdist<=0.){
     result=1.;
     dfunc=0.0;
  }else{
    if(type==smap){
      double sx=c*pow( rdist, a ); 
      result=pow( 1.0 + sx, d ); 
      dfunc=-b*sx/rdist*result/(1.0+sx); 
    } else if(type==rational){
      result=do_rational(rdist,dfunc,nn,mm);
    }else if(type==exponential){
      result=exp(-rdist);
      dfunc=-result;
    }else if(type==nativeq){
      double rdist2 = beta*(distance - lambda * ref);
      double exprdist=exp(rdist2);
      result=1./(1.+exprdist);
      dfunc=-exprdist/(1.+exprdist)/(1.+exprdist);
    }else if(type==gaussian){
      result=exp(-0.5*rdist*rdist);
      dfunc=-rdist*result;
    }else if(type==cubic){
      double tmp1=rdist-1, tmp2=(1+2*rdist);
      result=tmp1*tmp1*tmp2;
      dfunc=2*tmp1*tmp2 + 2*tmp1*tmp1;
    }else if(type==tanh){
      double tmp1=std::tanh(rdist);
      result = 1.0 - tmp1;
      dfunc=-(1-tmp1*tmp1);
#ifdef __PLUMED_HAS_MATHEVAL
    }else if(type==matheval){
      result=evaluator_evaluate_x(evaluator,rdist);
      dfunc=evaluator_evaluate_x(evaluator_deriv,rdist);
#endif
    }else plumed_merror("Unknown switching function type");
// this is for the chain rule:
    dfunc*=invr0;
// this is because calculate() sets dfunc to the derivative divided times the distance.
// (I think this is misleading and I would like to modify it - GB)
    dfunc/=distance;
  }

  result=result*stretch+shift;
  dfunc*=stretch;

  return result;
}
Example #2
0
double SwitchingFunction::calculateSqr(double distance2,double&dfunc)const{
  if(type==rational && nn%2==0 && mm%2==0 && d0==0.0){
    if(distance2>dmax_2){
      dfunc=0.0;
      return 0.0;
    }
    const double rdist_2 = distance2*invr0_2;
    double result=do_rational(rdist_2,dfunc,nn/2,mm/2);
// chain rule:
    dfunc*=2*invr0_2;
// stretch:
    result=result*stretch+shift;
    dfunc*=stretch;
    return result;
  } else {
    double distance=std::sqrt(distance2);
    return calculate(distance,dfunc);
  }
}
Example #3
0
double SwitchingFunction::calculate(double distance,double&dfunc)const{
  plumed_massert(init,"you are trying to use an unset SwitchingFunction");
  if(distance>dmax){
    dfunc=0.0;
    return 0.0;
  }
  const double rdist = (distance-d0)*invr0;
  double result;
  if(rdist<=0.){
     result=1.;
     dfunc=0.0;
  }else{
    if(type==smap){
      double sx=c*pow( rdist, a ); 
      result=pow( 1.0 + sx, d ); 
      dfunc=-b*sx/rdist*result/(1.0+sx); 
    } else if(type==rational){
      result=do_rational(rdist,dfunc,nn,mm);
    }else if(type==exponential){
      result=exp(-rdist);
      dfunc=-result;
    }else if(type==gaussian){
      result=exp(-0.5*rdist*rdist);
      dfunc=-rdist*result;
    }else plumed_merror("Unknown switching function type");
// this is for the chain rule:
    dfunc*=invr0;
// this is because calculate() sets dfunc to the derivative divided times the distance.
// (I think this is misleading and I would like to modify it - GB)
    dfunc/=distance;
  }

  result=result*stretch+shift;
  dfunc*=stretch;

  return result;
}