Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2017-2026 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_isdb_MetainferenceBase_h
23 : #define __PLUMED_isdb_MetainferenceBase_h
24 :
25 : #include "core/ActionWithValue.h"
26 : #include "core/ActionAtomistic.h"
27 : #include "core/ActionWithArguments.h"
28 : #include "MetainferenceCore.h"
29 : #include "core/PlumedMain.h"
30 : #include "tools/Communicator.h"
31 : #include <memory>
32 :
33 : #define PLUMED_METAINF_INIT(ao) Action(ao),MetainferenceBase(ao)
34 :
35 : namespace PLMD {
36 : namespace isdb {
37 :
38 : /**
39 : \ingroup INHERIT
40 : This is the abstract base class to use for implementing new ISDB Metainference actions, within it there is
41 : information as to how to go about implementing a new Metainference action.
42 : */
43 :
44 : class MetainferenceBase :
45 : public ActionAtomistic,
46 : public ActionWithArguments,
47 : public ActionWithValue {
48 : private:
49 : std::vector<double> forces;
50 : std::vector<double> forcesToApply;
51 :
52 : // activate metainference
53 : bool doscore_;
54 : // number of experimental data
55 : unsigned narg;
56 : // experimental data
57 : std::vector<double> parameters;
58 : // the Metainference algorithm
59 : std::unique_ptr<MetainferenceCore> core_;
60 : // output
61 : Value* valueScore;
62 : // selector
63 : unsigned iselect;
64 :
65 : public:
66 : static void registerKeywords( Keywords& keys );
67 : explicit MetainferenceBase(const ActionOptions&);
68 : ~MetainferenceBase();
69 : void Initialise(const unsigned input);
70 : void Selector();
71 : unsigned getNarg();
72 : void setNarg(const unsigned input);
73 : void setParameters(const std::vector<double>& input);
74 : void setParameter(const double input);
75 : void setCalcData(const unsigned index, const double datum);
76 : void setCalcData(const std::vector<double>& data);
77 : bool getDoScore();
78 : unsigned getWstride();
79 : double getScore();
80 : void setScore(const double score);
81 : void setDerivatives();
82 : double getMetaDer(const unsigned index);
83 : void writeStatus();
84 : void update() override;
85 : void turnOnDerivatives() override;
86 : unsigned getNumberOfDerivatives() override;
87 : void lockRequests() override;
88 : void unlockRequests() override;
89 : void calculateNumericalDerivatives( ActionWithValue* a ) override;
90 : void apply() override;
91 : void setArgDerivatives(Value *v, const double &d);
92 : void setAtomsDerivatives(Value*v, const unsigned i, const Vector&d);
93 : void setBoxDerivatives(Value*v, const Tensor&d);
94 : };
95 :
96 : inline
97 : void MetainferenceBase::setNarg(const unsigned input) {
98 83 : narg = input;
99 : }
100 :
101 : inline
102 : bool MetainferenceBase::getDoScore() {
103 25327 : return doscore_;
104 : }
105 :
106 : inline
107 : unsigned MetainferenceBase::getWstride() {
108 : return core_->getWriteStride();
109 : }
110 :
111 : inline
112 : unsigned MetainferenceBase::getNarg() {
113 : return narg;
114 : }
115 :
116 : inline
117 : double MetainferenceBase::getMetaDer(const unsigned index) {
118 : return core_->getMetaDer(index);
119 : }
120 :
121 : inline
122 : void MetainferenceBase::setCalcData(const unsigned index, const double datum) {
123 4498 : core_->data()[index] = datum;
124 4498 : }
125 :
126 : inline
127 : void MetainferenceBase::setCalcData(const std::vector<double>& data) {
128 : std::vector<double>& calc_data=core_->data();
129 : for(unsigned i=0; i<data.size(); i++) {
130 : calc_data[i] = data[i];
131 : }
132 : }
133 :
134 : inline
135 79 : void MetainferenceBase::setParameters(const std::vector<double>& input) {
136 656 : for(unsigned i=0; i<input.size(); i++) {
137 577 : parameters.push_back(input[i]);
138 : }
139 79 : }
140 :
141 : inline
142 : void MetainferenceBase::setParameter(const double input) {
143 2356 : parameters.push_back(input);
144 2356 : }
145 :
146 : inline
147 2503 : void MetainferenceBase::setScore(const double score) {
148 2503 : valueScore->set(score);
149 2503 : }
150 :
151 : inline
152 254 : void MetainferenceBase::setDerivatives() {
153 : // Get appropriate number of derivatives
154 : // Derivatives are first for arguments and then for atoms
155 : unsigned nder;
156 254 : if( getNumberOfAtoms()>0 ) {
157 254 : nder = 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
158 : } else {
159 0 : nder = getNumberOfArguments();
160 : }
161 :
162 : // Resize all derivative arrays
163 254 : forces.resize( nder );
164 254 : forcesToApply.resize( nder );
165 24396 : for(unsigned i=0; i<getNumberOfComponents(); ++i) {
166 24142 : getPntrToComponent(i)->resizeDerivatives(nder);
167 : }
168 254 : }
169 :
170 : inline
171 3513 : void MetainferenceBase::turnOnDerivatives() {
172 3513 : ActionWithValue::turnOnDerivatives();
173 3513 : }
174 :
175 : inline
176 2840758 : unsigned MetainferenceBase::getNumberOfDerivatives() {
177 2840758 : if( getNumberOfAtoms()>0 ) {
178 2840758 : return 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
179 : }
180 0 : return getNumberOfArguments();
181 : }
182 :
183 : inline
184 1323 : void MetainferenceBase::lockRequests() {
185 : ActionAtomistic::lockRequests();
186 : ActionWithArguments::lockRequests();
187 1323 : }
188 :
189 : inline
190 1323 : void MetainferenceBase::unlockRequests() {
191 : ActionAtomistic::unlockRequests();
192 : ActionWithArguments::unlockRequests();
193 1323 : }
194 :
195 : inline
196 75 : void MetainferenceBase::calculateNumericalDerivatives( ActionWithValue* a=NULL ) {
197 75 : if( getNumberOfArguments()>0 ) {
198 48 : ActionWithArguments::calculateNumericalDerivatives( a );
199 : }
200 75 : if( getNumberOfAtoms()>0 ) {
201 75 : Matrix<double> save_derivatives( getNumberOfComponents(), getNumberOfArguments() );
202 1293 : for(unsigned j=0; j<getNumberOfComponents(); ++j) {
203 2322 : for(unsigned i=0; i<getNumberOfArguments(); ++i) {
204 1104 : if(getPntrToComponent(j)->hasDerivatives()) {
205 48 : save_derivatives(j,i)=getPntrToComponent(j)->getDerivative(i);
206 : }
207 : }
208 : }
209 75 : calculateAtomicNumericalDerivatives( a, getNumberOfArguments() );
210 1293 : for(unsigned j=0; j<getNumberOfComponents(); ++j) {
211 2322 : for(unsigned i=0; i<getNumberOfArguments(); ++i) {
212 1104 : if(getPntrToComponent(j)->hasDerivatives()) {
213 48 : getPntrToComponent(j)->addDerivative( i, save_derivatives(j,i) );
214 : }
215 : }
216 : }
217 : }
218 75 : }
219 :
220 : inline
221 1323 : void MetainferenceBase::apply() {
222 : bool wasforced=false;
223 1323 : forcesToApply.assign(forcesToApply.size(),0.0);
224 42962 : for(unsigned i=0; i<getNumberOfComponents(); ++i) {
225 41639 : if( getPntrToComponent(i)->applyForce( forces ) ) {
226 : wasforced=true;
227 42521908 : for(unsigned ii=0; ii<forces.size(); ++ii) {
228 42513493 : forcesToApply[ii]+=forces[ii];
229 : }
230 : }
231 : }
232 1323 : if( wasforced ) {
233 865 : unsigned ind=0;
234 865 : addForcesOnArguments( 0, forcesToApply, ind );
235 865 : if( getNumberOfAtoms()>0 ) {
236 865 : setForcesOnAtoms( forcesToApply, ind );
237 : }
238 : }
239 1323 : }
240 :
241 : inline
242 : void MetainferenceBase::setArgDerivatives(Value *v, const double &d) {
243 : v->addDerivative(0,d);
244 : }
245 :
246 : inline
247 2868730 : void MetainferenceBase::setAtomsDerivatives(Value*v, const unsigned i, const Vector&d) {
248 2868730 : const unsigned noa=getNumberOfArguments();
249 2868730 : v->addDerivative(noa+3*i+0,d[0]);
250 2868730 : v->addDerivative(noa+3*i+1,d[1]);
251 2868730 : v->addDerivative(noa+3*i+2,d[2]);
252 2868730 : }
253 :
254 : inline
255 13344 : void MetainferenceBase::setBoxDerivatives(Value* v,const Tensor&d) {
256 13344 : const unsigned noa=getNumberOfArguments();
257 : const unsigned nat=getNumberOfAtoms();
258 13344 : v->addDerivative(noa+3*nat+0,d(0,0));
259 13344 : v->addDerivative(noa+3*nat+1,d(0,1));
260 13344 : v->addDerivative(noa+3*nat+2,d(0,2));
261 13344 : v->addDerivative(noa+3*nat+3,d(1,0));
262 13344 : v->addDerivative(noa+3*nat+4,d(1,1));
263 13344 : v->addDerivative(noa+3*nat+5,d(1,2));
264 13344 : v->addDerivative(noa+3*nat+6,d(2,0));
265 13344 : v->addDerivative(noa+3*nat+7,d(2,1));
266 13344 : v->addDerivative(noa+3*nat+8,d(2,2));
267 13344 : }
268 :
269 :
270 : }
271 : }
272 :
273 : #endif
274 :
|