diff --git a/dumux/multidomain/CMakeLists.txt b/dumux/multidomain/CMakeLists.txt index c983c6a65566e81c51d0770d7f099b4a2a4d4845..b0abcdb33eff405c1f231839ac1234602079723a 100644 --- a/dumux/multidomain/CMakeLists.txt +++ b/dumux/multidomain/CMakeLists.txt @@ -1,11 +1,15 @@ add_subdirectory(boundary) add_subdirectory(embedded) add_subdirectory(facet) +add_subdirectory(io) install(FILES couplingjacobianpattern.hh couplingmanager.hh fvassembler.hh +fvgridgeometry.hh +fvgridvariables.hh +fvproblem.hh newtonsolver.hh staggeredcouplingmanager.hh staggeredtraits.hh diff --git a/dumux/multidomain/fvgridgeometry.hh b/dumux/multidomain/fvgridgeometry.hh new file mode 100644 index 0000000000000000000000000000000000000000..2037664c188b54beaa42e3070685d78fa06cb5b4 --- /dev/null +++ b/dumux/multidomain/fvgridgeometry.hh @@ -0,0 +1,125 @@ +// -*- 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 2 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 MultiDomain + * \brief Multidomain wrapper for multiple grid geometries + */ +#ifndef DUMUX_MULTIDOMAIN_FVGRIDGEOMETRY_HH +#define DUMUX_MULTIDOMAIN_FVGRIDGEOMETRY_HH + +#include +#include +#include + +#include +#include + +namespace Dumux { + +/*! + * \ingroup MultiDomain + * \brief A multidomain wrapper for multiple grid geometries + * \tparam MDTraits The multidomain traits + */ +template +class MultiDomainFVGridGeometry +{ + static constexpr std::size_t numSubDomains = MDTraits::numSubDomains; + +public: + //! export base types of the stored type + template + using Type = typename MDTraits::template SubDomain::FVGridGeometry; + + //! export pointer types the stored type + template + using PtrType = std::shared_ptr>; + + //! export type of tuple of pointers + using TupleType = typename MDTraits::template Tuple; + + /*! + * \brief The default constructor + */ + MultiDomainFVGridGeometry() = default; + + /*! + * \brief Contruct the problem + * \param gridViews a tuple of gridViews + */ + template + MultiDomainFVGridGeometry(GridViews&& gridViews) + { + using namespace Dune::Hybrid; + forEach(std::make_index_sequence{}, [&](auto&& id) + { + constexpr auto i = std::decay_t::value; + elementAt(gridGeometries_, id) = std::make_shared>(std::get(gridViews)); + }); + } + + /*! + * \brief Update all grid geometries (do this again after grid adaption) + */ + void update() + { + using namespace Dune::Hybrid; + forEach(std::make_index_sequence{}, [&](auto&& id) + { + elementAt(gridGeometries_, id)->update(); + }); + } + + //! return the grid geometry for domain with index i + template + const Type& operator[] (Dune::index_constant id) const + { return *Dune::Hybrid::elementAt(gridGeometries_, id); } + + //! return the grid geometry for domain with index i + template + Type& operator[] (Dune::index_constant id) + { return *Dune::Hybrid::elementAt(gridGeometries_, id); } + + ///! return the grid geometry pointer for domain with index i + template + PtrType get(Dune::index_constant id = Dune::index_constant{}) + { return Dune::Hybrid::elementAt(gridGeometries_, id); } + + //! set the pointer for sub domain i + template + void set(PtrType p, Dune::index_constant id = Dune::index_constant{}) + { Dune::Hybrid::elementAt(gridGeometries_, Dune::index_constant{}) = p; } + + /*! + * \brief return the grid variables tuple we are wrapping + * \note the copy is not expensive since it is a tuple of shared pointers + */ + TupleType getTuple() + { return gridGeometries_; } + +private: + + //! a tuple of pointes to all grid variables + TupleType gridGeometries_; +}; + +} // end namespace Dumux + +#endif diff --git a/dumux/multidomain/fvgridvariables.hh b/dumux/multidomain/fvgridvariables.hh new file mode 100644 index 0000000000000000000000000000000000000000..d4abbfca8b3cec7e2c0b670af33512fcbbb1551d --- /dev/null +++ b/dumux/multidomain/fvgridvariables.hh @@ -0,0 +1,175 @@ +// -*- 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 2 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 MultiDomain + * \brief Multidomain wrapper for multiple grid variables + */ +#ifndef DUMUX_MULTIDOMAIN_FV_GRID_VARIABLES_HH +#define DUMUX_MULTIDOMAIN_FV_GRID_VARIABLES_HH + +#include +#include +#include + +#include +#include + +namespace Dumux { + +/*! + * \ingroup MultiDomain + * \brief A multidomain wrapper for multiple grid variables + * \tparam MDTraits the multidomain traits + */ +template +class MultiDomainFVGridVariables +{ + using SolutionVector = typename MDTraits::SolutionVector; + static constexpr std::size_t numSubDomains = MDTraits::numSubDomains; + + template + using GridGeometry = typename MDTraits::template SubDomain::FVGridGeometry; + using GridGeometries = typename MDTraits::template TupleOfSharedPtrConst; + + template + using Problem = typename MDTraits::template SubDomain::Problem; + using Problems = typename MDTraits::template TupleOfSharedPtrConst; + +public: + //! export base types of the stored type + template + using Type = typename MDTraits::template SubDomain::GridVariables; + + //! export pointer types the stored type + template + using PtrType = std::shared_ptr>; + + //! export type of tuple of pointers + using TupleType = typename MDTraits::template Tuple; + + /*! + * \brief The default constructor + */ + MultiDomainFVGridVariables() = default; + + /*! + * \brief Contruct the grid variables + * \param gridGeometries a tuple of grid geometry shared pointers + * \param problems a tuple of problem shared pointers + */ + MultiDomainFVGridVariables(GridGeometries&& gridGeometries, Problems&& problems) + { + using namespace Dune::Hybrid; + forEach(std::make_index_sequence{}, [&](auto&& id) + { + constexpr auto i = std::decay_t::value; + elementAt(gridVars_, id) = std::make_shared>( std::get(problems), std::get(gridGeometries)); + }); + } + + //! initialize all variables + void init(const SolutionVector& sol) + { + using namespace Dune::Hybrid; + forEach(std::make_index_sequence{}, [&](auto&& id) + { + elementAt(gridVars_, id)->init(sol[id]); + }); + } + + //! update all variables + void update(const SolutionVector& sol, bool forceFluxCacheUpdate = false) + { + using namespace Dune::Hybrid; + forEach(std::make_index_sequence{}, [&](auto&& id) + { + elementAt(gridVars_, id)->update(sol[id], forceFluxCacheUpdate); + }); + } + + //! update all variables after grid adaption + void updateAfterGridAdaption(const SolutionVector& sol) + { + using namespace Dune::Hybrid; + forEach(std::make_index_sequence{}, [&](auto&& id) + { + elementAt(gridVars_, id)->updateAfterGridAdaption(sol[id]); + }); + } + + /*! + * \brief Sets the current state as the previous for next time step + * \note this has to be called at the end of each time step + */ + void advanceTimeStep() + { + using namespace Dune::Hybrid; + forEach(std::make_index_sequence{}, [&](auto&& id) + { + elementAt(gridVars_, id)->advanceTimeStep(); + }); + } + + //! resets state to the one before time integration + void resetTimeStep(const SolutionVector& sol) + { + using namespace Dune::Hybrid; + forEach(std::make_index_sequence{}, [&](auto&& id) + { + elementAt(gridVars_, id)->resetTimeStep(sol[id]); + }); + } + + //! return the grid variables for domain with index i + template + const Type& operator[] (Dune::index_constant id) const + { return *Dune::Hybrid::elementAt(gridVars_, id); } + + //! return the grid variables for domain with index i + template + Type& operator[] (Dune::index_constant id) + { return *Dune::Hybrid::elementAt(gridVars_, id); } + + //! return the grid variables tuple we are wrapping + template + PtrType get(Dune::index_constant id = Dune::index_constant{}) + { return Dune::Hybrid::elementAt(gridVars_, id); } + + //! set the pointer for sub domain i + template + void set(PtrType p, Dune::index_constant id = Dune::index_constant{}) + { Dune::Hybrid::elementAt(gridVars_, id) = p; } + + /*! + * \brief return the grid variables tuple we are wrapping + * \note the copy is not expensive since it is a tuple of shared pointers + */ + TupleType getTuple() + { return gridVars_; } + +private: + + //! a tuple of pointes to all grid variables + TupleType gridVars_; +}; + +} // end namespace Dumux + +#endif diff --git a/dumux/multidomain/fvproblem.hh b/dumux/multidomain/fvproblem.hh new file mode 100644 index 0000000000000000000000000000000000000000..528431e0a0c4d952c9146632f7e379fddebb1203 --- /dev/null +++ b/dumux/multidomain/fvproblem.hh @@ -0,0 +1,130 @@ +// -*- 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 2 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 MultiDomain + * \brief Multidomain wrapper for multiple problems + */ +#ifndef DUMUX_MULTIDOMAIN_PROBLEM_HH +#define DUMUX_MULTIDOMAIN_PROBLEM_HH + +#include +#include +#include + +#include +#include + +namespace Dumux { + +/*! + * \ingroup MultiDomain + * \brief A multidomain wrapper for multiple problems + * \tparam MDTraits The multidomain traits + */ +template +class MultiDomainFVProblem +{ + using SolutionVector = typename MDTraits::SolutionVector; + static constexpr std::size_t numSubDomains = MDTraits::numSubDomains; + + template + using GridGeometry = typename MDTraits::template SubDomain::FVGridGeometry; + using GridGeometries = typename MDTraits::template Tuple; + +public: + //! export base types of the stored type + template + using Type = typename MDTraits::template SubDomain::Problem; + + //! export pointer types the stored type + template + using PtrType = std::shared_ptr>; + + //! export type of tuple of pointers + using TupleType = typename MDTraits::template Tuple; + + /*! + * \brief The default constructor + */ + MultiDomainFVProblem() = default; + + /*! + * \brief Contruct the problem + * \param gridGeometries a tuple of grid geometry shared pointers + */ + MultiDomainFVProblem(GridGeometries&& gridGeometries) + { + using namespace Dune::Hybrid; + forEach(std::make_index_sequence{}, [&](auto&& id) + { + constexpr auto i = std::decay_t::value; + elementAt(problems_, id) = std::make_shared>(std::get(gridGeometries)); + }); + } + + /*! + * \brief Applies the initial solution for all degrees of freedom of the grid. + * \param sol the initial solution vector + */ + void applyInitialSolution(SolutionVector& sol) const + { + using namespace Dune::Hybrid; + forEach(std::make_index_sequence{}, [&](auto&& id) + { + elementAt(problems_, id)->applyInitialSolution(sol[id]); + }); + } + + //! return the problem for domain with index i + template + const Type& operator[] (Dune::index_constant id) const + { return *Dune::Hybrid::elementAt(problems_, id); } + + //! return the problem for domain with index i + template + Type& operator[] (Dune::index_constant id) + { return *Dune::Hybrid::elementAt(problems_, id); } + + //! return the problem for domain with index i + template + PtrType get(Dune::index_constant id = Dune::index_constant{}) + { return Dune::Hybrid::elementAt(problems_, id); } + + //! set the pointer for sub domain i + template + void set(PtrType p, Dune::index_constant id = Dune::index_constant{}) + { Dune::Hybrid::elementAt(problems_, Dune::index_constant{}) = p; } + + /*! + * \brief return the grid variables tuple we are wrapping + * \note the copy is not expensive since it is a tuple of shared pointers + */ + TupleType getTuple() + { return problems_; } + +private: + + //! a tuple of pointes to all grid variables + TupleType problems_; +}; + +} // end namespace Dumux + +#endif diff --git a/dumux/multidomain/io/CMakeLists.txt b/dumux/multidomain/io/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..7cde1469dd35bce881e05c4299033aeb51448815 --- /dev/null +++ b/dumux/multidomain/io/CMakeLists.txt @@ -0,0 +1,3 @@ +install(FILES +vtkoutputmodule.hh +DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/multidomain/io) diff --git a/dumux/multidomain/io/vtkoutputmodule.hh b/dumux/multidomain/io/vtkoutputmodule.hh new file mode 100644 index 0000000000000000000000000000000000000000..54f96e63771dd2ab4fe60884e5b75f02d4da16da --- /dev/null +++ b/dumux/multidomain/io/vtkoutputmodule.hh @@ -0,0 +1,144 @@ +// -*- 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 2 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 MultiDomain + * \brief Multidomain wrapper for multiple vtk output modules + */ +#ifndef DUMUX_MULTIDOMAIN_VTK_OUTPUT_MODULE_HH +#define DUMUX_MULTIDOMAIN_VTK_OUTPUT_MODULE_HH + +#include +#include +#include + +#include +#include + +#include +#include + +namespace Dumux { + +/*! + * \ingroup MultiDomain + * \brief A multidomain wrapper for multiple vtk output modules + * \tparam MDTraits The multidomain traits + * \tparam Module An output module class template that takes GridVariables and SolutionVector as arugments + */ +template class Module = Dumux::VtkOutputModule> +class MultiDomainVtkOutputModule +{ + using MDSolutionVector = typename MDTraits::SolutionVector; + static constexpr std::size_t numSubDomains = MDTraits::numSubDomains; + + template + using GridVariables = typename MDTraits::template SubDomain::GridVariables; + + using MDGridVars = typename MDTraits::template TupleOfSharedPtrConst; + + template + using SolutionVector = typename MDTraits::template SubDomain::SolutionVector; + + template + using VtkOutputModule = Module, SolutionVector>; + + using VtkOutputModuleTuple = typename MDTraits::template TupleOfSharedPtr; + +public: + //! export base types of the stored type + template + using Type = VtkOutputModule; + + //! export pointer types the stored type + template + using PtrType = std::shared_ptr>; + + /*! + * \brief The default constructor + */ + MultiDomainVtkOutputModule() = default; + + /*! + * \brief Contruct the vtk output modules + * \param gridVars a tuple of grid variables + * \param sol the multidomain solution vector + * \param name the base name for the vtk output + */ + MultiDomainVtkOutputModule(MDGridVars&& gridVars, const MDSolutionVector& sol, + const std::array& name) + { + using namespace Dune::Hybrid; + forEach(std::make_index_sequence{}, [&](auto&& id) + { + constexpr auto i = std::decay_t::value; + elementAt(vtkOutputModule_, id) = std::make_shared>(*std::get(gridVars), sol[id], name[id]); + }); + } + + //! initialized all vtkoutput modules with the models default output fields + void initDefaultOutputFields() + { + using namespace Dune::Hybrid; + forEach(std::make_index_sequence{}, [&](auto&& id) + { + constexpr auto i = std::decay_t::value; + MDTraits::template SubDomain::IOFields::initOutputModule(*elementAt(vtkOutputModule_, id)); + }); + } + + //! Write the data for this timestep to file for all output moduless + void write(double t, Dune::VTK::OutputType type = Dune::VTK::ascii) + { + using namespace Dune::Hybrid; + forEach(std::make_index_sequence{}, [&](auto&& id) + { + elementAt(vtkOutputModule_, id)->write(t, type); + }); + } + + //! return the output module for domain with index i + template + const Type& operator[] (Dune::index_constant id) const + { return *Dune::Hybrid::elementAt(vtkOutputModule_, id); } + + //! return the output module for domain with index i + template + Type& operator[] (Dune::index_constant id) + { return *Dune::Hybrid::elementAt(vtkOutputModule_, id); } + + //! return the vtkoutput module for domain with index i + template + PtrType get(Dune::index_constant id = Dune::index_constant{}) + { return Dune::Hybrid::elementAt(vtkOutputModule_, id); } + + //! set the pointer for sub domain i + template + void set(PtrType p, Dune::index_constant id = Dune::index_constant{}) + { Dune::Hybrid::elementAt(vtkOutputModule_, id) = p; } + +private: + + //! a tuple of pointes to all vtk output modules + typename MDTraits::template Tuple vtkOutputModule_; +}; + +} // end namespace Dumux + +#endif diff --git a/test/multidomain/facet/1p_1p/threedomain/main.cc b/test/multidomain/facet/1p_1p/threedomain/main.cc index f24a0fc57e52bdcbe67bad48783ee8190db1dca1..4e7ba5306717619931817d1e5173a52a7e02cc0b 100644 --- a/test/multidomain/facet/1p_1p/threedomain/main.cc +++ b/test/multidomain/facet/1p_1p/threedomain/main.cc @@ -42,12 +42,14 @@ #include #include #include +#include +#include +#include #include #include #include - -#include +#include // obtain/define some types to be used below in the property definitions and in main class TestTraits @@ -92,16 +94,17 @@ int main(int argc, char** argv) try // initialize parameter tree Parameters::init(argc, argv); + // the multidomain traits and some indices + using Traits = typename TestTraits::MDTraits; + static const auto bulkId = Traits::template SubDomain<0>::Index{}; + static const auto facetId = Traits::template SubDomain<1>::Index{}; + static const auto edgeId = Traits::template SubDomain<2>::Index{}; + // try to create a grid (from the given grid file or the input file) - using BulkProblemTypeTag = Properties::TTag::OnePBulkTpfa; - using FacetProblemTypeTag = Properties::TTag::OnePFacetTpfa; - using EdgeProblemTypeTag = Properties::TTag::OnePEdgeTpfa; - using BulkGrid = GetPropType; - using FacetGrid = GetPropType; - using EdgeGrid = GetPropType; - - using GridManager = FacetCouplingGridManager; - GridManager gridManager; + FacetCouplingGridManager::Grid, + Traits::template SubDomain::Grid, + Traits::template SubDomain::Grid> gridManager; + gridManager.init(); gridManager.loadBalance(); @@ -110,94 +113,59 @@ int main(int argc, char** argv) try //////////////////////////////////////////////////////////// // we compute on the leaf grid views - const auto& bulkGridView = gridManager.template grid<0>().leafGridView(); - const auto& facetGridView = gridManager.template grid<1>().leafGridView(); - const auto& edgeGridView = gridManager.template grid<2>().leafGridView(); + const auto& bulkGridView = gridManager.template grid().leafGridView(); + const auto& facetGridView = gridManager.template grid().leafGridView(); + const auto& edgeGridView = gridManager.template grid().leafGridView(); // create the finite volume grid geometries - using BulkFVGridGeometry = GetPropType; - using FacetFVGridGeometry = GetPropType; - using EdgeFVGridGeometry = GetPropType; - auto bulkFvGridGeometry = std::make_shared(bulkGridView); - auto facetFvGridGeometry = std::make_shared(facetGridView); - auto edgeFvGridGeometry = std::make_shared(edgeGridView); - bulkFvGridGeometry->update(); - facetFvGridGeometry->update(); - edgeFvGridGeometry->update(); + MultiDomainFVGridGeometry fvGridGeometry(std::make_tuple(bulkGridView, facetGridView, edgeGridView)); + fvGridGeometry.update(); // the coupling manager using CouplingManager = typename TestTraits::CouplingManager; auto couplingManager = std::make_shared(); // the problems (boundary conditions) - using BulkProblem = GetPropType; - using FacetProblem = GetPropType; - using EdgeProblem = GetPropType; - auto bulkSpatialParams = std::make_shared(bulkFvGridGeometry, "Bulk"); - auto bulkProblem = std::make_shared(bulkFvGridGeometry, bulkSpatialParams, couplingManager, "Bulk"); - auto facetSpatialParams = std::make_shared(facetFvGridGeometry, "Facet"); - auto facetProblem = std::make_shared(facetFvGridGeometry, facetSpatialParams, couplingManager, "Facet"); - auto edgeSpatialParams = std::make_shared(edgeFvGridGeometry, "Edge"); - auto edgeProblem = std::make_shared(edgeFvGridGeometry, edgeSpatialParams, couplingManager, "Edge"); + MultiDomainFVProblem problem; - // the solution vector - using Traits = typename TestTraits::MDTraits; - using SolutionVector = typename Traits::SolutionVector; - SolutionVector x; + using BulkProblem = MultiDomainFVProblem::template Type; + using FacetProblem = MultiDomainFVProblem::template Type; + using EdgeProblem = MultiDomainFVProblem::template Type; - static const auto bulkId = Traits::template SubDomain<0>::Index(); - static const auto facetId = Traits::template SubDomain<1>::Index(); - static const auto edgeId = Traits::template SubDomain<2>::Index(); - bulkProblem->applyInitialSolution(x[bulkId]); - facetProblem->applyInitialSolution(x[facetId]); - edgeProblem->applyInitialSolution(x[edgeId]); + auto bulkSpatialParams = std::make_shared(fvGridGeometry.get(bulkId), "Bulk"); + auto facetSpatialParams = std::make_shared(fvGridGeometry.get(facetId), "Facet"); + auto edgeSpatialParams = std::make_shared(fvGridGeometry.get(edgeId), "Edge"); + + problem.set(std::make_shared(fvGridGeometry.get(bulkId), bulkSpatialParams, couplingManager, "Bulk"), bulkId); + problem.set(std::make_shared(fvGridGeometry.get(facetId), facetSpatialParams, couplingManager, "Facet"), facetId); + problem.set(std::make_shared(fvGridGeometry.get(edgeId), edgeSpatialParams, couplingManager, "Edge"), edgeId); + + // the solution vector + typename Traits::SolutionVector x; + problem.applyInitialSolution(x); // the coupling mapper using CouplingMapper = typename TestTraits::CouplingMapper; auto couplingMapper = std::make_shared(); - couplingMapper->update(*bulkFvGridGeometry, *facetFvGridGeometry, *edgeFvGridGeometry, gridManager.getEmbeddings()); + couplingMapper->update(fvGridGeometry[bulkId], fvGridGeometry[facetId], fvGridGeometry[edgeId], gridManager.getEmbeddings()); // initialize the coupling manager - couplingManager->init(bulkProblem, facetProblem, edgeProblem, couplingMapper, x); + couplingManager->init(problem.get(bulkId), problem.get(facetId), problem.get(edgeId), couplingMapper, x); // the grid variables - using BulkGridVariables = GetPropType; - using FacetGridVariables = GetPropType; - using EdgeGridVariables = GetPropType; - auto bulkGridVariables = std::make_shared(bulkProblem, bulkFvGridGeometry); - auto facetGridVariables = std::make_shared(facetProblem, facetFvGridGeometry); - auto edgeGridVariables = std::make_shared(edgeProblem, edgeFvGridGeometry); - bulkGridVariables->init(x[bulkId]); - facetGridVariables->init(x[facetId]); - edgeGridVariables->init(x[edgeId]); - - // intialize the vtk output module - using BulkSolutionVector = std::decay_t; - using FacetSolutionVector = std::decay_t; - using EdgeSolutionVector = std::decay_t; + using GridVariables = MultiDomainFVGridVariables; + GridVariables gridVars(fvGridGeometry.getTuple(), problem.getTuple()); + gridVars.init(x); // intialize the vtk output module - VtkOutputModule bulkVtkWriter(*bulkGridVariables, x[bulkId], bulkProblem->name()); - VtkOutputModule facetVtkWriter(*facetGridVariables, x[facetId], facetProblem->name()); - VtkOutputModule edgeVtkWriter(*edgeGridVariables, x[edgeId], edgeProblem->name()); - - // Add model specific output fields - using BulkIOFields = GetPropType; - using FacetIOFields = GetPropType; - using EdgeIOFields = GetPropType; - BulkIOFields::initOutputModule(bulkVtkWriter); - FacetIOFields::initOutputModule(facetVtkWriter); - EdgeIOFields::initOutputModule(edgeVtkWriter); - bulkVtkWriter.write(0.0); - facetVtkWriter.write(0.0); - edgeVtkWriter.write(0.0); + const std::array vtkOutputNames{{problem[bulkId].name(), problem[facetId].name(), problem[edgeId].name()}}; + MultiDomainVtkOutputModule vtkWriter(gridVars.getTuple(), x, vtkOutputNames); + vtkWriter.initDefaultOutputFields(); + vtkWriter.write(0.0); // the assembler using Assembler = MultiDomainFVAssembler; - auto assembler = std::make_shared( std::make_tuple(bulkProblem, facetProblem, edgeProblem), - std::make_tuple(bulkFvGridGeometry, facetFvGridGeometry, edgeFvGridGeometry), - std::make_tuple(bulkGridVariables, facetGridVariables, edgeGridVariables), - couplingManager); + auto assembler = std::make_shared( problem.getTuple(), fvGridGeometry.getTuple(), gridVars.getTuple(), couplingManager); // the linear solver using LinearSolver = ILU0BiCGSTABBackend; @@ -211,14 +179,10 @@ int main(int argc, char** argv) try newtonSolver->solve(x); // update grid variables for output - bulkGridVariables->update(x[bulkId]); - facetGridVariables->update(x[facetId]); - edgeGridVariables->update(x[edgeId]); + gridVars.update(x); // write vtk output - bulkVtkWriter.write(1.0); - facetVtkWriter.write(1.0); - edgeVtkWriter.write(1.0); + vtkWriter.write(1.0); //////////////////////////////////////////////////////////// // finalize, print dumux message to say goodbye