POC class is working and threadable

This commit is contained in:
Patrick McDonagh
2017-02-01 18:42:55 -06:00
parent a7073aae9c
commit 3093ddcdd9
18 changed files with 709 additions and 120 deletions

View File

@@ -1,5 +1,14 @@
package com.henrypump.poc;
import de.vandermeer.asciitable.v2.RenderedTable;
import de.vandermeer.asciitable.v2.V2_AsciiTable;
import de.vandermeer.asciitable.v2.render.V2_AsciiTableRenderer;
import de.vandermeer.asciitable.v2.render.WidthAbsoluteEven;
import de.vandermeer.asciitable.v2.themes.V2_E_TableThemes;
import static java.lang.Math.abs;
import static java.lang.Math.pow;
import static java.lang.Math.sqrt;
/**
* Created by patrickjmcd on 1/31/17.
*/
@@ -10,10 +19,48 @@ public class Card {
private double[] downholePosition = new double[maxPoints];
private double[] surfaceLoad = new double[maxPoints];
private double[] downholeLoad = new double[maxPoints];
private int numPointsUsed;
//Card
private int strokeNumber;
private LPPair surfacePositionMax;
private LPPair surfacePositionMin;
private LPPair surfaceLoadMax;
private LPPair surfaceLoadMin;
private LPPair downholePositionMax;
private LPPair downholePositionMin;
private LPPair downholeLoadMax;
private LPPair downholeLoadMin;
private LPPair topCorner;
private LPPair bottomCorner;
private double surfaceStrokeLength;
private double downholeNetStrokeLength;
private double downholeGrossStrokeLength;
private double downholeAdjustedGrossStrokeLength;
private double downholeLoadSpan;
private double fluidLoad;
private double pumpIntakePressure;
private double fluidLevel;
private double fillageEstimated;
private double fillageCalculated;
private double tubingMovement;
private double strokeSpeed;
private double plungerTravel;
private double dailyProduction;
private double structuralLoading;
private double polishedRodHorsepower;
private double pumpHorsepower;
private long strokeStartTime;
Card(int strokeNumber){
this.strokeNumber = strokeNumber;
strokeStartTime = System.currentTimeMillis();
}
public void setSurfacePosition(int i, double position){
this.surfacePosition[i] = position;
@@ -50,4 +97,281 @@ public class Card {
public LPPair getSurfacePositionMax() {
return this.surfacePositionMax;
}
public int getStrokeNumber() {
return strokeNumber;
}
public double getSurfaceStrokeLength() {
return surfaceStrokeLength;
}
public double getDownholeNetStrokeLength() {
return downholeNetStrokeLength;
}
public double getDownholeGrossStrokeLength() {
return downholeGrossStrokeLength;
}
public double getDownholeAdjustedGrossStrokeLength() {
return downholeAdjustedGrossStrokeLength;
}
public double getDownholeLoadSpan() {
return downholeLoadSpan;
}
public double getFluidLoad() {
return fluidLoad;
}
public double getFillageEstimated() {
return fillageEstimated;
}
public double getFillageCalculated() {
return fillageCalculated;
}
public double getTubingMovement() {
return tubingMovement;
}
public double getPlungerTravel() {
return plungerTravel;
}
public double getDailyProduction() {
return dailyProduction;
}
public double getStructuralLoading() {
return structuralLoading;
}
public int getNumPointsUsed() {
return numPointsUsed;
}
public void setNumPointsUsed(int numPointsUsed) {
this.numPointsUsed = numPointsUsed;
}
private void calculateSPM(){
long now = System.currentTimeMillis();
long strokeMillis = now - strokeStartTime;
strokeSpeed = 60000.0 / (double)(now - strokeStartTime);
}
private static double lineResolve(double x1, double x2, double y1, double y2, double xTest)
{
double line_m = (y2 - y1) / (x2 - x1);
double line_b = y1 - line_m * x1;
double yTest = line_m * xTest + line_b;
return yTest;
}
private static LPPair positionMax(double[] positionArr, double[] loadArr, int arrSize) {
double maxPos = positionArr[0];
double loadAtMaxP = Double.MIN_VALUE;
for(int i = 0; i < arrSize; i++) {
maxPos = Math.max(maxPos, positionArr[i]);
if (maxPos == positionArr[i]) loadAtMaxP = loadArr[i];
}
return new LPPair(maxPos, loadAtMaxP);
}
private static LPPair positionMin(double[] positionArr, double[] loadArr, int arrSize) {
double minPos = positionArr[0];
double loadAtMinP = Double.MAX_VALUE;
for(int i = 0; i < arrSize; i++) {
minPos = Math.min(minPos, positionArr[i]);
if (minPos == positionArr[i]) loadAtMinP = loadArr[i];
}
return new LPPair(minPos, loadAtMinP);
}
private static LPPair loadMax(double[] positionArr, double[] loadArr, int arrSize) {
double maxLoad = loadArr[0];
double posAtMaxL = Double.MIN_VALUE;
for(int i = 0; i < arrSize; i++) {
maxLoad = Math.max(maxLoad, loadArr[i]);
if (maxLoad == positionArr[i]) posAtMaxL = positionArr[i];
}
return new LPPair(posAtMaxL, maxLoad);
}
private static LPPair loadMin(double[] positionArr, double[] loadArr, int arrSize) {
double minLoad = loadArr[0];
double posAtMinL = Double.MAX_VALUE;
for(int i = 0; i < arrSize; i++) {
minLoad = Math.min(minLoad, loadArr[i]);
if (minLoad == positionArr[i]) posAtMinL = positionArr[i];
}
return new LPPair(posAtMinL, minLoad);
}
private double distanceToLine(double pos, double load)
{
double x1 = downholePositionMin.getPosition();
double x2 = downholePositionMax.getPosition();
double y1 = downholeLoadMin.getLoad();
double y2 = downholeLoadMax.getLoad();
return abs((y2-y1)*pos - (x2-x1)*load + x2*y1 - y2*x1) / sqrt(pow(y2-y1, 2) + pow(x2-x1,2));
};
void calcStrokeData(int numSlices, double fluidGradient, double rodDepth, double anchorDepth, double tubingCSA,
double pumpArea, double frictionEstimate, double structuralRating)
{
calculateSPM();
surfacePositionMax = positionMax(surfacePosition, surfaceLoad, numPointsUsed);
surfaceLoadMax = loadMax(surfacePosition, surfaceLoad, numPointsUsed);
surfacePositionMin = positionMin(surfacePosition, surfaceLoad, numPointsUsed);
surfaceLoadMin = loadMin(surfacePosition, surfaceLoad, numPointsUsed);
downholePositionMax = positionMax(downholePosition, downholeLoad, numPointsUsed);
downholeLoadMax = loadMax(downholePosition, downholeLoad, numPointsUsed);
downholePositionMin = positionMin(downholePosition, downholeLoad, numPointsUsed);
downholeLoadMin = loadMin(downholePosition, downholeLoad, numPointsUsed);
surfaceStrokeLength = surfacePositionMax.getPosition() - surfacePositionMin.getPosition();
downholeGrossStrokeLength = downholePositionMax.getPosition() - downholePositionMin.getPosition();
downholeLoadSpan = downholeLoadMax.getLoad() - downholeLoadMin.getLoad();
double dxSurf = (surfacePositionMax.getPosition() - surfacePositionMin.getPosition()) / (float) numSlices;
double dxDown = (downholePositionMax.getPosition() - downholePositionMin.getPosition()) / (float) numSlices;
pumpHorsepower = 0.0;
polishedRodHorsepower = 0.0;
double dhDistanceTop = 0.0;
double dhDistanceBottom = 0.0;
for (int i = 1; i < numSlices+1; i++)
{
double suPosTarget = surfacePositionMin.getPosition() + ((double) i * dxSurf);
double dhPosTarget = downholePositionMin.getPosition() + ((double) i * dxDown);
double suLoadAtTargetTop = 0.0;
double suLoadAtTargetBottom = 0.0;
double dhLoadAtTargetTop = 0.0;
double dhLoadAtTargetBottom = 0.0;
for(int j = 0; j < numPointsUsed - 1; j++)
{
if (downholePosition[j] <= dhPosTarget && downholePosition[j+1] > dhPosTarget){
dhLoadAtTargetTop = lineResolve(downholePosition[j], downholePosition[j+1], downholeLoad[j], downholeLoad[j+1], dhPosTarget);
}
if (downholePosition[j] > dhPosTarget && downholePosition[j+1] >= dhPosTarget){
dhLoadAtTargetBottom = lineResolve(downholePosition[j], downholePosition[j+1], downholeLoad[j], downholeLoad[j+1], dhPosTarget);
}
if (surfacePosition[j] <= suPosTarget && surfacePosition[j+1] > suPosTarget){
suLoadAtTargetTop = lineResolve(surfacePosition[j], surfacePosition[j+1], surfaceLoad[j], surfaceLoad[j+1], suPosTarget);
}
if (surfacePosition[j] > suPosTarget && surfacePosition[j+1] >= suPosTarget){
suLoadAtTargetBottom = lineResolve(surfacePosition[j], surfacePosition[j+1], surfaceLoad[j], surfaceLoad[j+1], suPosTarget);
}
}
polishedRodHorsepower += (dxSurf / 12.0) * (suLoadAtTargetTop - suLoadAtTargetBottom) * (strokeSpeed / 33000.0);
pumpHorsepower += (dxDown / 12.0) * (dhLoadAtTargetTop - dhLoadAtTargetBottom) * (strokeSpeed / 33000.0);
double tDistance = distanceToLine(dhPosTarget, dhLoadAtTargetTop);
double bDistance = distanceToLine(dhPosTarget, dhLoadAtTargetBottom);
if (tDistance > dhDistanceTop)
{
dhDistanceTop = tDistance;
topCorner = new LPPair(dhPosTarget, dhLoadAtTargetTop);
}
if (bDistance > dhDistanceBottom)
{
dhDistanceBottom = bDistance;
bottomCorner = new LPPair(dhPosTarget, dhLoadAtTargetBottom);
}
}
downholeAdjustedGrossStrokeLength = downholePositionMax.getPosition() - topCorner.getPosition();
downholeNetStrokeLength = bottomCorner.getPosition() - downholePositionMin.getPosition();
fillageCalculated = (downholeNetStrokeLength / downholeAdjustedGrossStrokeLength) * 100.0;
fillageEstimated =(downholeNetStrokeLength / downholeGrossStrokeLength) * 100.0;
if (fillageEstimated > 100)
fillageEstimated = 100.0;
if (fillageCalculated > 100)
fillageCalculated = 100.0;
fluidLoad = (downholeLoadMax.getLoad() - downholeLoadMin.getLoad()) - frictionEstimate;
pumpIntakePressure = fluidGradient * rodDepth - (fluidLoad / pumpArea);
//printf("PIP = %f * %f - (%f / %f) = %f\n", fluidGradient, rodDepth, fluidLoad, pumpArea, pumpIntakePressure);
fluidLevel = pumpIntakePressure / fluidGradient;
tubingMovement = 12 * (rodDepth - anchorDepth) * fluidLoad / (30500000 * tubingCSA);
structuralLoading = (surfaceLoadMax.getLoad() / (structuralRating * 100)) * 100;
};
public void printCard(String printType, boolean printDataTableToo){
if(printType.toLowerCase().equals("table")) {
V2_AsciiTable pointsTable = new V2_AsciiTable();
pointsTable.addRule();
pointsTable.addRow("Surface Position", "Surface Load", "Downhole Position", "Downhole Load");
pointsTable.addRule();
for (int i = 0; i < numPointsUsed; i++) {
pointsTable.addRow(surfacePosition[i], surfaceLoad[i], downholePosition[i], downholeLoad[i]);
}
pointsTable.addRule();
V2_AsciiTableRenderer rend = new V2_AsciiTableRenderer();
rend.setTheme(V2_E_TableThemes.UTF_LIGHT.get());
rend.setWidth(new WidthAbsoluteEven(100));
RenderedTable rt = rend.render(pointsTable);
System.out.println(rt);
System.out.println();
} else if (printType.toLowerCase().equals("csv")){
System.out.println("surf_pos,surf_load,down_pos,down_load");
for (int i = 0; i < numPointsUsed; i++) {
System.out.printf("%f,%f,%f,%f\n", surfacePosition[i], surfaceLoad[i], downholePosition[i], downholeLoad[i]);
}
System.out.println();
}
if(printDataTableToo){
V2_AsciiTable dataTable = new V2_AsciiTable();
dataTable.addRule();
dataTable.addRow("Card " + strokeNumber, "Value");
dataTable.addStrongRule();
dataTable.addRow("Fill % (Est.)", fillageEstimated);
dataTable.addRow("Fill % (Calc.)", fillageCalculated);
dataTable.addRule();
dataTable.addRow("Surf. Stroke Length", surfaceStrokeLength);
dataTable.addRow("Down. Gross Stroke", downholeGrossStrokeLength);
dataTable.addRow("Down. Net Stroke", downholeNetStrokeLength);
dataTable.addRow("Tubing Movement", tubingMovement);
dataTable.addRule();
dataTable.addRow("Polished Rod HP", polishedRodHorsepower);
dataTable.addRow("Pump HP", pumpHorsepower);
dataTable.addRule();
dataTable.addRow("Stroke Speed", strokeSpeed);
dataTable.addRule();
dataTable.addRow("Fluid Load", fluidLoad);
dataTable.addRow("Pump Intake Pressure", pumpIntakePressure);
dataTable.addRow("Fluid Level", fluidLevel);
dataTable.addRule();
dataTable.addRow("Structural Loading", structuralLoading);
dataTable.addRule();
V2_AsciiTableRenderer rend = new V2_AsciiTableRenderer();
rend.setTheme(V2_E_TableThemes.UTF_LIGHT.get());
rend.setWidth(new WidthAbsoluteEven(50));
RenderedTable rt = rend.render(dataTable);
System.out.println(rt);
System.out.println();
}
}
}