Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2013-2023 The plumed team 3 : (see the PEOPLE file at the root of the distribution for a list of names) 4 : 5 : See http://www.plumed.org for more information. 6 : 7 : This file is part of plumed, version 2. 8 : 9 : plumed 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 : plumed 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 plumed. If not, see <http://www.gnu.org/licenses/>. 21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 22 : #include "core/ActionShortcut.h" 23 : #include "core/ActionWithValue.h" 24 : #include "core/ActionRegister.h" 25 : #include "core/PlumedMain.h" 26 : #include "core/ActionSet.h" 27 : #include <string> 28 : #include <cmath> 29 : 30 : //+PLUMEDOC MCOLVAR ALPHABETA 31 : /* 32 : Calculate the alpha beta CV 33 : 34 : \par Examples 35 : 36 : 37 : */ 38 : //+ENDPLUMEDOC 39 : 40 : namespace PLMD { 41 : namespace multicolvar { 42 : 43 : class AlphaBeta : public ActionShortcut { 44 : public: 45 : static void registerKeywords(Keywords& keys); 46 : explicit AlphaBeta(const ActionOptions&); 47 : }; 48 : 49 : PLUMED_REGISTER_ACTION(AlphaBeta,"ALPHABETA") 50 : 51 4 : void AlphaBeta::registerKeywords(Keywords& keys) { 52 4 : ActionShortcut::registerKeywords( keys ); 53 8 : keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances"); 54 8 : keys.add("numbered","ATOMS","the atoms involved for each of the torsions you wish to calculate. " 55 : "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one torsion will be " 56 : "calculated for each ATOM keyword you specify"); 57 8 : keys.reset_style("ATOMS","atoms"); 58 8 : keys.add("numbered","REFERENCE","the reference values for each of the torsional angles. If you use a single REFERENCE value the " 59 : "same reference value is used for all torsions"); 60 8 : keys.add("numbered","COEFFICIENT","the coefficient for each of the torsional angles. If you use a single COEFFICIENT value the " 61 : "same reference value is used for all torsional angles"); 62 8 : keys.setValueDescription("scalar","the alpha beta CV"); 63 20 : keys.needsAction("CONSTANT"); keys.needsAction("TORSION"); keys.needsAction("COMBINE"); keys.needsAction("CUSTOM"); keys.needsAction("SUM"); 64 4 : } 65 : 66 2 : AlphaBeta::AlphaBeta(const ActionOptions& ao): 67 : Action(ao), 68 2 : ActionShortcut(ao) 69 : { 70 : // Read in the reference value 71 4 : std::string refstr; parse("REFERENCE",refstr); unsigned nref=0; 72 2 : if( refstr.length()==0 ) { 73 : for(unsigned i=0;; ++i) { 74 : std::string refval; 75 18 : if( !parseNumbered( "REFERENCE", i+1, refval ) ) break; 76 15 : if( i==0 ) refstr = refval; else refstr += "," + refval; 77 8 : nref++; 78 8 : } 79 : } 80 4 : std::string coeffstr; parse("COEFFICIENT",coeffstr); unsigned ncoeff=0; 81 2 : if( coeffstr.length()==0 ) { 82 : for(unsigned i=0;; ++i) { 83 : std::string coeff; 84 4 : if( !parseNumbered( "COEFFICIENT", i+1, coeff) ) break; 85 0 : if( i==0 ) coeffstr = coeff; else coeffstr += "," + coeff; 86 0 : ncoeff++; 87 0 : } 88 : } 89 2 : if( coeffstr.length()==0 ) coeffstr="1"; 90 : // Calculate angles 91 4 : readInputLine( getShortcutLabel() + "_torsions: TORSION " + convertInputLineToString() ); 92 2 : ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_torsions" ); 93 2 : plumed_assert( av && (av->copyOutput(0))->getRank()==1 ); 94 2 : if( nref==0 ) { 95 8 : std::string refval=refstr; for(unsigned i=1; i<(av->copyOutput(0))->getShape()[0]; ++i) refstr += "," + refval; 96 1 : } else if( nref!=(av->copyOutput(0))->getShape()[0] ) error("mismatch between number of reference values and number of ATOMS specified"); 97 2 : if( ncoeff==0 ) { 98 16 : std::string coeff=coeffstr; for(unsigned i=1; i<(av->copyOutput(0))->getShape()[0]; ++i) coeffstr += "," + coeff; 99 0 : } else if( ncoeff!=(av->copyOutput(0))->getShape()[0] ) error("mismatch between number of coefficients and number of ATOMS specified"); 100 4 : readInputLine( getShortcutLabel() + "_ref: CONSTANT VALUES=" + refstr ); 101 4 : readInputLine( getShortcutLabel() + "_coeff: CONSTANT VALUES=" + coeffstr ); 102 : // Caculate difference from reference using combine 103 4 : readInputLine( getShortcutLabel() + "_comb: COMBINE ARG=" + getShortcutLabel() + "_torsions," + getShortcutLabel() + "_ref COEFFICIENTS=1,-1 PERIODIC=NO" ); 104 : // Now matheval for cosine bit 105 4 : readInputLine( getShortcutLabel() + "_cos: CUSTOM ARG=" + getShortcutLabel() + "_comb," + getShortcutLabel() + "_coeff FUNC=y*(0.5+0.5*cos(x)) PERIODIC=NO"); 106 : // And combine to get final value 107 4 : readInputLine( getShortcutLabel() + ": SUM ARG=" + getShortcutLabel() + "_cos PERIODIC=NO"); 108 2 : } 109 : 110 : } 111 : }