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 |
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 |
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 + k * port_a.m_flow
.
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 |
Real | k | | 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) |
Modelica definition
model MassFlowRateMultiplier
extends Buildings.Fluid.Interfaces.PartialTwoPort;
parameter Real k ;
initial equation
assert(k > Modelica.Constants.small
or -k < -Modelica.Constants.small,
"Gain must not be zero. Received k = " +
String(k));
equation
port_a.p = port_b.p;
port_b.m_flow = -k*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);
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 transporting fluid between two ports without storing mass or energy).
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.SIunits.PressureDifference dp_nominal(displayUnit="Pa")
;
parameter Boolean linearized = false
;
parameter Modelica.SIunits.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.SIunits.DynamicViscosity eta_default=
Medium.dynamicViscosity(sta_default)
;
final parameter Modelica.SIunits.MassFlowRate m_flow_nominal_pos =
abs(m_flow_nominal)
;
final parameter Modelica.SIunits.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 |
Equations |
Dynamics | energyDynamics | Modelica.Fluid.Types.Dynamic... | Type of energy balance: dynamic (3 initialization options) or steady state |
Dynamics | massDynamics | energyDynamics | Type of mass 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] |
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.) |
Advanced |
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] |
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 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.SIunits.Time tau=10
;
parameter Modelica.SIunits.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.SIunits.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 massDynamics=massDynamics,
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
or
massDynamics <> 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;