Merge pull request #607 from osae/swatinit
Scaling of capillary pressure / initialisation from kw SWATINIT.
This commit is contained in:
commit
ace1e3306a
@ -95,7 +95,7 @@ try
|
|||||||
|
|
||||||
// Initialisation.
|
// Initialisation.
|
||||||
BlackoilState state;
|
BlackoilState state;
|
||||||
initStateEquil(grid, props, deck, grav, state);
|
initStateEquil(grid, props, deck, eclipseState, grav, state);
|
||||||
|
|
||||||
// Output.
|
// Output.
|
||||||
const std::string output_dir = param.getDefault<std::string>("output_dir", "output");
|
const std::string output_dir = param.getDefault<std::string>("output_dir", "output");
|
||||||
|
@ -239,5 +239,16 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Update capillary pressure scaling according to pressure diff. and initial water saturation.
|
||||||
|
/// \param[in] cell Cell index.
|
||||||
|
/// \param[in] pcow P_oil - P_water.
|
||||||
|
/// \param[in/out] swat Water saturation. / Possibly modified Water saturation.
|
||||||
|
void BlackoilPropertiesBasic::swatInitScaling(const int cell,
|
||||||
|
const double pcow,
|
||||||
|
double & swat)
|
||||||
|
{
|
||||||
|
OPM_THROW(std::runtime_error, "BlackoilPropertiesBasic::swatInitScaling() -- not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ namespace Opm
|
|||||||
double* dpcds) const;
|
double* dpcds) const;
|
||||||
|
|
||||||
|
|
||||||
/// Obtain the range of allowable saturation values.
|
/// Obtain the range of allowable saturation values.
|
||||||
/// In cell cells[i], saturation of phase p is allowed to be
|
/// In cell cells[i], saturation of phase p is allowed to be
|
||||||
/// in the interval [smin[i*P + p], smax[i*P + p]].
|
/// in the interval [smin[i*P + p], smax[i*P + p]].
|
||||||
/// \param[in] n Number of data points.
|
/// \param[in] n Number of data points.
|
||||||
@ -175,6 +175,16 @@ namespace Opm
|
|||||||
double* smin,
|
double* smin,
|
||||||
double* smax) const;
|
double* smax) const;
|
||||||
|
|
||||||
|
|
||||||
|
/// Update capillary pressure scaling according to pressure diff. and initial water saturation.
|
||||||
|
/// \param[in] cell Cell index.
|
||||||
|
/// \param[in] pcow P_oil - P_water.
|
||||||
|
/// \param[in/out] swat Water saturation. / Possibly modified Water saturation.
|
||||||
|
virtual void swatInitScaling(const int cell,
|
||||||
|
const double pcow,
|
||||||
|
double & swat);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RockBasic rock_;
|
RockBasic rock_;
|
||||||
PvtPropertiesBasic pvt_;
|
PvtPropertiesBasic pvt_;
|
||||||
|
@ -305,5 +305,16 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Update capillary pressure scaling according to pressure diff. and initial water saturation.
|
||||||
|
/// \param[in] cell Cell index.
|
||||||
|
/// \param[in] pcow P_oil - P_water.
|
||||||
|
/// \param[in/out] swat Water saturation. / Possibly modified Water saturation.
|
||||||
|
void BlackoilPropertiesFromDeck::swatInitScaling(const int cell,
|
||||||
|
const double pcow,
|
||||||
|
double & swat)
|
||||||
|
{
|
||||||
|
satprops_->swatInitScaling(cell, pcow, swat);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
|
||||||
|
@ -216,6 +216,15 @@ namespace Opm
|
|||||||
double* smin,
|
double* smin,
|
||||||
double* smax) const;
|
double* smax) const;
|
||||||
|
|
||||||
|
|
||||||
|
/// Update capillary pressure scaling according to pressure diff. and initial water saturation.
|
||||||
|
/// \param[in] cell Cell index.
|
||||||
|
/// \param[in] pcow P_oil - P_water.
|
||||||
|
/// \param[in/out] swat Water saturation. / Possibly modified Water saturation.
|
||||||
|
virtual void swatInitScaling(const int cell,
|
||||||
|
const double pcow,
|
||||||
|
double & swat);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int getTableIndex_(const int* pvtTableIdx, int cellIdx) const
|
int getTableIndex_(const int* pvtTableIdx, int cellIdx) const
|
||||||
{
|
{
|
||||||
|
@ -160,6 +160,16 @@ namespace Opm
|
|||||||
const int* cells,
|
const int* cells,
|
||||||
double* smin,
|
double* smin,
|
||||||
double* smax) const = 0;
|
double* smax) const = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/// Update capillary pressure scaling according to pressure diff. and initial water saturation.
|
||||||
|
/// \param[in] cell Cell index.
|
||||||
|
/// \param[in] pcow P_oil - P_water.
|
||||||
|
/// \param[in/out] swat Water saturation. / Possibly modified Water saturation.
|
||||||
|
virtual void swatInitScaling(const int cell,
|
||||||
|
const double pcow,
|
||||||
|
double & swat) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ namespace Opm
|
|||||||
double krSlopeCrit;
|
double krSlopeCrit;
|
||||||
double scaleKr(double s, double kr, double krsr_tab) const;
|
double scaleKr(double s, double kr, double krsr_tab) const;
|
||||||
double scaleKrDeriv(double s, double krDeriv) const; // Returns scaleKr'(kr(scaleSat(s)))*kr'((scaleSat(s))
|
double scaleKrDeriv(double s, double krDeriv) const; // Returns scaleKr'(kr(scaleSat(s)))*kr'((scaleSat(s))
|
||||||
|
double pcFactor; // Scaling factor for capillary pressure.
|
||||||
void printMe(std::ostream & out);
|
void printMe(std::ostream & out);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -99,6 +100,8 @@ namespace Opm
|
|||||||
double sogcr_; // Critical oil-in-gas-and-connate-water saturation.
|
double sogcr_; // Critical oil-in-gas-and-connate-water saturation.
|
||||||
double krorw_; // Oil relperm at critical water saturation.
|
double krorw_; // Oil relperm at critical water saturation.
|
||||||
double krorg_; // Oil relperm at critical gas saturation.
|
double krorg_; // Oil relperm at critical gas saturation.
|
||||||
|
double pcwmax_; // Max oil-water capillary pressure.
|
||||||
|
double pcgmax_; // Max gas-oil capillary pressure.
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PhaseUsage phase_usage; // A copy of the outer class' phase_usage_.
|
PhaseUsage phase_usage; // A copy of the outer class' phase_usage_.
|
||||||
@ -182,6 +185,7 @@ namespace Opm
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pcwmax_ = pcow.front();
|
||||||
}
|
}
|
||||||
if (phase_usage.phase_used[Vapour]) {
|
if (phase_usage.phase_used[Vapour]) {
|
||||||
Opm::SgofTable sgof(deck->getKeyword("SGOF"), table_num);
|
Opm::SgofTable sgof(deck->getKeyword("SGOF"), table_num);
|
||||||
@ -234,6 +238,7 @@ namespace Opm
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pcgmax_ = pcog.back();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,12 +553,12 @@ namespace Opm
|
|||||||
if (this->phase_usage.phase_used[BlackoilPhases::Aqua]) {
|
if (this->phase_usage.phase_used[BlackoilPhases::Aqua]) {
|
||||||
int pos = this->phase_usage.phase_pos[BlackoilPhases::Aqua];
|
int pos = this->phase_usage.phase_pos[BlackoilPhases::Aqua];
|
||||||
double _sw = epst->wat.scaleSatPc(s[pos], this->smin_[pos], this->smax_[pos]);
|
double _sw = epst->wat.scaleSatPc(s[pos], this->smin_[pos], this->smax_[pos]);
|
||||||
pc[pos] = this->pcow_(_sw);
|
pc[pos] = epst->wat.pcFactor*this->pcow_(_sw);
|
||||||
}
|
}
|
||||||
if (this->phase_usage.phase_used[BlackoilPhases::Vapour]) {
|
if (this->phase_usage.phase_used[BlackoilPhases::Vapour]) {
|
||||||
int pos = this->phase_usage.phase_pos[BlackoilPhases::Vapour];
|
int pos = this->phase_usage.phase_pos[BlackoilPhases::Vapour];
|
||||||
double _sg = epst->gas.scaleSatPc(s[pos], this->smin_[pos], this->smax_[pos]);
|
double _sg = epst->gas.scaleSatPc(s[pos], this->smin_[pos], this->smax_[pos]);
|
||||||
pc[pos] = this->pcog_(_sg);
|
pc[pos] = epst->gas.pcFactor*this->pcog_(_sg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,16 +602,16 @@ namespace Opm
|
|||||||
if (this->phase_usage.phase_used[BlackoilPhases::Aqua]) {
|
if (this->phase_usage.phase_used[BlackoilPhases::Aqua]) {
|
||||||
int pos = this->phase_usage.phase_pos[BlackoilPhases::Aqua];
|
int pos = this->phase_usage.phase_pos[BlackoilPhases::Aqua];
|
||||||
double _sw = epst->wat.scaleSatPc(s[pos], this->smin_[pos], this->smax_[pos]);
|
double _sw = epst->wat.scaleSatPc(s[pos], this->smin_[pos], this->smax_[pos]);
|
||||||
pc[pos] = this->pcow_(s[pos]);
|
pc[pos] = epst->wat.pcFactor*this->pcow_(s[pos]);
|
||||||
double _dsdsw = epst->wat.scaleSatDerivPc(s[pos], this->smin_[pos], this->smax_[pos]);
|
double _dsdsw = epst->wat.scaleSatDerivPc(s[pos], this->smin_[pos], this->smax_[pos]);
|
||||||
dpcds[np*pos + pos] = _dsdsw*this->pcow_.derivative(_sw);
|
dpcds[np*pos + pos] = epst->wat.pcFactor*_dsdsw*this->pcow_.derivative(_sw);
|
||||||
}
|
}
|
||||||
if (this->phase_usage.phase_used[BlackoilPhases::Vapour]) {
|
if (this->phase_usage.phase_used[BlackoilPhases::Vapour]) {
|
||||||
int pos = this->phase_usage.phase_pos[BlackoilPhases::Vapour];
|
int pos = this->phase_usage.phase_pos[BlackoilPhases::Vapour];
|
||||||
double _sg = epst->gas.scaleSatPc(s[pos], this->smin_[pos], this->smax_[pos]);
|
double _sg = epst->gas.scaleSatPc(s[pos], this->smin_[pos], this->smax_[pos]);
|
||||||
pc[pos] = this->pcog_(_sg);
|
pc[pos] = epst->gas.pcFactor*this->pcog_(_sg);
|
||||||
double _dsdsg = epst->gas.scaleSatDerivPc(s[pos], this->smin_[pos], this->smax_[pos]);
|
double _dsdsg = epst->gas.scaleSatDerivPc(s[pos], this->smin_[pos], this->smax_[pos]);
|
||||||
dpcds[np*pos + pos] = _dsdsg*this->pcog_.derivative(_sg);
|
dpcds[np*pos + pos] = epst->gas.pcFactor*_dsdsg*this->pcog_.derivative(_sg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +132,14 @@ namespace Opm
|
|||||||
const int* cells,
|
const int* cells,
|
||||||
const double* s);
|
const double* s);
|
||||||
|
|
||||||
|
/// Update capillary pressure scaling according to pressure diff. and initial water saturation.
|
||||||
|
/// \param[in] cell Cell index.
|
||||||
|
/// \param[in] pcow P_oil - P_water.
|
||||||
|
/// \param[in/out] swat Water saturation. / Possibly modified Water saturation.
|
||||||
|
void swatInitScaling(const int cell,
|
||||||
|
const double pcow,
|
||||||
|
double & swat);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PhaseUsage phase_usage_;
|
PhaseUsage phase_usage_;
|
||||||
std::vector<SatFuncSet> satfuncset_;
|
std::vector<SatFuncSet> satfuncset_;
|
||||||
@ -178,13 +186,15 @@ namespace Opm
|
|||||||
const double s0_tab,
|
const double s0_tab,
|
||||||
const double krsr_tab,
|
const double krsr_tab,
|
||||||
const double krmax_tab,
|
const double krmax_tab,
|
||||||
|
const double pcmax_tab,
|
||||||
const std::vector<double>& sl,
|
const std::vector<double>& sl,
|
||||||
const std::vector<double>& scr,
|
const std::vector<double>& scr,
|
||||||
const std::vector<double>& su,
|
const std::vector<double>& su,
|
||||||
const std::vector<double>& sxcr,
|
const std::vector<double>& sxcr,
|
||||||
const std::vector<double>& s0,
|
const std::vector<double>& s0,
|
||||||
const std::vector<double>& krsr,
|
const std::vector<double>& krsr,
|
||||||
const std::vector<double>& krmax);
|
const std::vector<double>& krmax,
|
||||||
|
const std::vector<double>& pcmax);
|
||||||
|
|
||||||
bool columnIsMasked_(Opm::DeckConstPtr deck,
|
bool columnIsMasked_(Opm::DeckConstPtr deck,
|
||||||
const std::string& keywordName,
|
const std::string& keywordName,
|
||||||
|
@ -412,6 +412,39 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Update capillary pressure scaling according to pressure diff. and initial water saturation.
|
||||||
|
/// \param[in] cell Cell index.
|
||||||
|
/// \param[in] pcow P_oil - P_water.
|
||||||
|
/// \param[in/out] swat Water saturation. / Possibly modified Water saturation.
|
||||||
|
template <class SatFuncSet>
|
||||||
|
void SaturationPropsFromDeck<SatFuncSet>::swatInitScaling(const int cell,
|
||||||
|
const double pcow,
|
||||||
|
double & swat)
|
||||||
|
{
|
||||||
|
if (phase_usage_.phase_used[Aqua]) {
|
||||||
|
// TODO: Mixed wettability systems - see ecl kw OPTIONS switch 74
|
||||||
|
if (swat <= eps_transf_[cell].wat.smin) {
|
||||||
|
swat = eps_transf_[cell].wat.smin;
|
||||||
|
} else if (pcow < 1.0e-8) {
|
||||||
|
swat = eps_transf_[cell].wat.smax;
|
||||||
|
} else {
|
||||||
|
const int wpos = phase_usage_.phase_pos[BlackoilPhases::Aqua];
|
||||||
|
const int np = phase_usage_.num_phases;
|
||||||
|
double s[np];
|
||||||
|
s[wpos] = swat;
|
||||||
|
double pc[np];
|
||||||
|
funcForCell(cell).evalPc(s, pc, &(eps_transf_[cell]));
|
||||||
|
if (pc[wpos] > 1.0e-8) {
|
||||||
|
eps_transf_[cell].wat.pcFactor *= pcow/pc[wpos];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
OPM_THROW(std::runtime_error, "swatInitScaling: no water phase! ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Map the cell number to the correct function set.
|
// Map the cell number to the correct function set.
|
||||||
template <class SatFuncSet>
|
template <class SatFuncSet>
|
||||||
const typename SaturationPropsFromDeck<SatFuncSet>::Funcs&
|
const typename SaturationPropsFromDeck<SatFuncSet>::Funcs&
|
||||||
@ -431,6 +464,8 @@ namespace Opm
|
|||||||
{
|
{
|
||||||
std::vector<double> swl, swcr, swu, sgl, sgcr, sgu, sowcr, sogcr;
|
std::vector<double> swl, swcr, swu, sgl, sgcr, sgu, sowcr, sogcr;
|
||||||
std::vector<double> krw, krg, kro, krwr, krgr, krorw, krorg;
|
std::vector<double> krw, krg, kro, krwr, krgr, krorw, krorg;
|
||||||
|
std::vector<double> pcw, pcg;
|
||||||
|
const std::vector<double> dummy;
|
||||||
// Initialize saturation scaling parameter
|
// Initialize saturation scaling parameter
|
||||||
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions,
|
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions,
|
||||||
std::string("SWL"), swl);
|
std::string("SWL"), swl);
|
||||||
@ -462,6 +497,10 @@ namespace Opm
|
|||||||
std::string("KRORW"), krorw);
|
std::string("KRORW"), krorw);
|
||||||
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions,
|
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions,
|
||||||
std::string("KRORG"), krorg);
|
std::string("KRORG"), krorg);
|
||||||
|
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions,
|
||||||
|
std::string("PCW"), pcw);
|
||||||
|
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions,
|
||||||
|
std::string("PCG"), pcg);
|
||||||
|
|
||||||
eps_transf_.resize(number_of_cells);
|
eps_transf_.resize(number_of_cells);
|
||||||
|
|
||||||
@ -474,31 +513,95 @@ namespace Opm
|
|||||||
for (int cell = 0; cell < number_of_cells; ++cell) {
|
for (int cell = 0; cell < number_of_cells; ++cell) {
|
||||||
if (oilWater) {
|
if (oilWater) {
|
||||||
// ### krw
|
// ### krw
|
||||||
initEPSParam(cell, eps_transf_[cell].wat, false, funcForCell(cell).smin_[wpos], funcForCell(cell).swcr_, funcForCell(cell).smax_[wpos],
|
initEPSParam(cell, eps_transf_[cell].wat, false,
|
||||||
funcForCell(cell).sowcr_, -1.0, funcForCell(cell).krwr_, funcForCell(cell).krwmax_, swl, swcr, swu, sowcr, sgl, krwr, krw);
|
funcForCell(cell).smin_[wpos],
|
||||||
|
funcForCell(cell).swcr_,
|
||||||
|
funcForCell(cell).smax_[wpos],
|
||||||
|
funcForCell(cell).sowcr_,
|
||||||
|
-1.0,
|
||||||
|
funcForCell(cell).krwr_,
|
||||||
|
funcForCell(cell).krwmax_,
|
||||||
|
funcForCell(cell).pcwmax_,
|
||||||
|
swl, swcr, swu, sowcr, sgl, krwr, krw, pcw);
|
||||||
// ### krow
|
// ### krow
|
||||||
initEPSParam(cell, eps_transf_[cell].watoil, true, 0.0, funcForCell(cell).sowcr_, funcForCell(cell).smin_[wpos],
|
initEPSParam(cell, eps_transf_[cell].watoil, true,
|
||||||
funcForCell(cell).swcr_, -1.0, funcForCell(cell).krorw_, funcForCell(cell).kromax_, swl, sowcr, swl, swcr, sgl, krorw, kro);
|
0.0,
|
||||||
|
funcForCell(cell).sowcr_,
|
||||||
|
funcForCell(cell).smin_[wpos],
|
||||||
|
funcForCell(cell).swcr_,
|
||||||
|
-1.0,
|
||||||
|
funcForCell(cell).krorw_,
|
||||||
|
funcForCell(cell).kromax_,
|
||||||
|
0.0,
|
||||||
|
swl, sowcr, swl, swcr, sgl, krorw, kro, dummy);
|
||||||
} else if (oilGas) {
|
} else if (oilGas) {
|
||||||
// ### krg
|
// ### krg
|
||||||
initEPSParam(cell, eps_transf_[cell].gas, false, funcForCell(cell).smin_[gpos], funcForCell(cell).sgcr_, funcForCell(cell).smax_[gpos],
|
initEPSParam(cell, eps_transf_[cell].gas, false,
|
||||||
funcForCell(cell).sogcr_, -1.0, funcForCell(cell).krgr_, funcForCell(cell).krgmax_, sgl, sgcr, sgu, sogcr, swl, krgr, krg);
|
funcForCell(cell).smin_[gpos],
|
||||||
|
funcForCell(cell).sgcr_,
|
||||||
|
funcForCell(cell).smax_[gpos],
|
||||||
|
funcForCell(cell).sogcr_,
|
||||||
|
-1.0,
|
||||||
|
funcForCell(cell).krgr_,
|
||||||
|
funcForCell(cell).krgmax_,
|
||||||
|
funcForCell(cell).pcgmax_,
|
||||||
|
sgl, sgcr, sgu, sogcr, swl, krgr, krg, pcg);
|
||||||
// ### krog
|
// ### krog
|
||||||
initEPSParam(cell, eps_transf_[cell].gasoil, true, 0.0, funcForCell(cell).sogcr_, funcForCell(cell).smin_[gpos],
|
initEPSParam(cell, eps_transf_[cell].gasoil, true,
|
||||||
funcForCell(cell).sgcr_, -1.0, funcForCell(cell).krorg_, funcForCell(cell).kromax_, sgl, sogcr, sgl, sgcr, swl, krorg, kro);
|
0.0,
|
||||||
|
funcForCell(cell).sogcr_,
|
||||||
|
funcForCell(cell).smin_[gpos],
|
||||||
|
funcForCell(cell).sgcr_,
|
||||||
|
-1.0,
|
||||||
|
funcForCell(cell).krorg_,
|
||||||
|
funcForCell(cell).kromax_,
|
||||||
|
0.0,
|
||||||
|
sgl, sogcr, sgl, sgcr, swl, krorg, kro, dummy);
|
||||||
} else if (threephase) {
|
} else if (threephase) {
|
||||||
// ### krw
|
// ### krw
|
||||||
initEPSParam(cell, eps_transf_[cell].wat, false, funcForCell(cell).smin_[wpos], funcForCell(cell).swcr_, funcForCell(cell).smax_[wpos], funcForCell(cell).sowcr_,
|
initEPSParam(cell, eps_transf_[cell].wat, false,
|
||||||
funcForCell(cell).smin_[gpos], funcForCell(cell).krwr_, funcForCell(cell).krwmax_, swl, swcr, swu, sowcr, sgl, krwr, krw);
|
funcForCell(cell).smin_[wpos],
|
||||||
|
funcForCell(cell).swcr_,
|
||||||
|
funcForCell(cell).smax_[wpos],
|
||||||
|
funcForCell(cell).sowcr_,
|
||||||
|
funcForCell(cell).smin_[gpos],
|
||||||
|
funcForCell(cell).krwr_,
|
||||||
|
funcForCell(cell).krwmax_,
|
||||||
|
funcForCell(cell).pcwmax_,
|
||||||
|
swl, swcr, swu, sowcr, sgl, krwr, krw, pcw);
|
||||||
// ### krow
|
// ### krow
|
||||||
initEPSParam(cell, eps_transf_[cell].watoil, true, 0.0, funcForCell(cell).sowcr_, funcForCell(cell).smin_[wpos], funcForCell(cell).swcr_,
|
initEPSParam(cell, eps_transf_[cell].watoil, true,
|
||||||
funcForCell(cell).smin_[gpos], funcForCell(cell).krorw_, funcForCell(cell).kromax_, swl, sowcr, swl, swcr, sgl, krorw, kro);
|
0.0,
|
||||||
|
funcForCell(cell).sowcr_,
|
||||||
|
funcForCell(cell).smin_[wpos],
|
||||||
|
funcForCell(cell).swcr_,
|
||||||
|
funcForCell(cell).smin_[gpos],
|
||||||
|
funcForCell(cell).krorw_,
|
||||||
|
funcForCell(cell).kromax_,
|
||||||
|
0.0,
|
||||||
|
swl, sowcr, swl, swcr, sgl, krorw, kro, dummy);
|
||||||
// ### krg
|
// ### krg
|
||||||
initEPSParam(cell, eps_transf_[cell].gas, false, funcForCell(cell).smin_[gpos], funcForCell(cell).sgcr_, funcForCell(cell).smax_[gpos], funcForCell(cell).sogcr_,
|
initEPSParam(cell, eps_transf_[cell].gas, false,
|
||||||
funcForCell(cell).smin_[wpos], funcForCell(cell).krgr_, funcForCell(cell).krgmax_, sgl, sgcr, sgu, sogcr, swl, krgr, krg);
|
funcForCell(cell).smin_[gpos],
|
||||||
|
funcForCell(cell).sgcr_,
|
||||||
|
funcForCell(cell).smax_[gpos],
|
||||||
|
funcForCell(cell).sogcr_,
|
||||||
|
funcForCell(cell).smin_[wpos],
|
||||||
|
funcForCell(cell).krgr_,
|
||||||
|
funcForCell(cell).krgmax_,
|
||||||
|
funcForCell(cell).pcgmax_,
|
||||||
|
sgl, sgcr, sgu, sogcr, swl, krgr, krg, pcg);
|
||||||
// ### krog
|
// ### krog
|
||||||
initEPSParam(cell, eps_transf_[cell].gasoil, true, 0.0, funcForCell(cell).sogcr_, funcForCell(cell).smin_[gpos], funcForCell(cell).sgcr_,
|
initEPSParam(cell, eps_transf_[cell].gasoil, true,
|
||||||
funcForCell(cell).smin_[wpos], funcForCell(cell).krorg_, funcForCell(cell).kromax_, sgl, sogcr, sgl, sgcr, swl, krorg, kro);
|
0.0,
|
||||||
|
funcForCell(cell).sogcr_,
|
||||||
|
funcForCell(cell).smin_[gpos],
|
||||||
|
funcForCell(cell).sgcr_,
|
||||||
|
funcForCell(cell).smin_[wpos],
|
||||||
|
funcForCell(cell).krorg_,
|
||||||
|
funcForCell(cell).kromax_,
|
||||||
|
0.0,
|
||||||
|
sgl, sogcr, sgl, sgcr, swl, krorg, kro, dummy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -514,6 +617,8 @@ namespace Opm
|
|||||||
{
|
{
|
||||||
std::vector<double> iswl, iswcr, iswu, isgl, isgcr, isgu, isowcr, isogcr;
|
std::vector<double> iswl, iswcr, iswu, isgl, isgcr, isgu, isowcr, isogcr;
|
||||||
std::vector<double> ikrw, ikrg, ikro, ikrwr, ikrgr, ikrorw, ikrorg;
|
std::vector<double> ikrw, ikrg, ikro, ikrwr, ikrgr, ikrorw, ikrorg;
|
||||||
|
std::vector<double> ipcw, ipcg;
|
||||||
|
const std::vector<double> dummy;
|
||||||
// Initialize hysteresis saturation scaling parameters
|
// Initialize hysteresis saturation scaling parameters
|
||||||
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions,
|
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions,
|
||||||
std::string("ISWL"), iswl);
|
std::string("ISWL"), iswl);
|
||||||
@ -545,6 +650,10 @@ namespace Opm
|
|||||||
std::string("IKRORW"), ikrorw);
|
std::string("IKRORW"), ikrorw);
|
||||||
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions,
|
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions,
|
||||||
std::string("IKRORG"), ikrorg);
|
std::string("IKRORG"), ikrorg);
|
||||||
|
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions,
|
||||||
|
std::string("IPCW"), ipcw);
|
||||||
|
initEPSKey(deck, number_of_cells, global_cell, begin_cell_centroid, dimensions,
|
||||||
|
std::string("IPCG"), ipcg);
|
||||||
|
|
||||||
eps_transf_hyst_.resize(number_of_cells);
|
eps_transf_hyst_.resize(number_of_cells);
|
||||||
sat_hyst_.resize(number_of_cells);
|
sat_hyst_.resize(number_of_cells);
|
||||||
@ -558,31 +667,95 @@ namespace Opm
|
|||||||
for (int cell = 0; cell < number_of_cells; ++cell) {
|
for (int cell = 0; cell < number_of_cells; ++cell) {
|
||||||
if (oilWater) {
|
if (oilWater) {
|
||||||
// ### krw
|
// ### krw
|
||||||
initEPSParam(cell, eps_transf_hyst_[cell].wat, false, funcForCell(cell).smin_[wpos], funcForCell(cell).swcr_, funcForCell(cell).smax_[wpos],
|
initEPSParam(cell, eps_transf_hyst_[cell].wat, false,
|
||||||
funcForCell(cell).sowcr_, -1.0, funcForCell(cell).krwr_, funcForCell(cell).krwmax_, iswl, iswcr, iswu, isowcr, isgl, ikrwr, ikrw);
|
funcForCell(cell).smin_[wpos],
|
||||||
|
funcForCell(cell).swcr_,
|
||||||
|
funcForCell(cell).smax_[wpos],
|
||||||
|
funcForCell(cell).sowcr_,
|
||||||
|
-1.0,
|
||||||
|
funcForCell(cell).krwr_,
|
||||||
|
funcForCell(cell).krwmax_,
|
||||||
|
funcForCell(cell).pcwmax_,
|
||||||
|
iswl, iswcr, iswu, isowcr, isgl, ikrwr, ikrw, ipcw);
|
||||||
// ### krow
|
// ### krow
|
||||||
initEPSParam(cell, eps_transf_hyst_[cell].watoil, true, 0.0, funcForCell(cell).sowcr_, funcForCell(cell).smin_[wpos],
|
initEPSParam(cell, eps_transf_hyst_[cell].watoil, true,
|
||||||
funcForCell(cell).swcr_, -1.0, funcForCell(cell).krorw_, funcForCell(cell).kromax_, iswl, isowcr, iswl, iswcr, isgl, ikrorw, ikro);
|
0.0,
|
||||||
|
funcForCell(cell).sowcr_,
|
||||||
|
funcForCell(cell).smin_[wpos],
|
||||||
|
funcForCell(cell).swcr_,
|
||||||
|
-1.0,
|
||||||
|
funcForCell(cell).krorw_,
|
||||||
|
funcForCell(cell).kromax_,
|
||||||
|
0.0,
|
||||||
|
iswl, isowcr, iswl, iswcr, isgl, ikrorw, ikro, dummy);
|
||||||
} else if (oilGas) {
|
} else if (oilGas) {
|
||||||
// ### krg
|
// ### krg
|
||||||
initEPSParam(cell, eps_transf_hyst_[cell].gas, false, funcForCell(cell).smin_[gpos], funcForCell(cell).sgcr_, funcForCell(cell).smax_[gpos],
|
initEPSParam(cell, eps_transf_hyst_[cell].gas, false,
|
||||||
funcForCell(cell).sogcr_, -1.0, funcForCell(cell).krgr_, funcForCell(cell).krgmax_, isgl, isgcr, isgu, isogcr, iswl, ikrgr, ikrg);
|
funcForCell(cell).smin_[gpos],
|
||||||
|
funcForCell(cell).sgcr_,
|
||||||
|
funcForCell(cell).smax_[gpos],
|
||||||
|
funcForCell(cell).sogcr_,
|
||||||
|
-1.0,
|
||||||
|
funcForCell(cell).krgr_,
|
||||||
|
funcForCell(cell).krgmax_,
|
||||||
|
funcForCell(cell).pcgmax_,
|
||||||
|
isgl, isgcr, isgu, isogcr, iswl, ikrgr, ikrg, ipcg);
|
||||||
// ### krog
|
// ### krog
|
||||||
initEPSParam(cell, eps_transf_hyst_[cell].gasoil, true, 0.0, funcForCell(cell).sogcr_, funcForCell(cell).smin_[gpos],
|
initEPSParam(cell, eps_transf_hyst_[cell].gasoil, true,
|
||||||
funcForCell(cell).sgcr_, -1.0, funcForCell(cell).krorg_, funcForCell(cell).kromax_, isgl, isogcr, isgl, isgcr, iswl, ikrorg, ikro);
|
0.0,
|
||||||
|
funcForCell(cell).sogcr_,
|
||||||
|
funcForCell(cell).smin_[gpos],
|
||||||
|
funcForCell(cell).sgcr_,
|
||||||
|
-1.0,
|
||||||
|
funcForCell(cell).krorg_,
|
||||||
|
funcForCell(cell).kromax_,
|
||||||
|
0.0,
|
||||||
|
isgl, isogcr, isgl, isgcr, iswl, ikrorg, ikro, dummy);
|
||||||
} else if (threephase) {
|
} else if (threephase) {
|
||||||
// ### krw
|
// ### krw
|
||||||
initEPSParam(cell, eps_transf_hyst_[cell].wat, false, funcForCell(cell).smin_[wpos], funcForCell(cell).swcr_, funcForCell(cell).smax_[wpos], funcForCell(cell).sowcr_,
|
initEPSParam(cell, eps_transf_hyst_[cell].wat, false,
|
||||||
funcForCell(cell).smin_[gpos], funcForCell(cell).krwr_, funcForCell(cell).krwmax_, iswl, iswcr, iswu, isowcr, isgl, ikrwr, ikrw);
|
funcForCell(cell).smin_[wpos],
|
||||||
|
funcForCell(cell).swcr_,
|
||||||
|
funcForCell(cell).smax_[wpos],
|
||||||
|
funcForCell(cell).sowcr_,
|
||||||
|
funcForCell(cell).smin_[gpos],
|
||||||
|
funcForCell(cell).krwr_,
|
||||||
|
funcForCell(cell).krwmax_,
|
||||||
|
funcForCell(cell).pcwmax_,
|
||||||
|
iswl, iswcr, iswu, isowcr, isgl, ikrwr, ikrw, ipcw);
|
||||||
// ### krow
|
// ### krow
|
||||||
initEPSParam(cell, eps_transf_hyst_[cell].watoil, true, 0.0, funcForCell(cell).sowcr_, funcForCell(cell).smin_[wpos], funcForCell(cell).swcr_,
|
initEPSParam(cell, eps_transf_hyst_[cell].watoil, true,
|
||||||
funcForCell(cell).smin_[gpos], funcForCell(cell).krorw_, funcForCell(cell).kromax_, iswl, isowcr, iswl, iswcr, isgl, ikrorw, ikro);
|
0.0,
|
||||||
|
funcForCell(cell).sowcr_,
|
||||||
|
funcForCell(cell).smin_[wpos],
|
||||||
|
funcForCell(cell).swcr_,
|
||||||
|
funcForCell(cell).smin_[gpos],
|
||||||
|
funcForCell(cell).krorw_,
|
||||||
|
funcForCell(cell).kromax_,
|
||||||
|
0.0,
|
||||||
|
iswl, isowcr, iswl, iswcr, isgl, ikrorw, ikro, dummy);
|
||||||
// ### krg
|
// ### krg
|
||||||
initEPSParam(cell, eps_transf_hyst_[cell].gas, false, funcForCell(cell).smin_[gpos], funcForCell(cell).sgcr_, funcForCell(cell).smax_[gpos], funcForCell(cell).sogcr_,
|
initEPSParam(cell, eps_transf_hyst_[cell].gas, false,
|
||||||
funcForCell(cell).smin_[wpos], funcForCell(cell).krgr_, funcForCell(cell).krgmax_, isgl, isgcr, isgu, isogcr, iswl, ikrgr, ikrg);
|
funcForCell(cell).smin_[gpos],
|
||||||
|
funcForCell(cell).sgcr_,
|
||||||
|
funcForCell(cell).smax_[gpos],
|
||||||
|
funcForCell(cell).sogcr_,
|
||||||
|
funcForCell(cell).smin_[wpos],
|
||||||
|
funcForCell(cell).krgr_,
|
||||||
|
funcForCell(cell).krgmax_,
|
||||||
|
funcForCell(cell).pcgmax_,
|
||||||
|
isgl, isgcr, isgu, isogcr, iswl, ikrgr, ikrg, ipcg);
|
||||||
// ### krog
|
// ### krog
|
||||||
initEPSParam(cell, eps_transf_hyst_[cell].gasoil, true, 0.0, funcForCell(cell).sogcr_, funcForCell(cell).smin_[gpos], funcForCell(cell).sgcr_,
|
initEPSParam(cell, eps_transf_hyst_[cell].gasoil, true,
|
||||||
funcForCell(cell).smin_[wpos], funcForCell(cell).krorg_, funcForCell(cell).kromax_, isgl, isogcr, isgl, isgcr, iswl, ikrorg, ikro);
|
0.0,
|
||||||
|
funcForCell(cell).sogcr_,
|
||||||
|
funcForCell(cell).smin_[gpos],
|
||||||
|
funcForCell(cell).sgcr_,
|
||||||
|
funcForCell(cell).smin_[wpos],
|
||||||
|
funcForCell(cell).krorg_,
|
||||||
|
funcForCell(cell).kromax_,
|
||||||
|
0.0,
|
||||||
|
isgl, isogcr, isgl, isgcr, iswl, ikrorg, ikro, dummy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -747,6 +920,16 @@ namespace Opm
|
|||||||
param_col[table_num] = enkrvd.getColumn(itab); // itab=[1-7]: krw krg kro krwr krgr krorw krorg
|
param_col[table_num] = enkrvd.getColumn(itab); // itab=[1-7]: krw krg kro krwr krgr krorw krorg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (useKeyword && (keyword[0] == 'P' || keyword[1] == 'P') ) {
|
||||||
|
if (useAqua && (keyword == std::string("PCW") || keyword == std::string("IPCW")) ) {
|
||||||
|
scaleparam.resize(number_of_cells);
|
||||||
|
for (int i=0; i<number_of_cells; ++i)
|
||||||
|
scaleparam[i] = funcForCell(i).pcwmax_;
|
||||||
|
} else if (useVapour && (keyword == std::string("PCG") || keyword == std::string("IPCG")) ) {
|
||||||
|
scaleparam.resize(number_of_cells);
|
||||||
|
for (int i=0; i<number_of_cells; ++i)
|
||||||
|
scaleparam[i] = funcForCell(i).pcgmax_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scaleparam.empty()) {
|
if (scaleparam.empty()) {
|
||||||
@ -802,13 +985,15 @@ namespace Opm
|
|||||||
const double s0_tab, // threephase complementary minimum saturation (-1.0 indicates 2-phase)
|
const double s0_tab, // threephase complementary minimum saturation (-1.0 indicates 2-phase)
|
||||||
const double krsr_tab, // relperm at displacing critical saturation
|
const double krsr_tab, // relperm at displacing critical saturation
|
||||||
const double krmax_tab, // relperm at maximum saturation
|
const double krmax_tab, // relperm at maximum saturation
|
||||||
|
const double pcmax_tab, // cap-pres at maximum saturation (zero => no scaling)
|
||||||
const std::vector<double>& sl, // For krow/krog calculations this is not used
|
const std::vector<double>& sl, // For krow/krog calculations this is not used
|
||||||
const std::vector<double>& scr,
|
const std::vector<double>& scr,
|
||||||
const std::vector<double>& su, // For krow/krog calculations this is SWL/SGL
|
const std::vector<double>& su, // For krow/krog calculations this is SWL/SGL
|
||||||
const std::vector<double>& sxcr,
|
const std::vector<double>& sxcr,
|
||||||
const std::vector<double>& s0,
|
const std::vector<double>& s0,
|
||||||
const std::vector<double>& krsr,
|
const std::vector<double>& krsr,
|
||||||
const std::vector<double>& krmax)
|
const std::vector<double>& krmax,
|
||||||
|
const std::vector<double>& pcmax) // For krow/krog calculations this is not used
|
||||||
{
|
{
|
||||||
if (scr.empty() && su.empty() && (sxcr.empty() || !do_3pt_) && s0.empty()) {
|
if (scr.empty() && su.empty() && (sxcr.empty() || !do_3pt_) && s0.empty()) {
|
||||||
data.doNotScale = true;
|
data.doNotScale = true;
|
||||||
@ -876,6 +1061,12 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (std::fabs(pcmax_tab) < 1.0e-8 || pcmax.empty() || pcmax_tab*pcmax[cell] < 0.0) {
|
||||||
|
data.pcFactor = 1.0;
|
||||||
|
} else {
|
||||||
|
data.pcFactor = pcmax[cell]/pcmax_tab;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
@ -81,6 +81,13 @@ namespace Opm
|
|||||||
const int* cells,
|
const int* cells,
|
||||||
const double* s) = 0;
|
const double* s) = 0;
|
||||||
|
|
||||||
|
/// Update capillary pressure scaling according to pressure diff. and initial water saturation.
|
||||||
|
/// \param[in] cell Cell index.
|
||||||
|
/// \param[in] pcow P_oil - P_water.
|
||||||
|
/// \param[in/out] swat Water saturation. / Possibly modified Water saturation.
|
||||||
|
virtual void swatInitScaling(const int cell,
|
||||||
|
const double pcow,
|
||||||
|
double & swat) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <opm/core/utility/Units.hpp>
|
#include <opm/core/utility/Units.hpp>
|
||||||
#include <opm/parser/eclipse/Utility/EquilWrapper.hpp>
|
#include <opm/parser/eclipse/Utility/EquilWrapper.hpp>
|
||||||
#include <opm/parser/eclipse/Utility/SingleRecordTable.hpp>
|
#include <opm/parser/eclipse/Utility/SingleRecordTable.hpp>
|
||||||
|
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@ -62,6 +63,7 @@ namespace Opm
|
|||||||
void initStateEquil(const UnstructuredGrid& grid,
|
void initStateEquil(const UnstructuredGrid& grid,
|
||||||
const BlackoilPropertiesInterface& props,
|
const BlackoilPropertiesInterface& props,
|
||||||
const Opm::DeckConstPtr deck,
|
const Opm::DeckConstPtr deck,
|
||||||
|
const Opm::EclipseStateConstPtr eclipseState,
|
||||||
const double gravity,
|
const double gravity,
|
||||||
BlackoilState& state);
|
BlackoilState& state);
|
||||||
|
|
||||||
@ -150,8 +152,9 @@ namespace Opm
|
|||||||
std::vector< std::vector<double> >
|
std::vector< std::vector<double> >
|
||||||
phaseSaturations(const Region& reg,
|
phaseSaturations(const Region& reg,
|
||||||
const CellRange& cells,
|
const CellRange& cells,
|
||||||
const BlackoilPropertiesInterface& props,
|
BlackoilPropertiesInterface& props,
|
||||||
const std::vector< std::vector<double> >& phase_pressures);
|
const std::vector<double> swat_init,
|
||||||
|
std::vector< std::vector<double> >& phase_pressures);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -229,13 +232,14 @@ namespace Opm
|
|||||||
inline
|
inline
|
||||||
std::vector<int>
|
std::vector<int>
|
||||||
equilnum(const Opm::DeckConstPtr deck,
|
equilnum(const Opm::DeckConstPtr deck,
|
||||||
|
const Opm::EclipseStateConstPtr eclipseState,
|
||||||
const UnstructuredGrid& G )
|
const UnstructuredGrid& G )
|
||||||
{
|
{
|
||||||
std::vector<int> eqlnum;
|
std::vector<int> eqlnum;
|
||||||
if (deck->hasKeyword("EQLNUM")) {
|
if (deck->hasKeyword("EQLNUM")) {
|
||||||
eqlnum.resize(G.number_of_cells);
|
eqlnum.resize(G.number_of_cells);
|
||||||
const std::vector<int>& e =
|
const std::vector<int>& e =
|
||||||
deck->getKeyword("EQLNUM")->getIntData();
|
eclipseState->getIntGridProperty("EQLNUM")->getData();
|
||||||
const int* gc = G.global_cell;
|
const int* gc = G.global_cell;
|
||||||
for (int cell = 0; cell < G.number_of_cells; ++cell) {
|
for (int cell = 0; cell < G.number_of_cells; ++cell) {
|
||||||
const int deck_pos = (gc == NULL) ? cell : gc[cell];
|
const int deck_pos = (gc == NULL) ? cell : gc[cell];
|
||||||
@ -254,8 +258,9 @@ namespace Opm
|
|||||||
|
|
||||||
class InitialStateComputer {
|
class InitialStateComputer {
|
||||||
public:
|
public:
|
||||||
InitialStateComputer(const BlackoilPropertiesInterface& props,
|
InitialStateComputer(BlackoilPropertiesInterface& props,
|
||||||
const Opm::DeckConstPtr deck,
|
const Opm::DeckConstPtr deck,
|
||||||
|
const Opm::EclipseStateConstPtr eclipseState,
|
||||||
const UnstructuredGrid& G ,
|
const UnstructuredGrid& G ,
|
||||||
const double grav = unit::gravity)
|
const double grav = unit::gravity)
|
||||||
: pp_(props.numPhases(),
|
: pp_(props.numPhases(),
|
||||||
@ -269,7 +274,7 @@ namespace Opm
|
|||||||
const std::vector<EquilRecord> rec = getEquil(deck);
|
const std::vector<EquilRecord> rec = getEquil(deck);
|
||||||
|
|
||||||
// Create (inverse) region mapping.
|
// Create (inverse) region mapping.
|
||||||
const RegionMapping<> eqlmap(equilnum(deck, G));
|
const RegionMapping<> eqlmap(equilnum(deck, eclipseState, G));
|
||||||
|
|
||||||
// Create Rs functions.
|
// Create Rs functions.
|
||||||
rs_func_.reserve(rec.size());
|
rs_func_.reserve(rec.size());
|
||||||
@ -334,6 +339,18 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check for presence of kw SWATINIT
|
||||||
|
if (deck->hasKeyword("SWATINIT")) {
|
||||||
|
const std::vector<double>& swat_init = eclipseState->getDoubleGridProperty("SWATINIT")->getData();
|
||||||
|
swat_init_.resize(G.number_of_cells);
|
||||||
|
const int* gc = G.global_cell;
|
||||||
|
for (int c = 0; c < G.number_of_cells; ++c) {
|
||||||
|
const int deck_pos = (gc == NULL) ? c : gc[c];
|
||||||
|
swat_init_[c] = swat_init[deck_pos];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Compute pressures, saturations, rs and rv factors.
|
// Compute pressures, saturations, rs and rv factors.
|
||||||
calcPressSatRsRv(eqlmap, rec, props, G, grav);
|
calcPressSatRsRv(eqlmap, rec, props, G, grav);
|
||||||
|
|
||||||
@ -360,15 +377,18 @@ namespace Opm
|
|||||||
PVec sat_;
|
PVec sat_;
|
||||||
Vec rs_;
|
Vec rs_;
|
||||||
Vec rv_;
|
Vec rv_;
|
||||||
|
Vec swat_init_;
|
||||||
|
|
||||||
template <class RMap>
|
template <class RMap>
|
||||||
void
|
void
|
||||||
calcPressSatRsRv(const RMap& reg ,
|
calcPressSatRsRv(const RMap& reg ,
|
||||||
const std::vector< EquilRecord >& rec ,
|
const std::vector< EquilRecord >& rec ,
|
||||||
const Opm::BlackoilPropertiesInterface& props,
|
Opm::BlackoilPropertiesInterface& props,
|
||||||
const UnstructuredGrid& G ,
|
const UnstructuredGrid& G ,
|
||||||
const double grav)
|
const double grav)
|
||||||
{
|
{
|
||||||
|
typedef Miscibility::NoMixing NoMix;
|
||||||
|
|
||||||
for (typename RMap::RegionId
|
for (typename RMap::RegionId
|
||||||
r = 0, nr = reg.numRegions();
|
r = 0, nr = reg.numRegions();
|
||||||
r < nr; ++r)
|
r < nr; ++r)
|
||||||
@ -383,7 +403,7 @@ namespace Opm
|
|||||||
|
|
||||||
PVec press = phasePressures(G, eqreg, cells, grav);
|
PVec press = phasePressures(G, eqreg, cells, grav);
|
||||||
|
|
||||||
const PVec sat = phaseSaturations(eqreg, cells, props, press);
|
const PVec sat = phaseSaturations(eqreg, cells, props, swat_init_, press);
|
||||||
|
|
||||||
const int np = props.numPhases();
|
const int np = props.numPhases();
|
||||||
for (int p = 0; p < np; ++p) {
|
for (int p = 0; p < np; ++p) {
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include <opm/core/grid.h>
|
#include <opm/core/grid.h>
|
||||||
#include <opm/core/props/BlackoilPhases.hpp>
|
#include <opm/core/props/BlackoilPhases.hpp>
|
||||||
|
#include <opm/core/simulator/initState.hpp>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@ -579,7 +580,8 @@ namespace Opm
|
|||||||
std::vector< std::vector<double> >
|
std::vector< std::vector<double> >
|
||||||
phaseSaturations(const Region& reg,
|
phaseSaturations(const Region& reg,
|
||||||
const CellRange& cells,
|
const CellRange& cells,
|
||||||
const BlackoilPropertiesInterface& props,
|
BlackoilPropertiesInterface& props,
|
||||||
|
const std::vector<double> swat_init,
|
||||||
std::vector< std::vector<double> >& phase_pressures)
|
std::vector< std::vector<double> >& phase_pressures)
|
||||||
{
|
{
|
||||||
const double z0 = reg.datum();
|
const double z0 = reg.datum();
|
||||||
@ -610,8 +612,14 @@ namespace Opm
|
|||||||
double sw = 0.0;
|
double sw = 0.0;
|
||||||
if (water) {
|
if (water) {
|
||||||
const double pcov = phase_pressures[oilpos][local_index] - phase_pressures[waterpos][local_index];
|
const double pcov = phase_pressures[oilpos][local_index] - phase_pressures[waterpos][local_index];
|
||||||
|
if (swat_init.empty()) { // Invert Pc to find sw
|
||||||
sw = satFromPc(props, waterpos, cell, pcov);
|
sw = satFromPc(props, waterpos, cell, pcov);
|
||||||
phase_saturations[waterpos][local_index] = sw;
|
phase_saturations[waterpos][local_index] = sw;
|
||||||
|
} else { // Scale Pc to reflect imposed sw
|
||||||
|
sw = swat_init[cell];
|
||||||
|
props.swatInitScaling(cell, pcov, sw);
|
||||||
|
phase_saturations[waterpos][local_index] = sw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
double sg = 0.0;
|
double sg = 0.0;
|
||||||
if (gas) {
|
if (gas) {
|
||||||
@ -621,18 +629,28 @@ namespace Opm
|
|||||||
sg = satFromPc(props, gaspos, cell, pcog, increasing);
|
sg = satFromPc(props, gaspos, cell, pcog, increasing);
|
||||||
phase_saturations[gaspos][local_index] = sg;
|
phase_saturations[gaspos][local_index] = sg;
|
||||||
}
|
}
|
||||||
bool overlap = false;
|
|
||||||
if (gas && water && (sg + sw > 1.0)) {
|
if (gas && water && (sg + sw > 1.0)) {
|
||||||
// Overlapping gas-oil and oil-water transition
|
// Overlapping gas-oil and oil-water transition
|
||||||
// zones can lead to unphysical saturations when
|
// zones can lead to unphysical saturations when
|
||||||
// treated as above. Must recalculate using gas-water
|
// treated as above. Must recalculate using gas-water
|
||||||
// capillary pressure.
|
// capillary pressure.
|
||||||
const double pcgw = phase_pressures[gaspos][local_index] - phase_pressures[waterpos][local_index];
|
const double pcgw = phase_pressures[gaspos][local_index] - phase_pressures[waterpos][local_index];
|
||||||
|
if (! swat_init.empty()) {
|
||||||
|
// Re-scale Pc to reflect imposed sw for vanishing oil phase.
|
||||||
|
// This seems consistent with ecl, and fails to honour
|
||||||
|
// swat_init in case of non-trivial gas-oil cap pressure.
|
||||||
|
props.swatInitScaling(cell, pcgw, sw);
|
||||||
|
}
|
||||||
sw = satFromSumOfPcs(props, waterpos, gaspos, cell, pcgw);
|
sw = satFromSumOfPcs(props, waterpos, gaspos, cell, pcgw);
|
||||||
sg = 1.0 - sw;
|
sg = 1.0 - sw;
|
||||||
phase_saturations[waterpos][local_index] = sw;
|
phase_saturations[waterpos][local_index] = sw;
|
||||||
phase_saturations[gaspos][local_index] = sg;
|
phase_saturations[gaspos][local_index] = sg;
|
||||||
overlap = true;
|
// Adjust oil pressure according to gas saturation and cap pressure
|
||||||
|
double pc[BlackoilPhases::MaxNumPhases];
|
||||||
|
double sat[BlackoilPhases::MaxNumPhases];
|
||||||
|
sat[gaspos] = sg;
|
||||||
|
props.capPress(1, sat, &cell, pc, 0);
|
||||||
|
phase_pressures[oilpos][local_index] = phase_pressures[gaspos][local_index] - pc[gaspos];
|
||||||
}
|
}
|
||||||
phase_saturations[oilpos][local_index] = 1.0 - sw - sg;
|
phase_saturations[oilpos][local_index] = 1.0 - sw - sg;
|
||||||
|
|
||||||
@ -643,7 +661,7 @@ namespace Opm
|
|||||||
sat[waterpos] = smax[waterpos];
|
sat[waterpos] = smax[waterpos];
|
||||||
props.capPress(1, sat, &cell, pc, 0);
|
props.capPress(1, sat, &cell, pc, 0);
|
||||||
phase_pressures[oilpos][local_index] = phase_pressures[waterpos][local_index] + pc[waterpos];
|
phase_pressures[oilpos][local_index] = phase_pressures[waterpos][local_index] + pc[waterpos];
|
||||||
} else if (overlap || sg > smax[gaspos]-1.0e-6) {
|
} else if (sg > smax[gaspos]-1.0e-6) {
|
||||||
sat[gaspos] = smax[gaspos];
|
sat[gaspos] = smax[gaspos];
|
||||||
props.capPress(1, sat, &cell, pc, 0);
|
props.capPress(1, sat, &cell, pc, 0);
|
||||||
phase_pressures[oilpos][local_index] = phase_pressures[gaspos][local_index] - pc[gaspos];
|
phase_pressures[oilpos][local_index] = phase_pressures[gaspos][local_index] - pc[gaspos];
|
||||||
@ -736,13 +754,14 @@ namespace Opm
|
|||||||
* \param[in] gravity Acceleration of gravity, assumed to be in Z direction.
|
* \param[in] gravity Acceleration of gravity, assumed to be in Z direction.
|
||||||
*/
|
*/
|
||||||
void initStateEquil(const UnstructuredGrid& grid,
|
void initStateEquil(const UnstructuredGrid& grid,
|
||||||
const BlackoilPropertiesInterface& props,
|
BlackoilPropertiesInterface& props,
|
||||||
const Opm::DeckConstPtr deck,
|
const Opm::DeckConstPtr deck,
|
||||||
|
const Opm::EclipseStateConstPtr eclipseState,
|
||||||
const double gravity,
|
const double gravity,
|
||||||
BlackoilState& state)
|
BlackoilState& state)
|
||||||
{
|
{
|
||||||
typedef Equil::DeckDependent::InitialStateComputer ISC;
|
typedef Equil::DeckDependent::InitialStateComputer ISC;
|
||||||
ISC isc(props, deck, grid, gravity);
|
ISC isc(props, deck, eclipseState, grid, gravity);
|
||||||
const auto pu = props.phaseUsage();
|
const auto pu = props.phaseUsage();
|
||||||
const int ref_phase = pu.phase_used[BlackoilPhases::Liquid]
|
const int ref_phase = pu.phase_used[BlackoilPhases::Liquid]
|
||||||
? pu.phase_pos[BlackoilPhases::Liquid]
|
? pu.phase_pos[BlackoilPhases::Liquid]
|
||||||
@ -751,7 +770,7 @@ namespace Opm
|
|||||||
state.saturation() = convertSats(isc.saturation());
|
state.saturation() = convertSats(isc.saturation());
|
||||||
state.gasoilratio() = isc.rs();
|
state.gasoilratio() = isc.rs();
|
||||||
state.rv() = isc.rv();
|
state.rv() = isc.rv();
|
||||||
// TODO: state.surfacevol() must be computed from s, rs, rv.
|
initBlackoilSurfvolUsingRSorRV(grid, props, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -338,7 +338,7 @@ BOOST_AUTO_TEST_CASE (DeckAllDead)
|
|||||||
Opm::DeckConstPtr deck = parser->parseFile("deadfluids.DATA");
|
Opm::DeckConstPtr deck = parser->parseFile("deadfluids.DATA");
|
||||||
Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck));
|
Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck));
|
||||||
Opm::BlackoilPropertiesFromDeck props(deck, eclipseState, *grid, false);
|
Opm::BlackoilPropertiesFromDeck props(deck, eclipseState, *grid, false);
|
||||||
Opm::Equil::DeckDependent::InitialStateComputer comp(props, deck, *grid, 10.0);
|
Opm::Equil::DeckDependent::InitialStateComputer comp(props, deck, eclipseState, *grid, 10.0);
|
||||||
const auto& pressures = comp.press();
|
const auto& pressures = comp.press();
|
||||||
BOOST_REQUIRE(pressures.size() == 3);
|
BOOST_REQUIRE(pressures.size() == 3);
|
||||||
BOOST_REQUIRE(int(pressures[0].size()) == grid->number_of_cells);
|
BOOST_REQUIRE(int(pressures[0].size()) == grid->number_of_cells);
|
||||||
@ -419,7 +419,7 @@ BOOST_AUTO_TEST_CASE (DeckWithCapillary)
|
|||||||
Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck));
|
Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck));
|
||||||
Opm::BlackoilPropertiesFromDeck props(deck, eclipseState, grid, false);
|
Opm::BlackoilPropertiesFromDeck props(deck, eclipseState, grid, false);
|
||||||
|
|
||||||
Opm::Equil::DeckDependent::InitialStateComputer comp(props, deck, grid, 10.0);
|
Opm::Equil::DeckDependent::InitialStateComputer comp(props, deck, eclipseState, grid, 10.0);
|
||||||
const auto& pressures = comp.press();
|
const auto& pressures = comp.press();
|
||||||
BOOST_REQUIRE(pressures.size() == 3);
|
BOOST_REQUIRE(pressures.size() == 3);
|
||||||
BOOST_REQUIRE(int(pressures[0].size()) == grid.number_of_cells);
|
BOOST_REQUIRE(int(pressures[0].size()) == grid.number_of_cells);
|
||||||
@ -459,7 +459,7 @@ BOOST_AUTO_TEST_CASE (DeckWithCapillaryOverlap)
|
|||||||
Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck));
|
Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck));
|
||||||
Opm::BlackoilPropertiesFromDeck props(deck, eclipseState, grid, false);
|
Opm::BlackoilPropertiesFromDeck props(deck, eclipseState, grid, false);
|
||||||
|
|
||||||
Opm::Equil::DeckDependent::InitialStateComputer comp(props, deck, grid, 9.80665);
|
Opm::Equil::DeckDependent::InitialStateComputer comp(props, deck, eclipseState, grid, 9.80665);
|
||||||
const auto& pressures = comp.press();
|
const auto& pressures = comp.press();
|
||||||
BOOST_REQUIRE(pressures.size() == 3);
|
BOOST_REQUIRE(pressures.size() == 3);
|
||||||
BOOST_REQUIRE(int(pressures[0].size()) == grid.number_of_cells);
|
BOOST_REQUIRE(int(pressures[0].size()) == grid.number_of_cells);
|
||||||
@ -521,7 +521,7 @@ BOOST_AUTO_TEST_CASE (DeckWithLiveOil)
|
|||||||
Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck));
|
Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck));
|
||||||
Opm::BlackoilPropertiesFromDeck props(deck, eclipseState, grid, false);
|
Opm::BlackoilPropertiesFromDeck props(deck, eclipseState, grid, false);
|
||||||
|
|
||||||
Opm::Equil::DeckDependent::InitialStateComputer comp(props, deck, grid, 9.80665);
|
Opm::Equil::DeckDependent::InitialStateComputer comp(props, deck, eclipseState, grid, 9.80665);
|
||||||
const auto& pressures = comp.press();
|
const auto& pressures = comp.press();
|
||||||
BOOST_REQUIRE(pressures.size() == 3);
|
BOOST_REQUIRE(pressures.size() == 3);
|
||||||
BOOST_REQUIRE(int(pressures[0].size()) == grid.number_of_cells);
|
BOOST_REQUIRE(int(pressures[0].size()) == grid.number_of_cells);
|
||||||
@ -600,7 +600,7 @@ BOOST_AUTO_TEST_CASE (DeckWithLiveGas)
|
|||||||
Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck));
|
Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck));
|
||||||
Opm::BlackoilPropertiesFromDeck props(deck, eclipseState, grid, false);
|
Opm::BlackoilPropertiesFromDeck props(deck, eclipseState, grid, false);
|
||||||
|
|
||||||
Opm::Equil::DeckDependent::InitialStateComputer comp(props, deck, grid, 9.80665);
|
Opm::Equil::DeckDependent::InitialStateComputer comp(props, deck, eclipseState, grid, 9.80665);
|
||||||
const auto& pressures = comp.press();
|
const auto& pressures = comp.press();
|
||||||
BOOST_REQUIRE(pressures.size() == 3);
|
BOOST_REQUIRE(pressures.size() == 3);
|
||||||
BOOST_REQUIRE(int(pressures[0].size()) == grid.number_of_cells);
|
BOOST_REQUIRE(int(pressures[0].size()) == grid.number_of_cells);
|
||||||
@ -682,7 +682,7 @@ BOOST_AUTO_TEST_CASE (DeckWithRSVDAndRVVD)
|
|||||||
Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck));
|
Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck));
|
||||||
Opm::BlackoilPropertiesFromDeck props(deck, eclipseState, grid, false);
|
Opm::BlackoilPropertiesFromDeck props(deck, eclipseState, grid, false);
|
||||||
|
|
||||||
Opm::Equil::DeckDependent::InitialStateComputer comp(props, deck, grid, 9.80665);
|
Opm::Equil::DeckDependent::InitialStateComputer comp(props, deck, eclipseState, grid, 9.80665);
|
||||||
const auto& pressures = comp.press();
|
const auto& pressures = comp.press();
|
||||||
BOOST_REQUIRE(pressures.size() == 3);
|
BOOST_REQUIRE(pressures.size() == 3);
|
||||||
BOOST_REQUIRE(int(pressures[0].size()) == grid.number_of_cells);
|
BOOST_REQUIRE(int(pressures[0].size()) == grid.number_of_cells);
|
||||||
|
Loading…
Reference in New Issue
Block a user