https://mooseframework.inl.gov
Loading...
Searching...
No Matches
AdaptiveMonteCarloDecision.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
10#include "Sampler.h"
11#include "DenseMatrix.h"
14
15#ifdef MOOSE_LIBTORCH_ENABLED
17#endif
18
20
23{
25 params.addClassDescription("Generic reporter which decides whether or not to accept a proposed "
26 "sample in Adaptive Monte Carlo type of algorithms.");
27 params.addRequiredParam<ReporterName>("output_value",
28 "Value of the model output from the SubApp.");
29 params.addParam<ReporterValueName>(
30 "output_required",
31 "output_required",
32 "Modified value of the model output from this reporter class.");
33 params.addParam<ReporterValueName>("inputs", "inputs", "Uncertain inputs to the model.");
34 params.addRequiredParam<SamplerName>("sampler", "The sampler object.");
35 params.addParam<UserObjectName>("gp_decision", "The Gaussian Process decision reporter.");
36 return params;
37}
38
40 : GeneralReporter(parameters),
41 _output_value(isParamValid("gp_decision") ? getReporterValue<std::vector<Real>>("output_value")
42 : getReporterValue<std::vector<Real>>(
43 "output_value", REPORTER_MODE_DISTRIBUTED)),
44 _output_required(declareValue<std::vector<Real>>("output_required")),
45 _inputs(declareValue<std::vector<std::vector<Real>>>("inputs")),
46 _sampler(getSampler("sampler")),
47 _ais(dynamic_cast<const AdaptiveImportanceSampler *>(&_sampler)),
48 _pss(dynamic_cast<const ParallelSubsetSimulation *>(&_sampler)),
49 _check_step(declareRestartableData<int>("check_step", std::numeric_limits<int>::max())),
50 _prev_val(declareRestartableData<std::vector<std::vector<Real>>>("prev_val")),
51 _prev_val_out(declareRestartableData<std::vector<Real>>("prev_val_out")),
52 _inputs_sto(declareRestartableData<std::vector<std::vector<Real>>>("inputs_sto")),
53 _inputs_sorted(declareRestartableData<std::vector<std::vector<Real>>>("inputs_sorted")),
54 _outputs_sto(declareRestartableData<std::vector<Real>>("outputs_sto")),
55 _output_sorted(declareRestartableData<std::vector<Real>>("output_sorted")),
56 _output_limit(declareRestartableData<Real>("output_limit", 0.0)),
57 _gp_used(isParamValid("gp_decision")),
58#ifdef MOOSE_LIBTORCH_ENABLED
59 _gp_training_samples(
60 _gp_used ? &getUserObject<ActiveLearningGPDecision>("gp_decision").getTrainingSamples()
61 : nullptr)
62#else
63 _gp_training_samples(nullptr)
64#endif
65{
66#ifndef MOOSE_LIBTORCH_ENABLED
67 if (_gp_used)
68 paramError("gp_decision", "The 'gp_decision' parameter requires libtorch.");
69#endif
70
71 // Check whether the selected sampler is an adaptive sampler or not
72 if (!_ais && !_pss)
73 paramError("sampler", "The selected sampler is not an adaptive sampler.");
74
75 const auto rows = _sampler.getNumberOfRows();
76 const auto cols = _sampler.getNumberOfCols();
77
78 // Initialize the required variables depending upon the type of adaptive Monte Carlo algorithm
79 _inputs.resize(cols, std::vector<Real>(rows));
80 _prev_val.resize(cols, std::vector<Real>(rows));
81 _output_required.resize(rows);
82 _prev_val_out.resize(rows);
83
84 if (_ais)
85 {
86 for (dof_id_type j = 0; j < _sampler.getNumberOfCols(); ++j)
87 _prev_val[j][0] = _ais->getInitialValues()[j];
89 }
90 else if (_pss)
91 {
92 _inputs_sto.resize(cols, std::vector<Real>(_pss->getNumSamplesSub()));
93 _inputs_sorted.resize(cols);
95 _output_limit = -std::numeric_limits<Real>::max();
96 }
97}
98
99void
101{
102 const std::vector<Real> & tmp1 = _ais->getInitialValues();
103 for (dof_id_type j = 0; j < tmp1.size(); ++j)
104 _inputs[j][0] = tmp1[j];
106 _prev_val_out[0] = 1.0;
107}
108
109void
111{
113 {
115 return;
116 }
117
118 /* Decision step to whether or not to accept the proposed sample by the sampler.
119 This decision step changes with the type of adaptive Monte Carlo sampling algorithm. */
120 if (_ais)
121 {
122 const Real tmp = _ais->getUseAbsoluteValue() ? std::abs(_output_value[0]) : _output_value[0];
123
124 /* Checking whether a GP surrogate is used. If it is used, importance sampling is not performed
125 during the training phase of the GP and all proposed samples are accepted until the training
126 phase is completed. Once the training is completed, the importance sampling starts.
127 If a GP surrogate is not used, the standard proposal and acceptance/rejection is performed as
128 part of the importance sampling. */
129 const bool restart_gp = _gp_used && _t_step == *_gp_training_samples;
130 const bool output_limit_reached = _gp_used || tmp >= _output_limit;
131 if (restart_gp)
132 reinitChain();
133
134 _output_required[0] = output_limit_reached ? 1.0 : 0.0;
135
136 if (_t_step <= _ais->getNumSamplesTrain() && !restart_gp)
137 {
138 /* This is the training phase of the Adaptive Importance Sampling algorithm.
139 Here, it is decided whether or not to accept a proposed sample by the
140 AdaptiveImportanceSampler.C sampler depending upon the model output_value. */
141 _inputs = output_limit_reached
143 : _prev_val;
144 if (output_limit_reached)
147 }
148 else if (_t_step > _ais->getNumSamplesTrain() && !restart_gp)
149 {
150 /* This is the sampling phase of the Adaptive Importance Sampling algorithm.
151 Here, all proposed samples by the AdaptiveImportanceSampler.C sampler are accepted since
152 the importance distribution traning phase is finished. */
154 _prev_val_out[0] = tmp;
155 }
156 }
157 else if (_pss)
158 {
159 // Track the current subset
160 const unsigned int subset =
162 const unsigned int sub_ind =
163 (_t_step - 1) - (_pss->getNumSamplesSub() / _sampler.getNumberOfRows()) * subset;
164 const unsigned int offset = sub_ind * _sampler.getNumberOfRows();
165 const unsigned int count_max = 1 / _pss->getSubsetProbability();
166
167 DenseMatrix<Real> data_in = _sampler.getGlobalSamples();
168
169 // Get the accepted samples outputs across all the procs from the previous step
170 mooseAssert(_output_value.size() >= _sampler.getNumberOfLocalRows(),
171 "Incorrectly sized outputs.");
172 _output_required.assign(_output_value.begin(),
177
178 // These are the subsequent subsets which use Markov Chain Monte Carlo sampling scheme
179 if (subset > 0)
180 {
181 if (sub_ind == 0)
182 {
183 // _output_sorted contains largest po percentile output values
186 // _inputs_sorted contains the input values corresponding to the largest po percentile
187 // output values
190 // Get the subset's intermediate failure threshold values
192 }
193 // Check whether the number of samples in a Markov chain exceeded the limit
194 if (sub_ind % count_max == 0)
195 {
196 const unsigned int soffset = (sub_ind / count_max) * _sampler.getNumberOfRows();
197 // Reinitialize the starting input values for the next set of Markov chains
198 for (dof_id_type j = 0; j < _sampler.getNumberOfCols(); ++j)
199 _prev_val[j].assign(_inputs_sorted[j].begin() + soffset,
200 _inputs_sorted[j].begin() + soffset + _sampler.getNumberOfRows());
201 _prev_val_out.assign(_output_sorted.begin() + soffset,
202 _output_sorted.begin() + soffset + _sampler.getNumberOfRows());
203 }
204 else
205 {
206 // Otherwise, use the previously accepted input values to propose the next set of input
207 // values
208 for (dof_id_type j = 0; j < _sampler.getNumberOfCols(); ++j)
209 _prev_val[j].assign(_inputs_sto[j].begin() + offset - _sampler.getNumberOfRows(),
210 _inputs_sto[j].begin() + offset);
211 _prev_val_out.assign(_outputs_sto.begin() + offset - _sampler.getNumberOfRows(),
212 _outputs_sto.begin() + offset);
213 }
214 }
215
216 // Check whether the outputs exceed the subset's intermediate failure threshold value
217 for (dof_id_type ss = 0; ss < _sampler.getNumberOfRows(); ++ss)
218 {
219 // Check whether the outputs exceed the subset's intermediate failure threshold value
220 // If so, accept the proposed input values by the Sampler object
221 // Otherwise, use the previously accepted input values
222 const bool output_limit_reached = _output_required[ss] >= _output_limit;
223 for (dof_id_type i = 0; i < _sampler.getNumberOfCols(); ++i)
224 {
225 _inputs[i][ss] = output_limit_reached ? data_in(ss, i) : _prev_val[i][ss];
226 _inputs_sto[i][ss + offset] = _inputs[i][ss];
227 }
228 if (!output_limit_reached)
230 _outputs_sto[ss + offset] = _output_required[ss];
231 }
232 }
233 // Track the current step
235}
registerMooseObject("StochasticToolsApp", AdaptiveMonteCarloDecision)
const ReporterMode REPORTER_MODE_DISTRIBUTED
void ErrorVector unsigned int
A class used to perform Adaptive Importance Sampling using a Markov Chain Monte Carlo algorithm.
const bool & getUseAbsoluteValue() const
const std::vector< Real > & getInitialValues() const
AdaptiveMonteCarloDecision will help make sample accept/reject decisions in adaptive Monte Carlo sche...
std::vector< std::vector< Real > > & _inputs
Model input data that is uncertain.
std::vector< Real > & _output_required
Modified value of model output by this reporter class.
const bool _gp_used
Check if a GP is used.
static InputParameters validParams()
std::vector< Real > & _prev_val_out
Storage for previously accepted output value.
std::vector< std::vector< Real > > & _inputs_sorted
Store the sorted input samples according to their corresponding outputs.
const int *const _gp_training_samples
Store the GP training samples.
const std::vector< Real > & _output_value
Model output value from SubApp.
int & _check_step
Ensure that the MCMC algorithm proceeds in a sequential fashion.
Sampler & _sampler
The adaptive Monte Carlo sampler.
AdaptiveMonteCarloDecision(const InputParameters &parameters)
std::vector< std::vector< Real > > & _prev_val
Storage for previously accepted input values. This helps in making decision on the next proposed inpu...
const AdaptiveImportanceSampler *const _ais
Adaptive Importance Sampler.
std::vector< std::vector< Real > > & _inputs_sto
Storage for the previously accepted sample inputs across all the subsets.
Real & _output_limit
Store the intermediate ouput failure thresholds.
std::vector< Real > & _outputs_sto
Storage for previously accepted sample outputs across all the subsets.
const ParallelSubsetSimulation *const _pss
Parallel Subset Simulation sampler.
void reinitChain()
This reinitializes the Markov chain to the starting value until the Gaussian process training is comp...
std::vector< Real > & _output_sorted
Store the sorted output sample values.
static InputParameters validParams()
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)
void paramError(const std::string &param, Args... args) const
A class used to perform Parallel Subset Simulation Sampling.
const Real & getSubsetProbability() const
Access the subset probability.
const unsigned int & getNumSamplesSub() const
Access the number samples per subset.
const bool & getUseAbsoluteValue() const
Access use absolute value bool.
dof_id_type getNumberOfLocalRows() const
std::vector< Real > getSampleRow(dof_id_type row_index) const
dof_id_type getNumberOfRows() const
dof_id_type getNumberOfCols() const
DenseMatrix< Real > getGlobalSamples()
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
const Parallel::Communicator & _communicator
std::vector< Real > sortOutput(const std::vector< Real > &outputs, const unsigned int samplessub, const Real subset_prob)
return the largest po percentile output values.
Real computeMin(const std::vector< Real > &data)
return the minimum value in a vector.
std::vector< std::vector< Real > > sortInput(const std::vector< std::vector< Real > > &inputs, const std::vector< Real > &outputs, const unsigned int samplessub, const Real subset_prob)
return input values corresponding to the largest po percentile output values.
std::vector< Real > computeVectorABS(const std::vector< Real > &data)
return the absolute values in a vector.
std::vector< std::vector< T > > reshapeVector(const std::vector< T > &vec, std::size_t n, bool row_major)
Reshape a vector into matrix-like vector of vectors.