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
Collection of json classes from JSON for Modern C++ library.
Utilities for template meta programming.
A helper function for class member function introspection.
An enum class to define various differentiation methods available in order to compute the derivatives...
Base class for grid geometries.
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
Declares all properties used in Dumux.
A linear system assembler (residual and Jacobian) for finite volume schemes.
The grid variable class for finite volume schemes, storing variables on scv and scvf (volume and flux...