diff --git a/opm/core/wells/WellsGroup.cpp b/opm/core/wells/WellsGroup.cpp index 6c1059a29..62663ce85 100644 --- a/opm/core/wells/WellsGroup.cpp +++ b/opm/core/wells/WellsGroup.cpp @@ -1141,4 +1141,55 @@ namespace Opm return return_value; } + + std::shared_ptr createGroupWellsGroup(GroupConstPtr group, size_t timeStep, const PhaseUsage& phase_usage ) + { + InjectionSpecification injection_specification; + if (group->isInjectionGroup(timeStep)) { + injection_specification.injector_type_ = toInjectorType(Phase::PhaseEnum2String(group->getInjectionPhase(timeStep))); + injection_specification.control_mode_ = toInjectionControlMode(GroupInjection::ControlEnum2String(group->getInjectionControlMode(timeStep))); + injection_specification.surface_flow_max_rate_ = group->getSurfaceMaxRate(timeStep); + injection_specification.reservoir_flow_max_rate_ = group->getReservoirMaxRate(timeStep); + injection_specification.reinjection_fraction_target_ = group->getTargetReinjectFraction(timeStep); + injection_specification.voidage_replacment_fraction_ = group->getTargetVoidReplacementFraction(timeStep); + } + ProductionSpecification production_specification; + if (group->isProductionGroup(timeStep)) { + production_specification.oil_max_rate_ = group->getOilTargetRate(timeStep); + production_specification.control_mode_ = toProductionControlMode(GroupProduction::ControlEnum2String(group->getProductionControlMode(timeStep))); + production_specification.water_max_rate_ = group->getWaterTargetRate(timeStep); + production_specification.gas_max_rate_ = group->getGasTargetRate(timeStep); + production_specification.liquid_max_rate_ = group->getLiquidTargetRate(timeStep); + production_specification.procedure_ = toProductionProcedure(GroupProductionExceedLimit::ActionEnum2String(group->getProductionExceedLimitAction(timeStep))); + production_specification.reservoir_flow_max_rate_ = group->getReservoirMaxRate(timeStep); + } + + std::shared_ptr wells_group(new WellsGroup(group->name(), production_specification, injection_specification, phase_usage)); + return wells_group; + } + + std::shared_ptr createWellWellsGroup(WellConstPtr well, size_t timeStep, const PhaseUsage& phase_usage ) + { + InjectionSpecification injection_specification; + ProductionSpecification production_specification; + if (well->isInjector(timeStep)) { + injection_specification.BHP_limit_ = well->getBHPLimit(timeStep); + injection_specification.injector_type_ = toInjectorType(WellInjector::Type2String(well->getInjectorType(timeStep))); + injection_specification.control_mode_ = toInjectionControlMode(WellInjector::ControlMode2String(well->getInjectorControlMode(timeStep))); + injection_specification.surface_flow_max_rate_ = well->getSurfaceInjectionRate(timeStep); + injection_specification.reservoir_flow_max_rate_ = well->getReservoirInjectionRate(timeStep); + production_specification.guide_rate_ = 0.0; // We know we're not a producer + } + + if (well->isProducer(timeStep)) { + production_specification.BHP_limit_ = well->getBHPLimit(timeStep); + production_specification.reservoir_flow_max_rate_ = well->getResVRate(timeStep); + production_specification.oil_max_rate_ = well->getOilRate(timeStep); + production_specification.control_mode_ = toProductionControlMode(WellProducer::ControlMode2String(well->getProducerControlMode(timeStep))); + production_specification.water_max_rate_ = well->getWaterRate(timeStep); + injection_specification.guide_rate_ = 0.0; // we know we're not an injector + } + std::shared_ptr wells_group(new WellNode(well->name(), production_specification, injection_specification, phase_usage)); + return wells_group; + } } diff --git a/opm/core/wells/WellsGroup.hpp b/opm/core/wells/WellsGroup.hpp index 143da9357..ebf9d986d 100644 --- a/opm/core/wells/WellsGroup.hpp +++ b/opm/core/wells/WellsGroup.hpp @@ -25,6 +25,10 @@ #include #include #include + +#include +#include + #include #include @@ -403,9 +407,21 @@ namespace Opm /// \param[in] name the name of the wells group. /// \param[in] deck the deck from which to fetch information. std::shared_ptr createWellsGroup(const std::string& name, - const EclipseGridParser& deck); + const EclipseGridParser& deck); + /// Creates the WellsGroupInterface for the given well + /// \param[in] well the Well to construct object for + /// \param[in] timeStep the time step in question + /// \param[in] the phase usage + std::shared_ptr createWellWellsGroup(WellConstPtr well, size_t timeStep, + const PhaseUsage& phase_usage ); + /// Creates the WellsGroupInterface for the given Group + /// \param[in] group the Group to construct object for + /// \param[in] timeStep the time step in question + /// \param[in] the phase usage + std::shared_ptr createGroupWellsGroup(GroupConstPtr group, size_t timeStep, + const PhaseUsage& phase_usage ); } #endif /* OPM_WELLSGROUP_HPP */ diff --git a/tests/test_wellsgroup.cpp b/tests/test_wellsgroup.cpp new file mode 100644 index 000000000..82c60163d --- /dev/null +++ b/tests/test_wellsgroup.cpp @@ -0,0 +1,108 @@ +/* + Copyright 2012 SINTEF ICT, Applied Mathematics. + + 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 . +*/ + +#include + +#if HAVE_DYNAMIC_BOOST_TEST +#define BOOST_TEST_DYN_LINK +#endif + +#define NVERBOSE // Suppress own messages when throw()ing + +#define BOOST_TEST_MODULE WellsGroupTest + +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +using namespace Opm; + +BOOST_AUTO_TEST_CASE(ConstructGroupFromWell) { + ParserPtr parser(new Parser()); + boost::filesystem::path scheduleFile("wells_group.data"); + DeckConstPtr deck = parser->parseFile(scheduleFile.string()); + EclipseStateConstPtr eclipseState(new EclipseState(deck)); + PhaseUsage pu = phaseUsageFromDeck(eclipseState); + + std::vector wells = eclipseState->getSchedule()->getWells(); + + for (size_t i=0; i wellsGroup = createWellWellsGroup(well, 2, pu); + BOOST_CHECK_EQUAL(well->name(), wellsGroup->name()); + if (well->isInjector(2)) { + BOOST_CHECK_EQUAL(well->getSurfaceInjectionRate(2), wellsGroup->injSpec().surface_flow_max_rate_); + BOOST_CHECK_EQUAL(well->getBHPLimit(2), wellsGroup->injSpec().BHP_limit_); + BOOST_CHECK_EQUAL(well->getReservoirInjectionRate(2), wellsGroup->injSpec().reservoir_flow_max_rate_); + BOOST_CHECK_EQUAL(0.0, wellsGroup->prodSpec().guide_rate_); + } + if (well->isProducer(2)) { + BOOST_CHECK_EQUAL(well->getResVRate(2), wellsGroup->prodSpec().reservoir_flow_max_rate_); + BOOST_CHECK_EQUAL(well->getBHPLimit(2), wellsGroup->prodSpec().BHP_limit_); + BOOST_CHECK_EQUAL(well->getOilRate(2), wellsGroup->prodSpec().oil_max_rate_); + BOOST_CHECK_EQUAL(well->getWaterRate(2), wellsGroup->prodSpec().water_max_rate_); + BOOST_CHECK_EQUAL(0.0, wellsGroup->injSpec().guide_rate_); + } + } +} + + +BOOST_AUTO_TEST_CASE(ConstructGroupFromGroup) { + ParserPtr parser(new Parser()); + boost::filesystem::path scheduleFile("wells_group.data"); + DeckConstPtr deck = parser->parseFile(scheduleFile.string()); + EclipseStateConstPtr eclipseState(new EclipseState(deck)); + PhaseUsage pu = phaseUsageFromDeck(eclipseState); + + std::vector nodes = eclipseState->getSchedule()->getGroupTree(2)->getNodes(); + + for (size_t i=0; igetSchedule()->getGroup(nodes[i]->name()); + std::shared_ptr wellsGroup = createGroupWellsGroup(group, 2, pu); + BOOST_CHECK_EQUAL(group->name(), wellsGroup->name()); + if (group->isInjectionGroup(2)) { + BOOST_CHECK_EQUAL(group->getSurfaceMaxRate(2), wellsGroup->injSpec().surface_flow_max_rate_); + BOOST_CHECK_EQUAL(group->getReservoirMaxRate(2), wellsGroup->injSpec().reservoir_flow_max_rate_); + BOOST_CHECK_EQUAL(group->getTargetReinjectFraction(2), wellsGroup->injSpec().reinjection_fraction_target_); + BOOST_CHECK_EQUAL(group->getTargetVoidReplacementFraction(2), wellsGroup->injSpec().voidage_replacment_fraction_); + } + if (group->isProductionGroup(2)) { + BOOST_CHECK_EQUAL(group->getReservoirMaxRate(2), wellsGroup->prodSpec().reservoir_flow_max_rate_); + BOOST_CHECK_EQUAL(group->getGasTargetRate(2), wellsGroup->prodSpec().gas_max_rate_); + BOOST_CHECK_EQUAL(group->getOilTargetRate(2), wellsGroup->prodSpec().oil_max_rate_); + BOOST_CHECK_EQUAL(group->getWaterTargetRate(2), wellsGroup->prodSpec().water_max_rate_); + BOOST_CHECK_EQUAL(group->getLiquidTargetRate(2), wellsGroup->prodSpec().liquid_max_rate_); + } + } +} + + + diff --git a/tests/wells_group.data b/tests/wells_group.data new file mode 100755 index 000000000..753d6031e --- /dev/null +++ b/tests/wells_group.data @@ -0,0 +1,61 @@ +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 / + +DEPTHZ +121*2000 +/ + +SCHEDULE + +GRUPTREE + 'G1' 'FIELD' / + 'G2' 'FIELD' / +/ + + +WELSPECS + 'INJ1' 'G1' 1 1 8335 'GAS' / + 'PROD1' 'G2' 10 10 8400 'OIL' / +/ + +TSTEP + 14.0 / +/ + +WELSPECS + 'INJ2' 'G1' 1 1 8335 'GAS' / + 'PROD2' 'G2' 10 10 8400 'OIL' / +/ + + +WCONINJE + 'INJ1' 'WATER' 'OPEN' 'RESV' 10 20 40 / + 'INJ2' 'WATER' 'OPEN' 'RESV' 10 20 40 / +/ + +WCONPROD + 'PROD1' 'OPEN' 'RESV' 999 3* 123 100 / + 'PROD2' 'OPEN' 'RESV' 999 3* 123 100 / +/ + +TSTEP + 3 / +/ + + +END diff --git a/tests/wells_manager_data.data b/tests/wells_manager_data.data index f22152c13..2df2dfd48 100755 --- a/tests/wells_manager_data.data +++ b/tests/wells_manager_data.data @@ -56,7 +56,23 @@ WCONINJE TSTEP -14.0 - / + 14.0 / +/ + + +WELSPECS + 'TEST1' 'G1' 1 1 8335 'GAS' / + 'TEST2' 'G2' 10 10 8400 'OIL' / +/ + +GRUPTREE + 'G1' 'SHIP' / + 'G2' 'SHIP' / +/ + +TSTEP + 3 / +/ + END