Commit 547b4909 authored by Thomas Fetzer's avatar Thomas Fetzer
Browse files

[multidomain]

- added asserts for the mass/mole formulations in the coupling
  conditions to ensure that the coupling conditions are applied
correctly
- skip test in case SuperLU or UMFPack are not available
- updated documention and use of properties

reviewed by gruenich



git-svn-id: svn://svn.iws.uni-stuttgart.de/DUMUX/dumux/trunk@15055 2fb0f335-1f38-0410-981e-8018bf24f1b0
parent 9d5566d9
...@@ -364,10 +364,10 @@ public: ...@@ -364,10 +364,10 @@ public:
DimVector normalMassFlux2(0.); DimVector normalMassFlux2(0.);
// velocity*normal*area*rho // velocity*normal*area*rho
// mass flux is needed for both (mass/mole) formulation, as the enthalpy is mass based
for (int phaseIdx=0; phaseIdx<numPhases2; ++phaseIdx) for (int phaseIdx=0; phaseIdx<numPhases2; ++phaseIdx)
normalMassFlux2[phaseIdx] = -boundaryVars2.volumeFlux(phaseIdx)* normalMassFlux2[phaseIdx] = -boundaryVars2.volumeFlux(phaseIdx)*
cParams.elemVolVarsCur2[vertInElem2].density(phaseIdx); cParams.elemVolVarsCur2[vertInElem2].density(phaseIdx);
////////////////////////////////////////
if (cParams.boundaryTypes1.isCouplingOutflow(energyEqIdx1)) if (cParams.boundaryTypes1.isCouplingOutflow(energyEqIdx1))
{ {
......
...@@ -155,10 +155,9 @@ class TwoCStokesTwoPTwoCLocalOperator : ...@@ -155,10 +155,9 @@ class TwoCStokesTwoPTwoCLocalOperator :
typedef typename GET_PROP_TYPE(Stokes2cTypeTag, FVElementGeometry) FVElementGeometry1; typedef typename GET_PROP_TYPE(Stokes2cTypeTag, FVElementGeometry) FVElementGeometry1;
typedef typename GET_PROP_TYPE(TwoPTwoCTypeTag, FVElementGeometry) FVElementGeometry2; typedef typename GET_PROP_TYPE(TwoPTwoCTypeTag, FVElementGeometry) FVElementGeometry2;
// Multidomain Grid and Subgrid types // Multidomain Grid types
typedef typename GET_PROP_TYPE(TypeTag, MultiDomainGrid) MDGrid; typedef typename GET_PROP_TYPE(TypeTag, MultiDomainGrid) MDGrid;
typedef typename MDGrid::Traits::template Codim<0>::Entity MDElement; typedef typename MDGrid::Traits::template Codim<0>::Entity MDElement;
typedef typename MDGrid::SubDomainGrid SDGrid;
typedef typename GET_PROP_TYPE(Stokes2cTypeTag, GridView) Stokes2cGridView; typedef typename GET_PROP_TYPE(Stokes2cTypeTag, GridView) Stokes2cGridView;
typedef typename GET_PROP_TYPE(TwoPTwoCTypeTag, GridView) TwoPTwoCGridView; typedef typename GET_PROP_TYPE(TwoPTwoCTypeTag, GridView) TwoPTwoCGridView;
...@@ -210,9 +209,13 @@ class TwoCStokesTwoPTwoCLocalOperator : ...@@ -210,9 +209,13 @@ class TwoCStokesTwoPTwoCLocalOperator :
typedef typename TwoPTwoCGridView::template Codim<dim>::EntityPointer VertexPointer2; typedef typename TwoPTwoCGridView::template Codim<dim>::EntityPointer VertexPointer2;
typedef typename MDGrid::Traits::template Codim<0>::EntityPointer MDElementPointer; typedef typename MDGrid::Traits::template Codim<0>::EntityPointer MDElementPointer;
//! \brief The constructor
TwoCStokesTwoPTwoCLocalOperator(GlobalProblem& globalProblem) TwoCStokesTwoPTwoCLocalOperator(GlobalProblem& globalProblem)
: globalProblem_(globalProblem) : globalProblem_(globalProblem)
{ {
static_assert(GET_PROP_VALUE(Stokes2cTypeTag, UseMoles) == GET_PROP_VALUE(TwoPTwoCTypeTag, UseMoles),
"The coupling conditions is only implemented for same formulations (mass or mole) in both subdomains.");
blModel_ = GET_PARAM_FROM_GROUP(TypeTag, int, BoundaryLayer, Model); blModel_ = GET_PARAM_FROM_GROUP(TypeTag, int, BoundaryLayer, Model);
massTransferModel_ = GET_PARAM_FROM_GROUP(TypeTag, int, MassTransfer, Model); massTransferModel_ = GET_PARAM_FROM_GROUP(TypeTag, int, MassTransfer, Model);
...@@ -406,12 +409,16 @@ class TwoCStokesTwoPTwoCLocalOperator : ...@@ -406,12 +409,16 @@ class TwoCStokesTwoPTwoCLocalOperator :
{ {
const DimVector& globalPos1 = cParams.fvGeometry1.subContVol[vertInElem1].global; const DimVector& globalPos1 = cParams.fvGeometry1.subContVol[vertInElem1].global;
const DimVector& bfNormal1 = boundaryVars1.face().normal; const DimVector& bfNormal1 = boundaryVars1.face().normal;
const Scalar normalMassFlux = boundaryVars1.normalVelocity() * const Scalar normalMassFlux = boundaryVars1.normalVelocity() *
cParams.elemVolVarsCur1[vertInElem1].density(); cParams.elemVolVarsCur1[vertInElem1].density();
//rho*v*n as NEUMANN condition for porous medium (set, if B&J defined as NEUMANN condition) //rho*v*n as NEUMANN condition for porous medium (set, if B&J defined as NEUMANN condition)
if (cParams.boundaryTypes2.isCouplingInflow(massBalanceIdx2)) if (cParams.boundaryTypes2.isCouplingInflow(massBalanceIdx2))
{ {
static_assert(!GET_PROP_VALUE(Stokes2cTypeTag, UseMoles),
"This coupling condition is only implemented for mass fraction formulation.");
if (globalProblem_.sdProblem1().isCornerPoint(globalPos1)) if (globalProblem_.sdProblem1().isCornerPoint(globalPos1))
{ {
couplingRes2.accumulate(lfsu_n.child(massBalanceIdx2), vertInElem2, couplingRes2.accumulate(lfsu_n.child(massBalanceIdx2), vertInElem2,
...@@ -435,6 +442,9 @@ class TwoCStokesTwoPTwoCLocalOperator : ...@@ -435,6 +442,9 @@ class TwoCStokesTwoPTwoCLocalOperator :
// only enter here, if a BOUNDARY LAYER MODEL is used for the computation of the diffusive fluxes // only enter here, if a BOUNDARY LAYER MODEL is used for the computation of the diffusive fluxes
if (blModel_) if (blModel_)
{ {
static_assert(!GET_PROP_VALUE(Stokes2cTypeTag, UseMoles),
"Boundary layer and mass transfer models are only implemented for mass fraction formulation.");
const Scalar massFractionOut = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, FreeFlow, RefMassfrac); const Scalar massFractionOut = GET_RUNTIME_PARAM_FROM_GROUP(TypeTag, Scalar, FreeFlow, RefMassfrac);
const Scalar M1 = FluidSystem::molarMass(transportCompIdx1); const Scalar M1 = FluidSystem::molarMass(transportCompIdx1);
const Scalar M2 = FluidSystem::molarMass(phaseCompIdx1); const Scalar M2 = FluidSystem::molarMass(phaseCompIdx1);
...@@ -520,6 +530,9 @@ class TwoCStokesTwoPTwoCLocalOperator : ...@@ -520,6 +530,9 @@ class TwoCStokesTwoPTwoCLocalOperator :
// compute fluxes explicitly at corner points - only quarter control volume // compute fluxes explicitly at corner points - only quarter control volume
if (globalProblem_.sdProblem1().isCornerPoint(globalPos1)) if (globalProblem_.sdProblem1().isCornerPoint(globalPos1))
{ {
static_assert(!GET_PROP_VALUE(TwoPTwoCTypeTag, UseMoles),
"This coupling condition is only implemented for mass fraction formulation.");
const Scalar advectiveFlux = const Scalar advectiveFlux =
normalMassFlux * normalMassFlux *
cParams.elemVolVarsCur1[vertInElem1].massFraction(transportCompIdx1); cParams.elemVolVarsCur1[vertInElem1].massFraction(transportCompIdx1);
...@@ -536,6 +549,9 @@ class TwoCStokesTwoPTwoCLocalOperator : ...@@ -536,6 +549,9 @@ class TwoCStokesTwoPTwoCLocalOperator :
// coupling via the defect // coupling via the defect
else else
{ {
static_assert(GET_PROP_VALUE(Stokes2cTypeTag, UseMoles) == GET_PROP_VALUE(TwoPTwoCTypeTag, UseMoles),
"This coupling condition is only implemented or different formulations (mass/mole) in the subdomains.");
// the component mass flux from the stokes domain // the component mass flux from the stokes domain
couplingRes2.accumulate(lfsu_n.child(contiWEqIdx2), vertInElem2, couplingRes2.accumulate(lfsu_n.child(contiWEqIdx2), vertInElem2,
globalProblem_.localResidual1().residual(vertInElem1)[transportEqIdx1]); globalProblem_.localResidual1().residual(vertInElem1)[transportEqIdx1]);
...@@ -611,6 +627,11 @@ class TwoCStokesTwoPTwoCLocalOperator : ...@@ -611,6 +627,11 @@ class TwoCStokesTwoPTwoCLocalOperator :
if (cParams.boundaryTypes1.isCouplingOutflow(transportEqIdx1)) if (cParams.boundaryTypes1.isCouplingOutflow(transportEqIdx1))
{ {
// set residualStokes[transportEqIdx1] = x in stokes2clocalresidual.hh // set residualStokes[transportEqIdx1] = x in stokes2clocalresidual.hh
static_assert(!GET_PROP_VALUE(Stokes2cTypeTag, UseMoles),
"This coupling condition is only implemented for mass fraction formulation.");
couplingRes1.accumulate(lfsu_s.child(transportEqIdx1), vertInElem1, couplingRes1.accumulate(lfsu_s.child(transportEqIdx1), vertInElem1,
-cParams.elemVolVarsCur2[vertInElem2].massFraction(nPhaseIdx2, wCompIdx2)); -cParams.elemVolVarsCur2[vertInElem2].massFraction(nPhaseIdx2, wCompIdx2));
} }
......
...@@ -48,6 +48,7 @@ class TwoCStokesTwoPTwoCNewtonController : public MultiDomainNewtonController<Ty ...@@ -48,6 +48,7 @@ class TwoCStokesTwoPTwoCNewtonController : public MultiDomainNewtonController<Ty
typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector; typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
public: public:
//! \brief The constructor
TwoCStokesTwoPTwoCNewtonController(const Problem &problem) TwoCStokesTwoPTwoCNewtonController(const Problem &problem)
: ParentType(problem) : ParentType(problem)
{ } { }
......
...@@ -40,21 +40,12 @@ namespace Properties ...@@ -40,21 +40,12 @@ namespace Properties
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
// Specify the multidomain gridview // Specify the multidomain gridview
SET_PROP(TwoCStokesTwoPTwoC, GridView) SET_TYPE_PROP(TwoCStokesTwoPTwoC, GridView,
{ typename GET_PROP_TYPE(TypeTag, MultiDomainGrid)::LeafGridView);
typedef typename GET_PROP_TYPE(TypeTag, MultiDomainGrid) MDGrid;
public:
typedef typename MDGrid::LeafGridView type;
};
// Specify the type of the used solution vector // Specify the type of the used solution vector
SET_PROP(TwoCStokesTwoPTwoC, SolutionVector) SET_TYPE_PROP(TwoCStokesTwoPTwoC, SolutionVector,
{ typename GET_PROP_TYPE(TypeTag, MultiDomainGridOperator)::Traits::Domain);
private:
typedef typename GET_PROP_TYPE(TypeTag, MultiDomainGridOperator) MDGridOperator;
public:
typedef typename MDGridOperator::Traits::Domain type;
};
// Specify the type of the multidomain assembler // Specify the type of the multidomain assembler
SET_TYPE_PROP(TwoCStokesTwoPTwoC, JacobianAssembler, Dumux::MultiDomainAssembler<TypeTag>); SET_TYPE_PROP(TwoCStokesTwoPTwoC, JacobianAssembler, Dumux::MultiDomainAssembler<TypeTag>);
......
...@@ -27,8 +27,6 @@ ...@@ -27,8 +27,6 @@
#include <dumux/implicit/nonisothermal/nilocalresidual.hh> #include <dumux/implicit/nonisothermal/nilocalresidual.hh>
#include <dumux/implicit/2p2c/2p2cproperties.hh> #include <dumux/implicit/2p2c/2p2cproperties.hh>
#define VELOCITY_OUTPUT 1 // uncomment this line if an output of the velocity is needed
namespace Dumux namespace Dumux
{ {
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#ifndef DUMUX_STOKESNC_COUPLING_LOCAL_RESIDUAL_HH #ifndef DUMUX_STOKESNC_COUPLING_LOCAL_RESIDUAL_HH
#define DUMUX_STOKESNC_COUPLING_LOCAL_RESIDUAL_HH #define DUMUX_STOKESNC_COUPLING_LOCAL_RESIDUAL_HH
#include <dumux/freeflow/stokesnc/stokesnclocalresidual.hh>
#include <dumux/freeflow/stokesnc/stokesncmodel.hh> #include <dumux/freeflow/stokesnc/stokesncmodel.hh>
namespace Dumux namespace Dumux
...@@ -368,7 +369,7 @@ protected: ...@@ -368,7 +369,7 @@ protected:
} }
} }
// return true, if at least one equation on the boundary has a coupling condition //! \brief Return true, if at least one equation on the boundary has a coupling condition
bool boundaryHasCoupling_(const BoundaryTypes& bcTypes) const bool boundaryHasCoupling_(const BoundaryTypes& bcTypes) const
{ {
for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) for (int eqIdx = 0; eqIdx < numEq; ++eqIdx)
...@@ -377,7 +378,7 @@ protected: ...@@ -377,7 +378,7 @@ protected:
return false; return false;
} }
// return true, if at least one equation on the boundary has a mortar coupling condition //! \brief Return true, if at least one equation on the boundary has a mortar coupling condition
bool boundaryHasMortarCoupling_(const BoundaryTypes& bcTypes) const bool boundaryHasMortarCoupling_(const BoundaryTypes& bcTypes) const
{ {
for (int eqIdx = 0; eqIdx < numEq; ++eqIdx) for (int eqIdx = 0; eqIdx < numEq; ++eqIdx)
......
...@@ -269,8 +269,14 @@ int startLocal(int argc, char **argv, ...@@ -269,8 +269,14 @@ int startLocal(int argc, char **argv,
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
#if (HAVE_SUPERLU || HAVE_UMFPACK)
typedef TTAG(TwoCNIStokesTwoPTwoCNIProblem) ProblemTypeTag; typedef TTAG(TwoCNIStokesTwoPTwoCNIProblem) ProblemTypeTag;
return startLocal<ProblemTypeTag>(argc, argv, printUsage); return startLocal<ProblemTypeTag>(argc, argv, printUsage);
#else
#warning "You need to have SuperLU or UMFPack installed to run this test."
std::cerr << "You need to have SuperLU or UMFPack installed to run this test\n";
return 77;
#endif
} }
#else #else
......
...@@ -340,8 +340,14 @@ int startLocal(int argc, char **argv, ...@@ -340,8 +340,14 @@ int startLocal(int argc, char **argv,
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
#if (HAVE_SUPERLU || HAVE_UMFPACK)
typedef TTAG(TwoCNIZeroEqTwoPTwoCNIProblem) ProblemTypeTag; typedef TTAG(TwoCNIZeroEqTwoPTwoCNIProblem) ProblemTypeTag;
return startLocal<ProblemTypeTag>(argc, argv, printUsage); return startLocal<ProblemTypeTag>(argc, argv, printUsage);
#else
#warning "You need to have SuperLU or UMFPack installed to run this test."
std::cerr << "You need to have SuperLU or UMFPack installed to run this test\n";
return 77;
#endif
} }
#else #else
......
...@@ -264,8 +264,14 @@ int startLocal(int argc, char **argv, ...@@ -264,8 +264,14 @@ int startLocal(int argc, char **argv,
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
#if (HAVE_SUPERLU || HAVE_UMFPACK)
typedef TTAG(TwoCStokesTwoPTwoCProblem) ProblemTypeTag; typedef TTAG(TwoCStokesTwoPTwoCProblem) ProblemTypeTag;
return startLocal<ProblemTypeTag>(argc, argv, printUsage); return startLocal<ProblemTypeTag>(argc, argv, printUsage);
#else
#warning "You need to have SuperLU or UMFPack installed to run this test."
std::cerr << "You need to have SuperLU or UMFPack installed to run this test\n";
return 77;
#endif
} }
#else #else
......
...@@ -328,8 +328,14 @@ int startLocal(int argc, char **argv, ...@@ -328,8 +328,14 @@ int startLocal(int argc, char **argv,
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
#if (HAVE_SUPERLU || HAVE_UMFPACK)
typedef TTAG(TwoCZeroEqTwoPTwoCProblem) ProblemTypeTag; typedef TTAG(TwoCZeroEqTwoPTwoCProblem) ProblemTypeTag;
return startLocal<ProblemTypeTag>(argc, argv, printUsage); return startLocal<ProblemTypeTag>(argc, argv, printUsage);
#else
#warning "You need to have SuperLU or UMFPack installed to run this test."
std::cerr << "You need to have SuperLU or UMFPack installed to run this test\n";
return 77;
#endif
} }
#else #else
......
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