From 35cdc65d0535277e8389285eb261f0a787e48790 Mon Sep 17 00:00:00 2001 From: AHaumer Date: Mon, 16 Feb 2026 17:46:35 +0100 Subject: [PATCH 01/13] implemented additonal approximation (Macfadyen) --- .../FluxTubes/BaseClasses/FixedShape.mo | 69 ++++--- .../Examples/BasicExamples/CompareModels.mo | 112 ++++++++++++ .../Examples/BasicExamples/EIcore.mo | 172 ++++++++++++++++++ .../Examples/BasicExamples/ShowMaterial.mo | 125 +++++++++++++ .../Examples/BasicExamples/package.order | 3 + .../SoftMagnetic/Macfadyen/BaseData.mo | 17 ++ .../SoftMagnetic/Macfadyen/M330_50A.mo | 11 ++ .../SoftMagnetic/Macfadyen/M400_50A.mo | 11 ++ .../SoftMagnetic/Macfadyen/package.mo | 10 + .../SoftMagnetic/Macfadyen/package.order | 3 + .../Material/SoftMagnetic/MaterialSettings.mo | 28 +++ .../SoftMagnetic/RawData/Functions/exMax.mo | 25 +++ .../RawData/Functions/interpolationTable.mo | 63 +++++++ .../SoftMagnetic/RawData/Functions/package.mo | 4 + .../RawData/Functions/package.order | 2 + .../Material/SoftMagnetic/RawData/M330_50A.mo | 40 ++++ .../Material/SoftMagnetic/RawData/M400_50A.mo | 16 ++ .../Material/SoftMagnetic/RawData/package.mo | 25 +++ .../SoftMagnetic/RawData/package.order | 3 + .../Material/SoftMagnetic/package.order | 3 + .../FluxTubes/Shapes/FixedShape/Cuboid.mo | 5 +- .../Shapes/FixedShape/GenericFluxTube.mo | 5 +- .../FixedShape/HollowCylinderAxialFlux.mo | 5 +- .../HollowCylinderCircumferentialFlux.mo | 6 +- .../FixedShape/HollowCylinderRadialFlux.mo | 8 +- .../FluxTubes/Shapes/FixedShape/Toroid.mo | 6 +- .../Magnetic/FluxTubes/Types/Magnetization.mo | 5 + Modelica/Magnetic/FluxTubes/Types/package.mo | 5 + .../Magnetic/FluxTubes/Types/package.order | 1 + .../FluxTubes/UsersGuide/Approximation.mo | 49 +++++ .../FluxTubes/UsersGuide/BasicFormulae.mo | 105 +++++++++++ .../Magnetic/FluxTubes/UsersGuide/Contact.mo | 5 + .../FluxTubes/UsersGuide/Literature.mo | 19 ++ .../FluxTubes/UsersGuide/ParameterFit.mo | 26 +++ .../FluxTubes/UsersGuide/ReleaseNotes.mo | 9 + .../FluxTubes/UsersGuide/package.order | 3 + Modelica/Magnetic/FluxTubes/package.order | 1 + .../Examples/BasicExamples/EIcore.png | Bin 0 -> 17545 bytes .../Examples/BasicExamples/EIcore.vsdx | Bin 0 -> 42490 bytes .../CompareModels/comparisonSignals.txt | 6 + .../EIcore/comparisonSignals.txt | 10 + .../ShowMaterial/comparisonSignals.txt | 7 + 42 files changed, 975 insertions(+), 53 deletions(-) create mode 100644 Modelica/Magnetic/FluxTubes/Examples/BasicExamples/CompareModels.mo create mode 100644 Modelica/Magnetic/FluxTubes/Examples/BasicExamples/EIcore.mo create mode 100644 Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial.mo create mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/BaseData.mo create mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/M330_50A.mo create mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/M400_50A.mo create mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/package.mo create mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/package.order create mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/MaterialSettings.mo create mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/exMax.mo create mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/interpolationTable.mo create mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/package.mo create mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/package.order create mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo create mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo create mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo create mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.order create mode 100644 Modelica/Magnetic/FluxTubes/Types/Magnetization.mo create mode 100644 Modelica/Magnetic/FluxTubes/Types/package.mo create mode 100644 Modelica/Magnetic/FluxTubes/Types/package.order create mode 100644 Modelica/Magnetic/FluxTubes/UsersGuide/Approximation.mo create mode 100644 Modelica/Magnetic/FluxTubes/UsersGuide/BasicFormulae.mo create mode 100644 Modelica/Magnetic/FluxTubes/UsersGuide/ParameterFit.mo create mode 100644 Modelica/Resources/Images/Magnetic/FluxTubes/Examples/BasicExamples/EIcore.png create mode 100644 Modelica/Resources/Images/Magnetic/FluxTubes/Examples/BasicExamples/EIcore.vsdx create mode 100644 Modelica/Resources/Reference/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/CompareModels/comparisonSignals.txt create mode 100644 Modelica/Resources/Reference/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/EIcore/comparisonSignals.txt create mode 100644 Modelica/Resources/Reference/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial/comparisonSignals.txt diff --git a/Modelica/Magnetic/FluxTubes/BaseClasses/FixedShape.mo b/Modelica/Magnetic/FluxTubes/BaseClasses/FixedShape.mo index 3ae8378627..f0e3f5bed6 100644 --- a/Modelica/Magnetic/FluxTubes/BaseClasses/FixedShape.mo +++ b/Modelica/Magnetic/FluxTubes/BaseClasses/FixedShape.mo @@ -1,42 +1,57 @@ within Modelica.Magnetic.FluxTubes.BaseClasses; partial model FixedShape "Base class for flux tubes with fixed shape during simulation; linear or non-linear material characteristics" + import Modelica.Magnetic.FluxTubes.Types.Magnetization; - extends Interfaces.TwoPort; - + // Material + // This parameter is kept for backwards compatibility reasons, might be replaced by a member "Linear" in the enumeration Magnetization parameter Boolean nonLinearPermeability=true "= true, if non-linear rel. permeability is used, otherwise constant rel. permeability" - annotation (Dialog(group="Material"), Evaluate=true); + annotation (Dialog(tab="Material"), Evaluate=true); parameter SI.RelativePermeability mu_rConst=1 - "Constant relative permeability; used if nonLinearPermeability = false" - annotation (Dialog(group="Material", enable=not nonLinearPermeability)); - - parameter FluxTubes.Material.SoftMagnetic.BaseData material= - Material.SoftMagnetic.BaseData() - "Ferromagnetic material characteristics; used if nonLinearPermeability = true" - annotation (choicesAllMatching=true, Dialog(group="Material", enable= - nonLinearPermeability)); - + "Constant relative permeability; used if nonLinearPermeability=false" + annotation (Dialog(tab="Material", enable=not nonLinearPermeability)); + parameter Magnetization magnetization=Magnetization.Roschke + "Choose the approximation of the magnetization characteristic" + annotation (Evaluate=true, Dialog(tab="Material", enable=nonLinearPermeability)); + parameter Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.BaseData + material=Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.BaseData() + "Ferromagnetic material characteristics, approximation according to Roschke" + annotation (choicesAllMatching=true, Dialog(tab="Material", enable=nonLinearPermeability and magnetization==Magnetization.Roschke)); + parameter + Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.Macfadyen.BaseData + materialMacfadyen= + Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.Macfadyen.BaseData() + "Ferromagnetic material characteristics, approximation according to Macfadyen" + annotation (choicesAllMatching=true, Dialog(tab="Material", enable= + nonLinearPermeability and magnetization == Magnetization.Macfadyen)); + extends Modelica.Magnetic.FluxTubes.Interfaces.TwoPort; + input SI.CrossSection A "Cross-sectional area"; SI.Reluctance R_m "Magnetic reluctance"; SI.Permeance G_m "Magnetic permeance"; - SI.MagneticFluxDensity B "Magnetic flux density"; - SI.CrossSection A "Cross-sectional area penetrated by magnetic flux"; - SI.MagneticFieldStrength H "Magnetic field strength"; - - SI.RelativePermeability mu_r "Relative magnetic permeability"; - + SI.MagneticFluxDensity B(start=0) "Magnetic flux density"; + SI.MagneticPolarization J "Magnetic polarization"; + SI.MagneticFieldStrength H(start=0) "Magnetic field strength"; + SI.RelativePermeability mu_r(start=mu_rConst) "Relative magnetic permeability"; protected - Real B_N "Absolute value of normalized B"; - + Real B_N=abs(B/material.B_myMax) "Absolute value of normalized B"; + Real epsilon=1e3*Modelica.Constants.eps; equation - B_N = abs(B/material.B_myMax); - mu_r = if nonLinearPermeability then - 1 + (material.mu_i - 1 + material.c_a*B_N)/(1 + material.c_b*B_N + B_N^material.n) else mu_rConst; - R_m = 1/G_m; V_m = Phi*R_m; - B = Phi/A; - H = B/(mu_0*mu_r); - + if nonLinearPermeability then + if magnetization == Magnetization.Roschke then + mu_r = 1 + (material.mu_i - 1 + material.c_a*B_N)/(1 + material.c_b*B_N + B_N^material.n); + else // if magnetization == Magnetization.Macfadyen then + mu_r = smooth(1, (if noEvent(abs(H)Shapes.FixedShape for utilisation of this partial model. diff --git a/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/CompareModels.mo b/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/CompareModels.mo new file mode 100644 index 0000000000..81651e8356 --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/CompareModels.mo @@ -0,0 +1,112 @@ +within Modelica.Magnetic.FluxTubes.Examples.BasicExamples; +model CompareModels "Compare non-hysteretic model and Tellinen/Everett" + extends Modelica.Icons.Example; + parameter SI.Current I=1 "Excitation peak current"; + SI.MagneticFieldStrength H1=coreNon_Hys.H "Field Strength in non-hysteretic core"; + SI.MagneticFluxDensity B1=coreNon_Hys.B "Flux Density in non-hysteretic core"; + SI.MagneticPolarization J1=B1 - mu_0*H1 "Magnetic polarisation in non-hysteretic core"; + SI.MagneticFieldStrength H2=coreEverett.H "Field Strength in hysteretic core = H1"; + SI.MagneticFluxDensity B2=coreEverett.B "Flux Density in hysteretic core"; + SI.MagneticPolarization J2=B2 - mu_0*H2 "Magnetic polarisation in hysteretic core"; + Modelica.Electrical.Analog.Sources.SignalCurrent signalCurrent1 annotation ( + Placement(transformation( + extent={{-10,-10},{10,10}}, + rotation=90, + origin={0,50}))); + Modelica.Electrical.Analog.Sources.SignalCurrent signalCurrent2 annotation ( + Placement(transformation( + extent={{-10,-10},{10,10}}, + rotation=90, + origin={0,-50}))); + Modelica.Electrical.Analog.Basic.Ground groundE1 + annotation (Placement(transformation(extent={{-10,10},{10,30}}))); + Modelica.Electrical.Analog.Basic.Ground groundE2 + annotation (Placement(transformation(extent={{-10,-90},{10,-70}}))); + Modelica.Magnetic.FluxTubes.Basic.ElectroMagneticConverter excitingCoil1(N=700) + annotation (Placement(transformation( + extent={{-10,-10},{10,10}}, + rotation=0, + origin={20,50}))); + Modelica.Magnetic.FluxTubes.Basic.ElectroMagneticConverter excitingCoil2(N=700) + annotation (Placement(transformation( + extent={{-10,-10},{10,10}}, + rotation=0, + origin={20,-50}))); + Modelica.Magnetic.FluxTubes.Shapes.FixedShape.GenericFluxTube + coreNon_Hys( + magnetization=Modelica.Magnetic.FluxTubes.Types.Magnetization.Macfadyen, + mu_rConst=1000, + material= + Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.ElectricSheet.M330_50A(), + materialMacfadyen= + Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.Macfadyen.M330_50A(), + area=0.000112, + l=0.94) annotation (Placement(transformation( + extent={{-10,-10},{10,10}}, + rotation=270, + origin={40,50}))); + Modelica.Magnetic.FluxTubes.Shapes.HysteresisAndMagnets.GenericHystTellinenEverett + coreEverett( + mat=Modelica.Magnetic.FluxTubes.Material.HysteresisEverettParameter.M330_50A(), + l=0.94, + A=0.000112, + MagRel(fixed=true)) + annotation (Placement(transformation( + extent={{-10,-10},{10,10}}, + rotation=270, + origin={40,-50}))); + Modelica.Magnetic.FluxTubes.Basic.Ground groundM1 + annotation (Placement(transformation(extent={{30,10},{50,30}}))); + Modelica.Magnetic.FluxTubes.Basic.Ground groundM2 + annotation (Placement(transformation(extent={{30,-90},{50,-70}}))); + Modelica.Blocks.Sources.Sine sine(amplitude=I, f=50) annotation (Placement( + transformation( + extent={{-10,-10},{10,10}}, + rotation=0, + origin={-50,0}))); +equation + connect(signalCurrent1.p, groundE1.p) + annotation (Line(points={{0,40},{0,30}}, color={0,0,255})); + connect(signalCurrent2.p, groundE2.p) + annotation (Line(points={{0,-60},{0,-70}}, color={0,0,255})); + connect(signalCurrent1.n, excitingCoil1.p) + annotation (Line(points={{0,60},{10,60}}, color={0,0,255})); + connect(signalCurrent1.p, excitingCoil1.n) + annotation (Line(points={{0,40},{10,40}}, color={0,0,255})); + connect(signalCurrent2.n, excitingCoil2.p) + annotation (Line(points={{0,-40},{10,-40}}, color={0,0,255})); + connect(signalCurrent2.p, excitingCoil2.n) + annotation (Line(points={{0,-60},{10,-60}}, color={0,0,255})); + connect(coreNon_Hys.port_n, groundM1.port) + annotation (Line(points={{40,40},{40,30}}, color={255,127,0})); + connect(excitingCoil1.port_n, coreNon_Hys.port_n) + annotation (Line(points={{30,40},{40,40}}, color={255,127,0})); + connect(excitingCoil1.port_p, coreNon_Hys.port_p) + annotation (Line(points={{30,60},{40,60}}, color={255,127,0})); + connect(coreEverett.port_n, groundM2.port) + annotation (Line(points={{40,-60},{40,-70}}, color={255,127,0})); + connect(excitingCoil2.port_n, coreEverett.port_n) + annotation (Line(points={{30,-60},{40,-60}}, color={255,127,0})); + connect(excitingCoil2.port_p, coreEverett.port_p) + annotation (Line(points={{30,-40},{40,-40}}, color={255,127,0})); + connect(sine.y, signalCurrent1.i) annotation (Line(points={{-39,0},{-20,0},{-20, + 50},{-12,50}}, color={0,0,127})); + connect(sine.y, signalCurrent2.i) annotation (Line(points={{-39,0},{-20,0},{-20, + -50},{-12,-50}}, color={0,0,127})); + annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram( + coordinateSystem(preserveAspectRatio=false)), + experiment( + StopTime=0.1, + Interval=1e-05, + Tolerance=1e-06), + Documentation(info=" +

+This model compares the magnetization characteristic of a non-hysteretic model with a Tellinen/Everett-model including hysteresis, both for M330-50A. +

+

+Plot B1 (flux density of the non-hysteretic model) and B1 (flux density of the hysteretic model) +versus H1 (field strength, which is the same as H2 due to the same geometry of the core and the same excitation). +Try different excitation peak currents I. +

+")); +end CompareModels; diff --git a/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/EIcore.mo b/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/EIcore.mo new file mode 100644 index 0000000000..06854692f8 --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/EIcore.mo @@ -0,0 +1,172 @@ +within Modelica.Magnetic.FluxTubes.Examples.BasicExamples; +model EIcore "An iron core with shape E and I" + extends Modelica.Icons.Example; + parameter SI.Length delta=0.5e-3 "Air gap"; + parameter SI.Current I=5 "Excitation current"; + parameter Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.MaterialSettings + materialSettings(magnetization=Modelica.Magnetic.FluxTubes.Types.Magnetization.Macfadyen, + materialMacfadyen= + Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.Macfadyen.M330_50A()) + annotation (Placement(transformation(extent={{20,50},{40,70}}))); + Modelica.Magnetic.FluxTubes.Shapes.FixedShape.Cuboid yokeUL( + nonLinearPermeability=materialSettings.nonLinearPermeability, + mu_rConst=materialSettings.mu_rConst, + magnetization=materialSettings.magnetization, + material=materialSettings.material, + materialMacfadyen=materialSettings.materialMacfadyen, + l(displayUnit="mm") = 0.075, + a(displayUnit="mm") = 0.04, + b(displayUnit="mm") = 0.02) + "Upper Left yoke" annotation (Placement(transformation(extent={{-40,90},{-60,70}}))); + Modelica.Magnetic.FluxTubes.Shapes.FixedShape.Cuboid yokeUR( + nonLinearPermeability=materialSettings.nonLinearPermeability, + mu_rConst=materialSettings.mu_rConst, + magnetization=materialSettings.magnetization, + material=materialSettings.material, + materialMacfadyen=materialSettings.materialMacfadyen, + l(displayUnit="mm") = 0.075, + a(displayUnit="mm") = 0.04, + b(displayUnit="mm") = 0.02) + "Upper RIght yoke" annotation (Placement(transformation(extent={{40,70},{60,90}}))); + Modelica.Magnetic.FluxTubes.Shapes.FixedShape.Cuboid yokeLL( + nonLinearPermeability=materialSettings.nonLinearPermeability, + mu_rConst=materialSettings.mu_rConst, + magnetization=materialSettings.magnetization, + material=materialSettings.material, + materialMacfadyen=materialSettings.materialMacfadyen, + l(displayUnit="mm") = 0.075, + a(displayUnit="mm") = 0.04, + b(displayUnit="mm") = 0.02) + "Lower Left yoke" annotation (Placement(transformation(extent={{-60,-90},{-40,-70}}))); + Modelica.Magnetic.FluxTubes.Shapes.FixedShape.Cuboid yokeLR( + nonLinearPermeability=materialSettings.nonLinearPermeability, + mu_rConst=materialSettings.mu_rConst, + magnetization=materialSettings.magnetization, + material=materialSettings.material, + materialMacfadyen=materialSettings.materialMacfadyen, + l(displayUnit="mm") = 0.075, + a(displayUnit="mm") = 0.04, + b(displayUnit="mm") = 0.02) + "Lower Right yoke" annotation (Placement(transformation(extent={{60,-90},{40,-70}}))); + Modelica.Magnetic.FluxTubes.Shapes.FixedShape.Cuboid legL( + nonLinearPermeability=materialSettings.nonLinearPermeability, + mu_rConst=materialSettings.mu_rConst, + magnetization=materialSettings.magnetization, + material=materialSettings.material, + materialMacfadyen=materialSettings.materialMacfadyen, + l(displayUnit="mm") = 0.1, + a(displayUnit="mm") = 0.04, + b(displayUnit="mm") = 0.02) + "Left leg" annotation (Placement(transformation( + extent={{10,10},{-10,-10}}, + rotation=90, + origin={-80,0}))); + Modelica.Magnetic.FluxTubes.Shapes.FixedShape.Cuboid legR( + nonLinearPermeability=materialSettings.nonLinearPermeability, + mu_rConst=materialSettings.mu_rConst, + magnetization=materialSettings.magnetization, + material=materialSettings.material, + materialMacfadyen=materialSettings.materialMacfadyen, + l(displayUnit="mm") = 0.1, + a(displayUnit="mm") = 0.04, + b(displayUnit="mm") = 0.02) + "Right leg" annotation (Placement(transformation( + extent={{10,10},{-10,-10}}, + rotation=90, + origin={80,0}))); + Modelica.Magnetic.FluxTubes.Shapes.FixedShape.Cuboid legM( + nonLinearPermeability=materialSettings.nonLinearPermeability, + mu_rConst=materialSettings.mu_rConst, + magnetization=materialSettings.magnetization, + material=materialSettings.material, + materialMacfadyen=materialSettings.materialMacfadyen, + l(displayUnit="mm") = 0.1 - delta, + a(displayUnit="mm") = 0.04, + b(displayUnit="mm") = 0.04) + "Middle leg" annotation (Placement(transformation(extent={{10,10},{-10, + -10}}, rotation=270))); + Modelica.Magnetic.FluxTubes.Shapes.FixedShape.Cuboid airgap( + nonLinearPermeability=false, + mu_rConst=1, + l(displayUnit="mm") = delta, + a(displayUnit="mm") = 0.04, + b(displayUnit="mm") = 0.04) + "Airgap" annotation (Placement(transformation( + extent={{10,10},{-10,-10}}, + rotation=270, + origin={0,-30}))); + Modelica.Magnetic.FluxTubes.Basic.Ground groundM + annotation (Placement(transformation(extent={{-10,-100},{10,-80}}))); + Modelica.Magnetic.FluxTubes.Basic.ElectroMagneticConverter coil(N=100) + annotation (Placement(transformation(extent={{-20,20},{0,40}}))); + Modelica.Electrical.Analog.Sources.SineCurrent sineCurrent(I=I, f=10) + annotation (Placement(transformation( + extent={{-10,-10},{10,10}}, + rotation=90, + origin={-60,30}))); + Modelica.Electrical.Analog.Basic.Ground groundE + annotation (Placement(transformation(extent={{-50,0},{-30,20}}))); + Modelica.Magnetic.FluxTubes.Sensors.MagneticFluxSensor magFluxSensor + annotation (Placement(transformation( + extent={{-10,-10},{10,10}}, + rotation=90, + origin={0,-60}))); + Modelica.Blocks.Math.Gain fluxDensity(k=1/(airgap.a*airgap.b)) + annotation (Placement(transformation(extent={{20,-70},{40,-50}}))); +equation + connect(coil.port_p, yokeUL.port_p) + annotation (Line(points={{0,40},{0,80},{-40,80}}, color={255,127,0})); + connect(yokeUL.port_n, legL.port_p) + annotation (Line(points={{-60,80},{-80,80},{-80,10}}, color={255,127,0})); + connect(legL.port_n, yokeLL.port_p) annotation (Line(points={{-80,-10},{-80,-80}, + {-60,-80}}, color={255,127,0})); + connect(yokeLL.port_n, groundM.port) + annotation (Line(points={{-40,-80},{0,-80}}, color={255,127,0})); + connect(groundM.port, yokeLR.port_n) + annotation (Line(points={{0,-80},{40,-80}}, color={255,127,0})); + connect(yokeLR.port_p, legR.port_n) + annotation (Line(points={{60,-80},{80,-80},{80,-10}}, color={255,127,0})); + connect(legR.port_p, yokeUR.port_n) + annotation (Line(points={{80,10},{80,80},{60,80}}, color={255,127,0})); + connect(yokeUR.port_p, yokeUL.port_p) + annotation (Line(points={{40,80},{-40,80}}, color={255,127,0})); + connect(coil.port_n, legM.port_n) + annotation (Line(points={{0,20},{0,10}}, color={255,127,0})); + connect(legM.port_p, airgap.port_n) + annotation (Line(points={{0,-10},{0,-20}}, color={255,127,0})); + connect(sineCurrent.n, coil.p) + annotation (Line(points={{-60,40},{-20,40}}, color={0,0,255})); + connect(sineCurrent.p,groundE. p) + annotation (Line(points={{-60,20},{-40,20}}, color={0,0,255})); + connect(groundE.p, coil.n) + annotation (Line(points={{-40,20},{-20,20}}, color={0,0,255})); + connect(magFluxSensor.Phi, fluxDensity.u) + annotation (Line(points={{10,-60},{18,-60}}, color={0,0,127})); + connect(magFluxSensor.port_p, groundM.port) + annotation (Line(points={{0,-70},{0,-80}}, color={255,127,0})); + connect(airgap.port_p, magFluxSensor.port_n) + annotation (Line(points={{0,-40},{0,-50}}, color={255,127,0})); + annotation (experiment( + Interval=0.0001, + Tolerance=1e-06), Documentation(info=" +

+This is a core shaped as an E and an I with an airgap. +

+ + + + + +
Fig. 1: EI - core
+ +
+

+You might vary different parameters: +

+ +")); +end EIcore; diff --git a/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial.mo b/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial.mo new file mode 100644 index 0000000000..17ec76dfce --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial.mo @@ -0,0 +1,125 @@ +within Modelica.Magnetic.FluxTubes.Examples.BasicExamples; +model ShowMaterial "Show material characteristic" + extends Modelica.Icons.Example; + parameter SI.Current I=1 "Peak exciting current"; + SI.MagneticFieldStrength H=coreNon_Hys.H "Magnetic field strength"; + SI.MagneticFluxDensity B=coreNon_Hys.B "Magnetic flix density"; + SI.MagneticPolarization J=B - mu_0*H "Magnetic polarisation J = B - mu_0*H"; + Modelica.Electrical.Analog.Sources.SineCurrent source(I=I, f=50) annotation ( + Placement(transformation( + extent={{-10,-10},{10,10}}, + rotation=90, + origin={-80,0}))); + Modelica.Electrical.Analog.Basic.Ground groundE1 + annotation (Placement(transformation(extent={{-90,-40},{-70,-20}}))); + Modelica.Magnetic.FluxTubes.Basic.ElectroMagneticConverter excitingCoil(N=700) + annotation (Placement(transformation(extent={{-60,-10},{-40,10}},rotation=0))); + Modelica.Magnetic.FluxTubes.Shapes.FixedShape.GenericFluxTube + coreNon_Hys( + magnetization=Modelica.Magnetic.FluxTubes.Types.Magnetization.Macfadyen, + material= + Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.ElectricSheet.M330_50A(), + materialMacfadyen= + Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.Macfadyen.M330_50A(), + area=0.000112, + l=0.94, + mu_rConst=1000) annotation (Placement(transformation( + extent={{-10,-10},{10,10}}, + rotation=0, + origin={-20,10}))); + Modelica.Magnetic.FluxTubes.Basic.Ground groundM + annotation (Placement(transformation(extent={{-30,-40},{-10,-20}}))); + Modelica.Magnetic.FluxTubes.Basic.ElectroMagneticConverter measurementCoil(N=700) + annotation (Placement(transformation( + extent={{-10,10},{10,-10}}, + rotation=180, + origin={10,0}))); + Modelica.Electrical.Analog.Sensors.VoltageSensor voltageSensor annotation ( + Placement(transformation( + extent={{-10,-10},{10,10}}, + rotation=90, + origin={40,0}))); + Modelica.Blocks.Continuous.Integrator integrator(k=1/measurementCoil.N) + annotation (Placement(transformation(extent={{70,-10},{90,10}}))); + Modelica.Electrical.Analog.Basic.Ground groundE2 + annotation (Placement(transformation(extent={{10,-40},{30,-20}}))); + Modelica.Blocks.Math.Harmonic harmonic1(f=source.f, k=1) + annotation (Placement(transformation(extent={{70,-40},{90,-20}}))); + Modelica.Blocks.Math.Harmonic harmonic3(f=source.f, k=3) + annotation (Placement(transformation(extent={{70,-70},{90,-50}}))); + Modelica.Magnetic.FluxTubes.Sensors.MagneticPotentialDifferenceSensor + magVoltageSensor + annotation (Placement(transformation(extent={{-30,40},{-10,20}}))); + Modelica.Blocks.Math.Gain gain(k=1/coreNon_Hys.l) + annotation (Placement(transformation(extent={{-10,40},{10,60}}))); + parameter Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData.M330_50A + material annotation (Placement(transformation(extent={{20,70},{40,90}}))); + Modelica.Blocks.Tables.CombiTable1Ds combiTable1Ds( + table=material.table, + smoothness=Modelica.Blocks.Types.Smoothness.MonotoneContinuousDerivative1, + extrapolation=Modelica.Blocks.Types.Extrapolation.HoldLastPoint) + annotation (Placement(transformation(extent={{20,40},{40,60}}))); +equation + connect(source.p, groundE1.p) + annotation (Line(points={{-80,-10},{-80,-20}}, color={0,0,255})); + connect(source.n, excitingCoil.p) + annotation (Line(points={{-80,10},{-60,10}}, color={0,0,255})); + connect(source.p, excitingCoil.n) + annotation (Line(points={{-80,-10},{-60,-10}}, color={0,0,255})); + connect(excitingCoil.port_p, coreNon_Hys.port_p) + annotation (Line(points={{-40,10},{-30,10}}, + color={255,127,0})); + connect(coreNon_Hys.port_n, measurementCoil.port_p) + annotation (Line(points={{-10,10},{0,10}}, color={255,127,0})); + connect(measurementCoil.port_n, groundM.port) + annotation (Line(points={{0,-10},{-20,-10},{-20,-20}}, color={255,127,0})); + connect(excitingCoil.port_n, groundM.port) annotation (Line(points={{-40,-10}, + {-20,-10},{-20,-20}}, color={255,127,0})); + connect(voltageSensor.v, integrator.u) + annotation (Line(points={{51,0},{68,0}}, color={0,0,127})); + connect(measurementCoil.n, groundE2.p) + annotation (Line(points={{20,-10},{20,-20}}, color={0,0,255})); + connect(measurementCoil.n, voltageSensor.p) + annotation (Line(points={{20,-10},{40,-10}}, color={0,0,255})); + connect(measurementCoil.p, voltageSensor.n) + annotation (Line(points={{20,10},{40,10}}, color={0,0,255})); + connect(voltageSensor.v, harmonic1.u) annotation (Line(points={{51,0},{60,0}, + {60,-30},{68,-30}}, color={0,0,127})); + connect(voltageSensor.v, harmonic3.u) annotation (Line(points={{51,0},{60,0}, + {60,-60},{68,-60}}, color={0,0,127})); + connect(magVoltageSensor.port_p, coreNon_Hys.port_p) + annotation (Line(points={{-30,30},{-30,10}}, color={255,127,0})); + connect(magVoltageSensor.port_n, coreNon_Hys.port_n) + annotation (Line(points={{-10,30},{-10,10}}, color={255,127,0})); + connect(magVoltageSensor.V_m, gain.u) + annotation (Line(points={{-20,40},{-20,50},{-12,50}}, color={0,0,127})); + connect(gain.y, combiTable1Ds.u) + annotation (Line(points={{11,50},{18,50}}, color={0,0,127})); + annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram( + coordinateSystem(preserveAspectRatio=false)), + experiment( + StopTime=0.1, + Interval=1e-05, + Tolerance=1e-06), + Documentation(info=" +

+This example demonstrates how to show the B(H) and J(H) of a material +by applying a sinusoidal excitation current to the exciting coil. +However, hysteresis is not taken into account. +

+

+Number of turns and measurements of the core are approximately as they would be of an Epstein frame. +

+

+It is possible to compare the approximation B versus H +with interpolated data from a manufacturer's datasheet combiTable1Ds.y[1] for material = M330_50A. +

+

+Note the non-sinusoidal trajectory of voltage excitingCoil.v due to saturation and a sonusoidal excitation current. +

+

+Note that the output of the integrated voltage (divided by the number of turns of the measurement coil) shows the magnetic flux in the core. +To achieve satisfying accuracy, a rather small tolerance has to be used. +

+")); +end ShowMaterial; diff --git a/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/package.order b/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/package.order index 1e32b8338f..07363811b9 100644 --- a/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/package.order +++ b/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/package.order @@ -2,3 +2,6 @@ QuadraticCoreAirgap ToroidalCoreAirgap ToroidalCoreQuadraticCrossSection SaturatedInductor +ShowMaterial +CompareModels +EIcore diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/BaseData.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/BaseData.mo new file mode 100644 index 0000000000..2a0a4ed7dd --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/BaseData.mo @@ -0,0 +1,17 @@ +within Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.Macfadyen; +record BaseData "Coefficients for approximation of soft magnetic materials" + extends Modelica.Icons.Record; + parameter String label="Macfadyen" "Name of material"; + parameter SI.RelativePermeability mu_ri=1 + sum(Chi_mk) - Chi_mc "Initial relative permeability"; + parameter SI.MagneticPolarization Jsat=mu_0*sum(Chi_mk.*Hk) "Saturation polarization"; + parameter Integer N=1 "Number of exponential terms"; + parameter SI.MagneticFieldStrength Hk[N]={1} "Field strength coefficients"; + parameter SI.MagneticSusceptibility Chi_mk[N]={1} "Susceptibility coefficients"; + parameter SI.MagneticFieldStrength Hc=1 "Field strength for correction at origin"; + parameter SI.MagneticSusceptibility Chi_mc=0 "Susceptibility for correction at origin"; + annotation (defaultComponentPrefixes="parameter", + Icon(graphics={Text( + extent={{-100,-10},{100,-40}}, + textColor={0,0,255}, + textString="%label")})); +end BaseData; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/M330_50A.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/M330_50A.mo new file mode 100644 index 0000000000..0b51a9b595 --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/M330_50A.mo @@ -0,0 +1,11 @@ +within Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.Macfadyen; +record M330_50A "M330-50A @ 50Hz 0/90 deg" + extends Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.Macfadyen.BaseData( + label="M330-50A", + N=4, + Hk={16.866, 189.0, 355.7, 11434}, + Chi_mk={49875, 204.73, 680.20, 41.012}, + Hc=30.407, + Chi_mc= 46703); + annotation (defaultComponentPrefixes="parameter"); +end M330_50A; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/M400_50A.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/M400_50A.mo new file mode 100644 index 0000000000..008e481cdb --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/M400_50A.mo @@ -0,0 +1,11 @@ +within Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.Macfadyen; +record M400_50A "M400-50A @ 50Hz 0/90 deg" + extends Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.Macfadyen.BaseData( + label="M400-50A", + N=4, + Hk={120.579, 65.806, 81.813, 10979.9}, + Chi_mk={6845.6, 3908.6, 754.75, 40.6525}, + Hc=44.32, + Chi_mc=9403.3); + annotation (defaultComponentPrefixes="parameter"); +end M400_50A; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/package.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/package.mo new file mode 100644 index 0000000000..6561e02f30 --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/package.mo @@ -0,0 +1,10 @@ +within Modelica.Magnetic.FluxTubes.Material.SoftMagnetic; +package Macfadyen "Approximation and datasets according to Macfadyen" + extends Modelica.Icons.MaterialPropertiesPackage; + annotation (Documentation(info=" +

+Parameters approximated for the formula of [Macfadyen1973] Macfadyen et al. +See Approximation formulae in the User's Guide. +

+")); +end Macfadyen; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/package.order b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/package.order new file mode 100644 index 0000000000..f3ad30c0d6 --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/Macfadyen/package.order @@ -0,0 +1,3 @@ +BaseData +M330_50A +M400_50A diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/MaterialSettings.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/MaterialSettings.mo new file mode 100644 index 0000000000..301d7703a5 --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/MaterialSettings.mo @@ -0,0 +1,28 @@ +within Modelica.Magnetic.FluxTubes.Material.SoftMagnetic; +record MaterialSettings "Gathers all settings for a softmagnetic material" + extends Modelica.Icons.Record; + import Modelica.Magnetic.FluxTubes.Types.Magnetization; + parameter Boolean nonLinearPermeability=true + "= true, if non-linear rel. permeability is used, otherwise constant rel. permeability" + annotation (Evaluate=true); + parameter SI.RelativePermeability mu_rConst=1 + "Constant relative permeability; used if nonLinearPermeability=false" + annotation (Dialog(enable=not nonLinearPermeability)); + parameter Magnetization magnetization=Magnetization.Roschke + "Choose the approximation of the magnetization characteristic" + annotation (Evaluate=true, Dialog(enable=nonLinearPermeability)); + parameter Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.BaseData + material=Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.BaseData() + "Ferromagnetic material characteristics, approximation according to Roschke" + annotation (choicesAllMatching=true, Dialog(enable=nonLinearPermeability and magnetization==Magnetization.Roschke)); + parameter Macfadyen.BaseData materialMacfadyen=Macfadyen.BaseData() + "Ferromagnetic material characteristics, approximation according to Macfadyen" + annotation (choicesAllMatching=true, Dialog(enable=nonLinearPermeability + and magnetization == Magnetization.Macfadyen)); + annotation(defaultComponentPrefixes="parameter", Documentation(info=" +

+This parameter record gathers all settings for a softmagnetic material. +It can be used once in an example to propagate to several components the same material settings. +

+")); +end MaterialSettings; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/exMax.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/exMax.mo new file mode 100644 index 0000000000..37432dd3a3 --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/exMax.mo @@ -0,0 +1,25 @@ +within Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData.Functions; +function exMax "Extrapolation from maximum" + extends Modelica.Icons.Function; + import Modelica.Math.Vectors.find; + input Real x[:] "Absicissa of nodes"; + input Real y[:] "Ordinates of nodes"; + input Real dyMin=1 "Minimum difference of ordinates"; + output Real z "Extrapolaion from maximum"; +protected + Real yMax=max(y) "Maximum of ordinates"; + Integer iMax=find(yMax, y) "Index of maximum"; + Integer i2 "2nd index for extrapolation"; +algorithm + // avoid horizontal approximation + i2:= if abs(y[iMax] - y[iMax + 1])x[end], "xSat has to be greater than last abszissa"); + assert(ySat>y[end], "ySat has to be greater than last ordinate"); + if originSymmetric then + if completeOrigin then + table:=[cat(1, -{xSat}, -reverse(x), {0}, x, {xSat}), + cat(1, -{ySat}, -reverse(y), {0}, y, {ySat})]; + else + table:=[cat(1, -{xSat}, -reverse(x), x, {xSat}), + cat(1, -{ySat}, -reverse(y), y, {ySat})]; + end if; + else + if completeOrigin then + table:=[cat(1, -{xSat}, -reverse(x), {0}, x, {xSat}), + cat(1, {ySat}, reverse(y), {0}, y, {ySat})]; + else + table:=[cat(1, -{xSat}, -reverse(x), x, {xSat}), + cat(1, {ySat}, reverse(y), y, {ySat})]; + end if; + end if; + annotation (Documentation(info=" +

+Assume we have a series of measurements only in the right half of the plane (x,y), e.g.
+x[:]={5, 11, 18}
+x[:]={1, 2, 3}
+and we want to create an interpolation table for the full plane, this function helps. +

+

+The parameter originSymmetric controls whether the resulting table is symmetric to the origin or not.
+The parameter cpmpleteOrigin controls whether the origin (0, 0) is explicitely added or not.
+Additonally, the parameters xSat and ySat specify a last point where saturation occurs. +

+

+originSymmetric=true and completeOrigin=true:
+Result

A[7, 2] = [-xSat, -ySat; -18, -3; -11, -2; -5, -1; 0, 0; 5, 1; 11, 2; 18, 3; xSat, ySat]
+

+

+originSymmetric=true and completeOrigin=false:
+Result

A[6, 2] = [-xSat, -ySat; -18, -3; -11, -2; -5, -1;       5, 1; 11, 2; 18, 3; xSat, ySat]
+

+

+originSymmetric=false and completeOrigin=true:
+Result

A[7, 2] = [-xSat, +ySat; -18, +3; -11, +2; -5, +1; 0, 0; 5, 1; 11, 2; 18, 3; xSat, ySat]
+

+

+originSymmetric=false and completeOrigin=false:
+Result

A[6, 2] = [-xSat, +ySat; -18, +3; -11, +2; -5, +1;       5, 1; 11, 2; 18, 3; xSat, ySat]
+

+")); +end interpolationTable; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/package.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/package.mo new file mode 100644 index 0000000000..8387a487f1 --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/package.mo @@ -0,0 +1,4 @@ +within Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData; +package Functions "Helper functions to analyze data" + extends Modelica.Icons.FunctionsPackage; +end Functions; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/package.order b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/package.order new file mode 100644 index 0000000000..71fb6e08cf --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/package.order @@ -0,0 +1,2 @@ +interpolationTable +exMax diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo new file mode 100644 index 0000000000..dde48fda8e --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo @@ -0,0 +1,40 @@ +within Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData; +record M330_50A "M330-50A @ 50Hz 0/90 deg" + extends Modelica.Icons.Record; + import Modelica.Math.Vectors.interpolate; + import Modelica.Math.Vectors.find; + import Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData.Functions.exMax; + import Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData.Functions.interpolationTable; + parameter String label="M330-50A @ 50Hz 0/90 deg" "Name of material"; + // saturation + parameter SI.MagneticPolarization Jsat=2.0 "Saturation polarization"; + parameter SI.MagneticFieldStrength Hsat=50e3 "Field strength to achieve Jsat"; + // given data points + parameter Integer N=size(J,1) "Length of measurement array"; + parameter SI.MagneticPolarization J[:]={0.5, 0.6, 0.7, 0.8, 0.9, 1.0, + 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9} "Polarization"; + parameter SI.MagneticFieldStrength H[N]={53, 60, 69, 79, 93, 112, + 141, 192, 313, 698, 1932, 4284, 7750, 13318, 19610} "Field strength"; + // calculated parameters + parameter SI.MagneticSusceptibility Chi[N]=1/mu_0*J./H "Susceptibility"; + parameter SI.RelativePermeability mu_r[N]=fill(1, N) + Chi "Relative permeability"; + // additional scalar parameters + parameter SI.RelativePermeability mu_ri=interpolate(H, mu_r, 0) + "Initial relative permeability at origin (extrapolation)"; + parameter SI.RelativePermeability mu_rMax=max(mu_r) "Maximum relative permeability"; + parameter Integer iMax=find(mu_rMax, mu_r) "Index of maximum relative permeability"; + parameter SI.RelativePermeability mu_ra=exMax(H, mu_r) + "Alternative initial relative permeability at origin (extrapolation)"; + // for use with CombiTables: add saturation and mirror at origin + parameter Real table[:,2]=interpolationTable(x=H, y=J, xSat=Hsat, ySat=Jsat, + originSymmetric=true, completeOrigin=true) "Table for interpolation"; + annotation (defaultComponentPrefixes="parameter", Documentation(info=" +

+M330-50A at 50Hz for 0/90 deg magnetization table H(J)taken from manufacturer's datasheet +

+"), + Icon(graphics={Text( + extent={{-100,-10},{100,-40}}, + textColor={0,0,0}, + textString=" %label ")})); +end M330_50A; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo new file mode 100644 index 0000000000..47102875c3 --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo @@ -0,0 +1,16 @@ +within Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData; +record M400_50A "M400-50A @ 50Hz 0/90 deg" + extends M330_50A( + label="M400-50A @ 50Hz 0/90 deg", + Jsat=2.0, + Hsat=50e3, + J={0.5, 0.6, 0.7, 0.8, 0.9, 1.0, + 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9}, + H={75, 84, 93, 104, 117, 134, + 159, 199, 282, 505, 1284, 3343, 6787, 11712, 19044}); + annotation (defaultComponentPrefixes="parameter", Documentation(info=" +

+M400-50A at 50Hz for 0/90 deg magnetization table taken from manufacturer's datasheet +

+")); +end M400_50A; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo new file mode 100644 index 0000000000..e9325c562d --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo @@ -0,0 +1,25 @@ +within Modelica.Magnetic.FluxTubes.Material.SoftMagnetic; +package RawData "Records with measurents or datasheet" + extends Modelica.Icons.RecordsPackage; + annotation (Documentation(info=" +

+The magnetization table H(J) is taken from manufacturer's datasheet. +

+

+Using the function interpolationTable +the dataset is expanded by saturation polarization Jsat, adding the origin (0,0) and mirrored at the origin +for interpolation, use smoothness = MonotoneContinuousDerivative and extrapolation = HoldLastPoint. +

+

+Assuming the maximum relative permeability is included in the measurements, additional parameters are calculated: +

+
    +
  • Susceptibility Chi(H)
  • +
  • Relative permeability mu_r(H)
  • +
  • Initial relative permeability mu_ri: linear extrapolation from the first two points to H=0
  • +
  • Maximum relative permeability mu_riMax
  • +
  • Alternative initial relative permeability mu_ra: linear extrapolation from right of the maximum to H=0 + using the function exMax (extrapolation from maximum)
  • +
+")); +end RawData; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.order b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.order new file mode 100644 index 0000000000..2bf5c47671 --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.order @@ -0,0 +1,3 @@ +Functions +M330_50A +M400_50A diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/package.order b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/package.order index 86919f923a..8c19d385a6 100644 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/package.order +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/package.order @@ -1,3 +1,5 @@ +MaterialSettings +RawData BaseData Steel ElectricSheet @@ -5,3 +7,4 @@ PureIron CobaltIron NickelIron mu_rApprox +Macfadyen diff --git a/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/Cuboid.mo b/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/Cuboid.mo index ecceabbac4..e16870e42f 100644 --- a/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/Cuboid.mo +++ b/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/Cuboid.mo @@ -1,9 +1,8 @@ within Modelica.Magnetic.FluxTubes.Shapes.FixedShape; model Cuboid "Flux tube with rectangular cross-section; fixed shape; linear or non-linear material characteristics" - - extends BaseClasses.FixedShape; extends Modelica.Magnetic.FluxTubes.Icons.Cuboid; + extends BaseClasses.FixedShape(final A=a*b); parameter SI.Length l=0.01 "Length in direction of flux" annotation ( Dialog(group="Fixed geometry", groupImage= @@ -14,9 +13,7 @@ model Cuboid annotation (Dialog(group="Fixed geometry")); equation - A = a*b; G_m = mu_0*mu_r*A/l; - annotation (Documentation(info="

Please refer to the enclosing sub-package FixedShape for a description of all elements of this package and to [Ro41] for derivation and/or coefficients of the equation for permeance G_m. diff --git a/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/GenericFluxTube.mo b/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/GenericFluxTube.mo index 64966d2eeb..19e3f4f8b9 100644 --- a/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/GenericFluxTube.mo +++ b/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/GenericFluxTube.mo @@ -1,9 +1,8 @@ within Modelica.Magnetic.FluxTubes.Shapes.FixedShape; model GenericFluxTube "Flux tube with fixed cross-section and length; linear or non-linear material characteristics" - - extends BaseClasses.FixedShape; extends Modelica.Magnetic.FluxTubes.Icons.Reluctance; + extends BaseClasses.FixedShape(final A=area); parameter SI.Length l=0.01 "Length in direction of flux" annotation(Dialog(group="Fixed geometry", groupImage= @@ -11,9 +10,7 @@ model GenericFluxTube parameter SI.CrossSection area=0.0001 "Area of cross section" annotation (Dialog(group="Fixed geometry")); equation - A = area; G_m = mu_0*mu_r*A/l; - annotation (defaultComponentName="generic", Documentation(info="

Please refer to the enclosing sub-package FixedShape for a description of all elements of this package and to [Ro41] for derivation and/or coefficients of the equation for permeance G_m. diff --git a/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/HollowCylinderAxialFlux.mo b/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/HollowCylinderAxialFlux.mo index fa6388c329..b61081a3a2 100644 --- a/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/HollowCylinderAxialFlux.mo +++ b/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/HollowCylinderAxialFlux.mo @@ -1,9 +1,8 @@ within Modelica.Magnetic.FluxTubes.Shapes.FixedShape; model HollowCylinderAxialFlux "(Hollow) cylinder with axial flux; fixed shape; linear or non-linear material characteristics" - - extends BaseClasses.FixedShape; extends Modelica.Magnetic.FluxTubes.Icons.HollowCylinderAxialFlux; + extends BaseClasses.FixedShape(final A = (r_o^2 - r_i^2)*alpha/2); parameter SI.Length l=0.01 "Axial length (in direction of flux)" annotation (Dialog(group="Fixed geometry", groupImage= @@ -16,9 +15,7 @@ model HollowCylinderAxialFlux parameter SI.Angle alpha=2*pi "Central angle" annotation (Dialog(group="Fixed geometry")); equation - A = (r_o^2 - r_i^2)*alpha/2; G_m = mu_0*mu_r*A/l; - annotation (defaultComponentName="cylinder", Documentation(info="

Please refer to the enclosing sub-package FixedShape for a description of all elements of this package and to [Ro41] for derivation and/or coefficients of the equation for permeance G_m. diff --git a/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/HollowCylinderCircumferentialFlux.mo b/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/HollowCylinderCircumferentialFlux.mo index 6e5127830c..4882daa986 100644 --- a/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/HollowCylinderCircumferentialFlux.mo +++ b/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/HollowCylinderCircumferentialFlux.mo @@ -1,9 +1,9 @@ within Modelica.Magnetic.FluxTubes.Shapes.FixedShape; model HollowCylinderCircumferentialFlux "Hollow cylinder with circumferential flux; fixed shape; linear or non-linear material characteristics" - - extends BaseClasses.FixedShape; extends Modelica.Magnetic.FluxTubes.Icons.HollowCylinderCircumferentialFlux; + extends BaseClasses.FixedShape(final A = (r_o - r_i)*l); + import Modelica.Constants.pi; parameter SI.Length l=0.02 "Width (orthogonal to flux direction)" annotation (Dialog(group= @@ -16,9 +16,7 @@ model HollowCylinderCircumferentialFlux parameter SI.Angle alpha=pi/2 "Angle of cylinder section" annotation (Dialog(group="Fixed geometry")); equation - A = (r_o - r_i)*l; G_m = mu_0*mu_r*A/((r_o + r_i)/2*alpha); - annotation (defaultComponentName="cylinder", Documentation(info="

Please refer to the enclosing sub-package FixedShape for a description of all elements of this package and to [Ro41] for derivation and/or coefficients of the equation for permeance G_m. diff --git a/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/HollowCylinderRadialFlux.mo b/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/HollowCylinderRadialFlux.mo index 2334f537eb..9441061c5e 100644 --- a/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/HollowCylinderRadialFlux.mo +++ b/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/HollowCylinderRadialFlux.mo @@ -1,10 +1,9 @@ within Modelica.Magnetic.FluxTubes.Shapes.FixedShape; model HollowCylinderRadialFlux "Hollow cylinder with radial flux; fixed shape; linear or non-linear material characteristics" - - extends BaseClasses.FixedShape; extends Modelica.Magnetic.FluxTubes.Icons.HollowCylinderRadialFlux; - + extends BaseClasses.FixedShape(final A = l*alpha*(r_o + r_i)/2); + // area at arithmetic mean radius for calculation of average flux density parameter SI.Length l=0.01 "Width (orthogonal to flux direction)" annotation (Dialog(group= "Fixed geometry", groupImage= @@ -16,10 +15,7 @@ model HollowCylinderRadialFlux parameter SI.Angle alpha=2*pi "Central angle" annotation (Dialog(group="Fixed geometry")); equation - A = l*alpha*(r_o + r_i)/2; - // Area at arithmetic mean radius for calculation of average flux density G_m = mu_0*mu_r*alpha*l/Modelica.Math.log(r_o/r_i); - annotation (defaultComponentName="cylinder", Documentation(info="

Please refer to the enclosing sub-package FixedShape for a description of all elements of this package and to [Ro41] for derivation and/or coefficients of the equation for permeance G_m. diff --git a/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/Toroid.mo b/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/Toroid.mo index 8a26a00be3..ea4b94d647 100644 --- a/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/Toroid.mo +++ b/Modelica/Magnetic/FluxTubes/Shapes/FixedShape/Toroid.mo @@ -1,9 +1,9 @@ within Modelica.Magnetic.FluxTubes.Shapes.FixedShape; model Toroid "Toroid with circular cross section; fixed shape; linear or non-linear material characteristics" - - extends BaseClasses.FixedShape; extends Modelica.Magnetic.FluxTubes.Icons.Toroid; + extends BaseClasses.FixedShape(final A = d^2*pi/4); + import Modelica.Constants.pi; parameter SI.Radius r=0.1 "Radius of toroid (middle)" annotation (Dialog(group="Fixed geometry", groupImage= @@ -13,9 +13,7 @@ model Toroid parameter SI.Angle alpha=pi/2 "Angle of toroid section" annotation (Dialog(group="Fixed geometry")); equation - A = d^2*pi/4 "Area at arithmetic mean radius for calculation of average flux density"; G_m = mu_0*mu_r*A/(r*alpha); - annotation (defaultComponentName="cylinder", Documentation(info="

Please refer to the enclosing sub-package FixedShape for a description of all elements of this package and to [Ro41] for derivation and/or coefficients of the equation for permeance G_m. diff --git a/Modelica/Magnetic/FluxTubes/Types/Magnetization.mo b/Modelica/Magnetic/FluxTubes/Types/Magnetization.mo new file mode 100644 index 0000000000..3c6cae7a4c --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Types/Magnetization.mo @@ -0,0 +1,5 @@ +within Modelica.Magnetic.FluxTubes.Types; +type Magnetization = enumeration( + Roschke "Approximation formula according to Roschke", + Macfadyen "Approximation formula according to Macfadyen et al") + "Enumeration defining the approximation of the magnetization characteristic"; diff --git a/Modelica/Magnetic/FluxTubes/Types/package.mo b/Modelica/Magnetic/FluxTubes/Types/package.mo new file mode 100644 index 0000000000..1e0c766b27 --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Types/package.mo @@ -0,0 +1,5 @@ +within Modelica.Magnetic.FluxTubes; +package Types "Types with choices, especially to build menus" + extends Modelica.Icons.TypesPackage; + +end Types; diff --git a/Modelica/Magnetic/FluxTubes/Types/package.order b/Modelica/Magnetic/FluxTubes/Types/package.order new file mode 100644 index 0000000000..70f67830c1 --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Types/package.order @@ -0,0 +1 @@ +Magnetization diff --git a/Modelica/Magnetic/FluxTubes/UsersGuide/Approximation.mo b/Modelica/Magnetic/FluxTubes/UsersGuide/Approximation.mo new file mode 100644 index 0000000000..ac78f889cf --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/UsersGuide/Approximation.mo @@ -0,0 +1,49 @@ +within Modelica.Magnetic.FluxTubes.UsersGuide; +model Approximation "Approximation formulae" + extends Modelica.Icons.Information; + annotation (Documentation(info=" +

+In literature a lot of functions have been discussed for approximation of magnetization characteristics: +[Fischer1956] Fischer and Moser
+In the FluxTubes library it is possible to choose between different approximation functions.
+Originally, the formula of [Ro00] Roschke has been implemented: +

+

+            µri - 1 + ca⋅BNr(B) = 1 + ---------------
+            1 + cb⋅BN + BNn
+     |B|
+BN = -----
+     BµMax
+
+

+BµMax is the flux density where the maximum of µr appears.
+µri is the relative permeability at the origin.
+The other parameters ca, cb, n have to be determined to achieve a best fit of given data.
+Note, this formula takes into account the rise of the relative permeability µr to a maximum at BµMax. +

+

+Additionally, the formula of [Macfadyen1973] Macfadyen et al has been implemented: +

+

+               n
+J(H) = ⋅sign(H)⋅∑ Jk⋅(1 - e-|H|/Hk) - µ0⋅χC⋅H⋅e-|H|/HC.
+               k=1
+Jk = µ0⋅χk⋅Hk
+
+

+The terms with index C were added to the original formula to achieve the rise of the relative permeability µr to a maximum. +

+

+The parameters {Hk, Jk} for k in 1:n have to be determined to achieve a best fit of given data under the following constraints: +

+

+      n
+Jsat = ∑ Jk
+      k=1
+         n
+µri = 1 + ∑ χk  - χC
+         k=1
+
+")); +end Approximation; diff --git a/Modelica/Magnetic/FluxTubes/UsersGuide/BasicFormulae.mo b/Modelica/Magnetic/FluxTubes/UsersGuide/BasicFormulae.mo new file mode 100644 index 0000000000..4ee5030ea0 --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/UsersGuide/BasicFormulae.mo @@ -0,0 +1,105 @@ +within Modelica.Magnetic.FluxTubes.UsersGuide; +model BasicFormulae "Basic relations of properties" + extends Modelica.Icons.Information; + annotation (Documentation(info=" + + + + + + + + + + + + + +
Fig. 1: Passive part of the magnetic circuit: Flux tubeFig. 2: Active part of the magnetic circuit: Electro-Magnetic converter
+

Note:

+

+The coil shown in Fig. 2 is wound counter-clockwise (positive mathematical direction). +For a coil wound clockwise the number of turns N has to be entered negative.
+There is a left-hand assignment between coil current i and magnetic potential difference Vm.
+The magnetomotive force mmf has the opposite direction as the magnetic potential difference Vm +(and therefore a right-hand assignement), but it is not used in this library. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Magnetic potential difference (in an active part, Fig. 2, i.e. Ampere's law)AVm = N⋅i
Ohm's law of the magnetic circuit∑ Vm = 0∑ VmPassive = -∑ VmActive
Magnetic potential difference (in a passive part, Fig. 1)AVm = H⋅l
Magnetic field strengthA/m H = Vm/l
MagnetizationA/mM = χ⋅H
Suceptibility1χ = µr - 1
Relative permeability1µr = 1 + χ
Magnetic constant(V⋅s)/(A⋅m)µ0 = 1.25663706127⋅10-6 ≈ 4⋅π⋅10-7
PolarizationTJ = µ0⋅χ⋅H
Flux densityTB = J + µ0⋅H = µ0⋅µr⋅H
Magnetic flux (per winding)WbΦ = B⋅A
Magnetic conductanceHGm = 1/Rm = Φ/Vm = µ0⋅µr⋅A/l
Magnetic flux linkage (of the whole coil)Wbψ = N⋅Φ
Induced voltage (Farady's law)Vv = -dψ/dt
(Self) InductanceHL = N2⋅µ0⋅µr⋅A/l
+")); +end BasicFormulae; diff --git a/Modelica/Magnetic/FluxTubes/UsersGuide/Contact.mo b/Modelica/Magnetic/FluxTubes/UsersGuide/Contact.mo index ac3ffb7e79..d15de103f7 100644 --- a/Modelica/Magnetic/FluxTubes/UsersGuide/Contact.mo +++ b/Modelica/Magnetic/FluxTubes/UsersGuide/Contact.mo @@ -23,6 +23,11 @@ class Contact "Contact" Fax: +49 - 351 - 463 37183
email: Johannes.Ziske@tu-dresden.de

+

+ Prof. Anton Haumer (retired)
+ Technical University of Applied Sciences OTH Regensburg, Germany
+ email: Anton.Haumer@oth-regensburg.de +

Acknowledgements

diff --git a/Modelica/Magnetic/FluxTubes/UsersGuide/Literature.mo b/Modelica/Magnetic/FluxTubes/UsersGuide/Literature.mo index aa9f8e9a9c..10aae65a0b 100644 --- a/Modelica/Magnetic/FluxTubes/UsersGuide/Literature.mo +++ b/Modelica/Magnetic/FluxTubes/UsersGuide/Literature.mo @@ -60,6 +60,25 @@ class Literature "Literature"
+
  • Approximation formulae of magnetization characteristics (besides [Ro00] are described in: + +
    + + + + + + + + + +
    [Fischer1956] J. Fischer and H. Moser: + Die Nachbildung von Magnetisierungskurven durch einfache algebraische und transzendente Funktionen, + etz Archiv 42 (1956), pp. 286-299 (in German).
    [Macfadyen1973] W. Macfadyen, W. Woods, R. Simpson and R. Slater: + Representation of magnetization curves by exponential series, + Proceedings of the Institution of Electrical Engineers Vol. 120 (1973), pp. 902-904.

    +
  • +
  • Information related to the implemented hysteresis models can be found in:
    diff --git a/Modelica/Magnetic/FluxTubes/UsersGuide/ParameterFit.mo b/Modelica/Magnetic/FluxTubes/UsersGuide/ParameterFit.mo new file mode 100644 index 0000000000..3b5756743f --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/UsersGuide/ParameterFit.mo @@ -0,0 +1,26 @@ +within Modelica.Magnetic.FluxTubes.UsersGuide; +model ParameterFit "Fitting the parameters" + extends Modelica.Icons.Information; + annotation (Documentation(info=" +

    The magnetisation characteristics of the originally included soft magnetic materials were compiled and measured respectively by Thomas Roschke, now with Johnson Electric. Provision of this data is highly appreciated. He also formulated the approximation function used for description of the magnetisation characteristics of these materials.

    +

    The workflow of paramter fitting for the approximation according to Macfadyen at al can be recommended as follows:

    +
      +
    • N = 4 exponential terms is a good compromise between effort and accuracy.
    • +
    • Use a tool of your choice capable of nonlieanr optimization under nonlinear constraints, e.g. the Solver of Microsoft Excel or OpenOffice Calc, or fmincon of Matlab or Octave.
    • +
    • First, compare the characteristic J(H) of the formula without the correction term (index "C", you may set χC = 0) with measured data, + i.e. sum up the absolute of the differences.
    • +
    • Use as 1st constraint: |1 + ∑ χk - µra| ≤ ε + where µra is the alternative initial relative permeability as described in the raw data directory.
    • +
    • Use as 2nd constraint |∑ χk⋅Hk - Jsat| ≤ ε + where Jsat is the saturation polarization as described in the raw data directory.
    • +
    • Since optimization is sensitive to the starting point, try to gues a good initial parameter set.
    • +
    • Try first with higher allowed deviation, then reduce ε step by step.
    • +
    • Check your solution in a diagram. If it looks good (except the region around the origin), proceed:
    • +
    • Try a good guess for HC and χC ≈ µra - µri + where µri is the initial relative permeability as described in the raw data directory.
    • +
    • Change the 1st constraint: |1 + ∑ χk - χC - µri| ≤ ε.
    • +
    • Again, try first with higher allowed deviation, then reduce ε step by step.
    • +
    • Last, check your solution in a diagram. If you are satisfied, you have find a good guess for the parameters.
    • +
    +")); +end ParameterFit; diff --git a/Modelica/Magnetic/FluxTubes/UsersGuide/ReleaseNotes.mo b/Modelica/Magnetic/FluxTubes/UsersGuide/ReleaseNotes.mo index c667cb7ca0..ebf46035d1 100644 --- a/Modelica/Magnetic/FluxTubes/UsersGuide/ReleaseNotes.mo +++ b/Modelica/Magnetic/FluxTubes/UsersGuide/ReleaseNotes.mo @@ -3,6 +3,15 @@ class ReleaseNotes "Release Notes" extends Modelica.Icons.ReleaseNotes; annotation (Documentation(info=" +
    Version 4.2.0, 2026-02-15 (Anton Haumer)
    + + +
    Version 3.2.2, 2014-12-05 (Johannes Ziske, Thomas Bödrich)
      diff --git a/Modelica/Magnetic/FluxTubes/UsersGuide/package.order b/Modelica/Magnetic/FluxTubes/UsersGuide/package.order index 25e1f11079..c2815151fb 100644 --- a/Modelica/Magnetic/FluxTubes/UsersGuide/package.order +++ b/Modelica/Magnetic/FluxTubes/UsersGuide/package.order @@ -1,4 +1,7 @@ FluxTubeConcept +BasicFormulae +Approximation +ParameterFit ReluctanceForceCalculation Hysteresis Literature diff --git a/Modelica/Magnetic/FluxTubes/package.order b/Modelica/Magnetic/FluxTubes/package.order index d7694b57e1..a672e25663 100644 --- a/Modelica/Magnetic/FluxTubes/package.order +++ b/Modelica/Magnetic/FluxTubes/package.order @@ -9,3 +9,4 @@ Interfaces BaseClasses Icons Utilities +Types diff --git a/Modelica/Resources/Images/Magnetic/FluxTubes/Examples/BasicExamples/EIcore.png b/Modelica/Resources/Images/Magnetic/FluxTubes/Examples/BasicExamples/EIcore.png new file mode 100644 index 0000000000000000000000000000000000000000..1e9f450e6c917c12fad5f14bbc81b4e0e6c5ecc3 GIT binary patch literal 17545 zcmeIac{r5s+c-S!gJMt=F@}${C`4H^HMUBT78OO)W)0cKHl}i;vP?zUNh(P~2wA44 zqU@4=&%PTw!_4ox$5x-`^L@V0@q3^5eV;#`j)RVw`?}BTyw2;~7xzx+Xl-B@U`HSj z8;%@SKZ!uBJO}?ESAuV3R&)7)|5n(Y)WRX&mTc_-A6AW5A{84WZNEuZHTTc-W{56Fr+|9oV2uS)y zvXu!TCNJ-o5+Y->z7=dhAdbHI#fd*r zEiE63w@@n)FO4+Uuwf9F3a*`f0Dr9g$j*a9eEeB(>JSczKo-(y$;xt%!Z-Z|UQK$F zkTB5SpAn;0V9a`2QczHkw7Y-YWe&}ChV@PPiQNs2jTbLmklVfW{T*;f)T`OuZ>swq zAH8<-Ce5&UrYeaA%BI7tb#TzC1EeucnseZrz&c2}Apk%BK|M0ian~Sy@>40E{oo%s52bDJtMrZU6{xKOI{U5*8MJ zdM5`5hqt%);OCxjz6q&yS~^b;Ay*(gL&L%hjg76->(dMp3=$#-9XHQ>D7(PvA9BzG zz`Ac|Z+|+zvWT43Xq96`sibBf+kP>{rdIZ@tL9>be^(Q8!M~9BBu0RW>d&RZXDv)2mSa;%l*eE`1tuF z>Z2R2(kprzX3jVD;o|rJ$!|StYislL^wf+gC+jCxj~XfnJY;<@8jy4J#k;h$j`i2y z+cXLtmT~6*7j`h{ds9(S5rdI?AR{&PD*2rISD|lm*IAF6YJ=t;83td@U>9ghg>MzQ znB`dPHV~Ydnd#0snr0KoE+Cf9dazqk5?rc-l2EMMT+rIA#SzS}(x(pK35jxPG+4JZK;NaSGhs2WM zy&rV6v^+IRtiNGsXgJ!;`5`N-&+Sl1$~NOepRHj6UF{hPOfu{yB{mip7f(-5GjvPY zU)=GkfI)tHXZzZ*fU?I@PJm9QhlPcCxcQ|;FE}m2+f$A_V(@RNsU%viIPh4 z@+M6?+SvLG%BtoeD=I04hJ^G0dF69dig3w^97$8V^6uR`TYGzTaHXq)r$V-eY9CCo zkUo`BeTNgiluOsHeRbOx;*N}PeXa+K8&c#<=b|!ZpgzwajDrO}0fnBN+4k>a{+ziuY>Hwh*W*3yCPD3K12@m3|2c35=LifGJ)*tL{4! zf5vsgIE}z5a@Bq1K;frcGjoi@wcWdR?J7BHE+;S;fDrjhOG|5-$&KB&+n#yp!8;0N zNHS(%;Kt+;1S;6WV^yptqvKMuJrHek+K|668l9!P^49R|SL4~Q_05b4MrNVALz(;< zAUgN^vtkZz=1HOEkP?&ie1FUagCpchsW(8k5ji$y?YnFbYD~GvGnQcwYMUe(tOKa!io9*gNiWLnS38Ww1|_VVby`vH4H5vUlag8(kJT+^QU1VGZNFu-M$j*>q2WSZ`qs@@ zNEbVosw{W79OFBAJQZ<*r;earY`CUT50hqaTw0E*bp*LW#I0`A=?$%E7S%vybauX^ ze|!azAE8zroH9swV!q~#T1Ij*-pIoaz4`I59;}1Skrrv8(>U>y3EZkj0dtmdL}yBw zA8r)d^v@sh%-mO)M}n;}e?jTPUo}<)hH4@Q=+C^qHR`dx0}}A!B{z-^R@o9xPi@ym zQFG3i2o_Xx^_-Mzk$9;pVgmK8HKfkEe^o=W} z1O7^@zcJcIqr~5C*LxxYxyEPi1Ufh{!U=i9?OxiEf{Q>oJpGA`uAzB$weO>Dg|+5U zKh%98W78rZNVrLI6~Y9COK#&R>M_)u>lGJSe0<54q7Fk6#B5Z~EoGyU~mD1WO6Ib1&()w!!PR z99tQ0%nT{04)v3dB%rGvWWJQG=J=>t8)#QcZlsxBusrTZ7oS zwuy3P?r1t`P!)0PFc#A2d;pFg^;x&2n9MKbkbAMmjedN9+)O`)j`FWzz}?v$Xu;cW(K8y3@KX9^_xx-Uz9g z*x~>(iJ8p7%vW2-96mm2x$8EJV(~2fYj$tnF%!LXO*@MEw}f&YIyEdYdw`6kH71fq z(kasplQNfh!VO~{C+;&bVz$qOQCw#u-ZnX40Etz@4&Ze-ec15~9v+8=i}V*Nnn>+@%GT`Zn!Jl^B^h4F}^ z&c3K8b?sFA(h-`WjiM3sekxV=C_ROWtE*6WMj2v;Re?>a=Qv`akzbB2o z{YAR|!ugJ^0IOeB?L2ziI)Mj>K}yf@;FY*@=6VTd0z;b&#OG;~lpLOYuDe-89D2dm zZLmgV8M5u+nv*163}o`mV$-x3tk_5uddC=eiRXxnR}RWPNUq<%_r_S+(=>^5*@Y(F_}= zp|*$|`M^Z5GX7JAVY~~Y)0)xguRLhOoZ$9S9?WPZ;Hn<#oZS5|K{NPR7lS z8#B|CO?Vd1+zVBj?<1VXC02)pgy_w1?C>y1s51RBIo>-~^*T}~_Eg+y;0raZlQvUU zR(==>xL>7`?G!s6c+sbK0^e+K)i-YxpBHMa4{8P(t&)SLqR*8WR}1 z5oc%ovt_W`6p6fn!-9g5q*(Sv44?;^bm+ zhRoIqSglbpc#ll(=|k{c8a>BcFf!WDf9yR6|DK|f5~BkKgo7d#)K)73cSPKd2YUKb;5oo0|0 zI=plDttNxYD{ql@CED3-z_ZfQdYG_%0moJl770;ROm27QvElK@=GQ=Fi*j{ZLUIDt zsluTy@9siB>-3oKpmjp83}$Q{Z!!H4Fp--t zkF)io^F6{WkYf>O|1vlkui+37PIoCchfLK*I`ZAM3PGZ{ zaGQQ78%$hS$9!APTA0YKv@E?}H{&L_*J^_^;?WC&;v)z3i>-eGDEL`*L7?Q+a73R4suM8@OmTbb~YqSNC!0X06q+PYQG-N87)>zhw%^ z!xRemokEip*trTWmEl{;0xEweXqJ7?kBfxH4*#`efb0*TrI!dG3KPHsSk3>G0AY9L zIkF^6lcUW#>f4{>?Kys~A2Wun_uH}A1dYefqOKPKu3zS8;A`}vwzk0 zJ1g2zC-ip_`4cZ-M{CA+@mpgvJ`g&SPvLl<*x25agT!mK&LyxX{%CEukYb|WzPkFg zFu3l%7ePks4B$)c4#B8|JT&CRU+R42@a-z>=J_D+Etm zWO2}&B2?tQr~{;t-Rj z4{8s_ilBhP1*xEQbadSF9Ikq&!b?4pc;*0O;+`+iI&KAO3M{DYT&*Di+EmJ^BFfid zinWz$G7YWI_$ro?&YUQngk!4At0E`lJFKWOHR?HHP8m0-s zDiT4|Di(cr5s(s2M&i&DH;l@Ge}^%1q!2F9l!^|GkyUI3+xVVpFs;>o71 zkf{zUFupcRq(t_-RM%qGw=J+nL?9G)oQ-SJ`**NlG!N>gV!J@Xga#SJniy*+x>&S2Vo+Up2 zPMvO2L-HQ8L(1>p??@mtmK(m@3xV_tNX~%_+u*8zJXI=4E$YWR01K@uZRTR(u(iIv z9(a6>R@KCojdY~Mc6zqbV~mQbYEx6wgv72`Ht!_;c;M)PbmY5tze*eAJj=!sjS|Cl zE9ltbPSg>hm!#3r(d*`cRrLyERlN!zJzCU!E~R$N=bI{(tw1$V=M?fdQ@}4TxT{hG zSJPG0un{WjiMjz%_MEv^uhl&!)gA}pg0^n&q|!al7L*T{B19~4c3{VKkCpDPlSs5d zy5=->c3$6=Zl2c5P_#OKKF+OM4SoM6b; zY`{V;J2Za6`LSV4t_Uu8;@RLvC`oEozA(@cjj?{R<#?ogVS6~Rx;~krTlFX4GuFt9 zTR-{k9yTQBnIu&+z}qi&mHy?#h-K6_MPR-8M+I7w-j&8zY^3I9r0ZS{D*!I|vUPeB zx4tzP8J!JuCb)}MII>veqLG&(kYXuI4QJ_YyuW0AmlQdj&dpcAh5wtewFbr(|I5U+ z4z|Z{ksO~Vm#t9JX*yEu*`G#``eRURebnzJ_8%kn6tbh<1&m~bN#8|DN7gL2^yI+ z%b*Vtv^>rN9^q0E`OU;gQD$v@yDDR&+&?_WSf&}s=+qPx98J)-n_s--uENe1C>*J~ z01Yq#yuv(KO<^#SYZtv4a5Bm7syN)a^-BkvH)&AP<|UJU3PlY!xy_xY9HEodXk=uh zN*KHlQ-03Cz&xU^v2h^0V7kwDe{Od6G2pPWJc)<-WHMPfqGV#?{dobK%CNE@aZ0SVNUzt{)~+;9D>qdc|9NU|ij{!7p5ol| z<3&hFNIsh6Mj*)3s*~4g31SI@TQQPeXsWOC7RT8p*P*$FF4byNxz5f`AjEZbq31Os zbWAKP;w#N>Sk7LKDG$b`ft-8kfyuuZN@f&y#-FaY^@207DxcX+W|$I*L{L;RGm8T? zysV2|X8u;`St%(MmhP`W3f>^WDm`qjk4qVLJp(7W86`urCH?*VpSiHvxw(VbUS$=P z*$!hyhnBFjb%H)P)f_F=m{bG2#@^q&eKX{mN$!%85=KMm+=T@F`noz>;o_M3f%gVM zXqWD2^E8+7-ZNe0zRmKk;nheEv0U=-@NiPO>Fh_Y*;~w66;Swk@C&V1sFN&aJ?{J#5sf zF;B}KqUV-onyB6ZIcGGJ=1Cu-821{Vz3?~JJ`VUhjf7_MTn%|cHb-c4d3pKl?Cjtm zwva&__2s2f4-bfe$|ShOQY>>eq|2`>t=h=&+_@xONybo^9XQ8t&hq8;(Lnct;4W%9 zBx=hjuB>{%F|4?gKX=#@9HvVFBk2pC&ll(t-N)liA|+Z|S}x)7pBl`DNycKOfAWzG z)HWm*9v0?G`^q12^H9{x&)7)f``-1}x010sNDf(sDwQ%5PjM-AZMxFDDQLXP&^iK3 zVx+rUyfOGA_NY+mZeHpR~l@NOCXMV@rY z0mVb(xk}@U=g%vSp2o1MC;(MshoPzXnI5g9(h3)mV=pJ_gGSY3Y zqi>K$d+wJ)PLg&<%65K5Tkj7`%$W#PwD3tUJ8eTEH8+S6tFxLa`x;e$erY=*_>W=X zrM#icu1NIkC-g?rMd{<|^$FEz%k+A)`~Vr4SMzGM;M{xjm7p8Z7Y|(_Omc-5zns4L zi+0s_^sU}+(br)$g*sL0^t5vhzb((e;2_}AmqNOE3Luoc-cE$pty@P{8M%8vv<64H zqnT1GXWU+jjZAHmYwH*LU9x4Mm;o`jR!{yJX6T+Do*ew3dU>6E6&u|p7r^}|sVzG16rIf}k$COJL0AHY#d!;cAh6z*plMS)l zxDGZS8Az;O4AjdbzI8k;w{-t@L21282?L3dECO4Zn3(WNt)pvNw0>j{J>ZjOQ0yM3 z+@?UE4}a|bRxNm?f|v2KfryZw=4TQPUqnd#W*1Hb$r`Xj_GFVQ+Im)pQXi&C(LxI(C&@ z%A+lDmM@os2c~pH@b#VRCM6MsCg<^96v3VqTz7IsJNrp%aj->?Kwkx^UrHywq}(E+ z%}(kJ`A4Q}&9D{OmY^~P|$RjH&-#ilO7(M}X1dL9_qx}zz~#;o7d^Lux^a7xuT!khd8 z&D3aMM)Is@^N@+%W1u~tCh;<S6s0?Q!$8P{;6+g|m`=Nw`y)j)&Ep!M>C( z*Ibiu_9mCg>GlBm0fmS~<_ey=c8$k)|6lN_U6Jb|*YuMV$SvO`qWYyufhpxTa{5Hn zwBk~o`WT;>+q?dy5Oyi1E+UNBS{+{h^#TWjDm6fRmg-Q?a2Y>q%zV{BI`i2zzYwD$T(5g|{STCj}Nb(6wxiQJ%OI5%0c z{u+UhUY-GjYXNCi%KbI(ex1LzU3*1@Vy&ygZ$`=n0?X@M@VzF<>p(pZ^)g_Z;jw{G zi;@`UsYDL{3M#0-6LR|A`U0ZPvmmQB05U`@?!%`U2&LfLt^fzlt5Hj#j^Ac-m#J?9 z2wD6=$im4>{Sw3mSpFXC4)BxQsx#d&ZQ1pwzVz(re?5J(?q*#Zkmk>WVk#;s;Zae9 z$bj7maG%EPH!am4R$Mp9w^=+^EQHIYf01T6S)6I)B+z35a&nY0ZA!Z@e?OplL+zGd zmfG{|1$eZmv=l8YTqm~W-7eGh^*FoFlRA2TJMV;|^Vl zp65Y;_KTkq+@(NwS~P<{(4hJbOhQS_d!P{7&F~;~9~LG%#1wD}pW|j}r)jlsgs9B` zoQ4qW7!T*W<`^aD3!3n^eDf!h(QY;wLj{GZRMBZT)5ma{aMjX^hnq&Ea>jnl%tR=X zQ^>G;Z9a$^X_WAaUe1HswB`Agk{F{vJC z%qE;&V9Rc~<_)wdrwqbm61glkUEiAx?_d8+0tvL8h5#&qp|slC+I48Rq!u5Ls`da~ zQt~vXAO00U0k9}llb)4DFDJYI6y}E8O{nAJ`w~0;5&5`RNq8qZvWx^CDgFZQ7)m-=J_0!gL*ts)GG|q9^H{i54 zFB3L{m9uc^Q0+uS(q=V#pvOntY9F9>>Ynq(Y;{CO%Qji=H+CJ^ z=c@i0lzOb)fAL1ytmP$3+yuE`81BSWdAVMW5wj{iSKR1O408_d&Psp(eyy->9m@l& zY`_$e7vSO1(F47e@xV!p!tUwjVzh9%k7*4Jjk`=-s-yko4?IL)K>RI3_DZlHiDtB- zBb_6|fe?EGTUltV8Z-(#tUofn{cxt(CeN5OHx6=YH*@1Jc!3rj%@`S-H6Vxb7b^?< z+>cq8I9E66J~V0WR_+BFxla=69Y0ELP zzIN@}l`Ef}OB7skn(|dAl4GM(hkUyfg-w7ZpI2L3+7feTUQg>}mc+CvC@HxNxi-^( zXfxIFV3!tV%-)ZvI_~Ugm#5>l(M)y>M&&maeXu__GZREG;>_=2HI0pPj3FjNiZoqV z;`D1s*(Q7!phz~k3_S!l2wu5y2KoU$^#U{~T4*NeH_+O}-XbHNWM!7^)WYwT2u z2bMXC#f}g@H8eH7tuzN7MIwdqf!P-euVp!Jm4`4z4F{a&>%8+k0vxrxDbP2VV`O~c z0(h}xx^x;CbHMs8Iqt1gPhg(lXb85RAYGpd3sI?Cr!45^0;B~Ukj|eJj>lGo7|2IU{n85UnTQyVo`o0&NZsBK|U7_K=oJEP_|FCCohts!SuTkDsi6+IUC86-&} zX+Rg~$EUr2U!~x{n4MN0${wY9a)9@V#GFd=5c;cCq=<+4p!Sp3pcQN~3)mmHZ^j^2 zHZa(`>-EXFU{^L!G6F$x3Gr^Ku}S#6jrLG;5~baUVI0@{ZLf{6xdCB}@8x-(%|(59 zYkdBA#>VV>FhVR@_=l>A&<<#a6laq<^05R+&Cln*7ahLEB9jNm@`!8FX9b_bZsM;E zzvoWGGRV^H3tZ-m>rV6EMLoo-Be8>=2^_V-(Wi6~NN2#z{uDLQy#0zd8O8Zb3HZM! zfOR#6@fM&XS8eUO4_Cg{d6#84`~1AHm4^i=57j#$w%!CN6isV1{siDkxa{Su=G0sD zwY7IArsyRMDCrgv;)QQ=$0al#Iqz|Mvq$6iaI)d~K%zkA_c9VluX>87NCD=3tZXyBmE%1lq3ee?Rt<-mf>Pw-Oa zrwIqsH}ChV(7qR#cI`KQ>JGp&`MvORN`P8aJbHoqr5>!iK@@ulu7881N>!?tbVs3I zq$p&@@)mxpFzw61s2s=t(!gMj#VFyEz5lt=wC^m^TkSu)XLd}s-yaFWg=4X*-bUGQ zGHdxrphON*a=+m>U&na}*Kz*)3roN&o7cPlqOb%g()2&DumqS>&%2CiDgW})l1cbm zxzb53c(H&A6#7!_@#}v`ju-sbDqa6AdB{a~>tE#|9sZ^Tma4P-)^IU&+fvmFv_;I6`{?DtX|I6I}%iM4`(|_I)@IO{_OEsaaEG_MIfa45$ z%|L`TT9I3m4+0c6yvz(H^+hr0T$uMZ7X5)M$oc`twx2JwgW#AmQ_4*= zf0vv=#&-`88IId4MPvp5RSRyZ zS!`~5jrnQFeoaJ}YLqB1D|<>&dmI10>-Wa$c!K@o4U zjSqCZJ<$X=`kogQ3a(5ZX#+Ld-(UWLjJ6}3o~=InC(MPfb6@rT3F;(rAS>qAq{bQ0 zhVk1C1mbEa%CBiY@t|7&+kNfuOd=6ZxBUkwM#$nuJwN)h*T0<;yauM9j1mbOFXXt4 zdy}TTLDT#=b70hv+1mUe1`oQe0Jsh(JN>*(1 zWA!xRHopN82_tBg-{FBtM#qS@v8|RzdRkiLfMcWL$LFk$MJ*%-^k6-MSllWGJpdg+ zdN>w$-t!)wn#v$$#hr{BBfS}u_b_}rbn$$S)8+Akrt!YP7_Z?_UC=CtAE*6`_)mhz`n#kgbtAf_Yg5IaQ^gSE; z%Y&_&O9brk zEIYP&Qln6F2`2p^dYYSlfbV0*v$_4pkX7XmhkNSEltHTqtEsuBs;a7ujBR4xe=0`* z5tN%M*;;E7%o)&^_d&NsJ$-)wU-;c)!2lDg-eQyGh=Xn zb`A$VI3FLOlTSRj@{bN;FP_k-sKnDdEi5bsSMmJqmEzXcXy;XTel+U+(I>qA+7-Un z(KiW!e>4}X)dqtZjJ&_Eeer`LWp3IabnTBu<&AO;D^`C7jk0%}h5XDDp8Z^GAZ&tm zh(N9HhI|Bm5wv0q;{gV=f37if(0L{?JLIZ`T-DLQzwgVCzgM#U?N7@ucU;e< z^?luC*4#U|AGi5KOpI7gVyf^*gEh9xJ>5_0o6O&`^H7l}+(C!MR`PT1nc9buYGAaf za;Z=Kv%-8e1mBIsJpHiPhc1a76^-_mFZ|+-TKRgZZ{1dzSoq2~XEh{k521hpTj(Eu zVmKItWWx{t0f5o~QiRcB(5>F3u66wI^^hH4R&sgsOmX+~Azy+vu>H3CK1%ZWX#?5T zwq{cQlrrFeRX7-BJ%c`L##>j-obj8(T!gGr;Z5)mhzDuvCH9O2x|BiwwNC0j%F7@1 zEY+V<5#c-+FnDC#qPT!Lf@OmnsB38AMjK1A8Q
      >Im0Jy}bOc%<057_DK0qj?A6 z@e|rJo4MjIf~sZJYjuVgSfVnnZ~jG)ZfP2LVf3C~SZjHe5m z-_G^CmgPJK5%spaD;`F6sMS!mhj(|h+=D4sVcliTYzSAM-KvCDG=lVoe+m4_&u4^ z)y(dpw+^{;ovX2+_lB4R)a_*QNZ+6=sewtF4t_^2WR_BrIjV;mR-KI^)}u+kgur-+ zR`b+-CR9*}t(|uK%B-Afxgv_zWg0W%^T0`evbS23M*F}ZO;q=Pm{pOvfgUAID9YP* zUYTSgv|AzttxwMy`*Epm8=(a-yAmD2yiQ|E!fJSM{MqyMxbIv$4N=b^B2N$>+ z=7{0p>suPG;<_o<W@FgU9f2UJ6FLl;MKe+Gp#?A?OX`RNBf{;fW=>Qs#WXNsx?W8T%FoZ& zft?ll^Hw&rIQVkAXIZB5PFv$Z)Jnu@@FDkKeSjT}-rVirl~?e1obpbG`FFZK%Nm3p ze~@~;iRzfuxB?Ma^Xu2MlSu1^jO2`r?GDDLRUuu~>8s3Z#}EfYh}8sQkl?*josZ%! zfi9c+fe+rcM-?FJobf6!x63U26kTb4F~jDQ(8^n8lP{!*W*{%_r~Uv^LwaWh5uKd6 zRS^i}D$LJoO^rXz(;C(x5O@*jLy>zB=oFY-fjGDs87)fRC1OL^h@h&2Nk(H{a#joi zwGH>`8)IirgV0weFfWY|QCEe`1osu>F>}v@?=~Ybzj(DdAvLFgy0oufH3+GJvqR5| z8uff{qeS;|cN|oJB6MQQO*3L%Ty5sxm!T}+-FJ46{?5mh2MAwo(h3}yhv-ZmO(b{7 zUE71mGh;3}dAlDUeZd6f^edBb$nOKMuZiEV9@k%|8%5f6FSad&*`|QRi1O-jBBPaZ zq?9@E={U!cX5Yxh!IlBEGuJ&a=G;%HkLatV-B{zE3%o z0r^(Omm^hWX!m8CW!YGupwe>gx$j^OBPL)IZkNN6YEnA0x}s29Ib=|mPEpG>;lZhI zd$tuB6(cqi!0(09ln{eV>VkNv_36h;jV4~q$+cnnVj{8T41F3EI=4{ z*GVIARjZx7I%$N8!W|a*lW@>#+}&^L|Mv@yr5QMQBQDix1bX1$k<7Y*2{3q1|9H9& z%=n@ZUqCeh_&OhA(yw-jY}bIw#;ncE%&uR5c``25V0RZA;#PO?Knm#jyr*%j=uq%R zHPEBEjX__DVDAjC>FUybYd51I>43xz-{yKgUOLsX4qLMlpD5rII3ePN7W1Gsy7ff;Qc z?hg1bL$m{mf}I}l1NH=eZ@@@h5loFDod2IZ1Of!~4rrep+>Us96|j#Dm^#190aOW? i9sPg*R~?h`J#}yQ+|{$@&in)2=ONBR#LKtW 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 He|-8cSbS!q literal 0 HcmV?d00001 diff --git a/Modelica/Resources/Reference/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/CompareModels/comparisonSignals.txt b/Modelica/Resources/Reference/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/CompareModels/comparisonSignals.txt new file mode 100644 index 0000000000..0de018aa6a --- /dev/null +++ b/Modelica/Resources/Reference/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/CompareModels/comparisonSignals.txt @@ -0,0 +1,6 @@ +time +coreNon_Hys.H +coreNon_Hys.B +coreEverett.B + + diff --git a/Modelica/Resources/Reference/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/EIcore/comparisonSignals.txt b/Modelica/Resources/Reference/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/EIcore/comparisonSignals.txt new file mode 100644 index 0000000000..d4bf328b14 --- /dev/null +++ b/Modelica/Resources/Reference/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/EIcore/comparisonSignals.txt @@ -0,0 +1,10 @@ +time +airGap.H +airGap.B +legM.H +legM.B +legL.H +legL.B +legR.H +legR.B +fluxDensity.y diff --git a/Modelica/Resources/Reference/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial/comparisonSignals.txt b/Modelica/Resources/Reference/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial/comparisonSignals.txt new file mode 100644 index 0000000000..01f298f22c --- /dev/null +++ b/Modelica/Resources/Reference/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial/comparisonSignals.txt @@ -0,0 +1,7 @@ +time +coreNon_Hys.H +coreNon_Hys.J +combiTable1Ds.y[1] +coreNon_Hys.Phi +integrator.y +voltageSensor.v From 324a5afacb7a4369f1e41403ee59951b162c9465 Mon Sep 17 00:00:00 2001 From: AHaumer Date: Mon, 16 Feb 2026 18:07:45 +0100 Subject: [PATCH 02/13] corrected html bug --- .../RawData/Functions/interpolationTable.mo | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/interpolationTable.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/interpolationTable.mo index 8e1a4d781e..823f14e654 100644 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/interpolationTable.mo +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/interpolationTable.mo @@ -43,21 +43,13 @@ The parameter originSymmetric controls whether the resulting table The parameter cpmpleteOrigin controls whether the origin (0, 0) is explicitely added or not.
      Additonally, the parameters xSat and ySat specify a last point where saturation occurs.

      -

      -originSymmetric=true and completeOrigin=true:
      -Result

      A[7, 2] = [-xSat, -ySat; -18, -3; -11, -2; -5, -1; 0, 0; 5, 1; 11, 2; 18, 3; xSat, ySat]
      -

      -

      -originSymmetric=true and completeOrigin=false:
      -Result

      A[6, 2] = [-xSat, -ySat; -18, -3; -11, -2; -5, -1;       5, 1; 11, 2; 18, 3; xSat, ySat]
      -

      -

      -originSymmetric=false and completeOrigin=true:
      -Result

      A[7, 2] = [-xSat, +ySat; -18, +3; -11, +2; -5, +1; 0, 0; 5, 1; 11, 2; 18, 3; xSat, ySat]
      -

      -

      -originSymmetric=false and completeOrigin=false:
      -Result

      A[6, 2] = [-xSat, +ySat; -18, +3; -11, +2; -5, +1;       5, 1; 11, 2; 18, 3; xSat, ySat]
      -

      +

      originSymmetric=true and completeOrigin=true:

      +
      Result A[7, 2] = [-xSat, -ySat; -18, -3; -11, -2; -5, -1; 0, 0; 5, 1; 11, 2; 18, 3; xSat, ySat]
      +

      originSymmetric=true and completeOrigin=false:

      +
      Result A[6, 2] = [-xSat, -ySat; -18, -3; -11, -2; -5, -1;       5, 1; 11, 2; 18, 3; xSat, ySat]
      +

      originSymmetric=false and completeOrigin=true:

      +
      Result A[7, 2] = [-xSat, +ySat; -18, +3; -11, +2; -5, +1; 0, 0; 5, 1; 11, 2; 18, 3; xSat, ySat]
      +

      originSymmetric=false and completeOrigin=false:

      +
      Result A[6, 2] = [-xSat, +ySat; -18, +3; -11, +2; -5, +1;       5, 1; 11, 2; 18, 3; xSat, ySat]
      ")); end interpolationTable; From d7c057d642b14d1158ed08f70a35ff98007202f8 Mon Sep 17 00:00:00 2001 From: AHaumer Date: Mon, 16 Feb 2026 18:14:37 +0100 Subject: [PATCH 03/13] corrected one more html bug --- Modelica/Magnetic/FluxTubes/UsersGuide/Contact.mo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modelica/Magnetic/FluxTubes/UsersGuide/Contact.mo b/Modelica/Magnetic/FluxTubes/UsersGuide/Contact.mo index d15de103f7..fc850f17aa 100644 --- a/Modelica/Magnetic/FluxTubes/UsersGuide/Contact.mo +++ b/Modelica/Magnetic/FluxTubes/UsersGuide/Contact.mo @@ -24,7 +24,7 @@ class Contact "Contact" email: Johannes.Ziske@tu-dresden.de

      - Prof. Anton Haumer (retired)
      + Prof. Anton Haumer (retired)
      Technical University of Applied Sciences OTH Regensburg, Germany
      email: Anton.Haumer@oth-regensburg.de

      From 572eaed2d8806ba003a5cba34d0f6abe88705866 Mon Sep 17 00:00:00 2001 From: AHaumer Date: Tue, 17 Feb 2026 12:11:30 +0100 Subject: [PATCH 04/13] added data to RawData records and added documentation (literature) --- .../Material/SoftMagnetic/RawData/M330_50A.mo | 13 +++++++-- .../Material/SoftMagnetic/RawData/M400_50A.mo | 5 ++++ .../Material/SoftMagnetic/RawData/package.mo | 29 +++++++++++++++---- .../Magnetic/FluxTubes/Types/package.order | 1 + .../FluxTubes/UsersGuide/Literature.mo | 20 +++++++++++++ 5 files changed, 61 insertions(+), 7 deletions(-) diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo index dde48fda8e..c2c5e8ecf1 100644 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo @@ -3,9 +3,18 @@ record M330_50A "M330-50A @ 50Hz 0/90 deg" extends Modelica.Icons.Record; import Modelica.Math.Vectors.interpolate; import Modelica.Math.Vectors.find; - import Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData.Functions.exMax; - import Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData.Functions.interpolationTable; + import FluxTubesExtensions.Material.SoftMagnetic.RawData.Functions.exMax; + import FluxTubesExtensions.Material.SoftMagnetic.RawData.Functions.interpolationTable; + constant Real lb2kg=0.45359237 "Conversion kg/lb"; parameter String label="M330-50A @ 50Hz 0/90 deg" "Name of material"; + parameter SI.Density rho=7650 "Density of material"; + // Losses + parameter SpecificPower p1=3.30 "Specific losses at 1.5 T and f1"; + parameter SI.Frequency f1=50 "Measurement frequency 1"; + parameter SpecificPower p2=1.9*lb2kg "Specific losses at 1.5 T and f2"; + parameter SI.Frequency f2=60 "Measurement frequency 2"; + parameter Real ratioHysteresis=(p2/p1*f1/f2 - f2/f1)/(1 - f2/f1) + "Ratio of hysteresis losses with respect to the total core losses at 1.5 T and f1"; // saturation parameter SI.MagneticPolarization Jsat=2.0 "Saturation polarization"; parameter SI.MagneticFieldStrength Hsat=50e3 "Field strength to achieve Jsat"; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo index 47102875c3..67b491479b 100644 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo @@ -2,6 +2,11 @@ within Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData; record M400_50A "M400-50A @ 50Hz 0/90 deg" extends M330_50A( label="M400-50A @ 50Hz 0/90 deg", + rho=7700, + p1=4.00, + f1=50, + p2=2.3*lb2kg, + f2=60, Jsat=2.0, Hsat=50e3, J={0.5, 0.6, 0.7, 0.8, 0.9, 1.0, diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo index e9325c562d..2703c974c2 100644 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo @@ -1,25 +1,44 @@ within Modelica.Magnetic.FluxTubes.Material.SoftMagnetic; package RawData "Records with measurents or datasheet" extends Modelica.Icons.RecordsPackage; + import Modelica.Magnetic.FluxTubes.Types.SpecificPower; + annotation (Documentation(info="

      -The magnetization table H(J) is taken from manufacturer's datasheet. +This raw data records cover the following information:

      +
        +
      • density
      • +
      • specific losses at 2 different frequencies and B = 1.5 T
      • +
      • saturation polarization
      • +
      • magnetic field strength where saturation polarization is reached with desired accuracy
      • +
      • magnetization table H(J) taken from manufacturer's datasheet
      • +

      -Using the function interpolationTable -the dataset is expanded by saturation polarization Jsat, adding the origin (0,0) and mirrored at the origin -for interpolation, use smoothness = MonotoneContinuousDerivative and extrapolation = HoldLastPoint. +Using the function interpolationTable +the dataset is expanded by saturation polarization Jsat, adding the origin (0,0) and mirrored at the origin.
      +For interpolation, use smoothness = MonotoneContinuousDerivative and extrapolation = HoldLastPoint.

      Assuming the maximum relative permeability is included in the measurements, additional parameters are calculated:

        +
      • Ratio of hysteresis losses with respect to the total core losses at 1.5 T and f1
      • Susceptibility Chi(H)
      • Relative permeability mu_r(H)
      • Initial relative permeability mu_ri: linear extrapolation from the first two points to H=0
      • Maximum relative permeability mu_riMax
      • Alternative initial relative permeability mu_ra: linear extrapolation from right of the maximum to H=0 - using the function exMax (extrapolation from maximum)
      • + using the function exMax (extrapolation from maximum)
      +

      +The separation of hysteresis and eddy current losses is done according to the formula of Jordan ([Jordan1924]): +

      +
      
      +P = vRef⋅m⋅[ratioHysteresis⋅(f/fRef) + (1 - ratioHysteresis)⋅(f/fRef)2]⋅(B/BRef)2
      +
      +

      +vRef are the total specific losses at reference frequency fRef and reference peak flux density fRef (usually 1.5 T). +

      ")); end RawData; diff --git a/Modelica/Magnetic/FluxTubes/Types/package.order b/Modelica/Magnetic/FluxTubes/Types/package.order index 70f67830c1..b4eba309d4 100644 --- a/Modelica/Magnetic/FluxTubes/Types/package.order +++ b/Modelica/Magnetic/FluxTubes/Types/package.order @@ -1 +1,2 @@ Magnetization +SpecificPower diff --git a/Modelica/Magnetic/FluxTubes/UsersGuide/Literature.mo b/Modelica/Magnetic/FluxTubes/UsersGuide/Literature.mo index 10aae65a0b..e20a7816e0 100644 --- a/Modelica/Magnetic/FluxTubes/UsersGuide/Literature.mo +++ b/Modelica/Magnetic/FluxTubes/UsersGuide/Literature.mo @@ -79,6 +79,26 @@ class Literature "Literature"

  • +
  • Calculation of iron losses is discussed in: + +
    + + + + + + + + + +
    [Jordan1924] Heinz Jordan: + Die ferromagnetischen Konstanten für schwache Wechselfelder, + Elektrische Nachrichtentechnik 1924 (1), no. 8, pp. 269-283 (in German).
    [Krings2010] Andreas Krings and Juliette Soulard: + Overview and Comparison of Iron Loss Models for Electrical Machines, + Journal of Electrical Engineering 2010 (10), pp. 162-169.

    +
  • + +
  • Information related to the implemented hysteresis models can be found in:
    From 6c05ec5ae42dbca41b11ec3caf73f2449eeda4d7 Mon Sep 17 00:00:00 2001 From: AHaumer Date: Tue, 17 Feb 2026 12:25:50 +0100 Subject: [PATCH 05/13] corrected lb2kg --- .../FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo | 2 +- .../FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo | 2 +- Modelica/Magnetic/FluxTubes/Types/SpecificPower.mo | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 Modelica/Magnetic/FluxTubes/Types/SpecificPower.mo diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo index c2c5e8ecf1..75846221e8 100644 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo @@ -11,7 +11,7 @@ record M330_50A "M330-50A @ 50Hz 0/90 deg" // Losses parameter SpecificPower p1=3.30 "Specific losses at 1.5 T and f1"; parameter SI.Frequency f1=50 "Measurement frequency 1"; - parameter SpecificPower p2=1.9*lb2kg "Specific losses at 1.5 T and f2"; + parameter SpecificPower p2=1.9/lb2kg "Specific losses at 1.5 T and f2"; parameter SI.Frequency f2=60 "Measurement frequency 2"; parameter Real ratioHysteresis=(p2/p1*f1/f2 - f2/f1)/(1 - f2/f1) "Ratio of hysteresis losses with respect to the total core losses at 1.5 T and f1"; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo index 67b491479b..a15d4325ac 100644 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo @@ -5,7 +5,7 @@ record M400_50A "M400-50A @ 50Hz 0/90 deg" rho=7700, p1=4.00, f1=50, - p2=2.3*lb2kg, + p2=2.3/lb2kg, f2=60, Jsat=2.0, Hsat=50e3, diff --git a/Modelica/Magnetic/FluxTubes/Types/SpecificPower.mo b/Modelica/Magnetic/FluxTubes/Types/SpecificPower.mo new file mode 100644 index 0000000000..90f3f167e1 --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Types/SpecificPower.mo @@ -0,0 +1,2 @@ +within Modelica.Magnetic.FluxTubes.Types; +type SpecificPower = Real (final quantity="SpecificPower", final unit="W/kg"); From 77310816f409e566d24707ad2240535fc9218083 Mon Sep 17 00:00:00 2001 From: AHaumer Date: Tue, 17 Feb 2026 16:25:35 +0100 Subject: [PATCH 06/13] improvement of RawData --- .../Examples/BasicExamples/ShowMaterial.mo | 11 ++-- .../Material/SoftMagnetic/RawData/BaseData.mo | 51 +++++++++++++++++ .../SoftMagnetic/RawData/Functions/exMax.mo | 2 +- .../RawData/Functions/interpolationTable.mo | 55 ------------------- .../RawData/Functions/package.order | 1 - .../Material/SoftMagnetic/RawData/M330_50A.mo | 50 +++++------------ .../Material/SoftMagnetic/RawData/M400_50A.mo | 8 +-- .../Material/SoftMagnetic/RawData/package.mo | 8 +-- .../SoftMagnetic/RawData/package.order | 1 + 9 files changed, 79 insertions(+), 108 deletions(-) create mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/BaseData.mo delete mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/interpolationTable.mo diff --git a/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial.mo b/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial.mo index 17ec76dfce..6de42c99d7 100644 --- a/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial.mo +++ b/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial.mo @@ -3,8 +3,10 @@ model ShowMaterial "Show material characteristic" extends Modelica.Icons.Example; parameter SI.Current I=1 "Peak exciting current"; SI.MagneticFieldStrength H=coreNon_Hys.H "Magnetic field strength"; - SI.MagneticFluxDensity B=coreNon_Hys.B "Magnetic flix density"; - SI.MagneticPolarization J=B - mu_0*H "Magnetic polarisation J = B - mu_0*H"; + SI.MagneticFluxDensity B=coreNon_Hys.B - mu_0*H "Magnetic polarisation J"; + SI.RelativePermeability mu_r=coreNon_Hys.mu_r "Relative permeability"; + SI.MagneticPolarization J_rD=combiTable1Ds.y[1] "Magnetic polarisation from raw data"; + SI.RelativePermeability mu_r_rD=combiTable1Ds.y[2] "Relative permability from raw data"; Modelica.Electrical.Analog.Sources.SineCurrent source(I=I, f=50) annotation ( Placement(transformation( extent={{-10,-10},{10,10}}, @@ -103,7 +105,7 @@ equation Tolerance=1e-06), Documentation(info="

    -This example demonstrates how to show the B(H) and J(H) of a material +This example demonstrates how to show the characteristics J(H) and mu_r(H) of a material by applying a sinusoidal excitation current to the exciting coil. However, hysteresis is not taken into account.

    @@ -111,8 +113,7 @@ However, hysteresis is not taken into account. Number of turns and measurements of the core are approximately as they would be of an Epstein frame.

    -It is possible to compare the approximation B versus H -with interpolated data from a manufacturer's datasheet combiTable1Ds.y[1] for material = M330_50A. +It is possible to compare the approximation with interpolated data from a manufacturer's datasheet (raw Data) J_rD and mu_r_rD for material = M330_50A.

    Note the non-sinusoidal trajectory of voltage excitingCoil.v due to saturation and a sonusoidal excitation current. diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/BaseData.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/BaseData.mo new file mode 100644 index 0000000000..1d75a0e02f --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/BaseData.mo @@ -0,0 +1,51 @@ +within Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData; +partial record BaseData "BaseData record for RawData" + extends Modelica.Icons.Record; + import Modelica.Math.Vectors.interpolate; + import Modelica.Math.Vectors.find; + import Modelica.Math.Vectors.reverse; + import FluxTubesExtensions.Material.SoftMagnetic.RawData.Functions.exMax; + constant Real lb2kg=0.45359237 "Conversion kg/lb"; + parameter String label="RawData" "Name of material"; + parameter SI.Density rho "Density of material"; + // Losses + parameter FluxTubesExtensions.Types.SpecificPower p1 + "Specific losses at 1.5 T and f1"; + parameter SI.Frequency f1 "Measurement frequency 1"; + parameter FluxTubesExtensions.Types.SpecificPower p2 + "Specific losses at 1.5 T and f2"; + parameter SI.Frequency f2 "Measurement frequency 2"; + parameter Real ratioHysteresis=(p2/p1*f1/f2 - f2/f1)/(1 - f2/f1) + "Ratio of hysteresis losses with respect to the total core losses at 1.5 T and f1"; + // saturation + parameter SI.MagneticPolarization Jsat "Saturation polarization"; + parameter SI.MagneticFieldStrength Hsat "Field strength to achieve Jsat"; + // given data points + parameter Integer N=size(J,1) "Length of measurement array"; + parameter SI.MagneticPolarization J[:]={1} "Polarization"; + parameter SI.MagneticFieldStrength H[N]={1} "Field strength"; + // calculated parameters + parameter SI.RelativePermeability mu_r[N]=fill(1, N) + 1/mu_0*J./H "Relative permeability"; + // additional scalar parameters (provided maximum of permability is included in the table) + parameter SI.RelativePermeability mu_ri=interpolate(H, mu_r, 0) + "Initial relative permeability at origin (extrapolation)"; + parameter SI.RelativePermeability mu_rMax=max(mu_r) "Maximum relative permeability"; + parameter Integer iMax=find(mu_rMax, mu_r) "Index of maximum relative permeability"; + parameter SI.RelativePermeability mu_ra=exMax(H, mu_r) + "Alternative initial relative permeability at origin (extrapolation)"; + // for use with CombiTables: add saturation and mirror at origin + parameter Real table[:,3]=[ + cat(1, -{Hsat}, -reverse(H), { 0}, H, {Hsat}), + cat(1, -{Jsat}, -reverse(J), { 0}, J, {Jsat}), + cat(1, { 1}, reverse(mu_r), {mu_ri}, mu_r, { 1})] + "Table for interpolation H, J, mu_r"; + annotation (defaultComponentPrefixes="parameter", Documentation(info=" +

    +BaseData Record for RawData +

    +"), + Icon(graphics={Text( + extent={{-100,-10},{100,-40}}, + textColor={0,0,0}, + textString=" %label ")})); +end BaseData; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/exMax.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/exMax.mo index 37432dd3a3..f7fd5dac9f 100644 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/exMax.mo +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/exMax.mo @@ -5,7 +5,7 @@ function exMax "Extrapolation from maximum" input Real x[:] "Absicissa of nodes"; input Real y[:] "Ordinates of nodes"; input Real dyMin=1 "Minimum difference of ordinates"; - output Real z "Extrapolaion from maximum"; + output Real z "Extrapolation from maximum"; protected Real yMax=max(y) "Maximum of ordinates"; Integer iMax=find(yMax, y) "Index of maximum"; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/interpolationTable.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/interpolationTable.mo deleted file mode 100644 index 823f14e654..0000000000 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/interpolationTable.mo +++ /dev/null @@ -1,55 +0,0 @@ -within Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData.Functions; -function interpolationTable "Constructs an interpolation table" - extends Modelica.Icons.Function; - import Modelica.Math.Vectors.reverse; - input Real x[:] "Abscissa of measurements"; - input Real y[:] "Ordinate of measurements"; - input Real xSat "Abscissa where saturation is reached"; - input Real ySat "Saturation ordinate"; - input Boolean originSymmetric=true "i.e. y(-x)=-y(x), otherwise y(-x)=y(x)"; - input Boolean completeOrigin=true "i.e. add (0, 0)"; - output Real table[(2*size(x,1) + 2 + (if completeOrigin then 1 else 0)), 2] - "Resulting interpolation table matrix"; -algorithm - assert(size(x,1)==size(y,1), "Abscissa and ordinate have to have the same length"); - assert(xSat>x[end], "xSat has to be greater than last abszissa"); - assert(ySat>y[end], "ySat has to be greater than last ordinate"); - if originSymmetric then - if completeOrigin then - table:=[cat(1, -{xSat}, -reverse(x), {0}, x, {xSat}), - cat(1, -{ySat}, -reverse(y), {0}, y, {ySat})]; - else - table:=[cat(1, -{xSat}, -reverse(x), x, {xSat}), - cat(1, -{ySat}, -reverse(y), y, {ySat})]; - end if; - else - if completeOrigin then - table:=[cat(1, -{xSat}, -reverse(x), {0}, x, {xSat}), - cat(1, {ySat}, reverse(y), {0}, y, {ySat})]; - else - table:=[cat(1, -{xSat}, -reverse(x), x, {xSat}), - cat(1, {ySat}, reverse(y), y, {ySat})]; - end if; - end if; - annotation (Documentation(info=" -

    -Assume we have a series of measurements only in the right half of the plane (x,y), e.g.
    -x[:]={5, 11, 18}
    -x[:]={1, 2, 3}
    -and we want to create an interpolation table for the full plane, this function helps. -

    -

    -The parameter originSymmetric controls whether the resulting table is symmetric to the origin or not.
    -The parameter cpmpleteOrigin controls whether the origin (0, 0) is explicitely added or not.
    -Additonally, the parameters xSat and ySat specify a last point where saturation occurs. -

    -

    originSymmetric=true and completeOrigin=true:

    -
    Result A[7, 2] = [-xSat, -ySat; -18, -3; -11, -2; -5, -1; 0, 0; 5, 1; 11, 2; 18, 3; xSat, ySat]
    -

    originSymmetric=true and completeOrigin=false:

    -
    Result A[6, 2] = [-xSat, -ySat; -18, -3; -11, -2; -5, -1;       5, 1; 11, 2; 18, 3; xSat, ySat]
    -

    originSymmetric=false and completeOrigin=true:

    -
    Result A[7, 2] = [-xSat, +ySat; -18, +3; -11, +2; -5, +1; 0, 0; 5, 1; 11, 2; 18, 3; xSat, ySat]
    -

    originSymmetric=false and completeOrigin=false:

    -
    Result A[6, 2] = [-xSat, +ySat; -18, +3; -11, +2; -5, +1;       5, 1; 11, 2; 18, 3; xSat, ySat]
    -")); -end interpolationTable; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/package.order b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/package.order index 71fb6e08cf..ab05869d81 100644 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/package.order +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/package.order @@ -1,2 +1 @@ -interpolationTable exMax diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo index 75846221e8..1590b8655b 100644 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo @@ -1,42 +1,18 @@ within Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData; record M330_50A "M330-50A @ 50Hz 0/90 deg" - extends Modelica.Icons.Record; - import Modelica.Math.Vectors.interpolate; - import Modelica.Math.Vectors.find; - import FluxTubesExtensions.Material.SoftMagnetic.RawData.Functions.exMax; - import FluxTubesExtensions.Material.SoftMagnetic.RawData.Functions.interpolationTable; - constant Real lb2kg=0.45359237 "Conversion kg/lb"; - parameter String label="M330-50A @ 50Hz 0/90 deg" "Name of material"; - parameter SI.Density rho=7650 "Density of material"; - // Losses - parameter SpecificPower p1=3.30 "Specific losses at 1.5 T and f1"; - parameter SI.Frequency f1=50 "Measurement frequency 1"; - parameter SpecificPower p2=1.9/lb2kg "Specific losses at 1.5 T and f2"; - parameter SI.Frequency f2=60 "Measurement frequency 2"; - parameter Real ratioHysteresis=(p2/p1*f1/f2 - f2/f1)/(1 - f2/f1) - "Ratio of hysteresis losses with respect to the total core losses at 1.5 T and f1"; - // saturation - parameter SI.MagneticPolarization Jsat=2.0 "Saturation polarization"; - parameter SI.MagneticFieldStrength Hsat=50e3 "Field strength to achieve Jsat"; - // given data points - parameter Integer N=size(J,1) "Length of measurement array"; - parameter SI.MagneticPolarization J[:]={0.5, 0.6, 0.7, 0.8, 0.9, 1.0, - 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9} "Polarization"; - parameter SI.MagneticFieldStrength H[N]={53, 60, 69, 79, 93, 112, - 141, 192, 313, 698, 1932, 4284, 7750, 13318, 19610} "Field strength"; - // calculated parameters - parameter SI.MagneticSusceptibility Chi[N]=1/mu_0*J./H "Susceptibility"; - parameter SI.RelativePermeability mu_r[N]=fill(1, N) + Chi "Relative permeability"; - // additional scalar parameters - parameter SI.RelativePermeability mu_ri=interpolate(H, mu_r, 0) - "Initial relative permeability at origin (extrapolation)"; - parameter SI.RelativePermeability mu_rMax=max(mu_r) "Maximum relative permeability"; - parameter Integer iMax=find(mu_rMax, mu_r) "Index of maximum relative permeability"; - parameter SI.RelativePermeability mu_ra=exMax(H, mu_r) - "Alternative initial relative permeability at origin (extrapolation)"; - // for use with CombiTables: add saturation and mirror at origin - parameter Real table[:,2]=interpolationTable(x=H, y=J, xSat=Hsat, ySat=Jsat, - originSymmetric=true, completeOrigin=true) "Table for interpolation"; + extends BaseData( + label="M330-50A @ 50Hz 0/90 deg", + rho=7650, + p1=3.30, + f1=50, + p2=1.9/lb2kg, + f2=60, + Jsat=2.0, + Hsat=1e5, + J={0.5, 0.6, 0.7, 0.8, 0.9, 1.0, + 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9}, + H={53, 60, 69, 79, 93, 112, + 141, 192, 313, 698, 1932, 4284, 7750, 13318, 19610}); annotation (defaultComponentPrefixes="parameter", Documentation(info="

    M330-50A at 50Hz for 0/90 deg magnetization table H(J)taken from manufacturer's datasheet diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo index a15d4325ac..34f4a7d19a 100644 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo @@ -1,6 +1,6 @@ within Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData; record M400_50A "M400-50A @ 50Hz 0/90 deg" - extends M330_50A( + extends BaseData( label="M400-50A @ 50Hz 0/90 deg", rho=7700, p1=4.00, @@ -8,11 +8,11 @@ record M400_50A "M400-50A @ 50Hz 0/90 deg" p2=2.3/lb2kg, f2=60, Jsat=2.0, - Hsat=50e3, + Hsat=1e5, J={0.5, 0.6, 0.7, 0.8, 0.9, 1.0, - 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9}, + 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9}, H={75, 84, 93, 104, 117, 134, - 159, 199, 282, 505, 1284, 3343, 6787, 11712, 19044}); + 159, 199, 282, 505, 1284, 3343, 6787, 11712, 19044}); annotation (defaultComponentPrefixes="parameter", Documentation(info="

    M400-50A at 50Hz for 0/90 deg magnetization table taken from manufacturer's datasheet diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo index 2703c974c2..22f975cdf2 100644 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo @@ -15,8 +15,7 @@ This raw data records cover the following information:

  • magnetization table H(J) taken from manufacturer's datasheet
  • -Using the function interpolationTable -the dataset is expanded by saturation polarization Jsat, adding the origin (0,0) and mirrored at the origin.
    +The dataset [H, J, mu_r] is expanded by saturation {Hsat, Jsat, 1}, adding the origin {0, 0, mu_ri} and mirrored at the origin.
    For interpolation, use smoothness = MonotoneContinuousDerivative and extrapolation = HoldLastPoint.

    @@ -24,15 +23,14 @@ Assuming the maximum relative permeability is included in the measurements, addi

    • Ratio of hysteresis losses with respect to the total core losses at 1.5 T and f1
    • -
    • Susceptibility Chi(H)
    • Relative permeability mu_r(H)
    • Initial relative permeability mu_ri: linear extrapolation from the first two points to H=0
    • Maximum relative permeability mu_riMax
    • Alternative initial relative permeability mu_ra: linear extrapolation from right of the maximum to H=0 - using the function exMax (extrapolation from maximum)
    • + using the function exMax (extrapolation from maximum)

    -The separation of hysteresis and eddy current losses is done according to the formula of Jordan ([Jordan1924]): +The separation of hysteresis and eddy current losses is done according to the formula of Jordan ([Jordan1924]):

    
     P = vRef⋅m⋅[ratioHysteresis⋅(f/fRef) + (1 - ratioHysteresis)⋅(f/fRef)2]⋅(B/BRef)2
    diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.order b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.order
    index 2bf5c47671..4329645234 100644
    --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.order
    +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.order
    @@ -1,3 +1,4 @@
     Functions
    +BaseData
     M330_50A
     M400_50A
    
    From 4b316e2574bf878d5eaf9bd52e8c89fff60ae737 Mon Sep 17 00:00:00 2001
    From: AHaumer 
    Date: Tue, 17 Feb 2026 17:23:59 +0100
    Subject: [PATCH 07/13] corrected a html bug
    
    ---
     .../Material/SoftMagnetic/RawData/package.mo          | 11 ++++++-----
     .../Magnetic/FluxTubes/UsersGuide/Approximation.mo    |  3 +++
     .../Magnetic/FluxTubes/UsersGuide/ParameterFit.mo     |  2 +-
     3 files changed, 10 insertions(+), 6 deletions(-)
    
    diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo
    index 22f975cdf2..0fb7e97007 100644
    --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo
    +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo
    @@ -15,7 +15,7 @@ This raw data records cover the following information:
     
  • magnetization table H(J) taken from manufacturer's datasheet
  • -The dataset [H, J, mu_r] is expanded by saturation {Hsat, Jsat, 1}, adding the origin {0, 0, mu_ri} and mirrored at the origin.
    +The dataset [H, J, mu_r] is expanded by saturation {Hsat, Jsat, 1}, adding the origin {0, 0, mu_ri} and mirrored at the origin.
    For interpolation, use smoothness = MonotoneContinuousDerivative and extrapolation = HoldLastPoint.

    @@ -27,16 +27,17 @@ Assuming the maximum relative permeability is included in the measurements, addi

  • Initial relative permeability mu_ri: linear extrapolation from the first two points to H=0
  • Maximum relative permeability mu_riMax
  • Alternative initial relative permeability mu_ra: linear extrapolation from right of the maximum to H=0 - using the function exMax (extrapolation from maximum)
  • + using the function exMax (extrapolation from maximum)

    -The separation of hysteresis and eddy current losses is done according to the formula of Jordan ([Jordan1924]): +The separation of hysteresis and eddy current losses is done according to the formula of Jordan ([Jordan1924]):

    
    -P = vRef⋅m⋅[ratioHysteresis⋅(f/fRef) + (1 - ratioHysteresis)⋅(f/fRef)2]⋅(B/BRef)2
    +P = kd⋅vRef⋅m⋅[ratioHysteresis⋅(f/fRef) + (1 - ratioHysteresis)⋅(f/fRef)2]⋅(B/BRef)2
     

    -vRef are the total specific losses at reference frequency fRef and reference peak flux density fRef (usually 1.5 T). +vRef are the total specific losses at reference frequency fRef and reference peak flux density fRef (usually 1.5 T).
    +kd is an (empirical) deterioration factor due to machining (punching).

    ")); end RawData; diff --git a/Modelica/Magnetic/FluxTubes/UsersGuide/Approximation.mo b/Modelica/Magnetic/FluxTubes/UsersGuide/Approximation.mo index ac78f889cf..461e185ee3 100644 --- a/Modelica/Magnetic/FluxTubes/UsersGuide/Approximation.mo +++ b/Modelica/Magnetic/FluxTubes/UsersGuide/Approximation.mo @@ -45,5 +45,8 @@ Jsat = ∑ Jk µri = 1 + ∑ χk - χC k=1
    +

    +Additonally, it is possible to implement an interpolation based on raw data instead of using approximation functions. +

    ")); end Approximation; diff --git a/Modelica/Magnetic/FluxTubes/UsersGuide/ParameterFit.mo b/Modelica/Magnetic/FluxTubes/UsersGuide/ParameterFit.mo index 3b5756743f..635f4e0a04 100644 --- a/Modelica/Magnetic/FluxTubes/UsersGuide/ParameterFit.mo +++ b/Modelica/Magnetic/FluxTubes/UsersGuide/ParameterFit.mo @@ -20,7 +20,7 @@ model ParameterFit "Fitting the parameters" where µri is the initial relative permeability as described in the raw data directory.
  • Change the 1st constraint: |1 + ∑ χk - χC - µri| ≤ ε.
  • Again, try first with higher allowed deviation, then reduce ε step by step.
  • -
  • Last, check your solution in a diagram. If you are satisfied, you have find a good guess for the parameters.
  • +
  • Last, check your solution in a diagram. If you are satisfied, you have found a good guess for the parameters.
  • ")); end ParameterFit; From a35fea5ec14427baa421174eff7b54ae05c80b4f Mon Sep 17 00:00:00 2001 From: AHaumer Date: Tue, 17 Feb 2026 20:37:20 +0100 Subject: [PATCH 08/13] had to correct import and links from my development version to MSL --- .../FluxTubes/Material/SoftMagnetic/RawData/BaseData.mo | 6 +++--- .../FluxTubes/Material/SoftMagnetic/RawData/package.mo | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/BaseData.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/BaseData.mo index 1d75a0e02f..6eb8f2f8a5 100644 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/BaseData.mo +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/BaseData.mo @@ -4,15 +4,15 @@ partial record BaseData "BaseData record for RawData" import Modelica.Math.Vectors.interpolate; import Modelica.Math.Vectors.find; import Modelica.Math.Vectors.reverse; - import FluxTubesExtensions.Material.SoftMagnetic.RawData.Functions.exMax; + import Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData.Functions.exMax; constant Real lb2kg=0.45359237 "Conversion kg/lb"; parameter String label="RawData" "Name of material"; parameter SI.Density rho "Density of material"; // Losses - parameter FluxTubesExtensions.Types.SpecificPower p1 + parameter FluxTubes.Types.SpecificPower p1 "Specific losses at 1.5 T and f1"; parameter SI.Frequency f1 "Measurement frequency 1"; - parameter FluxTubesExtensions.Types.SpecificPower p2 + parameter FluxTubes.Types.SpecificPower p2 "Specific losses at 1.5 T and f2"; parameter SI.Frequency f2 "Measurement frequency 2"; parameter Real ratioHysteresis=(p2/p1*f1/f2 - f2/f1)/(1 - f2/f1) diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo index 0fb7e97007..5c450b3db0 100644 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo @@ -27,10 +27,10 @@ Assuming the maximum relative permeability is included in the measurements, addi
  • Initial relative permeability mu_ri: linear extrapolation from the first two points to H=0
  • Maximum relative permeability mu_riMax
  • Alternative initial relative permeability mu_ra: linear extrapolation from right of the maximum to H=0 - using the function exMax (extrapolation from maximum)
  • + using the function exMax (extrapolation from maximum)

    -The separation of hysteresis and eddy current losses is done according to the formula of Jordan ([Jordan1924]): +The separation of hysteresis and eddy current losses is done according to the formula of Jordan ([Jordan1924]):

    
     P = kd⋅vRef⋅m⋅[ratioHysteresis⋅(f/fRef) + (1 - ratioHysteresis)⋅(f/fRef)2]⋅(B/BRef)2
    
    From e10e586687c6ed3be120791819f9ad0cbcd2771c Mon Sep 17 00:00:00 2001
    From: AHaumer 
    Date: Tue, 17 Feb 2026 20:58:40 +0100
    Subject: [PATCH 09/13] corrected cosmetics (MagneticPolarization has the same
     unit as MagneticFlux)
    
    ---
     .../Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial.mo | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial.mo b/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial.mo
    index 6de42c99d7..41cf5ac8c1 100644
    --- a/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial.mo
    +++ b/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial.mo
    @@ -3,9 +3,9 @@ model ShowMaterial "Show material characteristic"
       extends Modelica.Icons.Example;
       parameter SI.Current I=1 "Peak exciting current";
       SI.MagneticFieldStrength H=coreNon_Hys.H "Magnetic field strength";
    -  SI.MagneticFluxDensity B=coreNon_Hys.B - mu_0*H "Magnetic polarisation J";
    +  SI.MagneticPolarization J=coreNon_Hys.B - mu_0*H "Magnetic polarization";
       SI.RelativePermeability mu_r=coreNon_Hys.mu_r "Relative permeability";
    -  SI.MagneticPolarization J_rD=combiTable1Ds.y[1] "Magnetic polarisation from raw data";
    +  SI.MagneticPolarization J_rD=combiTable1Ds.y[1] "Magnetic polarization from raw data";
       SI.RelativePermeability mu_r_rD=combiTable1Ds.y[2] "Relative permability from raw data";
       Modelica.Electrical.Analog.Sources.SineCurrent source(I=I, f=50) annotation (
           Placement(transformation(
    
    From 800a32490fc5e935b3bf0c89b881a244a3b9fb2b Mon Sep 17 00:00:00 2001
    From: AHaumer 
    Date: Tue, 17 Feb 2026 22:13:02 +0100
    Subject: [PATCH 10/13] implemented table based interpolation om magnetization
     characteristic
    
    ---
     .../FluxTubes/BaseClasses/FixedShape.mo       | 33 ++++++++---
     .../Examples/BasicExamples/ShowMaterial.mo    |  4 +-
     .../Material/SoftMagnetic/RawData/BaseData.mo | 51 -----------------
     .../Material/SoftMagnetic/RawData/M330_50A.mo | 57 ++++++++++++++-----
     .../Material/SoftMagnetic/RawData/M400_50A.mo |  2 +-
     .../SoftMagnetic/RawData/package.order        |  1 -
     .../Magnetic/FluxTubes/Types/Magnetization.mo |  3 +-
     7 files changed, 74 insertions(+), 77 deletions(-)
     delete mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/BaseData.mo
    
    diff --git a/Modelica/Magnetic/FluxTubes/BaseClasses/FixedShape.mo b/Modelica/Magnetic/FluxTubes/BaseClasses/FixedShape.mo
    index f0e3f5bed6..1cde5a7d47 100644
    --- a/Modelica/Magnetic/FluxTubes/BaseClasses/FixedShape.mo
    +++ b/Modelica/Magnetic/FluxTubes/BaseClasses/FixedShape.mo
    @@ -1,6 +1,10 @@
     within Modelica.Magnetic.FluxTubes.BaseClasses;
     partial model FixedShape "Base class for flux tubes with fixed shape during simulation; linear or non-linear material characteristics"
       import Modelica.Magnetic.FluxTubes.Types.Magnetization;
    +  import Modelica.Blocks.Types.ExternalCombiTable1D;
    +  import Modelica.Blocks.Types.Smoothness;
    +  import Modelica.Blocks.Types.Extrapolation;
    +  import Modelica.Blocks.Tables.Internal.getTable1DValue;
     
       // Material
       // This parameter is kept for backwards compatibility reasons, might be replaced by a member "Linear" in the enumeration Magnetization
    @@ -16,14 +20,19 @@ partial model FixedShape "Base class for flux tubes with fixed shape during simu
       parameter Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.BaseData
         material=Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.BaseData()
         "Ferromagnetic material characteristics, approximation according to Roschke"
    -    annotation (choicesAllMatching=true, Dialog(tab="Material", enable=nonLinearPermeability and magnetization==Magnetization.Roschke));
    -  parameter
    -    Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.Macfadyen.BaseData
    -    materialMacfadyen=
    -      Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.Macfadyen.BaseData()
    +    annotation (choicesAllMatching=true, Dialog(tab="Material",
    +      enable=nonLinearPermeability and magnetization==Magnetization.Roschke));
    +  parameter Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.Macfadyen.BaseData
    +    materialMacfadyen=Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.Macfadyen.BaseData()
         "Ferromagnetic material characteristics, approximation according to Macfadyen"
    +    annotation (choicesAllMatching=true, Dialog(tab="Material",
    +      enable=nonLinearPermeability and magnetization == Magnetization.Macfadyen));
    +  parameter Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData.M330_50A
    +    materialTableBased=Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData.M330_50A()
    +    "Interpolation based on RawData table"
         annotation (choicesAllMatching=true, Dialog(tab="Material", enable=
    -          nonLinearPermeability and magnetization == Magnetization.Macfadyen));
    +          nonLinearPermeability and magnetization == Magnetization.TableBased));
    +
       extends Modelica.Magnetic.FluxTubes.Interfaces.TwoPort;
       input SI.CrossSection A "Cross-sectional area";
       SI.Reluctance R_m "Magnetic reluctance";
    @@ -34,17 +43,25 @@ partial model FixedShape "Base class for flux tubes with fixed shape during simu
       SI.RelativePermeability mu_r(start=mu_rConst) "Relative magnetic permeability";
     protected
       Real B_N=abs(B/material.B_myMax) "Absolute value of normalized B";
    -  Real epsilon=1e3*Modelica.Constants.eps;
    +  constant Real epsilon=1e3*Modelica.Constants.eps;
    +  final parameter ExternalCombiTable1D tableID=ExternalCombiTable1D(
    +    "NoName", "NoName",
    +    materialTableBased.table, 2:3,
    +    Smoothness.MonotoneContinuousDerivative2,
    +    Extrapolation.HoldLastPoint,
    +    false, ",", 0) "External table object";
     equation
       R_m = 1/G_m;
       V_m = Phi*R_m;
       if nonLinearPermeability then
         if magnetization == Magnetization.Roschke then
           mu_r = 1 + (material.mu_i - 1 + material.c_a*B_N)/(1 + material.c_b*B_N + B_N^material.n);
    -    else // if magnetization == Magnetization.Macfadyen then
    +    elseif magnetization == Magnetization.Macfadyen then
           mu_r = smooth(1, (if noEvent(abs(H)
    Date: Tue, 17 Feb 2026 22:24:17 +0100
    Subject: [PATCH 11/13] made an array expression easier (for tools)
    
    ---
     .../FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo         | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo
    index 949b675df3..c716ba9dc8 100644
    --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo
    +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo
    @@ -27,7 +27,7 @@ record M330_50A "M330-50A @ 50Hz 0/90 deg"
       parameter SI.MagneticFieldStrength H[N]={53, 60, 69, 79, 93, 112,
            141, 192, 313, 698, 1932, 4284, 7750, 13318, 19610} "Field strength";
       // calculated parameters
    -  parameter SI.RelativePermeability mu_r[N]=fill(1, N) + 1/mu_0*J./H "Relative permeability";
    +  parameter SI.RelativePermeability mu_r[N]={1 + J[k]/(mu_0*H[k]) for k in 1:N} "Relative permeability";
       // additional scalar parameters (provided maximum of permability is included in the table)
       parameter SI.RelativePermeability mu_ri=interpolate(H, mu_r, 0)
         "Initial relative permeability at origin (extrapolation)";
    
    From 993b1d5ce9a57347944caaca9fedb99d662f6fed Mon Sep 17 00:00:00 2001
    From: AHaumer 
    Date: Wed, 18 Feb 2026 15:05:28 +0100
    Subject: [PATCH 12/13] revert interpolation (could show oscillations)
    
    ---
     .../FluxTubes/BaseClasses/FixedShape.mo       | 19 +------
     .../Examples/BasicExamples/ShowMaterial.mo    |  5 +-
     .../SoftMagnetic/RawData/Functions/exMax.mo   | 25 ---------
     .../SoftMagnetic/RawData/Functions/package.mo |  4 --
     .../RawData/Functions/package.order           |  1 -
     .../RawData/Internal/analyzeRawData.mo        | 33 ++++++++++++
     .../SoftMagnetic/RawData/Internal/package.mo  |  4 ++
     .../RawData/Internal/package.order            |  1 +
     .../Material/SoftMagnetic/RawData/M330_50A.mo | 53 ++++++++-----------
     .../Material/SoftMagnetic/RawData/M400_50A.mo |  8 ++-
     .../Material/SoftMagnetic/RawData/package.mo  | 22 ++------
     .../SoftMagnetic/RawData/package.order        |  2 +-
     .../Magnetic/FluxTubes/Types/Magnetization.mo |  3 +-
     .../FluxTubes/UsersGuide/Approximation.mo     |  1 +
     .../FluxTubes/UsersGuide/Literature.mo        | 20 -------
     .../FluxTubes/UsersGuide/ParameterFit.mo      | 10 ++--
     .../FluxTubes/UsersGuide/ReleaseNotes.mo      |  4 +-
     .../ShowMaterial/comparisonSignals.txt        |  2 +
     18 files changed, 85 insertions(+), 132 deletions(-)
     delete mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/exMax.mo
     delete mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/package.mo
     delete mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/package.order
     create mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Internal/analyzeRawData.mo
     create mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Internal/package.mo
     create mode 100644 Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Internal/package.order
    
    diff --git a/Modelica/Magnetic/FluxTubes/BaseClasses/FixedShape.mo b/Modelica/Magnetic/FluxTubes/BaseClasses/FixedShape.mo
    index 1cde5a7d47..e6ddc1b5dd 100644
    --- a/Modelica/Magnetic/FluxTubes/BaseClasses/FixedShape.mo
    +++ b/Modelica/Magnetic/FluxTubes/BaseClasses/FixedShape.mo
    @@ -1,10 +1,6 @@
     within Modelica.Magnetic.FluxTubes.BaseClasses;
     partial model FixedShape "Base class for flux tubes with fixed shape during simulation; linear or non-linear material characteristics"
       import Modelica.Magnetic.FluxTubes.Types.Magnetization;
    -  import Modelica.Blocks.Types.ExternalCombiTable1D;
    -  import Modelica.Blocks.Types.Smoothness;
    -  import Modelica.Blocks.Types.Extrapolation;
    -  import Modelica.Blocks.Tables.Internal.getTable1DValue;
     
       // Material
       // This parameter is kept for backwards compatibility reasons, might be replaced by a member "Linear" in the enumeration Magnetization
    @@ -27,11 +23,6 @@ partial model FixedShape "Base class for flux tubes with fixed shape during simu
         "Ferromagnetic material characteristics, approximation according to Macfadyen"
         annotation (choicesAllMatching=true, Dialog(tab="Material",
           enable=nonLinearPermeability and magnetization == Magnetization.Macfadyen));
    -  parameter Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData.M330_50A
    -    materialTableBased=Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData.M330_50A()
    -    "Interpolation based on RawData table"
    -    annotation (choicesAllMatching=true, Dialog(tab="Material", enable=
    -          nonLinearPermeability and magnetization == Magnetization.TableBased));
     
       extends Modelica.Magnetic.FluxTubes.Interfaces.TwoPort;
       input SI.CrossSection A "Cross-sectional area";
    @@ -44,24 +35,16 @@ partial model FixedShape "Base class for flux tubes with fixed shape during simu
     protected
       Real B_N=abs(B/material.B_myMax) "Absolute value of normalized B";
       constant Real epsilon=1e3*Modelica.Constants.eps;
    -  final parameter ExternalCombiTable1D tableID=ExternalCombiTable1D(
    -    "NoName", "NoName",
    -    materialTableBased.table, 2:3,
    -    Smoothness.MonotoneContinuousDerivative2,
    -    Extrapolation.HoldLastPoint,
    -    false, ",", 0) "External table object";
     equation
       R_m = 1/G_m;
       V_m = Phi*R_m;
       if nonLinearPermeability then
         if magnetization == Magnetization.Roschke then
           mu_r = 1 + (material.mu_i - 1 + material.c_a*B_N)/(1 + material.c_b*B_N + B_N^material.n);
    -    elseif magnetization == Magnetization.Macfadyen then
    +    else // if magnetization == Magnetization.Macfadyen then
           mu_r = smooth(1, (if noEvent(abs(H)
     

    -It is possible to compare the approximation with interpolated data from a manufacturer's datasheet (raw Data) J_rD and mu_r_rD for material = M330_50A. +It is possible to compare the approximation with interpolated data from a manufacturer's datasheet (raw Data) J_rD and mu_r_rD, choosing the same material (e.g. M330_50A).
    +Note that smoothness (the interpolation method) is set to LinearSegments. This shows the nodes and avoids undesired curvature between them.

    Note the non-sinusoidal trajectory of voltage excitingCoil.v due to saturation and a sonusoidal excitation current. diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/exMax.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/exMax.mo deleted file mode 100644 index f7fd5dac9f..0000000000 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Functions/exMax.mo +++ /dev/null @@ -1,25 +0,0 @@ -within Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData.Functions; -function exMax "Extrapolation from maximum" - extends Modelica.Icons.Function; - import Modelica.Math.Vectors.find; - input Real x[:] "Absicissa of nodes"; - input Real y[:] "Ordinates of nodes"; - input Real dyMin=1 "Minimum difference of ordinates"; - output Real z "Extrapolation from maximum"; -protected - Real yMax=max(y) "Maximum of ordinates"; - Integer iMax=find(yMax, y) "Index of maximum"; - Integer i2 "2nd index for extrapolation"; -algorithm - // avoid horizontal approximation - i2:= if abs(y[iMax] - y[iMax + 1])0 and J[1]>0, "J=0 and H=0 are not expected in the given arrays!"); + assert(H[end]H[k - 1], "H is expected with ascending order!"); + end for; + mu_r :={1 + J[k]/(mu_0*H[k]) for k in 1:size(J, 1)}; + annotation (Documentation(info=" +

    This helper functions checks

    +
      +
    • whether the given arrays J and H have the same length.
    • +
    • whether the origin (0, 0) is not included in the given arrays.
    • +
    • whether saturation (Hsat, Jsat) is not included in the given arrays.
    • +
    • whether array H is of ascending order.
    • +
    +

    and calculates relative permeability:

    +
    
    +          J
    +µr = 1 + ----
    +         µ0⋅H
    +
    +")); +end analyzeRawData; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Internal/package.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Internal/package.mo new file mode 100644 index 0000000000..684e7b0a3a --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Internal/package.mo @@ -0,0 +1,4 @@ +within Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData; +package Internal "Internal helper function(s)" + extends Modelica.Icons.InternalPackage; +end Internal; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Internal/package.order b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Internal/package.order new file mode 100644 index 0000000000..6ac8f28b25 --- /dev/null +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/Internal/package.order @@ -0,0 +1 @@ +analyzeRawData diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo index c716ba9dc8..b5f47ea5c4 100644 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M330_50A.mo @@ -4,47 +4,40 @@ record M330_50A "M330-50A @ 50Hz 0/90 deg" import Modelica.Math.Vectors.interpolate; import Modelica.Math.Vectors.find; import Modelica.Math.Vectors.reverse; - import Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData.Functions.exMax; - constant Real lb2kg=0.45359237 "Conversion kg/lb"; + import Modelica.Magnetic.FluxTubes.Material.SoftMagnetic.RawData.Internal.analyzeRawData; parameter String label="M330-50A @ 50Hz 0/90 deg" "Name of material"; - parameter SI.Density rho=7650 "Density of material"; + parameter Modelica.Units.SI.Density rho=7650 "Density of material"; // Losses - parameter FluxTubes.Types.SpecificPower p1=3.30 - "Specific losses at 1.5 T and f1"; - parameter SI.Frequency f1=50 "Measurement frequency 1"; - parameter FluxTubes.Types.SpecificPower p2=21.9/lb2kg - "Specific losses at 1.5 T and f2"; - parameter SI.Frequency f2=60 "Measurement frequency 2"; - parameter Real ratioHysteresis=(p2/p1*f1/f2 - f2/f1)/(1 - f2/f1) - "Ratio of hysteresis losses with respect to the total core losses at 1.5 T and f1"; - // saturation - parameter SI.MagneticPolarization Jsat=2.0 "Saturation polarization"; - parameter SI.MagneticFieldStrength Hsat=1e5 "Field strength to achieve Jsat"; + parameter FluxTubes.Types.SpecificPower v15=3.30 + "Specific losses at 1.5 T and fRef"; + parameter Modelica.Units.SI.Frequency fRef=50 "Measurement frequency 1"; + // Saturation + parameter Modelica.Units.SI.MagneticPolarization Jsat=2.0 + "Saturation polarization"; + parameter Modelica.Units.SI.MagneticFieldStrength Hsat=1e5 + "Field strength to achieve Jsat"; // given data points - parameter Integer N=size(J,1) "Length of measurement array"; - parameter SI.MagneticPolarization J[:]={0.5, 0.6, 0.7, 0.8, 0.9, 1.0, - 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9} "Polarization"; - parameter SI.MagneticFieldStrength H[N]={53, 60, 69, 79, 93, 112, - 141, 192, 313, 698, 1932, 4284, 7750, 13318, 19610} "Field strength"; - // calculated parameters - parameter SI.RelativePermeability mu_r[N]={1 + J[k]/(mu_0*H[k]) for k in 1:N} "Relative permeability"; - // additional scalar parameters (provided maximum of permability is included in the table) - parameter SI.RelativePermeability mu_ri=interpolate(H, mu_r, 0) + parameter Modelica.Units.SI.MagneticPolarization J[:]={0.5,0.6,0.7,0.8,0.9, + 1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9} "Polarization"; + parameter Modelica.Units.SI.MagneticFieldStrength H[:]={53,60,69,79,93,112, + 141,192,313,698,1932,4284,7750,13318,19610} "Field strength"; + // Calculated parameters + parameter Modelica.Units.SI.RelativePermeability mu_r[size(J,1)]= + analyzeRawData(J, H, Jsat, Hsat) "Relative permeability"; + parameter Modelica.Units.SI.RelativePermeability mu_ri=interpolate(H, mu_r, 0) "Initial relative permeability at origin (extrapolation)"; - parameter SI.RelativePermeability mu_rMax=max(mu_r) "Maximum relative permeability"; + parameter Modelica.Units.SI.RelativePermeability mu_rMax=max(mu_r) + "Maximum relative permeability"; parameter Integer iMax=find(mu_rMax, mu_r) "Index of maximum relative permeability"; - parameter SI.RelativePermeability mu_ra=exMax(H, mu_r) - "Alternative initial relative permeability at origin (extrapolation)"; - // for use with CombiTables: add saturation and mirror at origin - parameter Real table[:,3]=[ + // for interpolation add saturation, origin and mirror at origin + parameter Real table[2*size(J,1) + 3,3]=[ cat(1, -{Hsat}, -reverse(H), { 0}, H, {Hsat}), cat(1, -{Jsat}, -reverse(J), { 0}, J, {Jsat}), cat(1, { 1}, reverse(mu_r), {mu_ri}, mu_r, { 1})] "Table for interpolation H, J, mu_r"; annotation (defaultComponentPrefixes="parameter", Documentation(info="

    -M330-50A at 50Hz for 0/90 deg magnetization table H(J)taken from manufacturer's datasheet, -also BaseData record definition. +M330-50A at 50Hz for 0/90 deg magnetization table H(J)taken from manufacturer's datasheet.

    "), Icon(graphics={Text( diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo index 0ed277fa90..db7e991a7f 100644 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/M400_50A.mo @@ -3,10 +3,8 @@ record M400_50A "M400-50A @ 50Hz 0/90 deg" extends M330_50A( label="M400-50A @ 50Hz 0/90 deg", rho=7700, - p1=4.00, - f1=50, - p2=2.3/lb2kg, - f2=60, + v15=4.00, + fRef=50, Jsat=2.0, Hsat=1e5, J={0.5, 0.6, 0.7, 0.8, 0.9, 1.0, @@ -15,7 +13,7 @@ record M400_50A "M400-50A @ 50Hz 0/90 deg" 159, 199, 282, 505, 1284, 3343, 6787, 11712, 19044}); annotation (defaultComponentPrefixes="parameter", Documentation(info="

    -M400-50A at 50Hz for 0/90 deg magnetization table taken from manufacturer's datasheet +M400-50A at 50Hz for 0/90 deg magnetization table taken from manufacturer's datasheet.

    ")); end M400_50A; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo index 5c450b3db0..1058777e64 100644 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.mo @@ -9,35 +9,23 @@ This raw data records cover the following information:

    • density
    • -
    • specific losses at 2 different frequencies and B = 1.5 T
    • +
    • specific losses at reference frequency and B = 1.5 T
    • saturation polarization
    • magnetic field strength where saturation polarization is reached with desired accuracy
    • magnetization table H(J) taken from manufacturer's datasheet

    -The dataset [H, J, mu_r] is expanded by saturation {Hsat, Jsat, 1}, adding the origin {0, 0, mu_ri} and mirrored at the origin.
    -For interpolation, use smoothness = MonotoneContinuousDerivative and extrapolation = HoldLastPoint. +The dataset [H, J, mu_r] is expanded by saturation {Hsat, Jsat, 1}, adding the origin {0, 0, mu_ri} and mirrored at the origin, +so the result can be used for interpolation.

    -Assuming the maximum relative permeability is included in the measurements, additional parameters are calculated: +Additional parameters are calculated:

      -
    • Ratio of hysteresis losses with respect to the total core losses at 1.5 T and f1
    • Relative permeability mu_r(H)
    • Initial relative permeability mu_ri: linear extrapolation from the first two points to H=0
    • Maximum relative permeability mu_riMax
    • -
    • Alternative initial relative permeability mu_ra: linear extrapolation from right of the maximum to H=0 - using the function exMax (extrapolation from maximum)
    • +
    • The index of maximum relative permeability iMax
    -

    -The separation of hysteresis and eddy current losses is done according to the formula of Jordan ([Jordan1924]): -

    -
    
    -P = kd⋅vRef⋅m⋅[ratioHysteresis⋅(f/fRef) + (1 - ratioHysteresis)⋅(f/fRef)2]⋅(B/BRef)2
    -
    -

    -vRef are the total specific losses at reference frequency fRef and reference peak flux density fRef (usually 1.5 T).
    -kd is an (empirical) deterioration factor due to machining (punching). -

    ")); end RawData; diff --git a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.order b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.order index 2bf5c47671..9f41a36023 100644 --- a/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.order +++ b/Modelica/Magnetic/FluxTubes/Material/SoftMagnetic/RawData/package.order @@ -1,3 +1,3 @@ -Functions +Internal M330_50A M400_50A diff --git a/Modelica/Magnetic/FluxTubes/Types/Magnetization.mo b/Modelica/Magnetic/FluxTubes/Types/Magnetization.mo index 057c6b31e3..3c6cae7a4c 100644 --- a/Modelica/Magnetic/FluxTubes/Types/Magnetization.mo +++ b/Modelica/Magnetic/FluxTubes/Types/Magnetization.mo @@ -1,6 +1,5 @@ within Modelica.Magnetic.FluxTubes.Types; type Magnetization = enumeration( Roschke "Approximation formula according to Roschke", - Macfadyen "Approximation formula according to Macfadyen et al", - TableBased "Interpolation based on RawData table") + Macfadyen "Approximation formula according to Macfadyen et al") "Enumeration defining the approximation of the magnetization characteristic"; diff --git a/Modelica/Magnetic/FluxTubes/UsersGuide/Approximation.mo b/Modelica/Magnetic/FluxTubes/UsersGuide/Approximation.mo index 461e185ee3..dc6e0c1c71 100644 --- a/Modelica/Magnetic/FluxTubes/UsersGuide/Approximation.mo +++ b/Modelica/Magnetic/FluxTubes/UsersGuide/Approximation.mo @@ -47,6 +47,7 @@ Jsat = ∑ Jk

    Additonally, it is possible to implement an interpolation based on raw data instead of using approximation functions. +Be careful regarding the interpolation method, it could reveal undesired curvature between the nodes.

    ")); end Approximation; diff --git a/Modelica/Magnetic/FluxTubes/UsersGuide/Literature.mo b/Modelica/Magnetic/FluxTubes/UsersGuide/Literature.mo index e20a7816e0..10aae65a0b 100644 --- a/Modelica/Magnetic/FluxTubes/UsersGuide/Literature.mo +++ b/Modelica/Magnetic/FluxTubes/UsersGuide/Literature.mo @@ -79,26 +79,6 @@ class Literature "Literature"

  • -
  • Calculation of iron losses is discussed in: - -
    - - - - - - - - - -
    [Jordan1924] Heinz Jordan: - Die ferromagnetischen Konstanten für schwache Wechselfelder, - Elektrische Nachrichtentechnik 1924 (1), no. 8, pp. 269-283 (in German).
    [Krings2010] Andreas Krings and Juliette Soulard: - Overview and Comparison of Iron Loss Models for Electrical Machines, - Journal of Electrical Engineering 2010 (10), pp. 162-169.

    -
  • - -
  • Information related to the implemented hysteresis models can be found in:
    diff --git a/Modelica/Magnetic/FluxTubes/UsersGuide/ParameterFit.mo b/Modelica/Magnetic/FluxTubes/UsersGuide/ParameterFit.mo index 635f4e0a04..129b4f376a 100644 --- a/Modelica/Magnetic/FluxTubes/UsersGuide/ParameterFit.mo +++ b/Modelica/Magnetic/FluxTubes/UsersGuide/ParameterFit.mo @@ -2,7 +2,8 @@ within Modelica.Magnetic.FluxTubes.UsersGuide; model ParameterFit "Fitting the parameters" extends Modelica.Icons.Information; annotation (Documentation(info=" -

    The magnetisation characteristics of the originally included soft magnetic materials were compiled and measured respectively by Thomas Roschke, now with Johnson Electric. Provision of this data is highly appreciated. He also formulated the approximation function used for description of the magnetisation characteristics of these materials.

    +

    The magnetisation characteristics of the originally included soft magnetic materials were compiled and measured respectively by Thomas Roschke. +Provision of this data is highly appreciated. He also formulated the approximation function used for description of the magnetisation characteristics of these materials.

    The workflow of paramter fitting for the approximation according to Macfadyen at al can be recommended as follows:

    • N = 4 exponential terms is a good compromise between effort and accuracy.
    • @@ -10,11 +11,11 @@ model ParameterFit "Fitting the parameters"
    • First, compare the characteristic J(H) of the formula without the correction term (index "C", you may set χC = 0) with measured data, i.e. sum up the absolute of the differences.
    • Use as 1st constraint: |1 + ∑ χk - µra| ≤ ε - where µra is the alternative initial relative permeability as described in the raw data directory.
    • + where µra is an extrapolation of the given relative permeability towards the origin neglecting the potential decline of this characteristics near the origin.
    • Use as 2nd constraint |∑ χk⋅Hk - Jsat| ≤ ε where Jsat is the saturation polarization as described in the raw data directory.
    • -
    • Since optimization is sensitive to the starting point, try to gues a good initial parameter set.
    • -
    • Try first with higher allowed deviation, then reduce ε step by step.
    • +
    • Since optimization is sensitive to the starting point, try to guess a good initial parameter set.
    • +
    • Try first with higher allowed deviation ε, then reduce ε step by step.
    • Check your solution in a diagram. If it looks good (except the region around the origin), proceed:
    • Try a good guess for HC and χC ≈ µra - µri where µri is the initial relative permeability as described in the raw data directory.
    • @@ -22,5 +23,6 @@ model ParameterFit "Fitting the parameters"
    • Again, try first with higher allowed deviation, then reduce ε step by step.
    • Last, check your solution in a diagram. If you are satisfied, you have found a good guess for the parameters.
    +

    Note: It is possible to neglect the potential decline of the relative permeabilty near the origin and keep χC = 0. ")); end ParameterFit; diff --git a/Modelica/Magnetic/FluxTubes/UsersGuide/ReleaseNotes.mo b/Modelica/Magnetic/FluxTubes/UsersGuide/ReleaseNotes.mo index ebf46035d1..f0a06e1869 100644 --- a/Modelica/Magnetic/FluxTubes/UsersGuide/ReleaseNotes.mo +++ b/Modelica/Magnetic/FluxTubes/UsersGuide/ReleaseNotes.mo @@ -3,11 +3,11 @@ class ReleaseNotes "Release Notes" extends Modelica.Icons.ReleaseNotes; annotation (Documentation(info=" -

    Version 4.2.0, 2026-02-15 (Anton Haumer)
    +
    Version 4.2.0, 2026-02-18 (Anton Haumer)
    diff --git a/Modelica/Resources/Reference/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial/comparisonSignals.txt b/Modelica/Resources/Reference/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial/comparisonSignals.txt index 01f298f22c..217f9a49a4 100644 --- a/Modelica/Resources/Reference/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial/comparisonSignals.txt +++ b/Modelica/Resources/Reference/Modelica/Magnetic/FluxTubes/Examples/BasicExamples/ShowMaterial/comparisonSignals.txt @@ -1,7 +1,9 @@ time coreNon_Hys.H coreNon_Hys.J +coreNon_Hys.mu_r combiTable1Ds.y[1] +combiTable1Ds.y[2] coreNon_Hys.Phi integrator.y voltageSensor.v From 5fe49df5954cde430d4f84e8dc5d89ccd03d8bae Mon Sep 17 00:00:00 2001 From: AHaumer Date: Wed, 18 Feb 2026 15:29:52 +0100 Subject: [PATCH 13/13] corrected html bug --- Modelica/Magnetic/FluxTubes/UsersGuide/ParameterFit.mo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modelica/Magnetic/FluxTubes/UsersGuide/ParameterFit.mo b/Modelica/Magnetic/FluxTubes/UsersGuide/ParameterFit.mo index 129b4f376a..43b06e082d 100644 --- a/Modelica/Magnetic/FluxTubes/UsersGuide/ParameterFit.mo +++ b/Modelica/Magnetic/FluxTubes/UsersGuide/ParameterFit.mo @@ -23,6 +23,6 @@ Provision of this data is highly appreciated. He also formulated the approximati
  • Again, try first with higher allowed deviation, then reduce ε step by step.
  • Last, check your solution in a diagram. If you are satisfied, you have found a good guess for the parameters.
  • -

    Note: It is possible to neglect the potential decline of the relative permeabilty near the origin and keep χC = 0. +

    Note: It is possible to neglect the potential decline of the relative permeabilty near the origin and keep χC = 0.

    ")); end ParameterFit;