Partial model of three-phase transformer.

within Modelica.Electrical.Machines.Interfaces;
partial model PartialBasicTransformer
  "Partial model of three-phase transformer"
  extends Machines.Icons.TransientTransformer;
  final parameter Integer m(min=1) = 3 "Number of phases"
  constant String VectorGroup="Yy00";
  parameter Real n(start=1)
    "Ratio primary voltage (line-to-line) / secondary voltage (line-to-line)";
  parameter SI.Resistance R1(start=5E-3/(if C1 == "D" then 1
         else 3)) "Primary resistance per phase at TRef"
  parameter SI.Temperature T1Ref(start=293.15)
    "Reference temperature of primary resistance"
  parameter Machines.Thermal.LinearTemperatureCoefficient20 alpha20_1(start=0)
    "Temperature coefficient of primary resistance at 20 degC"
  parameter SI.Inductance L1sigma(start=78E-6/(if C1 == "D"
         then 1 else 3)) "Primary stray inductance per phase"
  parameter SI.Resistance R2(start=5E-3/(if C2 == "d" then 1
         else 3)) "Secondary resistance per phase at TRef"
  parameter SI.Temperature T2Ref(start=293.15)
    "Reference temperature of secondary resistance"
  parameter Machines.Thermal.LinearTemperatureCoefficient20 alpha20_2(start=0)
    "Temperature coefficient of secondary resistance at 20 degC"
  parameter SI.Inductance L2sigma(start=78E-6/(if C2 == "d"
         then 1 else 3)) "Secondary stray inductance per phase"
  parameter Boolean useThermalPort=false
    "Enable / disable (=fixed temperatures) thermal port"
  parameter SI.Temperature T1Operational(start=293.15)
    "Operational temperature of primary resistance"
  parameter SI.Temperature T2Operational(start=293.15)
    "Operational temperature of secondary resistance"
  output Machines.Interfaces.PowerBalanceTransformer powerBalance(
    final power1=Machines.SpacePhasors.Functions.activePower(v1, i1),
    final power2=Machines.SpacePhasors.Functions.activePower(v2, i2),
    final lossPower1=sum(r1.resistor.LossPower),
    final lossPower2=sum(r2.resistor.LossPower),
    final lossPowerCore=0) "Power balance";
  output SI.Voltage v1[m]=plug1.pin.v "Primary voltage";
  output SI.Current i1[m]=plug1.pin.i "Primary current";
  output SI.Voltage v2[m]=plug2.pin.v "Secondary voltage";
  output SI.Current i2[m]=plug2.pin.i "Secondary current";
protected
  constant String C1=Modelica.Utilities.Strings.substring(
          VectorGroup,
          1,
          1);
  constant String C2=Modelica.Utilities.Strings.substring(
          VectorGroup,
          2,
          2);
  parameter Real ni=n*(if C2 == "z" then sqrt(3) else 2)*(if C2 == "d"
       then 1 else sqrt(3))/(if C1 == "D" then 1 else sqrt(3));
public
  Modelica.Electrical.Polyphase.Interfaces.PositivePlug plug1(final m=m)
    "Primary plug"
  Modelica.Electrical.Polyphase.Interfaces.NegativePlug plug2(final m=m)
    "Secondary plug"
  Modelica.Electrical.Polyphase.Basic.Resistor r1(
    final m=m,
    final R=fill(R1, m),
    final T_ref=fill(T1Ref, m),
    final alpha=fill(Machines.Thermal.convertAlpha(alpha20_1, T1Ref), m),
    final useHeatPort=true,
    final T=fill(T1Ref, m))
  Modelica.Electrical.Polyphase.Basic.Inductor l1sigma(final m=m, final L=
        fill(L1sigma, m))
  Modelica.Electrical.Polyphase.Basic.Resistor r2(
    final m=m,
    final R=fill(R2, m),
    final T_ref=fill(T2Ref, m),
    final alpha=fill(Machines.Thermal.convertAlpha(alpha20_2, T2Ref), m),
    final useHeatPort=true,
    final T=fill(T2Ref, m))
  Modelica.Electrical.Polyphase.Basic.Inductor l2sigma(final m=m, final L=
        fill(L2sigma, m))
  Machines.BasicMachines.Components.IdealCore core(
    final m=m,
    final n12=ni,
    final n13=ni)
  Machines.Interfaces.ThermalPortTransformer thermalPort(final m=m) if
    useThermalPort
  Machines.Thermal.ThermalAmbientTransformer thermalAmbient(
    final useTemperatureInputs=false,
    final T1=T1Operational,
    final T2=T2Operational,
    final m=m) if not useThermalPort
protected
  Machines.Interfaces.ThermalPortTransformer internalThermalPort(final m=m)
equation
  connect(r1.plug_n, l1sigma.plug_p)
  connect(plug1, r1.plug_p)
  connect(thermalPort, internalThermalPort)
  connect(thermalAmbient.thermalPort, internalThermalPort)
  connect(r1.heatPort, internalThermalPort.heatPort1)
  connect(r2.heatPort, internalThermalPort.heatPort2)
  connect(r2.plug_p, plug2)
  connect(l2sigma.plug_p, r2.plug_n)
end PartialBasicTransformer;


Thermal ports of DC machines

within Modelica.Electrical.Machines.Interfaces;
package DCMachines "Thermal ports of DC machines"
  extends Modelica.Icons.VariantsPackage;
end DCMachines;


Partial thermal ambience for DC machines.

within Modelica.Electrical.Machines.Interfaces.DCMachines;
model PartialThermalAmbientDCMachines
  "Partial thermal ambience for DC machines"
  parameter Boolean useTemperatureInputs=false
    "If true, temperature inputs are used; else, temperatures are constant"
  constant SI.Temperature TDefault=293.15
    "Default temperature";
  parameter SI.Temperature Ta(start=TDefault)
    "Temperature of armature"
  output SI.HeatFlowRate Q_flowArmature=temperatureArmature.port.Q_flow
    "Heat flow rate of armature";
  output SI.HeatFlowRate Q_flowCore=temperatureCore.port.Q_flow
    "Heat flow rate of core losses";
  output SI.HeatFlowRate Q_flowStrayLoad=
      temperatureStrayLoad.port.Q_flow
    "Heat flow rate of stray load losses";
  output SI.HeatFlowRate Q_flowFriction=temperatureFriction.port.Q_flow
    "Heat flow rate of friction losses";
  output SI.HeatFlowRate Q_flowBrush=temperatureBrush.port.Q_flow
    "Heat flow rate of brushes";
  replaceable Machines.Interfaces.DCMachines.PartialThermalPortDCMachines thermalPort
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature
    temperatureArmature
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature temperatureCore(
      final T=TDefault)
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature
    temperatureStrayLoad(final T=TDefault)
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature
    temperatureFriction(final T=TDefault)
  Modelica.Blocks.Interfaces.RealInput TArmature(unit="K") if useTemperatureInputs
    "Temperature of armature"
  Modelica.Blocks.Sources.Constant constTa(final k=Ta) if not
    useTemperatureInputs
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature temperatureBrush(
      final T=TDefault)
equation
  connect(constTa.y, temperatureArmature.T)
  connect(TArmature, temperatureArmature.T)

  connect(temperatureArmature.port, thermalPort.heatPortArmature)
  connect(temperatureBrush.port, thermalPort.heatPortBrush)
  connect(temperatureCore.port, thermalPort.heatPortCore)
  connect(temperatureStrayLoad.port, thermalPort.heatPortStrayLoad)
  connect(temperatureFriction.port, thermalPort.heatPortFriction)
end PartialThermalAmbientDCMachines;


within Modelica.Electrical.Machines.Interfaces;
package InductionMachines "Interfaces and partial models for induction machines"
  extends Modelica.Icons.VariantsPackage;
end InductionMachines;


Partial thermal ambience for induction machines.

within Modelica.Electrical.Machines.Interfaces.InductionMachines;
model PartialThermalAmbientInductionMachines
  "Partial thermal ambience for induction machines"
  parameter Integer m=3 "Number of stator phases"
  parameter Boolean useTemperatureInputs=false
    "If true, temperature inputs are used; else, temperatures are constant"
  constant SI.Temperature TDefault=293.15
    "Default temperature";
  parameter SI.Temperature Ts(start=TDefault)
    "Temperature of stator windings"
  output SI.HeatFlowRate Q_flowStatorWinding=
      temperatureStatorWinding.port.Q_flow
    "Heat flow rate of stator windings";
  output SI.HeatFlowRate Q_flowStatorCore=
      temperatureStatorCore.port.Q_flow
    "Heat flow rate of stator core losses";
  output SI.HeatFlowRate Q_flowRotorCore=
      temperatureRotorCore.port.Q_flow
    "Heat flow rate of stator core losses";
  output SI.HeatFlowRate Q_flowStrayLoad=
      temperatureStrayLoad.port.Q_flow
    "Heat flow rate of stray load losses";
  output SI.HeatFlowRate Q_flowFriction=temperatureFriction.port.Q_flow
    "Heat flow rate of friction losses";
  replaceable
    Machines.Interfaces.InductionMachines.PartialThermalPortInductionMachines thermalPort(final m=m)
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature
    temperatureStatorWinding
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature
    temperatureStatorCore(final T=TDefault)
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature
    temperatureRotorCore(final T=TDefault)
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature
    temperatureStrayLoad(final T=TDefault)
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature
    temperatureFriction(final T=TDefault)
  Modelica.Blocks.Interfaces.RealInput TStatorWinding(unit="K") if
    useTemperatureInputs "Temperature of stator windings"
  Modelica.Blocks.Sources.Constant constTs(final k=Ts) if not
    useTemperatureInputs
  Modelica.Thermal.HeatTransfer.Components.ThermalCollector
    thermalCollectorStator(final m=m)
equation
  connect(constTs.y, temperatureStatorWinding.T)
  connect(TStatorWinding, temperatureStatorWinding.T)

  connect(temperatureStrayLoad.port, thermalPort.heatPortStrayLoad)
  connect(temperatureFriction.port, thermalPort.heatPortFriction)
  connect(thermalCollectorStator.port_b, temperatureStatorWinding.port)
  connect(thermalCollectorStator.port_a, thermalPort.heatPortStatorWinding)
  connect(temperatureStatorCore.port, thermalPort.heatPortStatorCore)
  connect(temperatureRotorCore.port, thermalPort.heatPortRotorCore)
end PartialThermalAmbientInductionMachines;


Model of angular velocity dependent friction losses. The friction losses are considered by the equations

within Modelica.Electrical.Machines.Losses;
model Friction "Model of angular velocity dependent friction losses"
  extends Machines.Interfaces.FlangeSupport;
  parameter FrictionParameters frictionParameters
    "Friction loss parameters";
  extends
    Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT(
      useHeatPort=false);
equation
  if (frictionParameters.PRef <= 0) then
    tau = 0;
  else
    tau = -(if noEvent(abs(w)>frictionParameters.wLinear) then
      frictionParameters.tauRef*sign(w)*(abs(w)/frictionParameters.wRef)^frictionParameters.power_w else
      frictionParameters.tauLinear*w/frictionParameters.wLinear);
  end if;
  lossPower = -tau*w;
end Friction;


Loss models for electric machines

within Modelica.Electrical.Machines;
package Losses "Loss models for electric machines"
  extends Modelica.Icons.Package;
end Losses;


Model considering voltage drop of carbon brushes. Model of voltage drop and losses of carbon brushes. For currents between -ILinear and ILinear
 the voltage drop shows a linear behavior as depicted in Fig. 1.
 For positive currents greater or equal than ILinear the voltage drop equals V.
 For negative currents less or equal than -ILinear the voltage drop equals -V.

within Modelica.Electrical.Machines.Losses.DCMachines;
model Brush "Model considering voltage drop of carbon brushes"
  extends Modelica.Electrical.Analog.Interfaces.OnePort;
  parameter Machines.Losses.BrushParameters brushParameters
    "Brush loss parameters";
  extends
    Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT(
      useHeatPort=false);
equation
  if (brushParameters.V <= 0) then
    v = 0;
  else
    v = smooth(0, if (i > +brushParameters.ILinear) then +brushParameters.V
       else if (i < -brushParameters.ILinear) then -brushParameters.V
       else brushParameters.V*i/brushParameters.ILinear);
  end if;
  lossPower = v*i;
end Brush;


Model of core losses. Core losses can be separated into eddy current and hysteresis losses. The total core losses
can thus be expressed as

within Modelica.Electrical.Machines.Losses.DCMachines;
model Core "Model of core losses"
  extends Modelica.Electrical.Analog.Interfaces.OnePort;
  parameter Machines.Losses.CoreParameters coreParameters(m=1)
    "Armature core losses";
  extends
    Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT(
      useHeatPort=false);
  input SI.AngularVelocity w
    "Remagnetization angular velocity"
  SI.Conductance Gc "Variable core loss conductance";
protected
  SI.AngularVelocity wLimit=noEvent(max(noEvent(abs(w)),
      coreParameters.wMin)) "Limited angular velocity";
equation
  if (coreParameters.PRef <= 0) then
    Gc = 0;
    i = 0;
  else
    Gc = coreParameters.GcRef;
    // * (coreParameters.wRef/wLimit*coreParameters.ratioHysteresis + 1 - coreParameters.ratioHysteresis);
    i = Gc*v;
  end if;
  lossPower = v*i;
end Core;


Loss models for DC machines

within Modelica.Electrical.Machines.Losses;
package DCMachines "Loss models for DC machines"
  extends Modelica.Icons.VariantsPackage;
end DCMachines;


Model of stray load losses dependent on current and speed. The stray load loss torque is

within Modelica.Electrical.Machines.Losses.DCMachines;
model StrayLoad
  "Model of stray load losses dependent on current and speed"
  extends Modelica.Electrical.Analog.Interfaces.OnePort;
  extends Machines.Interfaces.FlangeSupport;
  parameter Machines.Losses.StrayLoadParameters strayLoadParameters
    "Stray load loss parameters";
  extends
    Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT(
      useHeatPort=false);
equation
  v = 0;
  if (strayLoadParameters.PRef <= 0) then
    tau = 0;
  else
    tau = -strayLoadParameters.tauRef*(i/strayLoadParameters.IRef)^2*
      sign(w)*(abs(w)/strayLoadParameters.wRef)^strayLoadParameters.power_w;
  end if;
  lossPower = -tau*w;
end StrayLoad;


Model considering voltage drop of carbon brushes. Model of voltage drop and losses of carbon brushes. This three-phase model uses three
DC Brush loss models.

within Modelica.Electrical.Machines.Losses.InductionMachines;
model Brush "Model considering voltage drop of carbon brushes"
  extends Modelica.Electrical.Polyphase.Interfaces.TwoPlug;
  parameter Machines.Losses.BrushParameters brushParameters
    "Brush loss parameters";
  extends Modelica.Thermal.HeatTransfer.Interfaces.PartialConditionalHeatPort(
      useHeatPort=false,final T=293.15);
  DCMachines.Brush brush[3](each final brushParameters=brushParameters,
      each final useHeatPort=true)
equation
  connect(plug_p.pin, brush.p)
  connect(brush.n, plug_n.pin)
  for j in 1:m loop
    connect(brush[j].heatPort, internalHeatPort)
  end for;
end Brush;


within Modelica.Electrical.Machines.Losses.InductionMachines;
model Core "Model of core losses"
  parameter Machines.Losses.CoreParameters coreParameters(m=3)
    "Core parameters";
  //for backwards compatibility present but unused
  final parameter Integer m=coreParameters.m "Number of phases"
  parameter Real turnsRatio(final min=Modelica.Constants.small)
    "Effective number of stator turns / effective number of rotor turns (if used as rotor core)";
  extends
    Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT(
      useHeatPort=false);
  Machines.Interfaces.SpacePhasor spacePhasor
  input SI.AngularVelocity w
    "Remagnetization angular velocity"
  SI.Conductance Gc "Variable core loss conductance";
protected
  SI.AngularVelocity wLimit=noEvent(max(noEvent(abs(w)),
      coreParameters.wMin)) "Limited angular velocity";
equation
  if (coreParameters.PRef <= 0) then
    Gc = 0;
    spacePhasor.i_ = zeros(2);
  else
    Gc = coreParameters.GcRef;
    //  * (coreParameters.wRef/wLimit*coreParameters.ratioHysteresis + 1 - coreParameters.ratioHysteresis);
    spacePhasor.i_ = Gc*spacePhasor.v_;
  end if;
  lossPower = 3/2*(+spacePhasor.v_[1]*spacePhasor.i_[1] + spacePhasor.v_[2]*spacePhasor.i_[2]);
end Core;


Loss models for induction machines

within Modelica.Electrical.Machines.Losses;
package InductionMachines "Loss models for induction machines"
  extends Modelica.Icons.VariantsPackage;
end InductionMachines;


Model of permanent magnet losses dependent on current and speed. Permanent magnet losses are modeled dependent on current and speed.

within Modelica.Electrical.Machines.Losses.InductionMachines;
model PermanentMagnetLosses
  "Model of permanent magnet losses dependent on current and speed"
  extends Machines.Interfaces.FlangeSupport;
  import Modelica.Electrical.Polyphase.Functions.quasiRMS;
  parameter Integer m(min=1) = 3 "Number of phases"
  parameter Machines.Losses.PermanentMagnetLossParameters permanentMagnetLossParameters
    "Permanent magnet loss parameters";
  extends
    Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT(
      useHeatPort=false);
  input SI.Current is[m] "Instantaneous stator currents";
  SI.Current iRMS=quasiRMS(is);
equation
  if (permanentMagnetLossParameters.PRef <= 0) then
    tau = 0;
  else
    tau = -permanentMagnetLossParameters.tauRef*(permanentMagnetLossParameters.c + (1 - permanentMagnetLossParameters.c)*
      (iRMS/permanentMagnetLossParameters.IRef)^permanentMagnetLossParameters.power_I)*
      sign(w)*(abs(w)/permanentMagnetLossParameters.wRef)^permanentMagnetLossParameters.power_w;
  end if;
  lossPower = -tau*w;
end PermanentMagnetLosses;


Model of stray load losses dependent on current and speed. Stray load losses are modeled similar to standards EN 60034-2 and IEEE 112, i.e., they are dependent on square of current,
but without scaling them to zero at no-load current.

within Modelica.Electrical.Machines.Losses.InductionMachines;
model StrayLoad
  "Model of stray load losses dependent on current and speed"
  extends Modelica.Electrical.Polyphase.Interfaces.OnePort;
  extends Machines.Interfaces.FlangeSupport;
  import Modelica.Electrical.Polyphase.Functions.quasiRMS;
  parameter Machines.Losses.StrayLoadParameters strayLoadParameters
    "Stray load loss parameters";
  extends
    Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT(
      useHeatPort=false);
  SI.Current iRMS=quasiRMS(i);
equation
  v = zeros(m);
  if (strayLoadParameters.PRef <= 0) then
    tau = 0;
  else
    tau = -strayLoadParameters.tauRef*(iRMS/strayLoadParameters.IRef)^2*
      sign(w)*(abs(w)/strayLoadParameters.wRef)^strayLoadParameters.power_w;
  end if;
  lossPower = -tau*w;
end StrayLoad;


Length of space phasor -> RMS current.

within Modelica.Electrical.Machines.Sensors;
model CurrentQuasiRMSSensor "Length of space phasor -> RMS current"
  extends Modelica.Icons.RoundSensor;
  constant Integer m(final min=1) = 3 "Number of phases";
  Modelica.Blocks.Interfaces.RealOutput I(final quantity="ElectricCurrent",
      final unit="A")
  Modelica.Electrical.Polyphase.Interfaces.PositivePlug plug_p(final m=m)
  Modelica.Electrical.Polyphase.Interfaces.NegativePlug plug_n(final m=m)
  Modelica.Electrical.Polyphase.Sensors.CurrentSensor CurrentSensor1(
      final m=m)
  Modelica.Blocks.Math.Gain Gain1(final k=1/sqrt(2))
  Machines.SpacePhasors.Blocks.ToSpacePhasor ToSpacePhasor1(m=m)
  Machines.SpacePhasors.Blocks.ToPolar ToPolar1
equation
  connect(plug_p, CurrentSensor1.plug_p)
  connect(CurrentSensor1.plug_n, plug_n)
  connect(CurrentSensor1.i, ToSpacePhasor1.u)
  connect(ToSpacePhasor1.y, ToPolar1.u)
  connect(ToPolar1.y[1], Gain1.u)
  connect(Gain1.y, I)
end CurrentQuasiRMSSensor;


Instantaneous power from space phasors.

within Modelica.Electrical.Machines.Sensors;
model ElectricalPowerSensor "Instantaneous power from space phasors"
  extends Modelica.Icons.RoundSensor;
  constant Integer m(final min=1) = 3 "Number of phases";
  Modelica.Blocks.Interfaces.RealOutput P(final quantity="Power", final
      unit="W")
  Modelica.Blocks.Interfaces.RealOutput Q(final quantity="Power", final
      unit="var")
  Modelica.Electrical.Polyphase.Interfaces.PositivePlug plug_p(final m=m)
  Modelica.Electrical.Polyphase.Interfaces.NegativePlug plug_ni(final m=m)
  Modelica.Electrical.Polyphase.Interfaces.NegativePlug plug_nv(final m=m)
protected
  SI.Voltage v_[2];
  SI.Current i_[2];
equation
  plug_p.pin.v = plug_ni.pin.v;
  plug_p.pin.i + plug_ni.pin.i = zeros(m);
  plug_nv.pin.i = zeros(m);
  v_ = Machines.SpacePhasors.Functions.ToSpacePhasor(plug_p.pin.v - plug_nv.pin.v);
  i_ = Machines.SpacePhasors.Functions.ToSpacePhasor(plug_p.pin.i);
  2/3*P = +v_[1]*i_[1] + v_[2]*i_[2];
  2/3*Q = -v_[1]*i_[2] + v_[2]*i_[1];
end ElectricalPowerSensor;


Hall sensor. Simple model of a hall sensor, i.e. measuring the angle of the flange (w.r.t. the optional support), multiplying by the number of phases p to obtain the electrical angle,
and adding a correction term i.e. the initial angle of the flange phi0.

within Modelica.Electrical.Machines.Sensors;
model HallSensor "Hall sensor"
  import Modelica.Constants.pi;
  extends
    Modelica.Mechanics.Rotational.Interfaces.PartialElementaryOneFlangeAndSupport2;
  parameter Integer p(final min=1, start=2) "Number of pole pairs";
  parameter SI.Angle phi0=-pi/p "Initial mechanical angle";
  Modelica.Blocks.Interfaces.RealOutput y(
    quantity="Angle",
    final unit="rad",
    displayUnit="deg") "\"Electrical angle\""
equation
  flange.tau=0;
  y=mod((flange.phi - phi_support - phi0)*p, 2*pi);
end HallSensor;


Mechanical power = torque x speed.

within Modelica.Electrical.Machines.Sensors;
model MechanicalPowerSensor "Mechanical power = torque x speed"
  extends Modelica.Icons.RoundSensor;
  extends Modelica.Mechanics.Rotational.Interfaces.PartialTwoFlanges;
  parameter Boolean useSupport=false "Use support or fixed housing"
  Modelica.Blocks.Interfaces.RealOutput P(final quantity="Power", final
      unit="W")
  Modelica.Mechanics.Rotational.Sensors.TorqueSensor torqueSensor
  Modelica.Blocks.Math.Product product
  Modelica.Mechanics.Rotational.Sensors.RelSpeedSensor relSpeedSensor
  Modelica.Mechanics.Rotational.Components.Fixed fixed if (not useSupport)
  Modelica.Mechanics.Rotational.Interfaces.Flange_a support if useSupport
    "Support at which the reaction torque is acting"
equation
  connect(flange_a, torqueSensor.flange_a)
  connect(torqueSensor.flange_b, flange_b)
  connect(flange_a, relSpeedSensor.flange_b)
  connect(relSpeedSensor.flange_a, fixed.flange)
  connect(relSpeedSensor.flange_a, support)
  connect(relSpeedSensor.w_rel, product.u1)
  connect(torqueSensor.tau, product.u2)
  connect(product.y, P)
end MechanicalPowerSensor;


Sensors for machine modelling

within Modelica.Electrical.Machines;
package Sensors "Sensors for machine modelling"
  extends Modelica.Icons.SensorsPackage;
end Sensors;


Rotor lagging angle.

within Modelica.Electrical.Machines.Sensors;
model RotorDisplacementAngle "Rotor lagging angle"
  parameter Integer m=3 "Number of phases"
  parameter Integer p(min=1) "Number of pole pairs";
  parameter Boolean positiveRange=false "Use only positive output range, if true";
  parameter Real threshold(final min=0)=0 "Below threshold the voltage is considered as zero";
  parameter Boolean useSupport=false "Use support or fixed housing"
  Modelica.Blocks.Interfaces.RealOutput rotorDisplacementAngle(final
      quantity="Angle", final unit="rad")
  Modelica.Electrical.Polyphase.Interfaces.PositivePlug plug_p(final m=m)
  Modelica.Electrical.Polyphase.Interfaces.NegativePlug plug_n(final m=m)
  Modelica.Electrical.Polyphase.Sensors.VoltageSensor VoltageSensor1(
      final m=m)
  SpacePhasors.Blocks.ToSpacePhasor ToSpacePhasorVS(final m=m)
  Modelica.Mechanics.Rotational.Interfaces.Flange_a flange
  Modelica.Mechanics.Rotational.Sensors.RelAngleSensor relativeAngleSensor
  Modelica.Blocks.Sources.Constant constant_(final k=Modelica.Constants.pi/
        2)
  Modelica.Blocks.Math.Add add(final k2=1, final k1=p)
  Modelica.Electrical.Machines.SpacePhasors.Blocks.Rotator rotatorVS2R
  Modelica.Electrical.Machines.SpacePhasors.Blocks.ToPolar ToPolarVSR
  Modelica.Mechanics.Rotational.Interfaces.Flange_a support if useSupport
    "Support at which the reaction torque is acting"
  Modelica.Mechanics.Rotational.Components.Fixed fixed if (not useSupport)
  Blocks.Math.WrapAngle wrapAngle(final positiveRange=positiveRange)
  SpacePhasors.Blocks.LessThreshold lessThreshold(final threshold=threshold)
equation
  connect(plug_p, VoltageSensor1.plug_p)
  connect(plug_n, VoltageSensor1.plug_n)
  connect(relativeAngleSensor.flange_b, flange)
  connect(relativeAngleSensor.flange_a, support)
  connect(relativeAngleSensor.flange_a, fixed.flange)
  connect(relativeAngleSensor.phi_rel, add.u1)
  connect(constant_.y, add.u2)
  connect(VoltageSensor1.v, ToSpacePhasorVS.u)
  connect(ToSpacePhasorVS.y, rotatorVS2R.u)
  connect(rotatorVS2R.y, ToPolarVSR.u)
  connect(add.y, rotatorVS2R.angle)
  connect(wrapAngle.y, rotorDisplacementAngle)
  connect(ToPolarVSR.y, lessThreshold.u)
  connect(lessThreshold.y, wrapAngle.u)
end RotorDisplacementAngle;


Sin-Cos-Resolver. Simple model of a sin-cos-resolver, i.e. sensing the angle of the flange phi (w.r.t. the optional support) and multiplied by p, providing 4 signals:

within Modelica.Electrical.Machines.Sensors;
model SinCosResolver "Sin-Cos-Resolver"
  import Modelica.Constants.pi;
  extends
    Modelica.Mechanics.Rotational.Interfaces.PartialElementaryOneFlangeAndSupport2;
  parameter Integer p(final min=1, start=2) "Number of pole pairs";
  parameter Real amplitude=1 "Amplitude of signals";
  parameter Real offset=1.5 "Offset of signals";
  parameter SI.Angle phi0=-pi/p "Initial mechanical angle";
  Modelica.Blocks.Interfaces.RealOutput y[4] "Track signals"
equation
  flange.tau=0;
  y[1] = offset + amplitude*cos(p*(flange.phi - phi_support - phi0));
  y[2] = offset - amplitude*cos(p*(flange.phi - phi_support - phi0));
  y[3] = offset + amplitude*sin(p*(flange.phi - phi_support - phi0));
  y[4] = offset - amplitude*sin(p*(flange.phi - phi_support - phi0));
end SinCosResolver;


Length of space phasor -> RMS voltage.

within Modelica.Electrical.Machines.Sensors;
model VoltageQuasiRMSSensor "Length of space phasor -> RMS voltage"
  extends Modelica.Icons.RoundSensor;
  constant Integer m(final min=1) = 3 "Number of phases";
  Modelica.Blocks.Interfaces.RealOutput V(final quantity=
        "ElectricPotential", final unit="V")
  Modelica.Electrical.Polyphase.Interfaces.PositivePlug plug_p(final m=m)
  Modelica.Electrical.Polyphase.Interfaces.NegativePlug plug_n(final m=m)
  Modelica.Electrical.Polyphase.Sensors.VoltageSensor VoltageSensor1(
      final m=m)
  Modelica.Blocks.Math.Gain Gain1(final k=1/sqrt(2))
  Machines.SpacePhasors.Blocks.ToSpacePhasor ToSpacePhasor1(m=m)
  Machines.SpacePhasors.Blocks.ToPolar ToPolar1
equation
  connect(plug_p, VoltageSensor1.plug_p)
  connect(VoltageSensor1.plug_n, plug_n)
  connect(VoltageSensor1.v, ToSpacePhasor1.u)
  connect(ToSpacePhasor1.y, ToPolar1.u)
  connect(ToPolar1.y[1], Gain1.u)
  connect(Gain1.y, V)
end VoltageQuasiRMSSensor;


Library with space phasor-models

within Modelica.Electrical.Machines;
package SpacePhasors "Library with space phasor-models"
  extends Modelica.Icons.Package;
end SpacePhasors;


Converts a space phasor from polar coordinates.

within Modelica.Electrical.Machines.SpacePhasors.Blocks;
block FromPolar "Converts a space phasor from polar coordinates"
  extends Modelica.Blocks.Interfaces.MIMOs(final n=2);
equation
  y = u[1]*{cos(u[2]),sin(u[2])};
end FromPolar;


Conversion of space phasors to polyphase instantaneous values.

within Modelica.Electrical.Machines.SpacePhasors.Blocks;
block FromSpacePhasor
  "Conversion of space phasors to polyphase instantaneous values"
  extends Modelica.Blocks.Interfaces.MIMO(final nin=2, final nout=m);
  parameter Integer m(min=1) = 3 "Number of phases"
protected
  parameter SI.Angle phi[m]=
      Modelica.Electrical.Polyphase.Functions.symmetricOrientation(m);
  parameter Real TransformationMatrix[2, m]=2/m*{+cos(+phi),+sin(+phi)};
  parameter Real InverseTransformation[m, 2]={{+cos(-phi[k]),-sin(-phi[k])}
      for k in 1:m};
public
  Modelica.Blocks.Interfaces.RealInput zero "Zero sequence component"
equation
  y = fill(zero, m) + InverseTransformation*u;
  // Alternative equivalent implementation:
  //m*zero = sum(y);
  //u = TransformationMatrix *y;
end FromSpacePhasor;


Sets angle to zero when length is below threshold.

within Modelica.Electrical.Machines.SpacePhasors.Blocks;
block LessThreshold "Sets angle to zero when length is below threshold"
  extends Modelica.Blocks.Interfaces.MISO(final nin=2);
  parameter Real threshold(final min=0) "Threshold";
equation
  y = if noEvent(u[1]<threshold) then 0 else u[2];
end LessThreshold;


Blocks for space phasor transformation

within Modelica.Electrical.Machines.SpacePhasors;
package Blocks "Blocks for space phasor transformation"
  extends Modelica.Icons.Package;
end Blocks;


This model determines the RMS value of the input space phasor u.
 . This model determines the RMS value of the input space phasor u.

within Modelica.Electrical.Machines.SpacePhasors.Blocks;
block QuasiRMS
  extends Modelica.Blocks.Interfaces.MISO(final nin=2);
  Modelica.Electrical.Machines.SpacePhasors.Blocks.ToPolar toPolar
  Modelica.Blocks.Math.Gain gain(final k=1/sqrt(2))
equation
  connect(u, toPolar.u)
  connect(toPolar.y[1], gain.u)
  connect(gain.y, y)
end QuasiRMS;


Rotates space phasor.

within Modelica.Electrical.Machines.SpacePhasors.Blocks;
block Rotator "Rotates space phasor"
  extends Modelica.Blocks.Interfaces.MIMOs(final n=2);
protected
  Real RotationMatrix[2, 2]={{+cos(-angle),-sin(-angle)},{+sin(-angle),+
      cos(-angle)}};
  // Alternative equivalent implementation;
  //Real InverseRotator[2,2] = {{+cos(+angle),-sin(+angle)},{+sin(+angle),+cos(+angle)}};
public
  Modelica.Blocks.Interfaces.RealInput angle(unit="rad")
equation
  y = RotationMatrix*u;
  // Alternative equivalent implementation;
  //u = InverseRotator*y;
end Rotator;


Converts a space phasor to polar coordinates.

within Modelica.Electrical.Machines.SpacePhasors.Blocks;
block ToPolar "Converts a space phasor to polar coordinates"
  extends Modelica.Blocks.Interfaces.MIMOs(final n=2);
  constant Real small=Modelica.Constants.small;
equation
  y[1] = sqrt(u[1]^2 + u[2]^2);
  y[2] = if noEvent(y[1] <= small) then 0 else Modelica.Math.atan2(u[2],
    u[1]);
  /*
  if y[1] <= small then
    y[2] = 0;
  else
    if u[2] >= 0 then
      y[2] =  Modelica.Math.acos(u[1]/y[1]);
    else
      y[2] = -Modelica.Math.acos(u[1]/y[1]);
    end if;
  end if;
*/
end ToPolar;


Conversion of polyphase instantaneous values to space phasors.

within Modelica.Electrical.Machines.SpacePhasors.Blocks;
block ToSpacePhasor
  "Conversion of polyphase instantaneous values to space phasors"
  extends Modelica.Blocks.Interfaces.MIMO(final nin=m, final nout=2);
  parameter Integer m(min=1) = 3 "Number of phases"
protected
  parameter SI.Angle phi[m]=
      Modelica.Electrical.Polyphase.Functions.symmetricOrientation(m);
  parameter Real TransformationMatrix[2, m]=2/m*{+cos(+phi),+sin(+phi)};
  parameter Real InverseTransformation[m, 2]={{+cos(-phi[k]),-sin(-phi[k])}
      for k in 1:m};
public
  Modelica.Blocks.Interfaces.RealOutput zero "Zero sequence component"
equation
  m*zero = sum(u);
  y = TransformationMatrix*u;
  // Alternative equivalent implementation;
  //u = fill(zero,m) + InverseTransformation*y;
end ToSpacePhasor;


Basic space phasor models

within Modelica.Electrical.Machines.SpacePhasors;
package Components "Basic space phasor models"
  extends Modelica.Icons.Package;
end Components;


Rotates space phasor.

within Modelica.Electrical.Machines.SpacePhasors.Components;
model Rotator "Rotates space phasor"
  import Modelica.Constants.pi;
protected
  Real RotationMatrix[2, 2]={{+cos(-angle),-sin(-angle)},{+sin(-angle),+
      cos(-angle)}};
  // Alternative equivalent implementation:
  //Real InverseRotator[2,2] = {{+cos(+angle),-sin(+angle)},{+sin(+angle),+cos(+angle)}};
public
  Machines.Interfaces.SpacePhasor spacePhasor_a
  Machines.Interfaces.SpacePhasor spacePhasor_b
  Modelica.Blocks.Interfaces.RealInput angle(unit="rad")
equation
  spacePhasor_b.v_ = RotationMatrix*spacePhasor_a.v_;
  // Alternative equivalent implementation:
  //spacePhasor_a.v_ = InverseRotator*spacePhasor_b.v_;
  spacePhasor_b.i_ + RotationMatrix*spacePhasor_a.i_ = zeros(2);
  // Alternative equivalent implementation:
  //spacePhasor_a.i_ + InverseRotator*spacePhasor_b.i_ = zeros(2);
end Rotator;


Physical transformation: three-phase <-> space phasors.

within Modelica.Electrical.Machines.SpacePhasors.Components;
model SpacePhasor
  "Physical transformation: three-phase <-> space phasors"
  import Modelica.Constants.pi;
  constant Integer m=3 "Number of phases";
  parameter Real turnsRatio=1 "Turns ratio";
  SI.Voltage v[m] "Instantaneous phase voltages";
  SI.Current i[m] "Instantaneous phase currents";
protected
  parameter Real InverseTransformation[m, 2]={{cos(-(k - 1)/m*2*pi),-sin(
      -(k - 1)/m*2*pi)} for k in 1:m};
  parameter Real TransformationMatrix[2, m]=2/m*{{cos(+(k - 1)/m*2*pi)
      for k in 1:m},{+sin(+(k - 1)/m*2*pi) for k in 1:m}};
public
  Modelica.Electrical.Polyphase.Interfaces.PositivePlug plug_p(final m=m)
  Modelica.Electrical.Polyphase.Interfaces.NegativePlug plug_n(final m=m)
  Modelica.Electrical.Analog.Interfaces.PositivePin zero
  Modelica.Electrical.Analog.Interfaces.NegativePin ground
  Machines.Interfaces.SpacePhasor spacePhasor
equation
  v/turnsRatio = plug_p.pin.v - plug_n.pin.v;
  i*turnsRatio = +plug_p.pin.i;
  i*turnsRatio = -plug_n.pin.i;
  m*zero.v = sum(v);
  spacePhasor.v_ = TransformationMatrix*v;
  // Alternative equivalent implementation:
  //v  = fill(zero.v,m) + InverseTransformation*spacePhasor.v_;
  -m*zero.i = sum(i);
  -spacePhasor.i_ = TransformationMatrix*i;
  // Alternative equivalent implementation:
  //-i  = fill(zero.i,m) + InverseTransformation*spacePhasor.i_;
  ground.v = 0;
end SpacePhasor;


within Modelica.Electrical.Machines.SpacePhasors;
package Functions "Functions for space phasor transformation"
  extends Modelica.Icons.FunctionsPackage;
end Functions;


Rotates space phasor.

within Modelica.Electrical.Machines.SpacePhasors.Functions;
function Rotator "Rotates space phasor"
  extends Modelica.Icons.Function;
  input Real x[2] "Input space phasor";
  input SI.Angle angle "Input angle of rotation";
  output Real y[2] "Output space phasor";
protected
  Real RotationMatrix[2, 2]={{+cos(-angle),-sin(-angle)},{+sin(-angle),+
      cos(-angle)}};
algorithm
  y := RotationMatrix*x;
end Rotator;


within Modelica.Electrical.Machines;
package Thermal "Library with models for connecting thermal models"
  extends Modelica.Icons.Package;
end Thermal;


Thermal ambient for transformers.

within Modelica.Electrical.Machines.Thermal;
model ThermalAmbientTransformer "Thermal ambient for transformers"
  parameter Integer m(min=1) = 3 "Number of phases"
  parameter Boolean useTemperatureInputs=false
    "If true, temperature inputs are used; else, temperatures are constant"
  constant SI.Temperature TDefault=293.15
    "Default temperature";
  parameter SI.Temperature T1(start=TDefault)
    "Temperature of primary windings"
  parameter SI.Temperature T2(start=TDefault)
    "Temperature of secondary windings"
  output SI.HeatFlowRate Q_flow1=temperature1.port.Q_flow
    "Heat flow rate of primary windings";
  output SI.HeatFlowRate Q_flow2=temperature2.port.Q_flow
    "Heat flow rate of secondary windings";
  output SI.HeatFlowRate Q_flowCore=temperatureCore.port.Q_flow
    "Heat flow rate of core losses";
  output SI.HeatFlowRate Q_flowTotal=Q_flow1 + Q_flow2 +
      Q_flowCore;
  Machines.Interfaces.ThermalPortTransformer thermalPort(final m=m)
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature temperature1
  Modelica.Blocks.Sources.Constant constT1(final k=T1) if not
    useTemperatureInputs
  Modelica.Blocks.Interfaces.RealInput TPrimary(unit="K") if useTemperatureInputs
    "Temperature of primary windings"
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature temperature2
  Modelica.Blocks.Sources.Constant constT2(final k=T2) if not
    useTemperatureInputs
  Modelica.Blocks.Interfaces.RealInput TSecondary(unit="K") if useTemperatureInputs
    "Temperature of secondary windings"
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature temperatureCore(
      final T=TDefault)
  Modelica.Thermal.HeatTransfer.Components.ThermalCollector
    thermalCollector1(final m=m)
  Modelica.Thermal.HeatTransfer.Components.ThermalCollector
    thermalCollector2(final m=m)
equation
  connect(TPrimary, temperature1.T)
  connect(constT1.y, temperature1.T)
  connect(TSecondary, temperature2.T)
  connect(constT2.y, temperature2.T)
  connect(temperatureCore.port, thermalPort.heatPortCore)
  connect(thermalCollector1.port_b, temperature1.port)
  connect(thermalCollector2.port_b, temperature2.port)
  connect(thermalCollector1.port_a, thermalPort.heatPort1)
  connect(thermalCollector2.port_a, thermalPort.heatPort2)
end ThermalAmbientTransformer;


Material Constants

within Modelica.Electrical.Machines.Thermal;
package Constants "Material Constants"
  extends Modelica.Icons.Package;
  constant SI.LinearTemperatureCoefficient alpha20Zero=0
    "Not temperature dependent";
  constant SI.LinearTemperatureCoefficient alpha20Aluminium=
      4.000e-3 "Aluminium";
  constant SI.LinearTemperatureCoefficient alpha20Brass=
      1.100e-3 "Brass";
  constant SI.LinearTemperatureCoefficient alpha20Bronze=
      0.800e-3 "Bronze";
  constant SI.LinearTemperatureCoefficient alpha20Copper=
      3.920e-3 "Copper";
end Constants;


Thermal parts of DC machines

within Modelica.Electrical.Machines.Thermal;
package DCMachines "Thermal parts of DC machines"
  extends Modelica.Icons.VariantsPackage;
end DCMachines;


Thermal ambient for DC machine with compound excitation.

within Modelica.Electrical.Machines.Thermal.DCMachines;
model ThermalAmbientDCCE
  "Thermal ambient for DC machine with compound excitation"
  extends Machines.Interfaces.DCMachines.PartialThermalAmbientDCMachines(
      redeclare final Machines.Interfaces.DCMachines.ThermalPortDCCE
      thermalPort);
  parameter SI.Temperature Te(start=TDefault)
    "Temperature of (shunt) excitation"
  parameter SI.Temperature Tse(start=TDefault)
    "Temperature of series excitation"
  output SI.HeatFlowRate Q_flowShuntExcitation=
      temperatureShuntExcitation.port.Q_flow
    "Heat flow rate of (shunt) excitation";
  output SI.HeatFlowRate Q_flowSeriesExcitation=
      temperatureSeriesExcitation.port.Q_flow
    "Heat flow rate of series excitation";
  output SI.HeatFlowRate Q_flowTotal=Q_flowArmature +
      Q_flowCore + Q_flowStrayLoad + Q_flowFriction + Q_flowBrush +
      Q_flowShuntExcitation + Q_flowSeriesExcitation;
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature
    temperatureShuntExcitation
  Modelica.Blocks.Sources.Constant constTe(final k=Te) if not
    useTemperatureInputs
  Modelica.Blocks.Interfaces.RealInput T_e(unit="K") if useTemperatureInputs
    "Temperature of (shunt) excitation"
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature
    temperatureSeriesExcitation
  Modelica.Blocks.Sources.Constant constTse(final k=Tse) if not
    useTemperatureInputs
  Modelica.Blocks.Interfaces.RealInput T_se(unit="K") if useTemperatureInputs
    "Temperature of series excitation"
equation
  connect(constTe.y, temperatureShuntExcitation.T)
  connect(T_e, temperatureShuntExcitation.T)
  connect(constTse.y, temperatureSeriesExcitation.T)
  connect(T_se, temperatureSeriesExcitation.T)
  connect(temperatureSeriesExcitation.port, thermalPort.heatPortSeriesExcitation)
  connect(temperatureShuntExcitation.port, thermalPort.heatPortShuntExcitation)
end ThermalAmbientDCCE;


Thermal ambient for DC machine with electrical excitation.

within Modelica.Electrical.Machines.Thermal.DCMachines;
model ThermalAmbientDCEE
  "Thermal ambient for DC machine with electrical excitation"
  extends Machines.Interfaces.DCMachines.PartialThermalAmbientDCMachines(
      redeclare final Machines.Interfaces.DCMachines.ThermalPortDCEE
      thermalPort);
  parameter SI.Temperature Te(start=TDefault)
    "Temperature of (shunt) excitation"
  output SI.HeatFlowRate Q_flowExcitation=
      temperatureExcitation.port.Q_flow
    "Heat flow rate of (shunt) excitation";
  output SI.HeatFlowRate Q_flowTotal=Q_flowArmature +
      Q_flowCore + Q_flowStrayLoad + Q_flowFriction + Q_flowBrush +
      Q_flowExcitation;
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature
    temperatureExcitation
  Modelica.Blocks.Sources.Constant constTe(final k=Te) if not
    useTemperatureInputs
  Modelica.Blocks.Interfaces.RealInput TExcitation(unit="K") if
    useTemperatureInputs "Temperature of (shunt) excitation"
equation
  connect(constTe.y, temperatureExcitation.T)
  connect(TExcitation, temperatureExcitation.T)
  connect(temperatureExcitation.port, thermalPort.heatPortExcitation)
end ThermalAmbientDCEE;


Thermal ambient for DC machine with permanent magnets.

within Modelica.Electrical.Machines.Thermal.DCMachines;
model ThermalAmbientDCPM
  "Thermal ambient for DC machine with permanent magnets"
  extends Machines.Interfaces.DCMachines.PartialThermalAmbientDCMachines(
      redeclare final Machines.Interfaces.DCMachines.ThermalPortDCPM
      thermalPort);
  parameter SI.Temperature Tpm(start=TDefault)
    "Temperature of permanent magnet"
  output SI.HeatFlowRate Q_flowPermanentMagnet=
      temperaturePermanentMagnet.port.Q_flow
    "Heat flow rate of permanent magnets";
  output SI.HeatFlowRate Q_flowTotal=Q_flowArmature +
      Q_flowCore + Q_flowStrayLoad + Q_flowFriction + Q_flowBrush +
      Q_flowPermanentMagnet;
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature
    temperaturePermanentMagnet
  Modelica.Blocks.Sources.Constant constTpm(final k=Tpm) if not
    useTemperatureInputs
  Modelica.Blocks.Interfaces.RealInput TPermanentMagnet(unit="K") if
    useTemperatureInputs "Temperature of permanent magnet"
equation
  connect(temperaturePermanentMagnet.port, thermalPort.heatPortPermanentMagnet)
  connect(constTpm.y, temperaturePermanentMagnet.T)
  connect(TPermanentMagnet, temperaturePermanentMagnet.T)
end ThermalAmbientDCPM;


Thermal ambient for DC machine with series excitation.

within Modelica.Electrical.Machines.Thermal.DCMachines;
model ThermalAmbientDCSE
  "Thermal ambient for DC machine with series excitation"
  extends Machines.Interfaces.DCMachines.PartialThermalAmbientDCMachines(
      redeclare final Machines.Interfaces.DCMachines.ThermalPortDCSE
      thermalPort);
  parameter SI.Temperature Tse(start=TDefault)
    "Temperature of series excitation"
  output SI.HeatFlowRate Q_flowSeriesExcitation=
      temperatureSeriesExcitation.port.Q_flow
    "Heat flow rate of series excitation";
  output SI.HeatFlowRate Q_flowTotal=Q_flowArmature +
      Q_flowCore + Q_flowStrayLoad + Q_flowFriction + Q_flowBrush +
      Q_flowSeriesExcitation;
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature
    temperatureSeriesExcitation
  Modelica.Blocks.Sources.Constant constTse(final k=Tse) if not
    useTemperatureInputs
  Modelica.Blocks.Interfaces.RealInput T_se(unit="K") if useTemperatureInputs
    "Temperature of series excitation"
equation
  connect(constTse.y, temperatureSeriesExcitation.T)
  connect(T_se, temperatureSeriesExcitation.T)
  connect(temperatureSeriesExcitation.port, thermalPort.heatPortSeriesExcitation)
end ThermalAmbientDCSE;


Thermal parts of induction machines

within Modelica.Electrical.Machines.Thermal;
package InductionMachines "Thermal parts of induction machines"
  extends Modelica.Icons.VariantsPackage;
end InductionMachines;


Thermal ambient for induction machine with squirrel cage.

within Modelica.Electrical.Machines.Thermal.InductionMachines;
model ThermalAmbientIMC
  "Thermal ambient for induction machine with squirrel cage"
  extends
    Machines.Interfaces.InductionMachines.PartialThermalAmbientInductionMachines(
      redeclare final Machines.Interfaces.InductionMachines.ThermalPortIMC
      thermalPort);
  parameter SI.Temperature Tr(start=TDefault)
    "Temperature of rotor (squirrel cage)"
  output SI.HeatFlowRate Q_flowRotorWinding=
      temperatureRotorWinding.port.Q_flow
    "Heat flow rate of rotor (squirrel cage)";
  output SI.HeatFlowRate Q_flowTotal=Q_flowStatorWinding +
      Q_flowRotorWinding + Q_flowStatorCore + Q_flowRotorCore +
      Q_flowStrayLoad + Q_flowFriction;
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature
    temperatureRotorWinding
  Modelica.Blocks.Interfaces.RealInput TRotorWinding(unit="K") if
    useTemperatureInputs "Temperature of squirrel cage"
  Modelica.Blocks.Sources.Constant constTr(final k=Tr) if not
    useTemperatureInputs
equation
  connect(constTr.y, temperatureRotorWinding.T)
  connect(temperatureRotorWinding.port, thermalPort.heatPortRotorWinding)
  connect(TRotorWinding, temperatureRotorWinding.T)
end ThermalAmbientIMC;


Thermal ambient for induction machine with slipring.

within Modelica.Electrical.Machines.Thermal.InductionMachines;
model ThermalAmbientIMS
  "Thermal ambient for induction machine with slipring"
  extends
    Machines.Interfaces.InductionMachines.PartialThermalAmbientInductionMachines(
      redeclare final Machines.Interfaces.InductionMachines.ThermalPortIMS
      thermalPort(final mr=mr));
  parameter Integer mr=m "Number of rotor phases"
  parameter SI.Temperature Tr(start=TDefault)
    "Temperature of rotor windings"
  output SI.HeatFlowRate Q_flowRotorWinding=
      temperatureRotorWinding.port.Q_flow
    "Heat flow rate of rotor (squirrel cage)";
  output SI.HeatFlowRate Q_flowBrush=temperatureBrush.port.Q_flow
    "Heat flow rate of brushes";
  output SI.HeatFlowRate Q_flowTotal=Q_flowStatorWinding +
      Q_flowRotorWinding + Q_flowStatorCore + Q_flowRotorCore +
      Q_flowStrayLoad + Q_flowFriction + Q_flowBrush;
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature
    temperatureRotorWinding
  Modelica.Blocks.Interfaces.RealInput TRotorWinding(unit="K") if
    useTemperatureInputs "Temperature of rotor windings"
  Modelica.Blocks.Sources.Constant constTr(final k=Tr) if not
    useTemperatureInputs
  Modelica.Thermal.HeatTransfer.Components.ThermalCollector
    thermalCollectorRotor(final m=mr)
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature temperatureBrush(
      final T=TDefault)
equation
  connect(constTr.y, temperatureRotorWinding.T)
  connect(thermalCollectorRotor.port_b, temperatureRotorWinding.port)
  connect(thermalCollectorRotor.port_a, thermalPort.heatPortRotorWinding)
  connect(temperatureBrush.port, thermalPort.heatPortBrush)
  connect(TRotorWinding, temperatureRotorWinding.T)
end ThermalAmbientIMS;


Thermal parts of synchronous machines

within Modelica.Electrical.Machines.Thermal;
package SynchronousMachines "Thermal parts of synchronous machines"
  extends Modelica.Icons.VariantsPackage;
end SynchronousMachines;


Thermal ambient for synchronous machine with electrical excitation.

within Modelica.Electrical.Machines.Thermal.SynchronousMachines;
model ThermalAmbientSMEE
  "Thermal ambient for synchronous machine with electrical excitation"
  parameter Boolean useDamperCage(start=true)
    "Enable / disable damper cage"
  extends
    Machines.Interfaces.InductionMachines.PartialThermalAmbientInductionMachines(
      redeclare final Machines.Interfaces.InductionMachines.ThermalPortSMEE
      thermalPort(final useDamperCage=useDamperCage));
  parameter SI.Temperature Tr(start=TDefault)
    "Temperature of damper cage (optional)"
  parameter SI.Temperature Te(start=TDefault)
    "Temperature of excitation"
  output SI.HeatFlowRate Q_flowRotorWinding=
      temperatureRotorWinding.port.Q_flow
    "Heat flow rate of damper cage (optional)";
  output SI.HeatFlowRate Q_flowExcitation=
      temperatureExcitation.port.Q_flow "Heat flow rate of excitation";
  output SI.HeatFlowRate Q_flowTotal=Q_flowStatorWinding +
      Q_flowRotorWinding + Q_flowExcitation + Q_flowStatorCore +
      Q_flowRotorCore + Q_flowStrayLoad + Q_flowFriction;
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature
    temperatureRotorWinding
  Modelica.Blocks.Interfaces.RealInput TRotorWinding(unit="K") if (
    useTemperatureInputs and useDamperCage)
    "Temperature of damper cage (optional)"
  Modelica.Blocks.Sources.Constant constTr(final k=if useDamperCage then
        Tr else TDefault) if (not useTemperatureInputs or not
    useDamperCage)
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature
    temperatureExcitation
  Modelica.Blocks.Interfaces.RealInput TExcitation(unit="K") if
    useTemperatureInputs "Temperature of excitation"
  Modelica.Blocks.Sources.Constant constTe(final k=Te) if not
    useTemperatureInputs
  Modelica.Thermal.HeatTransfer.Sources.FixedTemperature temperatureBrush(
      final T=TDefault)
equation
  connect(constTr.y, temperatureRotorWinding.T)
  connect(temperatureRotorWinding.port, thermalPort.heatPortRotorWinding)
  connect(TRotorWinding, temperatureRotorWinding.T)
  connect(constTe.y, temperatureExcitation.T)
  connect(TExcitation, temperatureExcitation.T)
  connect(temperatureExcitation.port, thermalPort.heatPortExcitation)
  connect(temperatureBrush.port, thermalPort.heatPortBrush)
end ThermalAmbientSMEE;


Thermal ambient for synchronous machine with permanent magnets.

within Modelica.Electrical.Machines.Thermal.SynchronousMachines;
model ThermalAmbientSMPM
  "Thermal ambient for synchronous machine with permanent magnets"
  parameter Boolean useDamperCage(start=true)
    "Enable / disable damper cage"
  extends
    Machines.Interfaces.InductionMachines.PartialThermalAmbientInductionMachines(
      redeclare final Machines.Interfaces.InductionMachines.ThermalPortSMPM
      thermalPort(final useDamperCage=useDamperCage));
  parameter SI.Temperature Tpm(start=TDefault)
    "Temperature of permanent magnet"
  parameter SI.Temperature Tr(start=TDefault)
    "Temperature of damper cage (optional)"
  output SI.HeatFlowRate Q_flowRotorWinding=
      temperatureRotorWinding.port.Q_flow
    "Heat flow rate of damper cage (optional)";
  output SI.HeatFlowRate Q_flowPermanentMagnet=
      temperaturePermanentMagnet.port.Q_flow
    "Heat flow rate of permanent magnets";
  output SI.HeatFlowRate Q_flowTotal=Q_flowStatorWinding +
      Q_flowRotorWinding + Q_flowPermanentMagnet + Q_flowStatorCore +
      Q_flowRotorCore + Q_flowStrayLoad + Q_flowFriction;
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature
    temperatureRotorWinding
  Modelica.Blocks.Interfaces.RealInput TRotorWinding(unit="K") if (
    useTemperatureInputs and useDamperCage)
    "Temperature of damper cage (optional)"
  Modelica.Blocks.Sources.Constant constTr(final k=if useDamperCage then
        Tr else TDefault) if (not useTemperatureInputs or not
    useDamperCage)
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature
    temperaturePermanentMagnet
  Modelica.Blocks.Sources.Constant constTpm(final k=Tpm) if (not
    useTemperatureInputs)
  Modelica.Blocks.Interfaces.RealInput TPermanentMagnet(unit="K") if
    useTemperatureInputs "Temperature of permanent magnet"
equation
  connect(constTr.y, temperatureRotorWinding.T)
  connect(temperatureRotorWinding.port, thermalPort.heatPortRotorWinding)
  connect(TRotorWinding, temperatureRotorWinding.T)
  connect(temperaturePermanentMagnet.port, thermalPort.heatPortPermanentMagnet)
  connect(constTpm.y, temperaturePermanentMagnet.T)
  connect(TPermanentMagnet, temperaturePermanentMagnet.T)
end ThermalAmbientSMPM;


Thermal ambient for synchronous machine with reluctance rotor.

within Modelica.Electrical.Machines.Thermal.SynchronousMachines;
model ThermalAmbientSMR
  "Thermal ambient for synchronous machine with reluctance rotor"
  parameter Boolean useDamperCage(start=true)
    "Enable / disable damper cage"
  extends
    Machines.Interfaces.InductionMachines.PartialThermalAmbientInductionMachines(
      redeclare final Machines.Interfaces.InductionMachines.ThermalPortSMR
      thermalPort(final useDamperCage=useDamperCage));
  parameter SI.Temperature Tr(start=TDefault)
    "Temperature of damper cage (optional)"
  output SI.HeatFlowRate Q_flowRotorWinding=
      temperatureRotorWinding.port.Q_flow
    "Heat flow rate of damper cage (optional))";
  output SI.HeatFlowRate Q_flowTotal=Q_flowStatorWinding +
      Q_flowRotorWinding + Q_flowStatorCore + Q_flowRotorCore +
      Q_flowStrayLoad + Q_flowFriction;
  Modelica.Thermal.HeatTransfer.Sources.PrescribedTemperature
    temperatureRotorWinding
  Modelica.Blocks.Interfaces.RealInput TRotorWinding(unit="K") if (
    useTemperatureInputs and useDamperCage)
    "Temperature of damper cage (optional)"
  Modelica.Blocks.Sources.Constant constTr(final k=if useDamperCage then
        Tr else TDefault) if (not useTemperatureInputs or not
    useDamperCage)
equation
  connect(constTr.y, temperatureRotorWinding.T)
  connect(temperatureRotorWinding.port, thermalPort.heatPortRotorWinding)
  connect(TRotorWinding, temperatureRotorWinding.T)
end ThermalAmbientSMR;


Current controller in dq coordinate system. Simple Current controller

within Modelica.Electrical.Machines.Utilities;
model DQCurrentController
  "Current controller in dq coordinate system"
  import Modelica.Constants.pi;
  constant Integer m=3 "Number of phases";
  parameter Integer p "Number of pole pairs";
  parameter Boolean useRMS=true "If true, inputs dq are multiplied by sqrt(2)";
  parameter SI.Frequency fsNominal "Nominal frequency";
  parameter SI.Voltage VsOpenCircuit
    "Open circuit RMS voltage per phase @ fsNominal";
  parameter SI.Resistance Rs "Stator resistance per phase";
  parameter SI.Inductance Ld "Inductance in d-axis";
  parameter SI.Inductance Lq "Inductance in q-axis";
  //Decoupling
  parameter Boolean decoupling=false "Use decoupling network";
  final parameter SI.MagneticFlux psiM=sqrt(2)*VsOpenCircuit/
      (2*pi*fsNominal) "Approximation of magnetic flux linkage";
  SI.AngularVelocity omega=p*der(phi);
  SI.Voltage Vd=sqrt(2)*(Rs*id - omega*Lq*iq);
  SI.Voltage Vq=sqrt(2)*(Rs*iq + omega*Ld*id) + omega*psiM;
  extends Modelica.Blocks.Interfaces.MO(final nout=m);
  Modelica.Blocks.Interfaces.RealInput id "Reference of d-current"
  Modelica.Blocks.Interfaces.RealInput iq "Reference of q-current"
  Modelica.Blocks.Interfaces.RealInput phi(unit="rad") "Rotor angle"
  Modelica.Blocks.Interfaces.RealInput iActual[m](each unit="A")
    "Measured three-phase currents"
  Machines.Utilities.FromDQ fromDQ(final p=p, final m=m)
  Machines.Utilities.ToDQ toDQ(final p=p, final m=m)
  Modelica.Blocks.Math.Gain toPeak_d(final k=if useRMS then sqrt(2) else 1)
  Modelica.Blocks.Math.Gain toPeak_q(final k=if useRMS then sqrt(2) else 1)
  Modelica.Blocks.Math.Feedback feedback_d
  Modelica.Blocks.Math.Feedback feedback_q
  Modelica.Blocks.Continuous.PI PI_d(
    final k=unitResistance/Rs,
    final T=Ld/Rs,
    initType=Modelica.Blocks.Types.Init.InitialOutput)
  Modelica.Blocks.Continuous.PI PI_q(
    final k=unitResistance/Rs,
    final T=Lq/Rs,
    initType=Modelica.Blocks.Types.Init.InitialOutput)
  Modelica.Blocks.Math.Add add[2](final k1=fill(+1, 2), final k2=fill(if
        decoupling then +1 else 0, 2))
  Modelica.Blocks.Sources.RealExpression deCoupling[2](y={Vd,Vq})
protected
  constant SI.Resistance unitResistance=1
equation
  connect(fromDQ.y, y)
  connect(phi, fromDQ.phi)
  connect(iActual, toDQ.u)
  connect(phi, toDQ.phi)
  connect(toPeak_d.u, id)
  connect(toPeak_q.u, iq)
  connect(toPeak_q.y, feedback_q.u1)
  connect(toPeak_d.y, feedback_d.u1)
  connect(feedback_d.y, PI_d.u)
  connect(feedback_q.y, PI_q.u)
  connect(toDQ.y[1], feedback_d.u2)

  connect(toDQ.y[2], feedback_q.u2)

  connect(add.y, fromDQ.u)
  connect(PI_d.y, add[1].u1)
  connect(PI_q.y, add[2].u1)
  connect(deCoupling.y, add.u2)
end DQCurrentController;


Transforms dq to three-phase. Transforms dq currents or voltages to three-phase currents or voltages.

within Modelica.Electrical.Machines.Utilities;
model DQToThreePhase "Transforms dq to three-phase"
  parameter Integer m=3 "Number of phases"
  parameter Integer p "Number of pole pairs";
  parameter Boolean useRMS=true "If true, inputs dq are multiplied by sqrt(2)";
  extends Modelica.Blocks.Interfaces.MO(final nout=m);
  Modelica.Blocks.Interfaces.RealInput d "d-component"
  Modelica.Blocks.Interfaces.RealInput q "q-component"
  Modelica.Blocks.Interfaces.RealInput phi(unit="rad") "Rotor angle"
  Modelica.Blocks.Math.Gain toPeak_d(k=if useRMS then sqrt(2) else 1)
  Modelica.Blocks.Math.Gain toPeak_q(k=if useRMS then sqrt(2) else 1)
  Modelica.Blocks.Math.Gain toGamma(k=-p)
  Machines.SpacePhasors.Blocks.Rotator rotator
  Modelica.Blocks.Sources.Constant i0(k=0)
  Machines.SpacePhasors.Blocks.FromSpacePhasor fromSpacePhasor(final m=m)
equation
  connect(q, toPeak_q.u)
  connect(phi, toGamma.u)
  connect(rotator.angle, toGamma.y)
  connect(rotator.y, fromSpacePhasor.u)
  connect(toPeak_d.u, d)
  connect(toPeak_d.y, rotator.u[1])
  connect(toPeak_q.y, rotator.u[2])
  connect(i0.y, fromSpacePhasor.zero)
  connect(fromSpacePhasor.y, y)
end DQToThreePhase;


Transform rotor fixed space phasor to instantaneous stator quantities. The d and q components of a space phasor u[2] are rotated back to the stator fixed reference system,
using the provided mechanical rotor angle phi. The output are the instantaneous polyphase values y[m].

within Modelica.Electrical.Machines.Utilities;
block FromDQ
  "Transform rotor fixed space phasor to instantaneous stator quantities"
  extends Modelica.Blocks.Interfaces.MIMO(final nin=2, final nout=m);
  parameter Integer m(min=1) = 3 "Number of phases"
  parameter Integer p "Number of pole pairs";
  Modelica.Blocks.Math.Gain toGamma(final k=-p)
  Modelica.Electrical.Machines.SpacePhasors.Blocks.Rotator rotator
  Modelica.Blocks.Sources.Constant i0(final k=0)
  Modelica.Electrical.Machines.SpacePhasors.Blocks.FromSpacePhasor fromSpacePhasor(final m=m)
  Modelica.Blocks.Interfaces.RealInput phi(unit="rad")
equation
  connect(phi, toGamma.u)
  connect(rotator.angle, toGamma.y)
  connect(rotator.y, fromSpacePhasor.u)
  connect(i0.y, fromSpacePhasor.zero)
  connect(u, rotator.u)
  connect(fromSpacePhasor.y, y)
end FromDQ;


Terminal box Y/D-connection. This model represents the internal connections of the terminal box of an electric machine.
The parameter terminalConnection is used to switch between star
(terminalConnection = \"Y\") and delta (terminalConnection = \"D\") connection.
The star point is a plug with
mSystem = Electrical.Polyphase.Functions.numberOfSymmetricBaseSystems(m) phases,
representing the star points of each base system; see
Modelica.Magnetic.FundamentalWave.UsersGuide.Polyphase.

within Modelica.Electrical.Machines.Utilities;
model MultiTerminalBox "Terminal box Y/D-connection"
  parameter Integer m(min=1) = 3 "Number of phases"
  final parameter Integer mSystems=
      Modelica.Electrical.Polyphase.Functions.numberOfSymmetricBaseSystems(
      m) "Number of symmetric base systems";
  final parameter Integer mBasic=integer(m/mSystems) "Number of phases of basic system";
  parameter String terminalConnection(start="Y") "Choose \"Y\" for star or \"D\" for delta connection"
  Modelica.Electrical.Polyphase.Interfaces.PositivePlug plug_sp(final m=m)
    "To be connected with positive stator plug"
  Modelica.Electrical.Polyphase.Interfaces.NegativePlug plug_sn(final m=m)
    "To be connected with negative stator plug"
  Polyphase.Basic.MultiStar multiStar(final m=m) if (terminalConnection
     <> "D")
  Polyphase.Basic.MultiDelta multiDelta(final m=m) if (terminalConnection
     == "D")
  Modelica.Electrical.Polyphase.Interfaces.PositivePlug plugSupply(final m=
       m) "To be connected with grid"
  Modelica.Electrical.Polyphase.Interfaces.NegativePlug starpoint(final m=
        mSystems) if (terminalConnection <> "D") "Star point"
equation
  connect(plug_sn, multiStar.plug_p)
  connect(plug_sn, multiDelta.plug_n)
  connect(multiDelta.plug_p, plug_sp)
  connect(plug_sp, plugSupply)
  connect(starpoint, multiStar.starpoints)
end MultiTerminalBox;


within Modelica.Electrical.Machines;
package Utilities "Library with auxiliary models for testing"
  extends Modelica.Icons.UtilitiesPackage;
end Utilities;


Rheostat with linearly decreasing resistance.

within Modelica.Electrical.Machines.Utilities;
model RampedRheostat "Rheostat with linearly decreasing resistance"
  parameter Integer m=3 "Number of phases"
  Modelica.Electrical.Polyphase.Interfaces.PositivePlug plug_p(final m=m)
    "To positive rotor plug"
  Modelica.Electrical.Polyphase.Interfaces.NegativePlug plug_n(final m=m)
    "To negative rotor plug"
  parameter SI.Resistance RStart "Starting resistance";
  parameter SI.Time tStart
    "Time instance of reducing the rheostat";
  parameter SI.Time tRamp "Duration of ramp";
  Modelica.Electrical.Polyphase.Basic.Star star(final m=m)
  Modelica.Electrical.Analog.Basic.Ground ground
  Modelica.Electrical.Polyphase.Basic.VariableResistor rheostat(final m=m)
  Modelica.Blocks.Sources.Ramp ramp[m](
    final height=fill(-RStart, m),
    final duration=fill(tRamp, m),
    final offset=fill(RStart, m),
    final startTime=fill(tStart, m))
equation
  connect(plug_p, rheostat.plug_p)
  connect(rheostat.plug_n, plug_n)
  connect(rheostat.R, ramp.y)
  connect(rheostat.plug_n, star.plug_p)
  connect(star.pin_n, ground.p)
end RampedRheostat;


Evaluation of the signals of a sin-cos-resolver. The sin-cos-resolver provides four tracks:

within Modelica.Electrical.Machines.Utilities;
block SinCosEvaluation "Evaluation of the signals of a sin-cos-resolver"
  extends Modelica.Blocks.Icons.Block;
  Blocks.Interfaces.RealInput u[4] "Signal from sin-cos-resolver"
  Blocks.Math.Feedback feedbackCos
  Blocks.Math.Feedback feedbackSin
  SpacePhasors.Blocks.Rotator rotator
  Blocks.Continuous.Integrator integrator(final k=1e6)
  Blocks.Continuous.Der der1
  Blocks.Interfaces.RealOutput phi(unit="rad") "Angle"
  Blocks.Interfaces.RealOutput w(unit="rad/s") "Angular velocity"
equation
  connect(u[1], feedbackCos.u1)
  connect(u[2], feedbackCos.u2)
  connect(u[3], feedbackSin.u1)
  connect(u[4], feedbackSin.u2)
  connect(feedbackCos.y, rotator.u[1])
  connect(feedbackSin.y, rotator.u[2])
  connect(rotator.y[2], integrator.u)
  connect(integrator.y, rotator.angle)
  connect(integrator.y, der1.u)
  connect(integrator.y, phi)
  connect(der1.y, w)
end SinCosEvaluation;


Rheostat which is shortened after a given time. Switched rheostat, used for starting induction motors with slipring rotor:

within Modelica.Electrical.Machines.Utilities;
model SwitchedRheostat "Rheostat which is shortened after a given time"
  parameter Integer m=3 "Number of phases"
  Modelica.Electrical.Polyphase.Interfaces.PositivePlug plug_p(final m=m)
    "To positive rotor plug"
  Modelica.Electrical.Polyphase.Interfaces.NegativePlug plug_n(final m=m)
    "To negative rotor plug"
  parameter SI.Resistance RStart "Starting resistance";
  parameter SI.Time tStart
    "Duration of switching on the starting resistor";
  Modelica.Electrical.Polyphase.Basic.Star star(final m=m)
  Modelica.Electrical.Analog.Basic.Ground ground
  Modelica.Electrical.Polyphase.Ideal.IdealCommutingSwitch
    idealCommutingSwitch(
    final m=m,
    Ron=fill(1e-5, m),
    Goff=fill(1e-5, m))
  Modelica.Electrical.Polyphase.Basic.Resistor rheostat(final m=m, final R=
       fill(RStart, m))
  Modelica.Electrical.Polyphase.Basic.Star starRheostat(final m=m)
  Modelica.Blocks.Sources.BooleanStep booleanStep[m](final startTime=fill(
        tStart, m), final startValue=fill(false, m))
equation
  connect(plug_p, idealCommutingSwitch.plug_p)
  connect(idealCommutingSwitch.plug_n2, plug_n)
  connect(rheostat.plug_p, idealCommutingSwitch.plug_n1)
  connect(idealCommutingSwitch.plug_n2, star.plug_p)
  connect(rheostat.plug_n, starRheostat.plug_p)
  connect(starRheostat.pin_n, star.pin_n)
  connect(star.pin_n, ground.p)
  connect(booleanStep.y, idealCommutingSwitch.control)
end SwitchedRheostat;


Y-D-switch.

within Modelica.Electrical.Machines.Utilities;
model SwitchYD "Y-D-switch"
  parameter Integer m=3 "Number of phases"
  parameter SI.Resistance Ron=1e-5 "Closed switch resistance";
  parameter SI.Conductance Goff=1e-5 "Opened switch conductance";
  parameter SI.Time delayTime(final min=0)=0 "Time delay";
  Modelica.Electrical.Polyphase.Interfaces.PositivePlug plugSupply(final m=
       m) "To grid"
  Modelica.Electrical.Polyphase.Interfaces.PositivePlug plug_sp(final m=m)
    "To positive stator plug"
  Modelica.Electrical.Polyphase.Interfaces.NegativePlug plug_sn(final m=m)
    "To negative stator plug"
  Modelica.Electrical.Polyphase.Basic.Star star(final m=m)
  Modelica.Electrical.Polyphase.Basic.Delta delta(final m=m)
  Polyphase.Ideal.IdealClosingSwitch idealCloser(
    final m=m,
    Ron=fill(Ron, m),
    Goff=fill(Goff, m))
  Modelica.Blocks.Interfaces.BooleanInput control[m]
  Polyphase.Ideal.IdealOpeningSwitch idealOpener(
    final m=m,
    Ron=fill(Ron, m),
    Goff=fill(Goff, m))
  Blocks.Logical.LogicalDelay logicalDelay[m](delayTime=fill(delayTime, m))
equation
  connect(delta.plug_p, plugSupply)
  connect(delta.plug_p, plug_sp)
  connect(idealCloser.plug_p, plug_sn)
  connect(idealCloser.plug_n, delta.plug_n)
  connect(idealOpener.plug_p, plug_sn)
  connect(idealOpener.plug_n, star.plug_p)
  connect(control, logicalDelay.u)
  connect(logicalDelay.y1, idealOpener.control)
  connect(logicalDelay.y2, idealCloser.control)
end SwitchYD;


Y-D-switch with arc.

within Modelica.Electrical.Machines.Utilities;
model SwitchYDwithArc "Y-D-switch with arc"
  parameter Integer m=3 "Number of phases"
  parameter SI.Resistance Ron=1e-5 "Closed switch resistance";
  parameter SI.Conductance Goff=1e-5 "Opened switch conductance";
  parameter SI.Time delayTime(final min=0)=0 "Time delay";
  parameter SI.Voltage V0(start=30) "Initial arc voltage";
  parameter SI.VoltageSlope dVdt(start=10E3) "Arc voltage slope";
  parameter SI.Voltage Vmax(start=60) "Max. arc voltage";
  Modelica.Electrical.Polyphase.Interfaces.PositivePlug plugSupply(final m=
       m) "To grid"
  Modelica.Electrical.Polyphase.Interfaces.PositivePlug plug_sp(final m=m)
    "To positive stator plug"
  Modelica.Electrical.Polyphase.Interfaces.NegativePlug plug_sn(final m=m)
    "To negative stator plug"
  Modelica.Electrical.Polyphase.Basic.Star star(final m=m)
  Modelica.Electrical.Polyphase.Basic.Delta delta(final m=m)
  Polyphase.Ideal.CloserWithArc      idealCloser(
    final m=m,
    Ron=fill(Ron, m),
    Goff=fill(Goff, m),
    V0=fill(V0, m),
    dVdt=fill(dVdt, m),
    Vmax=fill(Vmax, m),
    closerWithArc(off(start=fill(true, m), fixed=fill(true, m))))
  Modelica.Blocks.Interfaces.BooleanInput control[m]
  Polyphase.Ideal.OpenerWithArc      idealOpener(
    final m=m,
    Ron=fill(Ron, m),
    Goff=fill(Goff, m),
    V0=fill(V0, m),
    dVdt=fill(dVdt, m),
    Vmax=fill(Vmax, m),
    openerWithArc(off(start=fill(true, m), fixed=fill(true, m))))
  Blocks.Logical.LogicalDelay logicalDelay[m](delayTime=fill(delayTime, m))
equation
  connect(delta.plug_p, plugSupply)
  connect(delta.plug_p, plug_sp)
  connect(idealCloser.plug_p, plug_sn)
  connect(idealCloser.plug_n, delta.plug_n)
  connect(idealOpener.plug_p, plug_sn)
  connect(idealOpener.plug_n, star.plug_p)
  connect(control, logicalDelay.u)
  connect(logicalDelay.y1, idealOpener.control)
  connect(logicalDelay.y2, idealCloser.control)
end SwitchYDwithArc;


Computes machine parameter from usual datasheet. The parameters of the

synchronous machine model with electrical excitation (and damper) are calculated from parameters
normally given in a technical description, according to the standard EN 60034-4:2008 Appendix C.

within Modelica.Electrical.Machines.Utilities;
record SynchronousMachineData
  "Computes machine parameter from usual datasheet"
  extends Modelica.Icons.Record;
  import Modelica.Constants.pi;
  parameter SI.ApparentPower SNominal(start=30E3)
    "Nominal apparent power";
  parameter SI.Voltage VsNominal(start=100)
    "Nominal stator voltage per phase";
  final parameter SI.Current IsNominal=SNominal/(3*VsNominal)
    "Nominal stator current per phase";
  final parameter SI.Impedance ZReference=VsNominal/IsNominal
    "Reference impedance";
  parameter SI.Frequency fsNominal(start=50)
    "Nominal stator frequency";
  final parameter SI.AngularVelocity omega=2*pi*fsNominal
    "Nominal angular frequency";
  parameter SI.Current IeOpenCircuit(start=10)
    "Open circuit excitation current @ nominal voltage and frequency";
  parameter Real effectiveStatorTurns=1 "Effective number of stator turns";
  final parameter Real turnsRatio=sqrt(2)*VsNominal/(omega*Lmd*
      IeOpenCircuit) "Stator current / excitation current";
  parameter Real x0(start=0.1)
    "Stator stray inductance per phase (approximately zero impedance) [pu]";
  parameter Real xd(start=1.6)
    "Synchronous reactance per phase, d-axis [pu]";
  parameter Real xq(start=1.6)
    "Synchronous reactance per phase, q-axis [pu]";
  parameter Real xdTransient(start=0.1375)
    "Transient reactance per phase, d-axis [pu]";
  parameter Real xdSubtransient(start=0.121428571)
    "Subtransient reactance per phase, d-axis [pu]";
  parameter Real xqSubtransient(start=0.148387097)
    "Subtransient reactance per phase, q-axis [pu]";
  parameter SI.Time Ta(start=0.014171268)
    "Armature time constant";
  parameter SI.Time Td0Transient(start=0.261177343)
    "Open circuit field time constant Td0'";
  parameter SI.Time Td0Subtransient(start=0.006963029)
    "Open circuit subtransient time constant Td0'', d-axis";
  parameter SI.Time Tq0Subtransient(start=0.123345081)
    "Open circuit subtransient time constant Tq0'', q-axis";
  parameter SI.Temperature TsSpecification(start=293.15)
    "Specification temperature of stator resistance"
  parameter SI.Temperature TsRef(start=293.15)
    "Reference temperature of stator resistance"
  parameter Machines.Thermal.LinearTemperatureCoefficient20 alpha20s(start=0)
    "Temperature coefficient of stator resistance at 20 degC"
  parameter SI.Temperature TrSpecification(start=293.15)
    "Specification temperature of (optional) damper cage"
  parameter SI.Temperature TrRef(start=293.15)
    "Reference temperature of damper resistances in d- and q-axis"
  parameter Machines.Thermal.LinearTemperatureCoefficient20 alpha20r(start=0)
    "Temperature coefficient of damper resistances in d- and q-axis"
  parameter SI.Temperature TeSpecification(start=293.15)
    "Specification excitation temperature"
  parameter SI.Temperature TeRef(start=293.15)
    "Reference temperature of excitation resistance"
  parameter Machines.Thermal.LinearTemperatureCoefficient20 alpha20e(start=0)
    "Temperature coefficient of excitation resistance"
  final parameter Real xmd=xd - x0
    "Main field reactance per phase, d-axis [pu]";
  final parameter Real xmq=xq - x0
    "Main field reactance per phase, q-axis [pu]";
  final parameter Real xe=xmd^2/(xd - xdTransient)
    "Excitation reactance [pu]";
  final parameter Real xrd=xmd^2/(xdTransient - xdSubtransient)*(1 - (xmd/
      xe))^2 + xmd^2/xe "Damper reactance per phase, d-axis [pu]";
  final parameter Real xrq=xmq^2/(xq - xqSubtransient)
    "Damper reactance per phase, d-axis [pu]";
  final parameter Real rs=2/(1/xdSubtransient + 1/xqSubtransient)/(omega*Ta)
    "Stator resistance per phase at specification temperature [pu]";
  final parameter Real rrd=(xrd - xmd^2/xe)/(omega*Td0Subtransient)
    "Damper resistance per phase at specification temperature, d-axis [pu]";
  final parameter Real rrq=xrq/(omega*Tq0Subtransient)
    "Damper resistance per phase at specification temperature, q-axis [pu]";
  final parameter Real re=xe/(omega*Td0Transient)
    "Excitation resistance per phase at specification temperature [pu]";
  parameter SI.Resistance Rs=
      Machines.Thermal.convertResistance(
          rs*ZReference,
          TsSpecification,
          alpha20s,
          TsRef) "Stator resistance per phase at TRef"
  parameter SI.Inductance Lssigma=x0*ZReference/omega
    "Stator stray inductance per phase"
  parameter Real ratioCommonStatorLeakage(final min=0, final max=1)=1
    "Ratio of common stray inductance / total stray inductance of stator winding"
  parameter SI.Inductance Lmd=xmd*ZReference/omega
    "Main field inductance per phase in d-axis"
  parameter SI.Inductance Lmq=xmq*ZReference/omega
    "Main field inductance per phase in q-axis"
  parameter SI.Inductance Lrsigmad=(xrd - xmd)*ZReference/
      omega "Damper stray inductance in d-axis"
  parameter SI.Inductance Lrsigmaq=(xrq - xmq)*ZReference/
      omega "Damper stray inductance in q-axis"
  parameter SI.Resistance Rrd=
      Machines.Thermal.convertResistance(
          rrd*ZReference,
          TrSpecification,
          alpha20r,
          TrRef) "Damper resistance in d-axis at TRef"
  parameter SI.Resistance Rrq=
      Machines.Thermal.convertResistance(
          rrq*ZReference,
          TrSpecification,
          alpha20r,
          TrRef) "Damper resistance in q-axis at TRef"
  parameter SI.Resistance Re=3/2*turnsRatio^2*
      Machines.Thermal.convertResistance(
          re*ZReference,
          TeSpecification,
          alpha20e,
          TeRef) "Excitation resistance at TRef"
  parameter Real sigmae=1 - xmd/xe
    "Stray fraction of total excitation inductance"
end SynchronousMachineData;


Terminal box Y/D-connection. This model represents the internal connections of the terminal box of an electric machine.
The parameter terminalConnection is used to switch between star
(terminalConnection = \"Y\") and delta (terminalConnection = \"D\") connection.
The (single-phase) connector starPoint is only available if star connection is selected.

within Modelica.Electrical.Machines.Utilities;
model TerminalBox "Terminal box Y/D-connection"
  parameter Integer m=3 "Number of phases"
  parameter String terminalConnection(start="Y") "Choose \"Y\" for star or \"D\" for delta connection"
  Modelica.Electrical.Polyphase.Interfaces.PositivePlug plug_sp(final m=m)
    "To be connected with positive stator plug"
  Modelica.Electrical.Polyphase.Interfaces.NegativePlug plug_sn(final m=m)
    "To be connected with negative stator plug"
  Modelica.Electrical.Polyphase.Basic.Star star(final m=m) if (
    terminalConnection <> "D")
  Modelica.Electrical.Polyphase.Basic.Delta delta(final m=m) if (
    terminalConnection == "D")
  Modelica.Electrical.Polyphase.Interfaces.PositivePlug plugSupply(final m=
       m) "To be connected with grid"
  Modelica.Electrical.Analog.Interfaces.NegativePin starpoint if (
    terminalConnection <> "D") "Star point"
equation
  connect(plug_sn, star.plug_p)
  connect(plug_sn, delta.plug_n)
  connect(delta.plug_p, plug_sp)
  connect(plug_sp, plugSupply)
  connect(star.pin_n, starpoint)
end TerminalBox;


Transform instantaneous stator inputs to rotor fixed space phasor. The polyphase input values u[m] are transformed to the corresponding space phasor which is rotated to the rotor fixed reference system,
using the provided mechanical rotor angle phi. The output are the resulting d and q components of the space phasor arranged in one vector y[2].

within Modelica.Electrical.Machines.Utilities;
block ToDQ
  "Transform instantaneous stator inputs to rotor fixed space phasor"
  extends Modelica.Blocks.Interfaces.MIMO(final nin=m, final nout=2);
  parameter Integer m(min=1) = 3 "Number of phases"
  parameter Integer p "Number of pole pairs";
  Modelica.Blocks.Math.Gain toGamma(final k=p)
  Modelica.Electrical.Machines.SpacePhasors.Blocks.Rotator rotator
  Modelica.Blocks.Interfaces.RealInput phi(unit="rad")
  Modelica.Electrical.Machines.SpacePhasors.Blocks.ToSpacePhasor toSpacePhasor(final m=m)
equation
  connect(phi, toGamma.u)
  connect(rotator.angle, toGamma.y)
  connect(toSpacePhasor.y, rotator.u)
  connect(u, toSpacePhasor.u)
  connect(rotator.y, y)
end ToDQ;


Voltage-Frequency controller.

within Modelica.Electrical.Machines.Utilities;
block VfController "Voltage-Frequency controller"
  import Modelica.Constants.pi;
  extends Modelica.Blocks.Interfaces.SIMO(u(unit="Hz"), final nout=m);
  parameter Integer m=3 "Number of phases"
  parameter SI.Angle orientation[m]=-
      Modelica.Electrical.Polyphase.Functions.symmetricOrientation(m)
    "Orientation of phases";
  parameter SI.Voltage VNominal "Nominal RMS voltage per phase";
  parameter SI.Frequency fNominal "Nominal frequency";
  parameter SI.Angle BasePhase=0 "Common phase shift";
  parameter Boolean EconomyMode=false "Economy mode: voltage quadratic dependent on frequency"
  output SI.Angle x(start=0, fixed=true) "Integrator state";
  output SI.Voltage amplitude;
protected
  parameter Integer pow=if EconomyMode then 2 else 1
equation
  //amplitude = sqrt(2)*VNominal*min(abs(u)/fNominal, 1);
  amplitude = sqrt(2)*VNominal*(if abs(u) < fNominal then (abs(u)/fNominal)^pow else 1);
  der(x) = 2*pi*u;
  y = amplitude*sin(fill(x + BasePhase, m) + orientation);
end VfController;


Parameter records

within Modelica.Electrical.Machines.Utilities;
package ParameterRecords "Parameter records"
  extends Modelica.Icons.RecordsPackage;

end ParameterRecords;


within Modelica.Electrical;
package Polyphase "Library for electrical components of one or more phases"
  extends Modelica.Icons.Package;
end Polyphase;


Ideal linear electrical capacitors. Contains m capacitors (Modelica.Electrical.Analog.Basic.Capacitor)

within Modelica.Electrical.Polyphase.Basic;
model Capacitor "Ideal linear electrical capacitors"
  extends Interfaces.TwoPlug;
  parameter SI.Capacitance C[m](start=fill(1, m))
    "Capacitance";
  Modelica.Electrical.Analog.Basic.Capacitor capacitor[m](final C=C)
equation
  connect(capacitor.p, plug_p.pin)
  connect(capacitor.n, plug_n.pin)
end Capacitor;


Ideal linear electrical conductors. Contains m conductors (Modelica.Electrical.Analog.Basic.Conductor)

within Modelica.Electrical.Polyphase.Basic;
model Conductor "Ideal linear electrical conductors"
  extends Interfaces.TwoPlug;
  parameter SI.Conductance G[m](start=fill(1, m))
    "Conductances G_ref at temperatures T_ref";
  parameter SI.Temperature T_ref[m]=fill(300.15, m)
    "Reference temperatures";
  parameter SI.LinearTemperatureCoefficient alpha[m]=zeros(m)
    "Temperature coefficients of conductances at reference temperatures";
  extends Polyphase.Interfaces.ConditionalHeatPort(final mh=m, T=T_ref);
  Modelica.Electrical.Analog.Basic.Conductor conductor[m](
    final G=G,
    final T_ref=T_ref,
    final alpha=alpha,
    each final useHeatPort=useHeatPort,
    final T=T)
equation
  connect(plug_p.pin, conductor.p)
  connect(plug_n.pin, conductor.n)
  connect(conductor.heatPort, heatPort)
end Conductor;


Delta (polygon) connection.

within Modelica.Electrical.Polyphase.Basic;
model Delta "Delta (polygon) connection"
  parameter Integer m(final min=2) = 3 "Number of phases"
  Interfaces.PositivePlug plug_p(final m=m)
  Interfaces.NegativePlug plug_n(final m=m)

equation
  for j in 1:m-1 loop
    connect(plug_n.pin[j], plug_p.pin[j + 1]);
  end for;
  connect(plug_n.pin[m], plug_p.pin[1]);
end Delta;


Ideal linear electrical inductors. Contains m inductors (Modelica.Electrical.Analog.Basic.Inductor)

within Modelica.Electrical.Polyphase.Basic;
model Inductor "Ideal linear electrical inductors"
  extends Interfaces.TwoPlug;
  parameter SI.Inductance L[m](start=fill(1, m)) "Inductance";
  Modelica.Electrical.Analog.Basic.Inductor inductor[m](final L=L)
equation
  connect(inductor.p, plug_p.pin)
  connect(inductor.n, plug_n.pin)
end Inductor;


Delta (polygon) connection of polyphase systems consisting of multiple base systems. Delta (polygon) connection of a polyphase circuit consisting of multiple base systems (see
polyphase guidelines).

within Modelica.Electrical.Polyphase.Basic;
model MultiDelta
  "Delta (polygon) connection of polyphase systems consisting of multiple base systems"
  import Modelica.Electrical.Polyphase.Functions.numberOfSymmetricBaseSystems;
  parameter Integer m(final min=2) = 3 "Number of phases"
  parameter Integer kPolygon(final min=1)=1 "Alternative of polygon";
  final parameter Integer mSystems=numberOfSymmetricBaseSystems(m) "Number of base systems";
  final parameter Integer mBasic=integer(m/mSystems) "Phase number of base systems";
  Polyphase.Interfaces.PositivePlug plug_p(final m=m)
  Polyphase.Interfaces.NegativePlug plug_n(final m=m)
protected
  parameter Integer kP=if (mBasic<=2 or kPolygon<1 or kPolygon>integer(mBasic - 1)/2) then 1 else kPolygon;
equation
  for k in 1:mSystems loop
    for j in 1:(mBasic -kP) loop
      connect(plug_n.pin[(k - 1)*mBasic + j], plug_p.pin[(k - 1)*mBasic + j + kP]);
    end for;
    for j in (mBasic - kP + 1):mBasic loop
      connect(plug_n.pin[(k - 1)*mBasic + j], plug_p.pin[(k - 2)*mBasic + j + kP]);
    end for;
  end for;
end MultiDelta;


Star connection of polyphase systems consisting of multiple base systems. Star (wye) connection of a polyphase circuit consisting of multiple base systems (see
polyphase guidelines). The potentials at the star points are all equal.

within Modelica.Electrical.Polyphase.Basic;
model MultiStar
  "Star connection of polyphase systems consisting of multiple base systems"
  import Modelica.Electrical.Polyphase.Functions.numberOfSymmetricBaseSystems;
  parameter Integer m(final min=1) = 3 "Number of phases"
  final parameter Integer mSystems=numberOfSymmetricBaseSystems(m) "Number of base systems";
  final parameter Integer mBasic=integer(m/mSystems) "Phase number of base systems";
  Polyphase.Interfaces.PositivePlug plug_p(final m=m)
  Polyphase.Interfaces.NegativePlug starpoints(final m=mSystems)
equation
  for k in 1:mSystems loop
    for j in 1:mBasic loop
      connect(plug_p.pin[(k - 1)*mBasic + j], starpoints.pin[k]);
    end for;
  end for;
end MultiStar;


Resistance connection of star points. Multi star points are connected by resistors. This model is required to operate polyphase systems with even phase numbers to avoid ideal connections of start points of base systems; see
polyphase guidelines.

within Modelica.Electrical.Polyphase.Basic;
model MultiStarResistance "Resistance connection of star points"
  import Modelica.Electrical.Polyphase.Functions.numberOfSymmetricBaseSystems;
  parameter Integer m(final min=2) = 3 "Number of phases"
  final parameter Integer mBasic=numberOfSymmetricBaseSystems(m) "Number of symmetric base systems";
  parameter SI.Resistance R=1e6 "Insulation resistance between base systems";
  Polyphase.Interfaces.PositivePlug plug(m=m)
  Polyphase.Basic.MultiStar multiStar(m=m)
  Polyphase.Basic.Resistor resistor(m=mBasic, R=fill(R, mBasic))
  Polyphase.Basic.Star star(m=mBasic)
  Modelica.Electrical.Analog.Interfaces.NegativePin pin
equation
  connect(plug, multiStar.plug_p)
  connect(multiStar.starpoints, resistor.plug_p)
  connect(resistor.plug_n, star.plug_p)
  connect(star.pin_n, pin)
end MultiStarResistance;


Linear mutual inductor. Model of a polyphase inductor providing a mutual inductance matrix model.

within Modelica.Electrical.Polyphase.Basic;
model MutualInductor "Linear mutual inductor"
  extends Polyphase.Interfaces.OnePort;
  parameter Real epsilon=1e-9 "Relative accuracy tolerance of matrix symmetry";
  parameter SI.Inductance L[m, m] "Mutual inductance matrix";
initial equation
  if abs(Modelica.Math.Matrices.det(L)) < epsilon then
    Modelica.Utilities.Streams.print("Warning: mutual inductance matrix singular!");
  end if;
equation
  assert(sum(abs(L - transpose(L))) < epsilon*sum(abs(L)),"Mutual inductance matrix is not symmetric");
  for j in 1:m loop
    v[j] = sum(L[j, k]*der(i[k]) for k in 1:m);
  end for;
end MutualInductor;


within Modelica.Electrical.Polyphase;
package Basic "Basic components for electrical polyphase models"
  extends Modelica.Icons.Package;
end Basic;


Connect all (negative) Pins. Connects all pins of plug_n to the pin array pin_n.

within Modelica.Electrical.Polyphase.Basic;
model PlugToPins_n "Connect all (negative) Pins"
  parameter Integer m(final min=1) = 3 "Number of phases"
  Interfaces.NegativePlug plug_n(final m=m)
  Modelica.Electrical.Analog.Interfaces.NegativePin pin_n[m]
equation
  pin_n.v = plug_n.pin.v;
  plug_n.pin.i = -pin_n.i;
end PlugToPins_n;


Connect all (positive) Pins. Connects all pins of plug_p to the pin array pin_p.

within Modelica.Electrical.Polyphase.Basic;
model PlugToPins_p "Connect all (positive) Pins"
  parameter Integer m(final min=1) = 3 "Number of phases"
  Interfaces.PositivePlug plug_p(final m=m)
  Modelica.Electrical.Analog.Interfaces.PositivePin pin_p[m]
equation
  pin_p.v = plug_p.pin.v;
  plug_p.pin.i = -pin_p.i;
end PlugToPins_p;


Connect one (negative) Pin. Connects pin k of plug_n to pin_n, leaving the other pins of plug_n unconnected.

within Modelica.Electrical.Polyphase.Basic;
model PlugToPin_n "Connect one (negative) Pin"
  parameter Integer m(final min=1) = 3 "Number of phases"
  parameter Integer k(
    final min=1,
    final max=m,
    start=1) "Phase index"
  Interfaces.NegativePlug plug_n(final m=m)
  Modelica.Electrical.Analog.Interfaces.NegativePin pin_n
equation
  pin_n.v = plug_n.pin[k].v;
  for j in 1:m loop
    plug_n.pin[j].i = if j == k then -pin_n.i else 0;
  end for;
end PlugToPin_n;


Connect one (positive) Pin. Connects pin k of plug_p to pin_p, leaving the other pins of plug_p unconnected.

within Modelica.Electrical.Polyphase.Basic;
model PlugToPin_p "Connect one (positive) Pin"
  parameter Integer m(final min=1) = 3 "Number of phases"
  parameter Integer k(
    final min=1,
    final max=m,
    start=1) "Phase index"
  Interfaces.PositivePlug plug_p(final m=m)
  Modelica.Electrical.Analog.Interfaces.PositivePin pin_p
equation
  pin_p.v = plug_p.pin[k].v;
  for j in 1:m loop
    plug_p.pin[j].i = if j == k then -pin_p.i else 0;
  end for;
end PlugToPin_p;


Ideal linear electrical resistors. Contains m resistors (Modelica.Electrical.Analog.Basic.Resistor)

within Modelica.Electrical.Polyphase.Basic;
model Resistor "Ideal linear electrical resistors"
  extends Interfaces.TwoPlug;
  parameter SI.Resistance R[m](start=fill(1, m))
    "Resistances R_ref at temperatures T_ref";
  parameter SI.Temperature T_ref[m]=fill(300.15, m)
    "Reference temperatures";
  parameter SI.LinearTemperatureCoefficient alpha[m]=zeros(m)
    "Temperature coefficients of resistances at reference temperatures";
  extends Polyphase.Interfaces.ConditionalHeatPort(final mh=m, T=T_ref);
  Modelica.Electrical.Analog.Basic.Resistor resistor[m](
    final R=R,
    final T_ref=T_ref,
    final alpha=alpha,
    each final useHeatPort=useHeatPort,
    final T=T)
equation
  connect(resistor.p, plug_p.pin)
  connect(resistor.n, plug_n.pin)
  connect(resistor.heatPort, heatPort)
end Resistor;


Simple model of inductors with saturation. Contains m saturating inductors (Modelica.Electrical.Analog.Basic.SaturatingInductor)

within Modelica.Electrical.Polyphase.Basic;
model SaturatingInductor "Simple model of inductors with saturation"
  extends Interfaces.TwoPlug;
  parameter SI.Current Inom[m](start=fill(1, m))
    "Nominal current";
  parameter SI.Inductance Lnom[m](start=fill(1, m))
    "Nominal inductance at Nominal current";
  parameter SI.Inductance Lzer[m](start={2*Lnom[j] for j in 1
        :m}) "Inductance near current=0";
  parameter SI.Inductance Linf[m](start={Lnom[j]/2 for j in 1
        :m}) "Inductance at large currents";
  Modelica.Electrical.Analog.Basic.SaturatingInductor saturatingInductor[m](
    final Inom=Inom,
    final Lnom=Lnom,
    final Lzer=Lzer,
    final Linf=Linf)
equation
  connect(saturatingInductor.p, plug_p.pin)
  connect(saturatingInductor.n, plug_n.pin)
end SaturatingInductor;


Split m phases to subsystems. Splits the m phases in plug_p into subsystems, i.e., mSystems plugs with mBasic pins according to
phase orientation described in the users guide.

within Modelica.Electrical.Polyphase.Basic;
model SplitToSubsystems "Split m phases to subsystems"
  import Modelica.Electrical.Polyphase.Functions.numberOfSymmetricBaseSystems;
  parameter Integer m(min=1) = 3 "Number of phases"
  final parameter Integer mSystems=numberOfSymmetricBaseSystems(m)
    "Number of base systems";
  final parameter Integer mBasic=integer(m/mSystems)
    "Phase number of base systems";
  Interfaces.PositivePlug plug_p(final m=m)
    "Positive polyphase electrical plug with m pins"
  Interfaces.NegativePlug plugs_n[mSystems](each final m=mBasic)
    "mSystems negative polyphase electrical plugs with mBasic pins each"
equation
  for k in 1:mSystems loop
    for j in 1:mBasic loop
      connect(plug_p.pin[(k - 1)*mBasic + j], plugs_n[k].pin[j]);
    end for;
  end for;
end SplitToSubsystems;


Star-connection.

within Modelica.Electrical.Polyphase.Basic;
model Star "Star-connection"
  parameter Integer m(final min=1) = 3 "Number of phases"
  Interfaces.PositivePlug plug_p(final m=m)
  Modelica.Electrical.Analog.Interfaces.NegativePin pin_n

equation
  for j in 1:m loop
    connect(plug_p.pin[j], pin_n);
  end for;
end Star;


Polyphase Transformer. Contains m transformers (Modelica.Electrical.Analog.Basic.Transformer)

within Modelica.Electrical.Polyphase.Basic;
model Transformer "Polyphase Transformer"
  extends Interfaces.FourPlug;
  parameter SI.Inductance L1[m](start=fill(1, m))
    "Primary inductance";
  parameter SI.Inductance L2[m](start=fill(1, m))
    "Secondary inductance";
  parameter SI.Inductance M[m](start=fill(1, m))
    "Coupling inductance";
  Modelica.Electrical.Analog.Basic.Transformer transformer[m](
    final L1=L1,
    final L2=L2,
    final M=M)
equation

  connect(plug_p1.pin, transformer.p1)
  connect(plug_p2.pin, transformer.p2)
  connect(plug_n1.pin, transformer.n1)
  connect(plug_n2.pin, transformer.n2)
end Transformer;


Ideal linear electrical capacitors with variable capacitance. Contains m variable capacitors (Modelica.Electrical.Analog.Basic.VariableCapacitor)

within Modelica.Electrical.Polyphase.Basic;
model VariableCapacitor
  "Ideal linear electrical capacitors with variable capacitance"
  extends Interfaces.TwoPlug;
  parameter SI.Capacitance Cmin[m]=fill(Modelica.Constants.eps,
      m) "Minimum capacitance";
  Modelica.Blocks.Interfaces.RealInput C[m](each unit="F")
  Modelica.Electrical.Analog.Basic.VariableCapacitor variableCapacitor[m](
      final Cmin=Cmin)
equation
  connect(variableCapacitor.p, plug_p.pin)
  connect(variableCapacitor.n, plug_n.pin)
  connect(C, variableCapacitor.C)
end VariableCapacitor;


Ideal linear electrical conductors with variable conductance. Contains m variable conductors (Modelica.Electrical.Analog.Basic.VariableConductor)

within Modelica.Electrical.Polyphase.Basic;
model VariableConductor
  "Ideal linear electrical conductors with variable conductance"
  extends Interfaces.TwoPlug;
  parameter SI.Temperature T_ref[m]=fill(300.15, m)
    "Reference temperatures";
  parameter SI.LinearTemperatureCoefficient alpha[m]=zeros(m)
    "Temperature coefficients of conductances at reference temperatures";
  extends Polyphase.Interfaces.ConditionalHeatPort(final mh=m, T=T_ref);
  Modelica.Blocks.Interfaces.RealInput G[m](each unit="S")
  Modelica.Electrical.Analog.Basic.VariableConductor variableConductor[m](
    final T_ref=T_ref,
    final alpha=alpha,
    each final useHeatPort=useHeatPort,
    final T=T)
equation
  connect(variableConductor.p, plug_p.pin)
  connect(variableConductor.n, plug_n.pin)
  connect(G, variableConductor.G)
  connect(variableConductor.heatPort, heatPort)
end VariableConductor;


Ideal linear electrical inductors with variable inductance. Contains m variable inductors (Modelica.Electrical.Analog.Basic.VariableInductor)

within Modelica.Electrical.Polyphase.Basic;
model VariableInductor
  "Ideal linear electrical inductors with variable inductance"
  extends Interfaces.TwoPlug;
  parameter SI.Inductance Lmin[m]=fill(Modelica.Constants.eps,
      m) "Minimum inductance";
  Modelica.Blocks.Interfaces.RealInput L[m](each unit="H")
  Modelica.Electrical.Analog.Basic.VariableInductor variableInductor[m](
      final Lmin=Lmin)

equation
  connect(variableInductor.p, plug_p.pin)
  connect(variableInductor.n, plug_n.pin)
  connect(L, variableInductor.L)
end VariableInductor;


Ideal linear electrical resistors with variable resistance. Contains m variable resistors (Modelica.Electrical.Analog.Basic.VariableResistor)

within Modelica.Electrical.Polyphase.Basic;
model VariableResistor
  "Ideal linear electrical resistors with variable resistance"
  extends Interfaces.TwoPlug;
  parameter SI.Temperature T_ref[m]=fill(300.15, m)
    "Reference temperatures";
  parameter SI.LinearTemperatureCoefficient alpha[m]=zeros(m)
    "Temperature coefficients of resistances at reference temperatures";
  extends Polyphase.Interfaces.ConditionalHeatPort(final mh=m, T=T_ref);
  Modelica.Blocks.Interfaces.RealInput R[m](each unit="Ohm")
  Modelica.Electrical.Analog.Basic.VariableResistor variableResistor[m](
    final T_ref=T_ref,
    final alpha=alpha,
    each final useHeatPort=useHeatPort,
    final T=T)
equation
  connect(variableResistor.p, plug_p.pin)
  connect(variableResistor.n, plug_n.pin)
  connect(R, variableResistor.R)
  connect(variableResistor.heatPort, heatPort)
end VariableResistor;


Linear zero sequence inductor. Model of a polyphase zero sequence inductor.

within Modelica.Electrical.Polyphase.Basic;
model ZeroInductor "Linear zero sequence inductor"
  extends Polyphase.Interfaces.OnePort;
  parameter SI.Inductance Lzero "Zero sequence inductance";
  SI.Current i0;
  SI.Voltage v0;
equation
  m*i0 = sum(i);
  v0 = Lzero*der(i0);
  v = fill(v0, m);
end ZeroInductor;


Blocks for polyphase systems

within Modelica.Electrical.Polyphase;
package Blocks "Blocks for polyphase systems"
  extends Modelica.Icons.Package;
end Blocks;


Number of phases. This block determines the continuous quasi RMS value of a polyphase system, representing an equivalent RMS vector or phasor. If the waveform of the input deviates from a sine curve, the output of the sensor will not be exactly the average RMS value.

within Modelica.Electrical.Polyphase.Blocks;
block QuasiRMS
  extends Modelica.Blocks.Interfaces.SO;
  parameter Integer m(min=2) = 3 "Number of phases"
  Modelica.Blocks.Interfaces.RealInput u[m]
equation
  y = Polyphase.Functions.quasiRMS(u);
end QuasiRMS;


Polyphase test examples

within Modelica.Electrical.Polyphase;
package Examples "Polyphase test examples"
  extends Modelica.Icons.ExamplesPackage;
end Examples;


Demonstrate a polyphase diode rectifier. This example demonstrates a polyphase system with a rectifier per subsystem.

within Modelica.Electrical.Polyphase.Examples;
model PolyphaseRectifier "Demonstrate a polyphase diode rectifier"
  extends Icons.Example;
  parameter Utilities.PolyphaseRectifierData data
  Sources.SineVoltage sineVoltage(
    m=data.m,
    V=sqrt(2)*fill(data.VrmsY, data.m),
    f=fill(data.f, data.m))
  Basic.MultiStarResistance multiStar(m=data.m, R=data.RGnd)
  Analog.Basic.Resistor resistor2ground(R=data.RGnd)
  Analog.Basic.Ground groundAC
  Utilities.AnalysatorAC analysatorAC(m=data.m, f=data.f)
  Basic.SplitToSubsystems splitToSubsystems(m=data.m)
  Ideal.IdealDiode diode1[data.mSystems](
    each m=data.mBasic,
    each Ron=fill(1e-6, data.mBasic),
    each Goff=fill(1e-6, data.mBasic),
    each Vknee=fill(0, data.mBasic))
  Ideal.IdealDiode diode2[data.mSystems](
    each m=data.mBasic,
    each Ron=fill(1e-6, data.mBasic),
    each Goff=fill(1e-6, data.mBasic),
    each Vknee=fill(0, data.mBasic))
  Basic.Star star1[data.mSystems](each m=data.mBasic)
  Basic.Star star2[data.mSystems](each m=data.mBasic)
  Analog.Basic.Resistor resistorDC1[data.mSystems](each R=data.RDC/2)
  Analog.Basic.Inductor inductorDC1[data.mSystems](each i(fixed=true, start=0),
      each L=data.LDC/2)
  Utilities.AnalysatorDC analysatorDC[data.mSystems](each f=data.f)
  Analog.Basic.Resistor resistorDC2[data.mSystems](each R=data.RDC/2)
  Analog.Basic.Inductor inductorDC2[data.mSystems](each i(fixed=true, start=0),
      each L=data.LDC/2)
  Utilities.AnalysatorDC analysatorDCload(f=data.f)
  Analog.Basic.Resistor loadResistor1(R=data.RLoad/2)
  Analog.Basic.Resistor loadResistor2(R=data.RLoad/2)
  Analog.Basic.Ground groundDC
equation
  for p in 1:data.Par loop
    for s in 1:data.Ser - 1 loop
      connect(inductorDC2[(p - 1)*data.Ser + s].p, inductorDC1[(p - 1)*data.Ser + s + 1].n);
    end for;
    connect(inductorDC1[(p - 1)*data.Ser + 1].n, analysatorDCload.p);
    connect(loadResistor2.n, inductorDC2[p*data.Ser].p);
  end for;
  connect(sineVoltage.plug_n, multiStar.plug)
  connect(star1.plug_p, diode1.plug_n)
  connect(diode2.plug_p, star2.plug_p)
  connect(loadResistor1.n, groundDC.p)
  connect(groundDC.p, loadResistor2.p)
  connect(multiStar.pin, resistor2ground.p)
  connect(resistor2ground.n, groundAC.p)
  connect(diode1.plug_p, diode2.plug_n)
  connect(analysatorAC.plug_p, sineVoltage.plug_p)
  connect(analysatorAC.plug_nv, multiStar.plug)
  connect(analysatorDCload.n, loadResistor1.p)
  connect(loadResistor2.n, analysatorDCload.nv)
  connect(analysatorAC.plug_n, splitToSubsystems.plug_p)
  connect(splitToSubsystems.plugs_n, diode1.plug_p)
  connect(star1.pin_n, analysatorDC.p)
  connect(analysatorDC.n, resistorDC1.p)
  connect(resistorDC1.n, inductorDC1.p)
  connect(star2.pin_n, resistorDC2.n)
  connect(resistorDC2.p, inductorDC2.n)
  connect(star2.pin_n, analysatorDC.nv)
end PolyphaseRectifier;