Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses

Information

Extends from Modelica.Fluid.Icons.BaseClassLibrary (Icon for library).

Package Content

NameDescription
Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.TriggeredTrapezoid TriggeredTrapezoid Triggered trapezoid generator
Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.setReal setReal Set output signal to a time varying Real expression
Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.TankWith3InletOutletArraysWithEvaporatorCondensor TankWith3InletOutletArraysWithEvaporatorCondensor Tank with Heating and Evaporation
Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.InnerTank InnerTank  
Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.Controller Controller  
Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.ControllerUtilities ControllerUtilities  
Init Enumeration to define initialization options
Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.TankWithTopPorts TankWithTopPorts Tank with inlet/outlet ports and with inlet ports at the top

Types and constants

  type Init = enumeration(
    GuessValues "GuessValues -- Guess values (not fixed) for p, T or h, X, C",
    InitialValues "InitialValues -- Initial values for p, T or h, X, C",
    SteadyStateMomentum "SteadyStateMomentum: Steady state momentum",
    SteadyStateHydraulic 
      "SteadyStateHydraulic -- Hydraulic steady state (der(p)=0), guess value for p, initial values for T or h, X, C", 

    SteadyState 
      "SteadyState -- Steady state (guess values for p, T or h, X, C)") 
  "Enumeration to define initialization options";


Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.TriggeredTrapezoid Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.TriggeredTrapezoid

Triggered trapezoid generator

Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.TriggeredTrapezoid

Information


The block TriggeredTrapezoid has a boolean input and a real output signal and requires the parameters amplitude, rising, falling and offset. The output signal y represents a trapezoidal signal dependent on the input signal u.

The behaviour is as follows: Assume the initial input to be false. In this case, the output will be offset. After a rising edge (i.e. the input changes from false to true), the output is rising during rising to the sum of offset and amplitude. In contrast, after a falling edge (i.e. the input changes from true to false), the output is falling during falling to a value of offset.

Note, that the case of edges before expiration of rising or falling is handled properly.

Extends from Modelica.Blocks.Interfaces.partialBooleanBlockIcon (Basic graphical layout of logical block).

Parameters

TypeNameDefaultDescription
Realamplitude1Amplitude of trapezoid
Timerising0Rising duration of trapezoid [s]
TimefallingrisingFalling duration of trapezoid [s]
Realoffset0Offset of output signal

Connectors

TypeNameDescription
input BooleanInputuConnector of Boolean input signal
output RealOutputyConnector of Real output signal
output BooleanOutputy_high 

Modelica definition

block TriggeredTrapezoid "Triggered trapezoid generator"
  extends Modelica.Blocks.Interfaces.partialBooleanBlockIcon;

  parameter Real amplitude=1 "Amplitude of trapezoid";
  parameter Modelica.SIunits.Time rising(final min=0)=0 
    "Rising duration of trapezoid";
  parameter Modelica.SIunits.Time falling(final min=0)=rising 
    "Falling duration of trapezoid";
  parameter Real offset=0 "Offset of output signal";

  Modelica.Blocks.Interfaces.BooleanInput u "Connector of Boolean input signal";
  Modelica.Blocks.Interfaces.RealOutput y "Connector of Real output signal";

protected 
  discrete Real endValue "Value of y at time of recent edge";
  discrete Real rate "Current rising/falling rate";
  discrete Modelica.SIunits.Time T "Predicted time of output reaching endValue";
public 
  Modelica.Blocks.Interfaces.BooleanOutput y_high;
initial equation 
  /* A start value of y is set, because pre(y) is present
     to avoid a warning message from the compiler. However,
     this setting does not have an effect, because y is initialized
     correctly, before pre(y) is used
  */
  pre(y) = 0;
equation 
    y_high = time < T;
    y = if y_high then endValue - (T - time)*rate else  endValue;

    when {initial(),u,not u} then
      endValue = if u then offset + amplitude else offset;
      rate = if u and (rising > 0) then amplitude/rising else 
        if not u and (falling > 0) then -amplitude/falling else 0;
      T = if u and not (rising > 0) or not u and not (falling
         > 0) or not abs(amplitude) > 0 or initial() then time else time
         + (endValue - pre(y))/rate;
    end when;
end TriggeredTrapezoid;

Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.setReal Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.setReal

Set output signal to a time varying Real expression

Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.setReal

Information



Parameters

TypeNameDefaultDescription
Time varying input signal
RealInputu Set value of Real input

Connectors

TypeNameDescription
Time varying input signal
input RealInputuSet value of Real input

Modelica definition

block setReal "Set output signal to a time varying Real expression"

  Modelica.Blocks.Interfaces.RealInput u "Set value of Real input";


end setReal;

Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.TankWith3InletOutletArraysWithEvaporatorCondensor Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.TankWith3InletOutletArraysWithEvaporatorCondensor

Tank with Heating and Evaporation

Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.TankWith3InletOutletArraysWithEvaporatorCondensor

Information


This tank has the same geometric variables as TankWith3InletOutletArrays plus the feature of a HeatPort and the possibility of evaporation. (Assumption: The gas is condensed emidiatly afterwards so that a liquid boiling fluid is created.)

The tank can be initialized with the following options:

Full steady state initialization is not supported, because the corresponding intial equations for temperature/enthalpy are undetermined (the flow rate through the port at steady state is zero).

Parameters

TypeNameDefaultDescription
AreacrossArea Tank area [m2]
Areatop_pipeArea[n_TopPorts] Area of outlet pipe [m2]
Areaside_pipeArea[n_SidePorts] Area of outlet pipe [m2]
Areabottom_pipeArea[n_BottomPorts] Area of outlet pipe [m2]
Heightheight10Height of Tank [m]
VolumeV00Volume of the liquid when the level is zero [m3]
Realside_heights[n_SidePorts]zeros(n_SidePorts) 
Realbottom_heights[n_BottomPorts]zeros(n_BottomPorts) 
Realtop_heights[n_TopPorts]fill(height, n_TopPorts) 
AbsolutePressurep_ambient101325Tank surface pressure [Pa]
TemperatureT_ambient293.15Tank surface Temperature [K]
Integern_TopPorts1number of Top connectors
Integern_SidePorts1number of side connectors
Integern_BottomPorts1number of bootom connectors
Realmin_level_for_heating  
Initialization
Heightlevel_start Initial tank level [m]
InitinitTypeInit.GuessValuesInitialization option
Booleanuse_T_starttrueUse T_start if true, otherwise h_start
TemperatureT_startif use_T_start then 293.15 e...Start value of temperature [K]
SpecificEnthalpyh_startif use_T_start then Medium.s...Start value of specific enthalpy [J/kg]
MassFractionX_start[Medium.nX]Medium.reference_XStart value of mass fractions m_i/m [kg/kg]

Connectors

TypeNameDescription
FluidPort_bBottomFluidPort[n_BottomPorts] 
FluidPort_aTopFluidPort[n_TopPorts] 
FluidPort_bSideFluidPort[n_SidePorts] 
FluidPort_bCondensed 
HeatPort_aheatPort 

Modelica definition

model TankWith3InletOutletArraysWithEvaporatorCondensor 
  "Tank with Heating and Evaporation"
  import Modelica.SIunits.Conversions.*;
  import Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.Init;
  replaceable package Medium = Modelica.Media.Water.WaterIF97_ph 
    constrainedby Modelica.Media.Interfaces.PartialTwoPhaseMedium 
    "Medium in the component";
// parameter for Tank
  parameter Modelica.SIunits.Area crossArea "Tank area";
  parameter SI.Area top_pipeArea[n_TopPorts] "Area of outlet pipe";
  parameter SI.Area side_pipeArea[n_SidePorts] "Area of outlet pipe";
  parameter SI.Area bottom_pipeArea[n_BottomPorts] "Area of outlet pipe";
  parameter Modelica.SIunits.Height height(min=0) = 10 "Height of Tank";
  parameter SI.Volume V0=0 "Volume of the liquid when the level is zero";
  constant Modelica.SIunits.Acceleration g=Modelica.Constants.g_n;
  parameter Real side_heights[n_SidePorts]=zeros(n_SidePorts);
  parameter Real bottom_heights[n_BottomPorts]=zeros(n_BottomPorts);
  parameter Real top_heights[n_TopPorts]=fill(height, n_TopPorts);
  parameter SI.Height level_start(min=0) "Initial tank level";
  parameter Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.Init initType=
                                               Init.GuessValues 
    "Initialization option";
  parameter Boolean use_T_start=true "Use T_start if true, otherwise h_start";
  parameter Medium.Temperature T_start=if use_T_start then 293.15 else 
      Medium.temperature_phX(p_ambient, h_start, X_start) 
    "Start value of temperature";
  parameter Medium.SpecificEnthalpy h_start=if use_T_start then Medium.specificEnthalpy_pTX(
      p_ambient, T_start, X_start[1:Medium.nXi]) else 1e4 
    "Start value of specific enthalpy";
  parameter Medium.MassFraction X_start[Medium.nX]=Medium.reference_X 
    "Start value of mass fractions m_i/m";
  parameter Medium.AbsolutePressure p_ambient=101325 "Tank surface pressure";
  parameter Medium.Temperature T_ambient=293.15 "Tank surface Temperature";
  parameter Integer n_TopPorts=1 "number of Top connectors";
  parameter Integer n_SidePorts=1 "number of side connectors";
  parameter Integer n_BottomPorts=1 "number of bootom connectors";
  Medium.BaseProperties medium(
    preferredMediumStates=true,
    p(start=p_ambient),
    T(start=T_start),
    Xi(start=X_start[1:Medium.nXi]));
  Modelica.SIunits.Height level(
    stateSelect=StateSelect.prefer,
    min=0,
    max=height) "Level height of tank";
  SI.Volume V(stateSelect=StateSelect.never) "Actual tank volume";
  SI.Energy U "Internal energy of tank volume";
  Real m(quantity=Medium.mediumName, unit="kg") "Mass of tank volume";
  Real mXi[Medium.nXi](quantity=Medium.substanceNames, each unit="kg") 
    "Component masses of the independent substances";
// additional variables
  Real H_flow_BottomPorts[n_BottomPorts];
  Real H_flow_SidePorts[n_SidePorts];
  Real H_flow_TopPorts[n_TopPorts];
  Real m_flow_BottomPorts[n_BottomPorts];
  Real m_flow_SidePorts[n_SidePorts];
  Real m_flow_TopPorts[n_TopPorts];

  Real m_flow_BottomPorts_pos[n_BottomPorts];
  Real m_flow_SidePorts_pos[n_SidePorts];
  Real m_flow_TopPorts_pos[n_TopPorts];
  Real m_flow_pos;
  Medium.MassFlowRate mXi_flow_topPorts[n_TopPorts,Medium.nXi];
  Medium.MassFlowRate mXi_flowBottomPorts[n_BottomPorts,Medium.nXi];
  Medium.MassFlowRate mXi_flow_sidePorts[n_SidePorts,Medium.nXi];

// Connectors and InnerTanks
  Modelica.Fluid.Interfaces.FluidPort_b BottomFluidPort[n_BottomPorts](
    redeclare package Medium = Medium,
    m_flow(each start=0));
  Modelica.Fluid.Interfaces.FluidPort_a TopFluidPort[n_TopPorts](
    redeclare package Medium = Medium,
    m_flow(each start=0));
  Modelica.Fluid.Interfaces.FluidPort_b SideFluidPort[n_SidePorts](
    redeclare package Medium = Medium,
    m_flow(each start=0));
  Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.InnerTank InnerTankTop[n_TopPorts](
    each h=medium.h,
    each p_ambient=p_ambient,
    each d=medium.d,
    each Xi = medium.Xi,
    aboveLevel={level - top_heights[i] for i in 1:n_TopPorts},
    pipeArea={top_pipeArea[i] for i in 1:n_TopPorts},
    redeclare package Medium = Medium);
  Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.InnerTank InnerTankSide[n_SidePorts](
    each h=medium.h,
    each p_ambient=p_ambient,
    each d=medium.d,
    each Xi = medium.Xi,
    aboveLevel={level - side_heights[i] for i in 1:n_SidePorts},
    pipeArea={side_pipeArea[i] for i in 1:n_SidePorts},
    redeclare package Medium = Medium);
  Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.InnerTank InnerTankBottom[n_BottomPorts](
    each h=medium.h,
    each p_ambient=p_ambient,
    each d=medium.d,
    each Xi = medium.Xi,
    aboveLevel={level - bottom_heights[i] for i in 1:n_BottomPorts},
    pipeArea={bottom_pipeArea[i] for i in 1:n_BottomPorts},
    redeclare package Medium = Medium);
  Modelica.Fluid.Interfaces.FluidPort_b Condensed(redeclare package Medium = 
               Medium);

  // Heat transfer through boundary
  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,
    final states = {medium.state},
    surfaceAreas={crossArea+2*sqrt(crossArea*Modelica.Constants.pi)*level},
    final use_k = true);
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort;

// parameter for Evaporator
  parameter Real min_level_for_heating;

  Medium.SaturationProperties sat 
    "State vector to compute saturation properties";
  Medium.SpecificEnthalpy h_v=Medium.dewEnthalpy(sat) 
    "specific enthalpy of vapour";
  Medium.SpecificEnthalpy h_l=Medium.bubbleEnthalpy(sat) 
    "specific enthalpy of liquid";
  Medium.SpecificEnthalpy h "'is'specific enthalpy of liquid";
  Medium.Density rho_v=Medium.dewDensity(sat) "density in vapour phase";
  Medium.Density rho_l=Medium.bubbleDensity(sat) "density in liquid phase";
  Medium.Density rho "'is' density in liquid phase";

equation 
  H_flow_TopPorts   = InnerTankTop.H_flow;
  m_flow_TopPorts   = InnerTankTop.m_flow;
  mXi_flow_topPorts = InnerTankTop.mXi_flow;

  H_flow_SidePorts   = InnerTankSide.H_flow;
  m_flow_SidePorts   = InnerTankSide.m_flow;
  mXi_flow_sidePorts = InnerTankSide.mXi_flow;

  H_flow_BottomPorts  = InnerTankBottom.H_flow;
  m_flow_BottomPorts  = InnerTankBottom.m_flow;
  mXi_flowBottomPorts = InnerTankBottom.mXi_flow;

  for i in 1:n_BottomPorts loop
    m_flow_BottomPorts_pos[i] = (if m_flow_BottomPorts[i] > 0 then 
      m_flow_BottomPorts[i] else 0);
  end for;
  for i in 1:n_SidePorts loop
    m_flow_SidePorts_pos[i] = if m_flow_SidePorts[i] > 0 then m_flow_SidePorts[
      i] else 0;
  end for;
  for i in 1:n_TopPorts loop
    m_flow_TopPorts_pos[i] = if m_flow_TopPorts[i] > 0 then m_flow_TopPorts[i] else 
            0;
  end for;
  for i in 1:n_BottomPorts loop
    connect(InnerTankBottom[i].port, BottomFluidPort[i]);
  end for;
  for i in 1:n_TopPorts loop
    connect(InnerTankTop[i].port, TopFluidPort[i]);
  end for;
  for i in 1:n_SidePorts loop
    connect(InnerTankSide[i].port, SideFluidPort[i]);
  end for;

  medium.p = p_ambient;
// Mass balance
  der(m) = sum(m_flow_BottomPorts) + sum(m_flow_SidePorts) + sum(
    m_flow_TopPorts) + Condensed.m_flow;
// Energy balance

  U = m*medium.h - p_ambient*V "Internal energy of fluid";
  m = V*medium.d "Mass of fluid";
  V = crossArea*level + V0 "Volume of fluid";
  mXi = m*medium.Xi "Mass of fluid components";
  sat.psat = medium.p;
  sat.Tsat = Medium.saturationTemperature(medium.p);

  if noEvent(medium.T < sat.Tsat) then
    if Medium.singleState then
      der(U) = sum(H_flow_BottomPorts) + sum(H_flow_SidePorts) + sum(
        H_flow_TopPorts) + Condensed.m_flow*actualStream(Condensed.h_outflow) + heatTransfer.Q_flows[1] 
        "Mechanical work is neglected";
    else
      der(U) = sum(H_flow_BottomPorts) + sum(H_flow_SidePorts) + sum(
        H_flow_TopPorts) + Condensed.m_flow*actualStream(Condensed.h_outflow) - p_ambient*der(V) +
        heatTransfer.Q_flows[1];
    end if;
    Condensed.h_outflow = h;
    Condensed.m_flow = 0;
    rho = medium.d;
    h = medium.h;
  else
    if Medium.singleState then
      der(U) = sum(H_flow_BottomPorts) + sum(H_flow_SidePorts) + sum(H_flow_TopPorts)
         + Condensed.m_flow*actualStream(Condensed.h_outflow) 
        "Mechanical work is neglected";
    else
      der(U) = sum(H_flow_BottomPorts) + sum(H_flow_SidePorts) + sum(
        H_flow_TopPorts) + Condensed.m_flow*actualStream(Condensed.h_outflow) - p_ambient*der(V);
    end if;
    Condensed.h_outflow = h;
    Condensed.m_flow = -heatTransfer.Q_flows[1]/(h_v - h_l);
    rho = rho_l;//Density = liquid Densety
    h = h_l;    //Enthalpy = liquid Enthalpy
    if noEvent(heatPort.Q_flow > 0.0) then
      assert(noEvent(abs(m_flow_pos) <= 0.01), "Attempt to fill tank while evaporating.");
    end if;

  end if;

  m_flow_pos = sum(m_flow_TopPorts_pos) + sum(m_flow_SidePorts_pos) + sum(
    m_flow_BottomPorts_pos);

  for i in 1:Medium.nXi loop
       der(mXi[i]) = sum(mXi_flowBottomPorts[:,i]) +
                     sum(mXi_flow_sidePorts[:,i]) +
                     sum(mXi_flow_topPorts[:,i]);
  end for;

  assert(level < height, "
    Tank is overflowing.
    ");

  assert(not (heatPort.Q_flow > 0.0 and level <= min_level_for_heating), "
    Attempting to heat an empty tank
  ");

initial equation 
  if initType == Init.GuessValues then
    // no initial equations
  elseif initType == Init.InitialValues then
    level = level_start;
    if use_T_start then
      medium.T = T_start;
    else
      medium.h = h_start;
    end if;
    medium.Xi = X_start[1:Medium.nXi];
  elseif initType == Init.SteadyStateHydraulic then
    der(level) = 0;
    if use_T_start then
      medium.T = T_start;
    else
      medium.h = h_start;
    end if;
    medium.Xi = X_start[1:Medium.nXi];
  else
    assert(false, "Unsupported initialization option");
  end if;


equation 
  connect(heatPort, heatTransfer.heatPorts[1]);
end TankWith3InletOutletArraysWithEvaporatorCondensor;

Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.InnerTank Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.InnerTank

Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.InnerTank

Parameters

TypeNameDefaultDescription
MassFractionXi[Medium.nXi] Actual mass fractions of fluid in tank [kg/kg]

Connectors

TypeNameDescription
FluidPort_aport 

Modelica definition

model InnerTank
    replaceable package Medium = 
    Modelica.Media.Interfaces.PartialMedium "Medium in the component";

    Modelica.Fluid.Interfaces.FluidPort_a port(redeclare package Medium = 
        Medium);
    Boolean m_flow_negative( start = true) "true= massflow out of tank";
    constant Modelica.SIunits.Acceleration g=Modelica.Constants.g_n;
    input Real aboveLevel;
    input Real d;
    input Real p_ambient;
    input Real h;
    input Medium.MassFraction Xi[Medium.nXi] 
    "Actual mass fractions of fluid in tank";
    input Real pipeArea;
    output Real H_flow;
    output Real m_flow;
   output Medium.MassFlowRate mXi_flow[Medium.nXi] 
    "= port.mXi_flow (used to transform vector of connectors in vector of Real numbers)";

equation 
m_flow_negative = (pre(m_flow_negative) and not port.p>p_ambient) or (port.m_flow < -1e-6);

if noEvent(aboveLevel > 0) then
  port.p = aboveLevel*g*d + p_ambient - smooth(2,noEvent(if noEvent(m_flow < 0) then m_flow^2/(2*d*pipeArea^2) else 0));
else
 if pre(m_flow_negative) then
    port.m_flow = 0;
  else
    port.p = p_ambient;
  end if;
end if;

  H_flow = port.m_flow*actualStream(port.h_outflow);
  m_flow = port.m_flow;
  mXi_flow = port.m_flow*actualStream(port.Xi_outflow);
  port.h_outflow = h;
  port.Xi_outflow = Xi;
end InnerTank;

Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.Controller Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.Controller

Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.Controller

Parameters

TypeNameDefaultDescription
Realw_dilution0.003 
Realw_concentrate0.005 
RealstartTime1 
RealT5_batch_level0.211 

Connectors

TypeNameDescription
Port_Sensorssensors 
Port_Actuatorsactuators 

Modelica definition

model Controller

  Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.ControllerUtilities.Port_Sensors
    sensors;
  Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.ControllerUtilities.Port_Actuators
    actuators;

  parameter Real w_dilution=0.003;
  parameter Real w_concentrate=0.005;
  parameter Real startTime=1;
  parameter Real T5_batch_level=0.211;

  Modelica.StateGraph.InitialStep InitialStep1;
  Modelica.StateGraph.Transition Transition1(enableTimer=true, waitTime=
        startTime);
  Modelica.StateGraph.Step Step1;
  Modelica.StateGraph.Transition Transition2(condition=LIS_301 >= 0.13);
  Modelica.StateGraph.Step Step2;
  Modelica.StateGraph.Transition Transition3(
    condition=true,
    enableTimer=true,
    waitTime=500);
  Modelica.StateGraph.Step Step3;
  Modelica.StateGraph.Transition Transition4(condition=LIS_301 <= 0.01);
  Modelica.StateGraph.Step Step4;
  Modelica.StateGraph.Transition Transition5(condition=T5_idle);
  Modelica.StateGraph.Step Step5;
  Modelica.StateGraph.Transition Transition6(condition=LIS_501 >=
        T5_batch_level);
  Modelica.StateGraph.Step Step6;
  Modelica.StateGraph.Transition Transition7(
    condition=true,
    enableTimer=true,
    waitTime=300);
  Modelica.StateGraph.Parallel Parallel1;
  Modelica.StateGraph.Step Step7;
  Modelica.StateGraph.Step Step8;
  Modelica.StateGraph.Step Step9;
  Modelica.StateGraph.Step Step10;
  Modelica.StateGraph.Step Step11;
  Modelica.StateGraph.Step Step12;
  Modelica.StateGraph.Step Step13;
  Modelica.StateGraph.Step Step14;
  Modelica.StateGraph.Transition Transition8(condition=T7_idle);
  Modelica.StateGraph.Transition Transition9(condition=LIS_501 <= 0.01);
  Modelica.StateGraph.Transition Transition10(condition=TIS_702 <= 298);
  Modelica.StateGraph.Transition Transition11(condition=LIS_701 <= 0.01);
  Modelica.StateGraph.Transition Transition12(condition=TIS_602 <= 298);
  Modelica.StateGraph.Transition Transition13(condition=LIS_601 <= 0.01);

  Real LIS_301;
  Real LIS_501;
  Real LIS_601;
  Real LIS_701;
  Real QI_302;
  Real QIS_502;
  Real TIS_602;
  Real TIS_702;
  Boolean T5_idle;
  Boolean T7_idle;
  Modelica.StateGraph.TransitionWithSignal TransitionWithSignal1;
  Modelica.Blocks.Sources.BooleanExpression BooleanExpression1(y=time >
        2500);
equation 
  LIS_301 = sensors.LIS_301;
  LIS_501 = sensors.LIS_501;
  LIS_601 = sensors.LIS_601;
  LIS_701 = sensors.LIS_701;
  QI_302 = sensors.QI_302;
  QIS_502 = sensors.QIS_502;
  TIS_602 = sensors.TIS_602;
  TIS_702 = sensors.TIS_702;
  T5_idle = not actuators.V12 and not actuators.V15 and not actuators.T5_Heater
     and sensors.LIS_501 < 0.01;
  T7_idle = not actuators.V15 and not actuators.V18 and not actuators.
    T7_Cooling and sensors.LIS_701 < 0.01;

  actuators.P1 = Step10.active;
  actuators.P2 = Step13.active;
  actuators.T5_Heater = Step6.active;
  actuators.T7_Cooling = Step9.active;
  actuators.T6_Cooling = Step12.active;
  actuators.V1 = Step10.active;
  actuators.V2 = false;
  actuators.V3 = Step10.active;
  actuators.V4 = false;
  actuators.V5 = Step13.active;
  actuators.V6 = Step13.active;
  actuators.V8 = Step1.active;
  actuators.V9 = Step2.active;
  actuators.V10 = false;
  actuators.V11 = Step3.active;
  actuators.V12 = Step5.active;
  actuators.V15 = Step8.active;
  actuators.V18 = Step10.active;
  actuators.V19 = false;
  actuators.V20 = Step13.active;
  actuators.V21 = false;
  actuators.V22 = Step10.active;
  actuators.V23 = Step10.active;
  actuators.V25 = Step13.active;
  actuators.V24 = Step13.active;

  connect(InitialStep1.outPort[1], Transition1.inPort);
  connect(Transition1.outPort, Step1.inPort[1]);
  connect(Step1.outPort[1], Transition2.inPort);
  connect(Transition2.outPort, Step2.inPort[1]);
  connect(Step2.outPort[1], Transition3.inPort);
  connect(Transition3.outPort, Step3.inPort[1]);
  connect(Step3.outPort[1], Transition4.inPort);
  connect(Transition4.outPort, Step4.inPort[1]);
  connect(Step4.outPort[1], Transition5.inPort);
  connect(Transition5.outPort, Step5.inPort[1]);
  connect(Step5.outPort[1], Transition6.inPort);
  connect(Transition6.outPort, Step6.inPort[1]);
  connect(Step6.outPort[1], Transition7.inPort);
  connect(Step12.inPort[1], Parallel1.split[1]);
  connect(Step12.outPort[1], Transition12.inPort);
  connect(Transition12.outPort, Step13.inPort[1]);
  connect(Step13.outPort[1], Transition13.inPort);
  connect(Transition13.outPort, Step14.inPort[1]);
  connect(Step14.outPort[1], Parallel1.join[1]);
  connect(Step7.inPort[1], Parallel1.split[2]);
  connect(Step7.outPort[1], Transition8.inPort);
  connect(Transition8.outPort, Step8.inPort[1]);
  connect(Step8.outPort[1], Transition9.inPort);
  connect(Transition9.outPort, Step9.inPort[1]);
  connect(Step9.outPort[1], Transition10.inPort);
  connect(Transition10.outPort, Step10.inPort[1]);
  connect(Step10.outPort[1], Transition11.inPort);
  connect(Transition11.outPort, Step11.inPort[1]);
  connect(Step11.outPort[1], Parallel1.join[2]);
  connect(Transition7.outPort, Parallel1.inPort);
  connect(TransitionWithSignal1.inPort, Parallel1.outPort);
  connect(TransitionWithSignal1.outPort, InitialStep1.inPort[1]);
  connect(BooleanExpression1.y, TransitionWithSignal1.condition);
end Controller;

Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.TankWithTopPorts Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.TankWithTopPorts

Tank with inlet/outlet ports and with inlet ports at the top

Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.TankWithTopPorts

Information


Model of a tank that is open to the environment at the fixed pressure p_ambient. The tank is filled with a single or multiple-substance liquid, assumed to have uniform temperature and mass fractions.

At the top of the tank over the maximal fill level height a vector of FluidPorts, called topPorts, is present. The assumption is made that fluid flows always in to the tank via these ports (and never back in to the connector).

The vector of connectors ports are fluid ports at the bottom and side of the tank at a defineable height. Fluid can flow either out of or in to this port. The fluid level of the tank may be below one of these ports. This case is approximated by introducing a large pressure flow coefficient so that the mass flow rate through this port is very small in this case.

If the tank starts to over flow (i.e., level > height), an assertion is triggered.

When the diagram layer is open in the plot environment, the level of the tank is dynamically visualized. Note, the speed of the diagram animation in Dymola can be set via command animationSpeed(), e.g., animationSpeed(speed = 10)

Extends from Modelica.Fluid.Interfaces.PartialLumpedVolume (Lumped volume with mass and energy balance).

Parameters

TypeNameDefaultDescription
Heightheight Maximum level of tank before it overflows [m]
AreacrossArea Area of tank [m2]
VolumeV00Volume of the liquid when level = 0 [m3]
replaceable package MediumPartialMediumMedium in the component
VolumefluidVolumeVVolume [m3]
VesselPortsDataportsData[nPorts] Data of inlet/outlet ports at side and bottom of tank
Assumptions
Ambient
AbsolutePressurep_ambientsystem.p_ambientTank surface pressure [Pa]
TemperatureT_ambientsystem.T_ambientTank surface Temperature [K]
Dynamics
DynamicsenergyDynamicssystem.energyDynamicsFormulation of energy balance
DynamicsmassDynamicssystem.massDynamicsFormulation of mass balance
Heat transfer
Booleanuse_HeatTransferfalse= true to use the HeatTransfer model
Initialization
Heightlevel_start0.5*heightStart value of tank level [m]
AbsolutePressurep_startp_ambientStart value of pressure [Pa]
Booleanuse_T_starttrue= true, use T_start, otherwise h_start
TemperatureT_startif use_T_start then system.T...Start value of temperature [K]
SpecificEnthalpyh_startif use_T_start then Medium.s...Start value of specific enthalpy [J/kg]
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
Advanced
Port properties
RealhysteresisFactor0.1Hysteresis for empty pipe = diameter*hysteresisFactor
BooleanstiffCharacteristicForEmptyPortfalse=true, if steep pressure loss characteristic for empty pipe port
RealzetaLarge1e5Large pressure loss factor if mass flows out of empty pipe port
MassFlowRatem_flow_smallsystem.m_flow_smallRegularization range at zero mass flow rate [kg/s]

Connectors

TypeNameDescription
VesselFluidPorts_atopPorts[nTopPorts]Inlet ports over height at top of tank (fluid flows only from the port in to the tank)
VesselFluidPorts_bports[nPorts]inlet/outlet ports at bottom or side of tank (fluid flows in to or out of port; a port might be above the fluid level)
HeatPort_aheatPort 

Modelica definition

model TankWithTopPorts 
  "Tank with inlet/outlet ports and with inlet ports at the top"

    import Modelica.Constants;
    import Modelica.Fluid.Fittings.BaseClasses.lossConstant_D_zeta;
    import Modelica.Fluid.Utilities.regRoot2;
    import Modelica.Fluid.Vessels.BaseClasses.VesselPortsData;

  SI.Height level(stateSelect=StateSelect.prefer, start=level_start) 
    "Fluid level in the tank";

  //Tank geometry
  parameter SI.Height height "Maximum level of tank before it overflows";
  parameter SI.Area crossArea "Area of tank";
  parameter SI.Volume V0=0 "Volume of the liquid when level = 0";

  //Ambient
  parameter Medium.AbsolutePressure p_ambient=system.p_ambient 
    "Tank surface pressure";
  parameter Medium.Temperature T_ambient=system.T_ambient 
    "Tank surface Temperature";

  //Initialization
  parameter SI.Height level_start(min=0) = 0.5*height 
    "Start value of tank level";

  //Mass and energy balance
  extends Modelica.Fluid.Interfaces.PartialLumpedVolume(
    final fluidVolume = V,
    final initialize_p = false,
    final p_start = p_ambient);

  //Port definitions
  parameter Integer nTopPorts = 0 "Number of inlet ports above height (>= 1)";

  Vessels.BaseClasses.VesselFluidPorts_a topPorts[nTopPorts](redeclare package
      Medium =           Medium, m_flow(each start=0, each min=0)) 
    "Inlet ports over height at top of tank (fluid flows only from the port in to the tank)";
    

  parameter Integer nPorts = 0 
    "Number of inlet/outlet ports (on bottom and on the side)";
  parameter Modelica.Fluid.Vessels.BaseClasses.VesselPortsData portsData[
                                                                      nPorts] 
    "Data of inlet/outlet ports at side and bottom of tank";

  Vessels.BaseClasses.VesselFluidPorts_b ports[nPorts](redeclare package Medium
      =          Medium, m_flow(each start=0)) 
    "inlet/outlet ports at bottom or side of tank (fluid flows in to or out of port; a port might be above the fluid level)";
    

  // Heat transfer through boundary
  parameter Boolean use_HeatTransfer = false 
    "= true to use the HeatTransfer model";
  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,
    final states = {medium.state},
    surfaceAreas={crossArea+2*sqrt(crossArea*Modelica.Constants.pi)*level},
    final use_k = use_HeatTransfer);
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort if use_HeatTransfer;

  // Advanced
  parameter Real hysteresisFactor(min=0) = 0.1 
    "Hysteresis for empty pipe = diameter*hysteresisFactor";
  parameter Boolean stiffCharacteristicForEmptyPort = false 
    "=true, if steep pressure loss characteristic for empty pipe port";
  parameter Real zetaLarge(min=0) = 1e5 
    "Large pressure loss factor if mass flows out of empty pipe port";
  parameter SI.MassFlowRate m_flow_small(min=0) = system.m_flow_small 
    "Regularization range at zero mass flow rate";

  // Tank properties
  SI.Volume V(stateSelect=StateSelect.never) "Actual tank volume";
  Medium.EnthalpyFlowRate H_flow_top[nTopPorts] 
    "Enthalpy flow rates from the top ports in to the tank";
  Medium.EnthalpyFlowRate port_b_H_flow_bottom[nPorts] 
    "Enthalpy flow rates from the bottom ports in to the tank";
  Medium.MassFlowRate mXi_flow_top[nTopPorts, Medium.nXi] 
    "Substance mass flow rates from the top ports into the tank";
  Medium.MassFlowRate port_b_mXi_flow_bottom[nPorts, Medium.nXi] 
    "Substance mass flow rates from the bottom ports into the tank";
  Medium.MassFlowRate mC_flow_top[nTopPorts, Medium.nC] 
    "Trace substance mass flow rates from the top ports into the tank";
  Medium.MassFlowRate port_b_mC_flow_bottom[nPorts, Medium.nC] 
    "Trace substance mass flow rates from the bottom ports into the tank";
protected 
    SI.Area bottomArea[nPorts];
    SI.Diameter ports_emptyPipeHysteresis[nPorts];
    SI.Length levelAbovePort[nPorts] "Height of fluid over bottom ports";
    Boolean ports_m_flow_out[nPorts](each start = true, each fixed=true);
    Boolean aboveLevel[nPorts] "= true, if level >= ports[i].height";
    Real zetas_out[nPorts];
    Modelica.Blocks.Interfaces.RealInput portsData_diameter[nPorts] = portsData.diameter if nPorts > 0;
    Modelica.Blocks.Interfaces.RealInput portsData_diameter2[nPorts];
    Modelica.Blocks.Interfaces.RealInput portsData_height[nPorts] = portsData.height if nPorts > 0;
    Modelica.Blocks.Interfaces.RealInput portsData_height2[nPorts];
equation 
  assert(level <= height, "Tank starts to overflow (level = height = " + String(level) + ")");
  assert(m>=0, "Mass in tank is zero");

  // Compute constant data
  connect(portsData_diameter, portsData_diameter2);
  connect(portsData_height,portsData_height2);

  for i in 1:nPorts loop
      bottomArea[i]=Constants.pi*(portsData_diameter2[i]/2)^2;
      ports_emptyPipeHysteresis[i] = portsData_diameter2[i]*hysteresisFactor;
  end for;

  // Only one connection allowed to a port to avoid unwanted ideal mixing
/*
for i in 1:nTopPorts loop
  assert(cardinality(topPorts[i]) <= 1,"
topPorts[" + String(i) + "] of volume can at most be connected to one component.
If two or more connections are present, ideal mixing takes
place with these connections which is usually not the intention
of the modeller.
");
end for;

for i in 1:nPorts loop
  assert(cardinality(ports[i]) <= 1,"
ports[" + String(i) + "] of volume can at most be connected to one component.
If two or more connections are present, ideal mixing takes
place with these connections which is usually not the intention
of the modeller.
");
end for;
*/

  // Total quantities
  medium.p = p_ambient;
  V = crossArea*level + V0 "Volume of fluid";

  // Mass balances
  mb_flow = sum(topPorts.m_flow) + sum(ports.m_flow);
  for i in 1:Medium.nXi loop
    mbXi_flow[i] = sum(mXi_flow_top[:,i]) + sum(port_b_mXi_flow_bottom[:,i]);
  end for;
  for i in 1:Medium.nC loop
    mbC_flow[i]  = sum(mC_flow_top[:,i])  + sum(port_b_mC_flow_bottom[:,i]);
  end for;

  // Energy balance
  Hb_flow = sum(H_flow_top) + sum(port_b_H_flow_bottom);
  Qb_flow = heatTransfer.Q_flows[1];
  if Medium.singleState or energyDynamics == Types.Dynamics.SteadyState then
    Wb_flow = 0 
      "Mechanical work is neglected, since also neglected in medium model (otherwise unphysical small temperature change, if tank level changes)";
  else
    Wb_flow = -p_ambient*der(V);
  end if;

  // Properties at top ports
    for i in 1:nTopPorts loop
       // It is assumed that fluid flows only from one of the top ports in to the tank and never vice versa
       H_flow_top[i]     = topPorts[i].m_flow*actualStream(topPorts[i].h_outflow);
       mXi_flow_top[i,:] = topPorts[i].m_flow*actualStream(topPorts[i].Xi_outflow);
       mC_flow_top[i,:]  = topPorts[i].m_flow*actualStream(topPorts[i].C_outflow);
       topPorts[i].p     = p_ambient;
       topPorts[i].h_outflow = h_start;
       topPorts[i].Xi_outflow = X_start[1:Medium.nXi];
       topPorts[i].C_outflow  = C_start;
/*
       assert(topPorts[i].m_flow > -1, "Mass flows out of tank via topPorts[" + String(i) + "]\n" +
                                         "This indicates a wrong model");
*/
    end for;

  // Properties at bottom ports
    for i in 1:nPorts loop
       port_b_H_flow_bottom[i]   = ports[i].m_flow*actualStream(ports[i].h_outflow);
       port_b_mXi_flow_bottom[i,:] = ports[i].m_flow*actualStream(ports[i].Xi_outflow);
       port_b_mC_flow_bottom[i,:]  = ports[i].m_flow*actualStream(ports[i].C_outflow);
       aboveLevel[i] = level >= (portsData_height2[i] + ports_emptyPipeHysteresis[i])
                       or pre(aboveLevel[i]) and level >= (portsData_height2[i] - ports_emptyPipeHysteresis[i]);
       levelAbovePort[i] = if aboveLevel[i] then level - portsData_height2[i] else 0;
       ports[i].h_outflow = medium.h;
       ports[i].Xi_outflow = medium.Xi;
       ports[i].C_outflow  = C;

       if stiffCharacteristicForEmptyPort then
          // If port is above fluid level, use large zeta if fluid flows out of port (= small mass flow rate)
          zetas_out[i] = 1 + (if aboveLevel[i] then 0 else zetaLarge);
          ports[i].p = p_ambient + levelAbovePort[i]*system.g*medium.d
                               + Modelica.Fluid.Utilities.regSquare2(ports[i].m_flow, m_flow_small,
                                     lossConstant_D_zeta(portsData_diameter2[i], 0.01)/medium.d,
                                     lossConstant_D_zeta(portsData_diameter2[i], zetas_out[i])/medium.d);
          ports_m_flow_out[i] = false;

       else
          // Handling according to Remelhe/Poschlad
          ports_m_flow_out[i] = (pre(ports_m_flow_out[i]) and not ports[i].p>p_ambient)
                                     or ports[i].m_flow < -1e-6;
         if aboveLevel[i] then
             ports[i].p = p_ambient + levelAbovePort[i]*system.g*medium.d -
                               smooth(2,noEvent(if ports[i].m_flow < 0 then ports[i].m_flow^2/
                                     (2*medium.d*bottomArea[i]^2) else 0));
         else
            if pre(ports_m_flow_out[i]) then
               ports[i].m_flow = 0;
            else
               ports[i].p = p_ambient;
            end if;
         end if;
          zetas_out[i] =0;
       end if;
     end for;

initial equation 
    for i in 1:nPorts loop
       pre(aboveLevel[i]) = level_start >= portsData_height2[i];
    end for;

    if massDynamics == Types.Dynamics.FixedInitial then
      level = level_start;
    elseif massDynamics == Types.Dynamics.SteadyStateInitial then
      der(level) = 0;
    end if;


equation 
    connect(heatPort, heatTransfer.heatPorts[1]);
end TankWithTopPorts;

Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.TankWith3InletOutletArraysWithEvaporatorCondensor.HeatTransfer Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.TankWith3InletOutletArraysWithEvaporatorCondensor.HeatTransfer

Wall heat transfer

Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.TankWith3InletOutletArraysWithEvaporatorCondensor.HeatTransfer

Parameters

TypeNameDefaultDescription
Ambient
CoefficientOfHeatTransferk0Heat transfer coefficient to ambient [W/(m2.K)]
TemperatureT_ambientsystem.T_ambientAmbient temperature [K]
Internal Interface
replaceable package MediumPartialMediumMedium in the component
Integern1Number of heat transfer segments
Booleanuse_kfalse= true to use k value for thermal isolation

Connectors

TypeNameDescription
HeatPorts_aheatPorts[n]Heat port to component boundary

Modelica definition

replaceable model HeatTransfer = 
    Modelica.Fluid.Vessels.BaseClasses.HeatTransfer.IdealHeatTransfer 
  constrainedby 
  Modelica.Fluid.Vessels.BaseClasses.HeatTransfer.PartialVesselHeatTransfer 
  "Wall heat transfer";

Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.TankWithTopPorts.HeatTransfer Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.TankWithTopPorts.HeatTransfer

Wall heat transfer

Modelica.Fluid.Examples.AST_BatchPlant.BaseClasses.TankWithTopPorts.HeatTransfer

Parameters

TypeNameDefaultDescription
Ambient
CoefficientOfHeatTransferk0Heat transfer coefficient to ambient [W/(m2.K)]
TemperatureT_ambientsystem.T_ambientAmbient temperature [K]
Internal Interface
replaceable package MediumPartialMediumMedium in the component
Integern1Number of heat transfer segments
Booleanuse_kfalse= true to use k value for thermal isolation

Connectors

TypeNameDescription
HeatPorts_aheatPorts[n]Heat port to component boundary

Modelica definition

replaceable model HeatTransfer = 
    Modelica.Fluid.Vessels.BaseClasses.HeatTransfer.IdealHeatTransfer 
  constrainedby 
  Modelica.Fluid.Vessels.BaseClasses.HeatTransfer.PartialVesselHeatTransfer 
  "Wall heat transfer";

HTML-documentation generated by Dymola Sun Jan 17 21:12:07 2010.