https://mooseframework.inl.gov
MorrisSampler.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 "MorrisSampler.h"
11 #include "Distribution.h"
12 
13 registerMooseObject("StochasticToolsApp", MorrisSampler);
14 
17 {
19  params.addClassDescription("Morris variance-based sensitivity analysis Sampler.");
20  params.addRequiredParam<std::vector<DistributionName>>(
21  "distributions",
22  "The distribution names to be sampled, the number of distributions provided defines the "
23  "number of columns per matrix.");
25  "trajectories",
26  "trajectories > 0",
27  "Number of unique trajectories to perform. The higher number of these usually means a more "
28  "accurate sensitivity evaluation, but it is proportional to the number of required model "
29  "evaluations: 'trajectoris' x (number of 'distributions' + 1).");
30  params.addRangeCheckedParam<unsigned int>(
31  "levels",
32  4,
33  "levels % 2 = 0 & levels > 0",
34  "The number of levels in the sampling. This determines the discretization of the input "
35  "space, more levels means finer discretization and more possible model perturbations.");
36  return params;
37 }
38 
40  : Sampler(parameters),
41  _num_trajectories(getParam<dof_id_type>("trajectories")),
42  _num_levels(getParam<unsigned int>("levels"))
43 
44 {
45  for (const auto & name : getParam<std::vector<DistributionName>>("distributions"))
47 
50 }
51 
52 void
54 {
55  const dof_id_type nc = getNumberOfCols();
56  _b = RealEigenMatrix::Ones(nc + 1, nc).triangularView<Eigen::StrictlyLower>();
57  _pstar.resize(nc, nc);
58  _j.setOnes(nc + 1, nc);
59  _dstar.resize(nc, nc);
60  _xstar.resize(nc + 1, nc);
61  _bstar.resize(nc + 1, nc);
62 }
63 
64 Real
66 {
67  const dof_id_type traj_ind = row_index % (getNumberOfCols() + 1);
68  if (traj_ind == 0 && col_index == 0)
69  updateBstar();
70  return _distributions[col_index]->quantile(_bstar(traj_ind, col_index));
71 }
72 
73 void
75 {
76  const dof_id_type nc = getNumberOfCols(); // convenience
77  _pstar.setZero();
78  // Which parameter to perturb
79  std::vector<dof_id_type> pchoice(nc);
80  std::iota(pchoice.begin(), pchoice.end(), 0);
81  for (dof_id_type c = 0; c < nc; ++c)
82  {
83  const unsigned int ind = nc > 1 ? getRandl(0, 0, pchoice.size()) : 0;
84  _pstar(pchoice[ind], c) = 1.0;
85  pchoice.erase(pchoice.begin() + ind);
86  }
87 
88  _dstar.setZero();
89  // Direction of perturbation
90  for (dof_id_type c = 0; c < nc; ++c)
91  _dstar(c, c) = getRand() < 0.5 ? -1.0 : 1.0;
92 
93  // Initial value
94  for (dof_id_type c = 0; c < nc; ++c)
95  {
96  const auto lind = getRandl(0, 0, _num_levels / 2);
97  _xstar.col(c).setConstant((Real)lind * 1.0 / ((Real)_num_levels - 1));
98  }
99 
100  _bstar =
101  _xstar + _num_levels / 4.0 / (_num_levels - 1) * ((2.0 * _b * _pstar - _j) * _dstar + _j);
102 
103  // This matrix represent _n_cols * (_n_cols + 1) samples, but so far we have only
104  // advanced the generator 3 * _n_cols times. For the generator state restore
105  // to work properly, we need to finish advancing the generator
106  if (nc > 2)
107  advanceGenerator(0, nc * (nc - 2));
108 }
109 
112 {
113  std::vector<LocalRankConfig> all_rc(processor_id() + 1);
114  for (processor_id_type r = 0; r <= processor_id(); ++r)
115  all_rc[r] = rankConfig(
117  LocalRankConfig & rc = all_rc.back();
118 
119  rc.num_local_sims *= _distributions.size() + 1;
120  bool found_first = false;
121  for (auto it = all_rc.rbegin(); it != all_rc.rend(); ++it)
122  if (it->is_first_local_rank)
123  {
124  if (found_first)
125  rc.first_local_sim_index += it->num_local_sims * _distributions.size();
126  else
127  found_first = true;
128  }
129 
130  if (!batch_mode)
131  {
134  }
135 
136  return rc;
137 }
void setNumberOfRows(dof_id_type n_rows)
virtual Real computeSample(dof_id_type row_index, dof_id_type col_index) override
Definition: MorrisSampler.C:65
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, const std::string &doc_string)
uint32_t getRandl(unsigned int index, uint32_t lower, uint32_t upper)
RealEigenMatrix _xstar
Definition: MorrisSampler.h:60
static InputParameters validParams()
RealEigenMatrix _b
Definition: MorrisSampler.h:56
LocalRankConfig rankConfig(processor_id_type rank, processor_id_type nprocs, dof_id_type napps, processor_id_type min_app_procs, processor_id_type max_app_procs, bool batch_mode=false)
const dof_id_type & _num_trajectories
Number of trajectories.
Definition: MorrisSampler.h:41
dof_id_type first_local_app_index
virtual void advanceGenerator(const unsigned int seed_index, const dof_id_type count)
const dof_id_type _max_procs_per_row
Real getRand(unsigned int index=0)
virtual const std::string & name() const
void addRequiredParam(const std::string &name, const std::string &doc_string)
std::vector< const Distribution * > _distributions
Distribution to determine parameter from perturbations.
Definition: MorrisSampler.h:45
uint8_t processor_id_type
processor_id_type n_processors() const
static InputParameters validParams()
Definition: MorrisSampler.C:16
MorrisSampler(const InputParameters &parameters)
Definition: MorrisSampler.C:39
const T & getParam(const std::string &name) const
void updateBstar()
Function to calculate trajectories This is only called once per trajectory (_n_rows / (_n_cols + 1)) ...
Definition: MorrisSampler.C:74
const unsigned int & _num_levels
Number of levels used for input space discretization.
Definition: MorrisSampler.h:43
dof_id_type num_local_sims
RealEigenMatrix _bstar
Definition: MorrisSampler.h:61
const dof_id_type _min_procs_per_row
A class used to perform Monte Carlo sampling for performing Morris sensitivity analysis.
Definition: MorrisSampler.h:18
const Distribution & getDistributionByName(const DistributionName &name) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
RealEigenMatrix _pstar
Definition: MorrisSampler.h:57
void setNumberOfCols(dof_id_type n_cols)
RealEigenMatrix _dstar
Definition: MorrisSampler.h:59
virtual LocalRankConfig constructRankConfig(bool batch_mode) const override
Morris sampling should have a slightly different partitioning in order to keep the sample and resampl...
registerMooseObject("StochasticToolsApp", MorrisSampler)
RealEigenMatrix _j
Definition: MorrisSampler.h:58
void addClassDescription(const std::string &doc_string)
dof_id_type num_local_apps
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
dof_id_type first_local_sim_index
processor_id_type processor_id() const
void ErrorVector unsigned int
dof_id_type getNumberOfCols() const
virtual void sampleSetUp(const Sampler::SampleMode mode) override
Used to setup matrices for trajectory computation.
Definition: MorrisSampler.C:53
uint8_t dof_id_type