Changes in AggregateMSW data to write segment data to restart file

Changes in RestartIO to avoid writing of well and MSW data when wells not present
This commit is contained in:
Jostein Alvestad
2018-10-08 14:42:26 +02:00
committed by Bård Skaflestad
parent f867d7f82c
commit 613aafe4ae
2 changed files with 74 additions and 37 deletions

View File

@@ -347,9 +347,9 @@ namespace {
auto noElmSeg = nisegz(inteHead);
std::size_t segmentInd = 0;
auto orderedSegmentNo = segmentOrder(welSegSet, segmentInd);
for (int ind_seg = 1; ind_seg <= welSegSet.size(); ind_seg++) {
auto ind = welSegSet.segmentNumberToIndex(ind_seg);
auto iS = (ind_seg-1)*noElmSeg;
for (int segNumber = 1; segNumber <= welSegSet.size(); segNumber++) {
auto ind = welSegSet.segmentNumberToIndex(segNumber);
auto iS = (segNumber-1)*noElmSeg;
iSeg[iS + 0] = orderedSegmentNo[ind];
iSeg[iS + 1] = welSegSet[ind].outletSegment();
iSeg[iS + 2] = inflowSegmentCurBranch(welSegSet, ind);
@@ -395,36 +395,51 @@ namespace {
RSegArray& rSeg)
{
if (well.isMultiSegment(rptStep)) {
int segNumber = 1;
std::string stringSegNum = std::to_string(segNumber);
using M = ::Opm::UnitSystem::measure;
const auto gfactor = (units.getType() == Opm::UnitSystem::UnitType::UNIT_TYPE_FIELD)
? 0.1781076 : 0.001;
//loop over segment set and print out information
auto welSegSet = well.getWellSegments(rptStep);
auto completionSet = well.getCompletions(rptStep);
auto noElmSeg = nrsegz(inteHead);
auto& wname = well.name();
std::string bhpKey = "WBHP:" + wname;
auto get = [&smry, &wname, &stringSegNum](const std::string& vector)
{
const auto key = vector + ":" + wname + ":(" + stringSegNum + ")";
return smry.has(key) ? smry.get(key) : 0.0;
};
//treat the top segment individually
rSeg[0] = units.from_si(M::length, welSegSet.lengthTopSegment());
rSeg[1] = units.from_si(M::length, welSegSet.depthTopSegment());
rSeg[5] = units.from_si(M::volume, welSegSet.volumeTopSegment());
rSeg[6] = rSeg[0];
rSeg[7] = rSeg[1];
//Item 8: should be some segment cumulative flow rate, use a constant value for now
rSeg[8] = 200.;
//Item ind+9: not sure what this parameter is, the current value works well for tests on E100
rSeg[9] = 0.01;
// set item ind + 10 to 0.5 based on tests on E100
rSeg[10] = 0.5;
//Item 11 should be segment pressure - use flowing bottom hole pressure temporarily
//if (smry.has( bhpKey)) {
// rSeg[11] = smry.get(bhpKey);
//}
// use default value for now
rSeg[11] = 0.;
// segment pressure - set equal to item 8
rSeg[ 39] = rSeg[11];
//
//Field units:
//Rseg[8]= 1.0*sofr+0.1*swfr + 0.1781076*sgfr (= 1.0*sofr+0.1*swfr+0.001*1000*0.1781076*sgfr )
//Rseg[9] = swfr*0.1/ Rseg[8]
//Rseg[10]= sgfr*0.1781076*/ Rseg[8]
//Default values
//rSeg[ 39] = 1.0;
//Metric units:
//Rseg[8]= 1.0*sofr+0.1*swfr + 0.001*sgfr
//Rseg[9] = swfr*0.1/ Rseg[8]
//Rseg[10]= sgfr*0.001/ Rseg[8]
auto temp_o = - units.from_si(M::liquid_surface_rate, get("SOFR"));
auto temp_w = - units.from_si(M::liquid_surface_rate, get("SWFR"))*0.1;
auto temp_g = - units.from_si(M::gas_surface_rate, get("SGFR"))*gfactor;
rSeg[ 8] = temp_o + temp_w + temp_g;
rSeg[ 9] = (abs(temp_w) > 0) ? temp_w / rSeg[8] : 0.;
rSeg[10] = (abs(temp_g) > 0) ? temp_g / rSeg[8] : 0.;
//Item 12 Segment pressure
rSeg[11] = units.from_si(M::pressure, get("SPR"));
// segment pressure
rSeg[ 39] = rSeg[11];
rSeg[105] = 1.0;
rSeg[106] = 1.0;
@@ -434,12 +449,13 @@ namespace {
rSeg[110] = 1.0;
//Treat subsequent segments
for (int ind_seg = 2; ind_seg <= welSegSet.size(); ind_seg++) {
for (segNumber = 2; segNumber <= welSegSet.size(); segNumber++) {
stringSegNum = std::to_string(segNumber);
// set the elements of the rSeg array
auto ind = welSegSet.segmentNumberToIndex(ind_seg);
auto ind = welSegSet.segmentNumberToIndex(segNumber);
auto outSeg = welSegSet[ind].outletSegment();
auto ind_ofs = welSegSet.segmentNumberToIndex(outSeg);
auto iS = (ind_seg-1)*noElmSeg;
auto iS = (segNumber-1)*noElmSeg;
rSeg[iS + 0] = units.from_si(M::length, (welSegSet[ind].totalLength() - welSegSet[ind_ofs].totalLength()));
rSeg[iS + 1] = units.from_si(M::length, (welSegSet[ind].depth() - welSegSet[ind_ofs].depth()));
rSeg[iS + 2] = units.from_si(M::length, (welSegSet[ind].internalDiameter()));
@@ -451,17 +467,17 @@ namespace {
rSeg[iS + 6] = units.from_si(M::length, (welSegSet[ind].totalLength()));
rSeg[iS + 7] = units.from_si(M::length, (welSegSet[ind].depth()));
//Item ind+8: should be some segment cumulative flow rate, use a constant value for now
rSeg[iS + 8] = 200.;
//Item ind+9: not sure what this parameter is, the current value works well for tests on E100
rSeg[iS + 9] = 0.01;
// set item ind + 10 to 0.5 based on tests on E100
rSeg[iS + 10] = 0.5;
// segment pressure (to be added!!)
rSeg[iS + 11] = rSeg[11];
//Default values
//see section above for explanation of values
auto temp_o = - units.from_si(M::liquid_surface_rate, get("SOFR"));
auto temp_w = - units.from_si(M::liquid_surface_rate, get("SWFR"))*0.1;
auto temp_g = - units.from_si(M::gas_surface_rate, get("SGFR"))*gfactor;
rSeg[iS + 8] = temp_o + temp_w + temp_g;
rSeg[iS + 9] = (abs(temp_w) > 0) ? temp_w / rSeg[iS + 8] : 0.;
rSeg[iS + 10] = (abs(temp_g) > 0) ? temp_g / rSeg[iS + 8] : 0.;
//Item 12 Segment pressure
rSeg[iS +11] = units.from_si(M::pressure, get("SPR"));
rSeg[iS + 39] = rSeg[iS + 11];
rSeg[iS + 105] = 1.0;

View File

@@ -37,10 +37,12 @@
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Tuning.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Tables/Eqldims.hpp>
#include <algorithm>
#include <cstddef>
#include <iterator>
#include <string>
#include <unordered_set>
#include <vector>
@@ -469,12 +471,31 @@ void save(const std::string& filename,
const auto inteHD = writeHeader(rst_file.get(), sim_step, report_step,
seconds_elapsed, schedule, grid, es);
writeGroup(rst_file.get(), sim_step, ecl_compatible_rst, schedule, sumState, inteHD);
writeGroup(rst_file.get(), sim_step, ecl_compatible_rst,
schedule, sumState, inteHD);
writeMSWData(rst_file.get(), sim_step, units, schedule, grid, sumState, inteHD);
// Write well and MSW data only when applicable (i.e., when present)
{
const auto& wells = schedule.getWells(sim_step);
writeWell(rst_file.get(), sim_step, ecl_compatible_rst, es.runspec().phases(), units,
grid, schedule, value.wells, sumState, inteHD);
if (! wells.empty()) {
const auto numMSW =
std::count_if(std::begin(wells), std::end(wells),
[sim_step](const Well* well)
{
return well->isMultiSegment(sim_step);
});
if (numMSW > 0) {
writeMSWData(rst_file.get(), sim_step, units,
schedule, grid, sumState, inteHD);
}
writeWell(rst_file.get(), sim_step, ecl_compatible_rst,
es.runspec().phases(), units, grid, schedule,
value.wells, sumState, inteHD);
}
}
writeSolution(rst_file.get(), value, ecl_compatible_rst, write_double);