This commit is contained in:
Atgeirr Flø Rasmussen 2012-03-30 16:11:27 +02:00
commit 40b4fcb7ac
11 changed files with 447 additions and 29 deletions

View File

@ -57,7 +57,9 @@ opm/core/utility/newwells.c \
opm/core/utility/writeVtkData.cpp \
opm/core/GridManager.cpp \
opm/core/WellsManager.cpp \
opm/core/InjectionSpecification.cpp \
opm/core/WellsGroup.cpp \
opm/core/WellCollection.cpp \
opm/core/InjectionSpecification.cpp \
opm/core/ProductionSpecification.cpp \
opm/core/linalg/sparse_sys.c \
opm/core/linalg/LinearSolverInterface.cpp \
@ -164,6 +166,8 @@ opm/core/linalg/LinearSolverInterface.hpp \
opm/core/grid.h \
opm/core/well.h \
opm/core/newwells.h \
opm/core/WellsGroup.hpp \
opm/core/WellCollection.hpp \
opm/core/InjectionSpecification.hpp \
opm/core/ProductionSpecification.hpp \
opm/core/ColumnExtract.hpp \

View File

@ -3,8 +3,8 @@ namespace Opm
{
InjectionSpecification::InjectionSpecification()
: component_(WATER), control_mode_(NONE), surface_injection_target_(0.0),
reinjection_fraction_target_(0.0), BHP_target_(0.0)
: injector_type_(WATER), control_mode_(NONE), surface_flow_max_rate_(0.0),
reinjection_fraction_target_(0.0), BHP_limit_(0.0)
{
}

View File

@ -10,16 +10,16 @@ namespace Opm
enum ControlMode
{
NONE, RATE, REIN, RESV, VREP, WGRA, FLD
NONE, ORAT, REIN, RESV, VREP, WGRA, FLD, GRUP
};
InjectionSpecification();
surface_component component_;
surface_component injector_type_;
ControlMode control_mode_;
double surface_injection_target_;
double surface_flow_max_rate_;
double reinjection_fraction_target_;
double BHP_target_;
double BHP_limit_;
};
}
#endif /* OPM_INJECTORSPECIFICATION_HPP */

View File

@ -4,13 +4,13 @@ namespace Opm
{
ProductionSpecification::ProductionSpecification()
: component_(OIL),
:
control_mode_(NONE_CM),
procedure_(NONE_P),
oil_production_target_(-1.0),
oil_max_rate_(-1.0),
water_production_target_(-1.0),
liquid_production_target_(-1.0),
BHP_target_(-1.0)
fluid_volume_max_rate_(-1.0),
BHP_limit_(-1.0)
{
}

View File

@ -11,7 +11,7 @@ namespace Opm
enum ControlMode
{
NONE_CM, ORAT, WRAT, REIN, RESV, VREP, WGRA, FLD
NONE_CM, ORAT, WRAT, REIN, RESV, VREP, WGRA, FLD, GRUP
};
enum Procedure
@ -21,15 +21,15 @@ namespace Opm
ProductionSpecification();
surface_component component_;
ControlMode control_mode_;
Procedure procedure_;
double oil_production_target_;
double oil_max_rate_;
double water_production_target_;
double liquid_production_target_;
double BHP_target_;
double fluid_volume_max_rate_;
double BHP_limit_;
double gas_max_rate_;
double liquid_max_rate_;
};
}

View File

@ -0,0 +1,80 @@
/*
Copyright 2011 SINTEF ICT, Applied Mathematics.
This file is part of The Open Reservoir Simulator Project (OpenRS).
OpenRS 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.
OpenRS 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 OpenRS. If not, see <http://www.gnu.org/licenses/>.
*/
#include "WellCollection.hpp"
namespace Opm
{
WellCollection::WellCollection()
{
}
WellCollection::~WellCollection()
{
}
void WellCollection::addChild(std::string child_name, std::string parent_name,
const EclipseGridParser& deck)
{
WellsGroupInterface* parent = findNode(parent_name);
if (!parent) {
roots_.push_back(createWellsGroup(parent_name, deck));
parent = roots_[roots_.size() - 1].get();
}
std::tr1::shared_ptr<WellsGroupInterface> child;
for (int i = 0; i < roots_.size(); ++i) {
if (roots_[i]->name() == child_name) {
child = roots_[i];
// We've found a new parent to the previously thought root, need to remove it
for(int j = i; j < roots_.size() - 1; ++j) {
roots_[j] = roots_[j+1];
}
roots_.resize(roots_.size()-1);
break;
}
}
if (!child.get()) {
child = createWellsGroup(child_name, deck);
}
WellsGroup* parent_as_group = static_cast<WellsGroup*> (parent);
if (!parent_as_group) {
THROW("Trying to add child to group named " << parent_name << ", but it's not a group.");
}
parent_as_group->addChild(child);
}
WellsGroupInterface* WellCollection::findNode(std::string name)
{
for (int i = 0; i < roots_.size(); i++) {
WellsGroupInterface* result = roots_[i]->findGroup(name);
if (result) {
return result;
}
}
return NULL;
}
}

View File

@ -0,0 +1,49 @@
/*
Copyright 2011 SINTEF ICT, Applied Mathematics.
This file is part of The Open Reservoir Simulator Project (OpenRS).
OpenRS 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.
OpenRS 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 OpenRS. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_WELLCOLLECTION_HPP
#define OPM_WELLCOLLECTION_HPP
#include <vector>
#include <opm/core/WellsGroup.hpp>
#include <opm/core/eclipse/EclipseGridParser.hpp>
namespace Opm
{
class WellCollection
{
public:
WellCollection();
virtual ~WellCollection();
void addChild(std::string child, std::string parent,
const EclipseGridParser& deck);
private:
// To account for the possibility of a forest
std::vector<std::tr1::shared_ptr<WellsGroupInterface> > roots_;
WellsGroupInterface* findNode(std::string name);
};
} // namespace Opm
#endif /* OPM_WELLCOLLECTION_HPP */

View File

@ -5,16 +5,247 @@
* Created on March 27, 2012, 9:27 AM
*/
#include "WellsGroup.hpp"
namespace Opm {
WellsGroupInterface::AbstractWellsGroup() {
}
#include <opm/core/WellsGroup.hpp>
WellsGroupInterface::~WellsGroupInterface() {
}
namespace Opm
{
const std::string& WellsGroupInterface::name() {
return name_;
}
}
WellsGroupInterface::WellsGroupInterface(const std::string& name, ProductionSpecification prod_spec,
InjectionSpecification inje_spec)
: name_(name), production_specification_(prod_spec),
injection_specification_(inje_spec)
{
}
WellsGroupInterface::~WellsGroupInterface()
{
}
const std::string& WellsGroupInterface::name()
{
return name_;
}
WellsGroup::WellsGroup(const std::string& name, ProductionSpecification prod_spec,
InjectionSpecification inj_spec)
: WellsGroupInterface(name, prod_spec, inj_spec)
{
}
WellsGroupInterface* WellsGroup::findGroup(std::string name_of_node)
{
if (name() == name_of_node) {
return this;
} else {
for (int i = 0; i < children_.size(); i++) {
WellsGroupInterface* result = children_[i]->findGroup(name_of_node);
if (result) {
return result;
}
}
// Not found in this node.
return NULL;
}
}
void WellsGroup::addChild(std::tr1::shared_ptr<WellsGroupInterface> child) {
children_.push_back(child);
}
WellNode::WellNode(const std::string& name, ProductionSpecification prod_spec,
InjectionSpecification inj_spec)
: WellsGroupInterface(name, prod_spec, inj_spec)
{
}
WellsGroupInterface* WellNode::findGroup(std::string name_of_node)
{
if (name() == name_of_node) {
return this;
} else {
return NULL;
}
}
surface_component toSurfaceComponent(std::string type)
{
if (type == "OIL") {
return OIL;
}
if (type == "WATER") {
return WATER;
}
if (type == "GAS") {
return GAS;
}
THROW("Unknown type " << type << ", could not convert to surface_component");
}
InjectionSpecification::ControlMode toInjectionControlMode(std::string type)
{
if (type == "NONE") {
return InjectionSpecification::NONE;
}
if (type == "ORAT") {
return InjectionSpecification::ORAT;
}
if (type == "REIN") {
return InjectionSpecification::REIN;
}
if (type == "RESV") {
return InjectionSpecification::RESV;
}
if (type == "VREP") {
return InjectionSpecification::VREP;
}
if (type == "WGRA") {
return InjectionSpecification::WGRA;
}
if (type == "FLD") {
return InjectionSpecification::FLD;
}
if (type == "GRUP") {
return InjectionSpecification::GRUP;
}
THROW("Unknown type " << type << ", could not convert to ControlMode.");
}
ProductionSpecification::ControlMode toProductionControlMode(std::string type)
{
if (type == "NONE") {
return ProductionSpecification::NONE_CM;
}
if (type == "ORAT") {
return ProductionSpecification::ORAT;
}
if (type == "REIN") {
return ProductionSpecification::REIN;
}
if (type == "RESV") {
return ProductionSpecification::RESV;
}
if (type == "VREP") {
return ProductionSpecification::VREP;
}
if (type == "WGRA") {
return ProductionSpecification::WGRA;
}
if (type == "FLD") {
return ProductionSpecification::FLD;
}
if (type == "GRUP") {
return ProductionSpecification::GRUP;
}
THROW("Unknown type " << type << ", could not convert to ControlMode.");
}
ProductionSpecification::Procedure toProductionProcedure(std::string type)
{
if (type == "NONE") {
return ProductionSpecification::NONE_P;
}
if (type == "RATE") {
return ProductionSpecification::RATE;
}
if (type == "WELL") {
return ProductionSpecification::WELL;
}
THROW("Unknown type " << type << ", could not convert to ControlMode.");
}
std::tr1::shared_ptr<WellsGroupInterface> createWellsGroup(std::string name, const EclipseGridParser& deck)
{
std::tr1::shared_ptr<WellsGroupInterface> return_value;
// First we need to determine whether it's a group or just a well:
bool isWell = false;
if (deck.hasField("WELSPECS")) {
WELSPECS wspecs = deck.getWELSPECS();
for (int i = 0; i < wspecs.welspecs.size(); i++) {
if (wspecs.welspecs[i].name_ == name) {
isWell = true;
break;
}
}
}
// For now, assume that if it isn't a well, it's a group
if (isWell) {
InjectionSpecification injection_specification;
if (deck.hasField("WCONINJE")) {
WCONINJE wconinje = deck.getWCONINJE();
for (int i = 0; i < wconinje.wconinje.size(); i++) {
if (wconinje.wconinje[i].well_ == name) {
WconinjeLine line = wconinje.wconinje[i];
injection_specification.BHP_limit_ = line.BHP_limit_;
injection_specification.injector_type_ = toSurfaceComponent(line.injector_type_);
injection_specification.control_mode_ = toInjectionControlMode(line.control_mode_);
injection_specification.surface_flow_max_rate_ = line.surface_flow_max_rate_;
}
}
}
ProductionSpecification production_specification;
if (deck.hasField("WCONPROD")) {
WCONPROD wconprod = deck.getWCONPROD();
for (int i = 0; i < wconprod.wconprod.size(); i++) {
if (wconprod.wconprod[i].well_ == name) {
WconprodLine line = wconprod.wconprod[i];
production_specification.BHP_limit_ = line.BHP_limit_;
production_specification.fluid_volume_max_rate_ = line.fluid_volume_max_rate_;
production_specification.oil_max_rate_ = line.oil_max_rate_;
production_specification.control_mode_ = toProductionControlMode(line.control_mode_);
production_specification.water_production_target_ = line.water_max_rate_;
}
}
}
return_value.reset(new WellNode(name, production_specification, injection_specification));
} else {
InjectionSpecification injection_specification;
if (deck.hasField("GCONINJE")) {
GCONINJE gconinje = deck.getGCONINJE();
for (int i = 0; i < gconinje.gconinje.size(); i++) {
if (gconinje.gconinje[i].group_ == name) {
GconinjeLine line = gconinje.gconinje[i];
injection_specification.injector_type_ = toSurfaceComponent(line.injector_type_);
injection_specification.control_mode_ = toInjectionControlMode(line.control_mode_);
injection_specification.surface_flow_max_rate_ = line.surface_flow_max_rate_;
}
}
}
ProductionSpecification production_specification;
if (deck.hasField("GCONPROD")) {
GCONPROD gconprod = deck.getGCONPROD();
for (int i = 0; i < gconprod.gconprod.size(); i++) {
if (gconprod.gconprod[i].group_ == name) {
GconprodLine line = gconprod.gconprod[i];
production_specification.oil_max_rate_ = line.oil_max_rate_;
production_specification.control_mode_ = toProductionControlMode(line.control_mode_);
production_specification.water_production_target_ = line.water_max_rate_;
production_specification.gas_max_rate_ = line.gas_max_rate_;
production_specification.liquid_max_rate_ = line.liquid_max_rate_;
production_specification.procedure_ = toProductionProcedure(line.procedure_);
}
}
}
return_value.reset(new WellsGroup(name, production_specification, injection_specification));
}
return return_value;
}
}

View File

@ -3,32 +3,62 @@
#include <opm/core/InjectionSpecification.hpp>
#include <opm/core/ProductionSpecification.hpp>
#include <opm/core/eclipse/EclipseGridParser.hpp>
#include <string>
namespace Opm
{
class WellsGroupInterface
{
public:
WellsGroupInterface(const std::string& name);
WellsGroupInterface(const std::string& name, ProductionSpecification prod_spec,
InjectionSpecification inj_spec);
virtual ~WellsGroupInterface();
const std::string& name();
const ProductionSpecification& prodSpec() const;
const InjectionSpecification& injSpec() const;
/// \returns the pointer to the WellsGroupInterface with the given name. NULL if
/// the name is not found.a
virtual WellsGroupInterface* findGroup(std::string name_of_node) = 0;
private:
std::string name_;
ProductionSpecification production_specification_;
InjectionSpecification injection_specification_;
};
class WellsGroup : public WellsGroupInterface
{
public:
WellsGroup(const std::string& name, ProductionSpecification prod_spec,
InjectionSpecification inj_spec);
virtual WellsGroupInterface* findGroup(std::string name_of_node);
void addChild(std::tr1::shared_ptr<WellsGroupInterface> child);
private:
std::vector<std::tr1::shared_ptr<WellsGroupInterface> > children_;
};
class WellNode : public WellsGroupInterface
{
public:
WellNode(const std::string& name, ProductionSpecification prod_spec,
InjectionSpecification inj_spec);
virtual WellsGroupInterface* findGroup(std::string name_of_node);
};
std::tr1::shared_ptr<WellsGroupInterface> createWellsGroup(std::string name,
const EclipseGridParser& deck);
}
#endif /* OPM_WELLSGROUP_HPP */

View File

@ -24,6 +24,7 @@
#include <opm/core/newwells.h>
#include <opm/core/utility/ErrorMacros.hpp>
#include <opm/core/utility/Units.hpp>
#include <opm/core/WellCollection.hpp>
#include <tr1/array>
#include <cmath>
@ -504,6 +505,25 @@ namespace Opm
}
}
WellCollection well_collection;
if (deck.hasField("GRUPTREE")) {
std::cout << "Found gruptree" << std::endl;
const GRUPTREE& gruptree = deck.getGRUPTREE();
std::map<std::string, std::string>::const_iterator it = gruptree.tree.begin();
for( ; it != gruptree.tree.end(); ++it) {
well_collection.addChild(it->first, it->second, deck);
}
}
if(deck.hasField("WELSPECS")) {
WELSPECS welspecs = deck.getWELSPECS();
for(int i = 0; i < welspecs.welspecs.size(); ++i) {
WelspecsLine line = welspecs.welspecs[i];
well_collection.addChild(line.name_, line.group_, deck);
}
}
}

View File

@ -1247,6 +1247,10 @@ struct GCONPROD : public SpecialBase
GconprodLine gconprod_line;
gconprod_line.group_ = groupname;
gconprod_line.control_mode_ = readString(is);
if (gconprod_line.control_mode_[gconprod_line.control_mode_.size() - 1] == '*')
{
gconprod_line.control_mode_ = "NONE";
}
std::vector<double> double_data(4, 1.0E20);
const int num_to_read = 4;
int num_read = readDefaultedVectorData(is, double_data, num_to_read);