[FEM] use magnetization constraint for 2D
- uses the constraint for 2D magnetodynamics to perform e.g. Elmer's tutorial non. 15 - modify the Material manager to get rid of magnetization but keep the vectorial functionality because in future there will be support for e.g. birefringence materials etc.
This commit is contained in:
@@ -104,7 +104,7 @@ class MgDyn2Dwriter:
|
||||
permittivity = round(permittivity, 20) # to get rid of numerical artifacts
|
||||
self.write.constant("Permittivity Of Vacuum", permittivity)
|
||||
|
||||
def handleMagnetodynamic2DMaterial(self, bodies, equation):
|
||||
def handleMagnetodynamic2DMaterial(self, bodies):
|
||||
# check that all bodies have a set material
|
||||
for name in bodies:
|
||||
if self.write.getBodyMaterial(name) == None:
|
||||
@@ -142,49 +142,60 @@ class MgDyn2Dwriter:
|
||||
name, "Relative Permittivity",
|
||||
float(m["RelativePermittivity"])
|
||||
)
|
||||
if "Magnetization1" in m:
|
||||
magnetization = self.write.convert(m["Magnetization1"], "I/L")
|
||||
|
||||
def _outputMagnetodynamic2DBodyForce(self, obj, name, equation):
|
||||
if hasattr(obj, "CurrentDensity"):
|
||||
currentDensity = self.write.getFromUi(
|
||||
obj.CurrentDensity.getValueAs("A/m^2"), "A/m^2", "I/L^2"
|
||||
)
|
||||
currentDensity = round(currentDensity, 10) # to get rid of numerical artifacts
|
||||
if currentDensity == 0.0:
|
||||
# a zero density would break Elmer
|
||||
raise general_writer.WriteError("The current density must not be zero!")
|
||||
self.write.bodyForce(name, "Current Density", currentDensity)
|
||||
|
||||
if hasattr(obj, "Magnetization_im_1"):
|
||||
# output only if magnetization is enabled and needed
|
||||
if not obj.Magnetization_re_1_Disabled:
|
||||
if hasattr(obj, "Magnetization_re_1"):
|
||||
magnetization = float(obj.Magnetization_re_1.getValueAs("A/m"))
|
||||
self.write.material(name, "Magnetization 1", magnetization)
|
||||
if "Magnetization2" in m:
|
||||
magnetization = self.write.convert(m["Magnetization_2"], "I/L")
|
||||
if not obj.Magnetization_re_2_Disabled:
|
||||
if hasattr(obj, "Magnetization_re_2"):
|
||||
magnetization = float(obj.Magnetization_re_2.getValueAs("A/m"))
|
||||
self.write.material(name, "Magnetization 2", magnetization)
|
||||
if "Magnetization3" in m:
|
||||
magnetization = self.write.convert(m["Magnetization3"], "I/L")
|
||||
if not obj.Magnetization_re_3_Disabled:
|
||||
if hasattr(obj, "Magnetization_re_3"):
|
||||
magnetization = float(obj.Magnetization_re_3.getValueAs("A/m"))
|
||||
self.write.material(name, "Magnetization 3", magnetization)
|
||||
if equation.IsHarmonic:
|
||||
if "MagnetizationIm1" in m:
|
||||
magnetization = self.write.convert(m["MagnetizationIm1"], "I/L")
|
||||
# imaginaries are only needed for harmonic equation
|
||||
if equation.IsHarmonic:
|
||||
if not obj.Magnetization_im_1_Disabled:
|
||||
if hasattr(obj, "Magnetization_im_1"):
|
||||
magnetization = float(obj.Magnetization_im_1.getValueAs("A/m"))
|
||||
self.write.material(name, "Magnetization Im 1", magnetization)
|
||||
if "MagnetizationIm2" in m:
|
||||
magnetization = self.write.convert(m["MagnetizationIm2"], "I/L")
|
||||
if not obj.Magnetization_im_2_Disabled:
|
||||
if hasattr(obj, "Magnetization_im_2"):
|
||||
magnetization = float(obj.Magnetization_im_2.getValueAs("A/m"))
|
||||
self.write.material(name, "Magnetization Im 2", magnetization)
|
||||
if "MagnetizationIm3" in m:
|
||||
magnetization = self.write.convert(m["MagnetizationIm3"], "I/L")
|
||||
if not obj.Magnetization_im_3_Disabled:
|
||||
if hasattr(obj, "Magnetization_im_3"):
|
||||
magnetization = float(obj.Magnetization_im_3.getValueAs("A/m"))
|
||||
self.write.material(name, "Magnetization Im 3", magnetization)
|
||||
|
||||
def _outputMagnetodynamic2DBodyForce(self, obj, name):
|
||||
currentDensity = self.write.getFromUi(
|
||||
obj.CurrentDensity.getValueAs("A/m^2"), "A/m^2", "I/L^2"
|
||||
)
|
||||
currentDensity = round(currentDensity, 10) # to get rid of numerical artifacts
|
||||
if currentDensity == 0.0:
|
||||
# a zero density would break Elmer
|
||||
raise general_writer.WriteError("The current density must not be zero!")
|
||||
self.write.bodyForce(name, "Current Density", currentDensity)
|
||||
|
||||
def handleMagnetodynamic2DBodyForces(self, bodies):
|
||||
def handleMagnetodynamic2DBodyForces(self, bodies, equation):
|
||||
currentDensities = self.write.getMember("Fem::ConstraintCurrentDensity")
|
||||
for obj in currentDensities:
|
||||
if obj.References:
|
||||
for name in obj.References[0][1]:
|
||||
self._outputMagnetodynamic2DBodyForce(obj, name)
|
||||
self._outputMagnetodynamic2DBodyForce(obj, name, equation)
|
||||
self.write.handled(obj)
|
||||
else:
|
||||
# if there is only one current density without a reference,
|
||||
# add it to all bodies
|
||||
if len(currentDensities) == 1:
|
||||
for name in bodies:
|
||||
self._outputMagnetodynamic2DBodyForce(obj, name)
|
||||
self._outputMagnetodynamic2DBodyForce(obj, name, equation)
|
||||
else:
|
||||
raise general_writer.WriteError(
|
||||
"Several current density constraints found without reference to a body.\n"
|
||||
@@ -192,6 +203,25 @@ class MgDyn2Dwriter:
|
||||
)
|
||||
self.write.handled(obj)
|
||||
|
||||
magnetizations = self.write.getMember("Fem::ConstraintMagnetization")
|
||||
for obj in magnetizations:
|
||||
if obj.References:
|
||||
for name in obj.References[0][1]:
|
||||
self._outputMagnetodynamic2DBodyForce(obj, name, equation)
|
||||
self.write.handled(obj)
|
||||
else:
|
||||
# if there is only one magnetization without a reference,
|
||||
# add it to all bodies
|
||||
if len(magnetizations) == 1:
|
||||
for name in bodies:
|
||||
self._outputMagnetodynamic2DBodyForce(obj, name, equation)
|
||||
else:
|
||||
raise general_writer.WriteError(
|
||||
"Several magnetization constraints found without reference to a body.\n"
|
||||
"Please set a body for each current density constraint."
|
||||
)
|
||||
self.write.handled(obj)
|
||||
|
||||
def handleMagnetodynamic2DBndConditions(self):
|
||||
for obj in self.write.getMember("Fem::ConstraintElectrostaticPotential"):
|
||||
if obj.References:
|
||||
|
||||
@@ -564,8 +564,8 @@ class Writer(object):
|
||||
if activeIn:
|
||||
MgDyn2D.handleMagnetodynamic2DConstants()
|
||||
MgDyn2D.handleMagnetodynamic2DBndConditions()
|
||||
MgDyn2D.handleMagnetodynamic2DBodyForces(activeIn)
|
||||
MgDyn2D.handleMagnetodynamic2DMaterial(activeIn, equation)
|
||||
MgDyn2D.handleMagnetodynamic2DBodyForces(activeIn, equation)
|
||||
MgDyn2D.handleMagnetodynamic2DMaterial(activeIn)
|
||||
|
||||
#-------------------------------------------------------------------------------------------
|
||||
# Solver handling
|
||||
|
||||
@@ -51,7 +51,7 @@ class _TaskPanel(object):
|
||||
# magnetization is always a body force for 3D, therefore only allow solid
|
||||
self._selectionWidget = selection_widgets.GeometryElementsSelection(
|
||||
obj.References,
|
||||
["Solid"],
|
||||
["Solid", "Face"],
|
||||
True,
|
||||
False
|
||||
)
|
||||
@@ -128,17 +128,17 @@ class _TaskPanel(object):
|
||||
self._paramWidget.imagZQSB).bind(self._obj, "Magnetization_im_3")
|
||||
|
||||
self._paramWidget.reXunspecBox.setChecked(
|
||||
self._obj.Magnetization_re_1)
|
||||
self._obj.Magnetization_re_1_Disabled)
|
||||
self._paramWidget.reYunspecBox.setChecked(
|
||||
self._obj.Magnetization_re_2)
|
||||
self._obj.Magnetization_re_2_Disabled)
|
||||
self._paramWidget.reZunspecBox.setChecked(
|
||||
self._obj.Magnetization_re_3)
|
||||
self._obj.Magnetization_re_3_Disabled)
|
||||
self._paramWidget.imXunspecBox.setChecked(
|
||||
self._obj.Magnetization_im_1)
|
||||
self._obj.Magnetization_im_1_Disabled)
|
||||
self._paramWidget.imYunspecBox.setChecked(
|
||||
self._obj.Magnetization_im_2)
|
||||
self._obj.Magnetization_im_2_Disabled)
|
||||
self._paramWidget.imZunspecBox.setChecked(
|
||||
self._obj.Magnetization_im_3)
|
||||
self._obj.Magnetization_im_3_Disabled)
|
||||
|
||||
def _applyMagnetizationChanges(self, enabledBox, magnetizationQSB):
|
||||
enabled = enabledBox.isChecked()
|
||||
|
||||
@@ -682,15 +682,12 @@ def matProperWidget(parent=None, matproperty=None, Type="String", Value=None,
|
||||
# for properties with an underscored number (vectorial values),
|
||||
# we must strip the part after the first underscore to obtain the bound unit
|
||||
# since in cardutils.py in def get_material_template
|
||||
# the underscores were removed, we must first check for numbers
|
||||
# and then for "Im" (denotes an imaginery value)
|
||||
# the underscores were removed, we must check for numbers
|
||||
import re
|
||||
if re.search(r'\d', matproperty):
|
||||
matpropertyNum = matproperty.rstrip('0123456789')
|
||||
matproperty = matpropertyNum
|
||||
if matproperty.find("Im") != -1:
|
||||
matproperty = matproperty.split("Im")[0]
|
||||
|
||||
|
||||
if hasattr(FreeCAD.Units, matproperty):
|
||||
unit = getattr(FreeCAD.Units, matproperty)
|
||||
quantity = FreeCAD.Units.Quantity(1, unit)
|
||||
|
||||
@@ -123,15 +123,6 @@ ElectricalConductivity =
|
||||
; https://en.wikipedia.org/wiki/Permeability_(electromagnetism)
|
||||
RelativePermeability =
|
||||
|
||||
; The magnetization in [FreeCAD Magnetization unit]"
|
||||
; https://en.wikipedia.org/wiki/Magnetization
|
||||
Magnetization_1 =
|
||||
Magnetization_2 =
|
||||
Magnetization_3 =
|
||||
Magnetization_Im_1 =
|
||||
Magnetization_Im_2 =
|
||||
Magnetization_Im_3 =
|
||||
|
||||
[Architectural]
|
||||
; Description to be updated
|
||||
Color =
|
||||
|
||||
@@ -168,30 +168,6 @@
|
||||
Type: 'Float'
|
||||
URL: 'https://en.wikipedia.org/wiki/Permeability_(electromagnetism)'
|
||||
Description: "The ratio to the permeability of the vacuum"
|
||||
Magnetization_1:
|
||||
Type: 'Quantity'
|
||||
URL: 'https://en.wikipedia.org/wiki/Magnetization'
|
||||
Description: "Magnetization in x-direction in [FreeCAD Magnetization unit]"
|
||||
Magnetization_2:
|
||||
Type: 'Quantity'
|
||||
URL: 'https://en.wikipedia.org/wiki/Magnetization'
|
||||
Description: "Magnetization in y-direction in [FreeCAD Magnetization unit]"
|
||||
Magnetization_3:
|
||||
Type: 'Quantity'
|
||||
URL: 'https://en.wikipedia.org/wiki/Magnetization'
|
||||
Description: "Magnetization in z-direction in [FreeCAD Magnetization unit]"
|
||||
Magnetization_Im_1:
|
||||
Type: 'Quantity'
|
||||
URL: 'https://en.wikipedia.org/wiki/Magnetization'
|
||||
Description: "Magnetization, imagaginary part, in x-direction in [FreeCAD Magnetization unit]"
|
||||
Magnetization_Im_2:
|
||||
Type: 'Quantity'
|
||||
URL: 'https://en.wikipedia.org/wiki/Magnetization'
|
||||
Description: "Magnetization, imagaginary part, in y-direction in [FreeCAD Magnetization unit]"
|
||||
Magnetization_Im_3:
|
||||
Type: 'Quantity'
|
||||
URL: 'https://en.wikipedia.org/wiki/Magnetization'
|
||||
Description: "Magnetization, imagaginary part, in z-direction in [FreeCAD Magnetization unit]"
|
||||
- Architectural:
|
||||
Color:
|
||||
Type: 'String'
|
||||
|
||||
@@ -239,9 +239,6 @@ def get_material_template(withSpaces=False):
|
||||
new_proper = re.sub(r"(\w)([A-Z]+)", r"\1 \2", proper)
|
||||
# strip underscores of vectorial properties
|
||||
new_proper = new_proper.replace("_", " ")
|
||||
# this can lead to double spaces for imaginary properties
|
||||
# e.g. "_Im_1", therefore remove one
|
||||
new_proper = new_proper.replace(" ", " ")
|
||||
new_group[gg][new_proper] = group[gg][proper]
|
||||
new_template.append(new_group)
|
||||
template_data = new_template
|
||||
|
||||
Reference in New Issue
Block a user