Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2013-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 "FunctionVessel.h" 23 : #include "core/ActionWithValue.h" 24 : 25 : namespace PLMD { 26 : namespace vesselbase { 27 : 28 327 : void FunctionVessel::registerKeywords( Keywords& keys ) { 29 327 : ValueVessel::registerKeywords( keys ); 30 327 : } 31 : 32 327 : FunctionVessel::FunctionVessel( const VesselOptions& da ): 33 : ValueVessel(da), 34 327 : norm(false), 35 327 : usetol(false) 36 : { 37 327 : diffweight=getAction()->weightHasDerivatives; 38 327 : } 39 : 40 910 : void FunctionVessel::resize() { 41 910 : if( getAction()->derivativesAreRequired() ) { 42 540 : unsigned nderivatives=getAction()->getNumberOfDerivatives(); 43 540 : getFinalValue()->resizeDerivatives( nderivatives ); 44 540 : resizeBuffer( (1+nderivatives)*2 ); 45 540 : diffweight=getAction()->weightHasDerivatives; 46 : } else { 47 : resizeBuffer(2); 48 370 : diffweight=false; // Don't need to worry about differentiable weights if no derivatives 49 : } 50 910 : } 51 : 52 244640 : void FunctionVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const { 53 244640 : unsigned nderivatives=getFinalValue()->getNumberOfDerivatives(); 54 : double weight=myvals.get(0); 55 : plumed_dbg_assert( weight>=getTolerance() ); 56 : 57 : // This deals with the value 58 244640 : double dval, f=calcTransform( myvals.get(mycomp), dval ); 59 : 60 244640 : if( norm ) { 61 82812 : if( usetol && weight<getTolerance() ) return; 62 82812 : buffer[bufstart+1+nderivatives] += weight; 63 82812 : if( getAction()->derivativesAreRequired() && diffweight ) myvals.chainRule( 0, 1, 1, 0, 1.0, bufstart, buffer ); 64 : } 65 : 66 244640 : double contr=weight*f; 67 244640 : if( usetol && contr<getTolerance() ) return; 68 239718 : buffer[bufstart] += contr; 69 : 70 239718 : if( diffweight ) myvals.chainRule( 0, 0, 1, 0, f, bufstart, buffer ); 71 239718 : if( getAction()->derivativesAreRequired() && std::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(); 78 : } 79 : 80 26614 : void FunctionVessel::finish( const std::vector<double>& buffer ) { 81 26614 : unsigned nderivatives=getFinalValue()->getNumberOfDerivatives(); 82 26614 : 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 : } 88 26614 : } else if( norm ) { 89 1226 : double dv, val=finalTransform( buffer[bufstart], dv), weight=buffer[bufstart+1+nderivatives]; 90 1226 : getFinalValue()->set( val / weight ); 91 156782 : for(unsigned i=0; i<nderivatives; ++i) getFinalValue()->addDerivative( i, buffer[bufstart+1+i]/weight ); 92 : } else { 93 20274 : double dv, val=finalTransform( buffer[bufstart], dv); getFinalValue()->set( val ); 94 1530086 : for(unsigned i=0; i<nderivatives; ++i) getFinalValue()->addDerivative( i, dv*buffer[bufstart+1+i] ); 95 : } 96 26614 : } 97 : 98 22776 : double FunctionVessel::finalTransform( const double& val, double& dv ) { 99 22776 : dv=1.0; return val; 100 : } 101 : 102 : } 103 : } 104 :