diff --git a/IDEAS/Airflow/Multizone/CrackOrOperableDoor.mo b/IDEAS/Airflow/Multizone/CrackOrOperableDoor.mo new file mode 100644 index 0000000000..1584fe4e01 --- /dev/null +++ b/IDEAS/Airflow/Multizone/CrackOrOperableDoor.mo @@ -0,0 +1,192 @@ +within IDEAS.Airflow.Multizone; +model CrackOrOperableDoor + "Door model using discretization along height coordinate" + extends IDEAS.Fluid.Interfaces.PartialFourPortInterface( + redeclare final package Medium1 = Medium, + redeclare final package Medium2 = Medium, + final allowFlowReversal1=true, + final allowFlowReversal2=true, + final m1_flow_nominal=10/3600*1.2, + final m2_flow_nominal=m1_flow_nominal, + final m1_flow_small=1E-4*abs(m1_flow_nominal), + final m2_flow_small=1E-4*abs(m2_flow_nominal)); + extends IDEAS.Airflow.Multizone.BaseClasses.ErrorControl(forceErrorControlOnFlow=true); //force error control on flow rates + + replaceable package Medium = + Modelica.Media.Interfaces.PartialMedium "Medium in the component" + annotation (choices( + choice(redeclare package Medium = IDEAS.Media.Air "Moist air"))); + + parameter Modelica.Units.SI.Velocity vZer=0.001 + "Minimum velocity to prevent zero flow. Recommended: 0.001"; + parameter Modelica.Units.SI.Length wOpe=0.9 "Width of opening" + annotation (Dialog(group="Geometry")); + parameter Modelica.Units.SI.Length hOpe=2.1 "Height of opening" + annotation (Dialog(group="Geometry")); + + parameter BoundaryConditions.Types.InterZonalAirFlow interZonalAirFlowType + "Interzonal air flow type"; + parameter Modelica.Units.SI.PressureDifference dpCloRat( + min=0, + displayUnit="Pa") = 50 "Pressure drop at rating condition of closed door" + annotation (Dialog(group="Rating conditions")); + + parameter Modelica.Units.SI.Length h_b1 "Height at port b1"; + parameter Modelica.Units.SI.Length h_b2 = 0 "Height at port b2"; + parameter Modelica.Units.SI.Length h_a1 = 0 "Height at port a1"; + parameter Modelica.Units.SI.Length h_a2 "Height at port a2"; + + parameter Real CDCloRat(min=0, max=1)=1 + "Discharge coefficient at rating conditions of closed door" + annotation (Dialog(group="Rating conditions")); + parameter Modelica.Units.SI.Area A_q50 "Surface area for leakage computation (closed door)"; + parameter Real q50(unit="m3/(h.m2)") "Surface air tightness"; + + parameter Modelica.Units.SI.Area LClo(min=0) = q50*A_q50*1.2/3600 *(1.2/2/dpCloRat)^mClo/CDClo + "Effective leakage area of closed door" + annotation (Dialog(group="Closed door")); + + parameter Real CDOpe=0.65 "Discharge coefficient of open door" + annotation (Dialog(group="Open door")); + parameter Real CDClo=0.65 "Discharge coefficient of closed door" + annotation (Dialog(group="Closed door")); + + parameter Real mOpe = 0.5 "Flow exponent for door of open door" + annotation (Dialog(group="Open door")); + parameter Real mClo= 0.65 "Flow exponent for crack of closed door" + annotation (Dialog(group="Closed door")); + + parameter Integer nCom=if abs(hOpe) IDEAS.BoundaryConditions.Types.InterZonalAirFlow.TwoPorts + "Sets absolute pressure when the ports are not connected externally" annotation ( + Placement(visible = true, transformation(origin = {0, -90}, extent = {{-10, 10}, {10, -10}}, rotation = 90))); + Modelica.Blocks.Sources.Constant constOne(final k=1) + if not use_y + "Door constantly opened" annotation ( + Placement(visible = true, transformation(origin = {-54, -14}, extent = {{-6, -6}, {6, 6}}, rotation = 0))); +initial equation + assert( not (interZonalAirFlowType <> IDEAS.BoundaryConditions.Types.InterZonalAirFlow.TwoPorts and useDoor and use_y), + "In " +getInstanceName() + ": Cannot use a controllable door unless interZonalAirFlowType == TwoPorts."); + +equation + connect(col_a1.port_a, point_m_flow1.port_a) annotation ( + Line(points = {{-60, 80}, {-60, 84}, {-20, 84}, {-20, 60}, {-10, 60}}, color = {0, 127, 255})); + connect(col_b1.port_a, point_m_flow1.port_b) annotation ( + Line(points = {{60, 80}, {60, 84}, {20, 84}, {20, 60}, {10, 60}}, color = {0, 127, 255})); + connect(col_b2.port_a, point_m_flow2.port_a) annotation ( + Line(points = {{-60, -40}, {-60, -36}, {-20, -36}, {-20, -60}, {-10, -60}}, color = {0, 127, 255})); + connect(col_a2.port_a, point_m_flow2.port_b) annotation ( + Line(points = {{60, -40}, {60, -36}, {20, -36}, {20, -60}, {10, -60}}, color = {0, 127, 255})); + connect(col_b2.port_b, port_b2) annotation ( + Line(points = {{-60, -60}, {-100, -60}}, color = {0, 127, 255})); + connect(col_a2.port_b, port_a2) annotation ( + Line(points = {{60, -60}, {100, -60}}, color = {0, 127, 255})); + connect(col_b1.port_b, port_b1) annotation ( + Line(points = {{60, 60}, {100, 60}}, color = {0, 127, 255})); + connect(col_a1.port_b, port_a1) annotation ( + Line(points = {{-60, 60}, {-100, 60}}, color = {0, 127, 255})); + connect(y, doo.y) annotation ( + Line(points={{-110,0},{-11,0}}, color = {0, 0, 127})); + connect(bou.ports[1], port_a2) annotation ( + Line(points={{-1,-80},{100,-80},{100,-60}}, color = {0, 127, 255})); + if interZonalAirFlowType <> IDEAS.BoundaryConditions.Types.InterZonalAirFlow.TwoPorts then + connect(point_m_flow1.port_a, port_a1) annotation ( + Line(points = {{-10, 60}, {-100, 60}}, color = {0, 127, 255})); + connect(point_m_flow1.port_b, port_b1) annotation ( + Line(points = {{10, 60}, {100, 60}}, color = {0, 127, 255})); + connect(doo.port_b1, port_b1) annotation ( + Line(points = {{10, 6}, {20, 6}, {20, 60}, {100, 60}}, color = {0, 127, 255})); + connect(doo.port_a1, port_a1) annotation ( + Line(points = {{-10, 6}, {-20, 6}, {-20, 60}, {-100, 60}}, color = {0, 127, 255})); + end if; + connect(constOne.y, doo.y) annotation ( + Line(points={{-47.4,-14},{-32,-14},{-32,0},{-11,0}}, color = {0, 0, 127})); + connect(bou.ports[2], port_b2) annotation ( + Line(points={{1,-80},{-100,-80},{-100,-60}}, color = {0, 127, 255})); + connect(doo.port_a1, port_a1) annotation( + Line(points = {{-10, 6}, {-30, 6}, {-30, 60}, {-100, 60}}, color = {0, 127, 255})); + connect(doo.port_b1, port_b1) annotation( + Line(points = {{10, 6}, {30, 6}, {30, 60}, {100, 60}}, color = {0, 127, 255})); + connect(doo.port_b2, port_b2) annotation( + Line(points = {{-10, -6}, {-20, -6}, {-20, -34}, {-100, -34}, {-100, -60}}, color = {0, 127, 255})); + connect(doo.port_a2, port_a2) annotation( + Line(points = {{10, -6}, {20, -6}, {20, -34}, {100, -34}, {100, -60}}, color = {0, 127, 255})); + +annotation(Documentation(info=" +

+This models an open/closed door depending on the number of available fluid ports. +

+

+When only one port is available then an orrifice equation is used to approximate the closed door. +There is no support for open doors when using only a single fluid port. +

+", +revisions=" + +"), + Diagram, + Icon(graphics={ Polygon(lineColor = {0, 0, 255}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, points = {{-30, -10}, {-16, -8}, {-16, -14}, {-30, -16}, {-30, -10}}), Line(points = {{-54, 48}, {-36, 48}}), Line(points = {{-54, 20}, {-36, 20}}), Rectangle(fillColor = {255, 255, 255}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-100, 100}, {100, -100}}), Line(points = {{-54, -58}, {-36, -58}}), Rectangle(lineColor = {0, 0, 255}, fillColor = {255, 128, 0}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-46, -16}, {-20, -20}}), Rectangle(lineColor = {0, 0, 255}, fillColor = {85, 75, 55}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-60, 80}, {60, -84}}), Rectangle(fillColor = {215, 215, 215}, fillPattern = FillPattern.Solid, extent = {{-54, 72}, {56, -84}}), Polygon(fillColor = {95, 95, 95}, fillPattern = FillPattern.Solid, points = {{56, 72}, {-36, 66}, {-36, -90}, {56, -84}, {56, 72}}), Rectangle(lineColor = {0, 0, 255}, fillColor = {255, 128, 0}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-100, 2}, {-46, -2}}), Polygon(visible = false, origin = {75, 50}, rotation = 360, lineColor = {0, 128, 255}, fillColor = {0, 128, 255}, fillPattern = FillPattern.Solid, points = {{-5, 10}, {25, 10}, {-5, -10}, {-5, 10}}), Text(textColor = {0, 0, 127}, extent = {{-118, 34}, {-98, 16}}, textString = "y"), Line(points = {{-54, -6}, {-36, -6}}), Line(points = {{-54, -32}, {-36, -32}}), Polygon(visible = false, origin = {-79, -50}, rotation = 360, lineColor = {0, 128, 255}, fillColor = {0, 128, 255}, fillPattern = FillPattern.Solid, points = {{10, 10}, {-20, -10}, {10, -10}, {10, 10}}), Rectangle(lineColor = {0, 0, 255}, fillColor = {255, 128, 0}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-46, 2}, {-40, -16}})}, coordinateSystem(extent = {{-100, -100}, {100, 100}}))); +end CrackOrOperableDoor; \ No newline at end of file diff --git a/IDEAS/Airflow/Multizone/Examples/TrickleVentIDEAS.mo b/IDEAS/Airflow/Multizone/Examples/TrickleVentIDEAS.mo new file mode 100644 index 0000000000..b7b4982b02 --- /dev/null +++ b/IDEAS/Airflow/Multizone/Examples/TrickleVentIDEAS.mo @@ -0,0 +1,53 @@ +within IDEAS.Airflow.Multizone.Examples; +model TrickleVentIDEAS + "Model with a trickle vent modelled using the models with flow based on tabulated data" + extends IDEAS.Airflow.Multizone.Examples.TrickleVent(west(nPorts=2), east(nPorts=2)); + + IDEAS.Airflow.Multizone.TrickleVent vent( + redeclare package Medium = Medium, + dp_nominal = 10, + m_flow_nominal = 0.02614, + use_y = true) + "Analytic trickle vent implementation" annotation( + Placement(visible = true, transformation(origin = {20, -70}, extent = {{-10, 10}, {10, -10}}, rotation = 0))); + Modelica.Blocks.Sources.Ramp ramp( + duration = 1e6, + height = -1, + offset = 1, + startTime = 1592000) + "Step control signal" annotation( + Placement(visible = true, transformation(origin = {-90, -88}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); +equation + connect(vent.port_a, east.ports[2]) annotation( + Line(points = {{10, -70}, {-25, -70}, {-25, -30}, {-30, -30}}, color = {0, 127, 255})); + connect(vent.port_b, west.ports[2]) annotation( + Line(points = {{30, -70}, {65, -70}, {65, -30}, {70, -30}}, color = {0, 127, 255})); + connect(ramp.y, vent.y) annotation( + Line(points = {{-79, -88}, {20.5, -88}, {20.5, -82}, {20, -82}}, color = {0, 0, 127})); + annotation (__Dymola_Commands(file="modelica://IDEAS/Resources/Scripts/Dymola/Airflow/Multizone/Examples/TrickleVentIDEAS.mos" + "Simulate and plot"), + experiment( + StopTime=2592000, + Interval=600, + Tolerance=1e-06), + Documentation(info=" +

+This model illustrates the use of the models + +IDEAS.Airflow.Multizone.Table_V_flow, +which is an analytic alternative to the table implementation of + +IDEAS.Airflow.Multizone.Table_m_flow for + +modelling self regulating inlet vents. +

+", revisions=" + +"), + Diagram); +end TrickleVentIDEAS; \ No newline at end of file diff --git a/IDEAS/Airflow/Multizone/Examples/package.order b/IDEAS/Airflow/Multizone/Examples/package.order index 162a3ed47f..9940a37007 100644 --- a/IDEAS/Airflow/Multizone/Examples/package.order +++ b/IDEAS/Airflow/Multizone/Examples/package.order @@ -12,4 +12,5 @@ PressurizationData ReverseBuoyancy ReverseBuoyancy3Zones TrickleVent +TrickleVentIDEAS ZonalFlow diff --git a/IDEAS/Airflow/Multizone/ReversibleDensityColumn.mo b/IDEAS/Airflow/Multizone/ReversibleDensityColumn.mo new file mode 100644 index 0000000000..96360c35bb --- /dev/null +++ b/IDEAS/Airflow/Multizone/ReversibleDensityColumn.mo @@ -0,0 +1,42 @@ +within IDEAS.Airflow.Multizone; +model ReversibleDensityColumn + "Vertical shaft with no friction and no storage of heat and mass, reversible because it can handle negative column heights" + + extends IDEAS.Airflow.Multizone.MediumColumn( + h(min=-Modelica.Constants.inf), + final densitySelection = IDEAS.Airflow.Multizone.Types.densitySelection.fromBottom); + // by convention, port_b must be connected to a zone instead of a flow element + // h is allowed to be negative to accomodate for this convention + + annotation ( +Icon(graphics={ + Line( + points={{0,100},{0,-100},{0,-98}}), + Text(origin = {-126, 2},lineColor = {0, 0, 127}, extent = {{24, -78}, {106, -100}}, textString = "Zone/Amb"), + Text(origin = {-130, 4}, lineColor = {0, 0, 127}, extent = {{32, 104}, {98, 70}}, textString = "FlowElem"), + Text(lineColor = {0, 0, 127}, extent = {{36, 26}, {88, -10}}, textString = "h=%h"), + Rectangle(fillColor = {255, 0, 0}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-16, 80}, {16, -80}}), + Rectangle(visible = false, fillColor = {85, 170, 255}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-16, 80}, {16, 0}}), + Rectangle(visible = false, fillColor = {85, 170, 255}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-16, 80}, {16, 54}}), + Rectangle(fillColor = {85, 170, 255}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-16, 0}, {16, -82}}), + Rectangle(visible = false, fillColor = {85, 170, 255}, pattern = LinePattern.None, fillPattern = FillPattern.Solid, extent = {{-16, -55}, {16, -80}})}), + defaultComponentName="col", + Documentation(info=" +

+This model describes the pressure difference of a vertical medium +column. It can be used to model the pressure difference caused by +stack effect. +It is a variation on IDEAS.Airflow.Multizone.MediumColumn. +

+", + revisions=" + +")); +end ReversibleDensityColumn; \ No newline at end of file diff --git a/IDEAS/Airflow/Multizone/TrickleVent.mo b/IDEAS/Airflow/Multizone/TrickleVent.mo index 0a7ba4b9eb..74bcaa31e8 100644 --- a/IDEAS/Airflow/Multizone/TrickleVent.mo +++ b/IDEAS/Airflow/Multizone/TrickleVent.mo @@ -5,15 +5,21 @@ model TrickleVent "Self regulating trickle vent" final from_dp=true, final homotopyInitialization=true); + parameter Real l(min=1e-10, max=1) = 0.0001 + "Valve leakage, l=Kv(y=0)/Kv(y=1)"; parameter Real deltaM(min=1E-6) = 0.3 "Fraction of nominal mass flow rate where transition to turbulent occurs" annotation(Evaluate=true, Dialog(group = "Transition to laminar", enable = not linearized)); - + parameter Boolean use_y = false + "=true, to enable control input" + annotation(Evaluate=true, Dialog(group="Control")); final parameter Real k = if computeFlowResistance then m_flow_nominal_pos / sqrt(dp_nominal_pos) else 0 "Flow coefficient, k=m_flow/sqrt(dp), with unit=(kg.m)^(1/2)"; + Modelica.Blocks.Interfaces.RealInput y(min=0,max=1) if use_y "Control input for trickle vent Kv value" annotation( + Placement(visible = true, transformation(origin = {0, 120}, extent = {{-20, -20}, {20, 20}}, rotation = -90), iconTransformation(origin = {0, 120}, extent = {{-20, -20}, {20, 20}}, rotation = -90))); protected final parameter Boolean computeFlowResistance=(dp_nominal_pos > Modelica.Constants.eps) "Flag to enable/disable computation of flow resistance" @@ -23,6 +29,7 @@ protected then if from_dp then k^2/m_flow_nominal_pos else m_flow_nominal_pos/k^2 else 0 "Precomputed coefficient to avoid division by parameter"; + Modelica.Blocks.Interfaces.RealInput y_internal "Internal variable for conditional variables"; initial equation if computeFlowResistance then assert(m_flow_turbulent > 0, "m_flow_turbulent must be bigger than zero."); @@ -30,6 +37,10 @@ initial equation assert(m_flow_nominal_pos > 0, "m_flow_nominal_pos must be non-zero. Check parameters."); equation + connect(y, y_internal); + if not use_y then + y_internal = 1; + end if; // Pressure drop calculation if computeFlowResistance then if linearized then @@ -40,7 +51,7 @@ equation m_flow_nominal, IDEAS.Fluid.BaseClasses.FlowModels.basicFlowFunction_dp( dp=dp, - k=k, + k=k*(l + (1-l)*y_internal), m_flow_turbulent=m_flow_turbulent), m_flow_nominal/10); end if; // linearized @@ -56,12 +67,20 @@ The positive mass flow rate is limited to m_flow_nominal at a pressure difference of dp_nominal. For negative pressure differences the mass flow rate is not limited.

+

+An optional control input can be enabled, which reduces the flow rate for the same +pressure difference, but which does not affect the maximum flow rate. +

", revisions=" ")); -end TrickleVent; +end TrickleVent; \ No newline at end of file diff --git a/IDEAS/Airflow/Multizone/package.order b/IDEAS/Airflow/Multizone/package.order index cc28cc1a97..08612d5ffb 100644 --- a/IDEAS/Airflow/Multizone/package.order +++ b/IDEAS/Airflow/Multizone/package.order @@ -1,6 +1,7 @@ UsersGuide Coefficient_V_flow Coefficient_m_flow +CrackOrOperableDoor DoorDiscretizedOpen DoorDiscretizedOperable DoorOpen @@ -11,12 +12,13 @@ MediumColumnDynamic Orifice Point_m_flow Points_m_flow +ReversibleDensityColumn Table_V_flow Table_m_flow +TrickleVent ZonalFlow_ACS ZonalFlow_m_flow Types Examples Validation BaseClasses -TrickleVent diff --git a/IDEAS/BoundaryConditions/Interfaces/PartialSimInfoManager.mo b/IDEAS/BoundaryConditions/Interfaces/PartialSimInfoManager.mo index c39f8a65f0..5d57589e2e 100644 --- a/IDEAS/BoundaryConditions/Interfaces/PartialSimInfoManager.mo +++ b/IDEAS/BoundaryConditions/Interfaces/PartialSimInfoManager.mo @@ -43,7 +43,10 @@ partial model PartialSimInfoManager parameter Boolean openSystemConservationOfEnergy=false "Compute conservation of energy for open system" annotation (Evaluate=true, Dialog(tab="Conservation of energy", enable=computeConservationOfEnergy)); - + parameter Boolean use_port_1 = interZonalAirFlowType <> IDEAS.BoundaryConditions.Types.InterZonalAirFlow.None + "Whether port_1 of the propsbus connector should be used"; + parameter Boolean use_port_2 = interZonalAirFlowType == IDEAS.BoundaryConditions.Types.InterZonalAirFlow.TwoPorts + "Whether port_2 of the propsbus connector should be used"; parameter Boolean lineariseDymola=false "Linearises building model equations for Dymola linearisation approach" annotation (Dialog(tab="Linearisation")); parameter Boolean lineariseJModelica=false "Linearises building model equations for optimisations in JModelica" @@ -103,16 +106,21 @@ partial model PartialSimInfoManager parameter Modelica.Units.SI.Length H=10 "Building or roof height" annotation (Dialog(group="Wind")); - parameter Real A0=0.6 "Local terrain constant. 0.6 for Suburban,0.35 for Urban and 1 for Unshielded (Ashrae 1993) " annotation(Dialog(group="Wind")); + parameter Real A0=0.6 "Local terrain constant. 0.6 for Suburban,0.35 for Urban and 1 for Unshielded (Ashrae 1993) " + annotation(Dialog(group="Wind")); parameter Real a=0.28 "Velocity profile exponent. 0.28 for Suburban, 0.4 for Urban and 0.15 for Unshielded (Ashrae 1993) " - annotation(Dialog(group="Wind")); - parameter Modelica.Units.SI.Length Hwin=10 + annotation(Dialog(group="Wind")); + parameter Modelica.Units.SI.Length Hwind=10 "Height above ground of meteorological wind speed measurement" annotation (Dialog(group="Wind")); + parameter Real Cs_coeff = (A0*A0)*((1/Hwind)^(2*a)) "Multiplication factor for Habs" + annotation(Dialog(group="Wind")); + parameter Modelica.Units.SI.Length Hpres=1 "Height above ground of meteorological ambient pressure measurement" + annotation(Dialog(group="Wind")); + constant Modelica.Units.SI.Density rho_default = 1.2 "Default air density" + annotation(Dialog(group="Wind")); - parameter Real Cs= (A0*A0)*((H/Hwin)^(2*a)) "Wind speed modifier" - annotation(Dialog(group="Wind")); - + parameter Real Cs= Cs_coeff*(H^(2*a)) "Wind speed modifier" annotation(Dialog(group="Wind")); final parameter Integer numIncAndAziInBus = size(incAndAziInBus,1) "Number of pre-computed azimuth"; @@ -576,6 +584,10 @@ equation ", revisions="