diff --git a/framework/include/reporters/MeshInfo.h b/framework/include/reporters/MeshInfo.h index 4d78d48ed510..fbcbac004d20 100644 --- a/framework/include/reporters/MeshInfo.h +++ b/framework/include/reporters/MeshInfo.h @@ -10,7 +10,7 @@ #pragma once #include "GeneralReporter.h" -class Transient; + namespace libMesh { class EquationSystems; @@ -45,11 +45,9 @@ class MeshInfo : public GeneralReporter unsigned int & _num_local_elem; unsigned int & _num_local_node; - // Used to allow for optional declare - unsigned int _dummy_unsigned_int = 0; - // Helper to perform optional declaration based on "_items" - unsigned int & declareHelper(const std::string & item_name, const ReporterMode mode); + template + T & declareHelper(const std::string & item_name, const ReporterMode mode); private: const libMesh::EquationSystems & _equation_systems; @@ -57,3 +55,11 @@ class MeshInfo : public GeneralReporter const libMesh::System & _aux_system; const libMesh::MeshBase & _mesh; }; + +template +T & +MeshInfo::declareHelper(const std::string & item_name, const ReporterMode mode) +{ + return (!_items.isValid() || _items.contains(item_name)) ? declareValueByName(item_name, mode) + : declareUnusedValue(); +} diff --git a/framework/include/reporters/Reporter.h b/framework/include/reporters/Reporter.h index 88abae97d19c..e9f969aed64b 100644 --- a/framework/include/reporters/Reporter.h +++ b/framework/include/reporters/Reporter.h @@ -9,9 +9,15 @@ #pragma once +// Moose includes #include "OutputInterface.h" #include "ReporterData.h" #include "InputParameters.h" + +// System includes +#include + +// Forward declarations class FEProblemBase; /** @@ -105,7 +111,43 @@ class Reporter : public OutputInterface T & declareValueByName(const ReporterValueName & value_name, ReporterMode mode, Args &&... args); ///@} + /** + * Declare a unused value with type T. + * + * This is useful when you have a reporter that has optional values. In this case, + * you want to create references to all reporter values. However, because some values + * are optional, you need _something_ to fill into the reference. This helper will + * create a unused value. It also allows for the passing of arguments in the case + * that your value is not trivially default constructable (constructable by default + * without arguments). + */ + template + T & declareUnusedValue(Args &&... args); + private: + /** + * Internal base struct for use in storing unused values. + * + * In order to store a vector of arbitrary unused values for declareUnusedValue(), + * we need some base object that is constructable without template arguments. + */ + struct UnusedWrapperBase + { + /// Needed for polymorphism + virtual ~UnusedWrapperBase() {} + }; + + /** + * Internal struct for storing a unused value. This allows for the storage + * of arbitrarily typed objects in a single vector for use in + * declareUnusedValue(). + */ + template + struct UnusedWrapper : UnusedWrapperBase + { + T value; + }; + /// Ref. to MooseObject params const InputParameters & _reporter_params; @@ -117,6 +159,9 @@ class Reporter : public OutputInterface /// Data storage ReporterData & _reporter_data; + + /// Storage for unused values declared with declareUnusedValue(). + std::vector> _unused_values; }; template class S, typename... Args> @@ -181,3 +226,12 @@ Reporter::declareValueByName(const ReporterValueName & value_name, buildOutputHideVariableList({state_name.getCombinedName()}); return _reporter_data.declareReporterValue(state_name, mode, args...); } + +template +T & +Reporter::declareUnusedValue(Args &&... args) +{ + _unused_values.emplace_back(libmesh_make_unique>(std::forward(args)...)); + UnusedWrapper * wrapper = dynamic_cast *>(_unused_values.back().get()); + return wrapper->value; +} diff --git a/framework/src/reporters/MeshInfo.C b/framework/src/reporters/MeshInfo.C index 0a72cfc515dc..afd855ef9c8d 100644 --- a/framework/src/reporters/MeshInfo.C +++ b/framework/src/reporters/MeshInfo.C @@ -9,7 +9,6 @@ #include "MeshInfo.h" #include "SubProblem.h" -#include "Transient.h" #include "libmesh/system.h" #include "libmesh/equation_systems.h" @@ -34,16 +33,18 @@ MeshInfo::validParams() MeshInfo::MeshInfo(const InputParameters & parameters) : GeneralReporter(parameters), _items(getParam("items")), - _num_dofs(declareHelper("num_dofs", REPORTER_MODE_REPLICATED)), - _num_dofs_nl(declareHelper("num_dofs_nonlinear", REPORTER_MODE_REPLICATED)), - _num_dofs_aux(declareHelper("num_dofs_auxiliary", REPORTER_MODE_REPLICATED)), - _num_elem(declareHelper("num_elements", REPORTER_MODE_REPLICATED)), - _num_node(declareHelper("num_nodes", REPORTER_MODE_REPLICATED)), - _num_local_dofs(declareHelper("num_local_dofs", REPORTER_MODE_DISTRIBUTED)), - _num_local_dofs_nl(declareHelper("num_dofs_local_nonlinear", REPORTER_MODE_DISTRIBUTED)), - _num_local_dofs_aux(declareHelper("num_dofs_local_auxiliary", REPORTER_MODE_DISTRIBUTED)), - _num_local_elem(declareHelper("num_local_elements", REPORTER_MODE_DISTRIBUTED)), - _num_local_node(declareHelper("num_local_nodes", REPORTER_MODE_DISTRIBUTED)), + _num_dofs(declareHelper("num_dofs", REPORTER_MODE_REPLICATED)), + _num_dofs_nl(declareHelper("num_dofs_nonlinear", REPORTER_MODE_REPLICATED)), + _num_dofs_aux(declareHelper("num_dofs_auxiliary", REPORTER_MODE_REPLICATED)), + _num_elem(declareHelper("num_elements", REPORTER_MODE_REPLICATED)), + _num_node(declareHelper("num_nodes", REPORTER_MODE_REPLICATED)), + _num_local_dofs(declareHelper("num_local_dofs", REPORTER_MODE_DISTRIBUTED)), + _num_local_dofs_nl( + declareHelper("num_dofs_local_nonlinear", REPORTER_MODE_DISTRIBUTED)), + _num_local_dofs_aux( + declareHelper("num_dofs_local_auxiliary", REPORTER_MODE_DISTRIBUTED)), + _num_local_elem(declareHelper("num_local_elements", REPORTER_MODE_DISTRIBUTED)), + _num_local_node(declareHelper("num_local_nodes", REPORTER_MODE_DISTRIBUTED)), _equation_systems(_fe_problem.es()), _nonlinear_system(_fe_problem.es().get_system("nl0")), _aux_system(_fe_problem.es().get_system("aux0")), @@ -65,11 +66,3 @@ MeshInfo::execute() _num_local_node = _mesh.n_local_nodes(); _num_local_elem = _mesh.n_local_elem(); } - -unsigned int & -MeshInfo::declareHelper(const std::string & item_name, const ReporterMode mode) -{ - return (!_items.isValid() || _items.contains(item_name)) - ? declareValueByName(item_name, mode) - : _dummy_unsigned_int; -}