void SaturationPropsFromDeck<SatFuncSet>::init(const EclipseGridParser& deck, const UnstructuredGrid& grid, const int samples) { phase_usage_ = phaseUsageFromDeck(deck); // Extract input data. // Oil phase should be active. if (!phase_usage_.phase_used[Liquid]) { THROW("SaturationPropsFromDeck::init() -- oil phase must be active."); } // Obtain SATNUM, if it exists, and create cell_to_func_. // Otherwise, let the cell_to_func_ mapping be just empty. int satfuncs_expected = 1; if (deck.hasField("SATNUM")) { const std::vector<int>& satnum = deck.getIntegerValue("SATNUM"); satfuncs_expected = *std::max_element(satnum.begin(), satnum.end()); const int num_cells = grid.number_of_cells; cell_to_func_.resize(num_cells); const int* gc = grid.global_cell; for (int cell = 0; cell < num_cells; ++cell) { const int deck_pos = (gc == NULL) ? cell : gc[cell]; cell_to_func_[cell] = satnum[deck_pos] - 1; } } // Find number of tables, check for consistency. enum { Uninitialized = -1 }; int num_tables = Uninitialized; if (phase_usage_.phase_used[Aqua]) { const SWOF::table_t& swof_table = deck.getSWOF().swof_; num_tables = swof_table.size(); if (num_tables < satfuncs_expected) { THROW("Found " << num_tables << " SWOF tables, SATNUM specifies at least " << satfuncs_expected); } } if (phase_usage_.phase_used[Vapour]) { const SGOF::table_t& sgof_table = deck.getSGOF().sgof_; int num_sgof_tables = sgof_table.size(); if (num_sgof_tables < satfuncs_expected) { THROW("Found " << num_tables << " SGOF tables, SATNUM specifies at least " << satfuncs_expected); } if (num_tables == Uninitialized) { num_tables = num_sgof_tables; } else if (num_tables != num_sgof_tables) { THROW("Inconsistent number of tables in SWOF and SGOF."); } } // Initialize tables. satfuncset_.resize(num_tables); for (int table = 0; table < num_tables; ++table) { satfuncset_[table].init(deck, table, phase_usage_, samples); } }
void SatFuncGwsegUniform::init(const EclipseGridParser& deck, const int table_num, const PhaseUsage phase_usg, const int samples) { phase_usage = phase_usg; double swco = 0.0; double swmax = 1.0; if (phase_usage.phase_used[Aqua]) { const SWOF::table_t& swof_table = deck.getSWOF().swof_; const std::vector<double>& sw = swof_table[table_num][0]; const std::vector<double>& krw = swof_table[table_num][1]; const std::vector<double>& krow = swof_table[table_num][2]; const std::vector<double>& pcow = swof_table[table_num][3]; buildUniformMonotoneTable(sw, krw, samples, krw_); buildUniformMonotoneTable(sw, krow, samples, krow_); buildUniformMonotoneTable(sw, pcow, samples, pcow_); krocw_ = krow[0]; // At connate water -> ecl. SWOF swco = sw[0]; smin_[phase_usage.phase_pos[Aqua]] = sw[0]; swmax = sw.back(); smax_[phase_usage.phase_pos[Aqua]] = sw.back(); } if (phase_usage.phase_used[Vapour]) { const SGOF::table_t& sgof_table = deck.getSGOF().sgof_; const std::vector<double>& sg = sgof_table[table_num][0]; const std::vector<double>& krg = sgof_table[table_num][1]; const std::vector<double>& krog = sgof_table[table_num][2]; const std::vector<double>& pcog = sgof_table[table_num][3]; buildUniformMonotoneTable(sg, krg, samples, krg_); buildUniformMonotoneTable(sg, krog, samples, krog_); buildUniformMonotoneTable(sg, pcog, samples, pcog_); smin_[phase_usage.phase_pos[Vapour]] = sg[0]; if (std::fabs(sg.back() + swco - 1.0) > 1e-3) { THROW("Gas maximum saturation in SGOF table = " << sg.back() << ", should equal (1.0 - connate water sat) = " << (1.0 - swco)); } smax_[phase_usage.phase_pos[Vapour]] = sg.back(); } // These only consider water min/max sats. Consider gas sats? smin_[phase_usage.phase_pos[Liquid]] = 1.0 - swmax; smax_[phase_usage.phase_pos[Liquid]] = 1.0 - swco; }
void SatFuncSimpleUniform::init(const EclipseGridParser& deck, const int table_num, const PhaseUsage phase_usg, const int samples) { phase_usage = phase_usg; double swco = 0.0; double swmax = 1.0; if (phase_usage.phase_used[Aqua]) { const SWOF::table_t& swof_table = deck.getSWOF().swof_; const std::vector<double>& sw = swof_table[table_num][0]; const std::vector<double>& krw = swof_table[table_num][1]; const std::vector<double>& krow = swof_table[table_num][2]; const std::vector<double>& pcow = swof_table[table_num][3]; if (krw.front() != 0.0 || krow.back() != 0.0) { THROW("Error SWOF data - non-zero krw(swco) and/or krow(1-sor)"); } buildUniformMonotoneTable(sw, krw, samples, krw_); buildUniformMonotoneTable(sw, krow, samples, krow_); buildUniformMonotoneTable(sw, pcow, samples, pcow_); krocw_ = krow[0]; // At connate water -> ecl. SWOF swco = sw[0]; smin_[phase_usage.phase_pos[Aqua]] = sw[0]; swmax = sw.back(); smax_[phase_usage.phase_pos[Aqua]] = sw.back(); krwmax_ = krw.back(); kromax_ = krow.front(); swcr_ = swmax; sowcr_ = 1.0 - swco; krwr_ = krw.back(); krorw_ = krow.front(); for (std::vector<double>::size_type i=1; i<sw.size(); ++i) { if (krw[i]> 0.0) { swcr_ = sw[i-1]; krorw_ = krow[i-1]; break; } } for (std::vector<double>::size_type i=sw.size()-1; i>=1; --i) { if (krow[i-1]> 0.0) { sowcr_ = 1.0 - sw[i]; krwr_ = krw[i]; break; } } } if (phase_usage.phase_used[Vapour]) { const SGOF::table_t& sgof_table = deck.getSGOF().sgof_; const std::vector<double>& sg = sgof_table[table_num][0]; const std::vector<double>& krg = sgof_table[table_num][1]; const std::vector<double>& krog = sgof_table[table_num][2]; const std::vector<double>& pcog = sgof_table[table_num][3]; buildUniformMonotoneTable(sg, krg, samples, krg_); buildUniformMonotoneTable(sg, krog, samples, krog_); buildUniformMonotoneTable(sg, pcog, samples, pcog_); smin_[phase_usage.phase_pos[Vapour]] = sg[0]; if (std::fabs(sg.back() + swco - 1.0) > 1e-3) { THROW("Gas maximum saturation in SGOF table = " << sg.back() << ", should equal (1.0 - connate water sat) = " << (1.0 - swco)); } smax_[phase_usage.phase_pos[Vapour]] = sg.back(); } // These only consider water min/max sats. Consider gas sats? smin_[phase_usage.phase_pos[Liquid]] = 1.0 - swmax; smax_[phase_usage.phase_pos[Liquid]] = 1.0 - swco; }
void SatFuncBase<TableType>::init(const EclipseGridParser& deck, const int table_num, const PhaseUsage phase_usg, const int samples) { phase_usage = phase_usg; double swco = 0.0; double swmax = 1.0; if (phase_usage.phase_used[Aqua]) { const SWOF::table_t& swof_table = deck.getSWOF().swof_; const std::vector<double>& sw = swof_table[table_num][0]; const std::vector<double>& krw = swof_table[table_num][1]; const std::vector<double>& krow = swof_table[table_num][2]; const std::vector<double>& pcow = swof_table[table_num][3]; if (krw.front() != 0.0 || krow.back() != 0.0) { OPM_THROW(std::runtime_error, "Error SWOF data - non-zero krw(swco) and/or krow(1-sor)"); } // Extend the tables with constant values such that the // derivatives at the endpoints are zero int n = sw.size(); std::vector<double> sw_ex(n+2); std::vector<double> krw_ex(n+2); std::vector<double> krow_ex(n+2); std::vector<double> pcow_ex(n+2); extendTable(sw,sw_ex,1); extendTable(krw,krw_ex,0); extendTable(krow,krow_ex,0); extendTable(pcow,pcow_ex,0); initializeTableType(krw_,sw_ex, krw_ex, samples); initializeTableType(krow_,sw_ex, krow_ex, samples); initializeTableType(pcow_,sw_ex, pcow_ex, samples); krocw_ = krow[0]; // At connate water -> ecl. SWOF swco = sw[0]; smin_[phase_usage.phase_pos[Aqua]] = sw[0]; swmax = sw.back(); smax_[phase_usage.phase_pos[Aqua]] = sw.back(); krwmax_ = krw.back(); kromax_ = krow.front(); swcr_ = swmax; sowcr_ = 1.0 - swco; krwr_ = krw.back(); krorw_ = krow.front(); for (std::vector<double>::size_type i=1; i<sw.size(); ++i) { if (krw[i]> 0.0) { swcr_ = sw[i-1]; krorw_ = krow[i-1]; break; } } for (std::vector<double>::size_type i=sw.size()-1; i>=1; --i) { if (krow[i-1]> 0.0) { sowcr_ = 1.0 - sw[i]; krwr_ = krw[i]; break; } } } if (phase_usage.phase_used[Vapour]) { const SGOF::table_t& sgof_table = deck.getSGOF().sgof_; const std::vector<double>& sg = sgof_table[table_num][0]; const std::vector<double>& krg = sgof_table[table_num][1]; const std::vector<double>& krog = sgof_table[table_num][2]; const std::vector<double>& pcog = sgof_table[table_num][3]; // Extend the tables with constant values such that the // derivatives at the endpoints are zero int n = sg.size(); std::vector<double> sg_ex(n+2); std::vector<double> krg_ex(n+2); std::vector<double> krog_ex(n+2); std::vector<double> pcog_ex(n+2); extendTable(sg,sg_ex,1); extendTable(krg,krg_ex,0); extendTable(krog,krog_ex,0); extendTable(pcog,pcog_ex,0); initializeTableType(krg_,sg_ex, krg_ex, samples); initializeTableType(krog_,sg_ex, krog_ex, samples); initializeTableType(pcog_,sg_ex, pcog_ex, samples); smin_[phase_usage.phase_pos[Vapour]] = sg[0]; if (std::fabs(sg.back() + swco - 1.0) > 1e-3) { OPM_THROW(std::runtime_error, "Gas maximum saturation in SGOF table = " << sg.back() << ", should equal (1.0 - connate water sat) = " << (1.0 - swco)); } smax_[phase_usage.phase_pos[Vapour]] = sg.back(); smin_[phase_usage.phase_pos[Vapour]] = sg.front(); krgmax_ = krg.back(); sgcr_ = sg.front(); sogcr_ = 1.0 - sg.back(); krgr_ = krg.back(); krorg_ = krg.front(); for (std::vector<double>::size_type i=1; i<sg.size(); ++i) { if (krg[i]> 0.0) { sgcr_ = sg[i-1]; krorg_ = krog[i-1]; break; } } for (std::vector<double>::size_type i=sg.size()-1; i>=1; --i) { if (krog[i-1]> 0.0) { sogcr_ = 1.0 - sg[i]; krgr_ = krg[i]; break; } } } if (phase_usage.phase_used[Vapour] && phase_usage.phase_used[Aqua]) { sowcr_ -= smin_[phase_usage.phase_pos[Vapour]]; sogcr_ -= smin_[phase_usage.phase_pos[Aqua]]; smin_[phase_usage.phase_pos[Liquid]] = 0.0; smax_[phase_usage.phase_pos[Liquid]] = 1.0 - smin_[phase_usage.phase_pos[Aqua]] - smin_[phase_usage.phase_pos[Vapour]]; // First entry in SGOF-table supposed to be zero anyway ... } else if (phase_usage.phase_used[Aqua]) { smin_[phase_usage.phase_pos[Liquid]] = 1.0 - smax_[phase_usage.phase_pos[Aqua]]; smax_[phase_usage.phase_pos[Liquid]] = 1.0 - smin_[phase_usage.phase_pos[Aqua]]; } else if (phase_usage.phase_used[Vapour]) { smin_[phase_usage.phase_pos[Liquid]] = 1.0 - smax_[phase_usage.phase_pos[Vapour]]; smax_[phase_usage.phase_pos[Liquid]] = 1.0 - smin_[phase_usage.phase_pos[Vapour]]; } }
void SatFuncGwsegUniform::init(const EclipseGridParser& deck, const int table_num, const PhaseUsage phase_usg, const int samples) { phase_usage = phase_usg; double swco = 0.0; double swmax = 1.0; if (phase_usage.phase_used[Aqua]) { const SWOF::table_t& swof_table = deck.getSWOF().swof_; const std::vector<double>& sw = swof_table[table_num][0]; const std::vector<double>& krw = swof_table[table_num][1]; const std::vector<double>& krow = swof_table[table_num][2]; const std::vector<double>& pcow = swof_table[table_num][3]; // Extend the tables with constant values such that the // derivatives at the endpoints are zero int n = sw.size(); std::vector<double> sw_ex(n+2); std::vector<double> krw_ex(n+2); std::vector<double> krow_ex(n+2); std::vector<double> pcow_ex(n+2); SatFuncGwsegUniform::ExtendTable(sw,sw_ex,1); SatFuncGwsegUniform::ExtendTable(krw,krw_ex,0); SatFuncGwsegUniform::ExtendTable(krow,krow_ex,0); SatFuncGwsegUniform::ExtendTable(pcow,pcow_ex,0); buildUniformMonotoneTable(sw_ex, krw_ex, samples, krw_); buildUniformMonotoneTable(sw_ex, krow_ex, samples, krow_); buildUniformMonotoneTable(sw_ex, pcow_ex, samples, pcow_); krocw_ = krow[0]; // At connate water -> ecl. SWOF swco = sw[0]; smin_[phase_usage.phase_pos[Aqua]] = sw[0]; swmax = sw.back(); smax_[phase_usage.phase_pos[Aqua]] = sw.back(); } if (phase_usage.phase_used[Vapour]) { const SGOF::table_t& sgof_table = deck.getSGOF().sgof_; const std::vector<double>& sg = sgof_table[table_num][0]; const std::vector<double>& krg = sgof_table[table_num][1]; const std::vector<double>& krog = sgof_table[table_num][2]; const std::vector<double>& pcog = sgof_table[table_num][3]; // Extend the tables with constant values such that the // derivatives at the endpoints are zero int n = sg.size(); std::vector<double> sg_ex(n+2); std::vector<double> krg_ex(n+2); std::vector<double> krog_ex(n+2); std::vector<double> pcog_ex(n+2); SatFuncGwsegUniform::ExtendTable(sg,sg_ex,1); SatFuncGwsegUniform::ExtendTable(krg,krg_ex,0); SatFuncGwsegUniform::ExtendTable(krog,krog_ex,0); SatFuncGwsegUniform::ExtendTable(pcog,pcog_ex,0); buildUniformMonotoneTable(sg_ex, krg_ex, samples, krg_); buildUniformMonotoneTable(sg_ex, krog_ex, samples, krog_); buildUniformMonotoneTable(sg_ex, pcog_ex, samples, pcog_); smin_[phase_usage.phase_pos[Vapour]] = sg[0]; if (std::fabs(sg.back() + swco - 1.0) > 1e-3) { OPM_THROW(std::runtime_error, "Gas maximum saturation in SGOF table = " << sg.back() << ", should equal (1.0 - connate water sat) = " << (1.0 - swco)); } smax_[phase_usage.phase_pos[Vapour]] = sg.back(); } // These only consider water min/max sats. Consider gas sats? smin_[phase_usage.phase_pos[Liquid]] = 1.0 - swmax; smax_[phase_usage.phase_pos[Liquid]] = 1.0 - swco; }