Test complex transfer function block. This example shows the response of a PT2 (mechanical spring-mass-damper system with
an acceleration acting on the mass) defined by its transfer function

within Modelica.ComplexBlocks.Examples;
model ShowTransferFunction "Test complex transfer function block"
  extends Modelica.Icons.Example;
  parameter Modelica.Units.SI.Mass m = 0.2 "Mass";
  parameter Modelica.Units.SI.TranslationalDampingConstant d = 0.01 "Damping coefficient (not the damping ratio)";
  parameter Modelica.Units.SI.TranslationalSpringConstant c = 0.1 "Stiffness";
protected
  final constant Modelica.Units.SI.Mass oneUnitMass = 1
    "Helping constant to satisfy unit check";
  final constant Modelica.Units.SI.TranslationalDampingConstant oneUnitDampingConstant = 1
    "Helping constant to satisfy unit check";
  final constant Modelica.Units.SI.TranslationalSpringConstant oneUnitSpringConstant = 1
    "Helping constant to satisfy unit check";
public
  final parameter Real b[:]={-m/oneUnitMass} "Unitless numerator polynomial coefficients {-m} of the transfer function";
  final parameter Real a[:]={m/oneUnitMass, d/oneUnitDampingConstant, c/oneUnitSpringConstant}
    "Unitless denominator polynomial coefficients {m,d,c} of the transfer function";
  parameter Real wMin=0.01 "Lower bound for frequency sweep";
  parameter Real wMax=100 "Upper bound for frequency sweep";
  Real lg_w=log10(logFrequencySweep.y) "Logarithm of frequency";
  Real dB=20*log10(complexToPolar.len) "Magnitude of the transfer function in decibel";
  Modelica.Units.SI.Angle phi(displayUnit="deg")=complexToPolar.phi "Argument of the transfer function";
  Modelica.Blocks.Sources.LogFrequencySweep logFrequencySweep(
    duration=1,
    wMin=wMin,
    wMax=wMax)
  Modelica.ComplexBlocks.Sources.ComplexConstant const(k(re=1, im=0))
  Modelica.ComplexBlocks.ComplexMath.TransferFunction transferFunction(final b=b,
      final a=a)
  Modelica.ComplexBlocks.ComplexMath.ComplexToPolar complexToPolar
equation
  connect(const.y, transferFunction.u)
  connect(logFrequencySweep.y, transferFunction.w)
  connect(transferFunction.y, complexToPolar.u)
end ShowTransferFunction;


Test the conversion blocks. A Complex signal is defined by its length and angle, both linearly rising with time.
Plotting the imaginary part versus the real part, you will see an Archimedean spiral.

within Modelica.ComplexBlocks.Examples;
model TestConversionBlock "Test the conversion blocks"
  extends Modelica.Icons.Example;
  Modelica.Blocks.Sources.Ramp len(duration=1, offset=1E-6)
  Modelica.Blocks.Sources.Ramp phi(height=4*Modelica.Constants.pi, duration=
       1)
  Modelica.ComplexBlocks.ComplexMath.PolarToComplex polarToComplex
  Modelica.ComplexBlocks.ComplexMath.ComplexToReal complexToReal
equation
  connect(phi.y, polarToComplex.phi)
  connect(len.y, polarToComplex.len)
  connect(polarToComplex.y, complexToReal.u)
end TestConversionBlock;


within Modelica.ComplexBlocks.Icons;
partial block ComplexBlock "Basic graphical layout of Complex input/output block"
end ComplexBlock;


Icons for ComplexBlocks

within Modelica.ComplexBlocks;
package Icons "Icons for ComplexBlocks"
  extends Modelica.Icons.IconsPackage;
end Icons;


2 Multiple Input / Multiple Output continuous control block. Block has two continuous Complex input vectors u1 and u2 and one
continuous Complex output vector y.
All vectors have the same number of elements.

within Modelica.ComplexBlocks.Interfaces;
partial block ComplexMI2MO
  "2 Multiple Input / Multiple Output continuous control block"
  extends Modelica.ComplexBlocks.Icons.ComplexBlock;
  parameter Integer n=1 "Dimension of input and output vectors.";
  ComplexInput u1[n] "Connector 1 of Complex input signals"
  ComplexInput u2[n] "Connector 2 of Complex input signals"
  ComplexOutput y[n] "Connector of Complex output signals"

  parameter Boolean useConjugateInput1[n]=fill(false, n)
    "If true, inputs 1 are processed conjugate complex";
  parameter Boolean useConjugateInput2[n]=fill(false, n)
    "If true, inputs 2 are processed conjugate complex";
protected
  Complex u1Internal[n]={if useConjugateInput1[k] then
      Modelica.ComplexMath.conj(u1[k]) else u1[k] for k in 1:n}
    "Equals either u1 or conjugate complex input u1 if useComplexInput = true";
  Complex u2Internal[n]={if useConjugateInput2[k] then
      Modelica.ComplexMath.conj(u2[k]) else u2[k] for k in 1:n}
    "Equals either u1 or conjugate complex input u1 if useComplexInput = true";
end ComplexMI2MO;


Multiple Input Multiple Output continuous control block. Block has a continuous Complex input vector and a continuous Complex output signal vector.
The signal sizes of the input and output vector may be different.

within Modelica.ComplexBlocks.Interfaces;
partial block ComplexMIMO
  "Multiple Input Multiple Output continuous control block"
  extends Modelica.ComplexBlocks.Icons.ComplexBlock;
  parameter Integer nin=1 "Number of inputs";
  parameter Integer nout=1 "Number of outputs";
  ComplexInput u[nin] "Connector of Complex input signals"
  ComplexOutput y[nout] "Connector of Complex output signals"
  parameter Boolean useConjugateInput[nin]=fill(false, nin)
    "If true, inputs are processed conjugate complex";
protected
  Complex uInternal[nin]={if useConjugateInput[k] then
      Modelica.ComplexMath.conj(u[k]) else u[k] for k in 1:nin}
    "Equals either u or conjugate complex input u if useComplexInput = true";
end ComplexMIMO;


Multiple Input Multiple Output continuous control block with same number of inputs and outputs. Block has a continuous Complex input vector and a continuous Complex output signal vector
where the signal sizes of the input and output vector are identical.

within Modelica.ComplexBlocks.Interfaces;
partial block ComplexMIMOs
  "Multiple Input Multiple Output continuous control block with same number of inputs and outputs"
  extends Modelica.ComplexBlocks.Icons.ComplexBlock;
  parameter Integer n=1 "Number of inputs (= number of outputs)";
  ComplexInput u[n] "Connector of Complex input signals"
  ComplexOutput y[n] "Connector of Complex output signals"

  parameter Boolean useConjugateInput[n]=fill(false, n)
    "If true, inputs are processed conjugate complex";
protected
  Complex uInternal[n]={if useConjugateInput[k] then
      Modelica.ComplexMath.conj(u[k]) else u[k] for k in 1:n}
    "Equals either u or conjugate complex input u if useComplexInput = true";
end ComplexMIMOs;


Multiple Input Single Output continuous control block. Block has a vector of continuous Complex input signals and
one continuous Complex output signal.

within Modelica.ComplexBlocks.Interfaces;
partial block ComplexMISO
  "Multiple Input Single Output continuous control block"
  extends Modelica.ComplexBlocks.Icons.ComplexBlock;
  parameter Integer nin=1 "Number of inputs";
  ComplexInput u[nin] "Connector of Complex input signals"
  ComplexOutput y "Connector of Complex output signal"

  parameter Boolean useConjugateInput[nin]=fill(false, nin)
    "If true, inputs are processed conjugate complex";
protected
  Complex uInternal[nin]={if useConjugateInput[k] then
      Modelica.ComplexMath.conj(u[k]) else u[k] for k in 1:nin}
    "Equals either u or conjugate complex input u if useComplexInput = true";
end ComplexMISO;


Multiple Output continuous control block. Block has one continuous Complex output signal vector.

within Modelica.ComplexBlocks.Interfaces;
partial block ComplexMO "Multiple Output continuous control block"
  extends Modelica.ComplexBlocks.Icons.ComplexBlock;
  parameter Integer nout(min=1) = 1 "Number of outputs";
  ComplexOutput y[nout] "Connector of Complex output signals"
end ComplexMO;


2 Single Input / 1 Single Output continuous control block. Block has two continuous Complex input signals u1 and u2 and one
continuous Complex output signal y.

within Modelica.ComplexBlocks.Interfaces;
partial block ComplexSI2SO
  "2 Single Input / 1 Single Output continuous control block"
  extends Modelica.ComplexBlocks.Icons.ComplexBlock;
  ComplexInput u1 "Connector of Complex input signal 1"
  ComplexInput u2 "Connector of Complex input signal 2"
  ComplexOutput y "Connector of Complex output signal"
  parameter Boolean useConjugateInput1=false
    "If true, input 1 is processed conjugate complex";
  parameter Boolean useConjugateInput2=false
    "If true, input 2 is processed conjugate complex";
protected
  Complex u1Internal=(if useConjugateInput1 then Modelica.ComplexMath.conj(
      u1) else u1)
    "Equals either u1 or conjugate complex input u1 if useComplexInput1 = true";
  Complex u2Internal=(if useConjugateInput2 then Modelica.ComplexMath.conj(
      u2) else u2)
    "Equals either u2 or conjugate complex input u2 if useComplexInput2 = true";
end ComplexSI2SO;


Base class for continuous signal source. Basic block for Complex sources.
This component has one continuous Complex output signal y
and two parameters (offset, startTime) to shift the
generated signal.

within Modelica.ComplexBlocks.Interfaces;
partial block ComplexSignalSource "Base class for continuous signal source"
  extends ComplexBlocks.Interfaces.ComplexSO;
  parameter Complex offset=Complex(0) "Offset of output signal y";
  parameter Modelica.Units.SI.Time startTime=0
    "Output y = offset for time < startTime";
end ComplexSignalSource;


Single Input Multiple Output continuous control block. Block has one continuous Complex input signal and a
vector of continuous Complex output signals.

within Modelica.ComplexBlocks.Interfaces;
partial block ComplexSIMO
  "Single Input Multiple Output continuous control block"
  extends Modelica.ComplexBlocks.Icons.ComplexBlock;
  parameter Integer nout=1 "Number of outputs";

  ComplexInput u "Connector of Complex input signal"
  ComplexOutput y[nout] "Connector of Complex output signals"

  parameter Boolean useConjugateInput=false
    "If true, input is processed conjugate complex";
protected
  Complex uInternal=(if useConjugateInput then Modelica.ComplexMath.conj(u)
       else u)
    "Equals either u or conjugate complex input u if useComplexInput = true";
end ComplexSIMO;


Single Input Single Output continuous control block. Block has one continuous Complex input and one continuous Complex output signal.

within Modelica.ComplexBlocks.Interfaces;
partial block ComplexSISO
  "Single Input Single Output continuous control block"
  extends Modelica.ComplexBlocks.Icons.ComplexBlock;
  ComplexInput u "Connector of Complex input signal"
  ComplexOutput y "Connector of Complex output signal"
  parameter Boolean useConjugateInput=false
    "If true, input is processed conjugate complex";
protected
  Complex uInternal=(if useConjugateInput then Modelica.ComplexMath.conj(u)
       else u)
    "Equals either u or conjugate complex input u if useComplexInput = true";
end ComplexSISO;


Single Output continuous control block. Block has one continuous Complex output signal.

within Modelica.ComplexBlocks.Interfaces;
partial block ComplexSO "Single Output continuous control block"
  extends Modelica.ComplexBlocks.Icons.ComplexBlock;
  ComplexOutput y "Connector of Complex output signal"
end ComplexSO;


within Modelica.ComplexBlocks;
package Interfaces "Library of connectors and partial models for input/output blocks"
  extends Modelica.Icons.InterfacesPackage;
end Interfaces;


Pass a Complex signal through without modification. Passes a Complex signal through without modification. Enables signals to be read out of one bus, have their name changed and be sent back to a bus.

within Modelica.ComplexBlocks.Routing;
model ComplexPassThrough
  "Pass a Complex signal through without modification"
  extends Modelica.ComplexBlocks.Interfaces.ComplexSISO;
equation
  y = u;
end ComplexPassThrough;


Extract scalar signal out of signal vector dependent on IntegerRealInput index. This block extracts a scalar output signal out the
vector of input signals dependent on the Integer
value of the additional u index:

within Modelica.ComplexBlocks.Routing;
block Extractor
  "Extract scalar signal out of signal vector dependent on IntegerRealInput index"

  extends Modelica.ComplexBlocks.Interfaces.ComplexMISO;

  parameter Boolean allowOutOfRange=false "Index may be out of range";
  parameter Complex outOfRangeValue=Complex(1e10,0) "Output signal if index is out of range";

  Modelica.Blocks.Interfaces.IntegerInput index
protected
  Complex k[nin];
equation

  when {initial(),change(index)} then

    for i in 1:nin loop
      k[i] = if index == i then Complex(1,0) else Complex(0,0);

    end for;

  end when;

  y = if not allowOutOfRange or index > 0 and index <= nin then
              k*u else outOfRangeValue;
end Extractor;


Extract signals from an input signal vector. Extract signals from the input connector and transfer them
to the output connector.

within Modelica.ComplexBlocks.Routing;
block ExtractSignal "Extract signals from an input signal vector"
  extends Modelica.ComplexBlocks.Interfaces.ComplexMIMO;
  parameter Integer extract[nout]=1:nout "Extracting vector";

equation
  for i in 1:nout loop
    y[i] = u[extract[i]];

  end for;
end ExtractSignal;


within Modelica.ComplexBlocks;
package Routing "Library of blocks to combine and extract signals"
  extends Modelica.Icons.Package;
end Routing;


Signal replicator. This block replicates the input signal to an array of nout identical output signals.

within Modelica.ComplexBlocks.Routing;
block Replicator "Signal replicator"
  extends Modelica.ComplexBlocks.Interfaces.ComplexSIMO;
equation
  y = fill(u, nout);
end Replicator;


Generate constant signal of type Complex. The Complex output y is a constant signal:

within Modelica.ComplexBlocks.Sources;
block ComplexConstant "Generate constant signal of type Complex"
  parameter Complex k(re(start=1),im(start=0)) "Constant output value";
  extends Modelica.ComplexBlocks.Interfaces.ComplexSO;

equation
  y = k;
end ComplexConstant;


Set output signal to a time varying Complex expression. The (time varying) Complex output signal of this block can be defined in its
parameter menu via variable y. The purpose is to support the
easy definition of Complex expressions in a block diagram.
Note, that \"time\" is a built-in variable that is always
accessible and represents the \"model time\" and that
Variable y is both a variable and a connector.

within Modelica.ComplexBlocks.Sources;
block ComplexExpression
  "Set output signal to a time varying Complex expression"

  Modelica.ComplexBlocks.Interfaces.ComplexOutput y=Complex(0)
    "Value of Complex output"

end ComplexExpression;


Generate a phasor with ramped magnitude and constant angle. The output y is a complex phasor with constant angle and a ramped magnitude.

within Modelica.ComplexBlocks.Sources;
block ComplexRampPhasor "Generate a phasor with ramped magnitude and constant angle"
  extends Modelica.ComplexBlocks.Interfaces.ComplexSO;
  import Modelica.Constants.eps;
  parameter Real magnitude1(final min=0,start=1) "Magnitude of complex phasor at startTime"
  parameter Real magnitude2(final min=0,start=1) "Magnitude of complex phasor at startTime+duration";
  parameter Boolean useLogRamp = false "Ramp appears linear on a logarithmic scale, if true";
  parameter Modelica.Units.SI.Angle phi(start=0) "Angle of complex phasor";
  parameter Modelica.Units.SI.Time startTime=0 "Start time of frequency sweep";
  parameter Modelica.Units.SI.Time duration(min=0.0, start=1) "Duration of ramp (= 0.0 gives a Step)";
  Real magnitude "Actual magnitude of complex phasor";
equation
  assert(not useLogRamp or (magnitude1>eps and magnitude2>eps),
    "ComplexRampPhasor: magnitude1 and magnitude2 have to be greater than eps, if useLogRamp = true");
  magnitude = if not useLogRamp then
    magnitude1 + (if time < startTime then
      0 else
      if time < (startTime + duration) then
        (time - startTime)*(magnitude2-magnitude1)/duration
      else
      magnitude2-magnitude1)
  else
    if time < startTime then magnitude1 else
    if time < (startTime + duration) then
      10^(log10(magnitude1) + (log10(magnitude2) - log10(magnitude1))*min(1, (time-startTime)/duration))
    else
      magnitude2;

  y = magnitude*Modelica.ComplexMath.exp(Complex(0, phi));
end ComplexRampPhasor;


Generate a phasor with constant magnitude and constant angular velocity of type Complex. The output y is a complex phasor with constant magnitude, spinning with constant angular velocity.

within Modelica.ComplexBlocks.Sources;
block ComplexRotatingPhasor
  "Generate a phasor with constant magnitude and constant angular velocity of type Complex"
  parameter Real magnitude=1 "Magnitude of complex phasor";
  parameter Modelica.Units.SI.AngularVelocity w=1
    "Constant angular velocity of complex phasor";
  parameter Modelica.Units.SI.Angle phi0=0
    "Initial angle of complex phasor at time = 0";
  extends Modelica.ComplexBlocks.Interfaces.ComplexSO;
  Modelica.Units.SI.Angle phi "Angle";
equation
  phi = w*time + phi0;
  y = magnitude*Modelica.ComplexMath.exp(Complex(0, phi));
end ComplexRotatingPhasor;


Generate step signal of type Complex. The Complex output y is a step signal (of real and imaginary part):

within Modelica.ComplexBlocks.Sources;
block ComplexStep "Generate step signal of type Complex"
  parameter Complex height=Complex(1) "Height of step";
  extends ComplexBlocks.Interfaces.ComplexSignalSource;

equation
  y = offset + (if time < startTime then Complex(0) else height);
end ComplexStep;


within Modelica.ComplexBlocks;
package Sources "Library of signal source blocks generating Complex signals"
  extends Modelica.Icons.SourcesPackage;

end Sources;