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{
112 if (_check_step == _t_step)
113 return;
114
115 /* Decision step to whether or not to accept the proposed sample by the sampler.
116 This decision step changes with the type of adaptive Monte Carlo sampling algorithm. */
117 if (_ais)
118 {
119 // This branch hard-codes row index 0, so a rank with zero local rows has no data here.
121 {
123 return;
124 }
125
126 const Real tmp = _ais->getUseAbsoluteValue() ? std::abs(_output_value[0]) : _output_value[0];
127
128 /* Checking whether a GP surrogate is used. If it is used, importance sampling is not performed
129 during the training phase of the GP and all proposed samples are accepted until the training
130 phase is completed. Once the training is completed, the importance sampling starts.
131 If a GP surrogate is not used, the standard proposal and acceptance/rejection is performed as
132 part of the importance sampling. */
133 const bool restart_gp = _gp_used && _t_step == *_gp_training_samples;
134 const bool output_limit_reached = _gp_used || tmp >= _output_limit;
135 if (restart_gp)
136 reinitChain();
137
138 _output_required[0] = output_limit_reached ? 1.0 : 0.0;
139
140 if (_t_step <= _ais->getNumSamplesTrain() && !restart_gp)
141 {
142 /* This is the training phase of the Adaptive Importance Sampling algorithm.
143 Here, it is decided whether or not to accept a proposed sample by the
144 AdaptiveImportanceSampler.C sampler depending upon the model output_value. */
145 _inputs = output_limit_reached
147 : _prev_val;
148 if (output_limit_reached)
151 }
152 else if (_t_step > _ais->getNumSamplesTrain() && !restart_gp)
153 {
154 /* This is the sampling phase of the Adaptive Importance Sampling algorithm.
155 Here, all proposed samples by the AdaptiveImportanceSampler.C sampler are accepted since
156 the importance distribution traning phase is finished. */
158 _prev_val_out[0] = tmp;
159 }
160 }
161 else if (_pss)
162 {
163 // Track the current subset
164 const unsigned int subset =
166 const unsigned int sub_ind =
167 (_t_step - 1) - (_pss->getNumSamplesSub() / _sampler.getNumberOfRows()) * subset;
168 const unsigned int offset = sub_ind * _sampler.getNumberOfRows();
169 const unsigned int count_max = 1 / _pss->getSubsetProbability();
170
171 DenseMatrix<Real> data_in = _sampler.getGlobalSamples();
172
173 // Get the accepted samples outputs across all the procs from the previous step
174 mooseAssert(_output_value.size() >= _sampler.getNumberOfLocalRows(),
175 "Incorrectly sized outputs.");
176 _output_required.assign(_output_value.begin(),
181
182 // These are the subsequent subsets which use Markov Chain Monte Carlo sampling scheme
183 if (subset > 0)
184 {
185 if (sub_ind == 0)
186 {
187 // _output_sorted contains largest po percentile output values
190 // _inputs_sorted contains the input values corresponding to the largest po percentile
191 // output values
194 // Get the subset's intermediate failure threshold values
196 }
197 // Check whether the number of samples in a Markov chain exceeded the limit
198 if (sub_ind % count_max == 0)
199 {
200 const unsigned int soffset = (sub_ind / count_max) * _sampler.getNumberOfRows();
201 // Reinitialize the starting input values for the next set of Markov chains
202 for (dof_id_type j = 0; j < _sampler.getNumberOfCols(); ++j)
203 _prev_val[j].assign(_inputs_sorted[j].begin() + soffset,
204 _inputs_sorted[j].begin() + soffset + _sampler.getNumberOfRows());
205 _prev_val_out.assign(_output_sorted.begin() + soffset,
206 _output_sorted.begin() + soffset + _sampler.getNumberOfRows());
207 }
208 else
209 {
210 // Otherwise, use the previously accepted input values to propose the next set of input
211 // values
212 for (dof_id_type j = 0; j < _sampler.getNumberOfCols(); ++j)
213 _prev_val[j].assign(_inputs_sto[j].begin() + offset - _sampler.getNumberOfRows(),
214 _inputs_sto[j].begin() + offset);
215 _prev_val_out.assign(_outputs_sto.begin() + offset - _sampler.getNumberOfRows(),
216 _outputs_sto.begin() + offset);
217 }
218 }
219
220 // Check whether the outputs exceed the subset's intermediate failure threshold value
221 for (dof_id_type ss = 0; ss < _sampler.getNumberOfRows(); ++ss)
222 {
223 // Check whether the outputs exceed the subset's intermediate failure threshold value
224 // If so, accept the proposed input values by the Sampler object
225 // Otherwise, use the previously accepted input values
226 const bool output_limit_reached = _output_required[ss] >= _output_limit;
227 for (dof_id_type i = 0; i < _sampler.getNumberOfCols(); ++i)
228 {
229 _inputs[i][ss] = output_limit_reached ? data_in(ss, i) : _prev_val[i][ss];
230 _inputs_sto[i][ss + offset] = _inputs[i][ss];
231 }
232 if (!output_limit_reached)
234 _outputs_sto[ss + offset] = _output_required[ss];
235 }
236 }
237 // Track the current step
239}
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.