https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PMCMCBase.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#include "PMCMCBase.h"
12#include "Uniform.h"
13#include "DelimitedFileReader.h"
14
15registerMooseObject("StochasticToolsApp", PMCMCBase);
16
19{
21 params.addClassDescription("Parallel Markov chain Monte Carlo base.");
22 params.addRequiredParam<std::vector<DistributionName>>(
23 "prior_distributions", "The prior distributions of the parameters to be calibrated.");
24 params.addParam<DistributionName>(
25 "prior_variance", "The prior distribution of the variance parameter to be calibrated.");
26 params.addRequiredParam<unsigned int>(
27 "num_parallel_proposals",
28 "Number of proposals to make and corresponding subApps executed in "
29 "parallel.");
30 params.addRequiredParam<FileName>("file_name", "Name of the CSV file with configuration values.");
31 params.addParam<std::string>(
32 "file_column_name", "Name of column in CSV file to use, by default first column is used.");
33 params.addParam<unsigned int>(
34 "num_columns", "Number of columns to be used in the CSV file with the configuration values.");
35 params.addParam<std::vector<Real>>("lower_bound", "Lower bounds for making the next proposal.");
36 params.addParam<std::vector<Real>>("upper_bound", "Upper bounds for making the next proposal.");
37 params.addParam<Real>("variance_bound",
38 std::numeric_limits<Real>::max(),
39 "Upper bound for variance for making the next proposal.");
40 params.addRequiredParam<std::vector<Real>>("initial_values",
41 "The starting values of the inputs to be calibrated.");
42 params.addParam<unsigned int>(
43 "num_random_seeds",
44 100000,
45 "Initialize a certain number of random seeds. Change from the default only if you have to.");
46 return params;
47}
48
50 : Sampler(parameters),
52 _num_parallel_proposals(getParam<unsigned int>("num_parallel_proposals")),
53 _lower_bound(isParamValid("lower_bound") ? &getParam<std::vector<Real>>("lower_bound")
54 : nullptr),
55 _upper_bound(isParamValid("upper_bound") ? &getParam<std::vector<Real>>("upper_bound")
56 : nullptr),
57 _variance_bound(getParam<Real>("variance_bound")),
58 _initial_values(getParam<std::vector<Real>>("initial_values")),
59 _new_var_samples(declareRecoverableData<std::vector<Real>>("new_var_samples")),
60 _rnd_vec(declareRecoverableData<std::vector<Real>>("rnd_vec")),
61 _num_random_seeds(getParam<unsigned int>("num_random_seeds")),
62 _seed_index(0),
63 _rand_index(0),
64 _new_samples_confg(declareRecoverableData<std::vector<std::vector<Real>>>("new_samples_confg"))
65{
66 // Filling the `priors` vector with the user-provided distributions.
67 for (const DistributionName & name :
68 getParam<std::vector<DistributionName>>("prior_distributions"))
70
71 // Filling the `var_prior` object with the user-provided distribution for the variance.
72 if (isParamValid("prior_variance"))
73 _var_prior = &getDistributionByName(getParam<DistributionName>("prior_variance"));
74 else
75 _var_prior = nullptr;
76
77 // Read the experimental configurations from a csv file
78 MooseUtils::DelimitedFileReader reader(getParam<FileName>("file_name"));
79 reader.read();
80 _confg_values.resize(1);
81 if (isParamValid("file_column_name"))
82 _confg_values[0] = reader.getData(getParam<std::string>("file_column_name"));
83 else if (isParamValid("num_columns"))
84 {
85 _confg_values.resize(getParam<unsigned int>("num_columns"));
86 for (unsigned int i = 0; i < _confg_values.size(); ++i)
87 _confg_values[i] = reader.getData(i);
88 }
89 else
90 _confg_values[0] = reader.getData(0);
91
92 // Setting the number of sampler rows to be equal to the number of parallel proposals
94
95 // Setting the number of columns in the sampler matrix (equal to the number of distributions).
96 setNumberOfCols(_priors.size() + _confg_values.size());
97
98 // Resizing the vectors and vector of vectors
101 std::vector<Real>(_priors.size() + _confg_values.size(), 0.0));
104
107
108 // Check whether both the lower and the upper bounds are specified and of same size
109 bool bound_check1 = _lower_bound && !_upper_bound;
110 bool bound_check2 = !_lower_bound && _upper_bound;
111 if (bound_check1 || bound_check2)
112 mooseError("Both lower and upper bounds should be specified.");
113 bool size_check = _lower_bound ? ((*_lower_bound).size() != (*_upper_bound).size()) : 0;
114 if (size_check)
115 mooseError("Lower and upper bounds should be of the same size.");
116
117 // Check whether the priors, bounds, and initial values are all of the same size
118 if (_priors.size() != _initial_values.size())
119 mooseError("The priors and initial values should be of the same size.");
120}
121
122void
124{
125 for (unsigned int j = 0; j < _num_parallel_proposals; ++j)
126 for (unsigned int i = 0; i < _priors.size(); ++i)
127 _new_samples[j][i] = _priors[i]->quantile(random());
128}
129
130void
132{
134 _rand_index = 0;
135
136 // Filling the new_samples vector of vectors with new proposal samples
138
139 // At the first step, override with user-provided initial values
140 if (_t_step < 1)
141 for (unsigned int i = 0; i < _num_parallel_proposals; ++i)
143
144 // Draw random numbers to facilitate decision making later on
145 for (unsigned int j = 0; j < _num_parallel_proposals; ++j)
146 _rnd_vec[j] = random();
147
148 // Combine the proposed samples with experimental configurations
150}
151
152Real
157
158unsigned int
159PMCMCBase::randomIndex(const unsigned int & upper_bound, const unsigned int & exclude)
160{
161 auto req_index = exclude;
162 while (req_index == exclude)
163 req_index = getRandl(_rand_index++, 0, upper_bound, _seed_index);
164 return req_index;
165}
166
167std::pair<unsigned int, unsigned int>
168PMCMCBase::randomIndexPair(const unsigned int & upper_bound, const unsigned int & exclude)
169{
170 auto req_index1 = randomIndex(upper_bound, exclude);
171 auto req_index2 = req_index1;
172 while (req_index1 == req_index2)
173 req_index2 = randomIndex(upper_bound, exclude);
174 return {req_index1, req_index2};
175}
176
177void
179{
180 unsigned int index1;
181 int index2 = -1;
182 std::vector<Real> tmp;
183 for (unsigned int i = 0; i < _num_parallel_proposals * _confg_values[0].size(); ++i)
184 {
185 index1 = i % _num_parallel_proposals;
186 if (index1 == 0)
187 ++index2;
188 tmp = _new_samples[index1];
189 for (unsigned int j = 0; j < _confg_values.size(); ++j)
190 tmp.push_back(_confg_values[j][index2]);
191 _new_samples_confg[i] = tmp;
192 }
193}
194
195const std::vector<Real> &
197{
198 return _rnd_vec;
199}
200
201const std::vector<Real> &
203{
204 return _new_var_samples;
205}
206
207const std::vector<std::vector<Real>> &
209{
210 return _new_samples;
211}
212
213const std::vector<const Distribution *>
215{
216 return _priors;
217}
218
219const Distribution *
221{
222 return _var_prior;
223}
224
225Real
226PMCMCBase::computeSample(dof_id_type row_index, dof_id_type col_index) const
227{
228 return _new_samples_confg[row_index][col_index];
229}
registerMooseObject("StochasticToolsApp", PMCMCBase)
void ErrorVector unsigned int
const Distribution & getDistributionByName(const DistributionName &name) const
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
const std::string & name() const
void mooseError(Args &&... args) const
bool isParamValid(const std::string &name) const
const std::vector< std::vector< T > > & getData() const
A base class used to perform Parallel Markov Chain Monte Carlo (MCMC) sampling.
Definition PMCMCBase.h:20
const std::vector< Real > * _lower_bound
Lower bounds for making the next proposal.
Definition PMCMCBase.h:121
std::vector< Real > & _rnd_vec
Vector of random numbers for decision making.
Definition PMCMCBase.h:139
const std::vector< std::vector< Real > > & getSamples() const
Return the proposed samples to facilitate decision making in reporters.
Definition PMCMCBase.C:208
std::vector< const Distribution * > _priors
Storage for prior distribution objects to be utilized.
Definition PMCMCBase.h:115
const std::vector< Real > & getVarSamples() const
Return the proposed variance samples to facilitate decision making in reporters.
Definition PMCMCBase.C:202
void combineWithExperimentalConfig()
Generates combinations of the new samples with the experimental configurations.
Definition PMCMCBase.C:178
std::vector< std::vector< Real > > & _new_samples_confg
Vectors of new proposed samples combined with the experimental configuration values.
Definition PMCMCBase.h:160
const std::vector< const Distribution * > getPriors() const
Return the priors to facilitate decision making in reporters.
Definition PMCMCBase.C:214
static InputParameters validParams()
Definition PMCMCBase.C:18
Real random()
Sample a random number between 0 and 1.
Definition PMCMCBase.C:153
unsigned int _seed_index
Generator index when requesting random numbers.
Definition PMCMCBase.h:151
const std::vector< Real > & _initial_values
Initial values of the input params to get the MCMC scheme started.
Definition PMCMCBase.h:130
virtual Real computeSample(dof_id_type row_index, dof_id_type col_index) const override
Definition PMCMCBase.C:226
virtual void executeSetUp() override
Definition PMCMCBase.C:131
const Distribution * getVarPrior() const
Return the prior over variance to facilitate decision making in reporters.
Definition PMCMCBase.C:220
virtual void proposeSamples()
Fill in the _new_samples vector of vectors (happens within sampleSetUp)
Definition PMCMCBase.C:123
const Distribution * _var_prior
Storage for prior distribution object of the variance to be utilized.
Definition PMCMCBase.h:118
std::pair< unsigned int, unsigned int > randomIndexPair(const unsigned int &upper_bound, const unsigned int &exclude)
Sample two random indices without repitition excluding a specified index.
Definition PMCMCBase.C:168
const unsigned int _num_random_seeds
Initialize a certain number of random seeds. Change from the default only if you have to.
Definition PMCMCBase.h:148
std::vector< std::vector< Real > > _new_samples
Vectors of new proposed samples.
Definition PMCMCBase.h:133
std::size_t _rand_index
Running index for the random number generators.
Definition PMCMCBase.h:154
const std::vector< Real > & getRandomNumbers() const
Return the random numbers to facilitate decision making in reporters.
Definition PMCMCBase.C:196
PMCMCBase(const InputParameters &parameters)
Definition PMCMCBase.C:49
std::vector< std::vector< Real > > _confg_values
Configuration values.
Definition PMCMCBase.h:157
const unsigned int _num_parallel_proposals
Number of parallel proposals to be made and subApps to be executed.
Definition PMCMCBase.h:112
unsigned int randomIndex(const unsigned int &upper_bound, const unsigned int &exclude)
Sample a random index excluding a specified index.
Definition PMCMCBase.C:159
const std::vector< Real > * _upper_bound
Upper bounds for making the next proposal.
Definition PMCMCBase.h:124
std::vector< Real > & _new_var_samples
Vector of new proposed variance samples.
Definition PMCMCBase.h:136
void setNumberOfCols(dof_id_type n_cols)
Real getRand(std::size_t n, unsigned int index=0) const
unsigned int getRandl(std::size_t n, unsigned int lower, unsigned int upper, unsigned int index=0) const
void setAutoAdvanceGenerators(const bool state)
static InputParameters validParams()
void setNumberOfRows(dof_id_type n_rows)
void setNumberOfRandomSeeds(std::size_t number)