3.6-git
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
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 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 *****************************************************************************/
24#ifndef DUMUX_COMMON_METADATA_HH
25#define DUMUX_COMMON_METADATA_HH
26
27#include <iostream>
28#include <list>
29#include <sstream>
30#include <unordered_map>
31#include <fstream>
32#include <functional>
33#include <string>
34#include <tuple>
35
36#include <dune/common/hybridutilities.hh>
37#include <dune/common/indices.hh>
38#include <dune/common/concept.hh>
39#include <dune/common/classname.hh>
40#include <dune/grid/common/gridview.hh>
41
42#include <dumux/io/json.hh>
43
47
52
53namespace Dumux::MetaData {
54
55namespace Concept {
56
59{
60 template<class GG>
61 auto require(const GG& gg) -> decltype(
62 gg.isPeriodic(),
63 gg.numScv(),
64 gg.numScvf(),
65 gg.numBoundaryScvf(),
66 gg.numDofs(),
67 GG::discMethod
68 );
69};
70
73{
74 template<class GV>
75 auto require(const GV& gv) -> decltype(
76 Dune::Concept::requireType<typename GV::GridVolumeVariables>(),
77 Dune::Concept::requireType<typename GV::VolumeVariables>(),
78 Dune::Concept::requireType<typename GV::GridFluxVariablesCache>()
79 );
80};
81
84{
85 template<class GV>
86 auto require(const GV& gv) -> decltype(
87 Dune::Concept::requireBaseOf<Dune::GridView<typename GV::Traits>, GV>()
88 );
89};
90
91} // end namespace Concept
92
93namespace Detail {
94
95std::string removeNamespace(std::string&& s)
96{
97 std::size_t last = s.find_last_of("::");
98
99 if(last != std::string::npos)
100 s.erase(0, last+1);
101
102 return std::move(s);
103}
104
105template<class TTagTuple, class Collector>
106void collectTypeTagsFromTuple(Collector& collector, int depth=0, int parentBranch=-1)
107{
108 using namespace Dune::Hybrid;
109 forEach(std::make_index_sequence<std::tuple_size_v<TTagTuple>>{}, [&](auto i)
110 {
111 using type = typename std::tuple_element<i, TTagTuple>::type;
112 collector.push_back(std::tuple<int, int, std::string>{depth, parentBranch, removeNamespace(Dune::className<type>())});
113 if constexpr (Dumux::Properties::Detail::hasParentTypeTag<type>(int{}))
114 collectTypeTagsFromTuple<typename type::InheritsFrom>(collector, int{depth+1}, i);
115 });
116}
117
118} // end namespace Detail
119
125{
126
127 using JsonTree = Dumux::Json::JsonTree;
128
129public:
133 JsonTree& getTree()
134 {
135 return tree_;
136 }
137
138 const JsonTree& getTree() const
139 {
140 return tree_;
141 }
142
146 void merge(const Collector& collector)
147 {
148 this->getTree().merge_patch(collector.getTree());
149 }
150
156 void append(const Collector& collector, bool convertToArrays = false)
157 {
158 const auto& tree = collector.getTree();
159 for (const auto& [key, values] : tree.items())
160 {
161 auto& dataAtKey = this->getTree()[key];
162 if(dataAtKey.is_array())
163 {
164 if(values.is_array())
165 dataAtKey.insert(dataAtKey.end(), values.begin(), values.end());
166 else
167 dataAtKey.push_back(values);
168 }
169 else if(dataAtKey.is_null())
170 {
171 dataAtKey = values;
172 }
173 else if(convertToArrays)
174 {
175 // convert to array and append data
176 auto val(dataAtKey);
177 dataAtKey = JsonTree::array({val});
178 if(values.is_array())
179 dataAtKey.insert(dataAtKey.end(), values.begin(), values.end());
180 else
181 dataAtKey.push_back(values);
182 }
183 else
184 DUNE_THROW(Dune::InvalidStateException, "Unclear how to append data without conversion to array!");
185 }
186 }
187
191 auto& operator[] (const std::string& id)
192 { return getTree()[id]; }
193
194 template <class T>
195 static std::string className(const T& c, bool hideTemplates)
196 {
197 return hideTemplates ? hideTemplateArguments(Dune::className(c)) : Dune::className(c);
198 }
199
200 template <class T>
201 static std::string className(bool hideTemplates)
202 {
203 return hideTemplates ? hideTemplateArguments(Dune::className<T>()) : Dune::className<T>();
204 }
205
206 static std::string hideTemplateArguments(std::string&& s)
207 {
208 std::size_t first = s.find("<");
209 std::size_t last = s.find_last_of(">");
210
211 if(first != std::string::npos && last != std::string::npos)
212 s.replace(first, last-first+1, "<...>");
213
214 s.erase(std::unique(std::begin(s), std::end(s),
215 [](unsigned char a, unsigned char b){return std::isspace(a) && std::isspace(b);}), std::end(s));
216
217 return std::move(s);
218 }
219
220private:
221 JsonTree tree_;
222};
223
225bool jsonFileExists(const std::string& fileName)
226{
227 std::ifstream infile(fileName + ".json");
228 return infile.good();
229}
230
232template<class Collector>
233void readJsonFile(Collector& collector, const std::string& fileName)
234{
235 std::ifstream i(fileName + ".json");
236 i >> collector.getTree();
237}
238
240template<class Collector>
241void writeJsonFile(const Collector& collector, const std::string& fileName)
242{
243 std::ofstream o(fileName + ".json");
244 o << std::setw(4) << collector.getTree() << std::endl;
245}
246
248template<class Collector>
249void print(const Collector& collector)
250{
251 std::cout << collector.getTree().dump(4) << std::endl;
252}
253
254template<class Collector, class TypeTag, DiffMethod diffmethod, bool isImplicit>
255void collectMetaData(Collector& collector, const FVAssembler<TypeTag, diffmethod, isImplicit>& a, bool hideTemplates = true)
256{
257 auto& obj = collector["Assembler"];
258 obj["Type"] = Collector::className(a, hideTemplates);
259 obj["Stationary"] = a.isStationaryProblem();
260}
261
262template<class Collector, class GridGeometry>
263auto collectMetaData(Collector& collector, const GridGeometry& gg, bool hideTemplates = true)
264-> typename std::enable_if_t<Dune::models<Concept::GridGeometry, GridGeometry>()>
265{
266 auto& obj = collector["GridGeometry"];
267 obj["Type"] = Collector::className(gg, hideTemplates);
268 obj["IsPeriodic"] = gg.isPeriodic();
269 obj["DiscretizationMethod"] = GridGeometry::discMethod.name();
270 obj["NumScvs"] = gg.numScv();
271 obj["NumScvfs"] = gg.numScvf();
272 obj["NumBoundaryScvfs"] = gg.numBoundaryScvf();
273 obj["NumDofs"] = gg.numDofs();
274}
275
276template<class Collector, class GridVariables>
277auto collectMetaData(Collector& collector, const GridVariables& gv, bool hideTemplates = true)
278-> typename std::enable_if_t<Dune::models<Concept::GridVariables, GridVariables>()>
279{
280 auto& obj = collector["GridVariables"];
281 obj["Type"] = Collector::className(gv, hideTemplates);
282 obj["GridVolumeVariables"]["Type"] = Collector::template className<typename GridVariables::GridVolumeVariables>(hideTemplates);
283 obj["VolumeVariables"]["Type"] = Collector::template className<typename GridVariables::VolumeVariables>(hideTemplates);
284 obj["GridFluxVariablesCache"]["Type"] = Collector::template className<typename GridVariables::GridFluxVariablesCache>(hideTemplates);
285}
286
287template<class Collector, class GridView>
288auto collectMetaData(Collector& collector, const GridView& gridView, bool hideTemplates = true)
289-> typename std::enable_if_t<Dune::models<Concept::GridView, GridView>()>
290{
291 auto& obj = collector["GridView"];
292 obj["Type"] = Collector::className(gridView, hideTemplates);
293 obj["dimension"] = GridView::dimension;
294 obj["dimensionWorld"] = GridView::dimensionworld;
295 obj["conforming"] = GridView::conforming;
296 //obj["Grid"]["Type"] = Collector::className(gridView.grid(), hideTemplates);
297 for(int codim = 0; codim < GridView::dimension; ++codim)
298 obj["numEntities"]["codim " + std::to_string(codim) ] = gridView.size(codim);
299
300 // TODO parallel runs, i.e. overlapSize() etc.
301}
302
303template<class TypeTag, class Collector>
305{
306 auto& obj = collector["TTags"];
307 obj = Dumux::Json::JsonTree::array();
308 Detail::collectTypeTagsFromTuple<std::tuple<TypeTag>>(obj);
309}
310
311} // end namespace Dumux::MetaData
312
313#endif
An enum class to define various differentiation methods available in order to compute the derivatives...
A helper function for class member function introspection.
Utilities for template meta programming.
Base class for grid geometries.
Collection of json classes from JSON for Modern C++ library.
Definition: metadata.hh:53
auto collectTypeTags(Collector &collector)
Definition: metadata.hh:304
void writeJsonFile(const Collector &collector, const std::string &fileName)
writes a json tree to file
Definition: metadata.hh:241
void readJsonFile(Collector &collector, const std::string &fileName)
reads a json file into a tree
Definition: metadata.hh:233
bool jsonFileExists(const std::string &fileName)
convenience function to check if file exists
Definition: metadata.hh:225
void collectMetaData(Collector &collector, const FVAssembler< TypeTag, diffmethod, isImplicit > &a, bool hideTemplates=true)
Definition: metadata.hh:255
void print(const Collector &collector)
prints json tree
Definition: metadata.hh:249
std::string removeNamespace(std::string &&s)
Definition: metadata.hh:95
void collectTypeTagsFromTuple(Collector &collector, int depth=0, int parentBranch=-1)
Definition: metadata.hh:106
nlohmann::json JsonTree
Definition: json.hh:27
A linear system assembler (residual and Jacobian) for finite volume schemes (box, tpfa,...
Definition: assembly/fvassembler.hh:119
bool isStationaryProblem() const
Whether we are assembling a stationary or instationary problem.
Definition: assembly/fvassembler.hh:382
Concept of GridGeometry.
Definition: metadata.hh:59
auto require(const GG &gg) -> decltype(gg.isPeriodic(), gg.numScv(), gg.numScvf(), gg.numBoundaryScvf(), gg.numDofs(), GG::discMethod)
Concept of GridVariables.
Definition: metadata.hh:73
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:84
auto require(const GV &gv) -> decltype(Dune::Concept::requireBaseOf< Dune::GridView< typename GV::Traits >, GV >())
Class to collect metadata.
Definition: metadata.hh:125
auto & operator[](const std::string &id)
returns the object with id of the json tree
Definition: metadata.hh:191
static std::string className(const T &c, bool hideTemplates)
Definition: metadata.hh:195
void merge(const Collector &collector)
Merges two trees by overwriting existing values.
Definition: metadata.hh:146
void append(const Collector &collector, bool convertToArrays=false)
Append data from another collector.
Definition: metadata.hh:156
const JsonTree & getTree() const
Definition: metadata.hh:138
JsonTree & getTree()
Get the json tree.
Definition: metadata.hh:133
static std::string hideTemplateArguments(std::string &&s)
Definition: metadata.hh:206
static std::string className(bool hideTemplates)
Definition: metadata.hh:201
A linear system assembler (residual and Jacobian) for finite volume schemes.
Declares all properties used in Dumux.
The grid variable class for finite volume schemes, storing variables on scv and scvf (volume and flux...