ReservoirPropertyCapillaryAnisotropicRelperm_impl.hpp
Go to the documentation of this file.
1 //===========================================================================
2 //
3 // File: ReservoirPropertyCapillaryAnisotropicRelperm_impl.hpp
4 //
5 // Created: Mon Oct 26 10:12:15 2009
6 //
7 // Author(s): Atgeirr F Rasmussen <atgeirr@sintef.no>
8 // B�rd Skaflestad <bard.skaflestad@sintef.no>
9 //
10 // $Date$
11 //
12 // $Revision$
13 //
14 //===========================================================================
15 
16 /*
17  Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
18  Copyright 2009, 2010 Statoil ASA.
19 
20  This file is part of The Open Reservoir Simulator Project (OpenRS).
21 
22  OpenRS is free software: you can redistribute it and/or modify
23  it under the terms of the GNU General Public License as published by
24  the Free Software Foundation, either version 3 of the License, or
25  (at your option) any later version.
26 
27  OpenRS is distributed in the hope that it will be useful,
28  but WITHOUT ANY WARRANTY; without even the implied warranty of
29  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  GNU General Public License for more details.
31 
32  You should have received a copy of the GNU General Public License
33  along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
34 */
35 
36 #ifndef OPENRS_RESERVOIRPROPERTYCAPILLARYANISOTROPICRELPERM_IMPL_HEADER
37 #define OPENRS_RESERVOIRPROPERTYCAPILLARYANISOTROPICRELPERM_IMPL_HEADER
38 
39 #include <boost/lambda/lambda.hpp>
40 
41 namespace Opm
42 {
43 
44  template <int dim>
45  template <class MatrixType>
47  int cell_index,
48  double saturation,
49  MatrixType& phase_mob) const
50  {
51  const int region = Super::rock_.size() > 0 ? Super::cell_to_rock_[cell_index] : -1;
52  phaseMobilityByRock(phase_index, region, saturation, phase_mob);
53  }
54 
55 
56  template <int dim>
57  double ReservoirPropertyCapillaryAnisotropicRelperm<dim>::fractionalFlow(int cell_index, double saturation) const
58  {
59  // This method is a hack.
60  // Assumes that the relperm is diagonal.
61  Mobility m;
62  double ff_first = 0.0;
63  for (int direction = 0; direction < dim; ++direction) {
64  phaseMobility(0, cell_index, saturation, m.mob);
65  double l1 = m.mob(direction, direction);
66  phaseMobility(1, cell_index, saturation, m.mob);
67  double l2 = m.mob(direction, direction);
68  ff_first += l1/(l1 + l2);
69  }
70  ff_first /= double(dim);
71  return ff_first;
72  }
73 
74 
75  template <int dim>
76  template <class MatrixType>
78  int rock_index,
79  double saturation,
80  MatrixType& phase_mob) const
81  {
82  assert ((0 <= phase_index) && (phase_index < Super::NumberOfPhases));
83  static_assert(Super::NumberOfPhases == 2, "");
84 
85  double visc = phase_index == 0 ? Super::viscosity1_ : Super::viscosity2_;
86  if (rock_index != -1) {
87  assert (rock_index < int(Super::rock_.size()));
88  Super::rock_[rock_index].kr(phase_index, saturation, phase_mob);
89  //using namespace boost::lambda;
90  std::transform(phase_mob.data(), phase_mob.data() + dim*dim,
91  phase_mob.data(), boost::lambda::_1/visc);
92  } else {
93  // HACK: With no rocks, we use quadratic relperm functions.
94  double kr = phase_index == 0 ? saturation*saturation : (1.0 - saturation)*(1.0 - saturation);
95  double mob = kr/visc;
96  zero(phase_mob);
97  for (int j = 0; j < dim; ++j) {
98  phase_mob(j,j) = mob;
99  }
100  }
101  }
102 
103 
104  template <int dim>
105  void ReservoirPropertyCapillaryAnisotropicRelperm<dim>::cflFracFlows(int rock, int direction,
106  double s, double& ff_first, double& ff_gravity) const
107  {
108  // Assumes that the relperm is diagonal.
109  Mobility m;
110  phaseMobilityByRock(0, rock, s, m.mob);
111  double l1 = m.mob(direction, direction);
112  phaseMobilityByRock(1, rock, s, m.mob);
113  double l2 = m.mob(direction, direction);
114  ff_first = l1/(l1 + l2);
115  ff_gravity = l1*l2/(l1 + l2);
116  }
117 
118 
119 
120 
121  template <int dim>
122  std::array<double, 3> ReservoirPropertyCapillaryAnisotropicRelperm<dim>::computeSingleRockCflFactors(int rock) const
123  {
124  const int N = 257;
125  double delta = 1.0/double(N - 1);
126  double last_ff1, last_ffg;
127  double max_der1 = -1e100;
128  double max_derg = -1e100;
129  double min_ffg = -1e100;
130  for (int direction = 0; direction < dim; ++direction) {
131  cflFracFlows(rock, direction, 0.0, last_ff1, last_ffg);
132  min_ffg = std::min(min_ffg, last_ffg);
133  for (int i = 1; i < N; ++i) {
134  double s = double(i)*delta;
135  double ff1, ffg;
136  cflFracFlows(rock, direction, s, ff1, ffg);
137  double est_deriv_ff1 = std::fabs(ff1 - last_ff1)/delta;
138  double est_deriv_ffg = std::fabs(ffg - last_ffg)/delta;
139  max_der1 = std::max(max_der1, est_deriv_ff1);
140  max_derg = std::max(max_derg, est_deriv_ffg);
141  min_ffg = std::min(min_ffg, last_ffg);
142  last_ff1 = ff1;
143  last_ffg = ffg;
144  }
145  }
146  std::array<double, 3> retval = {{ 1.0/max_der1, 1.0/max_derg, min_ffg }};
147  return retval;
148  }
149 
150 
151 
152 
153  template <int dim>
155  {
156  if (Super::rock_.empty()) {
157  std::array<double, 3> fac = computeSingleRockCflFactors(-1);
158  Super::cfl_factor_ = fac[0];
159  Super::cfl_factor_gravity_ = fac[1];
160  Super::cfl_factor_capillary_ = fac[2];
161  } else {
162  Super::cfl_factor_ = 1e100;
163  Super::cfl_factor_gravity_ = 1e100;
164  Super::cfl_factor_capillary_ = 1e100;
165  for (int r = 0; r < int(Super::rock_.size()); ++r) {
166  std::array<double, 3> fac = computeSingleRockCflFactors(r);
167  Super::cfl_factor_ = std::min(Super::cfl_factor_, fac[0]);
168  Super::cfl_factor_gravity_ = std::min(Super::cfl_factor_gravity_, fac[1]);
169  Super::cfl_factor_capillary_ = std::max(Super::cfl_factor_capillary_, fac[2]);
170  }
171  }
172  }
173 
174 
175 
176 
177 
178 
179 } // namespace Opm
180 
181 
182 #endif // OPENRS_RESERVOIRPROPERTYCAPILLARYANISOTROPICRELPERM_IMPL_HEADER
void phaseMobility(int phase_index, int cell_index, double saturation, MatrixType &phase_mob) const
Anisotropic phase mobility.
Definition: ReservoirPropertyCapillaryAnisotropicRelperm_impl.hpp:46
Definition: BlackoilFluid.hpp:31
FullMatrix< double, SharedData, COrdering > mob
Definition: ReservoirPropertyCapillaryAnisotropicRelperm.hpp:96
double fractionalFlow(int cell_index, double saturation) const
Some approximation to a scalar fractional flow (of the first phase).
Definition: ReservoirPropertyCapillaryAnisotropicRelperm_impl.hpp:57
void computeCflFactors()
Definition: ReservoirPropertyCapillaryAnisotropicRelperm_impl.hpp:154
A property class for incompressible two-phase flow.
Definition: ReservoirPropertyCapillaryAnisotropicRelperm.hpp:104
A wrapper for a tensor.
Definition: ReservoirPropertyCapillaryAnisotropicRelperm.hpp:49
void zero(Matrix &A)
Zero-fill a.
Definition: Matrix.hpp:603