within Buildings.DHC.Plants.Steam.BaseClasses;
model BoilerPolynomial
  "A equilibrium boiler with water phase change from liquid to vapor, discharging
  saturated steam vapor, with the efficiency curve described by a polynomial."
  extends Buildings.BaseClasses.BaseIconLow;
  extends Buildings.DHC.BaseClasses.Steam.PartialTwoPortTwoMedium(
    redeclare final package Medium_a=MediumWat,
    redeclare final package Medium_b=MediumSte,
    final T_start=MediumSte.saturationTemperature(p_start));

  // Medium declarations
  replaceable package MediumWat =
    Buildings.Media.Specialized.Water.TemperatureDependentDensity
    "Water medium - port_a (inlet)";
  replaceable package MediumSte = Buildings.Media.Steam
     "Steam medium - port_b (oulet)";
  // Initialization
  parameter Boolean fixed_p_start=false
    "Set to true if p_start is to be used as an explicit initial equation,
    not an initial guess"
  // Nominal conditions
  parameter Modelica.Units.SI.PressureDifference dp_nominal(displayUnit="Pa")
    "Pressure drop at nominal mass flow rate"
  parameter Modelica.Units.SI.Power Q_flow_nominal "Nominal heating power";
  parameter Modelica.Units.SI.Temperature T_nominal = 373.15
    "Temperature used to compute nominal efficiency
    (only used if efficiency curve depends on temperature)";

  // Efficiency, fuel, and boiler properties
  parameter Buildings.Fluid.Types.EfficiencyCurves effCur=
    Buildings.Fluid.Types.EfficiencyCurves.Constant
    "Curve used to compute the efficiency";
  parameter Real a[:] = {0.9} "Coefficients for efficiency curve";
  parameter Buildings.Fluid.Data.Fuels.Generic fue "Fuel type"
  parameter Modelica.Units.SI.ThermalConductance UA=0.05*Q_flow_nominal/30
    "Overall UA value";
  parameter Modelica.Units.SI.Volume V = 1.5E-6*Q_flow_nominal
    "Total internal volume of boiler"
  parameter Modelica.Units.SI.Mass mDry = 1.5E-3*Q_flow_nominal
    "Mass of boiler that will be lumped to water heat capacity"

  // Variables
  Modelica.Units.SI.Efficiency eta=
    if effCur == Buildings.Fluid.Types.EfficiencyCurves.Constant then
      a[1]
    elseif effCur == Buildings.Fluid.Types.EfficiencyCurves.Polynomial then
      Buildings.Utilities.Math.Functions.polynomial(a=a, x=y_internal)
    elseif effCur == Buildings.Fluid.Types.EfficiencyCurves.QuadraticLinear then
      Buildings.Utilities.Math.Functions.quadraticLinear(
        a=aQuaLin,
        x1=y_internal,
        x2=MediumSte.saturationTemperature(port_a.p))
    else 0
    "Boiler efficiency";
  Modelica.Units.SI.Power QFue_flow = y_internal * Q_flow_nominal/eta_nominal
    "Heat released by fuel";
  Modelica.Units.SI.Power QWat_flow = eta * QFue_flow
    "Heat transfer from gas into water";
  Modelica.Units.SI.MassFlowRate mFue_flow = QFue_flow/fue.h
    "Fuel mass flow rate";
  Modelica.Units.SI.VolumeFlowRate VFue_flow = mFue_flow/fue.d
    "Fuel volume flow rate";

  Modelica.Blocks.Interfaces.RealInput y(min=0, max=1) if not steadyDynamics
    "Part load ratio"
  Modelica.Blocks.Interfaces.RealOutput VLiq(
    final quantity="Volume",
    final unit="m3",
    min=0) "Output liquid water volume"
  Modelica.Thermal.HeatTransfer.Interfaces.HeatPort_a heatPort if not steadyDynamics
    "Heat port, can be used to connect to ambient"
  Modelica.Thermal.HeatTransfer.Components.HeatCapacitor heaCapDry(
    C=500*mDry,
    T(start=T_start)) if not steadyDynamics
    "Heat capacity of boiler metal"
  Buildings.DHC.Plants.Steam.BaseClasses.ControlVolumeEvaporation vol(
    redeclare final package MediumSte = MediumSte,
    redeclare final package MediumWat = MediumWat,
    final allowFlowReversal=allowFlowReversal,
    final energyDynamics=energyDynamics,
    final massDynamics=massDynamics,
    final p_start=p_start,
    final m_flow_nominal=m_flow_nominal,
    final show_T=show_T,
    final V=V,
    final fixed_p_start=fixed_p_start)
    "Steam/water control volume"
  Buildings.Fluid.FixedResistances.PressureDrop res(
    redeclare final package Medium = MediumWat,
    final allowFlowReversal=allowFlowReversal,
    final m_flow_nominal=m_flow_nominal,
    final show_T=show_T,
    final dp_nominal=dp_nominal)
    "Flow resistance"

  Modelica.Blocks.Interfaces.RealOutput QFueFlo(
    final quantity="HeatFlowRate",
    final unit="W",
    min=0) "Heat flow rate of the fuel"

protected
  final parameter Boolean steadyDynamics=
    if energyDynamics == Modelica.Fluid.Types.Dynamics.SteadyState then true
    else false
    "= true, if steady state formulation";
  parameter Real eta_nominal(fixed=false) "Boiler efficiency at nominal condition";
  parameter Real aQuaLin[6] = if size(a, 1) == 6 then a else fill(0, 6)
  "Auxiliary variable for efficiency curve because quadraticLinear requires exactly 6 elements";

  Modelica.Blocks.Interfaces.RealInput y_internal(min=0, max=1)
    "Internal block needed for conditional input part load ratio";

  Buildings.HeatTransfer.Sources.PrescribedHeatFlow preHeaFlo if not steadyDynamics
  "Prescribed heat flow (if heatPort is connected)"
  Modelica.Blocks.Sources.RealExpression Q_flow_in(y=QWat_flow)
    if not steadyDynamics
    "Heat transfer from gas into water (if heatPort is connected)"

  Modelica.Thermal.HeatTransfer.Components.ThermalConductor UAOve(G=UA) if not steadyDynamics
    "Overall thermal conductance (if heatPort is connected)"

  Modelica.Blocks.Sources.RealExpression QFue_flow_out(y=QFue_flow)
    "Heat flow rate of the fuel"
initial equation
  if  effCur == Buildings.Fluid.Types.EfficiencyCurves.QuadraticLinear then
    assert(size(a, 1) == 6,
    "The boiler has the efficiency curve set to 'Buildings.Fluid.Types.EfficiencyCurves.QuadraticLinear',
    and hence the parameter 'a' must have exactly 6 elements.
    However, only " + String(size(a, 1)) + " elements were provided.");
  end if;

  if effCur == Buildings.Fluid.Types.EfficiencyCurves.Constant then
    eta_nominal = a[1];
  elseif effCur == Buildings.Fluid.Types.EfficiencyCurves.Polynomial then
    eta_nominal = Buildings.Utilities.Math.Functions.polynomial(
      a=a, x=1);
  elseif effCur == Buildings.Fluid.Types.EfficiencyCurves.QuadraticLinear then
    // For this efficiency curve, a must have 6 elements.
    eta_nominal = Buildings.Utilities.Math.Functions.quadraticLinear(
      a=aQuaLin, x1=1, x2=T_nominal);
  else
     eta_nominal = 999;
  end if;

equation
  assert(eta > 0.001, "Efficiency curve is wrong.");

  connect(y,y_internal);

  if steadyDynamics then
    if allowFlowReversal then
      -QWat_flow = port_a.m_flow*actualStream(port_a.h_outflow) +
                   port_b.m_flow*actualStream(port_b.h_outflow);
    else
      -QWat_flow = port_a.m_flow*inStream(port_a.h_outflow) +
                   port_b.m_flow*port_b.h_outflow;

    end if;
  end if;

  connect(UAOve.port_a, heatPort)
  connect(Q_flow_in.y,preHeaFlo. Q_flow)
  connect(heaCapDry.port, UAOve.port_b)
  connect(preHeaFlo.port, UAOve.port_b)
  connect(vol.heatPort, UAOve.port_b)
  connect(vol.port_b, port_b)
  connect(port_a, res.port_a)
  connect(res.port_b, vol.port_a)
  connect(vol.VLiq,VLiq)
  connect(QFue_flow_out.y, QFueFlo)
end BoilerPolynomial;


within Buildings.DHC.Plants.Steam.BaseClasses;
model ControlVolumeEvaporation
  "Control volume model exhibiting the evaporation process of water"
  extends Buildings.DHC.BaseClasses.Steam.PartialSaturatedControlVolume(
    redeclare final package Medium_a=MediumWat,
    redeclare final package Medium_b=MediumSte,
    hSte(start = MediumSte.h_default),
    hWat(start = MediumWat.h_default),
    p(final fixed=fixed_p_start));
  parameter Boolean fixed_p_start = false
    "Set to true if p_start is to be used as an explicit initial equation,
    not an initial guess"
equation
// boundary conditions at the ports
  port_a.m_flow = mWat_flow;
  port_a.h_outflow = hWat;
  port_b.m_flow = mSte_flow;
  port_b.h_outflow = hSte;
end ControlVolumeEvaporation;


within Buildings.DHC.Plants.Steam;
package BaseClasses "Package with base classes for Buildings.DHC.Plants.Steam"
  extends Modelica.Icons.BasesPackage;
end BaseClasses;


within Buildings.DHC.Plants.Steam.BaseClasses.Examples;
model BoilerPolynomial
  "Example model for the steam boiler with a polynomial efficiency curve"
  extends Modelica.Icons.Example;

  // Medium declarations
  package MediumWat =
      Buildings.Media.Specialized.Water.TemperatureDependentDensity
    "Water medium - port_a (inlet)";
  package MediumSte = Buildings.Media.Steam
     "Steam medium - port_b (oulet)";

  // Nominal conditions
  parameter Modelica.Units.SI.AbsolutePressure p_nominal = 300000
    "Nominal pressure";
  parameter Modelica.Units.SI.Temperature T_nominal=
    MediumSte.saturationTemperature(p_nominal)
    "Nominal saturation temperature";
  parameter Modelica.Units.SI.Power Q_flow_nominal = 50000 "Nominal power";
  parameter Modelica.Units.SI.SpecificEnthalpy dh_nominal=
    MediumSte.specificEnthalpy(
      MediumSte.setState_pTX(p=p_nominal, T=T_nominal, X=MediumSte.X_default))
    "Nominal change in enthalpy";
  parameter Modelica.Units.SI.MassFlowRate m_flow_nominal=
    Q_flow_nominal/dh_nominal/2
    "Nominal mass flow rate";
  parameter Modelica.Units.SI.PressureDifference dp_nominal = 3000
    "Pressure drop at m_flow_nominal";

  Modelica.Blocks.Sources.TimeTable y(
    table=[0,0; 1200,1; 1200,0; 2000,0; 2000,1; 3600,1])
    "Load ratio"
  Buildings.Fluid.Sources.Boundary_pT sin(
    redeclare package Medium = MediumSte,
    p(displayUnit="bar") = 300000,
    T=423.15,
    nPorts=2)
    "Sink"
  Buildings.Fluid.Sources.Boundary_pT sou(
    redeclare package Medium = MediumWat,
    p=300000 + dp_nominal,
    T=303.15,
    nPorts=2)
    "Source"
  Buildings.HeatTransfer.Sources.FixedTemperature TAmb(T=288.15)
    "Ambient temperature in boiler room"
  Buildings.DHC.Plants.Steam.BaseClasses.BoilerPolynomial boiDyn(
    redeclare package MediumSte = MediumSte,
    redeclare package MediumWat = MediumWat,
    energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial,
    m_flow_nominal=m_flow_nominal,
    Q_flow_nominal=Q_flow_nominal,
    fue=Buildings.Fluid.Data.Fuels.NaturalGasLowerHeatingValue(),
    dp_nominal=dp_nominal)
    "Steam boiler with dynamic balance"
  Buildings.DHC.Plants.Steam.BaseClasses.BoilerPolynomial boiSte(
    redeclare package MediumSte = MediumSte,
    redeclare package MediumWat = MediumWat,
    energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState,
    m_flow_nominal=m_flow_nominal,
    Q_flow_nominal=Q_flow_nominal,
    fue=Buildings.Fluid.Data.Fuels.NaturalGasLowerHeatingValue(),
    dp_nominal=dp_nominal)
    "Steam boiler with steady state balance"
equation
  connect(TAmb.port, boiDyn.heatPort)
  connect(y.y, boiDyn.y)
  connect(sou.ports[1], boiSte.port_a)
  connect(boiDyn.port_a, sou.ports[2])
  connect(boiSte.port_b, sin.ports[1])
  connect(boiDyn.port_b, sin.ports[2])
end BoilerPolynomial;


within Buildings.DHC.Plants.Steam.BaseClasses.Examples;
model ControlVolumeEvaporation
  "Example model for heat transfer with the evaporation control volume"
  extends Modelica.Icons.Example;

  package MediumSte = Buildings.Media.Steam
    "Steam medium - Medium model for port_b (outlet)";
  package MediumWat =
      Buildings.Media.Specialized.Water.TemperatureDependentDensity
    "Water medium - Medium model for port_a (inlet)";

  parameter Modelica.Units.SI.AbsolutePressure p_start = 1E6 "Initial pressure";

  Buildings.DHC.Plants.Steam.BaseClasses.ControlVolumeEvaporation volDyn(
    p_start=p_start,
    V=1,
    redeclare package MediumWat = MediumWat,
    redeclare package MediumSte = MediumSte,
    m_flow_nominal=0.01,
    energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial,
    allowFlowReversal=true) "Dynamic volume"
  Buildings.DHC.Plants.Steam.BaseClasses.ControlVolumeEvaporation volSte(
    V=1,
    redeclare package MediumWat = MediumWat,
    redeclare package MediumSte = MediumSte,
    m_flow_nominal=0.01,
    energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState,
    p_start=p_start,
    allowFlowReversal=true) "Steady volume"
  Modelica.Fluid.Sources.MassFlowSource_T sou(
    redeclare package Medium = MediumWat,
    use_m_flow_in=true,
    T=313.15,
    nPorts=1) "Flow source"
  Modelica.Fluid.Sources.MassFlowSource_T sou1(
    redeclare package Medium = MediumWat,
    use_m_flow_in=true,
    T=313.15,
    nPorts=1) "Flow source"
  Modelica.Fluid.Sources.FixedBoundary bou(
    redeclare package Medium = MediumSte,
    p=p_start,
    nPorts=2) "Boundary condition"
  Modelica.Blocks.Sources.Ramp ramp(
    duration=1,
    offset=1,
    height=-2) "Ramp"
  Modelica.Thermal.HeatTransfer.Sensors.HeatFlowSensor heaFlo
    "Heat flow sensor"
  Modelica.Blocks.Sources.Constant const(k=-1000000) "Heat loss"
  Modelica.Thermal.HeatTransfer.Sources.PrescribedHeatFlow preHeaFlo
    "Prescribed heat flow rate"
equation
  connect(sou.ports[1], volDyn.port_a)
  connect(preHeaFlo.port,heaFlo. port_a)
  connect(preHeaFlo.Q_flow,const. y)
  connect(heaFlo.port_b, volDyn.heatPort)
  connect(sou1.ports[1], volSte.port_a)
  connect(ramp.y, sou.m_flow_in)
  connect(ramp.y, sou1.m_flow_in)
  connect(volSte.port_b, bou.ports[1])
  connect(volDyn.port_b, bou.ports[2])
end ControlVolumeEvaporation;


within Buildings.DHC.Plants.Steam.BaseClasses;
package Examples "Collection of models that illustrate model use and test models"
  extends Modelica.Icons.ExamplesPackage;
end Examples;


Example models for steam plants

within Buildings.DHC.Plants.Steam;
package Examples "Example models for steam plants"
  extends Modelica.Icons.ExamplesPackage;
end Examples;


within Buildings.DHC.Plants.Steam.Examples;
model SingleBoiler "Example model to demonstrate the single-boiler steam plant
  in a single closed loop"
  extends Modelica.Icons.Example;

  package MediumSte = Buildings.Media.Steam (
    p_default=300000,
    T_default=273.15+200,
    h_default=2700000)
    "Steam medium";
  package MediumWat =
    Buildings.Media.Specialized.Water.TemperatureDependentDensity (
      p_default=101325,
      T_default=273.15+100)
    "Water medium";

  parameter Modelica.Units.SI.AbsolutePressure pSat=300000
    "Saturation pressure";
  parameter Modelica.Units.SI.Temperature TSat=
     MediumSte.saturationTemperature(pSat)
     "Saturation temperature";

  parameter Modelica.Units.SI.MassFlowRate m_flow_nominal=1
    "Nominal mass flow rate of plant";
  parameter Modelica.Units.SI.PressureDifference dpPip=6000
    "Pressure drop in the condensate return pipe";
  // pumps
  parameter Buildings.Fluid.Movers.Data.Generic perPumFW(
    pressure(
      V_flow=(m_flow_nominal/1000)*{0.4,0.6,0.8,1.0},
      dp=(pSat-101325)*{1.34,1.27,1.17,1.0}))
    "Performance data for feedwater pump";
    parameter Buildings.Fluid.Movers.Data.Generic perPumCNR(
   pressure(
     V_flow=(m_flow_nominal/1000)*{0,1,2},
     dp=dpPip*{2,1,0}))
    "Performance data for condensate return pumps";

  Buildings.DHC.Plants.Steam.SingleBoiler pla(
    redeclare final package Medium = MediumWat,
    redeclare final package MediumHea_b = MediumSte,
    allowFlowReversal=true,
    final m_flow_nominal=m_flow_nominal,
    final pSteSet=pSat,
    final per=perPumFW,
    energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial,
    massDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial)
    "Plant"
  Buildings.DHC.Loads.Steam.BaseClasses.ControlVolumeCondensation vol(
    redeclare final package MediumSte = MediumSte,
    redeclare final package MediumWat = MediumWat,
    energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState,
    final p_start=pSat,
    final m_flow_nominal=m_flow_nominal,
    V=1)
    "Volume"
  Buildings.Fluid.FixedResistances.PressureDrop res(
    redeclare final package Medium = MediumWat,
    final m_flow_nominal=m_flow_nominal,
    final dp_nominal = dpPip)
    "Resistance in district network"
  Buildings.DHC.Loads.Steam.BaseClasses.SteamTrap steTra(
    redeclare final package Medium = MediumWat,
    final m_flow_nominal=m_flow_nominal)
    "Steam trap"
  Modelica.Blocks.Sources.Sine inp(
    amplitude=-0.5,
    f=1/86400,
    phase=3.1415926535898,
    offset=0.5)
    "Input signal"
  Buildings.Fluid.Sensors.MassFlowRate senMasFlo(
    redeclare final package Medium = MediumWat)
    "Mass flow rate sensor"
  Buildings.Controls.Continuous.LimPID conPumCNR(
    controllerType=Modelica.Blocks.Types.SimpleController.PI,
    k=1,
    Ti=15)
    "Controller"
  Modelica.Blocks.Math.Gain m_flow(final k=m_flow_nominal)
    "Gain to calculate m_flow"
  Buildings.Fluid.Movers.SpeedControlled_y pumCNR(
    redeclare final package Medium = MediumWat,
    energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial,
    p_start=101325,
    final per=perPumCNR,
    y_start=1)
    "Condensate return pump"
equation
  connect(res.port_b, pla.port_aSerHea)
  connect(vol.port_b, steTra.port_a)
  connect(pla.port_bSerHea, vol.port_a)
  connect(steTra.port_b, senMasFlo.port_a)
  connect(senMasFlo.port_b, pumCNR.port_a)
  connect(pumCNR.port_b, res.port_a)
  connect(senMasFlo.m_flow, conPumCNR.u_m)
  connect(conPumCNR.y, pumCNR.y)
  connect(m_flow.y, conPumCNR.u_s)
  connect(inp.y, m_flow.u)
end SingleBoiler;


within Buildings;
package Electrical "Package with models for electrical systems"
  extends Modelica.Icons.Package;
end Electrical;


Electrical package user's guide

within Buildings.Electrical;
package UsersGuide "Electrical package user's guide"
  extends Modelica.Icons.Information;
end UsersGuide;


within Buildings.Electrical;
package AC "Package for electrical systems in which the frequency is modeled as quasi-stationary"
  extends Modelica.Icons.Package;

package UsersGuide "User's Guide"
  extends Modelica.Icons.Information;
end UsersGuide;
end AC;


within Buildings.Electrical.AC;
package Interfaces "Package that contains some useful interfaces"
extends Modelica.Icons.InterfacesPackage;
end Interfaces;


One phase AC systems

within Buildings.Electrical.AC;
package OnePhase "One phase AC systems"
extends Modelica.Icons.VariantsPackage;
end OnePhase;


Ground connection

within Buildings.Electrical.AC.OnePhase.Basics;
model Ground "Ground connection"
  extends Buildings.Electrical.Interfaces.Ground(
    redeclare package PhaseSystem = PhaseSystems.OnePhase,
    redeclare Interfaces.Terminal_n terminal);
end Ground;


Package with basic models

within Buildings.Electrical.AC.OnePhase;
package Basics "Package with basic models"
extends Modelica.Icons.BasesPackage;
end Basics;


AC AC converter single phase systems

within Buildings.Electrical.AC.OnePhase.Conversion;
model ACACConverter "AC AC converter single phase systems"
  extends Buildings.Electrical.Icons.RefAngleConversion;
  extends Buildings.Electrical.Interfaces.PartialConversion(
    redeclare package PhaseSystem_p = PhaseSystems.OnePhase,
    redeclare package PhaseSystem_n = PhaseSystems.OnePhase,
    redeclare replaceable Interfaces.Terminal_n terminal_n
      constrainedby Interfaces.Terminal_n(
      i(start = zeros(PhaseSystem_n.n),
      each stateSelect = StateSelect.prefer)),
    redeclare replaceable Interfaces.Terminal_p terminal_p
      constrainedby Interfaces.Terminal_p(
      i(start = zeros(PhaseSystem_p.n),
      each stateSelect = StateSelect.prefer)));
  parameter Real conversionFactor(min = Modelica.Constants.eps)
    "Ratio of QS rms voltage on side 2 / QS rms voltage on side 1";
  parameter Real eta(min=0, max=1)
    "Converter efficiency, pLoss = (1-eta) * Ptr";
  parameter Boolean ground_1 = false
    "If true, connect side 1 of converter to ground"
  parameter Boolean ground_2 = true
    "If true, connect side 2 of converter to ground"
  Modelica.Units.SI.Power LossPower[2] "Loss power";
protected
  Modelica.Units.SI.Power P_p[2]=PhaseSystem_p.phasePowers_vi(terminal_p.v,
      terminal_p.i) "Power transmitted at pin p";
  Modelica.Units.SI.Power P_n[2]=PhaseSystem_n.phasePowers_vi(terminal_n.v,
      terminal_n.i) "Power transmitted at pin n";
equation

  // Ideal transformation
  terminal_p.v = conversionFactor*terminal_n.v;

  // Power loss term
  terminal_p.i[1] = terminal_n.i[1]/conversionFactor*
    Buildings.Utilities.Math.Functions.spliceFunction(eta-2, 1/(eta-2), P_p[1], deltax=0.1);
  terminal_p.i[2] = terminal_n.i[2]/conversionFactor*
    Buildings.Utilities.Math.Functions.spliceFunction(eta-2, 1/(eta-2), P_p[1], deltax=0.1);
  LossPower = P_p + P_n;

  // The two sides have the same reference angle
  terminal_p.theta = terminal_n.theta;

  if ground_1 then
    Connections.potentialRoot(terminal_n.theta);
  end if;
  if ground_2 then
    Connections.root(terminal_p.theta);
  end if;
end ACACConverter;


within Buildings.Electrical.AC.OnePhase.Conversion;
model ACACTransformer "AC AC transformer simplified equivalent circuit"
  extends Buildings.Electrical.Icons.RefAngleConversion;
  extends Buildings.Electrical.Interfaces.PartialConversion(
    redeclare package PhaseSystem_p = PhaseSystems.OnePhase,
    redeclare package PhaseSystem_n = PhaseSystems.OnePhase,
    redeclare replaceable Interfaces.Terminal_n terminal_n
      constrainedby Interfaces.Terminal_n(
      i(start = zeros(PhaseSystem_n.n),
      each stateSelect = StateSelect.prefer)),
    redeclare replaceable Interfaces.Terminal_p terminal_p
      constrainedby Interfaces.Terminal_p(
      i(start = zeros(PhaseSystem_p.n),
      each stateSelect = StateSelect.prefer)));
  parameter Modelica.Units.SI.Voltage VHigh
    "Rms voltage on side 1 of the transformer (primary side)";
  parameter Modelica.Units.SI.Voltage VLow
    "Rms voltage on side 2 of the transformer (secondary side)";
  parameter Modelica.Units.SI.ApparentPower VABase
    "Nominal power of the transformer";
  parameter Real XoverR
    "Ratio between the complex and real components of the impedance (XL/R)";
  parameter Real Zperc "Short circuit impedance";
  parameter Boolean ground_1 = false
    "If true, connect side 1 of converter to ground"
  parameter Boolean ground_2 = true
    "If true, connect side 2 of converter to ground"
  parameter Modelica.Units.SI.Angle phi_1=0
    "Angle of the voltage side 1 at initialization"
  parameter Modelica.Units.SI.Angle phi_2=phi_1
    "Angle of the voltage side 2 at initialization"
  Modelica.Units.SI.Efficiency eta "Efficiency";
  Modelica.Units.SI.Power PLoss[2] "Loss power";

  Modelica.Units.SI.Voltage V1[2](start=PhaseSystem_n.phaseVoltages(VHigh,
        phi_1)) "Voltage at the winding - primary side";
  Modelica.Units.SI.Voltage V2[2](start=PhaseSystem_p.phaseVoltages(VLow, phi_2))
    "Voltage at the winding - secondary side";
protected
  Real N = VHigh/VLow "Winding ratio";
  Modelica.Units.SI.Current IHigh=VABase/VHigh
    "Nominal current on primary side";
  Modelica.Units.SI.Current ILow=VABase/VLow
    "Nominal current on secondary side";
  Modelica.Units.SI.Current IscHigh=IHigh/Zperc
    "Short circuit current on primary side";
  Modelica.Units.SI.Current IscLow=ILow/Zperc
    "Short circuit current on secondary side";
  Modelica.Units.SI.Impedance Zp=VHigh/IscHigh
    "Impedance of the primary side (module)";
  Modelica.Units.SI.Impedance Z1[2]={Zp*cos(atan(XoverR)),Zp*sin(atan(XoverR))}
    "Impedance of the primary side of the transformer";
  Modelica.Units.SI.Impedance Zs=VLow/IscLow
    "Impedance of the secondary side (module)";
  Modelica.Units.SI.Impedance Z2[2]={Zs*cos(atan(XoverR)),Zs*sin(atan(XoverR))}
    "Impedance of the secondary side of the transformer";
  Modelica.Units.SI.Power P_p[2]=PhaseSystem_p.phasePowers_vi(terminal_p.v,
      terminal_p.i) "Power transmitted at pin p (secondary)";
  Modelica.Units.SI.Power P_n[2]=PhaseSystem_n.phasePowers_vi(terminal_n.v,
      terminal_n.i) "Power transmitted at pin n (primary)";
  Modelica.Units.SI.Power S_p=Modelica.Fluid.Utilities.regRoot(P_p[1]^2 + P_p[2]
      ^2, delta=0.1) "Apparent power at terminal p";
  Modelica.Units.SI.Power S_n=Modelica.Fluid.Utilities.regRoot(P_n[1]^2 + P_n[2]
      ^2, delta=0.1) "Apparent power at terminal n";

equation
  // Efficiency
  eta = Buildings.Utilities.Math.Functions.smoothMin(
        x1=
        Modelica.Fluid.Utilities.regRoot(P_p[1]^2 + P_p[2]^2, delta=0.01)/
        Modelica.Fluid.Utilities.regRoot(P_n[1]^2 + P_n[2]^2 + 1e-6, delta=0.01),
        x2=
        Modelica.Fluid.Utilities.regRoot(P_n[1]^2 + P_n[2]^2, delta=0.01)/
        Modelica.Fluid.Utilities.regRoot(P_p[1]^2 + P_p[2]^2 + 1e-6, delta=0.01),
        deltaX = 0.01);

  // Ideal transformation
  V2 = V1/N;
  terminal_p.i[1] + terminal_n.i[1]*N = 0;
  terminal_p.i[2] + terminal_n.i[2]*N = 0;

  // Losses due to the impedance
  terminal_n.v = V1 + Buildings.Electrical.PhaseSystems.OnePhase.product(
    terminal_n.i, Z1);
  V2 = terminal_p.v;

  // Loss of power
  PLoss = P_p + P_n;

  // The two sides have the same reference angle
  terminal_p.theta = terminal_n.theta;

  if ground_1 then
    Connections.potentialRoot(terminal_n.theta);
  end if;
  if ground_2 then
    Connections.root(terminal_p.theta);
  end if;
end ACACTransformer;


within Buildings.Electrical.AC.OnePhase.Conversion;
model ACACTransformerFull "AC AC transformer with detailed equivalent circuit"
  extends Buildings.Electrical.Icons.RefAngleConversion;
  extends Buildings.Electrical.Interfaces.PartialConversion(
    redeclare package PhaseSystem_p = PhaseSystems.OnePhase,
    redeclare package PhaseSystem_n = PhaseSystems.OnePhase,
    redeclare replaceable Interfaces.Terminal_n terminal_n
      constrainedby Interfaces.Terminal_n(
      i(start = zeros(PhaseSystem_n.n),
      each stateSelect = StateSelect.prefer)),
    redeclare replaceable Interfaces.Terminal_p terminal_p
      constrainedby Interfaces.Terminal_p(
      i(start = zeros(PhaseSystem_p.n),
      each stateSelect = StateSelect.prefer)));
  parameter Modelica.Units.SI.Voltage VHigh
    "RMS voltage on side 1 of the transformer (primary side)";
  parameter Modelica.Units.SI.Voltage VLow
    "RMS voltage on side 2 of the transformer (secondary side)";
  parameter Modelica.Units.SI.ApparentPower VABase
    "Nominal power of the transformer";
  parameter Modelica.Units.SI.Frequency f(start=60) "Nominal frequency";
  parameter Buildings.Electrical.Types.PerUnit R1(min=0)
    "Resistance on side 1 of the transformer (pu)";
  parameter Buildings.Electrical.Types.PerUnit L1(min=0)
    "Inductance on side 1 of the transformer (pu)";
  parameter Buildings.Electrical.Types.PerUnit R2(min=0)
    "Resistance on side 2 of the transformer (pu)";
  parameter Buildings.Electrical.Types.PerUnit L2(min=0)
    "Inductance on side 2 of the transformer (pu)";
  parameter Boolean magEffects = false
    "If true, introduce magnetization effects"
  parameter Buildings.Electrical.Types.PerUnit Rm(min=0)
    "Magnetization resistance (pu)"
  parameter Buildings.Electrical.Types.PerUnit Lm(min=0)
    "Magnetization inductance (pu)"
  parameter Boolean ground_1 = false "Connect side 1 of converter to ground"
  parameter Boolean ground_2 = true "Connect side 2 of converter to ground"
  parameter Modelica.Units.SI.Angle phi_1=0
    "Angle of the voltage side 1 at initialization"
  parameter Modelica.Units.SI.Angle phi_2=phi_1
    "Angle of the voltage side 2 at initialization"
  Modelica.Units.SI.Efficiency eta "Efficiency";
  Modelica.Units.SI.Power PLoss[2] "Loss power";

  Modelica.Units.SI.Voltage V1[2](start=PhaseSystem_n.phaseVoltages(VHigh,
        phi_1)) "Voltage at the winding - primary side";
  Modelica.Units.SI.Voltage V2[2](start=PhaseSystem_n.phaseVoltages(VLow, phi_2))
    "Voltage at the winding - secondary side";
protected
  parameter Modelica.Units.SI.AngularVelocity omega_n=2*Modelica.Constants.pi*f;
  parameter Real N = VHigh/VLow "Winding ratio";
  parameter Modelica.Units.SI.Resistance RBaseHigh=VHigh^2/VABase
    "Base impedance of the primary side";
  parameter Modelica.Units.SI.Resistance RBaseLow=VLow^2/VABase
    "Base impedance of the secondary side";
  Modelica.Units.SI.Impedance Z1[2]={RBaseHigh*R1,omega*L1*RBaseHigh/omega_n}
    "Impedance of the primary side of the transformer";
  Modelica.Units.SI.Impedance Z2[2]={RBaseLow*R2,omega*L2*RBaseLow/omega_n}
    "Impedance of the secondary side of the transformer";
  Modelica.Units.SI.Impedance Zrm[2]={RBaseHigh*Rm,0}
    "Magnetization impedance - resistance";
  Modelica.Units.SI.Impedance Zlm[2]={0,omega*Lm*RBaseHigh/omega_n}
    "Magnetization impedance - impedence";
  Modelica.Units.SI.Power P_p[2]=PhaseSystem_p.phasePowers_vi(terminal_p.v,
      terminal_p.i) "Power transmitted at pin p (secondary)";
  Modelica.Units.SI.Power P_n[2]=PhaseSystem_n.phasePowers_vi(terminal_n.v,
      terminal_n.i) "Power transmitted at pin n (primary)";
  Modelica.Units.SI.Power S_p=Modelica.Fluid.Utilities.regRoot(P_p[1]^2 + P_p[2]
      ^2, delta=0.1) "Apparent power at terminal p";
  Modelica.Units.SI.Power S_n=Modelica.Fluid.Utilities.regRoot(P_n[1]^2 + P_n[2]
      ^2, delta=0.1) "Apparent power at terminal n";
  Modelica.Units.SI.AngularVelocity omega "Angular velocity";
  Modelica.Units.SI.Current Im[2] "Magnetization current";
  Modelica.Units.SI.Angle theRef "Absolute angle of rotating reference system";
equation
  assert(sqrt(P_p[1]^2 + P_p[2]^2) <= VABase*1.01,
    "The load power of the transformer is higher than VABase");

  // Angular velocity
  theRef = PhaseSystem_p.thetaRef(terminal_p.theta);
  omega = der(theRef);

  // Efficiency
  eta = Buildings.Utilities.Math.Functions.smoothMin(
        x1=
        Modelica.Fluid.Utilities.regRoot(P_p[1]^2 + P_p[2]^2, delta=0.01)/
        Modelica.Fluid.Utilities.regRoot(P_n[1]^2 + P_n[2]^2 + 1e-6, delta=0.01),
        x2=
        Modelica.Fluid.Utilities.regRoot(P_n[1]^2 + P_n[2]^2, delta=0.01)/
        Modelica.Fluid.Utilities.regRoot(P_p[1]^2 + P_p[2]^2 + 1e-6, delta=0.01),
        deltaX = 0.01);

  // Ideal transformation
  V2 = V1/N;
  terminal_p.i[1] + (terminal_n.i[1] - Im[1])*N = 0;
  terminal_p.i[2] + (terminal_n.i[2] - Im[2])*N = 0;

  // Magnetization current
  if magEffects then
    Im = Buildings.Electrical.PhaseSystems.OnePhase.divide(V1, Zrm) +
         Buildings.Electrical.PhaseSystems.OnePhase.divide(V1, Zlm);
  else
    Im = zeros(2);
  end if;

  // Losses due to the impedance - primary side
  terminal_n.v = V1 + Buildings.Electrical.PhaseSystems.OnePhase.product(
    terminal_n.i, Z1);

  // Losses due to the impedance - secondary side
  terminal_p.v = V2 + Buildings.Electrical.PhaseSystems.OnePhase.product(
    terminal_p.i, Z2);

  // Loss of power
  PLoss = P_p + P_n;

  // The two sides have the same reference angle
  terminal_p.theta = terminal_n.theta;

  if ground_1 then
    Connections.potentialRoot(terminal_n.theta);
  end if;
  if ground_2 then
    Connections.root(terminal_p.theta);
  end if;
end ACACTransformerFull;


AC DC converter

within Buildings.Electrical.AC.OnePhase.Conversion;
model ACDCConverter "AC DC converter"
  extends Buildings.Electrical.Interfaces.PartialConversion(
    redeclare package PhaseSystem_p = PhaseSystems.TwoConductor,
    redeclare package PhaseSystem_n = PhaseSystems.OnePhase,
    redeclare replaceable Interfaces.Terminal_n terminal_n
      constrainedby Interfaces.Terminal_n(
        i(start = zeros(PhaseSystem_n.n),
        each stateSelect = StateSelect.prefer)),
    redeclare DC.Interfaces.Terminal_p terminal_p(
        i(start = zeros(PhaseSystem_p.n),
        each stateSelect = StateSelect.prefer)));
  parameter Real conversionFactor(min = Modelica.Constants.eps)
    "Ratio of DC voltage / AC RMS voltage";
  parameter Real eta(min=0, max=1)
    "Converter efficiency, pLoss = (1-eta) * Ptr";
  Modelica.Units.SI.Power PLoss "Loss power";
  parameter Boolean ground_AC = false "Connect AC side of converter to ground"
  parameter Boolean ground_DC = true "Connect DC side of converter to ground"
protected
  PhaseSystem_p.Current i_dc "DC current";
  PhaseSystem_p.Voltage v_dc "DC voltage";
  Modelica.Units.SI.Power P_p[2]=PhaseSystem_p.phasePowers_vi(terminal_p.v,
      terminal_p.i) "Power transmitted at pin p (secondary)";
  Modelica.Units.SI.Power P_n[2](each start=0) = PhaseSystem_n.phasePowers_vi(
    terminal_n.v, terminal_n.i) "Power transmitted at pin n (primary)";
equation
  //voltage relation
  v_p = v_n*conversionFactor;

  // Power losses
  PLoss = (1-eta)*
    Buildings.Utilities.Math.Functions.spliceFunction(P_p[1], P_n[1], i_p, deltax=0.1);
  P_n + P_p = {PLoss, 0};

  if ground_AC then
    Connections.potentialRoot(terminal_n.theta);
  end if;

  if ground_DC then
    v_dc = 0;
    Connections.root(terminal_p.theta);
  else
    i_dc = 0;
    Connections.potentialRoot(terminal_p.theta);
  end if;

  v_dc = terminal_p.v[2];
  sum(terminal_p.i) + i_dc = 0;
end ACDCConverter;


within Buildings.Electrical.AC.OnePhase;
package Conversion "Package with models for AC/AC and AC/DC conversion"
  extends Modelica.Icons.Package;
end Conversion;


This example illustrates how to use the AC/AC converter model. This example illustrates the use of a model that converts AC voltage to AC voltage.
The transformer model assumes a linear loss when transmitting the power.

within Buildings.Electrical.AC.OnePhase.Conversion.Examples;
model ACACConverter
  "This example illustrates how to use the AC/AC converter model"
  extends Modelica.Icons.Example;
  Buildings.Electrical.AC.OnePhase.Conversion.ACACConverter
    conACAC(eta=0.9, conversionFactor=60/120) "ACAC transformer"
  Buildings.Electrical.AC.OnePhase.Sources.FixedVoltage                 sou(
    definiteReference=true,
    f=60,
    V=120) "Voltage source"
  Buildings.Electrical.AC.OnePhase.Loads.Inductive load(
    mode=Buildings.Electrical.Types.Load.VariableZ_P_input,
    V_nominal=60) "Load model"
  Modelica.Blocks.Sources.Ramp ramp(
    duration=0.5,
    startTime=0.3,
    height=2000,
    offset=-1000) "Power consumed by the model"
equation
  connect(sou.terminal, conACAC.terminal_n)
  connect(conACAC.terminal_p, load.terminal)
  connect(ramp.y, load.Pow)
end ACACConverter;


This example illustrates how to use the AC/AC simplified transformer model. This example illustrates the use of a the AC/AC transformer model.
The example shows three different configurations:

within Buildings.Electrical.AC.OnePhase.Conversion.Examples;
model ACACTransformer
  "This example illustrates how to use the AC/AC simplified transformer model"
  extends Modelica.Icons.Example;
  Buildings.Electrical.AC.OnePhase.Conversion.ACACTransformer tra_load(
    Zperc=0.03,
    VABase=4000,
    XoverR=8,
    VHigh=120,
    VLow=60) "Transformer with load"
  Buildings.Electrical.AC.OnePhase.Sources.FixedVoltage sou(
    definiteReference=true,
    f=60,
    V=120) "Voltage source"
  Buildings.Electrical.AC.OnePhase.Loads.Inductive load(
    mode=Buildings.Electrical.Types.Load.VariableZ_P_input,
    pf=0.8,
    V_nominal=60) "Load model"
  Modelica.Blocks.Sources.Ramp ramp(
    duration=0.5,
    startTime=0.3,
    offset=0,
    height=-4000*0.8) "Load power consumption profile"
  Buildings.Electrical.AC.OnePhase.Conversion.ACACTransformer tra_cc(
    XoverR=8,
    Zperc=0.03,
    VABase=4000,
    VHigh=120,
    VLow=60) "Transformer with short circuit"
  Buildings.Electrical.AC.OnePhase.Loads.Impedance shortCircuit(R=1e-8)
    "Short circuit"
  Buildings.Electrical.AC.OnePhase.Conversion.ACACTransformer tra_void(
    XoverR=8,
    Zperc=0.03,
    VABase=4000,
    VHigh=120,
    VLow=60) "Transformer with secondary not connected"
  Buildings.Electrical.AC.OnePhase.Sources.FixedVoltage sou1(
    definiteReference=true,
    f=60,
    V=120) "Voltage source for open and short circuit tests"
equation
  connect(sou.terminal, tra_load.terminal_n)
  connect(tra_load.terminal_p, load.terminal)
  connect(ramp.y, load.Pow)
  connect(tra_cc.terminal_p, shortCircuit.terminal)
  connect(sou1.terminal, tra_cc.terminal_n)
  connect(sou1.terminal, tra_void.terminal_n)
end ACACTransformer;


This example illustrates how to use the AC/AC transformer model. This example illustrates the use of the AC/AC transformer model
that includes losses at the primary and secondary side and magnetization
effects.
The example shows three different configurations:

within Buildings.Electrical.AC.OnePhase.Conversion.Examples;
model ACACTransformerFull
  "This example illustrates how to use the AC/AC transformer model"
  extends Modelica.Icons.Example;
  Buildings.Electrical.AC.OnePhase.Conversion.ACACTransformerFull tra_load(
    R1=0.0001,
    L1=0.0001,
    R2=0.0001,
    L2=0.0001,
    VABase=4000,
    magEffects=true,
    Rm=10,
    Lm=10,
    VHigh=120,
    VLow=60,
    f=60) "Transformer with load"
  Buildings.Electrical.AC.OnePhase.Sources.FixedVoltage sou(
    definiteReference=true,
    f=60,
    V=120) "Voltage source"
  Buildings.Electrical.AC.OnePhase.Loads.Inductive load(
    mode=Buildings.Electrical.Types.Load.VariableZ_P_input,
    pf=0.8,
    V_nominal=60) "Load model"
  Modelica.Blocks.Sources.Ramp ramp(
    duration=0.5,
    startTime=0.3,
    offset=0,
    height=-4000*0.8) "Load power consumption profile"
  Buildings.Electrical.AC.OnePhase.Conversion.ACACTransformerFull
                                                              tra_cc(
    VABase=4000,
    R1=0.01,
    L1=0.01,
    R2=0.01,
    L2=0.01,
    magEffects=false,
    Rm=100,
    Lm=100,
    VHigh=120,
    VLow=60,
    f=60) "Transformer with short circuit connection"
  Buildings.Electrical.AC.OnePhase.Loads.Impedance shortCircuit(R=1e-8)
    "Short circuit"
  Buildings.Electrical.AC.OnePhase.Conversion.ACACTransformerFull tra_void(
    VABase=4000,
    R1=0.01,
    L1=0.01,
    R2=0.01,
    L2=0.01,
    magEffects=false,
    Rm=100,
    Lm=100,
    VHigh=120,
    VLow=60,
    f=60) "Transformer with open connection"
  Buildings.Electrical.AC.OnePhase.Sources.FixedVoltage sou1(
    definiteReference=true,
    f=60,
    V=120) "Voltage source for short circuit and open tests "
equation
  connect(sou.terminal, tra_load.terminal_n)
  connect(tra_load.terminal_p, load.terminal)
  connect(ramp.y, load.Pow)
  connect(tra_cc.terminal_p, shortCircuit.terminal)
  connect(sou1.terminal, tra_cc.terminal_n)
  connect(sou1.terminal, tra_void.terminal_n)
end ACACTransformerFull;


This example illustrates how to use the AC/DC converter model. This example illustrates the use of a model that converts AC voltage to DC voltage.
The transformer model assumes a linear loss when transmitting the power.

within Buildings.Electrical.AC.OnePhase.Conversion.Examples;
model ACDCConverter
  "This example illustrates how to use the AC/DC converter model"
  extends Modelica.Icons.Example;

  Buildings.Electrical.DC.Loads.Resistor res(R=1, V_nominal=60)
    "Resistive load"
  Buildings.Electrical.AC.OnePhase.Conversion.ACDCConverter conversion(
    eta=0.9,
    ground_AC=false,
    ground_DC=true,
    conversionFactor=60/120) "AC/DC transformer"
  Buildings.Electrical.AC.OnePhase.Sources.FixedVoltage sou(
    definiteReference=true,
    f=60,
    V=120) "Voltage source"
  Buildings.Electrical.DC.Loads.Conductor load(mode=Buildings.Electrical.Types.Load.VariableZ_P_input,
    V_nominal=60) "Variable resistive load"
  Modelica.Blocks.Sources.Ramp pow(
    duration=0.5,
    startTime=0.2,
    offset=-200,
    height=5200) "Variable load profile"
equation
  connect(sou.terminal, conversion.terminal_n)
  connect(conversion.terminal_p, res.terminal)
  connect(conversion.terminal_p, load.terminal)
  connect(pow.y, load.Pow)
end ACDCConverter;


Package with example models

within Buildings.Electrical.AC.OnePhase.Conversion;
package Examples "Package with example models"
  extends Modelica.Icons.ExamplesPackage;
end Examples;


Generator with a load and grid connection. This model illustrates a generator, an inductive load and a grid connection.
The power output of the generator is equal to its input signal, which is
a ramp function.
The output grid.P shows
the actual and apparent power, the power factor and
the phase angle.

within Buildings.Electrical.AC.OnePhase.Examples;
model GeneratorLoadGrid "Generator with a load and grid connection"
  extends Modelica.Icons.Example;

  Sources.Grid grid(
    f=60,
    V=120,
    phiSou=0.5235987755983) "Electrical grid"
  Sources.Generator sou(f=60, phiGen(displayUnit="rad")) "Gas turbine"
  Buildings.Electrical.AC.OnePhase.Loads.Inductive res(
    mode=Buildings.Electrical.Types.Load.FixedZ_steady_state,
    P_nominal=-5e3,
    V_nominal=120,
    pf=1) "Inductive load"
  Modelica.Blocks.Sources.Ramp ramp(
    height=1e4,
    duration=0.6,
    startTime=0.1,
    offset=0)
equation
  connect(ramp.y, sou.P)
  connect(sou.terminal, grid.terminal)
  connect(res.terminal, grid.terminal)
end GeneratorLoadGrid;


Model of a DC load connected to the grid. This model illustrates the use of a model for inductive load. The circuit on the left hand side
uses an inductive load, whereas the circuit on the right hand side uses a resistor and inductance in
series.
The parameters of the inductor and resistor are such that the real power and the phase angle are
identical (up to the numerical precision of the parameters) for the two systems.

within Buildings.Electrical.AC.OnePhase.Examples;
model GridDCLoad "Model of a DC load connected to the grid"
  extends Modelica.Icons.Example;
  Buildings.Electrical.AC.OnePhase.Sources.Grid
               grid(
    f=60,
    phiSou=0,
    V=120)
  Buildings.Electrical.AC.OnePhase.Conversion.ACDCConverter
                                                   idealACDCConverter1(
                               eta=0.9,
    ground_AC=false,
    conversionFactor=12/120)
  Buildings.Electrical.DC.Loads.Resistor    resistor(R=1, V_nominal=12)
equation
  connect(grid.terminal, idealACDCConverter1.terminal_n)
  connect(idealACDCConverter1.terminal_p, resistor.terminal)
end GridDCLoad;


Package with example models

within Buildings.Electrical.AC.OnePhase;
package Examples "Package with example models"
extends Modelica.Icons.ExamplesPackage;
end Examples;


within Buildings.Electrical.AC.OnePhase;
package Interfaces "Package with interfaces for one phase AC systems"
  extends Modelica.Icons.InterfacesPackage;
end Interfaces;


Terminal n for AC one phase systems

within Buildings.Electrical.AC.OnePhase.Interfaces;
connector Terminal_n "Terminal n for AC one phase systems"
  extends Buildings.Electrical.Interfaces.Terminal(
    redeclare replaceable package PhaseSystem =
        Buildings.Electrical.PhaseSystems.OnePhase);
end Terminal_n;


Terminal p for AC one phase systems

within Buildings.Electrical.AC.OnePhase.Interfaces;
connector Terminal_p "Terminal p for AC one phase systems"
  extends Buildings.Electrical.Interfaces.Terminal(
    redeclare replaceable package PhaseSystem =
        Buildings.Electrical.PhaseSystems.OnePhase);
end Terminal_p;


Model of an electrical line

within Buildings.Electrical.AC.OnePhase.Lines;
model Line "Model of an electrical line"
  extends Buildings.Electrical.Transmission.BaseClasses.PartialLine(
    V_nominal(start = 110),
    redeclare package PhaseSystem_p = PhaseSystems.OnePhase,
    redeclare package PhaseSystem_n = PhaseSystems.OnePhase,
    redeclare replaceable Interfaces.Terminal_n terminal_n,
    redeclare replaceable Interfaces.Terminal_p terminal_p,
    commercialCable = Buildings.Electrical.Transmission.Functions.selectCable_low(P_nominal, V_nominal));
protected
  replaceable TwoPortRL line(
    R=R/3,
    L=L/3,
    mode=modelMode) constrainedby
    Buildings.Electrical.Transmission.BaseClasses.PartialTwoPortRLC(
      useHeatPort=true,
      M=M,
      T_ref=T_ref) "Model of the line"

equation
  connect(cableTemp.port, line.heatPort)
  connect(line.terminal_n, terminal_n)
  connect(terminal_p, line.terminal_p)
end Line;


Single phase AC network. This model represents a generalized electrical AC single phase network.

within Buildings.Electrical.AC.OnePhase.Lines;
model Network "Single phase AC network"
  extends Buildings.Electrical.Transmission.BaseClasses.PartialNetwork(
    V_nominal(start = 110),
    redeclare Interfaces.Terminal_p terminal,
    redeclare replaceable Transmission.Grids.TestGrid2Nodes grid,
    redeclare Line lines(
      commercialCable=grid.cables,
      each use_C=use_C,
      each modelMode=modelMode));
  parameter Boolean use_C = false "If true, model the cable capacity"
  parameter Buildings.Electrical.Types.Load modelMode=Types.Load.FixedZ_steady_state
    "Select between steady state and dynamic model"
  Modelica.Units.SI.Voltage VAbs[grid.nNodes] "RMS voltage of the grid nodes";
equation
  for i in 1:grid.nLinks loop
    connect(lines[i].terminal_p, terminal[grid.fromTo[i,1]]);
    connect(lines[i].terminal_n, terminal[grid.fromTo[i,2]]);
  end for;

  for i in 1:grid.nNodes loop
    VAbs[i] = Buildings.Electrical.PhaseSystems.OnePhase.systemVoltage(terminal[i].v);
  end for;
end Network;


within Buildings.Electrical.AC.OnePhase;
package Lines "Package with models for AC electrical lines"
  extends Modelica.Icons.Package;
end Lines;


within Buildings.Electrical.AC.OnePhase.Lines;
model TwoPortInductance
  "Model of an inductive element with two electrical ports"
  extends
    Buildings.Electrical.Transmission.BaseClasses.PartialTwoPortInductance(
    redeclare package PhaseSystem_p = PhaseSystems.OnePhase,
    redeclare package PhaseSystem_n = PhaseSystems.OnePhase,
    redeclare replaceable Interfaces.Terminal_n terminal_n,
    redeclare replaceable Interfaces.Terminal_p terminal_p);
  parameter Buildings.Electrical.Types.Load mode(
    min=Buildings.Electrical.Types.Load.FixedZ_steady_state,
    max=Buildings.Electrical.Types.Load.VariableZ_y_input)=
    Buildings.Electrical.Types.Load.FixedZ_steady_state
    "Type of model (e.g., steady state, dynamic, prescribed power consumption, etc.)"
protected
  Modelica.Units.SI.AngularVelocity omega
    "Frequency of the quasi-stationary sine waves";
  Modelica.Units.SI.Angle theRef "Absolute angle of rotating reference system";

equation
  theRef = PhaseSystem_p.thetaRef(terminal_p.theta);
  omega = der(theRef);

  if mode==Buildings.Electrical.Types.Load.FixedZ_dynamic then
    // Dynamics of the system
    der(L*terminal_p.i) + L*omega*PhaseSystem_p.j(terminal_p.i) = terminal_p.v - terminal_n.v;

  else
    // Steady state relationship
    L*omega*PhaseSystem_p.j(terminal_p.i) = terminal_p.v - terminal_n.v;

  end if;
end TwoPortInductance;


within Buildings.Electrical.AC.OnePhase.Lines;
model TwoPortResistance "Model of a resistance with two electrical ports"
  extends
    Buildings.Electrical.Transmission.BaseClasses.PartialTwoPortResistance(
    redeclare package PhaseSystem_p = PhaseSystems.OnePhase,
    redeclare package PhaseSystem_n = PhaseSystems.OnePhase,
    redeclare replaceable Interfaces.Terminal_n terminal_n,
    redeclare replaceable Interfaces.Terminal_p terminal_p);
equation
  terminal_p.v - terminal_n.v = terminal_p.i*diagonal(ones(PhaseSystem_p.n)*R_actual);

  // Joule losses
  LossPower = R_actual*(terminal_p.i[1]^2 + terminal_p.i[2]^2);
end TwoPortResistance;


within Buildings.Electrical.AC.OnePhase.Lines;
model TwoPortRL
  "Model of a resistive-inductive element with two electrical ports"
  extends Buildings.Electrical.Transmission.BaseClasses.PartialTwoPortRLC(
    final V_nominal=0,
    redeclare package PhaseSystem_p = PhaseSystems.OnePhase,
    redeclare package PhaseSystem_n = PhaseSystems.OnePhase,
    redeclare replaceable Interfaces.Terminal_n terminal_n,
    redeclare replaceable Interfaces.Terminal_p terminal_p,
    final C=0);
  parameter Modelica.Units.SI.Current i_start[PhaseSystem_p.n]=zeros(
      PhaseSystem_p.n)
    "Initial current phasor of the line (positive if entering from terminal p)"
  parameter Buildings.Electrical.Types.Load mode(
    min=Buildings.Electrical.Types.Load.FixedZ_steady_state,
    max=Buildings.Electrical.Types.Load.FixedZ_dynamic)=
    Buildings.Electrical.Types.Load.FixedZ_steady_state
    "Type of model (e.g., steady state, dynamic, prescribed power consumption, etc.)"
protected
  Modelica.Units.SI.Current i_p[2](start=i_start, each stateSelect=StateSelect.prefer)
    "Current phasor at terminal p";
  Modelica.Units.SI.AngularVelocity omega
    "Frequency of the quasi-stationary sine waves";
  Modelica.Units.SI.Angle theRef "Absolute angle of rotating reference system";

initial equation
  if mode==Buildings.Electrical.Types.Load.FixedZ_dynamic then
    i_p = i_start;
  end if;
equation
  theRef = PhaseSystem_p.thetaRef(terminal_p.theta);
  omega = der(theRef);

  terminal_p.i = - terminal_n.i;
  i_p = terminal_p.i;

  if mode==Buildings.Electrical.Types.Load.FixedZ_dynamic then
    // Dynamics of the system
    der(L*i_p) + L*omega*PhaseSystem_p.j(i_p) +
      i_p*diagonal(ones(PhaseSystem_p.n)*R_actual)
       = terminal_p.v - terminal_n.v;

  else
    // steady state relationship
    L*omega*PhaseSystem_p.j(i_p) +
      i_p*diagonal(ones(PhaseSystem_p.n)*R_actual)
      = terminal_p.v - terminal_n.v;
  end if;

  // Joule losses
  LossPower = R_actual*(i_p[1]^2 + i_p[2]^2);
end TwoPortRL;


within Buildings.Electrical.AC.OnePhase.Lines;
model TwoPortRLC "Model of an RLC element with two electrical ports"
  extends Buildings.Electrical.Transmission.BaseClasses.PartialTwoPortRLC(
    V_nominal(start = 110),
    redeclare package PhaseSystem_p = PhaseSystems.OnePhase,
    redeclare package PhaseSystem_n = PhaseSystems.OnePhase,
    redeclare replaceable Interfaces.Terminal_n terminal_n(
      redeclare package PhaseSystem = PhaseSystem_n),
    redeclare replaceable Interfaces.Terminal_p terminal_p(
      redeclare package PhaseSystem = PhaseSystem_p));
  parameter Modelica.Units.SI.Voltage Vc_start[2]={V_nominal,0}
    "Initial voltage phasor of the capacitance located in the middle of the line"
  parameter Buildings.Electrical.Types.Load mode(
    min=Buildings.Electrical.Types.Load.FixedZ_steady_state,
    max=Buildings.Electrical.Types.Load.FixedZ_dynamic)=
    Buildings.Electrical.Types.Load.FixedZ_steady_state
    "Type of model (e.g., steady state, dynamic, prescribed power consumption, etc.)"
protected
  Modelica.Units.SI.Voltage Vc[2](start=Vc_start, each stateSelect=StateSelect.prefer)
    "Voltage of the Capacitance located in the middle of the line";
  Modelica.Units.SI.Current Ic[2]
    "Currenbt of the capacitance located in the middle of the line";
  Modelica.Units.SI.AngularVelocity omega
    "Frequency of the quasi-stationary sine waves";
  Modelica.Units.SI.Angle theRef "Absolute angle of rotating reference system";

initial equation
  if C > 0 and mode == Buildings.Electrical.Types.Load.FixedZ_dynamic then
    Vc = Vc_start;
  end if;
equation
  theRef = PhaseSystem_p.thetaRef(terminal_p.theta);
  omega = der(theRef);

  terminal_p.i + terminal_n.i = Ic;

  L/2*omega*Buildings.Electrical.PhaseSystems.OnePhase.j(terminal_p.i) +
    terminal_p.i*diagonal(ones(PhaseSystem_p.n)*R_actual/2) = terminal_p.v - Vc;
  L/2*omega*Buildings.Electrical.PhaseSystems.OnePhase.j(terminal_n.i) +
    terminal_n.i*diagonal(ones(PhaseSystem_n.n)*R_actual/2) = terminal_n.v - Vc;

  if C > 0 then
    if mode == Buildings.Electrical.Types.Load.FixedZ_dynamic then
      // Dynamics of the system
      C*der(Vc) + omega*C*Buildings.Electrical.PhaseSystems.OnePhase.j(Vc) = Ic;
    else
      // steady state relationship
      omega*C*Buildings.Electrical.PhaseSystems.OnePhase.j(Vc) = Ic;
    end if;
  else
    // No capacitive effect, the voltage in the middle of the line is the linear
    // interpolation of the two phasors
    Vc = (terminal_p.v + terminal_n.v)/2;
  end if;

  // Joule losses
  LossPower = R_actual/2*(terminal_p.i[1]^2 + terminal_p.i[2]^2) +
              R_actual/2*(terminal_n.i[1]^2 + terminal_n.i[2]^2);
end TwoPortRLC;


Test model for a single phase line that uses commercial cable information. This example demonstrates how to use a line model to connect
a source to a load that uses commercial cable information.

within Buildings.Electrical.AC.OnePhase.Lines.Examples;
model ACLine
  "Test model for a single phase line that uses commercial cable information"
  extends Modelica.Icons.Example;
  Sources.FixedVoltage E(      definiteReference=true,
    f=60,
    V=120) "Voltage source"
  Loads.Impedance R1(R=10) "Resistive load 1"
  Line line_1(
    P_nominal=5000,
    l=2000,
    mode=Types.CableMode.commercial,
    commercialCable=Transmission.LowVoltageCables.Cu50(),
    V_nominal=120) "Resistive line that connects to load 1"
  Line line_2a(
    P_nominal=5000,
    mode=Types.CableMode.commercial,
    commercialCable=Transmission.LowVoltageCables.Cu50(),
    l=1000,
    V_nominal=120) "Resistive line that connects to load 2"
  Loads.Impedance R2(
    R=10) "Resistive load 2"
  Line line_2b(
    P_nominal=5000,
    mode=Types.CableMode.commercial,
    commercialCable=Transmission.LowVoltageCables.Cu50(),
    l=1000,
    V_nominal=120) "Resistive line that connects to load 2"
  Line line_3a(
    P_nominal=5000,
    mode=Types.CableMode.commercial,
    commercialCable=Transmission.LowVoltageCables.Cu50(),
    l=4000,
    V_nominal=120) "Resistive line that connects to load 3"
  Line line_3b(
    P_nominal=5000,
    mode=Types.CableMode.commercial,
    commercialCable=Transmission.LowVoltageCables.Cu50(),
    l=4000,
    V_nominal=120) "Resistive line that connects to load 3"
  Loads.Impedance R3(
    R=10) "Resistive load 3"
  Line line_sc(
    P_nominal=5000,
    l=2000,
    mode=Types.CableMode.commercial,
    commercialCable=Transmission.LowVoltageCables.Cu50(),
    V_nominal=120) "Line that connects the source and the short circuit"
  Loads.Impedance load_sc(R=0) "Short circuit"
equation
  connect(line_1.terminal_p, R1.terminal)
  connect(E.terminal, line_1.terminal_n)
  connect(E.terminal, line_2a.terminal_n)
  connect(line_2a.terminal_p, line_2b.terminal_n)
  connect(line_2b.terminal_p, R2.terminal)
  connect(line_3a.terminal_p, R3.terminal)
  connect(line_3b.terminal_p, R3.terminal)
  connect(E.terminal, line_3a.terminal_n)
  connect(E.terminal, line_3b.terminal_n)
  connect(line_sc.terminal_p, load_sc.terminal)
  connect(E.terminal, line_sc.terminal_n)
end ACLine;


Test model for a single phase inductive line. This example demonstrates how to use a purely inductive line model to connect
a source to a load.

within Buildings.Electrical.AC.OnePhase.Lines.Examples;
model ACLine_L "Test model for a single phase inductive line"
  extends Modelica.Icons.Example;
  parameter Modelica.Units.SI.Inductance Lbase=10/2/Modelica.Constants.pi/60
    "Base value for the line inductances";
  Sources.FixedVoltage E(      definiteReference=true,
    f=60,
    V=120) "Voltage source"
  Loads.Impedance R1(R=10) "Resistive load 1"
  Loads.Impedance R2(
    R=10) "Resistive load 2"
  Loads.Impedance R3(
    R=10) "Resistive load 3"
  Loads.Impedance load_sc(R=0) "Short circuit"
  TwoPortInductance Lline_sc(L=Lbase)
    "Inductive line connected to the short circuit"
  TwoPortInductance Lline_1(L=Lbase) "Inductive line connected to load 1"
  TwoPortInductance Lline_2a(L=0.5*Lbase) "Inductive line connected to load 2"
  TwoPortInductance Lline_2b(L=0.5*Lbase) "Inductive line connected to load 2"
  TwoPortInductance Lline_3(L=2*Lbase) "Inductive line connected to load 3"
  TwoPortInductance Lline_3b(L=2*Lbase) "Inductive line connected to load 3"
equation
  connect(E.terminal, Lline_sc.terminal_n)
  connect(Lline_sc.terminal_p, load_sc.terminal)
  connect(E.terminal, Lline_1.terminal_n)
  connect(Lline_1.terminal_p, R1.terminal)
  connect(E.terminal, Lline_2a.terminal_n)
  connect(Lline_2a.terminal_p, Lline_2b.terminal_n)
  connect(Lline_2b.terminal_p, R2.terminal)
  connect(E.terminal, Lline_3.terminal_n)
  connect(E.terminal, Lline_3b.terminal_n)
  connect(Lline_3.terminal_p, R3.terminal)
  connect(Lline_3b.terminal_p, R3.terminal)
end ACLine_L;


Test model for a single phase resistive line. This example demonstrates how to use a resistive line model to connect
a source to a load.

within Buildings.Electrical.AC.OnePhase.Lines.Examples;
model ACLine_R "Test model for a single phase resistive line"
  extends Modelica.Icons.Example;
  Sources.FixedVoltage E(definiteReference=true,
    f=60,
    V=120) "Voltage source"
  Loads.Impedance R1(R=10) "Resistive load 1"
  Loads.Impedance R2(
    R=10) "Resistive load 2"
  Loads.Impedance R3(
    R=10) "Resistive load 3"
  Loads.Impedance sc_load(R=0) "Short circuit load"
  TwoPortResistance Rline_sc(R=10, useHeatPort=false)
    "Resistive line that connects to the short circuit"
  TwoPortResistance Rline_1(R=10) "Resistive line that connects to load 1"
  TwoPortResistance Rline_2a(R=5) "Resistive line that connects to load 2"
  TwoPortResistance Rline_2b(R=5) "Resistive line that connects to load 2"
  TwoPortResistance Rline_3a(R=20) "Resistive line that connects to load 3"
  TwoPortResistance Rline_3b(R=20) "Resistive line that connects to load 3"
equation
  connect(E.terminal, Rline_sc.terminal_n)
  connect(Rline_sc.terminal_p, sc_load.terminal)
  connect(E.terminal, Rline_1.terminal_n)
  connect(Rline_1.terminal_p, R1.terminal)
  connect(E.terminal, Rline_2a.terminal_n)
  connect(Rline_2a.terminal_p, Rline_2b.terminal_n)
  connect(Rline_2b.terminal_p, R2.terminal)
  connect(E.terminal, Rline_3a.terminal_n)
  connect(E.terminal, Rline_3b.terminal_n)
  connect(Rline_3a.terminal_p, R3.terminal)
  connect(Rline_3b.terminal_p, R3.terminal)
end ACLine_R;


Test model for a single phase inductive-resistive line. This example demonstrates how to use a resistive-inductive line model to connect
a source to a load.

within Buildings.Electrical.AC.OnePhase.Lines.Examples;
model ACLine_RL "Test model for a single phase inductive-resistive line"
  extends Modelica.Icons.Example;
  parameter Modelica.Units.SI.Resistance Rbase=10
    "Base value for the line resistance";
  parameter Modelica.Units.SI.Inductance Lbase=Rbase/2/Modelica.Constants.pi/60
    "Base value for the line inductance";
  Sources.FixedVoltage E(      definiteReference=true,
    f=60,
    V=120) "Voltage source"
  Loads.Impedance load_sc_1(R=0) "Short circuit 1"
  Loads.Impedance load_sc_2(R=0) "Short circuit 2"
  TwoPortRL RL_2(R=Rbase, L=Lbase)
    "Resistive-Inductive line connected to short circuit 2"
  TwoPortResistance R_1(R=Rbase) "Resistance line connected to short circuit 1"
  TwoPortInductance L_1(L=Lbase) "Inductance line connected to short circuit 1"
  TwoPortRL RL_3(
    R=Rbase,
    L=Lbase,
    mode=Buildings.Electrical.Types.Load.FixedZ_dynamic,
    i_start={0,0})
    "Dynamic resistive-inductive line connected to short circuit 3"
  Loads.Impedance load_sc_3(R=0) "Short circuit 3"
equation
  connect(E.terminal, R_1.terminal_n)
  connect(R_1.terminal_p, L_1.terminal_n)
  connect(L_1.terminal_p, load_sc_1.terminal)
  connect(E.terminal, RL_2.terminal_n)
  connect(RL_2.terminal_p, load_sc_2.terminal)
  connect(E.terminal, RL_3.terminal_n)
  connect(RL_3.terminal_p, load_sc_3.terminal)
end ACLine_RL;


Test model for a network model. This example demonstrates how to use a network model to connect
a source to a load. In this simple case the network has two nodes
that are connected by a commercial line cable.

within Buildings.Electrical.AC.OnePhase.Lines.Examples;
model ACSimpleGrid "Test model for a network model"
  extends Modelica.Icons.Example;
  Network network(
    redeclare Buildings.Electrical.Transmission.Grids.TestGrid2Nodes grid,
    V_nominal=120)
    "Network model that represents the connection between the source and the load"
  Loads.Inductive load(
    mode=Types.Load.VariableZ_P_input,
    V_nominal=120) "Load connected to the network"
  Sources.FixedVoltage E(f=60, V=120) "Voltage source"
  Modelica.Blocks.Sources.Ramp load_inputs(
    height=5000,
    duration=2,
    offset=-2000,
    startTime=0.5) "Input signal for the power consumption of the loads"
equation
  connect(load.terminal, network.terminal[2])
  connect(E.terminal, network.terminal[1])
  connect(load_inputs.y, load.Pow)
end ACSimpleGrid;


Package with example models

within Buildings.Electrical.AC.OnePhase.Lines;
package Examples "Package with example models"
extends Modelica.Icons.ExamplesPackage;
end Examples;


within Buildings.Electrical.AC.OnePhase.Loads;
model Capacitive "Model of a capacitive and resistive load"
  extends Buildings.Electrical.Interfaces.CapacitiveLoad(
    redeclare package PhaseSystem = PhaseSystems.OnePhase,
    redeclare replaceable Interfaces.Terminal_n terminal,
    V_nominal(start = 110));

protected
  Modelica.Units.SI.Angle theRef "Absolute angle of rotating reference system";

initial equation
  if mode == Buildings.Electrical.Types.Load.FixedZ_dynamic then
    // q = Y[2]*{V_nominal, 0}/omega;
    // Steady state initialization
    der(q) = zeros(PhaseSystem.n);
  end if;
equation
  theRef = PhaseSystem.thetaRef(terminal.theta);
  omega = der(theRef);

  if mode == Buildings.Electrical.Types.Load.FixedZ_dynamic then

    // Use the dynamic phasorial representation
    Y[1] = -(P_nominal/pf)*pf/V_nominal^2;
    Y[2] = -(P_nominal/pf)*Modelica.Fluid.Utilities.regRoot(1 - pf^2, delta=0.001)/V_nominal^2;

    // Electric charge
    q = Y[2]*{v[1], v[2]}/omega;

    // Dynamics of the system
    der(q) + omega*j(q) + Y[1]*v = i;

  else

    // Use the power specified by the parameter or inputs
    if linearized then
      i[1] = -homotopy(actual= (v[2]*Q + v[1]*P)/(V_nominal^2), simplified= v[1]*Modelica.Constants.eps*1e3);
      i[2] = -homotopy(actual= (v[2]*P - v[1]*Q)/(V_nominal^2), simplified= v[2]*Modelica.Constants.eps*1e3);
    else
      if initMode == Buildings.Electrical.Types.InitMode.zero_current then
        i[1] = -homotopy(actual=(v[2]*Q + v[1]*P)/(v[1]^2 + v[2]^2), simplified=0.0);
        i[2] = -homotopy(actual=(v[2]*P - v[1]*Q)/(v[1]^2 + v[2]^2), simplified=0.0);
      else
        i[1] = -homotopy(actual=(v[2]*Q + v[1]*P)/(v[1]^2 + v[2]^2), simplified=(v[2]*Q + v[1]*P)/(V_nominal^2));
        i[2] = -homotopy(actual=(v[2]*P - v[1]*Q)/(v[1]^2 + v[2]^2), simplified=(v[2]*P - v[1]*Q)/(V_nominal^2));
      end if;

    end if;

    Y = {0, 0};
    q = {0, 0};

  end if;
end Capacitive;


Model of a generic impedance

within Buildings.Electrical.AC.OnePhase.Loads;
model Impedance "Model of a generic impedance"
  extends Buildings.Electrical.Interfaces.Impedance(
    redeclare replaceable package PhaseSystem = PhaseSystems.OnePhase,
    redeclare replaceable Interfaces.Terminal_n terminal);

protected
  Modelica.Units.SI.Angle theRef "Absolute angle of rotating reference system";
  Modelica.Units.SI.AngularVelocity omega
    "Frequency of the quasi-stationary sine waves";
  Modelica.Units.SI.Reactance X(start=1) "Complex component of the impedance";
equation
  theRef = PhaseSystem.thetaRef(terminal.theta);
  omega = der(theRef);

  if inductive then
    X = omega*L_internal;
  else
    X = -1/(omega*C_internal);
  end if;

  terminal.v = {{R_internal,-X}*terminal.i, {X,R_internal}*terminal.i};
end Impedance;


within Buildings.Electrical.AC.OnePhase.Loads;
model Inductive "Model of an inductive and resistive load"
  extends Buildings.Electrical.Interfaces.InductiveLoad(
    redeclare package PhaseSystem = PhaseSystems.OnePhase,
    redeclare replaceable Interfaces.Terminal_n terminal,
    V_nominal(start = 110));

protected
  Modelica.Units.SI.Angle theRef "Absolute angle of rotating reference system";

initial equation
  if mode == Buildings.Electrical.Types.Load.FixedZ_dynamic then
    // psi = Z[2]*{P_nominal/V_nominal, 0}/omega;
    // Steady state initialization
    der(psi) = zeros(PhaseSystem.n);
  end if;
equation
  theRef = PhaseSystem.thetaRef(terminal.theta);
  omega = der(theRef);

  if mode == Buildings.Electrical.Types.Load.FixedZ_dynamic then

    // Use the dynamic phasorial representation
    Z[1] = -pf*(V_nominal^2)/(P_nominal/pf);
    Z[2] = -Modelica.Fluid.Utilities.regRoot(1-pf^2, delta=0.001)*(V_nominal^2)/(P_nominal/pf);

    // Dynamics of the system
    der(psi) + omega*j(psi) + Z[1]*i = v;

    // Magnetic flux
    psi = Z[2]*{i[1], i[2]}/omega;

  else

    // Use the power specified by the parameter or inputs
    if linearized then
      i[1] = -homotopy(actual= (v[2]*Q + v[1]*P)/(V_nominal^2), simplified= v[1]*Modelica.Constants.eps*1e3);
      i[2] = -homotopy(actual= (v[2]*P - v[1]*Q)/(V_nominal^2), simplified= v[2]*Modelica.Constants.eps*1e3);
    else
      //PhaseSystem.phasePowers_vi(terminal.v, terminal.i) = PhaseSystem.phasePowers(P, Q);
      if initMode == Buildings.Electrical.Types.InitMode.zero_current then
        i[1] = -homotopy(actual = (v[2]*Q + v[1]*P)/(v[1]^2 + v[2]^2), simplified= 0.0);
        i[2] = -homotopy(actual = (v[2]*P - v[1]*Q)/(v[1]^2 + v[2]^2), simplified= 0.0);
      else
        i[1] = -homotopy(actual = (v[2]*Q + v[1]*P)/(v[1]^2 + v[2]^2), simplified= (v[2]*Q + v[1]*P)/(V_nominal^2));
        i[2] = -homotopy(actual = (v[2]*P - v[1]*Q)/(v[1]^2 + v[2]^2), simplified= (v[2]*P - v[1]*Q)/(V_nominal^2));
      end if;
    end if;

    Z = {0,0};
    psi = {0,0};

  end if;
end Inductive;


within Buildings.Electrical.AC.OnePhase;
package Loads "Package with load models for one phase AC systems"
  extends Modelica.Icons.VariantsPackage;
end Loads;


Model of a resistive load

within Buildings.Electrical.AC.OnePhase.Loads;
model Resistive "Model of a resistive load"
  extends Buildings.Electrical.Interfaces.ResistiveLoad(
    redeclare package PhaseSystem = PhaseSystems.OnePhase,
    redeclare replaceable Interfaces.Terminal_n terminal,
    V_nominal(start = 110));
equation

  if linearized then
    i[1] = -homotopy(actual = v[1]*P/V_nominal^2, simplified = v[1]*Modelica.Constants.eps*1e3);
    i[2] = -homotopy(actual = v[2]*P/V_nominal^2, simplified = v[2]*Modelica.Constants.eps*1e3);
  else
    if initMode == Buildings.Electrical.Types.InitMode.zero_current then
      i[1] = -homotopy(actual= v[1]*P/(v[1]^2 + v[2]^2),  simplified= 0.0);
      i[2] = -homotopy(actual= v[2]*P/(v[1]^2 + v[2]^2),  simplified= 0.0);
    else
      i[1] = -homotopy(actual= v[1]*P/(v[1]^2 + v[2]^2),
                       simplified= v[1]*P/V_nominal^2);
      i[2] = -homotopy(actual= v[2]*P/(v[1]^2 + v[2]^2),
                       simplified= v[2]*P/V_nominal^2);
    end if;
  end if;
end Resistive;


Example that illustrates the use of dynamic loads. This model compares two dynamic load models that use the dynamic
phasors.

within Buildings.Electrical.AC.OnePhase.Loads.Examples;
model DynamicLoads "Example that illustrates the use of dynamic loads"
  extends Modelica.Icons.Example;
  Buildings.Electrical.AC.OnePhase.Sources.FixedVoltage source(
    f=60,
    V=120) "Voltage source"
  Buildings.Electrical.AC.OnePhase.Loads.Capacitive dynRC(
    pf=0.8,
    mode=Buildings.Electrical.Types.Load.FixedZ_dynamic,
    P_nominal=-1200,
    V_nominal=120) "Dynamic RC load"
  Buildings.Electrical.AC.OnePhase.Lines.TwoPortResistance line(R=0.1)
    "Line resistance"
  Buildings.Electrical.AC.OnePhase.Loads.Inductive dynRL(
    pf=0.8,
    mode=Buildings.Electrical.Types.Load.FixedZ_dynamic,
    P_nominal=-1200,
    V_nominal=120) "Dynamic RL load"
equation
  connect(source.terminal, line.terminal_n)
  connect(line.terminal_p, dynRC.terminal)
  connect(dynRL.terminal, line.terminal_p)
end DynamicLoads;


Package with example models

within Buildings.Electrical.AC.OnePhase.Loads;
package Examples "Package with example models"
  extends Modelica.Icons.ExamplesPackage;
end Examples;


Example that illustrates the use of the load models at constant voltage. This model illustrates the use of the load models.
The first two lines are inductive loads, followed by two capacitive loads and a resistive load.

The inductive load varRL and the capacitive load varRC
have a variable load specified by the inputs Pow and y
respectively.

All the loads have a nominal power of 1kW, and varRL is the only one
that at t=0 produces power 1kW and as the time increases it start to
consume up to 1kW.

within Buildings.Electrical.AC.OnePhase.Loads.Examples;
model ParallelLoads
  "Example that illustrates the use of the load models at constant voltage"
  extends Modelica.Icons.Example;
  Buildings.Electrical.AC.OnePhase.Loads.Inductive varRL(
    mode=Buildings.Electrical.Types.Load.VariableZ_P_input,
    linearized=false,
    V_nominal=120) "Variable inductor and resistor"
  Buildings.Electrical.AC.OnePhase.Sources.FixedVoltage source(f=60, V=120)
    "Voltage source"
  Modelica.Blocks.Sources.Ramp load_y(duration=0.5, startTime=0.2)
    "Input signal for RC load"
  Buildings.Electrical.AC.OnePhase.Loads.Inductive RL(
    P_nominal=-1e3,
    linearized=false,
    V_nominal=120) "Constant inductor and resistor"
  Buildings.Electrical.AC.OnePhase.Loads.Capacitive varRC(mode=Buildings.Electrical.Types.Load.VariableZ_y_input,
      P_nominal=-1e3,
    linearized=false,
    V_nominal=120) "Variable conductor and resistor"
  Buildings.Electrical.AC.OnePhase.Loads.Capacitive RC(mode=Buildings.Electrical.Types.Load.FixedZ_steady_state,
      P_nominal=-1e3,
    linearized=false,
    V_nominal=120) "Constant conductor and resistor"
  Buildings.Electrical.AC.OnePhase.Loads.Resistive R(
    P_nominal=-1e3,
    mode=Buildings.Electrical.Types.Load.FixedZ_steady_state,
    linearized=false,
    V_nominal=120) "Resistive load"
  Modelica.Blocks.Sources.Ramp load_P(
    startTime=0.2,
    duration=0.5,
    height=-2000,
    offset=1000) "Power signal for load varRL"
equation
  connect(source.terminal, varRL.terminal)
  connect(source.terminal, RL.terminal)
  connect(source.terminal, varRC.terminal)
  connect(source.terminal, R.terminal)
  connect(RC.terminal, R.terminal)
  connect(load_y.y, varRC.y)
  connect(load_P.y, varRL.Pow)
end ParallelLoads;


Example that illustrates the use of the load models at constant voltage. This model compares two resistive loads. Model R consumes or produces
a variable amount of power, while model R1 consumes a fixed power.

within Buildings.Electrical.AC.OnePhase.Loads.Examples;
model ParallelResistors
  "Example that illustrates the use of the load models at constant voltage"
  extends Modelica.Icons.Example;
  Buildings.Electrical.AC.OnePhase.Sources.FixedVoltage
    source(f=60, V=120) "Voltage source"
  Modelica.Blocks.Sources.Ramp load(duration=0.5, startTime=0.2,
    height=2400,
    offset=-1200) "Power signal for load R"
  Buildings.Electrical.AC.OnePhase.Loads.Resistive R(
    mode=Buildings.Electrical.Types.Load.VariableZ_P_input,
    V_nominal=120) "Variable resistive load"
  Buildings.Electrical.AC.OnePhase.Loads.Resistive R1(
    mode=Buildings.Electrical.Types.Load.FixedZ_steady_state, P_nominal=-1.2e3,
    V_nominal=120) "Fixed resistive load"
equation
  connect(source.terminal, R.terminal)
  connect(load.y, R.Pow)
  connect(source.terminal, R1.terminal)
end ParallelResistors;


Example that illustrates the use of the impedances. This model shows how to use the impedance model in different configurations:

within Buildings.Electrical.AC.OnePhase.Loads.Examples;
model TestImpedance "Example that illustrates the use of the impedances"
  extends Modelica.Icons.Example;
  Buildings.Electrical.AC.OnePhase.Sources.FixedVoltage V(f=60, V=120)
  Buildings.Electrical.AC.OnePhase.Loads.Impedance Z1(R=0,
    inductive=true,
    L=1/(2*Modelica.Constants.pi*60)) "Inductive impedance"
  Buildings.Electrical.AC.OnePhase.Loads.Impedance Z2(R=0,
    inductive=false,
    C=1/(2*Modelica.Constants.pi*60)) "Capacitive impedance"
  Buildings.Electrical.AC.OnePhase.Loads.Impedance Z3(R=1)
    "Resistive impedance"
  Buildings.Electrical.AC.OnePhase.Loads.Impedance Z4(
    R=1,
    L=1/(2*Modelica.Constants.pi*60)) "Inductive-resistive impedance"
  Buildings.Electrical.AC.OnePhase.Loads.Impedance Z5(
    R=1,
    inductive=false,
    C=1/(2*Modelica.Constants.pi*60)) "Capacitive-resistive impedance"
equation
  connect(V.terminal, Z1.terminal)
  connect(V.terminal, Z2.terminal)
  connect(V.terminal, Z3.terminal)
  connect(V.terminal, Z4.terminal)
  connect(V.terminal, Z5.terminal)
end TestImpedance;


Examples that illustrates how to replicate a three-phase balanced system. This model shows how a balanced three phase system can be represented with three
independent single phase circuits.

within Buildings.Electrical.AC.OnePhase.Loads.Examples;
model ThreePhases
  "Examples that illustrates how to replicate a three-phase balanced system"
  extends Modelica.Icons.Example;
  Buildings.Electrical.AC.OnePhase.Sources.FixedVoltage Va(
    definiteReference=true,
    f=60,
    V=120) "Source phase A"
  Buildings.Electrical.AC.OnePhase.Loads.Impedance Za(
    inductive=true,
    L=1/(2*Modelica.Constants.pi*60),
    R=12) "Impedance phase A"
  Buildings.Electrical.AC.OnePhase.Sources.FixedVoltage Vb(
    definiteReference=true, phiSou=-2.0943951023932,
    f=60,
    V=120) "Source phase B"
  Buildings.Electrical.AC.OnePhase.Loads.Impedance Zb(
    inductive=true,
    L=1/(2*Modelica.Constants.pi*60),
    R=12) "Impedance phase B"
  Buildings.Electrical.AC.OnePhase.Sources.FixedVoltage Vc(
    definiteReference=true, phiSou=2.0943951023932,
    f=60,
    V=120) "Source phase C"
  Buildings.Electrical.AC.OnePhase.Loads.Impedance Zc(
    inductive=true,
    L=1/(2*Modelica.Constants.pi*60),
    R=12) "Impedance phase C"
equation
  connect(Va.terminal, Za.terminal)
  connect(Vb.terminal, Zb.terminal)
  connect(Vc.terminal, Zc.terminal)
end ThreePhases;


Example that illustrates how using variable impedances. This model shows how to vary the resistance,
capacitance or inductance of an impedance model.

within Buildings.Electrical.AC.OnePhase.Loads.Examples;
model VariableImpedance
  "Example that illustrates how using variable impedances"
  extends Modelica.Icons.Example;
  Buildings.Electrical.AC.OnePhase.Sources.FixedVoltage V(f=60, V=120)
    "Voltage source"
  Buildings.Electrical.AC.OnePhase.Loads.Impedance Z_L(
    R=0,
    inductive=true,
    L=1/(2*Modelica.Constants.pi*60),
    use_L_in=true,
    LMin=1/(2*Modelica.Constants.pi*60),
    LMax=2/(2*Modelica.Constants.pi*60)) "Impedance with variable L"
  Buildings.Electrical.AC.OnePhase.Loads.Impedance Z_C(
    R=0,
    inductive=false,
    C=1/(2*Modelica.Constants.pi*60),
    use_C_in=true,
    CMin=1/(2*Modelica.Constants.pi*60),
    CMax=2/(2*Modelica.Constants.pi*60)) "Impedance with variable C"
  Buildings.Electrical.AC.OnePhase.Loads.Impedance Z_R(
    R=1,
    RMin=1,
    RMax=2,
    use_R_in=true,
    L=0) "Impedance with variable R"
  Modelica.Blocks.Sources.Ramp load(duration=0.5, startTime=0.2,
    height=1,
    offset=0) "Input signal for the loads"
equation
  connect(V.terminal, Z_L.terminal)
  connect(V.terminal, Z_C.terminal)
  connect(V.terminal, Z_R.terminal)
  connect(load.y, Z_R.y_R)
  connect(load.y, Z_C.y_C)
  connect(load.y, Z_L.y_L)
end VariableImpedance;


Sensor for power, voltage and current

within Buildings.Electrical.AC.OnePhase.Sensors;
model GeneralizedSensor "Sensor for power, voltage and current"
  extends Buildings.Electrical.Icons.GeneralizedSensor;
  extends Buildings.Electrical.Interfaces.PartialTwoPort(
    redeclare package PhaseSystem_p = PhaseSystems.OnePhase,
    redeclare package PhaseSystem_n = PhaseSystems.OnePhase,
    redeclare Interfaces.Terminal_n terminal_n,
    redeclare Interfaces.Terminal_p terminal_p);
  Modelica.Blocks.Interfaces.RealOutput V(final quantity="ElectricPotential",
                                          final unit="V")=
      Buildings.Electrical.PhaseSystems.OnePhase.systemVoltage(terminal_n.v)
    "Voltage"
  Modelica.Blocks.Interfaces.RealOutput I(final quantity="ElectricCurrent",
                                          final unit="A")=
    Buildings.Electrical.PhaseSystems.OnePhase.systemCurrent(terminal_n.i)
    "Current"
  Modelica.Blocks.Interfaces.RealOutput S[PhaseSystems.OnePhase.n](
                                          each final quantity="Power",
                                          each final unit="W")=
     Buildings.Electrical.PhaseSystems.OnePhase.phasePowers_vi(v=terminal_n.v, i=terminal_n.i)
    "Phase powers"
equation
  connect(terminal_n, terminal_p)
end GeneralizedSensor;


within Buildings.Electrical.AC.OnePhase;
package Sensors "Package with sensors for AC electrical systems"
extends Modelica.Icons.SensorsPackage;
end Sensors;


Model of a probe that measures RMS voltage and angle. This model represents a probe that measures the RMS voltage and the angle
of the voltage phasor at a given point.

within Buildings.Electrical.AC.OnePhase.Sensors;
model Probe "Model of a probe that measures RMS voltage and angle"
  extends Icons.GeneralizedProbe;
  parameter Modelica.Units.SI.Voltage V_nominal(min=0, start=110)
    "Nominal voltage (V_nominal >= 0)";
  parameter Boolean perUnit = true "If true, display voltage in p.u.";
  replaceable Interfaces.Terminal_n term "Electrical connector"
  Modelica.Blocks.Interfaces.RealOutput V(unit=if perUnit then "1" else "V")
    "Voltage phasor magnitude"
  Modelica.Blocks.Interfaces.RealOutput theta(unit="rad", displayUnit="deg")
    "Voltage phasor angle"
equation
  theta = Buildings.Electrical.PhaseSystems.OnePhase.phase(term.v);
  if perUnit then
    V = Buildings.Electrical.PhaseSystems.OnePhase.systemVoltage(term.v)/V_nominal;
  else
    V = Buildings.Electrical.PhaseSystems.OnePhase.systemVoltage(term.v);
  end if;
  term.i = zeros(Buildings.Electrical.PhaseSystems.OnePhase.n);
end Probe;


This example illustrates how to use the generalized sensor model. This example illustrates the use of the generalized sensor.

within Buildings.Electrical.AC.OnePhase.Sensors.Examples;
model GeneralizedSensor
  "This example illustrates how to use the generalized sensor model"
  extends Modelica.Icons.Example;
  Buildings.Electrical.AC.OnePhase.Sensors.GeneralizedSensor sen
    "Sensor that measures V, I, and S"
  Buildings.Electrical.AC.OnePhase.Loads.Capacitive loa(
    mode=Buildings.Electrical.Types.Load.FixedZ_dynamic,
    P_nominal=-100,
    V_nominal=120) "Constant load"
  Buildings.Electrical.AC.OnePhase.Sources.FixedVoltage sou(f=60, V=120)
    "Voltage source"
  Buildings.Electrical.AC.OnePhase.Lines.TwoPortResistance res(R=0.05)
    "Line resistance"
equation
  connect(sen.terminal_p, loa.terminal)
  connect(sou.terminal, res.terminal_n)
  connect(res.terminal_p, sen.terminal_n)
end GeneralizedSensor;


Package with example models

within Buildings.Electrical.AC.OnePhase.Sensors;
package Examples "Package with example models"
  extends Modelica.Icons.ExamplesPackage;
end Examples;


This example illustrates how to use the probe model. This example illustrates the use of the probe model.

within Buildings.Electrical.AC.OnePhase.Sensors.Examples;
model Probe "This example illustrates how to use the probe model"
  extends Modelica.Icons.Example;
  Buildings.Electrical.AC.OnePhase.Loads.Capacitive loaRC(
    mode=Buildings.Electrical.Types.Load.FixedZ_steady_state,
    P_nominal=-10000,
    V_nominal=120) "Constant load"
  Buildings.Electrical.AC.OnePhase.Sources.FixedVoltage sou(f=60, V=120)
    "Voltage source"
  Buildings.Electrical.AC.OnePhase.Lines.TwoPortResistance res1(R=0.1)
    "First line resistance"
  Buildings.Electrical.AC.OnePhase.Sensors.Probe probe_source(V_nominal=120)
    "Probe that measures at the voltage source"
  Buildings.Electrical.AC.OnePhase.Sensors.Probe probe_loadRC(V_nominal=120)
    "Probe that measures at the RC load"
  Buildings.Electrical.AC.OnePhase.Lines.TwoPortResistance res2(R=0.1)
    "Second line resistance"
  Buildings.Electrical.AC.OnePhase.Loads.Inductive loaRL(
    mode=Buildings.Electrical.Types.Load.FixedZ_steady_state, P_nominal=-10000,
    V_nominal=120) "Constant load"
  Buildings.Electrical.AC.OnePhase.Sensors.Probe probe_loadRL(V_nominal=120)
    "Probe that measures at the RL load"
equation
  connect(sou.terminal, res1.terminal_n)
  connect(res1.terminal_p, loaRC.terminal)
  connect(sou.terminal, probe_source.term)
  connect(loaRC.terminal, probe_loadRC.term)
  connect(sou.terminal, res2.terminal_n)
  connect(res2.terminal_p, loaRL.terminal)
  connect(loaRL.terminal, probe_loadRL.term)
end Probe;


Fixed single phase AC voltage source

within Buildings.Electrical.AC.OnePhase.Sources;
model FixedVoltage "Fixed single phase AC voltage source"
  extends Buildings.Electrical.Interfaces.Source(
    redeclare package PhaseSystem = PhaseSystems.OnePhase,
    redeclare replaceable Interfaces.Terminal_p terminal);
  parameter Modelica.Units.SI.Frequency f(start=60) "Frequency of the source";
  parameter Modelica.Units.SI.Voltage V(start=110) "RMS voltage of the source";
  parameter Modelica.Units.SI.Angle phiSou=0 "Phase shift of the source";
protected
  Modelica.Units.SI.Angle thetaRel
    "Absolute angle of rotating system as offset to thetaRef";
equation
  if Connections.isRoot(terminal.theta) then
    PhaseSystem.thetaRef(terminal.theta) =  2*Modelica.Constants.pi*f*time;
  end if;
  thetaRel = PhaseSystem.thetaRel(terminal.theta);
  terminal.v = PhaseSystem.phaseVoltages(V, thetaRel + phiSou);
end FixedVoltage;


Model of a generator

within Buildings.Electrical.AC.OnePhase.Sources;
model Generator "Model of a generator"
  extends Buildings.Electrical.Interfaces.Source(
    redeclare package PhaseSystem = PhaseSystems.OnePhase,
    redeclare replaceable Interfaces.Terminal_p terminal);
  parameter Modelica.Units.SI.Frequency f(start=60) "Frequency of the source";
  parameter Modelica.Units.SI.Angle phiGen(displayUnit="deg") = 0
    "Phase shift of the source";
  Modelica.Units.SI.Current I "value of current";
  Modelica.Blocks.Interfaces.RealInput P
    "Variable power generated by the source"
protected
  Modelica.Units.SI.Angle thetaRel
    "Absolute angle of rotating system as offset to thetaRef";
equation
  if Connections.isRoot(terminal.theta) then
      PhaseSystem.thetaRef(terminal.theta) =  2*Modelica.Constants.pi*f*time;
  end if;

  thetaRel = PhaseSystem.thetaRel(terminal.theta);

  terminal.i = PhaseSystem.phaseCurrents(I, thetaRel+phiGen);
  0 = PhaseSystem.activePower(terminal.v, terminal.i) + P;
end Generator;


Electrical grid. Model that can be used to represent the electrical grid supply.

within Buildings.Electrical.AC.OnePhase.Sources;
model Grid "Electrical grid"

  replaceable Buildings.Electrical.AC.OnePhase.Interfaces.Terminal_p terminal
  parameter Modelica.Units.SI.Frequency f(start=60) "Frequency of the source";
  parameter Modelica.Units.SI.Voltage V(start=110) "RMS voltage of the source";
  parameter Modelica.Units.SI.Angle phiSou=0 "Phase shift angle of the source";
  Buildings.Electrical.AC.Interfaces.PowerOutput P
    "Power consumed from grid if positive, or fed to grid if negative"
  replaceable Buildings.Electrical.AC.OnePhase.Sources.FixedVoltage sou(
    potentialReference=true,
    definiteReference=true,
    final f=f,
    final V=V,
    final phiSou=phiSou) "Voltage source"
equation
  P.real = -sou.S[1];
  P.apparent = Modelica.Fluid.Utilities.regRoot(sou.S[2]^2 + sou.S[1]^2, delta = 0.01);
  P.phi = sou.phi;
  P.cosPhi = cos(sou.phi);
  connect(sou.terminal, terminal)
end Grid;


within Buildings.Electrical.AC.OnePhase;
package Sources "Package with sources models for one phase AC systems"
  extends Modelica.Icons.SourcesPackage;
end Sources;


Simple PV model

within Buildings.Electrical.AC.OnePhase.Sources;
model PVSimple "Simple PV model"
  extends Buildings.Electrical.Interfaces.PartialAcDcParameters;
  extends Buildings.Electrical.Interfaces.PartialPV(
    redeclare package PhaseSystem = Buildings.Electrical.PhaseSystems.OnePhase,
    redeclare replaceable Interfaces.Terminal_p terminal,
    V_nominal(start = 110));
  parameter Boolean linearized=false
    "If =true, introduce a linearization in the load";
  replaceable Buildings.Electrical.AC.OnePhase.Loads.Capacitive load(
    mode=Buildings.Electrical.Types.Load.VariableZ_P_input,
    final pf=pf,
    final V_nominal=V_nominal,
    final P_nominal = 0,
    final linearized=linearized) "Load model"
protected
  Modelica.Blocks.Math.Gain gain_DCAC(final k=eta_DCAC)
    "Gain that represents the DCAC conversion losses"
equation
  connect(load.terminal, terminal)
  connect(gain_DCAC.y, load.Pow)
  connect(gain_DCAC.u, solarPower.y)
  connect(gain_DCAC.y, P)
end PVSimple;


Simple PV model with orientation

within Buildings.Electrical.AC.OnePhase.Sources;
model PVSimpleOriented "Simple PV model with orientation"
  extends Buildings.Electrical.Interfaces.PartialAcDcParameters;
  extends Buildings.Electrical.Interfaces.PartialPVOriented(
    redeclare package PhaseSystem = Buildings.Electrical.PhaseSystems.OnePhase,
      V_nominal(start = 110),
      redeclare replaceable Interfaces.Terminal_p terminal,
      redeclare replaceable Buildings.Electrical.AC.OnePhase.Sources.PVSimple panel(
        pf=pf,
        eta_DCAC=eta_DCAC,
        V_nominal=V_nominal,
        linearized=linearized));
  parameter Boolean linearized=false "If =true, linearize the load";
end PVSimpleOriented;


Simple wind turbine model

within Buildings.Electrical.AC.OnePhase.Sources;
model WindTurbine "Simple wind turbine model"
  extends Buildings.Electrical.BaseClasses.WindTurbine.PartialWindTurbine(
    redeclare package PhaseSystem = Buildings.Electrical.PhaseSystems.OnePhase,
    redeclare replaceable Interfaces.Terminal_p terminal,
    V_nominal(start = 110));

  parameter Real pf(min=0, max=1) = 0.9 "Power factor"
  parameter Real eta_DCAC(min=0, max=1) = 0.9 "Efficiency of DC/AC conversion"
  replaceable Buildings.Electrical.AC.OnePhase.Loads.Capacitive load(
    final mode=Buildings.Electrical.Types.Load.VariableZ_P_input,
    final pf=pf,
    final P_nominal=0,
    final V_nominal=V_nominal) "Load model"
protected
  Modelica.Blocks.Math.Gain gain_DCAC(final k=eta_DCAC)
equation
  connect(load.terminal, terminal)
  connect(gain_DCAC.y, load.Pow)
  connect(gain.y, gain_DCAC.u)
end WindTurbine;


This example illustrates how using a fixed voltage source. This example shows how to use a fixed voltage generator model.

within Buildings.Electrical.AC.OnePhase.Sources.Examples;
model FixedVoltageSource
  "This example illustrates how using a fixed voltage source"
  extends Modelica.Icons.Example;
  Buildings.Electrical.AC.OnePhase.Loads.Inductive RL(
      P_nominal=-300, mode=Buildings.Electrical.Types.Load.FixedZ_steady_state,
    V_nominal=120) "Load model"
  FixedVoltage grid(
    f=60,
    V=120,
    phiSou=0.34906585039887) "AC one phase electrical grid"
  Sensors.Probe sen(V_nominal=120)
    "Probe that measures the voltage at the load"
equation
  connect(grid.terminal, RL.terminal)
  connect(grid.terminal, sen.term)
end FixedVoltageSource;


Package with example models

within Buildings.Electrical.AC.OnePhase.Sources;
package Examples "Package with example models"
  extends Modelica.Icons.ExamplesPackage;
end Examples;


This example illustrates how to use PV panel models. This example shows how to use a simple PV model without orientation
as well a PV model with orientation. The power produced by the PV is
partially consumed by the load while the remaining part is fed into
the grid.

within Buildings.Electrical.AC.OnePhase.Sources.Examples;
model PVPanels "This example illustrates how to use PV panel models"
  extends Modelica.Icons.Example;
  Buildings.Electrical.AC.OnePhase.Loads.Inductive RL(mode=Types.Load.VariableZ_y_input,
      P_nominal=-2000,
    V_nominal=120) "Load taht consumes the power generted by the PVs"
  Buildings.Electrical.AC.OnePhase.Sources.Grid grid(f=60, V=120)
    "Electrical grid model"
  Modelica.Blocks.Sources.Constant  load(k=0.5) "Load consumption"
  BoundaryConditions.SolarIrradiation.DiffusePerez HDifTil(til=0.34906585039887,
      azi=-0.78539816339745)
                           "Diffuse irradiation on tilted surface"
  BoundaryConditions.SolarIrradiation.DirectTiltedSurface HDirTil(til=
        0.34906585039887, azi=-0.78539816339745)
                           "Direct irradiation on tilted surface"
  BoundaryConditions.WeatherData.ReaderTMY3 weaDat(
      computeWetBulbTemperature=false, filNam=Modelica.Utilities.Files.loadResource("modelica://Buildings/Resources/weatherdata/USA_CA_San.Francisco.Intl.AP.724940_TMY3.mos"))
  Modelica.Blocks.Math.Add G "Total irradiation on tilted surface"
  PVSimple pvSimple(A=10, V_nominal=120) "PV array simplified"
  PVSimpleOriented pvOriented(
    A=10,
    til=0.34906585039887,
    azi=-0.78539816339745,
    V_nominal=120) "PV array oriented"
equation
  connect(grid.terminal, RL.terminal)
  connect(load.y, RL.y)
  connect(weaDat.weaBus,HDifTil. weaBus)
  connect(weaDat.weaBus,HDirTil. weaBus)
  connect(HDifTil.H,G. u1)
  connect(HDirTil.H,G. u2)
  connect(G.y,pvSimple. G)
  connect(pvSimple.terminal, RL.terminal)
  connect(weaDat.weaBus, pvOriented.weaBus)
  connect(pvOriented.terminal, RL.terminal)
end PVPanels;


This example illustrates how using a variable power source. This example shows how to use a variable generator model. The model has to be used
together with a voltage source generator.

within Buildings.Electrical.AC.OnePhase.Sources.Examples;
model VariablePowerSource
  "This example illustrates how using a variable power source"
  extends Modelica.Icons.Example;
  Buildings.Electrical.AC.OnePhase.Sources.Generator generator(phiGen(displayUnit="deg") = 0.26179938779915, f=60)
    "AC generator model"
  Modelica.Blocks.Sources.Sine generation(
    offset=200,
    startTime=1,
    amplitude=100,
    f=0.05) "Generated power"
  Buildings.Electrical.AC.OnePhase.Loads.Inductive RL(mode=Types.Load.VariableZ_y_input,
      P_nominal=-300,
    V_nominal=120) "Load model"
  Buildings.Electrical.AC.OnePhase.Sources.Grid grid(f=60, V=120)
    "AC one phase electrical grid"
  Modelica.Blocks.Sources.Trapezoid load(
    rising=2,
    width=3,
    falling=3,
    period=10,
    startTime=1,
    amplitude=0.8,
    offset=0.2) "Power consumption profile"
equation
  connect(generation.y, generator.P)
  connect(generator.terminal, RL.terminal)
  connect(grid.terminal, RL.terminal)
  connect(load.y, RL.y)
end VariablePowerSource;


Example for the WindTurbine AC model. This model illustrates the use of the wind turbine model which is connected to a AC voltage source and a resistance.
This voltage source can represent the grid to which the
circuit is connected.
Wind data for San Francisco, CA, are used.
The turbine cut-in wind speed is <i>3.5</i> m/s,
and hence it is off in the first day when the wind speed is low.

within Buildings.Electrical.AC.OnePhase.Sources.Examples;
model WindTurbine "Example for the WindTurbine AC model"
  extends Modelica.Icons.Example;
  Buildings.Electrical.AC.OnePhase.Sources.WindTurbine  tur(
    table=[3.5, 0;
           5.5,   100;
           12, 900;
           14, 1000;
           25, 1000], h=10,
    scale=10,
    V_nominal=120) "Wind turbine"
  Buildings.BoundaryConditions.WeatherData.ReaderTMY3 weaDat(
      computeWetBulbTemperature=false, filNam=Modelica.Utilities.Files.loadResource("modelica://Buildings/Resources/weatherdata/USA_CA_San.Francisco.Intl.AP.724940_TMY3.mos"))
    "Weather data"
  Buildings.BoundaryConditions.WeatherData.Bus weaBus "Weather bus"
  Buildings.Electrical.AC.OnePhase.Loads.Resistive
                                            res(P_nominal=-500, V_nominal=120)
    "Resistive line"
  Buildings.Electrical.AC.OnePhase.Sources.Grid sou(f=60, V=120)
    "Voltage source"
  Buildings.Electrical.AC.OnePhase.Lines.TwoPortResistance
                                                  lin(R=0.1)
    "Transmission line"
  Buildings.Electrical.AC.OnePhase.Sensors.GeneralizedSensor
                                                    sen "Generalized sensor"
equation
  connect(weaDat.weaBus,weaBus)
  connect(weaBus.winSpe,tur. vWin)
  connect(sou.terminal, lin.terminal_n)
  connect(sou.terminal, res.terminal)
  connect(lin.terminal_p, sen.terminal_n)
  connect(sen.terminal_p, tur.terminal)
end WindTurbine;


Simple model of a battery

within Buildings.Electrical.AC.OnePhase.Storage;
model Battery "Simple model of a battery"
 extends Buildings.Electrical.Interfaces.PartialAcDcParameters;
 replaceable package PhaseSystem =
      Buildings.Electrical.PhaseSystems.OnePhase constrainedby
    Buildings.Electrical.PhaseSystems.PartialPhaseSystem "Phase system"
  parameter Modelica.Units.SI.Efficiency etaCha(max=1) = 0.9
    "Efficiency during charging";
  parameter Modelica.Units.SI.Efficiency etaDis(max=1) = 0.9
    "Efficiency during discharging";
  parameter Real SOC_start(start=0.1) "Initial charge";
  parameter Modelica.Units.SI.Energy EMax(min=0, displayUnit="kW.h")
    "Maximum available charge";
  parameter Modelica.Units.SI.Voltage V_nominal(start=110)
    "Nominal voltage (V_nominal >= 0)";
  parameter Boolean linearized=false
    "If =true introduce a linearization in the load";
  parameter Buildings.Electrical.Types.InitMode initMode(
  min=Buildings.Electrical.Types.InitMode.zero_current,
  max=Buildings.Electrical.Types.InitMode.linearized) = Buildings.Electrical.Types.InitMode.zero_current
    "Initialization mode for homotopy operator"
 Modelica.Blocks.Interfaces.RealInput P(unit="W")
    "Power stored in battery (if positive), or extracted from battery (if negative)"
  Modelica.Blocks.Interfaces.RealOutput SOC "State of charge"
  replaceable Buildings.Electrical.AC.OnePhase.Interfaces.Terminal_p
     terminal "Generalized terminal"

protected
  Buildings.Electrical.DC.Storage.BaseClasses.Charge cha(
    final EMax=EMax,
    final SOC_start=SOC_start,
    final etaCha=etaCha,
    final etaDis=etaDis) "Charge model"
  replaceable Buildings.Electrical.AC.OnePhase.Loads.Resistive bat
    constrainedby Buildings.Electrical.Interfaces.Load(
    final initMode = initMode,
    final mode=Buildings.Electrical.Types.Load.VariableZ_P_input,
    final V_nominal=V_nominal,
    final linearized=linearized) "Power exchanged with battery pack"
  Modelica.Blocks.Math.Gain gain(final k=-1)
    "Gain that invert sign of the power (P<0 -> the load is consumed)"

  Modelica.Blocks.Math.Gain acdc_con_dis(final k = 2 - eta_DCAC)
    "Losses when P < 0"
  Buildings.Utilities.Math.Splice spl(deltax=1e-2)
    "Splice function that attributes the losses due to AC/DC conversion"
  Modelica.Blocks.Math.Gain acdc_con_cha(final k=eta_DCAC) "Losses when P > 0"
equation
  connect(cha.SOC, SOC)

  connect(gain.y, bat.Pow)
  connect(bat.terminal, terminal)
  connect(P, acdc_con_dis.u)
  connect(P, acdc_con_cha.u)
  connect(acdc_con_cha.y, spl.u1)
  connect(acdc_con_dis.y, spl.u2)
  connect(P, spl.x)
  connect(spl.y, cha.P)
  connect(P, gain.u)
end Battery;


within Buildings.Electrical.AC.OnePhase;
package Storage "Package with models for electrical storage with a AC one phase connector"
  extends Modelica.Icons.Package;
end Storage;


This example shows how to use the AC battery model. This example shows how to use an AC battery model.

within Buildings.Electrical.AC.OnePhase.Storage.Examples;
model AcBattery "This example shows how to use the AC battery model"
  extends Modelica.Icons.Example;
  Battery bat_ideal(
    eta_DCAC=1,
    etaCha=1,
    etaDis=1,
    SOC_start=0.5,
    EMax=749999.88,
    V_nominal=120) "Ideal battery without losses"
  Sources.FixedVoltage fixVol(f=60, V=120)
  Modelica.Blocks.Sources.Pulse pow(
    offset=-500,
    amplitude=1000,
    width=50,
    period=1200)
    "Signal that indicates how much power should be stored in the battery"
  Battery bat_loss_acdc(
    etaCha=1,
    etaDis=1,
    SOC_start=0.5,
    eta_DCAC=0.95,
    EMax=749999.88,
    V_nominal=120) "Battery with losses for AC/DC conversion"
  Battery bat(
    SOC_start=0.5,
    eta_DCAC=0.95,
    EMax=749999.88,
    V_nominal=120)
    "Battery with losses for AC/DC conversion and charge/discharge"
equation
  connect(fixVol.terminal, bat_ideal.terminal)
  connect(pow.y, bat_ideal.P)
  connect(fixVol.terminal, bat_loss_acdc.terminal)
  connect(fixVol.terminal, bat.terminal)
  connect(pow.y, bat_loss_acdc.P)
  connect(pow.y, bat.P)
end AcBattery;


Package with example models

within Buildings.Electrical.AC.OnePhase.Storage;
package Examples "Package with example models"
  extends Modelica.Icons.ExamplesPackage;
end Examples;


Three phases balanced AC systems

within Buildings.Electrical.AC;
package ThreePhasesBalanced "Three phases balanced AC systems"
  extends Modelica.Icons.VariantsPackage;
end ThreePhasesBalanced;


AC AC converter three phase balanced systems. This model represents a simplified conversion between two AC
three-phase balanced systems. The conversion losses are represented by a
constant efficiency <i>η</i>.

within Buildings.Electrical.AC.ThreePhasesBalanced.Conversion;
model ACACConverter "AC AC converter three phase balanced systems"
  extends Buildings.Electrical.AC.OnePhase.Conversion.ACACConverter(
    redeclare Interfaces.Terminal_n terminal_n,
    redeclare Interfaces.Terminal_p terminal_p);
end ACACConverter;


AC AC transformer three phase balanced systems. Simple transformer model for three-phase
balanced AC systems. The model does not include core and
magnetic losses.

within Buildings.Electrical.AC.ThreePhasesBalanced.Conversion;
model ACACTransformer "AC AC transformer three phase balanced systems"
  extends Buildings.Electrical.AC.OnePhase.Conversion.ACACTransformer(
    redeclare Interfaces.Terminal_n terminal_n,
    redeclare Interfaces.Terminal_p terminal_p);
end ACACTransformer;


AC AC transformer full model for three phase balanced systems. Model of a transformer for three-phase
balanced AC systems. The model includes core and magnetic losses.

within Buildings.Electrical.AC.ThreePhasesBalanced.Conversion;
model ACACTransformerFull
  "AC AC transformer full model for three phase balanced systems"
  extends Buildings.Electrical.AC.OnePhase.Conversion.ACACTransformerFull(
    redeclare Interfaces.Terminal_n terminal_n,
    redeclare Interfaces.Terminal_p terminal_p);
end ACACTransformerFull;


AC DC converter. This model represents a simplified conversion between a three-phase
balanced AC system and a DC systems.

within Buildings.Electrical.AC.ThreePhasesBalanced.Conversion;
model ACDCConverter "AC DC converter"
  extends Buildings.Electrical.AC.OnePhase.Conversion.ACDCConverter(
    redeclare Interfaces.Terminal_n terminal_n);
end ACDCConverter;


within Buildings.Electrical.AC.ThreePhasesBalanced;
package Conversion "Package with transformers and converter models for three-phase balanced AC systems"
  extends Modelica.Icons.Package;
end Conversion;


This example illustrates how to use the AC/AC converter model. This example illustrates the use of a model that converts AC voltage to AC voltage.
The transformer model assumes a linear loss when transmitting the power.

within Buildings.Electrical.AC.ThreePhasesBalanced.Conversion.Examples;
model ACACConverter
  "This example illustrates how to use the AC/AC converter model"
  extends Modelica.Icons.Example;

  Buildings.Electrical.AC.ThreePhasesBalanced.Conversion.ACACConverter
    conACAC(eta=0.9, conversionFactor=120/480) "ACAC transformer"
  Buildings.Electrical.AC.ThreePhasesBalanced.Sources.FixedVoltage sou(
    definiteReference=true,
    f=60,
    V=480) "Voltage source"
  Buildings.Electrical.AC.ThreePhasesBalanced.Loads.Inductive load(
    mode=Buildings.Electrical.Types.Load.VariableZ_P_input,
    V_nominal=120) "Load model"
  Modelica.Blocks.Sources.Ramp ramp(
    duration=0.5,
    startTime=0.3,
    height=2000,
    offset=-1000) "Power consumed by the model"
equation
  connect(sou.terminal, conACAC.terminal_n)
  connect(conACAC.terminal_p, load.terminal)
  connect(ramp.y, load.Pow)
end ACACConverter;