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 "MooseTypes.h"
13 : #include <vector>
14 :
15 : /**
16 : * IndexableProperty is a helper (proxy) object to obtain a scalar component
17 : * from a material property. Use it in objects that process a scalar quantity
18 : * instead of a `Real` material property to allow the user to supply any material
19 : * property of a type from the list below along with a component index parameter to
20 : * select a scalar component from the property value.
21 : */
22 : template <typename T, bool is_ad>
23 : class IndexableProperty
24 : {
25 : public:
26 : static InputParameters validParams();
27 :
28 : IndexableProperty(T * host,
29 : const std::string & property_param = "property",
30 : const std::string & component_param = "component");
31 :
32 : /// get the selected component value for the given quadrature point
33 : GenericReal<is_ad> operator[](int qp) const;
34 :
35 : /// integrity check
36 : void check() const;
37 :
38 : protected:
39 : void checkComponents(unsigned int components) const;
40 :
41 : /// pointer to the host object
42 : T * _host;
43 :
44 : /// name of the input parameter containing the material property name
45 : const std::string & _property_param;
46 : /// name of the coupled material property (for error reporting)
47 : const std::string & _property_name;
48 : /// name of the input parameter containing the component index
49 : const std::string & _component_param;
50 :
51 : /// Index of the selected scalar component of the material property
52 : const std::vector<unsigned int> _component;
53 :
54 : ///@{ only one of those pointers will be non-null and pointing to the selected property
55 : const GenericOptionalMaterialProperty<Real, is_ad> & _property_real;
56 : const GenericOptionalMaterialProperty<std::vector<Real>, is_ad> & _property_std_vector;
57 : const GenericOptionalMaterialProperty<RealVectorValue, is_ad> & _property_real_vector_value;
58 : const GenericOptionalMaterialProperty<RankTwoTensor, is_ad> & _property_rank_two_tensor;
59 : const GenericOptionalMaterialProperty<RankThreeTensor, is_ad> & _property_rank_three_tensor;
60 : const GenericOptionalMaterialProperty<RankFourTensor, is_ad> & _property_rank_four_tensor;
61 : ///@}
62 : };
63 :
64 : template <typename T, bool is_ad>
65 : InputParameters
66 71593 : IndexableProperty<T, is_ad>::validParams()
67 : {
68 71593 : auto params = T::validParams();
69 71593 : params.template addRequiredParam<MaterialPropertyName>("property",
70 : "The name of the material property");
71 71593 : params.template addParam<std::vector<unsigned int>>(
72 : "component",
73 : {},
74 : "Index vector of the scalar component to extract from "
75 : "the material property (empty for scalar properties)");
76 71593 : return params;
77 0 : }
78 :
79 : template <typename T, bool is_ad>
80 140 : IndexableProperty<T, is_ad>::IndexableProperty(T * host,
81 : const std::string & property_param,
82 : const std::string & component_param)
83 140 : : _host(host),
84 140 : _property_param(property_param),
85 140 : _property_name(_host->template getParam<MaterialPropertyName>(_property_param)),
86 140 : _component_param(component_param),
87 140 : _component(host->template getParam<std::vector<unsigned int>>(_component_param)),
88 140 : _property_real(
89 140 : _host->template getGenericOptionalMaterialProperty<Real, is_ad>(_property_param)),
90 140 : _property_std_vector(
91 140 : _host->template getGenericOptionalMaterialProperty<std::vector<Real>, is_ad>(
92 : _property_param)),
93 140 : _property_real_vector_value(
94 140 : _host->template getGenericOptionalMaterialProperty<RealVectorValue, is_ad>(
95 : _property_param)),
96 140 : _property_rank_two_tensor(
97 140 : _host->template getGenericOptionalMaterialProperty<RankTwoTensor, is_ad>(_property_param)),
98 140 : _property_rank_three_tensor(
99 140 : _host->template getGenericOptionalMaterialProperty<RankThreeTensor, is_ad>(
100 : _property_param)),
101 140 : _property_rank_four_tensor(
102 140 : _host->template getGenericOptionalMaterialProperty<RankFourTensor, is_ad>(_property_param))
103 : {
104 140 : }
105 :
106 : template <typename T, bool is_ad>
107 : GenericReal<is_ad>
108 17440 : IndexableProperty<T, is_ad>::operator[](int qp) const
109 : {
110 17440 : if (_property_real)
111 16320 : return _property_real[qp];
112 1120 : if (_property_std_vector)
113 160 : return _property_std_vector[qp][_component[0]];
114 960 : if (_property_real_vector_value)
115 320 : return _property_real_vector_value[qp](_component[0]);
116 640 : if (_property_rank_two_tensor)
117 320 : return _property_rank_two_tensor[qp](_component[0], _component[1]);
118 320 : if (_property_rank_three_tensor)
119 160 : return _property_rank_three_tensor[qp](_component[0], _component[1], _component[2]);
120 160 : if (_property_rank_four_tensor)
121 160 : return _property_rank_four_tensor[qp](
122 160 : _component[0], _component[1], _component[2], _component[3]);
123 0 : _host->mooseError("internal error in IndexableProperty");
124 : }
125 :
126 : template <typename T, bool is_ad>
127 : void
128 138 : IndexableProperty<T, is_ad>::check() const
129 : {
130 138 : if (_property_real)
131 39 : checkComponents(0);
132 99 : else if (_property_std_vector)
133 13 : checkComponents(1);
134 86 : else if (_property_real_vector_value)
135 34 : checkComponents(1);
136 52 : else if (_property_rank_two_tensor)
137 26 : checkComponents(2);
138 26 : else if (_property_rank_three_tensor)
139 13 : checkComponents(3);
140 13 : else if (_property_rank_four_tensor)
141 13 : checkComponents(4);
142 : else
143 0 : _host->mooseError("The ",
144 0 : is_ad ? "AD" : "non-AD",
145 : " material property '",
146 0 : _property_name,
147 : "' does not exist");
148 130 : }
149 :
150 : template <typename T, bool is_ad>
151 : void
152 138 : IndexableProperty<T, is_ad>::checkComponents(unsigned int components) const
153 : {
154 138 : if (_component.size() != components)
155 16 : _host->mooseError("Material property '",
156 8 : _property_name,
157 : "' is ",
158 : components,
159 : "-dimensional, but an index vector of size ",
160 8 : _component.size(),
161 : " was supplied to select a component. It looks like you were expecting the "
162 : "material property to have a different type.");
163 130 : }
|