Line data Source code
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 : 10 : #pragma once 11 : 12 : #include "libmesh/parameters.h" 13 : #include "MooseObjectParameterName.h" 14 : #include "MooseError.h" 15 : #include "ControlOutput.h" 16 : 17 : /** 18 : * An intermediate object for building a "controllable item", where an "item" can refer to multiple 19 : * input parameters with different names. 20 : * 21 : * The name supplied to the constructor is considered the "master" parameter. The parameter(s) 22 : * added via the connect method are considered the secondaries. 23 : * 24 : * In general, an ControllableItem will have a one-to-one relationship with an input parameter 25 : * value, but in some instances it is desirable to connect parameters with different names together. 26 : * For example, within MOOSE when a material is defined in an input file multiple Material objects 27 : * are generated automatically. If a parameter is controlled on one of these objects it is 28 : * necessary to also have the values on the other controlled as well. This example is the 29 : * driver behind the creation of this intermediate class. 30 : */ 31 : class ControllableItem 32 : { 33 : public: 34 : ControllableItem(const MooseObjectParameterName & name, 35 : libMesh::Parameters::Value * value, 36 : const std::set<ExecFlagType> & flags = {}); 37 1251149 : virtual ~ControllableItem() = default; 38 : 39 : ControllableItem(const ControllableItem &) = default; 40 : ControllableItem(ControllableItem &&) = default; 41 : 42 : ControllableItem & operator=(const ControllableItem &) = delete; 43 : ControllableItem & operator=(ControllableItem &&) = delete; 44 : 45 : /** 46 : * Connects the supplied item with this item to allow for multiple parameters to be changed by 47 : * one. 48 : */ 49 : void connect(ControllableItem * item, bool type_check = true); 50 : 51 : /** 52 : * Set the value(s) of the controlled parameters stored in this class. 53 : * 54 : * The 'skip_type_check' flag allows this object to work with ControllableParameter that 55 : * can store values of varying types. 56 : */ 57 : template <typename T> 58 : void set(const T & value, bool type_check = true); 59 : 60 : /** 61 : * Return a copy of all values for this "item". 62 : */ 63 : template <typename T> 64 : std::vector<T> get(bool type_check = true) const; 65 : 66 : /** 67 : * Return true if the template argument is valid for ALL items. 68 : */ 69 : template <typename T> 70 : bool check() const; 71 : 72 : ///@{ 73 : /** 74 : * Use the master name for comparison operators to allow object to work within a set/map. 75 : */ 76 : bool operator==(const ControllableItem & rhs) const { return name() == rhs.name(); } 77 : bool operator!=(const ControllableItem & rhs) const { return name() != rhs.name(); } 78 : bool operator<(const ControllableItem & rhs) const { return name() < rhs.name(); } 79 : ///@} 80 : 81 : /** 82 : * Return the name of the master parameter. 83 : */ 84 : virtual const MooseObjectParameterName & name() const; 85 : 86 : /** 87 : * Return the type of the master parameter. 88 : */ 89 : std::string type() const; 90 : 91 : /** 92 : * Returns a string displaying the parameter name and current value. 93 : */ 94 : virtual std::string dump(unsigned int indent = 0) const; 95 : 96 : ///@{ 97 : /** 98 : * Methods for ControlOutput::outputChangedControls, these don't have meaning outside of this 99 : * function. 100 : */ 101 60 : void resetChanged() { _changed = false; } 102 8280 : bool isChanged() { return _changed; } 103 : ///@} 104 : 105 : /** 106 : * Return the execute flag restrictions, an empty set is un-restricted 107 : */ 108 13517 : const std::set<ExecFlagType> & getExecuteOnFlags() const { return _execute_flags; } 109 : 110 : /// Allows this to be used with std:: cout 111 : friend std::ostream & operator<<(std::ostream & stream, const ControllableItem & obj); 112 : 113 : protected: 114 : /** 115 : * Constructor for creating an empty item (see ControllableAlias) 116 : */ 117 : ControllableItem(); 118 : 119 : /// List of names for this item 120 : std::vector<std::pair<MooseObjectParameterName, libMesh::Parameters::Value *>> _pairs; 121 : 122 : /// Flag for ControlOutput, allows output objects to keep track of when a parameter is altered 123 : bool _changed = false; 124 : 125 : /// Flags to which the control is restricted (if not set it is unrestricted) 126 : std::set<ExecFlagType> _execute_flags; 127 : }; 128 : 129 : template <typename T> 130 : void 131 12535 : ControllableItem::set(const T & value, bool type_check /*=true*/) 132 : { 133 26208 : for (auto & pair : _pairs) 134 : { 135 13675 : libMesh::Parameters::Parameter<T> * param = 136 13675 : dynamic_cast<libMesh::Parameters::Parameter<T> *>(pair.second); 137 13675 : if (type_check && param == nullptr) 138 4 : mooseError("Failed to set the '", 139 2 : pair.first, 140 : "' parameter the supplied template argument must be of type '", 141 2 : pair.second->type(), 142 : "'."); 143 13673 : else if (param != nullptr) 144 : { 145 13669 : param->set() = value; 146 13669 : _changed = true; 147 : } 148 : } 149 12533 : } 150 : 151 : template <typename T> 152 : std::vector<T> 153 1155 : ControllableItem::get(bool type_check /*=true*/) const 154 : { 155 1155 : std::vector<T> output; 156 1155 : output.reserve(_pairs.size()); 157 2825 : for (const auto & pair : _pairs) 158 : { 159 1672 : libMesh::Parameters::Parameter<T> * param = 160 1672 : dynamic_cast<libMesh::Parameters::Parameter<T> *>(pair.second); 161 1672 : if (type_check && param == nullptr) 162 4 : mooseError("Failed to get the '", 163 2 : pair.first, 164 : "' parameter the supplied template argument must be of type '", 165 2 : pair.second->type(), 166 : "'."); 167 1670 : else if (param != nullptr) 168 1650 : output.push_back(param->get()); 169 : } 170 1153 : return output; 171 2 : } 172 : 173 : template <typename T> 174 : bool 175 10 : ControllableItem::check() const 176 : { 177 10 : return std::all_of(_pairs.begin(), 178 : _pairs.end(), 179 11 : [](std::pair<MooseObjectParameterName, libMesh::Parameters::Value *> pair) 180 : { 181 11 : libMesh::Parameters::Parameter<T> * param = 182 11 : dynamic_cast<libMesh::Parameters::Parameter<T> *>(pair.second); 183 11 : return param != nullptr; 184 10 : }); 185 : } 186 : 187 : /** 188 : * Allows for aliases to be defined via InputParameterWarehouse::addControllableParameterAlias. 189 : */ 190 : class ControllableAlias : public ControllableItem 191 : { 192 : public: 193 : ControllableAlias(const MooseObjectParameterName & name, ControllableItem *); 194 : virtual const MooseObjectParameterName & name() const override; 195 : virtual std::string dump(unsigned int indent = 0) const override; 196 : 197 : private: 198 : MooseObjectParameterName _name; 199 : };