61 lines
2.4 KiB
Swift
61 lines
2.4 KiB
Swift
import Dependencies
|
|
import Foundation
|
|
import ManualDCore
|
|
|
|
extension ManualDClient: DependencyKey {
|
|
public static let liveValue: Self = .init(
|
|
ductSize: { request in
|
|
guard request.designCFM > 0 else {
|
|
throw ManualDError(message: "Design CFM should be greater than 0.")
|
|
}
|
|
let fr = pow(request.frictionRate, 0.5)
|
|
let ductulatorSize = pow(Double(request.designCFM) / (3.12 * fr), 0.38)
|
|
let finalSize = try roundSize(ductulatorSize)
|
|
let flexSize = try flexSize(request)
|
|
return .init(
|
|
ductulatorSize: ductulatorSize,
|
|
finalSize: finalSize,
|
|
flexSize: flexSize,
|
|
velocity: velocity(cfm: request.designCFM, roundSize: finalSize)
|
|
)
|
|
},
|
|
frictionRate: { request in
|
|
// Ensure the total effective length is greater than 0.
|
|
guard request.totalEffectiveLength > 0 else {
|
|
throw ManualDError(message: "Total Effective Length should be greater than 0.")
|
|
}
|
|
|
|
let totalComponentLosses = request.componentPressureLosses.totalLosses
|
|
let availableStaticPressure = request.externalStaticPressure - totalComponentLosses
|
|
let frictionRate = availableStaticPressure * 100.0 / Double(request.totalEffectiveLength)
|
|
return .init(availableStaticPressure: availableStaticPressure, frictionRate: frictionRate)
|
|
},
|
|
totalEffectiveLength: { request in
|
|
let trunkLengths = request.trunkLengths.reduce(0) { $0 + $1 }
|
|
let runoutLengths = request.runoutLengths.reduce(0) { $0 + $1 }
|
|
let groupLengths = request.effectiveLengthGroups.totalEffectiveLength
|
|
return trunkLengths + runoutLengths + groupLengths
|
|
},
|
|
equivalentRectangularDuct: { request in
|
|
let width = (Double.pi * (pow(Double(request.roundSize) / 2.0, 2.0))) / Double(request.height)
|
|
// Round the width up or fail (really should never fail since we know the input is a number).
|
|
guard let widthStr = numberFormatter.string(for: width),
|
|
let widthInt = Int(widthStr)
|
|
else {
|
|
throw ManualDError(
|
|
message: "Failed to convert to to rectangular duct size, width: \(width)"
|
|
)
|
|
}
|
|
return .init(height: request.height, width: widthInt)
|
|
}
|
|
)
|
|
}
|
|
|
|
private let numberFormatter: NumberFormatter = {
|
|
let formatter = NumberFormatter()
|
|
formatter.maximumFractionDigits = 0
|
|
formatter.minimumFractionDigits = 0
|
|
formatter.roundingMode = .ceiling
|
|
return formatter
|
|
}()
|