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 1764 : StatisticsReporter::validParams()
25 : {
26 1764 : InputParameters params = GeneralReporter::validParams();
27 1764 : params.addClassDescription(
28 : "Compute statistical values of a given VectorPostprocessor objects and vectors.");
29 :
30 3528 : params.addParam<std::vector<VectorPostprocessorName>>(
31 : "vectorpostprocessors",
32 : "List of VectorPostprocessor(s) to utilized for statistic computations.");
33 :
34 3528 : params.addParam<std::vector<ReporterName>>(
35 : "reporters", {}, "List of Reporter values to utilized for statistic computations.");
36 :
37 1764 : MultiMooseEnum stats = StochasticTools::makeCalculatorEnum();
38 3528 : 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 1764 : MooseEnum ci = StochasticTools::makeBootstrapCalculatorEnum();
45 3528 : params.addParam<MooseEnum>(
46 : "ci_method", ci, "The method to use for computing confidence level intervals.");
47 :
48 5292 : params.addParam<std::vector<Real>>(
49 : "ci_levels",
50 3528 : std::vector<Real>({0.1, 0.9}),
51 : "A vector of confidence levels to consider, values must be in (0, 1).");
52 3528 : params.addParam<unsigned int>(
53 : "ci_replicates",
54 3528 : 10000,
55 : "The number of replicates to use when computing confidence level intervals.");
56 3528 : params.addParam<unsigned int>("ci_seed",
57 3528 : 1,
58 : "The random number generator seed used for creating replicates "
59 : "while computing confidence level intervals.");
60 1764 : return params;
61 1764 : }
62 :
63 890 : StatisticsReporter::StatisticsReporter(const InputParameters & parameters)
64 : : GeneralReporter(parameters),
65 890 : _compute_stats(getParam<MultiMooseEnum>("compute")),
66 1780 : _ci_method(getParam<MooseEnum>("ci_method")),
67 1780 : _ci_levels(getParam<std::vector<Real>>("ci_levels")),
68 1780 : _ci_replicates(getParam<unsigned int>("ci_replicates")),
69 1780 : _ci_seed(getParam<unsigned int>("ci_seed")),
70 890 : _initialized(false)
71 : {
72 : // CI levels error checking
73 890 : if (_ci_method.isValid())
74 : {
75 712 : if (_ci_levels.empty())
76 4 : 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 708 : else if (*std::min_element(_ci_levels.begin(), _ci_levels.end()) <= 0)
81 4 : paramError("ci_levels", "The supplied levels must be greater than zero.");
82 :
83 704 : else if (*std::max_element(_ci_levels.begin(), _ci_levels.end()) >= 1)
84 4 : paramError("ci_levels", "The supplied levels must be less than 1.0");
85 : }
86 :
87 3512 : if ((!isParamValid("reporters") && !isParamValid("vectorpostprocessors")) ||
88 2038 : (getParam<std::vector<ReporterName>>("reporters").empty() &&
89 1442 : getParam<std::vector<VectorPostprocessorName>>("vectorpostprocessors").empty()))
90 4 : mooseError(
91 : "The 'vectorpostprocessors' and/or 'reporters' parameters must be defined and non-empty.");
92 874 : }
93 :
94 : void
95 938 : StatisticsReporter::initialize()
96 : {
97 938 : if (_initialized)
98 : return;
99 :
100 : // Stats for Reporters
101 1748 : if (isParamValid("reporters"))
102 : {
103 : std::vector<std::string> unsupported_types;
104 1748 : const auto & reporter_names = getParam<std::vector<ReporterName>>("reporters");
105 1934 : for (const auto & r_name : reporter_names)
106 : {
107 1060 : if (hasReporterValueByName<std::vector<Real>>(r_name))
108 912 : declareValueHelper<std::vector<Real>, Real>(r_name);
109 148 : else if (hasReporterValueByName<std::vector<int>>(r_name))
110 48 : declareValueHelper<std::vector<int>, Real>(r_name);
111 100 : else if (hasReporterValueByName<std::vector<std::vector<Real>>>(r_name))
112 96 : declareValueHelper<std::vector<std::vector<Real>>, std::vector<Real>>(r_name);
113 : else
114 8 : unsupported_types.emplace_back(r_name.getCombinedName());
115 : }
116 :
117 874 : if (!unsupported_types.empty())
118 4 : paramError("reporters",
119 : "The following reporter value(s) do not have a type supported by the "
120 : "StatisticsReporter:\n",
121 4 : MooseUtils::join(unsupported_types, ", "));
122 870 : }
123 :
124 : // Stats for VPP
125 1740 : if (isParamValid("vectorpostprocessors"))
126 : {
127 556 : const auto & vpp_names = getParam<std::vector<VectorPostprocessorName>>("vectorpostprocessors");
128 588 : for (const auto & vpp_name : vpp_names)
129 : {
130 : const VectorPostprocessor & vpp_object =
131 310 : _fe_problem.getVectorPostprocessorObjectByName(vpp_name);
132 310 : const std::set<std::string> & vpp_vectors = vpp_object.getVectorNames();
133 700 : for (const auto & vec_name : vpp_vectors)
134 : {
135 390 : ReporterName r_name(vpp_name, vec_name);
136 390 : declareValueHelper<std::vector<Real>, Real>(r_name);
137 : }
138 : }
139 : }
140 :
141 870 : _initialized = true;
142 : }
143 :
144 : void
145 450 : StatisticsReporter::store(nlohmann::json & json) const
146 : {
147 450 : Reporter::store(json);
148 450 : if (_ci_method.isValid())
149 370 : json["confidence_intervals"] = {{"method", _ci_method},
150 : {"levels", _ci_levels},
151 : {"replicates", _ci_replicates},
152 4810 : {"seed", _ci_seed}};
153 5260 : }
154 :
155 : template <typename InType, typename OutType>
156 : void
157 1446 : StatisticsReporter::declareValueHelper(const ReporterName & r_name)
158 : {
159 1446 : const auto & mode = _fe_problem.getReporterData().getReporterMode(r_name);
160 1446 : const auto & data = getReporterValueByName<InType>(r_name);
161 5118 : for (const auto & item : _compute_stats)
162 : {
163 7344 : const std::string s_name =
164 3672 : r_name.getObjectName() + "_" + r_name.getValueName() + "_" + item.name();
165 3672 : if (_ci_method.isValid())
166 : declareValueByName<std::pair<OutType, std::vector<OutType>>,
167 9184 : 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 5504 : ReporterStatisticsContext<InType, OutType>>(
179 : s_name, REPORTER_MODE_ROOT, data, mode, item);
180 : }
181 1446 : }
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);
|