183 const auto element = *problem_.gridView().template begin<0>();
184 FluidState fluidState;
185 fluidState.setPressure(wPhaseIdx, problem_.referencePressure(element));
186 fluidState.setPressure(nPhaseIdx, problem_.referencePressure(element));
187 fluidState.setTemperature(problem_.temperature(element));
188 fluidState.setSaturation(wPhaseIdx, 1.);
189 fluidState.setSaturation(nPhaseIdx, 0.);
190 density_[wPhaseIdx] = FluidSystem::density(fluidState, wPhaseIdx);
191 density_[nPhaseIdx] = FluidSystem::density(fluidState, nPhaseIdx);
192 viscosity_[wPhaseIdx] = FluidSystem::viscosity(fluidState, wPhaseIdx);
193 viscosity_[nPhaseIdx] = FluidSystem::viscosity(fluidState, nPhaseIdx);
197 pressTrace_.resize(problem_.gridView().size(1));
198 f_.resize(problem_.gridView().size(1));
199 lstiff_.initialize();
244 int size = problem_.gridView().size(0);
245 ScalarSolutionType *potential = writer.allocateManagedBuffer(size);
246 ScalarSolutionType *pressure = 0;
247 ScalarSolutionType *pressureSecond = 0;
248 ScalarSolutionType *potentialSecond = 0;
249 Dune::BlockVector < DimVector > *velocityWetting = 0;
250 Dune::BlockVector < DimVector > *velocityNonwetting = 0;
252 if (vtkOutputLevel_ > 0)
254 pressure = writer.allocateManagedBuffer(size);
255 pressureSecond = writer.allocateManagedBuffer(size);
256 potentialSecond = writer.allocateManagedBuffer(size);
257 velocityWetting = writer.template allocateManagedBuffer<Scalar, dim>(size);
258 velocityNonwetting = writer.template allocateManagedBuffer<Scalar, dim>(size);
262 for (
const auto& element : elements(problem_.gridView()))
264 int eIdxGlobal = problem_.variables().index(element);
265 CellData& cellData = problem_.variables().cellData(eIdxGlobal);
267 if (pressureType == pw)
269 (*potential)[eIdxGlobal] = cellData.potential(wPhaseIdx);
272 if (pressureType == pn)
274 (*potential)[eIdxGlobal] = cellData.potential(nPhaseIdx);
277 if (vtkOutputLevel_ > 0)
280 if (pressureType == pw)
282 (*pressure)[eIdxGlobal] = cellData.pressure(wPhaseIdx);
283 (*potentialSecond)[eIdxGlobal] = cellData.potential(nPhaseIdx);
284 (*pressureSecond)[eIdxGlobal] = cellData.pressure(nPhaseIdx);
287 if (pressureType == pn)
289 (*pressure)[eIdxGlobal] = cellData.pressure(nPhaseIdx);
290 (*potentialSecond)[eIdxGlobal] = cellData.potential(wPhaseIdx);
291 (*pressureSecond)[eIdxGlobal] = cellData.pressure(wPhaseIdx);
294 const typename Element::Geometry& geometry = element.geometry();
297 using ReferenceElements = Dune::ReferenceElements<Scalar, dim>;
298 const auto refElement = ReferenceElements::general(geometry.type());
300 const int numberOfFaces=refElement.size(1);
301 std::vector<Scalar> fluxW(numberOfFaces,0);
302 std::vector<Scalar> fluxNw(numberOfFaces,0);
305 for (
const auto& intersection : intersections(problem_.gridView(), element))
307 int isIndex = intersection.indexInInside();
309 fluxW[isIndex] += intersection.geometry().volume()
310 * (intersection.centerUnitOuterNormal() * cellData.fluxData().velocity(wPhaseIdx, isIndex));
311 fluxNw[isIndex] += intersection.geometry().volume()
312 * (intersection.centerUnitOuterNormal() * cellData.fluxData().velocity(nPhaseIdx, isIndex));
317 Dune::FieldVector<Scalar, dim> refVelocity;
319 if (refElement.type().isSimplex()) {
320 for (
int dimIdx = 0; dimIdx < dim; dimIdx++)
322 refVelocity[dimIdx] = -fluxW[dim - 1 - dimIdx];
323 for (
int fIdx = 0; fIdx < dim + 1; fIdx++)
325 refVelocity[dimIdx] += fluxW[fIdx]/(dim + 1);
330 else if (refElement.type().isCube()){
331 for (
int i = 0; i < dim; i++)
332 refVelocity[i] = 0.5 * (fluxW[2*i + 1] - fluxW[2*i]);
336 DUNE_THROW(Dune::NotImplemented,
"velocity output for prism/pyramid not implemented");
339 const DimVector& localPos = refElement.position(0, 0);
342 const JacobianTransposed jacobianT = geometry.jacobianTransposed(localPos);
345 DimVector elementVelocity(0);
346 jacobianT.umtv(refVelocity, elementVelocity);
347 elementVelocity /= geometry.integrationElement(localPos);
349 (*velocityWetting)[eIdxGlobal] = elementVelocity;
354 if (refElement.type().isSimplex()) {
355 for (
int dimIdx = 0; dimIdx < dim; dimIdx++)
357 refVelocity[dimIdx] = -fluxNw[dim - 1 - dimIdx];
358 for (
int fIdx = 0; fIdx < dim + 1; fIdx++)
360 refVelocity[dimIdx] += fluxNw[fIdx]/(dim + 1);
365 else if (refElement.type().isCube()){
366 for (
int i = 0; i < dim; i++)
367 refVelocity[i] = 0.5 * (fluxNw[2*i + 1] - fluxNw[2*i]);
371 DUNE_THROW(Dune::NotImplemented,
"velocity output for prism/pyramid not implemented");
376 jacobianT.umtv(refVelocity, elementVelocity);
377 elementVelocity /= geometry.integrationElement(localPos);
379 (*velocityNonwetting)[eIdxGlobal] = elementVelocity;
383 if (pressureType == pw)
385 writer.attachCellData(*potential,
"wetting potential");
388 if (pressureType == pn)
390 writer.attachCellData(*potential,
"nonwetting potential");
393 if (vtkOutputLevel_ > 0)
395 if (pressureType == pw)
397 writer.attachCellData(*pressure,
"wetting pressure");
398 writer.attachCellData(*pressureSecond,
"nonwetting pressure");
399 writer.attachCellData(*potentialSecond,
"nonwetting potential");
402 if (pressureType == pn)
404 writer.attachCellData(*pressure,
"nonwetting pressure");
405 writer.attachCellData(*pressureSecond,
"wetting pressure");
406 writer.attachCellData(*potentialSecond,
"wetting potential");
409 writer.attachCellData(*velocityWetting,
"wetting-velocity", dim);
410 writer.attachCellData(*velocityNonwetting,
"non-wetting-velocity", dim);