Buildings.Obsolete.Fluid.Movers.BaseClasses

Package with base classes for Buildings.Obsolete.Fluid.Movers

Information

This package contains base classes that are used to construct the models in Buildings.Obsolete.Fluid.Movers.

Extends from Modelica.Icons.BasesPackage (Icon for packages containing base classes).

Package Content

Name Description
Buildings.Obsolete.Fluid.Movers.BaseClasses.PartialFlowMachine PartialFlowMachine Partial model to interface fan or pump models with the medium

Buildings.Obsolete.Fluid.Movers.BaseClasses.PartialFlowMachine Buildings.Obsolete.Fluid.Movers.BaseClasses.PartialFlowMachine

Partial model to interface fan or pump models with the medium

Buildings.Obsolete.Fluid.Movers.BaseClasses.PartialFlowMachine

Information

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.

The parameter addPowerToMedium determines whether any power is added to the fluid. The default is addPowerToMedium=true, and hence the outlet enthalpy is higher than the inlet enthalpy if the flow device is operating. The setting addPowerToMedium=false is physically incorrect (since the flow work, the flow friction and the fan heat do not increase the enthalpy of the medium), but this setting does in some cases lead to simpler equations and more robust simulation, in particular if the mass flow is equal to zero.

In the previous implementation, this model extends from Buildings.Fluid.Interfaces.PartialTwoPortInterface. Now it copies much of the code instead. This is to resolve a potential circular parameter binding that occurs when Buildings.Fluid.Movers.Preconfigured.SpeedControlled_y extends from Buildings.Fluid.Movers.SpeedControlled_y. The former uses the nominal flow rate provided by user to construct the pressure curve, whilst the latter uses the user-provided pressure curve to determine the nominal flow rate. The new implementation removes the original declaration of nominal flow rate from Buildings.Fluid.Interfaces.PartialTwoPortInterface and hides it (protected _m_flow_nominal) from the user. This way, A higher-level model (e.g. Buildings.Fluid.Movers.FlowControlled_dp), can still provide a default but not the other way around. See discussions in #1705.

Extends from Buildings.Obsolete.BaseClasses.ObsoleteModel (Icon for classes that are obsolete and will be removed in later versions), Buildings.Fluid.Interfaces.LumpedVolumeDeclarations (Declarations for lumped volumes), Buildings.Fluid.Interfaces.PartialTwoPort (Partial component with two ports).

Parameters

TypeNameDefaultDescription
replaceable package MediumPartialMediumMedium in the component
Genericperredeclare parameter Building...Record with performance data
BooleancomputePowerUsingSimilarityLaws = true, compute power exactly, using similarity laws. Otherwise approximate.
BooleanaddPowerToMediumtrueSet to false to avoid any power (=heat and flow work) being added to medium (may give simpler equations)
BooleannominalValuesDefineDefaultPressureCurvefalseSet to true to avoid warning if m_flow_nominal and dp_nominal are used to construct the default pressure curve
Control
InputTypeinputTypeBuildings.Fluid.Types.InputT...Control input type
RealconstInput0Constant input set point
RealstageInputs[:] Vector of input set points corresponding to stages
Dynamics
Conservation equations
DynamicsenergyDynamicsModelica.Fluid.Types.Dynamic...Type of energy balance: dynamic (3 initialization options) or steady state
RealmSenFac1Factor for scaling the sensible thermal mass of the volume
Nominal condition
Timetau1Time constant of fluid volume for nominal flow, used if energy or mass balance is dynamic [s]
Filtered speed
Booleanuse_inputFiltertrue= true, if speed is filtered with a 2nd order CriticalDamping filter
TimeriseTime30Rise time of the filter (time to reach 99.6 % of the speed) [s]
InitinitModelica.Blocks.Types.Init.I...Type of initialization (no init/steady state/initial state/initial output)
Advanced
Dynamics
DynamicsmassDynamicsenergyDynamicsType of mass balance: dynamic (3 initialization options) or steady state, must be steady state if energyDynamics is steady state
MassFlowRatem_flow_small1E-4*abs(_m_flow_nominal)Small mass flow rate for regularization of zero flow [kg/s]
Diagnostics
Booleanshow_Tfalse= true, if actual temperature at port is computed
Initialization
AbsolutePressurep_startMedium.p_defaultStart value of pressure [Pa]
TemperatureT_startMedium.T_defaultStart value of temperature [K]
MassFractionX_start[Medium.nX]Medium.X_defaultStart value of mass fractions m_i/m [kg/kg]
ExtraPropertyC_start[Medium.nC]fill(0, Medium.nC)Start value of trace substances
ExtraPropertyC_nominal[Medium.nC]fill(1E-2, Medium.nC)Nominal value of trace substances. (Set to typical order of magnitude.)
Assumptions
BooleanallowFlowReversaltrue= false to simplify equations, assuming, but not enforcing, no flow reversal

Connectors

TypeNameDescription
FluidPort_aport_aFluid connector a (positive design flow direction is from port_a to port_b)
FluidPort_bport_bFluid connector b (positive design flow direction is from port_a to port_b)
input IntegerInputstageStage input signal for the pressure head
output RealOutputy_actualActual normalised fan or pump speed that is used for computations [1]
output RealOutputPElectrical power consumed [W]
HeatPort_aheatPortHeat dissipation to environment

Modelica definition

partial model PartialFlowMachine "Partial model to interface fan or pump models with the medium" extends Buildings.Obsolete.BaseClasses.ObsoleteModel; extends Buildings.Fluid.Interfaces.LumpedVolumeDeclarations( final massDynamics=energyDynamics, final mSenFac=1); extends Buildings.Fluid.Interfaces.PartialTwoPort( port_a( p(start=Medium.p_default), h_outflow(start=h_outflow_start)), port_b( p(start=p_start), h_outflow(start=h_outflow_start))); replaceable parameter Buildings.Obsolete.Fluid.Movers.Data.Generic per constrainedby Buildings.Obsolete.Fluid.Movers.Data.Generic "Record with performance data"; parameter Buildings.Fluid.Types.InputType inputType = Buildings.Fluid.Types.InputType.Continuous "Control input type"; parameter Real constInput = 0 "Constant input set point"; parameter Real stageInputs[:] "Vector of input set points corresponding to stages"; parameter Boolean computePowerUsingSimilarityLaws "= true, compute power exactly, using similarity laws. Otherwise approximate."; parameter Boolean addPowerToMedium=true "Set to false to avoid any power (=heat and flow work) being added to medium (may give simpler equations)"; parameter Boolean nominalValuesDefineDefaultPressureCurve = false "Set to true to avoid warning if m_flow_nominal and dp_nominal are used to construct the default pressure curve"; parameter Modelica.Units.SI.Time tau=1 "Time constant of fluid volume for nominal flow, used if energy or mass balance is dynamic"; // Classes used to implement the filtered speed parameter Boolean use_inputFilter=true "= true, if speed is filtered with a 2nd order CriticalDamping filter"; parameter Modelica.Units.SI.Time riseTime=30 "Rise time of the filter (time to reach 99.6 % of the speed)"; parameter Modelica.Blocks.Types.Init init=Modelica.Blocks.Types.Init.InitialOutput "Type of initialization (no init/steady state/initial state/initial output)"; // Connectors and ports Modelica.Blocks.Interfaces.IntegerInput stage if inputType == Buildings.Fluid.Types.InputType.Stages "Stage input signal for the pressure head"; Modelica.Blocks.Interfaces.RealOutput y_actual( final unit="1") "Actual normalised fan or pump speed that is used for computations"; Modelica.Blocks.Interfaces.RealOutput P( quantity="Power", final unit="W") "Electrical power consumed"; Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort "Heat dissipation to environment"; // Variables Modelica.Units.SI.VolumeFlowRate VMachine_flow(start=_VMachine_flow) = eff.V_flow "Volume flow rate"; Modelica.Units.SI.PressureDifference dpMachine(displayUnit="Pa") = -preSou.dp "Pressure difference"; Real eta(unit="1", final quantity="Efficiency") = eff.eta "Global efficiency"; Real etaHyd(unit="1", final quantity="Efficiency") = eff.etaHyd "Hydraulic efficiency"; Real etaMot(unit="1", final quantity="Efficiency") = eff.etaMot "Motor efficiency"; // Quantity to control // Copied from Fluid.Interfaces.PartialTwoPortInterface parameter Modelica.Units.SI.MassFlowRate m_flow_small(min=0) = 1E-4*abs( _m_flow_nominal) "Small mass flow rate for regularization of zero flow"; // Diagnostics parameter Boolean show_T = false "= true, if actual temperature at port is computed"; Modelica.Units.SI.MassFlowRate m_flow(start=_m_flow_start) = port_a.m_flow "Mass flow rate from port_a to port_b (m_flow > 0 is design flow direction)"; Modelica.Units.SI.PressureDifference dp( start=_dp_start, displayUnit="Pa") = port_a.p - port_b.p "Pressure difference between port_a and port_b"; Medium.ThermodynamicState sta_a= if allowFlowReversal then Medium.setState_phX(port_a.p, noEvent(actualStream(port_a.h_outflow)), noEvent(actualStream(port_a.Xi_outflow))) else Medium.setState_phX(port_a.p, noEvent(inStream(port_a.h_outflow)), noEvent(inStream(port_a.Xi_outflow))) if show_T "Medium properties in port_a"; Medium.ThermodynamicState sta_b= if allowFlowReversal then Medium.setState_phX(port_b.p, noEvent(actualStream(port_b.h_outflow)), noEvent(actualStream(port_b.Xi_outflow))) else Medium.setState_phX(port_b.p, noEvent(port_b.h_outflow), noEvent(port_b.Xi_outflow)) if show_T "Medium properties in port_b"; // - Copy continues in protected section protected parameter Modelica.Units.SI.MassFlowRate _m_flow_nominal= max(eff.per.pressure.V_flow)*rho_default "Nominal mass flow rate"; // Copied from Fluid.Interfaces.PartialTwoPortInterface final parameter Modelica.Units.SI.MassFlowRate _m_flow_start=0 "Start value for m_flow, used to avoid a warning if not set in m_flow, and to avoid m_flow.start in parameter window"; final parameter Modelica.Units.SI.PressureDifference _dp_start(displayUnit= "Pa") = 0 "Start value for dp, used to avoid a warning if not set in dp, and to avoid dp.start in parameter window"; // - End of copy final parameter Modelica.Units.SI.VolumeFlowRate _VMachine_flow=0 "Start value for VMachine_flow, used to avoid a warning if not specified"; parameter Buildings.Fluid.Movers.BaseClasses.Types.PrescribedVariable preVar "Type of prescribed variable"; // The parameter speedIsInput is required to conditionally remove the instance gain. // If the conditional removal of this instance where to use the test // preVar == Buildings.Fluid.Movers.BaseClasses.Types.PrescribedVariable.Speed, // then OpenModelica fails to translate the model with the message // .../PartialFlowMachine.mo:185:3-189:70:writable] // Error: Variable Types.PrescribedVariable.Speed not found in scope // Buildings.Fluid.Movers.SpeedControlled_y$floMac1. final parameter Boolean speedIsInput= (preVar == Buildings.Fluid.Movers.BaseClasses.Types.PrescribedVariable.Speed) "Parameter that is true if speed is the controlled variables"; final parameter Integer nOri = size(per.pressure.V_flow, 1) "Number of data points for pressure curve"; final parameter Boolean haveVMax = eff.haveVMax "Flag, true if user specified data that contain V_flow_max"; final parameter Modelica.Units.SI.VolumeFlowRate V_flow_max=eff.V_flow_max; final parameter Modelica.Units.SI.Density rho_default= Medium.density_pTX( p=Medium.p_default, T=Medium.T_default, X=Medium.X_default) "Default medium density"; final parameter Medium.ThermodynamicState sta_start=Medium.setState_pTX( T=T_start, p=p_start, X=X_start) "Medium state at start values"; final parameter Modelica.Units.SI.SpecificEnthalpy h_outflow_start= Medium.specificEnthalpy(sta_start) "Start value for outflowing enthalpy"; final parameter Modelica.Units.SI.Frequency fCut=5/(2*Modelica.Constants.pi* riseTime) "Cut-off frequency of filter"; Modelica.Blocks.Sources.Constant[size(stageInputs, 1)] stageValues( final k=stageInputs) if inputType == Buildings.Fluid.Types.InputType.Stages "Stage input values"; Modelica.Blocks.Sources.Constant setConst( final k=constInput) if inputType == Buildings.Fluid.Types.InputType.Constant "Constant input set point"; Extractor extractor(final nin=size(stageInputs,1)) if inputType == Buildings.Fluid.Types.InputType.Stages "Stage input extractor"; Modelica.Blocks.Routing.RealPassThrough inputSwitch "Dummy connection for easy connection of input options"; Buildings.Fluid.Delays.DelayFirstOrder vol( redeclare final package Medium = Medium, final tau=tau, final energyDynamics=energyDynamics, 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) "Fluid volume for dynamic model"; Buildings.Fluid.BaseClasses.ActuatorFilter filter( final n=2, final f=fCut, final normalized=true, final initType=init) if use_inputFilter "Second order filter to approximate dynamics of the fan or pump's speed, and to improve numerics"; Modelica.Blocks.Math.Gain gaiSpe(y(final unit="1")) if inputType == Buildings.Fluid.Types.InputType.Continuous and speedIsInput "Gain to normalized speed using speed_nominal or speed_rpm_nominal"; Buildings.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 == Buildings.Fluid.Movers.BaseClasses.Types.PrescribedVariable.FlowRate)) "Pressure source"; Buildings.Fluid.Movers.BaseClasses.PowerInterface heaDis( final motorCooledByFluid=per.motorCooledByFluid, final delta_V_flow=1E-3*V_flow_max) if addPowerToMedium "Heat dissipation into medium"; Modelica.Blocks.Math.Add PToMed(final k1=1, final k2=1) if addPowerToMedium "Heat and work input into medium"; Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow prePow( final alpha=0) if addPowerToMedium "Prescribed power (=heat and flow work) flow for dynamic model"; 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)))) "Density of the inflowing fluid"; Buildings.Fluid.Sensors.MassFlowRate senMasFlo( redeclare final package Medium = Medium) "Mass flow rate sensor"; Buildings.Fluid.Sensors.RelativePressure senRelPre( redeclare final package Medium = Medium) "Head of mover"; // Because the speed data are not used by FlowMachineInterface, we set them // to zero. Buildings.Fluid.Movers.BaseClasses.FlowMachineInterface eff( per( final powerOrEfficiencyIsHydraulic = per.powerOrEfficiencyIsHydraulic, final efficiency = per.efficiency, final motorEfficiency = per.motorEfficiency, final motorEfficiency_yMot = per.motorEfficiency_yMot, final motorCooledByFluid = per.motorCooledByFluid, final speed_nominal = 0, final constantSpeed = 0, final speeds = {0}, final power = per.power, final peak = per.peak), final nOri = nOri, final rho_default=rho_default, final computePowerUsingSimilarityLaws=computePowerUsingSimilarityLaws, r_V(start=_m_flow_nominal/rho_default), final preVar=preVar) "Flow machine"; protected block Extractor "Extract scalar signal out of signal vector dependent on IntegerRealInput index" extends Modelica.Blocks.Interfaces.MISO; Modelica.Blocks.Interfaces.IntegerInput index "Integer input for control input"; equation y = sum({if index == i then u[i] else 0 for i in 1:nin}); end Extractor; initial algorithm // The control signal is dp or m_flow but the user did not provide a fan or pump curve. // Hence, the speed is computed using default values, which likely are wrong. // Therefore, scaling the power using the speed is inaccurate. assert(nominalValuesDefineDefaultPressureCurve or per.havePressureCurve or (preVar == Buildings.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); // The control signal is dp or m_flow but the user did not provide a fan or pump curve. // Hence, the speed is computed using default values, which likely are wrong. // In addition, the user wants to use (V_flow, P) to compute the power. // This can lead to using a power that is less than the flow work. We avoid // this by ignoring the setting of per.etaHydMet. // The comment is split into two parts since otherwise the JModelica C-compiler // throws warnings. assert(nominalValuesDefineDefaultPressureCurve or (per.havePressureCurve or (preVar == Buildings.Fluid.Movers.BaseClasses.Types.PrescribedVariable.Speed)) or per.etaHydMet<> Buildings.Fluid.Movers.BaseClasses.Types.HydraulicEfficiencyMethod.Power_VolumeFlowRate, "*** Warning: You are using a flow or pressure controlled mover with the default pressure curve with per.etaHydMet set to Buildings.Fluid.Movers.BaseClasses.Types.HydraulicEfficiencyMethod.Power_VolumeFlowRate. Since this can cause wrong power consumption, the model will overwrite this setting and use instead Buildings.Fluid.Movers.BaseClasses.Types.HydraulicEfficiencyMethod.NotProvided." + "See the user guide to see what assumptions are made in this setting or provide other information to the model. Setting nominalValuesDefineDefaultPressureCurve=true will suppress this warning.", level=AssertionLevel.warning); assert(per.havePressureCurve or not (per.etaHydMet == Buildings.Fluid.Movers.BaseClasses.Types.HydraulicEfficiencyMethod.Power_VolumeFlowRate or per.etaHydMet == Buildings.Fluid.Movers.BaseClasses.Types.HydraulicEfficiencyMethod.EulerNumber), "*** Warning in "+ getInstanceName()+ ": per.etaHydMet is set to .Power_VolumeFlowRate or .EulerNumber. This requires that per.pressure be provided. Because it is not, the model will override this setting and use .NotProvided instead.", level=AssertionLevel.warning); assert(per.havePressureCurve or per.haveWMot_nominal or not (per.etaMotMet == Buildings.Fluid.Movers.BaseClasses.Types.MotorEfficiencyMethod.Efficiency_MotorPartLoadRatio or per.etaMotMet == Buildings.Fluid.Movers.BaseClasses.Types.MotorEfficiencyMethod.GenericCurve), "*** Warning in "+ getInstanceName()+ ": per.etaMotMet is set to .Efficiency_MotorPartLoadRatio or .GenericCurve. This requires that per.WMot_nominal be provided or at least per.pressure be provided so that per.WMot_nominal can be estimated. Because neither is provided, the model will override this setting and use .NotProvided instead.", level=AssertionLevel.warning); assert(per.powerOrEfficiencyIsHydraulic or not (per.etaMotMet == Buildings.Fluid.Movers.BaseClasses.Types.MotorEfficiencyMethod.Efficiency_MotorPartLoadRatio or per.etaMotMet == Buildings.Fluid.Movers.BaseClasses.Types.MotorEfficiencyMethod.GenericCurve), "*** Warning in "+ getInstanceName()+ ": per.etaMotMet is set to .Efficiency_MotorPartLoadRatio or .GenericCurve while information is provided for total electric power instead of hydraulic power. This forms an algebraic loop and may cause the simulation to not converge (see the \"Motor efficiency\" section in usersguide).", 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.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.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); connect(eff.WHyd, heaDis.WHyd); connect(eff.PEle, P); end PartialFlowMachine;

Buildings.Obsolete.Fluid.Movers.BaseClasses.PartialFlowMachine.Extractor Buildings.Obsolete.Fluid.Movers.BaseClasses.PartialFlowMachine.Extractor

Extract scalar signal out of signal vector dependent on IntegerRealInput index

Buildings.Obsolete.Fluid.Movers.BaseClasses.PartialFlowMachine.Extractor

Information

Extends from Modelica.Blocks.Interfaces.MISO (Multiple Input Single Output continuous control block).

Parameters

TypeNameDefaultDescription
Integernin1Number of inputs

Connectors

TypeNameDescription
input RealInputu[nin]Connector of Real input signals
output RealOutputyConnector of Real output signal
input IntegerInputindexInteger input for control input

Modelica definition

block Extractor "Extract scalar signal out of signal vector dependent on IntegerRealInput index" extends Modelica.Blocks.Interfaces.MISO; Modelica.Blocks.Interfaces.IntegerInput index "Integer input for control input"; equation y = sum({if index == i then u[i] else 0 for i in 1:nin}); end Extractor;