Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2013-2019 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 "FunctionVessel.h"
23 : #include "core/ActionWithValue.h"
24 :
25 : namespace PLMD {
26 : namespace vesselbase {
27 :
28 303 : void FunctionVessel::registerKeywords( Keywords& keys ) {
29 303 : ValueVessel::registerKeywords( keys );
30 303 : }
31 :
32 303 : FunctionVessel::FunctionVessel( const VesselOptions& da ):
33 : ValueVessel(da),
34 : norm(false),
35 303 : usetol(false)
36 : {
37 303 : diffweight=getAction()->weightHasDerivatives;
38 303 : }
39 :
40 848 : void FunctionVessel::resize() {
41 848 : if( getAction()->derivativesAreRequired() ) {
42 509 : unsigned nderivatives=getAction()->getNumberOfDerivatives();
43 509 : getFinalValue()->resizeDerivatives( nderivatives );
44 509 : resizeBuffer( (1+nderivatives)*2 );
45 509 : diffweight=getAction()->weightHasDerivatives;
46 : } else {
47 : resizeBuffer(2);
48 339 : diffweight=false; // Don't need to worry about differentiable weights if no derivatives
49 : }
50 848 : }
51 :
52 259247 : void FunctionVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
53 259247 : unsigned nderivatives=getFinalValue()->getNumberOfDerivatives();
54 : double weight=myvals.get(0);
55 : plumed_dbg_assert( weight>=getTolerance() );
56 :
57 : // This deals with the value
58 518494 : double dval, f=calcTransform( myvals.get(mycomp), dval );
59 :
60 259247 : if( norm ) {
61 55307 : if( usetol && weight<getTolerance() ) return;
62 105196 : buffer[bufstart+1+nderivatives] += weight;
63 52598 : if( diffweight ) myvals.chainRule( 0, 1, 1, 0, 1.0, bufstart, buffer );
64 : }
65 :
66 259247 : double contr=weight*f;
67 362182 : if( usetol && contr<getTolerance() ) return;
68 508734 : buffer[bufstart] += contr;
69 :
70 254367 : if( diffweight ) myvals.chainRule( 0, 0, 1, 0, f, bufstart, buffer );
71 254367 : if( getAction()->derivativesAreRequired() && fabs(dval)>0.0 ) myvals.chainRule( mycomp, 0, 1, 0, weight*dval, bufstart, buffer );
72 :
73 : return;
74 : }
75 :
76 0 : double FunctionVessel::calcTransform( const double&, double& ) const {
77 0 : plumed_error(); return 1.0;
78 : }
79 :
80 26768 : void FunctionVessel::finish( const std::vector<double>& buffer ) {
81 26768 : unsigned nderivatives=getFinalValue()->getNumberOfDerivatives();
82 26768 : if( norm && diffweight ) {
83 15342 : double dv, val=finalTransform( buffer[bufstart], dv), weight=buffer[bufstart+1+nderivatives];
84 5114 : getFinalValue()->set( val / weight );
85 830708 : for(unsigned i=0; i<nderivatives; ++i) {
86 1238391 : getFinalValue()->addDerivative( i, buffer[bufstart+1+i]/weight - val*buffer[bufstart+1+nderivatives+1+i]/(weight*weight) );
87 5114 : }
88 21654 : } else if( norm ) {
89 2706 : double dv, val=finalTransform( buffer[bufstart], dv), weight=buffer[bufstart+1+nderivatives];
90 902 : getFinalValue()->set( val / weight );
91 118334 : for(unsigned i=0; i<nderivatives; ++i) getFinalValue()->addDerivative( i, buffer[bufstart+1+i]/weight );
92 : } else {
93 41504 : double dv, val=finalTransform( buffer[bufstart], dv); getFinalValue()->set( val );
94 6253728 : for(unsigned i=0; i<nderivatives; ++i) getFinalValue()->addDerivative( i, dv*buffer[bufstart+1+i] );
95 : }
96 26768 : }
97 :
98 22930 : double FunctionVessel::finalTransform( const double& val, double& dv ) {
99 22930 : dv=1.0; return val;
100 : }
101 :
102 : }
103 4839 : }
104 :
|