Merge pull request #612 from bska/resv-support
Implement deep copy operation for struct WellControls
This commit is contained in:
@@ -22,7 +22,10 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
/**
|
||||
* @file
|
||||
* API for managing sets of well controls.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -42,6 +45,16 @@ well_controls_equal(const struct WellControls *ctrls1, const struct WellControls
|
||||
struct WellControls *
|
||||
well_controls_create(void);
|
||||
|
||||
/**
|
||||
* Create deep copy (clone) of an existing set of well controls.
|
||||
*
|
||||
* @param[in] ctrl Existing set of well controls.
|
||||
*
|
||||
* @return Deep copy of @c ctrl.
|
||||
*/
|
||||
struct WellControls *
|
||||
well_controls_clone(const struct WellControls *ctrl);
|
||||
|
||||
void
|
||||
well_controls_destroy(struct WellControls *ctrl);
|
||||
|
||||
|
||||
@@ -226,16 +226,38 @@ append_well_controls(enum WellControlType type ,
|
||||
int well_index,
|
||||
struct Wells *W);
|
||||
|
||||
|
||||
/**
|
||||
* Set the current control for a single well.
|
||||
* Set the current/active control for a single well.
|
||||
*
|
||||
* The new control ID must refer to a previously defined control mode.
|
||||
* Total number of defined control modes available through function
|
||||
* well_controls_get_num().
|
||||
*
|
||||
* \param[in] well_index
|
||||
* Identity of particular well. Must be in
|
||||
* \code [0 .. number_of_wells - 1] \endcode.
|
||||
*
|
||||
* \param[in] current_control
|
||||
* Index of new control mode.
|
||||
*
|
||||
* \param[in,out] W Existing set of wells.
|
||||
*/
|
||||
void
|
||||
set_current_control(int well_index, int current_control, struct Wells *W);
|
||||
|
||||
|
||||
/**
|
||||
* Clear all controls from a single well.
|
||||
*
|
||||
* Does not affect the control set capacity. */
|
||||
* Does not affect the control set capacity.
|
||||
*
|
||||
* \param[in] well_index
|
||||
* Identity of particular well. Must be in
|
||||
* \code [0 .. number_of_wells - 1] \endcode.
|
||||
*
|
||||
* \param[in,out] W Existing set of wells.
|
||||
*/
|
||||
void
|
||||
clear_well_controls(int well_index, struct Wells *W);
|
||||
|
||||
@@ -264,11 +286,47 @@ destroy_wells(struct Wells *W);
|
||||
struct Wells *
|
||||
clone_wells(const struct Wells *W);
|
||||
|
||||
|
||||
/**
|
||||
* Compare well structures for equality.
|
||||
*
|
||||
* Two sets of wells are equal if all of the following conditions hold
|
||||
* - They have the same number of wells
|
||||
*
|
||||
* - They have the same number of completions/connections
|
||||
*
|
||||
* - They specify the same number of phases
|
||||
*
|
||||
* - Individual wells with corresponding well IDs have the same names
|
||||
* (including both being \c NULL).
|
||||
*
|
||||
* - Individual wells with corresponding well IDs have the same
|
||||
* completions
|
||||
*
|
||||
* - Individual wells with corresponding well IDs have the same well
|
||||
* types
|
||||
*
|
||||
* - Individual wells with corresponding well IDs specify the same
|
||||
* reference depths
|
||||
*
|
||||
* - Individual wells with corresponding well IDs have the same set
|
||||
* of defined and active operational constraints as determined by
|
||||
* function well_controls_equal()
|
||||
*
|
||||
* \param[in] W1 Existing set of wells.
|
||||
* \param[in] W2 Existing set of wells.
|
||||
*
|
||||
* \param[in] verbose Flag for whether or not to report which
|
||||
* conditions do not hold. Use \code verbose =
|
||||
* true \endcode to print transcript to \c stdout.
|
||||
*
|
||||
* \return Whether or not well structures \c W1 and \c W2 represent
|
||||
* the same set of wells.
|
||||
*/
|
||||
bool
|
||||
wells_equal(const struct Wells *W1, const struct Wells *W2 , bool verbose);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -181,6 +181,65 @@ well_controls_reserve(int nctrl, struct WellControls *ctrl)
|
||||
}
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
struct WellControls *
|
||||
well_controls_clone(const struct WellControls *ctrl)
|
||||
/* ---------------------------------------------------------------------- */
|
||||
{
|
||||
int ok, i, n;
|
||||
double target;
|
||||
const double *distr;
|
||||
struct WellControls *new;
|
||||
enum WellControlType type;
|
||||
|
||||
new = well_controls_create();
|
||||
|
||||
if (new != NULL) {
|
||||
/* Assign appropriate number of phases */
|
||||
well_controls_assert_number_of_phases(new, ctrl->number_of_phases);
|
||||
|
||||
n = well_controls_get_num(ctrl);
|
||||
ok = well_controls_reserve(n, new);
|
||||
|
||||
if (! ok) {
|
||||
well_controls_destroy(new);
|
||||
new = NULL;
|
||||
}
|
||||
else {
|
||||
for (i = 0; ok && (i < n); i++) {
|
||||
type = well_controls_iget_type (ctrl, i);
|
||||
distr = well_controls_iget_distr (ctrl, i);
|
||||
target = well_controls_iget_target(ctrl, i);
|
||||
|
||||
ok = well_controls_add_new(type, target, distr, new);
|
||||
}
|
||||
|
||||
if (i < n) {
|
||||
assert (!ok);
|
||||
well_controls_destroy(new);
|
||||
|
||||
new = NULL;
|
||||
}
|
||||
else {
|
||||
i = well_controls_get_current(ctrl);
|
||||
well_controls_set_current(new, i);
|
||||
|
||||
if (well_controls_well_is_open(ctrl)) {
|
||||
well_controls_open_well(new);
|
||||
}
|
||||
else {
|
||||
well_controls_shut_well(new);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert (well_controls_equal(ctrl, new, true));
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
|
||||
int well_controls_get_num(const struct WellControls *ctrl) {
|
||||
return ctrl->num;
|
||||
}
|
||||
@@ -340,7 +399,6 @@ well_controls_equal(const struct WellControls *ctrls1, const struct WellControls
|
||||
if (verbose)
|
||||
printf("The ->target vectors are different \n");
|
||||
}
|
||||
are_equal = are_equal && (ctrls1->cpty == ctrls2->cpty);
|
||||
|
||||
return are_equal;
|
||||
}
|
||||
|
||||
@@ -474,14 +474,12 @@ struct Wells *
|
||||
clone_wells(const struct Wells *W)
|
||||
/* ---------------------------------------------------------------------- */
|
||||
{
|
||||
int c, np, nperf, ok, pos, w;
|
||||
double target;
|
||||
const int *cells;
|
||||
const double *WI, *comp_frac, *distr;
|
||||
enum WellControlType type;
|
||||
const struct WellControls *ctrls;
|
||||
int np, nperf, ok, pos, w;
|
||||
const int *cells;
|
||||
const double *WI, *comp_frac;
|
||||
|
||||
struct Wells *newWells;
|
||||
struct WellControls *ctrl;
|
||||
struct Wells *newWells;
|
||||
|
||||
if (W == NULL) {
|
||||
newWells = NULL;
|
||||
@@ -505,25 +503,16 @@ clone_wells(const struct Wells *W)
|
||||
ok = add_well(W->type[ w ], W->depth_ref[ w ], nperf,
|
||||
comp_frac, cells, WI, W->name[ w ], newWells);
|
||||
|
||||
/* Capacity should be sufficient from create_wells() */
|
||||
assert (ok);
|
||||
|
||||
ctrls = W->ctrls[ w ];
|
||||
|
||||
if (ok) {
|
||||
for (c = 0; ok && (c < well_controls_get_num(ctrls)); c++) {
|
||||
type = well_controls_iget_type( ctrls , c );
|
||||
target = well_controls_iget_target( ctrls , c );
|
||||
distr = well_controls_iget_distr( ctrls , c );
|
||||
|
||||
ok = append_well_controls(type, target, distr, w, newWells);
|
||||
|
||||
assert (ok);
|
||||
}
|
||||
ok = (ctrl = well_controls_clone(W->ctrls[w])) != NULL;
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
set_current_control(w, well_controls_get_current( ctrls) , newWells);
|
||||
/* Destroy control set implied by add_well() */
|
||||
well_controls_destroy(newWells->ctrls[w]);
|
||||
|
||||
/* Assign complete clone of w's control set */
|
||||
newWells->ctrls[w] = ctrl;
|
||||
}
|
||||
|
||||
pos = W->well_connpos[w + 1];
|
||||
@@ -536,6 +525,8 @@ clone_wells(const struct Wells *W)
|
||||
}
|
||||
}
|
||||
|
||||
assert (wells_equal(newWells, W, false));
|
||||
|
||||
return newWells;
|
||||
}
|
||||
|
||||
|
||||
@@ -116,3 +116,28 @@ BOOST_AUTO_TEST_CASE(OpenClose)
|
||||
well_controls_destroy( ctrls );
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Clone)
|
||||
{
|
||||
std::shared_ptr<WellControls>
|
||||
ctrls(well_controls_create(),
|
||||
& well_controls_destroy);
|
||||
|
||||
const WellControlType type1 = BHP;
|
||||
const WellControlType type2 = SURFACE_RATE;
|
||||
|
||||
const int num_phases = 3;
|
||||
const double dist1[] = { 0, 1, 2};
|
||||
const double dist2[] = {10, 11, 12};
|
||||
const double target = 77;
|
||||
|
||||
well_controls_assert_number_of_phases(ctrls.get(), num_phases);
|
||||
well_controls_add_new(type1, target, dist1, ctrls.get());
|
||||
well_controls_add_new(type2, 2*target, dist2, ctrls.get());
|
||||
|
||||
std::shared_ptr<WellControls>
|
||||
c(well_controls_clone(ctrls.get()),
|
||||
& well_controls_destroy);
|
||||
|
||||
BOOST_CHECK(well_controls_equal(ctrls.get(), c.get(), false));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user