Commit b9c80114 authored by Martin Schneider's avatar Martin Schneider
Browse files

[md][ffpm][box] Pass solution to projection class to be able to build elemVolVars

parent 1eb355c3
Pipeline #8459 waiting for manual action with stages
......@@ -65,6 +65,7 @@ class StokesDarcyCouplingDataBoxBase : public StokesDarcyCouplingDataImplementat
static constexpr auto freeFlowIdx = CouplingManager::freeFlowIdx;
static constexpr auto porousMediumIdx = CouplingManager::porousMediumIdx;
using SolutionVector = typename MDTraits::SolutionVector;
using VelocityVector = typename Element<freeFlowIdx>::Geometry::GlobalCoordinate;
template<std::size_t id> using BoundaryTypes = typename ProblemTraits<Problem<id>>::BoundaryTypes;
using StokesVelocityGradients = StaggeredVelocityGradients<Scalar, GridGeometry<freeFlowIdx>, BoundaryTypes<freeFlowIdx>, Indices<freeFlowIdx>>;
......@@ -78,7 +79,9 @@ class StokesDarcyCouplingDataBoxBase : public StokesDarcyCouplingDataImplementat
using Projector = Projection<MDTraits, CouplingManager>;
public:
StokesDarcyCouplingDataBoxBase(const CouplingManager& couplingmanager): ParentType(couplingmanager) {}
StokesDarcyCouplingDataBoxBase(const CouplingManager& couplingmanager,
const SolutionVector& sol) : ParentType(couplingmanager), projector_(sol)
{}
using ParentType::couplingPhaseIdx;
......@@ -104,7 +107,7 @@ public:
auto pressure = [darcyPhaseIdx](const auto& volVars)
{ return volVars.pressure(darcyPhaseIdx); };
Scalar momentumFlux = Projector::calculateProjection(this->couplingManager(), element, scvf, pressure);
Scalar momentumFlux = this->projector().calculateProjection(this->couplingManager(), element, scvf, pressure);
// normalize pressure
if(getPropValue<SubDomainTypeTag<freeFlowIdx>, Properties::NormalizePressure>())
......@@ -264,6 +267,15 @@ public:
velocity /= intersectionLength; //averaging
return velocity;
}
const Projector& projector() const
{
return projector_;
}
private:
Projector projector_;
};
/*!
......@@ -402,7 +414,7 @@ public:
//Calculate the projected temperature value for the stokes face
auto temp = [](const auto& volVars)
{ return volVars.temperature(); };
Scalar interfaceTemperature = Projector::calculateProjection(this->couplingManager(), stokesScvf, element, darcyElemVolVars, temp);
Scalar interfaceTemperature = this->projector().calculateProjection(this->couplingManager(), stokesScvf, element, darcyElemVolVars, temp);
const bool insideIsUpstream = velocity > 0.0;
flux += -1*energyFlux_(data.fvGeometry,
......@@ -436,7 +448,7 @@ public:
auto temp = [](const auto& volVars)
{ return volVars.temperature(); };
Scalar interfaceTemperature = Projector::calculateProjection(this->couplingManager(), element, scvf, temp);
Scalar interfaceTemperature = this->projector().calculateProjection(this->couplingManager(), element, scvf, temp);
Scalar flux = 0.0;
for (const auto& data : stokesContext)
......@@ -607,7 +619,7 @@ public:
auto value = [&compIdx](const auto& volVars)
{ return massOrMoleFraction(volVars, referenceSystemFormulation, couplingPhaseIdx(porousMediumIdx), compIdx); };
return Projector::calculateProjection(this->couplingManager(), stokesScvf, element, darcyElemVolVars, value);
return this->projector().calculateProjection(this->couplingManager(), stokesScvf, element, darcyElemVolVars, value);
};
// Division by scvf.area() is needed, because the final flux results from multiplication with scvf.area()
......@@ -647,7 +659,7 @@ public:
auto value = [&compIdx](const auto& volVars)
{ return massOrMoleFraction(volVars, referenceSystemFormulation, couplingPhaseIdx(porousMediumIdx), compIdx); };
return Projector::calculateProjection(this->couplingManager(), element, scvf, value);
return this->projector().calculateProjection(this->couplingManager(), element, scvf, value);
};
NumEqVector flux(0.0);
......@@ -714,13 +726,13 @@ public:
auto value = [&compIdx](const auto& volVars)
{ return massOrMoleFraction(volVars, referenceSystemFormulation, couplingPhaseIdx(porousMediumIdx), compIdx); };
return Projector::calculateProjection(this->couplingManager(), stokesScvf, element, darcyElemVolVars, value);
return this->projector().calculateProjection(this->couplingManager(), stokesScvf, element, darcyElemVolVars, value);
};
//Calculate the projected temperature value for the stokes face
auto temp = [](const auto& volVars)
{ return volVars.temperature(); };
Scalar interfaceTemperature = Projector::calculateProjection(this->couplingManager(), stokesScvf, element, darcyElemVolVars, temp);
Scalar interfaceTemperature = this->projector().calculateProjection(this->couplingManager(), stokesScvf, element, darcyElemVolVars, temp);
// Division by scvf.area() is needed, because the final flux results from multiplication with scvf.area()
flux += -1*energyFlux_(porousMediumIdx,
......@@ -761,14 +773,14 @@ public:
auto value = [&compIdx](const auto& volVars)
{ return massOrMoleFraction(volVars, referenceSystemFormulation, couplingPhaseIdx(porousMediumIdx), compIdx); };
return Projector::calculateProjection(this->couplingManager(), element, scvf, value);
return this->projector().calculateProjection(this->couplingManager(), element, scvf, value);
};
//Calculate the projected temperature value for the stokes face
auto temp = [](const auto& volVars)
{ return volVars.temperature(); };
Scalar interfaceTemperature = Projector::calculateProjection(this->couplingManager(), element, scvf, temp);
Scalar interfaceTemperature = this->projector().calculateProjection(this->couplingManager(), element, scvf, temp);
Scalar flux = 0.0;
const Scalar velocity = stokesElemFaceVars[scvf].velocitySelf() * scvf.directionSign();
......
......@@ -189,7 +189,7 @@ public:
this->setSubProblems(std::make_tuple(stokesProblem, stokesProblem, darcyProblem));
this->curSol() = curSol;
couplingData_ = std::make_shared<CouplingData>(*this);
couplingData_ = std::make_shared<CouplingData>(*this, this->curSol());
couplingMapper_.update(*this);
computeStencils();
}
......@@ -705,18 +705,6 @@ public:
}
}
//! Return the volume variables of domain i for a given element and scv
template<std::size_t i>
VolumeVariables<i> volVars(Dune::index_constant<i> domainI,
const Element<i>& element,
const SubControlVolume<i>& scv) const
{
VolumeVariables<i> volVars;
const auto elemSol = elementSolution(element, this->curSol()[domainI], this->problem(domainI).gridGeometry());
volVars.update(elemSol, this->problem(domainI), element, scv);
return volVars;
}
const auto& couplingMapper() const
{
return couplingMapper_;
......
......@@ -55,27 +55,6 @@ namespace Detail {
}
}
template<class CouplingManager, class Element, std::size_t id>
struct VolVarsWrapper
{
using Index = Dune::index_constant<id>;
VolVarsWrapper(const CouplingManager& cm, const Element& element)
: cm_(cm), element_(element), domainI_()
{}
template<class SubControlVolume>
auto operator[](const SubControlVolume& scv) const
{
return cm_.volVars(domainI_, element_, scv);
}
private:
const CouplingManager& cm_;
const Element& element_;
Index domainI_;
};
template<class MDTraits, class CouplingManager>
class Projection
{
......@@ -92,23 +71,28 @@ class Projection
template<std::size_t id> using FVElementGeometry = typename GridGeometry<id>::LocalView;
template<std::size_t id> using SubControlVolumeFace = typename GridGeometry<id>::LocalView::SubControlVolumeFace;
template<std::size_t id> using ElementVolumeVariables = typename GetPropType<SubDomainTypeTag<id>, Properties::GridVolumeVariables>::LocalView;
using SolutionVector = typename MDTraits::SolutionVector;
using ProjectionMethod = Detail::ProjectionMethod;
static constexpr auto projectionMethod = Detail::projectionMethod<MDTraits>();
public:
Projection(const SolutionVector& sol) : sol_(sol)
{ }
// calculate projection of pm solution needed for fluxes of the free-flow residual
template<class Function>
static Scalar calculateProjection(const CouplingManager& couplingManager,
const SubControlVolumeFace<freeFlowIdx>& stokesScvf,
const Element<porousMediumIdx>& darcyElement,
const ElementVolumeVariables<porousMediumIdx>& darcyElemVolVars,
Function evalPriVar)
Scalar calculateProjection(const CouplingManager& couplingManager,
const SubControlVolumeFace<freeFlowIdx>& stokesScvf,
const Element<porousMediumIdx>& darcyElement,
const ElementVolumeVariables<porousMediumIdx>& darcyElemVolVars,
Function evalPriVar) const
{
Scalar projection = 0.0;
auto domainI = Dune::index_constant<freeFlowIdx>();
auto fvGeometry = localView(couplingManager.problem(porousMediumIdx).gridGeometry());
auto elemVolVars = localView(darcyElemVolVars.gridVolVars());
// integrate darcy pressure over each coupling facet and average
for(const auto& couplingFacet : couplingFacets(domainI, couplingManager.couplingMapper(), stokesScvf.insideScvIdx(), stokesScvf.localFaceIdx()))
......@@ -125,7 +109,7 @@ public:
}
else
{
VolVarsWrapper<CouplingManager, Element<porousMediumIdx>, porousMediumIdx> elemVolVars(couplingManager, element);
elemVolVars.bind(element, fvGeometry, sol_[porousMediumIdx]);
projection += calculateFacetIntegral(element, fvGeometry, fvGeometry.scvf(couplingFacet.pmScvfIdx), elemVolVars, couplingFacet.geometry, evalPriVar);
}
......@@ -138,10 +122,10 @@ public:
// calculate projection of pm solution needed for fluxes of ff residual
template<class Function>
static Scalar calculateProjection(const CouplingManager& couplingManager,
const Element<freeFlowIdx>& element,
const SubControlVolumeFace<freeFlowIdx>& scvf,
Function evalPriVar)
Scalar calculateProjection(const CouplingManager& couplingManager,
const Element<freeFlowIdx>& element,
const SubControlVolumeFace<freeFlowIdx>& scvf,
Function evalPriVar) const
{
Scalar projection = 0.0;
......@@ -207,6 +191,10 @@ public:
return facetProjection;
}
private:
const SolutionVector& sol_;
};
} // end namespace Dumux
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment