GCC Code Coverage Report


Directory: ../../../builds/dumux-repositories/
File: /builds/dumux-repositories/dumux/dumux/common/metadata.hh
Date: 2024-05-04 19:09:25
Exec Total Coverage
Lines: 24 30 80.0%
Functions: 6 7 85.7%
Branches: 29 64 45.3%

Line Branch Exec Source
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 //
4 // SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5 // SPDX-License-Identifier: GPL-3.0-or-later
6 //
7 /*!
8 * \file
9 * \ingroup Core
10 * \brief The infrastructure to retrieve metadata information.
11 */
12 #ifndef DUMUX_COMMON_METADATA_HH
13 #define DUMUX_COMMON_METADATA_HH
14
15 #include <iostream>
16 #include <list>
17 #include <sstream>
18 #include <unordered_map>
19 #include <fstream>
20 #include <functional>
21 #include <string>
22 #include <tuple>
23
24 #include <dune/common/hybridutilities.hh>
25 #include <dune/common/indices.hh>
26 #include <dune/common/concept.hh>
27 #include <dune/common/classname.hh>
28 #include <dune/grid/common/gridview.hh>
29
30 #include <dumux/io/json.hh>
31
32 #include <dumux/common/properties.hh>
33 #include <dumux/common/typetraits/utility.hh>
34 #include <dumux/common/typetraits/isvalid.hh>
35
36 #include <dumux/assembly/fvassembler.hh>
37 #include <dumux/assembly/diffmethod.hh>
38 #include <dumux/discretization/basegridgeometry.hh>
39 #include <dumux/discretization/fvgridvariables.hh>
40
41 namespace Dumux::MetaData {
42
43 namespace Concept {
44
45 //! Concept of GridGeometry
46 struct GridGeometry
47 {
48 template<class GG>
49 auto require(const GG& gg) -> decltype(
50 gg.isPeriodic(),
51 gg.numScv(),
52 gg.numScvf(),
53 gg.numBoundaryScvf(),
54 gg.numDofs(),
55 GG::discMethod
56 );
57 };
58
59 //! Concept of GridVariables
60 struct GridVariables
61 {
62 template<class GV>
63 auto require(const GV& gv) -> decltype(
64 Dune::Concept::requireType<typename GV::GridVolumeVariables>(),
65 Dune::Concept::requireType<typename GV::VolumeVariables>(),
66 Dune::Concept::requireType<typename GV::GridFluxVariablesCache>()
67 );
68 };
69
70 //! Concept of GridView
71 struct GridView
72 {
73 template<class GV>
74 auto require(const GV& gv) -> decltype(
75 Dune::Concept::requireBaseOf<Dune::GridView<typename GV::Traits>, GV>()
76 );
77 };
78
79 } // end namespace Concept
80
81 namespace Detail {
82
83 std::string removeNamespace(std::string&& s)
84 {
85 std::size_t last = s.find_last_of("::");
86
87 if(last != std::string::npos)
88 s.erase(0, last+1);
89
90 return std::move(s);
91 }
92
93 template<class TTagTuple, class Collector>
94 void collectTypeTagsFromTuple(Collector& collector, int depth=0, int parentBranch=-1)
95 {
96 using namespace Dune::Hybrid;
97 forEach(std::make_index_sequence<std::tuple_size_v<TTagTuple>>{}, [&](auto i)
98 {
99 using type = typename std::tuple_element<i, TTagTuple>::type;
100 collector.push_back(std::tuple<int, int, std::string>{depth, parentBranch, removeNamespace(Dune::className<type>())});
101 if constexpr (Dumux::Properties::Detail::hasParentTypeTag<type>(int{}))
102 collectTypeTagsFromTuple<typename type::InheritsFrom>(collector, int{depth+1}, i);
103 });
104 }
105
106 } // end namespace Detail
107
108 /*!
109 * \ingroup Core
110 * \brief Class to collect metadata
111 */
112
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
66 class Collector
113 {
114
115 using JsonTree = Dumux::Json::JsonTree;
116
117 public:
118 /*!
119 * \brief Get the json tree
120 */
121 JsonTree& getTree()
122 {
123 59 return tree_;
124 }
125
126 const JsonTree& getTree() const
127 {
128 21 return tree_;
129 }
130
131 /*!
132 * \brief Merges two trees by overwriting existing values
133 */
134 void merge(const Collector& collector)
135 {
136 this->getTree().merge_patch(collector.getTree());
137 }
138
139 /*!
140 * \brief Append data from another collector
141 * \param collector The json collector from which data is taken
142 * \param convertToArrays Convert non-array types to array which allows appending data
143 */
144 void append(const Collector& collector, bool convertToArrays = false)
145 {
146 const auto& tree = collector.getTree();
147 for (const auto& [key, values] : tree.items())
148 {
149 auto& dataAtKey = this->getTree()[key];
150 if(dataAtKey.is_array())
151 {
152 if(values.is_array())
153 dataAtKey.insert(dataAtKey.end(), values.begin(), values.end());
154 else
155 dataAtKey.push_back(values);
156 }
157 else if(dataAtKey.is_null())
158 {
159 dataAtKey = values;
160 }
161 else if(convertToArrays)
162 {
163 // convert to array and append data
164 auto val(dataAtKey);
165 dataAtKey = JsonTree::array({val});
166 if(values.is_array())
167 dataAtKey.insert(dataAtKey.end(), values.begin(), values.end());
168 else
169 dataAtKey.push_back(values);
170 }
171 else
172 DUNE_THROW(Dune::InvalidStateException, "Unclear how to append data without conversion to array!");
173 }
174 }
175
176 /*!
177 * \brief returns the object with id of the json tree
178 */
179 auto& operator[] (const std::string& id)
180
11/22
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 21 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 1 times.
✗ Branch 23 not taken.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
✓ Branch 28 taken 1 times.
✗ Branch 29 not taken.
✓ Branch 31 taken 1 times.
✗ Branch 32 not taken.
51 { return getTree()[id]; }
181
182 template <class T>
183 1 static std::string className(const T& c, bool hideTemplates)
184 {
185
4/12
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
2 return hideTemplates ? hideTemplateArguments(Dune::className(c)) : Dune::className(c);
186 }
187
188 template <class T>
189 static std::string className(bool hideTemplates)
190 {
191 return hideTemplates ? hideTemplateArguments(Dune::className<T>()) : Dune::className<T>();
192 }
193
194 1 static std::string hideTemplateArguments(std::string&& s)
195 {
196 1 std::size_t first = s.find("<");
197 1 std::size_t last = s.find_last_of(">");
198
199
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(first != std::string::npos && last != std::string::npos)
200 s.replace(first, last-first+1, "<...>");
201
202 1 s.erase(std::unique(std::begin(s), std::end(s),
203
3/4
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 15 times.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
21 [](unsigned char a, unsigned char b){return std::isspace(a) && std::isspace(b);}), std::end(s));
204
205
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 return std::move(s);
206 }
207
208 private:
209 JsonTree tree_;
210 };
211
212 //! convenience function to check if file exists
213 20 bool jsonFileExists(const std::string& fileName)
214 {
215
1/2
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
20 std::ifstream infile(fileName + ".json");
216 40 return infile.good();
217 }
218
219 //! reads a json file into a tree
220 template<class Collector>
221 16 void readJsonFile(Collector& collector, const std::string& fileName)
222 {
223
1/2
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
32 std::ifstream i(fileName + ".json");
224
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 i >> collector.getTree();
225 16 }
226
227 //! writes a json tree to file
228 template<class Collector>
229 21 void writeJsonFile(const Collector& collector, const std::string& fileName)
230 {
231
1/2
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
21 std::ofstream o(fileName + ".json");
232
4/8
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 21 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 21 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 21 times.
✗ Branch 11 not taken.
63 o << std::setw(4) << collector.getTree() << std::endl;
233 21 }
234
235 //! prints json tree
236 template<class Collector>
237 void print(const Collector& collector)
238 {
239 std::cout << collector.getTree().dump(4) << std::endl;
240 }
241
242 template<class Collector, class TypeTag, DiffMethod diffmethod, bool isImplicit>
243 void collectMetaData(Collector& collector, const FVAssembler<TypeTag, diffmethod, isImplicit>& a, bool hideTemplates = true)
244 {
245 auto& obj = collector["Assembler"];
246 obj["Type"] = Collector::className(a, hideTemplates);
247 obj["Stationary"] = a.isStationaryProblem();
248 }
249
250 template<class Collector, class GridGeometry>
251 auto collectMetaData(Collector& collector, const GridGeometry& gg, bool hideTemplates = true)
252 -> typename std::enable_if_t<Dune::models<Concept::GridGeometry, GridGeometry>()>
253 {
254 auto& obj = collector["GridGeometry"];
255 obj["Type"] = Collector::className(gg, hideTemplates);
256 obj["IsPeriodic"] = gg.isPeriodic();
257 obj["DiscretizationMethod"] = GridGeometry::discMethod.name();
258 obj["NumScvs"] = gg.numScv();
259 obj["NumScvfs"] = gg.numScvf();
260 obj["NumBoundaryScvfs"] = gg.numBoundaryScvf();
261 obj["NumDofs"] = gg.numDofs();
262 }
263
264 template<class Collector, class GridVariables>
265 auto collectMetaData(Collector& collector, const GridVariables& gv, bool hideTemplates = true)
266 -> typename std::enable_if_t<Dune::models<Concept::GridVariables, GridVariables>()>
267 {
268 auto& obj = collector["GridVariables"];
269 obj["Type"] = Collector::className(gv, hideTemplates);
270 obj["GridVolumeVariables"]["Type"] = Collector::template className<typename GridVariables::GridVolumeVariables>(hideTemplates);
271 obj["VolumeVariables"]["Type"] = Collector::template className<typename GridVariables::VolumeVariables>(hideTemplates);
272 obj["GridFluxVariablesCache"]["Type"] = Collector::template className<typename GridVariables::GridFluxVariablesCache>(hideTemplates);
273 }
274
275 template<class Collector, class GridView>
276 auto collectMetaData(Collector& collector, const GridView& gridView, bool hideTemplates = true)
277 -> typename std::enable_if_t<Dune::models<Concept::GridView, GridView>()>
278 {
279 auto& obj = collector["GridView"];
280 obj["Type"] = Collector::className(gridView, hideTemplates);
281 obj["dimension"] = GridView::dimension;
282 obj["dimensionWorld"] = GridView::dimensionworld;
283 obj["conforming"] = GridView::conforming;
284 //obj["Grid"]["Type"] = Collector::className(gridView.grid(), hideTemplates);
285 for(int codim = 0; codim < GridView::dimension; ++codim)
286 obj["numEntities"]["codim " + std::to_string(codim) ] = gridView.size(codim);
287
288 // TODO parallel runs, i.e. overlapSize() etc.
289 }
290
291 template<class TypeTag, class Collector>
292 auto collectTypeTags(Collector& collector)
293 {
294 auto& obj = collector["TTags"];
295 obj = Dumux::Json::JsonTree::array();
296 Detail::collectTypeTagsFromTuple<std::tuple<TypeTag>>(obj);
297 }
298
299 } // end namespace Dumux::MetaData
300
301 #endif
302