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 
49 namespace Opm
50 {
51 
52  class RockJfunc
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
void setSigmaAndTheta(const double sigma, const double theta)
Definition: RockJfunc.hpp:65
double s_max() const
Definition: RockJfunc.hpp:94
Definition: BlackoilFluid.hpp:31
double s_min() const
Definition: RockJfunc.hpp:90
RockJfunc()
Definition: RockJfunc.hpp:55
void kro(const double saturation, double &kro_value) const
Definition: RockJfunc.hpp:75
void dkrw(const double saturation, double &dkrw_value) const
Definition: RockJfunc.hpp:80
double satFromCapPress(const FullMatrix< double, SP, OP > &perm, const double poro, const double cap_press) const
Definition: RockJfunc.hpp:130
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
double capPressDeriv(const FullMatrix< double, SP, OP > &perm, const double poro, const double saturation) const
Definition: RockJfunc.hpp:115
void setUseJfunctionScaling(const bool use_j)
Definition: RockJfunc.hpp:60
void dkro(const double saturation, double &dkro_value) const
Definition: RockJfunc.hpp:85
Matrix::value_type trace(const Matrix &A)
Compute matrix trace (i.e., sum(diag(A))).
Definition: Matrix.hpp:639
void read(const std::string &directory, const std::string &specification)
Definition: RockJfunc.hpp:147
Definition: RockJfunc.hpp:52