block Mean "Calculate mean over period 1/f"
    extends Modelica.Blocks.Interfaces.SISO;

    parameter Modelica.SIunits.Frequency f(start = 50) "Base frequency";
    parameter Real x0 = 0 "Start value of integrator state";
    parameter Boolean yGreaterOrEqualZero = false "=true, if output y is guaranteed to be >= 0 for the exact solution"
        annotation (
            Evaluate = true,
            Dialog(tab = "Advanced"));
    parameter Modelica.SIunits.Time t0(fixed = false) "Start time of simulation";
    Real x "Integrator state";
initial equation
    x = x0;
    y = 0;
    t0 = time;
    when sample(t0 + f ^ (-1), f ^ (-1)) then 
        y = if not yGreaterOrEqualZero then f * pre(x) else max(0, f * pre(x));
        reinit(x, 0);
    end when;
    der(x) = u;

    annotation (
        Documentation(info = "<html>\n<p>\nThis block calculates the mean of the input signal u over the given period 1/f:\n</p>\n<pre>\n1 T\n- &int; u(t) dt\nT 0\n</pre>\n<p>\nNote: The output is updated after each period defined by 1/f.\n</p>\n\n<p>\nIf parameter <strong>yGreaterOrEqualZero</strong> in the Advanced tab is <strong>true</strong> (default = <strong>false</strong>),\nthen the modeller provides the information that the mean of the input signal is guaranteed\nto be &ge; 0 for the exact solution. However, due to inaccuracies in the numerical integration scheme,\nthe output might be slightly negative. If this parameter is set to true, then the output is\nexplicitly set to 0.0, if the mean value results in a negative value.\n</p>\n</html>"),
        Icon(graphics = {
                extent = {
                    {-80, 60}, 
                    {80, 20}},
                textString = "mean"), 
                extent = {
                    {-80, -20}, 
                    {80, -60}},
                textString = "f=%f")}));
end Mean;