From 1181d1c1bce9e2430cdfa09b4cafeb227a9a1244 Mon Sep 17 00:00:00 2001 From: Kristian Flikka Date: Wed, 12 Feb 2014 15:39:57 +0100 Subject: [PATCH] Create WellsGroupInterface from opm-parser Well/Group objects --- opm/core/wells/WellCollection.cpp | 82 ++++++++++++++++++++++++++++ opm/core/wells/WellCollection.hpp | 30 ++++++++++- opm/core/wells/WellsGroup.cpp | 2 +- opm/core/wells/WellsGroup.hpp | 2 +- tests/test_wellcollection.cpp | 90 +++++++++++++++++++++++++++++++ 5 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 tests/test_wellcollection.cpp diff --git a/opm/core/wells/WellCollection.cpp b/opm/core/wells/WellCollection.cpp index 350d2ffb3..0cc7a9ce5 100644 --- a/opm/core/wells/WellCollection.cpp +++ b/opm/core/wells/WellCollection.cpp @@ -19,10 +19,92 @@ #include "config.h" #include + +#include +#include + #include namespace Opm { + void WellCollection::addChild(GroupConstPtr groupChild, GroupConstPtr groupParent, + size_t timeStep, const PhaseUsage& phaseUsage) { + WellsGroupInterface* parent = findNode(groupParent->name()); + if (!parent) { + roots_.push_back(createGroupWellsGroup(groupParent, timeStep, phaseUsage)); + parent = roots_[roots_.size() - 1].get(); + } + + std::shared_ptr child; + + for (size_t i = 0; i < roots_.size(); ++i) { + if (roots_[i]->name() == groupChild->name()) { + child = roots_[i]; + // We've found a new parent to the previously thought root, need to remove it + for(size_t j = i; j < roots_.size() - 1; ++j) { + roots_[j] = roots_[j+1]; + } + + roots_.resize(roots_.size()-1); + break; + } + } + if (!child.get()) { + child = createGroupWellsGroup(groupChild, timeStep, phaseUsage); + } + + WellsGroup* parent_as_group = static_cast (parent); + if (!parent_as_group) { + OPM_THROW(std::runtime_error, "Trying to add child to group named " << groupParent->name() << ", but it's not a group."); + } + parent_as_group->addChild(child); + + if(child->isLeafNode()) { + leaf_nodes_.push_back(static_cast(child.get())); + } + + child->setParent(parent); + } + + void WellCollection::addChild(WellConstPtr wellChild, GroupConstPtr groupParent, + size_t timeStep, const PhaseUsage& phaseUsage) { + WellsGroupInterface* parent = findNode(groupParent->name()); + if (!parent) { + roots_.push_back(createGroupWellsGroup(groupParent, timeStep, phaseUsage)); + parent = roots_[roots_.size() - 1].get(); + } + + std::shared_ptr child; + + for (size_t i = 0; i < roots_.size(); ++i) { + if (roots_[i]->name() == wellChild->name()) { + child = roots_[i]; + // We've found a new parent to the previously thought root, need to remove it + for(size_t j = i; j < roots_.size() - 1; ++j) { + roots_[j] = roots_[j+1]; + } + + roots_.resize(roots_.size()-1); + break; + } + } + if (!child.get()) { + child = createWellWellsGroup(wellChild, timeStep, phaseUsage); + } + + WellsGroup* parent_as_group = static_cast (parent); + if (!parent_as_group) { + OPM_THROW(std::runtime_error, "Trying to add child to group named " << groupParent->name() << ", but it's not a group."); + } + parent_as_group->addChild(child); + + if(child->isLeafNode()) { + leaf_nodes_.push_back(static_cast(child.get())); + } + + child->setParent(parent); + } + void WellCollection::addChild(const std::string& child_name, const std::string& parent_name, diff --git a/opm/core/wells/WellCollection.hpp b/opm/core/wells/WellCollection.hpp index 9cdb9e7f1..8933ff037 100644 --- a/opm/core/wells/WellCollection.hpp +++ b/opm/core/wells/WellCollection.hpp @@ -23,10 +23,15 @@ #define OPM_WELLCOLLECTION_HPP #include +#include + #include #include #include -#include +#include + +#include +#include namespace Opm { @@ -34,6 +39,29 @@ namespace Opm class WellCollection { public: + + /// Adds and creates if necessary the child to the collection + /// and appends it to parent's children. Also adds and creates the parent + /// if necessary. + /// \param[in] wellChild the child well + /// \param[in] groupParent the parent group + /// \param[in] phaseUsage the phase usage + /// \param[in] timeStep the current time step + void addChild(WellConstPtr wellChild, GroupConstPtr groupParent, + size_t timeStep, const PhaseUsage& phaseUsage); + + + /// Adds and creates if necessary the child to the collection + /// and appends it to parent's children. Also adds and creates the parent + /// if necessary. + /// \param[in] groupChild the child group + /// \param[in] groupParent the parent group + /// \param[in] phaseUsage the phase usage + /// \param[in] timeStep the current time step + void addChild(GroupConstPtr groupChild, GroupConstPtr groupParent, + size_t timeStep, const PhaseUsage& phaseUsage); + + /// Adds and creates if necessary the child to the collection /// and appends it to parent's children. Also adds and creates the parent /// if necessary. diff --git a/opm/core/wells/WellsGroup.cpp b/opm/core/wells/WellsGroup.cpp index 62663ce85..1087afcf3 100644 --- a/opm/core/wells/WellsGroup.cpp +++ b/opm/core/wells/WellsGroup.cpp @@ -74,7 +74,7 @@ namespace Opm { return parent_; } - const std::string& WellsGroupInterface::name() + const std::string& WellsGroupInterface::name() const { return name_; } diff --git a/opm/core/wells/WellsGroup.hpp b/opm/core/wells/WellsGroup.hpp index ebf9d986d..03a61d5e1 100644 --- a/opm/core/wells/WellsGroup.hpp +++ b/opm/core/wells/WellsGroup.hpp @@ -62,7 +62,7 @@ namespace Opm virtual ~WellsGroupInterface(); /// The unique identifier for the well or well group. - const std::string& name(); + const std::string& name() const; /// Production specifications for the well or well group. const ProductionSpecification& prodSpec() const; diff --git a/tests/test_wellcollection.cpp b/tests/test_wellcollection.cpp new file mode 100644 index 000000000..0c12af446 --- /dev/null +++ b/tests/test_wellcollection.cpp @@ -0,0 +1,90 @@ +/* + 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 WellCollectionTest +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace Opm; + +BOOST_AUTO_TEST_CASE(AddWellsAndGroupToCollection) { + 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); + + GroupTreeNodePtr field=eclipseState->getSchedule()->getGroupTree(2)->getNode("FIELD"); + GroupTreeNodePtr g1=eclipseState->getSchedule()->getGroupTree(2)->getNode("G1"); + GroupTreeNodePtr g2=eclipseState->getSchedule()->getGroupTree(2)->getNode("G2"); + + WellCollection collection; + + // Add groups to WellCollection + GroupConstPtr fieldGroup = eclipseState->getSchedule()->getGroup(field->name()); + for (auto iter = field->begin(); iter != field->end(); ++iter) { + GroupConstPtr childGroupNode = eclipseState->getSchedule()->getGroup((*iter).second->name()); + collection.addChild(childGroupNode, fieldGroup, 2, pu); + } + + GroupConstPtr g1Group = eclipseState->getSchedule()->getGroup(g1->name()); + for (auto iter = g1->begin(); iter != g1->end(); ++iter) { + GroupConstPtr childGroupNode = eclipseState->getSchedule()->getGroup((*iter).second->name()); + collection.addChild(childGroupNode, g1Group, 2, pu); + } + + + GroupConstPtr g2Group = eclipseState->getSchedule()->getGroup(g2->name()); + for (auto iter = g2->begin(); iter != g2->end(); ++iter) { + GroupConstPtr childGroupNode = eclipseState->getSchedule()->getGroup((*iter).second->name()); + collection.addChild(childGroupNode, g2Group, 2, pu); + } + + BOOST_CHECK_EQUAL("FIELD", collection.findNode("FIELD")->name()); + BOOST_CHECK_EQUAL("FIELD", collection.findNode("G1")->getParent()->name()); + BOOST_CHECK_EQUAL("FIELD", collection.findNode("G2")->getParent()->name()); + + // Add wells to WellCollection + WellCollection wellCollection; + std::vector wells = eclipseState->getSchedule()->getWells(); + for (size_t i=0; igetSchedule()->getGroup(wells[i]->getGroupName(2)); + collection.addChild(wells[i], parentGroup, 2, pu); + } + + BOOST_CHECK_EQUAL("G1", collection.findNode("INJ1")->getParent()->name()); + BOOST_CHECK_EQUAL("G1", collection.findNode("INJ2")->getParent()->name()); + BOOST_CHECK_EQUAL("G2", collection.findNode("PROD1")->getParent()->name()); + BOOST_CHECK_EQUAL("G2", collection.findNode("PROD2")->getParent()->name()); +} +