opm-simulators/opm/core/props/satfunc/SaturationPropsBasic.cpp
Andreas Lauser 40fe2abf04 make config.h the first header to be included in any compile unit
this is required for consistency amongst the compile units which are
linked into the same library and seems to be forgotten quite
frequently.
2013-04-10 12:56:14 +02:00

223 lines
6.7 KiB
C++

/*
Copyright 2012 SINTEF ICT, Applied Mathematics.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <opm/core/props/satfunc/SaturationPropsBasic.hpp>
#include <opm/core/utility/ErrorMacros.hpp>
#include <iostream>
namespace Opm
{
// ---------- Helper functions ----------
namespace {
struct KrFunConstant
{
double kr(double)
{
return 1.0;
}
double dkrds(double)
{
return 0.0;
}
};
struct KrFunLinear
{
double kr(double s)
{
return s;
}
double dkrds(double)
{
return 1.0;
}
};
struct KrFunQuadratic
{
double kr(double s)
{
return s*s;
}
double dkrds(double s)
{
return 2.0*s;
}
};
template <class Fun>
static inline void evalAllKrDeriv(const int n, const int np,
const double* s, double* kr, double* dkrds, Fun fun)
{
if (dkrds == 0) {
// #pragma omp parallel for
for (int i = 0; i < n*np; ++i) {
kr[i] = fun.kr(s[i]);
}
return;
}
// #pragma omp parallel for
for (int i = 0; i < n; ++i) {
std::fill(dkrds + i*np*np, dkrds + (i+1)*np*np, 0.0);
for (int phase = 0; phase < np; ++phase) {
kr[i*np + phase] = fun.kr(s[i*np + phase]);
// Only diagonal elements in derivative.
dkrds[i*np*np + phase*np + phase] = fun.dkrds(s[i*np + phase]);
}
}
}
} // anon namespace
// ---------- Class methods ----------
/// Default constructor.
SaturationPropsBasic::SaturationPropsBasic()
: num_phases_(0), relperm_func_(Constant)
{
}
/// Initialize from parameters.
void SaturationPropsBasic::init(const parameter::ParameterGroup& param)
{
int num_phases = param.getDefault("num_phases", 2);
if (num_phases > 2 || num_phases < 1) {
THROW("SaturationPropsBasic::init() illegal num_phases: " << num_phases);
}
num_phases_ = num_phases;
//std::string rpf = param.getDefault("relperm_func", std::string("Unset"));
std::string rpf = param.getDefault("relperm_func", std::string("Linear"));
if (rpf == "Constant") {
relperm_func_ = Constant;
if(num_phases!=1){
THROW("Constant relperm with more than one phase???");
}
} else if (rpf == "Linear") {
relperm_func_ = Linear;
} else if (rpf == "Quadratic") {
relperm_func_ = Quadratic;
} else {
THROW("SaturationPropsBasic::init() illegal relperm_func: " << rpf);
}
}
/// \return P, the number of phases.
int SaturationPropsBasic::numPhases() const
{
return num_phases_;
}
/// Relative permeability.
/// \param[in] n Number of data points.
/// \param[in] s Array of nP saturation values.
/// \param[out] kr Array of nP relperm values, array must be valid before calling.
/// \param[out] dkrds If non-null: array of nP^2 relperm derivative values,
/// array must be valid before calling.
/// The P^2 derivative matrix is
/// m_{ij} = \frac{dkr_i}{ds^j},
/// and is output in Fortran order (m_00 m_10 m_20 m01 ...)
void SaturationPropsBasic::relperm(const int n,
const double* s,
double* kr,
double* dkrds) const
{
switch (relperm_func_) {
case Constant:
{
evalAllKrDeriv(n, num_phases_, s, kr, dkrds, KrFunConstant());
break;
}
case Linear:
{
evalAllKrDeriv(n, num_phases_, s, kr, dkrds, KrFunLinear());
break;
}
case Quadratic:
{
evalAllKrDeriv(n, num_phases_, s, kr, dkrds, KrFunQuadratic());
break;
}
default:
THROW("SaturationPropsBasic::relperm() unhandled relperm func type: " << relperm_func_);
}
}
/// Capillary pressure.
/// \param[in] n Number of data points.
/// \param[in] s Array of nP saturation values.
/// \param[out] pc Array of nP capillary pressure values, array must be valid before calling.
/// \param[out] dpcds If non-null: array of nP^2 derivative values,
/// array must be valid before calling.
/// The P^2 derivative matrix is
/// m_{ij} = \frac{dpc_i}{ds^j},
/// and is output in Fortran order (m_00 m_10 m_20 m01 ...)
void SaturationPropsBasic::capPress(const int n,
const double* /*s*/,
double* pc,
double* dpcds) const
{
std::fill(pc, pc + num_phases_*n, 0.0);
if (dpcds) {
std::fill(dpcds, dpcds + num_phases_*num_phases_*n, 0.0);
}
}
/// Obtain the range of allowable saturation values.
/// \param[in] n Number of data points.
/// \param[out] smin Array of nP minimum s values, array must be valid before calling.
/// \param[out] smax Array of nP maximum s values, array must be valid before calling.
void SaturationPropsBasic::satRange(const int n,
double* smin,
double* smax) const
{
std::fill(smin, smin + num_phases_*n, 0.0);
std::fill(smax, smax + num_phases_*n, 1.0);
}
} // namespace Opm