// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
* See the file COPYING for full copying permissions. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see . *
*****************************************************************************/
/*!
* \file
* \ingroup Common
* \brief The infrastructure to retrieve metadata information.
*/
#ifndef DUMUX_METADATA_HH
#define DUMUX_METADATA_HH
#include
#include
#include
#include
#include
#include
#include
#include
#include "dumux/io/json/json.hpp"
#include "dumux/common/properties/propertysystem.hh"
#include "dumux/common/typetraits/utility.hh"
#include "dumux/common/typetraits/isvalid.hh"
#include "dumux/assembly/fvassembler.hh"
#include "dumux/assembly/diffmethod.hh"
#include "dumux/discretization/basegridgeometry.hh"
#include "dumux/discretization/fvgridvariables.hh"
namespace Dumux {
namespace Detail {
//! Helper to determine whether a given type inherits from BaseGridGeometry
struct isGridGeometry
{
template
void isConstructable(const BaseGridGeometry&)
{}
template
auto operator()(GridGeometry&& gg)
-> decltype(isConstructable(gg))
{}
};
//! Helper to determine whether a given type inherits from FVGridVariables
struct isGridVariables
{
template
void isConstructable(const FVGridVariables&)
{}
template
auto operator()(GridVariables&& gv)
-> decltype(isConstructable(gv))
{}
};
std::string removeNamespace(std::string&& s)
{
std::size_t last = s.find_last_of("::");
if(last != std::string::npos)
s.erase(0, last+1);
return std::move(s);
}
template
void collectTypeTagsFromTuple(Collector& collector, int depth=0, int parentBranch=-1)
{
using namespace Dune::Hybrid;
forEach(std::make_index_sequence>{}, [&](auto i)
{
using type = typename std::tuple_element::type;
collector.push_back(std::tuple{depth, parentBranch, removeNamespace(Dune::className())});
if constexpr (Dumux::Properties::Detail::hasParentTypeTag(int{}))
collectTypeTagsFromTuple(collector, int{depth+1}, i);
});
}
} // end namespace Detail
/*!
* \ingroup Common
* \brief Class to collect metadata
* \todo Doc me!
*/
class Metadata {
using JsonTree = nlohmann::json;
public:
/*!
* \brief Get the json tree
*/
JsonTree& getTree()
{
return tree_;
}
const JsonTree& getTree() const
{
return tree_;
}
/*!
* \brief returns the object with id of the json tree
*/
auto& operator[] (std::string id)
{ return getTree()[id]; }
template
static std::string className(const T& c, bool hideTemplates)
{
return hideTemplates ? hideTemplateArguments(Dune::className(c)) : Dune::className(c);
}
static std::string hideTemplateArguments(std::string&& s)
{
std::size_t first = s.find("<");
std::size_t last = s.find_last_of(">");
if(first != std::string::npos && last != std::string::npos)
s.replace(first, last-first+1, "<...>");
s.erase(std::unique(std::begin(s), std::end(s),
[](unsigned char a, unsigned char b){return std::isspace(a) && std::isspace(b);}), std::end(s));
return std::move(s);
}
private:
JsonTree tree_;
};
//! prints json tree
template
void print(const Collector& collector)
{
std::cout << collector.getTree().dump(4) << std::endl;
}
template
void collectMetaData(Collector& collector, const FVAssembler& a, bool hideTemplates = true)
{
auto& obj = collector["Assembler"];
obj["Type"] = Metadata::className(a, hideTemplates);
obj["Stationary"] = a.isStationaryProblem();
}
template
auto collectMetaData(Collector& collector, const GridGeometry& gg, bool hideTemplates = true)
-> typename std::enable_if_t
{
using GridView = typename GridGeometry::GridView;
auto& obj = collector["GridGeometry"];
obj["Type"] = Metadata::className(gg, hideTemplates);
obj["GridView"]["Type"] = Metadata::className(gg.gridView(), hideTemplates);
obj["GridView"]["dimension"] = GridView::dimension;
obj["GridView"]["dimensionWorld"] = GridView::dimensionworld;
obj["GridView"]["Grid"]["Type"] = Metadata::className(gg.gridView().grid(), hideTemplates);
obj["IsPeriodic"] = gg.isPeriodic();
obj["DiscretisationMethod"] = toString(GridGeometry::discMethod);
obj["MaxElementStencilSize"] = GridGeometry::maxElementStencilSize;
obj["NumScvs"] = gg.numScv();
obj["NumScvfs"] = gg.numScvf();
obj["SumBoundaryScvfs"] = gg.numBoundaryScvf();
obj["NumDofs"] = gg.numDofs();
}
template
auto collectMetaData(Collector& collector, const GridVariables& gv, bool hideTemplates = true)
-> typename std::enable_if_t
{
auto& obj = collector["GridVariables"];
obj["Type"] = Metadata::className(gv, hideTemplates);
}
template
auto collectTypeTags(Collector& collector)
{
auto& obj = collector["TTags"];
obj = nlohmann::json::array();
Detail::collectTypeTagsFromTuple>(obj);
}
} // end namespace Dumux
#endif