Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2014-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/ActionAtomistic.h" 23 : #include "core/ActionWithValue.h" 24 : #include "core/ActionRegister.h" 25 : 26 : //+PLUMEDOC MCOLVAR CHARGE 27 : /* 28 : Get the charges of one or multiple atoms 29 : 30 : The following example shows how you can print the charge of atom one: 31 : 32 : ```plumed 33 : q: CHARGE ATOMS=1 34 : PRINT ARG=q FILE=colvar 35 : ``` 36 : 37 : If you want to output the charges of multiple atoms you would use an input similar to the one below: 38 : 39 : ```plumed 40 : q: CHARGE ATOMS=1-10 41 : PRINT ARG=q FILE=colvar 42 : ``` 43 : 44 : This input outputs a 10 dimensional vector that contains the charges of the first 10 atoms. 45 : 46 : */ 47 : //+ENDPLUMEDOC 48 : 49 : //+PLUMEDOC MCOLVAR MASS 50 : /* 51 : Get the mass of one or multiple atoms 52 : 53 : The following example shows how you can print the mass of atom one: 54 : 55 : ```plumed 56 : m: MASS ATOMS=1 57 : PRINT ARG=m FILE=colvar 58 : ``` 59 : 60 : If you want to output the masses of multiple atoms you would use an input similar to the one below: 61 : 62 : ```plumed 63 : m: MASS ATOMS=1-10 64 : PRINT ARG=m FILE=colvar 65 : ``` 66 : 67 : This input outputs a 10 dimensional vector that contains the masses of the first 10 atoms. 68 : 69 : */ 70 : //+ENDPLUMEDOC 71 : 72 : namespace PLMD { 73 : namespace colvar { 74 : 75 : class SelectMassCharge : 76 : public ActionAtomistic, 77 : public ActionWithValue { 78 : public: 79 : static void registerKeywords( Keywords& keys ); 80 : explicit SelectMassCharge(const ActionOptions&); 81 : // active methods: 82 36 : unsigned getNumberOfDerivatives() override { 83 36 : return 0; 84 : } 85 : void calculate() override; 86 18 : void apply() override {} 87 : }; 88 : 89 : PLUMED_REGISTER_ACTION(SelectMassCharge,"MASS") 90 : PLUMED_REGISTER_ACTION(SelectMassCharge,"CHARGE") 91 : 92 40 : void SelectMassCharge::registerKeywords( Keywords& keys ) { 93 40 : Action::registerKeywords( keys ); 94 40 : ActionAtomistic::registerKeywords( keys ); 95 40 : ActionWithValue::registerKeywords( keys ); 96 40 : keys.add("atoms","ATOMS","the atom numbers that you would like to store the masses and charges of"); 97 40 : keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log"); 98 40 : keys.remove("NUMERICAL_DERIVATIVES"); 99 80 : keys.setValueDescription("scalar/vector","the " + keys.getDisplayName() + " of the atom/s"); 100 40 : } 101 : 102 18 : SelectMassCharge::SelectMassCharge(const ActionOptions&ao): 103 : Action(ao), 104 : ActionAtomistic(ao), 105 18 : ActionWithValue(ao) { 106 : std::vector<AtomNumber> atoms; 107 18 : parseAtomList("ATOMS",atoms); 108 18 : log.printf(" getting %s of atoms : ", getName().c_str() ); 109 5162 : for(unsigned i=0; i<atoms.size(); ++i) { 110 5144 : std::pair<std::size_t,std::size_t> p = getValueIndices( atoms[i] ); 111 5144 : if( getName()=="MASS" && !masv[p.first]->isConstant() ) { 112 0 : error("cannot deal with non-constant " + getName() + " values"); 113 : } 114 5144 : if( getName()=="CHARGE" && !chargev[p.first]->isConstant() ) { 115 0 : error("cannot deal with non-constant " + getName() + " values"); 116 : } 117 5144 : log.printf("%d ", atoms[i].serial() ); 118 : } 119 18 : log.printf("\n"); 120 18 : requestAtoms(atoms); 121 18 : std::vector<std::size_t> shape(1); 122 18 : if(atoms.size()==1) { 123 0 : shape.resize(0); 124 : } else { 125 18 : shape[0] = atoms.size(); 126 : } 127 18 : addValue( shape ); 128 18 : setNotPeriodic(); 129 18 : getPntrToComponent(0)->setConstant(); 130 18 : } 131 : 132 : // calculator 133 18 : void SelectMassCharge::calculate() { 134 18 : Value* myval = getPntrToComponent(0); 135 18 : if( getName()=="CHARGES" ) { 136 0 : if( !chargesWereSet ) { 137 0 : error("cannot determine charges are charges were not set"); 138 : } 139 0 : for(unsigned i=0; i<getNumberOfAtoms(); ++i) { 140 0 : myval->set( i, getCharge(i) ); 141 : } 142 : } else { 143 5162 : for(unsigned i=0; i<getNumberOfAtoms(); ++i) { 144 5144 : myval->set( i, getMass(i) ); 145 : } 146 : } 147 18 : } 148 : 149 : } 150 : } 151 : 152 : 153 :