Files
POC-Matlab/Well.m
2017-09-07 17:38:29 -05:00

214 lines
8.1 KiB
Matlab

classdef Well < handle
properties(Constant)
%% Constants (SHOULD THESE BE ELSEWHERE?)
DIRECTION_UNKNOWN=0;
DIRECTION_UP=1;
DIRECTION_DOWN=2;
end
properties
parameters;
%% Instrumentation
device;
mux;
positionSensor;
loadSensor;
%% Current Values
currentCard=Card(0);
lastCard=Card(0);
direction=0;
lastDirection=0;
%% Production Parameters
kFactor=1.0;
waterBblRatio=0.90;
oilBblRatio=0.10;
gasMcfRatio=5.0;
end
properties(Access=private)
topPosArray;
topLoadArray;
count;
end
methods
%% Constructor Function
function me = Well(dt, rodLengths, rodDiameters, ...
rodMaterials, rodDampingFactors, tubingHeadPressure, ...
stuffingBoxFriction, fluidGradient, pumpDiameter, ...
tubingOuterDiameter, tubingInnerDiameter, tubingAnchorDepth, ...
structuralRating)
me.parameters = wellSetup(dt, rodLengths, rodDiameters, ...
rodMaterials, rodDampingFactors, tubingHeadPressure, ...
stuffingBoxFriction, fluidGradient, pumpDiameter, tubingOuterDiameter, ...
tubingInnerDiameter, tubingAnchorDepth, structuralRating);
me.topPosArray = zeros(me.parameters.numTapers+1, 100);
me.topLoadArray = zeros(me.parameters.numTapers+1, 100);
me.count = zeros(1, me.parameters.numTapers);
me.device = 0;
me.mux = MuxSetupSim(me.device);
me.positionSensor = AnalogInputSim(me.mux, 1, 0.0, 65535.0, 0.0, 65535.0);
me.loadSensor = AnalogInputSim(me.mux, 2, 0.0, 65535.0, 0.0, 65535.0);
me.currentCard = Card(0);
me.lastCard = Card(0);
end
%% Check if the stroke has ended
function directionChanged = checkEndOfStroke(me, numConsecutivePoints)
directionChanged = 0;
tempDirection = me.DIRECTION_UNKNOWN;
startDirection = me.DIRECTION_UNKNOWN;
consecutivePointsAllSameDirection = 1;
if me.positionSensor.history(1) > me.positionSensor.history(2)
tempDirection = me.DIRECTION_UP;
startDirection = me.DIRECTION_UP;
elseif me.positionSensor.history(1) < me.positionSensor.history(2)
tempDirection = me.DIRECTION_DOWN;
startDirection = me.DIRECTION_DOWN;
end
if startDirection == me.DIRECTION_UP
for i = 1:numConsecutivePoints
if me.positionSensor.history(i) <= me.positionSensor.history(i+1)
consecutivePointsAllSameDirection = 0;
end
end
if consecutivePointsAllSameDirection == 1
tempDirection = me.DIRECTION_UP;
end
elseif startDirection == me.DIRECTION_DOWN
for i = 1:numConsecutivePoints
if me.positionSensor.history(i) >= me.positionSensor.history(i+1)
consecutivePointsAllSameDirection = 0;
end
end
if consecutivePointsAllSameDirection == 1
tempDirection = me.DIRECTION_DOWN;
end
end
if tempDirection ~= me.lastDirection
if (tempDirection == me.DIRECTION_UP) && ...
(me.currentCard.numPointsUsed > 1)
directionChanged = 1;
end
me.lastDirection = tempDirection;
end
end
%% Evaluation function for simulated position and load points
function evalSim(me, s_pos, s_load)
me.positionSensor.read(s_pos);
me.loadSensor.read(s_load);
[pumpPosition, pumpLoad, status, me.topPosArray, ...
me.topLoadArray, me.count] = pocAlgorithm( ...
me.positionSensor.lastValue, ...
me.positionSensor.history(2), ...
me.loadSensor.lastValue, ...
me.count, ...
me.parameters.dt, ...
me.parameters.a, ...
me.parameters.rodDampingFactors, ...
me.parameters.factorArray, ...
me.parameters.rodLengths, ...
double(me.parameters.lagIndex), ...
me.parameters.rodYMs * 10.0^6, ...
me.parameters.area, ...
me.parameters.lengthRequired, ...
me.parameters.centerPoint, ...
me.parameters.rodWeightFluidTotal, ...
me.parameters.stuffingBoxFriction, ...
me.parameters.force, ...
me.topPosArray, ...
me.topLoadArray);
if status == 1
me.currentCard.push(me.positionSensor.lastValue, ...
me.loadSensor.lastValue, pumpPosition, pumpLoad);
end
if me.checkEndOfStroke(5) == 1
me.endOfStroke()
end
end
%% End of Stroke actions
function endOfStroke(me)
me.currentCard.calcStrokeData( ...
me.parameters.fluidGradient, ...
me.parameters.rodDepthTotal, ...
me.parameters.tubingAnchorDepth, ...
me.parameters.tubingCrossSectionalArea, ...
me.parameters.pumpArea, ...
me.parameters.frictionEstimate, ...
me.parameters.structuralRating, ...
me.kFactor, ...
me.waterBblRatio, ...
me.oilBblRatio, ...
me.gasMcfRatio);
me.lastCard = me.currentCard;
me.currentCard = Card(me.lastCard.strokeNumber + 1);
end
%% Draws Cards
% Draws current card and shows last card
function plotCards(me)
figure;
% ax1 = subplot(2,2,1);
ax1 = subplot(2,1,1);
hold on;
plot(me.lastCard.surfacePosition(1:me.lastCard.numPointsUsed), ...
me.lastCard.surfaceLoad(1:me.lastCard.numPointsUsed), 'r')
plot(me.lastCard.repSurfacePosition, me.lastCard.repSurfaceLoadTop, 'g');
plot(me.lastCard.repSurfacePosition, me.lastCard.repSurfaceLoadBottom, 'b');
title('Last Surface Card')
hold off;
% ax3 = subplot(2,2,3);
ax3 = subplot(2,1,2);
hold on;
plot(me.lastCard.downholePosition(1:me.lastCard.numPointsUsed), ...
me.lastCard.downholeLoad(1:me.lastCard.numPointsUsed), 'r')
plot(me.lastCard.topCorner.position, me.lastCard.topCorner.load, ...
'gd', 'MarkerSize', 15, 'LineWidth', 2);
plot(me.lastCard.bottomCorner.position, me.lastCard.bottomCorner.load, ...
'bd', 'MarkerSize', 15, 'LineWidth', 2);
plot(me.lastCard.repDownholePosition, me.lastCard.repDownholeLoadTop, 'g');
plot(me.lastCard.repDownholePosition, me.lastCard.repDownholeLoadBottom, 'b');
title('Last Downhole Card')
hold off;
% ax2 = subplot(2,2,2);
% plot(me.currentCard.surfacePosition(1:me.currentCard.numPointsUsed), ...
% me.currentCard.surfaceLoad(1:me.currentCard.numPointsUsed))
% title('Current Surface Card')
%
% ax4 = subplot(2,2,4);
% plot(me.currentCard.downholePosition(1:me.currentCard.numPointsUsed), ...
% me.currentCard.downholeLoad(1:me.currentCard.numPointsUsed), 'r')
% title('Current Downhole Card')
% linkaxes([ax1, ax2, ax3, ax4], 'x')
linkaxes([ax1, ax3], 'x')
end
end
end