// -*- 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