Merge pull request #612 from bska/resv-support

Implement deep copy operation for struct WellControls
This commit is contained in:
Atgeirr Flø Rasmussen
2014-07-04 16:09:13 +02:00
5 changed files with 172 additions and 27 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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;
}

View File

@@ -474,13 +474,11 @@ struct Wells *
clone_wells(const struct Wells *W)
/* ---------------------------------------------------------------------- */
{
int c, np, nperf, ok, pos, w;
double target;
int np, nperf, ok, pos, w;
const int *cells;
const double *WI, *comp_frac, *distr;
enum WellControlType type;
const struct WellControls *ctrls;
const double *WI, *comp_frac;
struct WellControls *ctrl;
struct Wells *newWells;
if (W == 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;
}

View File

@@ -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));
}