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 6 : } 32 : 33 0 : PammObject::PammObject( const PammObject& in ): 34 0 : regulariser(in.regulariser), 35 0 : pbc(in.pbc), 36 0 : min(in.min), 37 0 : max(in.max) { 38 0 : for(unsigned i=0; i<in.kernels.size(); ++i) { 39 0 : kernels.emplace_back( Tools::make_unique<KernelFunctions>( in.kernels[i].get() ) ); 40 : } 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; 47 6 : regulariser=reg; 48 6 : if( !ifile.FileExist(filename) ) { 49 0 : errorstr = "could not find file named " + filename; 50 : return; 51 : } 52 : 53 : std::vector<std::unique_ptr<Value>> pos; 54 6 : pbc.resize( valnames.size() ); 55 6 : min.resize( valnames.size() ); 56 6 : max.resize( valnames.size() ); 57 21 : for(unsigned i=0; i<valnames.size(); ++i) { 58 15 : pbc[i]=pbcin[i]; 59 : min[i]=imin[i]; 60 : max[i]=imax[i]; 61 15 : pos.emplace_back( Tools::make_unique<Value>() ); 62 15 : if( !pbc[i] ) { 63 13 : pos[i]->setNotPeriodic(); 64 : } else { 65 2 : pos[i]->setDomain( min[i], max[i] ); 66 : } 67 : } 68 : 69 6 : ifile.open(filename); 70 6 : ifile.allowIgnoredFields(); 71 6 : kernels.resize(0); 72 : for(unsigned k=0;; ++k) { 73 59 : std::unique_ptr<KernelFunctions> kk = KernelFunctions::read( &ifile, false, valnames ); 74 59 : if( !kk ) { 75 : break ; 76 : } 77 53 : kk->normalize( Tools::unique2raw( pos ) ); 78 53 : kernels.emplace_back( std::move(kk) ); 79 53 : ifile.scanField(); 80 59 : } 81 6 : ifile.close(); 82 6 : } 83 : 84 787044 : void PammObject::evaluate( const std::vector<double>& invar, std::vector<double>& outvals, std::vector<std::vector<double> >& der ) const { 85 : std::vector<std::unique_ptr<Value>> pos; 86 3148138 : for(unsigned i=0; i<pbc.size(); ++i) { 87 2361094 : pos.emplace_back( Tools::make_unique<Value>() ); 88 2361094 : if( !pbc[i] ) { 89 2361058 : pos[i]->setNotPeriodic(); 90 : } else { 91 36 : pos[i]->setDomain( min[i], max[i] ); 92 : } 93 : // And set the value 94 2361094 : pos[i]->set( invar[i] ); 95 : } 96 : 97 : // convert pointers once 98 787044 : auto pos_ptr=Tools::unique2raw(pos); 99 : 100 : // Evaluate the set of kernels 101 787044 : double denom=regulariser; 102 787044 : std::vector<double> dderiv( der[0].size(), 0 ); 103 9444366 : for(unsigned i=0; i<kernels.size(); ++i) { 104 8657322 : outvals[i]=kernels[i]->evaluate( pos_ptr, der[i] ); 105 8657322 : denom+=outvals[i]; 106 34629122 : for(unsigned j=0; j<der[i].size(); ++j) { 107 25971800 : dderiv[j] += der[i][j]; 108 : } 109 : } 110 : // Evaluate the set of derivatives 111 9444366 : for(unsigned i=0; i<kernels.size(); ++i) { 112 8657322 : outvals[i]/=denom; 113 34629122 : for(unsigned j=0; j<der[i].size(); ++j) { 114 25971800 : der[i][j]=der[i][j]/denom - outvals[i]*dderiv[j]/denom; 115 : } 116 : } 117 : 118 787044 : } 119 : 120 : 121 : } 122 : }