vtkmultiphasemodule.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  Copyright (C) 2011-2013 by Andreas Lauser
5 
6  This file is part of the Open Porous Media project (OPM).
7 
8  OPM is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 2 of the License, or
11  (at your option) any later version.
12 
13  OPM is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with OPM. If not, see <http://www.gnu.org/licenses/>.
20 */
25 #ifndef EWOMS_VTK_MULTI_PHASE_MODULE_HH
26 #define EWOMS_VTK_MULTI_PHASE_MODULE_HH
27 
28 #include "vtkmultiwriter.hh"
29 #include "baseoutputmodule.hh"
30 
33 
34 #include <opm/material/common/MathToolbox.hpp>
35 
36 #include <dune/common/fvector.hh>
37 
38 #include <cstdio>
39 
40 namespace Ewoms {
41 namespace Properties {
42 // create new type tag for the VTK multi-phase output
43 NEW_TYPE_TAG(VtkMultiPhase);
44 
45 // create the property tags needed for the multi phase module
46 NEW_PROP_TAG(VtkWritePressures);
47 NEW_PROP_TAG(VtkWriteDensities);
48 NEW_PROP_TAG(VtkWriteSaturations);
49 NEW_PROP_TAG(VtkWriteMobilities);
50 NEW_PROP_TAG(VtkWriteRelativePermeabilities);
51 NEW_PROP_TAG(VtkWriteViscosities);
52 NEW_PROP_TAG(VtkWriteAverageMolarMasses);
53 NEW_PROP_TAG(VtkWritePorosity);
54 NEW_PROP_TAG(VtkWriteIntrinsicPermeabilities);
55 NEW_PROP_TAG(VtkWritePotentialGradients);
56 NEW_PROP_TAG(VtkWriteFilterVelocities);
57 NEW_PROP_TAG(VtkOutputFormat);
58 NEW_PROP_TAG(Evaluation);
59 
60 // set default values for what quantities to output
61 SET_BOOL_PROP(VtkMultiPhase, VtkWritePressures, true);
62 SET_BOOL_PROP(VtkMultiPhase, VtkWriteDensities, true);
63 SET_BOOL_PROP(VtkMultiPhase, VtkWriteSaturations, true);
64 SET_BOOL_PROP(VtkMultiPhase, VtkWriteMobilities, false);
65 SET_BOOL_PROP(VtkMultiPhase, VtkWriteRelativePermeabilities, true);
66 SET_BOOL_PROP(VtkMultiPhase, VtkWriteViscosities, false);
67 SET_BOOL_PROP(VtkMultiPhase, VtkWriteAverageMolarMasses, false);
68 SET_BOOL_PROP(VtkMultiPhase, VtkWritePorosity, true);
69 SET_BOOL_PROP(VtkMultiPhase, VtkWriteIntrinsicPermeabilities, false);
70 SET_BOOL_PROP(VtkMultiPhase, VtkWritePotentialGradients, false);
71 SET_BOOL_PROP(VtkMultiPhase, VtkWriteFilterVelocities, false);
72 } // namespace Properties
73 
92 template<class TypeTag>
93 class VtkMultiPhaseModule : public BaseOutputModule<TypeTag>
94 {
96 
97  typedef typename GET_PROP_TYPE(TypeTag, Simulator) Simulator;
98  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
99  typedef typename GET_PROP_TYPE(TypeTag, Evaluation) Evaluation;
100  typedef typename GET_PROP_TYPE(TypeTag, ElementContext) ElementContext;
101 
102  typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
103  typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
104  typedef typename GET_PROP_TYPE(TypeTag, DiscBaseOutputModule) DiscBaseOutputModule;
105 
106  static const int vtkFormat = GET_PROP_VALUE(TypeTag, VtkOutputFormat);
108 
109  typedef Opm::MathToolbox<Evaluation> Toolbox;
110 
111  enum { dimWorld = GridView::dimensionworld };
112  enum { numPhases = GET_PROP_VALUE(TypeTag, NumPhases) };
113 
114  typedef typename ParentType::ScalarBuffer ScalarBuffer;
115  typedef typename ParentType::VectorBuffer VectorBuffer;
116  typedef typename ParentType::TensorBuffer TensorBuffer;
117  typedef typename ParentType::PhaseBuffer PhaseBuffer;
118 
119  typedef Dune::FieldVector<Scalar, dimWorld> DimVector;
120 
121  typedef std::array<VectorBuffer, numPhases> PhaseVectorBuffer;
122 
123 public:
124  VtkMultiPhaseModule(const Simulator &simulator)
125  : ParentType(simulator)
126  {}
127 
131  static void registerParameters()
132  {
133  EWOMS_REGISTER_PARAM(TypeTag, bool, VtkWritePressures,
134  "Include the phase pressures in the VTK output files");
135  EWOMS_REGISTER_PARAM(TypeTag, bool, VtkWriteDensities,
136  "Include the phase densities in the VTK output files");
137  EWOMS_REGISTER_PARAM(TypeTag, bool, VtkWriteSaturations,
138  "Include the phase saturations in the VTK output files");
139  EWOMS_REGISTER_PARAM(TypeTag, bool, VtkWriteMobilities,
140  "Include the phase mobilities in the VTK output files");
141  EWOMS_REGISTER_PARAM(TypeTag, bool, VtkWriteRelativePermeabilities,
142  "Include the phase relative permeabilities in the VTK output files");
143  EWOMS_REGISTER_PARAM(TypeTag, bool, VtkWriteViscosities,
144  "Include component phase viscosities in the VTK output files");
145  EWOMS_REGISTER_PARAM(TypeTag, bool, VtkWriteAverageMolarMasses,
146  "Include the average phase mass in the VTK output files");
147  EWOMS_REGISTER_PARAM(TypeTag, bool, VtkWritePorosity,
148  "Include the porosity in the VTK output files");
149  EWOMS_REGISTER_PARAM(TypeTag, bool, VtkWriteIntrinsicPermeabilities,
150  "Include the intrinsic permeability in the VTK output files");
151  EWOMS_REGISTER_PARAM(TypeTag, bool, VtkWriteFilterVelocities,
152  "Include in the filter velocities of the phases the VTK output files");
153  EWOMS_REGISTER_PARAM(TypeTag, bool, VtkWritePotentialGradients,
154  "Include the phase pressure potential gradients in the VTK output files");
155  }
156 
162  {
163  if (pressureOutput_()) this->resizePhaseBuffer_(pressure_);
164  if (densityOutput_()) this->resizePhaseBuffer_(density_);
165  if (saturationOutput_()) this->resizePhaseBuffer_(saturation_);
166  if (mobilityOutput_()) this->resizePhaseBuffer_(mobility_);
167  if (relativePermeabilityOutput_()) this->resizePhaseBuffer_(relativePermeability_);
168  if (viscosityOutput_()) this->resizePhaseBuffer_(viscosity_);
169  if (averageMolarMassOutput_()) this->resizePhaseBuffer_(averageMolarMass_);
170 
171  if (porosityOutput_()) this->resizeScalarBuffer_(porosity_);
172  if (intrinsicPermeabilityOutput_()) this->resizeTensorBuffer_(intrinsicPermeability_);
173 
174  if (velocityOutput_()) {
175  Scalar nDof = this->simulator_.model().numGridDof();
176  for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
177  velocity_[phaseIdx].resize(nDof);
178  for (int dofIdx = 0; dofIdx < nDof; ++ dofIdx) {
179  velocity_[phaseIdx][dofIdx].resize(dimWorld);
180  velocity_[phaseIdx][dofIdx] = 0.0;
181  }
182  }
183  this->resizePhaseBuffer_(velocityWeight_);
184  }
185 
186  if (potentialGradientOutput_()) {
187  Scalar nDof = this->simulator_.model().numGridDof();
188  for (int phaseIdx = 0; phaseIdx < numPhases; ++ phaseIdx) {
189  potentialGradient_[phaseIdx].resize(nDof);
190  for (int dofIdx = 0; dofIdx < nDof; ++ dofIdx) {
191  potentialGradient_[phaseIdx][dofIdx].resize(dimWorld);
192  potentialGradient_[phaseIdx][dofIdx] = 0.0;
193  }
194  }
195 
196  this->resizePhaseBuffer_(potentialWeight_);
197  }
198  }
199 
204  void processElement(const ElementContext &elemCtx)
205  {
206  typedef Opm::MathToolbox<Evaluation> Toolbox;
207 
208  for (int i = 0; i < elemCtx.numPrimaryDof(/*timeIdx=*/0); ++i) {
209  int I = elemCtx.globalSpaceIndex(i, /*timeIdx=*/0);
210  const auto &intQuants = elemCtx.intensiveQuantities(i, /*timeIdx=*/0);
211  const auto &fs = intQuants.fluidState();
212 
213  if (porosityOutput_()) porosity_[I] = Toolbox::value(intQuants.porosity());
214  if (intrinsicPermeabilityOutput_()) {
215  const auto& K = intQuants.intrinsicPermeability();
216  intrinsicPermeability_[I].resize(K.rows, K.cols);
217  for (int rowIdx = 0; rowIdx < K.rows; ++rowIdx)
218  for (int colIdx = 0; colIdx < K.cols; ++colIdx)
219  intrinsicPermeability_[I][rowIdx][colIdx] = K[rowIdx][colIdx];
220  }
221 
222  for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
223  if (pressureOutput_())
224  pressure_[phaseIdx][I] = Toolbox::value(fs.pressure(phaseIdx));
225  if (densityOutput_())
226  density_[phaseIdx][I] = Toolbox::value(fs.density(phaseIdx));
227  if (saturationOutput_())
228  saturation_[phaseIdx][I] = Toolbox::value(fs.saturation(phaseIdx));
229  if (mobilityOutput_())
230  mobility_[phaseIdx][I] = Toolbox::value(intQuants.mobility(phaseIdx));
231  if (relativePermeabilityOutput_())
232  relativePermeability_[phaseIdx][I] = Toolbox::value(intQuants.relativePermeability(phaseIdx));
233  if (viscosityOutput_())
234  viscosity_[phaseIdx][I] = Toolbox::value(fs.viscosity(phaseIdx));
235  if (averageMolarMassOutput_())
236  averageMolarMass_[phaseIdx][I] = Toolbox::value(fs.averageMolarMass(phaseIdx));
237  }
238  }
239 
240  if (potentialGradientOutput_()) {
241  // calculate velocities if requested
242  for (int faceIdx = 0; faceIdx < elemCtx.numInteriorFaces(/*timeIdx=*/0); ++ faceIdx) {
243  const auto &extQuants = elemCtx.extensiveQuantities(faceIdx, /*timeIdx=*/0);
244 
245  int i = extQuants.interiorIndex();
246  int I = elemCtx.globalSpaceIndex(i, /*timeIdx=*/0);
247 
248  for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
249  Scalar weight = extQuants.extrusionFactor();
250 
251  potentialWeight_[phaseIdx][I] += weight;
252 
253  const auto &inputPGrad = extQuants.potentialGrad(phaseIdx);
254  DimVector pGrad;
255  for (int j = 0; j < numPhases; ++j)
256  pGrad[j] = Toolbox::value(inputPGrad[j])*weight;
257  potentialGradient_[phaseIdx][I] += pGrad;
258  } // end for all phases
259  } // end for all faces
260  }
261 
262  if (velocityOutput_()) {
263  // calculate velocities if requested
264  for (int faceIdx = 0; faceIdx < elemCtx.numInteriorFaces(/*timeIdx=*/0); ++ faceIdx) {
265  const auto &extQuants = elemCtx.extensiveQuantities(faceIdx, /*timeIdx=*/0);
266 
267  int i = extQuants.interiorIndex();
268  int I = elemCtx.globalSpaceIndex(i, /*timeIdx=*/0);
269 
270  int j = extQuants.exteriorIndex();
271  int J = elemCtx.globalSpaceIndex(j, /*timeIdx=*/0);
272 
273  for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
274  Scalar weight = std::max<Scalar>(1e-16,
275  std::abs(Toolbox::value(extQuants.volumeFlux(phaseIdx))));
276  Valgrind::CheckDefined(extQuants.extrusionFactor());
277  assert(extQuants.extrusionFactor() > 0);
278  weight *= extQuants.extrusionFactor();
279 
280  const auto& inputV = extQuants.filterVelocity(phaseIdx);
281  DimVector v;
282  for (int k = 0; k < dimWorld; ++k)
283  v[k] = Toolbox::value(inputV[k]);
284  if (v.two_norm() > 1e-20)
285  weight /= v.two_norm();
286  v *= weight;
287 
288  velocity_[phaseIdx][I] += v;
289  velocity_[phaseIdx][J] += v;
290 
291  velocityWeight_[phaseIdx][I] += weight;
292  velocityWeight_[phaseIdx][J] += weight;
293  } // end for all phases
294  } // end for all faces
295  }
296  }
297 
301  void commitBuffers(BaseOutputWriter &baseWriter)
302  {
303  VtkMultiWriter *vtkWriter = dynamic_cast<VtkMultiWriter*>(&baseWriter);
304  if (!vtkWriter)
305  return;
306 
307  if (pressureOutput_())
308  this->commitPhaseBuffer_(baseWriter, "pressure_%s", pressure_);
309  if (densityOutput_())
310  this->commitPhaseBuffer_(baseWriter, "density_%s", density_);
311  if (saturationOutput_())
312  this->commitPhaseBuffer_(baseWriter, "saturation_%s", saturation_);
313  if (mobilityOutput_())
314  this->commitPhaseBuffer_(baseWriter, "mobility_%s", mobility_);
315  if (relativePermeabilityOutput_())
316  this->commitPhaseBuffer_(baseWriter, "relativePerm_%s", relativePermeability_);
317  if (viscosityOutput_())
318  this->commitPhaseBuffer_(baseWriter, "viscosity_%s", viscosity_);
319  if (averageMolarMassOutput_())
320  this->commitPhaseBuffer_(baseWriter, "averageMolarMass_%s", averageMolarMass_);
321 
322  if (porosityOutput_())
323  this->commitScalarBuffer_(baseWriter, "porosity", porosity_);
324  if (intrinsicPermeabilityOutput_())
325  this->commitTensorBuffer_(baseWriter, "intrinsicPerm", intrinsicPermeability_);
326 
327  if (velocityOutput_()) {
328  int nDof = this->simulator_.model().numGridDof();
329 
330  for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
331  // first, divide the velocity field by the
332  // respective finite volume's surface area
333  for (int i = 0; i < nDof; ++i)
334  velocity_[phaseIdx][i] /= velocityWeight_[phaseIdx][i];
335  // commit the phase velocity
336  char name[512];
337  snprintf(name, 512, "filterVelocity_%s", FluidSystem::phaseName(phaseIdx));
338 
339  DiscBaseOutputModule::attachVectorDofData_(baseWriter, velocity_[phaseIdx], name);
340  }
341  }
342 
343  if (potentialGradientOutput_()) {
344  int nDof = this->simulator_.model().numGridDof();
345 
346  for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
347  // first, divide the velocity field by the
348  // respective finite volume's surface area
349  for (int i = 0; i < nDof; ++i)
350  potentialGradient_[phaseIdx][i] /= potentialWeight_[phaseIdx][i];
351  // commit the phase velocity
352  char name[512];
353  snprintf(name, 512, "gradP_%s", FluidSystem::phaseName(phaseIdx));
354 
355  DiscBaseOutputModule::attachVectorDofData_(baseWriter,
356  potentialGradient_[phaseIdx],
357  name);
358  }
359  }
360  }
361 
362 private:
363  static bool pressureOutput_()
364  { return EWOMS_GET_PARAM(TypeTag, bool, VtkWritePressures); }
365 
366  static bool densityOutput_()
367  { return EWOMS_GET_PARAM(TypeTag, bool, VtkWriteDensities); }
368 
369  static bool saturationOutput_()
370  { return EWOMS_GET_PARAM(TypeTag, bool, VtkWriteSaturations); }
371 
372  static bool mobilityOutput_()
373  { return EWOMS_GET_PARAM(TypeTag, bool, VtkWriteMobilities); }
374 
375  static bool relativePermeabilityOutput_()
376  { return EWOMS_GET_PARAM(TypeTag, bool, VtkWriteRelativePermeabilities); }
377 
378  static bool viscosityOutput_()
379  { return EWOMS_GET_PARAM(TypeTag, bool, VtkWriteViscosities); }
380 
381  static bool averageMolarMassOutput_()
382  { return EWOMS_GET_PARAM(TypeTag, bool, VtkWriteAverageMolarMasses); }
383 
384  static bool porosityOutput_()
385  { return EWOMS_GET_PARAM(TypeTag, bool, VtkWritePorosity); }
386 
387  static bool intrinsicPermeabilityOutput_()
388  { return EWOMS_GET_PARAM(TypeTag, bool, VtkWriteIntrinsicPermeabilities); }
389 
390  static bool velocityOutput_()
391  { return EWOMS_GET_PARAM(TypeTag, bool, VtkWriteFilterVelocities); }
392 
393  static bool potentialGradientOutput_()
394  { return EWOMS_GET_PARAM(TypeTag, bool, VtkWritePotentialGradients); }
395 
396  PhaseBuffer pressure_;
397  PhaseBuffer density_;
398  PhaseBuffer saturation_;
399  PhaseBuffer mobility_;
400  PhaseBuffer relativePermeability_;
401  PhaseBuffer viscosity_;
402  PhaseBuffer averageMolarMass_;
403 
404  ScalarBuffer porosity_;
405  TensorBuffer intrinsicPermeability_;
406 
407  PhaseVectorBuffer velocity_;
408  PhaseBuffer velocityWeight_;
409 
410  PhaseVectorBuffer potentialGradient_;
411  PhaseBuffer potentialWeight_;
412 };
413 
414 } // namespace Ewoms
415 
416 #endif
void commitTensorBuffer_(BaseOutputWriter &baseWriter, const char *name, TensorBuffer &buffer, BufferType bufferType=DofBuffer)
Add a buffer containing tensorial quantities to the result file.
Definition: baseoutputmodule.hh:319
static void registerParameters()
Register all run-time parameters for the multi-phase VTK output module.
Definition: vtkmultiphasemodule.hh:131
void processElement(const ElementContext &elemCtx)
Modify the internal buffers according to the intensive quantities seen on an element.
Definition: vtkmultiphasemodule.hh:204
void resizeTensorBuffer_(TensorBuffer &buffer, BufferType bufferType=DofBuffer)
Allocate the space for a buffer storing a tensorial quantity.
Definition: baseoutputmodule.hh:168
void resizeScalarBuffer_(ScalarBuffer &buffer, BufferType bufferType=DofBuffer)
Allocate the space for a buffer storing a scalar quantity.
Definition: baseoutputmodule.hh:148
void resizePhaseBuffer_(PhaseBuffer &buffer, BufferType bufferType=DofBuffer)
Allocate the space for a buffer storing a phase-specific quantity.
Definition: baseoutputmodule.hh:213
VtkMultiPhaseModule(const Simulator &simulator)
Definition: vtkmultiphasemodule.hh:124
#define GET_PROP_VALUE(TypeTag, PropTagName)
Access the value attribute of a property for a type tag.
Definition: propertysystem.hh:468
BaseOutputWriter::TensorBuffer TensorBuffer
Definition: baseoutputmodule.hh:92
void commitBuffers(BaseOutputWriter &baseWriter)
Add all buffers to the VTK output writer.
Definition: vtkmultiphasemodule.hh:301
std::array< VectorBuffer, numPhases > PhaseVectorBuffer
Definition: baseoutputmodule.hh:99
VTK output module for quantities which make sense for all models which deal with multiple fluid phase...
Definition: vtkmultiphasemodule.hh:93
NEW_PROP_TAG(Grid)
The type of the DUNE grid.
This file provides the infrastructure to retrieve run-time parameters.
The base class for all output writers.
Definition: baseoutputwriter.hh:41
Simplifies writing multi-file VTK datasets.
BaseOutputWriter::VectorBuffer VectorBuffer
Definition: baseoutputmodule.hh:91
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:73
Definition: baseauxiliarymodule.hh:35
#define EWOMS_REGISTER_PARAM(TypeTag, ParamType, ParamName, Description)
Register a run-time parameter.
Definition: parametersystem.hh:64
Model & model()
Return the physical model used in the simulation.
Definition: simulator.hh:176
std::array< ScalarBuffer, numPhases > PhaseBuffer
Definition: baseoutputmodule.hh:95
void commitScalarBuffer_(BaseOutputWriter &baseWriter, const char *name, ScalarBuffer &buffer, BufferType bufferType=DofBuffer)
Add a buffer containing scalar quantities to the result file.
Definition: baseoutputmodule.hh:283
NEW_TYPE_TAG(AuxModule)
Provides the magic behind the eWoms property system.
The base class for writer modules.
void commitPhaseBuffer_(BaseOutputWriter &baseWriter, const char *pattern, PhaseBuffer &buffer, BufferType bufferType=DofBuffer)
Add a phase-specific buffer to the result file.
Definition: baseoutputmodule.hh:386
SET_BOOL_PROP(FvBaseDiscretization, EnableVtkOutput, true)
Enable the VTK output by default.
The base class for writer modules.
Definition: baseoutputmodule.hh:71
const Simulator & simulator_
Definition: baseoutputmodule.hh:487
Simplifies writing multi-file VTK datasets.
Definition: vtkmultiwriter.hh:61
#define EWOMS_GET_PARAM(TypeTag, ParamType, ParamName)
Retrieve a runtime parameter.
Definition: parametersystem.hh:95
void allocBuffers()
Allocate memory for the scalar fields we would like to write to the VTK file.
Definition: vtkmultiphasemodule.hh:161
BaseOutputWriter::ScalarBuffer ScalarBuffer
Definition: baseoutputmodule.hh:90