LCOV - code coverage report
Current view: top level - ves - FermiSwitchingFunction.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 33 67 49.3 %
Date: 2024-10-11 08:09:47 Functions: 4 9 44.4 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2016-2021 The VES code team
       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
       4             : 
       5             :    See http://www.ves-code.org for more information.
       6             : 
       7             :    This file is part of VES code module.
       8             : 
       9             :    The VES code module is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    The VES code module is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : 
      23             : #include "FermiSwitchingFunction.h"
      24             : 
      25             : #include "tools/Tools.h"
      26             : #include "tools/Keywords.h"
      27             : 
      28             : #include <vector>
      29             : #include <limits>
      30             : 
      31             : 
      32             : namespace PLMD {
      33             : namespace ves {
      34             : 
      35             : 
      36           0 : void FermiSwitchingFunction::registerKeywords( Keywords& keys ) {
      37           0 :   keys.add("compulsory","R_0","the value of R_0 in the switching function");
      38           0 :   keys.add("compulsory","FERMI_LAMBDA","the value of lambda in the Fermi-type switching function (only needed for TYPE=FERMI).");
      39           0 :   keys.add("optional","FERMI_EXP_MAX","only needed for TYPE=FERMI");
      40           0 : }
      41             : 
      42           3 : void FermiSwitchingFunction::set(const std::string& definition,std::string& errormsg) {
      43           3 :   std::vector<std::string> data=Tools::getWords(definition);
      44           3 :   if( data.size()<1 ) {
      45             :     errormsg="missing all input for switching function";
      46             :     return;
      47             :   }
      48           3 :   std::string name=data[0];
      49             :   data.erase(data.begin());
      50           3 :   if(name!="FERMI") {errormsg="only FERMI is supported";}
      51           3 :   type=fermi;
      52             :   //
      53           3 :   bool found_r0=Tools::parse(data,"R_0",r0_);
      54           3 :   if(!found_r0) {errormsg="R_0 is required";}
      55             : 
      56             :   //
      57           3 :   fermi_exp_max_=std::numeric_limits<double>::max();
      58           3 :   Tools::parse(data,"FERMI_EXP_MAX",fermi_exp_max_);
      59             :   //
      60           3 :   bool found_lambda=Tools::parse(data,"FERMI_LAMBDA",fermi_lambda_);
      61           3 :   if(!found_lambda) {errormsg="FERMI_LAMBDA is required for FERMI";}
      62           3 :   if( !data.empty() ) {
      63             :     errormsg="found the following rogue keywords in switching function input : ";
      64           0 :     for(unsigned i=0; i<data.size(); ++i) errormsg = errormsg + data[i] + " ";
      65             :   }
      66           3 :   init=true;
      67           3 :   if(errormsg.size()>0) {init=false;}
      68           3 : }
      69             : 
      70           0 : std::string FermiSwitchingFunction::description() const {
      71           0 :   std::ostringstream ostr;
      72           0 :   ostr<<1./invr0_<<".  Using ";
      73           0 :   if(type==fermi) {
      74           0 :     ostr<< "fermi switching function with parameter";
      75           0 :     ostr<< " lambda="<<fermi_lambda_;
      76             :   }
      77             :   else {
      78           0 :     plumed_merror("Unknown switching function type");
      79             :   }
      80           0 :   return ostr.str();
      81           0 : }
      82             : 
      83             : 
      84        3263 : double FermiSwitchingFunction::calculate(double distance, double& dfunc) const {
      85        3263 :   plumed_massert(init,"you are trying to use an unset FermiSwitchingFunction");
      86        3263 :   double rdist=fermi_lambda_*(distance-r0_);
      87        3263 :   if(rdist >= fermi_exp_max_) {rdist = fermi_exp_max_;}
      88        3263 :   double result = 1.0/(1.0+exp(rdist));
      89        3263 :   dfunc=-fermi_lambda_*exp(rdist)*result*result;
      90             :   // this is because calculate() sets dfunc to the derivative divided times the distance.
      91             :   // (I think this is misleading and I would like to modify it - GB)
      92             :   // dfunc/=distance;
      93             :   //
      94        3263 :   return result;
      95             : }
      96             : 
      97             : 
      98           3 : FermiSwitchingFunction::FermiSwitchingFunction():
      99           3 :   init(false),
     100           3 :   type(fermi),
     101           3 :   r0_(0.0),
     102           3 :   invr0_(0.0),
     103           3 :   fermi_lambda_(1.0),
     104           3 :   fermi_exp_max_(100.0)
     105             : {
     106           3 : }
     107             : 
     108           0 : FermiSwitchingFunction::FermiSwitchingFunction(const FermiSwitchingFunction&sf):
     109           0 :   init(sf.init),
     110           0 :   type(sf.type),
     111           0 :   r0_(sf.r0_),
     112           0 :   invr0_(sf.invr0_),
     113           0 :   fermi_lambda_(sf.fermi_lambda_),
     114           0 :   fermi_exp_max_(sf.fermi_exp_max_)
     115             : {
     116           0 : }
     117             : 
     118           0 : void FermiSwitchingFunction::set(const double r0, const double fermi_lambda, const double fermi_exp_max) {
     119           0 :   init=true;
     120           0 :   type=fermi;
     121           0 :   r0_=r0;
     122           0 :   fermi_lambda_=fermi_lambda;
     123           0 :   if(fermi_exp_max>0.0) {
     124           0 :     fermi_exp_max_=fermi_exp_max;
     125             :   }
     126             :   else {
     127           0 :     fermi_exp_max_=100.0;
     128             :   }
     129             : 
     130           0 : }
     131             : 
     132           0 : double FermiSwitchingFunction::get_r0() const {
     133           0 :   return r0_;
     134             : }
     135             : 
     136             : 
     137           3 : FermiSwitchingFunction::~FermiSwitchingFunction() {
     138           3 : }
     139             : 
     140             : 
     141             : }
     142             : }

Generated by: LCOV version 1.15