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 "Colvar.h"
23 : #include "ColvarShortcut.h"
24 : #include "core/ActionRegister.h"
25 : #include "MultiColvarTemplate.h"
26 : #include "tools/Pbc.h"
27 :
28 : //+PLUMEDOC MCOLVAR CHARGE
29 : /*
30 : Get the charges of one or multiple atoms
31 :
32 : \par Examples
33 :
34 : */
35 : //+ENDPLUMEDOC
36 :
37 : //+PLUMEDOC MCOLVAR CHARGE_SCALAR
38 : /*
39 : Get the charges of one or multiple atoms
40 :
41 : \par Examples
42 :
43 : */
44 : //+ENDPLUMEDOC
45 :
46 : //+PLUMEDOC MCOLVAR CHARGE_VECTOR
47 : /*
48 : Get the charges of one or multiple atoms
49 :
50 : \par Examples
51 :
52 : */
53 : //+ENDPLUMEDOC
54 :
55 : //+PLUMEDOC MCOLVAR MASS
56 : /*
57 : Get the mass of one or multiple atoms
58 :
59 : \par Examples
60 :
61 : */
62 : //+ENDPLUMEDOC
63 :
64 : //+PLUMEDOC MCOLVAR MASS_SCALAR
65 : /*
66 : Get the mass of one or multiple atoms
67 :
68 : \par Examples
69 :
70 : */
71 : //+ENDPLUMEDOC
72 :
73 : //+PLUMEDOC MCOLVAR MASS_VECTOR
74 : /*
75 : Get the mass of one or multiple atoms
76 :
77 : \par Examples
78 :
79 : */
80 : //+ENDPLUMEDOC
81 :
82 : namespace PLMD {
83 : namespace colvar {
84 :
85 : class SelectMassCharge : public Colvar {
86 : public:
87 : static void registerKeywords( Keywords& keys );
88 : explicit SelectMassCharge(const ActionOptions&);
89 : static void parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa );
90 : static unsigned getModeAndSetupValues( ActionWithValue* av );
91 : // active methods:
92 : void calculate() override;
93 : static void calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
94 : const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
95 : std::vector<Tensor>& virial, const ActionAtomistic* aa );
96 : };
97 :
98 : typedef ColvarShortcut<SelectMassCharge> MQShortcut;
99 : PLUMED_REGISTER_ACTION(MQShortcut,"MASS")
100 : PLUMED_REGISTER_ACTION(MQShortcut,"CHARGE")
101 : PLUMED_REGISTER_ACTION(SelectMassCharge,"MASS_SCALAR")
102 : PLUMED_REGISTER_ACTION(SelectMassCharge,"CHARGE_SCALAR")
103 : typedef MultiColvarTemplate<SelectMassCharge> MQMulti;
104 : PLUMED_REGISTER_ACTION(MQMulti,"MASS_VECTOR")
105 : PLUMED_REGISTER_ACTION(MQMulti,"CHARGE_VECTOR")
106 :
107 84 : void SelectMassCharge::registerKeywords( Keywords& keys ) {
108 84 : Colvar::registerKeywords( keys );
109 168 : keys.add("atoms","ATOM","the atom number");
110 168 : keys.add("atoms","ATOMS","the atom numbers that you would like to store the masses and charges of");
111 168 : keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
112 84 : std::string acname = keys.getDisplayName();
113 84 : std::size_t und = acname.find("_SCALAR");
114 84 : if( und==std::string::npos ) {
115 80 : und = acname.find("_VECTOR");
116 : }
117 84 : keys.setDisplayName( acname.substr(0,und) );
118 168 : keys.setValueDescription("the " + keys.getDisplayName() + " of the atom");
119 84 : }
120 :
121 0 : SelectMassCharge::SelectMassCharge(const ActionOptions&ao):
122 0 : PLUMED_COLVAR_INIT(ao) {
123 : std::vector<AtomNumber> atoms;
124 0 : parseAtomList(-1,atoms,this);
125 0 : unsigned mode=getModeAndSetupValues(this);
126 0 : requestAtoms(atoms);
127 0 : }
128 :
129 0 : void SelectMassCharge::parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa ) {
130 0 : aa->parseAtomList("ATOM",num,t);
131 0 : if( t.size()==1 ) {
132 0 : aa->log.printf(" for atom %d\n",t[0].serial());
133 0 : } else if( num<0 || t.size()!=0 ) {
134 0 : aa->error("Number of specified atoms should be 1");
135 : }
136 0 : }
137 :
138 18 : unsigned SelectMassCharge::getModeAndSetupValues( ActionWithValue* av ) {
139 18 : av->addValueWithDerivatives();
140 18 : av->setNotPeriodic();
141 : bool constant=true;
142 18 : ActionAtomistic* aa=dynamic_cast<ActionAtomistic*>( av );
143 18 : plumed_assert( aa );
144 5162 : for(unsigned i=0; i<aa->getNumberOfAtoms(); ++i) {
145 5144 : std::pair<std::size_t,std::size_t> p = aa->getValueIndices( aa->getAbsoluteIndex(i) );
146 5144 : if( av->getName().find("MASS")!=std::string::npos && !aa->masv[p.first]->isConstant() ) {
147 : constant=false;
148 : }
149 5144 : if( av->getName().find("CHARGE")!=std::string::npos && !aa->chargev[p.first]->isConstant() ) {
150 : constant=false;
151 : }
152 : }
153 18 : if( !constant ) {
154 0 : av->error("cannot deal with non-constant " + av->getName() + " values");
155 : }
156 18 : (av->copyOutput(0))->setConstant();
157 18 : return 0;
158 : }
159 :
160 : // calculator
161 0 : void SelectMassCharge::calculate() {
162 0 : std::vector<double> masses(1), charges(1), vals(1);
163 : std::vector<Vector> pos;
164 : std::vector<std::vector<Vector> > derivs;
165 : std::vector<Tensor> virial;
166 0 : calculateCV( 0, masses, charges, pos, vals, derivs, virial, this );
167 0 : setValue( vals[0] );
168 0 : }
169 :
170 5144 : void SelectMassCharge::calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
171 : const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
172 : std::vector<Tensor>& virial, const ActionAtomistic* aa ) {
173 5144 : if( aa->getName().find("MASSES")!=std::string::npos ) {
174 0 : vals[0]=masses[0];
175 5144 : } else if( aa->chargesWereSet ) {
176 5144 : vals[0]=charges[0];
177 : }
178 5144 : }
179 :
180 : }
181 : }
182 :
183 :
184 :
|