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