Line data Source code
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 "StatisticsReporter.h"
11 :
12 : // MOOSE includes
13 : #include "MooseVariable.h"
14 : #include "ThreadedElementLoopBase.h"
15 : #include "ThreadedNodeLoop.h"
16 :
17 : #include "libmesh/quadrature.h"
18 :
19 : #include <numeric>
20 :
21 : registerMooseObject("StochasticToolsApp", StatisticsReporter);
22 :
23 : InputParameters
24 766 : StatisticsReporter::validParams()
25 : {
26 766 : InputParameters params = GeneralReporter::validParams();
27 766 : params.addClassDescription(
28 : "Compute statistical values of a given VectorPostprocessor objects and vectors.");
29 :
30 1532 : params.addParam<std::vector<VectorPostprocessorName>>(
31 : "vectorpostprocessors",
32 : "List of VectorPostprocessor(s) to utilized for statistic computations.");
33 :
34 1532 : params.addParam<std::vector<ReporterName>>(
35 : "reporters", {}, "List of Reporter values to utilized for statistic computations.");
36 :
37 766 : MultiMooseEnum stats = StochasticTools::makeCalculatorEnum();
38 1532 : params.addRequiredParam<MultiMooseEnum>(
39 : "compute",
40 : stats,
41 : "The statistic(s) to compute for each of the supplied vector postprocessors.");
42 :
43 : // Confidence Levels
44 766 : MooseEnum ci = StochasticTools::makeBootstrapCalculatorEnum();
45 1532 : params.addParam<MooseEnum>(
46 : "ci_method", ci, "The method to use for computing confidence level intervals.");
47 :
48 1532 : params.addParam<std::vector<Real>>(
49 : "ci_levels",
50 1532 : std::vector<Real>({0.1, 0.9}),
51 : "A vector of confidence levels to consider, values must be in (0, 1).");
52 1532 : params.addParam<unsigned int>(
53 : "ci_replicates",
54 1532 : 10000,
55 : "The number of replicates to use when computing confidence level intervals.");
56 1532 : params.addParam<unsigned int>("ci_seed",
57 1532 : 1,
58 : "The random number generator seed used for creating replicates "
59 : "while computing confidence level intervals.");
60 766 : return params;
61 766 : }
62 :
63 387 : StatisticsReporter::StatisticsReporter(const InputParameters & parameters)
64 : : GeneralReporter(parameters),
65 387 : _compute_stats(getParam<MultiMooseEnum>("compute")),
66 774 : _ci_method(getParam<MooseEnum>("ci_method")),
67 774 : _ci_levels(getParam<std::vector<Real>>("ci_levels")),
68 774 : _ci_replicates(getParam<unsigned int>("ci_replicates")),
69 774 : _ci_seed(getParam<unsigned int>("ci_seed")),
70 387 : _initialized(false)
71 : {
72 : // CI levels error checking
73 387 : if (_ci_method.isValid())
74 : {
75 307 : if (_ci_levels.empty())
76 2 : paramError("ci_levels",
77 : "If the 'ci_method' parameter is supplied then the 'ci_levels' must also be "
78 : "supplied with values in (0, 1).");
79 :
80 305 : else if (*std::min_element(_ci_levels.begin(), _ci_levels.end()) <= 0)
81 2 : paramError("ci_levels", "The supplied levels must be greater than zero.");
82 :
83 303 : else if (*std::max_element(_ci_levels.begin(), _ci_levels.end()) >= 1)
84 2 : paramError("ci_levels", "The supplied levels must be less than 1.0");
85 : }
86 :
87 1524 : if ((!isParamValid("reporters") && !isParamValid("vectorpostprocessors")) ||
88 895 : (getParam<std::vector<ReporterName>>("reporters").empty() &&
89 647 : getParam<std::vector<VectorPostprocessorName>>("vectorpostprocessors").empty()))
90 2 : mooseError(
91 : "The 'vectorpostprocessors' and/or 'reporters' parameters must be defined and non-empty.");
92 379 : }
93 :
94 : void
95 407 : StatisticsReporter::initialize()
96 : {
97 407 : if (_initialized)
98 : return;
99 :
100 : // Stats for Reporters
101 758 : if (isParamValid("reporters"))
102 : {
103 : std::vector<std::string> unsupported_types;
104 758 : const auto & reporter_names = getParam<std::vector<ReporterName>>("reporters");
105 824 : for (const auto & r_name : reporter_names)
106 : {
107 445 : if (hasReporterValueByName<std::vector<Real>>(r_name))
108 380 : declareValueHelper<std::vector<Real>, Real>(r_name);
109 65 : else if (hasReporterValueByName<std::vector<int>>(r_name))
110 21 : declareValueHelper<std::vector<int>, Real>(r_name);
111 44 : else if (hasReporterValueByName<std::vector<std::vector<Real>>>(r_name))
112 42 : declareValueHelper<std::vector<std::vector<Real>>, std::vector<Real>>(r_name);
113 : else
114 4 : unsupported_types.emplace_back(r_name.getCombinedName());
115 : }
116 :
117 379 : if (!unsupported_types.empty())
118 2 : paramError("reporters",
119 : "The following reporter value(s) do not have a type supported by the "
120 : "StatisticsReporter:\n",
121 2 : MooseUtils::join(unsupported_types, ", "));
122 377 : }
123 :
124 : // Stats for VPP
125 754 : if (isParamValid("vectorpostprocessors"))
126 : {
127 262 : const auto & vpp_names = getParam<std::vector<VectorPostprocessorName>>("vectorpostprocessors");
128 276 : for (const auto & vpp_name : vpp_names)
129 : {
130 : const VectorPostprocessor & vpp_object =
131 145 : _fe_problem.getVectorPostprocessorObjectByName(vpp_name);
132 145 : const std::set<std::string> & vpp_vectors = vpp_object.getVectorNames();
133 325 : for (const auto & vec_name : vpp_vectors)
134 : {
135 180 : ReporterName r_name(vpp_name, vec_name);
136 180 : declareValueHelper<std::vector<Real>, Real>(r_name);
137 : }
138 : }
139 : }
140 :
141 377 : _initialized = true;
142 : }
143 :
144 : void
145 212 : StatisticsReporter::store(nlohmann::json & json) const
146 : {
147 212 : Reporter::store(json);
148 212 : if (_ci_method.isValid())
149 172 : json["confidence_intervals"] = {{"method", _ci_method},
150 : {"levels", _ci_levels},
151 : {"replicates", _ci_replicates},
152 2236 : {"seed", _ci_seed}};
153 2448 : }
154 :
155 : template <typename InType, typename OutType>
156 : void
157 623 : StatisticsReporter::declareValueHelper(const ReporterName & r_name)
158 : {
159 623 : const auto & mode = _fe_problem.getReporterData().getReporterMode(r_name);
160 623 : const auto & data = getReporterValueByName<InType>(r_name);
161 2214 : for (const auto & item : _compute_stats)
162 : {
163 3182 : const std::string s_name =
164 1591 : r_name.getObjectName() + "_" + r_name.getValueName() + "_" + item.name();
165 1591 : if (_ci_method.isValid())
166 : declareValueByName<std::pair<OutType, std::vector<OutType>>,
167 3896 : ReporterStatisticsContext<InType, OutType>>(s_name,
168 : REPORTER_MODE_ROOT,
169 : data,
170 : mode,
171 : item,
172 : _ci_method,
173 : _ci_levels,
174 : _ci_replicates,
175 : _ci_seed);
176 : else
177 : declareValueByName<std::pair<OutType, std::vector<OutType>>,
178 2468 : ReporterStatisticsContext<InType, OutType>>(
179 : s_name, REPORTER_MODE_ROOT, data, mode, item);
180 : }
181 623 : }
182 :
183 : template void
184 : StatisticsReporter::declareValueHelper<std::vector<Real>, Real>(const ReporterName & r_name);
185 : template void
186 : StatisticsReporter::declareValueHelper<std::vector<int>, Real>(const ReporterName & r_name);
|