From 8b3911d7286963da2768e1bb3576ec0781ec75da Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Fri, 1 Jul 2016 17:00:11 -0500 Subject: [PATCH] Initial Commit --- HP_POC.swift | 746 +++++++++++++++++ POC.playground/Contents.swift | 760 ++++++++++++++++++ POC.playground/Sources/SupportCode.swift | 3 + POC.playground/contents.xcplayground | 4 + .../contents.xcworkspacedata | 7 + .../xcshareddata/playground.xccheckout | 41 + .../UserInterfaceState.xcuserstate | Bin 0 -> 7508 bytes POC.playground/timeline.xctimeline | 6 + TestPlayground.playground/Contents.swift | 755 +++++++++++++++++ .../Sources/SupportCode.swift | 3 + .../contents.xcplayground | 2 + .../contents.xcworkspacedata | 7 + .../xcshareddata/playground.xccheckout | 41 + .../UserInterfaceState.xcuserstate | Bin 0 -> 9256 bytes wellParamsIn_1.csv | 34 + 15 files changed, 2409 insertions(+) create mode 100644 HP_POC.swift create mode 100644 POC.playground/Contents.swift create mode 100644 POC.playground/Sources/SupportCode.swift create mode 100644 POC.playground/contents.xcplayground create mode 100644 POC.playground/playground.xcworkspace/contents.xcworkspacedata create mode 100644 POC.playground/playground.xcworkspace/xcshareddata/playground.xccheckout create mode 100644 POC.playground/playground.xcworkspace/xcuserdata/patrickjmcd.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 POC.playground/timeline.xctimeline create mode 100644 TestPlayground.playground/Contents.swift create mode 100644 TestPlayground.playground/Sources/SupportCode.swift create mode 100644 TestPlayground.playground/contents.xcplayground create mode 100644 TestPlayground.playground/playground.xcworkspace/contents.xcworkspacedata create mode 100644 TestPlayground.playground/playground.xcworkspace/xcshareddata/playground.xccheckout create mode 100644 TestPlayground.playground/playground.xcworkspace/xcuserdata/patrickjmcd.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 wellParamsIn_1.csv diff --git a/HP_POC.swift b/HP_POC.swift new file mode 100644 index 0000000..5f6988a --- /dev/null +++ b/HP_POC.swift @@ -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>(); + var topLoadArray = Array>(); + + 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, '&'); + //} + //} +} + + + + diff --git a/POC.playground/Contents.swift b/POC.playground/Contents.swift new file mode 100644 index 0000000..0cf96f6 --- /dev/null +++ b/POC.playground/Contents.swift @@ -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>(); + var topLoadArray = Array>(); + + 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); + + + + + + diff --git a/POC.playground/Sources/SupportCode.swift b/POC.playground/Sources/SupportCode.swift new file mode 100644 index 0000000..03c80fc --- /dev/null +++ b/POC.playground/Sources/SupportCode.swift @@ -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. +// diff --git a/POC.playground/contents.xcplayground b/POC.playground/contents.xcplayground new file mode 100644 index 0000000..06828af --- /dev/null +++ b/POC.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/POC.playground/playground.xcworkspace/contents.xcworkspacedata b/POC.playground/playground.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..71c1740 --- /dev/null +++ b/POC.playground/playground.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/POC.playground/playground.xcworkspace/xcshareddata/playground.xccheckout b/POC.playground/playground.xcworkspace/xcshareddata/playground.xccheckout new file mode 100644 index 0000000..73ae620 --- /dev/null +++ b/POC.playground/playground.xcworkspace/xcshareddata/playground.xccheckout @@ -0,0 +1,41 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + F63752C8-BC3A-4E8B-83CF-87055B0E471D + IDESourceControlProjectName + playground + IDESourceControlProjectOriginsDictionary + + 7BF837D10FB421D5AEF1283459C27C2BF38FFB44 + http://192.168.2.45/Bonobo.Git.Server/Swift_POC.git + + IDESourceControlProjectPath + POC.playground/playground.xcworkspace + IDESourceControlProjectRelativeInstallPathDictionary + + 7BF837D10FB421D5AEF1283459C27C2BF38FFB44 + ../.. + + IDESourceControlProjectURL + http://192.168.2.45/Bonobo.Git.Server/Swift_POC.git + IDESourceControlProjectVersion + 111 + IDESourceControlProjectWCCIdentifier + 7BF837D10FB421D5AEF1283459C27C2BF38FFB44 + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + 7BF837D10FB421D5AEF1283459C27C2BF38FFB44 + IDESourceControlWCCName + Swift%20POC + + + + diff --git a/POC.playground/playground.xcworkspace/xcuserdata/patrickjmcd.xcuserdatad/UserInterfaceState.xcuserstate b/POC.playground/playground.xcworkspace/xcuserdata/patrickjmcd.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..484dd60efd4d586bfc28dd01fb42adde98455ee4 GIT binary patch literal 7508 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 bzn0&VKbHR(=40S}YWRoki+o1^%YXV0b>$g@ literal 0 HcmV?d00001 diff --git a/POC.playground/timeline.xctimeline b/POC.playground/timeline.xctimeline new file mode 100644 index 0000000..bf468af --- /dev/null +++ b/POC.playground/timeline.xctimeline @@ -0,0 +1,6 @@ + + + + + diff --git a/TestPlayground.playground/Contents.swift b/TestPlayground.playground/Contents.swift new file mode 100644 index 0000000..008ce66 --- /dev/null +++ b/TestPlayground.playground/Contents.swift @@ -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>(); + var topLoadArray = Array>(); + + 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); + + + + + + diff --git a/TestPlayground.playground/Sources/SupportCode.swift b/TestPlayground.playground/Sources/SupportCode.swift new file mode 100644 index 0000000..e258b50 --- /dev/null +++ b/TestPlayground.playground/Sources/SupportCode.swift @@ -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. +// diff --git a/TestPlayground.playground/contents.xcplayground b/TestPlayground.playground/contents.xcplayground new file mode 100644 index 0000000..da0a4a6 --- /dev/null +++ b/TestPlayground.playground/contents.xcplayground @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/TestPlayground.playground/playground.xcworkspace/contents.xcworkspacedata b/TestPlayground.playground/playground.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..24d38f8 --- /dev/null +++ b/TestPlayground.playground/playground.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/TestPlayground.playground/playground.xcworkspace/xcshareddata/playground.xccheckout b/TestPlayground.playground/playground.xcworkspace/xcshareddata/playground.xccheckout new file mode 100644 index 0000000..cb9681e --- /dev/null +++ b/TestPlayground.playground/playground.xcworkspace/xcshareddata/playground.xccheckout @@ -0,0 +1,41 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + EDEEFAB5-5519-4B14-9908-8C3055C0C758 + IDESourceControlProjectName + playground + IDESourceControlProjectOriginsDictionary + + 7BF837D10FB421D5AEF1283459C27C2BF38FFB44 + http://192.168.2.45/Bonobo.Git.Server/Swift_POC.git + + IDESourceControlProjectPath + TestPlayground.playground/playground.xcworkspace + IDESourceControlProjectRelativeInstallPathDictionary + + 7BF837D10FB421D5AEF1283459C27C2BF38FFB44 + ../.. + + IDESourceControlProjectURL + http://192.168.2.45/Bonobo.Git.Server/Swift_POC.git + IDESourceControlProjectVersion + 111 + IDESourceControlProjectWCCIdentifier + 7BF837D10FB421D5AEF1283459C27C2BF38FFB44 + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + 7BF837D10FB421D5AEF1283459C27C2BF38FFB44 + IDESourceControlWCCName + Swift%20POC + + + + diff --git a/TestPlayground.playground/playground.xcworkspace/xcuserdata/patrickjmcd.xcuserdatad/UserInterfaceState.xcuserstate b/TestPlayground.playground/playground.xcworkspace/xcuserdata/patrickjmcd.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..d14b414bfdd0084fa31005a1eaae7d4b4fa56e37 GIT binary patch literal 9256 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 literal 0 HcmV?d00001 diff --git a/wellParamsIn_1.csv b/wellParamsIn_1.csv new file mode 100644 index 0000000..870418c --- /dev/null +++ b/wellParamsIn_1.csv @@ -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