https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
13registerMooseObject("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.");
24 params.addRequiredRangeCheckedParam<dof_id_type>(
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
51
52 _b = RealEigenMatrix::Ones(nc + 1, nc).triangularView<Eigen::StrictlyLower>();
53 _j.setOnes(nc + 1, nc);
54 _bstar.resize(nc + 1, nc);
55}
56
57Real
58MorrisSampler::computeSample(dof_id_type row_index, dof_id_type col_index) const
59{
60 const dof_id_type traj = row_index / (getNumberOfCols() + 1);
61 const dof_id_type traj_ind = row_index % (getNumberOfCols() + 1);
62 if (traj != _curr_trajectory)
63 {
64 _curr_trajectory = traj;
66 }
67 return _distributions[col_index]->quantile(_bstar(traj_ind, col_index));
68}
69
70void
71MorrisSampler::updateBstar(dof_id_type trajectory_index) const
72{
73 mooseAssert(trajectory_index < _num_trajectories,
74 "Current trajectory index is greater than the prescribed number of trajectories.");
75
76 const dof_id_type nc = getNumberOfCols();
77 dof_id_type rn_ind = trajectory_index * nc * (nc + 1);
78
79 RealEigenMatrix pstar = RealEigenMatrix::Zero(nc, nc);
80 std::vector<dof_id_type> pchoice(nc);
81 std::iota(pchoice.begin(), pchoice.end(), 0);
82 for (dof_id_type c = 0; c < nc; ++c)
83 {
84 const unsigned int ind = nc > 1 ? getRandl(rn_ind++, 0, pchoice.size()) : 0;
85 pstar(pchoice[ind], c) = 1.0;
86 pchoice.erase(pchoice.begin() + ind);
87 }
88
89 RealEigenMatrix dstar = RealEigenMatrix::Zero(nc, nc);
90 for (dof_id_type c = 0; c < nc; ++c)
91 dstar(c, c) = getRand(rn_ind++) < 0.5 ? -1.0 : 1.0;
92
93 RealEigenMatrix xstar(nc + 1, nc);
94 for (dof_id_type c = 0; c < nc; ++c)
95 {
96 const auto lind = getRandl(rn_ind++, 0, _num_levels / 2);
97 xstar.col(c).setConstant((Real)lind * 1.0 / ((Real)_num_levels - 1));
98 }
99
100 _bstar = xstar + _num_levels / 4.0 / (_num_levels - 1) * ((2.0 * _b * pstar - _j) * dstar + _j);
101}
102
105{
106 std::vector<LocalRankConfig> all_rc(processor_id() + 1);
107 for (processor_id_type r = 0; r <= processor_id(); ++r)
108 all_rc[r] = rankConfig(
110 LocalRankConfig & rc = all_rc.back();
111
112 rc.num_local_sims *= _distributions.size() + 1;
113 bool found_first = false;
114 for (auto it = all_rc.rbegin(); it != all_rc.rend(); ++it)
115 if (it->is_first_local_rank)
116 {
117 if (found_first)
118 rc.first_local_sim_index += it->num_local_sims * _distributions.size();
119 else
120 found_first = true;
121 }
122
123 if (!batch_mode)
124 {
127 }
128
129 return rc;
130}
registerMooseObject("StochasticToolsApp", MorrisSampler)
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)
void ErrorVector unsigned int
const Distribution & getDistributionByName(const DistributionName &name) const
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, const std::string &doc_string)
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
const std::string & name() const
A class used to perform Monte Carlo sampling for performing Morris sensitivity analysis.
dof_id_type _curr_trajectory
void updateBstar(dof_id_type trajectory_index) const
Compute _bstar for the given trajectory index.
static InputParameters validParams()
RealEigenMatrix _j
std::vector< const Distribution * > _distributions
Distribution to determine parameter from perturbations.
const unsigned int & _num_levels
Number of levels used for input space discretization.
MorrisSampler(const InputParameters &parameters)
const dof_id_type & _num_trajectories
Number of trajectories.
virtual Real computeSample(dof_id_type row_index, dof_id_type col_index) const override
RealEigenMatrix _bstar
virtual LocalRankConfig constructRankConfig(bool batch_mode) const override
Morris sampling should have a slightly different partitioning in order to keep the sample and resampl...
RealEigenMatrix _b
void setNumberOfCols(dof_id_type n_cols)
Real getRand(std::size_t n, unsigned int index=0) const
const dof_id_type _max_procs_per_row
unsigned int getRandl(std::size_t n, unsigned int lower, unsigned int upper, unsigned int index=0) const
static InputParameters validParams()
dof_id_type getNumberOfCols() const
void setNumberOfRows(dof_id_type n_rows)
const dof_id_type _min_procs_per_row
processor_id_type processor_id() const
processor_id_type n_processors() const
dof_id_type num_local_sims
dof_id_type first_local_sim_index
dof_id_type num_local_apps
dof_id_type first_local_app_index