Renamed UDQInput -> UDQCOnfig

UDQConfig object has merged DEFINE & ASSIGN

Log use of UDA for output purposes

Output UDQ keywords to restart file

Add size() method to UDQConfig

Add UDQVarTYpe member to UDQInput class

Add UDQIndex type to keep track of sequence number of variable types

Add unit to UDQInput class

use maps

Add operator[] to UDQConfig class

Use UDQInput class when creating restart file

UDQInput: use correct input index

Add UDQActive::get() method

Make sure UDQ DEFINE overwrite correctly

WIP

WIP - further code to output IGPH vector

WIP

Fix IUAD input index

Output use_index for IUAD

Fix bug with size of IUAD array

UAD usage hashing based on udqstring and controltype

Add UDQ test and input file

Refactor UDQActive - handles vanishing UDA

minor correction for iuad[1] and for test_UDQ_x.cpp

Further work for making unit tests for UDQ restart data

WIP Further work unit tests

WIP some minor corrections

WIP changes to add first version of BOOST test for IUDQ

WIP Added code to write InteHead and DoubHead data as well as IGPH to restart file,

Further added unit tests to the writing of UDQ data

add code to output IUAP array

Fixed group-group2 transition, disable Restart output

WIP Initial changes to add DUDW array to restart output

WIP further work on DUDW data

WIP - further work to output and test DUDW vector data to restart file

Further changes to write DUDW array to Restartfile
This commit is contained in:
Joakim Hove
2019-07-26 17:17:06 +02:00
committed by Jostein Alvestad
parent f2bc961bd4
commit 16a8f4040c
22 changed files with 487 additions and 100 deletions

View File

@@ -24,7 +24,7 @@ EQLDIMS
2 /
WELLDIMS
4 20 4 2 /
5 20 4 2 /
UNIFIN
UNIFOUT
@@ -336,10 +336,10 @@ UDQ
DEFINE WUOPRL (WOPR PROD1 - 150) * 0.90 /
DEFINE WULPRL (WLPR PROD1 - 200) * 0.90 /
DEFINE WUOPRU (WOPR PROD2 - 250) * 0.80 /
DEFINE GUOPRU (GOPR WGRP2 - 449) * 0.77 /
DEFINE GUOPRU (GOPR GRP1 - 449) * 0.77 /
DEFINE WULPRU (WLPR PROD2 - 300) * 0.80 /
ASSIGN WULPRL 400. /
DEFINE FULPR (FLPR - 543) * 0.65 /
DEFINE FULPR (FLPR - 543) * 0.65 /
DEFINE WUOPRL (WOPR PROD1 - 170) * 0.60 /
-- units
UNITS WUOPRL SM3/DAY /
@@ -347,7 +347,7 @@ UNITS WULPRL SM3/DAY /
UNITS GUOPRU SM3/DAY /
UNITS WUOPRU SM3/DAY /
UNITS WULPRU SM3/DAY /
UNITS FULPR SM3/DAY /
UNITS FULPR SM3/DAY /
--
/

View File

@@ -1240,6 +1240,7 @@ UDQ
BOOST_CHECK( fuopr.is<UDQDefine>() );
const auto& def2 = fuopr.get<UDQDefine>();
BOOST_CHECK_EQUAL(def2.input_string(), "MAX(WOPR)");
}
@@ -1370,6 +1371,208 @@ WCONPROD
)";
auto schedule = make_udq_schedule(udq_string);
// First timestep
{
const auto& udq_active = schedule.udqActive(0);
BOOST_CHECK(udq_active);
BOOST_CHECK_EQUAL(udq_active.IUAD_size(), 2);
const auto& record0 = udq_active[0];
BOOST_CHECK_EQUAL( record0.uad_code, 300004);
BOOST_CHECK_EQUAL( record0.input_index, 2);
BOOST_CHECK_EQUAL( record0.use_count, 2);
BOOST_CHECK_EQUAL( record0.use_index, 0);
const auto& record1 = udq_active[1];
BOOST_CHECK_EQUAL( record1.uad_code, 600004);
BOOST_CHECK_EQUAL( record1.input_index, 3);
BOOST_CHECK_EQUAL( record1.use_count, 2);
BOOST_CHECK_EQUAL( record1.use_index, 2);
}
{
// Second timestep
// - The WUOPRU and WULPRU udq are still used in the same manner for the PROD1 well.
// - The new UDQs WUXO and WUXL are now used for the PROD2 well.
const auto& udq_active = schedule.udqActive(1);
BOOST_CHECK(udq_active);
BOOST_CHECK_EQUAL(udq_active.IUAD_size(), 4);
const auto& record0 = udq_active[0];
BOOST_CHECK_EQUAL( record0.uad_code, 300004);
BOOST_CHECK_EQUAL( record0.input_index, 2);
BOOST_CHECK_EQUAL( record0.use_count, 1);
BOOST_CHECK_EQUAL( record0.use_index, 0);
const auto& record1 = udq_active[1];
BOOST_CHECK_EQUAL( record1.uad_code, 600004);
BOOST_CHECK_EQUAL( record1.input_index, 3);
BOOST_CHECK_EQUAL( record1.use_count, 1);
BOOST_CHECK_EQUAL( record1.use_index, 1);
const auto& record2 = udq_active[2];
BOOST_CHECK_EQUAL( record2.uad_code, 300004);
BOOST_CHECK_EQUAL( record2.input_index, 4);
BOOST_CHECK_EQUAL( record2.use_count, 1);
BOOST_CHECK_EQUAL( record2.use_index, 2);
const auto& record3 = udq_active[3];
BOOST_CHECK_EQUAL( record3.uad_code, 600004);
BOOST_CHECK_EQUAL( record3.input_index, 5);
BOOST_CHECK_EQUAL( record3.use_count, 1);
BOOST_CHECK_EQUAL( record3.use_index, 3);
}
{
// Third timestep
// - The new UDQs WUXO and WUXL are now used for the PROD2 well.
// - The PROD1 well does not use UDQ
const auto& udq_active = schedule.udqActive(2);
BOOST_CHECK(udq_active);
BOOST_CHECK_EQUAL(udq_active.IUAD_size(), 2);
const auto& record0 = udq_active[0];
BOOST_CHECK_EQUAL( record0.uad_code, 300004);
BOOST_CHECK_EQUAL( record0.input_index, 4);
BOOST_CHECK_EQUAL( record0.use_count, 1);
BOOST_CHECK_EQUAL( record0.use_index, 0);
const auto& record1 = udq_active[1];
BOOST_CHECK_EQUAL( record1.uad_code, 600004);
BOOST_CHECK_EQUAL( record1.input_index, 5);
BOOST_CHECK_EQUAL( record1.use_count, 1);
BOOST_CHECK_EQUAL( record1.use_index, 1);
BOOST_AUTO_TEST_CASE(UDQ_USAGE) {
UDQActive usage;
UDQParams params;
UDQConfig conf(params);
BOOST_CHECK_EQUAL( usage.IUAD_size(), 0 );
UDAValue uda1("WUX");
conf.add_assign(uda1.get<std::string>(), {}, 100);
usage.update(conf, uda1, "W1", UDAControl::WCONPROD_ORAT);
BOOST_CHECK_EQUAL( usage.IUAD_size(), 1 );
BOOST_CHECK_EQUAL( usage[0].use_count, 1);
usage.update(conf, uda1, "W1", UDAControl::WCONPROD_GRAT);
BOOST_CHECK_EQUAL( usage.IUAD_size(), 2 );
BOOST_CHECK_EQUAL( usage[1].use_count, 1);
const auto& rec = usage[0];
BOOST_CHECK_EQUAL(rec.wgname, "W1");
BOOST_CHECK_EQUAL(rec.udq, "WUX");
BOOST_CHECK(rec.control == UDAControl::WCONPROD_ORAT);
for (std::size_t index = 0; index < usage.IUAD_size(); index++) {
const auto& record = usage[index];
BOOST_CHECK_EQUAL(record.input_index, 0);
BOOST_CHECK_EQUAL(record.wgname, "W1");
if (index == 0)
BOOST_CHECK(record.control == UDAControl::WCONPROD_ORAT);
else
BOOST_CHECK(record.control == UDAControl::WCONPROD_GRAT);
index += 1;
}
}
BOOST_AUTO_TEST_CASE(IntegrationTest) {
#include "data/integration_tests/udq.data"
auto schedule = make_schedule(deck_string);
{
const auto& active = schedule.udqActive(1);
BOOST_CHECK_EQUAL(active.IUAD_size(), 4);
BOOST_CHECK(active[0].control == UDAControl::WCONPROD_ORAT);
BOOST_CHECK(active[1].control == UDAControl::WCONPROD_LRAT);
BOOST_CHECK(active[2].control == UDAControl::WCONPROD_ORAT);
BOOST_CHECK(active[3].control == UDAControl::WCONPROD_LRAT);
BOOST_CHECK(active[0].wgname == "OPL02");
BOOST_CHECK(active[1].wgname == "OPL02");
BOOST_CHECK(active[2].wgname == "OPU02");
BOOST_CHECK(active[3].wgname == "OPU02");
BOOST_CHECK(active[0].udq == "WUOPRL");
BOOST_CHECK(active[1].udq == "WULPRL");
BOOST_CHECK(active[2].udq == "WUOPRU");
BOOST_CHECK(active[3].udq == "WULPRU");
BOOST_CHECK(active[0].input_index == 0);
BOOST_CHECK(active[1].input_index == 1);
BOOST_CHECK(active[2].input_index == 2);
BOOST_CHECK(active[3].input_index == 3);
BOOST_CHECK(active[0].use_count == 1);
BOOST_CHECK(active[1].use_count == 1);
BOOST_CHECK(active[2].use_count == 1);
BOOST_CHECK(active[3].use_count == 1);
}
}
Schedule make_udq_schedule(const std::string& schedule_string) {
#include "data/integration_tests/udq2.data"
deck_string += schedule_string;
return make_schedule(deck_string);
}
BOOST_AUTO_TEST_CASE(IntegrationTest2) {
const std::string udq_string = R"(
UDQ
DEFINE WUOPRL (WOPR PROD1 - 150) * 0.90 /
DEFINE WULPRL (WLPR PROD1 - 200) * 0.90 /
DEFINE WUOPRU (WOPR PROD2 - 250) * 0.80 /
DEFINE WULPRU (WLPR PROD2 - 300) * 0.80 /
DEFINE WUOPRL (WOPR PROD1 - 170) * 0.60 /
DEFINE WUXO (WOPR PROD1 - 170) * 0.60 /
DEFINE WUXL (WOPR PROD1 - 170) * 0.60 /
-- units
UNITS WUOPRL SM3/DAY /
UNITS WULPRL SM3/DAY /
UNITS WUOPRU SM3/DAY /
UNITS WULPRU SM3/DAY /
/
WCONPROD
'PROD1' 'OPEN' 'GRUP' WUOPRU 1* 1* WULPRU 1* 60.0 / single wells
/
WCONPROD
'PROD2' 'OPEN' 'GRUP' WUOPRU 1* 1* WULPRU 1* 60.0 / single wells
/
WCONINJE
'WINJ1' 'WAT' 'OPEN' 'BHP' 1* 1200 3500 1* /
'WINJ2' 'WAT' 'OPEN' 'BHP' 1* 800 3500 1* /
/
TSTEP
5 /
WCONPROD
'PROD2' 'OPEN' 'GRUP' WUXO 1* 1* WUXL 1* 60.0 / single wells
/
TSTEP
5 /
WCONPROD
'PROD1' 'OPEN' 'GRUP' 100 1* 1* 100 1* 60.0 / single wells
/
)";
auto schedule = make_udq_schedule(udq_string);

View File

@@ -40,7 +40,7 @@ namespace {
Opm::Deck first_sim(std::string fname) {
return Opm::Parser{}.parseFile(fname);
}
/*
Opm::UDQActive udq_active() {
int update_count = 0;
// construct record data for udq_active
@@ -67,8 +67,41 @@ namespace {
}
return udq_act;
}
*/
}
Opm::SummaryState sum_state()
{
auto state = Opm::SummaryState{};
state.update_well_var("PROD1", "WUOPRL", 210.);
state.update_well_var("PROD2", "WUOPRL", 211.);
state.update_well_var("WINJ1", "WUOPRL", 212.);
state.update_well_var("WINJ2", "WUOPRL", 213.);
state.update_well_var("PROD1", "WULPRL", 230.);
state.update_well_var("PROD2", "WULPRL", 231.);
state.update_well_var("WINJ1", "WULPRL", 232.);
state.update_well_var("WINJ2", "WULPRL", 233.);
state.update_well_var("PROD1", "WUOPRU", 220.);
state.update_well_var("PROD2", "WUOPRU", 221.);
state.update_well_var("WINJ1", "WUOPRU", 222.);
state.update_well_var("WINJ2", "WUOPRU", 223.);
state.update_group_var("WGRP1", "GUOPRU", 360.);
state.update_group_var("WGRP2", "GUOPRU", 361.);
state.update_group_var("GRP1", "GUOPRU", 362.);
state.update_group_var("GRP2", "GUOPRU", 363.);
state.update_well_var("PROD1", "WULPRU", 160.);
state.update_well_var("PROD2", "WULPRU", 161.);
state.update_well_var("WINJ1", "WULPRU", 162.);
state.update_well_var("WINJ2", "WULPRU", 163.);
state.update("FULPR", 460.);
return state;
}
//int main(int argc, char* argv[])
@@ -76,8 +109,8 @@ struct SimulationCase
{
explicit SimulationCase(const Opm::Deck& deck)
: es { deck }
, grid { deck }
, sched{ deck, es }
, grid { deck }
, sched{ deck, es }
{}
// Order requirement: 'es' must be declared/initialised before 'sched'.
@@ -97,11 +130,11 @@ BOOST_AUTO_TEST_CASE (Declared_UDQ_data)
const auto simCase = SimulationCase{first_sim("UDQ_TEST_WCONPROD_IUAD-2.DATA")};
Opm::EclipseState es = simCase.es;
Opm::SummaryState st = sum_state();
Opm::Schedule sched = simCase.sched;
Opm::EclipseGrid grid = simCase.grid;
const auto& ioConfig = es.getIOConfig();
const auto& restart = es.cfg().restart();
//Opm::UDQActive udq_act = udq_active();
//const auto& restart = es.cfg().restart();
// Report Step 1: 2008-10-10 --> 2011-01-20
const auto rptStep = std::size_t{1};
@@ -112,9 +145,9 @@ BOOST_AUTO_TEST_CASE (Declared_UDQ_data)
Opm::EclIO::OutputStream::ResultSet { outputDir, baseName },
rptStep,
Opm::EclIO::OutputStream::Formatted { ioConfig.getFMTOUT() },
Opm::EclIO::OutputStream::Unified { ioConfig.getUNIFOUT() }
Opm::EclIO::OutputStream::Unified { ioConfig.getUNIFOUT() }
};
double secs_elapsed = 3.1536E07;
const auto ih = Opm::RestartIO::Helpers::createInteHead(es, grid, sched,
secs_elapsed, rptStep, rptStep);
@@ -125,14 +158,15 @@ BOOST_AUTO_TEST_CASE (Declared_UDQ_data)
const auto udqDims = Opm::RestartIO::Helpers::createUdqDims(sched, rptStep, ih);
auto udqData = Opm::RestartIO::Helpers::AggregateUDQData(udqDims);
udqData.captureDeclaredUDQData(sched, rptStep, ih);
udqData.captureDeclaredUDQData(sched, rptStep, st, ih);
rstFile.write("IUDQ", udqData.getIUDQ());
rstFile.write("IUAD", udqData.getIUAD());
rstFile.write("IGPH", udqData.getIGPH());
rstFile.write("IUAP", udqData.getIUAP());
rstFile.write("ZUDN", udqData.getZUDN());
rstFile.write("ZUDL", udqData.getZUDL());
rstFile.write("IUDQ", udqData.getIUDQ());
rstFile.write("DUDW", udqData.getDUDW());
rstFile.write("IUAD", udqData.getIUAD());
rstFile.write("IUAP", udqData.getIUAP());
rstFile.write("IGPH", udqData.getIGPH());
{
/*
@@ -327,19 +361,18 @@ BOOST_AUTO_TEST_CASE (Declared_UDQ_data)
BOOST_CHECK_EQUAL(zUdl[start + 2].c_str() , "0) * 0.6"); // udq NO. 1
BOOST_CHECK_EQUAL(zUdl[start + 3].c_str() , "0 "); // udq NO. 1
/*start = 1*udqDims[5];
BOOST_CHECK_EQUAL(zUdl[start + 0].c_str() , "(WLPR PR"); // udq NO. 1
BOOST_CHECK_EQUAL(zUdl[start + 1].c_str() , "OD1 - 20"); // udq NO. 1
BOOST_CHECK_EQUAL(zUdl[start + 2].c_str() , "0) * 0.9"); // udq NO. 1
BOOST_CHECK_EQUAL(zUdl[start + 3].c_str() , "0 "); // udq NO. 1
*/
start = 3*udqDims[5];
BOOST_CHECK_EQUAL(zUdl[start + 0].c_str() , "(GOPR WG"); // udq NO. 1
BOOST_CHECK_EQUAL(zUdl[start + 1].c_str() , "RP2 - 44"); // udq NO. 1
BOOST_CHECK_EQUAL(zUdl[start + 2].c_str() , "9) * 0.7"); // udq NO. 1
BOOST_CHECK_EQUAL(zUdl[start + 3].c_str() , "7 "); // udq NO. 1
BOOST_CHECK_EQUAL(zUdl[start + 0].c_str() , "(GOPR GR"); // udq NO. 1
BOOST_CHECK_EQUAL(zUdl[start + 1].c_str() , "P1 - 449"); // udq NO. 1
BOOST_CHECK_EQUAL(zUdl[start + 2].c_str() , ") * 0.77"); // udq NO. 1
BOOST_CHECK_EQUAL(zUdl[start + 3].c_str() , " "); // udq NO. 1
start = 4*udqDims[5];
BOOST_CHECK_EQUAL(zUdl[start + 0].c_str() , "(WLPR PR"); // udq NO. 1
BOOST_CHECK_EQUAL(zUdl[start + 1].c_str() , "OD2 - 30"); // udq NO. 1
BOOST_CHECK_EQUAL(zUdl[start + 2].c_str() , "0) * 0.8"); // udq NO. 1
BOOST_CHECK_EQUAL(zUdl[start + 3].c_str() , "0 "); // udq NO. 1
start = 5*udqDims[5];
BOOST_CHECK_EQUAL(zUdl[start + 0].c_str() , "(FLPR - "); // udq NO. 1
BOOST_CHECK_EQUAL(zUdl[start + 1].c_str() , "543) * 0"); // udq NO. 1
@@ -348,6 +381,34 @@ BOOST_AUTO_TEST_CASE (Declared_UDQ_data)
}
{
/*
'DUDW ' 24 'DOUB'
Dimension = max no wells * no of UDQ's
Value = value of UDQ for the different wells
*/
const auto& dUdw = udqData.getDUDW();
auto start = 0*udqDims[8];
BOOST_CHECK_EQUAL(dUdw[start + 0] , 210); // duDw NO. 1
BOOST_CHECK_EQUAL(dUdw[start + 1] , 211); // duDw NO. 1
BOOST_CHECK_EQUAL(dUdw[start + 2] , 212); // duDw NO. 1
BOOST_CHECK_EQUAL(dUdw[start + 3] , 213); // duDw NO. 1
BOOST_CHECK_EQUAL(dUdw[start + 4] , -0.3E+21); // duDw NO. 1
start = 1*udqDims[8];
BOOST_CHECK_EQUAL(dUdw[start + 0] , 230); // duDw NO. 1
BOOST_CHECK_EQUAL(dUdw[start + 1] , 231); // duDw NO. 1
BOOST_CHECK_EQUAL(dUdw[start + 2] , 232); // duDw NO. 1
BOOST_CHECK_EQUAL(dUdw[start + 3] , 233); // duDw NO. 1
BOOST_CHECK_EQUAL(dUdw[start + 4] , -0.3E+21); // duDw NO. 1
}
}