Initial Commit

This commit is contained in:
Patrick McDonagh
2016-07-01 17:00:11 -05:00
commit 8b3911d728
15 changed files with 2409 additions and 0 deletions

746
HP_POC.swift Normal file
View File

@@ -0,0 +1,746 @@
//: Playground - noun: a place where people can play
import UIKit
struct LoadSpan //structure to hold load spans
{
var top:Double;
var bottom:Double;
var span:Double;
};
func findMax(arr:[Double], len:Int) -> Double
// find the maximum value of a given array of length len
{
var max = arr[0];
for(var i = 0; i < len; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
return max;
};
func findMin(arr:[Double], len:Int) -> Double
// find the min value of a given array of length len
{
var min = arr[0];
for(var i = 0; i < len; i++)
{
if(arr[i] < min)
{
min = arr[i];
}
}
return min;
};
func updAverage(prevAverage:Double, currentMeasurement:Double, numMeasurements:Int) -> Double
{
var newAverage:Double;
newAverage = prevAverage * ((Double(numMeasurements) - 1)/Double(numMeasurements)) + (currentMeasurement / Double(numMeasurements));
return newAverage;
};
class LPPair //structure to hold Load and Position
{
var load:Double;
var position:Double;
func clr()
{
load = 0;
position = 0;
}
init(){
clr();
}
};
class WellData
{
var polishedRodHorsepower:Double;
var pumpHorsepower:Double;
var pumpIntakePressure:Double;
var fluidLevel:Double;
var strokeSPM:Double;
var strokeNumber:Int;
var surfacePositionMax: LPPair;
var surfacePositionMin: LPPair;
var surfaceLoadMax: LPPair;
var surfaceLoadMin: LPPair;
var downholePositionMax: LPPair;
var downholePositionMin: LPPair;
var downholeLoadMax: LPPair;
var downholeLoadMin: LPPair;
var topRight: LPPair;
var topLeft: LPPair;
var fillPoint: LPPair;
var fullFillPoint: LPPair;
var bottomLeft: LPPair;
var surfaceStrokeLength:Double;
var downholeNetStrokeLength:Double;
var downholeGrossStrokeLength:Double;
var downholeAdjustedGrossStrokeLength:Double;
var downholeLoadSpan:Double;
var fluidLoad:Double;
var fillageEstimated:Double;
var fillageCalculated:Double;
var tubingMovement:Double;
var plungerTravel:Double;
var dailyProduction:Double;
var structuralLoading:Double;
func clearAll()
{
polishedRodHorsepower = 0;
pumpHorsepower = 0;
pumpIntakePressure = 0;
fluidLevel = 0;
strokeSPM = 0;
strokeNumber = 1;
surfacePositionMax.clr();
surfacePositionMin.clr();
surfaceLoadMax.clr();
surfaceLoadMin.clr();
downholePositionMax.clr();
downholePositionMin.clr();
downholeLoadMax.clr();
downholeLoadMin.clr();
topRight.clr();
topLeft.clr();
fillPoint.clr();
fullFillPoint.clr();
bottomLeft.clr();
surfaceStrokeLength = 0;
downholeNetStrokeLength = 0;
downholeGrossStrokeLength = 0;
downholeAdjustedGrossStrokeLength = 0;
downholeLoadSpan = 0;
fluidLoad = 0;
fillageEstimated = 0;
fillageCalculated = 0;
tubingMovement = 0;
plungerTravel = 0;
dailyProduction = 0;
structuralLoading = 0;
};
init(){
clearAll();
}
};
class Card
//Object for card calculations and data
{
var surfacePosition = [Double](count: 1000, repeatedValue: 0.0);;
var downholePosition = [Double](count: 1000, repeatedValue: 0.0);;
var surfaceLoad = [Double](count: 1000, repeatedValue: 0.0);;
var downholeLoad = [Double](count: 1000, repeatedValue: 0.0);;
var data:WellData;
var pointCounter:Int;
func findLoadAtPosition(pos:Double, posArray:[Double], loadArray: [Double], size:Int) -> Double
{
for(var i = 0; i < size; i++)
{
if(posArray[i] == pos){
return loadArray[i];
}
}
};
func findPositionAtLoad(load:Double, posArray:[Double], loadArray: [Double], size:Int) -> Double
{
for(var i = 0; i < size; i++)
{
if(loadArray[i] == load){
return posArray[i];
}
}
};
func findLimits()
{
//find maximum values of the arrays
data.surfacePositionMax.position = findMax(surfacePosition, pointCounter);
data.surfacePositionMax.load = findLoadAtPosition(data.surfacePositionMax.position, posArray: surfacePosition,loadArray: surfaceLoad ,size: pointCounter);
data.surfaceLoadMax.load = findMax(surfaceLoad, pointCounter);
data.surfaceLoadMax.position = findPositionAtLoad(data.surfaceLoadMax.load, posArray: surfacePosition, loadArray: surfaceLoad ,size: pointCounter);
data.downholePositionMax.position = findMax(downholePosition, pointCounter);
data.downholePositionMax.load = findLoadAtPosition(data.downholePositionMax.position, posArray: downholePosition, loadArray: downholeLoad ,size: pointCounter);
data.downholeLoadMax.load = findMax(downholeLoad, pointCounter);
data.downholeLoadMax.position = findPositionAtLoad(data.downholeLoadMax.load, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
//find minimum values of the arrays
data.surfacePositionMin.position = findMin(surfacePosition, pointCounter);
data.surfacePositionMin.load = findLoadAtPosition(data.surfacePositionMin.position, posArray: surfacePosition, loadArray: surfaceLoad, size: pointCounter);
data.surfaceLoadMin.load = findMin(surfaceLoad, pointCounter);
data.surfaceLoadMin.position = findPositionAtLoad(data.surfaceLoadMin.load, posArray: surfacePosition, loadArray: surfaceLoad, size: pointCounter);
data.downholePositionMin.position = findMin(downholePosition, pointCounter);
data.downholePositionMin.load = findLoadAtPosition(data.downholePositionMin.position, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
data.downholeLoadMin.load = findMin(downholeLoad, pointCounter);
data.downholeLoadMin.position = findPositionAtLoad(data.downholeLoadMin.load, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
data.surfaceStrokeLength = data.surfacePositionMax.position - data.surfacePositionMin.position;
data.downholeGrossStrokeLength = data.downholePositionMax.position - data.downholePositionMin.position;
data.downholeLoadSpan = data.downholeLoadMax.load - data.downholeLoadMin.load;
};
func findNearestPointToLoad(direction:String, cardHalf:String, targetLoad:Double, posArray:[Double], loadArray:[Double], size:Int) -> LPPair
{
var posMin = findMin(posArray, size);
var posMax = findMax(posArray, size);
var leftIgnore = posMin + (posMax - posMin)*(0.75);
var rightIgnore = posMin + (posMax - posMin)*(0.25);
var foundPoint:LPPair;
if (direction=="up")
{
for(var i = 1; i < size; i++)
{
if(cardHalf == "right" && posArray[i] >= rightIgnore)
{
if(loadArray[i] <= targetLoad && loadArray[i-1] > targetLoad)
{
foundPoint.position = posArray[i];
foundPoint.load = loadArray[i];
return foundPoint;
}
}
else
{
if(loadArray[i] >= targetLoad && loadArray[i-1] < targetLoad)
{
foundPoint.position = posArray[i];
foundPoint.load = loadArray[i];
return foundPoint;
}
}
}
}
else {
for(var i = 1; i < size; i++)
{
if(cardHalf == "right" && posArray[i] >= rightIgnore)
{
if(loadArray[i] >= targetLoad && loadArray[i-1] < targetLoad)
{
foundPoint.position = posArray[i];
foundPoint.load = loadArray[i];
return foundPoint;
}
}
else
{
if(loadArray[i] <= targetLoad && loadArray[i-1] > targetLoad)
{
foundPoint.position = posArray[i];
foundPoint.load = loadArray[i];
return foundPoint;
}
}
}
}
}
func findIncrementalLoad(targetPosition:Double, posArray:[Double], loadArray:[Double], size:Int) -> LoadSpan
{
var result:LoadSpan;
var upPointGreater:LPPair;
var upPointLesser:LPPair;
var downPointGreater:LPPair;
var downPointLesser:LPPair;
for(var i = 1; i < size; i++)
{
if ((posArray[i] >= targetPosition) && (posArray[i-1] < targetPosition))
{
upPointGreater.position = posArray[i];
upPointGreater.load = loadArray[i];
upPointLesser.position = posArray[i-1];
upPointLesser.load = loadArray[i-1];
}
if ((posArray[i] <= targetPosition) && (posArray[i-1] > targetPosition))
{
downPointGreater.position = posArray[i];
downPointGreater.load = loadArray[i];
downPointLesser.position = posArray[i-1];
downPointLesser.load = loadArray[i-1];
}
var mUp = (upPointGreater.load - upPointLesser.load) / (upPointGreater.position - upPointLesser.position);
var bUp = upPointGreater.load - (mUp * upPointGreater.position);
result.top = (mUp * targetPosition) + bUp;
var mDown = (downPointGreater.load - downPointLesser.load) / (downPointGreater.position - downPointLesser.position);
var bDown = downPointGreater.load - (mDown * downPointGreater.position);
result.bottom = (mDown * targetPosition) + bDown;
result.span = result.top - result.bottom;
return result;
}
}
func findCorners(pctTop:Double, pctBottom:Double)
{
var halfLoadLine = data.downholeLoadMin.load + data.downholeLoadSpan/2;
var halfLoad:LPPair;
halfLoad = findNearestPointToLoad("up", cardHalf: "left", targetLoad: halfLoadLine, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
var topLoadLine = data.downholeLoadMax.load - (data.downholeLoadSpan * (pctTop/100));
var bottomLoadLine = data.downholeLoadMin.load + (data.downholeLoadSpan * (pctBottom/100));
if(data.downholePositionMin.position < halfLoad.position)
{
data.bottomLeft = data.downholePositionMin;
data.topLeft = findNearestPointToLoad("up", cardHalf: "left", targetLoad: topLoadLine, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
}
else
{
data.bottomLeft = findNearestPointToLoad("up", cardHalf: "left", targetLoad: bottomLoadLine, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
data.topLeft = data.downholePositionMin;
}
data.topRight = data.downholePositionMax;
data.fillPoint = findNearestPointToLoad("up", cardHalf: "right", targetLoad: bottomLoadLine, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
data.fullFillPoint.position = data.bottomLeft.position + data.topRight.position - data.topLeft.position;
data.fullFillPoint.load = data.bottomLeft.load;
};
func calcFillage(anchorDepth:Double, rodDepth:Double, tubingCSA:Double)
{
data.tubingMovement = 12 * (rodDepth - anchorDepth)*data.fluidLoad / (30500000 * tubingCSA);
data.downholeAdjustedGrossStrokeLength = data.downholeGrossStrokeLength - data.tubingMovement;
data.downholeNetStrokeLength = data.fillPoint.position - data.bottomLeft.position;
data.fillageEstimated = ((data.fillPoint.position - data.bottomLeft.position)/(data.fullFillPoint.position - data.bottomLeft.position))*100.0;
data.fillageCalculated = ((data.downholeNetStrokeLength + data.tubingMovement)/data.downholeGrossStrokeLength)*100.0;
if (data.fillageEstimated > 100)
{
data.fillageEstimated = 100.0;
}
if (data.fillageCalculated > 100)
{
data.fillageCalculated = 100.0;
}
};
func calcHorsepower (riemannSlices:Int)
{
data.polishedRodHorsepower = 0.0;
data.pumpHorsepower = 0.0;
var topSlices = [Double](count: riemannSlices, repeatedValue: 0.0);
var bottomSlices = [Double](count: riemannSlices, repeatedValue: 0.0);
var dxSurface = data.surfaceStrokeLength / (Double(riemannSlices) + 1);
var dxDownhole = data.downholeNetStrokeLength / (Double(riemannSlices) + 1);
for (var i = 1; i < riemannSlices; i++)
{
var targetSurface = dxSurface * Double(i) + data.surfacePositionMin.position;
var targetDownhole = dxDownhole * Double(i) + data.downholePositionMin.position;
var sliceSurface:LoadSpan;
var sliceDownhole:LoadSpan;
sliceSurface = findIncrementalLoad(targetSurface, posArray: surfacePosition, loadArray: surfaceLoad, size: pointCounter);
sliceDownhole = findIncrementalLoad(targetDownhole, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
topSlices[i] = sliceDownhole.top;
bottomSlices[i] = sliceDownhole.bottom;
data.polishedRodHorsepower += (dxSurface/12) * sliceSurface.span * data.strokeSPM / 33000;
data.pumpHorsepower += abs((dxDownhole / 12) * sliceDownhole.span * data.strokeSPM / 33000);
}
};
func calcFluidLevel(fluidGradient:Double, rodDepth:Double, pumpArea:Double, frictionEstimate:Double)
{
data.fluidLoad = (data.downholeLoadMax.load - data.downholeLoadMin.load) - frictionEstimate;
data.pumpIntakePressure = fluidGradient * rodDepth - (data.fluidLoad / pumpArea);
//printf("PIP = %f * %f - (%f / %f) = %f\n", fluidGradient, rodDepth, data.fluidLoad, pumpArea, data.pumpIntakePressure);
data.fluidLevel = data.pumpIntakePressure / fluidGradient;
};
func calcLoading(structuralRating:Double)
{
data.structuralLoading = (data.surfaceLoadMax.load / (structuralRating * 100)) * 100;
}
init(){
}
};
class Well
//well object holding all pertinant calculations for the well
{
var currentCard:Card;
var topPosArray = Array<Array<Double>>();
var topLoadArray = Array<Array<Double>>();
var NumColumns = 100;
var NumRows = 10;
for (var i = 0; i < NumColumns; i++)
{
topPosArray.append(Array(count:NumRows, repeatedValue:Double()))
topLoadArray.append(Array(count:NumRows, repeatedValue:Double()))
}
var loadBefore:Double;
var loadAfter:Double;
var loadBefore3:Double;
var loadAfter3:Double;
var dt:Double; //delta T for measurements
var tubingHeadPressure:Double; //Tubing Head Pressure (PSI)
var fluidGradient:Double; //Tubing Fluid Gradient (PSI/ft)
var sbfriction:Double; //Stuffing Box Friction (lbs)
var numTapers:Int; //Number of Rod String Tapers
var nT1:Int; //number of tapers + 1
var anchorDepth:Double;
var pumpDiameter:Double;
var pumpArea:Double;
var tubingID:Double;
var tubingOD:Double;
var tubingCrossSectionalArea:Double;
var frictionEstimate:Double;
var theoreticalMaxFluidLoad:Double;
var structuralRating:Double;
//arrays of size nT1 due to addresses starting at 0
//Rod String Inputs
var c = [Double](count: 11, repeatedValue: 0.0); //User-Defined damping constant per taper (1/sec)
var rodLength = [Double](count: 11, repeatedValue: 0.0); //Length of each rod taper (top to bottom)(ft)
var rodDiameter = [Double](count: 11, repeatedValue: 0.0); //Diameter of each rod taper (top to bottom)(in)
var rodYM = [Double](count: 11, repeatedValue: 0.0); //Youngs modulus of each rod taper (top to bottom)(PSI) Steel=30.5, fiberglass=7.2
var rodWeightPerFoot = [Double](count: 11, repeatedValue: 0.0); //Weight per foot of each rod (ft/lb)
var a = [Double](count: 11, repeatedValue: 0.0);
var area = [Double](count: 12, repeatedValue: 0.0);
var pressure = [Double](count: 11, repeatedValue: 0.0);
var buoyantForce = [Double](count: 11, repeatedValue: 0.0);
var buoyantForceTotal:Double;
var stretch = [Double](count: 11, repeatedValue: 0.0);
var weightData = [Double](count: 11, repeatedValue: 0.0);
var weightDataTotal:Double;
var annularForceData = [Double](count: 11, repeatedValue: 0.0);
var annularForceDataTotal:Double;
var force = [Double](count: 11, repeatedValue: 0.0);
var alpha = [Double](count: 11, repeatedValue: 0.0);
var xOverA = [Double](count: 11, repeatedValue: 0.0);
var factorArray = [Double](count: 11, repeatedValue: 0);
var lagIndexArray = [Int](count: 11, repeatedValue: 0);
var centerPoint = [Int](count: 11, repeatedValue: 0);
var sumCenterPoint = [Int](count: 11, repeatedValue: 0);
var lengthRequired = [Int](count: 11, repeatedValue: 0);
var rodDepth = [Double](count: 11, repeatedValue: 0.0);
var rodDepthTotal:Double;
var rodWeightAir = [Double](count: 11, repeatedValue: 0.0);
var rodWeightAirTotal:Double;
var rodWeightFluid = [Double](count: 11, repeatedValue: 0.0);
var rodWeightFluidTotal:Double;
var count = [Int](count: 11, repeatedValue: 0);
var sPositionPrevious:Double;
func printTaperSetup()
//prints the current taper setup to the console
//TODO: update this to print to a file.
{
println("Taper Parameters");
println(NSString(format: "dt: %.2f", dt))
println(NSString(format: "tubingHeadPressure: %.2f", tubingHeadPressure))
println(NSString(format: "fluidGradient: %.2f", fluidGradient))
println(NSString(format: "sbfriction: %.2f", sbfriction))
println(NSString(format: "numTapers: %.2f", numTapers))
println("c:")
dump(c);
println("rodLength:")
dump(rodLength)
println("rodDiameter:")
dump(rodDiameter);
println("rodYM:")
dump(rodYM);
println("rodWeightPerFoot:")
dump(rodWeightPerFoot)
println("a:");
dump(a);
println("area:")
dump(area)
println("pressure:")
dump(pressure)
println("buoyantForce:")
dump(buoyantForce)
println("stretch")
dump(stretch)
println("weightData")
dump(weightData)
println("annularForceData:")
dump(annularForceData)
println("force:")
dump(force)
println("alpha:")
dump(alpha)
println("xOverA:")
dump(xOverA)
println("factorArray")
dump(factorArray)
println("lagIndexArray")
dump(lagIndexArray)
println("centerPoint:")
dump(centerPoint)
println("sumCenterPoint:")
dump(sumCenterPoint)
println("lengthRequired:")
dump(lengthRequired)
println("rodDepth")
dump(rodDepth)
println("rodWeightAir")
dump(rodWeightAir)
println("rodWeightFluid")
dump(rodWeightFluid)
println(NSString(format: "buoyantForceTotal: %.2f", buoyantForceTotal))
println(NSString(format: "weightDataTotal: %.2f", weightDataTotal))
println(NSString(format: "annularForceDataTotal: %.2f", annularForceDataTotal))
println(NSString(format: "rodDepthTotal: %.2f", rodDepthTotal))
println(NSString(format: "rodWeightAirTotal: %.2f", rodWeightAirTotal))
println(NSString(format: "rodWeightFluidTotal: %.2f", rodWeightFluidTotal))
println(NSString(format: "tubingID: %.2f", tubingID))
println(NSString(format: "tubingOD: %.2f", tubingOD))
println(NSString(format: "tubingCSA: %.2f", tubingCrossSectionalArea))
println(NSString(format: "structuralRating: %.2f", structuralRating))
}
func lookupRodWeightPerFoot(i_ym:Double, i_diam:Double) -> Double
//looks up rod Weight per foot
{
var wtPerFt:Double;
if (i_ym == 30.5)
{
if (i_diam <= 2 && i_diam > 1.75)
{
wtPerFt = 10.7;
}
else if (i_diam <= 1.75 && i_diam > 1.65)
{
wtPerFt = 8.2;
}
else if (i_diam <= 1.65 && i_diam > 1.5)
{
wtPerFt = 7;
}
else if (i_diam <= 1.5 && i_diam > 1.375)
{
wtPerFt = 6;
}
else if (i_diam <= 1.375 && i_diam > 1.125)
{
wtPerFt = 5;
}
else if (i_diam <= 1.125 && i_diam > 1)
{
wtPerFt = 3.676;
}
else if (i_diam <= 1 && i_diam > 0.875)
{
wtPerFt = 2.904;
}
else if (i_diam <= 0.875 && i_diam > 0.75)
{
wtPerFt = 2.224;
}
else if (i_diam <= 0.75 && i_diam > 0.625)
{
wtPerFt = 1.634;
}
else if (i_diam <= 0.625 && i_diam > 0.5)
{
wtPerFt = 1.13;
}
else if (i_diam <= 0.5)
{
wtPerFt = 0.72;
}
else
{
wtPerFt = 0;
}
}
else if (i_ym == 7.2)
{
if (i_diam <= 1.25 && i_diam > 1.125)
{
wtPerFt = 1.2879;
}
else if (i_diam <= 1.125 && i_diam > 1)
{
wtPerFt = 1.09;
}
else if (i_diam <= 1 && i_diam > 0.875)
{
wtPerFt = 0.8188;
}
else if (i_diam <= 0.875 && i_diam > 0.75)
{
wtPerFt = 0.6108;
}
else if (i_diam <= 0.75)
{
wtPerFt = 0.484;
}
else
{
wtPerFt = 0;
}
}
else
{
wtPerFt = 0;
}
return wtPerFt;
}
init(){
}
// func readTaperCSV(filename:String)
// //reads the rod string configuration from a CSV
// {
//
// let csvURL = NSURL(string: "/Users/patrickjmcd/wellParamsIn_1.csv")!
// var error: NSErrorPointer = nil
// let csv = CSV(contentsOfURL: csvURL, error: error)
//
// // Rows
// let rows = csv.rows
//
// for(var row in csv.rows){
//
// }
// Float parseFloat(std::string dblStr);
// Float parseFloatString(Float *arr, std::string dblStr, int len, char delim );
//
// std::ifstream file (filename.c_str());
//
// while ( file.good() )
// {
// std::string key;
// std::string value;
// getline( file, key, ',' );
// getline( file, value, '\n');
//
// if(key.compare("dt")==0){
// dt = parseFloat(value);
// }
// else if (key.compare("tubingHeadPressure")==0)
// {
// tubingHeadPressure = parseFloat(value);
// }
// else if (key.compare("fluidGradient")==0)
// {
// fluidGradient = parseFloat(value);
// }
// else if (key.compare("sbfriction")==0)
// {
// sbfriction = parseFloat(value);
// }
// else if (key.compare("tubingID")==0)
// {
// tubingID = parseFloat(value);
// }
// else if (key.compare("tubingOD")==0)
// {
// tubingOD = parseFloat(value);
// }
// else if (key.compare("numTapers")==0)
// {
// std::istringstream(value) >> numTapers;
// }
// else if (key.compare("anchorDepth")==0)
// {
// anchorDepth = parseFloat(value);
// }
// else if (key.compare("pumpDiameter")==0)
// {
// pumpDiameter = parseFloat(value);
// pumpArea = pow(pumpDiameter,2) * M_PI;
// }
// else if (key.compare("structuralRating")==0)
// {
// structuralRating = parseFloat(value);
// }
// else if (key.compare("c")==0)
// {
// parseFloatString(c, value, 10, '&');
//}
//else if (key.compare("rodLength")==0)
//{
// parseFloatString(rodLength, value, 10, '&');
//}
//else if (key.compare("rodDiameter")==0)
//{
// parseFloatString(rodDiameter, value, 10, '&');
//}
//else if (key.compare("rodYM")==0)
//{
// parseFloatString(rodYM, value, 10, '&');
//}
//}
}

View File

@@ -0,0 +1,760 @@
//: Playground - noun: a place where people can play
import Cocoa
var test = "Hello";
struct LoadSpan //structure to hold load spans
{
var top:Double;
var bottom:Double;
var span:Double;
};
func findMax(arr:[Double], len:Int) -> Double
// find the maximum value of a given array of length len
{
var max = arr[0];
for(var i = 0; i < len; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
return max;
};
func findMin(arr:[Double], len:Int) -> Double
// find the min value of a given array of length len
{
var min = arr[0];
for(var i = 0; i < len; i++)
{
if(arr[i] < min)
{
min = arr[i];
}
}
return min;
};
func updAverage(prevAverage:Double, currentMeasurement:Double, numMeasurements:Int) -> Double
{
var newAverage:Double;
newAverage = prevAverage * ((Double(numMeasurements) - 1)/Double(numMeasurements)) + (currentMeasurement / Double(numMeasurements));
return newAverage;
};
class LPPair //structure to hold Load and Position
{
var load:Double;
var position:Double;
func clr()
{
load = 0;
position = 0;
}
init(){
clr();
}
};
class WellData
{
var polishedRodHorsepower:Double;
var pumpHorsepower:Double;
var pumpIntakePressure:Double;
var fluidLevel:Double;
var strokeSPM:Double;
var strokeNumber:Int;
var surfacePositionMax: LPPair;
var surfacePositionMin: LPPair;
var surfaceLoadMax: LPPair;
var surfaceLoadMin: LPPair;
var downholePositionMax: LPPair;
var downholePositionMin: LPPair;
var downholeLoadMax: LPPair;
var downholeLoadMin: LPPair;
var topRight: LPPair;
var topLeft: LPPair;
var fillPoint: LPPair;
var fullFillPoint: LPPair;
var bottomLeft: LPPair;
var surfaceStrokeLength:Double;
var downholeNetStrokeLength:Double;
var downholeGrossStrokeLength:Double;
var downholeAdjustedGrossStrokeLength:Double;
var downholeLoadSpan:Double;
var fluidLoad:Double;
var fillageEstimated:Double;
var fillageCalculated:Double;
var tubingMovement:Double;
var plungerTravel:Double;
var dailyProduction:Double;
var structuralLoading:Double;
func clearAll()
{
polishedRodHorsepower = 0;
pumpHorsepower = 0;
pumpIntakePressure = 0;
fluidLevel = 0;
strokeSPM = 0;
strokeNumber = 1;
surfacePositionMax.clr();
surfacePositionMin.clr();
surfaceLoadMax.clr();
surfaceLoadMin.clr();
downholePositionMax.clr();
downholePositionMin.clr();
downholeLoadMax.clr();
downholeLoadMin.clr();
topRight.clr();
topLeft.clr();
fillPoint.clr();
fullFillPoint.clr();
bottomLeft.clr();
surfaceStrokeLength = 0;
downholeNetStrokeLength = 0;
downholeGrossStrokeLength = 0;
downholeAdjustedGrossStrokeLength = 0;
downholeLoadSpan = 0;
fluidLoad = 0;
fillageEstimated = 0;
fillageCalculated = 0;
tubingMovement = 0;
plungerTravel = 0;
dailyProduction = 0;
structuralLoading = 0;
};
init(){
clearAll();
}
};
class Card
//Object for card calculations and data
{
var surfacePosition = [Double](count: 1000, repeatedValue: 0.0);;
var downholePosition = [Double](count: 1000, repeatedValue: 0.0);;
var surfaceLoad = [Double](count: 1000, repeatedValue: 0.0);;
var downholeLoad = [Double](count: 1000, repeatedValue: 0.0);;
var data:WellData;
var pointCounter:Int;
func findLoadAtPosition(pos:Double, posArray:[Double], loadArray: [Double], size:Int) -> Double
{
for(var i = 0; i < size; i++)
{
if(posArray[i] == pos){
return loadArray[i];
}
}
};
func findPositionAtLoad(load:Double, posArray:[Double], loadArray: [Double], size:Int) -> Double
{
for(var i = 0; i < size; i++)
{
if(loadArray[i] == load){
return posArray[i];
}
}
};
func findLimits()
{
//find maximum values of the arrays
data.surfacePositionMax.position = findMax(surfacePosition, pointCounter);
data.surfacePositionMax.load = findLoadAtPosition(data.surfacePositionMax.position, posArray: surfacePosition,loadArray: surfaceLoad ,size: pointCounter);
data.surfaceLoadMax.load = findMax(surfaceLoad, pointCounter);
data.surfaceLoadMax.position = findPositionAtLoad(data.surfaceLoadMax.load, posArray: surfacePosition, loadArray: surfaceLoad ,size: pointCounter);
data.downholePositionMax.position = findMax(downholePosition, pointCounter);
data.downholePositionMax.load = findLoadAtPosition(data.downholePositionMax.position, posArray: downholePosition, loadArray: downholeLoad ,size: pointCounter);
data.downholeLoadMax.load = findMax(downholeLoad, pointCounter);
data.downholeLoadMax.position = findPositionAtLoad(data.downholeLoadMax.load, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
//find minimum values of the arrays
data.surfacePositionMin.position = findMin(surfacePosition, pointCounter);
data.surfacePositionMin.load = findLoadAtPosition(data.surfacePositionMin.position, posArray: surfacePosition, loadArray: surfaceLoad, size: pointCounter);
data.surfaceLoadMin.load = findMin(surfaceLoad, pointCounter);
data.surfaceLoadMin.position = findPositionAtLoad(data.surfaceLoadMin.load, posArray: surfacePosition, loadArray: surfaceLoad, size: pointCounter);
data.downholePositionMin.position = findMin(downholePosition, pointCounter);
data.downholePositionMin.load = findLoadAtPosition(data.downholePositionMin.position, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
data.downholeLoadMin.load = findMin(downholeLoad, pointCounter);
data.downholeLoadMin.position = findPositionAtLoad(data.downholeLoadMin.load, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
data.surfaceStrokeLength = data.surfacePositionMax.position - data.surfacePositionMin.position;
data.downholeGrossStrokeLength = data.downholePositionMax.position - data.downholePositionMin.position;
data.downholeLoadSpan = data.downholeLoadMax.load - data.downholeLoadMin.load;
};
func findNearestPointToLoad(direction:String, cardHalf:String, targetLoad:Double, posArray:[Double], loadArray:[Double], size:Int) -> LPPair
{
var posMin = findMin(posArray, size);
var posMax = findMax(posArray, size);
var leftIgnore = posMin + (posMax - posMin)*(0.75);
var rightIgnore = posMin + (posMax - posMin)*(0.25);
var foundPoint:LPPair;
if (direction=="up")
{
for(var i = 1; i < size; i++)
{
if(cardHalf == "right" && posArray[i] >= rightIgnore)
{
if(loadArray[i] <= targetLoad && loadArray[i-1] > targetLoad)
{
foundPoint.position = posArray[i];
foundPoint.load = loadArray[i];
return foundPoint;
}
}
else
{
if(loadArray[i] >= targetLoad && loadArray[i-1] < targetLoad)
{
foundPoint.position = posArray[i];
foundPoint.load = loadArray[i];
return foundPoint;
}
}
}
}
else {
for(var i = 1; i < size; i++)
{
if(cardHalf == "right" && posArray[i] >= rightIgnore)
{
if(loadArray[i] >= targetLoad && loadArray[i-1] < targetLoad)
{
foundPoint.position = posArray[i];
foundPoint.load = loadArray[i];
return foundPoint;
}
}
else
{
if(loadArray[i] <= targetLoad && loadArray[i-1] > targetLoad)
{
foundPoint.position = posArray[i];
foundPoint.load = loadArray[i];
return foundPoint;
}
}
}
}
}
func findIncrementalLoad(targetPosition:Double, posArray:[Double], loadArray:[Double], size:Int) -> LoadSpan
{
var result:LoadSpan;
var upPointGreater:LPPair;
var upPointLesser:LPPair;
var downPointGreater:LPPair;
var downPointLesser:LPPair;
for(var i = 1; i < size; i++)
{
if ((posArray[i] >= targetPosition) && (posArray[i-1] < targetPosition))
{
upPointGreater.position = posArray[i];
upPointGreater.load = loadArray[i];
upPointLesser.position = posArray[i-1];
upPointLesser.load = loadArray[i-1];
}
if ((posArray[i] <= targetPosition) && (posArray[i-1] > targetPosition))
{
downPointGreater.position = posArray[i];
downPointGreater.load = loadArray[i];
downPointLesser.position = posArray[i-1];
downPointLesser.load = loadArray[i-1];
}
var mUp = (upPointGreater.load - upPointLesser.load) / (upPointGreater.position - upPointLesser.position);
var bUp = upPointGreater.load - (mUp * upPointGreater.position);
result.top = (mUp * targetPosition) + bUp;
var mDown = (downPointGreater.load - downPointLesser.load) / (downPointGreater.position - downPointLesser.position);
var bDown = downPointGreater.load - (mDown * downPointGreater.position);
result.bottom = (mDown * targetPosition) + bDown;
result.span = result.top - result.bottom;
return result;
}
}
func findCorners(pctTop:Double, pctBottom:Double)
{
var halfLoadLine = data.downholeLoadMin.load + data.downholeLoadSpan/2;
var halfLoad:LPPair;
halfLoad = findNearestPointToLoad("up", cardHalf: "left", targetLoad: halfLoadLine, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
var topLoadLine = data.downholeLoadMax.load - (data.downholeLoadSpan * (pctTop/100));
var bottomLoadLine = data.downholeLoadMin.load + (data.downholeLoadSpan * (pctBottom/100));
if(data.downholePositionMin.position < halfLoad.position)
{
data.bottomLeft = data.downholePositionMin;
data.topLeft = findNearestPointToLoad("up", cardHalf: "left", targetLoad: topLoadLine, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
}
else
{
data.bottomLeft = findNearestPointToLoad("up", cardHalf: "left", targetLoad: bottomLoadLine, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
data.topLeft = data.downholePositionMin;
}
data.topRight = data.downholePositionMax;
data.fillPoint = findNearestPointToLoad("up", cardHalf: "right", targetLoad: bottomLoadLine, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
data.fullFillPoint.position = data.bottomLeft.position + data.topRight.position - data.topLeft.position;
data.fullFillPoint.load = data.bottomLeft.load;
};
func calcFillage(anchorDepth:Double, rodDepth:Double, tubingCSA:Double)
{
data.tubingMovement = 12 * (rodDepth - anchorDepth)*data.fluidLoad / (30500000 * tubingCSA);
data.downholeAdjustedGrossStrokeLength = data.downholeGrossStrokeLength - data.tubingMovement;
data.downholeNetStrokeLength = data.fillPoint.position - data.bottomLeft.position;
data.fillageEstimated = ((data.fillPoint.position - data.bottomLeft.position)/(data.fullFillPoint.position - data.bottomLeft.position))*100.0;
data.fillageCalculated = ((data.downholeNetStrokeLength + data.tubingMovement)/data.downholeGrossStrokeLength)*100.0;
if (data.fillageEstimated > 100)
{
data.fillageEstimated = 100.0;
}
if (data.fillageCalculated > 100)
{
data.fillageCalculated = 100.0;
}
};
func calcHorsepower (riemannSlices:Int)
{
data.polishedRodHorsepower = 0.0;
data.pumpHorsepower = 0.0;
var topSlices = [Double](count: riemannSlices, repeatedValue: 0.0);
var bottomSlices = [Double](count: riemannSlices, repeatedValue: 0.0);
var dxSurface = data.surfaceStrokeLength / (Double(riemannSlices) + 1);
var dxDownhole = data.downholeNetStrokeLength / (Double(riemannSlices) + 1);
for (var i = 1; i < riemannSlices; i++)
{
var targetSurface = dxSurface * Double(i) + data.surfacePositionMin.position;
var targetDownhole = dxDownhole * Double(i) + data.downholePositionMin.position;
var sliceSurface:LoadSpan;
var sliceDownhole:LoadSpan;
sliceSurface = findIncrementalLoad(targetSurface, posArray: surfacePosition, loadArray: surfaceLoad, size: pointCounter);
sliceDownhole = findIncrementalLoad(targetDownhole, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
topSlices[i] = sliceDownhole.top;
bottomSlices[i] = sliceDownhole.bottom;
data.polishedRodHorsepower += (dxSurface/12) * sliceSurface.span * data.strokeSPM / 33000;
data.pumpHorsepower += abs((dxDownhole / 12) * sliceDownhole.span * data.strokeSPM / 33000);
}
};
func calcFluidLevel(fluidGradient:Double, rodDepth:Double, pumpArea:Double, frictionEstimate:Double)
{
data.fluidLoad = (data.downholeLoadMax.load - data.downholeLoadMin.load) - frictionEstimate;
data.pumpIntakePressure = fluidGradient * rodDepth - (data.fluidLoad / pumpArea);
//printf("PIP = %f * %f - (%f / %f) = %f\n", fluidGradient, rodDepth, data.fluidLoad, pumpArea, data.pumpIntakePressure);
data.fluidLevel = data.pumpIntakePressure / fluidGradient;
};
func calcLoading(structuralRating:Double)
{
data.structuralLoading = (data.surfaceLoadMax.load / (structuralRating * 100)) * 100;
}
init(){
}
};
class Well
//well object holding all pertinant calculations for the well
{
var currentCard:Card;
var topPosArray = Array<Array<Double>>();
var topLoadArray = Array<Array<Double>>();
var NumColumns = 100;
var NumRows = 10;
var loadBefore:Double;
var loadAfter:Double;
var loadBefore3:Double;
var loadAfter3:Double;
var dt:Double; //delta T for measurements
var tubingHeadPressure:Double; //Tubing Head Pressure (PSI)
var fluidGradient:Double; //Tubing Fluid Gradient (PSI/ft)
var sbfriction:Double; //Stuffing Box Friction (lbs)
var numTapers:Int; //Number of Rod String Tapers
var nT1:Int; //number of tapers + 1
var anchorDepth:Double;
var pumpDiameter:Double;
var pumpArea:Double;
var tubingID:Double;
var tubingOD:Double;
var tubingCrossSectionalArea:Double;
var frictionEstimate:Double;
var theoreticalMaxFluidLoad:Double;
var structuralRating:Double;
//arrays of size nT1 due to addresses starting at 0
//Rod String Inputs
var c = [Double](count: 11, repeatedValue: 0.0); //User-Defined damping constant per taper (1/sec)
var rodLength = [Double](count: 11, repeatedValue: 0.0); //Length of each rod taper (top to bottom)(ft)
var rodDiameter = [Double](count: 11, repeatedValue: 0.0); //Diameter of each rod taper (top to bottom)(in)
var rodYM = [Double](count: 11, repeatedValue: 0.0); //Youngs modulus of each rod taper (top to bottom)(PSI) Steel=30.5, fiberglass=7.2
var rodWeightPerFoot = [Double](count: 11, repeatedValue: 0.0); //Weight per foot of each rod (ft/lb)
var a = [Double](count: 11, repeatedValue: 0.0);
var area = [Double](count: 12, repeatedValue: 0.0);
var pressure = [Double](count: 11, repeatedValue: 0.0);
var buoyantForce = [Double](count: 11, repeatedValue: 0.0);
var buoyantForceTotal:Double;
var stretch = [Double](count: 11, repeatedValue: 0.0);
var weightData = [Double](count: 11, repeatedValue: 0.0);
var weightDataTotal:Double;
var annularForceData = [Double](count: 11, repeatedValue: 0.0);
var annularForceDataTotal:Double;
var force = [Double](count: 11, repeatedValue: 0.0);
var alpha = [Double](count: 11, repeatedValue: 0.0);
var xOverA = [Double](count: 11, repeatedValue: 0.0);
var factorArray = [Double](count: 11, repeatedValue: 0);
var lagIndexArray = [Int](count: 11, repeatedValue: 0);
var centerPoint = [Int](count: 11, repeatedValue: 0);
var sumCenterPoint = [Int](count: 11, repeatedValue: 0);
var lengthRequired = [Int](count: 11, repeatedValue: 0);
var rodDepth = [Double](count: 11, repeatedValue: 0.0);
var rodDepthTotal:Double;
var rodWeightAir = [Double](count: 11, repeatedValue: 0.0);
var rodWeightAirTotal:Double;
var rodWeightFluid = [Double](count: 11, repeatedValue: 0.0);
var rodWeightFluidTotal:Double;
var count = [Int](count: 11, repeatedValue: 0);
var sPositionPrevious:Double;
init(){
topArraySetup()
}
func topArraySetup(){
for (var i = 0; i < NumColumns; i++)
{
topPosArray.append(Array(count:NumRows, repeatedValue:Double()))
topLoadArray.append(Array(count:NumRows, repeatedValue:Double()))
}
}
func printTaperSetup()
//prints the current taper setup to the console
//TODO: update this to print to a file.
{
println("Taper Parameters");
println(NSString(format: "dt: %.2f", dt))
println(NSString(format: "tubingHeadPressure: %.2f", tubingHeadPressure))
println(NSString(format: "fluidGradient: %.2f", fluidGradient))
println(NSString(format: "sbfriction: %.2f", sbfriction))
println(NSString(format: "numTapers: %.2f", numTapers))
println("c:")
dump(c);
println("rodLength:")
dump(rodLength)
println("rodDiameter:")
dump(rodDiameter);
println("rodYM:")
dump(rodYM);
println("rodWeightPerFoot:")
dump(rodWeightPerFoot)
println("a:");
dump(a);
println("area:")
dump(area)
println("pressure:")
dump(pressure)
println("buoyantForce:")
dump(buoyantForce)
println("stretch")
dump(stretch)
println("weightData")
dump(weightData)
println("annularForceData:")
dump(annularForceData)
println("force:")
dump(force)
println("alpha:")
dump(alpha)
println("xOverA:")
dump(xOverA)
println("factorArray")
dump(factorArray)
println("lagIndexArray")
dump(lagIndexArray)
println("centerPoint:")
dump(centerPoint)
println("sumCenterPoint:")
dump(sumCenterPoint)
println("lengthRequired:")
dump(lengthRequired)
println("rodDepth")
dump(rodDepth)
println("rodWeightAir")
dump(rodWeightAir)
println("rodWeightFluid")
dump(rodWeightFluid)
println(NSString(format: "buoyantForceTotal: %.2f", buoyantForceTotal))
println(NSString(format: "weightDataTotal: %.2f", weightDataTotal))
println(NSString(format: "annularForceDataTotal: %.2f", annularForceDataTotal))
println(NSString(format: "rodDepthTotal: %.2f", rodDepthTotal))
println(NSString(format: "rodWeightAirTotal: %.2f", rodWeightAirTotal))
println(NSString(format: "rodWeightFluidTotal: %.2f", rodWeightFluidTotal))
println(NSString(format: "tubingID: %.2f", tubingID))
println(NSString(format: "tubingOD: %.2f", tubingOD))
println(NSString(format: "tubingCSA: %.2f", tubingCrossSectionalArea))
println(NSString(format: "structuralRating: %.2f", structuralRating))
}
func lookupRodWeightPerFoot(i_ym:Double, i_diam:Double) -> Double
//looks up rod Weight per foot
{
var wtPerFt:Double;
if (i_ym == 30.5)
{
if (i_diam <= 2 && i_diam > 1.75)
{
wtPerFt = 10.7;
}
else if (i_diam <= 1.75 && i_diam > 1.65)
{
wtPerFt = 8.2;
}
else if (i_diam <= 1.65 && i_diam > 1.5)
{
wtPerFt = 7;
}
else if (i_diam <= 1.5 && i_diam > 1.375)
{
wtPerFt = 6;
}
else if (i_diam <= 1.375 && i_diam > 1.125)
{
wtPerFt = 5;
}
else if (i_diam <= 1.125 && i_diam > 1)
{
wtPerFt = 3.676;
}
else if (i_diam <= 1 && i_diam > 0.875)
{
wtPerFt = 2.904;
}
else if (i_diam <= 0.875 && i_diam > 0.75)
{
wtPerFt = 2.224;
}
else if (i_diam <= 0.75 && i_diam > 0.625)
{
wtPerFt = 1.634;
}
else if (i_diam <= 0.625 && i_diam > 0.5)
{
wtPerFt = 1.13;
}
else if (i_diam <= 0.5)
{
wtPerFt = 0.72;
}
else
{
wtPerFt = 0;
}
}
else if (i_ym == 7.2)
{
if (i_diam <= 1.25 && i_diam > 1.125)
{
wtPerFt = 1.2879;
}
else if (i_diam <= 1.125 && i_diam > 1)
{
wtPerFt = 1.09;
}
else if (i_diam <= 1 && i_diam > 0.875)
{
wtPerFt = 0.8188;
}
else if (i_diam <= 0.875 && i_diam > 0.75)
{
wtPerFt = 0.6108;
}
else if (i_diam <= 0.75)
{
wtPerFt = 0.484;
}
else
{
wtPerFt = 0;
}
}
else
{
wtPerFt = 0;
}
return wtPerFt;
}
// func readTaperCSV(filename:String)
// //reads the rod string configuration from a CSV
// {
//
// let csvURL = NSURL(string: "/Users/patrickjmcd/wellParamsIn_1.csv")!
// var error: NSErrorPointer = nil
// let csv = CSV(contentsOfURL: csvURL, error: error)
//
// // Rows
// let rows = csv.rows
//
// for(var row in csv.rows){
//
// }
// Float parseFloat(std::string dblStr);
// Float parseFloatString(Float *arr, std::string dblStr, int len, char delim );
//
// std::ifstream file (filename.c_str());
//
// while ( file.good() )
// {
// std::string key;
// std::string value;
// getline( file, key, ',' );
// getline( file, value, '\n');
//
// if(key.compare("dt")==0){
// dt = parseFloat(value);
// }
// else if (key.compare("tubingHeadPressure")==0)
// {
// tubingHeadPressure = parseFloat(value);
// }
// else if (key.compare("fluidGradient")==0)
// {
// fluidGradient = parseFloat(value);
// }
// else if (key.compare("sbfriction")==0)
// {
// sbfriction = parseFloat(value);
// }
// else if (key.compare("tubingID")==0)
// {
// tubingID = parseFloat(value);
// }
// else if (key.compare("tubingOD")==0)
// {
// tubingOD = parseFloat(value);
// }
// else if (key.compare("numTapers")==0)
// {
// std::istringstream(value) >> numTapers;
// }
// else if (key.compare("anchorDepth")==0)
// {
// anchorDepth = parseFloat(value);
// }
// else if (key.compare("pumpDiameter")==0)
// {
// pumpDiameter = parseFloat(value);
// pumpArea = pow(pumpDiameter,2) * M_PI;
// }
// else if (key.compare("structuralRating")==0)
// {
// structuralRating = parseFloat(value);
// }
// else if (key.compare("c")==0)
// {
// parseFloatString(c, value, 10, '&');
//}
//else if (key.compare("rodLength")==0)
//{
// parseFloatString(rodLength, value, 10, '&');
//}
//else if (key.compare("rodDiameter")==0)
//{
// parseFloatString(rodDiameter, value, 10, '&');
//}
//else if (key.compare("rodYM")==0)
//{
// parseFloatString(rodYM, value, 10, '&');
//}
//}
}
var well:Well;
well.printTaperSetup();
println(well.numTapers);

View File

@@ -0,0 +1,3 @@
//
// This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to POC.playground.
//

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='osx'>
<timeline fileName='timeline.xctimeline'/>
</playground>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:../../Dropbox (Henry Pump)/Patrick McDonagh/POC/Swift POC/POC.playground">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
<false/>
<key>IDESourceControlProjectIdentifier</key>
<string>F63752C8-BC3A-4E8B-83CF-87055B0E471D</string>
<key>IDESourceControlProjectName</key>
<string>playground</string>
<key>IDESourceControlProjectOriginsDictionary</key>
<dict>
<key>7BF837D10FB421D5AEF1283459C27C2BF38FFB44</key>
<string>http://192.168.2.45/Bonobo.Git.Server/Swift_POC.git</string>
</dict>
<key>IDESourceControlProjectPath</key>
<string>POC.playground/playground.xcworkspace</string>
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
<dict>
<key>7BF837D10FB421D5AEF1283459C27C2BF38FFB44</key>
<string>../..</string>
</dict>
<key>IDESourceControlProjectURL</key>
<string>http://192.168.2.45/Bonobo.Git.Server/Swift_POC.git</string>
<key>IDESourceControlProjectVersion</key>
<integer>111</integer>
<key>IDESourceControlProjectWCCIdentifier</key>
<string>7BF837D10FB421D5AEF1283459C27C2BF38FFB44</string>
<key>IDESourceControlProjectWCConfigurations</key>
<array>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>7BF837D10FB421D5AEF1283459C27C2BF38FFB44</string>
<key>IDESourceControlWCCName</key>
<string>Swift%20POC</string>
</dict>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Timeline
version = "3.0">
<TimelineItems>
</TimelineItems>
</Timeline>

View File

@@ -0,0 +1,755 @@
//: Playground - noun: a place where people can play
import UIKit
println("hello world");
struct LoadSpan //structure to hold load spans
{
var top:Double;
var bottom:Double;
var span:Double;
};
func findMax(arr:[Double], len:Int) -> Double
// find the maximum value of a given array of length len
{
var max = arr[0];
for(var i = 0; i < len; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
return max;
};
func findMin(arr:[Double], len:Int) -> Double
// find the min value of a given array of length len
{
var min = arr[0];
for(var i = 0; i < len; i++)
{
if(arr[i] < min)
{
min = arr[i];
}
}
return min;
};
func updAverage(prevAverage:Double, currentMeasurement:Double, numMeasurements:Int) -> Double
{
var newAverage:Double;
newAverage = prevAverage * ((Double(numMeasurements) - 1)/Double(numMeasurements)) + (currentMeasurement / Double(numMeasurements));
return newAverage;
};
class LPPair //structure to hold Load and Position
{
var load:Double;
var position:Double;
func clr()
{
load = 0;
position = 0;
}
init(){
clr();
}
};
class WellData
{
var polishedRodHorsepower:Double;
var pumpHorsepower:Double;
var pumpIntakePressure:Double;
var fluidLevel:Double;
var strokeSPM:Double;
var strokeNumber:Int;
var surfacePositionMax: LPPair;
var surfacePositionMin: LPPair;
var surfaceLoadMax: LPPair;
var surfaceLoadMin: LPPair;
var downholePositionMax: LPPair;
var downholePositionMin: LPPair;
var downholeLoadMax: LPPair;
var downholeLoadMin: LPPair;
var topRight: LPPair;
var topLeft: LPPair;
var fillPoint: LPPair;
var fullFillPoint: LPPair;
var bottomLeft: LPPair;
var surfaceStrokeLength:Double;
var downholeNetStrokeLength:Double;
var downholeGrossStrokeLength:Double;
var downholeAdjustedGrossStrokeLength:Double;
var downholeLoadSpan:Double;
var fluidLoad:Double;
var fillageEstimated:Double;
var fillageCalculated:Double;
var tubingMovement:Double;
var plungerTravel:Double;
var dailyProduction:Double;
var structuralLoading:Double;
func clearAll()
{
polishedRodHorsepower = 0;
pumpHorsepower = 0;
pumpIntakePressure = 0;
fluidLevel = 0;
strokeSPM = 0;
strokeNumber = 1;
surfacePositionMax.clr();
surfacePositionMin.clr();
surfaceLoadMax.clr();
surfaceLoadMin.clr();
downholePositionMax.clr();
downholePositionMin.clr();
downholeLoadMax.clr();
downholeLoadMin.clr();
topRight.clr();
topLeft.clr();
fillPoint.clr();
fullFillPoint.clr();
bottomLeft.clr();
surfaceStrokeLength = 0;
downholeNetStrokeLength = 0;
downholeGrossStrokeLength = 0;
downholeAdjustedGrossStrokeLength = 0;
downholeLoadSpan = 0;
fluidLoad = 0;
fillageEstimated = 0;
fillageCalculated = 0;
tubingMovement = 0;
plungerTravel = 0;
dailyProduction = 0;
structuralLoading = 0;
};
init(){
clearAll();
}
};
class Card
//Object for card calculations and data
{
var surfacePosition = [Double](count: 1000, repeatedValue: 0.0);;
var downholePosition = [Double](count: 1000, repeatedValue: 0.0);;
var surfaceLoad = [Double](count: 1000, repeatedValue: 0.0);;
var downholeLoad = [Double](count: 1000, repeatedValue: 0.0);;
var data:WellData;
var pointCounter:Int;
func findLoadAtPosition(pos:Double, posArray:[Double], loadArray: [Double], size:Int) -> Double
{
for(var i = 0; i < size; i++)
{
if(posArray[i] == pos){
return loadArray[i];
}
}
};
func findPositionAtLoad(load:Double, posArray:[Double], loadArray: [Double], size:Int) -> Double
{
for(var i = 0; i < size; i++)
{
if(loadArray[i] == load){
return posArray[i];
}
}
};
func findLimits()
{
//find maximum values of the arrays
data.surfacePositionMax.position = findMax(surfacePosition, pointCounter);
data.surfacePositionMax.load = findLoadAtPosition(data.surfacePositionMax.position, posArray: surfacePosition,loadArray: surfaceLoad ,size: pointCounter);
data.surfaceLoadMax.load = findMax(surfaceLoad, pointCounter);
data.surfaceLoadMax.position = findPositionAtLoad(data.surfaceLoadMax.load, posArray: surfacePosition, loadArray: surfaceLoad ,size: pointCounter);
data.downholePositionMax.position = findMax(downholePosition, pointCounter);
data.downholePositionMax.load = findLoadAtPosition(data.downholePositionMax.position, posArray: downholePosition, loadArray: downholeLoad ,size: pointCounter);
data.downholeLoadMax.load = findMax(downholeLoad, pointCounter);
data.downholeLoadMax.position = findPositionAtLoad(data.downholeLoadMax.load, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
//find minimum values of the arrays
data.surfacePositionMin.position = findMin(surfacePosition, pointCounter);
data.surfacePositionMin.load = findLoadAtPosition(data.surfacePositionMin.position, posArray: surfacePosition, loadArray: surfaceLoad, size: pointCounter);
data.surfaceLoadMin.load = findMin(surfaceLoad, pointCounter);
data.surfaceLoadMin.position = findPositionAtLoad(data.surfaceLoadMin.load, posArray: surfacePosition, loadArray: surfaceLoad, size: pointCounter);
data.downholePositionMin.position = findMin(downholePosition, pointCounter);
data.downholePositionMin.load = findLoadAtPosition(data.downholePositionMin.position, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
data.downholeLoadMin.load = findMin(downholeLoad, pointCounter);
data.downholeLoadMin.position = findPositionAtLoad(data.downholeLoadMin.load, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
data.surfaceStrokeLength = data.surfacePositionMax.position - data.surfacePositionMin.position;
data.downholeGrossStrokeLength = data.downholePositionMax.position - data.downholePositionMin.position;
data.downholeLoadSpan = data.downholeLoadMax.load - data.downholeLoadMin.load;
};
func findNearestPointToLoad(direction:String, cardHalf:String, targetLoad:Double, posArray:[Double], loadArray:[Double], size:Int) -> LPPair
{
var posMin = findMin(posArray, size);
var posMax = findMax(posArray, size);
var leftIgnore = posMin + (posMax - posMin)*(0.75);
var rightIgnore = posMin + (posMax - posMin)*(0.25);
var foundPoint:LPPair;
if (direction=="up")
{
for(var i = 1; i < size; i++)
{
if(cardHalf == "right" && posArray[i] >= rightIgnore)
{
if(loadArray[i] <= targetLoad && loadArray[i-1] > targetLoad)
{
foundPoint.position = posArray[i];
foundPoint.load = loadArray[i];
return foundPoint;
}
}
else
{
if(loadArray[i] >= targetLoad && loadArray[i-1] < targetLoad)
{
foundPoint.position = posArray[i];
foundPoint.load = loadArray[i];
return foundPoint;
}
}
}
}
else {
for(var i = 1; i < size; i++)
{
if(cardHalf == "right" && posArray[i] >= rightIgnore)
{
if(loadArray[i] >= targetLoad && loadArray[i-1] < targetLoad)
{
foundPoint.position = posArray[i];
foundPoint.load = loadArray[i];
return foundPoint;
}
}
else
{
if(loadArray[i] <= targetLoad && loadArray[i-1] > targetLoad)
{
foundPoint.position = posArray[i];
foundPoint.load = loadArray[i];
return foundPoint;
}
}
}
}
}
func findIncrementalLoad(targetPosition:Double, posArray:[Double], loadArray:[Double], size:Int) -> LoadSpan
{
var result:LoadSpan;
var upPointGreater:LPPair;
var upPointLesser:LPPair;
var downPointGreater:LPPair;
var downPointLesser:LPPair;
for(var i = 1; i < size; i++)
{
if ((posArray[i] >= targetPosition) && (posArray[i-1] < targetPosition))
{
upPointGreater.position = posArray[i];
upPointGreater.load = loadArray[i];
upPointLesser.position = posArray[i-1];
upPointLesser.load = loadArray[i-1];
}
if ((posArray[i] <= targetPosition) && (posArray[i-1] > targetPosition))
{
downPointGreater.position = posArray[i];
downPointGreater.load = loadArray[i];
downPointLesser.position = posArray[i-1];
downPointLesser.load = loadArray[i-1];
}
var mUp = (upPointGreater.load - upPointLesser.load) / (upPointGreater.position - upPointLesser.position);
var bUp = upPointGreater.load - (mUp * upPointGreater.position);
result.top = (mUp * targetPosition) + bUp;
var mDown = (downPointGreater.load - downPointLesser.load) / (downPointGreater.position - downPointLesser.position);
var bDown = downPointGreater.load - (mDown * downPointGreater.position);
result.bottom = (mDown * targetPosition) + bDown;
result.span = result.top - result.bottom;
return result;
}
}
func findCorners(pctTop:Double, pctBottom:Double)
{
var halfLoadLine = data.downholeLoadMin.load + data.downholeLoadSpan/2;
var halfLoad:LPPair;
halfLoad = findNearestPointToLoad("up", cardHalf: "left", targetLoad: halfLoadLine, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
var topLoadLine = data.downholeLoadMax.load - (data.downholeLoadSpan * (pctTop/100));
var bottomLoadLine = data.downholeLoadMin.load + (data.downholeLoadSpan * (pctBottom/100));
if(data.downholePositionMin.position < halfLoad.position)
{
data.bottomLeft = data.downholePositionMin;
data.topLeft = findNearestPointToLoad("up", cardHalf: "left", targetLoad: topLoadLine, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
}
else
{
data.bottomLeft = findNearestPointToLoad("up", cardHalf: "left", targetLoad: bottomLoadLine, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
data.topLeft = data.downholePositionMin;
}
data.topRight = data.downholePositionMax;
data.fillPoint = findNearestPointToLoad("up", cardHalf: "right", targetLoad: bottomLoadLine, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
data.fullFillPoint.position = data.bottomLeft.position + data.topRight.position - data.topLeft.position;
data.fullFillPoint.load = data.bottomLeft.load;
};
func calcFillage(anchorDepth:Double, rodDepth:Double, tubingCSA:Double)
{
data.tubingMovement = 12 * (rodDepth - anchorDepth)*data.fluidLoad / (30500000 * tubingCSA);
data.downholeAdjustedGrossStrokeLength = data.downholeGrossStrokeLength - data.tubingMovement;
data.downholeNetStrokeLength = data.fillPoint.position - data.bottomLeft.position;
data.fillageEstimated = ((data.fillPoint.position - data.bottomLeft.position)/(data.fullFillPoint.position - data.bottomLeft.position))*100.0;
data.fillageCalculated = ((data.downholeNetStrokeLength + data.tubingMovement)/data.downholeGrossStrokeLength)*100.0;
if (data.fillageEstimated > 100)
{
data.fillageEstimated = 100.0;
}
if (data.fillageCalculated > 100)
{
data.fillageCalculated = 100.0;
}
};
func calcHorsepower (riemannSlices:Int)
{
data.polishedRodHorsepower = 0.0;
data.pumpHorsepower = 0.0;
var topSlices = [Double](count: riemannSlices, repeatedValue: 0.0);
var bottomSlices = [Double](count: riemannSlices, repeatedValue: 0.0);
var dxSurface = data.surfaceStrokeLength / (Double(riemannSlices) + 1);
var dxDownhole = data.downholeNetStrokeLength / (Double(riemannSlices) + 1);
for (var i = 1; i < riemannSlices; i++)
{
var targetSurface = dxSurface * Double(i) + data.surfacePositionMin.position;
var targetDownhole = dxDownhole * Double(i) + data.downholePositionMin.position;
var sliceSurface:LoadSpan;
var sliceDownhole:LoadSpan;
sliceSurface = findIncrementalLoad(targetSurface, posArray: surfacePosition, loadArray: surfaceLoad, size: pointCounter);
sliceDownhole = findIncrementalLoad(targetDownhole, posArray: downholePosition, loadArray: downholeLoad, size: pointCounter);
topSlices[i] = sliceDownhole.top;
bottomSlices[i] = sliceDownhole.bottom;
data.polishedRodHorsepower += (dxSurface/12) * sliceSurface.span * data.strokeSPM / 33000;
data.pumpHorsepower += abs((dxDownhole / 12) * sliceDownhole.span * data.strokeSPM / 33000);
}
};
func calcFluidLevel(fluidGradient:Double, rodDepth:Double, pumpArea:Double, frictionEstimate:Double)
{
data.fluidLoad = (data.downholeLoadMax.load - data.downholeLoadMin.load) - frictionEstimate;
data.pumpIntakePressure = fluidGradient * rodDepth - (data.fluidLoad / pumpArea);
//printf("PIP = %f * %f - (%f / %f) = %f\n", fluidGradient, rodDepth, data.fluidLoad, pumpArea, data.pumpIntakePressure);
data.fluidLevel = data.pumpIntakePressure / fluidGradient;
};
func calcLoading(structuralRating:Double)
{
data.structuralLoading = (data.surfaceLoadMax.load / (structuralRating * 100)) * 100;
}
init(){
}
};
class Well
//well object holding all pertinant calculations for the well
{
var currentCard:Card;
var topPosArray = Array<Array<Double>>();
var topLoadArray = Array<Array<Double>>();
var NumColumns = 100;
var NumRows = 10;
for(var i = 0; i < NumColumns; i++)
{
topPosArray.append(Array(count:NumRows, repeatedValue:Double()))
topLoadArray.append(Array(count:NumRows, repeatedValue:Double()))
}
var loadBefore:Double;
var loadAfter:Double;
var loadBefore3:Double;
var loadAfter3:Double;
var dt:Double; //delta T for measurements
var tubingHeadPressure:Double; //Tubing Head Pressure (PSI)
var fluidGradient:Double; //Tubing Fluid Gradient (PSI/ft)
var sbfriction:Double; //Stuffing Box Friction (lbs)
var numTapers:Int; //Number of Rod String Tapers
var nT1:Int; //number of tapers + 1
var anchorDepth:Double;
var pumpDiameter:Double;
var pumpArea:Double;
var tubingID:Double;
var tubingOD:Double;
var tubingCrossSectionalArea:Double;
var frictionEstimate:Double;
var theoreticalMaxFluidLoad:Double;
var structuralRating:Double;
//arrays of size nT1 due to addresses starting at 0
//Rod String Inputs
var c = [Double](count: 11, repeatedValue: 0.0); //User-Defined damping constant per taper (1/sec)
var rodLength = [Double](count: 11, repeatedValue: 0.0); //Length of each rod taper (top to bottom)(ft)
var rodDiameter = [Double](count: 11, repeatedValue: 0.0); //Diameter of each rod taper (top to bottom)(in)
var rodYM = [Double](count: 11, repeatedValue: 0.0); //Youngs modulus of each rod taper (top to bottom)(PSI) Steel=30.5, fiberglass=7.2
var rodWeightPerFoot = [Double](count: 11, repeatedValue: 0.0); //Weight per foot of each rod (ft/lb)
var a = [Double](count: 11, repeatedValue: 0.0);
var area = [Double](count: 12, repeatedValue: 0.0);
var pressure = [Double](count: 11, repeatedValue: 0.0);
var buoyantForce = [Double](count: 11, repeatedValue: 0.0);
var buoyantForceTotal:Double;
var stretch = [Double](count: 11, repeatedValue: 0.0);
var weightData = [Double](count: 11, repeatedValue: 0.0);
var weightDataTotal:Double;
var annularForceData = [Double](count: 11, repeatedValue: 0.0);
var annularForceDataTotal:Double;
var force = [Double](count: 11, repeatedValue: 0.0);
var alpha = [Double](count: 11, repeatedValue: 0.0);
var xOverA = [Double](count: 11, repeatedValue: 0.0);
var factorArray = [Double](count: 11, repeatedValue: 0);
var lagIndexArray = [Int](count: 11, repeatedValue: 0);
var centerPoint = [Int](count: 11, repeatedValue: 0);
var sumCenterPoint = [Int](count: 11, repeatedValue: 0);
var lengthRequired = [Int](count: 11, repeatedValue: 0);
var rodDepth = [Double](count: 11, repeatedValue: 0.0);
var rodDepthTotal:Double;
var rodWeightAir = [Double](count: 11, repeatedValue: 0.0);
var rodWeightAirTotal:Double;
var rodWeightFluid = [Double](count: 11, repeatedValue: 0.0);
var rodWeightFluidTotal:Double;
var count = [Int](count: 11, repeatedValue: 0);
var sPositionPrevious:Double;
func printTaperSetup()
//prints the current taper setup to the console
//TODO: update this to print to a file.
{
println("Taper Parameters");
println(NSString(format: "dt: %.2f", dt))
println(NSString(format: "tubingHeadPressure: %.2f", tubingHeadPressure))
println(NSString(format: "fluidGradient: %.2f", fluidGradient))
println(NSString(format: "sbfriction: %.2f", sbfriction))
println(NSString(format: "numTapers: %.2f", numTapers))
println("c:")
dump(c);
println("rodLength:")
dump(rodLength)
println("rodDiameter:")
dump(rodDiameter);
println("rodYM:")
dump(rodYM);
println("rodWeightPerFoot:")
dump(rodWeightPerFoot)
println("a:");
dump(a);
println("area:")
dump(area)
println("pressure:")
dump(pressure)
println("buoyantForce:")
dump(buoyantForce)
println("stretch")
dump(stretch)
println("weightData")
dump(weightData)
println("annularForceData:")
dump(annularForceData)
println("force:")
dump(force)
println("alpha:")
dump(alpha)
println("xOverA:")
dump(xOverA)
println("factorArray")
dump(factorArray)
println("lagIndexArray")
dump(lagIndexArray)
println("centerPoint:")
dump(centerPoint)
println("sumCenterPoint:")
dump(sumCenterPoint)
println("lengthRequired:")
dump(lengthRequired)
println("rodDepth")
dump(rodDepth)
println("rodWeightAir")
dump(rodWeightAir)
println("rodWeightFluid")
dump(rodWeightFluid)
println(NSString(format: "buoyantForceTotal: %.2f", buoyantForceTotal))
println(NSString(format: "weightDataTotal: %.2f", weightDataTotal))
println(NSString(format: "annularForceDataTotal: %.2f", annularForceDataTotal))
println(NSString(format: "rodDepthTotal: %.2f", rodDepthTotal))
println(NSString(format: "rodWeightAirTotal: %.2f", rodWeightAirTotal))
println(NSString(format: "rodWeightFluidTotal: %.2f", rodWeightFluidTotal))
println(NSString(format: "tubingID: %.2f", tubingID))
println(NSString(format: "tubingOD: %.2f", tubingOD))
println(NSString(format: "tubingCSA: %.2f", tubingCrossSectionalArea))
println(NSString(format: "structuralRating: %.2f", structuralRating))
}
func lookupRodWeightPerFoot(i_ym:Double, i_diam:Double) -> Double
//looks up rod Weight per foot
{
var wtPerFt:Double;
if (i_ym == 30.5)
{
if (i_diam <= 2 && i_diam > 1.75)
{
wtPerFt = 10.7;
}
else if (i_diam <= 1.75 && i_diam > 1.65)
{
wtPerFt = 8.2;
}
else if (i_diam <= 1.65 && i_diam > 1.5)
{
wtPerFt = 7;
}
else if (i_diam <= 1.5 && i_diam > 1.375)
{
wtPerFt = 6;
}
else if (i_diam <= 1.375 && i_diam > 1.125)
{
wtPerFt = 5;
}
else if (i_diam <= 1.125 && i_diam > 1)
{
wtPerFt = 3.676;
}
else if (i_diam <= 1 && i_diam > 0.875)
{
wtPerFt = 2.904;
}
else if (i_diam <= 0.875 && i_diam > 0.75)
{
wtPerFt = 2.224;
}
else if (i_diam <= 0.75 && i_diam > 0.625)
{
wtPerFt = 1.634;
}
else if (i_diam <= 0.625 && i_diam > 0.5)
{
wtPerFt = 1.13;
}
else if (i_diam <= 0.5)
{
wtPerFt = 0.72;
}
else
{
wtPerFt = 0;
}
}
else if (i_ym == 7.2)
{
if (i_diam <= 1.25 && i_diam > 1.125)
{
wtPerFt = 1.2879;
}
else if (i_diam <= 1.125 && i_diam > 1)
{
wtPerFt = 1.09;
}
else if (i_diam <= 1 && i_diam > 0.875)
{
wtPerFt = 0.8188;
}
else if (i_diam <= 0.875 && i_diam > 0.75)
{
wtPerFt = 0.6108;
}
else if (i_diam <= 0.75)
{
wtPerFt = 0.484;
}
else
{
wtPerFt = 0;
}
}
else
{
wtPerFt = 0;
}
return wtPerFt;
}
init(){
}
// func readTaperCSV(filename:String)
// //reads the rod string configuration from a CSV
// {
//
// let csvURL = NSURL(string: "/Users/patrickjmcd/wellParamsIn_1.csv")!
// var error: NSErrorPointer = nil
// let csv = CSV(contentsOfURL: csvURL, error: error)
//
// // Rows
// let rows = csv.rows
//
// for(var row in csv.rows){
//
// }
// Float parseFloat(std::string dblStr);
// Float parseFloatString(Float *arr, std::string dblStr, int len, char delim );
//
// std::ifstream file (filename.c_str());
//
// while ( file.good() )
// {
// std::string key;
// std::string value;
// getline( file, key, ',' );
// getline( file, value, '\n');
//
// if(key.compare("dt")==0){
// dt = parseFloat(value);
// }
// else if (key.compare("tubingHeadPressure")==0)
// {
// tubingHeadPressure = parseFloat(value);
// }
// else if (key.compare("fluidGradient")==0)
// {
// fluidGradient = parseFloat(value);
// }
// else if (key.compare("sbfriction")==0)
// {
// sbfriction = parseFloat(value);
// }
// else if (key.compare("tubingID")==0)
// {
// tubingID = parseFloat(value);
// }
// else if (key.compare("tubingOD")==0)
// {
// tubingOD = parseFloat(value);
// }
// else if (key.compare("numTapers")==0)
// {
// std::istringstream(value) >> numTapers;
// }
// else if (key.compare("anchorDepth")==0)
// {
// anchorDepth = parseFloat(value);
// }
// else if (key.compare("pumpDiameter")==0)
// {
// pumpDiameter = parseFloat(value);
// pumpArea = pow(pumpDiameter,2) * M_PI;
// }
// else if (key.compare("structuralRating")==0)
// {
// structuralRating = parseFloat(value);
// }
// else if (key.compare("c")==0)
// {
// parseFloatString(c, value, 10, '&');
//}
//else if (key.compare("rodLength")==0)
//{
// parseFloatString(rodLength, value, 10, '&');
//}
//else if (key.compare("rodDiameter")==0)
//{
// parseFloatString(rodDiameter, value, 10, '&');
//}
//else if (key.compare("rodYM")==0)
//{
// parseFloatString(rodYM, value, 10, '&');
//}
//}
}
var well:Well;
well.printTaperSetup();
println(well.numTapers);

View File

@@ -0,0 +1,3 @@
//
// This file (and all other Swift source files in the Sources directory of this playground) will be precompiled into a framework which is automatically made available to TestPlayground.playground.
//

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='ios' auto-termination-delay='9'/>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:../../Dropbox (Henry Pump)/Patrick McDonagh/POC/Swift POC/TestPlayground.playground">
</FileRef>
</Workspace>

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
<false/>
<key>IDESourceControlProjectIdentifier</key>
<string>EDEEFAB5-5519-4B14-9908-8C3055C0C758</string>
<key>IDESourceControlProjectName</key>
<string>playground</string>
<key>IDESourceControlProjectOriginsDictionary</key>
<dict>
<key>7BF837D10FB421D5AEF1283459C27C2BF38FFB44</key>
<string>http://192.168.2.45/Bonobo.Git.Server/Swift_POC.git</string>
</dict>
<key>IDESourceControlProjectPath</key>
<string>TestPlayground.playground/playground.xcworkspace</string>
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
<dict>
<key>7BF837D10FB421D5AEF1283459C27C2BF38FFB44</key>
<string>../..</string>
</dict>
<key>IDESourceControlProjectURL</key>
<string>http://192.168.2.45/Bonobo.Git.Server/Swift_POC.git</string>
<key>IDESourceControlProjectVersion</key>
<integer>111</integer>
<key>IDESourceControlProjectWCCIdentifier</key>
<string>7BF837D10FB421D5AEF1283459C27C2BF38FFB44</string>
<key>IDESourceControlProjectWCConfigurations</key>
<array>
<dict>
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
<string>public.vcs.git</string>
<key>IDESourceControlWCCIdentifierKey</key>
<string>7BF837D10FB421D5AEF1283459C27C2BF38FFB44</string>
<key>IDESourceControlWCCName</key>
<string>Swift%20POC</string>
</dict>
</array>
</dict>
</plist>

34
wellParamsIn_1.csv Normal file
View File

@@ -0,0 +1,34 @@
dt,0.06
tubingHeadPressure,200
fluidGradient,0.45
sbfriction,300
numTapers,2
c,0&0.08&0.08&0&0&0&0&0&0&0&
rodLength,0&10095&300&0&0&0&0&0&0&0&
rodDiameter,0&0.75&1.5&0&0&0&0&0&0&0&
rodYM,0&30.5&30.5&0&0&0&0&0&0&0&
rodWeightPerFoot,0&1.634&6&0&0&0&0&0&0&0&
a,0&16295.1376523724&17007.4197367572&0&0&0&0&0&0&0&
area,0&0.441786466911065&1.76714586764426&0&0&0&0&0&0&0&0&
pressure,200&200&200&0&0&0&0&0&0&0&
buoyantForce,0&265.071880146639&-353.429173528852&0&0&0&0&0&0&0&
buoyantForceTotal,-2510.562045
stretch,0&0&0&0&0&0&0&0&0&0&
weightData,0&1800&0&0&0&0&0&0&0&0&
weightDataTotal,1800
annularForceData,0&-6815.99205812064&0&0&0&0&0&0&0&0&
annularForceDataTotal,-19652.76053
force,0&0&-353.429173528852&0&0&0&0&0&0&0&
alpha,0&0&-6.55737704918033E-06&0&0&0&0&0&0&0&
xOverA,0&0&0&0&0&0&0&0&0&0&
factorArray,0&0&0&0&0&0&0&0&0&0&
lagIndexArray,0&0&0&0&0&0&0&0&0&0&
centerPoint,0&2&2&0&0&0&0&0&0&0&
sumCenterPoint,0&2&0&0&0&0&0&0&0&0&
lengthRequired,0&3&3&0&0&0&0&0&0&0&
rodDepth,0&0&0&0&0&0&0&0&0&0&
rodDepthTotal,10395
rodWeightAir,0&0&0&0&0&0&0&0&0&0&
rodWeightAirTotal,18295.23
rodWeightFluid,0&265.071880146639&-353.429173528852&0&0&0&0&0&0&0&
rodWeightFluidTotal,-176.7145868
1 dt 0.06
2 tubingHeadPressure 200
3 fluidGradient 0.45
4 sbfriction 300
5 numTapers 2
6 c 0&0.08&0.08&0&0&0&0&0&0&0&
7 rodLength 0&10095&300&0&0&0&0&0&0&0&
8 rodDiameter 0&0.75&1.5&0&0&0&0&0&0&0&
9 rodYM 0&30.5&30.5&0&0&0&0&0&0&0&
10 rodWeightPerFoot 0&1.634&6&0&0&0&0&0&0&0&
11 a 0&16295.1376523724&17007.4197367572&0&0&0&0&0&0&0&
12 area 0&0.441786466911065&1.76714586764426&0&0&0&0&0&0&0&0&
13 pressure 200&200&200&0&0&0&0&0&0&0&
14 buoyantForce 0&265.071880146639&-353.429173528852&0&0&0&0&0&0&0&
15 buoyantForceTotal -2510.562045
16 stretch 0&0&0&0&0&0&0&0&0&0&
17 weightData 0&1800&0&0&0&0&0&0&0&0&
18 weightDataTotal 1800
19 annularForceData 0&-6815.99205812064&0&0&0&0&0&0&0&0&
20 annularForceDataTotal -19652.76053
21 force 0&0&-353.429173528852&0&0&0&0&0&0&0&
22 alpha 0&0&-6.55737704918033E-06&0&0&0&0&0&0&0&
23 xOverA 0&0&0&0&0&0&0&0&0&0&
24 factorArray 0&0&0&0&0&0&0&0&0&0&
25 lagIndexArray 0&0&0&0&0&0&0&0&0&0&
26 centerPoint 0&2&2&0&0&0&0&0&0&0&
27 sumCenterPoint 0&2&0&0&0&0&0&0&0&0&
28 lengthRequired 0&3&3&0&0&0&0&0&0&0&
29 rodDepth 0&0&0&0&0&0&0&0&0&0&
30 rodDepthTotal 10395
31 rodWeightAir 0&0&0&0&0&0&0&0&0&0&
32 rodWeightAirTotal 18295.23
33 rodWeightFluid 0&265.071880146639&-353.429173528852&0&0&0&0&0&0&0&
34 rodWeightFluidTotal -176.7145868