diff --git a/src/function/FunctionOfVector.h b/src/function/FunctionOfVector.h index 64ec10537f..325cc7c985 100644 --- a/src/function/FunctionOfVector.h +++ b/src/function/FunctionOfVector.h @@ -36,14 +36,8 @@ class FunctionOfVector : public ActionWithVector { private: /// Do the calculation at the end of the run bool doAtEnd; -/// Is this the first time we are doing the calc - bool firststep; /// The function that is being computed T myfunc; -/// The number of derivatives for this action - unsigned nderivatives; -/// A vector that tells us if we have stored the input value - std::vector stored_arguments; public: static void registerKeywords(Keywords&); /// This method is used to run the calculation with functions such as highest/lowest and sort. @@ -60,14 +54,10 @@ class FunctionOfVector : public ActionWithVector { unsigned getNumberOfDerivatives() override ; /// Resize vectors that are the wrong size void prepare() override ; -/// Check if all he actions are required - void areAllTasksRequired( std::vector& task_reducing_actions ); /// Get the label to write in the graph std::string writeInGraph() const override { return myfunc.getGraphInfo( getName() ); } /// This builds the task list for the action void calculate() override; -/// This ensures that we create some bookeeping stuff during the first step - void setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol ) override ; /// Calculate the function void performTask( const unsigned& current, MultiValue& myvals ) const override ; }; @@ -99,9 +89,7 @@ template FunctionOfVector::FunctionOfVector(const ActionOptions&ao): Action(ao), ActionWithVector(ao), - doAtEnd(true), - firststep(true), - nderivatives(0) + doAtEnd(true) { // Get the shape of the output std::vector shape(1); shape[0]=getNumberOfFinalTasks(); @@ -110,7 +98,7 @@ FunctionOfVector::FunctionOfVector(const ActionOptions&ao): // Create the task list if( myfunc.doWithTasks() ) { doAtEnd=false; if( shape[0]>0 ) done_in_chain=true; - } else { plumed_assert( getNumberOfArguments()==1 ); done_in_chain=false; getPntrToArgument(0)->buildDataStore(); } + } else { plumed_assert( getNumberOfArguments()==1 ); getPntrToArgument(0)->buildDataStore(); } // Get the names of the components std::vector components( keywords.getOutputComponents() ); // Create the values to hold the output @@ -143,35 +131,10 @@ FunctionOfVector::FunctionOfVector(const ActionOptions&ao): } // Check if this is a timeseries unsigned argstart=myfunc.getArgStart(); - // for(unsigned i=argstart; iisTimeSeries() ) { - // for(unsigned i=0; imakeHistoryDependent(); - // break; - // } - // } // Set the periodicities of the output components myfunc.setPeriodicityForOutputs( this ); - // Check if we can put the function in a chain - for(unsigned i=argstart; i( getPntrToArgument(i)->getPntrToAction() ); - // if( ab && ab->hasClear() ) { doNotChain=true; getPntrToArgument(i)->buildDataStore( getLabel() ); } - // No chains if we are using a sum or a mean - if( getPntrToArgument(i)->getRank()==0 ) { - FunctionOfVector* as = dynamic_cast*>( getPntrToArgument(i)->getPntrToAction() ); - if(as) done_in_chain=false; - } else { - ActionWithVector* av=dynamic_cast( getPntrToArgument(i)->getPntrToAction() ); - if( !av ) done_in_chain=false; - else if( av->getNumberOfMasks()>=0 && !myfunc.checkIfMaskAllowed( getArguments() ) ) error("cannot use argument masks in input as not all elements are computed"); - } - } - // Don't need to do the calculation in a chain if the input is constant - bool allconstant=true; - for(unsigned i=argstart; iisConstant() ) { allconstant=false; break; } - } - if( allconstant ) done_in_chain=false; - nderivatives = buildArgumentStore(myfunc.getArgStart()); + // Setup the derivatives + unsigned nderivatives = buildArgumentStore(myfunc.getArgStart()); } template @@ -189,7 +152,9 @@ void FunctionOfVector::turnOnDerivatives() { template unsigned FunctionOfVector::getNumberOfDerivatives() { - return nderivatives; + unsigned nder = 0, argstart = myfunc.getArgStart(); + for(unsigned i=argstart; igetNumberOfStoredValues(); + return nder; } template @@ -207,102 +172,35 @@ void FunctionOfVector::prepare() { ActionWithVector::prepare(); } -template -void FunctionOfVector::setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol ) { - if( firststep ) { - stored_arguments.resize( getNumberOfArguments() ); - std::string control = getFirstActionInChain()->getLabel(); - for(unsigned i=0; iisConstant() ) stored_arguments[i]=false; - else stored_arguments[i] = !getPntrToArgument(i)->ignoreStoredValue( control ); - } - firststep=false; - } - ActionWithVector::setupStreamedComponents( headstr, nquants, nmat, maxcol ); -} - template void FunctionOfVector::performTask( const unsigned& current, MultiValue& myvals ) const { unsigned argstart=myfunc.getArgStart(); std::vector args( getNumberOfArguments()-argstart); - if( actionInChain() ) { - for(unsigned i=argstart; igetRank()==0 ) args[i-argstart] = getPntrToArgument(i)->get(); - else if( !getPntrToArgument(i)->valueHasBeenSet() ) args[i-argstart] = myvals.get( getPntrToArgument(i)->getPositionInStream() ); - else args[i-argstart] = getPntrToArgument(i)->get( myvals.getTaskIndex() ); - } - } else { - for(unsigned i=argstart; igetRank()==1 ) args[i-argstart]=getPntrToArgument(i)->get(current); - else args[i-argstart] = getPntrToArgument(i)->get(); - } + for(unsigned i=argstart; igetRank()==1 ) args[i-argstart]=getPntrToArgument(i)->get(current); + else args[i-argstart] = getPntrToArgument(i)->get(); } // Calculate the function and its derivatives std::vector vals( getNumberOfComponents() ); Matrix derivatives( getNumberOfComponents(), args.size() ); myfunc.calc( this, args, vals, derivatives ); // And set the values - for(unsigned i=0; igetPositionInStream(), vals[i] ); + for(unsigned i=0; igetPositionInStream(); - if( stored_arguments[argstart+j] ) { - unsigned task_index = myvals.getTaskIndex(); if( getPntrToArgument(argstart+j)->getRank()==0 ) task_index=0; - myvals.addDerivative( istrn, task_index, 1.0 ); myvals.updateIndex( istrn, task_index ); - } - unsigned arg_deriv_s = arg_deriv_starts[argstart+j]; - for(unsigned k=0; kgetPositionInStream(); - myvals.addDerivative( ostrn, arg_deriv_s + kind, derivatives(i,j)*myvals.getDerivative( istrn, kind ) ); - } - } - // Ensure we only store one lot of derivative indices - bool found=false; ActionWithValue* aav=getPntrToArgument(argstart+j)->getPntrToAction(); - for(unsigned k=0; kgetPntrToAction()!=aav ) { - ActionWithVector* av = dynamic_cast( getPntrToArgument(argstart+j)->getPntrToAction() ); - if( av ) { - for(int i=0; iupdateAdditionalIndices( getConstPntrToComponent(i)->getPositionInStream(), myvals ); - } - } - found=true; break; - } - } - if( found ) continue; - for(unsigned k=0; kgetPositionInStream(); - myvals.updateIndex( ostrn, arg_deriv_s + kind ); - } + + unsigned base=0; + for(unsigned j=0; jgetRank()==1 ) { + for(int i=0; igetRank()==1 ) { - for(int i=0; igetPositionInStream(); - myvals.addDerivative( ostrn, base+current, derivatives(i,j) ); - myvals.updateIndex( ostrn, base+current ); - } - } else { - for(int i=0; igetPositionInStream(); - myvals.addDerivative( ostrn, base, derivatives(i,j) ); - myvals.updateIndex( ostrn, base ); - } + } else { + for(int i=0; igetNumberOfValues(); } + base += getPntrToArgument(argstart+j)->getNumberOfValues(); } } @@ -313,8 +211,6 @@ unsigned FunctionOfVector::getNumberOfFinalTasks() { plumed_assert( getPntrToArgument(i)->getRank()<2 ); if( getPntrToArgument(i)->getRank()==1 ) { if( nelements>0 ) { - // if( getPntrToArgument(i)->isTimeSeries() && getPntrToArgument(i)->getShape()[0]isTimeSeries(); - // else if(getPntrToArgument(i)->getShape()[0]!=nelements ) error("all vectors input should have the same length"); } else if( nelements==0 ) nelements=getPntrToArgument(i)->getShape()[0]; plumed_assert( !getPntrToArgument(i)->hasDerivatives() ); @@ -325,12 +221,6 @@ unsigned FunctionOfVector::getNumberOfFinalTasks() { return nelements; } -template -void FunctionOfVector::areAllTasksRequired( std::vector& task_reducing_actions ) { - if( task_reducing_actions.size()==0 ) return; - if( !myfunc.allComponentsRequired( getArguments(), task_reducing_actions ) ) task_reducing_actions.push_back(this); -} - template void FunctionOfVector::runSingleTaskCalculation( const Value* arg, ActionWithValue* action, T& f ) { // This is used if we are doing sorting actions on a single vector @@ -349,8 +239,6 @@ void FunctionOfVector::runSingleTaskCalculation( const Value* arg, ActionWith template void FunctionOfVector::calculate() { - // Everything is done elsewhere - if( actionInChain() ) return; // This is done if we are calculating a function of multiple cvs if( !doAtEnd ) runAllTasks(); // This is used if we are doing sorting actions on a single vector