368 lines
13 KiB
C
368 lines
13 KiB
C
/*
|
|
* File: pocAlgorithm.c
|
|
*
|
|
* MATLAB Coder version : 3.3
|
|
* C/C++ source code generated on : 06-Sep-2017 14:43:17
|
|
*/
|
|
|
|
/* Include Files */
|
|
#include "rt_nonfinite.h"
|
|
#include "pocAlgorithm.h"
|
|
|
|
/* Function Declarations */
|
|
static void positionLoadI(double dt, double ai, double ci, double factori,
|
|
double lengthi, double lagi, double yi, double areai, unsigned int centeri,
|
|
const double topPosArrayI[100], const double topLoadArrayI[100], double
|
|
*pumpPosition, double *pumpLoad);
|
|
static double rt_roundd_snf(double u);
|
|
|
|
/* Function Definitions */
|
|
|
|
/*
|
|
* FUNCTION PARAMETERS
|
|
* dt [seconds] = amount of time between measurements
|
|
* ai [?] = a value for the specific taper
|
|
* ci [?] = damping factor for the taper
|
|
* factori [?] = factor value for the taper
|
|
* lengthi [feet] = length of the taper
|
|
* lagi [?] = lag index of the taper
|
|
* yi [?] = youngs modulus for the taper
|
|
* (SHOULD BE 7.2 * 10^6 or 30.6 * 10^6)
|
|
* areai [in^2] = annulus area of the taper
|
|
* centeri [?] = centerpoint of the taper
|
|
* topPosArrayI [] = array of position values
|
|
* topLoadArrayI [] = array of load values
|
|
* Arguments : double dt
|
|
* double ai
|
|
* double ci
|
|
* double factori
|
|
* double lengthi
|
|
* double lagi
|
|
* double yi
|
|
* double areai
|
|
* unsigned int centeri
|
|
* const double topPosArrayI[100]
|
|
* const double topLoadArrayI[100]
|
|
* double *pumpPosition
|
|
* double *pumpLoad
|
|
* Return Type : void
|
|
*/
|
|
static void positionLoadI(double dt, double ai, double ci, double factori,
|
|
double lengthi, double lagi, double yi, double areai, unsigned int centeri,
|
|
const double topPosArrayI[100], const double topLoadArrayI[100], double
|
|
*pumpPosition, double *pumpLoad)
|
|
{
|
|
double loadBefore3;
|
|
unsigned int iBefore;
|
|
unsigned int iAfter;
|
|
double insideIntegral;
|
|
int jj;
|
|
long i0;
|
|
double loadBefore;
|
|
double loadAfter;
|
|
unsigned int qY;
|
|
unsigned int b_qY;
|
|
double loadAfter3;
|
|
|
|
/* Position and Load Function */
|
|
/* This function calculates the position and load for a given taper */
|
|
loadBefore3 = rt_roundd_snf((double)centeri - lagi);
|
|
if (loadBefore3 < 65536.0) {
|
|
if (loadBefore3 >= 0.0) {
|
|
iBefore = (unsigned int)loadBefore3;
|
|
} else {
|
|
iBefore = 0U;
|
|
}
|
|
} else if (loadBefore3 >= 65536.0) {
|
|
iBefore = MAX_uint16_T;
|
|
} else {
|
|
iBefore = 0U;
|
|
}
|
|
|
|
loadBefore3 = rt_roundd_snf((double)centeri + lagi);
|
|
if (loadBefore3 < 65536.0) {
|
|
if (loadBefore3 >= 0.0) {
|
|
iAfter = (unsigned int)loadBefore3;
|
|
} else {
|
|
iAfter = 0U;
|
|
}
|
|
} else if (loadBefore3 >= 65536.0) {
|
|
iAfter = MAX_uint16_T;
|
|
} else {
|
|
iAfter = 0U;
|
|
}
|
|
|
|
/* %% Position Calculation */
|
|
insideIntegral = 0.0;
|
|
loadBefore3 = 2.0 * lagi - 1.0;
|
|
for (jj = 0; jj < (int)loadBefore3; jj++) {
|
|
i0 = ((long)iBefore + jj) + 1L;
|
|
if (i0 < 0L) {
|
|
i0 = 0L;
|
|
} else {
|
|
if (i0 > 65535L) {
|
|
i0 = 65535L;
|
|
}
|
|
}
|
|
|
|
insideIntegral += dt / (yi * areai) * (exp(-ci * (lagi - (1.0 + (double)jj))
|
|
* dt / 2.0) * topLoadArrayI[(int)i0 - 1]);
|
|
}
|
|
|
|
insideIntegral += 0.5 * dt / (yi * areai) * (exp(-ci * lagi * dt / 2.0) *
|
|
topLoadArrayI[(int)iBefore - 1] + exp(-ci * -lagi * dt / 2.0) *
|
|
topLoadArrayI[(int)iAfter - 1]);
|
|
loadBefore = exp(-ci * lagi * dt / 2.0) * topLoadArrayI[(int)iBefore - 1] +
|
|
factori * (exp(-ci * (lagi + 1.0) * dt / 2.0) * topLoadArrayI[(int)iBefore -
|
|
2] - exp(-ci * lagi * dt / 2.0) * topLoadArrayI[(int)iBefore - 1]);
|
|
loadAfter = exp(-ci * -lagi * dt / 2.0) * topLoadArrayI[(int)iAfter - 1] +
|
|
factori * (exp(-ci * (-lagi - 1.0) * dt / 2.0) * topLoadArrayI[(int)iAfter]
|
|
- exp(-ci * -lagi * dt / 2.0) * topLoadArrayI[(int)iAfter - 1]);
|
|
insideIntegral += 0.5 * factori * dt / (yi * areai) * (loadBefore + exp(-ci *
|
|
lagi * dt / 2.0) * topLoadArrayI[(int)iBefore - 1]);
|
|
insideIntegral += 0.5 * factori * dt / (yi * areai) * (loadAfter + exp(-ci *
|
|
-lagi * dt / 2.0) * topLoadArrayI[(int)iAfter - 1]);
|
|
insideIntegral *= 0.5 * ai;
|
|
qY = iAfter + 1U;
|
|
if (qY < iAfter) {
|
|
qY = MAX_uint16_T;
|
|
}
|
|
|
|
b_qY = iBefore - 1U;
|
|
if (b_qY > iBefore) {
|
|
b_qY = 0U;
|
|
}
|
|
|
|
*pumpPosition = 0.5 * (exp(ci * lengthi / (2.0 * ai)) * (topPosArrayI[(int)
|
|
iAfter - 1] + factori * (topPosArrayI[(int)qY - 1] - topPosArrayI[(int)
|
|
iAfter - 1])) + exp(-ci * lengthi / (2.0 * ai)) * (topPosArrayI[(int)iBefore
|
|
- 1] + factori * (topPosArrayI[(int)b_qY - 1] - topPosArrayI[(int)iBefore -
|
|
1]))) + insideIntegral;
|
|
insideIntegral = 0.0;
|
|
loadBefore3 = 2.0 * lagi - 1.0;
|
|
for (jj = 0; jj < (int)loadBefore3; jj++) {
|
|
i0 = ((long)iBefore + jj) + 1L;
|
|
if (i0 < 0L) {
|
|
i0 = 0L;
|
|
} else {
|
|
if (i0 > 65535L) {
|
|
i0 = 65535L;
|
|
}
|
|
}
|
|
|
|
insideIntegral += dt * (exp(-ci * (lagi - (1.0 + (double)jj)) * dt / 2.0) *
|
|
topPosArrayI[(int)i0 - 1]);
|
|
}
|
|
|
|
insideIntegral += 0.5 * dt * (exp(-ci * lagi * dt / 2.0) * topPosArrayI[(int)
|
|
iBefore - 1] + exp(-ci * -lagi * dt / 2.0) * topPosArrayI[(int)iAfter - 1]);
|
|
loadBefore3 = exp(-ci * lagi * dt / 2.0) * topPosArrayI[(int)iBefore - 1] +
|
|
factori * (exp(-ci * (lagi + 1.0) * dt / 2.0) * topPosArrayI[(int)iBefore -
|
|
2] - exp(-ci * lagi * dt / 2.0) * topPosArrayI[(int)iBefore - 1]);
|
|
loadAfter3 = exp(-ci * -lagi * dt / 2.0) * topPosArrayI[(int)iAfter - 1] +
|
|
factori * (exp(-ci * (-lagi - 1.0) * dt / 2.0) * topPosArrayI[(int)iAfter] -
|
|
exp(-ci * -lagi * dt / 2.0) * topPosArrayI[(int)iAfter - 1]);
|
|
insideIntegral += 0.5 * factori * dt * (loadBefore3 + exp(-ci * lagi * dt /
|
|
2.0) * topPosArrayI[(int)iBefore - 1]);
|
|
insideIntegral += 0.5 * factori * dt * (loadAfter3 + exp(-ci * -lagi * dt /
|
|
2.0) * topPosArrayI[(int)iAfter - 1]);
|
|
insideIntegral *= -(ci * lengthi / 4.0) * 0.5 * (ci / (2.0 * ai));
|
|
*pumpPosition += insideIntegral;
|
|
|
|
/* %% Load Calculation */
|
|
*pumpLoad = yi * areai * (((exp(ci * lengthi / (2.0 * ai)) * ((topPosArrayI
|
|
[(int)iAfter] - topPosArrayI[(int)iAfter - 2]) / (2.0 * dt)) - exp(-ci *
|
|
lengthi / (2.0 * ai)) * ((topPosArrayI[(int)iBefore] - topPosArrayI[(int)
|
|
iBefore - 2]) / (2.0 * dt))) / (2.0 * ai) + (ci * exp(ci * lengthi / (2.0 *
|
|
ai)) * topPosArrayI[(int)iAfter - 1] - ci * exp(-ci * lengthi / (2.0 * ai)) *
|
|
topPosArrayI[(int)iBefore - 1]) / (4.0 * ai)) + (0.5 * (ai / (yi * areai)) *
|
|
(1.0 / ai) * (loadBefore + loadAfter) - ci * lengthi / 4.0 * (0.5 * (ci /
|
|
(2.0 * ai))) * (1.0 / ai) * (loadBefore3 + loadAfter3)));
|
|
}
|
|
|
|
/*
|
|
* Arguments : double u
|
|
* Return Type : double
|
|
*/
|
|
static double rt_roundd_snf(double u)
|
|
{
|
|
double y;
|
|
if (fabs(u) < 4.503599627370496E+15) {
|
|
if (u >= 0.5) {
|
|
y = floor(u + 0.5);
|
|
} else if (u > -0.5) {
|
|
y = u * 0.0;
|
|
} else {
|
|
y = ceil(u - 0.5);
|
|
}
|
|
} else {
|
|
y = u;
|
|
}
|
|
|
|
return y;
|
|
}
|
|
|
|
/*
|
|
* Arguments : double polishedRodPosition
|
|
* double lastPolishedRodPosition
|
|
* double polishedRodLoad
|
|
* double count_data[]
|
|
* int count_size[2]
|
|
* double dt
|
|
* const double a_data[]
|
|
* const int a_size[2]
|
|
* const double c_data[]
|
|
* const int c_size[2]
|
|
* const double factorArray_data[]
|
|
* const int factorArray_size[2]
|
|
* const double rodLengths_data[]
|
|
* const int rodLengths_size[2]
|
|
* const double lagIndex_data[]
|
|
* const int lagIndex_size[2]
|
|
* const double rodYMs_data[]
|
|
* const int rodYMs_size[2]
|
|
* const double area_data[]
|
|
* const int area_size[2]
|
|
* const unsigned int lengthRequired_data[]
|
|
* const int lengthRequired_size[2]
|
|
* const unsigned int centerPoint_data[]
|
|
* const int centerPoint_size[2]
|
|
* double rodWeightFluidTotal
|
|
* double stuffingBoxFriction
|
|
* const double force_data[]
|
|
* const int force_size[2]
|
|
* double topPosArray_data[]
|
|
* int topPosArray_size[2]
|
|
* double topLoadArray_data[]
|
|
* int topLoadArray_size[2]
|
|
* double *pumpPosition
|
|
* double *pumpLoad
|
|
* double *status
|
|
* Return Type : void
|
|
*/
|
|
void pocAlgorithm(double polishedRodPosition, double lastPolishedRodPosition,
|
|
double polishedRodLoad, double count_data[], int count_size[2],
|
|
double dt, const double a_data[], const int a_size[2], const
|
|
double c_data[], const int c_size[2], const double
|
|
factorArray_data[], const int factorArray_size[2], const
|
|
double rodLengths_data[], const int rodLengths_size[2], const
|
|
double lagIndex_data[], const int lagIndex_size[2], const
|
|
double rodYMs_data[], const int rodYMs_size[2], const double
|
|
area_data[], const int area_size[2], const unsigned int
|
|
lengthRequired_data[], const int lengthRequired_size[2], const
|
|
unsigned int centerPoint_data[], const int centerPoint_size[2],
|
|
double rodWeightFluidTotal, double stuffingBoxFriction, const
|
|
double force_data[], const int force_size[2], double
|
|
topPosArray_data[], int topPosArray_size[2], double
|
|
topLoadArray_data[], int topLoadArray_size[2], double
|
|
*pumpPosition, double *pumpLoad, double *status)
|
|
{
|
|
double tapersAllowed;
|
|
int varargin_2;
|
|
unsigned int ii;
|
|
int tap;
|
|
int i1;
|
|
double topPosArray[100];
|
|
double topLoadArray[100];
|
|
double position;
|
|
double load;
|
|
unsigned int qY;
|
|
(void)count_size;
|
|
(void)a_size;
|
|
(void)c_size;
|
|
(void)factorArray_size;
|
|
(void)lagIndex_size;
|
|
(void)rodYMs_size;
|
|
(void)area_size;
|
|
(void)lengthRequired_size;
|
|
(void)centerPoint_size;
|
|
(void)force_size;
|
|
|
|
/* computeLoadPositionStatus Function */
|
|
*pumpPosition = -1.0;
|
|
*pumpLoad = -1.0;
|
|
*status = -1.0;
|
|
tapersAllowed = 1.0;
|
|
varargin_2 = rodLengths_size[1];
|
|
for (ii = 2U; ii <= lengthRequired_data[0]; ii++) {
|
|
topPosArray_data[topPosArray_size[0] * ((int)ii - 2)] =
|
|
topPosArray_data[topPosArray_size[0] * ((int)ii - 1)];
|
|
topLoadArray_data[topLoadArray_size[0] * ((int)ii - 2)] =
|
|
topLoadArray_data[topLoadArray_size[0] * ((int)ii - 1)];
|
|
}
|
|
|
|
topPosArray_data[topPosArray_size[0] * ((int)lengthRequired_data[0] - 1)] =
|
|
-polishedRodPosition / 12.0;
|
|
if (polishedRodPosition > lastPolishedRodPosition) {
|
|
topLoadArray_data[topLoadArray_size[0] * ((int)lengthRequired_data[0] - 1)] =
|
|
(polishedRodLoad - rodWeightFluidTotal) - stuffingBoxFriction;
|
|
} else if (polishedRodPosition < lastPolishedRodPosition) {
|
|
topLoadArray_data[topLoadArray_size[0] * ((int)lengthRequired_data[0] - 1)] =
|
|
(polishedRodLoad - rodWeightFluidTotal) + stuffingBoxFriction;
|
|
} else {
|
|
topLoadArray_data[topLoadArray_size[0] * ((int)lengthRequired_data[0] - 1)] =
|
|
polishedRodLoad - rodWeightFluidTotal;
|
|
}
|
|
|
|
for (tap = 0; tap + 1 <= tapersAllowed; tap++) {
|
|
count_data[tap]++;
|
|
if (count_data[tap] >= lengthRequired_data[tap]) {
|
|
if (tap + 2 <= varargin_2) {
|
|
/* working our way down to the bottom of the well */
|
|
ii = lengthRequired_data[tap + 1];
|
|
qY = ii + 1U;
|
|
if (qY < ii) {
|
|
qY = MAX_uint16_T;
|
|
}
|
|
|
|
for (ii = 2U; ii <= qY; ii++) {
|
|
topPosArray_data[(tap + topPosArray_size[0] * ((int)ii - 2)) + 1] =
|
|
topPosArray_data[(tap + topPosArray_size[0] * ((int)ii - 1)) + 1];
|
|
topLoadArray_data[(tap + topLoadArray_size[0] * ((int)ii - 2)) + 1] =
|
|
topLoadArray_data[(tap + topLoadArray_size[0] * ((int)ii - 1)) + 1];
|
|
}
|
|
|
|
for (i1 = 0; i1 < 100; i1++) {
|
|
topPosArray[i1] = topPosArray_data[tap + topPosArray_size[0] * i1];
|
|
topLoadArray[i1] = topLoadArray_data[tap + topLoadArray_size[0] * i1];
|
|
}
|
|
|
|
positionLoadI(dt, a_data[tap], c_data[tap], factorArray_data[tap],
|
|
rodLengths_data[tap], lagIndex_data[tap], rodYMs_data[tap],
|
|
area_data[tap], centerPoint_data[tap], topPosArray,
|
|
topLoadArray, pumpPosition, pumpLoad);
|
|
*status = 0.0;
|
|
topPosArray_data[(tap + topPosArray_size[0] * ((int)
|
|
lengthRequired_data[tap + 1] - 1)) + 1] = *pumpPosition;
|
|
topLoadArray_data[(tap + topLoadArray_size[0] * ((int)
|
|
lengthRequired_data[tap + 1] - 1)) + 1] = *pumpLoad;
|
|
} else {
|
|
for (i1 = 0; i1 < 100; i1++) {
|
|
topPosArray[i1] = topPosArray_data[tap + topPosArray_size[0] * i1];
|
|
topLoadArray[i1] = topLoadArray_data[tap + topLoadArray_size[0] * i1];
|
|
}
|
|
|
|
positionLoadI(dt, a_data[tap], c_data[tap], factorArray_data[tap],
|
|
rodLengths_data[tap], lagIndex_data[tap], rodYMs_data[tap],
|
|
area_data[tap], centerPoint_data[tap], topPosArray,
|
|
topLoadArray, &position, &load);
|
|
*pumpPosition = -12.0 * position;
|
|
*pumpLoad = load + force_data[varargin_2 - 1];
|
|
*status = 1.0;
|
|
}
|
|
|
|
count_data[tap]--;
|
|
tapersAllowed++;
|
|
if (tapersAllowed > varargin_2) {
|
|
tapersAllowed = varargin_2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* File trailer for pocAlgorithm.c
|
|
*
|
|
* [EOF]
|
|
*/
|