LCOV - code coverage report
Current view: top level - crystallization - VectorMean.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 46 46 100.0 %
Date: 2020-11-18 11:20:57 Functions: 13 14 92.9 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2014-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 "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          12 : class VectorMean : public vesselbase::FunctionVessel {
      32             : private:
      33             :   unsigned nder;
      34             : public:
      35             :   static void registerKeywords( Keywords& keys );
      36             :   static void reserveKeyword( Keywords& keys );
      37             :   explicit VectorMean( 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        6458 : PLUMED_REGISTER_VESSEL(VectorMean,"VMEAN")
      45             : 
      46           6 : void VectorMean::registerKeywords( Keywords& keys ) {
      47           6 :   vesselbase::FunctionVessel::registerKeywords(keys);
      48           6 : }
      49             : 
      50        1613 : void VectorMean::reserveKeyword( Keywords& keys ) {
      51        6452 :   keys.reserve("vessel","VMEAN","calculate the norm of the mean vector.");
      52        6452 :   keys.addOutputComponent("vmean","VMEAN","the norm of the mean vector. The output component can be refererred to elsewhere in the input "
      53             :                           "file by using the label.vmean");
      54        1613 : }
      55             : 
      56           6 : VectorMean::VectorMean( const vesselbase::VesselOptions& da ) :
      57             :   FunctionVessel(da),
      58           6 :   nder(0)
      59             : {
      60           6 : }
      61             : 
      62           6 : std::string VectorMean::value_descriptor() {
      63           6 :   return "the norm of the mean vector";
      64             : }
      65             : 
      66          23 : void VectorMean::resize() {
      67          23 :   unsigned ncomp=getAction()->getNumberOfQuantities() - 2;
      68             : 
      69          23 :   if( getAction()->derivativesAreRequired() ) {
      70          16 :     nder=getAction()->getNumberOfDerivatives();
      71          32 :     resizeBuffer( (1+nder)*(ncomp+1) ); getFinalValue()->resizeDerivatives( nder );
      72             :   } else {
      73           7 :     nder=0; resizeBuffer(ncomp+1);
      74             :   }
      75          23 : }
      76             : 
      77       14712 : void VectorMean::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
      78       14712 :   unsigned ncomp=getAction()->getNumberOfQuantities()-2;
      79             : 
      80       14712 :   double weight=myvals.get(0); plumed_dbg_assert( weight>=getTolerance() );
      81       29424 :   buffer[bufstart] += weight;
      82      154296 :   for(unsigned i=0; i<ncomp; ++i) buffer[bufstart + (1+i)*(1+nder)] += weight*myvals.get(2+i);
      83       14712 :   if( !getAction()->derivativesAreRequired() ) return;
      84             : 
      85       14712 :   if( diffweight ) myvals.chainRule( 0, 0, 1, 0, 1.0, bufstart, buffer );
      86      107768 :   for(unsigned i=0; i<ncomp; ++i) {
      87       93056 :     double colvar=myvals.get(2+i);
      88       46528 :     myvals.chainRule( 2+i, 1+i, 1, 0, weight, bufstart, buffer );
      89       46528 :     if( diffweight ) myvals.chainRule( 0, 1+i, 1, 0, colvar, bufstart, buffer );
      90             :   }
      91             :   return;
      92             : }
      93             : 
      94        1828 : void VectorMean::finish( const std::vector<double>& buffer ) {
      95        1828 :   unsigned ncomp=getAction()->getNumberOfQuantities()-2;
      96        3656 :   double sum=0, ww=buffer[bufstart];
      97       12888 :   for(unsigned i=0; i<ncomp; ++i) {
      98       11060 :     double tmp = buffer[bufstart+(nder+1)*(i+1)] / ww;
      99        5530 :     sum+=tmp*tmp;
     100             :   }
     101        1828 :   setOutputValue( sqrt(sum) );
     102        1828 :   if( !getAction()->derivativesAreRequired() ) return;
     103             : 
     104        1828 :   Value* fval=getFinalValue(); double tw = 1.0 / sqrt(sum);
     105        7358 :   for(unsigned icomp=0; icomp<ncomp; ++icomp) {
     106       11060 :     double tmp = buffer[bufstart + (icomp+1)*(1+nder)] / ww;
     107        5530 :     unsigned bstart = bufstart + (1+icomp)*(nder+1) + 1;
     108     1825954 :     for(unsigned jder=0; jder<nder; ++jder) fval->addDerivative( jder, (tw*tmp/ww)*( buffer[bstart + jder] - tmp*buffer[bufstart + 1 + jder] ) );
     109             :   }
     110             : }
     111             : 
     112             : }
     113        4839 : }

Generated by: LCOV version 1.13