# TotalHarmonicDistortion

```block TotalHarmonicDistortion "Output the total harmonic distortion (THD)"
extends Interfaces.SISO;

parameter Modelica.SIunits.Frequency f(start = 1) "Base frequency";
parameter Boolean useFirstHarmonic = true "THD with respect to first harmonic, if true; otherwise with respect to total RMS";
Harmonic harmonic(final f = f, final k = 1, final x0Cos = 0, final x0Sin = 0) annotation (Placement(transformation(extent = {
{-70, -62},
{-50, -42}})));
RootMeanSquare rootMeanSquare(final f = f, final x0 = 0) annotation (Placement(transformation(extent = {
{-70, 20},
{-50, 40}})));
Logical.GreaterThreshold greaterThreshold annotation (Placement(transformation(extent = {
{10, -70},
{30, -50}})));
Interfaces.BooleanOutput valid "True, if output y is valid"
annotation (Placement(transformation(extent = {
{100, -70},
{120, -50}})));
Division division annotation (Placement(transformation(extent = {
{60, -10},
{80, 10}})));
Nonlinear.Limiter limiter(uMin = Modelica.Constants.eps, uMax = Modelica.Constants.inf) annotation (Placement(transformation(extent = {
{10, -30},
{30, -10}})));
Pythagoras pythagoras(u1IsHypotenuse = true) annotation (Placement(transformation(extent = {
{10, 0},
{30, 20}})));
Logical.And andValid annotation (Placement(transformation(extent = {
{60, -50},
{80, -30}})));
Sources.BooleanExpression booleanExpression(final y = not useFirstHarmonic) annotation (Placement(transformation(extent = {
{-70, -30},
{-50, -10}})));
Logical.Switch switch1 annotation (Placement(transformation(extent = {
{-20, -30},
{0, -10}})));
equation
connect(u,harmonic.u) annotation (Line(
points = {
{-120, 0},
{-90, 0},
{-90, -52},
{-72, -52}},
color = {0, 0, 127}));
connect(u,rootMeanSquare.u) annotation (Line(
points = {
{-120, 0},
{-90, 0},
{-90, 30},
{-72, 30}},
color = {0, 0, 127}));
connect(andValid.y,valid) annotation (Line(
points = {
{81, -40},
{90, -40},
{90, -60},
{110, -60}},
color = {255, 0, 255}));
connect(division.y,y) annotation (Line(
points = {
{81, 0},
{110, 0}},
color = {0, 0, 127}));
connect(harmonic.y_rms,switch1.u3) annotation (Line(
points = {
{-49, -46},
{-40, -46},
{-40, -28},
{-22, -28}},
color = {0, 0, 127}));
connect(harmonic.y_rms,greaterThreshold.u) annotation (Line(
points = {
{-49, -46},
{-40, -46},
{-40, -60},
{8, -60}},
color = {0, 0, 127}));
connect(harmonic.y_rms,pythagoras.u2) annotation (Line(
points = {
{-49, -46},
{-40, -46},
{-40, 4},
{8, 4}},
color = {0, 0, 127}));
connect(limiter.y,division.u2) annotation (Line(
points = {
{31, -20},
{50, -20},
{50, -6},
{58, -6}},
color = {0, 0, 127}));
connect(switch1.y,limiter.u) annotation (Line(
points = {
{1, -20},
{8, -20}},
color = {0, 0, 127}));
connect(switch1.u1,rootMeanSquare.y) annotation (Line(
points = {
{-22, -12},
{-30, -12},
{-30, 30},
{-49, 30}},
color = {0, 0, 127}));
connect(booleanExpression.y,switch1.u2) annotation (Line(
points = {
{-49, -20},
{-22, -20}},
color = {255, 0, 255}));
connect(greaterThreshold.y,andValid.u2) annotation (Line(
points = {
{31, -60},
{40, -60},
{40, -48},
{58, -48}},
color = {255, 0, 255}));
connect(pythagoras.y,division.u1) annotation (Line(
points = {
{31, 10},
{50, 10},
{50, 6},
{58, 6}},
color = {0, 0, 127}));
connect(pythagoras.u1,rootMeanSquare.y) annotation (Line(
points = {
{8, 16},
{-30, 16},
{-30, 30},
{-49, 30}},
color = {0, 0, 127}));
connect(pythagoras.valid,andValid.u1) annotation (Line(
points = {
{31, 4},
{40, 4},
{40, -40},
{58, -40}},
color = {255, 0, 255}));

annotation (
defaultComponentName = "thd",
Icon(
coordinateSystem(grid = {2, 2}),
graphics = {
Line(
points = {
{-80, -80},
{-80, 68}},
color = {192, 192, 192}),
Polygon(
points = {
{-80, 90},
{-88, 68},
{-72, 68},
{-80, 90}},
lineColor = {192, 192, 192},
fillColor = {192, 192, 192},
fillPattern = FillPattern.Solid),
Line(
points = {
{-90, 0},
{68, 0}},
color = {192, 192, 192}),
Polygon(
points = {
{90, 0},
{68, 8},
{68, -8},
{90, 0}},
lineColor = {192, 192, 192},
fillColor = {192, 192, 192},
fillPattern = FillPattern.Solid),
Polygon(
points = {
{-80, 0},
{-69, 34},
{-62, 53},
{-55, 68},
{-50, 75},
{-44, 79},
{-38, 80},
{-32, 76},
{-27, 70},
{-21, 59},
{-15, 44},
{-7, 21},
{10, -31},
{17, -50},
{24, -64},
{29, -73},
{35, -78},
{41, -81},
{46, -78},
{52, -71},
{57, -62},
{64, -47},
{72, -25},
{80, 0},
{72, -53},
{59, -37},
{46, -95},
{34, -53},
{22, -81},
{10, -10},
{-3, -27},
{-13, 63},
{-26, 46},
{-26, 48},
{-38, 94},
{-51, 49},
{-59, 80},
{-65, 18},
{-75, 38},
{-80, 0}},
fillColor = {192, 192, 192},
fillPattern = FillPattern.Solid),
Text(
extent = {
{2, 80},
{82, 20}},
fillColor = {192, 192, 192},
fillPattern = FillPattern.Solid,
textString = "1",
visible = useFirstHarmonic),
Text(
extent = {
{2, 80},
{82, 20}},
fillColor = {192, 192, 192},
fillPattern = FillPattern.Solid,
textString = "rms",
visible = not useFirstHarmonic),
Text(
extent = {
{-150, -110},
{150, -150}},
textString = "f=%f")}),
Diagram(coordinateSystem(grid = {2, 2})),
Documentation(info = "<html>\n<p>This block determines the total harmonic distortion (THD) over the given period <code>1/f</code>.\nConsider that the input <code>u</code> consists of harmonic RMS components\n<code>U<sub>1</sub></code>, <code>U<sub>2</sub></code>, <code>U<sub>3</sub></code>, etc.\nThe total RMS component is then determined by:</p>\n\n<p>\n<img src=\"modelica://Modelica/Resources/Images/Blocks/Math/Urms.png\">\n</p>\n\n<p>\nThe calculation of the total harmonic distortion is based on the parameter <code>useFirstHarmonic</code>.\nThe default value <code>useFirstHarmonic = true</code> represents the <strong>standard</strong> THD calculation used in\n<a href=\"http://www.electropedia.org/iev/iev.nsf/display?openform&amp;ievref=551-20-13\">electrical engineering</a>.\nThe non-default value <code>useFirstHarmonic = false</code>\ncalculates the THD typically used for the assessment of audio signals.\n</p>\n\n<p>\nIf <code>useFirstHarmonic = true</code>, the total higher harmonic content (harmonic order numbers &gt; 1)\nrefers to the RMS value of the fundamental wave:<br>\n<img src=\"modelica://Modelica/Resources/Images/Blocks/Math/THD1.png\">\n</p>\n\n<p>\nIf <code>useFirstHarmonic = false</code>, the total higher harmonic content (harmonic order numbers &gt; 1)\nrefers to the total RMS:<br>\n<img src=\"modelica://Modelica/Resources/Images/Blocks/Math/THDrms.png\">\n</p>\n\n<p>\nIn case of a zero input signal or within the first period of calculation, the boolean output signal\n<code>valid</code> becomes <code>false</code> to indicate that the calculation result is not valid. Valid\ncalculations are indicated by <code>valid = true</code>.\n</p>\n</html>"));
end TotalHarmonicDistortion;

```