Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2014-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 "vesselbase/VesselRegister.h" 23 : #include "vesselbase/FunctionVessel.h" 24 : #include "vesselbase/ActionWithVessel.h" 25 : #include "multicolvar/ActionVolume.h" 26 : #include "VectorMultiColvar.h" 27 : 28 : namespace PLMD { 29 : namespace crystallization { 30 : 31 : class VectorSum : public vesselbase::FunctionVessel { 32 : private: 33 : unsigned nder; 34 : public: 35 : static void registerKeywords( Keywords& keys ); 36 : static void reserveKeyword( Keywords& keys ); 37 : explicit VectorSum( const vesselbase::VesselOptions& da ); 38 : std::string value_descriptor(); 39 : void resize(); 40 : void calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const ; 41 : void finish( const std::vector<double>& buffer ); 42 : }; 43 : 44 13785 : PLUMED_REGISTER_VESSEL(VectorSum,"VSUM") 45 : 46 0 : void VectorSum::registerKeywords( Keywords& keys ) { 47 0 : vesselbase::FunctionVessel::registerKeywords(keys); 48 0 : } 49 : 50 4595 : void VectorSum::reserveKeyword( Keywords& keys ) { 51 9190 : keys.reserve("vessel","VSUM","calculate the norm of the sum of vectors."); 52 9190 : keys.addOutputComponent("vsum","VSUM","the norm of sum of vectors. The output component can be referred to elsewhere in the input " 53 : "file by using the label.vsum"); 54 4595 : } 55 : 56 0 : VectorSum::VectorSum( const vesselbase::VesselOptions& da ) : 57 : FunctionVessel(da), 58 0 : nder(0) { 59 0 : } 60 : 61 0 : std::string VectorSum::value_descriptor() { 62 0 : return "the norm of the mean vector"; 63 : } 64 : 65 0 : void VectorSum::resize() { 66 0 : unsigned ncomp=getAction()->getNumberOfQuantities() - 2; 67 : 68 0 : if( getAction()->derivativesAreRequired() ) { 69 0 : nder=getAction()->getNumberOfDerivatives(); 70 0 : resizeBuffer( (1+nder)*ncomp ); 71 0 : getFinalValue()->resizeDerivatives( nder ); 72 : } else { 73 0 : nder=0; 74 : resizeBuffer(ncomp); 75 : } 76 0 : } 77 : 78 0 : void VectorSum::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const { 79 0 : unsigned ncomp=getAction()->getNumberOfQuantities()-2; 80 : 81 0 : double weight=myvals.get(0); 82 : plumed_dbg_assert( weight>=getTolerance() ); 83 0 : for(unsigned i=0; i<ncomp; ++i) { 84 0 : buffer[bufstart + i*(1+nder)] += weight*myvals.get(2+i); 85 : } 86 0 : if( !getAction()->derivativesAreRequired() ) { 87 : return; 88 : } 89 : 90 0 : for(unsigned i=0; i<ncomp; ++i) { 91 0 : double colvar=myvals.get(2+i); 92 0 : myvals.chainRule( 2+i, i, 1, 0, weight, bufstart, buffer ); 93 0 : if( diffweight ) { 94 0 : myvals.chainRule( 0, i, 1, 0, colvar, bufstart, buffer ); 95 : } 96 : } 97 0 : return; 98 : } 99 : 100 0 : void VectorSum::finish( const std::vector<double>& buffer ) { 101 0 : unsigned ncomp=getAction()->getNumberOfQuantities()-2; 102 : 103 : double sum=0; 104 0 : for(unsigned i=0; i<ncomp; ++i) { 105 0 : double tmp = buffer[bufstart+(nder+1)*i]; 106 0 : sum+=tmp*tmp; 107 : } 108 0 : double tw = 1.0 / sqrt(sum); 109 0 : setOutputValue( sqrt(sum) ); 110 0 : if( !getAction()->derivativesAreRequired() ) { 111 : return; 112 : } 113 : 114 : Value* fval=getFinalValue(); 115 0 : for(unsigned icomp=0; icomp<ncomp; ++icomp) { 116 0 : double tmp = buffer[bufstart + icomp*(1+nder)]; 117 0 : unsigned bstart = bufstart + icomp*(nder+1) + 1; 118 0 : for(unsigned jder=0; jder<nder; ++jder) { 119 0 : fval->addDerivative( jder, tw*tmp*buffer[bstart + jder] ); 120 : } 121 : } 122 : } 123 : 124 : } 125 : }