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
41namespace 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
A property class for incompressible two-phase flow.
Definition: ReservoirPropertyCapillaryAnisotropicRelperm.hpp:106
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
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:32
void zero(Matrix &A)
Zero-fill a.
Definition: Matrix.hpp:603
A wrapper for a tensor.
Definition: ReservoirPropertyCapillaryAnisotropicRelperm.hpp:50
FullMatrix< double, SharedData, COrdering > mob
Definition: ReservoirPropertyCapillaryAnisotropicRelperm.hpp:96