1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 Copyright (c) 2014-2021 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 #ifndef __PLUMED_multicolvar_AtomValuePack_h
23 #define __PLUMED_multicolvar_AtomValuePack_h
24
25 #include "tools/MultiValue.h"
26 #include "MultiColvarBase.h"
27
28 namespace PLMD {
29
30 class LinkCells;
31
32 namespace multicolvar {
33
34 class CatomPack;
35
36 class AtomValuePack {
37 friend class MultiColvarBase;
38 friend class LocalAverage;
39 private:
40 /// Copy of the values that we are adding to
41 MultiValue& myvals;
42 /// Copy of the underlying multicolvar
43 MultiColvarBase const * mycolv;
44 /// Number of atoms at the moment
45 unsigned natoms;
46 /// Atom indices
47 std::vector<unsigned>& indices;
48 /// This is used to sort the atom indices
49 std::vector<unsigned>& sort_vector;
50 /// This holds atom positions
51 std::vector<Vector>& myatoms;
52 /// This is stuff for link cells
53 std::vector<unsigned> cells_required;
54 ///
55 void addAtomsDerivatives( const unsigned&, const unsigned&, const Vector& );
56 ///
57 void addTemporyAtomsDerivatives( const unsigned& jder, const Vector& der );
58 public:
59 AtomValuePack( MultiValue& vals, MultiColvarBase const * mcolv );
60 /// Set the number of atoms
61 void setNumberOfAtoms( const unsigned& );
62 /// Set the index for one of the atoms
63 void setIndex( const unsigned&, const unsigned& );
64 ///
65 void setAtomIndex( const unsigned& j, const unsigned& ind );
66 ///
67 void setAtom( const unsigned& j, const unsigned& ind );
68 ///
69 unsigned setupAtomsFromLinkCells( const std::vector<unsigned>& cind, const Vector& cpos, const LinkCells& linkcells );
70 ///
71 unsigned getIndex( const unsigned& j ) const ;
72 ///
73 unsigned getNumberOfAtoms() const ;
74 ///
75 unsigned getNumberOfDerivatives() const ;
76 /// Get the position of the ith atom
77 Vector& getPosition( const unsigned& );
78 /// Get the absolute index of the ith atom in the list
79 AtomNumber getAbsoluteIndex( const unsigned& j ) const ;
80 ///
81 void setValue( const unsigned&, const double& );
82 ///
83 void addValue( const unsigned& ival, const double& vv );
84 ///
85 double getValue( const unsigned& ) const ;
86 ///
87 void addBoxDerivatives( const unsigned&, const Tensor& );
88 ///
89 void addTemporyBoxDerivatives( const Tensor& vir );
90 ///
91 void updateUsingIndices();
92 ///
93 void updateDynamicList();
94 ///
95 void addComDerivatives( const int&, const Vector&, CatomPack& );
96 ///
97 MultiValue& getUnderlyingMultiValue();
98 ///
99 void addDerivative( const unsigned&, const unsigned&, const double& );
100 };
101
102 inline
setNumberOfAtoms(const unsigned & nat)103 void AtomValuePack::setNumberOfAtoms( const unsigned& nat ) {
104 natoms=nat;
105 }
106
107 inline
getNumberOfAtoms()108 unsigned AtomValuePack::getNumberOfAtoms() const {
109 return natoms;
110 }
111
112 inline
getNumberOfDerivatives()113 unsigned AtomValuePack::getNumberOfDerivatives() const {
114 return myvals.getNumberOfDerivatives();
115 }
116
117 inline
setIndex(const unsigned & j,const unsigned & ind)118 void AtomValuePack::setIndex( const unsigned& j, const unsigned& ind ) {
119 plumed_dbg_assert( j<natoms ); indices[j]=ind;
120 }
121
122 inline
setAtomIndex(const unsigned & j,const unsigned & ind)123 void AtomValuePack::setAtomIndex( const unsigned& j, const unsigned& ind ) {
124 plumed_dbg_assert( j<natoms ); indices[j]=ind;
125 }
126
127 inline
setAtom(const unsigned & j,const unsigned & ind)128 void AtomValuePack::setAtom( const unsigned& j, const unsigned& ind ) {
129 setAtomIndex( j, ind ); myatoms[j]=mycolv->getPositionOfAtomForLinkCells( ind );
130 }
131
132 inline
getIndex(const unsigned & j)133 unsigned AtomValuePack::getIndex( const unsigned& j ) const {
134 plumed_dbg_assert( j<natoms ); return indices[j];
135 }
136
137 inline
getAbsoluteIndex(const unsigned & j)138 AtomNumber AtomValuePack::getAbsoluteIndex( const unsigned& j ) const {
139 plumed_dbg_assert( j<natoms ); unsigned jatom=indices[j];
140 if( mycolv->atom_lab[jatom].first>0 ) {
141 unsigned mmc=mycolv->atom_lab[jatom].first - 1;
142 return (mycolv->mybasemulticolvars[mmc])->getAbsoluteIndexOfCentralAtom( mycolv->atom_lab[jatom].second );
143 }
144 return mycolv->getAbsoluteIndex( mycolv->atom_lab[jatom].second );
145 }
146
147 inline
getPosition(const unsigned & iatom)148 Vector& AtomValuePack::getPosition( const unsigned& iatom ) {
149 plumed_dbg_assert( iatom<natoms );
150 return myatoms[iatom];
151 }
152
153 inline
setValue(const unsigned & ival,const double & vv)154 void AtomValuePack::setValue( const unsigned& ival, const double& vv ) {
155 myvals.setValue( ival, vv );
156 }
157
158 inline
addValue(const unsigned & ival,const double & vv)159 void AtomValuePack::addValue( const unsigned& ival, const double& vv ) {
160 myvals.addValue( ival, vv );
161 }
162
163 inline
getValue(const unsigned & ival)164 double AtomValuePack::getValue( const unsigned& ival ) const {
165 return myvals.get( ival );
166 }
167
168 inline
addDerivative(const unsigned & ival,const unsigned & jder,const double & der)169 void AtomValuePack::addDerivative( const unsigned& ival, const unsigned& jder, const double& der ) {
170 myvals.addDerivative( ival, jder, der );
171 }
172
173 inline
addAtomsDerivatives(const unsigned & ival,const unsigned & jder,const Vector & der)174 void AtomValuePack::addAtomsDerivatives( const unsigned& ival, const unsigned& jder, const Vector& der ) {
175 plumed_dbg_assert( jder<natoms );
176 myvals.addDerivative( ival, 3*indices[jder] + 0, der[0] );
177 myvals.addDerivative( ival, 3*indices[jder] + 1, der[1] );
178 myvals.addDerivative( ival, 3*indices[jder] + 2, der[2] );
179 }
180
181 inline
addTemporyAtomsDerivatives(const unsigned & jder,const Vector & der)182 void AtomValuePack::addTemporyAtomsDerivatives( const unsigned& jder, const Vector& der ) {
183 plumed_dbg_assert( jder<natoms );
184 myvals.addTemporyDerivative( 3*indices[jder] + 0, der[0] );
185 myvals.addTemporyDerivative( 3*indices[jder] + 1, der[1] );
186 myvals.addTemporyDerivative( 3*indices[jder] + 2, der[2] );
187 }
188
189 inline
addTemporyBoxDerivatives(const Tensor & vir)190 void AtomValuePack::addTemporyBoxDerivatives( const Tensor& vir ) {
191 unsigned nvir=3*mycolv->getNumberOfAtoms();
192 for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) myvals.addTemporyDerivative( nvir + 3*i+j, vir(i,j) );
193 }
194
195 inline
addBoxDerivatives(const unsigned & ival,const Tensor & vir)196 void AtomValuePack::addBoxDerivatives( const unsigned& ival, const Tensor& vir ) {
197 unsigned nvir=3*mycolv->getNumberOfAtoms();
198 for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) myvals.addDerivative( ival, nvir + 3*i+j, vir(i,j) );
199 }
200
201 inline
updateDynamicList()202 void AtomValuePack::updateDynamicList() {
203 if( myvals.updateComplete() ) return;
204 myvals.updateDynamicList();
205 }
206
207 inline
getUnderlyingMultiValue()208 MultiValue& AtomValuePack::getUnderlyingMultiValue() {
209 return myvals;
210 }
211
212 }
213 }
214 #endif
215
216