OGS
Properties-impl.h
Go to the documentation of this file.
1
13#include <typeinfo>
14
15template <typename T>
16PropertyVector<T>* Properties::createNewPropertyVector(
17 std::string_view name, MeshItemType mesh_item_type,
18 std::size_t n_components)
19{
20 auto it(_properties.find(std::string(name)));
21 if (it != _properties.end()) {
22 ERR("A property of the name '{:s}' is already assigned to the mesh.",
23 name);
24 return nullptr;
25 }
26 auto entry_info(_properties.insert(
27 std::make_pair(std::string(name),
28 new PropertyVector<T>(std::string(name), mesh_item_type,
29 n_components))));
30 return static_cast<PropertyVector<T>*>((entry_info.first)->second);
31}
32
33template <typename T>
34PropertyVector<T>* Properties::createNewPropertyVector(
35 std::string_view name, MeshItemType mesh_item_type,
36 std::size_t n_property_values, std::size_t n_components)
37{
38 auto it(_properties.find(std::string(name)));
39 if (it != _properties.end())
40 {
41 ERR("A property of the name '{:s}' is already assigned to the mesh.",
42 name);
43 return nullptr;
44 }
45 auto entry_info(_properties.insert(std::make_pair(
46 std::string(name),
47 new PropertyVector<T>(n_property_values, std::string(name),
48 mesh_item_type, n_components))));
49 return static_cast<PropertyVector<T>*>((entry_info.first)->second);
50}
51
52template <typename T>
53PropertyVector<T>* Properties::createNewPropertyVector(
54 std::string const& name,
55 std::size_t n_prop_groups,
56 std::vector<std::size_t> const& item2group_mapping,
57 MeshItemType mesh_item_type,
58 std::size_t n_components)
59{
60 // check if there is already a PropertyVector with the same name
61 auto it(_properties.find(name));
62 if (it != _properties.end()) {
63 ERR("A property of the name '{:s}' already assigned to the mesh.",
64 name);
65 return nullptr;
66 }
67
68 // check entries of item2group_mapping for consistence
69 for (std::size_t k(0); k<item2group_mapping.size(); k++) {
70 std::size_t const group_id (item2group_mapping[k]);
71 if (group_id >= n_prop_groups) {
72 ERR("The mapping to property {:d} for item {:d} is not in the "
73 "correct range [0,{:d}).",
74 group_id, k, n_prop_groups);
75 return nullptr;
76 }
77 }
78
79 auto entry_info(
80 _properties.insert(
81 std::pair<std::string, PropertyVectorBase*>(
82 name,
83 new PropertyVector<T>(n_prop_groups,
84 item2group_mapping, name, mesh_item_type, n_components)
85 )
86 )
87 );
88 return static_cast<PropertyVector<T>*>((entry_info.first)->second);
89}
90
91template <typename T>
92bool Properties::existsPropertyVector(std::string_view name) const
93{
94 auto it(_properties.find(std::string(name)));
95 // Check that a PropertyVector with the appropriate name exists.
96 if (it == _properties.end())
97 {
98 return false;
99 }
100 // Check that the PropertyVector has the correct data type.
101 return dynamic_cast<PropertyVector<T> const*>(it->second) != nullptr;
102}
103
104template <typename T>
105bool Properties::existsPropertyVector(std::string_view name,
106 MeshItemType const mesh_item_type,
107 int const number_of_components) const
108{
109 auto const it = _properties.find(std::string(name));
110 if (it == _properties.end())
111 {
112 return false;
113 }
114
115 auto property = dynamic_cast<PropertyVector<T>*>(it->second);
116 if (property == nullptr)
117 {
118 WARN("Property {} exists but does not have the requested type {}.",
119 name, typeid(T).name());
120 return false;
121 }
122 if (property->getMeshItemType() != mesh_item_type)
123 {
124 WARN(
125 "Property {} exists but does not have the requested mesh item type "
126 "{}.",
127 name, toString(mesh_item_type));
128 return false;
129 }
130 if (property->getNumberOfGlobalComponents() != number_of_components)
131 {
132 WARN(
133 "Property {} exists but does not have the requested number of "
134 "components {}",
135 name, number_of_components);
136 return false;
137 }
138 return true;
139}
140
141template <typename T>
142PropertyVector<T> const* Properties::getPropertyVector(
143 std::string_view name) const
144{
145 return const_cast<PropertyVector<T> const*>(
146 const_cast<Properties*>(this)->getPropertyVector<T>(name));
147}
148
149template <typename T>
150PropertyVector<T>* Properties::getPropertyVector(std::string_view name)
151{
152 auto it(_properties.find(std::string(name)));
153 if (it == _properties.end())
154 {
155 OGS_FATAL(
156 "A PropertyVector with the specified name '{:s}' is not available.",
157 name);
158 }
159 if (!dynamic_cast<PropertyVector<T>*>(it->second))
160 {
161 OGS_FATAL(
162 "The PropertyVector '{:s}' has a different type than the requested "
163 "PropertyVector.",
164 name);
165 }
166 return dynamic_cast<PropertyVector<T>*>(it->second);
167}
168
169template <typename T>
170bool Properties::hasPropertyVector(std::string const& name,
171 MeshItemType const item_type) const
172{
173 auto const it = _properties.find(name);
174
175 if (it == _properties.end())
176 {
177 return false;
178 }
179
180 auto property = dynamic_cast<PropertyVector<T>*>(it->second);
181
182 return (property == nullptr) ? false
183 : property->getMeshItemType() == item_type;
184}
185
186template <typename T>
187PropertyVector<T> const* Properties::getPropertyVector(
188 std::string_view name, MeshItemType const item_type,
189 int const n_components) const
190{
191 auto const it = _properties.find(std::string(name));
192 if (it == _properties.end())
193 {
194 OGS_FATAL(
195 "A PropertyVector with name '{:s}' does not exist in the mesh.",
196 name);
197 }
198
199 auto property = dynamic_cast<PropertyVector<T>*>(it->second);
200 if (property == nullptr)
201 {
202 OGS_FATAL(
203 "Could not cast the data type of the PropertyVector '{:s}' (type: "
204 "'{:s}') to the requested data type '{:s}'.",
205 name, typeid(decltype(*it->second)).name(),
206 typeid(PropertyVector<T>).name());
207 }
208 if (property->getMeshItemType() != item_type)
209 {
210 OGS_FATAL(
211 "The PropertyVector '{:s}' has type '{:s}'. A '{:s}' field is "
212 "requested.",
213 name, toString(property->getMeshItemType()), toString(item_type));
214 }
215 if (property->getNumberOfGlobalComponents() != n_components)
216 {
217 OGS_FATAL(
218 "PropertyVector '{:s}' has {:d} components, {:d} components are "
219 "needed.",
220 name, property->getNumberOfGlobalComponents(), n_components);
221 }
222 return property;
223}
224
225template <typename T>
226PropertyVector<T>* Properties::getPropertyVector(std::string_view name,
227 MeshItemType const item_type,
228 int const n_components)
229{
230 auto const it = _properties.find(std::string(name));
231 if (it == _properties.end())
232 {
233 OGS_FATAL(
234 "A PropertyVector with name '{:s}' does not exist in the mesh.",
235 name);
236 }
237
238 auto property = dynamic_cast<PropertyVector<T>*>(it->second);
239 if (property == nullptr)
240 {
241 OGS_FATAL(
242 "Could not cast the data type of the PropertyVector '{:s}' to "
243 "requested data type.",
244 name);
245 }
246 if (property->getMeshItemType() != item_type)
247 {
248 OGS_FATAL(
249 "The PropertyVector '{:s}' has type '{:s}'. A '{:s}' field is "
250 "requested.",
251 name, toString(property->getMeshItemType()), toString(item_type));
252 }
253 if (property->getNumberOfGlobalComponents() != n_components)
254 {
255 OGS_FATAL(
256 "PropertyVector '{:s}' has {:d} components, {:d} components are "
257 "needed.",
258 name, property->getNumberOfGlobalComponents(), n_components);
259 }
260 return property;
261}
262
263template <typename Function>
264void applyToPropertyVectors(Properties const& properties, Function f)
265{
266 for (auto [name, property] : properties)
267 {
268 // Open question, why is the 'unsigned long' case not compiling giving
269 // an error "expected '(' for function-style cast or type construction"
270 // with clang-7, and "error C4576: a parenthesized type followed by an
271 // initializer list is a non-standard explicit type conversion syntax"
272 // with MSVC-15.
273 bool success = f(double{}, property) || f(float{}, property) ||
274 f(int{}, property) || f(unsigned{}, property) ||
275 f(long{}, property) ||
276 f(static_cast<unsigned long>(0), property) ||
277 f(std::size_t{}, property) || f(char{}, property) ||
278 f(static_cast<unsigned char>(0), property);
279 if (!success)
280 {
281 OGS_FATAL("Could not apply function to PropertyVector '{:s}'.",
282 property->getPropertyName());
283 }
284 }
285}
#define OGS_FATAL(...)
Definition Error.h:26
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:45
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
void applyToPropertyVectors(Properties const &properties, Function f)
Property manager on mesh items. Class Properties manages scalar, vector or matrix properties....
Definition Properties.h:33
PropertyVector< T > const * getPropertyVector(std::string_view name) const
MeshItemType getMeshItemType() const