This is an interface that implements the functions to compute the head, power draw
and efficiency of fans and pumps.
The nominal hydraulic characteristic (volume flow rate versus total pressure)
is given by a set of data points
using the data record per
, which is an instance of
Annex60.Fluid.Movers.Data.Generic.
A cubic hermite spline with linear extrapolation is used to compute
the performance at other operating points.
For numerical reasons, the user-provided data points for volume flow rate
versus pressure rise are modified to add a fan internal flow resistance.
Because this flow resistance is subtracted during the simulation when
computing the fan pressure rise, the model reproduces the exact points
that were provided by the user.
Also for numerical reasons, the pressure rise at zero flow rate and
the flow rate at zero pressure rise is added to the user-provided data,
unless the user already provides these data points.
Since Modelica 3.2 does not allow dynamic memory allocation, this
implementation required the use of three different arrays for the
situation where no additional point is added, where one additional
point is added and where two additional points are added.
The parameter curve
causes the correct data record
to be used during the simulation.
model FlowMachineInterface
extends Modelica.Blocks.Interfaces.BlockIcon;
import cha =
Annex60.Fluid.Movers.BaseClasses.Characteristics;
parameter Annex60.Fluid.Movers.Data.Generic per
;
parameter Annex60.Fluid.Movers.BaseClasses.Types.PrescribedVariable preVar=
Annex60.Fluid.Movers.BaseClasses.Types.PrescribedVariable.Speed ;
parameter Boolean computePowerUsingSimilarityLaws
;
final parameter Modelica.SIunits.VolumeFlowRate V_flow_nominal=
per.pressure.V_flow[nOri] ;
parameter Modelica.SIunits.Density rho_default
;
parameter Boolean haveVMax
;
parameter Modelica.SIunits.VolumeFlowRate V_flow_max
;
parameter Integer nOri(min=1) ;
parameter Boolean homotopyInitialization = true ;
Modelica.Blocks.Interfaces.RealInput y_in(
final unit="1")
if preSpe
;
Modelica.Blocks.Interfaces.RealOutput y_out(
final unit="1") ;
Modelica.Blocks.Interfaces.RealInput m_flow(
final quantity="MassFlowRate",
final unit="kg/s") ;
Modelica.Blocks.Interfaces.RealInput rho(
final quantity="Density",
final unit="kg/m3",
min=0.0) ;
Modelica.Blocks.Interfaces.RealOutput V_flow(
quantity="VolumeFlowRate",
final unit="m3/s") ;
Modelica.Blocks.Interfaces.RealInput dp_in(
quantity="PressureDifference",
final unit="Pa")
if prePre ;
Modelica.Blocks.Interfaces.RealOutput dp(
quantity="Pressure",
final unit="Pa")
if not prePre ;
Modelica.Blocks.Interfaces.RealOutput WFlo(
quantity="Power",
final unit="W") ;
Modelica.Blocks.Interfaces.RealOutput PEle(
quantity="Power",
final unit="W") ;
Modelica.Blocks.Interfaces.RealOutput eta(
final quantity="Efficiency",
final unit="1") ;
Modelica.Blocks.Interfaces.RealOutput etaHyd(
final quantity="Efficiency",
final unit="1") ;
Modelica.Blocks.Interfaces.RealOutput etaMot(
final quantity="Efficiency",
final unit="1") ;
Modelica.Blocks.Interfaces.RealOutput r_N(unit="1")
;
Real r_V(start=1, unit="1") ;
protected
final parameter Boolean preSpe=
preVar == Annex60.Fluid.Movers.BaseClasses.Types.PrescribedVariable.Speed
;
final parameter Boolean prePre=
preVar == Annex60.Fluid.Movers.BaseClasses.Types.PrescribedVariable.PressureDifference
or
preVar == Annex60.Fluid.Movers.BaseClasses.Types.PrescribedVariable.FlowRate
;
final parameter Real motDer[
size(per.motorEfficiency.V_flow, 1)](
each fixed=false)
;
final parameter Real hydDer[
size(per.hydraulicEfficiency.V_flow,1)](
each fixed=false)
;
parameter Modelica.SIunits.PressureDifference dpMax(displayUnit="Pa")=
if haveDPMax
then
per.pressure.dp[1]
else
per.pressure.dp[1] - ((per.pressure.dp[2] - per.pressure.dp[1])/(
per.pressure.V_flow[2] - per.pressure.V_flow[1]))*per.pressure.V_flow[1]
;
parameter Real delta = 0.05
;
parameter Real kRes(min=0, unit="kg/(s.m4)") = dpMax/V_flow_max*delta^2/10
;
parameter Integer curve=
if (haveVMax
and haveDPMax)
or (nOri == 2)
then 1
elseif haveVMax
or haveDPMax
then 2
else 3
;
final parameter Annex60.Fluid.Movers.BaseClasses.Characteristics.flowParametersInternal
pCur1(
final n = nOri,
final V_flow =
if (haveVMax
and haveDPMax)
or (nOri == 2)
then
{per.pressure.V_flow[i]
for i
in 1:nOri}
else
zeros(nOri),
final dp =
if (haveVMax
and haveDPMax)
or (nOri == 2)
then
{(per.pressure.dp[i] + per.pressure.V_flow[i] * kRes)
for i
in 1:nOri}
else
zeros(nOri))
;
parameter Annex60.Fluid.Movers.BaseClasses.Characteristics.flowParametersInternal
pCur2(
final n = nOri + 1,
V_flow =
if (haveVMax
and haveDPMax)
or (nOri == 2)
then
zeros(nOri + 1)
elseif haveVMax
then
cat(1, {0}, {per.pressure.V_flow[i]
for i
in 1:nOri})
elseif haveDPMax
then
cat(1, { per.pressure.V_flow[i]
for i
in 1:nOri}, {V_flow_max})
else
zeros(nOri + 1),
dp =
if (haveVMax
and haveDPMax)
or (nOri == 2)
then
zeros(nOri + 1)
elseif haveVMax
then
cat(1, {dpMax}, {per.pressure.dp[i] + per.pressure.V_flow[i] * kRes
for i
in 1:nOri})
elseif haveDPMax
then
cat(1, {per.pressure.dp[i] + per.pressure.V_flow[i] * kRes
for i
in 1:nOri}, {0})
else
zeros(nOri+1))
;
parameter Annex60.Fluid.Movers.BaseClasses.Characteristics.flowParametersInternal
pCur3(
final n = nOri + 2,
V_flow =
if (haveVMax
and haveDPMax)
or (nOri == 2)
then
zeros(nOri + 2)
elseif haveVMax
or haveDPMax
then
zeros(nOri + 2)
else
cat(1, {0}, {per.pressure.V_flow[i]
for i
in 1:nOri}, {V_flow_max}),
dp =
if (haveVMax
and haveDPMax)
or (nOri == 2)
then
zeros(nOri + 2)
elseif haveVMax
or haveDPMax
then
zeros(nOri + 2)
else
cat(1, {dpMax}, {per.pressure.dp[i] + per.pressure.V_flow[i] * kRes
for i
in 1:nOri}, {0}))
;
parameter Real preDer1[nOri](
each fixed=false)
;
parameter Real preDer2[nOri+1](
each fixed=false)
;
parameter Real preDer3[nOri+2](
each fixed=false)
;
parameter Real powDer[
size(per.power.V_flow,1)]=
if per.use_powerCharacteristic
then
Annex60.Utilities.Math.Functions.splineDerivatives(
x=per.power.V_flow,
y=per.power.P,
ensureMonotonicity=
Annex60.Utilities.Math.Functions.isMonotonic(x=per.power.P,
strict=false))
else
zeros(
size(per.power.V_flow,1))
;
parameter Boolean haveMinimumDecrease=
Modelica.Math.BooleanVectors.allTrue({(per.pressure.dp[i + 1] -
per.pressure.dp[i])/(per.pressure.V_flow[i + 1] - per.pressure.V_flow[
i]) < -kRes
for i
in 1:nOri - 1}) ;
parameter Boolean haveDPMax = (
abs(per.pressure.V_flow[1]) < Modelica.Constants.eps)
;
Modelica.Blocks.Interfaces.RealOutput dp_internal
;
function getPerformanceDataAsString
input Annex60.Fluid.Movers.BaseClasses.Characteristics.flowParameters pressure
;
input Real derivative[:](unit="kg/(s.m4)") ;
input Integer minimumLength = 6 ;
input Integer significantDigits = 6 ;
output String str ;
algorithm
str :="";
for i
in 1:
size(derivative, 1)
loop
str :=str + " V_flow[" +
String(i) + "]=" +
String(
pressure.V_flow[i],
minimumLength=minimumLength,
significantDigits=significantDigits) + "\t" + "dp[" +
String(i) + "]=" +
String(
pressure.dp[i],
minimumLength=minimumLength,
significantDigits=significantDigits) + "\tResulting derivative dp/dV_flow = "
+
String(
derivative[i],
minimumLength=minimumLength,
significantDigits=significantDigits) + "\n";
end for;
end getPerformanceDataAsString;
function getArrayAsString
input Real array[:] ;
input String varName ;
input Integer minimumLength = 6 ;
input Integer significantDigits = 6 ;
output String str ;
algorithm
str :="";
for i
in 1:
size(array, 1)
loop
str :=str + " " + varName + "[" +
String(i) + "]=" +
String(
array[i],
minimumLength=minimumLength,
significantDigits=significantDigits) + "\n";
end for;
end getArrayAsString;
initial equation
assert(nOri > 1, "Must have at least two data points for pressure.V_flow.");
assert(
Annex60.Utilities.Math.Functions.isMonotonic(x=per.pressure.V_flow, strict=true)
and
per.pressure.V_flow[1] > -Modelica.Constants.eps,
"The fan pressure rise must be a strictly decreasing sequence with respect to the volume flow rate,
with the first element for the fan pressure raise being non-zero.
The following performance data have been entered:
" +
getArrayAsString(per.pressure.V_flow, "pressure.V_flow"));
if not haveVMax
then
assert((per.pressure.V_flow[nOri]-per.pressure.V_flow[nOri-1])
/((per.pressure.dp[nOri]-per.pressure.dp[nOri-1]))<0,
"The last two pressure points for the fan or pump performance curve must be decreasing.
You need to set more reasonable parameters.
Received
" +
getArrayAsString(per.pressure.dp, "dp"));
end if;
if (
not haveMinimumDecrease)
then
Modelica.Utilities.Streams.print("
Warning:
========
It is recommended that the volume flow rate versus pressure relation
of the fan or pump satisfies the minimum decrease condition
(per.pressure.dp[i+1]-per.pressure.dp[i])
d[i] = ------------------------------------------------- < " +
String(-kRes) + "
(per.pressure.V_flow[i+1]-per.pressure.V_flow[i])
is
" +
getArrayAsString({(per.pressure.dp[i+1]-per.pressure.dp[i])
/(per.pressure.V_flow[i+1]-per.pressure.V_flow[i])
for i
in 1:nOri-1}, "d") + "
Otherwise, a solution to the equations may not exist if the fan or pump speed is reduced.
In this situation, the solver will fail due to non-convergence and
the simulation stops.");
end if;
if (haveVMax
and haveDPMax)
or (nOri == 2)
then
preDer1=
Annex60.Utilities.Math.Functions.splineDerivatives(x=pCur1.V_flow,
y=pCur1.dp);
preDer2=
zeros(nOri + 1);
preDer3=
zeros(nOri + 2);
elseif haveVMax
or haveDPMax
then
preDer1=
zeros(nOri);
preDer2=
Annex60.Utilities.Math.Functions.splineDerivatives(x=pCur2.V_flow,
y=pCur2.dp);
preDer3=
zeros(nOri + 2);
else
preDer1=
zeros(nOri);
preDer2=
zeros(nOri + 1);
preDer3=
Annex60.Utilities.Math.Functions.splineDerivatives(x=pCur3.V_flow,
y=pCur3.dp);
end if;
motDer =
if per.use_powerCharacteristic
then zeros(
size(per.motorEfficiency.V_flow,
1))
elseif (
size(per.motorEfficiency.V_flow, 1) == 1)
then {0}
else
Annex60.Utilities.Math.Functions.splineDerivatives(
x=per.motorEfficiency.V_flow,
y=per.motorEfficiency.eta,
ensureMonotonicity=
Annex60.Utilities.Math.Functions.isMonotonic(x=per.motorEfficiency.eta,
strict=false));
hydDer =
if per.use_powerCharacteristic
then zeros(
size(per.hydraulicEfficiency.V_flow,
1))
elseif (
size(per.hydraulicEfficiency.V_flow, 1) == 1)
then {0}
else Annex60.Utilities.Math.Functions.splineDerivatives(x=per.hydraulicEfficiency.V_flow,
y=per.hydraulicEfficiency.eta);
equation
connect(dp_internal,dp);
connect(dp_internal,dp_in);
connect(r_N, y_in);
y_out=r_N;
V_flow = m_flow/rho;
r_V = V_flow/V_flow_max;
if (computePowerUsingSimilarityLaws == false)
and preVar <> Annex60.Fluid.Movers.BaseClasses.Types.PrescribedVariable.Speed
then
r_N=1;
else
if (curve == 1)
then
if homotopyInitialization
then
V_flow*kRes + dp_internal =
homotopy(actual=
cha.pressure(
V_flow=V_flow,
r_N=r_N,
dpMax=dpMax,
V_flow_max=V_flow_max,
d=preDer1,
per=pCur1),
simplified=r_N * (
cha.pressure(
V_flow=V_flow_nominal,
r_N=1,
dpMax=dpMax,
V_flow_max=V_flow_max,
d=preDer1,
per=pCur1)
+(V_flow-V_flow_nominal) * (
cha.pressure(
V_flow=(1+delta)*V_flow_nominal,
r_N=1,
dpMax=dpMax,
V_flow_max=V_flow_max,
d=preDer1,
per=pCur1)
-
cha.pressure(V_flow=(1-delta)*V_flow_nominal,
r_N=1,
dpMax=dpMax,
V_flow_max=V_flow_max,
d=preDer1,
per=pCur1))
/(2*delta*V_flow_nominal)));
else
V_flow*kRes + dp_internal=
cha.pressure(V_flow=V_flow,
r_N=r_N,
dpMax=dpMax,
V_flow_max=V_flow_max,
d=preDer1,
per=pCur1);
end if;
elseif (curve == 2)
then
if homotopyInitialization
then
V_flow*kRes + dp_internal =
homotopy(actual=
cha.pressure(
V_flow=V_flow,
r_N=r_N,
dpMax=dpMax,
V_flow_max=V_flow_max,
d=preDer2,
per=pCur2),
simplified=r_N * (
cha.pressure(
V_flow=V_flow_nominal,
r_N=1,
dpMax=dpMax,
V_flow_max=V_flow_max,
d=preDer2,
per=pCur2)
+(V_flow-V_flow_nominal) * (
cha.pressure(
V_flow=(1+delta)*V_flow_nominal,
r_N=1,
dpMax=dpMax,
V_flow_max=V_flow_max,
d=preDer2,
per=pCur2)
-
cha.pressure(V_flow=(1-delta)*V_flow_nominal,
r_N=1,
dpMax=dpMax,
V_flow_max=V_flow_max,
d=preDer2,
per=pCur2))
/(2*delta*V_flow_nominal)));
else
V_flow*kRes + dp_internal=
cha.pressure(V_flow=V_flow,
r_N=r_N,
dpMax=dpMax,
V_flow_max=V_flow_max,
d=preDer2,
per=pCur2);
end if;
else
if homotopyInitialization
then
V_flow*kRes + dp_internal =
homotopy(actual=
cha.pressure(
V_flow=V_flow,
r_N=r_N,
dpMax=dpMax,
V_flow_max=V_flow_max,
d=preDer3,
per=pCur3),
simplified=r_N * (
cha.pressure(
V_flow=V_flow_nominal,
r_N=1,
dpMax=dpMax,
V_flow_max=V_flow_max,
d=preDer3,
per=pCur3)
+(V_flow-V_flow_nominal)*
(
cha.pressure(V_flow=(1+delta)*V_flow_nominal,
r_N=1,
dpMax=dpMax,
V_flow_max=V_flow_max,
d=preDer3,
per=pCur3)
-
cha.pressure(V_flow=(1-delta)*V_flow_nominal,
r_N=1,
dpMax=dpMax,
V_flow_max=V_flow_max,
d=preDer3,
per=pCur3))
/(2*delta*V_flow_nominal)));
else
V_flow*kRes + dp_internal=
cha.pressure(V_flow=V_flow,
r_N=r_N,
dpMax=dpMax,
V_flow_max=V_flow_max,
d=preDer3,
per=pCur3);
end if;
end if;
end if;
WFlo = dp_internal*V_flow;
if per.use_powerCharacteristic
then
if homotopyInitialization
then
PEle =
homotopy(actual=
cha.power(per=per.power, V_flow=V_flow, r_N=r_N, d=powDer, delta=delta),
simplified=V_flow/V_flow_nominal*
cha.power(per=per.power, V_flow=V_flow_nominal, r_N=1, d=powDer, delta=delta));
else
PEle = (rho/rho_default)*
cha.power(per=per.power, V_flow=V_flow, r_N=r_N, d=powDer, delta=delta);
end if;
eta = WFlo /
Annex60.Utilities.Math.Functions.smoothMax(x1=PEle, x2=1E-5, deltaX=1E-6);
etaHyd = 1;
etaMot = eta;
else
if homotopyInitialization
then
etaHyd =
homotopy(actual=
cha.efficiency(per=per.hydraulicEfficiency, V_flow=V_flow, d=hydDer, r_N=r_N, delta=delta),
simplified=
cha.efficiency(per=per.hydraulicEfficiency, V_flow=V_flow_max, d=hydDer, r_N=r_N, delta=delta));
etaMot =
homotopy(actual=
cha.efficiency(per=per.motorEfficiency, V_flow=V_flow, d=motDer, r_N=r_N, delta=delta),
simplified=
cha.efficiency(per=per.motorEfficiency, V_flow=V_flow_max, d=motDer, r_N=r_N, delta=delta));
else
etaHyd =
cha.efficiency(per=per.hydraulicEfficiency, V_flow=V_flow, d=hydDer, r_N=r_N, delta=delta);
etaMot =
cha.efficiency(per=per.motorEfficiency, V_flow=V_flow, d=motDer, r_N=r_N, delta=delta);
end if;
PEle = WFlo /
Annex60.Utilities.Math.Functions.smoothMax(x1=eta, x2=1E-5, deltaX=1E-6);
eta = etaHyd * etaMot;
end if;
end FlowMachineInterface;
Model of a fictitious pipe that is used as a base class
for a pressure source or to prescribe a mass flow rate.
Note that for fans and pumps with dynamic balance,
both the heat and the flow work are added to the volume of
air or water. This simplifies the equations compared to
adding heat to the volume, and flow work to this model.
This is the base model for fans and pumps.
It provides an interface
between the equations that compute head and power consumption,
and the implementation of the energy and pressure balance
of the fluid.
Optionally, the fluid volume
is computed using a dynamic balance or a steady-state balance.
partial model PartialFlowMachine
extends Annex60.Fluid.Interfaces.LumpedVolumeDeclarations(
final mSenFac=1);
extends Annex60.Fluid.Interfaces.PartialTwoPortInterface(
show_T=false,
port_a(
h_outflow(start=h_outflow_start)),
port_b(
h_outflow(start=h_outflow_start),
p(start=p_start),
final m_flow(max =
if allowFlowReversal
then +Modelica.Constants.inf
else 0)));
replaceable parameter Annex60.Fluid.Movers.Data.Generic per
constrainedby Annex60.Fluid.Movers.Data.Generic
;
parameter Annex60.Fluid.Types.InputType inputType = Annex60.Fluid.Types.InputType.Continuous
;
parameter Real constInput = 0 ;
parameter Real stageInputs[:]
;
parameter Boolean computePowerUsingSimilarityLaws
;
parameter Boolean addPowerToMedium=true
;
parameter Boolean nominalValuesDefineDefaultPressureCurve = false
;
parameter Modelica.SIunits.Time tau=1
;
parameter Boolean filteredSpeed=true
;
parameter Modelica.SIunits.Time riseTime=30
;
parameter Modelica.Blocks.Types.Init init=Modelica.Blocks.Types.Init.InitialOutput
;
parameter Real y_start(min=0, max=1, unit="1")=0 ;
Modelica.Blocks.Interfaces.IntegerInput stage
if
inputType == Annex60.Fluid.Types.InputType.Stages
;
Modelica.Blocks.Interfaces.RealOutput y_actual(
final unit="1")
;
Modelica.Blocks.Interfaces.RealOutput P(
quantity="Power",
final unit="W") ;
Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort
;
Modelica.SIunits.VolumeFlowRate VMachine_flow(start=_VMachine_flow) = eff.V_flow ;
Modelica.SIunits.PressureDifference dpMachine(displayUnit="Pa")=
-preSou.dp ;
Real eta(unit="1",
final quantity="Efficiency") = eff.eta ;
Real etaHyd(unit="1",
final quantity="Efficiency") = eff.etaHyd ;
Real etaMot(unit="1",
final quantity="Efficiency") = eff.etaMot ;
protected
final parameter Modelica.SIunits.VolumeFlowRate _VMachine_flow = 0
;
parameter Types.PrescribedVariable preVar ;
final parameter Boolean speedIsInput=
(preVar == Annex60.Fluid.Movers.BaseClasses.Types.PrescribedVariable.Speed)
;
final parameter Integer nOri =
size(per.pressure.V_flow, 1)
;
final parameter Boolean haveVMax = (
abs(per.pressure.dp[nOri]) < Modelica.Constants.eps)
;
final parameter Modelica.SIunits.VolumeFlowRate V_flow_max=
if per.havePressureCurve
then
(
if haveVMax
then
per.pressure.V_flow[nOri]
else
per.pressure.V_flow[nOri] - (per.pressure.V_flow[nOri] - per.pressure.V_flow[
nOri - 1])/((per.pressure.dp[nOri] - per.pressure.dp[nOri - 1]))*per.pressure.dp[nOri])
else
m_flow_nominal/rho_default ;
final parameter Modelica.SIunits.Density rho_default=
Medium.density_pTX(
p=Medium.p_default,
T=Medium.T_default,
X=Medium.X_default) ;
final parameter Medium.ThermodynamicState sta_start=
Medium.setState_pTX(
T=T_start,
p=p_start,
X=X_start) ;
final parameter Modelica.SIunits.SpecificEnthalpy h_outflow_start =
Medium.specificEnthalpy(sta_start)
;
Modelica.Blocks.Sources.Constant[
size(stageInputs, 1)] stageValues(
final k=stageInputs)
if
inputType == Annex60.Fluid.Types.InputType.Stages ;
Modelica.Blocks.Sources.Constant setConst(
final k=constInput)
if
inputType == Annex60.Fluid.Types.InputType.Constant
;
Extractor extractor(
final nin=
size(stageInputs,1))
if
inputType == Annex60.Fluid.Types.InputType.Stages ;
Modelica.Blocks.Routing.RealPassThrough inputSwitch
;
Annex60.Fluid.Delays.DelayFirstOrder vol(
redeclare final package Medium =
Medium,
final tau=tau,
final energyDynamics=energyDynamics,
final massDynamics=massDynamics,
final T_start=T_start,
final X_start=X_start,
final C_start=C_start,
final m_flow_nominal=m_flow_nominal,
final m_flow_small=m_flow_small,
final p_start=p_start,
final prescribedHeatFlowRate=true,
final allowFlowReversal=allowFlowReversal,
nPorts=2) ;
Modelica.Blocks.Continuous.Filter filter(
order=2,
f_cut=5/(2*Modelica.Constants.pi*riseTime),
final init=init,
x(
each stateSelect=StateSelect.always),
final analogFilter=Modelica.Blocks.Types.AnalogFilter.CriticalDamping,
final filterType=Modelica.Blocks.Types.FilterType.LowPass)
if
filteredSpeed
;
Modelica.Blocks.Math.Gain gaiSpe(y(
final unit="1"))
if
inputType == Annex60.Fluid.Types.InputType.Continuous
and
speedIsInput
;
Annex60.Fluid.Movers.BaseClasses.IdealSource preSou(
redeclare final package Medium =
Medium,
final m_flow_small=m_flow_small,
final allowFlowReversal=allowFlowReversal,
final control_m_flow= (preVar == Annex60.Fluid.Movers.BaseClasses.Types.PrescribedVariable.FlowRate))
;
Annex60.Fluid.Movers.BaseClasses.PowerInterface heaDis(
final motorCooledByFluid=per.motorCooledByFluid,
final delta_V_flow=1E-3*V_flow_max)
if
addPowerToMedium ;
Modelica.Blocks.Math.Add PToMed(
final k1=1,
final k2=1)
if
addPowerToMedium ;
Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow prePow(
final alpha=0)
if
addPowerToMedium
;
Modelica.Blocks.Sources.RealExpression rho_inlet(y=
Medium.density(
Medium.setState_phX(port_a.p,
inStream(port_a.h_outflow),
inStream(port_a.Xi_outflow))))
;
Annex60.Fluid.Sensors.MassFlowRate senMasFlo(
redeclare final package Medium =
Medium) ;
Sensors.RelativePressure senRelPre(
redeclare final package Medium =
Medium) ;
FlowMachineInterface eff(
per(
final hydraulicEfficiency = per.hydraulicEfficiency,
final motorEfficiency = per.motorEfficiency,
final motorCooledByFluid = per.motorCooledByFluid,
final speed_nominal = 0,
final constantSpeed = 0,
final speeds = {0},
final power = per.power),
final nOri = nOri,
final rho_default=rho_default,
final computePowerUsingSimilarityLaws=computePowerUsingSimilarityLaws,
final haveVMax=haveVMax,
final V_flow_max=V_flow_max,
r_N(start=y_start),
r_V(start=m_flow_nominal/rho_default),
final preVar=preVar) ;
protected
block Extractor
extends Modelica.Blocks.Interfaces.MISO;
Modelica.Blocks.Interfaces.IntegerInput index ;
equation
y =
sum({
if index == i
then u[i]
else 0
for i
in 1:nin});
end Extractor;
initial equation
assert(nominalValuesDefineDefaultPressureCurve
or
per.havePressureCurve
or
(preVar == Annex60.Fluid.Movers.BaseClasses.Types.PrescribedVariable.Speed),
"*** Warning: You are using a flow or pressure controlled mover with the
default pressure curve.
This leads to approximate calculations of the electrical power
consumption. Add the correct pressure curve in the record per
to obtain an accurate computation.
Setting nominalValuesDefineDefaultPressureCurve=true will suppress this warning.",
level=AssertionLevel.warning);
assert(nominalValuesDefineDefaultPressureCurve
or
(per.havePressureCurve
or
(preVar == Annex60.Fluid.Movers.BaseClasses.Types.PrescribedVariable.Speed))
or
per.use_powerCharacteristic == false,
"*** Warning: You are using a flow or pressure controlled mover with the
default pressure curve and you set use_powerCharacteristic = true.
Since this can cause wrong power consumption, the model will overwrite
this setting and use instead use_powerCharacteristic = false.
Since this causes the efficiency curve to be used,
make sure that the efficiency curves in the performance record per
are correct or add the pressure curve of the mover.
Setting nominalValuesDefineDefaultPressureCurve=true will suppress this warning.",
level=AssertionLevel.warning);
equation
connect(prePow.port, vol.heatPort);
connect(vol.heatPort, heatPort);
connect(preSou.port_b, port_b);
connect(stageValues.y, extractor.u);
connect(extractor.y, inputSwitch.u);
connect(setConst.y, inputSwitch.u);
connect(extractor.index, stage);
connect(PToMed.y, prePow.Q_flow);
connect(PToMed.u1, heaDis.Q_flow);
connect(senRelPre.port_b, preSou.port_a);
connect(senRelPre.port_a, preSou.port_b);
connect(heaDis.etaHyd,eff. etaHyd);
connect(heaDis.V_flow,eff. V_flow);
connect(eff.PEle, heaDis.PEle);
connect(eff.WFlo, heaDis.WFlo);
connect(rho_inlet.y,eff. rho);
connect(eff.m_flow, senMasFlo.m_flow);
connect(eff.PEle, P);
connect(eff.WFlo, PToMed.u2);
connect(inputSwitch.y, filter.u);
connect(senRelPre.p_rel, eff.dp_in);
connect(eff.y_out, y_actual);
connect(port_a, vol.ports[1]);
connect(vol.ports[2], senMasFlo.port_a);
connect(senMasFlo.port_b, preSou.port_a);
end PartialFlowMachine;