Skip to content

Commit

Permalink
Merge pull request #28135 from pbehne/enum
Browse files Browse the repository at this point in the history
Improved documentation and readability of MultiMooseEnum class.
  • Loading branch information
GiudGiud authored Aug 3, 2024
2 parents 44c21b0 + 8cfbdfb commit b4f5a8a
Show file tree
Hide file tree
Showing 53 changed files with 466 additions and 290 deletions.
2 changes: 1 addition & 1 deletion framework/include/auxkernels/TagAuxBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ TagAuxBase<T>::TagAuxBase(const InputParameters & parameters)
: T(parameters), _scaled(this->template getParam<bool>("scaled"))
{
auto & execute_on = this->template getParam<ExecFlagEnum>("execute_on");
if (execute_on.size() != 1 || !execute_on.contains(EXEC_TIMESTEP_END))
if (execute_on.size() != 1 || !execute_on.isValueSet(EXEC_TIMESTEP_END))
paramError("execute_on", "must be set to EXEC_TIMESTEP_END");
}

Expand Down
2 changes: 1 addition & 1 deletion framework/include/outputs/AdvancedOutput.h
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ AdvancedOutput::initPostprocessorOrVectorPostprocessorLists(const std::string &
{
if (!_advanced_execute_on.contains(execute_data_name) ||
(_advanced_execute_on[execute_data_name].isValid() &&
_advanced_execute_on[execute_data_name].contains("none")))
_advanced_execute_on[execute_data_name].isValueSet("none")))
{
const bool is_pp_type = (execute_data_name == "postprocessors");
const std::string pp_type_str = is_pp_type ? "post-processor" : "vector post-processor";
Expand Down
2 changes: 1 addition & 1 deletion framework/include/reporters/IterationInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ template <typename T>
T &
IterationInfo::declareHelper(const std::string & item_name, T & dummy, bool extra_check)
{
return (extra_check && (!_items.isValid() || _items.contains(item_name)))
return (extra_check && (!_items.isValid() || _items.isValueSet(item_name)))
? declareValueByName<T>(item_name, REPORTER_MODE_REPLICATED)
: dummy;
}
5 changes: 3 additions & 2 deletions framework/include/reporters/MeshInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,9 @@ template <typename T>
T &
MeshInfo::declareHelper(const std::string & item_name, const ReporterMode mode)
{
return (!_items.isValid() || _items.contains(item_name)) ? declareValueByName<T>(item_name, mode)
: declareUnusedValue<T>();
return (!_items.isValid() || _items.isValueSet(item_name))
? declareValueByName<T>(item_name, mode)
: declareUnusedValue<T>();
}

void to_json(nlohmann::json & json, const std::map<BoundaryID, MeshInfo::SidesetInfo> & sidesets);
Expand Down
179 changes: 133 additions & 46 deletions framework/include/utils/MultiMooseEnum.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// MOOSE includes
#include "Moose.h"
#include "MooseEnumBase.h"
#include "MooseError.h"

// C++ includes
#include <vector>
Expand All @@ -27,29 +28,48 @@ typedef std::vector<MooseEnumItem>::const_iterator MooseEnumIterator;

/**
* This is a "smart" enum class intended to replace many of the
* shortcomings in the C++ enum type It should be initialized with a
* comma-separated list of strings which become the enum values. You
* may also optionally supply numeric ints for one or more values
* similar to a C++ enum. This is done with the "=" sign. It can be
* used any place where an integer (switch statements), const char* or
* std::string is expected. In addition the InputParameters system
* has full support for this Enum type
* shortcomings in the C++ enum type. There are two parts to a MultiMooseEnum:
* 1) The list of all possible values that a variable can have and
* 2) The subset of these values that the variable is actually set to.
* It should be initialized with a comma-separated list of strings which
* become the possible enum values. You may also optionally supply numeric
* ints for one or more values similar to a C++ enum. This is done with the
* "=" sign. It can be used any place where an integer (switch statements),
* const char* or * std::string is expected. In addition the
* InputParameters system has full support for this Enum type.
*/
class MultiMooseEnum : public MooseEnumBase
{
public:
///@{
/**
* Constructor that takes a list of enumeration values, and a separate string to set a default for
* this instance
* @param names - a list of names for this enumeration
* @param default_names - the default value for this enumeration instance
* Constructor that takes a list of valid enumeration values, and a separate string to set default
* values for this instance
* @param valid_names - a list of all possible values (names) for this enumeration
* @param initialization_values - the value(s) to set this enumeration instance to
* @param allow_out_of_range - determines whether this enumeration will accept values outside of
* it's range of
* defined values.
* its range of initially defined values. A value of true allows the addition of valid
* values to an object after it has been initialized.
*/
MultiMooseEnum(std::string names,
std::string default_names = "",
MultiMooseEnum(std::string valid_names,
std::string initialization_values,
bool allow_out_of_range = false);
// We need to explicitly define this version so MultiMooseEnum("one two", "one")
// doesn't implicitly convert "one" to a bool and use the 2-parameter constructor
MultiMooseEnum(std::string valid_names,
const char * initialization_values,
bool allow_out_of_range = false);
///@}

/**
* Constructor that takes a list of valid enumeration values, and does not set this instance to
* any particular value.
* @param valid_names - a list of all possible values (names) for this enumeration
* @param allow_out_of_range - determines whether this enumeration will accept values outside of
* its range of initially defined values. A value of true allows the addition of valid
* values to an object after it has been initialized.
*/
MultiMooseEnum(std::string valid_names, bool allow_out_of_range = false);

/**
* Copy Constructor
Expand All @@ -76,19 +96,32 @@ class MultiMooseEnum : public MooseEnumBase

///@{
/**
* Contains methods for seeing if a value is in the MultiMooseEnum.
* @return bool - the truth value indicating whether the value is present
* Methods for seeing if a value is set in the MultiMooseEnum.
* @return bool - the truth value indicating whether the value is set
*/
bool contains(const std::string & value) const { return isValueSet(value); }
bool contains(int value) const { return isValueSet(value); }
bool contains(unsigned short value) const { return isValueSet(value); }
bool contains(const MultiMooseEnum & value) const { return isValueSet(value); }
bool contains(const MooseEnumItem & value) const { return isValueSet(value); }
///@}

// The following are aliases for contains with more descriptive name
///@{
/**
* Methods for seeing if a value is set in the MultiMooseEnum.
* @return bool - the truth value indicating whether the value is set
*/
bool contains(const std::string & value) const;
bool contains(int value) const;
bool contains(unsigned short value) const;
bool contains(const MultiMooseEnum & value) const;
bool contains(const MooseEnumItem & value) const;
bool isValueSet(const std::string & value) const;
bool isValueSet(int value) const;
bool isValueSet(unsigned short value) const;
bool isValueSet(const MultiMooseEnum & value) const;
bool isValueSet(const MooseEnumItem & value) const;
///@}

///@{
/**
* Assignment operators
* Assignment operators to set the objects value from the list of possible values.
* @param names - a string, set, or vector representing one of the enumeration values.
* @return A reference to this object for chaining
*/
Expand All @@ -99,27 +132,52 @@ class MultiMooseEnum : public MooseEnumBase

///@{
/**
* Un-assign a value
* Un-assign, or unset a value. Deprecated, use eraseSetValue instead.
* @param names - a string, set, or vector giving the name to erase from the enumeration values
*/
void erase(const std::string & names);
void erase(const std::vector<std::string> & names);
void erase(const std::set<std::string> & names);
///@}

// The following replaces erase with a more descriptive name
///@{
/**
* Un-assign, or unset a value
* @param names - a string, set, or vector giving the name to erase from the enumeration values
*/
void eraseSetValue(const std::string & names);
void eraseSetValue(const std::vector<std::string> & names);
void eraseSetValue(const std::set<std::string> & names);
///@}

///@{
/**
* Insert operators
* Operator to insert (push_back) values into the enum. Existing values are preserved and
* duplicates are stored.
* @param names - a string, set, or vector representing one of the enumeration values.
* duplicates are stored. Deprecated, use setAdditionalValue instead.
* @param names - a string, set, or vector representing the enumeration values to set.
*/
void push_back(const std::string & names);
void push_back(const std::vector<std::string> & names);
void push_back(const std::set<std::string> & names);
void push_back(const MultiMooseEnum & other_enum);
///@}

// The following replaces push_back with a more descriptive name
///@{
/**
* Insert operators
* Operator to insert (push_back) values into the enum. Existing values are preserved and
* duplicates are stored.
* @param names - a string, set, or vector representing the enumeration values to set.
*/
void setAdditionalValue(const std::string & names);
void setAdditionalValue(const std::vector<std::string> & names);
void setAdditionalValue(const std::set<std::string> & names);
void setAdditionalValue(const MultiMooseEnum & other_enum);
///@}

/**
* Indexing operator
* Operator to retrieve an item from the MultiMooseEnum. The reference may not be used to change
Expand All @@ -131,29 +189,37 @@ class MultiMooseEnum : public MooseEnumBase

/**
* Indexing operator
* Operator to retrieve an item from the MultiMooseEnum.
* @param i index
* Operator to retrieve the id of an item from the MultiMooseEnum.
* @param i index corresponding to the desired item
* @returns the id of the MooseEnumItem at the supplied index
*/
unsigned int get(unsigned int i) const;

/// get the current values cast to a vector of enum type T
/// get the current values cast to a vector of enum type T. Deprecated, use getSetValueIDs instead.
template <typename T>
std::vector<T> getEnum() const;

// The following replaces getEnum with a more descriptive name
/// get the current values cast to a vector of enum type T
template <typename T>
std::vector<T> getSetValueIDs() const;

///@{
/**
* Returns a begin/end iterator to all of the items in the enum. Items will
* always be capitalized.
* Returns a begin/end iterator to all of the set values in the enum.
* Items will always be capitalized.
*/
MooseEnumIterator begin() const { return _current.begin(); }
MooseEnumIterator end() const { return _current.end(); }
MooseEnumIterator begin() const { return _current_values.begin(); }
MooseEnumIterator end() const { return _current_values.end(); }
///@}

///@{
/**
* Clear the MultiMooseEnum
*/
void clearSetValues();
void clear();
///@}

/**
* Return the number of active items in the MultiMooseEnum
Expand All @@ -164,7 +230,7 @@ class MultiMooseEnum : public MooseEnumBase
* IsValid
* @return - a Boolean indicating whether this Enumeration has been set
*/
virtual bool isValid() const override { return !_current.empty(); }
virtual bool isValid() const override { return !_current_values.empty(); }

// InputParameters and Output is allowed to create an empty enum but is responsible for
// filling it in after the fact
Expand All @@ -173,29 +239,42 @@ class MultiMooseEnum : public MooseEnumBase
/// Operator for printing to iostreams
friend std::ostream & operator<<(std::ostream & out, const MultiMooseEnum & obj);

// The following functions would add possible values
// (to _items) that an enumerated variable can take. However "+=" is not a
// descriptive enough funtion name for this and should not be used in case
// users get confused that the operator actually changes the set values of the
// variable (_current_values). We have re-implemented this logic under a method
// with a more descirptive name to force users to be informed. These are deprecated.
MooseEnumBase & operator+=(const std::string & name);
MooseEnumBase & operator+=(const std::initializer_list<std::string> & names);

// The following replaces operator+= with a more descriptive name
/// Extends the range of possible values the variable can be set to
void addValidName(const std::string & name);
void addValidName(const std::initializer_list<std::string> & names);

protected:
/// Check whether any of the current values are deprecated when called
virtual void checkDeprecated() const override;

/**
* Helper method for all inserts and assignment operators
* @param first An iterator specifying the beginning of the range of values to set
* @param last An iterator specifying the end of the range of values to set
*/
template <typename InputIterator>
MultiMooseEnum & assign(InputIterator first, InputIterator last, bool append);
MultiMooseEnum & assignValues(InputIterator first, InputIterator last, bool append);

/**
* Helper method for un-assigning enumeration values
* @param first An iterator specifying the beginning of the range of values to set
* @param last An iterator specifying the end of the range of values to set
*/
template <typename InputIterator>
void remove(InputIterator first, InputIterator last);

/**
* Set the current items.
*/
void setCurrentItems(const std::vector<MooseEnumItem> & current);
void removeSetValues(InputIterator first, InputIterator last);

/// The current id
std::vector<MooseEnumItem> _current;
/// The current value(s) of the MultiMooseEnum.
std::vector<MooseEnumItem> _current_values;

/**
* Protected constructor for use by libmesh::Parameters
Expand All @@ -211,14 +290,22 @@ class MultiMooseEnum : public MooseEnumBase

template <typename T>
std::vector<T>
MultiMooseEnum::getEnum() const
MultiMooseEnum::getSetValueIDs() const
{
#ifdef LIBMESH_HAVE_CXX11_TYPE_TRAITS
static_assert(std::is_enum<T>::value == true,
"The type requested from MooseEnum::getEnum must be an enum type!\n\n");
#endif
std::vector<T> enum_vec;
for (const auto & current : _current)
enum_vec.push_back(static_cast<T>(current.id()));
for (const auto & current_value : _current_values)
enum_vec.push_back(static_cast<T>(current_value.id()));
return enum_vec;
}

template <typename T>
std::vector<T>
MultiMooseEnum::getEnum() const
{
mooseDeprecated("MultiMooseEnum::getEnum is deprecated, use MultiMooseEnum::getSetValueIDs");
return MultiMooseEnum::getSetValueIDs<T>();
}
10 changes: 5 additions & 5 deletions framework/src/executioners/EigenExecutionerBase.C
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ EigenExecutionerBase::init()
// check when the postprocessors are evaluated
const ExecFlagEnum & bx_exec =
_problem.getUserObject<UserObject>(getParam<PostprocessorName>("bx_norm")).getExecuteOnEnum();
if (!bx_exec.contains(EXEC_LINEAR))
if (!bx_exec.isValueSet(EXEC_LINEAR))
mooseError("Postprocessor " + getParam<PostprocessorName>("bx_norm") +
" requires execute_on = 'linear'");

Expand All @@ -112,7 +112,7 @@ EigenExecutionerBase::init()
_norm_exec = bx_exec;

// check if _source_integral has been evaluated during initialSetup()
if (!bx_exec.contains(EXEC_INITIAL))
if (!bx_exec.isValueSet(EXEC_INITIAL))
_problem.execute(EXEC_LINEAR);

if (_source_integral == 0.0)
Expand Down Expand Up @@ -185,7 +185,7 @@ EigenExecutionerBase::inversePowerIteration(unsigned int min_iter,
{
solution_diff = &_problem.getPostprocessorValueByName(xdiff);
const ExecFlagEnum & xdiff_exec = _problem.getUserObject<UserObject>(xdiff).getExecuteOnEnum();
if (!xdiff_exec.contains(EXEC_LINEAR))
if (!xdiff_exec.isValueSet(EXEC_LINEAR))
mooseError("Postprocessor " + xdiff + " requires execute_on = 'linear'");
}

Expand Down Expand Up @@ -391,14 +391,14 @@ EigenExecutionerBase::postExecute()
}

Real s = 1.0;
if (_norm_exec.contains(EXEC_CUSTOM))
if (_norm_exec.isValueSet(EXEC_CUSTOM))
{
_console << " Cannot let the normalization postprocessor on custom.\n";
_console << " Normalization is abandoned!" << std::endl;
}
else
{
bool force = _norm_exec.contains(EXEC_TIMESTEP_END) || _norm_exec.contains(EXEC_LINEAR);
bool force = _norm_exec.isValueSet(EXEC_TIMESTEP_END) || _norm_exec.isValueSet(EXEC_LINEAR);
s = normalizeSolution(force);
if (!MooseUtils::absoluteFuzzyEqual(s, 1.0))
_console << " Solution is rescaled with factor " << s << " for normalization!" << std::endl;
Expand Down
2 changes: 1 addition & 1 deletion framework/src/executioners/Eigenvalue.C
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ Eigenvalue::init()
{
const auto & normpp = getParam<PostprocessorName>("normalization");
const auto & exec = _eigen_problem.getUserObject<UserObject>(normpp).getExecuteOnEnum();
if (!exec.contains(EXEC_LINEAR))
if (!exec.isValueSet(EXEC_LINEAR))
mooseError("Normalization postprocessor ", normpp, " requires execute_on = 'linear'");
}

Expand Down
Loading

0 comments on commit b4f5a8a

Please sign in to comment.