https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PolynomialChaosReporter.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
11
12#include "SobolReporter.h"
13#include "StochasticReporter.h"
14
16
19{
22 "Tool for extracting data from PolynomialChaos surrogates and computing statistics.");
23 params.addRequiredParam<std::vector<UserObjectName>>(
24 "pc_name", "Name(s) of PolynomialChaos surrogate object(s).");
25 params.addParam<bool>("include_data",
26 false,
27 "True to output information on the polynomial chaos model, including "
28 "polynomial types, orders, and coefficients.");
29 MultiMooseEnum stats("mean=1 stddev=2 skewness=3 kurtosis=4", "");
30 params.addParam<MultiMooseEnum>("statistics", stats, "Statistics to compute.");
31 params.addParam<bool>("include_sobol", false, "True to compute Sobol indices.");
32 params.addParam<std::vector<std::vector<Real>>>(
33 "local_sensitivity_points",
34 std::vector<std::vector<Real>>(0),
35 "Points for each polynomial chaos surrogate specifying desired location of sensitivity "
36 "measurement.");
37 params.addParam<std::vector<SamplerName>>(
38 "local_sensitivity_sampler",
39 std::vector<SamplerName>(0),
40 "Sampler for each polynomial chaos surrogate specifying desired location of sensitivity "
41 "measurement.");
42 return params;
43}
44
46 : GeneralReporter(parameters),
48 _loc_point(getParam<std::vector<std::vector<Real>>>("local_sensitivity_points"))
49{
50 for (const auto & sn : getParam<std::vector<SamplerName>>("local_sensitivity_sampler"))
51 _loc_sampler.push_back(&getSamplerByName(sn));
52
53 for (const auto & nm : getParam<std::vector<UserObjectName>>("pc_name"))
54 {
55 // Gather polynomial chaos surrogates
56 _pc.push_back(&getSurrogateModelByName<PolynomialChaos>(nm));
57 // PolynomialChaos data reporter
58 if (getParam<bool>("include_data"))
59 {
60 auto & pc_ptr = declareValueByName<const PolynomialChaos *>(nm, REPORTER_MODE_ROOT);
61 pc_ptr = _pc.back();
62 }
63 // Statistics reporter
64 for (const auto & stat : getParam<MultiMooseEnum>("statistics"))
65 declareValueByName<std::pair<Real, std::vector<Real>>, PCStatisticsContext<Real>>(
66 nm + "_" + stat.name(), REPORTER_MODE_ROOT, *_pc.back(), stat);
67 // Sobol reporter
68 if (getParam<bool>("include_sobol"))
69 declareValueByName<std::pair<std::vector<Real>, std::vector<std::vector<Real>>>,
70 PCSobolContext<Real>>(nm + "_SOBOL", REPORTER_MODE_ROOT, *_pc.back());
71 // Local sensitivity points reporter
72 if (_loc_point.size() > 0)
73 {
74 if (_loc_point.size() < _pc.size())
75 paramError("local_sensitivity_points",
76 "There must be a set of points for each inputted polynomial chaos model.");
77 _loc_point_sense.push_back(&declareValueByName<std::vector<std::vector<Real>>>(
78 nm + "_POINT_SENSITIVITY", REPORTER_MODE_ROOT));
79 }
80 // Local sensitivity sampler reporter
81 if (_loc_sampler.size() > 0)
82 {
83 if (_loc_sampler.size() < _pc.size())
84 paramError("local_sensitivity_sampler",
85 "There must be a sampler for each inputted polynomial chaos model.");
86 _loc_sampler_sense.push_back(
87 &declareValueByName<std::vector<std::vector<Real>>,
88 StochasticReporterContext<std::vector<Real>>>(
89 nm + "_SAMPLE_SENSITIVITY", REPORTER_MODE_ROOT, *_loc_sampler[_pc.size() - 1]));
90 }
91 }
92}
93
94void
96{
97 if ((_loc_point.size() + _loc_sampler.size()) == 0)
98 return;
99
100 for (const auto & i : index_range(_pc))
101 {
102 const auto & pc = *_pc[i];
103 const auto nparam = pc.getNumberOfParameters();
104 if (_loc_point.size() > 0)
105 {
106 if (_loc_point[i].size() % pc.getNumberOfParameters() != 0)
107 paramError("local_sensitivity_points",
108 "Number of values must be divisible by number of parameters in "
109 "Polynomial Chaos model.");
110
111 const auto npoint = _loc_point[i].size() / nparam;
112 _loc_point_sense[i]->resize(npoint);
113 for (const auto & p : make_range(npoint))
114 {
115 const std::vector<Real> data(_loc_point[i].begin() + p * nparam,
116 _loc_point[i].begin() + (p + 1) * nparam);
117 (*_loc_point_sense[i])[p] = computeLocalSensitivity(pc, data);
118 }
119
120 if (_loc_sampler.size() > 0)
121 {
122 if (_loc_sampler[i]->getNumberOfCols() != nparam)
124 "local_sensitivity_sampler",
125 "Sampler ",
126 _loc_sampler[i]->name(),
127 " does not have the same number of columns as the number of dimensions in model ",
128 pc.name(),
129 ".");
130 for (const auto & p : make_range(_loc_sampler[i]->getNumberOfLocalRows()))
131 (*_loc_sampler_sense[i])[p] =
132 computeLocalSensitivity(pc, _loc_sampler[i]->getNextLocalRow());
133 }
134 }
135 }
136}
137
138std::vector<Real>
140 const std::vector<Real> & data)
141{
142 std::vector<Real> sense(data.size());
143 const auto val = pc.evaluate(data);
144 for (const auto & d : index_range(data))
145 sense[d] = data[d] / val * pc.computeDerivative(d, data);
146 return sense;
147}
148
149void
150to_json(nlohmann::json & json, const PolynomialChaos * const & pc)
151{
152 pc->store(json);
153}
154
155template <typename OutType>
157 const libMesh::ParallelObject & other,
158 const MooseObject & producer,
159 ReporterState<std::pair<OutType, std::vector<OutType>>> & state,
160 const PolynomialChaos & pc,
161 const MooseEnumItem & stat)
162 : ReporterGeneralContext<std::pair<OutType, std::vector<OutType>>>(other, producer, state),
163 _pc(pc),
164 _stat(stat)
165{
166}
167
168template <typename OutType>
169void
171{
172 // Compute standard deviation
173 OutType sig = OutType();
174 if (_stat == "stddev" || _stat == "skewness" || _stat == "kurtosis")
175 sig = _pc.computeStandardDeviation();
176
177 OutType & val = this->_state.value().first;
178 val = OutType();
179 // Mean
180 if (_stat == "mean" && this->processor_id() == 0)
181 val = _pc.computeMean();
182 // Standard Deviation
183 else if (_stat == "stddev" && this->processor_id() == 0)
184 val = sig;
185 // Skewness
186 else if (_stat == "skewness")
187 val = _pc.powerExpectation(3) / (sig * sig * sig);
188 // Kurtosis
189 else if (_stat == "kurtosis")
190 val = _pc.powerExpectation(4) / (sig * sig * sig * sig);
191 this->_communicator.sum(val);
192
194}
195
196template <typename OutType>
197void
198PCStatisticsContext<OutType>::storeInfo(nlohmann::json & json) const
199{
201 json["stat"] = _stat.name();
202}
203
204template <typename OutType>
206 const libMesh::ParallelObject & other,
207 const MooseObject & producer,
208 ReporterState<std::pair<std::vector<OutType>, std::vector<std::vector<OutType>>>> & state,
209 const PolynomialChaos & pc)
210 : ReporterGeneralContext<std::pair<std::vector<OutType>, std::vector<std::vector<OutType>>>>(
211 other, producer, state),
212 _pc(pc)
213{
214}
215
216template <typename OutType>
217void
219{
220 const unsigned int nparam = _pc.getNumberOfParameters();
221 std::vector<OutType> & val = this->_state.value().first;
222 val.clear();
223
224 // Compute variance
225 auto var = _pc.computeStandardDeviation();
226 var *= var;
227
228 // First order
229 for (const auto & i : make_range(nparam))
230 val.push_back(_pc.computeSobolIndex({i}) / var);
231 // Total
232 for (const auto & i : make_range(nparam))
233 val.push_back(_pc.computeSobolTotal(i) / var);
234 // Second order
235 for (const auto & i : make_range(nparam))
236 for (const auto & j : make_range(i + 1, nparam))
237 val.push_back(_pc.computeSobolIndex({i, j}) / var);
238}
239
240template <typename OutType>
241void
242PCSobolContext<OutType>::store(nlohmann::json & json) const
243{
244 SobolReporterContext<std::vector<OutType>, OutType>::storeSobol(
245 json, this->_state.value(), _pc.getNumberOfParameters());
246}
247
248template class PCStatisticsContext<Real>;
249template class PCSobolContext<Real>;
const Real p
registerMooseObject("StochasticToolsApp", PolynomialChaosReporter)
void to_json(nlohmann::json &json, const PolynomialChaos *const &pc)
const ReporterMode REPORTER_MODE_ROOT
static InputParameters validParams()
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
const std::string & name() const
void paramError(const std::string &param, Args... args) const
PCSobolContext is almost identical to SobolReporterContext with InType == Outype.
virtual void store(nlohmann::json &json) const override
virtual void finalize() override
PCSobolContext(const libMesh::ParallelObject &other, const MooseObject &producer, ReporterState< std::pair< std::vector< OutType >, std::vector< std::vector< OutType > > > > &state, const PolynomialChaos &pc)
PCStatisticsContext is almost identical to ReporterStatisticsContext with InType == Outype.
PCStatisticsContext(const libMesh::ParallelObject &other, const MooseObject &producer, ReporterState< std::pair< OutType, std::vector< OutType > > > &state, const PolynomialChaos &pc, const MooseEnumItem &stat)
virtual void storeInfo(nlohmann::json &json) const override
virtual void finalize() override
static std::vector< Real > computeLocalSensitivity(const PolynomialChaos &pc, const std::vector< Real > &data)
Helper function for computing local sensitivity from a polynomial chaos model.
static InputParameters validParams()
virtual void execute() override
std::vector< Sampler * > _loc_sampler
Samplers for local sensitivity calculation.
std::vector< std::vector< std::vector< Real > > * > _loc_sampler_sense
Local sensitivity from sampled points.
const std::vector< std::vector< Real > > & _loc_point
Points for local sensitivity calculation.
PolynomialChaosReporter(const InputParameters &parameters)
std::vector< std::vector< std::vector< Real > > * > _loc_point_sense
Local sensitivity from specified points.
std::vector< const PolynomialChaos * > _pc
Polynomial chaos models.
Real computeDerivative(const unsigned int dim, const std::vector< Real > &x) const
Evaluates partial derivative of expansion: du(x)/dx_dim.
virtual Real evaluate(const std::vector< Real > &x) const override
Evaluate surrogate model given a row of parameters.
void store(nlohmann::json &json) const
virtual void resize(dof_id_type local_size) final
T & declareValueByName(const ReporterValueName &value_name, Args &&... args)
T & getSamplerByName(const SamplerName &name)
Interface for objects that need to use samplers.