void Mapping::mergeDerivatives( const unsigned& ider, const double& df ){ unsigned cur = getCurrentTask(), frameno=ider*getNumberOfReferencePoints() + cur; for(unsigned i=0;i<getNumberOfArguments();++i){ accumulateDerivative( i, df*dfframes[frameno]*mymap->getArgumentDerivative(cur,i) ); } if( getNumberOfAtoms()>0 ){ Vector ader; Tensor tmpvir; tmpvir.zero(); unsigned n=getNumberOfArguments(); for(unsigned i=0;i<getNumberOfAtoms();++i){ ader=mymap->getAtomDerivatives( cur, i ); accumulateDerivative( n, df*dfframes[frameno]*ader[0] ); n++; accumulateDerivative( n, df*dfframes[frameno]*ader[1] ); n++; accumulateDerivative( n, df*dfframes[frameno]*ader[2] ); n++; tmpvir += -1.0*Tensor( getPosition(i), ader ); } Tensor vir; if( !mymap->getVirial( cur, vir ) ) vir=tmpvir; accumulateDerivative( n, df*dfframes[frameno]*vir(0,0) ); n++; accumulateDerivative( n, df*dfframes[frameno]*vir(0,1) ); n++; accumulateDerivative( n, df*dfframes[frameno]*vir(0,2) ); n++; accumulateDerivative( n, df*dfframes[frameno]*vir(1,0) ); n++; accumulateDerivative( n, df*dfframes[frameno]*vir(1,1) ); n++; accumulateDerivative( n, df*dfframes[frameno]*vir(1,2) ); n++; accumulateDerivative( n, df*dfframes[frameno]*vir(2,0) ); n++; accumulateDerivative( n, df*dfframes[frameno]*vir(2,1) ); n++; accumulateDerivative( n, df*dfframes[frameno]*vir(2,2) ); } }
std::string Mapping::getArgumentName( unsigned& iarg ){ if( iarg < getNumberOfArguments() ) return getPntrToArgument(iarg)->getName(); unsigned iatom=iarg - getNumberOfArguments(); std::string atnum; Tools::convert( getAbsoluteIndex(iatom).serial(),atnum); unsigned icomp=iatom%3; if(icomp==0) return "pos" + atnum + "x"; if(icomp==1) return "pos" + atnum + "y"; return "pos" + atnum + "z"; }
void AdaptivePath::update() { double weight2 = -1.*mypathv->dx; double weight1 = 1.0 + mypathv->dx; if( weight1>1.0 ) { weight1=1.0; weight2=0.0; } else if( weight2>1.0 ) { weight1=0.0; weight2=1.0; } // Add projections to dispalcement accumulators ReferenceConfiguration* myref = getReferenceConfiguration( mypathv->iclose1 ); myref->extractDisplacementVector( getPositions(), getArguments(), mypathv->cargs, false, displacement ); getReferenceConfiguration( mypathv->iclose2 )->extractDisplacementVector( myref->getReferencePositions(), getArguments(), myref->getReferenceArguments(), false, displacement2 ); displacement.addDirection( -mypathv->dx, displacement2 ); pdisplacements[mypathv->iclose1].addDirection( weight1, displacement ); pdisplacements[mypathv->iclose2].addDirection( weight2, displacement ); // Update weight accumulators wsum[mypathv->iclose1] *= fadefact; wsum[mypathv->iclose2] *= fadefact; wsum[mypathv->iclose1] += weight1; wsum[mypathv->iclose2] += weight2; // This does the update of the path if it is time to if( (getStep()>0) && (getStep()%update_str==0) ) { wsum[fixedn[0]]=wsum[fixedn[1]]=0.; for(unsigned inode=0; inode<getNumberOfReferencePoints(); ++inode) { if( wsum[inode]>0 ) { // First displace the node by the weighted direction getReferenceConfiguration( inode )->displaceReferenceConfiguration( 1./wsum[inode], pdisplacements[inode] ); // Reset the displacement pdisplacements[inode].zeroDirection(); } } // Now ensure all the nodes of the path are equally spaced PathReparameterization myspacings( getPbc(), getArguments(), getAllReferenceConfigurations() ); myspacings.reparameterize( fixedn[0], fixedn[1], tolerance ); } if( (getStep()>0) && (getStep()%wstride==0) ) { pathfile.printf("# PATH AT STEP %d TIME %f \n", getStep(), getTime() ); std::vector<std::unique_ptr<ReferenceConfiguration>>& myconfs=getAllReferenceConfigurations(); std::vector<SetupMolInfo*> moldat=plumed.getActionSet().select<SetupMolInfo*>(); if( moldat.size()>1 ) error("you should only have one MOLINFO action in your input file"); SetupMolInfo* mymoldat=NULL; if( moldat.size()==1 ) mymoldat=moldat[0]; std::vector<std::string> argument_names( getNumberOfArguments() ); for(unsigned i=0; i<getNumberOfArguments(); ++i) argument_names[i] = getPntrToArgument(i)->getName(); PDB mypdb; mypdb.setArgumentNames( argument_names ); for(unsigned i=0; i<myconfs.size(); ++i) { pathfile.printf("REMARK TYPE=%s\n", myconfs[i]->getName().c_str() ); mypdb.setAtomPositions( myconfs[i]->getReferencePositions() ); for(unsigned j=0; j<getNumberOfArguments(); ++j) mypdb.setArgumentValue( getPntrToArgument(j)->getName(), myconfs[i]->getReferenceArgument(j) ); mypdb.print( atoms.getUnits().getLength()/0.1, mymoldat, pathfile, ofmt ); } pathfile.flush(); } }
Bias::Bias(const ActionOptions&ao): Action(ao), ActionPilot(ao), ActionWithValue(ao), ActionWithArguments(ao), outputForces(getNumberOfArguments(),0.0) { if(getStride()>1) error("Using bias with stride!=1 is not currently supported"); for(unsigned i=0;i<getNumberOfArguments();++i){ (getPntrToArgument(i)->getPntrToAction())->turnOnDerivatives(); } }
void Mapping::calculateNumericalDerivatives( ActionWithValue* a ){ if( getNumberOfAtoms()>0 ){ ActionWithArguments::calculateNumericalDerivatives( a ); } if( getNumberOfAtoms()>0 ){ Matrix<double> save_derivatives( getNumberOfComponents(), getNumberOfArguments() ); for(unsigned j=0;j<getNumberOfComponents();++j){ for(unsigned i=0;i<getNumberOfArguments();++i) save_derivatives(j,i)=getPntrToComponent(j)->getDerivative(i); } calculateAtomicNumericalDerivatives( a, getNumberOfArguments() ); for(unsigned j=0;j<getNumberOfComponents();++j){ for(unsigned i=0;i<getNumberOfArguments();++i) getPntrToComponent(j)->addDerivative( i, save_derivatives(j,i) ); } } }
void Function::addValueWithDerivatives() { plumed_massert( getNumberOfArguments()!=0, "for functions you must requestArguments before adding values"); ActionWithValue::addValueWithDerivatives(); getPntrToValue()->resizeDerivatives(getNumberOfArguments()); if( keywords.exists("PERIODIC") ) { std::vector<std::string> period; parseVector("PERIODIC",period); if(period.size()==1 && period[0]=="NO") { setNotPeriodic(); } else if(period.size()==2) { setPeriodic(period[0],period[1]); } else error("missing PERIODIC keyword"); } }
void Function::apply() { const unsigned noa=getNumberOfArguments(); const unsigned ncp=getNumberOfComponents(); const unsigned cgs=comm.Get_size(); vector<double> f(noa,0.0); unsigned stride=1; unsigned rank=0; if(ncp>4*cgs) { stride=comm.Get_size(); rank=comm.Get_rank(); } unsigned at_least_one_forced=0; #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(f) { vector<double> omp_f(noa,0.0); vector<double> forces(noa); #pragma omp for reduction( + : at_least_one_forced) for(unsigned i=rank; i<ncp; i+=stride) { if(getPntrToComponent(i)->applyForce(forces)) { at_least_one_forced+=1; for(unsigned j=0; j<noa; j++) omp_f[j]+=forces[j]; } } #pragma omp critical for(unsigned j=0; j<noa; j++) f[j]+=omp_f[j]; } if(noa>0&&ncp>4*cgs) { comm.Sum(&f[0],noa); comm.Sum(at_least_one_forced); } if(at_least_one_forced>0) for(unsigned i=0; i<noa; ++i) getPntrToArgument(i)->addForce(f[i]); }
void Bias::apply() { const unsigned noa=getNumberOfArguments(); const unsigned ncp=getNumberOfComponents(); if(onStep()) { double gstr = static_cast<double>(getStride()); for(unsigned i=0; i<noa; ++i) { getPntrToArgument(i)->addForce(gstr*outputForces[i]); } } // additional forces on the bias component std::vector<double> f(noa,0.0); std::vector<double> forces(noa); bool at_least_one_forced=false; for(unsigned i=0; i<ncp; ++i) { if(getPntrToComponent(i)->applyForce(forces)) { at_least_one_forced=true; for(unsigned j=0; j<noa; j++) f[j]+=forces[j]; } } if(at_least_one_forced && !onStep()) error("you are biasing a bias with an inconsistent STRIDE"); if(at_least_one_forced) for(unsigned i=0; i<noa; ++i) { getPntrToArgument(i)->addForce(f[i]); } }
unsigned Histogram::getNumberOfDerivatives() { if( in_apply ) { unsigned nder=0; for(unsigned i=0; i<myvessels.size(); ++i) nder += myvessels[i]->getNumberOfDerivatives(); return nder; } return getNumberOfArguments(); }
Bias::Bias(const ActionOptions&ao): Action(ao), ActionPilot(ao), ActionWithValue(ao), ActionWithArguments(ao), outputForces(getNumberOfArguments(),0.0) { if(getStride()>1) error("Using bias with stride!=1 is not currently supported"); }
Bias::Bias(const ActionOptions&ao): Action(ao), ActionPilot(ao), ActionWithValue(ao), ActionWithArguments(ao), outputForces(getNumberOfArguments(),0.0) { addComponentWithDerivatives("bias"); componentIsNotPeriodic("bias"); valueBias=getPntrToComponent("bias"); if(getStride()>1) { log<<" multiple time step "<<getStride()<<" "; log<<cite("Ferrarotti, Bottaro, Perez-Villa, and Bussi, J. Chem. Theory Comput. 11, 139 (2015)")<<"\n"; } for(unsigned i=0; i<getNumberOfArguments(); ++i) { (getPntrToArgument(i)->getPntrToAction())->turnOnDerivatives(); } turnOnDerivatives(); }
void Mapping::prepare(){ if( mymap->mappingNeedsSetup() ){ // Get the arguments and atoms that are required std::vector<AtomNumber> atoms; std::vector<std::string> args; mymap->getAtomAndArgumentRequirements( atoms, args ); requestAtoms( atoms ); std::vector<Value*> req_args; interpretArgumentList( args, req_args ); requestArguments( req_args ); // Duplicate all frames (duplicates are used by sketch-map) mymap->duplicateFrameList(); // Get the number of frames in the path unsigned nfram=getNumberOfReferencePoints(); fframes.resize( 2*nfram, 0.0 ); dfframes.resize( 2*nfram, 0.0 ); plumed_assert( !mymap->mappingNeedsSetup() ); // Resize all derivative arrays mymap->setNumberOfAtomsAndArguments( atoms.size(), args.size() ); // Resize forces array forcesToApply.resize( 3*getNumberOfAtoms() + 9 + getNumberOfArguments() ); } }
void FunctionHasColumnInTable::getReturnTypeAndPrerequisitesImpl( const ColumnsWithTypeAndName & arguments, DataTypePtr & out_return_type, ExpressionActions::Actions & out_prerequisites) { static const std::string arg_pos_description[] = {"First", "Second", "Third"}; for (size_t i = 0; i < getNumberOfArguments(); ++i) { const ColumnWithTypeAndName & argument = arguments[i]; const ColumnConstString * column = typeid_cast<const ColumnConstString *>(argument.column.get()); if (!column) { throw Exception( arg_pos_description[i] + " argument for function " + getName() + " must be const String.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); } } out_return_type = std::make_shared<DataTypeUInt8>(); }
void Histogram::prepareForAveraging() { if( myvessels.size()>0 ) { deactivateAllTasks(); double norm=0; for(unsigned i=0; i<stashes[0]->getNumberOfStoredValues(); ++i) { std::vector<double> cvals( myvessels[0]->getNumberOfQuantities() ); stashes[0]->retrieveSequentialValue( i, false, cvals ); unsigned itask=myvessels[0]->getActiveTask(i); double tnorm = cvals[0]; for(unsigned j=1; j<myvessels.size(); ++j) { if( myvessels[j]->getActiveTask(i)!=itask ) error("mismatched task identities in histogram suggests histogram is meaningless"); if( cvals.size()!=myvessels[j]->getNumberOfQuantities() ) cvals.resize( myvessels[j]->getNumberOfQuantities() ); stashes[j]->retrieveSequentialValue( i, false, cvals ); tnorm *= cvals[0]; } norm += tnorm; taskFlags[i]=1; } lockContributors(); // Sort out normalization of histogram if( !noNormalization() ) ww = cweight / norm; else ww = cweight; } else { // Now fetch the kernel and the active points std::vector<double> point( getNumberOfArguments() ); for(unsigned i=0; i<point.size(); ++i) point[i]=getArgument(i); unsigned num_neigh; std::vector<unsigned> neighbors(1); kernel = myhist->getKernelAndNeighbors( point, num_neigh, neighbors ); if( num_neigh>1 ) { // Activate relevant tasks deactivateAllTasks(); for(unsigned i=0; i<num_neigh; ++i) taskFlags[neighbors[i]]=1; lockContributors(); } else { // This is used when we are not doing kernel density evaluation mygrid->addToGridElement( neighbors[0], 0, cweight ); } } }
void Bias::apply(){ if(onStep()) for(unsigned i=0;i<getNumberOfArguments();++i){ getPntrToArgument(i)->addForce(getStride()*outputForces[i]); } }
void Mapping::apply(){ if( getForcesFromVessels( forcesToApply ) ){ addForcesOnArguments( forcesToApply ); if( getNumberOfAtoms()>0 ) setForcesOnAtoms( forcesToApply, getNumberOfArguments() ); } }
Mapping::Mapping(const ActionOptions&ao): Action(ao), ActionAtomistic(ao), ActionWithArguments(ao), ActionWithValue(ao), ActionWithVessel(ao) { // Read the input std::string mtype; parse("TYPE",mtype); bool skipchecks; parseFlag("DISABLE_CHECKS",skipchecks); // Setup the object that does the mapping mymap = new PointWiseMapping( mtype, skipchecks ); // Read the properties we require if( keywords.exists("PROPERTY") ){ std::vector<std::string> property; parseVector("PROPERTY",property); if(property.size()==0) error("no properties were specified"); mymap->setPropertyNames( property, false ); } else { std::vector<std::string> property(1); property[0]="sss"; mymap->setPropertyNames( property, true ); } // Open reference file std::string reference; parse("REFERENCE",reference); FILE* fp=fopen(reference.c_str(),"r"); if(!fp) error("could not open reference file " + reference ); // Read all reference configurations bool do_read=true; std::vector<double> weights; unsigned nfram=0, wnorm=0., ww; while (do_read){ PDB mypdb; // Read the pdb file do_read=mypdb.readFromFilepointer(fp,plumed.getAtoms().usingNaturalUnits(),0.1/atoms.getUnits().getLength()); // Fix argument names expandArgKeywordInPDB( mypdb ); if(do_read){ mymap->readFrame( mypdb ); ww=mymap->getWeight( nfram ); weights.push_back( ww ); wnorm+=ww; nfram++; } else { break; } } fclose(fp); if(nfram==0 ) error("no reference configurations were specified"); log.printf(" found %d configurations in file %s\n",nfram,reference.c_str() ); for(unsigned i=0;i<weights.size();++i) weights[i] /= wnorm; mymap->setWeights( weights ); // Finish the setup of the mapping object // Get the arguments and atoms that are required std::vector<AtomNumber> atoms; std::vector<std::string> args; mymap->getAtomAndArgumentRequirements( atoms, args ); requestAtoms( atoms ); std::vector<Value*> req_args; interpretArgumentList( args, req_args ); requestArguments( req_args ); // Duplicate all frames (duplicates are used by sketch-map) mymap->duplicateFrameList(); fframes.resize( 2*nfram, 0.0 ); dfframes.resize( 2*nfram, 0.0 ); plumed_assert( !mymap->mappingNeedsSetup() ); // Resize all derivative arrays mymap->setNumberOfAtomsAndArguments( atoms.size(), args.size() ); // Resize forces array if( getNumberOfAtoms()>0 ){ forcesToApply.resize( 3*getNumberOfAtoms() + 9 + getNumberOfArguments() ); } else { forcesToApply.resize( getNumberOfArguments() ); } }
/* Procedure checkNode performs * type checking at a single tree node */ static void checkNode(TreeNode * t) { switch (t->nodekind) { case DecK: if ((t->detailKind).kindInDecl == VarK) { if ((t->bDataType) == Void) { typeError(t, "Variable cannot be of type void !"); exit(-10); } } break; case ExpK: // +, *, -, /, <=, >=, ==, !=, >, < if ((t->detailKind).kindInExp == CalcK) { if ( ((t->child[0]->bDataType) == Integer) && ((t->child[1]->bDataType) == Integer)) { t->bDataType = Integer; } else { typeError(t, "Calculation Error, There is at least one void type at calculation expression"); exit(-10); } } break; case StmtK: /* assignment statement */ /* rvalue should be Integer */ if ((t->detailKind).kindInStmt == AssignK) { TreeNode *rightChild = t->child[1]; if (rightChild->bDataType != Integer) { typeError(t, "Assign statement Error, rvalue should be Integer!"); exit(-10); } else { t->bDataType = rightChild->bDataType; } } /* Function Call Statement */ /* determine Node of Callk's type */ else if((t->detailKind).kindInStmt == CallK) { BucketListEntity *pFunctionCall = st_lookup_atCharScope("", t->name); int count = 0; int bTypeOfFunctionCall = pFunctionCall->bType; count = getNumberOfArguments(t->child[0]); if (pFunctionCall->nArguments != count) { typeError(t, "# of Arguments in Call Statment is not consistent with # of Arguments in Function Declaration"); exit(-10); } if (bTypeOfFunctionCall == 1) /* if the type of return value is Integer */ { t->bDataType = Integer; } else { t->bDataType = Void; } } /* return statement */ else if((t->detailKind).kindInStmt == RetK) { char *pszFuncName = NULL; BucketListEntity *pFunctionEntity = NULL; pszFuncName = strtok(gScope, ":"); pFunctionEntity = st_lookup_atCharScope("", pszFuncName); if(pFunctionEntity->bType == 1) { /* function returns int but return statement doesn't return */ if(t->bReturnWithValue == 0) { typeError(t, "Function should return!"); exit(-10); } else { if ((t->child[0])->bDataType != Integer) { typeError(t, "Function that returns int cannot return void type"); exit(-10); } } } else { /* function cannot return the value, but return statement has a value to return */ if(t->bReturnWithValue == 1) { typeError(t, "Function cannot return any value"); exit(-10); } } } /* when encounters if statement, conditional expression should be of type Integer */ else if((t->detailKind).kindInStmt == SelK) { if ((t->child[0]->bDataType) != Integer) { typeError(t, "expression in If statement should be of type Integer!"); exit(-10); } } break; default: break; } }
/* Procedure insertNode inserts * identifiers stored in t into * the symbol table */ static void insertNode(TreeNode * t) { switch (t->nodekind) { case StmtK: if ((t->detailKind).kindInStmt == CallK) { BucketListEntity *pTemp = st_lookup_at_now_scope("", t->name); if (pTemp == NULL) { fprintf(listing,"Line = %d, Function didn't declared.. \n",t->lineno); exit(-2); } else { addLine("", t->name, t->lineno); } } break; case ExpK: if ((t->detailKind).kindInExp == IdK) { BucketListEntity *pTemp = st_lookup_atCharScope(gScope, t->name); if (pTemp == NULL) { fprintf(listing, "Line = %d, Id didn't declared.. \n", t->lineno); exit(-2); } else { addLine(gScope, t->name, t->lineno); } } break; case DecK: switch((t->detailKind).kindInDecl) { /**/ case VarK: { BucketListEntity *pTemp = st_lookup_at_now_scope(gScope, t->name); if (pTemp == NULL) /* there is no t->name at Symbol Table of gScope*/ { if (t->bWithIndex == 1) { st_insert_atCharScope(gScope, t->name, 1, gLocation, 1, -1, t->lineno); } else { st_insert_atCharScope(gScope, t->name, 1, gLocation, 0, -1 , t->lineno); } } else { fprintf(listing, "Line = %d, Var Decl Error, Already Declared.!\n",t->lineno); exit(-2); } } break; case FunK: { // Find the symbol at global scope() BucketListEntity *pTemp = st_lookup_at_now_scope("", t->name); // If function declaration is not in the symbol table. if (pTemp == NULL) { gbNowFunctionDeclaration = 1; int paramCount = getNumberOfArguments(t->child[0]); if (t->bDataType == Integer) { st_insert_atCharScope("",t->name, 1, gLocation,0, paramCount,t->lineno); } else { st_insert_atCharScope("", t->name, 0, gLocation, 0, paramCount,t->lineno); } } else { fprintf(listing, "Line = %d, Func Decl Error, Already Declared!\n", t->lineno); exit(-2); } } break; case ParamK: // Parameter Declaration. { BucketListEntity *pTemp = st_lookup_at_now_scope(gScope, t->name); if (pTemp == NULL) { if (t->bWithIndex == 1) { st_insert_atCharScope(gScope, t->name, 1, gLocation, 1, -1,t->lineno); } else { st_insert_atCharScope(gScope, t->name, 1, gLocation, 0, -1,t->lineno); } } else { fprintf(listing, "Line = %d, Parameter Decl Error, Already Declared..\n",t->lineno); } } break; default: break; } break; } }
void Histogram::compute( const unsigned& current, MultiValue& myvals ) const { if( mvectors ) { std::vector<double> cvals( myvessels[0]->getNumberOfQuantities() ); stashes[0]->retrieveSequentialValue( current, true, cvals ); for(unsigned i=2; i<myvessels[0]->getNumberOfQuantities(); ++i) myvals.setValue( i-1, cvals[i] ); myvals.setValue( 0, cvals[0] ); myvals.setValue( myvessels[0]->getNumberOfQuantities() - 1, ww ); if( in_apply ) { MultiValue& tmpval = stashes[0]->getTemporyMultiValue(0); if( tmpval.getNumberOfValues()!=myvessels[0]->getNumberOfQuantities() || tmpval.getNumberOfDerivatives()!=myvessels[0]->getNumberOfDerivatives() ) tmpval.resize( myvessels[0]->getNumberOfQuantities(), myvessels[0]->getNumberOfDerivatives() ); stashes[0]->retrieveDerivatives( stashes[0]->getTrueIndex(current), true, tmpval ); for(unsigned j=0; j<tmpval.getNumberActive(); ++j) { unsigned jder=tmpval.getActiveIndex(j); myvals.addDerivative( 0, jder, tmpval.getDerivative(0, jder) ); for(unsigned i=2; i<myvessels[0]->getNumberOfQuantities(); ++i) myvals.addDerivative( i-1, jder, tmpval.getDerivative(i, jder) ); } myvals.updateDynamicList(); } } else if( myvessels.size()>0 ) { std::vector<double> cvals( myvessels[0]->getNumberOfQuantities() ); stashes[0]->retrieveSequentialValue( current, false, cvals ); unsigned derbase; double totweight=cvals[0], tnorm = cvals[0]; myvals.setValue( 1, cvals[1] ); // Get the derivatives as well if we are in apply if( in_apply ) { // This bit gets the total weight double weight0 = cvals[0]; // Store the current weight for(unsigned j=1; j<myvessels.size(); ++j) { stashes[j]->retrieveSequentialValue( current, false, cvals ); totweight *= cvals[0]; } // And this bit the derivatives MultiValue& tmpval = stashes[0]->getTemporyMultiValue(0); if( tmpval.getNumberOfValues()!=myvessels[0]->getNumberOfQuantities() || tmpval.getNumberOfDerivatives()!=myvessels[0]->getNumberOfDerivatives() ) tmpval.resize( myvessels[0]->getNumberOfQuantities(), myvessels[0]->getNumberOfDerivatives() ); stashes[0]->retrieveDerivatives( stashes[0]->getTrueIndex(current), false, tmpval ); for(unsigned j=0; j<tmpval.getNumberActive(); ++j) { unsigned jder=tmpval.getActiveIndex(j); myvals.addDerivative( 1, jder, tmpval.getDerivative(1,jder) ); myvals.addDerivative( 0, jder, (totweight/weight0)*tmpval.getDerivative(0,jder) ); } derbase = myvessels[0]->getNumberOfDerivatives(); } for(unsigned i=1; i<myvessels.size(); ++i) { if( cvals.size()!=myvessels[i]->getNumberOfQuantities() ) cvals.resize( myvessels[i]->getNumberOfQuantities() ); stashes[i]->retrieveSequentialValue( current, false, cvals ); tnorm *= cvals[0]; myvals.setValue( 1+i, cvals[1] ); // Get the derivatives as well if we are in apply if( in_apply ) { MultiValue& tmpval = stashes[0]->getTemporyMultiValue(0); if( tmpval.getNumberOfValues()!=myvessels[0]->getNumberOfQuantities() || tmpval.getNumberOfDerivatives()!=myvessels[0]->getNumberOfDerivatives() ) tmpval.resize( myvessels[0]->getNumberOfQuantities(), myvessels[0]->getNumberOfDerivatives() ); stashes[i]->retrieveDerivatives( stashes[i]->getTrueIndex(current), false, tmpval ); for(unsigned j=0; j<tmpval.getNumberActive(); ++j) { unsigned jder=tmpval.getActiveIndex(j); myvals.addDerivative( 1+i, derbase+jder, tmpval.getDerivative(1,jder) ); myvals.addDerivative( 0, derbase+jder, (totweight/cvals[0])*tmpval.getDerivative(0,jder) ); } derbase += myvessels[i]->getNumberOfDerivatives(); } } myvals.setValue( 0, tnorm ); myvals.setValue( 1+myvessels.size(), ww ); if( in_apply ) myvals.updateDynamicList(); } else { plumed_assert( !in_apply ); std::vector<Value*> vv( myhist->getVectorOfValues() ); std::vector<double> val( getNumberOfArguments() ), der( getNumberOfArguments() ); // Retrieve the location of the grid point at which we are evaluating the kernel mygrid->getGridPointCoordinates( current, val ); if( kernel ) { for(unsigned i=0; i<getNumberOfArguments(); ++i) vv[i]->set( val[i] ); // Evaluate the histogram at the relevant grid point and set the values double vvh = kernel->evaluate( vv, der,true); myvals.setValue( 1, vvh ); } else { plumed_merror("normalisation of vectors does not work with arguments and spherical grids"); // Evalulate dot product double dot=0; for(unsigned j=0; j<getNumberOfArguments(); ++j) { dot+=val[j]*getArgument(j); der[j]=val[j]; } // Von misses distribution for concentration parameter double newval = (myhist->von_misses_norm)*exp( (myhist->von_misses_concentration)*dot ); myvals.setValue( 1, newval ); // And final derivatives for(unsigned j=0; j<getNumberOfArguments(); ++j) der[j] *= (myhist->von_misses_concentration)*newval; } // Set the derivatives and delete the vector of values for(unsigned i=0; i<getNumberOfArguments(); ++i) { myvals.setDerivative( 1, i, der[i] ); delete vv[i]; } } }
void Function::addComponentWithDerivatives( const std::string& name ) { plumed_massert( getNumberOfArguments()!=0, "for functions you must requestArguments before adding values"); ActionWithValue::addComponentWithDerivatives(name); getPntrToComponent(name)->resizeDerivatives(getNumberOfArguments()); }