diff --git a/Annex60/Fluid/Movers/BaseClasses/Characteristics.mo b/Annex60/Fluid/Movers/BaseClasses/Characteristics.mo deleted file mode 100644 index 49bc87b346..0000000000 --- a/Annex60/Fluid/Movers/BaseClasses/Characteristics.mo +++ /dev/null @@ -1,514 +0,0 @@ -within Annex60.Fluid.Movers.BaseClasses; -package Characteristics "Functions for fan or pump characteristics" - - record flowParameters "Record for flow parameters" - extends Modelica.Icons.Record; - - parameter Modelica.SIunits.VolumeFlowRate V_flow[:](each min=0) - "Volume flow rate at user-selected operating points"; - parameter Modelica.SIunits.Pressure dp[size(V_flow,1)]( - each min=0, each displayUnit="Pa") - "Fan or pump total pressure at these flow rates"; - - // This is needed for OpenModelica. - // fixme: Check if this can be put into FlowMachineInterface instead of here. - final parameter Integer n = size(V_flow,1) - "Number of data points for flow rate in V_flow vs. pressure data"; - - annotation (Documentation(info=" -

-Data record for performance data that describe volume flow rate versus -pressure rise. -The volume flow rate V_flow must be increasing, i.e., -V_flow[i] < V_flow[i+1]. -Both vectors, V_flow and dp -must have the same size. -

-", - revisions=" - -")); - end flowParameters; - - record flowParametersInternal - "Record for flow parameters with prescribed size" - extends Modelica.Icons.Record; - parameter Integer n "Number of elements in each array" - annotation(Evaluate=true); - parameter Modelica.SIunits.VolumeFlowRate V_flow[n](each min=0) - "Volume flow rate at user-selected operating points"; - parameter Modelica.SIunits.Pressure dp[n]( - each min=0, each displayUnit="Pa") - "Fan or pump total pressure at these flow rates"; - annotation (Documentation(info=" -

-Data record for performance data that describe volume flow rate versus -pressure rise. -The volume flow rate V_flow must be increasing, i.e., -V_flow[i] < V_flow[i+1]. -Both vectors, V_flow and dp -must have the same size. -

-

-This record is identical to - -Annex60.Fluid.Movers.BaseClasses.Characteristic.flowParameters, -except that it takes the size of the array as a parameter. This is required -in Dymola 2014. Otherwise, the array size would need to be computed in - -Annex60.Fluid.Movers.BaseClasses.FlowMachineInterface -in the initial algorithm section, which is not supported. -

-", - revisions=" - -")); - end flowParametersInternal; - - record efficiencyParameters "Record for efficiency parameters" - extends Modelica.Icons.Record; - parameter Modelica.SIunits.VolumeFlowRate V_flow[:]( - each min=0) "Volumetric flow rate at user-selected operating points"; - parameter Real eta[size(V_flow,1)]( - each min=0, - each max=1, - each displayUnit="1") "Fan or pump efficiency at these flow rates"; - annotation (Documentation(info=" -

-Data record for performance data that describe volume flow rate versus -efficiency. -The volume flow rate r_V must be increasing, i.e., -r_V[i] < r_V[i+1]. -Both vectors, r_V and eta -must have the same size. -

-", - revisions=" - -")); - end efficiencyParameters; - - record powerParameters "Record for electrical power parameters" - extends Modelica.Icons.Record; - parameter Modelica.SIunits.VolumeFlowRate V_flow[:](each min=0) - "Volume flow rate at user-selected operating points"; - parameter Modelica.SIunits.Power P[size(V_flow,1)](each min=0) - "Fan or pump electrical power at these flow rates"; - annotation (Documentation(info=" -

-Data record for performance data that describe volume flow rate versus -electrical power. -The volume flow rate V_flow must be increasing, i.e., -V_flow[i] < V_flow[i+1]. -Both vectors, V_flow and P -must have the same size. -

-", - revisions=" - -")); - end powerParameters; - - function pressure - "Flow vs. head characteristics for fan or pump pressure raise" - extends Modelica.Icons.Function; - input - Annex60.Fluid.Movers.BaseClasses.Characteristics.flowParametersInternal per - "Pressure performance data"; - input Modelica.SIunits.VolumeFlowRate V_flow "Volumetric flow rate"; - input Real r_N(unit="1") "Relative revolution, r_N=N/N_nominal"; - input Modelica.SIunits.VolumeFlowRate VDelta_flow "Small volume flow rate"; - input Modelica.SIunits.Pressure dpDelta "Small pressure"; - - input Modelica.SIunits.VolumeFlowRate V_flow_max - "Maximum volume flow rate at r_N=1 and dp=0"; - input Modelica.SIunits.Pressure dpMax(min=0) - "Maximum pressure at r_N=1 and V_flow=0"; - - input Real d[:] "Derivatives at support points for spline interpolation"; - input Real delta "Small value used to transition to other fan curve"; - input Real cBar[2] - "Coefficients for linear approximation of pressure vs. flow rate"; - input Real kRes(unit="kg/(s.m4)") - "Linear coefficient for fan-internal pressure drop"; - output Modelica.SIunits.Pressure dp "Pressure raise"; - - protected - Integer dimD(min=2)=size(per.V_flow, 1) "Dimension of data vector"; - - function performanceCurve "Performance curve away from the origin" - input Modelica.SIunits.VolumeFlowRate V_flow "Volumetric flow rate"; - input Real r_N(unit="1") "Relative revolution, r_N=N/N_nominal"; - input Real d[dimD] - "Coefficients for polynomial of pressure vs. flow rate"; - input - Annex60.Fluid.Movers.BaseClasses.Characteristics.flowParametersInternal - per - "Pressure performance data"; - input Integer dimD "Dimension of data vector"; - - output Modelica.SIunits.Pressure dp "Pressure raise"; - - protected - Modelica.SIunits.VolumeFlowRate rat "Ratio of V_flow/r_N"; - Integer i "Integer to select data interval"; - algorithm - rat := V_flow/r_N; - i :=1; - // Since the coefficients for the spline were evaluated for - // rat_nominal = V_flow_nominal/r_N_nominal = V_flow_nominal/1, we use - // V_flow_nominal below - for j in 1:dimD-1 loop - if rat > per.V_flow[j] then - i := j; - end if; - end for; - // Extrapolate or interpolate the data - dp:=r_N^2*Annex60.Utilities.Math.Functions.cubicHermiteLinearExtrapolation( - x=rat, - x1=per.V_flow[i], - x2=per.V_flow[i + 1], - y1=per.dp[i], - y2=per.dp[i + 1], - y1d=d[i], - y2d=d[i+1]); - annotation(smoothOrder=1); - end performanceCurve; - - algorithm - if r_N >= delta then - dp := performanceCurve(V_flow=V_flow, r_N=r_N, d=d, - per=per, dimD=dimD); - elseif r_N <= delta/2 then - dp := flowApproximationAtOrigin(r_N=r_N, V_flow=V_flow, - VDelta_flow= VDelta_flow, dpDelta=dpDelta, - delta=delta, cBar=cBar); - else - dp := Modelica.Fluid.Utilities.regStep(x=r_N-0.75*delta, - y1=performanceCurve(V_flow=V_flow, r_N=r_N, d=d, - per=per, dimD=dimD), - y2=flowApproximationAtOrigin(r_N=r_N, V_flow=V_flow, - VDelta_flow=VDelta_flow, dpDelta=dpDelta, - delta=delta, cBar=cBar), - x_small=delta/4); - end if; - // linear equation for being able to handle r_N=0, see - // Annex60/Resources/Images/Fluid/Movers/UsersGuide/2013-IBPSA-Wetter.pdf - dp := dp - V_flow*kRes; - annotation(smoothOrder=1, - Documentation(info=" -

-This function computes the fan static -pressure raise as a function of volume flow rate and revolution in the form -

-

- Δp = rN2   s(V̇/rN, d) - - Δpr , -

-

-where -Δp is the pressure rise, -rN is the normalized fan speed, - is the volume flow rate and -d are performance data for fan or pump power consumption at rN=1. -The term -

-

-Δpr = V̇   Δpmax ⁄ V̇max   δ -

-

-where δ > 0 is a pressure that is small compared to pressure raise of the -fan at the nominal conditions, -models the flow resistance of the fan, approximated using a linear equation. -This is done for numerical reasons to avoid a singularity at rN=0. -Since δ is small, the contribution of this term is small. -The fan and pump models in - -Annex60.Fluid.Movers modify the user-supplied performance data to add the term -Δpr prior to computing the performance curve. -Thus, at full speed, the fan or pump can operate exactly at the user-supplied performance data. -

-

Implementation

-

-The function s(·, ·) is a cubic hermite spline. -If the data d define a monotone decreasing sequence, then -s(·, d) is a monotone decreasing function. -

-

-For rN < δ, the polynomial is replaced with an other model to avoid -a singularity at the origin. The composite model is once continuously differentiable -in all input variables. -

-", revisions=" - - -"), smoothOrder=1); - end pressure; - - function flowApproximationAtOrigin - "Approximation for fan or pump pressure raise at origin" - extends Modelica.Icons.Function; - input Modelica.SIunits.VolumeFlowRate V_flow "Volumetric flow rate"; - input Real r_N(unit="1") "Relative revolution, r_N=N/N_nominal"; - input Modelica.SIunits.VolumeFlowRate VDelta_flow "Small volume flow rate"; - input Modelica.SIunits.Pressure dpDelta "Small pressure"; - input Real delta "Small value used to transition to other fan curve"; - input Real cBar[2] - "Coefficients for linear approximation of pressure vs. flow rate"; - output Modelica.SIunits.Pressure dp "Pressure raise"; - algorithm - - // see equation 20 in Annex60/Resources/Images/Fluid/Movers/UsersGuide/2013-IBPSA-Wetter.pdf - // this equation satisfies the constraints detailed in the paper - // the first term is added for having a faster convergence - // the last term in the paper is absent here because it can be found in - // Annex60.Fluid.Movers.BaseClasses.Characteristics.pressure - dp := r_N * dpDelta + r_N^2 * (cBar[1] + cBar[2]*V_flow); - annotation (Documentation(info=" -

-This function computes the fan static -pressure raise as a function of volume flow rate and revolution near the origin. -It is used to avoid a singularity in the pump or fan curve if the revolution -approaches zero. -

-", revisions=" - -"), smoothOrder=100); - end flowApproximationAtOrigin; - - function power "Flow vs. electrical power characteristics for fan or pump" - extends Modelica.Icons.Function; - input Annex60.Fluid.Movers.BaseClasses.Characteristics.powerParameters per - "Pressure performance data"; - input Modelica.SIunits.VolumeFlowRate V_flow "Volumetric flow rate"; - input Real r_N(unit="1") "Relative revolution, r_N=N/N_nominal"; - input Real d[:] "Derivatives at support points for spline interpolation"; - input Real delta "Small value for switching implementation around zero rpm"; - output Modelica.SIunits.Power P "Power consumption"; - - protected - Integer n=size(per.V_flow, 1) "Dimension of data vector"; - - Modelica.SIunits.VolumeFlowRate rat "Ratio of V_flow/r_N"; - Integer i "Integer to select data interval"; - - algorithm - if n == 1 then - P := r_N^3*per.P[1]; - else - i :=1; - // The use of the max function to avoids problems for low speeds - // and turned off pumps - rat:=V_flow/ - Annex60.Utilities.Math.Functions.smoothMax( - x1=r_N, - x2=0.1, - deltaX=delta); - for j in 1:n-1 loop - if rat > per.V_flow[j] then - i := j; - end if; - end for; - // Extrapolate or interpolate the data - P:=r_N^3*Annex60.Utilities.Math.Functions.cubicHermiteLinearExtrapolation( - x=rat, - x1=per.V_flow[i], - x2=per.V_flow[i + 1], - y1=per.P[i], - y2=per.P[i + 1], - y1d=d[i], - y2d=d[i+1]); - end if; - annotation(smoothOrder=1, - Documentation(info=" -

-This function computes the fan power consumption for given volume flow rate, -speed and performance data. The power consumption is -

-

- P = rN3   s(V̇/rN, d), -

-

-where -P is the power consumption, -rN is the normalized fan speed, - is the volume flow rate and -d are performance data for fan or pump power consumption at rN=1. -

-

Implementation

-

-The function s(·, ·) is a cubic hermite spline. -If the data d define a monotone decreasing sequence, then -s(·, d) is a monotone decreasing function. -

-", revisions=" - -"), smoothOrder=1); - end power; - - function efficiency "Flow vs. efficiency characteristics for fan or pump" - extends Modelica.Icons.Function; - input Annex60.Fluid.Movers.BaseClasses.Characteristics.efficiencyParameters - per "Efficiency performance data"; - input Modelica.SIunits.VolumeFlowRate V_flow "Volumetric flow rate"; - input Real d[:] "Derivatives at support points for spline interpolation"; - input Real r_N(unit="1") "Relative revolution, r_N=N/N_nominal"; - input Real delta "Small value for switching implementation around zero rpm"; - output Real eta(min=0, unit="1") "Efficiency"; - - protected - Integer n = size(per.V_flow, 1) "Number of data points"; - Real rat "Ratio of V_flow/r_N"; - Integer i "Integer to select data interval"; - algorithm - if n == 1 then - eta := per.eta[1]; - else - // The use of the max function to avoids problems for low speeds - // and turned off pumps - rat:=V_flow/ - Annex60.Utilities.Math.Functions.smoothMax( - x1=r_N, - x2=0.1, - deltaX=delta); - i :=1; - for j in 1:n-1 loop - if rat > per.V_flow[j] then - i := j; - end if; - end for; - // Extrapolate or interpolate the data - eta:=Annex60.Utilities.Math.Functions.cubicHermiteLinearExtrapolation( - x=rat, - x1=per.V_flow[i], - x2=per.V_flow[i + 1], - y1=per.eta[i], - y2=per.eta[i + 1], - y1d=d[i], - y2d=d[i+1]); - end if; - - annotation(smoothOrder=1, - Documentation(info=" -

-This function computes the fan or pump efficiency for given normalized volume flow rate -and performance data. The efficiency is -

-

- η = s(V̇/rN, d), -

-

-where -η is the efficiency, -rN is the normalized fan speed, - is the volume flow rate, and -d are performance data for fan or pump efficiency. -

-

Implementation

-

-The function s(·, ·) is a cubic hermite spline. -If the data d define a monotone decreasing sequence, then -s(·, d) is a monotone decreasing function. -

-", - revisions=" - -"), smoothOrder=1); - end efficiency; - - annotation (Documentation(info=" -

-This package implements performance curves for fans and pumps, -and records for parameter that can be used with these performance -curves. -

-

-See the - -User's Guide for information about these performance curves. -

-", -revisions=" - -")); -end Characteristics; diff --git a/Annex60/Fluid/Movers/BaseClasses/Characteristics/efficiency.mo b/Annex60/Fluid/Movers/BaseClasses/Characteristics/efficiency.mo new file mode 100644 index 0000000000..2adcb720e0 --- /dev/null +++ b/Annex60/Fluid/Movers/BaseClasses/Characteristics/efficiency.mo @@ -0,0 +1,93 @@ +within Annex60.Fluid.Movers.BaseClasses.Characteristics; +function efficiency "Flow vs. efficiency characteristics for fan or pump" + extends Modelica.Icons.Function; + input Annex60.Fluid.Movers.BaseClasses.Characteristics.efficiencyParameters per + "Efficiency performance data"; + input Modelica.SIunits.VolumeFlowRate V_flow "Volumetric flow rate"; + input Real d[:] "Derivatives at support points for spline interpolation"; + input Real r_N(unit="1") "Relative revolution, r_N=N/N_nominal"; + input Real delta "Small value for switching implementation around zero rpm"; + output Real eta(min=0, unit="1") "Efficiency"; + +protected + Integer n = size(per.V_flow, 1) "Number of data points"; + Real rat "Ratio of V_flow/r_N"; + Integer i "Integer to select data interval"; +algorithm + if n == 1 then + eta := per.eta[1]; + else + // The use of the max function to avoids problems for low speeds + // and turned off pumps + rat:=V_flow/ + Annex60.Utilities.Math.Functions.smoothMax( + x1=r_N, + x2=0.1, + deltaX=delta); + i :=1; + for j in 1:n-1 loop + if rat > per.V_flow[j] then + i := j; + end if; + end for; + // Extrapolate or interpolate the data + eta:=Annex60.Utilities.Math.Functions.cubicHermiteLinearExtrapolation( + x=rat, + x1=per.V_flow[i], + x2=per.V_flow[i + 1], + y1=per.eta[i], + y2=per.eta[i + 1], + y1d=d[i], + y2d=d[i+1]); + end if; + + annotation(smoothOrder=1, + Documentation(info=" +

+This function computes the fan or pump efficiency for given normalized volume flow rate +and performance data. The efficiency is +

+

+ η = s(V̇/rN, d), +

+

+where +η is the efficiency, +rN is the normalized fan speed, + is the volume flow rate, and +d are performance data for fan or pump efficiency. +

+

Implementation

+

+The function s(·, ·) is a cubic hermite spline. +If the data d define a monotone decreasing sequence, then +s(·, d) is a monotone decreasing function. +

+", +revisions=" + +"), smoothOrder=1); +end efficiency; diff --git a/Annex60/Fluid/Movers/BaseClasses/Characteristics/efficiencyParameters.mo b/Annex60/Fluid/Movers/BaseClasses/Characteristics/efficiencyParameters.mo new file mode 100644 index 0000000000..e61478b9cc --- /dev/null +++ b/Annex60/Fluid/Movers/BaseClasses/Characteristics/efficiencyParameters.mo @@ -0,0 +1,28 @@ +within Annex60.Fluid.Movers.BaseClasses.Characteristics; +record efficiencyParameters "Record for efficiency parameters" + extends Modelica.Icons.Record; + parameter Modelica.SIunits.VolumeFlowRate V_flow[:]( + each min=0) "Volumetric flow rate at user-selected operating points"; + parameter Real eta[size(V_flow,1)]( + each min=0, + each max=1, + each displayUnit="1") "Fan or pump efficiency at these flow rates"; + annotation (Documentation(info=" +

+Data record for performance data that describe volume flow rate versus +efficiency. +The volume flow rate r_V must be increasing, i.e., +r_V[i] < r_V[i+1]. +Both vectors, r_V and eta +must have the same size. +

+", +revisions=" + +")); +end efficiencyParameters; diff --git a/Annex60/Fluid/Movers/BaseClasses/Characteristics/flowApproximationAtOrigin.mo b/Annex60/Fluid/Movers/BaseClasses/Characteristics/flowApproximationAtOrigin.mo new file mode 100644 index 0000000000..9e44be2b10 --- /dev/null +++ b/Annex60/Fluid/Movers/BaseClasses/Characteristics/flowApproximationAtOrigin.mo @@ -0,0 +1,37 @@ +within Annex60.Fluid.Movers.BaseClasses.Characteristics; +function flowApproximationAtOrigin + "Approximation for fan or pump pressure raise at origin" + extends Modelica.Icons.Function; + input Modelica.SIunits.VolumeFlowRate V_flow "Volumetric flow rate"; + input Real r_N(unit="1") "Relative revolution, r_N=N/N_nominal"; + input Modelica.SIunits.VolumeFlowRate VDelta_flow "Small volume flow rate"; + input Modelica.SIunits.Pressure dpDelta "Small pressure"; + input Real delta "Small value used to transition to other fan curve"; + input Real cBar[2] + "Coefficients for linear approximation of pressure vs. flow rate"; + output Modelica.SIunits.Pressure dp "Pressure raise"; +algorithm + + // see equation 20 in Annex60/Resources/Images/Fluid/Movers/UsersGuide/2013-IBPSA-Wetter.pdf + // this equation satisfies the constraints detailed in the paper + // the first term is added for having a faster convergence + // the last term in the paper is absent here because it can be found in + // Annex60.Fluid.Movers.BaseClasses.Characteristics.pressure + dp := r_N * dpDelta + r_N^2 * (cBar[1] + cBar[2]*V_flow); + annotation (Documentation(info=" +

+This function computes the fan static +pressure raise as a function of volume flow rate and revolution near the origin. +It is used to avoid a singularity in the pump or fan curve if the revolution +approaches zero. +

+", + revisions=" + +"), smoothOrder=100); +end flowApproximationAtOrigin; diff --git a/Annex60/Fluid/Movers/BaseClasses/Characteristics/flowParameters.mo b/Annex60/Fluid/Movers/BaseClasses/Characteristics/flowParameters.mo new file mode 100644 index 0000000000..bcdfcc5a54 --- /dev/null +++ b/Annex60/Fluid/Movers/BaseClasses/Characteristics/flowParameters.mo @@ -0,0 +1,34 @@ +within Annex60.Fluid.Movers.BaseClasses.Characteristics; +record flowParameters "Record for flow parameters" + extends Modelica.Icons.Record; + + parameter Modelica.SIunits.VolumeFlowRate V_flow[:](each min=0) + "Volume flow rate at user-selected operating points"; + parameter Modelica.SIunits.Pressure dp[size(V_flow,1)]( + each min=0, each displayUnit="Pa") + "Fan or pump total pressure at these flow rates"; + + // This is needed for OpenModelica. + // fixme: Check if this can be put into FlowMachineInterface instead of here. + final parameter Integer n = size(V_flow,1) + "Number of data points for flow rate in V_flow vs. pressure data"; + + annotation (Documentation(info=" +

+Data record for performance data that describe volume flow rate versus +pressure rise. +The volume flow rate V_flow must be increasing, i.e., +V_flow[i] < V_flow[i+1]. +Both vectors, V_flow and dp +must have the same size. +

+", +revisions=" + +")); +end flowParameters; diff --git a/Annex60/Fluid/Movers/BaseClasses/Characteristics/flowParametersInternal.mo b/Annex60/Fluid/Movers/BaseClasses/Characteristics/flowParametersInternal.mo new file mode 100644 index 0000000000..c124c8e27f --- /dev/null +++ b/Annex60/Fluid/Movers/BaseClasses/Characteristics/flowParametersInternal.mo @@ -0,0 +1,39 @@ +within Annex60.Fluid.Movers.BaseClasses.Characteristics; +record flowParametersInternal "Record for flow parameters with prescribed size" + extends Modelica.Icons.Record; + parameter Integer n "Number of elements in each array" + annotation(Evaluate=true); + parameter Modelica.SIunits.VolumeFlowRate V_flow[n](each min=0) + "Volume flow rate at user-selected operating points"; + parameter Modelica.SIunits.Pressure dp[n]( + each min=0, each displayUnit="Pa") + "Fan or pump total pressure at these flow rates"; + annotation (Documentation(info=" +

+Data record for performance data that describe volume flow rate versus +pressure rise. +The volume flow rate V_flow must be increasing, i.e., +V_flow[i] < V_flow[i+1]. +Both vectors, V_flow and dp +must have the same size. +

+

+This record is identical to + +Annex60.Fluid.Movers.BaseClasses.Characteristic.flowParameters, +except that it takes the size of the array as a parameter. This is required +in Dymola 2014. Otherwise, the array size would need to be computed in + +Annex60.Fluid.Movers.BaseClasses.FlowMachineInterface +in the initial algorithm section, which is not supported. +

+", +revisions=" + +")); +end flowParametersInternal; diff --git a/Annex60/Fluid/Movers/BaseClasses/Characteristics/package.mo b/Annex60/Fluid/Movers/BaseClasses/Characteristics/package.mo new file mode 100644 index 0000000000..a43be84208 --- /dev/null +++ b/Annex60/Fluid/Movers/BaseClasses/Characteristics/package.mo @@ -0,0 +1,33 @@ +within Annex60.Fluid.Movers.BaseClasses; +package Characteristics "Functions for fan or pump characteristics" + + + + + + + + + + + annotation (Documentation(info=" +

+This package implements performance curves for fans and pumps, +and records for parameter that can be used with these performance +curves. +

+

+See the + +User's Guide for information about these performance curves. +

+", +revisions=" + +")); +end Characteristics; diff --git a/Annex60/Fluid/Movers/BaseClasses/Characteristics/package.order b/Annex60/Fluid/Movers/BaseClasses/Characteristics/package.order new file mode 100644 index 0000000000..56c4589ed4 --- /dev/null +++ b/Annex60/Fluid/Movers/BaseClasses/Characteristics/package.order @@ -0,0 +1,8 @@ +flowParameters +flowParametersInternal +efficiencyParameters +powerParameters +pressure +flowApproximationAtOrigin +power +efficiency diff --git a/Annex60/Fluid/Movers/BaseClasses/Characteristics/power.mo b/Annex60/Fluid/Movers/BaseClasses/Characteristics/power.mo new file mode 100644 index 0000000000..d747f6100b --- /dev/null +++ b/Annex60/Fluid/Movers/BaseClasses/Characteristics/power.mo @@ -0,0 +1,84 @@ +within Annex60.Fluid.Movers.BaseClasses.Characteristics; +function power "Flow vs. electrical power characteristics for fan or pump" + extends Modelica.Icons.Function; + input Annex60.Fluid.Movers.BaseClasses.Characteristics.powerParameters per + "Pressure performance data"; + input Modelica.SIunits.VolumeFlowRate V_flow "Volumetric flow rate"; + input Real r_N(unit="1") "Relative revolution, r_N=N/N_nominal"; + input Real d[:] "Derivatives at support points for spline interpolation"; + input Real delta "Small value for switching implementation around zero rpm"; + output Modelica.SIunits.Power P "Power consumption"; + +protected + Integer n=size(per.V_flow, 1) "Dimension of data vector"; + + Modelica.SIunits.VolumeFlowRate rat "Ratio of V_flow/r_N"; + Integer i "Integer to select data interval"; + +algorithm + if n == 1 then + P := r_N^3*per.P[1]; + else + i :=1; + // The use of the max function to avoids problems for low speeds + // and turned off pumps + rat:=V_flow/ + Annex60.Utilities.Math.Functions.smoothMax( + x1=r_N, + x2=0.1, + deltaX=delta); + for j in 1:n-1 loop + if rat > per.V_flow[j] then + i := j; + end if; + end for; + // Extrapolate or interpolate the data + P:=r_N^3*Annex60.Utilities.Math.Functions.cubicHermiteLinearExtrapolation( + x=rat, + x1=per.V_flow[i], + x2=per.V_flow[i + 1], + y1=per.P[i], + y2=per.P[i + 1], + y1d=d[i], + y2d=d[i+1]); + end if; + annotation(smoothOrder=1, + Documentation(info=" +

+This function computes the fan power consumption for given volume flow rate, +speed and performance data. The power consumption is +

+

+ P = rN3   s(V̇/rN, d), +

+

+where +P is the power consumption, +rN is the normalized fan speed, + is the volume flow rate and +d are performance data for fan or pump power consumption at rN=1. +

+

Implementation

+

+The function s(·, ·) is a cubic hermite spline. +If the data d define a monotone decreasing sequence, then +s(·, d) is a monotone decreasing function. +

+", + revisions=" + +"), smoothOrder=1); +end power; diff --git a/Annex60/Fluid/Movers/BaseClasses/Characteristics/powerParameters.mo b/Annex60/Fluid/Movers/BaseClasses/Characteristics/powerParameters.mo new file mode 100644 index 0000000000..8bd8fbfda1 --- /dev/null +++ b/Annex60/Fluid/Movers/BaseClasses/Characteristics/powerParameters.mo @@ -0,0 +1,31 @@ +within Annex60.Fluid.Movers.BaseClasses.Characteristics; +record powerParameters "Record for electrical power parameters" + extends Modelica.Icons.Record; + parameter Modelica.SIunits.VolumeFlowRate V_flow[:](each min=0) + "Volume flow rate at user-selected operating points"; + parameter Modelica.SIunits.Power P[size(V_flow,1)](each min=0) + "Fan or pump electrical power at these flow rates"; + annotation (Documentation(info=" +

+Data record for performance data that describe volume flow rate versus +electrical power. +The volume flow rate V_flow must be increasing, i.e., +V_flow[i] < V_flow[i+1]. +Both vectors, V_flow and P +must have the same size. +

+", +revisions=" + +")); +end powerParameters; diff --git a/Annex60/Fluid/Movers/BaseClasses/Characteristics/pressure.mo b/Annex60/Fluid/Movers/BaseClasses/Characteristics/pressure.mo new file mode 100644 index 0000000000..0955acc67e --- /dev/null +++ b/Annex60/Fluid/Movers/BaseClasses/Characteristics/pressure.mo @@ -0,0 +1,143 @@ +within Annex60.Fluid.Movers.BaseClasses.Characteristics; +function pressure + "Flow vs. head characteristics for fan or pump pressure raise" + extends Modelica.Icons.Function; + input Annex60.Fluid.Movers.BaseClasses.Characteristics.flowParametersInternal + per "Pressure performance data"; + input Modelica.SIunits.VolumeFlowRate V_flow "Volumetric flow rate"; + input Real r_N(unit="1") "Relative revolution, r_N=N/N_nominal"; + input Modelica.SIunits.VolumeFlowRate VDelta_flow "Small volume flow rate"; + input Modelica.SIunits.Pressure dpDelta "Small pressure"; + + input Modelica.SIunits.VolumeFlowRate V_flow_max + "Maximum volume flow rate at r_N=1 and dp=0"; + input Modelica.SIunits.Pressure dpMax(min=0) + "Maximum pressure at r_N=1 and V_flow=0"; + + input Real d[:] "Derivatives at support points for spline interpolation"; + input Real delta "Small value used to transition to other fan curve"; + input Real cBar[2] + "Coefficients for linear approximation of pressure vs. flow rate"; + input Real kRes(unit="kg/(s.m4)") + "Linear coefficient for fan-internal pressure drop"; + output Modelica.SIunits.Pressure dp "Pressure raise"; + +protected + Integer dimD(min=2)=size(per.V_flow, 1) "Dimension of data vector"; + + function performanceCurve "Performance curve away from the origin" + input Modelica.SIunits.VolumeFlowRate V_flow "Volumetric flow rate"; + input Real r_N(unit="1") "Relative revolution, r_N=N/N_nominal"; + input Real d[dimD] "Coefficients for polynomial of pressure vs. flow rate"; + input + Annex60.Fluid.Movers.BaseClasses.Characteristics.flowParametersInternal per + "Pressure performance data"; + input Integer dimD "Dimension of data vector"; + + output Modelica.SIunits.Pressure dp "Pressure raise"; + + protected + Modelica.SIunits.VolumeFlowRate rat "Ratio of V_flow/r_N"; + Integer i "Integer to select data interval"; + algorithm + rat := V_flow/r_N; + i :=1; + // Since the coefficients for the spline were evaluated for + // rat_nominal = V_flow_nominal/r_N_nominal = V_flow_nominal/1, we use + // V_flow_nominal below + for j in 1:dimD-1 loop + if rat > per.V_flow[j] then + i := j; + end if; + end for; + // Extrapolate or interpolate the data + dp:=r_N^2*Annex60.Utilities.Math.Functions.cubicHermiteLinearExtrapolation( + x=rat, + x1=per.V_flow[i], + x2=per.V_flow[i + 1], + y1=per.dp[i], + y2=per.dp[i + 1], + y1d=d[i], + y2d=d[i+1]); + annotation(smoothOrder=1); + end performanceCurve; + +algorithm + if r_N >= delta then + dp := performanceCurve(V_flow=V_flow, r_N=r_N, d=d, + per=per, dimD=dimD); + elseif r_N <= delta/2 then + dp := flowApproximationAtOrigin(r_N=r_N, V_flow=V_flow, + VDelta_flow= VDelta_flow, dpDelta=dpDelta, + delta=delta, cBar=cBar); + else + dp := Modelica.Fluid.Utilities.regStep(x=r_N-0.75*delta, + y1=performanceCurve(V_flow=V_flow, r_N=r_N, d=d, + per=per, dimD=dimD), + y2=flowApproximationAtOrigin(r_N=r_N, V_flow=V_flow, + VDelta_flow=VDelta_flow, dpDelta=dpDelta, + delta=delta, cBar=cBar), + x_small=delta/4); + end if; + // linear equation for being able to handle r_N=0, see + // Annex60/Resources/Images/Fluid/Movers/UsersGuide/2013-IBPSA-Wetter.pdf + dp := dp - V_flow*kRes; + annotation(smoothOrder=1, + Documentation(info=" +

+This function computes the fan static +pressure raise as a function of volume flow rate and revolution in the form +

+

+ Δp = rN2   s(V̇/rN, d) + - Δpr , +

+

+where +Δp is the pressure rise, +rN is the normalized fan speed, + is the volume flow rate and +d are performance data for fan or pump power consumption at rN=1. +The term +

+

+Δpr = V̇   Δpmax ⁄ V̇max   δ +

+

+where δ > 0 is a pressure that is small compared to pressure raise of the +fan at the nominal conditions, +models the flow resistance of the fan, approximated using a linear equation. +This is done for numerical reasons to avoid a singularity at rN=0. +Since δ is small, the contribution of this term is small. +The fan and pump models in + +Annex60.Fluid.Movers modify the user-supplied performance data to add the term +Δpr prior to computing the performance curve. +Thus, at full speed, the fan or pump can operate exactly at the user-supplied performance data. +

+

Implementation

+

+The function s(·, ·) is a cubic hermite spline. +If the data d define a monotone decreasing sequence, then +s(·, d) is a monotone decreasing function. +

+

+For rN < δ, the polynomial is replaced with an other model to avoid +a singularity at the origin. The composite model is once continuously differentiable +in all input variables. +

+", + revisions=" + + +"), smoothOrder=1); +end pressure;