2012-03-27 09:57:01 -05:00
|
|
|
#ifndef OPM_WELLSGROUP_HPP
|
|
|
|
#define OPM_WELLSGROUP_HPP
|
2012-03-28 08:49:39 -05:00
|
|
|
|
2012-03-27 09:57:01 -05:00
|
|
|
#include <opm/core/InjectionSpecification.hpp>
|
|
|
|
#include <opm/core/ProductionSpecification.hpp>
|
2012-03-29 11:34:51 -05:00
|
|
|
#include <opm/core/eclipse/EclipseGridParser.hpp>
|
2012-04-12 07:25:39 -05:00
|
|
|
#include <opm/core/grid.h>
|
2012-03-28 08:49:39 -05:00
|
|
|
#include <string>
|
|
|
|
|
2012-03-29 11:34:51 -05:00
|
|
|
|
2012-03-28 08:49:39 -05:00
|
|
|
namespace Opm
|
|
|
|
{
|
2012-04-25 09:40:31 -05:00
|
|
|
// Need to forward declare this one, some of the methods in the base
|
|
|
|
// class returns pointers to it.
|
2012-04-25 09:14:40 -05:00
|
|
|
class WellNode;
|
2012-04-25 09:40:31 -05:00
|
|
|
|
|
|
|
/// Basic information needed for group control (each group should typically
|
|
|
|
/// not exceed the sum of its leaf nodes)
|
2012-04-25 09:14:40 -05:00
|
|
|
struct WellPhasesSummed {
|
|
|
|
WellPhasesSummed();
|
|
|
|
double bhp_sum;
|
|
|
|
double rate_sum;
|
|
|
|
|
2012-04-25 09:40:31 -05:00
|
|
|
/// Sums each component
|
2012-04-25 09:14:40 -05:00
|
|
|
void operator+=(const WellPhasesSummed& other);
|
2012-04-17 09:36:49 -05:00
|
|
|
};
|
2012-04-25 07:03:57 -05:00
|
|
|
|
2012-03-28 08:49:39 -05:00
|
|
|
class WellsGroupInterface
|
|
|
|
{
|
|
|
|
public:
|
2012-04-11 03:52:45 -05:00
|
|
|
WellsGroupInterface(const std::string& name,
|
|
|
|
ProductionSpecification prod_spec,
|
|
|
|
InjectionSpecification inj_spec);
|
2012-03-28 08:49:39 -05:00
|
|
|
virtual ~WellsGroupInterface();
|
|
|
|
|
2012-03-30 03:51:31 -05:00
|
|
|
/// The unique identifier for the well or well group.
|
2012-03-28 08:49:39 -05:00
|
|
|
const std::string& name();
|
2012-03-30 03:51:31 -05:00
|
|
|
|
|
|
|
/// Production specifications for the well or well group.
|
2012-03-28 08:49:39 -05:00
|
|
|
const ProductionSpecification& prodSpec() const;
|
2012-03-30 03:51:31 -05:00
|
|
|
|
|
|
|
/// Injection specifications for the well or well group.
|
2012-03-28 08:49:39 -05:00
|
|
|
const InjectionSpecification& injSpec() const;
|
2012-03-30 03:51:31 -05:00
|
|
|
|
2012-04-13 03:32:36 -05:00
|
|
|
/// Production specifications for the well or well group.
|
|
|
|
ProductionSpecification& prodSpec();
|
|
|
|
|
|
|
|
/// Injection specifications for the well or well group.
|
|
|
|
InjectionSpecification& injSpec();
|
|
|
|
|
2012-04-13 13:41:09 -05:00
|
|
|
|
2012-03-30 03:51:31 -05:00
|
|
|
/// \returns true if the object is a leaf node (WellNode), false otherwise.
|
|
|
|
virtual bool isLeafNode() const;
|
2012-04-12 07:25:39 -05:00
|
|
|
|
2012-03-29 11:34:51 -05:00
|
|
|
/// \returns the pointer to the WellsGroupInterface with the given name. NULL if
|
|
|
|
/// the name is not found.a
|
2012-04-25 09:42:55 -05:00
|
|
|
virtual WellsGroupInterface* findGroup(const std::string& name_of_node) = 0;
|
2012-04-25 09:40:31 -05:00
|
|
|
|
|
|
|
/// Sets the parent
|
|
|
|
/// \param[in] parent the pointer to the parent
|
2012-04-12 08:48:24 -05:00
|
|
|
void setParent(WellsGroupInterface* parent);
|
2012-04-25 09:40:31 -05:00
|
|
|
|
|
|
|
/// Gets the parent of the group, NULL if no parent.
|
2012-04-13 04:37:50 -05:00
|
|
|
const WellsGroupInterface* getParent() const;
|
2012-04-13 03:32:36 -05:00
|
|
|
|
2012-04-16 06:44:53 -05:00
|
|
|
/// Recursively calculate the guide rate for each member of the well group.
|
|
|
|
/// This should be called after the guide rates are set to the non-normalized values.
|
2012-04-13 03:32:36 -05:00
|
|
|
virtual void calculateGuideRates() = 0;
|
2012-04-16 06:44:53 -05:00
|
|
|
|
|
|
|
/// Calculates the number of leaf nodes in the given group.
|
|
|
|
/// A leaf node is defined to have one leaf node in its group.
|
|
|
|
virtual int numberOfLeafNodes() = 0;
|
2012-04-25 09:14:40 -05:00
|
|
|
|
2012-04-25 09:40:31 -05:00
|
|
|
/// Checks if each condition is met, applies well controls where needed
|
|
|
|
/// (that is, it either changes the active control of violating wells, or shuts
|
|
|
|
/// down wells). Only one change is applied per invocation. Typical use will be
|
|
|
|
/// \code
|
|
|
|
/// solve_pressure();
|
|
|
|
/// while(!group.conditionsMet(well_bhp, well_rate, summed_phases)) {
|
|
|
|
/// solve_pressure();
|
|
|
|
/// }
|
|
|
|
/// \endcode
|
|
|
|
///
|
|
|
|
/// \note It's highly recommended to use the conditionsMet found in WellsManager.
|
|
|
|
/// \param[in] well_bhp A vector containing the bhp for each well. Is assumed
|
|
|
|
/// to be ordered the same way as the related Wells-struct.
|
|
|
|
/// \param[in] well_rate A vector containing the rate for each well. Is assumed
|
|
|
|
/// to be ordered the same way as the related Wells-struct.
|
|
|
|
/// \param[out] summed_phases Will at end of invocation contain the summed phases
|
|
|
|
/// (bhp, rate ,etc.) for the group.
|
|
|
|
/// \param[in] epsilon The error tolerated for each inequality. Formally, it will accept
|
|
|
|
/// (a - b <= epsilon) as (a <= b).
|
|
|
|
/// \return true if no violations were found, false otherwise (false also implies a change).
|
2012-04-25 09:14:40 -05:00
|
|
|
virtual bool conditionsMet(const std::vector<double>& well_bhp,
|
|
|
|
const std::vector<double>& well_rate,
|
|
|
|
WellPhasesSummed& summed_phases,
|
|
|
|
const double epsilon = 1e-8) = 0;
|
|
|
|
|
2012-04-25 09:40:31 -05:00
|
|
|
/// Sets the current active control to the provided one for all wells within the group
|
|
|
|
/// \note Also changes the target based on type.
|
|
|
|
/// \param[in] type the type to change to which the control is changed.
|
2012-04-25 09:14:40 -05:00
|
|
|
virtual void applyControl(const WellControlType type) = 0;
|
|
|
|
|
2012-04-25 09:40:31 -05:00
|
|
|
/// Gets the worst offending well based on the input
|
|
|
|
/// \param values A vector of a values for each well. This is assumed to be ordered the same way as the
|
|
|
|
/// relevant Wells struct.
|
|
|
|
/// \return first will be a pointer to the worst offending well, second will be the obtained value at that well.
|
2012-04-25 09:14:40 -05:00
|
|
|
virtual std::pair<WellNode*, double> getWorstOffending(const std::vector<double>& values) = 0;
|
|
|
|
|
2012-04-12 08:48:24 -05:00
|
|
|
protected:
|
|
|
|
WellsGroupInterface* parent_;
|
|
|
|
|
2012-03-28 08:49:39 -05:00
|
|
|
private:
|
|
|
|
std::string name_;
|
|
|
|
ProductionSpecification production_specification_;
|
|
|
|
InjectionSpecification injection_specification_;
|
|
|
|
};
|
2012-03-27 09:57:01 -05:00
|
|
|
|
2012-04-11 03:52:45 -05:00
|
|
|
|
|
|
|
|
2012-03-28 08:49:39 -05:00
|
|
|
class WellsGroup : public WellsGroupInterface
|
|
|
|
{
|
2012-03-29 11:34:51 -05:00
|
|
|
public:
|
2012-04-11 03:52:45 -05:00
|
|
|
WellsGroup(const std::string& name,
|
|
|
|
ProductionSpecification prod_spec,
|
|
|
|
InjectionSpecification inj_spec);
|
2012-03-29 11:34:51 -05:00
|
|
|
|
2012-04-25 09:42:55 -05:00
|
|
|
virtual WellsGroupInterface* findGroup(const std::string& name_of_node);
|
2012-03-29 11:34:51 -05:00
|
|
|
|
|
|
|
void addChild(std::tr1::shared_ptr<WellsGroupInterface> child);
|
2012-04-12 07:25:39 -05:00
|
|
|
|
2012-04-25 09:14:40 -05:00
|
|
|
virtual bool conditionsMet(const std::vector<double>& well_bhp,
|
|
|
|
const std::vector<double>& well_rate,
|
|
|
|
WellPhasesSummed& summed_phases,
|
|
|
|
const double epsilon = 1e-8);
|
|
|
|
|
2012-04-13 03:32:36 -05:00
|
|
|
|
|
|
|
virtual void calculateGuideRates();
|
2012-04-16 06:44:53 -05:00
|
|
|
|
|
|
|
virtual int numberOfLeafNodes();
|
2012-04-25 09:14:40 -05:00
|
|
|
virtual std::pair<WellNode*, double> getWorstOffending(const std::vector<double>& values);
|
|
|
|
virtual void applyControl(const WellControlType type);
|
|
|
|
|
2012-03-29 11:34:51 -05:00
|
|
|
private:
|
|
|
|
std::vector<std::tr1::shared_ptr<WellsGroupInterface> > children_;
|
2012-03-28 08:49:39 -05:00
|
|
|
};
|
2012-03-27 09:57:01 -05:00
|
|
|
|
2012-04-11 03:52:45 -05:00
|
|
|
|
|
|
|
|
2012-03-29 11:34:51 -05:00
|
|
|
class WellNode : public WellsGroupInterface
|
|
|
|
{
|
|
|
|
public:
|
2012-04-11 03:52:45 -05:00
|
|
|
WellNode(const std::string& name,
|
|
|
|
ProductionSpecification prod_spec,
|
2012-03-29 11:34:51 -05:00
|
|
|
InjectionSpecification inj_spec);
|
|
|
|
|
2012-04-25 09:42:55 -05:00
|
|
|
virtual WellsGroupInterface* findGroup(const std::string& name_of_node);
|
2012-04-25 09:14:40 -05:00
|
|
|
virtual bool conditionsMet(const std::vector<double>& well_bhp,
|
|
|
|
const std::vector<double>& well_rate,
|
|
|
|
WellPhasesSummed& summed_phases,
|
|
|
|
const double epsilon = 1e-8);
|
|
|
|
|
2012-03-30 03:51:31 -05:00
|
|
|
virtual bool isLeafNode() const;
|
2012-04-12 07:25:39 -05:00
|
|
|
|
2012-04-25 09:14:40 -05:00
|
|
|
void setWellsPointer(Wells* wells, int self_index);
|
2012-04-12 07:25:39 -05:00
|
|
|
|
2012-04-13 03:32:36 -05:00
|
|
|
virtual void calculateGuideRates();
|
2012-04-16 06:44:53 -05:00
|
|
|
virtual int numberOfLeafNodes();
|
2012-04-25 09:14:40 -05:00
|
|
|
|
2012-04-25 09:40:31 -05:00
|
|
|
// Shuts the well (in the well struct)
|
2012-04-25 09:14:40 -05:00
|
|
|
void shutWell();
|
|
|
|
|
|
|
|
virtual std::pair<WellNode*, double> getWorstOffending(const std::vector<double>& values);
|
|
|
|
virtual void applyControl(const WellControlType type);
|
|
|
|
|
2012-04-12 07:25:39 -05:00
|
|
|
private:
|
2012-04-25 09:14:40 -05:00
|
|
|
Wells* wells_;
|
2012-04-12 07:25:39 -05:00
|
|
|
int self_index_;
|
2012-03-29 11:34:51 -05:00
|
|
|
};
|
|
|
|
|
2012-04-25 09:45:32 -05:00
|
|
|
/// Creates the WellsGroupInterface for the given name
|
|
|
|
/// \param[in] name the name of the wells group.
|
|
|
|
/// \param[in] deck the deck from which to fetch information.
|
|
|
|
std::tr1::shared_ptr<WellsGroupInterface> createWellsGroup(const std::string& name,
|
2012-04-11 03:52:45 -05:00
|
|
|
const EclipseGridParser& deck);
|
2012-03-29 11:34:51 -05:00
|
|
|
|
|
|
|
|
2012-03-27 09:57:01 -05:00
|
|
|
}
|
|
|
|
#endif /* OPM_WELLSGROUP_HPP */
|
|
|
|
|