feat: Initial interpolation calculations, requires tests.
This commit is contained in:
@@ -32,3 +32,14 @@ private struct OptionalContainerValidator: AsyncValidation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension Capacity.ManufacturersContainer: AsyncValidatable {
|
||||||
|
public var body: some AsyncValidation<Self> {
|
||||||
|
AsyncValidator.accumulating {
|
||||||
|
AsyncValidator.greaterThan(\.wetBulb, 0)
|
||||||
|
AsyncValidator.greaterThan(\.totalCapacity, 0)
|
||||||
|
AsyncValidator.greaterThan(\.sensibleCapacity, 0)
|
||||||
|
AsyncValidator.greaterThanOrEquals(\.totalCapacity, \.sensibleCapacity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,89 +4,375 @@ import Validations
|
|||||||
extension Interpolate.Request {
|
extension Interpolate.Request {
|
||||||
func respond() async throws -> Interpolate.Response {
|
func respond() async throws -> Interpolate.Response {
|
||||||
try await validate()
|
try await validate()
|
||||||
fatalError()
|
let interpolatedCapacity = await interpolation.interpolatedCapacity(
|
||||||
|
outdoorDesignTemperature: designInfo.summer.outdoorTemperature
|
||||||
|
)
|
||||||
|
let excessLatent = self.excessLatent(interpolatedLatent: interpolatedCapacity.latent)
|
||||||
|
let elevationDeratings = try await Derating.Request(
|
||||||
|
elevation: designInfo.elevation,
|
||||||
|
systemType: systemType
|
||||||
|
).respond()
|
||||||
|
|
||||||
|
let sizingLimits = try await SizingLimits.Request(
|
||||||
|
systemType: systemType,
|
||||||
|
houseLoad: houseLoad
|
||||||
|
).respond()
|
||||||
|
|
||||||
|
let finalCapacity = interpolatedCapacity
|
||||||
|
.applying(excessLatent: excessLatent)
|
||||||
|
.applying(adjustmentMultipliers: interpolation.adjustmentMultipliers)
|
||||||
|
.applying(adjustmentMultipliers: elevationDeratings)
|
||||||
|
|
||||||
|
let capacityAsPercentOfLoad = Capacity.Cooling(
|
||||||
|
total: normalizePercentage(finalCapacity.total, houseLoad.coolingTotal),
|
||||||
|
sensible: normalizePercentage(finalCapacity.sensible, houseLoad.coolingSensible),
|
||||||
|
latent: normalizePercentage(finalCapacity.latent, houseLoad.coolingLatent)
|
||||||
|
)
|
||||||
|
|
||||||
|
return .init(
|
||||||
|
failures: sizingLimits.validate(capacityAsPercentOfLoad: capacityAsPercentOfLoad),
|
||||||
|
interpolatedCapacity: interpolatedCapacity,
|
||||||
|
excessLatent: excessLatent,
|
||||||
|
finalCapacityAtDesign: finalCapacity,
|
||||||
|
altitudeDerating: elevationDeratings,
|
||||||
|
capacityAsPercentOfLoad: capacityAsPercentOfLoad,
|
||||||
|
sizingLimits: sizingLimits
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private extension SizingLimits.Response {
|
||||||
|
|
||||||
|
func validate(capacityAsPercentOfLoad: Capacity.Cooling) -> [String]? {
|
||||||
|
var failures = [String]()
|
||||||
|
|
||||||
|
// Check oversizing limits.
|
||||||
|
if capacityAsPercentOfLoad.total > oversizing.coolingTotal {
|
||||||
|
failures.append(
|
||||||
|
"Oversizing total failure."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if let coolingLatent = oversizing.coolingLatent,
|
||||||
|
capacityAsPercentOfLoad.latent > coolingLatent
|
||||||
|
{
|
||||||
|
failures.append(
|
||||||
|
"Oversizing latent failure."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if capacityAsPercentOfLoad.total < undersizing.coolingTotal {
|
||||||
|
failures.append(
|
||||||
|
"Undersizing total failure."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if let coolingSensible = undersizing.coolingSensible,
|
||||||
|
capacityAsPercentOfLoad.sensible < coolingSensible
|
||||||
|
{
|
||||||
|
failures.append(
|
||||||
|
"Undersizing sensible failure."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if let coolingLatent = undersizing.coolingLatent,
|
||||||
|
capacityAsPercentOfLoad.latent < coolingLatent
|
||||||
|
{
|
||||||
|
failures.append(
|
||||||
|
"Undersizing latent failure."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return failures.isEmpty ? nil : failures
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func normalizePercentage(
|
||||||
|
_ lhs: Int,
|
||||||
|
_ rhs: Int
|
||||||
|
) -> Int {
|
||||||
|
let value = Double(lhs) / Double(rhs)
|
||||||
|
return Int((value * 1000).rounded() / 10.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension Capacity.Cooling {
|
||||||
|
func applying(excessLatent: Int) -> Self {
|
||||||
|
.init(total: total, sensible: sensible + excessLatent)
|
||||||
|
}
|
||||||
|
|
||||||
|
func applying(adjustmentMultipliers: AdjustmentMultiplier?) -> Self {
|
||||||
|
guard let adjustmentMultipliers else { return self }
|
||||||
|
|
||||||
|
return .init(
|
||||||
|
total: Int(Double(total) * (adjustmentMultipliers.coolingTotal ?? 1)),
|
||||||
|
sensible: Int(Double(sensible) * (adjustmentMultipliers.coolingSensible ?? 1))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension Interpolate.Request {
|
||||||
|
|
||||||
|
func excessLatent(interpolatedLatent: Int) -> Int {
|
||||||
|
(interpolatedLatent - houseLoad.coolingLatent) / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension Interpolate.InterpolationRequest {
|
||||||
|
|
||||||
|
func interpolatedCapacity(outdoorDesignTemperature: Int) async -> Capacity.Cooling {
|
||||||
|
switch self {
|
||||||
|
case let .noInterpolation(request, _):
|
||||||
|
return .init(total: request.capacity.totalCapacity, sensible: request.capacity.sensibleCapacity)
|
||||||
|
case let .oneWayIndoor(request):
|
||||||
|
return await request.interpolatedCapacity()
|
||||||
|
case let .oneWayOutdoor(request):
|
||||||
|
return await request.interpolatedCapacity(outdoorDesignTemperature: outdoorDesignTemperature)
|
||||||
|
case let .twoWay(request):
|
||||||
|
return await request.interpolatedCapacity(outdoorDesignTemperature: outdoorDesignTemperature)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var adjustmentMultipliers: AdjustmentMultiplier? {
|
||||||
|
switch self {
|
||||||
|
case let .noInterpolation(_, adjustmentMultipliers):
|
||||||
|
return adjustmentMultipliers
|
||||||
|
case let .oneWayIndoor(request):
|
||||||
|
return request.adjustmentMultipliers
|
||||||
|
case let .oneWayOutdoor(request):
|
||||||
|
return request.adjustmentMultipliers
|
||||||
|
case let .twoWay(request):
|
||||||
|
return request.adjustmentMultipliers
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func interpolateIndoorCapacity(
|
||||||
|
above: Capacity.ManufacturersContainer,
|
||||||
|
below: Capacity.ManufacturersContainer
|
||||||
|
) async -> Capacity.Cooling {
|
||||||
|
let total = Double(below.totalCapacity)
|
||||||
|
+ (
|
||||||
|
Double(above.totalCapacity - below.totalCapacity)
|
||||||
|
/ Double(above.wetBulb - below.wetBulb)
|
||||||
|
)
|
||||||
|
* Double(63 - below.wetBulb)
|
||||||
|
|
||||||
|
let sensible = Double(below.sensibleCapacity)
|
||||||
|
+ Double(above.sensibleCapacity - below.sensibleCapacity)
|
||||||
|
/ Double(below.totalCapacity - above.totalCapacity)
|
||||||
|
* Double(below.totalCapacity)
|
||||||
|
- total
|
||||||
|
|
||||||
|
return .init(total: Int(total), sensible: Int(sensible))
|
||||||
|
}
|
||||||
|
|
||||||
|
private func interpolateOutdoorCapacity(
|
||||||
|
outdoorDesignTemperature: Int,
|
||||||
|
aboveCapacity: Int,
|
||||||
|
aboveOutdoorTemperature: Int,
|
||||||
|
belowCapacity: Int,
|
||||||
|
belowOutdoorTemperature: Int
|
||||||
|
) async -> Int {
|
||||||
|
return belowCapacity
|
||||||
|
- (outdoorDesignTemperature - belowOutdoorTemperature)
|
||||||
|
* ((belowCapacity - aboveCapacity) / (aboveOutdoorTemperature - belowOutdoorTemperature))
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension Interpolate.OneWayIndoor {
|
||||||
|
|
||||||
|
func interpolatedCapacity() async -> Capacity.Cooling {
|
||||||
|
return await interpolateIndoorCapacity(
|
||||||
|
above: capacities.aboveDewpoint,
|
||||||
|
below: capacities.belowDewpoint
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension Interpolate.OneWayOutdoor {
|
||||||
|
func interpolatedCapacity(outdoorDesignTemperature: Int) async -> Capacity.Cooling {
|
||||||
|
let total = await interpolate(
|
||||||
|
outdoorDesignTemperature: outdoorDesignTemperature,
|
||||||
|
aboveCapacity: \.totalCapacity,
|
||||||
|
belowCapacity: \.totalCapacity
|
||||||
|
)
|
||||||
|
let sensible = await interpolate(
|
||||||
|
outdoorDesignTemperature: outdoorDesignTemperature,
|
||||||
|
aboveCapacity: \.sensibleCapacity,
|
||||||
|
belowCapacity: \.sensibleCapacity
|
||||||
|
)
|
||||||
|
|
||||||
|
return .init(total: total, sensible: sensible)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func interpolate(
|
||||||
|
outdoorDesignTemperature: Int,
|
||||||
|
aboveCapacity: KeyPath<Interpolate.OneWayOutdoor.Capacities.Capacity, Int>,
|
||||||
|
belowCapacity: KeyPath<Interpolate.OneWayOutdoor.Capacities.Capacity, Int>,
|
||||||
|
) async -> Int {
|
||||||
|
return await interpolateOutdoorCapacity(
|
||||||
|
outdoorDesignTemperature: outdoorDesignTemperature,
|
||||||
|
aboveCapacity: capacities.aboveOutdoor[keyPath: aboveCapacity],
|
||||||
|
aboveOutdoorTemperature: capacities.aboveOutdoor.outdoorTemperature,
|
||||||
|
belowCapacity: capacities.belowOutdoor[keyPath: belowCapacity],
|
||||||
|
belowOutdoorTemperature: capacities.belowOutdoor.outdoorTemperature
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension Interpolate.TwoWay {
|
||||||
|
|
||||||
|
func interpolatedCapacity(outdoorDesignTemperature: Int) async -> Capacity.Cooling {
|
||||||
|
let aboveIndoorInterpolation = await self.aboveIndoorInterpolation()
|
||||||
|
let belowIndoorInterpolation = await self.belowIndoorInterpolation()
|
||||||
|
return await interpolate(
|
||||||
|
outdoorDesignTemperature: outdoorDesignTemperature,
|
||||||
|
aboveIndoor: aboveIndoorInterpolation,
|
||||||
|
belowIndoor: belowIndoorInterpolation
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func interpolate(
|
||||||
|
outdoorDesignTemperature: Int,
|
||||||
|
aboveIndoor: Capacity.Cooling,
|
||||||
|
belowIndoor: Capacity.Cooling
|
||||||
|
) async -> Capacity.Cooling {
|
||||||
|
let request = Interpolate.OneWayOutdoor(
|
||||||
|
airflow: 0,
|
||||||
|
wetBulb: 63,
|
||||||
|
capacities: .init(
|
||||||
|
aboveOutdoor: .init(
|
||||||
|
outdoorTemperature: capacities.above.outdoorTemperature,
|
||||||
|
totalCapacity: aboveIndoor.total,
|
||||||
|
sensibleCapacity: aboveIndoor.sensible
|
||||||
|
),
|
||||||
|
belowOutdoor: .init(
|
||||||
|
outdoorTemperature: capacities.below.outdoorTemperature,
|
||||||
|
totalCapacity: belowIndoor.total,
|
||||||
|
sensibleCapacity: belowIndoor.sensible
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return await request.interpolatedCapacity(outdoorDesignTemperature: outdoorDesignTemperature)
|
||||||
|
}
|
||||||
|
|
||||||
|
func aboveIndoorInterpolation() async -> Capacity.Cooling {
|
||||||
|
return await interpolateIndoorCapacity(
|
||||||
|
above: capacities.above.aboveDewPoint,
|
||||||
|
below: capacities.above.belowDewPoint
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func belowIndoorInterpolation() async -> Capacity.Cooling {
|
||||||
|
return await interpolateIndoorCapacity(
|
||||||
|
above: capacities.below.aboveDewPoint,
|
||||||
|
below: capacities.below.belowDewPoint
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Validations
|
||||||
|
|
||||||
// Basic validations of the request.
|
// Basic validations of the request.
|
||||||
extension Interpolate.Request: AsyncValidatable {
|
extension Interpolate.Request: AsyncValidatable {
|
||||||
public var body: some AsyncValidation<Self> {
|
public var body: some AsyncValidation<Self> {
|
||||||
AsyncValidator.accumulating {
|
AsyncValidator.accumulating {
|
||||||
AsyncValidator.validate(\.designInfo)
|
AsyncValidator.validate(\.designInfo)
|
||||||
AsyncValidator.validate(\.houseLoad)
|
AsyncValidator.validate(\.houseLoad)
|
||||||
AsyncValidator.validate(\.manufacturersCapacity)
|
AsyncValidator.validate(\.interpolation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension Interpolate.Request {
|
extension Interpolate.InterpolationRequest: AsyncValidatable {
|
||||||
|
|
||||||
func parseInterpolationType() throws -> Interpolate.InterpolationType {
|
public typealias Value = Interpolate.InterpolationRequest
|
||||||
guard let otherCapacity = manufacturersCapacity.otherCapacity else {
|
|
||||||
let capacity = manufacturersCapacity.capacity
|
public func validate(_ value: Self) async throws {
|
||||||
guard capacity.wetBulbTemperature == 63 else {
|
switch value {
|
||||||
throw ValidationError(
|
case let .noInterpolation(request, _):
|
||||||
message: "Expected manufacturers wet bulb temperature to be 63, but found: \(capacity.wetBulbTemperature)"
|
try await request.validate()
|
||||||
)
|
case let .oneWayIndoor(request):
|
||||||
|
try await request.validate()
|
||||||
|
case let .oneWayOutdoor(request):
|
||||||
|
try await request.validate()
|
||||||
|
case let .twoWay(request):
|
||||||
|
try await request.validate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return .noInterpolation
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the
|
extension Interpolate.OneWayIndoor: AsyncValidatable {
|
||||||
fatalError()
|
public var body: some AsyncValidation<Self> {
|
||||||
|
AsyncValidator.accumulating {
|
||||||
|
AsyncValidator.greaterThan(\.airflow, 0)
|
||||||
|
AsyncValidator.greaterThan(\.outdoorTemperature, 0)
|
||||||
|
AsyncValidator.validate(\.capacities)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func checkOneWayIndoorInterpolation(
|
extension Interpolate.OneWayIndoor.Capacities: AsyncValidatable {
|
||||||
_ capacity: Capacity.ManufacturersCooling.Container,
|
public var body: some AsyncValidation<Self> {
|
||||||
_ other: Capacity.ManufacturersCooling.Container
|
AsyncValidator.accumulating {
|
||||||
) -> CapacityContainer? {
|
AsyncValidator.validate(\.aboveDewpoint)
|
||||||
// ensure outdoor temperatures match, otherwise we are not a one way indoor interpolation.
|
AsyncValidator.validate(\.belowDewpoint)
|
||||||
guard capacity.outdoorTemperature == other.outdoorTemperature else {
|
}
|
||||||
return nil
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure indoor temperatures are not the same.
|
extension Interpolate.OneWayOutdoor: AsyncValidatable {
|
||||||
guard capacity.dryBulbTemperature != other.dryBulbTemperature else {
|
public var body: some AsyncValidation<Self> {
|
||||||
return nil
|
AsyncValidator.accumulating {
|
||||||
|
AsyncValidator.greaterThan(\.airflow, 0)
|
||||||
|
AsyncValidator.greaterThan(\.wetBulb, 0)
|
||||||
|
AsyncValidator.validate(\.capacities)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if capacity.dryBulbTemperature < other.dryBulbTemperature {
|
extension Interpolate.OneWayOutdoor.Capacities: AsyncValidatable {
|
||||||
return .init(above: other, below: capacity)
|
|
||||||
|
public var body: some AsyncValidation<Self> {
|
||||||
|
AsyncValidator.accumulating {
|
||||||
|
AsyncValidator.validate(\.aboveOutdoor)
|
||||||
|
AsyncValidator.validate(\.belowOutdoor)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return .init(above: capacity, below: other)
|
extension Interpolate.OneWayOutdoor.Capacities.Capacity: AsyncValidatable {
|
||||||
|
public var body: some AsyncValidation<Self> {
|
||||||
|
AsyncValidator.accumulating {
|
||||||
|
AsyncValidator.greaterThan(\.outdoorTemperature, 0)
|
||||||
|
AsyncValidator.greaterThan(\.totalCapacity, 0)
|
||||||
|
AsyncValidator.greaterThan(\.sensibleCapacity, 0)
|
||||||
|
AsyncValidator.greaterThanOrEquals(\.totalCapacity, \.sensibleCapacity)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func checkOneWayOutdoorInterpolation(
|
extension Interpolate.TwoWay: AsyncValidatable {
|
||||||
_ capacity: Capacity.ManufacturersCooling.Container,
|
public var body: some AsyncValidation<Self> {
|
||||||
_ other: Capacity.ManufacturersCooling.Container
|
AsyncValidator.accumulating {
|
||||||
) -> CapacityContainer? {
|
AsyncValidator.greaterThan(\.airflow, 0)
|
||||||
// ensure outdoor temperatures match, otherwise we are not a one way indoor interpolation.
|
AsyncValidator.validate(\.capacities)
|
||||||
guard capacity.dryBulbTemperature == other.dryBulbTemperature else {
|
}
|
||||||
return nil
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure outdoor temperatures are not the same.
|
extension Interpolate.TwoWay.Capacities: AsyncValidatable {
|
||||||
guard capacity.outdoorTemperature != other.outdoorTemperature else {
|
public var body: some AsyncValidation<Self> {
|
||||||
return nil
|
AsyncValidator.accumulating {
|
||||||
|
AsyncValidator.validate(\.above)
|
||||||
|
AsyncValidator.validate(\.below)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if capacity.outdoorTemperature < other.outdoorTemperature {
|
extension Interpolate.TwoWay.Capacities.CapacityContainer: AsyncValidatable {
|
||||||
return .init(above: other, below: capacity)
|
public var body: some AsyncValidation<Self> {
|
||||||
|
AsyncValidator.accumulating {
|
||||||
|
AsyncValidator.validate(\.aboveDewPoint)
|
||||||
|
AsyncValidator.validate(\.belowDewPoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
return .init(above: capacity, below: other)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func checkTwoWayInterpolation(
|
|
||||||
_ capacity: Capacity.ManufacturersCooling.Container,
|
|
||||||
_ other: Capacity.ManufacturersCooling.Container
|
|
||||||
) -> CapacityContainer? {
|
|
||||||
// ensure outdoor temperatures do not match.
|
|
||||||
guard capacity.outdoorTemperature != other.outdoorTemperature else { return nil }
|
|
||||||
guard capacity.dryBulbTemperature != other.dryBulbTemperature else { return nil }
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ public enum Capacity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Remove.
|
||||||
public struct ManufacturersCooling: Codable, Equatable, Sendable {
|
public struct ManufacturersCooling: Codable, Equatable, Sendable {
|
||||||
|
|
||||||
public let airflow: Int
|
public let airflow: Int
|
||||||
@@ -87,18 +88,15 @@ public enum Capacity {
|
|||||||
public let wetBulb: Int
|
public let wetBulb: Int
|
||||||
public let totalCapacity: Int
|
public let totalCapacity: Int
|
||||||
public let sensibleCapacity: Int
|
public let sensibleCapacity: Int
|
||||||
public let adjustmentMultipliers: AdjustmentMultiplier?
|
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
wetBulb: Int,
|
wetBulb: Int,
|
||||||
totalCapacity: Int,
|
totalCapacity: Int,
|
||||||
sensibleCapacity: Int,
|
sensibleCapacity: Int
|
||||||
adjustmentMultipliers: AdjustmentMultiplier? = nil
|
|
||||||
) {
|
) {
|
||||||
self.wetBulb = wetBulb
|
self.wetBulb = wetBulb
|
||||||
self.totalCapacity = totalCapacity
|
self.totalCapacity = totalCapacity
|
||||||
self.sensibleCapacity = sensibleCapacity
|
self.sensibleCapacity = sensibleCapacity
|
||||||
self.adjustmentMultipliers = adjustmentMultipliers
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,18 +5,18 @@ public enum Interpolate {
|
|||||||
public let designInfo: DesignInfo
|
public let designInfo: DesignInfo
|
||||||
public let houseLoad: HouseLoad
|
public let houseLoad: HouseLoad
|
||||||
public let systemType: SystemType
|
public let systemType: SystemType
|
||||||
public let manufacturersCapacity: Capacity.ManufacturersCooling
|
public let interpolation: InterpolationRequest
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
designInfo: DesignInfo,
|
designInfo: DesignInfo,
|
||||||
houseLoad: HouseLoad,
|
houseLoad: HouseLoad,
|
||||||
systemType: SystemType,
|
systemType: SystemType,
|
||||||
manufacturersCapacity: Capacity.ManufacturersCooling
|
interpolation: InterpolationRequest
|
||||||
) {
|
) {
|
||||||
self.designInfo = designInfo
|
self.designInfo = designInfo
|
||||||
self.houseLoad = houseLoad
|
self.houseLoad = houseLoad
|
||||||
self.systemType = systemType
|
self.systemType = systemType
|
||||||
self.manufacturersCapacity = manufacturersCapacity
|
self.interpolation = interpolation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,7 +24,6 @@ public enum Interpolate {
|
|||||||
|
|
||||||
public let failed: Bool
|
public let failed: Bool
|
||||||
public let failures: [String]?
|
public let failures: [String]?
|
||||||
public let interpolationType: InterpolationType
|
|
||||||
public let interpolatedCapacity: Capacity.Cooling
|
public let interpolatedCapacity: Capacity.Cooling
|
||||||
public let excessLatent: Int
|
public let excessLatent: Int
|
||||||
public let finalCapacityAtDesign: Capacity.Cooling
|
public let finalCapacityAtDesign: Capacity.Cooling
|
||||||
@@ -34,7 +33,6 @@ public enum Interpolate {
|
|||||||
|
|
||||||
public init(
|
public init(
|
||||||
failures: [String]? = nil,
|
failures: [String]? = nil,
|
||||||
interpolationType: InterpolationType,
|
|
||||||
interpolatedCapacity: Capacity.Cooling,
|
interpolatedCapacity: Capacity.Cooling,
|
||||||
excessLatent: Int,
|
excessLatent: Int,
|
||||||
finalCapacityAtDesign: Capacity.Cooling,
|
finalCapacityAtDesign: Capacity.Cooling,
|
||||||
@@ -44,7 +42,6 @@ public enum Interpolate {
|
|||||||
) {
|
) {
|
||||||
self.failed = failures != nil ? failures!.count > 0 : false
|
self.failed = failures != nil ? failures!.count > 0 : false
|
||||||
self.failures = failures
|
self.failures = failures
|
||||||
self.interpolationType = interpolationType
|
|
||||||
self.interpolatedCapacity = interpolatedCapacity
|
self.interpolatedCapacity = interpolatedCapacity
|
||||||
self.excessLatent = excessLatent
|
self.excessLatent = excessLatent
|
||||||
self.finalCapacityAtDesign = finalCapacityAtDesign
|
self.finalCapacityAtDesign = finalCapacityAtDesign
|
||||||
@@ -54,10 +51,11 @@ public enum Interpolate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum InterpolationType2: Codable, Equatable, Sendable {
|
public enum InterpolationRequest: Codable, Equatable, Sendable {
|
||||||
case noInterpolation(Capacity.ManufacturersCooling)
|
case noInterpolation(Capacity.ManufacturersCooling, AdjustmentMultiplier? = nil)
|
||||||
case oneWayIndoor(OneWayIndoor)
|
case oneWayIndoor(OneWayIndoor)
|
||||||
case oneWayOutdoor(OneWayOutdoor)
|
case oneWayOutdoor(OneWayOutdoor)
|
||||||
|
case twoWay(TwoWay)
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct OneWayIndoor: Codable, Equatable, Sendable {
|
public struct OneWayIndoor: Codable, Equatable, Sendable {
|
||||||
@@ -136,13 +134,54 @@ public enum Interpolate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum InterpolationType: String, CaseIterable, Codable, Equatable, Sendable {
|
public struct TwoWay: Codable, Equatable, Sendable {
|
||||||
case noInterpolation
|
|
||||||
case oneWayIndoor
|
public let airflow: Int
|
||||||
case oneWayOutdoor
|
public let capacities: Capacities
|
||||||
case twoWay
|
public let adjustmentMultipliers: AdjustmentMultiplier?
|
||||||
|
|
||||||
|
public init(
|
||||||
|
airflow: Int,
|
||||||
|
capacities: Interpolate.TwoWay.Capacities,
|
||||||
|
adjustmentMultipliers: AdjustmentMultiplier? = nil
|
||||||
|
) {
|
||||||
|
self.airflow = airflow
|
||||||
|
self.capacities = capacities
|
||||||
|
self.adjustmentMultipliers = adjustmentMultipliers
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct Capacities: Codable, Equatable, Sendable {
|
||||||
|
|
||||||
|
public let above: CapacityContainer
|
||||||
|
public let below: CapacityContainer
|
||||||
|
|
||||||
|
public init(
|
||||||
|
above: Interpolate.TwoWay.Capacities.CapacityContainer,
|
||||||
|
below: Interpolate.TwoWay.Capacities.CapacityContainer
|
||||||
|
) {
|
||||||
|
self.above = above
|
||||||
|
self.below = below
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct CapacityContainer: Codable, Equatable, Sendable {
|
||||||
|
|
||||||
|
public let outdoorTemperature: Int
|
||||||
|
public let aboveDewPoint: Capacity.ManufacturersContainer
|
||||||
|
public let belowDewPoint: Capacity.ManufacturersContainer
|
||||||
|
|
||||||
|
public init(
|
||||||
|
outdoorTemperature: Int,
|
||||||
|
aboveDewPoint: Capacity.ManufacturersContainer,
|
||||||
|
belowDewPoint: Capacity.ManufacturersContainer
|
||||||
|
) {
|
||||||
|
self.outdoorTemperature = outdoorTemperature
|
||||||
|
self.aboveDewPoint = aboveDewPoint
|
||||||
|
self.belowDewPoint = belowDewPoint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user