Commit 175f8007 authored by Andreas Nüßing's avatar Andreas Nüßing

Merge branch 'feature/cutfem-eeg' into 'master'

[CutFEM] add first implementation of cutfem

See merge request duneuro/duneuro!47
parents 93a3472f e1055324
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNEURO_CUTFEM_GRIDOPERATOR_HH
#define DUNEURO_CUTFEM_GRIDOPERATOR_HH
#include <dune/istl/io.hh>
#include <dune/pdelab/gridfunctionspace/interpolate.hh>
#include <dune/pdelab/gridoperator/common/borderdofexchanger.hh>
#include <dune/pdelab/gridoperator/common/gridoperatorutilities.hh>
#include <dune/udg/pdelab/assembler/assembler.hh>
#include <dune/udg/pdelab/assembler/localassembler.hh>
#include <dune/udg/pdelab/ghostpenalty.hh>
namespace duneuro
{
template <class GO, class ST, class ENP>
class CutFEMGridOperator
{
public:
using Traits = typename GO::Traits;
//! Constructor for non trivial constraints
explicit CutFEMGridOperator(const GO& go, std::shared_ptr<const ST> subTriangulation,
const ENP& edgeNormProvider, const Dune::ParameterTree& config)
: go_(go)
, subTriangulation_(subTriangulation)
, edgeNormProvider_(edgeNormProvider)
, ghost_penalty_(config.get<double>("ghost_penalty"))
, conductivities_(config.get<std::vector<double>>("conductivities"))
{
}
void fill_pattern(typename GO::Pattern& p) const
{
go_.fill_pattern(p);
}
void residual(const typename GO::Domain& x, typename GO::Range& r) const
{
go_.residual(x, r);
}
//! Assembler jacobian
void jacobian(const typename GO::Domain& x, typename GO::Jacobian& a) const
{
go_.jacobian(x, a);
Dune::UDG::add_ghost_penalty_cutfem(*subTriangulation_, go_.trialGridFunctionSpace(),
edgeNormProvider_, ghost_penalty_, conductivities_, 0,
Dune::PDELab::Backend::native(a));
}
const typename GO::Traits::TrialGridFunctionSpace& trialGridFunctionSpace() const
{
return go_.trialGridFunctionSpace();
}
const typename GO::Traits::TestGridFunctionSpace& testGridFunctionSpace() const
{
return go_.testGridFunctionSpace();
}
const typename GO::Traits::MatrixBackend& matrixBackend() const
{
return go_.matrixBackend();
}
private:
const GO& go_;
std::shared_ptr<const ST> subTriangulation_;
ENP edgeNormProvider_;
double ghost_penalty_;
std::vector<double> conductivities_;
};
}
#endif
#ifndef DUNEURO_CUTFEM_MULTI_PHASE_SPACE_HH
#define DUNEURO_CUTFEM_MULTI_PHASE_SPACE_HH
#include <dune/localfunctions/lagrange.hh>
#include <dune/localfunctions/lagrange/equidistantpoints.hh>
#include <dune/pdelab/backend/istl.hh>
#include <dune/udg/pdelab/finiteelementmap.hh>
#include <dune/udg/vtriangulation.hh>
#include <duneuro/common/grid_function_space_utilities.hh>
namespace duneuro
{
struct CutFEMLeafOrderingParams : public Dune::PDELab::NoConstOrderingSize<true> {
};
template <class TGV, class N, int degree, int phases>
class CutFEMMultiPhaseSpace
{
public:
typedef TGV GV;
enum { dim = GV::dimension };
typedef typename GV::ctype ctype;
typedef N NT;
static const int blockSize = 1;
typedef Dune::LagrangeLocalFiniteElement<Dune::EquidistantPointSet, dim, double, double> LFE;
typedef VirtualSubTriangulation<GV> SubTriangulation;
typedef Dune::PDELab::istl::VectorBackend<> VBE;
typedef Dune::PDELab::UnfittedFiniteElementMapTraits<LFE, typename SubTriangulation::EntityPart>
UFEMTraits;
typedef Dune::PDELab::UnfittedFiniteElementMap<UFEMTraits, SubTriangulation> FEM;
typedef Dune::PDELab::LeafOrderingTag<CutFEMLeafOrderingParams> LeafOrderingTag;
typedef Dune::PDELab::GridFunctionSpace<GV, FEM, Dune::PDELab::NoConstraints, VBE,
LeafOrderingTag>
DomainGFS;
typedef Dune::PDELab::istl::VectorBackend<> PVBE;
typedef Dune::PDELab::PowerGridFunctionSpace<DomainGFS, phases, PVBE,
Dune::PDELab::EntityBlockedOrderingTag>
GFS;
typedef typename Dune::PDELab::Backend::Vector<GFS, N> DOF;
CutFEMMultiPhaseSpace(const GV& gv, std::shared_ptr<SubTriangulation> subTriangulation)
: gridView_(gv)
, entitySet_(gridView_)
, subTriangulation_(subTriangulation)
, lfe_(Dune::GeometryType(Dune::GeometryType::BasicType::cube, dim), degree)
{
for (unsigned int i = 0; i < phases; ++i) {
fems_[i] = std::make_shared<FEM>(lfe_, *subTriangulation_, i, false);
domainGfss_[i] = std::make_shared<DomainGFS>(entitySet_, *(fems_[i]));
}
gfs_ = make_power_gfs<DomainGFS, PVBE, typename GFS::Traits::OrderingTag>(domainGfss_);
gfs_->ordering();
}
// return gfs reference
GFS& getGFS()
{
return *gfs_;
}
// return gfs reference const version
const GFS& getGFS() const
{
return *gfs_;
}
CutFEMMultiPhaseSpace(const CutFEMMultiPhaseSpace&) = delete;
CutFEMMultiPhaseSpace& operator=(const CutFEMMultiPhaseSpace&) = delete;
private:
GV gridView_;
Dune::PDELab::AllEntitySet<GV> entitySet_;
std::shared_ptr<SubTriangulation> subTriangulation_;
LFE lfe_;
std::array<std::shared_ptr<FEM>, phases> fems_;
std::array<std::shared_ptr<DomainGFS>, phases> domainGfss_;
std::shared_ptr<GFS> gfs_;
};
}
#endif // DUNEURO_CUTFEM_MULTI_PHASE_SPACE_HH
#ifndef DUNEURO_CUTFEM_SOLVER_HH
#define DUNEURO_CUTFEM_SOLVER_HH
#include <dune/udg/pdelab/cutfemmultiphaseoperator.hh>
#include <dune/udg/pdelab/multiphaseoperator.hh>
#include <dune/udg/pdelab/operator.hh>
#include <dune/udg/pdelab/subtriangulation.hh>
#include <dune/pdelab/backend/istl.hh>
#include <dune/pdelab/stationary/linearproblem.hh>
#include <duneuro/common/convection_diffusion_dg_operator.hh>
#include <duneuro/common/convection_diffusion_udg_default_parameter.hh>
#include <duneuro/common/cutfem_gridoperator.hh>
#include <duneuro/common/cutfem_multi_phase_space.hh>
#include <duneuro/common/edge_norm_provider.hh>
#include <duneuro/common/linear_problem_solver.hh>
#include <duneuro/common/penalty_flux_weighting.hh>
#include <duneuro/common/random.hh>
#include <duneuro/common/vector_initialization.hh>
namespace duneuro
{
template <class ST, int comps, int degree, class P, class DF, class RF, class JF>
struct CutFEMSolverTraits {
using SubTriangulation = ST;
using FundamentalGridView = typename ST::BaseT::GridView;
static const int dimension = FundamentalGridView::dimension;
static const int compartments = comps;
using Problem = P;
using FunctionSpace = CutFEMMultiPhaseSpace<FundamentalGridView, RF, degree, compartments>;
using DomainField = DF;
using RangeField = RF;
using DomainDOFVector = Dune::PDELab::Backend::Vector<typename FunctionSpace::GFS, DF>;
using RangeDOFVector = Dune::PDELab::Backend::Vector<typename FunctionSpace::GFS, RF>;
using EdgeNormProvider = MultiEdgeNormProvider;
using PenaltyFluxWeighting = UnfittedDynamicPenaltyFluxWeights;
using LocalOperator =
ConvectionDiffusion_DG_LocalOperator<Problem, EdgeNormProvider, PenaltyFluxWeighting>;
using WrappedLocalOperator = Dune::UDG::CutFEMMultiPhaseLocalOperatorWrapper<LocalOperator>;
// using WrappedLocalOperator = Dune::UDG::MultiPhaseLocalOperatorWrapper<LocalOperator>;
using UnfittedSubTriangulation = Dune::PDELab::UnfittedSubTriangulation<FundamentalGridView>;
using MatrixBackend = Dune::PDELab::istl::BCRSMatrixBackend<>;
using RawGridOperator =
Dune::UDG::UDGGridOperator<typename FunctionSpace::GFS, typename FunctionSpace::GFS,
WrappedLocalOperator, MatrixBackend, DF, RF, JF,
UnfittedSubTriangulation>;
using GridOperator = CutFEMGridOperator<RawGridOperator, ST, EdgeNormProvider>;
using SolverBackend = Dune::PDELab::ISTLBackend_SEQ_CG_AMG_SSOR<GridOperator>;
using LinearSolver = LinearProblemSolver<GridOperator, DomainDOFVector, RangeDOFVector>;
};
template <class ST, int compartments, int degree,
class P = ConvectionDiffusion_UDG_DefaultParameter<typename ST::BaseT::GridView>,
class DF = double, class RF = double, class JF = double>
class CutFEMSolver
{
public:
using Traits = CutFEMSolverTraits<ST, compartments, degree, P, DF, RF, JF>;
CutFEMSolver(std::shared_ptr<typename Traits::SubTriangulation> subTriangulation,
const Dune::ParameterTree& config)
: CutFEMSolver(subTriangulation, std::make_shared<typename Traits::Problem>(
config.get<std::vector<double>>("conductivities")),
config)
{
}
CutFEMSolver(std::shared_ptr<typename Traits::SubTriangulation> subTriangulation,
std::shared_ptr<typename Traits::Problem> problem,
const Dune::ParameterTree& config)
: subTriangulation_(subTriangulation)
, problem_(problem)
, functionSpace_(subTriangulation_->gridView(), subTriangulation_)
, edgeNormProvider_(config.get<std::string>("edge_norm_type"), 1.0)
, weighting_(config.get<std::string>("weights"))
, localOperator_(
*problem_, edgeNormProvider_, weighting_,
ConvectionDiffusion_DG_Scheme::fromString(config.get<std::string>("scheme")),
config.get<RF>("penalty"))
, wrappedLocalOperator_(localOperator_)
, unfittedSubTriangulation_(subTriangulation_->gridView(), *subTriangulation_)
, rawGridOperator_(functionSpace_.getGFS(), functionSpace_.getGFS(),
unfittedSubTriangulation_, wrappedLocalOperator_,
typename Traits::MatrixBackend(2 * Traits::dimension + 1))
, gridOperator_(rawGridOperator_, subTriangulation, edgeNormProvider_, config)
, linearSolver_(gridOperator_, config)
{
}
template <class SolverBackend>
void solve(SolverBackend& solverBackend, const typename Traits::RangeDOFVector& rightHandSide,
typename Traits::DomainDOFVector& solution, const Dune::ParameterTree& config,
DataTree dataTree = DataTree())
{
Dune::Timer timer;
randomize_uniform(Dune::PDELab::Backend::native(solution), DF(-1.0), DF(1.0));
linearSolver_.apply(solverBackend, solution, rightHandSide, config, dataTree);
dataTree.set("time", timer.elapsed());
}
template <class SolverBackend>
void solve(SolverBackend& solverBackend, typename Traits::DomainDOFVector& solution,
const Dune::ParameterTree& config, DataTree dataTree = DataTree())
{
Dune::Timer timer;
initialize(Dune::PDELab::Backend::native(solution), config.hasSub("initialization") ?
config.sub("initialization") :
Dune::ParameterTree());
linearSolver_.apply(solverBackend, solution, config, dataTree);
dataTree.set("time", timer.elapsed());
}
const typename Traits::FunctionSpace& functionSpace() const
{
return functionSpace_;
}
const typename Traits::SubTriangulation& subTriangulation() const
{
return *subTriangulation_;
}
typename Traits::Problem& problem()
{
return *problem_;
}
#if HAVE_TBB
tbb::mutex& functionSpaceMutex()
{
return fsMutex_;
}
#endif
private:
std::shared_ptr<typename Traits::SubTriangulation> subTriangulation_;
std::shared_ptr<typename Traits::Problem> problem_;
typename Traits::FunctionSpace functionSpace_;
typename Traits::EdgeNormProvider edgeNormProvider_;
typename Traits::PenaltyFluxWeighting weighting_;
typename Traits::LocalOperator localOperator_;
typename Traits::WrappedLocalOperator wrappedLocalOperator_;
typename Traits::UnfittedSubTriangulation unfittedSubTriangulation_;
typename Traits::RawGridOperator rawGridOperator_;
typename Traits::GridOperator gridOperator_;
typename Traits::LinearSolver linearSolver_;
#if HAVE_TBB
tbb::mutex fsMutex_;
#endif
};
}
#endif // DUNEURO_CUTFEM_SOLVER_HH
#ifndef DUNEURO_CUTFEM_SOLVER_BACKEND_HH
#define DUNEURO_CUTFEM_SOLVER_BACKEND_HH
#include <dune/pdelab/backend/istl.hh>
namespace duneuro
{
template <typename Solver>
struct CutFEMSolverBackendTraits {
using SolverBackend =
Dune::PDELab::ISTLBackend_SEQ_CG_AMG_SSOR<typename Solver::Traits::GridOperator>;
};
template <typename Solver>
class CutFEMSolverBackend
{
public:
using Traits = CutFEMSolverBackendTraits<Solver>;
explicit CutFEMSolverBackend(std::shared_ptr<Solver> solver, const Dune::ParameterTree& config)
: solver_(solver)
, solverBackend_(config.get<unsigned int>("max_iterations", 5000),
config.get<unsigned int>("verbose", 0), true)
{
}
const typename Traits::SolverBackend& get() const
{
return solverBackend_;
}
typename Traits::SolverBackend& get()
{
return solverBackend_;
}
private:
std::shared_ptr<Solver> solver_;
typename Traits::SolverBackend solverBackend_;
};
}
#endif // DUNEURO_CUTFEM_SOLVER_BACKEND_HH
#include <duneuro/common/deprecated.hh>
#include <iostream>
namespace duneuro
{
void issueDeprecationWarning(const std::string& msg)
{
std::cout << "DEPRECATION WARNING:\n" << msg << std::endl;
}
}
#ifndef DUNEURO_DEPRECATED_HH
#define DUNEURO_DEPRECATED_HH
#include <string>
namespace duneuro
{
void issueDeprecationWarning(const std::string& msg);
}
#endif // DUNEURO_DEPRECATED_HH
......@@ -11,6 +11,7 @@
#include <duneuro/common/edge_norm_provider.hh>
#include <duneuro/common/flags.hh>
#include <duneuro/common/linear_problem_solver.hh>
#include <duneuro/common/penalty_flux_weighting.hh>
#include <duneuro/common/random.hh>
#include <duneuro/io/data_tree.hh>
......@@ -44,7 +45,9 @@ namespace duneuro
using DomainDOFVector = Dune::PDELab::Backend::Vector<typename FunctionSpace::GFS, DF>;
using RangeDOFVector = Dune::PDELab::Backend::Vector<typename FunctionSpace::GFS, RF>;
using EdgeNormProvider = MultiEdgeNormProvider;
using LocalOperator = ConvectionDiffusion_DG_LocalOperator<Problem, EdgeNormProvider>;
using PenaltyFluxWeighting = FittedDynamicPenaltyFluxWeights;
using LocalOperator =
ConvectionDiffusion_DG_LocalOperator<Problem, EdgeNormProvider, PenaltyFluxWeighting>;
using Assembler = GalerkinGlobalAssembler<FunctionSpace, LocalOperator, DF, RF, JF>;
using LinearSolver =
LinearProblemSolver<typename Assembler::GO, DomainDOFVector, RangeDOFVector>;
......@@ -64,11 +67,10 @@ namespace duneuro
, problem_(problem)
, functionSpace_(volumeConductor_->gridView())
, edgeNormProvider_(config.get<std::string>("edge_norm_type"), 1.0)
, weighting_(config.get<std::string>("weights"))
, localOperator_(
*problem_, edgeNormProvider_,
*problem_, edgeNormProvider_, weighting_,
ConvectionDiffusion_DG_Scheme::fromString(config.get<std::string>("scheme")),
config.get<bool>("weights") ? ConvectionDiffusion_DG_Weights::weightsOn :
ConvectionDiffusion_DG_Weights::weightsOff,
config.get<DF>("penalty"), false, config.get<unsigned int>("intorderadd", 0))
, assembler_(functionSpace_, localOperator_, 2 * VC::dim + 1)
, linearSolver_(*assembler_, config)
......@@ -146,6 +148,7 @@ namespace duneuro
std::shared_ptr<typename Traits::Problem> problem_;
typename Traits::FunctionSpace functionSpace_;
typename Traits::EdgeNormProvider edgeNormProvider_;
typename Traits::PenaltyFluxWeighting weighting_;
typename Traits::LocalOperator localOperator_;
typename Traits::Assembler assembler_;
typename Traits::LinearSolver linearSolver_;
......
......@@ -164,6 +164,44 @@ namespace duneuro
}
};
class FundamentalCellBasedEdgeNormProvider
: public EdgeNormProviderInterface<FundamentalCellBasedEdgeNormProvider>
{
public:
#if HAVE_DUNE_UDG
template <typename Impl>
void edgeNorm(const Dune::PDELab::UnfittedIntersectionWrapper<Impl>& ig,
typename Dune::PDELab::UnfittedIntersectionWrapper<Impl>::ctype& h,
const bool boundary = false) const
{
// {harmonic average of inside and outside volume}^{1/dim}
// == 2.0*getEdgeNorm() of Dune::UDG::MarchingCube33SubTriangulation
typedef Dune::PDELab::UnfittedIntersectionWrapper<Impl> IG;
typedef typename IG::Geometry::ctype ctype;
const ctype iv = ig.inside().geometry().volume();
const ctype ov = boundary ? iv : ig.outside().geometry().volume();
const ctype harmonic_av = 2.0 * iv * ov / (iv + ov + 1e-20);
const int dim = IG::dimension;
h = std::pow(harmonic_av, 1.0 / ctype(dim));
}
#endif
template <typename Impl>
void edgeNorm(const Dune::PDELab::IntersectionGeometry<Impl>& ig,
typename Dune::PDELab::IntersectionGeometry<Impl>::Geometry::ctype& h,
const bool boundary = false) const
{
// {harmonic average of inside and outside volume}^{1/dim}
typedef Dune::PDELab::IntersectionGeometry<Impl> IG;
typedef typename IG::Geometry::ctype ctype;
const ctype iv = ig.inside().geometry().volume();
const ctype ov = boundary ? iv : ig.outside().geometry().volume();
const ctype harmonic_av = 2.0 * iv * ov / (iv + ov + 1e-20);
const int dim = IG::dimension;
h = std::pow(harmonic_av, 1.0 / ctype(dim));
}
};
/**
* \brief Edge norm provider for using local operators which implement
* interior penalty DG schemes together with the PDELab assembler,
......@@ -218,6 +256,7 @@ namespace duneuro
}
};
/**
* \brief Edge norm provider for using local operators which implement
* interior penalty DG schemes together with the PDELab assembler,
......@@ -236,6 +275,7 @@ namespace duneuro
, structuredENP_(gridWidth)
, faceBasedENP_()
, cellBasedENP_()
, fundamentalCellBasedENP_()
, houstonENP_()
{
}
......@@ -246,7 +286,11 @@ namespace duneuro
}
MultiEdgeNormProvider(const std::string& type, double gridWidth)
: structuredENP_(gridWidth), faceBasedENP_(), cellBasedENP_(), houstonENP_()
: structuredENP_(gridWidth)
, faceBasedENP_()
, cellBasedENP_()
, fundamentalCellBasedENP_()
, houstonENP_()
{
if (type == "structured") {
realEdgeNormProviderType_ = 0;
......@@ -256,8 +300,10 @@ namespace duneuro
realEdgeNormProviderType_ = 2;
} else if (type == "houston") {
realEdgeNormProviderType_ = 3;
} else if (type == "fundamentalcell") {
realEdgeNormProviderType_ = 4;
} else {
DUNE_THROW(Dune::Exception, "unknown edge norm type");
DUNE_THROW(Dune::Exception, "unknown edge norm type \"" << type << "\"");
}
}
......@@ -283,6 +329,10 @@ namespace duneuro
// edge norm provider using Houston's choice
houstonENP_.edgeNorm(ig, h, boundary);
break;
case 4:
// edge norm provider using volume of fundamental cells
fundamentalCellBasedENP_.edgeNorm(ig, h, boundary);
break;
default:
DUNE_THROW(Dune::RangeError,
"Invalid edge norm type: " << (unsigned int) realEdgeNormProviderType_);
......@@ -298,94 +348,9 @@ namespace duneuro
const StructuredGridEdgeNormProvider structuredENP_;
const FaceBasedEdgeNormProvider faceBasedENP_;
const CellBasedEdgeNormProvider cellBasedENP_;
const FundamentalCellBasedEdgeNormProvider fundamentalCellBasedENP_;
const HoustonEdgeNormProvider houstonENP_;
};
// #include <algorithm> // provides std::min, std::max
// #include <dune/common/fvector.hh> // provides FieldVector
// #include <dune/geometry/type.hh> // provides GeometryType
// #include <dune/geometry/referenceelements.hh> // provides GenericReferenceElements
// /**
// * \brief Edge norm provider for using local operators which implement
// * interior penalty DG schemes together with the PDELab assembler,
// * i.e. the Dune::PDELab::GridOperator.
// * Computes an edge norm using the length of the adjacent domain
// * cells' edges.
// *
// * \author Sebastian Westerheide.
// */
// class EdgeBasedEdgeNormProvider
// : public EdgeNormProviderInterface
// {
// public:
// template <typename IntersectionGeometry>
// void edgeNorm (const IntersectionGeometry& ig,
// typename IntersectionGeometry::Geometry::ctype& h,
// const bool boundary = false) const
// {
// static const bool use_udg_assembler
// = UDGAssemblerSwitch<IntersectionGeometry>::use_udg_assembler;
// if (use_udg_assembler)
// DUNE_THROW(Dune::NotImplemented,"UDG assembler detected but "
// << "EdgeBasedEdgeNormProvider only implemented for "
// << "PDELab assembler.");
// else
// {
// // TODO: should be revised for anisotropic meshes?
// typedef IntersectionGeometry IG;
// typedef typename IG::Geometry::ctype ctype;
// ctype h_s, h_n;
// ctype hmax_s, hmax_n;
// element_size(ig.inside()->geometry(),h_s,hmax_s);
// if (boundary)
// h_n = h_s;
// else
// element_size(ig.outside()->geometry(),h_n,hmax_n);
// h = std::min(h_s,h_n);
// }
// }
// protected:
// /**
// * \brief Computes an entity's minimum and maximum edge length.
// */
// template <class GEO>
// void element_size (const GEO& geo,
// typename GEO::ctype& hmin, typename GEO::ctype hmax) const
// {
// typedef typename GEO::ctype DF;
// hmin = 1.0E100;
// hmax = -1.0E00;
// const int dim = GEO::coorddimension;
// if (dim == 1)
// {
// Dune::FieldVector<DF,dim> x = geo.corner(0);
// x -= geo.corner(1);
// hmin = hmax = x.two_norm();
// return;
// }
// else
// {
// const Dune::GeometryType gt = geo.type();
// for (int i = 0;
// i < Dune::GenericReferenceElements<DF,dim>::general(gt).size(dim-1);
// i++)
// {
// Dune::FieldVector<DF,dim> x
// = geo.corner(Dune::GenericReferenceElements<DF,dim>
// ::general(gt).subEntity(i,dim-1,0,dim));
// x -= geo.corner(Dune::GenericReferenceElements<DF,dim>
// ::general(gt).subEntity(i,dim-1,1,dim));
// hmin = std::min(hmin,x.two_norm());
// hmax = std::max(hmax,x.two_norm());
// }
// }
// return;
// }
// };
}
#endif // DUNEURO_EDGE_NORM_PROVIDER_HH
......@@ -31,6 +31,7 @@ namespace duneuro
};
enum class FittedSolverType { cg, dg };
enum class UnfittedSolverType { cutfem, udg};
}
#endif // DUNEURO_FLAGS_HH
......@@ -7,11 +7,13 @@ namespace duneuro
{
template <class GFS, int k, class Backend, class OrderingTag>
std::shared_ptr<Dune::PDELab::PowerGridFunctionSpace<GFS, k, Backend, OrderingTag>>
make_power_gfs(std::array<std::shared_ptr<GFS>, k>& gfss, Backend backend, OrderingTag tag);
make_power_gfs(std::array<std::shared_ptr<GFS>, k>& gfss, Backend backend = Backend(),
OrderingTag tag = OrderingTag());
template <class GFS, class Backend, class OrderingTag>
std::shared_ptr<Dune::PDELab::PowerGridFunctionSpace<GFS, 1, Backend, OrderingTag>>
make_power_gfs(std::array<std::shared_ptr<GFS>, 1>& gfss, Backend backend, OrderingTag tag)
make_power_gfs(std::array<std::shared_ptr<GFS>, 1>& gfss, Backend backend = Backend(),
OrderingTag tag = OrderingTag())
{
return std::make_shared<Dune::PDELab::PowerGridFunctionSpace<GFS, 1, Backend, OrderingTag>>(
*(gfss[0]), backend, tag);
......@@ -19,7 +21,8 @@ namespace duneuro
template <class GFS, class Backend, class OrderingTag>
std::shared_ptr<Dune::PDELab::PowerGridFunctionSpace<GFS, 2, Backend, OrderingTag>>
make_power_gfs(std::array<std::shared_ptr<GFS>, 2>& gfss, Backend backend, OrderingTag tag)
make_power_gfs(std::array<std::shared_ptr<GFS>, 2>& gfss, Backend backend = Backend(),
OrderingTag tag = OrderingTag())
{
return std::make_shared<Dune::PDELab::PowerGridFunctionSpace<GFS, 2, Backend, OrderingTag>>(
*(gfss[0]), *(gfss[1]), backend, tag);
......@@ -27,7 +30,8 @@ namespace duneuro
template <class GFS, class Backend, class OrderingTag>
std::shared_ptr<Dune::PDELab::PowerGridFunctionSpace<GFS, 3, Backend, OrderingTag>>
make_power_gfs(std::array<std::shared_ptr<GFS>, 3>& gfss, Backend backend, OrderingTag tag)
make_power_gfs(std::array<std::shared_ptr<GFS>, 3>& gfss, Backend backend = Backend(),
OrderingTag tag = OrderingTag())
{
return std::make_shared<Dune::PDELab::PowerGridFunctionSpace<GFS, 3, Backend, OrderingTag>>(
*(gfss[0]), *(gfss[1]), *(gfss[2]), backend, tag);
......@@ -35,7 +39,8 @@ namespace duneuro
template <class GFS, class Backend, class OrderingTag>
std::shared_ptr<Dune::PDELab::PowerGridFunctionSpace<GFS, 4, Backend, OrderingTag>>
make_power_gfs(std::array<std::shared_ptr<GFS>, 4>& gfss, Backend backend, OrderingTag tag)
make_power_gfs(std::array<std::shared_ptr<GFS>, 4>& gfss, Backend backend = Backend(),
OrderingTag tag = OrderingTag())
{
return std::make_shared<Dune::PDELab::PowerGridFunctionSpace<GFS, 4, Backend, OrderingTag>>(
*(gfss[0]), *(gfss[1]), *(gfss[2]), *(gfss[3]), backend, tag);
......@@ -43,7 +48,8 @@ namespace duneuro
template <class GFS, class Backend, class OrderingTag>
std::shared_ptr<Dune::PDELab::PowerGridFunctionSpace<GFS, 5, Backend, OrderingTag>>
make_power_gfs(std::array<std::shared_ptr<GFS>, 5>& gfss, Backend backend, OrderingTag tag)
make_power_gfs(std::array<std::shared_ptr<GFS>, 5>& gfss, Backend backend = Backend(),
OrderingTag tag = OrderingTag())
{
return std::make_shared<Dune::PDELab::PowerGridFunctionSpace<GFS, 5, Backend, OrderingTag>>(
*(gfss[0]), *(gfss[1]), *(gfss[2]), *(gfss[3]), *(gfss[4]), backend, tag);
......@@ -51,7 +57,8 @@ namespace duneuro
template <class GFS, class Backend, class OrderingTag>
std::shared_ptr<Dune::PDELab::PowerGridFunctionSpace<GFS, 6, Backend, OrderingTag>>
make_power_gfs(std::array<std::shared_ptr<GFS>, 6>& gfss, Backend backend, OrderingTag tag)
make_power_gfs(std::array<std::shared_ptr<GFS>, 6>& gfss, Backend backend = Backend(),
OrderingTag tag = OrderingTag())
{
return std::make_shared<Dune::PDELab::PowerGridFunctionSpace<GFS, 6, Backend, OrderingTag>>(
*(gfss[0]), *(gfss[1]), *(gfss[2]), *(gfss[3]), *(gfss[4]), *(gfss[5]), backend, tag);
......
This diff is collapsed.
......@@ -49,7 +49,7 @@ namespace duneuro
fems_[i] = std::make_shared<FEM>(lfe_, *subTriangulation_, i);