Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2013-2018 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 279 : void FunctionVessel::registerKeywords( Keywords& keys ) {
29 279 : ValueVessel::registerKeywords( keys );
30 279 : }
31 :
32 279 : FunctionVessel::FunctionVessel( const VesselOptions& da ):
33 : ValueVessel(da),
34 : norm(false),
35 279 : usetol(false)
36 : {
37 279 : diffweight=getAction()->weightHasDerivatives;
38 279 : }
39 :
40 759 : void FunctionVessel::resize() {
41 759 : if( getAction()->derivativesAreRequired() ) {
42 450 : unsigned nderivatives=getAction()->getNumberOfDerivatives();
43 450 : getFinalValue()->resizeDerivatives( nderivatives );
44 450 : resizeBuffer( (1+nderivatives)*2 );
45 450 : diffweight=getAction()->weightHasDerivatives;
46 : } else {
47 309 : resizeBuffer(2);
48 309 : diffweight=false; // Don't need to worry about differentiable weights if no derivatives
49 : }
50 759 : }
51 :
52 245914 : void FunctionVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
53 245914 : unsigned nderivatives=getFinalValue()->getNumberOfDerivatives();
54 245954 : double weight=myvals.get(0);
55 : plumed_dbg_assert( weight>=getTolerance() );
56 :
57 : // This deals with the value
58 246093 : double dval, f=calcTransform( myvals.get(mycomp), dval );
59 :
60 246140 : if( norm ) {
61 49286 : if( usetol && weight<getTolerance() ) return;
62 49235 : buffer[bufstart+1+nderivatives] += weight;
63 49236 : if( diffweight ) myvals.chainRule( 0, 1, 1, 0, 1.0, bufstart, buffer );
64 : }
65 :
66 246093 : double contr=weight*f;
67 246093 : if( usetol && contr<getTolerance() ) return;
68 241085 : buffer[bufstart] += contr;
69 :
70 241195 : if( diffweight ) myvals.chainRule( 0, 0, 1, 0, f, bufstart, buffer );
71 241355 : if( getAction()->derivativesAreRequired() && fabs(dval)>0.0 ) myvals.chainRule( mycomp, 0, 1, 0, weight*dval, bufstart, buffer );
72 :
73 241337 : return;
74 : }
75 :
76 0 : double FunctionVessel::calcTransform( const double&, double& ) const {
77 0 : plumed_error(); return 1.0;
78 : }
79 :
80 22976 : void FunctionVessel::finish( const std::vector<double>& buffer ) {
81 22976 : unsigned nderivatives=getFinalValue()->getNumberOfDerivatives();
82 22976 : if( norm && diffweight ) {
83 5114 : double dv, val=finalTransform( buffer[bufstart], dv), weight=buffer[bufstart+1+nderivatives];
84 5114 : getFinalValue()->set( val / weight );
85 417911 : for(unsigned i=0; i<nderivatives; ++i) {
86 412797 : getFinalValue()->addDerivative( i, buffer[bufstart+1+i]/weight - val*buffer[bufstart+1+nderivatives+1+i]/(weight*weight) );
87 5114 : }
88 17862 : } else if( norm ) {
89 649 : double dv, val=finalTransform( buffer[bufstart], dv), weight=buffer[bufstart+1+nderivatives];
90 649 : getFinalValue()->set( val / weight );
91 649 : for(unsigned i=0; i<nderivatives; ++i) getFinalValue()->addDerivative( i, buffer[bufstart+1+i]/weight );
92 : } else {
93 17213 : double dv, val=finalTransform( buffer[bufstart], dv); getFinalValue()->set( val );
94 17213 : for(unsigned i=0; i<nderivatives; ++i) getFinalValue()->addDerivative( i, dv*buffer[bufstart+1+i] );
95 : }
96 22976 : }
97 :
98 19138 : double FunctionVessel::finalTransform( const double& val, double& dv ) {
99 19138 : dv=1.0; return val;
100 : }
101 :
102 : }
103 2523 : }
104 :
|