Line data Source code
1 : /*************************************************/ 2 : /* DO NOT MODIFY THIS HEADER */ 3 : /* */ 4 : /* MASTODON */ 5 : /* */ 6 : /* (c) 2015 Battelle Energy Alliance, LLC */ 7 : /* ALL RIGHTS RESERVED */ 8 : /* */ 9 : /* Prepared by Battelle Energy Alliance, LLC */ 10 : /* With the U. S. Department of Energy */ 11 : /* */ 12 : /* See COPYRIGHT for full restrictions */ 13 : /*************************************************/ 14 : 15 : #ifndef LAYEREDMATERIALINTERFACE_H 16 : #define LAYEREDMATERIALINTERFACE_H 17 : 18 : // MOOSE includes 19 : #include "MastodonTypes.h" 20 : #include "Material.h" 21 : 22 : // Mastodon includes 23 : #include "LayerParameter.h" 24 : 25 : /** 26 : * An interface class to build materials based on a layer number from a 27 : * variable. 28 : * 29 : * The main purpose is to add the getLayerParam function that allows access to 30 : * input parameters associated with a layer id in a simple manner. 31 : */ 32 : template <class T = Material> 33 : class LayeredMaterialInterface : public T 34 : { 35 : public: 36 : LayeredMaterialInterface(const InputParameters & parameters); 37 : 38 : static InputParameters validParams(); 39 : 40 : /** 41 : * Adds updating of the layer parameter data structure. 42 : */ 43 : virtual void computeProperties() override; 44 : 45 : /* 46 : * Add a vector of data that corresponds with the "layer_ids" parameter. 47 : * @param data A reference to a vector of data to correspond with layer id 48 : * data. 49 : * 50 : * This method exists to allow data to be associated with layer ids can be 51 : * computed and the accessed with 52 : * similar functionality as from getLayerParam. 53 : */ 54 : template <typename P> 55 : const MooseArray<P> & addLayerVector(const std::vector<P> & data); 56 : 57 : /** 58 : * Get a reference to the current value of a input parameter for the current 59 : * layer id. 60 : * @param param_name Name of the parameter to lookup according to layer id, it 61 : * must be the same length as "layer_ids" 62 : * and of type std::vector<Real>. 63 : */ 64 : template <typename P> 65 : const MooseArray<P> & getLayerParam(const std::string & param_name); 66 : 67 : protected: 68 : /// The variable containing the layer ids 69 : const VariableValue & _layer_variable; 70 : 71 : // The following are functions that shouldn't be modified in parent classes, 72 : // they are used to implement the internal 73 : // connection between the "layer_id" and other layer parameters. These also 74 : // must be defined prior to the _layer_id, 75 : // which is intended for use in parent classes, because the getLayerParam 76 : // function that sets the reference for the 77 : // _layer_id uses these members. 78 : private: 79 : /// The "input_ids" as entered in the input file, this is used for size 80 : /// checking of other layer parameters and 81 : /// indexing into the other parameters vectors (see _layer_id_to_param_index) 82 : const std::vector<unsigned int> & _input_layer_ids; 83 : 84 : /// Provides the index in the input parameter data for a given layer id. 85 : /// A vector is used here that is sized to the maximum available layer_id 86 : /// value, this is inefficient with respect to 87 : /// to storage because the vector might be quite large depending with only a 88 : /// few non-zero entries. However, this 89 : /// vector must be accessed at each quadrature point, so doing some sort of 90 : /// look-up will impact performance, so we 91 : /// are sacrificing memory for performance. 92 : std::vector<unsigned int> _layer_id_to_param_index; 93 : 94 : /// The vector of data to reference and parameter data from the input 95 : /// parameters object. 96 : /// This uses a shared pointer rather than a unique pointer so it can be cast 97 : /// to the LayerParameter<P> type for 98 : /// returning the MooseArray reference (see addLayerVector). 99 : std::vector<std::shared_ptr<LayerParameterBase>> _layer_data; 100 : 101 : protected: 102 : /// The current "layer id" to be used for looking up the parameters. 103 : const MooseArray<unsigned int> & _layer_id; 104 : }; 105 : 106 : template <class T> 107 766 : LayeredMaterialInterface<T>::LayeredMaterialInterface(const InputParameters & parameters) 108 : : T(parameters), 109 766 : _layer_variable(T::coupledValue("layer_variable")), 110 1532 : _input_layer_ids(T::template getParam<std::vector<unsigned int>>("layer_ids")), 111 1532 : _layer_id(getLayerParam<unsigned int>("layer_ids")) 112 : { 113 : if (!dynamic_cast<Material *>(this)) 114 : mooseError("The LayeredMaterialInterface requires that the template class " 115 : "be a Material object."); 116 : 117 766 : const std::string & doc = parameters.getDocString("layer_ids"); 118 766 : if (doc.find("[This should be modified in the parent classes") != std::string::npos) 119 0 : mooseError("The documentation for the 'layer_ids' parameter must be " 120 : "modified using InputParameters::setDocString in the " 121 : "validParams function to include information on the parameters " 122 : "which the layer ids correspond."); 123 766 : } 124 : 125 : template <class T> 126 : void 127 1176541 : LayeredMaterialInterface<T>::computeProperties() 128 : { 129 : // Number of quadrature points 130 1176541 : auto n = _layer_variable.size(); 131 : 132 5882701 : for (auto & data : _layer_data) 133 : { 134 : // Resize the MooseArray 135 4706161 : data->resize(n); 136 : 137 41588369 : for (unsigned int qp = 0; qp < n; ++qp) 138 : { 139 : // The current "layer id" 140 36882209 : unsigned int current_layer_id = static_cast<unsigned int>(std::round(_layer_variable[qp])); 141 : 142 : // The location of the data in parameter data (i.e., data.second) 143 36882209 : const unsigned int & idx = _layer_id_to_param_index[current_layer_id]; 144 36882209 : if (idx == Mastodon::INVALID_LAYER_ID) 145 1 : mooseError("The current layer id variable value (", 146 : current_layer_id, 147 : ") was not provided in the 'layer_ids' parameter of the \"", 148 : T::name(), 149 : "\" block."); 150 : 151 : // Update the reference data for the current quadrature point and layer id 152 : // qp = The current quadrature point 153 : // idx: The location in the input vectors given the current layer id 154 36882208 : data->reinit(qp, idx); 155 : } 156 : } 157 : 158 : // Call the base method 159 1176540 : T::computeProperties(); 160 1176540 : } 161 : 162 : template <class T> 163 : template <typename P> 164 : const MooseArray<P> & 165 2886 : LayeredMaterialInterface<T>::getLayerParam(const std::string & param_name) 166 : { 167 : // Get the parameter data and check that it is the same size as "layer_ids" 168 : const std::vector<P> & data = T::template getParam<std::vector<P>>(param_name); 169 2886 : if (data.size() != _input_layer_ids.size()) 170 2 : mooseError("The parameter \"", 171 : param_name, 172 : "\" in the \"", 173 : T::name(), 174 : "\" block must be the same length as the \"layer_ids\" parameter."); 175 : 176 2884 : return addLayerVector<P>(data); 177 : } 178 : 179 : template <class T> 180 : template <class P> 181 : const MooseArray<P> & 182 3181 : LayeredMaterialInterface<T>::addLayerVector(const std::vector<P> & data) 183 : { 184 : // Initialize the layer id to index map, this is done here rather than the 185 : // constructor so that 186 : // the "layer_id" can utilize the getLayerParam function. 187 3181 : if (_layer_id_to_param_index.empty()) 188 : { 189 766 : unsigned int n = *std::max_element(_input_layer_ids.begin(), _input_layer_ids.end()); 190 766 : _layer_id_to_param_index.resize(n + 1, Mastodon::INVALID_LAYER_ID); 191 2126 : for (unsigned int i = 0; i < _input_layer_ids.size(); ++i) 192 1360 : _layer_id_to_param_index[_input_layer_ids[i]] = i; 193 : } 194 : 195 : // Check that the input data being retrieved is the same size as "layer_ids" 196 3181 : if (data.size() != _input_layer_ids.size()) 197 0 : mooseError("The data in the \"", 198 : T::name(), 199 : "\" block supplied with the addLayerVector method must be the " 200 : "same length as the \"layer_ids\" parameter."); 201 : 202 : // Add the data to the list and return a reference to the MooseArray that will 203 : // be populated in computeProperties 204 6362 : _layer_data.emplace_back(std::make_shared<LayerParameter<P>>(data)); 205 : std::shared_ptr<LayerParameter<P>> ptr = 206 : std::static_pointer_cast<LayerParameter<P>>(_layer_data.back()); 207 3181 : return ptr->array(); 208 : } 209 : 210 : template <typename T> 211 : InputParameters 212 994 : LayeredMaterialInterface<T>::validParams() 213 : { 214 994 : InputParameters params = emptyInputParameters(); 215 1988 : params.addRequiredParam<std::vector<unsigned int>>( 216 : "layer_ids", 217 : "Vector of layer ids that maps one-to-one with the layered " 218 : "input parameters. [This should be modified in the parent " 219 : "classes validParam function using setDocString to include " 220 : "information on the parameters which the layer ids " 221 : "correspond.]"); 222 1988 : params.addRequiredCoupledVar("layer_variable", 223 : "The variable providing the soil layer identification."); 224 994 : return params; 225 0 : } 226 : 227 : #endif