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(); std::size_t und = acname.find("_SCALAR");
113 84 : if( und==std::string::npos ) und = acname.find("_VECTOR");
114 252 : keys.setDisplayName( acname.substr(0,und) ); keys.setValueDescription("scalar/vector","the " + keys.getDisplayName() + " of the atom");
115 84 : }
116 :
117 0 : SelectMassCharge::SelectMassCharge(const ActionOptions&ao):
118 0 : PLUMED_COLVAR_INIT(ao)
119 : {
120 0 : std::vector<AtomNumber> atoms; parseAtomList(-1,atoms,this);
121 0 : unsigned mode=getModeAndSetupValues(this);
122 0 : requestAtoms(atoms);
123 0 : }
124 :
125 0 : void SelectMassCharge::parseAtomList( const int& num, std::vector<AtomNumber>& t, ActionAtomistic* aa ) {
126 0 : aa->parseAtomList("ATOM",num,t);
127 0 : if( t.size()==1 ) aa->log.printf(" for atom %d\n",t[0].serial());
128 0 : else if( num<0 || t.size()!=0 ) aa->error("Number of specified atoms should be 1");
129 0 : }
130 :
131 18 : unsigned SelectMassCharge::getModeAndSetupValues( ActionWithValue* av ) {
132 36 : av->addValueWithDerivatives(); av->setNotPeriodic(); bool constant=true;
133 18 : ActionAtomistic* aa=dynamic_cast<ActionAtomistic*>( av ); plumed_assert( aa );
134 5162 : for(unsigned i=0; i<aa->getNumberOfAtoms(); ++i) {
135 5144 : std::pair<std::size_t,std::size_t> p = aa->getValueIndices( aa->getAbsoluteIndex(i) );
136 5144 : if( av->getName().find("MASS")!=std::string::npos && !aa->masv[p.first]->isConstant() ) constant=false;
137 5144 : if( av->getName().find("CHARGE")!=std::string::npos && !aa->chargev[p.first]->isConstant() ) constant=false;
138 : }
139 18 : if( !constant ) av->error("cannot deal with non-constant " + av->getName() + " values");
140 18 : (av->copyOutput(0))->setConstant();
141 18 : return 0;
142 : }
143 :
144 : // calculator
145 0 : void SelectMassCharge::calculate() {
146 0 : std::vector<double> masses(1), charges(1), vals(1);
147 : std::vector<Vector> pos; std::vector<std::vector<Vector> > derivs; std::vector<Tensor> virial;
148 0 : calculateCV( 0, masses, charges, pos, vals, derivs, virial, this ); setValue( vals[0] );
149 0 : }
150 :
151 5144 : void SelectMassCharge::calculateCV( const unsigned& mode, const std::vector<double>& masses, const std::vector<double>& charges,
152 : const std::vector<Vector>& pos, std::vector<double>& vals, std::vector<std::vector<Vector> >& derivs,
153 : std::vector<Tensor>& virial, const ActionAtomistic* aa ) {
154 5144 : if( aa->getName().find("MASSES")!=std::string::npos ) vals[0]=masses[0];
155 5144 : else if( aa->chargesWereSet ) vals[0]=charges[0];
156 5144 : }
157 :
158 : }
159 : }
160 :
161 :
162 :
|