Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2016-2018 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 6 : std::vector<std::string> data=Tools::getWords(definition);
44 3 : if( data.size()<1 ) {
45 : errormsg="missing all input for switching function";
46 0 : return;
47 : }
48 : 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 6 : 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 6 : Tools::parse(data,"FERMI_EXP_MAX",fermi_exp_max_);
59 : //
60 6 : 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 : }
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 : }
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 : init(false),
100 : type(fermi),
101 : r0_(0.0),
102 : invr0_(0.0),
103 : 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 : }
|