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  const dof_id_type nc = _distributions.size();
48 
49  setNumberOfCols(nc);
51 
52  _b = RealEigenMatrix::Ones(nc + 1, nc).triangularView<Eigen::StrictlyLower>();
53  _pstar.resize(nc, nc);
54  _j.setOnes(nc + 1, nc);
55  _dstar.resize(nc, nc);
56  _xstar.resize(nc + 1, nc);
57  _bstar.resize(nc + 1, nc);
58 }
59 
60 Real
62 {
63  const dof_id_type traj = row_index / (getNumberOfCols() + 1);
64  const dof_id_type traj_ind = row_index % (getNumberOfCols() + 1);
65  if (traj != _curr_trajectory)
66  {
67  _curr_trajectory = traj;
68  updateBstar();
69  }
70  return _distributions[col_index]->quantile(_bstar(traj_ind, col_index));
71 }
72 
73 void
75 {
76  mooseAssert(_curr_trajectory < _num_trajectories,
77  "Current trajectory index is greater than the prescribed number of trajectories.");
78 
79  const dof_id_type nc = getNumberOfCols(); // convenience
80  dof_id_type rn_ind = _curr_trajectory * nc * (nc + 1);
81 
82  _pstar.setZero();
83  // Which parameter to perturb
84  std::vector<dof_id_type> pchoice(nc);
85  std::iota(pchoice.begin(), pchoice.end(), 0);
86  for (dof_id_type c = 0; c < nc; ++c)
87  {
88  const unsigned int ind = nc > 1 ? getRandl(rn_ind++, 0, pchoice.size()) : 0;
89  _pstar(pchoice[ind], c) = 1.0;
90  pchoice.erase(pchoice.begin() + ind);
91  }
92 
93  _dstar.setZero();
94  // Direction of perturbation
95  for (dof_id_type c = 0; c < nc; ++c)
96  _dstar(c, c) = getRand(rn_ind++) < 0.5 ? -1.0 : 1.0;
97 
98  // Initial value
99  for (dof_id_type c = 0; c < nc; ++c)
100  {
101  const auto lind = getRandl(rn_ind++, 0, _num_levels / 2);
102  _xstar.col(c).setConstant((Real)lind * 1.0 / ((Real)_num_levels - 1));
103  }
104 
105  _bstar =
106  _xstar + _num_levels / 4.0 / (_num_levels - 1) * ((2.0 * _b * _pstar - _j) * _dstar + _j);
107 }
108 
111 {
112  std::vector<LocalRankConfig> all_rc(processor_id() + 1);
113  for (processor_id_type r = 0; r <= processor_id(); ++r)
114  all_rc[r] = rankConfig(
116  LocalRankConfig & rc = all_rc.back();
117 
118  rc.num_local_sims *= _distributions.size() + 1;
119  bool found_first = false;
120  for (auto it = all_rc.rbegin(); it != all_rc.rend(); ++it)
121  if (it->is_first_local_rank)
122  {
123  if (found_first)
124  rc.first_local_sim_index += it->num_local_sims * _distributions.size();
125  else
126  found_first = true;
127  }
128 
129  if (!batch_mode)
130  {
133  }
134 
135  return rc;
136 }
void setNumberOfRows(dof_id_type n_rows)
virtual Real computeSample(dof_id_type row_index, dof_id_type col_index) override
Definition: MorrisSampler.C:61
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, const std::string &doc_string)
RealEigenMatrix _xstar
Definition: MorrisSampler.h:58
static InputParameters validParams()
const T & getParam(const std::string &name) const
RealEigenMatrix _b
Definition: MorrisSampler.h:54
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)
unsigned int getRandl(std::size_t n, unsigned int lower, unsigned int upper, unsigned int index=0) const
const dof_id_type & _num_trajectories
Number of trajectories.
Definition: MorrisSampler.h:36
dof_id_type first_local_app_index
const dof_id_type _max_procs_per_row
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:40
uint8_t processor_id_type
processor_id_type n_processors() const
const std::string & name() const
Real getRand(std::size_t n, unsigned int index=0) const
static InputParameters validParams()
Definition: MorrisSampler.C:16
MorrisSampler(const InputParameters &parameters)
Definition: MorrisSampler.C:39
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:38
dof_id_type num_local_sims
RealEigenMatrix _bstar
Definition: MorrisSampler.h:59
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:55
void setNumberOfCols(dof_id_type n_cols)
RealEigenMatrix _dstar
Definition: MorrisSampler.h:57
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:56
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
dof_id_type _curr_trajectory
The trajectory the current _bstar represents.
Definition: MorrisSampler.h:50
uint8_t dof_id_type