Capacity control type.

within AixLib.Obsolete.Year2019.Fluid.HeatPumps.BaseClasses;
model CycleHP
  extends AixLib.Obsolete.BaseClasses.ObsoleteModel;
  import      Modelica.Units.SI;
  parameter Boolean HPctrlType =  true "Capacity control type"
  parameter Integer capCalcType = 1 "Type of capacity calculation"

  parameter DataBase.HeatPump.HeatPumpBaseDataDefinition
    dataTable=AixLib.Obsolete.Year2024.DataBase.HeatPump.EN255.Vitocal350BWH113()
    "Look-up table data for on/off heat pump according to EN255/EN14511"
protected
  final parameter Real tableQdot_con[:,:]=dataTable.tableQdot_con;
  final parameter Real tableP_ele[:,:]= dataTable.tableP_ele;
public
  replaceable function data_poly =
  AixLib.Obsolete.Year2024.DataBase.HeatPump.Functions.Characteristics.ConstantQualityGrade
    constrainedby
    AixLib.Obsolete.Year2024.DataBase.HeatPump.Functions.Characteristics.PartialBaseFct
    "Polynomial heat pump characteristics"

  replaceable function Corr_icing =
  AixLib.Obsolete.Year2024.DataBase.HeatPump.Functions.DefrostCorrection.NoModel   constrainedby
    AixLib.Obsolete.Year2024.DataBase.HeatPump.Functions.DefrostCorrection.PartialBaseFct
    "Frost/Defrost model (only air-to-water heat pumps)"
parameter SI.Temperature T_conMax=338.15 "Maximum condenser outlet temperature"
  parameter Real N_max=4200
    "Maximum speed of compressor in 1/min (only used if used in polynom)"
  parameter Real N_min=1500
    "Minimum speed of compressor in 1/min (only used if used in polynom)"
  parameter Real N_nom=3600
    "Nominal speed of compressor in 1/min (only used if used in polynom)"
  parameter Boolean PT1_cycle=false "First Order model for capacity"
  parameter SI.Time timeConstantCycle=1 "Time constant for first order model"
  parameter Real eta_ele=1
    "Assumption of P_tech/P_el (for calculation of Evaporator load)"
  parameter Real factorScale=1
    "Scaling factor (Attention: not physically correct)"
  parameter SI.Power P_eleAdd=0
    "Additional electric power when heat pump is on (not influenced through scaling factor)"

  parameter Boolean CorrFlowCo=false
    "Correction of mass flow different from nominal flow in condenser (use only if not included in polynom)"

  parameter SI.MassFlowRate mFlow_conNominal=0.5
    "Nominal mass flow rate in condenser"

  parameter Boolean CorrFlowEv=false
    "Correction of mass flow different from nominal flow in evaporator  (use only if not included in polynom)"

  parameter SI.MassFlowRate mFlow_evaNominal=0.5
    "Nominal mass flow rate in evaporator"

  SI.Power P_ele;
  SI.Power P_eleChar;
  SI.HeatFlowRate Qdot_eva;
  SI.HeatFlowRate Qdot_con;
  SI.HeatFlowRate Qdot_conChar;
  Real CoP;
  Real CoP_corr;
  Real CoP_char;
  Real N;
  Real factorCoP_icing;
  Real Char[2];
  Real T_conOutCorr;
  Real T_evaInCorr;

  Modelica.Blocks.Interfaces.RealOutput P_eleOut
  Modelica.Blocks.Interfaces.BooleanInput onOff_in
  Modelica.Blocks.Interfaces.RealOutput CoP_out
  Modelica.Blocks.Interfaces.RealInput N_in

protected
  Modelica.Blocks.Interfaces.RealInput firstOrder_outInternal
    "Needed to connect to conditional model";
  Modelica.Blocks.Interfaces.RealOutput firstOrder_inInternal
    "Needed to connect to conditional model";
  Modelica.Blocks.Interfaces.RealInput Qdot_conTableInternal
    "Needed to connect to conditional model";
  Modelica.Blocks.Interfaces.RealInput P_eleTableInternal
    "Needed to connect to conditional model";
  SI.MassFlowRate mFlow_conNom;
  SI.MassFlowRate mFlow_evaNom;

public
  Modelica.Blocks.Sources.RealExpression realQdot_con(y=Qdot_con)
public
  Modelica.Blocks.Sources.RealExpression realQdot_eva(y=Qdot_eva)
public
  Modelica.Blocks.Sources.RealExpression realPel(y=P_ele)
public
  Modelica.Blocks.Sources.RealExpression realCoP(y=CoP)

  Modelica.Blocks.Tables.CombiTable2Ds Qdot_ConTable(
    tableName="NoName",
    fileName="NoName",
    table=tableQdot_con,
    smoothness=smoothness) if not (capCalcType == 1)

  Modelica.Blocks.Tables.CombiTable2Ds P_eleTable(
    tableName="NoName",
    fileName="NoName",
    table=tableP_ele,
    smoothness=smoothness) if not (capCalcType == 1) "Electrical power table"
public
  Modelica.Blocks.Sources.RealExpression realT_evaIn(y=T_evaInCorr)
public
  Modelica.Blocks.Sources.RealExpression realT_conOut(y=T_conOutCorr)
  Modelica.Blocks.Continuous.FirstOrder firstOrder(T=timeConstantCycle)
                                                                 if PT1_cycle
public
  Modelica.Blocks.Math.Product productPelCoP1
  Modelica.Blocks.Math.UnitConversions.To_degC t_Ev_in
  Modelica.Blocks.Math.UnitConversions.To_degC t_Co_out
public
  Modelica.Blocks.Sources.RealExpression dummyZero(y=0)
public
  Modelica.Blocks.Sources.RealExpression realCoP_corr(y=CoP_corr)
  parameter Modelica.Blocks.Types.Smoothness smoothness=Modelica.Blocks.Types.Smoothness.LinearSegments
    "Smoothness of table interpolation"
public
  Modelica.Blocks.Logical.TriggeredTrapezoid realP_eleAdd(amplitude=P_eleAdd)
public
  Modelica.Blocks.Logical.GreaterThreshold greaterZero
  Modelica.Blocks.Math.Add add

public
  Modelica.Blocks.Sources.RealExpression dummyOne(y=1)

public
  Modelica.Blocks.Interfaces.RealOutput Qdot_conOut "Value of Real output"
  Modelica.Blocks.Math.UnitConversions.To_degC t_conIn
  Modelica.Blocks.Interfaces.RealInput T_conIn
    "Connector of Real input signal to be converted"
  Modelica.Blocks.Interfaces.RealInput T_evaIn
    "Connector of Real input signal to be converted"
  Modelica.Blocks.Interfaces.RealOutput Qdot_evaOut "Value of Real output"
  Modelica.Blocks.Interfaces.RealInput T_conOut
    "Connector of Real input signal to be converted"
  Modelica.Blocks.Interfaces.RealInput T_evaOut
    "Connector of Real input signal to be converted"
  Modelica.Blocks.Interfaces.RealInput mFlow_eva
    "Connector of Real input signal to be converted"
  Modelica.Blocks.Interfaces.RealInput mFlow_con
    "Connector of Real input signal to be converted"
public
  Modelica.Blocks.Sources.RealExpression maxTempCon(y=T_conMax)
public
  Modelica.Blocks.Math.Product productPelCoP2
  Modelica.Blocks.Continuous.LimPID PIDmaxHeatFlowCon(
    controllerType=Modelica.Blocks.Types.SimpleController.PI,
    Ti=1,
    yMax=1,
    yMin=0,
    y_start=1)
equation
  // correction of temperatures used in the table/polynomial
  if capCalcType==1 then
    mFlow_conNom= mFlow_conNominal;
    mFlow_evaNom= mFlow_evaNominal;
  else
    mFlow_conNom=dataTable.mFlow_conNom;
    mFlow_evaNom=dataTable.mFlow_evaNom;
  end if;

  if CorrFlowCo then
    T_conOutCorr=1/2*(mFlow_con/mFlow_conNom*(T_conOut-T_conIn)+T_conIn+T_conOut);
  else
    T_conOutCorr=T_conOut;
  end if;

  if CorrFlowEv then
    T_evaInCorr=1/2*(mFlow_eva/mFlow_evaNom*(T_evaIn-T_evaOut)+(T_evaIn+T_evaOut));
  else
    T_evaInCorr=T_evaIn;
  end if;

  // determination of speed N
if HPctrlType then
    N=N_nom;
else
  if N_in > N_max then
      N=N_max;
  else
    if N_in < N_min then
      N=N_min;
    else
      N=N_in;
    end if;
  end if;
end if;
  // determination of basic heat pump characteristics Qdot_conChar and P_eleChar and CoP_char
  if capCalcType==1 then //polynom
    Char=data_poly(N,T_conOutCorr, T_evaInCorr,mFlow_con,mFlow_eva);
  else //table
    Char={P_eleTableInternal,Qdot_conTableInternal};
  end if;

  if onOff_in then
    Qdot_conChar=Char[2];
    P_eleChar=Char[1];
    CoP_char=Qdot_conChar/P_eleChar;
  else
    Qdot_conChar=0;
    P_eleChar=0;
    CoP_char=0;
  end if;

  // determination of CoP-corrections
  if capCalcType==1 then
    factorCoP_icing=Corr_icing( T_evaInCorr-273.15);
  else
    factorCoP_icing=1;
  end if;

  CoP_corr=CoP_char*factorCoP_icing;//*f_cop_spread;

    P_ele=P_eleChar*factorScale;
  Qdot_con=firstOrder_outInternal;
  if onOff_in then
    if Qdot_con-P_ele*eta_ele>0 then
      Qdot_eva=Qdot_con-P_ele*eta_ele;
    else
      Qdot_eva=0;
    end if;
    CoP=Qdot_con/add.y;
  else
    Qdot_eva=0;
    CoP=0;
  end if;
  //internal connections for conditional models

  connect(productPelCoP1.y, firstOrder_inInternal);
  if PT1_cycle then
    connect(firstOrder_inInternal,firstOrder.u);
    connect(firstOrder.y,firstOrder_outInternal);
  else
     connect(firstOrder_inInternal,firstOrder_outInternal);
  end if;

   if capCalcType==1 then //polynom
    connect(Qdot_conTableInternal, dummyZero.y);
    connect(P_eleTableInternal, dummyZero.y);
   else
     connect(Qdot_conTableInternal,Qdot_ConTable.y);
    connect(P_eleTableInternal, P_eleTable.y);
   end if;

  connect(realPel.y, productPelCoP1.u1)
  connect(realCoP.y, CoP_out)
  connect(realT_evaIn.y, t_Ev_in.u)
  connect(realT_conOut.y, t_Co_out.u)
  connect(realCoP_corr.y, productPelCoP1.u2)
  connect(t_Ev_in.y,Qdot_ConTable. u2)
  connect(t_Ev_in.y, P_eleTable.u2)
  connect(t_Co_out.y,Qdot_ConTable. u1)
  connect(t_Co_out.y, P_eleTable.u1)

  connect(greaterZero.y, realP_eleAdd.u)

  connect(realPel.y, greaterZero.u)

  connect(realP_eleAdd.y, add.u2)
  connect(realPel.y, add.u1)

  connect(t_conIn.u,T_conIn)
  connect(realQdot_eva.y,Qdot_evaOut)
  connect(add.y, P_eleOut)
  connect(productPelCoP2.y, Qdot_conOut)
  connect(realQdot_con.y, productPelCoP2.u2)
  connect(PIDmaxHeatFlowCon.u_s, maxTempCon.y)
  connect(PIDmaxHeatFlowCon.u_m, T_conOut)
  connect(PIDmaxHeatFlowCon.y, productPelCoP2.u1)
end CycleHP;


within AixLib.Obsolete.Year2019.Fluid.HeatPumps.Examples;
model HeatPumpDetailed
  "Example for the detailed heat pump model in order to compare to simple one."
  extends AixLib.Obsolete.BaseClasses.ObsoleteModel;
 extends Modelica.Icons.Example;
  replaceable package Medium_sin = AixLib.Media.Water
    constrainedby Modelica.Media.Interfaces.PartialMedium
  replaceable package Medium_sou = AixLib.Media.Air
    constrainedby Modelica.Media.Interfaces.PartialMedium
  .AixLib.Obsolete.Year2019.Fluid.HeatPumps.HeatPumpDetailed heatPump(
    P_eleOutput=true,
    capCalcType=2,
    CorrFlowCo=false,
    CorrFlowEv=false,
    dataTable=DataBase.HeatPump.EN255.Vitocal350BWH113(),
    PT1_cycle=true,
    timeConstantCycle=1,
    mFlow_conNominal=1,
    mFlow_evaNominal=1,
    T_evaIn(transferHeat=true, TAmb=291.15),
    T_evaOut(transferHeat=true, TAmb=291.15),
    T_conIn(transferHeat=true, TAmb=273.15),
    T_conOut(transferHeat=true, TAmb=273.15),
    redeclare package Medium_con = Medium_sin,
    redeclare package Medium_eva = Medium_sou) "Detailed heat pump mainly based on manufacturing data"
  AixLib.Fluid.Sources.MassFlowSource_T sourceSideMassFlowSource(
    use_T_in=true,
    m_flow=1,
    redeclare package Medium = Medium_sou,
    nPorts=1,
    T=275.15) "Ideal mass flow source at the inlet of the source side"

  AixLib.Fluid.Sources.Boundary_pT sourceSideFixedBoundary(redeclare package Medium =
               Medium_sou, nPorts=1)
    "Fixed boundary at the outlet of the source side"
  Modelica.Blocks.Sources.Ramp TsuSourceRamp(
    duration=1000,
    startTime=1000,
    height=25,
    offset=278)
    "Ramp signal for the temperature input of the source side's ideal mass flow source"
  AixLib.Fluid.Sensors.TemperatureTwoPort senTAct(
    final transferHeat=true,
    final m_flow_nominal=heatPump.mFlow_conNominal,
    final tau=1,
    final initType=Modelica.Blocks.Types.Init.InitialState,
    final tauHeaTra=1200,
    redeclare final package Medium = Medium_sin,
    final T_start=303.15,
    final TAmb=291.15) "Temperature at sink  inlet"
  Modelica.Blocks.Logical.Hysteresis hys(
    pre_y_start=true,
    uLow=273.15 + 30,
    uHigh=273.15 + 40)
  Modelica.Blocks.Sources.Sine sine(
    f=1/3600,
    amplitude=3000,
    offset=3000)
  AixLib.Obsolete.Year2024.Fluid.Movers.SpeedControlled_Nrpm pumSou(
    redeclare final package Medium = Medium_sin,
    redeclare final AixLib.Fluid.Movers.Data.Pumps.Wilo.Stratos25slash1to8 per,

    final allowFlowReversal=true,
    final addPowerToMedium=false) "Fan or pump at source side of HP"
  AixLib.Fluid.MixingVolumes.MixingVolume Room(
    nPorts=2,
    final use_C_flow=false,
    final m_flow_nominal=heatPump.mFlow_conNominal,
    final V=5,
    redeclare package Medium = Medium_sin,
    final allowFlowReversal=true) "Volume of Condenser"

  Modelica.Blocks.Sources.Constant nIn(k=100)
  Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow heatFlowRateCon
    "Heat flow rate of the condenser"
  Modelica.Blocks.Math.Gain gain(k=-1)
  Modelica.Blocks.Logical.Not not2 "Negate output of hysteresis"
  AixLib.Fluid.Sources.Boundary_pT sinkSideFixedBoundary(redeclare package Medium =
               Medium_sin, nPorts=1)
    "Fixed boundary at the outlet of the sink side"
equation

  connect(TsuSourceRamp.y,sourceSideMassFlowSource. T_in)
  connect(nIn.y,pumSou. Nrpm)
  connect(Room.heatPort,heatFlowRateCon. port)
  connect(sine.y,gain. u)
  connect(heatFlowRateCon.Q_flow,gain. y)
  connect(Room.ports[1],pumSou. port_a)
  connect(senTAct.T,hys. u)
  connect(hys.y,not2. u)
  connect(senTAct.port_b,sinkSideFixedBoundary. ports[1])
  connect(senTAct.port_b,Room. ports[2])
  connect(not2.y, heatPump.onOff_in)
  connect(pumSou.port_b, heatPump.port_conIn)
  connect(heatPump.port_conOut, senTAct.port_a)
  connect(sourceSideMassFlowSource.ports[1], heatPump.port_evaIn)
  connect(heatPump.port_evaOut, sourceSideFixedBoundary.ports[1])
end HeatPumpDetailed;


within AixLib.Obsolete.Year2019.Fluid.HeatPumps.Examples;
model HeatPumpSimple
  "Example for the simple heat pump model in order to compare to detailed one."
 extends AixLib.Obsolete.BaseClasses.ObsoleteModel;
 import AixLib;

 extends Modelica.Icons.Example;
  Modelica.Blocks.Sources.BooleanPulse booleanPulse(period=1000)
    "Pulse signal for the on/off input of the heat pump"
  AixLib.Fluid.Sources.MassFlowSource_T sourceSideMassFlowSource(
    use_T_in=true,
    redeclare package Medium =
        Modelica.Media.Water.ConstantPropertyLiquidWater,
    m_flow=1,
    nPorts=1,
    T=275.15) "Ideal mass flow source at the inlet of the source side"

  AixLib.Fluid.Sources.Boundary_pT sourceSideFixedBoundary(redeclare package Medium =
               Modelica.Media.Water.ConstantPropertyLiquidWater, nPorts=1)
    "Fixed boundary at the outlet of the source side"
  AixLib.Fluid.Sources.Boundary_pT sinkSideFixedBoundary(redeclare package Medium =
               Modelica.Media.Water.ConstantPropertyLiquidWater, nPorts=1)
    "Fixed boundary at the outlet of the sink side"
  AixLib.Fluid.Sources.MassFlowSource_T sinkSideMassFlowSource(
    redeclare package Medium =
        Modelica.Media.Water.ConstantPropertyLiquidWater,
    m_flow=0.5,
    use_m_flow_in=true,
    nPorts=1,
    T=308.15) "Ideal mass flow source at the inlet of the sink side"

  Modelica.Blocks.Sources.Ramp TsuSourceRamp(
    duration=1000,
    startTime=1000,
    height=25,
    offset=278)
    "Ramp signal for the temperature input of the source side's ideal mass flow source"
  Modelica.Blocks.Sources.Pulse massFlowPulse(
    amplitude=0.5,
    period=1000,
    offset=0,
    startTime=0,
    width=51)
    "Pulse signal for the mass flow input of the sink side's ideal mass flow source"
  AixLib.Fluid.Sensors.TemperatureTwoPort temperature(redeclare package Medium =
               Modelica.Media.Water.ConstantPropertyLiquidWater,
      m_flow_nominal=0.01)
    "Temperature sensor at the outlet of the sink side"
  Modelica.Blocks.Interfaces.RealOutput Pel
    "Power consumption of the heat pump"
  Modelica.Blocks.Interfaces.RealOutput T_Co_out
    "Temperature at the outlet of the sink side of the heat pump"
  AixLib.Obsolete.Year2019.Fluid.HeatPumps.HeatPumpSimple heatPump(
    tablePower=[0.0,273.15,283.15; 308.15,1100,1150; 328.15,1600,1750],
    tableHeatFlowCondenser=[0.0,273.15,283.15; 308.15,4800,6300; 328.15,4400,5750],
    redeclare package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater,
    VolumeEvaporator=0.004,
    VolumeCondenser=0.004) "Simple heat pump based on manufacturing data"

equation
  connect(TsuSourceRamp.y, sourceSideMassFlowSource.T_in)
  connect(massFlowPulse.y, sinkSideMassFlowSource.m_flow_in)
  connect(sinkSideFixedBoundary.ports[1], temperature.port_b)
  connect(temperature.T, T_Co_out)

  connect(booleanPulse.y, heatPump.OnOff)
  connect(sourceSideMassFlowSource.ports[1], heatPump.port_a_source)
  connect(heatPump.port_b_source, sourceSideFixedBoundary.ports[1])
  connect(heatPump.Power, Pel)
  connect(heatPump.port_a_sink, sinkSideMassFlowSource.ports[1])
  connect(heatPump.port_b_sink, temperature.port_a)
end HeatPumpSimple;


within AixLib.Obsolete.Year2019.Fluid.HeatPumps;
package Examples "Collection of models that illustrate model use and test models"
  extends Modelica.Icons.ExamplesPackage;
end Examples;


Boundary source component. This model defines constant values for boundary conditions:

within AixLib.Obsolete.Year2019.Fluid.Sources;
model FixedBoundary "Boundary source component"
  extends AixLib.Obsolete.BaseClasses.ObsoleteModel;
  extends AixLib.Fluid.Sources.BaseClasses.PartialSource(final verifyInputs=true);
  parameter Boolean use_p=true "select p or d"
  parameter Medium.AbsolutePressure p=Medium.p_default "Boundary pressure"
  parameter Medium.Density d=Medium.density_pTX(
    p = Medium.p_default,
    T = Medium.T_default,
    X = Medium.X_default) "Boundary density"
  parameter Boolean use_T=true "select T or h"
  parameter Medium.Temperature T=Medium.T_default "Boundary temperature"
  parameter Medium.SpecificEnthalpy h=Medium.h_default
    "Boundary specific enthalpy"
  parameter Medium.MassFraction X[Medium.nX](
    final quantity=Medium.substanceNames) = Medium.X_default
    "Boundary mass fractions m_i/m"

  parameter Medium.ExtraProperty C[Medium.nC](
    final quantity=Medium.extraPropertiesNames)=fill(0, Medium.nC)
    "Boundary trace substances"

protected
  Modelica.Blocks.Interfaces.RealInput T_in_internal(final unit="K",
                                                     displayUnit="degC")
    "Needed to connect to conditional connector";
  Modelica.Blocks.Interfaces.RealInput p_in_internal(final unit="Pa")
    "Needed to connect to conditional connector";
  Modelica.Blocks.Interfaces.RealInput h_in(final unit="J/kg")
    "Needed to connect to conditional connector";

  Modelica.Blocks.Interfaces.RealInput h_in_internal= Medium.specificEnthalpy(Medium.setState_pTX(p_in_internal, T_in_internal, X_in_internal));
  // Modelica.Blocks.Interfaces.RealInput d_in_internal = Medium.density(Medium.setState_pTX(p_in_internal, T_in_internal, X_in_internal));

initial equation
  Modelica.Fluid.Utilities.checkBoundary(Medium.mediumName, Medium.substanceNames,
                                        Medium.singleState, use_p, X,
                                        "FixedBoundary");

equation
  h_in = h;
  if use_p or Medium.singleState then
    p_in_internal = p;
    connect(medium.p, p_in_internal);
  else
    p_in_internal = Medium.p_default;
    connect(medium.p, p_in_internal);
  end if;
  if use_T then
    T_in_internal = T;
    connect(medium.h, h_in_internal);
  else
    T_in_internal = Medium.T_default;
    connect(medium.h, h_in);
  end if;

  X_in_internal = X;
  connect(X_in_internal[1:Medium.nXi], Xi_in_internal);
  connect(medium.Xi, Xi_in_internal);

  ports.C_outflow = fill(C, nPorts);
  C_in_internal = C;

  if not verifyInputs then
    h_in_internal = Medium.h_default;
    p_in_internal = Medium.p_default;
    X_in_internal = Medium.X_default;
    T_in_internal = Medium.T_default;
  end if;

  for i in 1:nPorts loop
     ports[i].p          = p_in_internal;
     ports[i].h_outflow  = h_in_internal;
     ports[i].Xi_outflow = Xi_in_internal;
  end for;
end FixedBoundary;


Package with boundary condition models

within AixLib.Obsolete.Year2019.Fluid;
package Sources "Package with boundary condition models"
  extends Modelica.Icons.SourcesPackage;
end Sources;


Sandwich wall construction for heat storages.

within AixLib.Obsolete.Year2019.Fluid.Storage;
model StorageWall "Sandwich wall construction for heat storages"

  extends AixLib.Obsolete.BaseClasses.ObsoleteModel;
  extends AixLib.Fluid.Storage.BaseClasses.StorageCover(AWall= D1*Modelica.Constants.pi * height,
    condIns1(G=(AIns)*(lambdaIns)/(sIns/2)),
    condIns2(G=(AIns)*(lambdaIns)/(sIns/2)),
    convOutside(hCon=hConOut, A=AOutside),
    loadIns(C=cIns*(rhoIns)*(AIns)*(sIns)));

  parameter Modelica.Units.SI.Length height=0.15 "Height of layer"
  parameter Modelica.Units.SI.Area AIns=(D1 + 2*sWall)*Modelica.Constants.pi*
      height;
  parameter Modelica.Units.SI.Area AOutside=(D1 + 2*(sWall + sIns))*Modelica.Constants.pi
      *height;

equation
end StorageWall;


within AixLib.Obsolete.Year2019;
package Utilities "Package with utility functions such as for I/O"
  extends Modelica.Icons.Package;
end Utilities;


Adaptor for approximative longwave radiation exchange.

within AixLib.Obsolete.Year2019.Utilities.HeatTransfer;
model HeatToStar "Adaptor for approximative longwave radiation exchange"
  extends AixLib.Obsolete.BaseClasses.ObsoleteModel;
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a Therm
  AixLib.Utilities.Interfaces.RadPort Star
  parameter Modelica.Units.SI.Area A(min=0) "Area of radiation exchange";
  parameter Modelica.Units.SI.Emissivity eps=0.95 "Emissivity";
equation
  Therm.Q_flow + Star.Q_flow = 0;

  // To prevent negative solutions for T, the max() expression is used.
  // Negative solutions also occur when using max(T,0), therefore, 1 K is used.
  Therm.Q_flow = Modelica.Constants.sigma * eps * A * (
    max(Therm.T,1) * max(Therm.T,1) * max(Therm.T,1) * max(Therm.T,1) -
    max(Star.T,1) * max(Star.T,1) * max(Star.T,1) * max(Star.T,1));
end HeatToStar;


within AixLib.Obsolete.Year2019.Utilities;
package HeatTransfer "Models for different types of heat transfer"
  extends Modelica.Icons.Package;

end HeatTransfer;


Model for sensible heat output area specific. Overview

within AixLib.Obsolete.Year2019.Utilities.Sources.InternalGains.Humans;
model HumanSensibleHeatAreaSpecific "Model for sensible heat output area specific"
  extends AixLib.Obsolete.BaseClasses.ObsoleteModel;
  //Internal Gains People
  parameter Modelica.Units.SI.HeatFlux InternalGainsPeopleSpecific=1.0
    "Specific Heat Flow from people to the environment"
  parameter Real RatioConvectiveHeat = 0.5
    "Ratio of convective heat from overall heat output"
  parameter Modelica.Units.SI.Area RoomArea=20 "Area of room"
  parameter Modelica.Units.SI.Temperature T0=
      Modelica.Units.Conversions.from_degC(22) "Initial temperature";
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a ConvHeat
  AixLib.Utilities.HeatTransfer.HeatToRad RadiationConvertor(eps=Emissivity_Human, use_A_in=true)
  AixLib.Utilities.Interfaces.RadPort RadHeat
  Modelica.Blocks.Interfaces.RealInput Schedule
  Modelica.Blocks.Math.Gain internalGainsPeopleSpecific(k=
        InternalGainsPeopleSpecific)
  Modelica.Blocks.Math.Gain SurfaceArea_People(k = SurfaceArea_Human)
  Modelica.Blocks.Nonlinear.Limiter limiter(uMax = 1e+23, uMin=1)
  Modelica.Blocks.Math.Gain gain(k = RatioConvectiveHeat)
  Modelica.Blocks.Math.Gain gain1(k = 1 - RatioConvectiveHeat)
  Modelica.Blocks.Sources.Constant Area(k=RoomArea)
  Modelica.Blocks.Math.MultiProduct productHeatOutput(nu=2)
  Modelica.Blocks.Math.Gain PersonHeat(k=1/HeatPerPerson)
    "Divides total heat by the Heat Output per Person to get number of persons"
protected
  parameter Modelica.Units.SI.Area SurfaceArea_Human=2;
  parameter Real Emissivity_Human = 0.98;
  parameter Modelica.Units.SI.HeatFlowRate HeatPerPerson=70
    "Average Heat Flow per person taken from DIN V 18599-10"
  Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow ConvectiveHeat(T_ref = T0)
  Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow RadiativeHeat(T_ref = T0)
equation
  connect(ConvectiveHeat.port, ConvHeat)
  connect(RadiativeHeat.port, RadiationConvertor.convPort)
  connect(RadiationConvertor.radPort, RadHeat)
  connect(Schedule, internalGainsPeopleSpecific.u)
  connect(gain.y, ConvectiveHeat.Q_flow)
  connect(gain1.y, RadiativeHeat.Q_flow)
  connect(limiter.y, SurfaceArea_People.u)
  connect(SurfaceArea_People.y, RadiationConvertor.A_in)
  connect(internalGainsPeopleSpecific.y, productHeatOutput.u[1])
  connect(productHeatOutput.y, gain1.u)
  connect(productHeatOutput.y, gain.u)
  connect(PersonHeat.y, limiter.u)
  connect(productHeatOutput.y, PersonHeat.u)
  connect(Area.y, productHeatOutput.u[2])
end HumanSensibleHeatAreaSpecific;


Model for sensible heat output after VDI 2078. Overview

within AixLib.Obsolete.Year2019.Utilities.Sources.InternalGains.Humans;
model HumanSensibleHeat_VDI2078 "Model for sensible heat output after VDI 2078"
  extends AixLib.Obsolete.BaseClasses.ObsoleteModel;
  // Number of Persons
  parameter Integer ActivityType = 2 "Physical activity"
  parameter Real NrPeople = 1.0 "Number of people in the room"
  parameter Real RatioConvectiveHeat = 0.5
    "Ratio of convective heat from overall heat output"
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a ConvHeat
  AixLib.Utilities.HeatTransfer.HeatToRad RadiationConvertor(eps=Emissivity_Human, use_A_in=true)
  AixLib.Utilities.Interfaces.RadPort RadHeat
  Modelica.Blocks.Math.MultiProduct productHeatOutput(nu=2)
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a TRoom
    "Air temperature in room"
  Modelica.Thermal.HeatTransfer.Sensors.TemperatureSensor temperatureSensor
  Modelica.Blocks.Math.UnitConversions.To_degC to_degC
  Modelica.Blocks.Interfaces.RealInput Schedule
  Modelica.Blocks.Math.Gain Nr_People(k = NrPeople)
  Modelica.Blocks.Math.Gain SurfaceArea_People(k = SurfaceArea_Human)
  parameter Modelica.Units.SI.Temperature T0=
      Modelica.Units.Conversions.from_degC(22) "Initial temperature";
  Modelica.Blocks.Nonlinear.Limiter limiter(uMax = 1e+23, uMin=1)
  Modelica.Blocks.Math.Gain gain(k = RatioConvectiveHeat)
  Modelica.Blocks.Math.Gain gain1(k = 1 - RatioConvectiveHeat)
  Modelica.Thermal.HeatTransfer.Components.ThermalCollector thermalCollector(m=
        1)
protected
  parameter Modelica.Units.SI.Area SurfaceArea_Human=2;
  parameter Real Emissivity_Human = 0.98;
  Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow ConvectiveHeat(T_ref = T0)
  Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow RadiativeHeat(T_ref = T0)
  Modelica.Blocks.Tables.CombiTable1Dv HeatOutput(
    table=[10,100,125,155; 18,100,125,155; 20,95,115,140; 22,90,105,120; 23,85,
        100,115; 24,75,95,110; 25,75,85,105; 26,70,85,95; 35,70,85,95],
    smoothness=Modelica.Blocks.Types.Smoothness.LinearSegments,
    tableOnFile=false,
    columns={ActivityType})
equation
  connect(RadiativeHeat.port, RadiationConvertor.convPort)
  connect(RadiationConvertor.radPort, RadHeat)
  connect(TRoom, temperatureSensor.port)
  connect(temperatureSensor.T, to_degC.u)
  connect(to_degC.y, HeatOutput.u[1])
  connect(Schedule, Nr_People.u)
  connect(gain1.y, RadiativeHeat.Q_flow)
  connect(productHeatOutput.y, gain.u)
  connect(productHeatOutput.y, gain1.u)
  connect(Nr_People.y, limiter.u)
  connect(limiter.y, SurfaceArea_People.u)
  connect(SurfaceArea_People.y, RadiationConvertor.A_in)
  connect(HeatOutput.y, productHeatOutput.u[1:1])
  connect(Nr_People.y, productHeatOutput.u[2])
  connect(gain.y, ConvectiveHeat.Q_flow)
  connect(ConvectiveHeat.port, thermalCollector.port_a[1])
  connect(thermalCollector.port_b, ConvHeat)
end HumanSensibleHeat_VDI2078;


Model for sensible and latent heat output after VDI 2078. Overview

within AixLib.Obsolete.Year2019.Utilities.Sources.InternalGains.Humans;
model HumanTotalHeat_VDI2078 "Model for sensible and latent heat output after VDI 2078"
  extends AixLib.Obsolete.BaseClasses.ObsoleteModel;
  extends AixLib.Obsolete.Year2019.Utilities.Sources.InternalGains.Humans.HumanSensibleHeat_VDI2078(
                                    thermalCollector(m=2));
  Modelica.Blocks.Math.MultiProduct productMoistureOutput(nu=2)
  Modelica.Blocks.Interfaces.RealOutput MoistGain "in kg/s"
  Modelica.Blocks.Math.Gain toKgPerSecond(k=1/(3600*1000))
  Modelica.Blocks.Math.MultiProduct productLatentHeatOutput(nu=2)
protected
  Modelica.Blocks.Tables.CombiTable1Dv MoistureOutput(
    smoothness=Modelica.Blocks.Types.Smoothness.LinearSegments,
    tableOnFile=false,
    columns={ActivityType},
    table=[10,35,95,165; 18,35,95,165; 20,35,110,185; 22,40,125,215; 23,50,135,
        225; 24,60,140,230; 25,60,145,240; 26,65,150,250; 35,65,150,250])
  Modelica.Blocks.Tables.CombiTable1Dv HeatOutputLatent(
    smoothness=Modelica.Blocks.Types.Smoothness.LinearSegments,
    tableOnFile=false,
    columns={ActivityType},
    table=[10,25,75,115; 18,25,65,115; 20,25,75,130; 22,30,85,150; 23,35,90,155;
        24,40,95,160; 25,40,100,165; 26,45,105,175; 35,45,105,175])
  Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow ConvectiveHeatLatent(T_ref=T0)
equation
  connect(to_degC.y, MoistureOutput.u[1])
  connect(MoistureOutput.y, productMoistureOutput.u[1:1])
  connect(Nr_People.y, productMoistureOutput.u[2])
  connect(productMoistureOutput.y, toKgPerSecond.u)
  connect(toKgPerSecond.y, MoistGain)
  connect(HeatOutputLatent.y, productLatentHeatOutput.u[1:1])
  connect(Nr_People.y, productLatentHeatOutput.u[2])
  connect(to_degC.y, HeatOutputLatent.u[1])
  connect(productLatentHeatOutput.y, ConvectiveHeatLatent.Q_flow)
  connect(ConvectiveHeatLatent.port, thermalCollector.port_a[2])
end HumanTotalHeat_VDI2078;


PVSystem

within AixLib.Obsolete.Year2021.Electrical;
package PVSystem

  model PVSystem "PVSystem"
    extends
      AixLib.Obsolete.Year2021.Electrical.PVSystem.BaseClasses.PartialPVSystem;
    extends AixLib.Obsolete.BaseClasses.ObsoleteModel;

    Modelica.Blocks.Interfaces.RealInput TOutside(final quantity=
          "ThermodynamicTemperature", final unit="K") "Ambient temperature"
    AixLib.Utilities.Interfaces.SolarRad_in IcTotalRad
      "Solar radiation in W/m2"

    Modelica.Blocks.Sources.RealExpression realExpression(y=IcTotalRad.I)
  equation

    connect(TOutside, PVModuleDC.T_amb)
    connect(realExpression.y, PVModuleDC.SolarIrradiationPerSquareMeter)
  end PVSystem;

  model PVSystemTMY3
    extends
      AixLib.Obsolete.Year2021.Electrical.PVSystem.BaseClasses.PartialPVSystem;
    extends AixLib.Obsolete.BaseClasses.ObsoleteModel;

    parameter Modelica.Units.SI.Angle Latitude=0.65798912800186
      "Location's Latitude"

    parameter Modelica.Units.SI.Angle til=0.34906585039887
      "Surface's tilt angle (0:flat)"

    parameter Modelica.Units.SI.Angle azi=-0.78539816339745
      "Surface's azimut angle (0:South)"

    AixLib.BoundaryConditions.WeatherData.Bus weaBus
    Modelica.Blocks.Math.Add G "Total irradiation on tilted surface"
    AixLib.BoundaryConditions.SolarIrradiation.DiffusePerez HDifTil(til=til,
        azi=azi) "Diffuse irradiation on tilted surface"
    AixLib.BoundaryConditions.SolarIrradiation.DirectTiltedSurface HDirTil(til=
          til, azi=azi) "Direct irradiation on tilted surface"
  equation

    connect(weaBus, HDifTil.weaBus)
    connect(weaBus, HDirTil.weaBus)
    connect(HDifTil.H, G.u1)
    connect(HDirTil.H, G.u2)
    connect(PVModuleDC.T_amb, weaBus.TDryBul)
    connect(G.y, PVModuleDC.SolarIrradiationPerSquareMeter)
  end PVSystemTMY3;

  package Examples
    extends Modelica.Icons.ExamplesPackage;

    model ExamplePV
      extends Modelica.Icons.Example;
      extends AixLib.Obsolete.BaseClasses.ObsoleteModel;

      Modelica.Blocks.Interfaces.RealOutput Power(
        final quantity="Power",
        final unit="W")
        "Output Power of the PV system including the inverter"
      AixLib.BoundaryConditions.WeatherData.Old.WeatherTRY.Weather Weather(
        Latitude=49.5,
        Longitude=8.5,
        GroundReflection=0.2,
        tableName="wetter",
        extrapolation=Modelica.Blocks.Types.Extrapolation.Periodic,
        Wind_dir=false,
        Air_temp=true,
        Wind_speed=false,
        SOD=AixLib.DataBase.Weather.SurfaceOrientation.SurfaceOrientationData_N_E_S_W_RoofN_Roof_S(),
        fileName=Modelica.Utilities.Files.loadResource(
            "modelica://AixLib/Resources/WeatherData/TRY2010_12_Jahr_Modelica-Library.txt"))
        "Weather data input for simulation of PV power "

      PVSystem                            PVsystem(
        MaxOutputPower=4000,
        NumberOfPanels=5,
        data=AixLib.DataBase.SolarElectric.SymphonyEnergySE6M181())
        "PV system model including the inverter"

    equation
      connect(Weather.SolarRadiation_OrientedSurfaces[6], PVsystem.IcTotalRad)
      connect(Weather.AirTemp, PVsystem.TOutside)
      connect(PVsystem.PVPowerW, Power)
    end ExamplePV;

    model ExamplePVTMY3
      extends Modelica.Icons.Example;
      extends AixLib.Obsolete.BaseClasses.ObsoleteModel;

      Modelica.Blocks.Interfaces.RealOutput Power(
        final quantity="Power",
        final unit="W")
        "Output Power of the PV system including the inverter"
      PVSystemTMY3                            PVsystem(
        MaxOutputPower=4000,
        NumberOfPanels=5,
        data=AixLib.DataBase.SolarElectric.SymphonyEnergySE6M181())
        "PV system model including the inverter"

      AixLib.BoundaryConditions.WeatherData.ReaderTMY3 weaDat(filNam=
            Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos"))
    equation
      connect(weaDat.weaBus, PVsystem.weaBus)
      connect(PVsystem.PVPowerW, Power)
    end ExamplePVTMY3;
  end Examples;

  package BaseClasses
    extends Modelica.Icons.BasesPackage;

    partial model PartialPVSystem "Partial model for PV System"
      extends AixLib.Obsolete.BaseClasses.ObsoleteModel;

      parameter Integer NumberOfPanels = 1
        "Number of panels";
      parameter AixLib.Obsolete.Year2021.DataBase.SolarElectric.PVBaseRecord
        data "PV data set"
      parameter Modelica.Units.SI.Power MaxOutputPower
        "Maximum output power for inverter";
      Modelica.Blocks.Interfaces.RealOutput PVPowerW(
        final quantity="Power",
        final unit="W")
        "Output Power of the PV system including the inverter"

      AixLib.Obsolete.Year2021.Electrical.PVSystem.BaseClasses.PVModuleDC PVModuleDC(
        final Eta0=data.Eta0,
        final NoctTemp=data.NoctTemp,
        final NoctTempCell=data.NoctTempCell,
        final NoctRadiation=data.NoctRadiation,
        final TempCoeff=data.TempCoeff,
        final Area=NumberOfPanels*data.Area)
        "PV module with temperature dependent efficiency"
      AixLib.Obsolete.Year2021.Electrical.PVSystem.BaseClasses.PVInverterRMS PVInverterRMS(final
          uMax2=MaxOutputPower) "Inverter model including system management"
    equation

      connect(PVModuleDC.DCOutputPower, PVInverterRMS.DCPowerInput)
      connect(PVInverterRMS.PVPowerRmsW, PVPowerW)
    end PartialPVSystem;

    model PVInverterRMS "Inverter model including system management"
      extends AixLib.Obsolete.BaseClasses.ObsoleteModel;

      parameter Modelica.Units.SI.Power uMax2=3800
        "Upper limits of input signals (MaxOutputPower)";
     Modelica.Blocks.Interfaces.RealOutput PVPowerRmsW(
      final quantity="Power",
      final unit="W")
      "Output power of the PV system including the inverter"
     Modelica.Blocks.Interfaces.RealInput DCPowerInput(
      final quantity="Power",
      final unit="W")
      "DC output power of PV panels as input for the inverter"
     Modelica.Blocks.Nonlinear.Limiter MaxOutputPower(
       uMax(
        final quantity="Power",
        final displayUnit="Nm/s")=uMax2,
       uMin=0)
       "Limitier for maximum output power"
     Modelica.Blocks.Tables.CombiTable1Ds EfficiencyConverterSunnyBoy3800(
       tableOnFile=false,
       table=[0,0.798700;100,0.848907;200,0.899131;250,0.911689;300,0.921732;350,0.929669;400,0.935906;450,0.940718;500,0.943985;550,0.946260;600,0.947839;700,0.950638;800,0.952875;900,0.954431;1000,0.955214;1250,0.956231;1500,0.956449;2000,0.955198;2500,0.952175;3000,0.948659;3500,0.944961;3800,0.942621])
         "Efficiency of the inverter for different operating points"
     Modelica.Blocks.Math.Product Product2
         "Multiplies the output power of the PV cell with the efficiency of the inverter "

    equation
      connect(Product2.u2,EfficiencyConverterSunnyBoy3800.y[1])
      connect(Product2.y,MaxOutputPower.u)
      connect(MaxOutputPower.y,PVPowerRmsW)
      connect(Product2.u1,DCPowerInput)
      connect(EfficiencyConverterSunnyBoy3800.u,DCPowerInput)
    end PVInverterRMS;

    model PVModuleDC "partial model for PV module"
      extends AixLib.Obsolete.BaseClasses.ObsoleteModel;

      parameter Modelica.Units.SI.Area Area "Area of one Panel";
      parameter Modelica.Units.SI.Efficiency Eta0 "Maximum efficiency";
      parameter Modelica.Units.SI.Temperature NoctTemp "Defined temperature";
      parameter Modelica.Units.SI.Temperature NoctTempCell
        "Meassured cell temperature";
      parameter Modelica.Units.SI.RadiantEnergyFluenceRate NoctRadiation
        "Defined radiation";
      parameter Modelica.Units.SI.LinearTemperatureCoefficient TempCoeff
        "Temperature coeffient";
      Modelica.Units.SI.Power PowerPV "Power of PV panels";
      Modelica.Units.SI.Efficiency EtaVar "Efficiency of PV cell";
      Modelica.Units.SI.Temperature TCell "Cell temperature";

     Modelica.Blocks.Interfaces.RealOutput DCOutputPower(
      final quantity="Power",
      final unit="W")
      "DC output power of PV panels"
     Modelica.Blocks.Interfaces.RealInput T_amb(final quantity=
            "ThermodynamicTemperature", final unit="K") "Ambient temperature"

      Modelica.Blocks.Interfaces.RealInput SolarIrradiationPerSquareMeter

    equation
      TCell=T_amb + (NoctTempCell - NoctTemp)*SolarIrradiationPerSquareMeter/
        NoctRadiation;
      PowerPV=SolarIrradiationPerSquareMeter*Area*EtaVar;
      EtaVar=Eta0-TempCoeff*(TCell-NoctTemp)*Eta0;
      DCOutputPower=PowerPV;
    end PVModuleDC;
  end BaseClasses;
end PVSystem;


System wide properties

within AixLib.Obsolete.Year2021.Fluid.Actuators.Valves;
model MixingValve

  extends AixLib.Obsolete.BaseClasses.ObsoleteModel;

  extends Modelica.Fluid.Fittings.BaseClasses.PartialTeeJunction;
  outer AixLib.Utilities.Sources.BaseParameters baseParameters
    "System wide properties";

  parameter Real Kvs = 1.4 "Kv value at full opening (=1)";
  parameter Boolean filteredOpening=false
    "= true, if opening is filtered with a 2nd order CriticalDamping filter"
  parameter Modelica.Units.SI.Time riseTime=1
    "Rise time of the filter (time to reach 99.6 % of an opening step)"
  parameter Real leakageOpening(min=0,max=1)=1e-3
    "The opening signal is limited by leakageOpening (to improve the numerics)";

    ///////////////////////////////////////////////////////////////////////////
    //Valves                                                                 //
    ///////////////////////////////////////////////////////////////////////////
  AixLib.Obsolete.Year2021.Fluid.Actuators.Valves.SimpleValve Valve(
    Kvs=Kvs,
    m_flow_small=1e-4,
    redeclare package Medium = Medium)
  AixLib.Obsolete.Year2021.Fluid.Actuators.Valves.SimpleValve Valve2(
    Kvs=Kvs,
    m_flow_small=1e-4,
    redeclare package Medium = Medium)

    ///////////////////////////////////////////////////////////////////////////
    //Calculation of Opening                                                 //
    ///////////////////////////////////////////////////////////////////////////
  Modelica.Blocks.Interfaces.RealInput opening(min=0, max=1)
    "Valve position in the range 0..1"
  Modelica.Blocks.Sources.Constant Constant(k=1)
    "To compute opening of second valve"
  Modelica.Blocks.Math.Add add(k1=-1)

    ///////////////////////////////////////////////////////////////////////////
    //Filter                                                                 //
    ///////////////////////////////////////////////////////////////////////////

  Modelica.Blocks.Interfaces.RealOutput opening_filtered if filteredOpening
    "Filtered valve position in the range 0..1"

  Modelica.Blocks.Continuous.Filter filter(order=2, f_cut=5/(2*Modelica.Constants.pi
        *riseTime)) if filteredOpening

  Modelica.Blocks.Interfaces.RealOutput opening_actual
    "Actual opening dpending if filtered or not."
block MinLimiter "Limit the signal above a threshold"
 parameter Real uMin=0 "Lower limit of input signal";
  extends Modelica.Blocks.Interfaces.SISO;

equation
  y = smooth(0, noEvent( if u < uMin then uMin else u));
end MinLimiter;

  MinLimiter minLimiter(uMin=leakageOpening)

equation
  connect(filter.y, opening_filtered)
  connect(minLimiter.y, filter.u)
  connect(opening, minLimiter.u)
  connect(Valve.opening, opening_actual)
  connect(port_3, Valve.port_a)
  connect(Valve2.port_a, port_1)
  connect(add.y, Valve2.opening)
  connect(add.u1, opening_actual)
  connect(add.u2, Constant.y)
  connect(Valve.port_b, port_2)
  connect(Valve2.port_b, port_2)

  //Connection of Filter if used
  if filteredOpening then
     connect(filter.y, opening_actual);
  else
     connect(opening, opening_actual);
  end if;
end MixingValve;


Kv value at full opening (=1)

within AixLib.Obsolete.Year2021.Fluid.Actuators.Valves;
model SimpleValve

  extends AixLib.Obsolete.BaseClasses.ObsoleteModel;

  extends AixLib.Fluid.Interfaces.PartialTwoPortTransport;
  parameter Real Kvs = 1.4 "Kv value at full opening (=1)";
  Modelica.Blocks.Interfaces.RealInput opening "valve opening"

protected
  Modelica.Units.SI.Density rho "Density of the fluid";
equation
  rho = Medium.density(Medium.setState_phX(port_a.p, inStream(port_a.h_outflow), inStream(port_a.Xi_outflow)));
  // Enthalpy flow
  port_a.h_outflow = inStream(port_b.h_outflow);
  port_b.h_outflow = inStream(port_a.h_outflow);
  //Calculate the pressure drop
  //m_flow = rho * 1/3600 * Kvs * opening * sqrt(p / 100000);    //This is an educational purposes equation, can be used to show the functionality of a valve when the flow direction is correct
  m_flow = rho * 1 / 3600 * Kvs * opening * Modelica.Fluid.Utilities.regRoot2(dp, Modelica.Constants.small, 1e-4, 1e-4);
  //This equation is better suited for stable simulations as it works for both flow directions and is continuous at flow zero
end SimpleValve;


Kv value at full opening (=1)

within AixLib.Obsolete.Year2021.Fluid.Actuators.Valves;
model ThermostaticValve

  extends AixLib.Obsolete.BaseClasses.ObsoleteModel;

  extends AixLib.Fluid.Interfaces.PartialTwoPortTransport;
  parameter Real Kvs = 1.4 "Kv value at full opening (=1)"
  parameter Real Kv_setT = 0.8
    "Kv value when set temperature = measured temperature"
  parameter Real P = 2 "Deviation of P-controller when valve is closed"
  parameter Real Influence_PressureDrop = 0.14
    "influence of the pressure drop in K"
  parameter Real leakageOpening = 0.0001
    "may be useful for simulation stability. Always check the influence it has on your results";
  //Variable
  Real opening "valve opening";
  Real TempDiff "Difference between measured temperature and set temperature";
  Real Influence_PressureDrop_inK "Influence of pressure drop in Kelvin.";
  Modelica.Blocks.Interfaces.RealInput T_room "temperature in room"
  Modelica.Blocks.Interfaces.RealInput T_setRoom "set temperature in room"
protected
  Modelica.Units.SI.Density rho "Density of the fluid";
equation
  rho = Medium.density(Medium.setState_phX(port_a.p, inStream(port_a.h_outflow), inStream(port_a.Xi_outflow)));
  // Enthalpie flow
  port_a.h_outflow = inStream(port_b.h_outflow);
  port_b.h_outflow = inStream(port_a.h_outflow);
  //Calculate the pressure drop
  m_flow = rho * 1 / 3600 * Kvs * opening * Modelica.Fluid.Utilities.regRoot2(dp, Modelica.Constants.small, 1e-4, 1e-4);
  //original equation valve
  //calculate the influence of the pressure drop
  Influence_PressureDrop_inK = Influence_PressureDrop * (dp / 100000 - 0.1) / 0.5;
  //calculate the measured temperature difference
  TempDiff = T_room - T_setRoom - Influence_PressureDrop_inK;
  //Calculating the valve opening depending on the temperature deviation
  if TempDiff > P * (1- leakageOpening * Kvs / Kv_setT) then
    opening = leakageOpening;
  else
    opening = min(1, (P - TempDiff) * (Kv_setT / Kvs) / P);
  end if;
end ThermostaticValve;


within AixLib.Obsolete.Year2021.Fluid.Examples;
model PumpHydraulicResistance_closedLoop
  "Example with pump, hydraulic resistance and pipes in a closed loop"
  import AixLib;
  extends Modelica.Icons.Example;

  replaceable package Medium = AixLib.Media.Water;
  AixLib.Obsolete.Year2021.Fluid.Movers.Pump pump(
    V_flow(fixed=false),
    MinMaxCharacteristics=AixLib.DataBase.Pumps.Pump1(),
    V_flow_max=2,
    ControlStrategy=2,
    redeclare package Medium = Medium,
    m_flow_small=1e-4)
  AixLib.Fluid.FixedResistances.HydraulicResistance hydraulicResistance(
    zeta=2,
    redeclare package Medium = Medium,
    diameter=0.05,
    m_flow_nominal=0.001)
  AixLib.Fluid.FixedResistances.PressureDrop pipe(
    redeclare package Medium = Medium,
    m_flow_nominal=0.5,
    dp_nominal=200)
  AixLib.Fluid.FixedResistances.PressureDrop pipe1(
    redeclare package Medium = Medium,
    m_flow_nominal=0.5,
    dp_nominal=200)
  Modelica.Blocks.Sources.BooleanPulse NightSignal(period = 86400)
  AixLib.Fluid.Sources.Boundary_pT
                     PointFixedPressure(nPorts=1, redeclare package Medium =
        Medium)
equation
  connect(pump.port_b, pipe.port_a)
  connect(pipe.port_b, hydraulicResistance.port_a)
  connect(hydraulicResistance.port_b, pipe1.port_a)
  connect(pipe1.port_b, pump.port_a)
  connect(NightSignal.y, pump.IsNight)
  connect(PointFixedPressure.ports[1], pump.port_a)
end PumpHydraulicResistance_closedLoop;


within AixLib.Obsolete.Year2021.Fluid.Examples;
model PumpRadiatorThermostaticValve
  "Example of a simple heating system with radiator and thermostatic valve"
  import AixLib;
  extends Modelica.Icons.Example;

  package Medium = AixLib.Media.Water;

  AixLib.Obsolete.Year2021.Fluid.Movers.Pump pump(
    MinMaxCharacteristics=AixLib.DataBase.Pumps.Pump1(),
    V_flow_max=2,
    ControlStrategy=2,
    V_flow(fixed=false),
    redeclare package Medium = Medium,
    m_flow_small=1e-4)
  AixLib.Fluid.FixedResistances.PressureDrop pipe(
    redeclare package Medium = Medium,
    dp_nominal=200,
    m_flow_nominal=0.1)
  AixLib.Fluid.FixedResistances.PressureDrop pipe1(
    redeclare package Medium = Medium,
    dp_nominal=200,
    m_flow_nominal=0.1)
  Modelica.Blocks.Sources.BooleanConstant NightSignal(k = false)
  inner AixLib.Utilities.Sources.BaseParameters baseParameters
  AixLib.Fluid.Sources.Boundary_pT
                     PointFixedPressure(nPorts=1, redeclare package Medium =
        Medium)
  AixLib.Obsolete.Year2021.Fluid.Actuators.Valves.ThermostaticValve simpleValve(
    Influence_PressureDrop=0.15,
    Kvs=0.4,
    Kv_setT=0.12,
    leakageOpening=0,
    redeclare package Medium = Medium,
    m_flow_small=1e-4,
    dp(start=20000))
  AixLib.Fluid.HeatExchangers.Radiators.Radiator radiator(
    redeclare package Medium = Medium,
    m_flow_nominal=0.01,
    selectable=true,
    radiatorType=
        AixLib.DataBase.Radiators.Standard_MFD_WSchV1984_OneAppartment.Radiator_Kitchen())
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature AirTemp
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature RadTemp
  Modelica.Blocks.Sources.Constant Source_Temp(k = 273.15 + 20)
  Modelica.Blocks.Sources.Sine Source_opening(
    f=1/86400,
    amplitude=1,
    startTime=0,
    offset=273.15 + 18.5)
  Modelica.Blocks.Sources.Constant Source_TempSet_Boiler(k = 273.15 + 75)
  AixLib.Fluid.HeatExchangers.Heater_T       hea(
    redeclare package Medium = Medium,
    m_flow_nominal=0.01,
    dp_nominal=0)
equation
  connect(pipe1.port_b, pump.port_a)
  connect(NightSignal.y, pump.IsNight)
  connect(pipe.port_b, simpleValve.port_a)
  connect(simpleValve.port_b, radiator.port_a)
  connect(radiator.port_b, pipe1.port_a)
  connect(Source_Temp.y, AirTemp.T)
  connect(Source_Temp.y, RadTemp.T)
  connect(Source_Temp.y, simpleValve.T_room)
  connect(Source_opening.y, simpleValve.T_setRoom)
  connect(PointFixedPressure.ports[1], pump.port_a)
  connect(pipe.port_a, hea.port_b)
  connect(pump.port_b, hea.port_a)
  connect(hea.TSet, Source_TempSet_Boiler.y)
  connect(AirTemp.port, radiator.ConvectiveHeat)
  connect(radiator.RadiativeHeat, RadTemp.port)
end PumpRadiatorThermostaticValve;


within AixLib.Obsolete.Year2021.Fluid.Examples;
model PumpRadiatorValve
  "Example of a simple heating system with radiator and simple valve"
  import AixLib;
  extends Modelica.Icons.Example;

  package Medium = AixLib.Media.Water;

  AixLib.Obsolete.Year2021.Fluid.Movers.Pump pump(
    MinMaxCharacteristics=AixLib.DataBase.Pumps.Pump1(),
    V_flow_max=2,
    ControlStrategy=2,
    V_flow(fixed=false),
    Head_max=2,
    redeclare package Medium = Medium,
    m_flow_small=1e-4)
  AixLib.Fluid.FixedResistances.PressureDrop pipe(
    redeclare package Medium = Medium,
    m_flow_nominal=0.1,
    dp_nominal=200)
  AixLib.Fluid.FixedResistances.PressureDrop pipe1(
    redeclare package Medium = Medium,
    m_flow_nominal=0.1,
    dp_nominal=200)
  Modelica.Blocks.Sources.BooleanConstant NightSignal(k = false)
  AixLib.Fluid.Sources.Boundary_pT
                     PointFixedPressure(nPorts=1, redeclare package Medium =
        Medium)
  AixLib.Obsolete.Year2021.Fluid.Actuators.Valves.SimpleValve simpleValve(
    Kvs=0.4,
    redeclare package Medium = Medium,
    m_flow_small=1e-4)
  AixLib.Fluid.HeatExchangers.Radiators.Radiator radiator(
    redeclare package Medium = Medium,
    m_flow_nominal=0.01,
    selectable=true,
    radiatorType=
        AixLib.DataBase.Radiators.Standard_MFD_WSchV1984_OneAppartment.Radiator_Kitchen())
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature AirTemp
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature RadTemp
  Modelica.Blocks.Sources.Constant Source_Temp(k = 273.15 + 20)
  Modelica.Blocks.Sources.Sine Source_opening(
    f=1/86400,
    offset=0.5,
    startTime=-21600,
    amplitude=0.49)
  Modelica.Blocks.Sources.Constant Source_TempSet_Boiler(k = 273.15 + 75)
  AixLib.Fluid.HeatExchangers.Heater_T       hea(
    redeclare package Medium = Medium,
    m_flow_nominal=0.01,
    dp_nominal=0)
equation
  connect(pipe1.port_b, pump.port_a)
  connect(NightSignal.y, pump.IsNight)
  connect(pipe.port_b, simpleValve.port_a)
  connect(simpleValve.port_b, radiator.port_a)
  connect(radiator.port_b, pipe1.port_a)
  connect(Source_Temp.y, AirTemp.T)
  connect(Source_Temp.y, RadTemp.T)
  connect(Source_opening.y, simpleValve.opening)
  connect(PointFixedPressure.ports[1], pump.port_a)
  connect(pipe.port_a, hea.port_b)
  connect(pump.port_b, hea.port_a)
  connect(hea.TSet, Source_TempSet_Boiler.y)
  connect(AirTemp.port, radiator.ConvectiveHeat)
  connect(radiator.RadiativeHeat, RadTemp.port)
end PumpRadiatorValve;


within AixLib.Obsolete.Year2021.Fluid.Movers;
model Pump

  extends AixLib.Obsolete.BaseClasses.ObsoleteModel;

  extends AixLib.Fluid.Interfaces.PartialTwoPortTransport;
  parameter AixLib.DataBase.Pumps.MinMaxCharacteristicsBaseDataDefinition MinMaxCharacteristics = AixLib.DataBase.Pumps.Pump1()
    "Head = f(V_flow) for minimal and maximal rotational speed"
  parameter Integer ControlStrategy = 1 "Control Strategy"
  parameter Modelica.Units.SI.Height Head_max=max(MinMaxCharacteristics.minMaxHead[
      :, 3]) "Set head for the control strategy"
  parameter Real V_flow_max(unit="m3/h") = max(MinMaxCharacteristics.minMaxHead[:,1]) "Vmax in m3/h for the control strategy"
  Modelica.Units.SI.Height Head(start=0, min=0) "Pumping head";
  Modelica.Blocks.Tables.CombiTable1Ds table_minMaxCharacteristics(tableOnFile = false, columns = {2, 3}, table = MinMaxCharacteristics.minMaxHead)
    "Table with Head = f(V_flow) min amd max characteristics for the pump"
  Modelica.Blocks.Interfaces.BooleanInput IsNight

  parameter Modelica.Units.SI.MassFlowRate m_flowsPump[:]=MinMaxCharacteristics.minMaxHead[
      :, 1] ./ 3600.*rho_default "Convert VFlow in m3/h to kg/s";
  parameter Modelica.Units.SI.PressureDifference dpsPump[:]=
      MinMaxCharacteristics.minMaxHead[:, 3] .* rho_default .* Modelica.Constants.g_n
    "Convert m of head to Pa";

protected
  final parameter Medium.ThermodynamicState state_default = Medium.setState_pTX(
      T=Medium.T_default,
      p=Medium.p_default,
      X=Medium.X_default[1:Medium.nXi]) "Medium state at default values";
  // Density at medium default values, used to compute the size of control volumes
  final parameter Modelica.Units.SI.Density rho_default=Medium.density(state=
      state_default) "Density, used to volume flow rate from mass flow rate";
equation
  // Enthalpie flow
  port_a.h_outflow = inStream(port_b.h_outflow);
  port_b.h_outflow = inStream(port_a.h_outflow);
  // Set input to min max characteristics table
  table_minMaxCharacteristics.u = V_flow * 3600;
  if IsNight then
    //night mode active
    Head = table_minMaxCharacteristics.y[1];
    // minimal characteristic
  else
    if ControlStrategy == 1 then
      Head = min(max(Head_max, table_minMaxCharacteristics.y[1]), table_minMaxCharacteristics.y[2]);
      //Set Head according to the control strategy
    else
      Head = min(max(0.5 * Head_max + 0.5 * Head_max / V_flow_max * V_flow * 3600, table_minMaxCharacteristics.y[1]), table_minMaxCharacteristics.y[2]);
      //Set Head according to the control strategy
    end if;
  end if;
  // Connect the pump variables with the variables of the two port model
  Head = -dp / (Medium.density(Medium.setState_phX(port_a.p, inStream(port_a.h_outflow), inStream(port_a.Xi_outflow))) * Modelica.Constants.g_n);
end Pump;


modelica://AixLib/Resources/NcDataReader_ExampleData/Temp_Year.nc. Overview

within AixLib.Obsolete.Year2022.Examples;
model NcDataReader
  extends Modelica.Icons.Example;
  Obsolete.Year2022.Utilities.NcDataReader NcDataReader_test(
    fileName=Modelica.Utilities.Files.loadResource(
        "modelica://AixLib/Resources/NcDataReader_ExampleData/Temp_Year.nc"),
    use_varName=true,
    use_attNameReal=true,
    use_attNameInt=true,
    varName={"temp_year"},
    attNameReal={"float_ex"},
    attNameInt={"Region","TRY"})
end NcDataReader;


Simulation of 1 apartment

within AixLib.Obsolete.Year2022.ThermalZones.HighOrder.Examples;
model Appartment_VoWo "Simulation of 1 apartment"
  extends Modelica.Icons.Example;
  parameter AixLib.DataBase.Weather.TRYWeatherBaseDataDefinition weatherDataDay = AixLib.DataBase.Weather.TRYWinterDay();
  replaceable package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater
    "Medium in the system"
  AixLib.Obsolete.Year2022.ThermalZones.HighOrder.House.MFD.BuildingAndEnergySystem.OneAppartment_Radiators
    VoWoWSchV1984(
    redeclare package Medium = Medium,
    redeclare model WindowModel =
        AixLib.ThermalZones.HighOrder.Components.WindowsDoors.WindowSimple,
    redeclare model CorrSolarGainWin =
        AixLib.ThermalZones.HighOrder.Components.WindowsDoors.BaseClasses.CorrectionSolarGain.CorGSimple,

    fixedHeatFlow3(T_ref=288.15),
    fixedHeatFlow5(T_ref=283.15),
    fixedHeatFlow16(T_ref=288.15),
    ratioSunblind=0.8,
    solIrrThreshold=350,
    TOutAirLimit=290.15)
  AixLib.Obsolete.Year2021.Fluid.Movers.Pump Pump(redeclare package Medium = Medium, m_flow_small=0.0001) "Pump in heating system"
  AixLib.Fluid.FixedResistances.PressureDrop res1(
    redeclare package Medium = Medium,
    dp_nominal=200,
    m_flow_nominal=0.3) "Hydraulic resistance of supply"
  AixLib.Fluid.FixedResistances.PressureDrop res2(
    redeclare package Medium = Medium,
    dp_nominal=200,
    m_flow_nominal=0.3) "Hydraulic resistance of return"
  Modelica.Blocks.Sources.Constant Source_TsetChildren(k = 273.15 + 22)
  Modelica.Blocks.Sources.Constant Source_TsetLivingroom(k = 273.15 + 20)
  Modelica.Blocks.Sources.Constant Source_TsetBedroom(k = 273.15 + 20)
  Modelica.Blocks.Sources.Constant Source_TsetKitchen(k = 273.15 + 20)
  AixLib.BoundaryConditions.WeatherData.Old.WeatherTRY.Weather combinedWeather(
    Latitude=49.5,
    Longitude=8.5,
    Wind_dir=false,
    Wind_speed=true,
    Air_temp=true,
    SOD=AixLib.DataBase.Weather.SurfaceOrientation.SurfaceOrientationData_NE_SE_SW_NW_Hor(),
    fileName=
        "modelica://AixLib/Resources/WeatherData/TRY2010_12_Jahr_Modelica-Library.txt",
    WeatherData(tableOnFile=false, table=weatherDataDay.weatherData))

  Modelica.Blocks.Sources.Constant Source_TsetBath(k = 273.15 + 24)
  Modelica.Blocks.Sources.Constant AirExWindow[5](each k = 0.5)
  AixLib.Fluid.Sources.Boundary_ph
                                 tank(nPorts=2, redeclare package Medium =
        Medium)
  Modelica.Blocks.Sources.BooleanExpression booleanExpression
  inner AixLib.Utilities.Sources.BaseParameters baseParameters
  Modelica.Blocks.Sources.Constant Source_TseBoiler(k = 273.15 + 55)
  output Real Ta = combinedWeather.AirTemp;
  // Livingroom
  output Real airTLi = VoWoWSchV1984.Appartment.Livingroom.airload.T;
  output Real radPowerLiConv = -VoWoWSchV1984.Hydraulic.convLi.Q_flow;
  output Real radPowerLiRad = -VoWoWSchV1984.Hydraulic.radLi.Q_flow;
  output Real travelHVLi = VoWoWSchV1984.Hydraulic.valveLi.opening;
  output Real massFlowLi = VoWoWSchV1984.Hydraulic.valveLi.port_a.m_flow;
  // Bath
  output Real airTBa = VoWoWSchV1984.Appartment.Bathroom.airload.T;
  output Real radPowerBaConv = -VoWoWSchV1984.Hydraulic.convBa.Q_flow;
  output Real radPowerBaRad = -VoWoWSchV1984.Hydraulic.radBa.Q_flow;
  output Real travelHVBa = VoWoWSchV1984.Hydraulic.valveBa.opening;
  output Real massFlowBa = VoWoWSchV1984.Hydraulic.valveBa.port_a.m_flow;
  // Bedroom
  output Real airTBe = VoWoWSchV1984.Appartment.Bedroom.airload.T;
  output Real radPowerBeConv = -VoWoWSchV1984.Hydraulic.convBe.Q_flow;
  output Real radPowerBeRad = -VoWoWSchV1984.Hydraulic.radBe.Q_flow;
  output Real travelHVBe = VoWoWSchV1984.Hydraulic.valveBe.opening;
  output Real massFlowBe = VoWoWSchV1984.Hydraulic.valveBe.port_a.m_flow;
  // Children
  output Real airTCh = VoWoWSchV1984.Appartment.Children.airload.T;
  output Real radPowerChConv = -VoWoWSchV1984.Hydraulic.convCh.Q_flow;
  output Real radPowerChRad = -VoWoWSchV1984.Hydraulic.radCh.Q_flow;
  output Real travelHVCh = VoWoWSchV1984.Hydraulic.valveCh.opening;
  output Real massFlowCh = VoWoWSchV1984.Hydraulic.valveCh.port_a.m_flow;
  // Kitchen
  output Real airTKi = VoWoWSchV1984.Appartment.Kitchen.airload.T;
  output Real radPowerKiConv = -VoWoWSchV1984.Hydraulic.convKi.Q_flow;
  output Real radPowerKiRad = -VoWoWSchV1984.Hydraulic.radKi.Q_flow;
  output Real travelHVKi = VoWoWSchV1984.Hydraulic.valveKi.opening;
  output Real massFlowKi = VoWoWSchV1984.Hydraulic.valveKi.port_a.m_flow;
  Fluid.HeatExchangers.Heater_T              hea(
    redeclare package Medium = Medium,
    m_flow_nominal=0.01,
    dp_nominal=0)
equation
  connect(Pump.port_b, hea.port_a)
  connect(hea.port_b,res1. port_a)
  connect(res1.port_b, VoWoWSchV1984.Inflow)
  connect(VoWoWSchV1984.Returnflow, res2.port_a)
  // Here the relevant Variables for the simulation are set as output to limit the dimension of the result file
  connect(combinedWeather.WindSpeed, VoWoWSchV1984.WindSpeedPort)
  connect(AirExWindow.y, VoWoWSchV1984.AirExchangePort_Window)
  connect(combinedWeather.SolarRadiation_OrientedSurfaces[2], VoWoWSchV1984.SolarRadiation[1])
  connect(combinedWeather.SolarRadiation_OrientedSurfaces[4], VoWoWSchV1984.SolarRadiation[2])
  connect(combinedWeather.AirTemp, VoWoWSchV1984.air_temp)
  connect(Source_TsetLivingroom.y, VoWoWSchV1984.TSet[1])
  connect(Source_TsetBedroom.y, VoWoWSchV1984.TSet[2])
  connect(Source_TsetChildren.y, VoWoWSchV1984.TSet[3])
  connect(booleanExpression.y, Pump.IsNight)
  connect(Source_TsetBath.y, VoWoWSchV1984.TSet[4])
  connect(Source_TsetKitchen.y, VoWoWSchV1984.TSet[5])
  connect(res2.port_b, tank.ports[1])
  connect(Pump.port_a, tank.ports[2])
  connect(Source_TseBoiler.y, hea.TSet)
end Appartment_VoWo;


File reader for external data.

within AixLib.Obsolete.Year2022.Utilities;
model NcDataReader "File reader for external data"
  import nc = NcDataReader2.Functions;
  parameter String fileName
    "File where external data is stored"
  parameter Boolean use_varName=false "Get variables from fileName"
  parameter Boolean use_attNameReal=false "Get real attributes from fileName"
  parameter Boolean use_attNameInt=false "Get integer attributes from fileName"
  parameter String varName[:]={""} "Array name in .nc file"
  parameter String attNameReal[:]={""}
    "Name of attribute of type real in .nc file"
  parameter String attNameInt[:]={""}
    "Name of attribute of type integer in .nc file"
  parameter Modelica.Units.SI.Time offset=0
    "Time period prior current simulation time";
  Modelica.Blocks.Interfaces.RealOutput y[size(varName, 1)]
    if use_varName
    "Output Vector with all variables"
  Modelica.Blocks.Interfaces.RealOutput yAttReal[size(attNameReal, 1)]
    if use_attNameReal
    "Output Vector with all attributes of type double"
  Modelica.Blocks.Interfaces.IntegerOutput yAttInt[size(attNameInt, 1)]
    if use_attNameInt
    "Output Vector with all attributes of type integer"
protected
  Modelica.Blocks.Interfaces.RealOutput y_internal[size(varName, 1)]
    "Needed to connect to conditional connector";
  Modelica.Blocks.Interfaces.RealOutput yAttReal_internal[size(attNameReal, 1)]
    "Needed to connect to conditional connector";
  Modelica.Blocks.Interfaces.IntegerOutput yAttInt_internal[size(attNameInt, 1)]
    "Needed to connect to conditional connector";
equation
  connect(y, y_internal);
  connect(yAttReal, yAttReal_internal);
  connect(yAttInt, yAttInt_internal);

  if use_varName then
    for i in 1:size(varName, 1) loop
      y_internal[i] = nc.ncEasyGet1D(
        fileName,
        varName[i],
        time - offset);
    end for;
  else
    for i in 1:size(varName, 1) loop
      y_internal[i] = 0;
    end for;
  end if;

  if use_attNameReal then
    for i in 1:size(attNameReal, 1) loop
      yAttReal_internal[i] = nc.ncEasyGetAttributeDouble(
        fileName,
        "",
        attNameReal[i]);
    end for;
  else
    for i in 1:size(attNameReal, 1) loop
      yAttReal_internal[i] = 0;
    end for;
  end if;

  if use_attNameInt then
    for i in 1:size(attNameInt, 1) loop
      yAttInt_internal[i] = nc.ncEasyGetAttributeLong(
        fileName,
        "",
        attNameInt[i]);
    end for;
  else
    for i in 1:size(attNameInt, 1) loop
      yAttInt_internal[i] = 0;
    end for;
  end if;
end NcDataReader;


Function for the interpolation of table data for airflow models. This function returns the value on a cubic hermite spline through the given support points
 and provided spline derivatives at these points with monotonically increasing values.
 The last 2 points in the table are linearly interpolated.

within AixLib.Obsolete.Year2024.Airflow.Multizone.BaseClasses;
function interpolate
  "Function for the interpolation of table data for airflow models"
  extends Modelica.Icons.Function;
  extends AixLib.Obsolete.BaseClasses.ObsoleteModel;
  input Real u "Independent variable";
  input Real[:] xd "X-axis support points";
  input Real[size(xd, 1)] yd "Y-axis support points";
  input Real[size(xd, 1)] d(each fixed=false) "Derivatives at the support points";

  output Real z "Dependent variable with monotone interpolation";

protected
  Integer i "Integer to select data interval";

algorithm
  i := 1;
  for j in 1:size(xd, 1) - 1 loop
    if u > xd[j] then
      i := j;
    end if;
  end for;

  // Extrapolate or interpolate the data
  if i == 1 then
    z:=yd[1]+(u-xd[1])*(yd[2]-yd[1])/(xd[2]-xd[1]); //Interpolate linearly between first and second point
  elseif i == (size(xd, 1) - 1) then
    z:=yd[end-1]+(u-xd[end-1])*(yd[end]-yd[end-1])/(xd[end]-xd[end-1]); //Interpolate linearly between last and second-to-last point.

  else
    z :=AixLib.Utilities.Math.Functions.cubicHermiteLinearExtrapolation(
        x=u,
        x1=xd[i],
        x2=xd[i + 1],
        y1=yd[i],
        y2=yd[i + 1],
        y1d=d[i],
        y2d=d[i + 1]);
  end if;
end interpolate;


Test model for the function flowElementData. This example demonstrates the function

 AixLib.Airflow.Multizone.BaseClasses.interpolate.

within AixLib.Obsolete.Year2024.Airflow.Multizone.BaseClasses.Examples;
model Interpolate "Test model for the function flowElementData"
  extends Modelica.Icons.Example;

  parameter Real table[:,:]=[-50,-0.08709; -25,-0.06158; -10,-0.03895; -5,-0.02754;
      -3,-0.02133; -2,-0.01742; -1,-0.01232; 0,0; 1,0.01232; 2,0.01742; 3,0.02133;
      4.5,0.02613; 50,0.02614]
      "Table of mass flow rate in kg/s (second column) as a function of pressure difference in Pa (first column)";

  Modelica.Units.SI.PressureDifference dp
    "Pressure difference";
  Modelica.Units.SI.MassFlowRate m_flow
    "Mass flow rate";

protected
  parameter Real[:] xd=table[:,1] "X-axis support points";
  parameter Real[size(xd, 1)] yd=table[:,2] "Y-axis support points";
  parameter Real[size(xd, 1)] d(each fixed=false) "Derivatives at the support points";

  Modelica.Blocks.Sources.Ramp ramp(
    duration=500,
    height=100,
    offset=-50) "Ramp from -50Pa to +50Pa";
initial equation
  d =AixLib.Utilities.Math.Functions.splineDerivatives(
    x=xd,
    y=yd,
    ensureMonotonicity=true);
equation
   dp=ramp.y;
   m_flow =AixLib.Obsolete.Year2024.Airflow.Multizone.BaseClasses.interpolate(
    u=dp,
    xd=xd,
    yd=yd,
    d=d);
end Interpolate;


fixme: add brief description

within AixLib.Obsolete.Year2024;
package Controls "fixme: add brief description"
  extends Modelica.Icons.Package;
end Controls;


fixme: add brief description

within AixLib.Obsolete.Year2024.Controls;
package HeatPump "fixme: add brief description"
  extends Modelica.Icons.Package;
end HeatPump;


Model to prevent source from freezing. This models takes the minimum of the two temperatures evaporator
  outlet and condenser inlet. If this minimal temperature falls below
  the given lower boundary, the hystereses will trigger an error and
  cause the device to switch off.

within AixLib.Obsolete.Year2024.Controls.HeatPump.SafetyControls;
model AntiFreeze "Model to prevent source from freezing"
  extends BaseClasses.PartialSafetyControl;

  parameter Boolean use_antFre=true
    "True if anti freeze control is part of safety control"
  parameter Modelica.Units.SI.ThermodynamicTemperature TAntFre=276.15
    "Limit temperature for anti freeze control"
  parameter Real dTHys=2
    "Hysteresis interval width";
  Modelica.Blocks.Sources.BooleanConstant booConAntFre(final k=true) if not
    use_antFre
  Modelica.Blocks.Logical.Hysteresis       hysteresis(
    final uLow=TAntFre,
    final pre_y_start=true,
    final uHigh=TAntFre + dTHys)
    if use_antFre
                           //assume that the initial temperature is high enough.
  Modelica.Blocks.Math.Min min if use_antFre

equation
  connect(nSet,swiErr.u1)
  connect(booConAntFre.y, swiErr.u2)
  connect(hysteresis.y, swiErr.u2)
  connect(modeSet, modeOut)
  connect(min.y, hysteresis.u)
  connect(sigBusHP.TConInMea, min.u1)

  connect(sigBusHP.TEvaOutMea, min.u2)

  connect(hysteresis.y, not1.u)
  connect(booConAntFre.y, not1.u)
end AntiFreeze;


Control block to ensure no frost limits heat flow at the evaporator. Basic model for a defrost control. The icing factor is calculated in
  the heat pump based on functions or other models.

within AixLib.Obsolete.Year2024.Controls.HeatPump.SafetyControls;
block DefrostControl
  "Control block to ensure no frost limits heat flow at the evaporator"
  extends AixLib.Obsolete.BaseClasses.ObsoleteModel;
  parameter Real minIceFac "Minimal value above which no defrost is necessary";
  parameter Boolean use_chiller=true
    "True if defrost operates by changing mode to cooling. False to use an electrical heater"
  parameter Modelica.Units.SI.Power calcPel_deFro
    "Calculate how much eletrical energy is used to melt ice"
  parameter Real deltaIceFac = 0.1 "Bandwitdth for hystereses. If the icing factor is based on the duration of defrost, this value is necessary to avoid state-events.";
  Modelica.Blocks.Logical.Hysteresis            iceFacGreMinHea(
    final uLow=minIceFac,
    final uHigh=minIceFac + deltaIceFac,
    final pre_y_start=true)
                  if not use_chiller
    "Check if icing factor is greater than a boundary"
 Modelica.Blocks.Interfaces.RealOutput Pel_deFro if not use_chiller
    "Relative speed of compressor. From 0 to 1"
  Modelica.Blocks.Sources.BooleanConstant conTrueNotUseChi(final k=true)
 if not use_chiller
    "If ice is melted with an additional heater, HP can continue running"
  Modelica.Blocks.Sources.Constant constPel_deFro(final k=calcPel_deFro)
                                                                        if not
    use_chiller "Calculate how much eletrical energy is used to melt ice"
  Modelica.Blocks.Interfaces.BooleanInput modeSet "Set value of HP mode"
  Modelica.Blocks.Interfaces.RealInput nSet
    "Set value relative speed of compressor. Analog from 0 to 1"
  Utilities.Logical.SmoothSwitch swiErr
    "If an error occurs, the value of the conZero block will be used(0)"
  Modelica.Blocks.Sources.Constant conOne(final k=1)
    "If Defrost is enabled, HP runs at full power"
  Modelica.Blocks.Interfaces.RealOutput nOut
    "Relative speed of compressor. From 0 to 1"
  Modelica.Blocks.Interfaces.BooleanOutput modeOut
  Interfaces.VapourCompressionMachineControlBus sigBusHP
  Utilities.Logical.SmoothSwitch swiPel if not use_chiller
    "If defrost is on, output will be positive"
  Modelica.Blocks.Sources.Constant conZero(final k=0) if not use_chiller
    "If Defrost is enabled, HP runs at full power"
  Modelica.Blocks.Logical.Hysteresis            iceFacGreMinChi(
    final uLow=minIceFac,
    final uHigh=minIceFac + deltaIceFac,
    final pre_y_start=true)
                  if use_chiller
    "Check if icing factor is greater than a boundary"
  Modelica.Blocks.Logical.LogicalSwitch logicalSwitch
    "If a chiller is used to defrost, mode will be false"
  Modelica.Blocks.Sources.BooleanConstant conFalseNotUseChi(final k=true)
                                                                       if not
    use_chiller "Just to omit warnings"
  Modelica.Blocks.Sources.BooleanConstant conTrueUseChi(final k=false)
 if use_chiller "Set mode to false to simulate the defrost cycle"
equation
  connect(conOne.y, swiErr.u3)
  connect(swiErr.y, nOut)
  connect(nSet, swiErr.u1)
  connect(sigBusHP.iceFacMea, iceFacGreMinHea.u)
  connect(Pel_deFro, swiPel.y)
  connect(conTrueNotUseChi.y, swiErr.u2)
  connect(iceFacGreMinHea.y, swiPel.u2)

  connect(constPel_deFro.y, swiPel.u3)
  connect(swiPel.u1, conZero.y)
  connect(sigBusHP.iceFacMea, iceFacGreMinChi.u)
  connect(iceFacGreMinChi.y, swiErr.u2)
  connect(logicalSwitch.y, modeOut)
  connect(modeSet, logicalSwitch.u1)
  connect(conTrueNotUseChi.y, logicalSwitch.u2)
  connect(conFalseNotUseChi.y, logicalSwitch.u3)
  connect(iceFacGreMinChi.y, logicalSwitch.u2)
  connect(conTrueUseChi.y, logicalSwitch.u3)
end DefrostControl;


Controlls if the minimal runtime, stoptime and max. runs per hour are inside given boundaries. Checks if the nSet value is legal by checking if the device can
  either be turned on or off, depending on which state it was in.

within AixLib.Obsolete.Year2024.Controls.HeatPump.SafetyControls;
model OnOffControl
  "Controlls if the minimal runtime, stoptime and max. runs per hour are inside given boundaries"
  extends AixLib.Obsolete.BaseClasses.ObsoleteModel;
  parameter Boolean use_minRunTime
    "False if minimal runtime of HP is not considered"
  parameter Modelica.Units.SI.Time minRunTime(displayUnit="min")
    "Mimimum runtime of heat pump"
  parameter Boolean use_minLocTime
    "False if minimal locktime of HP is not considered"
  parameter Modelica.Units.SI.Time minLocTime(displayUnit="min")
    "Minimum lock time of heat pump"
  parameter Boolean use_runPerHou
    "False if maximal runs per hour of HP are not considered"
  parameter Integer maxRunPerHou "Maximal number of on/off cycles in one hour"
  parameter Boolean pre_n_start=true "Start value of pre(n) at initial time";
  Modelica.Blocks.Logical.GreaterThreshold
                                  nSetGreaterZero(final threshold=Modelica.Constants.eps)
                                                  "True if device is set on"
  Modelica.Blocks.Logical.And andRun
  Modelica.Blocks.Logical.Pre pre1(final pre_u_start=pre_n_start)
  BaseClasses.RunPerHouBoundary runPerHouBoundary(final maxRunPer_h=
        maxRunPerHou, final delayTime=3600) if use_runPerHou
  BaseClasses.TimeControl locTimControl(final minRunTime=minLocTime)
 if use_minLocTime
  Modelica.Blocks.Logical.Not notIsOn
  BaseClasses.TimeControl runTimControl(final minRunTime=minRunTime)
 if use_minRunTime
  Modelica.Blocks.Logical.And andLoc

  Modelica.Blocks.Sources.BooleanConstant booleanConstantRunPerHou(final k=true) if not
    use_runPerHou
  Modelica.Blocks.Sources.BooleanConstant booleanConstantLocTim(final k=true) if not
    use_minLocTime
  Modelica.Blocks.Sources.BooleanConstant booleanConstantRunTim(final k=true) if not
    use_minRunTime
  Modelica.Blocks.Logical.Not notSetOn
  Modelica.Blocks.Logical.And andTurnOff
    "Check if HP is on and is set to be turned off"
  Modelica.Blocks.Logical.And andTurnOn
    "Check if HP is Off and is set to be turned on"
  Modelica.Blocks.Logical.And andIsOn
    "Check if both set and actual value are greater zero"
  Modelica.Blocks.Interfaces.RealInput nSet
    "Set value relative speed of compressor. Analog from 0 to 1"
  Modelica.Blocks.Interfaces.RealOutput nOut
    "Relative speed of compressor. From 0 to 1"
  Interfaces.VapourCompressionMachineControlBus sigBusHP
  Utilities.Logical.SmoothSwitch swinOutnSet
    "If any of the ornSet conditions is true, nSet will be passed. Else nOut will stay the same"
  Modelica.Blocks.MathBoolean.Or orSetN(nu=4)
    "Output is true if nSet value is correct"
  Modelica.Blocks.Logical.And andIsOff
    "Check if both set and actual value are equal to zero"
  Modelica.Blocks.Logical.And andLocOff
equation
  connect(pre1.y, runPerHouBoundary.u)
  connect(pre1.y, notIsOn.u)
  connect(notIsOn.y, locTimControl.u)
  connect(runTimControl.y, andRun.u2)
  connect(runTimControl.u, pre1.y)
  connect(locTimControl.y, andLoc.u1)
  connect(runPerHouBoundary.y, andLoc.u2)
  connect(booleanConstantRunPerHou.y, andLoc.u2)
  connect(booleanConstantRunTim.y, andRun.u2)

  connect(nSet,nSetGreaterZero. u)
  connect(nSetGreaterZero.y, notSetOn.u)
  connect(pre1.y, andIsOn.u2)
  connect(nSetGreaterZero.y, andIsOn.u1)
  connect(nOut, nOut)
  connect(swinOutnSet.y, nOut)
  connect(nSet, swinOutnSet.u1)
  connect(andTurnOff.y, andRun.u1)
  connect(orSetN.y, swinOutnSet.u2)
  connect(notSetOn.y, andIsOff.u1)
  connect(andIsOff.y, orSetN.u[1])
  connect(andIsOn.y, orSetN.u[2])
  connect(andRun.y, orSetN.u[3])
  connect(andLoc.y, andLocOff.u1)
  connect(andTurnOn.y, andLocOff.u2)
  connect(andLocOff.y, orSetN.u[4])
  connect(notSetOn.y, andTurnOff.u2)
  connect(pre1.y, andTurnOff.u1)
  connect(nSetGreaterZero.y, andTurnOn.u2)
  connect(notIsOn.y, andTurnOn.u1)
  connect(notIsOn.y, andIsOff.u2)
  connect(sigBusHP.nSet, swinOutnSet.u3)
  connect(booleanConstantLocTim.y, andLoc.u1)
  connect(pre1.u, sigBusHP.onOffMea)
end OnOffControl;


Block which computes an error if the current values are outside of the given operatinal envelope. Model for checking if the given condenser return temperature and
  evaporator inlet temperature are in the given boundaries. If not, the
  heat pump will switch off.

within AixLib.Obsolete.Year2024.Controls.HeatPump.SafetyControls;
block OperationalEnvelope
  "Block which computes an error if the current values are outside of the given operatinal envelope"
  extends BaseClasses.PartialSafetyControl;
  extends BaseClasses.BoundaryMapIcon(final iconMin=-70,
  final iconMax=70);
  parameter Boolean use_opeEnv
    "False to allow HP to run out of operational envelope"
  parameter Modelica.Units.SI.TemperatureDifference dTHyst=5
    "Temperature difference used for both upper and lower hysteresis in the operational envelope."
    Modelica.Blocks.Math.UnitConversions.To_degC toDegCT_ret_co
  Modelica.Blocks.Math.UnitConversions.To_degC toDegCT_flow_ev
  BaseClasses.BoundaryMap boundaryMap(                         final tableUpp=
        tableUpp,
    final use_opeEnvFroRec=use_opeEnvFroRec,
    final dataTable=dataTable,
    final dx=dTHyst)
                  if use_opeEnv
  Modelica.Blocks.Sources.BooleanConstant booConOpeEnv(final k=true) if not
    use_opeEnv

equation
  connect(boundaryMap.noErr, swiErr.u2)
  connect(nSet,swiErr.u1)
  connect(booConOpeEnv.y, swiErr.u2)

  connect(modeSet, modeOut)
  connect(sigBusHP.TEvaInMea, toDegCT_flow_ev.u)
  connect(boundaryMap.x_in, toDegCT_flow_ev.y)
  connect(boundaryMap.y_in, toDegCT_ret_co.y)
  connect(sigBusHP.TConOutMea, toDegCT_ret_co.u)
  connect(boundaryMap.noErr, not1.u)
  connect(booConOpeEnv.y, not1.u)
end OperationalEnvelope;


    November 26, 2018  by Fabian Wüllhorst:

    First implementation (see issue <a href=
    \

within AixLib.Obsolete.Year2024.Controls.HeatPump;
package SafetyControls
end SafetyControls;


Block including all safety levels. Aggregation of the four main safety measurements of a heat pump. The
  order is based on the relevance to the real system. Only the
  AntiFreeze-Control is put last because of the relevance for the
  simulation. If the medium temperature falls below the critical value,
  the simulation will fail.

within AixLib.Obsolete.Year2024.Controls.HeatPump.SafetyControls;
block SafetyControl "Block including all safety levels"
  extends BaseClasses.PartialSafetyControl;

  parameter Boolean use_minRunTime=true
    "False if minimal runtime of HP is not considered"
  parameter Modelica.Units.SI.Time minRunTime "Mimimum runtime of heat pump"
  parameter Boolean use_minLocTime=true
    "False if minimal locktime of HP is not considered"
  parameter Modelica.Units.SI.Time minLocTime "Minimum lock time of heat pump"
  parameter Boolean use_runPerHou=true
    "False if maximal runs per hour HP are not considered"
  parameter Integer maxRunPerHou "Maximal number of on/off cycles in one hour"
  parameter Boolean use_opeEnv=true
    "False to allow HP to run out of operational envelope"
  parameter Boolean use_opeEnvFroRec=true
    "Use a the operational envelope given in the datasheet"
  parameter Obsolete.Year2024.DataBase.HeatPump.HeatPumpBaseDataDefinition
    dataTable "Data Table of HP"
  parameter Real tableUpp[:,2] "Upper boundary of envelope"
  parameter Modelica.Units.SI.TemperatureDifference dTHystOperEnv=5
    "Temperature difference used for both upper and lower hysteresis in the operational envelope."
  parameter Boolean pre_n_start=true "Start value of pre(n) at initial time"
  parameter Boolean use_deFro
    "True if defrost control should be enabled(only air-source HPs)"
  parameter Real minIceFac "Minimal value above which no defrost is necessary"
  parameter Real deltaIceFac = 0.1 "Bandwitdth for hystereses. If the icing factor is based on the duration of defrost, this value is necessary to avoid state-events."
  parameter Boolean use_chiller=true
    "True if defrost operates by changing mode to cooling. False to use an electrical heater"
  parameter Modelica.Units.SI.Power calcPel_deFro
    "Calculate how much eletrical energy is used to melt ice"
  parameter Boolean use_antFre=true
    "True if anti freeze control is part of safety control"
  parameter Modelica.Units.SI.ThermodynamicTemperature TantFre=276.15
    "Limit temperature for anti freeze control"

  Obsolete.Year2024.Controls.HeatPump.SafetyControls.OperationalEnvelope operationalEnvelope(
    final use_opeEnv=use_opeEnv,
    final tableUpp=tableUpp,
    final use_opeEnvFroRec=use_opeEnvFroRec,
    final dataTable=dataTable,
    final dTHyst=dTHystOperEnv)
  Obsolete.Year2024.Controls.HeatPump.SafetyControls.OnOffControl onOffController(
    final minRunTime=minRunTime,
    final minLocTime=minLocTime,
    final use_minRunTime=use_minRunTime,
    final use_minLocTime=use_minLocTime,
    final use_runPerHou=use_runPerHou,
    final maxRunPerHou=maxRunPerHou,
    final pre_n_start=pre_n_start)

  Obsolete.Year2024.Controls.HeatPump.SafetyControls.DefrostControl defrostControl(
    final minIceFac=minIceFac,
    final deltaIceFac=deltaIceFac,
    final use_chiller=use_chiller,
    final calcPel_deFro=calcPel_deFro) if use_deFro
  Modelica.Blocks.Routing.RealPassThrough realPasThrDef if not use_deFro
    "No 2. Layer"
  Modelica.Blocks.Sources.BooleanConstant conTru(final k=true)
    "Always true as the two blocks OperationalEnvelope and OnOffControl deal with whether the nSet value is correct or not"
  Modelica.Blocks.Interfaces.RealOutput Pel_deFro if not use_chiller and
    use_deFro
    "Relative speed of compressor. From 0 to 1"
  Obsolete.Year2024.Controls.HeatPump.SafetyControls.AntiFreeze antiFreeze(final TAntFre=TantFre, final use_antFre=use_antFre)
  Modelica.Blocks.Routing.BooleanPassThrough boolPasThrDef
                                                        if not use_deFro
    "No 2. Layer"
  Modelica.Blocks.Interfaces.IntegerOutput ERR_opeEnv
                                                  if use_opeEnv
  Modelica.Blocks.Interfaces.IntegerOutput ERR_antFre
                                                  if use_antFre
equation
  connect(conTru.y,swiErr.u2)
  connect(onOffController.nOut, operationalEnvelope.nSet)

  connect(sigBusHP, onOffController.sigBusHP)
  connect(sigBusHP, operationalEnvelope.sigBusHP)
  connect(sigBusHP, defrostControl.sigBusHP)
  connect(nSet, defrostControl.nSet)
  connect(nSet, realPasThrDef.u)
  connect(realPasThrDef.y, onOffController.nSet)
  connect(modeSet, defrostControl.modeSet)
  connect(defrostControl.nOut, onOffController.nSet)
  connect(defrostControl.modeOut, operationalEnvelope.modeSet)
  connect(modeSet, boolPasThrDef.u)
  connect(boolPasThrDef.y, operationalEnvelope.modeSet)
  connect(defrostControl.Pel_deFro, Pel_deFro)
  connect(antiFreeze.nSet, operationalEnvelope.nOut)
  connect(antiFreeze.modeSet, operationalEnvelope.modeOut)
  connect(antiFreeze.nOut, swiErr.u1)
  connect(antiFreeze.modeOut, modeOut)
  connect(sigBusHP, antiFreeze.sigBusHP)
  connect(conTru.y, not1.u)
  connect(antiFreeze.ERR, ERR_antFre)
  connect(operationalEnvelope.ERR, ERR_opeEnv)
end SafetyControl;


Block which returns false if the input parameters are out of the given charasteristic map.
For the boundaries of the y-input value, a dynamic hysteresis is used to ensure a used device will stay off a certain time after shutdown.. Given an input of the x and y-Axis, the block returns true if the
  given point is outside of the given envelope.

within AixLib.Obsolete.Year2024.Controls.HeatPump.SafetyControls.BaseClasses;
block BoundaryMap
  "Block which returns false if the input parameters are out of the given charasteristic map.
For the boundaries of the y-input value, a dynamic hysteresis is used to ensure a used device will stay off a certain time after shutdown."
  extends AixLib.Obsolete.Year2024.Controls.HeatPump.SafetyControls.BaseClasses.BoundaryMapIcon(
     final iconMin=-70, final iconMax=70);
  parameter Real dx "Delta value used for both upper and lower hysteresis. Used to avoid state events when used as a safety control."
  Modelica.Blocks.Interfaces.BooleanOutput noErr
    "If an error occurs, this will be false"
  Modelica.Blocks.Interfaces.RealInput x_in "Current value of x-Axis"
  Modelica.Blocks.Interfaces.RealInput y_in "Current value on y-Axis"

  Modelica.Blocks.Tables.CombiTable1Ds uppCombiTable1Ds(
    final table=tableUpp_internal,
    final smoothness= Modelica.Blocks.Types.Smoothness.LinearSegments,
    final tableOnFile=false)
  Modelica.Blocks.MathBoolean.Nor
                             nor1(
                                 nu=3)
  AixLib.Utilities.Logical.DynamicHysteresis lessUpp(final pre_y_start=false)
  Modelica.Blocks.Logical.Less lessLef
  Modelica.Blocks.Logical.Greater greaterRig
  Modelica.Blocks.Sources.Constant conXMin(k=xMin)
  Modelica.Blocks.Sources.Constant conXMax(k=xMax)

  Modelica.Blocks.Math.Add addUpp(final k2=-1)
  Modelica.Blocks.Sources.Constant constDx(final k=dx)

equation
  connect(x_in, uppCombiTable1Ds.u)
  connect(nor1.y, noErr)
  connect(lessUpp.y, nor1.u[1])
  connect(lessLef.y, nor1.u[2])
  connect(greaterRig.y, nor1.u[3])
  connect(x_in, lessLef.u1)
  connect(x_in, greaterRig.u1)
  connect(conXMax.y, greaterRig.u2)
  connect(conXMin.y, lessLef.u2)
  connect(y_in, lessUpp.u)
  connect(uppCombiTable1Ds.y[1], lessUpp.uHigh)
  connect(lessUpp.uLow, addUpp.y)
  connect(uppCombiTable1Ds.y[1], addUpp.u1)
  connect(addUpp.u2, constDx.y)
end BoundaryMap;


PartialModel for the icon of a boundary map. Icon block used for the icon of the dynamic icon of the model

  BoundaryMap. Extending this model will display the used
  operational envelope in the top-layer of the used models.

within AixLib.Obsolete.Year2024.Controls.HeatPump.SafetyControls.BaseClasses;
partial block BoundaryMapIcon "PartialModel for the icon of a boundary map"
  extends AixLib.Obsolete.BaseClasses.ObsoleteModel;

  parameter Boolean use_opeEnvFroRec=true
    "Use a the operational envelope given in the datasheet"
  parameter Obsolete.Year2024.DataBase.HeatPump.HeatPumpBaseDataDefinition
    dataTable "Data Table of HP"
  parameter Real tableUpp[:,2] "Table matrix (grid = first column; e.g., table=[0,2])"
  parameter Real iconMin=-70
    "Used to set the frame where the icon should appear"
  parameter Real iconMax = 70
    "Used to set the frame where the icon should appear"
protected
  parameter Real tableUpp_internal[:,2] = if use_opeEnvFroRec then dataTable.tableUppBou else tableUpp;
  parameter Real xMax=tableUpp_internal[end, 1]
    "Maximal value of lower and upper table data";
  parameter Real xMin=tableUpp_internal[1, 1]
    "Minimal value of lower and upper table data";
  parameter Real yMax=max(tableUpp_internal[:, 2])
    "Maximal value of lower and upper table data";
  parameter Real yMin=0
    "Minimal value of lower and upper table data";
  final Real[size(scaledX, 1), 2] points=transpose({unScaledX,unScaledY})
  Real tableMerge[:,2] = tableUpp_internal;
  input Real scaledX[:] = tableMerge[:,1];
  input Real scaledY[:] = tableMerge[:,2];
  Real unScaledX[size(scaledX, 1)](min=-100, max=100) = (scaledX - fill(xMin, size(scaledX, 1)))*(iconMax-iconMin)/(xMax - xMin) + fill(iconMin, size(scaledX,1));
  Real unScaledY[size(scaledX, 1)](min=-100, max=100) = (scaledY - fill(yMin, size(scaledY, 1)))*(iconMax-iconMin)/(yMax - yMin) + fill(iconMin, size(scaledY,1));
end BoundaryMapIcon;


within AixLib.Obsolete.Year2024.Controls.HeatPump.SafetyControls;
package BaseClasses "Package with base classes for AixLib.Obsolete.Year2024.Controls.HeatPump.SafetyControls"
end BaseClasses;


Base Block. Partial block for a safety control. Based on the signals in the
  sigBusHP either the input signals are equal to the output signals or,
  if an error occurs, set to 0.

within AixLib.Obsolete.Year2024.Controls.HeatPump.SafetyControls.BaseClasses;
partial block PartialSafetyControl "Base Block"
    extends AixLib.Obsolete.BaseClasses.ObsoleteModel;

  Modelica.Blocks.Interfaces.RealInput nSet
    "Set value relative speed of compressor. Analog from 0 to 1"
  Modelica.Blocks.Interfaces.RealOutput nOut
    "Relative speed of compressor. From 0 to 1"
  AixLib.Utilities.Logical.SmoothSwitch swiErr
    "If an error occurs, the value of the conZero block will be used(0)"
  Modelica.Blocks.Sources.Constant conZer(final k=0)
    "If an error occurs, the compressor speed is set to zero"
  Interfaces.VapourCompressionMachineControlBus sigBusHP
    "Bus-connector for the heat pump"
  Modelica.Blocks.Interfaces.BooleanOutput modeOut
    "Heat pump mode, =true: heating, =false: chilling"
  Modelica.Blocks.Interfaces.BooleanInput modeSet "Set value of heat pump mode"
  Modelica.Blocks.MathInteger.TriggeredAdd disErr(
    y_start=0,
    use_reset=false,
    use_set=false)
               "Used to show if the error was triggered"
  Modelica.Blocks.Interfaces.IntegerOutput ERR
    "Integer for displaying number off Errors during simulation"
  Modelica.Blocks.Logical.Not not1
  Modelica.Blocks.Sources.IntegerConstant intConOne(final k=1)
    "Used for display of current error"
equation
  connect(conZer.y,swiErr. u3)
  connect(swiErr.y, nOut)
  connect(disErr.y, ERR)
  connect(not1.y, disErr.trigger)
  connect(intConOne.y, disErr.u)
end PartialSafetyControl;


Checks if a maximal run per hour value is in boundary. Everytime the boolean input signal has a rising edge, a counter is
  triggered and adds 1 to the total sum. This represents an on-turning
  of a certain device. With a delay this number is being substracted
  again, as this block counts the number of rising edges in a given
  amount of time(e.g. 1 hour). If this value is higher than a given
  maximal value, the output turns to false.

within AixLib.Obsolete.Year2024.Controls.HeatPump.SafetyControls.BaseClasses;
block RunPerHouBoundary "Checks if a maximal run per hour value is in boundary"
  extends Modelica.Blocks.Interfaces.BooleanSISO;
  extends AixLib.Obsolete.BaseClasses.ObsoleteModel;
  parameter Integer maxRunPer_h "Number of maximal on/off cycles per hour";
  parameter Modelica.Units.SI.Time delayTime(displayUnit="h") = 3600
    "Delay time of output with respect to input signal";
 Modelica.Blocks.Logical.LessThreshold
                              runCouLesMax(threshold=maxRunPer_h)
    "Checks if the count of total runs is lower than the maximal value"
  Modelica.Blocks.MathInteger.TriggeredAdd triggeredAdd
  Modelica.Blocks.Sources.IntegerConstant intConPluOne(final k=1)
    "Value for counting"
  Modelica.Blocks.Math.IntegerToReal intToReal
  Modelica.Blocks.Math.Add sub(k2=-1)
  Modelica.Blocks.Nonlinear.FixedDelay fixedDelay(final delayTime(displayUnit=
          "h") = delayTime)
equation
  connect(intConPluOne.y, triggeredAdd.u)
  connect(intToReal.u, triggeredAdd.y)
  connect(intToReal.y, sub.u1)
  connect(intToReal.y, fixedDelay.u)
  connect(fixedDelay.y, sub.u2)
  connect(runCouLesMax.y, y)
  connect(u, triggeredAdd.trigger)
  connect(sub.y, runCouLesMax.u)
end RunPerHouBoundary;


Counts seconds a device is turned on and returns true if the time is inside given boundaries. When the input is true, a timer thats counting seconds until it is
  false again. As long as the counted time is smaller than a given
  minimal time, the block yields false.

within AixLib.Obsolete.Year2024.Controls.HeatPump.SafetyControls.BaseClasses;
block TimeControl
  "Counts seconds a device is turned on and returns true if the time is inside given boundaries"
  extends Modelica.Blocks.Interfaces.BooleanSISO;
  extends AixLib.Obsolete.BaseClasses.ObsoleteModel;

  parameter Modelica.Units.SI.Time minRunTime
    "Minimal time the device is turned on or off";
  Modelica.Blocks.Logical.Timer runTim
    "Counts the seconds the heat pump is locked still"
  Modelica.Blocks.Logical.GreaterEqualThreshold
                                       runTimGreaterMin(final threshold=
        minRunTime)
    "Checks if the runtime is greater than the minimal runtime"
equation
  connect(runTimGreaterMin.y, y)
  connect(u,runTim. u)
  connect(runTim.y, runTimGreaterMin.u)
end TimeControl;


fixme: add brief description

within AixLib.Obsolete.Year2024.Controls;
package Interfaces "fixme: add brief description"
  extends Modelica.Icons.Package;
end Interfaces;


fixme: add brief description

within AixLib.Obsolete.Year2024;
package DataBase "fixme: add brief description"
  extends Modelica.Icons.Package;
end DataBase;


Collection of Chiller Database Records

within AixLib.Obsolete.Year2024.DataBase;
package Chiller "Collection of Chiller Database Records"
   extends Modelica.Icons.Package;
end Chiller;


within AixLib.Obsolete.Year2024.DataBase.Chiller;
package EN14511
end EN14511;


within AixLib.Obsolete.Year2024.DataBase.Chiller.PerformanceData;
package BaseClasses "Package with partial classes of Performance Data"
  partial model PartialPerformanceData
    "Model with a replaceable for different methods of data aggregation"
    extends AixLib.Obsolete.BaseClasses.ObsoleteModel;

    Modelica.Blocks.Interfaces.RealOutput Pel(final unit="W", final displayUnit="kW")
                                                        "Electrical Power consumed by HP"
    Modelica.Blocks.Interfaces.RealOutput QCon(final unit="W", final displayUnit="kW")
      "Heat flow rate through Condenser"
    AixLib.Obsolete.Year2024.Controls.Interfaces.VapourCompressionMachineControlBus sigBus
      "Bus-connector used in a chiller"
    Modelica.Blocks.Interfaces.RealOutput QEva(final unit="W", final displayUnit="kW")
                                                                           "Heat flow rate through Evaporator"
  protected
    parameter Real scalingFactor=1 "Scaling factor of chiller";

  end PartialPerformanceData;
end BaseClasses;


Performance data coming from manufacturer. This model uses the 2-dimensional table data given in the DIN EN
  14511 (formerly EN255) to calculate QEva and P_el. To
  model an inverter controlled chiller, the relative compressor
  speed n is scaled linearly with the ouput of the tables.
  Furthermore, the design of a chiller is modeled via a scaling factor.
  As a result, the equations follow below:

within AixLib.Obsolete.Year2024.DataBase.Chiller.PerformanceData;
model LookUpTable2D "Performance data coming from manufacturer"
  extends
    AixLib.Obsolete.Year2024.DataBase.Chiller.PerformanceData.BaseClasses.PartialPerformanceData;

  parameter Modelica.Blocks.Types.Smoothness smoothness=Modelica.Blocks.Types.Smoothness.LinearSegments
    "Smoothness of table interpolation";
  parameter AixLib.Obsolete.Year2024.DataBase.Chiller.ChillerBaseDataDefinition dataTable = AixLib.Obsolete.Year2024.DataBase.Chiller.EN14511.Vitocal200AWO201()
    "Data Table of Chiller"
  parameter Boolean extrapolation=true "False to hold last value";
  parameter Boolean printAsserts=false
    "WARNING: This will lead to a lot of state-events if extrapolation occurs frequently! If extrapolation is enabled, the user will get warnings when extrapolation occurs."

  Utilities.Tables.CombiTable2DExtra  Qdot_EvaTable(
    final smoothness=smoothness,
    final u1(unit="degC"),
    final u2(unit="degC"),
    final y(unit="W", displayUnit="kW"),
    final extrapolation=extrapolation,
    final table=dataTable.tableQdot_eva)
  Utilities.Tables.CombiTable2DExtra  P_eleTable(
    final smoothness=smoothness,
    extrapolation=extrapolation,
    final u1(unit="degC"),
    final u2(unit="degC"),
    final y(unit="W", displayUnit="kW"),
    final table=dataTable.tableP_ele)
                    "Electrical power table"

  Modelica.Blocks.Math.UnitConversions.To_degC t_Co_in
  Modelica.Blocks.Math.UnitConversions.To_degC t_Ev_ou
  Modelica.Blocks.Math.Product nTimesPel
  Modelica.Blocks.Math.Product nTimesQEva
  Modelica.Blocks.Math.Product proRedQEva
    "Based on the icing factor, the heat flow to the evaporator is reduced"
  Modelica.Blocks.Math.Add calcRedQCon
    "Based on redcued heat flow to the evaporator, the heat flow to the condenser is also reduced"

  Modelica.Blocks.Math.Product nTimesSF
    "Create the product of the scaling factor and relative compressor speed"

protected
  parameter Real minSou = min(dataTable.tableP_ele[1,2:end]);
  parameter Real minSup = min(dataTable.tableP_ele[2:end,1]);
  parameter Real maxSou = max(dataTable.tableP_ele[1,2:end]);
  parameter Real maxSup = max(dataTable.tableP_ele[2:end,1]);
  Modelica.Blocks.Sources.Constant realCorr(final k=scalingFactor)
    "Calculates correction of table output based on scaling factor"

equation
  if printAsserts then
    assert(
        minSou + 273.15 <sigBus.TConInMea,
        "Current T_flow_co is too low. Extrapolation of data will result in unrealistic results",
        level=AssertionLevel.warning);
    assert(
        maxSou + 273.15 >sigBus.TConInMea,
        "Current T_flow_co is too high. Extrapolation of data will result in unrealistic results",
        level=AssertionLevel.warning);
    assert(
      minSup + 273.15 < sigBus.TEvaOutMea,
      "Current T_ret_ev is too low. Extrapolation of data will result in unrealistic results",
      level=AssertionLevel.warning);
    assert(
      maxSup + 273.15 > sigBus.TEvaOutMea,
      "Current T_ret_ev is too high. Extrapolation of data will result in unrealistic results",
      level=AssertionLevel.warning);
  else
  end if;
  connect(t_Co_in.y,Qdot_EvaTable. u2)
  connect(t_Co_in.y, P_eleTable.u2)
  connect(t_Ev_ou.y, P_eleTable.u1)
  connect(t_Ev_ou.y,Qdot_EvaTable. u1)
  connect(sigBus.TEvaOutMea, t_Ev_ou.u)
  connect(sigBus.TConInMea,t_Co_in. u)
  connect(P_eleTable.y, nTimesPel.u2)
  connect(Qdot_EvaTable.y,nTimesQEva. u1)
  connect(proRedQEva.y, calcRedQCon.u1)
  connect(sigBus.iceFacMea, proRedQEva.u1)

  connect(nTimesPel.y, Pel)
  connect(realCorr.y, nTimesSF.u2)
  connect(sigBus.nSet, nTimesSF.u1)
  connect(nTimesQEva.y, proRedQEva.u2)
  connect(proRedQEva.y, QEva)
  connect(calcRedQCon.y, QCon)
  connect(nTimesPel.y, calcRedQCon.u2)
  connect(nTimesSF.y, nTimesPel.u1)
  connect(nTimesSF.y, nTimesQEva.u2)
end LookUpTable2D;