MEASUR-Tools-Suite v1.0.11
The MEASUR Tools Suite is a collection of industrial efficiency calculations written in C++ and with bindings for compilation to WebAssembly.
Loading...
Searching...
No Matches
fan_affinity_laws.h
Go to the documentation of this file.
1#pragma once
2
20#include <stdexcept>
21#include <cmath>
22
24public:
25 enum MotorControlType {
26 OnOff,
27 TwoSpeed,
28 VSD,
29 None
30 };
31
32 enum FlowMode {
33 Percent,
34 Volume
35 };
36
43 struct Output {
44 Output(const double annualEnergyBaseline, const double annualEnergyNew, const double annualCostSavings)
45 : annualEnergyBaseline(annualEnergyBaseline), annualEnergyNew(annualEnergyNew), annualCostSavings(annualCostSavings) {}
46
47 const double annualEnergyBaseline, annualEnergyNew, annualCostSavings;
48 };
49
67 struct Input {
68 double electricityCost;
69 double driveEfficiency, motorEfficiency, flowPercentBaseline;
70 double operatingHours, motorPower, ratedFlow;
71 MotorControlType motorControlTypeCurrent, motorControlTypeNew;
72 FlowMode flowMode;
73 double desiredFlowRate;
74 };
75
80 FanAffinityLaws(const Input& input) : FanAffinityLaws(input.electricityCost, input.driveEfficiency, input.motorEfficiency, input.flowPercentBaseline,
81 input.operatingHours, input.motorPower, input.ratedFlow,
82 input.motorControlTypeCurrent, input.motorControlTypeNew,
83 input.flowMode, input.desiredFlowRate) {}
84
101 FanAffinityLaws(const double electricityCost,
102 const double driveEfficiency, const double motorEfficiency, const double flowPercentBaseline,
103 const double operatingHours, const double motorPower, const double ratedFlow,
104 const MotorControlType motorControlTypeCurrent, const MotorControlType motorControlTypeNew,
105 const FlowMode flowMode, const double desiredFlowRate) : electricityCost(electricityCost),
106 driveEfficiency(driveEfficiency/100), motorEfficiency(motorEfficiency/100), flowPercentBaseline(flowPercentBaseline/100),
107 operatingHours(operatingHours), motorPower(motorPower), ratedFlow(ratedFlow),
108 motorControlTypeCurrent(motorControlTypeCurrent), motorControlTypeNew(motorControlTypeNew) {
109 if (electricityCost <= 0) {
110 throw std::invalid_argument("Electricity cost must be greater than 0.");
111 }
112 if (driveEfficiency <= 0 || driveEfficiency > 100) {
113 throw std::invalid_argument("Drive efficiency must be between 0 and 100.");
114 }
115 if (motorEfficiency <= 0 || motorEfficiency > 100) {
116 throw std::invalid_argument("Motor efficiency must be between 0 and 100.");
117 }
118 if (flowPercentBaseline < 0 || flowPercentBaseline > 100) {
119 throw std::invalid_argument("Flow percent baseline must be between 0 and 100.");
120 }
121 if (operatingHours <= 0 || operatingHours > 8760) {
122 throw std::invalid_argument("Operating hours must be between 1 and 8760.");
123 }
124 if (motorPower <= 0) {
125 throw std::invalid_argument("Motor power must be greater than 0.");
126 }
127 if (ratedFlow <= 0) {
128 throw std::invalid_argument("Rated flow must be greater than 0.");
129 }
130
131 if (flowMode == Percent) {
132 if (desiredFlowRate < 0 || desiredFlowRate > 100) {
133 throw std::invalid_argument("Desired flow rate percentage must be between 0 and 100.");
134 }
135 desiredFlowPercent = desiredFlowRate / 100.0;
136 desiredFlowVolume = desiredFlowRate * ratedFlow / 100.0;
137 } else if (flowMode == Volume) {
138 if (desiredFlowRate < 0) {
139 throw std::invalid_argument("Desired flow rate volume must be greater than or equal to 0.");
140 }
141 desiredFlowVolume = desiredFlowRate;
142 desiredFlowPercent = desiredFlowRate / ratedFlow;
143 }
144 }
145
151 Output calculate() const { return compute(0.0); }
152
160 Output changeFanSize(const double fanDiameterCurrent, const double fanDiameter) const {
161 if (fanDiameterCurrent <= 0 || fanDiameter <= 0) {
162 throw std::invalid_argument("Fan diameters must be greater than 0.");
163 }
164
165 return compute(fanDiameter / fanDiameterCurrent);
166 }
167
168private:
169 const double electricityCost;
170 const double driveEfficiency, motorEfficiency, flowPercentBaseline;
171 const double operatingHours, motorPower, ratedFlow;
172 const MotorControlType motorControlTypeCurrent, motorControlTypeNew;
173 double desiredFlowPercent = 0, desiredFlowVolume = 0;
174
175 Output compute(const double fanDiameterRatio) const {
176 const double powerBaseline = motorPower / motorEfficiency / driveEfficiency;
177
178 double powerCurrent = powerBaseline;
179 if (motorControlTypeCurrent == VSD) {
180 powerCurrent *= std::pow(flowPercentBaseline, 3);
181 }
182 else if (motorControlTypeCurrent == TwoSpeed) {
183 powerCurrent = powerBaseline * get50PercentTimeFactor(flowPercentBaseline);
184 }
185
186 double powerNew = powerBaseline;
187 if (motorControlTypeNew == TwoSpeed) {
188 powerNew = powerBaseline * get50PercentTimeFactor(desiredFlowPercent);
189 }
190
191 if (fanDiameterRatio != 0) {
192 if (motorControlTypeNew == VSD) {
193 const auto fanRatedFlow = ratedFlow * std::pow(fanDiameterRatio, 3);
194 const auto newFlowPercent = desiredFlowVolume / fanRatedFlow;
195 powerNew = powerBaseline * std::pow(newFlowPercent, 3) * std::pow(fanDiameterRatio, 5);
196 }
197 else if (motorControlTypeNew == TwoSpeed) {
198 powerNew *= std::pow(fanDiameterRatio, 5);
199 }
200 else {
201 powerNew = powerBaseline * std::pow(fanDiameterRatio, 5);
202 }
203 }
204 else if (motorControlTypeNew == VSD) {
205 powerNew = powerBaseline * std::pow(desiredFlowPercent, 3);
206 }
207
208 return {powerCurrent * operatingHours, powerNew * operatingHours,
209 (powerCurrent - powerNew) * operatingHours * electricityCost};
210 }
211
212 static double get50PercentTimeFactor(const double flowPercent) {
213 const double timeAbove50Percent = (flowPercent - 0.5) / 0.5 < 0 ? 0 : (flowPercent - 0.5) / 0.5;
214 const double timeAt0Percent = (0.5 - flowPercent) / 0.5 < 0 ? 0 : (0.5 - flowPercent) / 0.5;
215 const double timeAt50Percent = 1 - timeAbove50Percent - timeAt0Percent;
216
217 return timeAbove50Percent + timeAt50Percent * 0.125;
218 }
219};
FanAffinityLaws(const Input &input)
FanAffinityLaws(const double electricityCost, const double driveEfficiency, const double motorEfficiency, const double flowPercentBaseline, const double operatingHours, const double motorPower, const double ratedFlow, const MotorControlType motorControlTypeCurrent, const MotorControlType motorControlTypeNew, const FlowMode flowMode, const double desiredFlowRate)
Output calculate() const
Compute annual baseline and changed energy based on current and changed state of motor Control at a d...
Output changeFanSize(const double fanDiameterCurrent, const double fanDiameter) const
Compute annual baseline and changed energy based on current and changed state of motor Control at a d...