forked from idaholab/moose
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Creating StatisticsReporter to replace Statistics VPP
(refs idaholab#16584)
- Loading branch information
1 parent
b59e00e
commit 0761f48
Showing
15 changed files
with
657 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
122 changes: 122 additions & 0 deletions
122
modules/stochastic_tools/include/reporters/StatisticsReporter.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
//* This file is part of the MOOSE framework | ||
//* https://www.mooseframework.org | ||
//* | ||
//* All rights reserved, see COPYRIGHT for full restrictions | ||
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT | ||
//* | ||
//* Licensed under LGPL 2.1, please see LICENSE for details | ||
//* https://www.gnu.org/licenses/lgpl-2.1.html | ||
|
||
#pragma once | ||
|
||
#include "GeneralReporter.h" | ||
#include "Calculators.h" | ||
#include "BootstrapCalculators.h" | ||
|
||
#include "nlohmann/json.h" | ||
|
||
/** | ||
* ReporterContext that utilizes a Calculator object to compute its value and confidence levels | ||
*/ | ||
template <typename T> | ||
class ReporterStatisticsContext : public ReporterContext<T> | ||
{ | ||
public: | ||
ReporterStatisticsContext(const libMesh::ParallelObject & other, | ||
ReporterState<T> & state, | ||
const std::vector<T> & data, | ||
const ReporterProducerEnum & mode, | ||
const MooseEnumItem & stat, | ||
const StochasticTools::BootstrapCalculator * ci_calc); | ||
virtual void finalize() override; | ||
virtual void store(nlohmann::json & json) const override; | ||
|
||
private: | ||
/// Data used for the statistic calculation | ||
const std::vector<T> & _data; | ||
|
||
/// Mode in which the above data was produced | ||
const ReporterProducerEnum & _data_mode; | ||
|
||
/// Storage for the Calculator object for the desired stat, this is created in constructor | ||
std::unique_ptr<const StochasticTools::Calculator> _calc_ptr; | ||
|
||
/// Storage for the BootstrapCalculator for the desired confidence interval calculations (optional) | ||
const StochasticTools::BootstrapCalculator * _ci_calc_ptr; | ||
|
||
/// The results | ||
std::vector<T> _ci_results; | ||
}; | ||
|
||
template <typename T> | ||
ReporterStatisticsContext<T>::ReporterStatisticsContext( | ||
const libMesh::ParallelObject & other, | ||
ReporterState<T> & state, | ||
const std::vector<T> & data, | ||
const ReporterProducerEnum & mode, | ||
const MooseEnumItem & stat, | ||
const StochasticTools::BootstrapCalculator * ci_calc) | ||
: ReporterContext<T>(other, state), | ||
_data(data), | ||
_data_mode(mode), | ||
_calc_ptr(StochasticTools::makeCalculator(stat, other)), | ||
_ci_calc_ptr(ci_calc) | ||
{ | ||
} | ||
|
||
template <typename T> | ||
void | ||
ReporterStatisticsContext<T>::finalize() | ||
{ | ||
this->_state.value() = _calc_ptr->compute(_data, _data_mode == REPORTER_MODE_DISTRIBUTED); | ||
ReporterContext<T>::finalize(); | ||
|
||
if (_ci_calc_ptr) | ||
_ci_results = _ci_calc_ptr->compute(_data, *_calc_ptr, _data_mode == REPORTER_MODE_DISTRIBUTED); | ||
} | ||
|
||
template <typename T> | ||
void | ||
ReporterStatisticsContext<T>::store(nlohmann::json & json) const | ||
{ | ||
ReporterContext<T>::store(json); | ||
json["stat"] = _calc_ptr->name(); | ||
if (_ci_calc_ptr) | ||
json["confidence_intervals"] = {{"method", _ci_calc_ptr->name()}, | ||
{"values", _ci_results}, | ||
{"levels", _ci_calc_ptr->levels()}, | ||
{"replicates", _ci_calc_ptr->replicates()}, | ||
{"seed", _ci_calc_ptr->seed()}}; | ||
} | ||
|
||
/** | ||
* Compute several metrics for supplied data. | ||
* | ||
* This class uses Calculator objects defined in StatisticsReporter.h and is setup such that if a | ||
* new calculation is needed it can be added in StatisticsReporter.h without modification of this | ||
* object. | ||
*/ | ||
class StatisticsReporter : public GeneralReporter | ||
{ | ||
public: | ||
static InputParameters validParams(); | ||
StatisticsReporter(const InputParameters & parameters); | ||
|
||
/// Not used; all operations are wrapped in the ReporterStatisticsContext | ||
virtual void execute() final{}; | ||
virtual void initialize() final{}; | ||
virtual void finalize() final{}; | ||
|
||
protected: | ||
/// Confidence level calculator, this is shared by all reporters that are declared. | ||
std::unique_ptr<const StochasticTools::BootstrapCalculator> _ci_calculator = nullptr; | ||
|
||
private: | ||
/** | ||
* Helper function for converting confidence levels given in (0, 0.5] into levels in (0, 1). | ||
* For example, levels_in = {0.05, 0.1, 0.5} converts to {0.05 0.1, 0.5, 0.9, 0.95}. | ||
* | ||
* This also performs error checking on the supplied "ci_levels". | ||
*/ | ||
std::vector<Real> computeLevels(const std::vector<Real> & levels_in) const; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
125 changes: 125 additions & 0 deletions
125
modules/stochastic_tools/src/reporters/StatisticsReporter.C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
//* This file is part of the MOOSE framework | ||
//* https://www.mooseframework.org | ||
//* | ||
//* All rights reserved, see COPYRIGHT for full restrictions | ||
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT | ||
//* | ||
//* Licensed under LGPL 2.1, please see LICENSE for details | ||
//* https://www.gnu.org/licenses/lgpl-2.1.html | ||
|
||
#include "StatisticsReporter.h" | ||
|
||
// MOOSE includes | ||
#include "MooseVariable.h" | ||
#include "ThreadedElementLoopBase.h" | ||
#include "ThreadedNodeLoop.h" | ||
|
||
#include "libmesh/quadrature.h" | ||
|
||
#include <numeric> | ||
|
||
registerMooseObject("StochasticToolsApp", StatisticsReporter); | ||
|
||
InputParameters | ||
StatisticsReporter::validParams() | ||
{ | ||
InputParameters params = GeneralReporter::validParams(); | ||
params.addClassDescription( | ||
"Compute statistical values of a given VectorPostprocessor objects and vectors."); | ||
|
||
params.addRequiredParam<std::vector<VectorPostprocessorName>>( | ||
"vectorpostprocessors", | ||
"List of VectorPostprocessor(s) to utilized for statistic computations."); | ||
|
||
MultiMooseEnum stats = StochasticTools::makeCalculatorEnum(); | ||
params.addRequiredParam<MultiMooseEnum>( | ||
"compute", | ||
stats, | ||
"The statistic(s) to compute for each of the supplied vector postprocessors."); | ||
|
||
// Confidence Levels | ||
MooseEnum ci = StochasticTools::makeBootstrapCalculatorEnum(); | ||
params.addParam<MooseEnum>( | ||
"ci_method", ci, "The method to use for computing confidence level intervals."); | ||
|
||
params.addParam<std::vector<Real>>( | ||
"ci_levels", "A vector of confidence levels to consider, values must be in (0, 0.5]."); | ||
params.addParam<unsigned int>( | ||
"ci_replicates", | ||
10000, | ||
"The number of replicates to use when computing confidence level intervals."); | ||
params.addParam<unsigned int>("ci_seed", | ||
1, | ||
"The random number generator seed used for creating replicates " | ||
"while computing confidence level intervals."); | ||
return params; | ||
} | ||
|
||
StatisticsReporter::StatisticsReporter(const InputParameters & parameters) | ||
: GeneralReporter(parameters) | ||
{ | ||
// Statistics to be computed | ||
const auto & compute_stats = getParam<MultiMooseEnum>("compute"); | ||
|
||
// Bootstrap CI | ||
std::unique_ptr<const StochasticTools::BootstrapCalculator> ci_calculator = nullptr; | ||
const MooseEnum & ci_method = getParam<MooseEnum>("ci_method"); | ||
if (ci_method.isValid()) | ||
{ | ||
std::vector<Real> ci_levels = computeLevels(getParam<std::vector<Real>>("ci_levels")); | ||
unsigned int replicates = getParam<unsigned int>("ci_replicates"); | ||
unsigned int seed = getParam<unsigned int>("ci_seed"); | ||
_ci_calculator = | ||
StochasticTools::makeBootstrapCalculator(ci_method, *this, ci_levels, replicates, seed); | ||
} | ||
|
||
// Stats for VPP | ||
const auto & vpp_names = getParam<std::vector<VectorPostprocessorName>>("vectorpostprocessors"); | ||
for (const auto & vpp_name : vpp_names) | ||
{ | ||
const VectorPostprocessor & vpp_object = | ||
_fe_problem.getVectorPostprocessorObjectByName(vpp_name); | ||
const std::set<std::string> & vpp_vectors = vpp_object.getVectorNames(); | ||
for (const auto & vec_name : vpp_vectors) | ||
{ | ||
ReporterName r_name(vpp_name, vec_name); | ||
const auto & data = getReporterValueByName<std::vector<Real>>(r_name); | ||
const auto & mode = _fe_problem.getReporterData().getReporterMode(r_name); | ||
for (const auto & item : compute_stats) | ||
{ | ||
const std::string s_name = vpp_name + "::" + vec_name + "_" + item.name(); | ||
declareValueByName<Real, ReporterStatisticsContext>( | ||
s_name, REPORTER_MODE_ROOT, data, mode, item, _ci_calculator.get()); | ||
} | ||
} | ||
} | ||
} | ||
|
||
std::vector<Real> | ||
StatisticsReporter::computeLevels(const std::vector<Real> & levels_in) const | ||
{ | ||
if (levels_in.empty()) | ||
paramError("ci_levels", | ||
"If the 'ci_method' parameter is supplied then the 'ci_levels' must also be " | ||
"supplied with values in (0, 0.5]."); | ||
|
||
else if (*std::min_element(levels_in.begin(), levels_in.end()) <= 0) | ||
paramError("ci_levels", "The supplied levels must be greater than zero."); | ||
|
||
else if (*std::max_element(levels_in.begin(), levels_in.end()) > 0.5) | ||
paramError("ci_levels", "The supplied levels must be less than or equal to 0.5"); | ||
|
||
std::list<Real> levels_out; | ||
for (auto it = levels_in.rbegin(); it != levels_in.rend(); ++it) | ||
{ | ||
if (*it == 0.5) | ||
levels_out.push_back(*it); | ||
|
||
else | ||
{ | ||
levels_out.push_front(*it); | ||
levels_out.push_back(1 - *it); | ||
} | ||
} | ||
return std::vector<Real>(levels_out.begin(), levels_out.end()); | ||
} |
Oops, something went wrong.