Output the input signal filtered with an n-th order filter with critical damping. This block defines the transfer function between the
input u and the output y
as an n-th order filter with critical damping
characteristics and cut-off frequency f. It is
a slightly simplified version of the Modelica.Blocks.Continuous.CriticalDamping block.
It doesn't provide the same initialization capabilities as the continuous block, since the initialization of
clocked partitions is currently performed differently to the continuous time partitions.

within Modelica.Clocked.Examples.Systems.Utilities.ComponentsMixingUnit;
block CriticalDamping
  "Output the input signal filtered with an n-th order filter with critical damping"

  import Modelica.Blocks.Types.Init;
  extends Modelica.Blocks.Interfaces.SISO;

  parameter Integer n=2 "Order of filter";
  parameter SI.Frequency f(start=1) "Cut-off frequency";
  parameter Boolean normalized = true
    "= true, if amplitude at f_cut is 3 dB, otherwise unmodified filter";
  output Real x[n](start=zeros(n)) "Filter states";
protected
  parameter Real alpha=if normalized then sqrt(2^(1/n) - 1) else 1.0
    "Frequency correction factor for normalized filter";
  parameter Real w=2*Modelica.Constants.pi*f/alpha;
equation
  der(x[1]) = (u - x[1])*w;
  for i in 2:n loop
    der(x[i]) = (x[i - 1] - x[i])*w;
  end for;
  y = x[n];
end CriticalDamping;


Block to determine the minimum filter order.

within Modelica.Clocked.Examples.Systems.Utilities.ComponentsMixingUnit;
model FilterOrder "Block to determine the minimum filter order"
   extends Modelica.Icons.Example;
  MixingUnit mixingUnit
  Modelica.Blocks.Math.InverseBlockConstraints
    inverseBlockConstraints
  Modelica.Blocks.Interfaces.RealInput c_ref
equation
  connect(inverseBlockConstraints.u1, c_ref)
  connect(mixingUnit.T_c, inverseBlockConstraints.y2)
  connect(mixingUnit.c, inverseBlockConstraints.u2)
end FilterOrder;


Mixing unit demo from Foellinger, Nichtlineare Regelungen II, p. 280.

within Modelica.Clocked.Examples.Systems.Utilities.ComponentsMixingUnit;
model MixingUnit
  "Mixing unit demo from Foellinger, Nichtlineare Regelungen II, p. 280"

  Modelica.Blocks.Interfaces.RealInput T_c(unit="K")
    "Cooling temperature"
  Modelica.Blocks.Interfaces.RealOutput c(unit="mol/l") "Concentration"
  Modelica.Blocks.Interfaces.RealOutput T(unit="K")
    "Temperature in mixing unit"
  parameter Real c0(unit="mol/l") = 0.848 "Nominal concentration";
  parameter SI.Temperature T0 = 308.5 "Nominal temperature";
  parameter Real a1 = 0.2674 "Process parameter (see references in help)";
  parameter Real a21 = 1.815 "Process parameter (see references in help)";
  parameter Real a22 = 0.4682 "Process parameter (see references in help)";
  parameter Real b = 1.5476 "Process parameter (see references in help)";
  parameter Real k0 = 1.05e14 "Process parameter (see references in help)";
  parameter Real eps = 34.2894 "Process parameter (see references in help)";
  Real gamma "Reaction speed";
protected
  parameter SI.Time tau0 = 60;
  parameter Real wk0 = k0/c0;
  parameter Real weps = eps*T0;
  parameter Real wa11 = a1/tau0;
  parameter Real wa12 = c0/tau0;
  parameter Real wa13 = c0*a1/tau0;
  parameter Real wa21 = a21/tau0;
  parameter Real wa22 = a22*T0/tau0;
  parameter Real wa23 = T0*(a21 - b)/tau0;
  parameter Real wb = b/tau0;
equation
  gamma = c*wk0*exp( -weps/T);
  der(c) = -wa11*c - wa12*gamma + wa13;
  der(T) = -wa21*T + wa22*gamma + wa23 + wb*T_c;
end MixingUnit;


Simple example of a mixing unit where a (continuous) nonlinear inverse plant model is used as feedforward controller.

within Modelica.Clocked.Examples.Systems.Utilities.ComponentsMixingUnit;
model MixingUnitWithContinuousControl "Simple example of a mixing unit where a (continuous) nonlinear inverse plant model is used as feedforward controller"
  extends Modelica.Icons.Example;

  parameter SI.Frequency freq = 1/300 "Critical frequency of filter";
  parameter Real c0(unit="mol/l") = 0.848 "Nominal concentration";
  parameter SI.Temperature T0 = 308.5 "Nominal temperature";
  parameter Real a1_inv =  0.2674 "Process parameter of inverse plant model (see references in help)";
  parameter Real a21_inv = 1.815 "Process parameter of inverse plant model (see references in help)";
  parameter Real a22_inv = 0.4682 "Process parameter of inverse plant model (see references in help)";
  parameter Real b_inv =   1.5476 "Process parameter of inverse plant model (see references in help)";
  parameter Real k0_inv =  1.05e14 "Process parameter of inverse plant model (see references in help)";
  parameter Real eps = 34.2894 "Process parameter (see references in help)";

  parameter Real x10 = 0.42 "Relative offset between nominal concentration and initial concentration";
  parameter Real x20 = 0.01 "Relative offset between nominal temperature and initial temperature";
  parameter Real u0 = -0.0224 "Relative offset between initial cooling temperature and nominal temperature";

  final parameter Real c_start(unit="mol/l") = c0*(1-x10) "Initial concentration";
  final parameter SI.Temperature T_start = T0*(1+x20) "Initial temperature";
  final parameter Real c_high_start(unit="mol/l") = c0*(1-0.72) "Reference concentration";
  final parameter Real T_c_start = T0*(1+u0) "Initial cooling temperature";

  parameter Real pro=1.1
    "Deviations of plant to inverse plant parameters";
  final parameter Real a1=a1_inv*pro "Process parameter of plant model (see references in help)";
  final parameter Real a21=a21_inv*pro "Process parameter of plant model (see references in help)";
  final parameter Real a22=a22_inv*pro "Process parameter of plant model (see references in help)";
  final parameter Real b=b_inv*pro "Process parameter of plant model (see references in help)";
  final parameter Real k0=k0_inv*pro "Process parameter of plant model (see references in help)";

  Utilities.ComponentsMixingUnit.MixingUnit invMixingUnit(
    c0= c0,
    T0= T0,
    a1= a1_inv,
    a21=a21_inv,
    a22=a22_inv,
    b = b_inv,
    k0= k0_inv,
    eps=eps,
    c(start=c_start, fixed=true),
    T(start=T_start,
      fixed=true,
      stateSelect=StateSelect.always),
    T_c(start=T_c_start, fixed=true))
  Modelica.Blocks.Math.Add add
  Modelica.Blocks.Math.InverseBlockConstraints inverseBlockConstraints
  Modelica.Blocks.Continuous.CriticalDamping filter(f=freq, n=3,
    normalized=false)
  Utilities.ComponentsMixingUnit.MixingUnit   mixingUnit(
    c(start=c_start, fixed=true),
    T(start=T_start, fixed=true),
    c0= c0,
    T0= T0,
    a1= a1,
    a21=a21,
    a22=a22,
    b = b,
    k0= k0,
    eps=eps)
  Modelica.Blocks.Math.Feedback feedback
  Modelica.Blocks.Sources.Step step(height=c_high_start - c_start, offset=
        c_start)
  Modelica.Blocks.Math.Gain gain(k=20)
equation
  connect(step.y, filter.u)
  connect(mixingUnit.T, feedback.u2)
  connect(feedback.y, gain.u)
  connect(add.y, mixingUnit.T_c)
  connect(gain.y, add.u2)
  connect(inverseBlockConstraints.y2, invMixingUnit.T_c)
  connect(inverseBlockConstraints.y1, add.u1)
  connect(filter.y, inverseBlockConstraints.u1)
  connect(invMixingUnit.T, feedback.u1)
  connect(invMixingUnit.c, inverseBlockConstraints.u2)
end MixingUnitWithContinuousControl;


within Modelica.Clocked.Examples.Systems.Utilities;
package ComponentsMixingUnit "Utilities for the mixing unit control example"
  extends Modelica.Icons.Package;

end ComponentsMixingUnit;


Integrates the air mass flow into a cylinder. After the charge for one
   cylinder is complete, resets the mass to 0..

within Modelica.Clocked.Examples.Systems.Utilities.ComponentsThrottleControl;
block CylinderAirCharge
  "Integrates the air mass flow into a cylinder. After the charge for one
   cylinder is complete, resets the mass to 0."
  extends Modelica.Blocks.Icons.Block;

  Modelica.Blocks.Interfaces.RealOutput m_a(unit="g")
    "Mass of an cylinder air charge (g)"
  Modelica.Blocks.Interfaces.RealInput m_ao_der(unit="g/s")
    "Mass flow rate of air out of manifold (g/s)"
  ClockSignals.Interfaces.ClockInput clock
  Modelica.Blocks.Math.Add add(k2 = -1)
  RealSignals.Sampler.SampleClocked sample1
  RealSignals.Sampler.Hold hold1
  Modelica.Blocks.Continuous.Integrator integrator

equation
  connect(add.y, m_a)
  connect(clock, sample1.clock)
  connect(sample1.y, hold1.u)
  connect(hold1.y, add.u2)
  connect(m_ao_der, integrator.u)
  connect(integrator.y, add.u1)
  connect(integrator.y, sample1.u)
end CylinderAirCharge;


Internal combustion engine..

within Modelica.Clocked.Examples.Systems.Utilities.ComponentsThrottleControl;
model Engine "Internal combustion engine."
  Modelica.Blocks.Interfaces.RealInput Theta(unit="deg")
    "Throttle angle (deg)"
  ThrottleBody throttleBody
  IntakeManifold intakeManifold
  TorqueGeneration torqueGeneration
  ClockSignals.Clocks.Rotational.FixedRotationalClock crankshaftPositionEvent(
    trigger_interval = 3.1415926535898)
  InductionToPowerDelay inductionToPowerDelay
  CylinderAirCharge cylinderAirCharge
  Modelica.Mechanics.Rotational.Sources.Torque torque(useSupport = false)
  Modelica.Mechanics.Rotational.Components.Inertia inertia(
    J = 0.14,
    w(fixed = true, start = 209),
    phi(fixed = true, start = 0))
  Modelica.Mechanics.Rotational.Sensors.SpeedSensor speedSensor
  Modelica.Mechanics.Rotational.Interfaces.Flange_b flange_b
  Modelica.Mechanics.Rotational.Sensors.AngleSensor angleSensor
  ClockSignals.Interfaces.ClockOutput synchronize

equation
  connect(Theta, throttleBody.Theta)
  connect(throttleBody.m_ai_der, intakeManifold.m_ai_der)
  connect(intakeManifold.P_m, throttleBody.Pm)
  connect(inductionToPowerDelay.m_a_delayed, torqueGeneration.m_a)
  connect(cylinderAirCharge.m_a, inductionToPowerDelay.m_a)
  connect(intakeManifold.m_ao_der, cylinderAirCharge.m_ao_der)
  connect(torque.tau, torqueGeneration.T_torque_e)
  connect(torque.flange, inertia.flange_a)
  connect(inertia.flange_b, speedSensor.flange)
  connect(inertia.flange_b, flange_b)
  connect(torqueGeneration.N, speedSensor.w)
  connect(intakeManifold.N, speedSensor.w)
  connect(angleSensor.flange, inertia.flange_b)
  connect(angleSensor.phi, crankshaftPositionEvent.angle)
  connect(crankshaftPositionEvent.y, inductionToPowerDelay.clock)
  connect(crankshaftPositionEvent.y, cylinderAirCharge.clock)
  connect(crankshaftPositionEvent.y, synchronize)
end Engine;


Accounts for the induction-to-power stroke lag..

within Modelica.Clocked.Examples.Systems.Utilities.ComponentsThrottleControl;
block InductionToPowerDelay
  "Accounts for the induction-to-power stroke lag."
  extends Modelica.Blocks.Icons.Block;

  Modelica.Blocks.Interfaces.RealInput m_a(unit = "g")
    "Mass of cylinder air charge (g)"
  Modelica.Blocks.Interfaces.RealOutput m_a_delayed(unit = "g")
    "180deg delayed mass of cylinder air charge (g)"
  ClockSignals.Interfaces.ClockInput clock
  RealSignals.Sampler.SampleClocked sample1
  RealSignals.Sampler.Hold hold1(y_start=0.152)
  RealSignals.NonPeriodic.FractionalDelay delay(
    shift = 1,
    final resolution = 1 "Prepare model for usage in event-clock partitions")

equation
  connect(clock, sample1.clock)
  connect(m_a, sample1.u)
  connect(hold1.y, m_a_delayed)
  connect(sample1.y, delay.u)
  connect(delay.y, hold1.u)
end InductionToPowerDelay;


Dynamics of the intake manifold.

within Modelica.Clocked.Examples.Systems.Utilities.ComponentsThrottleControl;
block IntakeManifold "Dynamics of the intake manifold"
  extends Modelica.Blocks.Icons.Block;

  parameter Real RTVmRatio = 0.41328
    "RT/V_m";
  parameter Modelica.Units.NonSI.Pressure_bar P_0 = 0.543
    "Initial value for P_m, (bar)";
  Modelica.Blocks.Interfaces.RealInput m_ai_der(unit="g/s")
    "Mass flow rate of air into manifold (g/s)"
  Modelica.Blocks.Interfaces.RealInput N(unit="rad/s") "Engine speed (rad/sec)"
  Modelica.Blocks.Interfaces.RealOutput m_ao_der(unit="g/s")
    "Mass flow rate of air out of manifold (g/s)"
  Modelica.Blocks.Interfaces.RealOutput P_m(start=P_0, fixed=true, unit="bar")
    "Intake manifold pressure (bar)"
equation
  der(P_m) = RTVmRatio*(m_ai_der - m_ao_der);
  m_ao_der = -0.366 + 0.08979*N*P_m - 0.0337*N*P_m^2 + 0.0001*N^2*P_m;
end IntakeManifold;


within Modelica.Clocked.Examples.Systems.Utilities;
package ComponentsThrottleControl "Utilities for the engine throttle control example"
  extends Modelica.Icons.Package;

end ComponentsThrottleControl;


Discrete control of crankshaft speed by throttle actuation.

within Modelica.Clocked.Examples.Systems.Utilities.ComponentsThrottleControl;
block SpeedControl
  "Discrete control of crankshaft speed by throttle actuation"

  parameter Real k_p = 0.0614 "Proportional gain";
  parameter Real k_I = 0.0723 "Integral gain";
  Modelica.Blocks.Interfaces.RealInput N_des(unit="rad/s", start=0) "Desired speed, (rad/s)"
  Modelica.Blocks.Interfaces.RealInput N(unit="rad/s", start=0) "Measured speed, (rad/s)"
  Modelica.Blocks.Interfaces.RealOutput Theta(start=8.9, unit="deg")
    "Throttle angle (deg)"
protected
  Modelica.Units.NonSI.Angle_deg x_d(start=8.973, fixed=true);
/*
initial equation
  N_des = pre(N_des);
  N = pre(N);
*/
equation
  when Clock() then
     x_d = previous(x_d) + k_I*interval()*(previous(N_des) - previous(N));
     Theta = k_p*(N_des - N) + x_d;
  end when;
end SpeedControl;


Basic throttle body equations.

within Modelica.Clocked.Examples.Systems.Utilities.ComponentsThrottleControl;
block ThrottleBody "Basic throttle body equations"
  extends Modelica.Blocks.Icons.Block;

parameter Modelica.Units.NonSI.Pressure_bar P_0 = 1 "Atmospheric pressure (bar)";
protected
  Real m_ai(start=0, fixed=true, unit="g") "Mass";
  Modelica.Units.NonSI.Angle_deg f_Theta "Auxiliary variable";
  Real g_Pm "Auxiliary variable";
public
  Modelica.Blocks.Interfaces.RealInput Theta(unit="deg") "Throttle angle (deg)"
  Modelica.Blocks.Interfaces.RealInput Pm(unit="bar")
    "Intake manifold pressure (bar)"
  Modelica.Blocks.Interfaces.RealOutput m_ai_der(unit="g/s")
    "Mass flow rate of air into manifold (g/s)"

protected
  Real tmp1;
  Real tmp2;
  Real pratio;
  Real gpratio;
equation

der(m_ai) = f_Theta * g_Pm;
f_Theta = 2.821 - 0.05231*Theta + 0.10299*Theta^2 - 0.00063*Theta^3; // different to paper 0.0063*Theta^3
// Note: If the flow direction changes, i.e. Pm>P_0 the logic will fail since sqrt(-x)
tmp1 = Pm / P_0;
tmp2 = P_0 / Pm;
pratio = min(tmp1, tmp2);
gpratio = if pratio >= 0.5 then 2*sqrt(pratio - pratio^2) else 1;
g_Pm = sign(P_0 - Pm) * gpratio;
/*
g_Pm = if Pm <= P_0/2 then 1.0 else 2/P_0*sqrt(Pm*P_0 - Pm^2);
*/
m_ai_der = der(m_ai);
end ThrottleBody;


Torque generation.

within Modelica.Clocked.Examples.Systems.Utilities.ComponentsThrottleControl;
block TorqueGeneration "Torque generation"
extends Modelica.Blocks.Icons.Block;
  parameter Real AFR = 14.6
    "Air-fuel ratio";
  parameter Real sigma = 15.0
    "Spark advance, BTDC";
  Modelica.Blocks.Interfaces.RealInput m_a(unit="g")
    "Mass of air charge in cylinder (delayed of 180deg crankshaft rotation) (g)"
  Modelica.Blocks.Interfaces.RealInput N(unit="rad/s") "Engine speed (rad/sec)"
  Modelica.Blocks.Interfaces.RealOutput T_torque_e(unit="N.m")
    "Torque generated by engine"
equation

 T_torque_e = -181.3 + 379.36*m_a + 21.91*AFR - 0.85*AFR^2 + 0.26*sigma
 - 0.0028*sigma^2 + 0.027*N - 0.000107*N^2 + 0.00048*N*sigma
 + 2.55*sigma*m_a - 0.05*sigma^2*m_a;
end TorqueGeneration;


within Modelica.Clocked;
package IntegerSignals "Library of clocked blocks for Integer signals"
  extends Modelica.Icons.Package;
  import Modelica.Units.SI;
end IntegerSignals;


within Modelica.Clocked.IntegerSignals;
package Interfaces "Library of partial blocks for components with clocked Integer signals"
  extends Modelica.Icons.InterfacesPackage;
end Interfaces;


Block with clocked single input and clocked single output Integer signals.

within Modelica.Clocked.IntegerSignals.Interfaces;
partial block PartialClockedSISO
  "Block with clocked single input and clocked single output Integer signals"
  extends Clocked.ClockSignals.Interfaces.ClockedBlockIcon;

  Modelica.Blocks.Interfaces.IntegerInput u
    "Connector of clocked, Real input signal"
  Modelica.Blocks.Interfaces.IntegerOutput y
    "Connector of clocked, Real output signal"

end PartialClockedSISO;


Block with clocked single output Integer signal.

within Modelica.Clocked.IntegerSignals.Interfaces;
partial block PartialClockedSO
  "Block with clocked single output Integer signal"
  extends Clocked.ClockSignals.Interfaces.ClockedBlockIcon;

  Modelica.Blocks.Interfaces.IntegerOutput y
    "Connector of clocked, Real output signal"

end PartialClockedSO;


Basic block used for zero order hold of Integer signals.

within Modelica.Clocked.IntegerSignals.Interfaces;
partial block PartialSISOHold
  "Basic block used for zero order hold of Integer signals"
  parameter Integer y_start = 0
    "Value of output y before the first tick of the clock associated to input u";

  Modelica.Blocks.Interfaces.IntegerInput u(final start=y_start)
    "Connector of clocked, Integer input signal"
  Modelica.Blocks.Interfaces.IntegerOutput y
    "Connector of continuous-time, Integer output signal"
end PartialSISOHold;


Basic block used for sampling of Integer signals.

within Modelica.Clocked.IntegerSignals.Interfaces;
partial block PartialSISOSampler
  "Basic block used for sampling of Integer signals"
extends Clocked.IntegerSignals.Interfaces.SamplerIcon;
  Modelica.Blocks.Interfaces.IntegerInput u
    "Connector of continuous-time, Real input signal"
  Modelica.Blocks.Interfaces.IntegerOutput y
    "Connector of clocked, Real output signal"
end PartialSISOSampler;


Basic graphical layout of block used for of Integer signals.

within Modelica.Clocked.IntegerSignals.Interfaces;
partial block SamplerIcon
  "Basic graphical layout of block used for of Integer signals"
end SamplerIcon;


Delay the clocked input signal for a fractional multiple of the sample period.

within Modelica.Clocked.IntegerSignals.NonPeriodic;
block FractionalDelay
  "Delay the clocked input signal for a fractional multiple of the sample period"
extends Clocked.IntegerSignals.Interfaces.PartialClockedSISO;

  parameter Integer shift(min=0) = 0
    "Delay = interval() * shift/resolution";
  parameter Integer resolution(min=1) = 1
    "Time quantization resolution of sample interval";
protected
  parameter Integer n = div(shift,resolution);
  Integer u_buffer[n+1](each start=0)
    "The previous values of the inputs; u_last[1] = u, u_last[2] = previous(u_last[1]); u_last[3] = previous(u_last[2])";
  Boolean first(start=true) "Used to identify the first clock tick";
equation
 first = false;
 u_buffer = if previous(first) then fill(u,n+1) else cat(1, {u}, previous(u_buffer[1:n]));
 y = shiftSample(u_buffer[n+1], shift, resolution);
end FractionalDelay;


Indicate Integer signal changing. This block is a synchronous version of
Modelica.Blocks.Math.IntegerChange.
It uses previous instead of the implicit pre of
change to set the Boolean output y to
true when the integer input u changed. Thus, it's
logic is:

within Modelica.Clocked.IntegerSignals.NonPeriodic;
block IntegerChange "Indicate Integer signal changing"
  extends Clocked.ClockSignals.Interfaces.ClockedBlockIcon;

  Modelica.Blocks.Interfaces.IntegerInput u(start=0)
    "Connector of Integer input signal."
  Modelica.Blocks.Interfaces.BooleanOutput y
    "Connector of Boolean output signal."

equation
  if firstTick() then
    y = false;
  else
    y = not (u == previous(u));
  end if;
end if;

This block might be superfluous and replaced by
Modelica.Blocks.Math.IntegerChange when the semantics
of change are relaxed and well-defined for
clocked discrete-time partitions.

"));
end IntegerChange;


within Modelica.Clocked.IntegerSignals;
package NonPeriodic "Library of blocks that operate on periodically and non-periodically clocked signals"
  extends Modelica.Icons.Package;

end NonPeriodic;


Delay the clocked input signal for one sample period. This block describes a unit delay:

within Modelica.Clocked.IntegerSignals.NonPeriodic;
block UnitDelay "Delay the clocked input signal for one sample period"
  extends Clocked.IntegerSignals.Interfaces.PartialClockedSISO(u(final
        start=y_start));
  parameter Integer y_start=0 "Value of output signal at first clock tick";
equation
  y = previous(u);
end UnitDelay;


Assign a clock to a clocked Integer signal. This block for Integer signals works similarly as the corresponding block for Real signals (see RealSignals.Sampler.AssignClock).

within Modelica.Clocked.IntegerSignals.Sampler;
block AssignClock "Assign a clock to a clocked Integer signal"
  Modelica.Blocks.Interfaces.IntegerInput u
    "Connector of clocked, Integer input signal"
  Modelica.Blocks.Interfaces.IntegerOutput y
    "Connector of clocked, Integer output signal"
   Clocked.ClockSignals.Interfaces.ClockInput clock
equation
  when clock then
    y = u;
  end when;
end AssignClock;


Assign a clock to a clocked Integer signal vector. This block for Integer signals works similarly as the corresponding block for Real signals (see RealSignals.Sampler.AssignClockVectorized).

within Modelica.Clocked.IntegerSignals.Sampler;
block AssignClockVectorized
  "Assign a clock to a clocked Integer signal vector"
  parameter Integer n(min=1)=1
    "Size of input signal vector u (= size of output signal vector y)";
  Modelica.Blocks.Interfaces.IntegerInput u[n]
    "Connector of clocked, Integer input signal"
  Modelica.Blocks.Interfaces.IntegerOutput y[n]
    "Connector of clocked, Integer output signal"
   Clocked.ClockSignals.Interfaces.ClockInput clock
equation
  when clock then
    y = u;
  end when;
end AssignClockVectorized;


Shift clock of Integer input signal backwards in time (and access the most recent value of the input at this new clock). This block for Integer signals works similarly as the corresponding block for Real signals (see RealSignals.Sampler.BackSample).

within Modelica.Clocked.IntegerSignals.Sampler;
block BackSample
  "Shift clock of Integer input signal backwards in time (and access the most recent value of the input at this new clock)"
  parameter Integer backCounter(min=0)=0 "Numerator of shifting formula"
  parameter Integer resolution(min=1)=1 "Denominator of shifting formula"
  parameter Integer y_start=0
    "Value of output y before the first clock tick of the input u";
  Modelica.Blocks.Interfaces.IntegerInput u(start=y_start)
    "Connector of clocked, Integer input signal"
  Modelica.Blocks.Interfaces.IntegerOutput y
    "Connector of clocked, Integer output signal (clock of y is faster than clock of u)"
equation
  y = backSample(u,backCounter,resolution);
end BackSample;


Hold the clocked, Integer input signal and provide it as continuous-time output signal (zero order hold). This block for Integer signals works similarly as the corresponding block for Real signals (see RealSignals.Sampler.Hold).

within Modelica.Clocked.IntegerSignals.Sampler;
block Hold
  "Hold the clocked, Integer input signal and provide it as continuous-time output signal (zero order hold)"
  extends Clocked.IntegerSignals.Interfaces.PartialSISOHold;
  parameter Integer y_start = 0
    "Value of output y before the first tick of the clock associated to input u";

equation
    y = hold(u);
end Hold;


within Modelica.Clocked.IntegerSignals;
package Sampler "Library of sampler and hold blocks for Integer signals"
  extends Modelica.Icons.Package;
end Sampler;


Sample the continuous-time, Integer input signal and provide it as clocked output signal (clock is inferred). This block for Integer signals works similarly as the corresponding block for Real signals
(see RealSignals.Sampler.Sample).

within Modelica.Clocked.IntegerSignals.Sampler;
block Sample
  "Sample the continuous-time, Integer input signal and provide it as clocked output signal (clock is inferred)"
  extends Clocked.IntegerSignals.Interfaces.PartialSISOSampler;

equation
  y = sample(u);
end Sample;


Sample the continuous-time, Integer input signal and provide it as clocked output signal. The clock is provided as input signal. This block for Integer signals works similarly as the corresponding block for Real signals (see RealSignals.Sampler.SampleClocked).

within Modelica.Clocked.IntegerSignals.Sampler;
block SampleClocked
  "Sample the continuous-time, Integer input signal and provide it as clocked output signal. The clock is provided as input signal"
  extends Clocked.IntegerSignals.Interfaces.SamplerIcon;
  Clocked.ClockSignals.Interfaces.ClockInput clock
    "Output signal y is associated with this clock input"
  Modelica.Blocks.Interfaces.IntegerInput
                                       u
    "Connector of continuous-time, Integer input signal"
  Modelica.Blocks.Interfaces.IntegerOutput
                                        y
    "Connector of clocked, Integer output signal"
equation
  y = sample(u,clock);
end SampleClocked;


Sample the continuous-time, Integer input signal vector and provide it as clocked output signal vector. The clock is provided as input signal. This block for Integer signals works similarly as the corresponding block for Real signals (see RealSignals.Sampler.SampleVectorizedAndClocked).

within Modelica.Clocked.IntegerSignals.Sampler;
block SampleVectorizedAndClocked
  "Sample the continuous-time, Integer input signal vector and provide it as clocked output signal vector. The clock is provided as input signal"
  extends Clocked.IntegerSignals.Interfaces.SamplerIcon;
  parameter Integer n(min=1)=1
    "Size of input signal vector u (= size of output signal vector y)";
  Modelica.Blocks.Interfaces.IntegerInput u[n]
    "Connector of continuous-time, Integer input signal vector"
  Modelica.Blocks.Interfaces.IntegerOutput y[n]
    "Connector of clocked, Integer output signal vector"
  Clocked.ClockSignals.Interfaces.ClockInput clock
    "Output signal vector y is associated with this clock input"
equation
  y = sample(u,clock);
end SampleVectorizedAndClocked;


Shift the clocked Integer input signal by a fraction of the last interval and provide it as clocked output signal. This block for Integer signals works similarly as the corresponding block for Real signals (see RealSignals.Sampler.ShiftSample).

within Modelica.Clocked.IntegerSignals.Sampler;
block ShiftSample
  "Shift the clocked Integer input signal by a fraction of the last interval and provide it as clocked output signal"
  parameter Integer shiftCounter(min=0)=0 "Numerator of shifting formula"
  parameter Integer resolution(min=1)=1 "Denominator of shifting formula"
  Modelica.Blocks.Interfaces.IntegerInput u
    "Connector of clocked, Integer input signal"
  Modelica.Blocks.Interfaces.IntegerOutput y
    "Connector of clocked, Integer output signal"
equation
  y = shiftSample(u,shiftCounter,resolution);
end ShiftSample;


Sub-sample the clocked Integer input signal and provide it as clocked output signal. This block for Integer signals works similarly as the corresponding block for Real signals (see RealSignals.Sampler.SubSample).

within Modelica.Clocked.IntegerSignals.Sampler;
block SubSample
  "Sub-sample the clocked Integer input signal and provide it as clocked output signal"
  parameter Boolean inferFactor=true
    "= true, if sub-sampling factor is inferred"
  parameter Integer factor(min=1)=1
    "Sub-sampling factor >= 1 (ignored if inferFactor=true)"
  Modelica.Blocks.Interfaces.IntegerInput u
    "Connector of clocked, Integer input signal"
  Modelica.Blocks.Interfaces.IntegerOutput y
    "Connector of clocked, Integer output signal (clock of y is slower as clock of u)"
equation
  if inferFactor then
     y = subSample(u);
  else
     y = subSample(u,factor);
  end if;
end SubSample;


Super-sample the clocked Integer input signal and provide it as clocked output signal. This block for Integer signals works similarly as the corresponding block for Real signals (see RealSignals.Sampler.SuperSample).

within Modelica.Clocked.IntegerSignals.Sampler;
block SuperSample
  "Super-sample the clocked Integer input signal and provide it as clocked output signal"
  parameter Boolean inferFactor=true
    "= true, if super-sampling factor is inferred"
  parameter Integer factor(min=1)=1
    "Super-sampling factor >= 1 (ignored if inferFactor=true)"
  Modelica.Blocks.Interfaces.IntegerInput u
    "Connector of clocked, Integer input signal"
  Modelica.Blocks.Interfaces.IntegerOutput y
    "Connector of clocked, Integer output signal (clock of y is faster as clock of u)"
equation
  if inferFactor then
     y = superSample(u);
  else
     y = superSample(u,factor);
  end if;
end SuperSample;


Generate a Boolean continuous-time square signal from a clocked Integer input. This block for Integer signals works similar as the corresponding block for Real signals (see
RealSignals.Sampler.Utilities.AssignClockToSquareWaveHold).

within Modelica.Clocked.IntegerSignals.Sampler.Utilities;
block AssignClockToSquareWaveHold
"Generate a Boolean continuous-time square signal from a clocked Integer input"
  extends Clocked.ClockSignals.Interfaces.ClockedBlockIcon;
  parameter Boolean y_start=false "Initial value of output signal";
  Modelica.Blocks.Interfaces.IntegerInput u
  Modelica.Blocks.Interfaces.BooleanOutput y
  "Connector of Boolean output signal"
protected
  Boolean y2(start=y_start);
equation
  // dummy condition to relate clock of u with y2
  y2 = if u > 0 then not previous(y2) else not previous(y2);
  y = hold(y2);
end AssignClockToSquareWaveHold;


Generate a Boolean continuous-time trigger signal from a clocked Integer input. This block for Integer signals works similar as the corresponding block for Real signals (see
RealSignals.Sampler.Utilities.AssignClockToTriggerHold).

within Modelica.Clocked.IntegerSignals.Sampler.Utilities;
block AssignClockToTriggerHold
"Generate a Boolean continuous-time trigger signal from a clocked Integer input"
  extends Clocked.ClockSignals.Interfaces.ClockedBlockIcon;
  parameter Boolean y_start=false "Initial value of output signal";
  Modelica.Blocks.Interfaces.IntegerInput u
  Modelica.Blocks.Interfaces.BooleanOutput y
  "Connector of Boolean output signal"
protected
  Boolean y2(start=y_start);
  Boolean y3(start=y_start, fixed=true);
  Real uu
equation
  when Clock() then
     uu = u "Dummy assignment to relate clock of u with y2";
     y2 = not previous(y2);
  end when;
  y3 = hold(y2);
  y = change(y3);
end AssignClockToTriggerHold;


within Modelica.Clocked.IntegerSignals.Sampler;
package Utilities "Utility components that are usually not directly used"
   extends Modelica.Icons.UtilitiesPackage;
end Utilities;


Upsample the clocked Integer input signal and provide it as clocked output signal. This block for Integer signals works similarly as the corresponding block for Real signals (see
RealSignals.Sampler.Utilities.UpSample).

within Modelica.Clocked.IntegerSignals.Sampler.Utilities;
block UpSample
  "Upsample the clocked Integer input signal and provide it as clocked output signal"
  parameter Boolean inferFactor=true
    "= true, if upsampling factor is inferred"
  parameter Integer factor(min=1)=1
    "Upsampling factor >= 1 (if inferFactor=false)"
  Modelica.Blocks.Interfaces.IntegerInput u
    "Connector of clocked, Integer input signal"
  Modelica.Blocks.Interfaces.IntegerOutput y
    "Connector of clocked, Integer output signal (clock of y is faster as clock of u)"
protected
  Integer dummy
  Boolean b(start=false);
  Boolean b_super(start=false);
  Integer u_super;
equation
  when Clock() then // clock of u
     dummy = u;
     b = not previous(b);
  end when;

  when Clock() then // clock of y
     b_super = superSample(b);
     if inferFactor then
        u_super = superSample(u);
     else
        u_super = superSample(u,factor);
     end if;
     y = if b_super <> previous(b_super) then u_super else 0;
  end when;
end UpSample;


within Modelica.Clocked.IntegerSignals;
package TickBasedSources "Package of signal source blocks generating clocked tick/sample based Integer signals"
   extends Modelica.Icons.SourcesPackage;
end TickBasedSources;


Generate step signal of type Integer. The Integer output y is a step signal. The signal is defined in terms of clock ticks instead of simulation time:

within Modelica.Clocked.IntegerSignals.TickBasedSources;
block Step "Generate step signal of type Integer"
    extends Interfaces.PartialClockedSO;
  parameter Integer height = 1 "Height of step";
  parameter Integer offset = 0 "Offset of output signal y";
  parameter Integer startTick(min=1) = 1
    "Output y = offset for clock tick < startTick";
protected
  Integer counter(start=0);
equation
  // stop counter after counter = startTick to avoid integer overflow for long running simulations
  counter = if previous(counter) < startTick then previous(counter) + 1 else previous(counter);
  y = offset + (if counter < startTick then 0 else height);
end Step;


within Modelica.Clocked.IntegerSignals;
package TimeBasedSources "Package of signal source blocks generating clocked simulation time based Integer signals"
   extends Modelica.Icons.SourcesPackage;
end TimeBasedSources;


Generate step signal of type Integer. The block is similar to the block in Modelica.Blocks.Sources.IntegerStep, but adapted to work in clocked partitions (by internal sampling of the continuous time variable).

within Modelica.Clocked.IntegerSignals.TimeBasedSources;
block Step "Generate step signal of type Integer"
   extends Interfaces.PartialClockedSO;
 parameter Integer height = 1 "Height of step";
 parameter Integer offset = 0 "Offset of output signal y";
 parameter SI.Time startTime = 0
   "Output y = offset for time < startTime";
protected
 SI.Time simTime;
equation
 simTime = sample(time);
 y = offset + (if simTime < startTime then 0 else height);
end Step;


within Modelica.Clocked;
package RealSignals "Library of clocked blocks for Real signals"
  extends Modelica.Icons.Package;
  import Modelica.Units.SI;
end RealSignals;


within Modelica.Clocked.RealSignals;
package Interfaces "Library of partial blocks for components with clocked Real signals"
  extends Modelica.Icons.InterfacesPackage;
end Interfaces;


Block with multiple clocked input and multiple clocked output Real signals.

within Modelica.Clocked.RealSignals.Interfaces;
partial block PartialClockedMIMO
  "Block with multiple clocked input and multiple clocked output Real signals"
  extends Clocked.ClockSignals.Interfaces.ClockedBlockIcon;

  parameter Integer nin=1 "Number of inputs";
  parameter Integer nout=1 "Number of outputs";

  Modelica.Blocks.Interfaces.RealInput u[nin]
    "Connector of clocked, Real input signals"
  Modelica.Blocks.Interfaces.RealOutput y[nout]
    "Connector of clocked, Real output signals"

end PartialClockedMIMO;


Block with clocked single input and clocked single output Real signals.

within Modelica.Clocked.RealSignals.Interfaces;
partial block PartialClockedSISO
  "Block with clocked single input and clocked single output Real signals"
  extends Clocked.ClockSignals.Interfaces.ClockedBlockIcon;

  Modelica.Blocks.Interfaces.RealInput u
    "Connector of clocked, Real input signal"
  Modelica.Blocks.Interfaces.RealOutput y
    "Connector of clocked, Real output signal"

end PartialClockedSISO;


Block with clocked single output Real signal.

within Modelica.Clocked.RealSignals.Interfaces;
partial block PartialClockedSO
  "Block with clocked single output Real signal"
  extends Clocked.ClockSignals.Interfaces.ClockedBlockIcon;

  Modelica.Blocks.Interfaces.RealOutput y
    "Connector of clocked, Real output signal"

end PartialClockedSO;


Interface for SISO blocks with Real signals that add noise to the signal. Interface block for uniformly distributed noise in some range noiseMin … noiseMax applied to a clocked Real input signal; the resulting noisy signal is provided as clocked Real output signal.

within Modelica.Clocked.RealSignals.Interfaces;
partial block PartialNoise
  "Interface for SISO blocks with Real signals that add noise to the signal"
  extends Clocked.RealSignals.Interfaces.PartialClockedSISO;

  parameter Real noiseMax=0.1 "Upper limit of noise band";
  parameter Real noiseMin=-noiseMax "Lower limit of noise band";
end PartialNoise;


Basic block used for zero order hold of Real signals.

within Modelica.Clocked.RealSignals.Interfaces;
partial block PartialSISOHold
  "Basic block used for zero order hold of Real signals"

  parameter Real y_start = 0.0
    "Value of output y before the first tick of the clock associated to input u";

  Modelica.Blocks.Interfaces.RealInput u(final start=y_start)
    "Connector of clocked, Real input signal"
  Modelica.Blocks.Interfaces.RealOutput y
    "Connector of continuous-time, Real output signal"
end PartialSISOHold;


Basic block used for sampling of Real signals.

within Modelica.Clocked.RealSignals.Interfaces;
partial block PartialSISOSampler
  "Basic block used for sampling of Real signals"
extends Clocked.RealSignals.Interfaces.SamplerIcon;
  Modelica.Blocks.Interfaces.RealInput u
    "Connector of continuous-time, Real input signal"
  Modelica.Blocks.Interfaces.RealOutput y
    "Connector of clocked, Real output signal"
equation

end PartialSISOSampler;


Basic graphical layout of block used for sampling of Real signals.

within Modelica.Clocked.RealSignals.Interfaces;
partial block SamplerIcon
  "Basic graphical layout of block used for sampling of Real signals"
end SamplerIcon;


Delay the clocked input signal for a fractional multiple of the sample period. This block delays a signal. Similar to the ShiftSample block the first activation of the clock of the output y is delayed by shiftCounter/resolution*interval(u) relative to the input u (interval(u) is the sample period of the clock associated to input u). However, in contrast to ShiftSample, the block provides a buffer for the input values and truly delays the input signal.

within Modelica.Clocked.RealSignals.NonPeriodic;
block FractionalDelay
  "Delay the clocked input signal for a fractional multiple of the sample period"
extends Clocked.RealSignals.Interfaces.PartialClockedSISO;

  parameter Integer shift(min=0) = 0
    "Delay = interval() * shift/resolution";
  parameter Integer resolution(min=1) = 1
    "Time quantization resolution of sample interval";
protected
  parameter Integer n = div(shift,resolution);
  Real u_buffer[n+1](each start=0.0)
    "The previous values of the inputs; u_last[1] = u, u_last[2] = previous(u_last[1]); u_last[3] = previous(u_last[2])";
  Boolean first(start=true) "Used to identify the first clock tick";
equation
 first = false;
 u_buffer = if previous(first) then fill(u,n+1) else cat(1, {u}, previous(u_buffer[1:n]));
 y = shiftSample(u_buffer[n+1], shift, resolution);
end FractionalDelay;


within Modelica.Clocked.RealSignals;
package NonPeriodic "Library of blocks that operate on periodically and non-periodically clocked signals"
extends Modelica.Icons.Package;
end NonPeriodic;


Discrete-time PI controller with clocked input and output signals (for periodic and aperiodic systems using the parameterization of the continuous PI controller). Discrete-time PI controller that has been derived from the continuous-time
PI controller

within Modelica.Clocked.RealSignals.NonPeriodic;
block PI
  "Discrete-time PI controller with clocked input and output signals (for periodic and aperiodic systems using the parameterization of the continuous PI controller)"
  extends Clocked.RealSignals.Interfaces.PartialClockedSISO;
  parameter Real k "Gain of continuous PI controller";
  parameter Real T(min=Modelica.Constants.small)
    "Time constant of continuous PI controller";
  output Real x(start=0) "Discrete PI state";
protected
  Real Ts = interval(u) "Sample time (periodic or non-periodic)";
equation
  when Clock() then
     x = previous(x) + u*(Ts/T);
     y = k*(x + u);
  end when;
end PI;


Delay the clocked input signal for one sample period. This block describes a unit delay:

within Modelica.Clocked.RealSignals.NonPeriodic;
block UnitDelay "Delay the clocked input signal for one sample period"
  extends Clocked.RealSignals.Interfaces.PartialClockedSISO(u(final start=
          y_start));
  parameter Real y_start=0 "Value of output signal at first clock tick";
equation
  y = previous(u);
end UnitDelay;


FIR filter defined by coefficients. This block computes the output y as a linear combination of the input u
and of its past values (= FIR filter):

within Modelica.Clocked.RealSignals.Periodic;
block FIRbyCoefficients "FIR filter defined by coefficients"
  extends Clocked.RealSignals.Interfaces.PartialClockedSISO;
  input Real a[:]={1/2,1/2} "Coefficients of FIR filter"
  parameter Real cBufStart[size(a,1)-1] = ones(size(a,1)-1)
    "The u-buffer [u(i-1), u(i-2), ..., u(size(a,1)-1)] is initialized with u(i=1)*cBufStart"
protected
  parameter Integer n = size(a, 1) - 1 "Order of filter";
  Real u_buffer[n+1](each start=0.0)
    "The previous values of the inputs; u_buffer[1] = u, u_buffer[2] = previous(u_buffer[1]); u_buffer[3] = previous(u_buffer[2])";
  Boolean first(start=true) "Used to identify the first clock tick";
equation
  when Clock() then
     first = false;

     // At the first clock tick u_last is filled with "u" (to initialize in steady state).
     u_buffer = if previous(first) then cat( 1, {u}, u*cBufStart)  else
                     cat( 1, {u}, previous(u_buffer[1:n]));

     // FIR formula
     y = a*u_buffer;
  end when;
end FIRbyCoefficients;


Moving average filter (= FIR filter with coefficients a = fill(1/n,n), but implemented recursively). This block computes the output y as the average of the input u and of
its past values (= moving average filter):

within Modelica.Clocked.RealSignals.Periodic;
block MovingAverage
  "Moving average filter (= FIR filter with coefficients a = fill(1/n,n), but implemented recursively)"
  extends Clocked.RealSignals.Interfaces.PartialClockedSISO;
  parameter Integer n = 2
    "Number of points that are averaged (= number of coefficients of corresponding FIR filter)";
protected
  Real u_buffer[n+1](each start=0.0)
    "The previous values of the inputs; u_buffer[1] = u, u_buffer[2] = previous(u_buffer[1]); u_buffer[3] = previous(u_buffer[2])";
  Boolean first(start=true) "Used to identify the first clock tick";
  Real uu(start=0.0)
    "Dummy variable to provide a dummy start value for u (which has no effect)";
  Real yy(start=0.0)
    "Dummy variable to provide a dummy start value for y (which has no effect)";
equation
  when Clock() then
     first = false;
     uu = u;

     // At the first clock tick u_last is filled with "u" (to initialize in steady state).
     u_buffer = if previous(first) then fill(uu,n+1) else
                     cat( 1, {uu}, previous(u_buffer[1:n]));

     // Moving average formula
     y = if previous(first) then uu else previous(yy) + (u_buffer[1] - u_buffer[n+1])/n;
     yy = y;
  end when;
end MovingAverage;


within Modelica.Clocked.RealSignals;
package Periodic "Library of blocks that are designed to operate only on periodically clocked signals (mainly described by z transforms)"
extends Modelica.Icons.Package;
end Periodic;


Discrete-time PI controller. This block defines a discrete-time PI controller by the formula:

within Modelica.Clocked.RealSignals.Periodic;
block PI "Discrete-time PI controller"
  extends Clocked.RealSignals.Interfaces.PartialClockedSISO;
  parameter Real kd "Gain of discrete PI controller";
  parameter Real Td(min=Modelica.Constants.small)
    "Time constant of discrete PI controller";
  output Real x(start=0) "Discrete PI state";
equation
  when Clock() then
     x = previous(x) + u/Td;
     y = kd*(x + u);
  end when;

// Transfer function form:
   y(z) = kd*(c*z-1)/(z-1)*u(z);
          c = 1 + 1/Td

where kd is the gain, Td is the time constant, ti is the time instant
of the i-th clock tick and z is the inverse shift operator.

This discrete-time form has been derived from the continuous-time
form of a PI controller by using the implicit Euler discretization formula.

"));
end PI;


Discrete-time State Space block. This block defines the state space representation of a discrete-time block
with input vector u, output vector y and state vector x:

within Modelica.Clocked.RealSignals.Periodic;
block StateSpace "Discrete-time State Space block"
  parameter Real A[:, size(A, 1)] "Matrix A of state space model";
  parameter Real B[size(A, 1), :] "Matrix B of state space model";
  parameter Real C[:, size(A, 1)] "Matrix C of state space model";
  parameter Real D[size(C, 1), size(B, 2)]=zeros(size(C, 1), size(B, 2))
    "Matrix D of state space model";
  extends Clocked.RealSignals.Interfaces.PartialClockedMIMO(final nin=size(
        B, 2), final nout=size(C, 1));
  output Real x[size(A, 1)](each start=0.0) "State vector";

equation
  when Clock() then
    x = A*previous(x) + B*u;
    y = C*previous(x) + D*u;
  end when;
end StateSpace;


Discrete-time Transfer Function block. The discrete transfer function block defines the
transfer function between the input signal u and the output
signal y. The numerator has the order nb-1, the denominator
has the order na-1.

within Modelica.Clocked.RealSignals.Periodic;
block TransferFunction "Discrete-time Transfer Function block"
  extends Clocked.RealSignals.Interfaces.PartialClockedSISO;
  parameter Real b[:]={1} "Numerator coefficients of transfer function.";
  parameter Real a[:] "Denominator coefficients of transfer function.";

  output Real x[size(a, 1) - 1](each start=0.0)
    "State vector of controller canonical form";
protected
  parameter Integer nb=size(b, 1) "Size of Numerator of transfer function";
  parameter Integer na=size(a, 1)
    "Size of Denominator of transfer function";
  Real x1;
  Real xext[size(a, 1)];

equation
  when Clock() then
    /* State variables x are defined according to
       controller canonical form. */
    x1 = (u - a[2:size(a, 1)]*previous(x))/a[1];
    xext = vector([x1; previous(x)]);
    x = xext[1:size(x, 1)];
    y = vector([zeros(na - nb, 1); b])*xext;
  end when;

results in the following transfer function:

     2*z + 4
y = --------- * u
      z + 3

",
        revisions="

Release Notes:

August 13, 2012
    by Bernhard Thiele:

    Used the original code from Blocks.Discrete.TransferFunction and converted it into
    the Modelica 3.3 clocked equation style.

November 15, 2000
    by Hans Olsson:

    Converted to when-semantics of Modelica 1.4 with special
    care to avoid unnecessary algebraic loops.

June 18, 2000
    by Martin Otter:

    Realized based on a corresponding model of Dieter Moormann
    and Hilding Elmqvist.

"),
    Icon(coordinateSystem(
        preserveAspectRatio=false,
        extent={{-100,-100},{100,100}}), graphics={
        Line(points={{82,0},{-84,0}}, color={0,0,127}),
        Text(
          extent={{-92,92},{86,12}},
          textColor={0,0,127},
          textString="b(z)"),
        Text(
          extent={{-90,-12},{90,-90}},
          textColor={0,0,127},
          textString="a(z)")}),
    Diagram(coordinateSystem(
        preserveAspectRatio=true,
        extent={{-100,-100},{100,100}}), graphics={
        Rectangle(extent={{-60,60},{60,-60}}, lineColor={0,0,255}),
        Line(
          points={{40,0},{-44,0}},
          thickness=0.5),
        Text(
          extent={{-54,54},{54,4}},
          textString="b(z)"),
        Text(
          extent={{-54,-6},{56,-56}},
          textString="a(z)"),
        Line(points={{-100,0},{-60,0}}, color={0,0,255}),
        Line(points={{60,0},{100,0}}, color={0,0,255})}));
end TransferFunction;


Assign a clock to a clocked Real signal. This block assigns a clock to the Real input signal u
and provides u as output signal y.

within Modelica.Clocked.RealSignals.Sampler;
block AssignClock "Assign a clock to a clocked Real signal"

  Modelica.Blocks.Interfaces.RealInput u
    "Connector of clocked, Real input signal"
  Modelica.Blocks.Interfaces.RealOutput y
    "Connector of clocked, Real output signal"
  Clocked.ClockSignals.Interfaces.ClockInput clock
equation
  when clock then
    y = u;
  end when;
end AssignClock;


Assign a clock to a clocked Real signal vector. This block assigns a clock to the Real vector input signal u
and provides u as vector output signal y.

within Modelica.Clocked.RealSignals.Sampler;
block AssignClockVectorized
  "Assign a clock to a clocked Real signal vector"

  parameter Integer n(min=1)=1
    "Size of input signal vector u (= size of output signal vector y)";
  Modelica.Blocks.Interfaces.RealInput u[n]
    "Connector of clocked, Real input signal"
  Modelica.Blocks.Interfaces.RealOutput y[n]
    "Connector of clocked, Real output signal"
   Clocked.ClockSignals.Interfaces.ClockInput clock
equation
  when clock then
    y = u;
  end when;
end AssignClockVectorized;


Shift the clock of the Real input signal backwards in time (and access the most recent value of the input at this new clock). This block shifts the first activation of the clock of the output y by
fraction backCounter/resolution of the period (or for a non-periodic signal by a fraction of the last interval)
before the first activation of the clock of u.
The output y is set to the last available value of the input u.
Here, backCounter and resolution are positive Integer parameters.

within Modelica.Clocked.RealSignals.Sampler;
block BackSample
  "Shift the clock of the Real input signal backwards in time (and access the most recent value of the input at this new clock)"
  parameter Integer backCounter(min=0)=0 "Numerator of shifting formula"
  parameter Integer resolution(min=1)=1 "Denominator of shifting formula"
  parameter Real y_start=0
    "Value of output y before the first clock tick of the input u";

  Modelica.Blocks.Interfaces.RealInput u(start=y_start)
    "Connector of clocked, Real input signal"
  Modelica.Blocks.Interfaces.RealOutput y
    "Connector of clocked, Real output signal (clock of y is faster than clock of u)"
equation
  y = backSample(u,backCounter,resolution);
end BackSample;


Hold the clocked, Real input signal and provide it as continuous-time output signal (zero order hold). This block holds the clocked Real input signal u with a zero order hold
and provides it as continuous-time output signal y.
The clock of the input signal is inferred
(that is, it needs to be defined somewhere else in the clocked partition).

within Modelica.Clocked.RealSignals.Sampler;
block Hold
  "Hold the clocked, Real input signal and provide it as continuous-time output signal (zero order hold)"
extends Clocked.RealSignals.Interfaces.PartialSISOHold;

equation
    y = hold(u);
end Hold;


Hold with (simulated) Digital-Analog converter effects and computational delay. This block is similar to the
Hold
block. The only difference is that simulated real-world effects are applied on the
clocked input signal u before transforming the signal to a continuous-time signal
with a zero-order hold. In particular:

within Modelica.Clocked.RealSignals.Sampler;
block HoldWithDAeffects
  "Hold with (simulated) Digital-Analog converter effects and computational delay"
  extends Clocked.RealSignals.Interfaces.PartialSISOHold;

  parameter Boolean computationalDelay = false
    "=true, if a computational delay should be imposed"
  parameter Integer shiftCounter(min=0,max=resolution) = 0
    "(min=0, max=resolution), computational delay = interval()*shiftCounter/resolution"
  parameter Integer resolution(min=1) = 1
    "Time quantization resolution of sample interval"

  parameter Boolean limited = false "= true, if output is limited"
  parameter Boolean quantized = false
    "= true, if output quantization effects included"
  parameter Real yMax=1 "Upper limit of output (if limited = true)"
  parameter Real yMin=-yMax "Lower limit of output (if limited = true)"
  parameter Integer bits(min=1)=8
    "Number of bits of quantization (if quantized = true)"

  Clocked.RealSignals.Sampler.Utilities.Internal.Limiter limiter(uMax=yMax,
      uMin=yMin) if limited
  Clocked.RealSignals.Sampler.Utilities.Internal.Quantization quantization(
    quantized=quantized,
    yMax=yMax,
    yMin=yMin,
    bits=bits) if quantized and limited
  Clocked.RealSignals.Sampler.Utilities.Internal.ComputationalDelay compDelay(
      shiftCounter=shiftCounter, resolution=resolution) if
    computationalDelay
  Hold hold1(y_start=y_start)
protected
  Modelica.Blocks.Interfaces.RealInput uFeedthrough2 if not limited
  Modelica.Blocks.Interfaces.RealInput uFeedthrough3 if not quantized or not limited
  Modelica.Blocks.Interfaces.RealInput uFeedthrough4 if not computationalDelay
  Modelica.Blocks.Interfaces.RealOutput y2
  Modelica.Blocks.Interfaces.RealOutput y3
  Modelica.Blocks.Interfaces.RealOutput y4
  Modelica.Blocks.Interfaces.RealOutput y5
equation
  connect(y2, limiter.u)
  connect(y2, uFeedthrough2)
  connect(limiter.y, y3)
  connect(y3, quantization.u)
  connect(y3, uFeedthrough3)
  connect(quantization.y, y4)
  connect(y4, compDelay.u)
  connect(uFeedthrough3, y4)
  connect(y4, uFeedthrough4)
  connect(uFeedthrough2, y3)

  connect(y5, compDelay.y)
  connect(y5, uFeedthrough4)

  connect(y5, hold1.u)
  connect(u, y2)
  connect(hold1.y, y)
end HoldWithDAeffects;


within Modelica.Clocked.RealSignals;
package Sampler "Library of sampler and hold blocks for Real signals"
  extends Modelica.Icons.Package;
end Sampler;


Sample the continuous-time, Real input signal and provide it as clocked output signal (clock is inferred). This block samples the continuous-time, Real input signal u and provides it as
clocked output signal y. The clock of the output signal is inferred
(that is, it needs to be defined somewhere else in the clocked partition).
If this is not desired, use block
SampleClocked
instead, to explicitly assign a clock to the output signal.

within Modelica.Clocked.RealSignals.Sampler;
block Sample
  "Sample the continuous-time, Real input signal and provide it as clocked output signal (clock is inferred)"
  extends Clocked.RealSignals.Interfaces.PartialSISOSampler;

equation
  y = sample(u);
end Sample;


Sample the continuous-time, Real input signal and provide it as clocked output signal. The clock is provided as input signal. This block is similar to the
Sample
block. The only difference is that a clock signal is provided via a second
input and the output is associated to this clock.

within Modelica.Clocked.RealSignals.Sampler;
block SampleClocked
  "Sample the continuous-time, Real input signal and provide it as clocked output signal. The clock is provided as input signal"
  extends Clocked.RealSignals.Interfaces.SamplerIcon;
  Modelica.Blocks.Interfaces.RealInput u
    "Connector of continuous-time, Real input signal"
  Modelica.Blocks.Interfaces.RealOutput y
    "Connector of clocked, Real output signal"
  Clocked.ClockSignals.Interfaces.ClockInput clock
    "Output signal y is associated with this clock input"

equation
  y = sample(u,clock);
end SampleClocked;


Sample the continuous-time, Real input signal vector and provide it as clocked output signal vector. The clock is provided as input signal. This block is similar to the
SampleClocked
block. The only difference is that the continuous-time input signal is a vector: All input
signals are sampled and are associated with the
scalar clock signal provided via the second input.

within Modelica.Clocked.RealSignals.Sampler;
block SampleVectorizedAndClocked
  "Sample the continuous-time, Real input signal vector and provide it as clocked output signal vector. The clock is provided as input signal"
  extends Clocked.RealSignals.Interfaces.SamplerIcon;
  parameter Integer n(min=1)=1
    "Size of input signal vector u (= size of output signal vector y)";
  Modelica.Blocks.Interfaces.RealInput u[n]
    "Connector of continuous-time, Real input signal vector"
  Modelica.Blocks.Interfaces.RealOutput y[n]
    "Connector of clocked, Real output signal vector"
   Clocked.ClockSignals.Interfaces.ClockInput clock
    "Output signal vector y is associated with this clock input"
equation
  y = sample(u,clock);
end SampleVectorizedAndClocked;


Sample with (simulated) Analog-Digital converter effects including noise. This block is similar to the
Sample
block. The only difference is that after the sampling of the input signal,
simulated real-world effects are applied on the sampled signal. In particular:

within Modelica.Clocked.RealSignals.Sampler;
block SampleWithADeffects
  "Sample with (simulated) Analog-Digital converter effects including noise"
  extends Clocked.RealSignals.Interfaces.PartialSISOSampler;

  parameter Boolean noisy = false
    "= true, if output should be superimposed with noise"

  parameter Boolean limited = false "= true, if output is limited"
  parameter Boolean quantized = false
    "= true, if output quantization effects included"
  parameter Real yMax=1 "Upper limit of output (if limited = true)"
  parameter Real yMin=-yMax "Lower limit of output (if limited = true)"
  parameter Integer bits(min=1)=8
    "Number of bits of quantization (if quantized = true)"

  Sample sample1

  replaceable Clocked.RealSignals.Sampler.Utilities.Internal.UniformNoise noise if noisy
    constrainedby Clocked.RealSignals.Interfaces.PartialNoise "Noise model"
  Clocked.RealSignals.Sampler.Utilities.Internal.Limiter limiter(uMax=yMax,
      uMin=yMin) if limited
  Clocked.RealSignals.Sampler.Utilities.Internal.Quantization quantization(
    quantized=quantized,
    yMax=yMax,
    yMin=yMin,
    bits=bits) if quantized and limited
protected
  Modelica.Blocks.Interfaces.RealInput uFeedthrough1 if not noisy
  Modelica.Blocks.Interfaces.RealInput uFeedthrough2 if not limited
  Modelica.Blocks.Interfaces.RealInput uFeedthrough3 if not quantized or not limited
  Modelica.Blocks.Interfaces.RealOutput y1
    "Connector with a Real output signal"
  Modelica.Blocks.Interfaces.RealOutput y2
  Modelica.Blocks.Interfaces.RealOutput y3
  Modelica.Blocks.Interfaces.RealOutput y4

equation
  connect(uFeedthrough1, y1)
  connect(y1, noise.u)
  connect(noise.y, y2)
  connect(y2, limiter.u)
  connect(uFeedthrough1, y2)
  connect(y2, uFeedthrough2)
  connect(limiter.y, y3)
  connect(y3, quantization.u)
  connect(y3, uFeedthrough3)
  connect(quantization.y, y4)
  connect(uFeedthrough3, y4)
  connect(uFeedthrough2, y3)

  connect(sample1.y, y1)

  connect(u, sample1.u)
  connect(y4, y)
end SampleWithADeffects;


Shift the clocked Real input signal by a fraction of the last interval and provide it as clocked output signal. This block shifts the first activation of the clock of the output y by
fraction shiftCounter/resolution of the period (or for a non-periodic signal by a fraction of the last interval)
and the output y is set to the last available value of the input u.
Here, shiftCounter and resolution are positive Integer parameters.

within Modelica.Clocked.RealSignals.Sampler;
block ShiftSample
  "Shift the clocked Real input signal by a fraction of the last interval and provide it as clocked output signal"

  parameter Integer shiftCounter(min=0)=0 "Numerator of shifting formula"
  parameter Integer resolution(min=1)=1 "Denominator of shifting formula"

  Modelica.Blocks.Interfaces.RealInput u
    "Connector of clocked, Real input signal"
  Modelica.Blocks.Interfaces.RealOutput y
    "Connector of clocked, Real output signal"
equation
     y = shiftSample(u,shiftCounter,resolution);
end ShiftSample;


Sub-sample the clocked Real input signal and provide it as clocked output signal. This block sub-samples the clocked Real input signal u and provides it as
clocked output signal y.

within Modelica.Clocked.RealSignals.Sampler;
block SubSample
  "Sub-sample the clocked Real input signal and provide it as clocked output signal"
  parameter Boolean inferFactor=true
    "= true, if sub-sampling factor is inferred"
  parameter Integer factor(min=1)=1
    "Sub-sampling factor >= 1 (ignored if inferFactor=true)"

  Modelica.Blocks.Interfaces.RealInput u
    "Connector of clocked, Real input signal"
  Modelica.Blocks.Interfaces.RealOutput y
    "Connector of clocked, Real output signal (clock of y is slower as clock of u)"
equation
  if inferFactor then
     y = subSample(u);
  else
     y = subSample(u,factor);
  end if;
end SubSample;


Super-sample the clocked Real input signal and provide it as clocked output signal. This block super-samples the clocked Real input signal u and provides it as
clocked output signal y.

within Modelica.Clocked.RealSignals.Sampler;
block SuperSample
  "Super-sample the clocked Real input signal and provide it as clocked output signal"
  parameter Boolean inferFactor=true
    "= true, if super-sampling factor is inferred"
  parameter Integer factor(min=1)=1
    "Super-sampling factor >= 1 (ignored if inferFactor=true)"

  Modelica.Blocks.Interfaces.RealInput u
    "Connector of clocked, Real input signal"
  Modelica.Blocks.Interfaces.RealOutput y
    "Connector of clocked, Real output signal (clock of y is faster as clock of u)"
equation
  if inferFactor then
     y = superSample(u);
  else
     y = superSample(u,factor);
  end if;
end SuperSample;


Super-sample the clocked Real input signal and provide it linearly interpolated as clocked output signal (this is also called an Interpolator). This block super-samples the clocked Real input signal u and provides it
linearly interpolated between the u-values as
clocked output signal y.

within Modelica.Clocked.RealSignals.Sampler;
block SuperSampleInterpolated
  "Super-sample the clocked Real input signal and provide it linearly interpolated as clocked output signal (this is also called an Interpolator)"

  parameter Boolean inferFactor=true
    "= true, if super-sampling factor is inferred"
  parameter Integer factor(min=1)=1
    "Super-sampling factor >= 1 (if inferFactor=false)"
  Modelica.Blocks.Interfaces.RealInput u
    "Connector of clocked, Real input signal"
  Modelica.Blocks.Interfaces.RealOutput y
    "Connector of clocked, Real output signal"
protected
  Real uu(start=0.0);
  Real u_super;
  Real u_pre;
  Real u_preSuper;
  Integer usedFactor = if inferFactor then integer( (superSample(interval(u))/interval(u_super)) + 0.5) else factor;
  Integer ticks(start=0);
  Boolean first(start=true);
equation
  when Clock() then  // clock of u
     uu = u;
     first = false;
     u_pre = if previous(first) then u else previous(uu);
  end when;

  when Clock() then  // clock of y
     if inferFactor then
        u_super = superSample(u);
     else
        u_super = superSample(u,factor);
     end if;
     u_preSuper = superSample(u_pre);
     ticks = if previous(ticks) < usedFactor then previous(ticks) + 1 else 1;
     y = u_preSuper + ticks/usedFactor*(u_super - u_preSuper);
  end when;
end SuperSampleInterpolated;


Generate a Boolean continuous-time square-wave output from a clocked Real input. This block creates a Boolean, continuous time, square-wave output. Whenever the clock of the input signal is active the Boolean output value changes.

within Modelica.Clocked.RealSignals.Sampler.Utilities;
block AssignClockToSquareWaveHold
"Generate a Boolean continuous-time square-wave output from a clocked Real input"
  extends Clocked.ClockSignals.Interfaces.ClockedBlockIcon;
  parameter Boolean y_start=false "Initial value of output signal";
  Modelica.Blocks.Interfaces.RealInput u
  Modelica.Blocks.Interfaces.BooleanOutput y
  "Connector of Boolean output signal"
protected
  Boolean y2(start=y_start);
  Real uu;
equation
  when Clock() then
     uu = u "Dummy assignment to relate clock of u with y2";
     y2 = not previous(y2);
  end when;
  y = hold(y2);
end AssignClockToSquareWaveHold;


Generate a Boolean continuous-time trigger signal from a clocked Real input. This block creates a Boolean, continuous time, trigger signal whenever the clock of the input signal is active.

within Modelica.Clocked.RealSignals.Sampler.Utilities;
block AssignClockToTriggerHold
"Generate a Boolean continuous-time trigger signal from a clocked Real input"
  extends Clocked.ClockSignals.Interfaces.ClockedBlockIcon;
  parameter Boolean y_start=false "Initial value of output signal";
  Modelica.Blocks.Interfaces.RealInput u
  Modelica.Blocks.Interfaces.BooleanOutput y
  "Connector of Boolean output signal"
protected
  Boolean y2(start=y_start);
  Boolean y3(start=y_start, fixed=true);
  Real uu
equation
  when Clock() then
     uu = u "Dummy assignment to relate clock of u with y2";
     y2 = not previous(y2);
  end when;
  y3 = hold(y2);
  y = change(y3);
end AssignClockToTriggerHold;


within Modelica.Clocked.RealSignals.Sampler;
package Utilities "Utility components that are usually not directly used"
   extends Modelica.Icons.UtilitiesPackage;
end Utilities;


Upsample the clocked Real input signal and provide it as clocked output signal. This block upsamples the clocked Real input signal u and provides it as clocked output signal y.

within Modelica.Clocked.RealSignals.Sampler.Utilities;
block UpSample
  "Upsample the clocked Real input signal and provide it as clocked output signal"

  parameter Boolean inferFactor=true
    "= true, if upsampling factor is inferred"
  parameter Integer factor(min=1)=1
    "Upsampling factor >= 1 (if inferFactor=false)"
  Modelica.Blocks.Interfaces.RealInput u
    "Connector of clocked, Real input signal"
  Modelica.Blocks.Interfaces.RealOutput y
    "Connector of clocked, Real output signal (clock of y is faster as clock of u)"
protected
  Real dummy
  Boolean b(start=false);
  Boolean b_super(start=false);
  Real u_super;
equation
  when Clock() then // clock of u
     dummy = u;
     b = not previous(b);
  end when;

  when Clock() then // clock of y
     b_super = superSample(b);
     if inferFactor then
        u_super = superSample(u);
     else
        u_super = superSample(u,factor);
     end if;
     y = if b_super <> previous(b_super) then u_super else 0.0;
  end when;
end UpSample;


Delay a clocked signal for at most one period, in order to model a computational delay. This block delays a clocked Real input signal by the fraction
shiftCounter/resolution of the last interval.
There is the restriction that shiftCounter/resolution ≤ 1.

within Modelica.Clocked.RealSignals.Sampler.Utilities.Internal;
block ComputationalDelay
  "Delay a clocked signal for at most one period, in order to model a computational delay"
extends Clocked.RealSignals.Interfaces.PartialClockedSISO;
  parameter Integer shiftCounter(min=0,max=resolution) = 0
    "(min=0, max=resolution), computational delay = interval()*shiftCounter/resolution"
  parameter Integer resolution(min=1) = 1
    "Time quantization resolution of sample interval"
protected
  Real ubuf(start=0.0);
equation
  assert(resolution >= shiftCounter, "The maximal computational delay has the length of one sample interval, however a larger value than that was set");
  ubuf = u;
  if shiftCounter < resolution then
     y = shiftSample(u, shiftCounter, resolution);
  else
     y = shiftSample(previous(ubuf), shiftCounter, resolution);
  end if;
end ComputationalDelay;


Limit the range of a signal. The Limiter block passes its input signal as output signal
as long as the input is within the specified upper and lower
limits. If this is not the case, the corresponding limits are passed
as output.

within Modelica.Clocked.RealSignals.Sampler.Utilities.Internal;
block Limiter "Limit the range of a signal"
extends Clocked.RealSignals.Interfaces.PartialClockedSISO;
  parameter Real uMax(start=1) "Upper limits of input signals";
  parameter Real uMin= -uMax "Lower limits of input signals";

equation
  assert(uMax >= uMin, "Limiter: Limits must be consistent. However, uMax (=" + String(uMax) +
                       ") < uMin (=" + String(uMin) + ")");
  y = if u > uMax then uMax else if u < uMin then uMin else u;
end Limiter;


within Modelica.Clocked.RealSignals.Sampler.Utilities;
package Internal "Internal blocks and functions that are usually of no interest for the user"
  extends Modelica.Icons.InternalPackage;
end Internal;


DAC quantization effects. The clocked Real input signal is value discretized
(the discretization is defined by parameter bits).

within Modelica.Clocked.RealSignals.Sampler.Utilities.Internal;
model Quantization "DAC quantization effects"
extends Clocked.RealSignals.Interfaces.PartialClockedSISO;

  parameter Boolean quantized = false
    "= true, if quantization effects shall be computed";
  parameter Real yMax=1 "Upper limit of output";
  parameter Real yMin=-1 "Lower limit of output";
  parameter Integer bits(min=1)=8
    "Number of bits of quantization (if quantized = true)";
protected
  parameter Real resolution = if quantized then ((yMax - yMin)/2^bits) else 0;
equation

  if quantized then
    y = resolution*floor(abs(u/resolution) + 0.5)*
           (if u >= 0 then +1 else -1);
  else
    y = u;
  end if;
end Quantization;


Add band-limited uniform noise using a variant of the Wichmann-Hill algorithm. This block adds uniformly distributed noise
in the range noiseMin … noiseMax to the clocked Real input signal
and provides the sum as clocked Real output signal.

within Modelica.Clocked.RealSignals.Sampler.Utilities.Internal;
block UniformNoise "Add band-limited uniform noise using a variant of the Wichmann-Hill algorithm"
  extends Clocked.RealSignals.Interfaces.PartialNoise;
  parameter Integer firstSeed[3](each min=0, each max=255) = {23,87,187}
    "Integer[3] defining random sequence; required element range: 0..255";
protected
  Integer seedState[3](start=firstSeed, each fixed=true)
    "State of seed"
  Real noise "Noise in the range 0..1"
equation
  (noise,seedState) =
    Clocked.RealSignals.Sampler.Utilities.Internal.random(previous(
    seedState));
    y = u + noiseMin + (noiseMax - noiseMin)*noise;
end UniformNoise;


Add band-limited uniform noise based on a xorshift64* number generator. This block adds uniformly distributed noise in the range noiseMin … noiseMax to the clocked Real input signal and provides the sum as clocked Real output signal.

within Modelica.Clocked.RealSignals.Sampler.Utilities.Internal;
block UniformNoiseXorshift64star
  "Add band-limited uniform noise based on a xorshift64* number generator"
  extends Clocked.RealSignals.Interfaces.PartialNoise;

  parameter Integer globalSeed = 30020 "Global seed to initialize random number generator";
  // Random number generators with exposed state
  parameter Integer localSeed = 614657 "Local seed to initialize random number generator";
  output Real r64(start=0) "Random number generated with Xorshift64star";
protected
  discrete Integer state64[2](start=Modelica.Math.Random.Generators.Xorshift64star.initialState(localSeed, globalSeed));

equation
  (r64, state64) = Modelica.Math.Random.Generators.Xorshift64star.random(previous(state64));
   y = u + noiseMin + (noiseMax - noiseMin)*r64;
end UniformNoiseXorshift64star;


within Modelica.Clocked.RealSignals;
package TickBasedSources "Package of signal source blocks generating clocked ticked/sample based Real signals"
   extends Modelica.Icons.SourcesPackage;
end TickBasedSources;


Generate ramp signal based on counted clock ticks. The Real output y is a ramp signal. The signal is defined in terms of clock ticks instead of simulation time:

within Modelica.Clocked.RealSignals.TickBasedSources;
block Ramp "Generate ramp signal based on counted clock ticks"
  extends Interfaces.PartialClockedSO;
  parameter Real height=1 "Height of ramp";
  parameter Integer durationTicks(min=1) = 1
"Durations of ramp in number of clock ticks";
  parameter Real offset=0 "Offset of output signal";

  parameter Integer startTick(min=1) = 1
"Output y = offset for clock tick < startTick";
protected
  Integer counter(start=0);
equation
  // stop counter after counter = startTick+durationTicks to avoid integer overflow for long running simulations
  counter = if previous(counter) < startTick+durationTicks then previous(counter) + 1 else previous(counter);

  y = offset + (if counter < startTick then 0 else if counter < (startTick +
    durationTicks) then (counter - startTick)*height/durationTicks else height);
end Ramp;


Generate sine signal. The Real output y is a sine signal. The signal is defined in terms of clock ticks instead of simulation time:

within Modelica.Clocked.RealSignals.TickBasedSources;
block Sine "Generate sine signal"
  extends Interfaces.PartialClockedSO;
  parameter Real amplitude=1 "Amplitude of sine wave";
  parameter Real offset=0 "Offset of output signal";
  parameter Integer periodTicks = 10
"Number of clock ticks for one period";
  parameter Integer periodOffset=0
"Number of periods the sine signal is offset";
  parameter Integer startTick(min=1)=1
"Output = offset for clock tick < startTick";
protected
  constant Real pi=Modelica.Constants.pi;
  Real Ts = interval(y) "Sample time (periodic or non-periodic)";
  Integer counter(start=0);
  Boolean startOutput(start=false)
"Flag whether counter >= startTick reached once";
equation
  // restart counter after reaching threshold to avoid integer overflow for long running simulations
  if previous(startOutput) then
      counter = if previous(counter) == (periodTicks-1) then 0 else previous(counter) + 1;
      startOutput = previous(startOutput);
  else
    startOutput = previous(counter) >= (startTick-1);
    counter = if startOutput then 0 else previous(counter) + 1;
  end if;

  y = offset + (if startOutput then
  amplitude*Modelica.Math.sin(2*pi/periodTicks*(counter + periodOffset)) else 0);
end Sine;


Generate step signal of type Real based on counted clock ticks. The Real output y is a step signal. The signal is defined in terms of clock ticks instead of simulation time:

within Modelica.Clocked.RealSignals.TickBasedSources;
block Step "Generate step signal of type Real based on counted clock ticks"
  extends Interfaces.PartialClockedSO;
  parameter Real height = 1 "Height of step";
  parameter Real offset = 0 "Offset of output signal y";
  parameter Integer startTick(min=1) = 1
"Output y = offset for clock tick < startTick";
protected
  Integer counter(start=0);
equation
  // stop counter after counter = startTick to avoid integer overflow for long running simulations
  counter = if previous(counter) < startTick then previous(counter) + 1 else previous(counter);
  y = offset + (if counter < startTick then 0 else height);
end Step;


within Modelica.Clocked.RealSignals;
package TimeBasedSources "Package of signal source blocks generating clocked simulation time based Real signals"
   extends Modelica.Icons.SourcesPackage;
end TimeBasedSources;


Generate ramp signal. The block is similar to the block in Modelica.Blocks.Sources.Ramp, but adapted to work in clocked partitions (by internal sampling of the continuous time variable).

within Modelica.Clocked.RealSignals.TimeBasedSources;
block Ramp "Generate ramp signal"
  extends Interfaces.PartialClockedSO;
  parameter Real height=1 "Height of ramp";
  parameter SI.Time duration(min=Modelica.Constants.small, start = 2)
"Durations of ramp";
  parameter Real offset=0 "Offset of output signal";
  parameter SI.Time startTime=0
"Output = offset for time < startTime";
protected
  SI.Time simTime;
equation
  simTime = sample(time);
  y = offset + (if simTime < startTime then 0 else if simTime < (startTime +
    duration) then (simTime - startTime)*height/duration else height);
end Ramp;


Generate sine signal. The block is similar to the block in Modelica.Blocks.Sources.Sine, but adapted to work in clocked partitions (by internal sampling of the continuous time variable).

within Modelica.Clocked.RealSignals.TimeBasedSources;
block Sine "Generate sine signal"
  extends Interfaces.PartialClockedSO;
  parameter Real amplitude=1 "Amplitude of sine wave";
  parameter SI.Frequency f(start=1)
"Frequency of sine wave";
  parameter SI.Angle phase=0 "Phase of sine wave";
  parameter Real offset=0 "Offset of output signal";
  parameter SI.Time startTime=0
"Output = offset for time < startTime";
protected
  constant Real pi=Modelica.Constants.pi;
  SI.Time simTime;
equation
  simTime = sample(time);
  y = offset + (if simTime < startTime then 0 else amplitude*
    Modelica.Math.sin(2*pi*f*(simTime - startTime) + phase));
end Sine;


Generate step signal of type Real. The block is similar to the block in Modelica.Blocks.Sources.Step, but adapted to work in clocked partitions (by internal sampling of the continuous time variable).

within Modelica.Clocked.RealSignals.TimeBasedSources;
block Step "Generate step signal of type Real"
  extends Interfaces.PartialClockedSO;
  parameter Real height = 1 "Height of step";
  parameter Real offset = 0 "Offset of output signal y";
  parameter SI.Time startTime = 0
"Output y = offset for time < startTime";
protected
  SI.Time simTime;
equation
  simTime = sample(time);
  y = offset + (if simTime < startTime then 0 else height);
end Step;


within Modelica.Clocked;
package Types "Library of types with choices, especially to build menus"
extends Modelica.Icons.TypesPackage;
end Types;


within Modelica;
package ComplexBlocks "Library of basic input/output control blocks with Complex signals"
  extends Modelica.Icons.Package;
end ComplexBlocks;


Output the arc cosine of the input. This blocks computes the output y as the
cosine-inverse of the input u. Optionally, the input u can be processed conjugate complex, when parameter useConjugateInput is true. Depending on useConjugateInput the internal signal uInternal represents either the original or the conjugate complex input signal.

within Modelica.ComplexBlocks.ComplexMath;
block Acos "Output the arc cosine of the input"
  extends Interfaces.ComplexSISO;
equation
  y = Modelica.ComplexMath.acos(uInternal);

"));
end Acos;


Output the sum of the two inputs. This blocks computes output y as sum of the
two input signals u1 and u2. Optionally, either input u1 or u2 or both inputs can be processed conjugate complex, when parameters useConjugateInput1 and useConjugateInput2 are true, respectively.

within Modelica.ComplexBlocks.ComplexMath;
block Add "Output the sum of the two inputs"
  extends Interfaces.ComplexSI2SO;
  parameter Complex k1=Complex(1, 0) "Gain of input 1";
  parameter Complex k2=Complex(1, 0) "Gain of input 2";
equation
  y = k1*u1Internal + k2*u2Internal;
end Add;


Output the sum of the three inputs. This blocks computes output y as sum of the
three input signals u1, u2 and u3. Optionally, inputs u1 and u2 and u3 can be processed conjugate complex, when parameters useConjugateInput1 and useConjugateInput2 and useConjugateInput3 are true, respectively.

within Modelica.ComplexBlocks.ComplexMath;
block Add3 "Output the sum of the three inputs"
  extends Modelica.ComplexBlocks.Icons.ComplexBlock;

  parameter Complex k1=Complex(1, 0) "Gain of upper input";
  parameter Boolean useConjugateInput1=false
    "If true, input 1 is processed conjugate complex";

  parameter Complex k2=Complex(1, 0) "Gain of middle input";
  parameter Boolean useConjugateInput2=false
    "If true, input 2 is processed conjugate complex";

  parameter Complex k3=Complex(1, 0) "Gain of lower input";
  parameter Boolean useConjugateInput3=false
    "If true, input 3 is processed conjugate complex";

  Interfaces.ComplexInput u1 "Connector 1 of Complex input signals"
  Interfaces.ComplexInput u2 "Connector 2 of Complex input signals"
  Interfaces.ComplexInput u3 "Connector 3 of Complex input signals"
  Interfaces.ComplexOutput y "Connector of Complex output signals"

equation
  y = k1*(if useConjugateInput1 then Modelica.ComplexMath.conj(u1) else u1)
     + k2*(if useConjugateInput2 then Modelica.ComplexMath.conj(u2) else u2)
     + k3*(if useConjugateInput3 then Modelica.ComplexMath.conj(u3) else u3);

Example parameters:

k1 = +2,

k2 = -3,

k3 = +1,

useConjugateInput1 = true,

useConjugateInput2 = false

useConjugateInput3 = false

result in the following equation:

y = 2 * Modelica.ComplexMath.conj(u1) - 3 * u2 + u3;

"),
    Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{
            100,100}}), graphics={Text(extent={{-98,50},{5,90}}, textString="%k1"),
            Text(extent={{-98,-20},{5,20}}, textString="%k2"),
            Text(extent={{-98,-50},{5,-90}}, textString="%k3"),
            Text(extent={{10,40},{90,-40}},
          textColor={85,170,255},
          textString="+")}));
end Add3;


Output the arc sine of the input. This blocks computes the output y as the
sine-inverse of the input u. Optionally, the input u can be processed conjugate complex, when parameter useConjugateInput is true. Depending on useConjugateInput the internal signal uInternal represents either the original or the conjugate complex input signal.

within Modelica.ComplexBlocks.ComplexMath;
block Asin "Output the arc sine of the input"
  extends Interfaces.ComplexSISO;
equation
  y = Modelica.ComplexMath.asin(uInternal);

"));
end Asin;


Output the arc tangent of the input. This blocks computes the output y as the
tangent-inverse of the input u. Optionally, the input u can be processed conjugate complex, when parameter useConjugateInput is true. Depending on useConjugateInput the internal signal uInternal represents either the original or the conjugate complex input signal.

within Modelica.ComplexBlocks.ComplexMath;
block Atan "Output the arc tangent of the input"
  extends Interfaces.ComplexSISO;
equation
  y = Modelica.ComplexMath.atan(uInternal);

"));
end Atan;


Calculate quantities to plot Bode diagram. This complex block is used to determine variables of a Bode diagram for the output y.
The output y is calculated by u / divisor if useDivisor == true.
Otherwise the output y = u.

within Modelica.ComplexBlocks.ComplexMath;
block Bode "Calculate quantities to plot Bode diagram"
  extends Modelica.ComplexBlocks.Icons.ComplexBlock;
  parameter Boolean useDivisor = true "Use divisor input, if true"
  constant Modelica.Units.SI.AmplitudeLevelDifference dB = 20 "Amplitude level difference";
  Interfaces.ComplexInput u "Dividend if useDivisor == true"
  Interfaces.ComplexInput divisor if useDivisor "Divisor"
  Blocks.Interfaces.RealOutput abs_y "Absolute value of ratio u / divisor"
  Blocks.Interfaces.RealOutput arg_y(unit="rad") "Angle of ratio u / divisor"
  Interfaces.ComplexOutput y "Quotient y = u / divisor"
  Sources.ComplexConstant complexOne(final k=Complex(1, 0)) if not useDivisor "Complex(1,0)"
  Division division(final useConjugateInput1=false, final useConjugateInput2=false)
  ComplexToPolar complexToPolar(final useConjugateInput=false)
  Blocks.Interfaces.RealOutput dB_y(unit="dB") "Log10 of absolute value of ratio u / divisor"
  Blocks.Math.Log10 log10_y
  Blocks.Math.Gain gain(final k=dB)
  Blocks.Nonlinear.Limiter limiter(final uMax=Modelica.Constants.inf, final uMin=Modelica.Constants.eps)
equation

  connect(complexOne.y, division.u2)
  connect(divisor, division.u2)
  connect(division.u1, u)
  connect(division.y, y)
  connect(complexToPolar.u, y)
  connect(complexToPolar.phi, arg_y)
  connect(complexToPolar.len, abs_y)
  connect(log10_y.y, gain.u)
  connect(gain.y, dB_y)
  connect(limiter.y, log10_y.u)
  connect(complexToPolar.len, limiter.u)
end Bode;


Converts complex to polar representation. Converts the Complex input u to the Real outputs len (length, absolute) and phi (angle, argument).

within Modelica.ComplexBlocks.ComplexMath;
block ComplexToPolar "Converts complex to polar representation"
  extends Modelica.ComplexBlocks.Icons.ComplexBlock;
  Blocks.Interfaces.RealOutput len
  Blocks.Interfaces.RealOutput phi(unit="rad")
  Interfaces.ComplexInput u
  parameter Boolean useConjugateInput=false
    "If true, input is processed conjugate complex";
equation
  len = sqrt(u.re^2 + u.im^2);
  phi = (if useConjugateInput then Modelica.Math.atan2(-u.im, u.re) else
    Modelica.Math.atan2(u.im, u.re));
end ComplexToPolar;


Converts complex to Cartesian representation. Converts the Complex input u to the Real outputs re (real part) and im (imaginary part).

within Modelica.ComplexBlocks.ComplexMath;
block ComplexToReal "Converts complex to Cartesian representation"
  extends Modelica.ComplexBlocks.Icons.ComplexBlock;
  Blocks.Interfaces.RealOutput re
  Blocks.Interfaces.RealOutput im
  Interfaces.ComplexInput u
  parameter Boolean useConjugateInput=false
    "If true, input is processed conjugate complex";
equation
  re = u.re;
  im = (if useConjugateInput then -u.im else u.im);
end ComplexToReal;


Output is equal to the conjugate complex input signal. This block computes output y as
conjugate complex input u.

within Modelica.ComplexBlocks.ComplexMath;
block Conj "Output is equal to the conjugate complex input signal"

  extends Modelica.ComplexBlocks.Interfaces.ComplexSISO(final
      useConjugateInput=true);

equation
  y = uInternal;
end Conj;


Output the cosine of the input. This blocks computes the output y
as cos of the input u. Optionally, the input u can be processed conjugate complex, when parameter useConjugateInput is true. Depending on useConjugateInput the internal signal uInternal represents either the original or the conjugate complex input signal.

within Modelica.ComplexBlocks.ComplexMath;
block Cos "Output the cosine of the input"
  extends Interfaces.ComplexSISO;
equation
  y = Modelica.ComplexMath.cos(uInternal);

"));
end Cos;


Output the hyperbolic cosine of the input. This blocks computes the output y as the
hyperbolic cosine of the input u. Optionally, the input u can be processed conjugate complex, when parameter useConjugateInput is true. Depending on useConjugateInput the internal signal uInternal represents either the original or the conjugate complex input signal.

within Modelica.ComplexBlocks.ComplexMath;
block Cosh "Output the hyperbolic cosine of the input"
  extends Interfaces.ComplexSISO;
equation
  y = Modelica.ComplexMath.cosh(uInternal);

"));
end Cosh;


Output first input divided by second input. This block computes the output y (element-wise)
by dividing the corresponding elements of
the two inputs u1 and u2. Optionally, either input u1 or u2 or both inputs can be processed conjugate complex, when parameters useConjugateInput1 and useConjugateInput2 are true, respectively. Depending on useConjugateInput1 and useConjugateInput2 the internal signals represent either the original or the conjugate complex input signal.

within Modelica.ComplexBlocks.ComplexMath;
block Division "Output first input divided by second input"
  extends Interfaces.ComplexSI2SO;
  parameter Boolean useConjugateInput1=false
    "If true, input 1 is processed conjugate complex";
  parameter Boolean useConjugateInput2=false
    "If true, input 2 is processed conjugate complex";
equation
  y = (if useConjugateInput1 then Modelica.ComplexMath.conj(u1) else u1)/(
    if useConjugateInput2 then Modelica.ComplexMath.conj(u2) else u2);
end Division;


Output the exponential (base e) of the input. This blocks computes the output y as the
exponential (of base e) of the input u. Optionally, the input u can be processed conjugate complex, when parameter useConjugateInput is true. Depending on useConjugateInput the internal signal uInternal represents either the original or the conjugate complex input signal.

within Modelica.ComplexBlocks.ComplexMath;
block Exp "Output the exponential (base e) of the input"
  extends Interfaces.ComplexSISO;
equation
  y = Modelica.ComplexMath.exp(uInternal);

"));
end Exp;


Output difference between commanded input 1 and feedback input 2. This blocks computes output y as difference of the
commanded input u1 and the feedback
input u2. Optionally, either input u1 or u2 or both inputs can be processed conjugate complex, when parameters useConjugateInput1 and useConjugateInput2 are true, respectively.

within Modelica.ComplexBlocks.ComplexMath;
block Feedback
  "Output difference between commanded input 1 and feedback input 2"

  Interfaces.ComplexInput u1
  Interfaces.ComplexInput u2
  Interfaces.ComplexOutput y

  parameter Boolean useConjugateInput1=false
    "If true, input 1 is processed conjugate complex";
  parameter Boolean useConjugateInput2=false
    "If true, input 2 is processed conjugate complex";

equation
  y = (if useConjugateInput1 then Modelica.ComplexMath.conj(u1) else u1) -
    (if useConjugateInput2 then Modelica.ComplexMath.conj(u2) else u2);

Example parameters:

useConjugateInput1 = true,

useConjugateInput2 = false

result in the following equation:

y = Modelica.ComplexMath.conj(u1) - u2

"),
    Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{
            100,100}}), graphics={Ellipse(
              extent={{-20,20},{20,-20}},
              lineColor={85,170,255},
              fillColor={235,235,235},
              fillPattern=FillPattern.Solid),Line(points={{-60,0},{-20,0}},
          color={85,170,255}),
                           Line(points={{20,0},{80,0}}, color={85,170,255}),
          Line(points={{0,-20},{0,-60}}, color={85,170,255}),
                              Text(
              extent={{-150,94},{150,44}},
              textString="%name",
              textColor={0,0,255}),                       Text(
              extent={{20,-20},{100,-100}},
          textColor={85,170,255},
          textString="-")}));
end Feedback;


Output the product of a gain value with the input signal. This block computes output y as
product of gain k with the
input u. Optionally, the input u can be processed conjugate complex, when parameter useConjugateInput is true. Depending on useConjugateInput either the original or the conjugate complex input signal are processed.

within Modelica.ComplexBlocks.ComplexMath;
block Gain "Output the product of a gain value with the input signal"

  parameter Complex k(re(start=1), im(start=0))
    "Gain value multiplied with input signal";
  parameter Boolean useConjugateInput=false
    "If true, input is processed conjugate complex";
  Interfaces.ComplexInput u "Input signal connector"
  Interfaces.ComplexOutput y "Output signal connector"

equation
  y = k*(if useConjugateInput then Modelica.ComplexMath.conj(u) else u);

Example: If useConjugateInput = true and k = 2 the output signal y = 2 * Modelica.ComplexMath.conj(u).

"),
    Icon(coordinateSystem(preserveAspectRatio=true, extent={{-100,-100},{
            100,100}}), graphics={Polygon(
          points={{-100,-100},{-100,100},{100,0},{-100,-100}},
          lineColor={85,170,255},
          fillColor={255,255,255},
          fillPattern=FillPattern.Solid),    Text(
              extent={{-150,-140},{150,-100}},
              textString="k=%k"),Text(
              extent={{-150,140},{150,100}},
              textString="%name",
              textColor={0,0,255})}));
end Gain;


Output the natural (base e) logarithm of the input (input <> '0' required). This blocks computes the output y as the
natural (base e) logarithm of the input u. Optionally, the input u can be processed conjugate complex, when parameter useConjugateInput is true. Depending on useConjugateInput the internal signal uInternal represents either the original or the conjugate complex input signal.

within Modelica.ComplexBlocks.ComplexMath;
block Log
  "Output the natural (base e) logarithm of the input (input <> '0' required)"
  extends Interfaces.ComplexSISO;
equation
  y = Modelica.ComplexMath.log(uInternal);

An error occurs if the elements of the input u is zero.

"));
end Log;


within Modelica.ComplexBlocks;
package ComplexMath "Library of mathematical functions as input/output blocks"
  extends Modelica.Icons.Package;
end ComplexMath;


Converts polar representation to complex. Converts the Real inputs len (length, absolute) and phi (angle, argument) to the Complex output y.

within Modelica.ComplexBlocks.ComplexMath;
block PolarToComplex "Converts polar representation to complex"
  extends Modelica.ComplexBlocks.Interfaces.ComplexSO;
  Blocks.Interfaces.RealInput len
  Blocks.Interfaces.RealInput phi(unit="rad")
equation
  y = Complex(len*cos(phi), len*sin(phi));
end PolarToComplex;


Output product of the two inputs. This blocks computes the output y (element-wise)
as product of the corresponding elements of
the two inputs u1 and u2. Optionally, either input u1 or u2 or both inputs can be processed conjugate complex, when parameters useConjugateInput1 and useConjugateInput2 are true, respectively. Depending on useConjugateInput1 and useConjugateInput2 the internal signals represent either the original or the conjugate complex input signal.

within Modelica.ComplexBlocks.ComplexMath;
block Product "Output product of the two inputs"
  extends Interfaces.ComplexSI2SO;
equation
  y = u1Internal*u2Internal;
end Product;


Converts Cartesian representation to complex. Converts the Real inputs re (real part) and im (imaginary part) to the Complex output y.

within Modelica.ComplexBlocks.ComplexMath;
block RealToComplex "Converts Cartesian representation to complex"
  extends Modelica.ComplexBlocks.Interfaces.ComplexSO;
  Blocks.Interfaces.RealInput re
  Blocks.Interfaces.RealInput im
equation
  y = Complex(re, im);
end RealToComplex;


Output the sine of the input. This blocks computes the output y
as sine of the input u. Optionally, the input u can be processed conjugate complex, when parameter useConjugateInput is true. Depending on useConjugateInput the internal signal uInternal represents either the original or the conjugate complex input signal.

within Modelica.ComplexBlocks.ComplexMath;
block Sin "Output the sine of the input"
  extends Interfaces.ComplexSISO;
equation
  y = Modelica.ComplexMath.sin(uInternal);

"));
end Sin;


Output the hyperbolic sine of the input. This blocks computes the output y as the
hyperbolic sine of the input u. Optionally, the input u can be processed conjugate complex, when parameter useConjugateInput is true. Depending on useConjugateInput the internal signal uInternal represents either the original or the conjugate complex input signal.

within Modelica.ComplexBlocks.ComplexMath;
block Sinh "Output the hyperbolic sine of the input"
  extends Interfaces.ComplexSISO;
equation
  y = Modelica.ComplexMath.sinh(uInternal);

"));
end Sinh;


Output the square root of the input (= principal square root of complex number). This blocks computes the output y
as square root of the input u (= principal square root of the complex input). Optionally, the input u can be processed conjugate complex, when parameter useConjugateInput is true. Depending on useConjugateInput the internal signal uInternal represents either the original or the conjugate complex input signal.

within Modelica.ComplexBlocks.ComplexMath;
block Sqrt
  "Output the square root of the input (= principal square root of complex number)"
  extends Interfaces.ComplexSISO;
equation
  y = Modelica.ComplexMath.sqrt(uInternal);
</pre></blockquote>
</html>"));
end Sqrt;


Output the sum of the elements of the input vector. This blocks computes output y as
sum of the elements of the input signal vector
u:

within Modelica.ComplexBlocks.ComplexMath;
block Sum "Output the sum of the elements of the input vector"
  extends Interfaces.ComplexMISO;
  parameter Complex k[nin]=fill(Complex(1, 0), nin)
    "Optional: sum coefficients";
equation
  y = k*uInternal;
end Sum;


Output the tangent of the input. This blocks computes the output y
as tan of the input u. Optionally, the input u can be processed conjugate complex, when parameter useConjugateInput is true. Depending on useConjugateInput the internal signal uInternal represents either the original or the conjugate complex input signal.

within Modelica.ComplexBlocks.ComplexMath;
block Tan "Output the tangent of the input"
  extends Interfaces.ComplexSISO;
equation
  y = Modelica.ComplexMath.tan(uInternal);

"));
end Tan;


Output the hyperbolic tangent of the input. This blocks computes the output y as the
hyperbolic tangent of the input u. Optionally, the input u can be processed conjugate complex, when parameter useConjugateInput is true. Depending on useConjugateInput the internal signal uInternal represents either the original or the conjugate complex input signal.

within Modelica.ComplexBlocks.ComplexMath;
block Tanh "Output the hyperbolic tangent of the input"
  extends Interfaces.ComplexSISO;
equation
  y = Modelica.ComplexMath.tanh(uInternal);

"));
end Tanh;


Complex Transfer Function. The complex input u is multiplied by the complex transfer function (depending on the angular frequency input w) to obtain the complex output y (nb = dimension of b, na = dimension of a):

within Modelica.ComplexBlocks.ComplexMath;
block TransferFunction "Complex Transfer Function"
  extends Modelica.ComplexBlocks.Interfaces.ComplexSISO;
  import Modelica.ComplexMath.j;
  parameter Real b[:]={1}
    "Numerator coefficients of transfer function (e.g., 2*(jw)+3 is specified as {2,3})";
  parameter Real a[:]={1}
    "Denominator coefficients of transfer function (e.g., 5*(jw)+6 is specified as {5,6})";
  Modelica.Blocks.Interfaces.RealInput w(unit="rad/s") "Angular frequency input"
protected
  Complex bw[size(b,1)];
  Complex aw[size(a,1)];
  Complex bSum;
  Complex aSum;
  function powerOfJ "Internal function to compute j^k for any integer"
    input Integer k;
    output Complex x;
  protected
    Integer m=mod(k,4);
  algorithm
   x:=if m==0 then Complex(1) elseif m==1 then j elseif m==2 then Complex(-1) else -j;
  end powerOfJ;
equation
  // Avoid computing power of Complex numbers - since it fails for w==0
  bw = {b[i]*(w)^(size(b,1)-i)*powerOfJ(size(b,1)-i) for i in 1:size(b,1)};
  aw = {a[i]*(w)^(size(a,1)-i)*powerOfJ(size(a,1)-i) for i in 1:size(a,1)};
  bSum = Complex(sum(bw.re), sum(bw.im));
  aSum = Complex(sum(aw.re), sum(aw.im));
  y = u*bSum/aSum;
end TransferFunction;


within Modelica.ComplexBlocks;
package Examples "Library of examples to demonstrate the usage of package Blocks"
  extends Modelica.Icons.ExamplesPackage;
end Examples;