Package with base classes for Buildings.Fluid
Information
This package contains base classes that are used to construct the models in
Buildings.Fluid.
Extends from Modelica.Icons.BasesPackage (Icon for packages containing base classes).
Package Content
Name |
Description |
ActuatorFilter
|
Filter used for actuators of valves, dampers and movers |
IndexMassFraction
|
Computes the index of a substance in the mass fraction vector Xi |
MassFlowRateMultiplier
|
Model that multiplies the mass flow rate |
PartialResistance
|
Partial model for a hydraulic resistance |
PartialThreeWayResistance
|
Flow splitter with partial resistance model at each port |
FlowModels
|
Flow models for pressure drop calculations |
Validation
|
Collection of validation models |
Filter used for actuators of valves, dampers and movers
Information
This block implements a filter that is used to approximate the actuators
of valves, dampers and fans.
Implementation
The implementation is based on
Modelica.Blocks.Continuous.CriticalDamping.
It differs from that model in that the internal state of the filter s
is transformed using x = u_nominal*s
.
It turns out that this transformation leads to smaller system of nonlinear equations if u_nominal ≠ 0
, see
IBPSA, #1498
for a discussion.
Extends from Modelica.Blocks.Interfaces.SISO (Single Input Single Output continuous control block).
Parameters
Type | Name | Default | Description |
Frequency | f | | Cut-off frequency [Hz] |
Boolean | normalized | true | = true, if amplitude at f_cut is 3 dB, otherwise unmodified filter |
Real | u_nominal | 1 | Magnitude of input |
Initialization |
Init | initType | Modelica.Blocks.Types.Init.N... | Type of initialization (1: no init, 2: steady state, 3: initial state, 4: initial output) |
Real | x_start[n] | zeros(n) | Initial or guess values of states |
Real | y_start | 0.0 | Initial value of output (remaining states are in steady state) |
Connectors
Type | Name | Description |
input RealInput | u | Connector of Real input signal |
output RealOutput | y | Connector of Real output signal |
Modelica definition
block ActuatorFilter
import Modelica.Blocks.Types.Init;
extends Modelica.Blocks.Interfaces.SISO;
constant Integer n=2 ;
parameter Modelica.Units.SI.Frequency f(start=1) ;
parameter Boolean normalized = true
;
parameter Modelica.Blocks.Types.Init initType=Modelica.Blocks.Types.Init.NoInit
;
parameter Real x_start[n]=
zeros(n) ;
parameter Real y_start=0.0
;
parameter Real u_nominal = 1 ;
Real x[n](
each final stateSelect=StateSelect.never) = u_nom*s
;
protected
final parameter Real u_nom =
if abs(u_nominal-1) < 1E-12
then 1-1E-12
else u_nominal
;
parameter Real alpha=
if normalized
then sqrt(2^(1/n) - 1)
else 1.0
;
parameter Real w_u=2*Modelica.Constants.pi*f/alpha/u_nom;
Real s[n](start=x_start/u_nom) ;
initial equation
if initType == Init.SteadyState
then
der(s) =
zeros(n);
elseif initType == Init.InitialState
then
s = x_start/u_nom;
elseif initType == Init.InitialOutput
then
y = y_start;
der(s[1:n - 1]) =
zeros(n - 1);
end if;
equation
der(s[1]) = (u - u_nom*s[1])*w_u;
for i
in 2:n
loop
der(s[i]) = (u_nom*s[i - 1] - u_nom*s[i])*w_u;
end for;
y =u_nom*s[n];
end ActuatorFilter;
Computes the index of a substance in the mass fraction vector Xi
Information
This block computes the index that the subtance with name
substanceName
has in the mass fraction vector X
.
If the medium model has no component called substanceName
,
then the block writes an error message and terminates the simulation.
This block is used for example to obtain the index of the subtance 'water'
to obtain the water vapor concentration, or to measure any other mass fraction.
Parameters
Type | Name | Default | Description |
replaceable package Medium | Modelica.Media.Interfaces.Pa... | Medium model |
String | substanceName | "" | Name of species substance |
Connectors
Type | Name | Description |
replaceable package Medium | Medium model |
Modelica definition
block IndexMassFraction
replaceable package Medium =
Modelica.Media.Interfaces.PartialCondensingGases ;
parameter String substanceName="" ;
protected
parameter Integer i_x =
sum(
if Modelica.Utilities.Strings.isEqual(string1=Medium.substanceNames[i],
string2=substanceName,
caseSensitive=false)
then i
else 0
for i
in 1:Medium.nXi) ;
initial equation
assert(i_x > 0, "Substance '" + substanceName + "' is not present in medium '"
+ Medium.mediumName + "'.\n"
+ "Change medium model to one that has '" + substanceName + "' as a substance.");
end IndexMassFraction;
Model that multiplies the mass flow rate
Information
This model multiplies the mass flow rate so that
0 = port_b.m_flow + gain * port_a.m_flow
where gain > 0
is either equal to
the input variable u
if use_input
is set to true
, or equal to
the parameter k
if use_input
is set to false
.
The specific enthalpy, the species concentration and the trace substance concentration
remain unchanged.
Therefore, this model does not conserve mass or energy.
It is used in
Buildings.Fluid.Geothermal.Borefields.BaseClasses.PartialBorefield
and also in the Buildings library
to avoid having to instantiate circuits in parallel, with each
having the same mass flow rate and temperatures.
Extends from Buildings.Fluid.Interfaces.PartialTwoPort (Partial component with two ports).
Parameters
Type | Name | Default | Description |
replaceable package Medium | PartialMedium | Medium in the component |
Boolean | use_input | false | Set to true for multiplier factor provided as an input instead of a parameter |
Real | k | 1 | Gain for mass flow rate |
Assumptions |
Boolean | allowFlowReversal | true | = false to simplify equations, assuming, but not enforcing, no flow reversal |
Connectors
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) |
input RealInput | u | Multiplier factor [1] |
output RealOutput | uInv | Inverse of the multiplier factor |
Modelica definition
model MassFlowRateMultiplier
extends Buildings.Fluid.Interfaces.PartialTwoPort;
parameter Boolean use_input=false
;
parameter Real k=1
;
Modelica.Blocks.Interfaces.RealInput u(
final unit="1",
final min=Modelica.Constants.small)
if use_input
;
Modelica.Blocks.Interfaces.RealOutput uInv
if use_input
;
protected
Modelica.Blocks.Interfaces.RealInput u_internal
;
Modelica.Blocks.Sources.Constant cst(
final k=k)
if not use_input
;
Modelica.Blocks.Math.Division div1
if use_input
;
Modelica.Blocks.Sources.Constant one(
final k=1)
if use_input
;
initial equation
assert(k > Modelica.Constants.small,
"Gain must be strictly positive. Received k = " +
String(k));
equation
assert(u_internal > Modelica.Constants.small,
"Gain must be strictly positive. Received u = " +
String(u_internal));
port_a.p = port_b.p;
port_b.m_flow = -u_internal * port_a.m_flow;
port_a.h_outflow =
inStream(port_b.h_outflow);
port_b.h_outflow =
inStream(port_a.h_outflow);
port_a.Xi_outflow =
inStream(port_b.Xi_outflow);
port_b.Xi_outflow =
inStream(port_a.Xi_outflow);
port_a.C_outflow =
inStream(port_b.C_outflow);
port_b.C_outflow =
inStream(port_a.C_outflow);
connect(cst.y, u_internal);
connect(u_internal, div1.u2);
connect(one.y, div1.u1);
connect(div1.y, uInv);
connect(u, u_internal);
end MassFlowRateMultiplier;
Partial model for a hydraulic resistance
Information
Partial model for a flow resistance, possible with variable flow coefficient.
Models that extend this class need to implement an equation that relates
m_flow
and dp
, and they need to assign the parameter
m_flow_turbulent
.
See for example
Buildings.Fluid.FixedResistances.PressureDrop for a model that extends
this base class.
Extends from Buildings.Fluid.Interfaces.PartialTwoPortInterface (Partial model with two ports and declaration of quantities that are used by many models).
Parameters
Type | Name | Default | Description |
replaceable package Medium | PartialMedium | Medium in the component |
MassFlowRate | m_flow_turbulent | | Turbulent flow if |m_flow| >= m_flow_turbulent [kg/s] |
Nominal condition |
MassFlowRate | m_flow_nominal | | Nominal mass flow rate [kg/s] |
PressureDifference | dp_nominal | | Pressure drop at nominal mass flow rate [Pa] |
Assumptions |
Boolean | allowFlowReversal | true | = false to simplify equations, assuming, but not enforcing, no flow reversal |
Advanced |
MassFlowRate | m_flow_small | 1E-4*abs(m_flow_nominal) | Small mass flow rate for regularization of zero flow [kg/s] |
Boolean | from_dp | false | = true, use m_flow = f(dp) else dp = f(m_flow) |
Boolean | linearized | false | = true, use linear relation between m_flow and dp for any flow rate |
Diagnostics |
Boolean | show_T | false | = true, if actual temperature at port is computed |
Connectors
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) |
Modelica definition
partial model PartialResistance
extends Buildings.Fluid.Interfaces.PartialTwoPortInterface(
show_T=false,
dp(nominal=
if dp_nominal_pos > Modelica.Constants.eps
then dp_nominal_pos
else 1),
m_flow(
nominal=
if m_flow_nominal_pos > Modelica.Constants.eps
then m_flow_nominal_pos
else 1),
final m_flow_small = 1E-4*
abs(m_flow_nominal));
constant Boolean homotopyInitialization = true ;
parameter Boolean from_dp = false
;
parameter Modelica.Units.SI.PressureDifference dp_nominal(displayUnit="Pa")
;
parameter Boolean linearized = false
;
parameter Modelica.Units.SI.MassFlowRate m_flow_turbulent(min=0)
;
protected
parameter Medium.ThermodynamicState sta_default=
Medium.setState_pTX(T=Medium.T_default, p=Medium.p_default, X=Medium.X_default);
parameter Modelica.Units.SI.DynamicViscosity eta_default=
Medium.dynamicViscosity(sta_default)
;
final parameter Modelica.Units.SI.MassFlowRate m_flow_nominal_pos=
abs(
m_flow_nominal) ;
final parameter Modelica.Units.SI.PressureDifference dp_nominal_pos(
displayUnit="Pa") =
abs(dp_nominal)
;
initial equation
assert(homotopyInitialization, "In " +
getInstanceName() +
": The constant homotopyInitialization has been modified from its default value. This constant will be removed in future releases.",
level = AssertionLevel.warning);
equation
port_a.h_outflow =
if allowFlowReversal
then inStream(port_b.h_outflow)
else Medium.h_default;
port_b.h_outflow =
inStream(port_a.h_outflow);
port_a.m_flow + port_b.m_flow = 0;
port_a.Xi_outflow =
if allowFlowReversal
then inStream(port_b.Xi_outflow)
else Medium.X_default[1:Medium.nXi];
port_b.Xi_outflow =
inStream(port_a.Xi_outflow);
port_a.C_outflow =
if allowFlowReversal
then inStream(port_b.C_outflow)
else zeros(Medium.nC);
port_b.C_outflow =
inStream(port_a.C_outflow);
end PartialResistance;
Flow splitter with partial resistance model at each port
Information
Partial model for flow resistances with three ports such as a
flow mixer/splitter or a three way valve.
If energyDynamics ≠ Modelica.Fluid.Types.Dynamics.SteadyState
,
then at the junction of the three flows,
a mixing volume will be present. This will introduce a dynamic energy and momentum
balance, which often breaks algebraic loops.
The time constant of the mixing volume is determined by the parameter tau
.
Extends from Buildings.Fluid.Interfaces.LumpedVolumeDeclarations (Declarations for lumped volumes).
Parameters
Type | Name | Default | Description |
replaceable package Medium | PartialMedium | Medium in the component |
PartialTwoPortInterface | res1 | redeclare Buildings.Fluid.In... | Partial model, to be replaced with a fluid component |
PartialTwoPortInterface | res2 | redeclare Buildings.Fluid.In... | Partial model, to be replaced with a fluid component |
PartialTwoPortInterface | res3 | redeclare Buildings.Fluid.In... | Partial model, to be replaced with a fluid component |
Dynamics |
Conservation equations |
Dynamics | energyDynamics | Modelica.Fluid.Types.Dynamic... | Type of energy balance: dynamic (3 initialization options) or steady state |
MassFlowRate | mDyn_flow_nominal | | Nominal mass flow rate for dynamic momentum and energy balance [kg/s] |
Real | mSenFac | 1 | Factor for scaling the sensible thermal mass of the volume |
Nominal condition |
Time | tau | 10 | Time constant at nominal flow for dynamic energy and momentum balance [s] |
Advanced |
Dynamics |
Dynamics | massDynamics | energyDynamics | Type of mass balance: dynamic (3 initialization options) or steady state, must be steady state if energyDynamics is steady state |
Boolean | from_dp | true | = true, use m_flow = f(dp) else dp = f(m_flow) |
PortFlowDirection | portFlowDirection_1 | Modelica.Fluid.Types.PortFlo... | Flow direction for port_1 |
PortFlowDirection | portFlowDirection_2 | Modelica.Fluid.Types.PortFlo... | Flow direction for port_2 |
PortFlowDirection | portFlowDirection_3 | Modelica.Fluid.Types.PortFlo... | Flow direction for port_3 |
Boolean | verifyFlowReversal | false | =true, to assert that the flow does not reverse when portFlowDirection_* does not equal Bidirectional |
MassFlowRate | m_flow_small | | Small mass flow rate for checking flow reversal [kg/s] |
Initialization |
AbsolutePressure | p_start | Medium.p_default | Start value of pressure [Pa] |
Temperature | T_start | Medium.T_default | Start value of temperature [K] |
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 |
ExtraProperty | C_nominal[Medium.nC] | fill(1E-2, Medium.nC) | Nominal value of trace substances. (Set to typical order of magnitude.) |
Connectors
Type | Name | Description |
FluidPort_a | port_1 | First port, typically inlet |
FluidPort_b | port_2 | Second port, typically outlet |
FluidPort_a | port_3 | Third port, can be either inlet or outlet |
Modelica definition
partial model PartialThreeWayResistance
extends Buildings.Fluid.Interfaces.LumpedVolumeDeclarations(
final massDynamics=energyDynamics,
final mSenFac=1);
Modelica.Fluid.Interfaces.FluidPort_a port_1(
redeclare package Medium =
Medium,
h_outflow(start=Medium.h_default, nominal=Medium.h_default),
m_flow(min=
if (portFlowDirection_1 == Modelica.Fluid.Types.PortFlowDirection.Entering)
then 0.0
else -Modelica.Constants.inf,
max=
if (portFlowDirection_1== Modelica.Fluid.Types.PortFlowDirection.Leaving)
then 0.0
else Modelica.Constants.inf))
;
Modelica.Fluid.Interfaces.FluidPort_b port_2(
redeclare package Medium =
Medium,
h_outflow(start=Medium.h_default, nominal=Medium.h_default),
m_flow(min=
if (portFlowDirection_2 == Modelica.Fluid.Types.PortFlowDirection.Entering)
then 0.0
else -Modelica.Constants.inf,
max=
if (portFlowDirection_2 == Modelica.Fluid.Types.PortFlowDirection.Leaving)
then 0.0
else Modelica.Constants.inf))
;
Modelica.Fluid.Interfaces.FluidPort_a port_3(
redeclare package Medium=
Medium,
h_outflow(start=Medium.h_default, nominal=Medium.h_default),
m_flow(min=
if (portFlowDirection_3==Modelica.Fluid.Types.PortFlowDirection.Entering)
then 0.0
else -Modelica.Constants.inf,
max=
if (portFlowDirection_3==Modelica.Fluid.Types.PortFlowDirection.Leaving)
then 0.0
else Modelica.Constants.inf))
;
parameter Modelica.Units.SI.Time tau=10
;
parameter Modelica.Units.SI.MassFlowRate mDyn_flow_nominal
;
parameter Boolean from_dp = true
;
parameter Modelica.Fluid.Types.PortFlowDirection portFlowDirection_1=Modelica.Fluid.Types.PortFlowDirection.Bidirectional
;
parameter Modelica.Fluid.Types.PortFlowDirection portFlowDirection_2=Modelica.Fluid.Types.PortFlowDirection.Bidirectional
;
parameter Modelica.Fluid.Types.PortFlowDirection portFlowDirection_3=Modelica.Fluid.Types.PortFlowDirection.Bidirectional
;
parameter Boolean verifyFlowReversal = false
;
parameter Modelica.Units.SI.MassFlowRate m_flow_small
;
replaceable Buildings.Fluid.Interfaces.PartialTwoPortInterface res1
constrainedby Buildings.Fluid.Interfaces.PartialTwoPortInterface(
redeclare final package Medium =
Medium,
allowFlowReversal=portFlowDirection_1 == Modelica.Fluid.Types.PortFlowDirection.Bidirectional)
;
replaceable Buildings.Fluid.Interfaces.PartialTwoPortInterface res2
constrainedby Buildings.Fluid.Interfaces.PartialTwoPortInterface(
redeclare final package Medium =
Medium,
allowFlowReversal=portFlowDirection_2 == Modelica.Fluid.Types.PortFlowDirection.Bidirectional)
;
replaceable Buildings.Fluid.Interfaces.PartialTwoPortInterface res3
constrainedby Buildings.Fluid.Interfaces.PartialTwoPortInterface(
redeclare final package Medium =
Medium,
allowFlowReversal=portFlowDirection_3 == Modelica.Fluid.Types.PortFlowDirection.Bidirectional)
;
Buildings.Fluid.Delays.DelayFirstOrder vol(
redeclare final package Medium =
Medium,
final nPorts=3,
final tau=tau,
final m_flow_nominal=mDyn_flow_nominal,
final energyDynamics=energyDynamics,
final p_start=p_start,
final T_start=T_start,
final X_start=X_start,
final C_start=C_start,
final allowFlowReversal=true,
final prescribedHeatFlowRate=false)
if have_controlVolume ;
protected
parameter Boolean have_controlVolume=
energyDynamics <> Modelica.Fluid.Types.Dynamics.SteadyState
;
Modelica.Fluid.Interfaces.FluidPort_a port_internal(
redeclare package Medium =
Medium)
if not have_controlVolume
;
initial equation
assert(portFlowDirection_1<>Modelica.Fluid.Types.PortFlowDirection.Leaving
or
portFlowDirection_2<>Modelica.Fluid.Types.PortFlowDirection.Leaving
or
portFlowDirection_3<>Modelica.Fluid.Types.PortFlowDirection.Leaving,
"In " +
getInstanceName() + ": All ports are configured to
Modelica.Fluid.Types.PortFlowDirection.Leaving, which is non-physical.");
assert(portFlowDirection_1<>Modelica.Fluid.Types.PortFlowDirection.Entering
or
portFlowDirection_2<>Modelica.Fluid.Types.PortFlowDirection.Entering
or
portFlowDirection_3<>Modelica.Fluid.Types.PortFlowDirection.Entering,
"In " +
getInstanceName() + ": All ports are configured to
Modelica.Fluid.Types.PortFlowDirection.Entering, which is non-physical.");
equation
if verifyFlowReversal
then
if portFlowDirection_1==Modelica.Fluid.Types.PortFlowDirection.Entering
then
assert(port_1.m_flow> -m_flow_small,
"In " +
getInstanceName() + ":
Flow is leaving port_1 despite portFlowDirection_1=PortFlowDirection.Entering, since m_flow=" +
String(port_1.m_flow) + "<-"+
String(m_flow_small));
end if;
if portFlowDirection_1==Modelica.Fluid.Types.PortFlowDirection.Leaving
then
assert(port_1.m_flow< m_flow_small,
"In " +
getInstanceName() + ":
Flow is entering port_1 despite portFlowDirection_1=PortFlowDirection.Leaving, since m_flow=" +
String(port_1.m_flow) + ">"+
String(m_flow_small));
end if;
if portFlowDirection_2==Modelica.Fluid.Types.PortFlowDirection.Entering
then
assert(port_2.m_flow> -m_flow_small,
"In " +
getInstanceName() + ":
Flow is leaving port_2 despite portFlowDirection_2=PortFlowDirection.Entering, since m_flow=" +
String(port_2.m_flow) + "<-"+
String(m_flow_small));
end if;
if portFlowDirection_2==Modelica.Fluid.Types.PortFlowDirection.Leaving
then
assert(port_2.m_flow< m_flow_small,
"In " +
getInstanceName() + ":
Flow is entering port_2 despite portFlowDirection_2=PortFlowDirection.Leaving, since m_flow=" +
String(port_2.m_flow) + ">"+
String(m_flow_small));
end if;
if portFlowDirection_3==Modelica.Fluid.Types.PortFlowDirection.Entering
then
assert(port_3.m_flow> -m_flow_small,
"In " +
getInstanceName() + ":
Flow is leaving port_3 despite portFlowDirection_3=PortFlowDirection.Entering, since m_flow=" +
String(port_3.m_flow) + "<-"+
String(m_flow_small));
end if;
if portFlowDirection_3==Modelica.Fluid.Types.PortFlowDirection.Leaving
then
assert(port_3.m_flow< m_flow_small,
"In " +
getInstanceName() + ":
Flow is entering port_3 despite portFlowDirection_3=PortFlowDirection.Leaving, since m_flow=" +
String(port_3.m_flow) + ">"+
String(m_flow_small));
end if;
end if;
if portFlowDirection_1==Modelica.Fluid.Types.PortFlowDirection.Leaving
then
if not have_controlVolume
then
connect(res1.port_a, port_internal);
else
connect(res1.port_a, vol.ports[1]);
end if;
connect(port_1, res1.port_b);
else
if not have_controlVolume
then
connect(res1.port_b, port_internal);
else
connect(res1.port_b, vol.ports[1]);
end if;
connect(port_1, res1.port_a);
end if;
if portFlowDirection_2==Modelica.Fluid.Types.PortFlowDirection.Leaving
then
if not have_controlVolume
then
connect(res2.port_a, port_internal);
else
connect(res2.port_a, vol.ports[2]);
end if;
connect(port_2, res2.port_b);
else
if not have_controlVolume
then
connect(res2.port_b, port_internal);
else
connect(res2.port_b, vol.ports[2]);
end if;
connect(port_2, res2.port_a);
end if;
if portFlowDirection_3==Modelica.Fluid.Types.PortFlowDirection.Leaving
then
if not have_controlVolume
then
connect(res3.port_a, port_internal);
else
connect(res3.port_a, vol.ports[3]);
end if;
connect(port_3, res3.port_b);
else
if not have_controlVolume
then
connect(res3.port_b, port_internal);
else
connect(res3.port_b, vol.ports[3]);
end if;
connect(port_3, res3.port_a);
end if;
end PartialThreeWayResistance;