Name | Description |
---|---|
Characteristics | Functions for fan or pump characteristics |
assertPositiveDifference | |
FlowMachine | Fan or pump with ideally controlled mass flow rate or pressure difference |
PartialFlowMachine | Base model for fans or pumps |
Type | Name | Default | Description |
---|---|---|---|
Pressure | p | [Pa] | |
Pressure | p_sat | [Pa] | |
String | message |
Type | Name | Description |
---|---|---|
Pressure | dp | [Pa] |
function assertPositiveDifference extends Modelica.Icons.Function; input Modelica.SIunits.Pressure p; input Modelica.SIunits.Pressure p_sat; input String message; output Modelica.SIunits.Pressure dp; algorithm dp := p - p_sat; assert(p >= p_sat, message); end assertPositiveDifference;
This model describes a fan or pump (or a group of nParallel fans/pumps) with ideally controlled mass flow rate or pressure.
Nominal values are used to predefine an exemplary fan or pump characteristics and to define the operation of the fan/pump. The input connectors m_flow_set or dp_set can optionally be enabled to provide time varying set points.
Use this model if the fan or pump characteristics is of secondary interest. The actual characteristics can be configured later on for the appropriate rotational speed N. Then the model can be replaced with Buildings.Fluid.Movers.FlowMachine_y or Buildings.Fluid.Movers.FlowMachine_N_rpm or
Extends from Buildings.Fluid.Movers.BaseClasses.PartialFlowMachine (Base model for fans or pumps).
Type | Name | Default | Description |
---|---|---|---|
replaceable package Medium | PartialMedium | Medium in the component | |
AbsolutePressure | p_a_nominal | system.p_start | Nominal inlet pressure for predefined fan or pump characteristics [Pa] |
AbsolutePressure | dp_set_nominal | 1000 | Nominal total pressure difference, fixed if not control_m_flow and not use_dp_set [Pa] |
MassFlowRate | m_flow_nominal | Nominal mass flow rate, fixed if control_m_flow and not use_m_flow_set [kg/s] | |
Boolean | control_m_flow | true | = false to control outlet pressure port_b.p instead of m_flow |
Boolean | use_m_flow_set | false | = true to use input signal m_flow_set instead of m_flow_nominal |
Boolean | use_dp_set | false | = true to use input signal dp_set instead of dp_set_nominal |
Characteristics | |||
Integer | nParallel | 1 | Number of fans or pumps in parallel |
replaceable function flowCharacteristic | Characteristics.quadraticFlo... | Total pressure vs. V_flow characteristic at nominal speed | |
AngularVelocity_rpm | N_nominal | 1500 | Nominal rotational speed for flow characteristic [1/min] |
Density | rho_nominal | Medium.density_pTX(Medium.p_... | Nominal fluid density [kg/m3] |
Boolean | use_powerCharacteristic | false | Use powerCharacteristic (vs. efficiencyCharacteristic) |
replaceable function powerCharacteristic | Characteristics.quadraticPow... | Power consumption vs. V_flow at nominal speed and density | |
replaceable function efficiencyCharacteristic | Characteristics.constantEffi... | Efficiency vs. V_flow at nominal speed and density | |
Assumptions | |||
Boolean | allowFlowReversal | system.allowFlowReversal | = true to allow flow reversal, false restricts to design direction (port_a -> port_b) |
Boolean | checkValve | false | = true to prevent reverse flow |
Volume | V | 0 | Volume inside the pump [m3] |
Dynamics | |||
Dynamics | energyDynamics | Modelica.Fluid.Types.Dynamic... | Formulation of energy balance |
Dynamics | massDynamics | energyDynamics | Formulation of mass balance |
Heat transfer | |||
Boolean | use_HeatTransfer | false | = true to use a HeatTransfer model, e.g. for a housing |
replaceable model HeatTransfer | IdealHeatTransfer | Wall heat transfer | |
Initialization | |||
AbsolutePressure | p_a_start | system.p_start | Guess value for inlet pressure [Pa] |
AbsolutePressure | p_b_start | p_a_start | Guess value for outlet pressure [Pa] |
MassFlowRate | m_flow_start | 1 | Guess value of m_flow = port_a.m_flow [kg/s] |
Boolean | use_T_start | true | = true, use T_start, otherwise h_start |
Temperature | T_start | if use_T_start then system.T... | Start value of temperature [K] |
SpecificEnthalpy | h_start | if use_T_start then Medium.s... | Start value of specific enthalpy [J/kg] |
MassFraction | X_start[Medium.nX] | Medium.X_default | Start value of mass fractions m_i/m [kg/kg] |
ExtraProperty | C_start[Medium.nC] | fill(0, Medium.nC) | Start value of trace substances |
Advanced | |||
Diagnostics | |||
Boolean | show_NPSHa | false | = true to compute Net Positive Suction Head available |
Type | Name | Description |
---|---|---|
FluidPort_a | port_a | Fluid connector a (positive design flow direction is from port_a to port_b) |
FluidPort_b | port_b | Fluid connector b (positive design flow direction is from port_a to port_b) |
HeatPort_a | heatPort | |
input RealInput | m_flow_set | Prescribed mass flow rate |
input RealInput | dp_set | Prescribed outlet pressure |
Characteristics | ||
replaceable function flowCharacteristic | Total pressure vs. V_flow characteristic at nominal speed |
model FlowMachine "Fan or pump with ideally controlled mass flow rate or pressure difference" import Modelica.SIunits.Conversions.NonSIunits.AngularVelocity_rpm; extends Buildings.Fluid.Movers.BaseClasses.PartialFlowMachine( N_nominal=1500, N(start=N_nominal), redeclare replaceable function flowCharacteristic = Characteristics.quadraticFlow (V_flow_nominal={0,V_flow_op,1.5* V_flow_op}, dp_nominal={2*dp_op,dp_op,0})); // nominal values parameter Medium.AbsolutePressure p_a_nominal(displayUnit="Pa") = system.p_start "Nominal inlet pressure for predefined fan or pump characteristics"; parameter Medium.AbsolutePressure dp_set_nominal(displayUnit="Pa") = 1000 "Nominal total pressure difference, fixed if not control_m_flow and not use_dp_set"; parameter Medium.MassFlowRate m_flow_nominal "Nominal mass flow rate, fixed if control_m_flow and not use_m_flow_set"; // what to control parameter Boolean control_m_flow = true "= false to control outlet pressure port_b.p instead of m_flow"; parameter Boolean use_m_flow_set = false "= true to use input signal m_flow_set instead of m_flow_nominal"; parameter Boolean use_dp_set = false "= true to use input signal dp_set instead of dp_set_nominal"; // exemplary characteristics final parameter Modelica.SIunits.VolumeFlowRate V_flow_op=m_flow_nominal/ rho_nominal "operational volume flow rate according to nominal values"; final parameter Modelica.SIunits.AbsolutePressure dp_op=dp_set_nominal "operational fan or pump total pressure according to nominal values";Modelica.Blocks.Interfaces.RealInput m_flow_set if use_m_flow_set "Prescribed mass flow rate"; Modelica.Blocks.Interfaces.RealInput dp_set if use_dp_set "Prescribed outlet pressure"; protected Modelica.Blocks.Interfaces.RealInput m_flow_set_internal "Needed to connect to conditional connector"; Modelica.Blocks.Interfaces.RealInput dp_set_internal "Needed to connect to conditional connector"; equation // Ideal control if control_m_flow then m_flow = m_flow_set_internal; else dp = dp_set_internal; end if; // Internal connector value when use_m_flow_set = false if not use_m_flow_set then m_flow_set_internal = m_flow_nominal; end if; if not use_dp_set then dp_set_internal = dp_set_nominal; end if; connect(m_flow_set, m_flow_set_internal); connect(dp_set, dp_set_internal); assert(dp_set_internal >= 0, "dp_set cannot be negative. Obtained dp_set = " + realString(dp_set_internal));end FlowMachine;
This is the base model for fans and pumps.
The model is similar to Modelica.Fluid.Machines.BaseClasses.PartialPump, except for the parameterization which has been changed so that the model is also applicable for fans. See the revision notes of this model for details.
The model describes a fan or pump, or a group of nParallel identical fans or pumps. The model is based on the theory of kinematic similarity: the fan or pump characteristics are given for nominal operating conditions (rotational speed and fluid density), and then adapted to actual operating condition, according to the similarity equations.
Fan or pump characteristics
The nominal hydraulic characteristic (total pressure vs. volume flow rate) is given by the the replaceable function flowCharacteristic.
The fan or pump energy balance can be specified in two alternative ways:
Several functions are provided in the package Characteristics to specify the characteristics as a function of some operating points at nominal conditions.
Depending on the value of the checkValve parameter, the model either supports reverse flow conditions, or includes a built-in check valve to avoid flow reversal.
It is possible to take into account the heat capacity of the fluid inside the fan or pump by specifying its volume V; this is necessary to avoid singularities in the computation of the outlet enthalpy in case of zero flow rate. If zero flow rate conditions are always avoided, this dynamic effect can be neglected by leaving the default value V = 0, thus avoiding a fast state variable in the model.
Dynamics options
Steady-state mass and energy balances are assumed per default, neglecting the holdup of fluid in the fan or pump. Dynamic mass and energy balance can be used by setting the corresponding dynamic parameters. This might be desirable if the fan or pump is assembled together with valves before port_a and behind port_b. If both valves are closed, then the fluid is useful to define the thermodynamic state and in particular the absolute pressure in the fan or pump. Note that the flowCharacteristic only specifies a pressure difference.
Heat transfer
The boolean paramter use_HeatTransfer can be set to true if heat exchanged with the environment should be taken into account or to model a housing. This might be desirable if a fan or pump with realistic powerCharacteristic for zero flow operates while a valve prevents fluid flow.
Diagnostics of Cavitation
The boolean parameter show_NPSHa can set true to compute the Net Positive Suction Head available and check for cavitation, provided a two-phase medium model is used.
Extends from Modelica.Fluid.Interfaces.PartialTwoPort (Partial component with two ports), Modelica.Fluid.Interfaces.PartialLumpedVolume (Lumped volume with mass and energy balance).
Type | Name | Default | Description |
---|---|---|---|
replaceable package Medium | PartialMedium | Medium in the component | |
Volume | fluidVolume | V | Volume [m3] |
Characteristics | |||
Integer | nParallel | 1 | Number of fans or pumps in parallel |
AngularVelocity_rpm | N_nominal | 1500 | Nominal rotational speed for flow characteristic [1/min] |
Density | rho_nominal | Medium.density_pTX(Medium.p_... | Nominal fluid density [kg/m3] |
Boolean | use_powerCharacteristic | false | Use powerCharacteristic (vs. efficiencyCharacteristic) |
Assumptions | |||
Boolean | allowFlowReversal | system.allowFlowReversal | = true to allow flow reversal, false restricts to design direction (port_a -> port_b) |
Boolean | checkValve | false | = true to prevent reverse flow |
Volume | V | 0 | Volume inside the pump [m3] |
Dynamics | |||
Dynamics | energyDynamics | Modelica.Fluid.Types.Dynamic... | Formulation of energy balance |
Dynamics | massDynamics | energyDynamics | Formulation of mass balance |
Heat transfer | |||
Boolean | use_HeatTransfer | false | = true to use a HeatTransfer model, e.g. for a housing |
Initialization | |||
AbsolutePressure | p_a_start | system.p_start | Guess value for inlet pressure [Pa] |
AbsolutePressure | p_b_start | p_a_start | Guess value for outlet pressure [Pa] |
MassFlowRate | m_flow_start | 1 | Guess value of m_flow = port_a.m_flow [kg/s] |
AbsolutePressure | p_start | p_b_start | Start value of pressure [Pa] |
Boolean | use_T_start | true | = true, use T_start, otherwise h_start |
Temperature | T_start | if use_T_start then system.T... | Start value of temperature [K] |
SpecificEnthalpy | h_start | if use_T_start then Medium.s... | Start value of specific enthalpy [J/kg] |
MassFraction | X_start[Medium.nX] | Medium.X_default | Start value of mass fractions m_i/m [kg/kg] |
ExtraProperty | C_start[Medium.nC] | fill(0, Medium.nC) | Start value of trace substances |
Advanced | |||
Diagnostics | |||
Boolean | show_NPSHa | false | = true to compute Net Positive Suction Head available |
Type | Name | Description |
---|---|---|
HeatPort_a | heatPort |
partial model PartialFlowMachine "Base model for fans or pumps" // import Modelica.SIunits.Conversions.NonSIunits.*; import Modelica.Constants; extends Modelica.Fluid.Interfaces.PartialTwoPort( port_b_exposesState = energyDynamics<>Modelica.Fluid.Types.Dynamics.SteadyState or massDynamics<>Modelica.Fluid.Types.Dynamics.SteadyState, port_a( p(start=p_a_start), m_flow(start = m_flow_start, min = if allowFlowReversal and not checkValve then -Constants.inf else 0)), port_b( p(start=p_b_start), m_flow(start = -m_flow_start, max = if allowFlowReversal and not checkValve then +Constants.inf else 0))); // Initialization parameter Medium.AbsolutePressure p_a_start=system.p_start "Guess value for inlet pressure"; parameter Medium.AbsolutePressure p_b_start=p_a_start "Guess value for outlet pressure"; parameter Medium.MassFlowRate m_flow_start = 1 "Guess value of m_flow = port_a.m_flow"; // Characteristics parameter Integer nParallel(min=1) = 1 "Number of fans or pumps in parallel"; replaceable function flowCharacteristic = Characteristics.baseFlow "Total pressure vs. V_flow characteristic at nominal speed"; parameter Modelica.SIunits.Conversions.NonSIunits.AngularVelocity_rpm N_nominal = 1500 "Nominal rotational speed for flow characteristic"; parameter Medium.Density rho_nominal = Medium.density_pTX(Medium.p_default, Medium.T_default, Medium.X_default) "Nominal fluid density"; parameter Boolean use_powerCharacteristic = false "Use powerCharacteristic (vs. efficiencyCharacteristic)"; replaceable function powerCharacteristic = Characteristics.quadraticPower ( V_flow_nominal={0,0,0},W_nominal={0,0,0}) "Power consumption vs. V_flow at nominal speed and density"; replaceable function efficiencyCharacteristic = Characteristics.constantEfficiency(eta_nominal = 0.8) constrainedby Characteristics.baseEfficiency "Efficiency vs. V_flow at nominal speed and density"; // Assumptions parameter Boolean checkValve=false "= true to prevent reverse flow"; parameter Modelica.SIunits.Volume V=0 "Volume inside the pump"; // Energy and mass balance extends Modelica.Fluid.Interfaces.PartialLumpedVolume( final fluidVolume = V, energyDynamics = Modelica.Fluid.Types.Dynamics.SteadyState, massDynamics = energyDynamics, final p_start = p_b_start); // Heat transfer through boundary, e.g. to add a housing parameter Boolean use_HeatTransfer = false "= true to use a HeatTransfer model, e.g. for a housing"; replaceable model HeatTransfer = Modelica.Fluid.Vessels.BaseClasses.HeatTransfer.IdealHeatTransfer constrainedby Modelica.Fluid.Vessels.BaseClasses.HeatTransfer.PartialVesselHeatTransfer "Wall heat transfer";HeatTransfer heatTransfer( redeclare final package Medium = Medium, final n=1, surfaceAreas={4*Modelica.Constants.pi*(3/4*V/Modelica.Constants.pi)^(2/3)}, final states = {medium.state}, final use_k = use_HeatTransfer); Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort if use_HeatTransfer; // Variables // final parameter Modelica.SIunits.Acceleration g=system.g; // Medium.Density rho = medium.d; Modelica.SIunits.Pressure dp(displayUnit="Pa")=port_b.p - port_a.p "Pressure increase"; // Modelica.SIunits.Height head=dp_pump/(medium.d*g) "Pump head"; Modelica.SIunits.MassFlowRate m_flow=port_a.m_flow "Mass flow rate (total)"; Modelica.SIunits.MassFlowRate m_flow_single=m_flow/nParallel "Mass flow rate (single pump)"; Modelica.SIunits.VolumeFlowRate V_flow=m_flow/medium.d "Volume flow rate (total)"; Modelica.SIunits.VolumeFlowRate V_flow_single(start=m_flow_start/rho_nominal/ nParallel)=V_flow/nParallel "Volume flow rate (single pump)"; Modelica.SIunits.Conversions.NonSIunits.AngularVelocity_rpm N(min=0, start = N_nominal) "Shaft rotational speed"; Modelica.SIunits.Power W_single "Power consumption (single fan or pump)"; Modelica.SIunits.Power W_total=W_single*nParallel "Power consumption (total)"; Real eta "Global efficiency"; Real s(start = m_flow_start) "Curvilinear abscissa for the flow curve in parametric form (either mass flow rate or total pressure)"; // Diagnostics parameter Boolean show_NPSHa = false "= true to compute Net Positive Suction Head available"; Medium.ThermodynamicState state_a= Medium.setState_phX(port_a.p, inStream(port_a.h_outflow), inStream(port_a.Xi_outflow)) if show_NPSHa "state for medium inflowing through port_a"; Medium.Density rho_in = Medium.density(state_a) if show_NPSHa "Liquid density at the inlet port_a"; Modelica.SIunits.Length NPSHa=NPSPa/(rho_in*system.g) if show_NPSHa "Net Positive Suction Head available"; Modelica.SIunits.Pressure NPSPa=assertPositiveDifference( port_a.p, Medium.saturationPressure(Medium.temperature(state_a)), "Cavitation occurs at the pump inlet") if show_NPSHa "Net Positive Suction Pressure available"; Modelica.SIunits.Pressure NPDPa=assertPositiveDifference( port_b.p, Medium.saturationPressure(medium.T), "Cavitation occurs in the pump") if show_NPSHa "Net Positive Discharge Pressure available"; // constant Modelica.SIunits.Height unitHead=1; protected constant Modelica.SIunits.Pressure unitPressure=1; constant Modelica.SIunits.MassFlowRate unitMassFlowRate=1; equation // Flow equations if not checkValve then // Regular flow characteristics without check valve // With a replaceable function, Dymola 7.3 does not find the derivative function. // Support request: Dynasim #10872 dp = (N/N_nominal)^2*flowCharacteristic(V_flow_single*(N_nominal/N)); // With the statement below, Dymola 7.3 finds the derivative function // dp = (N/N_nominal)^2*Buildings.Fluid.Movers.BaseClasses.Characteristics.quadraticFlow(V_flow_nominal={0,1.8,3}, dp_nominal={1000,600,0}, // V_flow=V_flow_single*(N_nominal/N)); s = 0; elseif s > 0 then // Flow characteristics when check valve is open dp = (N/N_nominal)^2*flowCharacteristic(V_flow_single*(N_nominal/N)); V_flow_single = s*unitMassFlowRate/medium.d; else // Flow characteristics when check valve is closed dp = (N/N_nominal)^2*flowCharacteristic(0) - s*unitPressure; V_flow_single = 0; end if; // Power consumption if use_powerCharacteristic then W_single = (N/N_nominal)^3*(medium.d/rho_nominal)*powerCharacteristic(V_flow_single*(N_nominal/N)); eta = dp*V_flow_single/W_single; else eta = efficiencyCharacteristic(V_flow_single*(N_nominal/N)); W_single = dp*V_flow_single/eta; end if; // Energy balance Wb_flow = W_total; Qb_flow = heatTransfer.Q_flows[1]; Hb_flow = port_a.m_flow*actualStream(port_a.h_outflow) + port_b.m_flow*actualStream(port_b.h_outflow); // Ports port_a.h_outflow = medium.h; port_b.h_outflow = medium.h; port_b.p = medium.p "outlet pressure is equal to medium pressure, which includes Wb_flow"; // Mass balance mb_flow = port_a.m_flow + port_b.m_flow; mbXi_flow = port_a.m_flow*actualStream(port_a.Xi_outflow) + port_b.m_flow*actualStream(port_b.Xi_outflow); port_a.Xi_outflow = medium.Xi; port_b.Xi_outflow = medium.Xi; mbC_flow = port_a.m_flow*actualStream(port_a.C_outflow) + port_b.m_flow*actualStream(port_b.C_outflow); port_a.C_outflow = C; port_b.C_outflow = C;connect(heatTransfer.heatPorts[1], heatPort); end PartialFlowMachine;
Type | Name | Default | Description |
---|---|---|---|
Ambient | |||
CoefficientOfHeatTransfer | k | 0 | Heat transfer coefficient to ambient [W/(m2.K)] |
Temperature | T_ambient | system.T_ambient | Ambient temperature [K] |
Internal Interface | |||
replaceable package Medium | PartialMedium | Medium in the component | |
Integer | n | 1 | Number of heat transfer segments |
Boolean | use_k | false | = true to use k value for thermal isolation |
Type | Name | Description |
---|---|---|
HeatPorts_a | heatPorts[n] | Heat port to component boundary |
replaceable model HeatTransfer = Modelica.Fluid.Vessels.BaseClasses.HeatTransfer.IdealHeatTransfer constrainedby Modelica.Fluid.Vessels.BaseClasses.HeatTransfer.PartialVesselHeatTransfer "Wall heat transfer";