version 3.8
metadata.hh
Go to the documentation of this file.
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//
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
35
40
41namespace Dumux::MetaData {
42
43namespace Concept {
44
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
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
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
81namespace Detail {
82
83std::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
93template<class TTagTuple, class Collector>
94void 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
113{
114
115 using JsonTree = Dumux::Json::JsonTree;
116
117public:
121 JsonTree& getTree()
122 {
123 return tree_;
124 }
125
126 const JsonTree& getTree() const
127 {
128 return tree_;
129 }
130
134 void merge(const Collector& collector)
135 {
136 this->getTree().merge_patch(collector.getTree());
137 }
138
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
179 auto& operator[] (const std::string& id)
180 { return getTree()[id]; }
181
182 template <class T>
183 static std::string className(const T& c, bool hideTemplates)
184 {
185 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 static std::string hideTemplateArguments(std::string&& s)
195 {
196 std::size_t first = s.find("<");
197 std::size_t last = s.find_last_of(">");
198
199 if(first != std::string::npos && last != std::string::npos)
200 s.replace(first, last-first+1, "<...>");
201
202 s.erase(std::unique(std::begin(s), std::end(s),
203 [](unsigned char a, unsigned char b){return std::isspace(a) && std::isspace(b);}), std::end(s));
204
205 return std::move(s);
206 }
207
208private:
209 JsonTree tree_;
210};
211
213bool jsonFileExists(const std::string& fileName)
214{
215 std::ifstream infile(fileName + ".json");
216 return infile.good();
217}
218
220template<class Collector>
221void readJsonFile(Collector& collector, const std::string& fileName)
222{
223 std::ifstream i(fileName + ".json");
224 i >> collector.getTree();
225}
226
228template<class Collector>
229void writeJsonFile(const Collector& collector, const std::string& fileName)
230{
231 std::ofstream o(fileName + ".json");
232 o << std::setw(4) << collector.getTree() << std::endl;
233}
234
236template<class Collector>
237void print(const Collector& collector)
238{
239 std::cout << collector.getTree().dump(4) << std::endl;
240}
241
242template<class Collector, class TypeTag, DiffMethod diffmethod, bool isImplicit>
243void 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
250template<class Collector, class GridGeometry>
251auto 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
264template<class Collector, class GridVariables>
265auto 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
275template<class Collector, class GridView>
276auto 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
291template<class TypeTag, class 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
A linear system assembler (residual and Jacobian) for finite volume schemes.
Base class for grid geometries.
A linear system assembler (residual and Jacobian) for finite volume schemes (box, tpfa,...
Definition: assembly/fvassembler.hh:93
bool isStationaryProblem() const
Whether we are assembling a stationary or instationary problem.
Definition: assembly/fvassembler.hh:317
Class to collect metadata.
Definition: metadata.hh:113
auto & operator[](const std::string &id)
returns the object with id of the json tree
Definition: metadata.hh:179
static std::string className(const T &c, bool hideTemplates)
Definition: metadata.hh:183
void merge(const Collector &collector)
Merges two trees by overwriting existing values.
Definition: metadata.hh:134
void append(const Collector &collector, bool convertToArrays=false)
Append data from another collector.
Definition: metadata.hh:144
const JsonTree & getTree() const
Definition: metadata.hh:126
JsonTree & getTree()
Get the json tree.
Definition: metadata.hh:121
static std::string hideTemplateArguments(std::string &&s)
Definition: metadata.hh:194
static std::string className(bool hideTemplates)
Definition: metadata.hh:189
Defines all properties used in Dumux.
An enum class to define various differentiation methods available in order to compute the derivatives...
The grid variable class for finite volume schemes, storing variables on scv and scvf (volume and flux...
A helper function for class member function introspection.
Collection of json classes from JSON for Modern C++ library.
nlohmann::json JsonTree
Definition: json.hh:15
std::string removeNamespace(std::string &&s)
Definition: metadata.hh:83
void collectTypeTagsFromTuple(Collector &collector, int depth=0, int parentBranch=-1)
Definition: metadata.hh:94
Definition: metadata.hh:41
auto collectTypeTags(Collector &collector)
Definition: metadata.hh:292
void writeJsonFile(const Collector &collector, const std::string &fileName)
writes a json tree to file
Definition: metadata.hh:229
void readJsonFile(Collector &collector, const std::string &fileName)
reads a json file into a tree
Definition: metadata.hh:221
bool jsonFileExists(const std::string &fileName)
convenience function to check if file exists
Definition: metadata.hh:213
void collectMetaData(Collector &collector, const FVAssembler< TypeTag, diffmethod, isImplicit > &a, bool hideTemplates=true)
Definition: metadata.hh:243
void print(const Collector &collector)
prints json tree
Definition: metadata.hh:237
Concept of GridGeometry.
Definition: metadata.hh:47
auto require(const GG &gg) -> decltype(gg.isPeriodic(), gg.numScv(), gg.numScvf(), gg.numBoundaryScvf(), gg.numDofs(), GG::discMethod)
Concept of GridVariables.
Definition: metadata.hh:61
auto require(const GV &gv) -> decltype(Dune::Concept::requireType< typename GV::GridVolumeVariables >(), Dune::Concept::requireType< typename GV::VolumeVariables >(), Dune::Concept::requireType< typename GV::GridFluxVariablesCache >())
Concept of GridView.
Definition: metadata.hh:72
auto require(const GV &gv) -> decltype(Dune::Concept::requireBaseOf< Dune::GridView< typename GV::Traits >, GV >())
Utilities for template meta programming.