3.3.0
DUNE for Multi-{Phase, Component, Scale, Physics, ...} flow and transport in porous media
operatoradaptive.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 * See the file COPYING for full copying permissions. *
5 * *
6 * This program is free software: you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation, either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18*****************************************************************************/
24#ifndef DUMUX_MIMETICOPERATOR2PADAPTIVE_HH
25#define DUMUX_MIMETICOPERATOR2PADAPTIVE_HH
26
27#include "croperatoradaptive.hh"
30
32
33namespace Dumux {
34
45template<class TypeTag>
47{
49
53
54 enum
55 {
56 dim=GridView::dimension,
57 dimWorld=GridView::dimensionworld
58 };
60
61 using Element = typename GridView::template Codim<0>::Entity;
62
68 using PrimaryVariables = typename SolutionTypes::PrimaryVariables;
69
71
72 enum
73 {
74 pw = Indices::pressureW,
75 pn = Indices::pressureNw,
76 pressureType = getPropValue<TypeTag, Properties::PressureFormulation>(),
77 wPhaseIdx = Indices::wPhaseIdx,
78 nPhaseIdx = Indices::nPhaseIdx,
79 saturationIdx = Indices::saturationIdx,
80 satEqIdx = Indices::satEqIdx
81 };
82
83 using FieldVector = Dune::FieldVector<Scalar, dimWorld>;
84public:
85
86 MimeticOperatorAssemblerTwoPAdaptive (const GridView& gridView)
87 : ParentType(gridView)
88 {}
89
90 // TODO doc me!
91 template<class Vector>
92 void calculatePressure(LocalStiffness& loc, Vector& u, Problem& problem)
93 {
94 Dune::DynamicVector<Scalar> velocityW(2*dim);
95 Dune::DynamicVector<Scalar> velocityNw(2*dim);
96 Dune::DynamicVector<Scalar> pressTraceW(2*dim);
97 Dune::DynamicVector<Scalar> pressTraceNw(2*dim);
98
99 const auto firstElement = *problem.gridView().template begin<0>();
100 FluidState fluidState;
101 fluidState.setPressure(wPhaseIdx, problem.referencePressure(firstElement));
102 fluidState.setPressure(nPhaseIdx, problem.referencePressure(firstElement));
103 fluidState.setTemperature(problem.temperature(firstElement));
104 fluidState.setSaturation(wPhaseIdx, 1.);
105 fluidState.setSaturation(nPhaseIdx, 0.);
106 Scalar densityDiff = FluidSystem::density(fluidState, nPhaseIdx) - FluidSystem::density(fluidState, wPhaseIdx);
107 Scalar viscosityW = FluidSystem::viscosity(fluidState, wPhaseIdx);
108 Scalar viscosityNw = FluidSystem::viscosity(fluidState, nPhaseIdx);
109
110 // reset velocity
111 for (int i = 0; i < problem.gridView().size(0); i++)
112 {
113 problem.variables().cellData(i).fluxData().resetVelocity();
114 }
115
116 // run over all level elements
117 for (const auto& element : elements(this->gridView_))
118 {
119 int eIdxGlobal = problem.variables().index(element);
120
121 unsigned int numFaces = this->intersectionMapper_.size(eIdxGlobal);
122
123 // get local to global id map and pressure traces
124 velocityW.resize(numFaces);
125 velocityNw.resize(numFaces);
126 pressTraceW.resize(numFaces);
127 pressTraceNw.resize(numFaces);
128
129 CellData& cellData = problem.variables().cellData(eIdxGlobal);
130 FieldVector globalPos = element.geometry().center();
131
132 int intersectionIdx = -1;
133 // get local to global id map and pressure traces
134 for (const auto& intersection : intersections(problem.gridView(), element))
135 {
136 ++intersectionIdx;
137
138 int fIdxGlobal = this->intersectionMapper_.subIndex(element, intersectionIdx);
139
140 Scalar pcPotFace = (problem.bBoxMax() - intersection.geometry().center()) * problem.gravity() * densityDiff;
141
142 switch (pressureType)
143 {
144 case pw:
145 {
146 pressTraceW[intersectionIdx] = u[fIdxGlobal];
147 pressTraceNw[intersectionIdx] = u[fIdxGlobal] + pcPotFace;
148 break;
149 }
150 case pn:
151 {
152 pressTraceNw[intersectionIdx] = u[fIdxGlobal];
153 pressTraceW[intersectionIdx] = u[fIdxGlobal] - pcPotFace;
154
155 break;
156 }
157 }
158 }
159
160 switch (pressureType)
161 {
162 case pw:
163 {
164 Scalar potW = loc.constructPressure(element, pressTraceW);
165 Scalar gravPot = (problem.bBoxMax() - globalPos) * problem.gravity() * densityDiff;
166 Scalar potNw = potW + gravPot;
167
168 cellData.setPotential(wPhaseIdx, potW);
169 cellData.setPotential(nPhaseIdx, potNw);
170
171 gravPot = (problem.bBoxMax() - globalPos) * problem.gravity() * FluidSystem::density(fluidState, wPhaseIdx);
172
173 cellData.setPressure(wPhaseIdx, potW - gravPot);
174
175 gravPot = (problem.bBoxMax() - globalPos) * problem.gravity() * FluidSystem::density(fluidState, nPhaseIdx);
176
177 cellData.setPressure(nPhaseIdx, potNw - gravPot);
178
179 break;
180 }
181 case pn:
182 {
183 Scalar potNw = loc.constructPressure(element, pressTraceNw);
184 Scalar gravPot = (problem.bBoxMax() - globalPos) * problem.gravity() * densityDiff;
185 Scalar potW = potNw - gravPot;
186
187 cellData.setPotential(nPhaseIdx, potNw);
188 cellData.setPotential(wPhaseIdx, potW);
189
190 gravPot = (problem.bBoxMax() - globalPos) * problem.gravity() * FluidSystem::density(fluidState, wPhaseIdx);
191
192 cellData.setPressure(wPhaseIdx, potW - gravPot);
193
194 gravPot = (problem.bBoxMax() - globalPos) * problem.gravity() * FluidSystem::density(fluidState, nPhaseIdx);
195
196 cellData.setPressure(nPhaseIdx, potNw - gravPot);
197
198 break;
199 }
200 }
201
202 // velocity reconstruction: !!! The velocity which is not reconstructed from the primary
203 // pressure variable can be slightly wrong and not conservative!!!!
204 // -> Should not be used for transport!!
205 loc.constructVelocity(element, velocityW, pressTraceW, cellData.potential(wPhaseIdx));
206 loc.constructVelocity(element, velocityNw, pressTraceNw, cellData.potential(nPhaseIdx));
207
208 intersectionIdx = -1;
209 for (const auto& intersection : intersections(problem.gridView(), element))
210 {
211 ++intersectionIdx;
212 int idxInInside = intersection.indexInInside();
213
214 cellData.fluxData().addUpwindPotential(wPhaseIdx, idxInInside, velocityW[intersectionIdx]);
215 cellData.fluxData().addUpwindPotential(nPhaseIdx, idxInInside, velocityNw[intersectionIdx]);
216
217 Scalar mobilityW = 0;
218 Scalar mobilityNw = 0;
219
220 if (intersection.neighbor())
221 {
222 int neighborIdx = problem.variables().index(intersection.outside());
223
224 CellData& cellDataNeighbor = problem.variables().cellData(neighborIdx);
225
226 mobilityW =
227 (velocityW[intersectionIdx] >= 0.) ? cellData.mobility(wPhaseIdx) :
228 cellDataNeighbor.mobility(wPhaseIdx);
229 mobilityNw =
230 (velocityNw[intersectionIdx] >= 0.) ? cellData.mobility(nPhaseIdx) :
231 cellDataNeighbor.mobility(nPhaseIdx);
232
233 if (velocityW[intersectionIdx] >= 0.)
234 {
235 FieldVector velocity(intersection.centerUnitOuterNormal());
236 velocity *= mobilityW/(mobilityW+mobilityNw) * velocityW[intersectionIdx];
237 cellData.fluxData().addVelocity(wPhaseIdx, idxInInside, velocity);
238 cellDataNeighbor.fluxData().addVelocity(wPhaseIdx, intersection.indexInOutside(), velocity);
239 }
240 if (velocityNw[intersectionIdx] >= 0.)
241 {
242 FieldVector velocity(intersection.centerUnitOuterNormal());
243 velocity *= mobilityNw/(mobilityW+mobilityNw) * velocityNw[intersectionIdx];
244 cellData.fluxData().addVelocity(nPhaseIdx, idxInInside, velocity);
245 cellDataNeighbor.fluxData().addVelocity(nPhaseIdx, intersection.indexInOutside(), velocity);
246 }
247
248 cellData.fluxData().setVelocityMarker(idxInInside);
249 }
250 else
251 {
252 BoundaryTypes bctype;
253 problem.boundaryTypes(bctype, intersection);
254 if (bctype.isDirichlet(satEqIdx))
255 {
256 PrimaryVariables boundValues(0.0);
257 problem.dirichlet(boundValues, intersection);
258
259 // old material law interface is deprecated: Replace this by
260 // const auto& fluidMatrixInteraction = spatialParams.fluidMatrixInteractionAtPos(element.geometry().center());
261 // after the release of 3.3, when the deprecated interface is no longer supported
262 const auto fluidMatrixInteraction = Deprecated::makePcKrSw(Scalar{}, problem.spatialParams(), element);
263
264 if (velocityW[intersectionIdx] >= 0.)
265 {
266 mobilityW = cellData.mobility(wPhaseIdx);
267 }
268 else
269 {
270 mobilityW = fluidMatrixInteraction.krw(boundValues[saturationIdx]) / viscosityW;
271 }
272
273 if (velocityNw[intersectionIdx] >= 0.)
274 {
275 mobilityNw = cellData.mobility(nPhaseIdx);
276 }
277 else
278 {
279 mobilityNw = fluidMatrixInteraction.krn(boundValues[saturationIdx]) / viscosityNw;
280 }
281 }
282 else
283 {
284 mobilityW = cellData.mobility(wPhaseIdx);
285 mobilityNw = cellData.mobility(nPhaseIdx);
286 }
287
288 FieldVector velocity(intersection.centerUnitOuterNormal());
289 velocity *= mobilityW/(mobilityW+mobilityNw) * velocityW[intersectionIdx];
290 cellData.fluxData().addVelocity(wPhaseIdx, idxInInside, velocity);
291
292
293 velocity = intersection.centerUnitOuterNormal();
294 velocity *= mobilityNw/(mobilityW+mobilityNw) * velocityNw[intersectionIdx];
295 cellData.fluxData().addVelocity(nPhaseIdx, idxInInside, velocity);
296 cellData.fluxData().setVelocityMarker(idxInInside);
297 }
298 }
299 }
300 }
301};
302} // end namespace Dumux
303#endif
Helpers for deprecation.
Defines a class for Crozieux-Raviart piecewise linear finite element functions.
Definition: adapt.hh:29
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type GetProp
get the type of a property (equivalent to old macro GET_PROP(...))
Definition: propertysystem.hh:140
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:149
std::string viscosity(int phaseIdx) noexcept
I/O name of viscosity for multiphase systems.
Definition: name.hh:74
std::string density(int phaseIdx) noexcept
I/O name of density for multiphase systems.
Definition: name.hh:65
int subIndex(int elemIdx, int fIdx)
Map interface fIdx'th interface of element index to array index.
Definition: intersectionmapper.hh:236
unsigned int size() const
Definition: intersectionmapper.hh:292
Extends CROperatorBase by a generic methods to assemble global stiffness matrix from local stiffness ...
Definition: croperatoradaptive.hh:69
const GridView gridView_
Definition: croperatoradaptive.hh:163
IntersectionMapper intersectionMapper_
Definition: croperatoradaptive.hh:165
Levelwise assembler.
Definition: operatoradaptive.hh:47
void calculatePressure(LocalStiffness &loc, Vector &u, Problem &problem)
Definition: operatoradaptive.hh:92
MimeticOperatorAssemblerTwoPAdaptive(const GridView &gridView)
Definition: operatoradaptive.hh:86
Specifies the properties for immiscible 2p diffusion/pressure models.
Defines the basic properties required for a mimetic method.