OGS
Properties-impl.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
5
6namespace MeshLib
7{
8template <typename T>
10 std::string_view name, MeshItemType mesh_item_type,
11 std::size_t n_components)
12{
13 auto it(_properties.find(std::string(name)));
14 if (it != _properties.end()) {
15 ERR("A property of the name '{:s}' is already assigned to the mesh.",
16 name);
17 return nullptr;
18 }
19 auto entry_info(_properties.insert(
20 std::make_pair(std::string(name),
21 new PropertyVector<T>(std::string(name), mesh_item_type,
22 n_components))));
23 return static_cast<PropertyVector<T>*>((entry_info.first)->second);
24}
25
26template <typename T>
28 std::string_view name, MeshItemType mesh_item_type,
29 std::size_t n_property_values, std::size_t n_components)
30{
31 auto it(_properties.find(std::string(name)));
32 if (it != _properties.end())
33 {
34 ERR("A property of the name '{:s}' is already assigned to the mesh.",
35 name);
36 return nullptr;
37 }
38 auto entry_info(_properties.insert(std::make_pair(
39 std::string(name),
40 new PropertyVector<T>(n_property_values, std::string(name),
41 mesh_item_type, n_components))));
42 return static_cast<PropertyVector<T>*>((entry_info.first)->second);
43}
44
45template <typename T>
47 std::string const& name,
48 std::size_t n_prop_groups,
49 std::vector<std::size_t> const& item2group_mapping,
50 MeshItemType mesh_item_type,
51 std::size_t n_components)
52{
53 // check if there is already a PropertyVector with the same name
54 auto it(_properties.find(name));
55 if (it != _properties.end()) {
56 ERR("A property of the name '{:s}' already assigned to the mesh.",
57 name);
58 return nullptr;
59 }
60
61 // check entries of item2group_mapping for consistence
62 for (std::size_t k(0); k<item2group_mapping.size(); k++) {
63 std::size_t const group_id (item2group_mapping[k]);
64 if (group_id >= n_prop_groups) {
65 ERR("The mapping to property {:d} for item {:d} is not in the "
66 "correct range [0,{:d}).",
67 group_id, k, n_prop_groups);
68 return nullptr;
69 }
70 }
71
72 auto entry_info(
73 _properties.insert(
74 std::pair<std::string, PropertyVectorBase*>(
75 name,
76 new PropertyVector<T>(n_prop_groups,
77 item2group_mapping, name, mesh_item_type, n_components)
78 )
79 )
80 );
81 return static_cast<PropertyVector<T>*>((entry_info.first)->second);
82}
83
84template <typename T>
85bool Properties::existsPropertyVector(std::string_view name) const
86{
87 auto it(_properties.find(std::string(name)));
88 // Check that a PropertyVector with the appropriate name exists.
89 if (it == _properties.end())
90 {
91 return false;
92 }
93
94 if (dynamic_cast<PropertyVector<T> const*>(it->second) == nullptr)
95 {
96 WARN("Property '{}' exists but does not have the requested type {}.",
97 name, typeid(T).name());
98 return false;
99 }
100
101 return true;
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 {}.",
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>
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>
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_view name,
171 MeshItemType const item_type) const
172{
173 auto const it = _properties.find(std::string(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>
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, BaseLib::typeToString(*it->second),
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>
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}
286} // namespace MeshLib
#define OGS_FATAL(...)
Definition Error.h:19
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:34
Property manager on mesh items. Class Properties manages scalar, vector or matrix properties....
std::map< std::string, PropertyVectorBase * > _properties
bool hasPropertyVector(std::string_view name) const
bool existsPropertyVector(std::string_view name) const
PropertyVector< T > * createNewPropertyVector(std::string_view name, MeshItemType mesh_item_type, std::size_t n_components=1)
PropertyVector< T > const * getPropertyVector(std::string_view name) const
MeshItemType getMeshItemType() const
std::string typeToString()
void applyToPropertyVectors(Properties const &properties, Function f)
static constexpr char const * toString(const MeshItemType t)
Returns a char array for a specific MeshItemType.
Definition MeshEnums.h:25