https://mooseframework.inl.gov
NestedMonteCarloSampler.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 
11 #include "Distribution.h"
12 
13 registerMooseObjectAliased("StochasticToolsApp", NestedMonteCarloSampler, "NestedMonteCarlo");
14 
17 {
19  params.addClassDescription("Monte Carlo sampler for nested loops of parameters.");
20  params.addRequiredParam<std::vector<dof_id_type>>(
21  "num_rows",
22  "The number of rows for each loop of parameters. The first number represents the outermost "
23  "loop.");
24  params.addRequiredParam<std::vector<std::vector<DistributionName>>>(
25  "distributions",
26  "Sets of distribution names to be sampled. Each set defines the parameters for the nested "
27  "loop, with the first set being the outermost loop.");
28  return params;
29 }
30 
32  : Sampler(parameters)
33 {
34  // Grab inputs and make sure size is consistent
35  const auto & dnames = getParam<std::vector<std::vector<DistributionName>>>("distributions");
36  const auto & nrows = getParam<std::vector<dof_id_type>>("num_rows");
37  if (dnames.size() != nrows.size())
38  paramError("distributions",
39  "There must be a set of distributions for each loop defined by 'num_rows'.");
40 
41  // Gather distribution pointers and fill in loop index
42  const std::size_t nloop = dnames.size();
43  for (const auto & n : make_range(nloop))
44  for (const auto & name : dnames[n])
45  {
47  _loop_index.push_back(n);
48  }
49 
50  // Compute what row indices need to recompute which columns
51  _loop_mod.resize(nloop);
52  std::partial_sum(
53  nrows.rbegin(), nrows.rend(), _loop_mod.rbegin(), std::multiplies<dof_id_type>());
54  _loop_mod.erase(_loop_mod.begin());
55  _loop_mod.push_back(1);
56 
57  // Allocate row storage
58  _row_data.resize(_distributions.size());
59 
60  setNumberOfRows(std::accumulate(nrows.begin(), nrows.end(), 1, std::multiplies<dof_id_type>()));
62 }
63 
64 void
66 {
67  if (mode == Sampler::SampleMode::GLOBAL || getNumberOfRows() == 0)
68  return;
69 
70  dof_id_type curr_row = 0;
71  for (const auto & mod : _loop_mod)
72  {
73  if (getLocalRowBegin() % mod == 0)
74  break;
75 
76  const dof_id_type target_row = std::floor(getLocalRowBegin() / mod) * mod;
77  advanceGenerators((target_row - curr_row) * getNumberOfCols());
78  for (const auto & j : make_range(getNumberOfCols()))
79  computeSample(target_row, j);
80  curr_row = target_row + 1;
81  }
83 }
84 
85 Real
87 {
88  const Real rn = getRand();
89  const auto & loop = _loop_index[col_index];
90  if (row_index % _loop_mod[loop] == 0)
91  _row_data[col_index] = _distributions[col_index]->quantile(rn);
92  return _row_data[col_index];
93 }
void setNumberOfRows(dof_id_type n_rows)
static InputParameters validParams()
static InputParameters validParams()
virtual void advanceGenerators(const dof_id_type count)
NestedMonteCarloSampler(const InputParameters &parameters)
std::vector< const Distribution * > _distributions
Storage for distribution objects to be utilized.
std::vector< std::size_t > _loop_index
The loop index for distribution.
dof_id_type getLocalRowBegin() const
registerMooseObjectAliased("StochasticToolsApp", NestedMonteCarloSampler, "NestedMonteCarlo")
void restoreGeneratorState()
Real getRand(unsigned int index=0)
virtual const std::string & name() const
void addRequiredParam(const std::string &name, const std::string &doc_string)
void paramError(const std::string &param, Args... args) const
virtual Real computeSample(dof_id_type row_index, dof_id_type col_index) override
Return the sample for the given row and column.
dof_id_type getNumberOfRows() const
const Distribution & getDistributionByName(const DistributionName &name) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void setNumberOfCols(dof_id_type n_cols)
std::vector< dof_id_type > _loop_mod
Helper for determining if a set of columns need to be recomputed: if (row_index % _loop_mod[_loop_ind...
IntRange< T > make_range(T beg, T end)
void addClassDescription(const std::string &doc_string)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
std::vector< Real > _row_data
Storage for row data (to be used when not recomputing a column)
virtual void sampleSetUp(const SampleMode mode) override
Here we need to precompute rows that might not be assigned to this processor.
dof_id_type getNumberOfCols() const
A class used to perform nested Monte Carlo Sampling.
uint8_t dof_id_type