Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2015-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 "PammObject.h" 23 : #include "tools/IFile.h" 24 : #include <memory> 25 : 26 : namespace PLMD { 27 : namespace pamm { 28 : 29 6 : PammObject::PammObject(): 30 6 : regulariser(0.001) 31 : { 32 6 : } 33 : 34 0 : PammObject::PammObject( const PammObject& in ): 35 0 : regulariser(in.regulariser), 36 0 : pbc(in.pbc), 37 0 : min(in.min), 38 0 : max(in.max) 39 : { 40 0 : for(unsigned i=0; i<in.kernels.size(); ++i) kernels.emplace_back( Tools::make_unique<KernelFunctions>( in.kernels[i].get() ) ); 41 0 : } 42 : 43 6 : void PammObject::setup( const std::string& filename, const double& reg, const std::vector<std::string>& valnames, 44 : const std::vector<bool>& pbcin, const std::vector<std::string>& imin, const std::vector<std::string>& imax, 45 : std::string& errorstr ) { 46 6 : IFile ifile; regulariser=reg; 47 6 : if( !ifile.FileExist(filename) ) { 48 0 : errorstr = "could not find file named " + filename; 49 : return; 50 : } 51 : 52 : std::vector<std::unique_ptr<Value>> pos; 53 6 : pbc.resize( valnames.size() ); 54 6 : min.resize( valnames.size() ); 55 6 : max.resize( valnames.size() ); 56 21 : for(unsigned i=0; i<valnames.size(); ++i) { 57 15 : pbc[i]=pbcin[i]; min[i]=imin[i]; max[i]=imax[i]; 58 15 : pos.emplace_back( Tools::make_unique<Value>() ); 59 15 : if( !pbc[i] ) pos[i]->setNotPeriodic(); 60 2 : else pos[i]->setDomain( min[i], max[i] ); 61 : } 62 : 63 6 : ifile.open(filename); ifile.allowIgnoredFields(); kernels.resize(0); 64 : for(unsigned k=0;; ++k) { 65 59 : std::unique_ptr<KernelFunctions> kk = KernelFunctions::read( &ifile, false, valnames ); 66 59 : if( !kk ) break ; 67 53 : kk->normalize( Tools::unique2raw( pos ) ); 68 53 : kernels.emplace_back( std::move(kk) ); 69 53 : ifile.scanField(); 70 59 : } 71 6 : ifile.close(); 72 6 : } 73 : 74 787044 : void PammObject::evaluate( const std::vector<double>& invar, std::vector<double>& outvals, std::vector<std::vector<double> >& der ) const { 75 : std::vector<std::unique_ptr<Value>> pos; 76 3148138 : for(unsigned i=0; i<pbc.size(); ++i) { 77 2361094 : pos.emplace_back( Tools::make_unique<Value>() ); 78 2361094 : if( !pbc[i] ) pos[i]->setNotPeriodic(); 79 36 : else pos[i]->setDomain( min[i], max[i] ); 80 : // And set the value 81 2361094 : pos[i]->set( invar[i] ); 82 : } 83 : 84 : // convert pointers once 85 787044 : auto pos_ptr=Tools::unique2raw(pos); 86 : 87 : // Evaluate the set of kernels 88 787044 : double denom=regulariser; std::vector<double> dderiv( der[0].size(), 0 ); 89 9444366 : for(unsigned i=0; i<kernels.size(); ++i) { 90 8657322 : outvals[i]=kernels[i]->evaluate( pos_ptr, der[i] ); denom+=outvals[i]; 91 34629122 : for(unsigned j=0; j<der[i].size(); ++j) dderiv[j] += der[i][j]; 92 : } 93 : // Evaluate the set of derivatives 94 9444366 : for(unsigned i=0; i<kernels.size(); ++i) { 95 8657322 : outvals[i]/=denom; 96 34629122 : for(unsigned j=0; j<der[i].size(); ++j) der[i][j]=der[i][j]/denom - outvals[i]*dderiv[j]/denom; 97 : } 98 : 99 787044 : } 100 : 101 : 102 : } 103 : }