RockJfunc.hpp
Go to the documentation of this file.
1//===========================================================================
2//
3// File: RockJfunc.hpp
4//
5// Created: Fri Oct 23 08:59:52 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_ROCKJFUNC_HEADER
37#define OPENRS_ROCKJFUNC_HEADER
38
39#include <dune/common/fvector.hh>
40#include <opm/core/utility/NonuniformTableLinear.hpp>
42
43#include <fstream>
44#include <vector>
45#include <algorithm>
46#include <cmath>
47#include <iostream>
48
49namespace Opm
50{
51
53 {
54 public:
56 : use_jfunction_scaling_(true), sigma_cos_theta_(1.0)
57 {
58 }
59
60 void setUseJfunctionScaling(const bool use_j)
61 {
62 use_jfunction_scaling_ = use_j;
63 }
64
65 void setSigmaAndTheta(const double sigma, const double theta)
66 {
67 sigma_cos_theta_ = sigma*std::cos(theta);
68 }
69
70 void krw(const double saturation, double& krw_value) const
71 {
72 krw_value = krw_(saturation);
73 }
74
75 void kro(const double saturation, double& kro_value) const
76 {
77 kro_value = kro_(saturation);
78 }
79
80 void dkrw(const double saturation, double& dkrw_value) const
81 {
82 dkrw_value = krw_.derivative(saturation);
83 }
84
85 void dkro(const double saturation, double& dkro_value) const
86 {
87 dkro_value = kro_.derivative(saturation);
88 }
89
90 double s_min() const
91 {
92 return s_min_;
93 }
94 double s_max() const
95 {
96 return s_max_;
97 }
98
99 template <template <class> class SP, class OP>
100 double capPress(const FullMatrix<double, SP, OP>& perm, const double poro, const double saturation) const
101 {
102 if (use_jfunction_scaling_) {
103 // p_{cow} = J\frac{\sigma \cos \theta}{\sqrt{k/\phi}}
104 // \sigma \cos \theta is by default approximated by 1.0;
105 // k is approximated by the average of the diagonal terms.
106 double sqrt_k_phi = std::sqrt(trace(perm)/(perm.numRows()*poro));
107 return Jfunc_(saturation)*sigma_cos_theta_/sqrt_k_phi;
108 } else {
109 // The Jfunc_ table actually contains the pressure directly.
110 return Jfunc_(saturation);
111 }
112 }
113
114 template <template <class> class SP, class OP>
115 double capPressDeriv(const FullMatrix<double, SP, OP>& perm, const double poro, const double saturation) const
116 {
117 if (use_jfunction_scaling_) {
118 // p_{cow} = J\frac{\sigma \cos \theta}{\sqrt{k/\phi}}
119 // \sigma \cos \theta is by default approximated by 1.0;
120 // k is approximated by the average of the diagonal terms.
121 double sqrt_k_phi = std::sqrt(trace(perm)/(perm.numRows()*poro));
122 return Jfunc_.derivative(saturation)*sigma_cos_theta_/sqrt_k_phi;
123 } else {
124 // The Jfunc_ table actually contains the pressure directly.
125 return Jfunc_.derivative(saturation);
126 }
127 }
128
129 template <template <class> class SP, class OP>
130 double satFromCapPress(const FullMatrix<double, SP, OP>& perm, const double poro, const double cap_press) const
131 {
132 double s = 0;
133 if (use_jfunction_scaling_) {
134 // p_{cow} = J\frac{\sigma \cos \theta}{\sqrt{k/\phi}}
135 // \sigma \cos \theta is by default approximated by 1.0;
136 // k is approximated by the average of the diagonal terms.
137 double sqrt_k_phi = std::sqrt(trace(perm)/(perm.numRows()*poro));
138 s = Jfunc_.inverse(cap_press*sqrt_k_phi/sigma_cos_theta_);
139 } else {
140 // The Jfunc_ table actually contains the pressure directly.
141 s = Jfunc_.inverse(cap_press);
142 }
143 s = std::min(s_max_, std::max(s_min_, s));
144 return s;
145 }
146
147 void read(const std::string& directory, const std::string& specification)
148 {
149 // For this type of rock, the specification is simply a line with the file name.
150 std::istringstream specstream(specification);
151 std::string rockname;
152 specstream >> rockname;
153 std::string rockfilename = directory + rockname;
154 std::ifstream rock_stream(rockfilename.c_str());
155 if (!rock_stream) {
156 OPM_THROW(std::runtime_error, "Could not open file " << rockfilename);
157 }
158 readStatoilFormat(rock_stream);
159 }
160
161 private:
162 void readStatoilFormat(std::istream& is)
163 {
164 /* Skip lines at the top of the file starting with '#' or '--' */
165 char c = is.peek();
166 while ((c == '-' || c == '#') && is) {
167 if (c == '#') {
168 std::string commentline;
169 std::getline(is, commentline);
170 c = is.peek();
171 }
172 else { /* Check if the initial '-' was first byte of the sequence '--' */
173 is.get(c);
174 if (c == '-') {
175 std::string commentline;
176 std::getline(is, commentline);
177 c = is.peek();
178 } else {
179 is.putback(c);
180 }
181 }
182 }
183 if (!is) {
184 OPM_THROW(std::runtime_error, "Something went wrong while skipping optional comment header of rock file.");
185 }
186 typedef Dune::FieldVector<double, 4> Data;
187 std::istream_iterator<Data> start(is);
188 std::istream_iterator<Data> end;
189 std::vector<Data> data(start, end);
190 if (!is.eof()) {
191 OPM_THROW(std::runtime_error, "Reading stopped but we're not at eof: something went wrong reading data of rock file.");
192 }
193 std::vector<double> svals, krw, kro, Jfunc;
194 for (int i = 0; i < int(data.size()); ++i) {
195 svals.push_back(data[i][0]);
196 krw.push_back(data[i][1]);
197 kro.push_back(data[i][2]);
198 Jfunc.push_back(data[i][3]);
199 }
200 if (krw[0] != 0.0) {
201 krw[0] = 0.0;
202 std::cout << "Warning: krw table were modified to go to zero at the beginning." << std::endl;
203 }
204 if (kro.back() != 0.0) {
205 kro.back() = 0.0;
206 std::cout << "Warning: kro table were modified to go to zero at the end." << std::endl;
207 }
208 s_min_ = svals.front();
209 s_max_ = svals.back();
210 krw_ = TabFunc(svals, krw);
211 kro_ = TabFunc(svals, kro);
212 Jfunc_ = TabFunc(svals, Jfunc);
213 std::vector<double> invJfunc(Jfunc);
214 std::reverse(invJfunc.begin(), invJfunc.end());
215 std::vector<double> invsvals(svals);
216 std::reverse(invsvals.begin(), invsvals.end());
217 invJfunc_ = TabFunc(invJfunc, invsvals);
218 }
219
220 typedef NonuniformTableLinear<double> TabFunc;
221 TabFunc krw_;
222 TabFunc kro_;
223 TabFunc Jfunc_;
224 TabFunc invJfunc_;
225 bool use_jfunction_scaling_;
226 double sigma_cos_theta_;
227 double s_min_;
228 double s_max_;
229
230
231 };
232
233} // namespace Opm
234
235
236#endif // OPENRS_ROCKJFUNC_HEADER
Definition: RockJfunc.hpp:53
double capPressDeriv(const FullMatrix< double, SP, OP > &perm, const double poro, const double saturation) const
Definition: RockJfunc.hpp:115
double satFromCapPress(const FullMatrix< double, SP, OP > &perm, const double poro, const double cap_press) const
Definition: RockJfunc.hpp:130
void kro(const double saturation, double &kro_value) const
Definition: RockJfunc.hpp:75
void setUseJfunctionScaling(const bool use_j)
Definition: RockJfunc.hpp:60
RockJfunc()
Definition: RockJfunc.hpp:55
void dkrw(const double saturation, double &dkrw_value) const
Definition: RockJfunc.hpp:80
double s_min() const
Definition: RockJfunc.hpp:90
double s_max() const
Definition: RockJfunc.hpp:94
void setSigmaAndTheta(const double sigma, const double theta)
Definition: RockJfunc.hpp:65
double capPress(const FullMatrix< double, SP, OP > &perm, const double poro, const double saturation) const
Definition: RockJfunc.hpp:100
void krw(const double saturation, double &krw_value) const
Definition: RockJfunc.hpp:70
void dkro(const double saturation, double &dkro_value) const
Definition: RockJfunc.hpp:85
void read(const std::string &directory, const std::string &specification)
Definition: RockJfunc.hpp:147
Definition: BlackoilFluid.hpp:32
Matrix::value_type trace(const Matrix &A)
Compute matrix trace (i.e., sum(diag(A))).
Definition: Matrix.hpp:639