Merge from joakim/wellmanager

This commit is contained in:
Kristian Flikka
2014-01-07 16:09:35 +01:00
14 changed files with 1046 additions and 322 deletions

105
tests/test_wellcontrols.cpp Normal file
View File

@@ -0,0 +1,105 @@
/*
Copyright 2014 Statoil.
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>
#if HAVE_DYNAMIC_BOOST_TEST
#define BOOST_TEST_DYN_LINK
#endif
#define NVERBOSE // Suppress own messages when throw()ing
#define BOOST_TEST_MODULE WellsModuleTest
#include <boost/test/unit_test.hpp>
#include <opm/core/wells.h>
#include <opm/core/well_controls.h>
#include <iostream>
#include <vector>
#include <memory>
BOOST_AUTO_TEST_CASE(Construction)
{
struct WellControls * ctrls = well_controls_create();
well_controls_set_current( ctrls , 1 );
BOOST_CHECK_EQUAL( 1 , well_controls_get_current( ctrls ));
well_controls_set_current( ctrls , 2 );
BOOST_CHECK_EQUAL( 2 , well_controls_get_current( ctrls ));
well_controls_invert_current( ctrls );
BOOST_CHECK( well_controls_get_current( ctrls ) < 0 );
well_controls_invert_current( ctrls );
BOOST_CHECK_EQUAL( 2 , well_controls_get_current( ctrls ));
{
enum WellControlType type1 = BHP;
enum WellControlType type2 = SURFACE_RATE;
int num_phases = 3;
double dist1[3] = {0 , 1 , 2};
double dist2[3] = {10, 11 , 12};
double target = 77;
well_controls_assert_number_of_phases( ctrls , num_phases );
well_controls_add_new( type1 , target , dist1 , ctrls );
well_controls_add_new( type2 , 2*target , dist2 , ctrls );
BOOST_CHECK_EQUAL( target , well_controls_iget_target(ctrls , 0 ));
BOOST_CHECK_EQUAL( type1 , well_controls_iget_type(ctrls , 0 ));
BOOST_CHECK_EQUAL( 2*target , well_controls_iget_target(ctrls , 1 ));
BOOST_CHECK_EQUAL( type2 , well_controls_iget_type(ctrls , 1 ));
well_controls_set_current( ctrls , 1 );
BOOST_CHECK_EQUAL( type2 , well_controls_get_current_type( ctrls ));
BOOST_CHECK_EQUAL( well_controls_iget_target( ctrls , 1 ) , well_controls_get_current_target( ctrls ));
{
const double * d1 = well_controls_iget_distr( ctrls , 0 );
const double * d2 = well_controls_iget_distr( ctrls , 1 );
BOOST_CHECK( memcmp(d1 , dist1 , num_phases * sizeof * d1 ) == 0);
BOOST_CHECK( memcmp(d2 , dist2 , num_phases * sizeof * d2 ) == 0);
}
}
well_controls_iset_target( ctrls , 0 , 123);
BOOST_CHECK_EQUAL( 123 , well_controls_iget_target( ctrls , 0 ));
well_controls_iset_target( ctrls , 1 , 456);
BOOST_CHECK_EQUAL( 456 , well_controls_iget_target( ctrls , 1 ));
well_controls_iset_type( ctrls , 0 , SURFACE_RATE);
BOOST_CHECK_EQUAL( SURFACE_RATE , well_controls_iget_type( ctrls , 0 ));
well_controls_iset_type( ctrls , 1 , BHP);
BOOST_CHECK_EQUAL( BHP, well_controls_iget_type( ctrls , 1 ));
{
double newDist[3] = {77,78,79};
const double * tmp;
well_controls_iset_distr( ctrls , 0 , newDist );
tmp = well_controls_iget_distr( ctrls , 0);
BOOST_CHECK( memcmp(tmp , newDist , 3 * sizeof * tmp ) == 0);
}
well_controls_destroy( ctrls );
}

View File

@@ -29,6 +29,7 @@
#include <boost/test/unit_test.hpp>
#include <opm/core/wells.h>
#include <opm/core/well_controls.h>
#include <iostream>
#include <vector>
@@ -104,20 +105,20 @@ BOOST_AUTO_TEST_CASE(Controls)
if (ok1 && ok2) {
WellControls* ctrls = W->ctrls[0];
BOOST_CHECK_EQUAL(ctrls->num , 2);
BOOST_CHECK_EQUAL(ctrls->current, -1);
BOOST_CHECK_EQUAL(well_controls_get_num(ctrls) , 2);
BOOST_CHECK_EQUAL(well_controls_get_current(ctrls), -1);
set_current_control(0, 0, W.get());
BOOST_CHECK_EQUAL(ctrls->current, 0);
BOOST_CHECK_EQUAL(well_controls_get_current(ctrls), 0);
set_current_control(0, 1, W.get());
BOOST_CHECK_EQUAL(ctrls->current, 1);
BOOST_CHECK_EQUAL(well_controls_get_current(ctrls), 1);
BOOST_CHECK_EQUAL(ctrls->type[0], BHP);
BOOST_CHECK_EQUAL(ctrls->type[1], SURFACE_RATE);
BOOST_CHECK_EQUAL(well_controls_iget_type(ctrls , 0) , BHP);
BOOST_CHECK_EQUAL(well_controls_iget_type(ctrls , 1) , SURFACE_RATE);
BOOST_CHECK_EQUAL(ctrls->target[0], 1.0);
BOOST_CHECK_EQUAL(ctrls->target[1], 1.0);
BOOST_CHECK_EQUAL(well_controls_iget_target(ctrls , 0), 1.0);
BOOST_CHECK_EQUAL(well_controls_iget_target(ctrls , 1), 1.0);
}
}
}
@@ -188,18 +189,48 @@ BOOST_AUTO_TEST_CASE(Copy)
WellControls* c1 = W1->ctrls[w];
WellControls* c2 = W2->ctrls[w];
BOOST_CHECK_EQUAL(c2->num , c1->num );
BOOST_CHECK_EQUAL(c2->current, c1->current);
BOOST_CHECK_EQUAL(well_controls_get_num(c2) , well_controls_get_num(c1));
BOOST_CHECK_EQUAL(well_controls_get_current(c2) , well_controls_get_current(c1));
for (int c = 0; c < c1->num; ++c) {
BOOST_CHECK_EQUAL(c2->type [c], c1->type [c]);
BOOST_CHECK_EQUAL(c2->target[c], c1->target[c]);
for (int c = 0; c < well_controls_get_num(c1); ++c) {
BOOST_CHECK_EQUAL(well_controls_iget_type(c2, c) , well_controls_iget_type(c1 , c));
BOOST_CHECK_EQUAL(well_controls_iget_target(c2, c) , well_controls_iget_target(c1 , c));
for (int p = 0; p < W1->number_of_phases; ++p) {
BOOST_CHECK_EQUAL(c2->distr[c*W1->number_of_phases + p],
c1->distr[c*W1->number_of_phases + p]);
{
const double * dist1 = well_controls_iget_distr(c1 , c );
const double * dist2 = well_controls_iget_distr(c2 , c );
for (int p = 0; p < W1->number_of_phases; ++p)
BOOST_CHECK_EQUAL( dist1[p] , dist2[p]);
}
}
BOOST_CHECK( well_controls_equal( c1 , c2 ));
}
}
}
BOOST_AUTO_TEST_CASE(Equals_WellsEqual_ReturnsTrue) {
const int nphases = 2;
const int nwells = 2;
const int nperfs = 2;
std::shared_ptr<Wells> W1(create_wells(nphases, nwells, nperfs),
destroy_wells);
std::shared_ptr<Wells> W2(create_wells(nphases, nwells, nperfs),
destroy_wells);
BOOST_CHECK(wells_equal(W1.get(), W2.get()));
}
BOOST_AUTO_TEST_CASE(Equals_WellsDiffer_ReturnsFalse) {
const int nphases = 2;
const int nperfs = 2;
std::shared_ptr<Wells> W1(create_wells(nphases, 2, nperfs),
destroy_wells);
std::shared_ptr<Wells> W2(create_wells(nphases, 3, nperfs),
destroy_wells);
BOOST_CHECK(!wells_equal(W1.get(), W2.get()));
}

236
tests/test_wellsmanager.cpp Normal file
View File

@@ -0,0 +1,236 @@
/*
Copyright 2013 Statoil ASA.
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>
#if HAVE_DYNAMIC_BOOST_TEST
#define BOOST_TEST_DYN_LINK
#endif
#define NVERBOSE // Suppress own messages when throw()ing
#define BOOST_TEST_MODULE WellsManagerTests
#include <boost/test/unit_test.hpp>
#include <opm/core/wells/WellsManager.hpp>
#include <opm/core/wells.h>
#include <opm/core/well_controls.h>
#include <opm/core/io/eclipse/EclipseGridParser.hpp>
#include <opm/core/grid/GridManager.hpp>
void wells_static_check(const Wells* wells) {
BOOST_CHECK_EQUAL(2 , wells->number_of_wells);
BOOST_CHECK_EQUAL(3 , wells->number_of_phases);
BOOST_CHECK_EQUAL("INJ1" , wells->name[0]);
BOOST_CHECK_EQUAL("PROD1" , wells->name[1]);
/* The mapping from well number into the wells->WI and wells->well_cells arrays. */
BOOST_CHECK_EQUAL(0 , wells->well_connpos[0]);
BOOST_CHECK_EQUAL(1 , wells->well_connpos[1]);
BOOST_CHECK_EQUAL(2 , wells->well_connpos[2]);
/* Connection factor */
BOOST_CHECK_CLOSE(1.2279166666666664e-12 , wells->WI[0] , 0.001);
BOOST_CHECK_CLOSE(1.2279166666666664e-12 , wells->WI[1] , 0.001);
/* Completed cells */
BOOST_CHECK_EQUAL(0 , wells->well_cells[0]);
BOOST_CHECK_EQUAL(9 + 2*10 + 2*10*10 , wells->well_cells[1]);
}
/*
The number of controls is determined by looking at which elements
have been given explicit - non-default - values in the WCONxxxx
keyword. Is that at all interesting?
*/
void check_controls_epoch0( struct WellControls ** ctrls) {
// The injector
{
const struct WellControls * ctrls0 = ctrls[0];
BOOST_CHECK_EQUAL( 3 , well_controls_get_num(ctrls0)); // The number of controls for the injector == 3??
BOOST_CHECK_EQUAL( SURFACE_RATE , well_controls_iget_type(ctrls0 , 0) );
BOOST_CHECK_EQUAL( RESERVOIR_RATE , well_controls_iget_type(ctrls0 , 1) );
BOOST_CHECK_EQUAL( BHP , well_controls_iget_type(ctrls0 , 2) );
// The different targets
BOOST_CHECK_EQUAL( 100.0 / 86400 , well_controls_iget_target(ctrls0,0));
BOOST_CHECK_EQUAL( 200.0 / 86400 , well_controls_iget_target(ctrls0,1));
BOOST_CHECK_EQUAL( 400 * 100000 , well_controls_iget_target(ctrls0,2));
// Which control is active
BOOST_CHECK_EQUAL( 0 , well_controls_get_current(ctrls0) );
// The phase distribution in the active target
{
const double * distr = well_controls_iget_distr( ctrls0 , 0 );
BOOST_CHECK_EQUAL( 0 , distr[0] ); // Water
BOOST_CHECK_EQUAL( 0 , distr[1] ); // Oil
BOOST_CHECK_EQUAL( 1 , distr[2] ); // Gas
}
}
// The producer
{
const struct WellControls * ctrls1 = ctrls[1];
BOOST_CHECK_EQUAL( 2 , well_controls_get_num( ctrls1 )); // The number of controls for the producer == 2??
BOOST_CHECK_EQUAL( SURFACE_RATE , well_controls_iget_type(ctrls1 , 0) );
BOOST_CHECK_EQUAL( BHP , well_controls_iget_type(ctrls1 , 1) );
// The different targets
BOOST_CHECK_EQUAL( -20000.0 / 86400 , well_controls_iget_target(ctrls1,0));
BOOST_CHECK_EQUAL( 1000 * 100000 , well_controls_iget_target(ctrls1,1));
// Which control is active
BOOST_CHECK_EQUAL( 0 , well_controls_get_current(ctrls1));
// The phase distribution in the active target
{
const double * distr = well_controls_iget_distr( ctrls1 , 0 );
BOOST_CHECK_EQUAL( 0 , distr[0] ); // Water
BOOST_CHECK_EQUAL( 1 , distr[1] ); // Oil
BOOST_CHECK_EQUAL( 0 , distr[2] ); // Gas
}
}
}
void check_controls_epoch1( struct WellControls ** ctrls) {
// The injector
{
const struct WellControls * ctrls0 = ctrls[0];
BOOST_CHECK_EQUAL( 3 , well_controls_get_num(ctrls0)); // The number of controls for the injector == 3??
BOOST_CHECK_EQUAL( SURFACE_RATE , well_controls_iget_type(ctrls0 , 0 ));
BOOST_CHECK_EQUAL( RESERVOIR_RATE , well_controls_iget_type(ctrls0 , 1 ));
BOOST_CHECK_EQUAL( BHP , well_controls_iget_type(ctrls0 , 2 ));
// The different targets
BOOST_CHECK_CLOSE( 10.0 / 86400 , well_controls_iget_target(ctrls0 , 0) , 0.001);
BOOST_CHECK_CLOSE( 20.0 / 86400 , well_controls_iget_target(ctrls0 , 1) , 0.001);
BOOST_CHECK_CLOSE( 40 * 100000 , well_controls_iget_target(ctrls0 , 2) , 0.001);
// Which control is active
BOOST_CHECK_EQUAL( 1 , well_controls_get_current(ctrls0));
{
const double * distr = well_controls_iget_distr( ctrls0 , 1 );
BOOST_CHECK_EQUAL( 1 , distr[0] ); // Water
BOOST_CHECK_EQUAL( 0 , distr[1] ); // Oil
BOOST_CHECK_EQUAL( 0 , distr[2] ); // Gas
}
}
// The producer
{
const struct WellControls * ctrls1 = ctrls[1];
BOOST_CHECK_EQUAL( 3 , well_controls_get_num(ctrls1)); // The number of controls for the producer - now 3.
BOOST_CHECK_EQUAL( SURFACE_RATE , well_controls_iget_type(ctrls1 , 0) );
BOOST_CHECK_EQUAL( RESERVOIR_RATE , well_controls_iget_type(ctrls1 , 1) );
BOOST_CHECK_EQUAL( BHP , well_controls_iget_type(ctrls1 , 2) );
// The different targets
BOOST_CHECK_CLOSE( -999.0 / 86400 , well_controls_iget_target(ctrls1 , 0), 0.001);
BOOST_CHECK_CLOSE( -123.0 / 86400 , well_controls_iget_target(ctrls1 , 1), 0.001);
BOOST_CHECK_CLOSE( 100 * 100000 , well_controls_iget_target(ctrls1 , 2), 0.001);
// Which control is active
BOOST_CHECK_EQUAL( 1 , well_controls_get_current(ctrls1) );
{
const double * distr = well_controls_iget_distr( ctrls1 , 1 );
BOOST_CHECK_EQUAL( 1 , distr[0] ); // Water
BOOST_CHECK_EQUAL( 1 , distr[1] ); // Oil
BOOST_CHECK_EQUAL( 1 , distr[2] ); // Gas
}
}
}
BOOST_AUTO_TEST_CASE(Constructor_Works) {
Opm::EclipseGridParser Deck("wells_manager_data.data");
Opm::GridManager gridManager(Deck);
Deck.setCurrentEpoch(0);
{
Opm::WellsManager wellsManager(Deck, *gridManager.c_grid(), NULL);
const Wells* wells = wellsManager.c_wells();
wells_static_check( wells );
check_controls_epoch0( wells->ctrls );
}
Deck.setCurrentEpoch(1);
{
Opm::WellsManager wellsManager(Deck, *gridManager.c_grid(), NULL);
const Wells* wells = wellsManager.c_wells();
wells_static_check( wells );
check_controls_epoch1( wells->ctrls );
}
}
BOOST_AUTO_TEST_CASE(WellsEqual) {
Opm::EclipseGridParser Deck("wells_manager_data.data");
Opm::GridManager gridManager(Deck);
Deck.setCurrentEpoch(0);
Opm::WellsManager wellsManager0(Deck, *gridManager.c_grid(), NULL);
Deck.setCurrentEpoch(1);
Opm::WellsManager wellsManager1(Deck, *gridManager.c_grid(), NULL);
BOOST_CHECK( wells_equal( wellsManager0.c_wells() , wellsManager0.c_wells()) );
BOOST_CHECK( !wells_equal( wellsManager0.c_wells() , wellsManager1.c_wells()) );
}
BOOST_AUTO_TEST_CASE(ControlsEqual) {
Opm::EclipseGridParser Deck("wells_manager_data.data");
Opm::GridManager gridManager(Deck);
Deck.setCurrentEpoch(0);
Opm::WellsManager wellsManager0(Deck, *gridManager.c_grid(), NULL);
Deck.setCurrentEpoch(1);
Opm::WellsManager wellsManager1(Deck, *gridManager.c_grid(), NULL);
BOOST_CHECK( well_controls_equal( wellsManager0.c_wells()->ctrls[0] , wellsManager0.c_wells()->ctrls[0]));
BOOST_CHECK( well_controls_equal( wellsManager0.c_wells()->ctrls[1] , wellsManager0.c_wells()->ctrls[1]));
BOOST_CHECK( well_controls_equal( wellsManager1.c_wells()->ctrls[0] , wellsManager1.c_wells()->ctrls[0]));
BOOST_CHECK( well_controls_equal( wellsManager1.c_wells()->ctrls[1] , wellsManager1.c_wells()->ctrls[1]));
BOOST_CHECK( !well_controls_equal( wellsManager0.c_wells()->ctrls[0] , wellsManager0.c_wells()->ctrls[1]));
BOOST_CHECK( !well_controls_equal( wellsManager0.c_wells()->ctrls[1] , wellsManager0.c_wells()->ctrls[0]));
BOOST_CHECK( !well_controls_equal( wellsManager1.c_wells()->ctrls[0] , wellsManager0.c_wells()->ctrls[0]));
BOOST_CHECK( !well_controls_equal( wellsManager1.c_wells()->ctrls[1] , wellsManager0.c_wells()->ctrls[1]));
}

58
tests/wells_manager_data.data Executable file
View File

@@ -0,0 +1,58 @@
OIL
GAS
WATER
DIMENS
10 10 5 /
GRID
DXV
10*1000.0 /
DYV
10*1000.0 /
DZV
10.0 20.0 30.0 10.0 5.0 /
SCHEDULE
WELSPECS
'INJ1' 'G' 1 1 8335 'GAS' /
'PROD1' 'G' 10 10 8400 'OIL' /
/
COMPDAT
'INJ1' 1 1 1 1 'OPEN' 1 10.6092 0.5 /
'PROD1' 10 3 3 3 'OPEN' 0 10.6092 0.5 /
/
WCONPROD
'PROD1' 'OPEN' 'ORAT' 20000 4* 1000 /
/
WCONINJE
'INJ1' 'GAS' 'OPEN' 'RATE' 100 200 400 /
/
DATES
1 'FEB' 2000 /
/
WCONPROD
'PROD1' 'OPEN' 'RESV' 999 3* 123 100 /
/
WCONINJE
'INJ1' 'WATER' 'OPEN' 'RESV' 10 20 40 /
/
TSTEP
14.0
/
END