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 4 : keys.setValueDescription("the alpha beta CV"); 63 4 : keys.needsAction("CONSTANT"); 64 4 : keys.needsAction("TORSION"); 65 4 : keys.needsAction("COMBINE"); 66 4 : keys.needsAction("CUSTOM"); 67 4 : keys.needsAction("SUM"); 68 4 : } 69 : 70 2 : AlphaBeta::AlphaBeta(const ActionOptions& ao): 71 : Action(ao), 72 2 : ActionShortcut(ao) { 73 : // Read in the reference value 74 : std::string refstr; 75 4 : parse("REFERENCE",refstr); 76 : unsigned nref=0; 77 2 : if( refstr.length()==0 ) { 78 : for(unsigned i=0;; ++i) { 79 : std::string refval; 80 18 : if( !parseNumbered( "REFERENCE", i+1, refval ) ) { 81 : break; 82 : } 83 8 : if( i==0 ) { 84 : refstr = refval; 85 : } else { 86 14 : refstr += "," + refval; 87 : } 88 8 : nref++; 89 8 : } 90 : } 91 : std::string coeffstr; 92 4 : parse("COEFFICIENT",coeffstr); 93 : unsigned ncoeff=0; 94 2 : if( coeffstr.length()==0 ) { 95 : for(unsigned i=0;; ++i) { 96 : std::string coeff; 97 4 : if( !parseNumbered( "COEFFICIENT", i+1, coeff) ) { 98 : break; 99 : } 100 0 : if( i==0 ) { 101 : coeffstr = coeff; 102 : } else { 103 0 : coeffstr += "," + coeff; 104 : } 105 0 : ncoeff++; 106 0 : } 107 : } 108 2 : if( coeffstr.length()==0 ) { 109 : coeffstr="1"; 110 : } 111 : // Calculate angles 112 4 : readInputLine( getShortcutLabel() + "_torsions: TORSION " + convertInputLineToString() ); 113 2 : ActionWithValue* av = plumed.getActionSet().selectWithLabel<ActionWithValue*>( getShortcutLabel() + "_torsions" ); 114 2 : plumed_assert( av && (av->copyOutput(0))->getRank()==1 ); 115 2 : if( nref==0 ) { 116 1 : std::string refval=refstr; 117 8 : for(unsigned i=1; i<(av->copyOutput(0))->getShape()[0]; ++i) { 118 14 : refstr += "," + refval; 119 : } 120 1 : } else if( nref!=(av->copyOutput(0))->getShape()[0] ) { 121 0 : error("mismatch between number of reference values and number of ATOMS specified"); 122 : } 123 2 : if( ncoeff==0 ) { 124 2 : std::string coeff=coeffstr; 125 16 : for(unsigned i=1; i<(av->copyOutput(0))->getShape()[0]; ++i) { 126 28 : coeffstr += "," + coeff; 127 : } 128 0 : } else if( ncoeff!=(av->copyOutput(0))->getShape()[0] ) { 129 0 : error("mismatch between number of coefficients and number of ATOMS specified"); 130 : } 131 4 : readInputLine( getShortcutLabel() + "_ref: CONSTANT VALUES=" + refstr ); 132 4 : readInputLine( getShortcutLabel() + "_coeff: CONSTANT VALUES=" + coeffstr ); 133 : // Caculate difference from reference using combine 134 4 : readInputLine( getShortcutLabel() + "_comb: COMBINE ARG=" + getShortcutLabel() + "_torsions," + getShortcutLabel() + "_ref COEFFICIENTS=1,-1 PERIODIC=NO" ); 135 : // Now matheval for cosine bit 136 4 : readInputLine( getShortcutLabel() + "_cos: CUSTOM ARG=" + getShortcutLabel() + "_comb," + getShortcutLabel() + "_coeff FUNC=y*(0.5+0.5*cos(x)) PERIODIC=NO"); 137 : // And combine to get final value 138 4 : readInputLine( getShortcutLabel() + ": SUM ARG=" + getShortcutLabel() + "_cos PERIODIC=NO"); 139 2 : } 140 : 141 : } 142 : }