Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2016-2024 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 : #ifndef __PLUMED_gridtools_GridSearch_h
23 : #define __PLUMED_gridtools_GridSearch_h
24 :
25 : #include "core/Value.h"
26 : #include "tools/MinimiseBase.h"
27 : #include "GridCoordinatesObject.h"
28 : #include "Interpolator.h"
29 : #include <iostream>
30 : #include <memory>
31 :
32 : namespace PLMD {
33 : namespace gridtools {
34 :
35 : template <class FCLASS>
36 : class GridSearch {
37 : private:
38 : /// This is the pointer to the member function in the energy
39 : /// calculating class that calculates the energy
40 : typedef double(FCLASS::*engf_pointer)( const std::vector<double>& p, std::vector<double>& der );
41 : FCLASS* myclass_func;
42 : bool using_fgrid;
43 : std::unique_ptr<Value> value;
44 : std::unique_ptr<Interpolator> myinterp;
45 : GridCoordinatesObject mygrid;
46 : GridCoordinatesObject myfgrid;
47 : public:
48 1 : GridSearch( const std::vector<double>& mmin, const std::vector<double>& mmax, const std::vector<unsigned>& ng, const std::vector<unsigned>& nfg, FCLASS* funcc ) :
49 1 : myclass_func( funcc ),
50 1 : using_fgrid(false)
51 : {
52 : // Setup the min and max values for the grid
53 1 : std::vector<std::string> gmin( nfg.size() ), gmax( nfg.size() );
54 1 : std::vector<bool> pbc( nfg.size(), false ); std::vector<double> dummy_spacing;
55 3 : for(unsigned i=0; i<nfg.size(); ++i) { Tools::convert(mmin[i],gmin[i]); Tools::convert(mmax[i],gmax[i]); }
56 : // Create the coarse grid grid objects
57 1 : mygrid.setup( "flat", pbc, 0, 0.0 );
58 1 : mygrid.setBounds( gmin, gmax, ng, dummy_spacing );
59 : // Setup the fine grid object
60 1 : if( nfg[0]>0 ) {
61 2 : using_fgrid=true; myfgrid.setup("flat", pbc, 0, 0.0 ); dummy_spacing.resize(0);
62 1 : myfgrid.setBounds( gmin, gmax, nfg, dummy_spacing );
63 : }
64 2 : value.reset( new Value( NULL, "gval", true, mygrid.getNbin(true)) );
65 1 : myinterp.reset( new Interpolator( value.get(), mygrid ) );
66 1 : }
67 : void setGridElement( const unsigned& ind, const double& emin, const std::vector<double>& der );
68 : bool minimise( std::vector<double>& p, engf_pointer myfunc );
69 : };
70 :
71 : template <class FCLASS>
72 24200 : void GridSearch<FCLASS>::setGridElement( const unsigned& ind, const double& emin, const std::vector<double>& der ) {
73 72600 : value->set( ind, emin ); for(unsigned j=0; j<der.size(); ++j) value->setGridDerivatives( ind, j, der[j] );
74 24200 : }
75 :
76 : template <class FCLASS>
77 200 : bool GridSearch<FCLASS>::minimise( std::vector<double>& p, engf_pointer myfunc ) {
78 200 : std::vector<double> der( p.size() ); std::vector<double> coords( p.size() );
79 200 : double initial_eng = (myclass_func->*myfunc)( p, der );
80 200 : mygrid.getGridPointCoordinates( 0, coords ); unsigned pmin=0;
81 200 : double emin=(myclass_func->*myfunc)( coords, der ); setGridElement( 0, emin, der );
82 24200 : for(unsigned i=1; i<mygrid.getNumberOfPoints(); ++i) {
83 24000 : mygrid.getGridPointCoordinates( i, coords );
84 24000 : double eng = (myclass_func->*myfunc)( coords, der );
85 24000 : setGridElement( i, eng, der );
86 24000 : if( eng<emin ) { emin=eng; pmin=i; }
87 : }
88 :
89 200 : if( using_fgrid ) {
90 200 : myfgrid.getGridPointCoordinates( 0, coords ); pmin=0;
91 200 : double emin = myinterp->splineInterpolation( coords, der );
92 520200 : for(unsigned i=1; i<myfgrid.getNumberOfPoints(); ++i) {
93 520000 : myfgrid.getGridPointCoordinates( i, coords );
94 520000 : double eng = myinterp->splineInterpolation( coords, der );
95 520000 : if( eng<emin ) { emin=eng; pmin=i; }
96 : }
97 200 : myfgrid.getGridPointCoordinates( pmin, coords );
98 200 : double checkEng = (myclass_func->*myfunc)( coords, der );
99 200 : if( checkEng<initial_eng ) {
100 22 : myfgrid.getGridPointCoordinates( pmin, p );
101 : return true;
102 : } else {
103 : return false;
104 : }
105 : }
106 :
107 0 : if( emin<initial_eng ) {
108 0 : mygrid.getGridPointCoordinates( pmin, p );
109 : return true;
110 : }
111 : return false;
112 : }
113 :
114 : }
115 : }
116 : #endif
117 :
|