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(std::numeric_limits<int>::max()),
50 _local_comm(_sampler.getLocalComm()),
51 _gp_used(isParamValid("gp_decision")),
52#ifdef MOOSE_LIBTORCH_ENABLED
53 _gp_training_samples(
54 _gp_used ? &getUserObject<ActiveLearningGPDecision>("gp_decision").getTrainingSamples()
55 : nullptr)
56#else
57 _gp_training_samples(nullptr)
58#endif
59{
60#ifndef MOOSE_LIBTORCH_ENABLED
61 if (_gp_used)
62 paramError("gp_decision", "The 'gp_decision' parameter requires libtorch.");
63#endif
64
65 // Check whether the selected sampler is an adaptive sampler or not
66 if (!_ais && !_pss)
67 paramError("sampler", "The selected sampler is not an adaptive sampler.");
68
69 const auto rows = _sampler.getNumberOfRows();
70 const auto cols = _sampler.getNumberOfCols();
71
72 // Initialize the required variables depending upon the type of adaptive Monte Carlo algorithm
73 _inputs.resize(cols, std::vector<Real>(rows));
74 _prev_val.resize(cols, std::vector<Real>(rows));
75 _output_required.resize(rows);
76 _prev_val_out.resize(rows);
77
78 if (_ais)
79 {
80 for (dof_id_type j = 0; j < _sampler.getNumberOfCols(); ++j)
81 _prev_val[j][0] = _ais->getInitialValues()[j];
83 }
84 else if (_pss)
85 {
86 _inputs_sto.resize(cols, std::vector<Real>(_pss->getNumSamplesSub()));
87 _inputs_sorted.resize(cols);
89 _output_limit = -std::numeric_limits<Real>::max();
90 }
91}
92
93void
95{
96 const std::vector<Real> & tmp1 = _ais->getInitialValues();
97 for (dof_id_type j = 0; j < tmp1.size(); ++j)
98 _inputs[j][0] = tmp1[j];
100 _prev_val_out[0] = 1.0;
101}
102
103void
105{
107 {
109 return;
110 }
111
112 /* Decision step to whether or not to accept the proposed sample by the sampler.
113 This decision step changes with the type of adaptive Monte Carlo sampling algorithm. */
114 if (_ais)
115 {
116 const Real tmp = _ais->getUseAbsoluteValue() ? std::abs(_output_value[0]) : _output_value[0];
117
118 /* Checking whether a GP surrogate is used. If it is used, importance sampling is not performed
119 during the training phase of the GP and all proposed samples are accepted until the training
120 phase is completed. Once the training is completed, the importance sampling starts.
121 If a GP surrogate is not used, the standard proposal and acceptance/rejection is performed as
122 part of the importance sampling. */
123 const bool restart_gp = _gp_used && _t_step == *_gp_training_samples;
124 const bool output_limit_reached = _gp_used || tmp >= _output_limit;
125 if (restart_gp)
126 reinitChain();
127
128 _output_required[0] = output_limit_reached ? 1.0 : 0.0;
129
130 if (_t_step <= _ais->getNumSamplesTrain() && !restart_gp)
131 {
132 /* This is the training phase of the Adaptive Importance Sampling algorithm.
133 Here, it is decided whether or not to accept a proposed sample by the
134 AdaptiveImportanceSampler.C sampler depending upon the model output_value. */
135 _inputs = output_limit_reached
137 : _prev_val;
138 if (output_limit_reached)
141 }
142 else if (_t_step > _ais->getNumSamplesTrain() && !restart_gp)
143 {
144 /* This is the sampling phase of the Adaptive Importance Sampling algorithm.
145 Here, all proposed samples by the AdaptiveImportanceSampler.C sampler are accepted since
146 the importance distribution traning phase is finished. */
148 _prev_val_out[0] = tmp;
149 }
150 }
151 else if (_pss)
152 {
153 // Track the current subset
154 const unsigned int subset =
156 const unsigned int sub_ind =
157 (_t_step - 1) - (_pss->getNumSamplesSub() / _sampler.getNumberOfRows()) * subset;
158 const unsigned int offset = sub_ind * _sampler.getNumberOfRows();
159 const unsigned int count_max = 1 / _pss->getSubsetProbability();
160
161 DenseMatrix<Real> data_in(_sampler.getNumberOfRows(), _sampler.getNumberOfCols());
162 for (dof_id_type ss = _sampler.getLocalRowBegin(); ss < _sampler.getLocalRowEnd(); ++ss)
163 {
164 const auto data = _sampler.getNextLocalRow();
165 for (unsigned int j = 0; j < _sampler.getNumberOfCols(); ++j)
166 data_in(ss, j) = data[j];
167 }
168 _local_comm.sum(data_in.get_values());
169
170 // Get the accepted samples outputs across all the procs from the previous step
175
176 // These are the subsequent subsets which use Markov Chain Monte Carlo sampling scheme
177 if (subset > 0)
178 {
179 if (sub_ind == 0)
180 {
181 // _output_sorted contains largest po percentile output values
184 // _inputs_sorted contains the input values corresponding to the largest po percentile
185 // output values
188 // Get the subset's intermediate failure threshold values
190 }
191 // Check whether the number of samples in a Markov chain exceeded the limit
192 if (sub_ind % count_max == 0)
193 {
194 const unsigned int soffset = (sub_ind / count_max) * _sampler.getNumberOfRows();
195 // Reinitialize the starting input values for the next set of Markov chains
196 for (dof_id_type j = 0; j < _sampler.getNumberOfCols(); ++j)
197 _prev_val[j].assign(_inputs_sorted[j].begin() + soffset,
198 _inputs_sorted[j].begin() + soffset + _sampler.getNumberOfRows());
199 _prev_val_out.assign(_output_sorted.begin() + soffset,
200 _output_sorted.begin() + soffset + _sampler.getNumberOfRows());
201 }
202 else
203 {
204 // Otherwise, use the previously accepted input values to propose the next set of input
205 // values
206 for (dof_id_type j = 0; j < _sampler.getNumberOfCols(); ++j)
207 _prev_val[j].assign(_inputs_sto[j].begin() + offset - _sampler.getNumberOfRows(),
208 _inputs_sto[j].begin() + offset);
209 _prev_val_out.assign(_outputs_sto.begin() + offset - _sampler.getNumberOfRows(),
210 _outputs_sto.begin() + offset);
211 }
212 }
213
214 // Check whether the outputs exceed the subset's intermediate failure threshold value
215 for (dof_id_type ss = 0; ss < _sampler.getNumberOfRows(); ++ss)
216 {
217 // Check whether the outputs exceed the subset's intermediate failure threshold value
218 // If so, accept the proposed input values by the Sampler object
219 // Otherwise, use the previously accepted input values
220 const bool output_limit_reached = _output_required[ss] >= _output_limit;
221 for (dof_id_type i = 0; i < _sampler.getNumberOfCols(); ++i)
222 {
223 _inputs[i][ss] = output_limit_reached ? data_in(ss, i) : _prev_val[i][ss];
224 _inputs_sto[i][ss + offset] = _inputs[i][ss];
225 }
226 if (!output_limit_reached)
228 _outputs_sto[ss + offset] = _output_required[ss];
229 }
230 }
231 // Track the current step
233}
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< Real > _output_sorted
Store the sorted output sample values.
std::vector< std::vector< Real > > _prev_val
Storage for previously accepted input values. This helps in making decision on the next proposed inpu...
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()
const int *const _gp_training_samples
Store the GP training samples.
libMesh::Parallel::Communicator & _local_comm
Communicator that was split based on samples that have rows.
const std::vector< Real > & _output_value
Model output value from SubApp.
Sampler & _sampler
The adaptive Monte Carlo sampler.
AdaptiveMonteCarloDecision(const InputParameters &parameters)
std::vector< Real > _outputs_sto
Storage for previously accepted sample outputs across all the subsets.
const AdaptiveImportanceSampler *const _ais
Adaptive Importance Sampler.
Real _output_limit
Store the intermediate ouput failure thresholds.
std::vector< Real > _prev_val_out
Storage for previously accepted output value.
int _check_step
Ensure that the MCMC algorithm proceeds in a sequential fashion.
const ParallelSubsetSimulation *const _pss
Parallel Subset Simulation sampler.
std::vector< std::vector< Real > > _inputs_sto
Storage for the previously accepted sample inputs across all the subsets.
void reinitChain()
This reinitializes the Markov chain to the starting value until the Gaussian process training is comp...
std::vector< std::vector< Real > > _inputs_sorted
Store the sorted input samples according to their corresponding outputs.
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.
std::vector< Real > getNextLocalRow()
dof_id_type getNumberOfLocalRows() const
dof_id_type getLocalRowEnd() const
dof_id_type getLocalRowBegin() const
dof_id_type getNumberOfRows() const
dof_id_type getNumberOfCols() const
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
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.