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 : // Setup the min and max values for the grid
52 1 : std::vector<std::string> gmin( nfg.size() ), gmax( nfg.size() );
53 1 : std::vector<bool> pbc( nfg.size(), false );
54 : std::vector<double> dummy_spacing;
55 3 : for(unsigned i=0; i<nfg.size(); ++i) {
56 2 : Tools::convert(mmin[i],gmin[i]);
57 2 : Tools::convert(mmax[i],gmax[i]);
58 : }
59 : // Create the coarse grid grid objects
60 1 : mygrid.setup( "flat", pbc, 0, 0.0 );
61 1 : mygrid.setBounds( gmin, gmax, ng, dummy_spacing );
62 : // Setup the fine grid object
63 1 : if( nfg[0]>0 ) {
64 1 : using_fgrid=true;
65 1 : myfgrid.setup("flat", pbc, 0, 0.0 );
66 1 : dummy_spacing.resize(0);
67 1 : myfgrid.setBounds( gmin, gmax, nfg, dummy_spacing );
68 : }
69 2 : value.reset( new Value( NULL, "gval", true, mygrid.getNbin(true)) );
70 1 : myinterp.reset( new Interpolator( value.get(), mygrid ) );
71 1 : }
72 : void setGridElement( const unsigned& ind, const double& emin, const std::vector<double>& der );
73 : bool minimise( std::vector<double>& p, engf_pointer myfunc );
74 : };
75 :
76 : template <class FCLASS>
77 24200 : void GridSearch<FCLASS>::setGridElement( const unsigned& ind, const double& emin, const std::vector<double>& der ) {
78 24200 : value->set( ind, emin );
79 72600 : for(unsigned j=0; j<der.size(); ++j) {
80 : value->setGridDerivatives( ind, j, der[j] );
81 : }
82 24200 : }
83 :
84 : template <class FCLASS>
85 200 : bool GridSearch<FCLASS>::minimise( std::vector<double>& p, engf_pointer myfunc ) {
86 200 : std::vector<double> der( p.size() );
87 200 : std::vector<double> coords( p.size() );
88 200 : double initial_eng = (myclass_func->*myfunc)( p, der );
89 200 : mygrid.getGridPointCoordinates( 0, coords );
90 200 : unsigned pmin=0;
91 200 : double emin=(myclass_func->*myfunc)( coords, der );
92 200 : setGridElement( 0, emin, der );
93 24200 : for(unsigned i=1; i<mygrid.getNumberOfPoints(); ++i) {
94 24000 : mygrid.getGridPointCoordinates( i, coords );
95 24000 : double eng = (myclass_func->*myfunc)( coords, der );
96 24000 : setGridElement( i, eng, der );
97 24000 : if( eng<emin ) {
98 2344 : emin=eng;
99 2344 : pmin=i;
100 : }
101 : }
102 :
103 200 : if( using_fgrid ) {
104 200 : myfgrid.getGridPointCoordinates( 0, coords );
105 200 : pmin=0;
106 200 : double emin = myinterp->splineInterpolation( coords, der );
107 520200 : for(unsigned i=1; i<myfgrid.getNumberOfPoints(); ++i) {
108 520000 : myfgrid.getGridPointCoordinates( i, coords );
109 520000 : double eng = myinterp->splineInterpolation( coords, der );
110 520000 : if( eng<emin ) {
111 : emin=eng;
112 16431 : pmin=i;
113 : }
114 : }
115 200 : myfgrid.getGridPointCoordinates( pmin, coords );
116 200 : double checkEng = (myclass_func->*myfunc)( coords, der );
117 200 : if( checkEng<initial_eng ) {
118 22 : myfgrid.getGridPointCoordinates( pmin, p );
119 : return true;
120 : } else {
121 : return false;
122 : }
123 : }
124 :
125 0 : if( emin<initial_eng ) {
126 0 : mygrid.getGridPointCoordinates( pmin, p );
127 : return true;
128 : }
129 : return false;
130 : }
131 :
132 : }
133 : }
134 : #endif
135 :
|