OGS
Properties-impl.h
Go to the documentation of this file.
1
13template <typename T>
14PropertyVector<T>* Properties::createNewPropertyVector(
15 std::string_view name, MeshItemType mesh_item_type,
16 std::size_t n_components)
17{
18 auto it(_properties.find(std::string(name)));
19 if (it != _properties.end()) {
20 ERR("A property of the name '{:s}' is already assigned to the mesh.",
21 name);
22 return nullptr;
23 }
24 auto entry_info(_properties.insert(
25 std::make_pair(std::string(name),
26 new PropertyVector<T>(std::string(name), mesh_item_type,
27 n_components))));
28 return static_cast<PropertyVector<T>*>((entry_info.first)->second);
29}
30
31template <typename T>
32PropertyVector<T>* Properties::createNewPropertyVector(
33 std::string const& name,
34 std::size_t n_prop_groups,
35 std::vector<std::size_t> const& item2group_mapping,
36 MeshItemType mesh_item_type,
37 std::size_t n_components)
38{
39 // check if there is already a PropertyVector with the same name
40 auto it(_properties.find(name));
41 if (it != _properties.end()) {
42 ERR("A property of the name '{:s}' already assigned to the mesh.",
43 name);
44 return nullptr;
45 }
46
47 // check entries of item2group_mapping for consistence
48 for (std::size_t k(0); k<item2group_mapping.size(); k++) {
49 std::size_t const group_id (item2group_mapping[k]);
50 if (group_id >= n_prop_groups) {
51 ERR("The mapping to property {:d} for item {:d} is not in the "
52 "correct range [0,{:d}).",
53 group_id, k, n_prop_groups);
54 return nullptr;
55 }
56 }
57
58 auto entry_info(
59 _properties.insert(
60 std::pair<std::string, PropertyVectorBase*>(
61 name,
62 new PropertyVector<T>(n_prop_groups,
63 item2group_mapping, name, mesh_item_type, n_components)
64 )
65 )
66 );
67 return static_cast<PropertyVector<T>*>((entry_info.first)->second);
68}
69
70template <typename T>
71bool Properties::existsPropertyVector(std::string_view name) const
72{
73 auto it(_properties.find(std::string(name)));
74 // Check that a PropertyVector with the appropriate name exists.
75 if (it == _properties.end())
76 {
77 return false;
78 }
79 // Check that the PropertyVector has the correct data type.
80 return dynamic_cast<PropertyVector<T> const*>(it->second) != nullptr;
81}
82
83template <typename T>
84bool Properties::existsPropertyVector(std::string_view name,
85 MeshItemType const mesh_item_type,
86 int const number_of_components) const
87{
88 auto const it = _properties.find(std::string(name));
89 if (it == _properties.end())
90 {
91 return false;
92 }
93
94 auto property = dynamic_cast<PropertyVector<T>*>(it->second);
95 if (property == nullptr)
96 {
97 return false;
98 }
99 if (property->getMeshItemType() != mesh_item_type)
100 {
101 return false;
102 }
103 if (property->getNumberOfGlobalComponents() != number_of_components)
104 {
105 return false;
106 }
107 return true;
108}
109
110template <typename T>
111PropertyVector<T> const* Properties::getPropertyVector(
112 std::string_view name) const
113{
114 auto it(_properties.find(std::string(name)));
115 if (it == _properties.end())
116 {
117 OGS_FATAL("The PropertyVector '{:s}' is not available in the mesh.",
118 name);
119 }
120 if (!dynamic_cast<PropertyVector<T> const*>(it->second))
121 {
122 OGS_FATAL(
123 "The PropertyVector '{:s}' has a different type than the requested "
124 "PropertyVector.",
125 name);
126 }
127 return dynamic_cast<PropertyVector<T> const*>(it->second);
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}' to "
185 "requested data type.",
186 name);
187 }
188 if (property->getMeshItemType() != item_type)
189 {
190 OGS_FATAL(
191 "The PropertyVector '{:s}' has type '{:s}'. A '{:s}' field is "
192 "requested.",
193 name, toString(property->getMeshItemType()), toString(item_type));
194 }
195 if (property->getNumberOfGlobalComponents() != n_components)
196 {
197 OGS_FATAL(
198 "PropertyVector '{:s}' has {:d} components, {:d} components are "
199 "needed.",
200 name, property->getNumberOfGlobalComponents(), n_components);
201 }
202 return property;
203}
204
205template <typename T>
206PropertyVector<T>* Properties::getPropertyVector(std::string_view name,
207 MeshItemType const item_type,
208 int const n_components)
209{
210 auto const it = _properties.find(std::string(name));
211 if (it == _properties.end())
212 {
213 OGS_FATAL(
214 "A PropertyVector with name '{:s}' does not exist in the mesh.",
215 name);
216 }
217
218 auto property = dynamic_cast<PropertyVector<T>*>(it->second);
219 if (property == nullptr)
220 {
221 OGS_FATAL(
222 "Could not cast the data type of the PropertyVector '{:s}' to "
223 "requested data type.",
224 name);
225 }
226 if (property->getMeshItemType() != item_type)
227 {
228 OGS_FATAL(
229 "The PropertyVector '{:s}' has type '{:s}'. A '{:s}' field is "
230 "requested.",
231 name, toString(property->getMeshItemType()), toString(item_type));
232 }
233 if (property->getNumberOfGlobalComponents() != n_components)
234 {
235 OGS_FATAL(
236 "PropertyVector '{:s}' has {:d} components, {:d} components are "
237 "needed.",
238 name, property->getNumberOfGlobalComponents(), n_components);
239 }
240 return property;
241}
242
243template <typename Function>
244void applyToPropertyVectors(Properties const& properties, Function f)
245{
246 for (auto [name, property] : properties)
247 {
248 // Open question, why is the 'unsigned long' case not compiling giving
249 // an error "expected '(' for function-style cast or type construction"
250 // with clang-7, and "error C4576: a parenthesized type followed by an
251 // initializer list is a non-standard explicit type conversion syntax"
252 // with MSVC-15.
253 bool success = f(double{}, property) || f(float{}, property) ||
254 f(int{}, property) || f(unsigned{}, property) ||
255 f(long{}, property) ||
256 f(static_cast<unsigned long>(0), property) ||
257 f(std::size_t{}, property) || f(char{}, property) ||
258 f(static_cast<unsigned char>(0), property);
259 if (!success)
260 {
261 OGS_FATAL("Could not apply function to PropertyVector '{:s}'.",
262 property->getPropertyName());
263 }
264 }
265}
#define OGS_FATAL(...)
Definition Error.h:26
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:45
void applyToPropertyVectors(Properties const &properties, Function f)
MeshItemType getMeshItemType() const
MeshItemType
Definition Location.h:21