mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Added reading of WGRUPCON, also added guide_rates to the well groups. Fixed a small bug in calculateWDP
This commit is contained in:
parent
74fc0a5c25
commit
f1cc0d56e8
@ -99,4 +99,10 @@ namespace Opm
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WellCollection::calculateGuideRates()
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < roots_.size(); i++) {
|
||||||
|
roots_[i]->calculateGuideRates();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -43,6 +43,8 @@ namespace Opm
|
|||||||
bool conditionsMet(const std::vector<double>& well_bhp, const std::vector<double>& well_rate) const;
|
bool conditionsMet(const std::vector<double>& well_bhp, const std::vector<double>& well_rate) const;
|
||||||
|
|
||||||
const std::vector<std::tr1::shared_ptr<WellsGroupInterface> >& getLeafNodes() const;
|
const std::vector<std::tr1::shared_ptr<WellsGroupInterface> >& getLeafNodes() const;
|
||||||
|
|
||||||
|
void calculateGuideRates();
|
||||||
private:
|
private:
|
||||||
// To account for the possibility of a forest
|
// To account for the possibility of a forest
|
||||||
std::vector<std::tr1::shared_ptr<WellsGroupInterface> > roots_;
|
std::vector<std::tr1::shared_ptr<WellsGroupInterface> > roots_;
|
||||||
|
@ -11,12 +11,12 @@ namespace Opm
|
|||||||
{
|
{
|
||||||
|
|
||||||
WellsGroupInterface::WellsGroupInterface(const std::string& myname,
|
WellsGroupInterface::WellsGroupInterface(const std::string& myname,
|
||||||
ProductionSpecification prod_spec,
|
ProductionSpecification prod_spec,
|
||||||
InjectionSpecification inje_spec)
|
InjectionSpecification inje_spec)
|
||||||
: parent_(NULL),
|
: parent_(NULL),
|
||||||
name_(myname),
|
name_(myname),
|
||||||
production_specification_(prod_spec),
|
production_specification_(prod_spec),
|
||||||
injection_specification_(inje_spec)
|
injection_specification_(inje_spec)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,22 +30,48 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
|
|
||||||
WellsGroup::WellsGroup(const std::string& myname,
|
WellsGroup::WellsGroup(const std::string& myname,
|
||||||
ProductionSpecification prod_spec,
|
ProductionSpecification prod_spec,
|
||||||
InjectionSpecification inj_spec)
|
InjectionSpecification inj_spec)
|
||||||
: WellsGroupInterface(myname, prod_spec, inj_spec)
|
: WellsGroupInterface(myname, prod_spec, inj_spec)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WellsGroupInterface::isLeafNode() const
|
bool WellsGroupInterface::isLeafNode() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WellsGroupInterface::setParent(WellsGroupInterface* parent)
|
void WellsGroupInterface::setParent(WellsGroupInterface* parent)
|
||||||
{
|
{
|
||||||
parent_ = parent;
|
parent_ = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ProductionSpecification& WellsGroupInterface::prodSpec() const
|
||||||
|
{
|
||||||
|
return production_specification_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Injection specifications for the well or well group.
|
||||||
|
|
||||||
|
const InjectionSpecification& WellsGroupInterface::injSpec() const
|
||||||
|
{
|
||||||
|
return injection_specification_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Production specifications for the well or well group.
|
||||||
|
|
||||||
|
ProductionSpecification& WellsGroupInterface::prodSpec()
|
||||||
|
{
|
||||||
|
return production_specification_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Injection specifications for the well or well group.
|
||||||
|
|
||||||
|
InjectionSpecification& WellsGroupInterface::injSpec()
|
||||||
|
{
|
||||||
|
return injection_specification_;
|
||||||
|
}
|
||||||
|
|
||||||
WellsGroupInterface* WellsGroup::findGroup(std::string name_of_node)
|
WellsGroupInterface* WellsGroup::findGroup(std::string name_of_node)
|
||||||
{
|
{
|
||||||
if (name() == name_of_node) {
|
if (name() == name_of_node) {
|
||||||
@ -64,39 +90,59 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool WellsGroup::conditionsMet(const std::vector<double>& well_bhp, const std::vector<double>& well_rate,
|
void WellsGroup::calculateGuideRates()
|
||||||
const struct Wells* wells, int index_of_well)
|
|
||||||
{
|
{
|
||||||
if(parent_ != NULL) {
|
double guide_rate_sum = 0.0;
|
||||||
bool parent_ok = (static_cast<WellsGroup*>(parent_))->conditionsMet(well_bhp, well_rate, wells, index_of_well);
|
for(size_t i = 0; i < children_.size(); i++) {
|
||||||
if(!parent_ok) {
|
if(children_[i]->isLeafNode()) {
|
||||||
|
guide_rate_sum += children_[i]->prodSpec().guide_rate_;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
children_[i]->calculateGuideRates();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(guide_rate_sum != 0.0) {
|
||||||
|
for(size_t i = 0; i < children_.size(); i++) {
|
||||||
|
children_[i]->prodSpec().guide_rate_ /= guide_rate_sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool WellsGroup::conditionsMet(const std::vector<double>& well_bhp, const std::vector<double>& well_rate,
|
||||||
|
const struct Wells* wells, int index_of_well)
|
||||||
|
{
|
||||||
|
if (parent_ != NULL) {
|
||||||
|
bool parent_ok = (static_cast<WellsGroup*> (parent_))->conditionsMet(well_bhp, well_rate, wells, index_of_well);
|
||||||
|
if (!parent_ok) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WellsGroup::addChild(std::tr1::shared_ptr<WellsGroupInterface> child)
|
void WellsGroup::addChild(std::tr1::shared_ptr<WellsGroupInterface> child)
|
||||||
{
|
{
|
||||||
children_.push_back(child);
|
children_.push_back(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
WellNode::WellNode(const std::string& myname,
|
WellNode::WellNode(const std::string& myname,
|
||||||
ProductionSpecification prod_spec,
|
ProductionSpecification prod_spec,
|
||||||
InjectionSpecification inj_spec)
|
InjectionSpecification inj_spec)
|
||||||
: WellsGroupInterface(myname, prod_spec, inj_spec)
|
: WellsGroupInterface(myname, prod_spec, inj_spec)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WellNode::conditionsMet(const std::vector<double>& well_bhp, const std::vector<double>& well_rate)
|
bool WellNode::conditionsMet(const std::vector<double>& well_bhp, const std::vector<double>& well_rate)
|
||||||
{
|
{
|
||||||
if(parent_ != NULL) {
|
if (parent_ != NULL) {
|
||||||
bool parent_ok = (static_cast<WellsGroup*>(parent_))->conditionsMet(well_bhp, well_rate, wells_, self_index_);
|
bool parent_ok = (static_cast<WellsGroup*> (parent_))->conditionsMet(well_bhp, well_rate, wells_, self_index_);
|
||||||
if(!parent_ok) {
|
if (!parent_ok) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,17 +155,23 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WellNode::isLeafNode() const
|
bool WellNode::isLeafNode() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WellNode::setWellsPointer(const struct Wells* wells, int self_index) {
|
void WellNode::setWellsPointer(const struct Wells* wells, int self_index)
|
||||||
|
{
|
||||||
wells_ = wells;
|
wells_ = wells;
|
||||||
self_index_ = self_index;
|
self_index_ = self_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WellNode::calculateGuideRates()
|
||||||
|
{
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -199,8 +251,7 @@ namespace Opm
|
|||||||
|
|
||||||
THROW("Unknown type " << type << ", could not convert to ControlMode.");
|
THROW("Unknown type " << type << ", could not convert to ControlMode.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ProductionSpecification::Procedure toProductionProcedure(std::string type)
|
ProductionSpecification::Procedure toProductionProcedure(std::string type)
|
||||||
{
|
{
|
||||||
if (type == "NONE") {
|
if (type == "NONE") {
|
||||||
@ -212,7 +263,7 @@ namespace Opm
|
|||||||
if (type == "WELL") {
|
if (type == "WELL") {
|
||||||
return ProductionSpecification::WELL;
|
return ProductionSpecification::WELL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
THROW("Unknown type " << type << ", could not convert to ControlMode.");
|
THROW("Unknown type " << type << ", could not convert to ControlMode.");
|
||||||
}
|
}
|
||||||
@ -220,7 +271,7 @@ namespace Opm
|
|||||||
|
|
||||||
std::tr1::shared_ptr<WellsGroupInterface> createWellsGroup(std::string name, const EclipseGridParser& deck)
|
std::tr1::shared_ptr<WellsGroupInterface> createWellsGroup(std::string name, const EclipseGridParser& deck)
|
||||||
{
|
{
|
||||||
|
|
||||||
std::tr1::shared_ptr<WellsGroupInterface> return_value;
|
std::tr1::shared_ptr<WellsGroupInterface> return_value;
|
||||||
// First we need to determine whether it's a group or just a well:
|
// First we need to determine whether it's a group or just a well:
|
||||||
bool isWell = false;
|
bool isWell = false;
|
||||||
@ -265,7 +316,7 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return_value.reset(new WellNode(name, production_specification, injection_specification));
|
return_value.reset(new WellNode(name, production_specification, injection_specification));
|
||||||
} else {
|
} else {
|
||||||
InjectionSpecification injection_specification;
|
InjectionSpecification injection_specification;
|
||||||
@ -296,7 +347,7 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return_value.reset(new WellsGroup(name, production_specification, injection_specification));
|
return_value.reset(new WellsGroup(name, production_specification, injection_specification));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,12 @@ namespace Opm
|
|||||||
/// Injection specifications for the well or well group.
|
/// Injection specifications for the well or well group.
|
||||||
const InjectionSpecification& injSpec() const;
|
const InjectionSpecification& injSpec() const;
|
||||||
|
|
||||||
|
/// Production specifications for the well or well group.
|
||||||
|
ProductionSpecification& prodSpec();
|
||||||
|
|
||||||
|
/// Injection specifications for the well or well group.
|
||||||
|
InjectionSpecification& injSpec();
|
||||||
|
|
||||||
/// \returns true if the object is a leaf node (WellNode), false otherwise.
|
/// \returns true if the object is a leaf node (WellNode), false otherwise.
|
||||||
virtual bool isLeafNode() const;
|
virtual bool isLeafNode() const;
|
||||||
|
|
||||||
@ -36,6 +42,8 @@ namespace Opm
|
|||||||
virtual WellsGroupInterface* findGroup(std::string name_of_node) = 0;
|
virtual WellsGroupInterface* findGroup(std::string name_of_node) = 0;
|
||||||
|
|
||||||
void setParent(WellsGroupInterface* parent);
|
void setParent(WellsGroupInterface* parent);
|
||||||
|
|
||||||
|
virtual void calculateGuideRates() = 0;
|
||||||
protected:
|
protected:
|
||||||
WellsGroupInterface* parent_;
|
WellsGroupInterface* parent_;
|
||||||
|
|
||||||
@ -60,6 +68,8 @@ namespace Opm
|
|||||||
|
|
||||||
bool conditionsMet(const std::vector<double>& well_bhp, const std::vector<double>& well_rate, const struct Wells* wells,
|
bool conditionsMet(const std::vector<double>& well_bhp, const std::vector<double>& well_rate, const struct Wells* wells,
|
||||||
int index_of_well);
|
int index_of_well);
|
||||||
|
|
||||||
|
virtual void calculateGuideRates();
|
||||||
private:
|
private:
|
||||||
std::vector<std::tr1::shared_ptr<WellsGroupInterface> > children_;
|
std::vector<std::tr1::shared_ptr<WellsGroupInterface> > children_;
|
||||||
};
|
};
|
||||||
@ -79,6 +89,7 @@ namespace Opm
|
|||||||
|
|
||||||
void setWellsPointer(const struct Wells* wells, int self_index);
|
void setWellsPointer(const struct Wells* wells, int self_index);
|
||||||
|
|
||||||
|
virtual void calculateGuideRates();
|
||||||
private:
|
private:
|
||||||
const struct Wells* wells_;
|
const struct Wells* wells_;
|
||||||
int self_index_;
|
int self_index_;
|
||||||
|
@ -207,6 +207,9 @@ namespace Opm
|
|||||||
std::vector<std::string> well_names;
|
std::vector<std::string> well_names;
|
||||||
std::vector<WellData> well_data;
|
std::vector<WellData> well_data;
|
||||||
std::vector<std::vector<PerfData> > wellperf_data;
|
std::vector<std::vector<PerfData> > wellperf_data;
|
||||||
|
|
||||||
|
// For easy lookup:
|
||||||
|
std::map<std::string, int> well_names_to_index;
|
||||||
|
|
||||||
// Get WELSPECS data
|
// Get WELSPECS data
|
||||||
const WELSPECS& welspecs = deck.getWELSPECS();
|
const WELSPECS& welspecs = deck.getWELSPECS();
|
||||||
@ -218,6 +221,7 @@ namespace Opm
|
|||||||
well_names.push_back(welspecs.welspecs[w].name_);
|
well_names.push_back(welspecs.welspecs[w].name_);
|
||||||
WellData wd;
|
WellData wd;
|
||||||
well_data.push_back(wd);
|
well_data.push_back(wd);
|
||||||
|
well_names_to_index[welspecs.welspecs[w].name_] = w;
|
||||||
well_data.back().reference_bhp_depth = welspecs.welspecs[w].datum_depth_BHP_;
|
well_data.back().reference_bhp_depth = welspecs.welspecs[w].datum_depth_BHP_;
|
||||||
if (welspecs.welspecs[w].datum_depth_BHP_ < 0.0) {
|
if (welspecs.welspecs[w].datum_depth_BHP_ < 0.0) {
|
||||||
// Set refdepth to a marker value, will be changed
|
// Set refdepth to a marker value, will be changed
|
||||||
@ -505,32 +509,44 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WellCollection wells_;
|
|
||||||
if (deck.hasField("GRUPTREE")) {
|
if (deck.hasField("GRUPTREE")) {
|
||||||
std::cout << "Found gruptree" << std::endl;
|
std::cout << "Found gruptree" << std::endl;
|
||||||
const GRUPTREE& gruptree = deck.getGRUPTREE();
|
const GRUPTREE& gruptree = deck.getGRUPTREE();
|
||||||
|
|
||||||
std::map<std::string, std::string>::const_iterator it = gruptree.tree.begin();
|
std::map<std::string, std::string>::const_iterator it = gruptree.tree.begin();
|
||||||
for( ; it != gruptree.tree.end(); ++it) {
|
for( ; it != gruptree.tree.end(); ++it) {
|
||||||
wells_.addChild(it->first, it->second, deck);
|
well_collection_.addChild(it->first, it->second, deck);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < welspecs.welspecs.size(); ++i) {
|
for (size_t i = 0; i < welspecs.welspecs.size(); ++i) {
|
||||||
WelspecsLine line = welspecs.welspecs[i];
|
WelspecsLine line = welspecs.welspecs[i];
|
||||||
wells_.addChild(line.name_, line.group_, deck);
|
well_collection_.addChild(line.name_, line.group_, deck);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(size_t i = 0; i < wells_.getLeafNodes().size(); i++) {
|
for(size_t i = 0; i < well_collection_.getLeafNodes().size(); i++) {
|
||||||
WellNode* node = static_cast<WellNode*>(wells_.getLeafNodes()[i].get());
|
WellNode* node = static_cast<WellNode*>(well_collection_.getLeafNodes()[i].get());
|
||||||
|
|
||||||
// We know that getLeafNodes() is ordered the same way as they're indexed in w_
|
// We know that getLeafNodes() is ordered the same way as they're indexed in w_
|
||||||
node->setWellsPointer(w_, i);
|
node->setWellsPointer(w_, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the guide rates:
|
// Set the guide rates:
|
||||||
if(deck.hasField("WCONPROD")) {
|
if(deck.hasField("WGRUPCON")) {
|
||||||
WCONPROD wconprod = deck.getWCONPROD();
|
std::cout << "Found Wgrupcon" << std::endl;
|
||||||
|
WGRUPCON wgrupcon = deck.getWGRUPCON();
|
||||||
|
const std::vector<WgrupconLine>& lines = wgrupcon.wgrupcon;
|
||||||
|
std::cout << well_collection_.getLeafNodes().size() << std::endl;
|
||||||
|
for(size_t i = 0; i < lines.size(); i++) {
|
||||||
|
std::string name = lines[i].well_;
|
||||||
|
int index = well_names_to_index[name];
|
||||||
|
ASSERT(well_collection_.getLeafNodes()[index]->name() == name);
|
||||||
|
well_collection_.getLeafNodes()[index]->prodSpec().guide_rate_ = lines[i].guide_rate_;
|
||||||
|
well_collection_.getLeafNodes()[index]->prodSpec().guide_rate_type_
|
||||||
|
= lines[i].phase_ == "OIL" ? ProductionSpecification::OIL : ProductionSpecification::RAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
well_collection_.calculateGuideRates();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,11 +416,18 @@ namespace Opm
|
|||||||
|
|
||||||
// Is this correct wrt. depth_ref?
|
// Is this correct wrt. depth_ref?
|
||||||
double cell_depth = grid.cell_centroids[3*cell+2];
|
double cell_depth = grid.cell_centroids[3*cell+2];
|
||||||
|
|
||||||
|
double saturation_sum = 0.0;
|
||||||
|
for(size_t i = 0; i < densities.size(); i++) {
|
||||||
|
saturation_sum += saturations[densities.size()*cell + i];
|
||||||
|
}
|
||||||
|
if(saturation_sum == 0) {
|
||||||
|
saturation_sum = 1.0;
|
||||||
|
}
|
||||||
double density = 0.0;
|
double density = 0.0;
|
||||||
for(size_t i = 0; i < densities.size(); i++) {
|
for(size_t i = 0; i < densities.size(); i++) {
|
||||||
// Is this a smart way of doing it?
|
// Is this a smart way of doing it?
|
||||||
density += saturations[densities.size()*cell+i]*densities[i];
|
density += saturations[densities.size()*cell+i]*densities[i]/saturation_sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is the sign correct?
|
// Is the sign correct?
|
||||||
|
Loading…
Reference in New Issue
Block a user