discretefractureintensivequantities.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) 2009-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 */
26 #ifndef EWOMS_DISCRETE_FRACTURE_INTENSIVE_QUANTITIES_HH
27 #define EWOMS_DISCRETE_FRACTURE_INTENSIVE_QUANTITIES_HH
28 
30 
32 
33 namespace Ewoms {
34 
43 template <class TypeTag>
45 {
47  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
48  typedef typename GET_PROP_TYPE(TypeTag, MaterialLaw) MaterialLaw;
49  typedef typename GET_PROP_TYPE(TypeTag, ElementContext) ElementContext;
50  typedef typename GET_PROP_TYPE(TypeTag, FluidSystem) FluidSystem;
51  typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
52 
53  enum { numPhases = FluidSystem::numPhases };
54  enum { dimWorld = GridView::dimensionworld };
55 
56  static_assert(dimWorld == 2, "The fracture module currently is only "
57  "implemented for the 2D case!");
58  static_assert(numPhases == 2, "The fracture module currently is only "
59  "implemented for two fluid phases!");
60 
61  enum { enableEnergy = GET_PROP_VALUE(TypeTag, EnableEnergy) };
62  enum { wettingPhaseIdx = MaterialLaw::wettingPhaseIdx };
63  enum { nonWettingPhaseIdx = MaterialLaw::nonWettingPhaseIdx };
64  typedef Dune::FieldMatrix<Scalar, dimWorld, dimWorld> DimMatrix;
65  typedef Opm::ImmiscibleFluidState<Scalar, FluidSystem,
66  /*storeEnthalpy=*/enableEnergy> FluidState;
67 
68 public:
72  void update(const ElementContext &elemCtx, int vertexIdx, int timeIdx)
73  {
74  ParentType::update(elemCtx, vertexIdx, timeIdx);
75 
76  const auto &problem = elemCtx.problem();
77  const auto &fractureMapper = problem.fractureMapper();
78  int globalVertexIdx = elemCtx.globalSpaceIndex(vertexIdx, timeIdx);
79 
80  Valgrind::SetUndefined(fractureFluidState_);
81  Valgrind::SetUndefined(fractureVolume_);
82  Valgrind::SetUndefined(fracturePorosity_);
83  Valgrind::SetUndefined(fractureIntrinsicPermeability_);
84  Valgrind::SetUndefined(fractureRelativePermeabilities_);
85 
86  // do nothing if there is no fracture within the current degree of freedom
87  if (!fractureMapper.isFractureVertex(globalVertexIdx)) {
88  fractureVolume_ = 0;
89  return;
90  }
91 
92  // Make sure that the wetting saturation in the matrix fluid
93  // state does not get larger than 1
94  Scalar SwMatrix = std::min(1.0, this->fluidState_.saturation(wettingPhaseIdx));
95  this->fluidState_.setSaturation(wettingPhaseIdx, SwMatrix);
96  this->fluidState_.setSaturation(nonWettingPhaseIdx, 1 - SwMatrix);
97 
98  // retrieve the facture width and intrinsic permeability from
99  // the problem
100  fracturePorosity_ =
101  problem.fracturePorosity(elemCtx, vertexIdx, timeIdx);
102  fractureIntrinsicPermeability_ =
103  problem.fractureIntrinsicPermeability(elemCtx, vertexIdx, timeIdx);
104 
105  // compute the fracture volume for the current sub-control
106  // volume. note, that we don't take overlaps of fractures into
107  // account for this.
108  fractureVolume_ = 0;
109  const auto &vertexPos = elemCtx.pos(vertexIdx, timeIdx);
110  for (int vertex2Idx = 0; vertex2Idx < elemCtx.numDof(/*timeIdx=*/0); ++ vertex2Idx) {
111  int globalVertex2Idx = elemCtx.globalSpaceIndex(vertex2Idx, timeIdx);
112 
113  if (vertexIdx == vertex2Idx ||
114  !fractureMapper.isFractureEdge(globalVertexIdx, globalVertex2Idx))
115  continue;
116 
117  Scalar fractureWidth =
118  problem.fractureWidth(elemCtx, vertexIdx, vertex2Idx, timeIdx);
119 
120  auto distVec = elemCtx.pos(vertex2Idx, timeIdx);
121  distVec -= vertexPos;
122 
123  Scalar edgeLength = distVec.two_norm();
124 
125  // the fracture is always adjacent to two sub-control
126  // volumes of the control volume, so when calculating the
127  // volume of the fracture which gets attributed to one
128  // SCV, the fracture width needs to divided by 2. Also,
129  // only half of the edge is located in the current control
130  // volume, so its length also needs to divided by 2.
131  fractureVolume_ += (fractureWidth / 2) * (edgeLength / 2);
132  }
133 
134  if (fractureVolume_ <= 0.0)
135  return;
136 
138  // set the fluid state for the fracture.
140 
141  // start with the same fluid state as in the matrix. This
142  // implies equal saturations, pressures, temperatures,
143  // enthalpies, etc.
144  fractureFluidState_.assign(this->fluidState_);
145 
146  // ask the problem for the material law parameters of the
147  // fracture.
148  const auto &fractureMatParams =
149  problem.fractureMaterialLawParams(elemCtx, vertexIdx, timeIdx);
150 
151  // calculate the fracture saturations which would be required
152  // to be consistent with the pressures
153  Scalar saturations[numPhases];
154  MaterialLaw::saturations(saturations, fractureMatParams,
155  fractureFluidState_);
156  for (int phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx)
157  fractureFluidState_.setSaturation(phaseIdx, saturations[phaseIdx]);
158 
159  // Make sure that the wetting saturation in the fracture does
160  // not get negative
161  Scalar SwFracture = std::max(0.0, fractureFluidState_.saturation(wettingPhaseIdx));
162  fractureFluidState_.setSaturation(wettingPhaseIdx, SwFracture);
163  fractureFluidState_.setSaturation(nonWettingPhaseIdx, 1 - SwFracture);
164 
165  // calculate the relative permeabilities of the fracture
166  MaterialLaw::relativePermeabilities(fractureRelativePermeabilities_,
167  fractureMatParams,
168  fractureFluidState_);
169 
170  // make sure that valgrind complains if the fluid state is not
171  // fully defined.
172  fractureFluidState_.checkDefined();
173  }
174 
175 public:
182  Scalar fractureRelativePermeability(int phaseIdx) const
183  { return fractureRelativePermeabilities_[phaseIdx]; }
184 
191  Scalar fractureMobility(int phaseIdx) const
192  {
193  return fractureRelativePermeabilities_[phaseIdx]
194  / fractureFluidState_.viscosity(phaseIdx);
195  }
196 
200  Scalar fracturePorosity() const
201  { return fracturePorosity_; }
202 
207  const DimMatrix &fractureIntrinsicPermeability() const
208  { return fractureIntrinsicPermeability_; }
209 
214  Scalar fractureVolume() const
215  { return fractureVolume_; }
216 
221  const FluidState &fractureFluidState() const
222  { return fractureFluidState_; }
223 
224 protected:
225  FluidState fractureFluidState_;
226  Scalar fractureVolume_;
227  Scalar fracturePorosity_;
228  DimMatrix fractureIntrinsicPermeability_;
229  Scalar fractureRelativePermeabilities_[numPhases];
230 };
231 
232 } // namespace Ewoms
233 
234 #endif
void update(const ElementContext &elemCtx, int dofIdx, int timeIdx)
Definition: immiscibleintensivequantities.hh:82
#define GET_PROP_VALUE(TypeTag, PropTagName)
Access the value attribute of a property for a type tag.
Definition: propertysystem.hh:468
Contains the quantities which are are constant within a finite volume in the discret fracture immisci...
Definition: discretefractureintensivequantities.hh:44
Definition: baseauxiliarymodule.hh:35
FluidState fluidState_
Definition: immiscibleintensivequantities.hh:181
Defines the properties required for the immiscible multi-phase model which considers discrete fractur...
Contains the quantities which are are constant within a finite volume for the immiscible multi-phase ...
Definition: immiscibleintensivequantities.hh:46
Contains the quantities which are are constant within a finite volume for the immiscible multi-phase ...