Skip to content

Commit

Permalink
Reporter that accumulates values over time idaholab#18469
Browse files Browse the repository at this point in the history
  • Loading branch information
zachmprince committed Jul 31, 2021
1 parent 9805f3c commit 97b9451
Show file tree
Hide file tree
Showing 8 changed files with 1,029 additions and 21 deletions.
25 changes: 25 additions & 0 deletions framework/doc/content/source/reporters/AccumulateReporter.md
@@ -0,0 +1,25 @@
# AccumulateReporter

!syntax description /Reporters/AccumulateReporter

## Overview

AccumulateReporter gives the ability to accumulate reporter values over time and assigns it to a vector reporter value. Currently supported reporter value types:

- `int`
- `Real` (this covers postprocessors)
- `std::string`
- `std::vector<int>`
- `std::vector<Real>` (this covers vectorpostprocessors)
- `std::vector<std::string>`

If more types need to be supported, they can easily be added by adding a line in the `if` statement in `AccumulateReporter::initialSetup()`:

!listing framework/src/reporters/AccumulateReporter.C
re=void\nAccumulateReporter::initialSetup.*?^}

!syntax parameters /Reporters/AccumulateReporter

!syntax inputs /Reporters/AccumulateReporter

!syntax children /Reporters/AccumulateReporter
111 changes: 111 additions & 0 deletions framework/include/reporters/AccumulateReporter.h
@@ -0,0 +1,111 @@
//* 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"

class AccumulatedValueBase;
template <typename T>
class AccumulatedValue;

class AccumulateReporter : public GeneralReporter
{
public:
static InputParameters validParams();
AccumulateReporter(const InputParameters & parameters);
virtual void initialSetup() override;
virtual void initialize() override {}
virtual void execute() override;
virtual void finalize() override {}

protected:
/**
* Helper for declaring an accumalative reporter value
* This will fill in _accumulated_values if the reporter value is found
*/
template <typename T>
bool declareAccumulateHelper(const ReporterName & rname);

/// Vector of accumulated value objects
std::vector<std::unique_ptr<AccumulatedValueBase>> _accumulated_values;
};

template <typename T>
bool
AccumulateReporter::declareAccumulateHelper(const ReporterName & rname)
{
const ReporterData & rdata = _fe_problem.getReporterData();

if (!rdata.hasReporterValue<T>(rname))
return false;

const auto & pmode = rdata.getReporterMode(rname);
ReporterMode rmode = REPORTER_MODE_UNSET;
if (pmode == REPORTER_MODE_ROOT)
rmode = REPORTER_MODE_ROOT;
else if (pmode == REPORTER_MODE_REPLICATED)
rmode = REPORTER_MODE_REPLICATED;
else if (pmode == REPORTER_MODE_DISTRIBUTED)
rmode = REPORTER_MODE_DISTRIBUTED;
const T & val = getReporterValueByName<T>(rname);
std::vector<T> & acc_val =
declareValueByName<std::vector<T>>(rname.getObjectName() + ":" + rname.getValueName(), rmode);

_accumulated_values.push_back(libmesh_make_unique<AccumulatedValue<T>>(val, acc_val));
return true;
}

class AccumulatedValueBase
{
public:
AccumulatedValueBase() = default;
virtual ~AccumulatedValueBase() = default;

virtual void accumulate(Real acc_id)
{
auto it = std::find(_acc_index.begin(), _acc_index.end(), acc_id);
unsigned int ind;
if (it == _acc_index.end())
{
_acc_index.push_back(acc_id);
ind = _acc_index.size() - 1;
}
else
ind = std::distance(_acc_index.begin(), it);
accumulateInternal(ind);
}

protected:
virtual void accumulateInternal(unsigned int index) = 0;
std::vector<Real> _acc_index;
};

template <typename T>
class AccumulatedValue : public AccumulatedValueBase
{
public:
AccumulatedValue(const T & val, std::vector<T> & acc_val)
: AccumulatedValueBase(), _val(val), _acc_val(acc_val)
{
}

protected:
virtual void accumulateInternal(unsigned int index) override
{
if (_acc_val.size() <= index)
_acc_val.resize(index + 1, _val);
else
_acc_val[index] = _val;
}

private:
const T & _val;
std::vector<T> & _acc_val;
};
13 changes: 0 additions & 13 deletions framework/include/reporters/ConstantReporter.h
Expand Up @@ -32,19 +32,6 @@ class ConstantReporter : public GeneralReporter
template <typename T>
std::vector<std::vector<T> *> declareConstantVectorReporterValues(const std::string & prefix);
///@}

/// Integer reporter data
std::vector<int *> _int;
/// Real reporter data
std::vector<Real *> _real;
/// String reporter data
std::vector<std::string *> _string;
/// Vector of integers reporter data
std::vector<std::vector<int> *> _int_vec;
/// Vector of reals reporter data
std::vector<std::vector<Real> *> _real_vec;
/// Vector of strings reporter data
std::vector<std::vector<std::string> *> _string_vec;
};

template <typename T>
Expand Down
60 changes: 60 additions & 0 deletions framework/src/reporters/AccumulateReporter.C
@@ -0,0 +1,60 @@
//* 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 "AccumulateReporter.h"

registerMooseObject("MooseApp", AccumulateReporter);

InputParameters
AccumulateReporter::validParams()
{
InputParameters params = GeneralReporter::validParams();
params.addClassDescription("Reporter the accumulates the value of a inputted reporter value over "
"time into a vector reporter value of the same type.");
params.addRequiredParam<std::vector<ReporterName>>("reporters", "The reporters to accumulate.");

params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_TIMESTEP_END};
params.suppressParameter<ExecFlagEnum>("execute_on");
return params;
}

AccumulateReporter::AccumulateReporter(const InputParameters & parameters)
: GeneralReporter(parameters)
{
}

void
AccumulateReporter::initialSetup()
{
const ReporterData & rdata = _fe_problem.getReporterData();
for (const auto & rname : getParam<std::vector<ReporterName>>("reporters"))
{
if (!rdata.hasReporterValue(rname))
paramError("reporters", "Reporter ", rname, " does not exist.");

if (!declareAccumulateHelper<int>(rname) && !declareAccumulateHelper<Real>(rname) &&
!declareAccumulateHelper<std::string>(rname) &&
!declareAccumulateHelper<std::vector<int>>(rname) &&
!declareAccumulateHelper<std::vector<Real>>(rname) &&
!declareAccumulateHelper<std::vector<std::string>>(rname))
paramError("reporters",
"Reporter value ",
rname,
" is of unsupported type ",
rdata.getReporterContextBase(rname).type(),
".");
}
}

void
AccumulateReporter::execute()
{
for (auto & val : _accumulated_values)
val->accumulate(_t);
}
15 changes: 7 additions & 8 deletions framework/src/reporters/ConstantReporter.C
Expand Up @@ -25,13 +25,12 @@ ConstantReporter::validParams()
return params;
}

ConstantReporter::ConstantReporter(const InputParameters & parameters)
: GeneralReporter(parameters),
_int(declareConstantReporterValues<int>("integer")),
_real(declareConstantReporterValues<Real>("real")),
_string(declareConstantReporterValues<std::string>("string")),
_int_vec(declareConstantVectorReporterValues<int>("integer")),
_real_vec(declareConstantVectorReporterValues<Real>("real")),
_string_vec(declareConstantVectorReporterValues<std::string>("string"))
ConstantReporter::ConstantReporter(const InputParameters & parameters) : GeneralReporter(parameters)
{
declareConstantReporterValues<int>("integer");
declareConstantReporterValues<Real>("real");
declareConstantReporterValues<std::string>("string");
declareConstantVectorReporterValues<int>("integer");
declareConstantVectorReporterValues<Real>("real");
declareConstantVectorReporterValues<std::string>("string");
}
69 changes: 69 additions & 0 deletions test/tests/reporters/accumulated_reporter/accumulate_reporter.i
@@ -0,0 +1,69 @@
[Mesh/mesh]
type = GeneratedMeshGenerator
dim = 1
[]

[Problem]
kernel_coverage_check = false
solve = false
[]

[Functions/fun]
type = ParsedFunction
value = 't * x'
[]

[Postprocessors/pp]
type = FunctionValuePostprocessor
function = fun
point = '1 0 0'
execute_on = 'initial timestep_end'
[]

[VectorPostprocessors/vpp]
type = LineFunctionSampler
functions = fun
start_point = '0 0 0'
end_point = '1 0 0'
num_points = 6
sort_by = x
execute_on = 'initial timestep_end'
[]

[Reporters]
[rep]
type = ConstantReporter
integer_names = 'int'
integer_values = '1'
string_names = 'str'
string_values = 'two'
integer_vector_names = 'int_vec'
integer_vector_values = '3 4'
string_vector_names = 'str_vec'
string_vector_values = 'five six seven eight'
outputs = none
[]
[accumulate]
type = AccumulateReporter
reporters = 'pp/value vpp/fun rep/int rep/str rep/int_vec rep/str_vec'
[]
[]

[Executioner]
type = Transient
num_steps = 5

# This is just testing that AccumulateReporter doesn't accumulate picard iterations
fixed_point_max_its = 3
custom_pp = pp
direct_pp_value = true
disable_fixed_point_residual_norm_check = true
accept_on_max_fixed_point_iteration = true
[]
[Outputs]
[out]
type = JSON
execute_system_information_on = none
[]
[]

0 comments on commit 97b9451

Please sign in to comment.