version 3.11-dev
Loading...
Searching...
No Matches
couplingconditions_cvfe_cvfe.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3//
4// SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
12
13#ifndef DUMUX_MD_FREEFLOW_POROUSMEDIUM_COUPLINGCONDITIONS_CVFE_CVFE_HH
14#define DUMUX_MD_FREEFLOW_POROUSMEDIUM_COUPLINGCONDITIONS_CVFE_CVFE_HH
15
16#include <cstddef>
17#include <vector>
18
19#include <dune/common/exceptions.hh>
20#include <dune/common/fvector.hh>
21
22#include <dumux/common/math.hh>
24#include <dumux/common/concepts/variables_.hh>
26
29
30namespace Dumux {
31
32template<class MDTraits, class CouplingManager, bool enableEnergyBalance, bool isCompositional>
34
43template<class MDTraits, class CouplingManager>
46 MDTraits, CouplingManager,
47 GetPropType<typename MDTraits::template SubDomain<0>::TypeTag, Properties::ModelTraits>::enableEnergyBalance(),
48 (GetPropType<typename MDTraits::template SubDomain<0>::TypeTag, Properties::ModelTraits>::numFluidComponents() > 1)
49 >;
50
55template<class MDTraits, class CouplingManager>
57{
58 using Scalar = typename MDTraits::Scalar;
59
60 template<std::size_t id> using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag;
61 template<std::size_t id> using GridDiscretization = GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>;
62 template<std::size_t id> using ElementDiscretization = typename GridDiscretization<id>::LocalView;
63 template<std::size_t id> using FluidSystem = GetPropType<SubDomainTypeTag<id>, Properties::FluidSystem>;
64 template<std::size_t id> using ModelTraits = GetPropType<SubDomainTypeTag<id>, Properties::ModelTraits>;
65 template<std::size_t id> using GridVariables = GetPropType<SubDomainTypeTag<id>, Properties::GridVariables>;
66 template<std::size_t id> using AdvectionType = GetPropType<SubDomainTypeTag<id>, Properties::AdvectionType>;
67 template<std::size_t id> using GlobalPosition = typename GridDiscretization<id>::GridView::template Codim<0>::Geometry::GlobalCoordinate;
68
69public:
70 static constexpr auto freeFlowMomentumIndex = CouplingManager::freeFlowMomentumIndex;
71 static constexpr auto freeFlowMassIndex = CouplingManager::freeFlowMassIndex;
72 static constexpr auto porousMediumIndex = CouplingManager::porousMediumIndex;
73private:
74
75 static constexpr bool adapterUsed = ModelTraits<porousMediumIndex>::numFluidPhases() > 1;
77
78 static constexpr int enableEnergyBalance = ModelTraits<freeFlowMassIndex>::enableEnergyBalance();
79 static_assert(ModelTraits<porousMediumIndex>::enableEnergyBalance() == enableEnergyBalance,
80 "All submodels must both be either isothermal or non-isothermal");
81
83 FluidSystem<porousMediumIndex>>::value,
84 "All submodels must use the same fluid system");
85
86public:
90 template<std::size_t i>
91 static constexpr auto couplingPhaseIdx(Dune::index_constant<i> id, int coupledPhaseIdx = 0)
92 { return IndexHelper::couplingPhaseIdx(id, coupledPhaseIdx); }
93
97 template<std::size_t i>
98 static constexpr auto couplingCompIdx(Dune::index_constant<i> id, int coupledCompIdx)
99 { return IndexHelper::couplingCompIdx(id, coupledCompIdx); }
100
107 template<class IpData, class Context>
108 static auto darcyPermeability(const ElementDiscretization<freeFlowMomentumIndex>& elemDisc,
109 const IpData& ipData,
110 const Context& context)
111 {
112 const auto& pmElemDisc = context.elemDisc;
113 return context.vars(pmElemDisc.scv(closestBoundaryScvIdx_(pmElemDisc, ipData.global()))).permeability();
114 }
115
122 template<class Context, class IpData>
123 static auto darcyVelocity(const Context& context, const IpData& ipData)
124 {
125 static_assert(!Concept::FVGridVariables<GridVariables<porousMediumIndex>>,
126 "The Darcy velocity requires the porous-medium model to use the general grid variables");
127
128 const auto pmPhaseIdx = couplingPhaseIdx(porousMediumIndex);
129 const auto& elemDisc = context.elemDisc;
130
131 // the coupling context provides the variables per local dof like the element variables,
132 // but holds no interpolation point cache, so the cache is evaluated here
133 typename Concept::GridVariablesCache_t<GridVariables<porousMediumIndex>>::InterpolationPointData ipCache;
134 ipCache.update(context.problem, elemDisc.element(), elemDisc, context, ipData);
135
136 const auto mobilityTensor = [&](const auto& pmElemDisc, const auto& pmElemVars, const auto& pmIpData)
137 {
138 const auto vars = pmElemVars[pmElemDisc.scv(closestBoundaryScvIdx_(pmElemDisc, pmIpData.global()))];
139 auto tensor = vars.permeability();
140 tensor /= vars.viscosity(pmPhaseIdx);
141 return tensor;
142 };
143
144 return AdvectionType<porousMediumIndex>::fluxTerm(context.problem, elemDisc.element(), elemDisc,
145 context, pmPhaseIdx, ipData, ipCache, mobilityTensor);
146 }
147
151 template<class ElementDiscretization, class ContextOrElementVars, class IpData>
152 static Scalar density(const ElementDiscretization& elemDisc,
153 const ContextOrElementVars& vars,
154 const IpData& ipData)
155 {
156 const auto pmPhaseIdx = couplingPhaseIdx(porousMediumIndex);
157
158 const auto& localBasis = elemDisc.feLocalBasis();
159
160 std::vector<Dune::FieldVector<Scalar, 1>> shapeValues;
161 localBasis.evaluateFunction(ipData.local(), shapeValues);
162
163 // interpolate density
164 Scalar density(0.0);
165 for (const auto& localDof : localDofs(elemDisc))
166 density += vars[localDof].density(pmPhaseIdx)*shapeValues[localDof.index()][0];
167
168 return density;
169 }
170
174 template<class ElementDiscretization, class ContextOrElementVars, class IpData>
175 static Scalar pressure(const ElementDiscretization& elemDisc,
176 const ContextOrElementVars& vars,
177 const IpData& ipData)
178 {
179 const auto pmPhaseIdx = couplingPhaseIdx(porousMediumIndex);
180
181 const auto& localBasis = elemDisc.feLocalBasis();
182
183 std::vector<Dune::FieldVector<Scalar, 1>> shapeValues;
184 localBasis.evaluateFunction(ipData.local(), shapeValues);
185
186 // interpolate pressure
187 Scalar pressure(0.0);
188 for (const auto& localDof : localDofs(elemDisc))
189 pressure += vars[localDof].pressure(pmPhaseIdx)*shapeValues[localDof.index()][0];
190
191 return pressure;
192 }
193
196 */
197 static Scalar advectiveFlux(const Scalar insideQuantity, const Scalar outsideQuantity, const Scalar volumeFlow, bool insideIsUpstream)
198 { return (insideIsUpstream ? insideQuantity : outsideQuantity) * volumeFlow; }
199
200private:
202 template<class PMElementDiscretization>
203 static std::size_t closestBoundaryScvIdx_(const PMElementDiscretization& elemDisc,
204 const GlobalPosition<porousMediumIndex>& pos)
205 {
206 Scalar minDistance = 0.0;
207 std::size_t closestScvfIdx = 0;
208 bool foundClosestScvf = false;
209
210 for (const auto& scvf : scvfs(elemDisc))
211 {
212 if (!scvf.boundary())
213 continue;
214
215 const auto distance = (scvf.ipGlobal() - pos).two_norm();
216 if (!foundClosestScvf || distance < minDistance)
217 {
218 minDistance = distance;
219 closestScvfIdx = scvf.index();
220 foundClosestScvf = true;
221 }
222 }
223
224 if (!foundClosestScvf)
225 DUNE_THROW(Dune::InvalidStateException, "Expected at least one boundary SCVF in porous-medium element discretization");
226
227 return elemDisc.scvf(closestScvfIdx).insideScvIdx();
228 }
229};
230
235template<class MDTraits, class CouplingManager, bool enableEnergyBalance>
236class FFPMCouplingConditionsCvfeImpl<MDTraits, CouplingManager, enableEnergyBalance, false>
237: public FFPMCouplingConditionsCvfeImplBase<MDTraits, CouplingManager>
238{
240
241 template<std::size_t id>
242 using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag;
243
244 static_assert(GetPropType<SubDomainTypeTag<ParentType::porousMediumIndex>, Properties::ModelTraits>::numFluidComponents() == GetPropType<SubDomainTypeTag<ParentType::porousMediumIndex>, Properties::ModelTraits>::numFluidPhases(),
245 "Darcy Model must not be compositional");
246
247 static_assert(!enableEnergyBalance, "Non-isothermal coupling is not implemented for control-volume finite element schemes");
248
249public:
250 using ParentType::ParentType;
252};
253
254} // end namespace Dumux
255
256#endif
The interface of the coupling manager for multi domain problems.
Definition multidomain/couplingmanager.hh:37
A base class which provides some common methods used for Stokes-Darcy coupling.
Definition couplingconditions_cvfe_cvfe.hh:56
static constexpr auto freeFlowMassIndex
Definition couplingconditions_cvfe_cvfe.hh:70
static constexpr auto freeFlowMomentumIndex
Definition couplingconditions_cvfe_cvfe.hh:69
static constexpr auto couplingCompIdx(Dune::index_constant< i > id, int coupledCompIdx)
Returns the corresponding component index needed for coupling.
Definition couplingconditions_cvfe_cvfe.hh:97
static constexpr auto porousMediumIndex
Definition couplingconditions_cvfe_cvfe.hh:71
static Scalar density(const ElementDiscretization &elemDisc, const ContextOrElementVars &vars, const IpData &ipData)
Returns the porous medium density at a given interpolation point.
Definition couplingconditions_cvfe_cvfe.hh:151
static Scalar advectiveFlux(const Scalar insideQuantity, const Scalar outsideQuantity, const Scalar volumeFlow, bool insideIsUpstream)
Evaluate an advective flux across the interface with full upwinding.
Definition couplingconditions_cvfe_cvfe.hh:196
static constexpr auto couplingPhaseIdx(Dune::index_constant< i > id, int coupledPhaseIdx=0)
Returns the corresponding phase index needed for coupling.
Definition couplingconditions_cvfe_cvfe.hh:90
static Scalar pressure(const ElementDiscretization &elemDisc, const ContextOrElementVars &vars, const IpData &ipData)
Returns the porous medium pressure at a given interpolation point.
Definition couplingconditions_cvfe_cvfe.hh:174
static auto darcyVelocity(const Context &context, const IpData &ipData)
Returns the Darcy velocity at an interpolation point of the coupled Darcy element.
Definition couplingconditions_cvfe_cvfe.hh:122
static auto darcyPermeability(const ElementDiscretization< freeFlowMomentumIndex > &elemDisc, const IpData &ipData, const Context &context)
Returns the intrinsic permeability of the coupled Darcy element.
Definition couplingconditions_cvfe_cvfe.hh:107
Definition couplingconditions_cvfe_cvfe.hh:33
Defines all properties used in Dumux.
FFPMCouplingConditionsCvfeImpl< MDTraits, CouplingManager, GetPropType< typename MDTraits::template SubDomain< 0 >::TypeTag, Properties::ModelTraits >::enableEnergyBalance(),(GetPropType< typename MDTraits::template SubDomain< 0 >::TypeTag, Properties::ModelTraits >::numFluidComponents() > 1) > FFPMCouplingConditionsCvfe
Coupling conditions for a Darcy model and a (Navier-)Stokes model, both discretized with control-volu...
Definition couplingconditions_cvfe_cvfe.hh:44
static ctype distance(const Dune::FieldVector< ctype, dimWorld > &a, const Dune::FieldVector< ctype, dimWorld > &b)
Compute the shortest distance between two points.
Definition distance.hh:302
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition propertysystem.hh:296
Index helpers for the free-flow/porous-medium-flow coupling.
Class representing dofs on elements for control-volume finite element schemes.
Define some often used mathematical functions.
Traits for the free-flow/porous-medium-flow coupling.
Definition adapt.hh:17
auto localDofs(const FVElementGeometry &fvGeometry)
range over local dofs
Definition localdof.hh:50
Helper struct to choose the correct index for phases and components. This is need if the porous-mediu...
Definition indexhelper.hh:30
This structs helps to check if the two sub models use the same fluidsystem. Specialization for the ca...
Definition multidomain/boundary/freeflowporousmedium/traits.hh:30