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 {
16 ERR("A property of the name '{:s}' is already assigned to the mesh.",
17 name);
18 return nullptr;
19 }
20 auto entry_info(_properties.insert(
21 std::make_pair(std::string(name),
22 new PropertyVector<T>(std::string(name), mesh_item_type,
23 n_components))));
24 return static_cast<PropertyVector<T>*>((entry_info.first)->second);
25}
26
27template <typename T>
29 std::string_view name, MeshItemType mesh_item_type,
30 std::size_t n_property_values, std::size_t n_components)
31{
32 auto it(_properties.find(std::string(name)));
33 if (it != _properties.end())
34 {
35 ERR("A property of the name '{:s}' is already assigned to the mesh.",
36 name);
37 return nullptr;
38 }
39 auto entry_info(_properties.insert(std::make_pair(
40 std::string(name),
41 new PropertyVector<T>(n_property_values, std::string(name),
42 mesh_item_type, n_components))));
43 return static_cast<PropertyVector<T>*>((entry_info.first)->second);
44}
45
46template <typename T>
47bool Properties::existsPropertyVector(std::string_view name) const
48{
49 auto it(_properties.find(std::string(name)));
50 // Check that a PropertyVector with the appropriate name exists.
51 if (it == _properties.end())
52 {
53 return false;
54 }
55
56 if (dynamic_cast<PropertyVector<T> const*>(it->second) == nullptr)
57 {
58 WARN("Property '{}' exists but does not have the requested type {}.",
60 return false;
61 }
62
63 return true;
64}
65
66template <typename T>
67bool Properties::existsPropertyVector(std::string_view name,
68 MeshItemType const mesh_item_type,
69 int const number_of_components) const
70{
71 auto const it = _properties.find(std::string(name));
72 if (it == _properties.end())
73 {
74 return false;
75 }
76
77 auto property = dynamic_cast<PropertyVector<T>*>(it->second);
78 if (property == nullptr)
79 {
80 WARN("Property {} exists but does not have the requested type {}.",
82 return false;
83 }
84 if (property->getMeshItemType() != mesh_item_type)
85 {
86 WARN(
87 "Property {} exists but does not have the requested mesh item type "
88 "{}.",
89 name, toString(mesh_item_type));
90 return false;
91 }
92 if (property->getNumberOfGlobalComponents() != number_of_components)
93 {
94 WARN(
95 "Property {} exists but does not have the requested number of "
96 "components {}",
97 name, number_of_components);
98 return false;
99 }
100 return true;
101}
102
103template <typename T>
105 std::string_view name) const
106{
107 return const_cast<PropertyVector<T> const*>(
108 const_cast<Properties*>(this)->getPropertyVector<T>(name));
109}
110
111template <typename T>
113{
114 auto it(_properties.find(std::string(name)));
115 if (it == _properties.end())
116 {
117 OGS_FATAL(
118 "A PropertyVector with the specified name '{:s}' is not available.",
119 name);
120 }
121 if (!dynamic_cast<PropertyVector<T>*>(it->second))
122 {
123 OGS_FATAL(
124 "The PropertyVector '{:s}' has a different type than the requested "
125 "PropertyVector.",
126 name);
127 }
128 return dynamic_cast<PropertyVector<T>*>(it->second);
129}
130
131template <typename T>
132bool Properties::hasPropertyVector(std::string_view name,
133 MeshItemType const item_type) const
134{
135 auto const it = _properties.find(std::string(name));
136
137 if (it == _properties.end())
138 {
139 return false;
140 }
141
142 auto property = dynamic_cast<PropertyVector<T>*>(it->second);
143
144 return (property == nullptr) ? false
145 : property->getMeshItemType() == item_type;
146}
147
148template <typename T>
150 std::string_view name, MeshItemType const item_type,
151 int const n_components) const
152{
153 auto const it = _properties.find(std::string(name));
154 if (it == _properties.end())
155 {
156 OGS_FATAL(
157 "A PropertyVector with name '{:s}' does not exist in the mesh.",
158 name);
159 }
160
161 auto property = dynamic_cast<PropertyVector<T>*>(it->second);
162 if (property == nullptr)
163 {
164 OGS_FATAL(
165 "Could not cast the data type of the PropertyVector '{:s}' (type: "
166 "'{:s}') to the requested data type '{:s}'.",
167 name, BaseLib::typeToString(*it->second),
169 }
170 if (property->getMeshItemType() != item_type)
171 {
172 OGS_FATAL(
173 "The PropertyVector '{:s}' has type '{:s}'. A '{:s}' field is "
174 "requested.",
175 name, toString(property->getMeshItemType()), toString(item_type));
176 }
177 if (property->getNumberOfGlobalComponents() != n_components)
178 {
179 OGS_FATAL(
180 "PropertyVector '{:s}' has {:d} components, {:d} components are "
181 "needed.",
182 name, property->getNumberOfGlobalComponents(), n_components);
183 }
184 return property;
185}
186
187template <typename T>
189 MeshItemType const item_type,
190 int const n_components)
191{
192 auto const it = _properties.find(std::string(name));
193 if (it == _properties.end())
194 {
195 OGS_FATAL(
196 "A PropertyVector with name '{:s}' does not exist in the mesh.",
197 name);
198 }
199
200 auto property = dynamic_cast<PropertyVector<T>*>(it->second);
201 if (property == nullptr)
202 {
203 OGS_FATAL(
204 "Could not cast the data type of the PropertyVector '{:s}' to "
205 "requested data type.",
206 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 Function>
226void applyToPropertyVectors(Properties const& properties, Function f)
227{
228 for (auto [name, property] : properties)
229 {
230 // Open question, why is the 'unsigned long' case not compiling giving
231 // an error "expected '(' for function-style cast or type construction"
232 // with clang-7, and "error C4576: a parenthesized type followed by an
233 // initializer list is a non-standard explicit type conversion syntax"
234 // with MSVC-15.
235 bool success = f(double{}, property) || f(float{}, property) ||
236 f(int{}, property) || f(unsigned{}, property) ||
237 f(long{}, property) ||
238 f(static_cast<unsigned long>(0), property) ||
239 f(std::size_t{}, property) || f(char{}, property) ||
240 f(static_cast<unsigned char>(0), property);
241 if (!success)
242 {
243 OGS_FATAL("Could not apply function to PropertyVector '{:s}'.",
244 property->getPropertyName());
245 }
246 }
247}
248} // namespace MeshLib
#define OGS_FATAL(...)
Definition Error.h:10
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:26