Merge pull request #25897 from marioalexis84/fem-magnetic_flux_density

This commit is contained in:
Max Wilfinger
2026-01-07 10:15:20 +01:00
committed by GitHub
18 changed files with 1442 additions and 808 deletions

View File

@@ -98,6 +98,7 @@ SET(FemExamples_SRCS
femexamples/equation_magnetostatics_2D_elmer.py
femexamples/equation_staticcurrent_elmer.py
femexamples/frequency_beamsimple.py
femexamples/magnetic_shielding_2D.py
femexamples/manager.py
femexamples/material_multiple_bendingbeam_fiveboxes.py
femexamples/material_multiple_bendingbeam_fivefaces.py

View File

@@ -103,8 +103,8 @@ with a harmonic/oscillating driving force</string>
<property name="checkable">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_3" columnstretch="0,0,255,255">
<item row="0" column="2">
<layout class="QGridLayout" name="gridLayout_3" columnstretch="0,255,255">
<item row="0" column="1">
<widget class="QLabel" name="labelReal">
<property name="enabled">
<bool>true</bool>
@@ -114,7 +114,7 @@ with a harmonic/oscillating driving force</string>
</property>
</widget>
</item>
<item row="0" column="3">
<item row="0" column="2">
<widget class="QLabel" name="labelImaginary">
<property name="enabled">
<bool>true</bool>
@@ -125,23 +125,13 @@ with a harmonic/oscillating driving force</string>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelScalar">
<property name="enabled">
<bool>true</bool>
</property>
<widget class="QCheckBox" name="ckb_av">
<property name="text">
<string>Scalar</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="ckb_av">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="Gui::QuantitySpinBox" name="qsb_av_re">
<property name="enabled">
<bool>true</bool>
@@ -163,7 +153,7 @@ with a harmonic/oscillating driving force</string>
</property>
</widget>
</item>
<item row="1" column="3">
<item row="1" column="2">
<widget class="Gui::QuantitySpinBox" name="qsb_av_im">
<property name="enabled">
<bool>true</bool>
@@ -186,23 +176,13 @@ with a harmonic/oscillating driving force</string>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelX">
<property name="enabled">
<bool>true</bool>
</property>
<widget class="QCheckBox" name="ckb_av_1">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="ckb_av_1">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="Gui::QuantitySpinBox" name="qsb_av_re_1">
<property name="enabled">
<bool>true</bool>
@@ -225,7 +205,7 @@ Note: has no effect if a solid was selected</string>
</property>
</widget>
</item>
<item row="2" column="3">
<item row="2" column="2">
<widget class="Gui::QuantitySpinBox" name="qsb_av_im_1">
<property name="enabled">
<bool>true</bool>
@@ -249,23 +229,13 @@ Note: has no effect if a solid was selected</string>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelY">
<property name="enabled">
<bool>true</bool>
</property>
<widget class="QCheckBox" name="ckb_av_2">
<property name="text">
<string>Y</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="ckb_av_2">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="Gui::QuantitySpinBox" name="qsb_av_re_2">
<property name="enabled">
<bool>true</bool>
@@ -288,7 +258,7 @@ Note: has no effect if a solid was selected</string>
</property>
</widget>
</item>
<item row="3" column="3">
<item row="3" column="2">
<widget class="Gui::QuantitySpinBox" name="qsb_av_im_2">
<property name="enabled">
<bool>true</bool>
@@ -312,23 +282,13 @@ Note: has no effect if a solid was selected</string>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="labelZ">
<property name="enabled">
<bool>true</bool>
</property>
<widget class="QCheckBox" name="ckb_av_3">
<property name="text">
<string>Z</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="ckb_av_3">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="Gui::QuantitySpinBox" name="qsb_av_re_3">
<property name="enabled">
<bool>true</bool>
@@ -351,7 +311,7 @@ Note: has no effect if a solid was selected</string>
</property>
</widget>
</item>
<item row="4" column="3">
<item row="4" column="2">
<widget class="Gui::QuantitySpinBox" name="qsb_av_im_3">
<property name="enabled">
<bool>true</bool>
@@ -380,15 +340,15 @@ Note: has no effect if a solid was selected</string>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="0">
<widget class="QCheckBox" name="ckb_electric_infinity">
<widget class="QCheckBox" name="ckb_far_field">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Whether the boundary condition defines a farfield potential</string>
<string>Far field approximation assuming spherical symmetry</string>
</property>
<property name="text">
<string>Electric infinity</string>
<string>Far field</string>
</property>
</widget>
</item>
@@ -412,6 +372,8 @@ Note: has no effect if a solid was selected</string>
<property name="title">
<string>Neumann</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="gridLayout_8">
<item row="0" column="0">
<widget class="QLabel" name="surfacechargedensityLbl">
@@ -431,6 +393,213 @@ Note: has no effect if a solid was selected</string>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="ckb_magnetic">
<property name="toolTip">
<string>To define magnetic flux density</string>
</property>
<property name="text">
<string>Magnetic flux density</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gb_magnetic">
<property name="title">
<string></string>
</property>
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Imaginary part is only used for equations
with a harmonic/oscillating driving force</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_4" columnstretch="0,255,255">
<item row="0" column="1">
<widget class="QLabel" name="l_real_magnetic">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Real</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="l_imag_magnetic">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Imaginary</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="ckb_magnetic_1">
<property name="text">
<string>X</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Gui::QuantitySpinBox" name="qsb_magnetic_re_1">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Real part of magnetic flux density x-component</string>
</property>
<property name="keyboardTracking">
<bool>true</bool>
</property>
<property name="unit" stdset="0">
<string notr="true">Wb/m^2</string>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="Gui::QuantitySpinBox" name="qsb_magnetic_im_1">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Imaginary part of magnetic flux density x-component</string>
</property>
<property name="keyboardTracking">
<bool>true</bool>
</property>
<property name="unit" stdset="0">
<string notr="true">Wb/m^2</string>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="ckb_magnetic_2">
<property name="text">
<string>Y</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="Gui::QuantitySpinBox" name="qsb_magnetic_re_2">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Real part of magnetic flux density y-component</string>
</property>
<property name="keyboardTracking">
<bool>true</bool>
</property>
<property name="unit" stdset="0">
<string notr="true">Wb/m^2</string>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="Gui::QuantitySpinBox" name="qsb_magnetic_im_2">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Imaginary part of magnetic flux density y-component</string>
</property>
<property name="keyboardTracking">
<bool>true</bool>
</property>
<property name="unit" stdset="0">
<string notr="true">Wb/m^2</string>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="ckb_magnetic_3">
<property name="text">
<string>Z</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="Gui::QuantitySpinBox" name="qsb_magnetic_re_3">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Real part of magnetic flux density z-component</string>
</property>
<property name="keyboardTracking">
<bool>true</bool>
</property>
<property name="unit" stdset="0">
<string notr="true">Wb/m^2</string>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="Gui::QuantitySpinBox" name="qsb_magnetic_im_3">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Imaginary part of magnetic flux density z-component</string>
</property>
<property name="keyboardTracking">
<bool>true</bool>
</property>
<property name="unit" stdset="0">
<string notr="true">Wb/m^2</string>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">

View File

@@ -141,7 +141,7 @@ def setup(doc=None, solvertype="elmer"):
name_pot1 = "ElectrostaticPotential1"
con_elect_pot1 = ObjectsFem.makeConstraintElectrostaticPotential(doc, name_pot1)
con_elect_pot1.References = [(geom_obj, "Face1")]
con_elect_pot1.ElectricInfinity = True
con_elect_pot1.FarField = True
con_elect_pot1.PotentialEnabled = False
analysis.addObject(con_elect_pot1)

View File

@@ -0,0 +1,163 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# ***************************************************************************
# * Copyright (c) 2025 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
# * *
# * This file is part of FreeCAD. *
# * *
# * FreeCAD is free software: you can redistribute it and/or modify it *
# * under the terms of the GNU Lesser General Public License as *
# * published by the Free Software Foundation, either version 2.1 of the *
# * License, or (at your option) any later version. *
# * *
# * FreeCAD is distributed in the hope that it will be useful, but *
# * WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
# * Lesser General Public License for more details. *
# * *
# * You should have received a copy of the GNU Lesser General Public *
# * License along with FreeCAD. If not, see *
# * <https://www.gnu.org/licenses/>. *
# * *
# ***************************************************************************
# to run the example use:
"""
from femexamples.magnetic_shielding_2D import setup
setup()
"""
import sys
import FreeCAD
import ObjectsFem
import Materials
import Part
from . import manager
def get_information():
return {
"name": "Magnetic shielding 2D",
"meshtype": "face",
"meshelement": "Tria6",
"constraints": ["electrostatic potential"],
"solvers": ["elmer"],
"material": "solid",
"equations": ["electromagnetic"],
}
def get_explanation(header=""):
return (
header
+ """
To run the example from Python console use:
from femexamples.magnetic_shielding_2D import setup
setup()
Magnetostatic equation - Elmer solver
"""
)
def setup(doc=None, solvertype="elmer"):
# init FreeCAD document
if doc is None:
doc = manager.init_doc()
# explanation object
manager.add_explanation_obj(doc, get_explanation(manager.get_header(get_information())))
# geometric objects
c1 = Part.makeCircle(15)
c2 = Part.makeCircle(20)
c3 = Part.makeCircle(100)
f1 = Part.makeFace([c1])
f2 = Part.makeFace([c1, c2])
f3 = Part.makeFace([c2, c3])
shape = Part.makeShell([f1, f2, f3])
shell = doc.addObject("Part::Feature", "Shell")
shell.Shape = shape
if FreeCAD.GuiUp:
shell.ViewObject.Visibility = True
shell.ViewObject.Document.ActiveView.viewTop()
shell.ViewObject.Document.ActiveView.fitAll()
# analysis
analysis = ObjectsFem.makeAnalysis(doc, "Analysis")
if FreeCAD.GuiUp:
import FemGui
FemGui.setActiveAnalysis(analysis)
# solver
if solvertype == "elmer":
solver_obj = ObjectsFem.makeSolverElmer(doc, "SolverElmer")
solver_obj.SimulationType = "Steady State"
solver_obj.CoordinateSystem = "Cartesian 2D"
eq_mgdyn_2d = ObjectsFem.makeEquationMagnetodynamic2D(doc, solver_obj)
eq_mgdyn_2d.References = [(shell, ("Face1", "Face2", "Face3"))]
else:
FreeCAD.Console.PrintWarning(
"Unknown or unsupported solver type: {}. "
"No solver object was created.\n".format(solvertype)
)
analysis.addObject(solver_obj)
# material
mat_manager = Materials.MaterialManager()
air = mat_manager.getMaterial("94370b96-c97e-4a3f-83b2-11d7461f7da7")
air_obj = ObjectsFem.makeMaterialFluid(doc, "Air")
air_obj.UUID = "94370b96-c97e-4a3f-83b2-11d7461f7da7"
air_obj.Material = air.Properties
iron = mat_manager.getMaterial("1826c364-d26a-43fb-8f61-288281236836")
iron_obj = ObjectsFem.makeMaterialFluid(doc, "Iron")
iron_obj.UUID = "1826c364-d26a-43fb-8f61-288281236836"
iron_obj.Material = iron.Properties
air_obj.References = [(shell, ("Face1","Face3"))]
iron_obj.References = [(shell, ("Face2",))]
analysis.addObject(air_obj)
analysis.addObject(iron_obj)
# boundary condition
mg_den = ObjectsFem.makeConstraintElectrostaticPotential(doc, "MagneticDensity")
mg_den.References = [(shell, "Edge3")]
mg_den.BoundaryCondition = "Neumann"
mg_den.EnableMagnetic_1 = True
mg_den.Magnetic_re_1 = "10.0 G"
analysis.addObject(mg_den)
# mesh
femmesh_obj = analysis.addObject(ObjectsFem.makeMeshGmsh(doc, manager.get_meshname()))[0]
femmesh_obj.Shape = shell
femmesh_obj.ElementOrder = "2nd"
femmesh_obj.CharacteristicLengthMax = "8 mm"
femmesh_obj.ViewObject.Visibility = False
# mesh_region
mesh_region = ObjectsFem.makeMeshRegion(doc, femmesh_obj, name="MeshRegion")
mesh_region.CharacteristicLength = "2 mm"
mesh_region.References = [(shell, "Face2")]
mesh_region.ViewObject.Visibility = False
# generate the mesh
from femmesh import gmshtools
gmsh_mesh = gmshtools.GmshTools(femmesh_obj, analysis)
try:
gmsh_mesh.create_mesh()
except Exception:
error = sys.exc_info()[1]
FreeCAD.Console.PrintError(f"Unexpected error when creating mesh: {error}\n")
doc.recompute()
return doc

View File

@@ -210,9 +210,9 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject)
prop.append(
_PropHelper(
type="App::PropertyBool",
name="ElectricInfinity",
name="FarField",
group="Parameter",
doc="Electric Infinity",
doc="Far field approximation assuming spherical symmetry",
value=False,
)
)
@@ -245,6 +245,89 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject)
)
)
prop.append(
_PropHelper(
type="App::PropertyMagneticFluxDensity",
name="Magnetic_re_1",
group="Magnetic Flux Density",
doc="Real part of magnetic flux density x-component",
value="0 Wb/m^2",
)
)
prop.append(
_PropHelper(
type="App::PropertyMagneticFluxDensity",
name="Magnetic_re_2",
group="Magnetic Flux Density",
doc="Real part of magnetic flux density y-component",
value="0 Wb/m^2",
)
)
prop.append(
_PropHelper(
type="App::PropertyMagneticFluxDensity",
name="Magnetic_re_3",
group="Magnetic Flux Density",
doc="Real part of magnetic flux density z-component",
value="0 Wb/m^2",
)
)
prop.append(
_PropHelper(
type="App::PropertyMagneticFluxDensity",
name="Magnetic_im_1",
group="Magnetic Flux Density",
doc="Imaginary part of magnetic flux density x-component",
value="0 Wb/m^2",
)
)
prop.append(
_PropHelper(
type="App::PropertyMagneticFluxDensity",
name="Magnetic_im_2",
group="Magnetic Flux Density",
doc="Imaginary part of magnetic flux density y-component",
value="0 Wb/m^2",
)
)
prop.append(
_PropHelper(
type="App::PropertyMagneticFluxDensity",
name="Magnetic_im_3",
group="Magnetic Flux Density",
doc="Imaginary part of magnetic flux density z-component",
value="0 Wb/m^2",
)
)
prop.append(
_PropHelper(
type="App::PropertyBool",
name="EnableMagnetic_1",
group="Magnetic Flux Density",
doc="Enable magnetic flux density x-component boundary condition",
value=False,
)
)
prop.append(
_PropHelper(
type="App::PropertyBool",
name="EnableMagnetic_2",
group="Magnetic Flux Density",
doc="Enable magnetic flux density y-component boundary condition",
value=False,
)
)
prop.append(
_PropHelper(
type="App::PropertyBool",
name="EnableMagnetic_3",
group="Magnetic Flux Density",
doc="Enable magnetic flux density z-component boundary condition",
value=False,
)
)
return prop
def onDocumentRestored(self, obj):
@@ -281,7 +364,9 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject)
obj.EnableAV_3 = not obj.getPropertyByName(
"AV_re_3_Disabled"
) or not obj.getPropertyByName("AV_im_3_Disabled")
obj.EnableAV = not obj.getPropertyByName("AV_im_Disabled")
obj.EnableAV = not obj.getPropertyByName("AV_re_Disabled") or not obj.getPropertyByName(
"AV_im_Disabled"
)
# remove old properties
obj.setPropertyStatus("AV_re_1_Disabled", "-LockDynamic")
@@ -296,9 +381,10 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject)
obj.removeProperty("AV_im_2_Disabled")
obj.setPropertyStatus("AV_im_3_Disabled", "-LockDynamic")
obj.removeProperty("AV_im_3_Disabled")
obj.setPropertyStatus("AV_re_Disabled", "-LockDynamic")
obj.removeProperty("AV_re_Disabled")
obj.setPropertyStatus("AV_im_Disabled", "-LockDynamic")
obj.removeProperty("AV_im_Disabled")
except Base.PropertyError:
pass
@@ -310,3 +396,12 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject)
except Base.PropertyError:
pass
# rename ElectricInfinity
try:
obj.FarField = obj.getPropertyByName("ElectricInfinity")
obj.setPropertyStatus("ElectricInfinity", "-LockDynamic")
obj.removeProperty("ElectricInfinity")
except Base.PropertyError:
pass

View File

@@ -138,7 +138,7 @@ class ESwriter:
self.write.boundary(name, "Electric Flux", flux_density)
if obj.PotentialConstant:
self.write.boundary(name, "Potential Constant", True)
if obj.ElectricInfinity:
if obj.FarField:
self.write.boundary(name, "Electric Infinity BC", True)
if obj.ElectricForcecalculation:
self.write.boundary(name, "Calculate Electric Force", True)

View File

@@ -215,8 +215,24 @@ class MgDyn2Dwriter:
potential = obj.AV_im_3.getValueAs("Wb/m")
self.write.boundary(name, "Potential im", potential)
if obj.ElectricInfinity:
elif obj.BoundaryCondition == "Neumann":
if obj.EnableMagnetic_1:
b_1 = obj.Magnetic_re_1.getValueAs("Wb/m^2")
self.write.boundary(name, "Magnetic Flux Density 1", b_1)
if equation.IsHarmonic:
b_1 = obj.Magnetic_im_1.getValueAs("Wb/m^2")
self.write.boundary(name, "Magnetic Flux Density 1 im", b_1)
if obj.EnableMagnetic_2:
b_2 = obj.Magnetic_re_2.getValueAs("Wb/m^2")
self.write.boundary(name, "Magnetic Flux Density 2", b_2)
if equation.IsHarmonic:
b_2 = obj.Magnetic_im_2.getValueAs("Wb/m^2")
self.write.boundary(name, "Magnetic Flux Density 2 im", b_2)
if obj.FarField:
self.write.boundary(name, "Infinity BC", True)
self.write.handled(obj)
def handleMagnetodynamic2DEquation(self, bodies, equation):

View File

@@ -282,38 +282,61 @@ class MgDynwriter:
self.write.boundary(name, "Electric Current Density Im", current_density)
if femutils.is_derived_from(obj, "Fem::ConstraintElectrostaticPotential"):
if obj.EnableAV:
potential = obj.AV_re.getValueAs("V")
if equation.IsHarmonic:
self.write.boundary(name, "AV re", potential)
potential = obj.AV_im.getValueAs("V")
self.write.boundary(name, "AV im", potential)
else:
self.write.boundary(name, "AV", potential)
if obj.EnableAV_1:
potential = obj.AV_re_1.getValueAs("Wb/m")
if equation.IsHarmonic:
self.write.boundary(name, "AV re {e} 1", potential)
potential = obj.AV_im_1.getValueAs("Wb/m")
self.write.boundary(name, "AV im {e} 1", potential)
else:
self.write.boundary(name, "AV {e} 1", potential)
if obj.EnableAV_2:
potential = obj.AV_re_2.getValueAs("Wb/m")
if equation.IsHarmonic:
self.write.boundary(name, "AV re {e} 2", potential)
potential = obj.AV_im_2.getValueAs("Wb/m")
self.write.boundary(name, "AV im {e} 2", potential)
else:
self.write.boundary(name, "AV {e} 2", potential)
if obj.EnableAV_3:
potential = obj.AV_re_3.getValueAs("Wb/m")
if equation.IsHarmonic:
self.write.boundary(name, "AV re {e} 3", potential)
potential = obj.AV_im_3.getValueAs("Wb/m")
self.write.boundary(name, "AV im {e} 3", potential)
else:
self.write.boundary(name, "AV {e} 3", potential)
if obj.BoundaryCondition == "Dirichlet":
if obj.EnableAV:
potential = obj.AV_re.getValueAs("V")
if equation.IsHarmonic:
self.write.boundary(name, "AV re", potential)
potential = obj.AV_im.getValueAs("V")
self.write.boundary(name, "AV im", potential)
else:
self.write.boundary(name, "AV", potential)
if obj.EnableAV_1:
potential = obj.AV_re_1.getValueAs("Wb/m")
if equation.IsHarmonic:
self.write.boundary(name, "AV re {e} 1", potential)
potential = obj.AV_im_1.getValueAs("Wb/m")
self.write.boundary(name, "AV im {e} 1", potential)
else:
self.write.boundary(name, "AV {e} 1", potential)
if obj.EnableAV_2:
potential = obj.AV_re_2.getValueAs("Wb/m")
if equation.IsHarmonic:
self.write.boundary(name, "AV re {e} 2", potential)
potential = obj.AV_im_2.getValueAs("Wb/m")
self.write.boundary(name, "AV im {e} 2", potential)
else:
self.write.boundary(name, "AV {e} 2", potential)
if obj.EnableAV_3:
potential = obj.AV_re_3.getValueAs("Wb/m")
if equation.IsHarmonic:
self.write.boundary(name, "AV re {e} 3", potential)
potential = obj.AV_im_3.getValueAs("Wb/m")
self.write.boundary(name, "AV im {e} 3", potential)
else:
self.write.boundary(name, "AV {e} 3", potential)
elif obj.BoundaryCondition == "Neumann":
if obj.EnableMagnetic_1:
b1 = obj.Magnetic_re_1.getValueAs("Wb/m^2")
self.write.boundary(name, "Magnetic Flux Density 1", b1)
if equation.IsHarmonic:
b1 = obj.Magnetic_im_1.getValueAs("Wb/m^2")
self.write.boundary(name, "Magnetic Flux Density Im 1", b1)
if obj.EnableMagnetic_2:
b2 = obj.Magnetic_re_2.getValueAs("Wb/m^2")
self.write.boundary(name, "Magnetic Flux Density 2", b2)
if equation.IsHarmonic:
b2 = obj.Magnetic_im_2.getValueAs("Wb/m^2")
self.write.boundary(name, "Magnetic Flux Density Im 2", b2)
if obj.EnableMagnetic_3:
b3 = obj.Magnetic_re_3.getValueAs("Wb/m^2")
self.write.boundary(name, "Magnetic Flux Density 3", b3)
if equation.IsHarmonic:
b3 = obj.Magnetic_im_3.getValueAs("Wb/m^2")
self.write.boundary(name, "Magnetic Flux Density Im 3", b3)
def handleMagnetodynamicBndConditions(self, equation):
# the current density can either be a body force or a boundary constraint

View File

@@ -166,9 +166,9 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
self.potential_constant_changed,
)
QtCore.QObject.connect(
self.parameter_widget.ckb_electric_infinity,
self.parameter_widget.ckb_far_field,
QtCore.SIGNAL("toggled(bool)"),
self.electric_infinity_changed,
self.far_field_changed,
)
QtCore.QObject.connect(
self.parameter_widget.qsb_electric_flux_density,
@@ -176,6 +176,58 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
self.electric_flux_density_changed,
)
QtCore.QObject.connect(
self.parameter_widget.ckb_magnetic,
QtCore.SIGNAL("toggled(bool)"),
self.magnetic_enabled_changed,
)
QtCore.QObject.connect(
self.parameter_widget.ckb_magnetic_1,
QtCore.SIGNAL("toggled(bool)"),
self.magnetic_1_enabled_changed,
)
QtCore.QObject.connect(
self.parameter_widget.qsb_magnetic_re_1,
QtCore.SIGNAL("valueChanged(Base::Quantity)"),
self.magnetic_re_1_changed,
)
QtCore.QObject.connect(
self.parameter_widget.qsb_magnetic_im_1,
QtCore.SIGNAL("valueChanged(Base::Quantity)"),
self.magnetic_im_1_changed,
)
QtCore.QObject.connect(
self.parameter_widget.ckb_magnetic_2,
QtCore.SIGNAL("toggled(bool)"),
self.magnetic_2_enabled_changed,
)
QtCore.QObject.connect(
self.parameter_widget.qsb_magnetic_re_2,
QtCore.SIGNAL("valueChanged(Base::Quantity)"),
self.magnetic_re_2_changed,
)
QtCore.QObject.connect(
self.parameter_widget.qsb_magnetic_im_2,
QtCore.SIGNAL("valueChanged(Base::Quantity)"),
self.magnetic_im_2_changed,
)
QtCore.QObject.connect(
self.parameter_widget.ckb_magnetic_3,
QtCore.SIGNAL("toggled(bool)"),
self.magnetic_3_enabled_changed,
)
QtCore.QObject.connect(
self.parameter_widget.qsb_magnetic_re_3,
QtCore.SIGNAL("valueChanged(Base::Quantity)"),
self.magnetic_re_3_changed,
)
QtCore.QObject.connect(
self.parameter_widget.qsb_magnetic_im_3,
QtCore.SIGNAL("valueChanged(Base::Quantity)"),
self.magnetic_im_3_changed,
)
self.init_parameter_widget()
def open(self):
@@ -229,11 +281,22 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
self.boundary_condition = self.obj.BoundaryCondition
self.potential_constant = self.obj.PotentialConstant
self.electric_infinity = self.obj.ElectricInfinity
self.far_field = self.obj.FarField
self.capacitance_body_enabled = self.obj.CapacitanceBodyEnabled
self.capacitance_body = self.obj.CapacitanceBody
self.electric_flux_density = self.obj.ElectricFluxDensity
self.magnetic_1_enabled = self.obj.EnableMagnetic_1
self.magnetic_2_enabled = self.obj.EnableMagnetic_2
self.magnetic_3_enabled = self.obj.EnableMagnetic_3
self.magnetic_re_1 = self.obj.Magnetic_re_1
self.magnetic_re_2 = self.obj.Magnetic_re_2
self.magnetic_re_3 = self.obj.Magnetic_re_3
self.magnetic_im_1 = self.obj.Magnetic_im_1
self.magnetic_im_2 = self.obj.Magnetic_im_2
self.magnetic_im_3 = self.obj.Magnetic_im_3
def _set_params(self):
self.obj.Potential = self.potential
self.obj.PotentialEnabled = self.potential_enabled
@@ -254,12 +317,23 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
self.obj.BoundaryCondition = self.boundary_condition
self.obj.PotentialConstant = self.potential_constant
self.obj.ElectricInfinity = self.electric_infinity
self.obj.FarField = self.far_field
self.obj.CapacitanceBodyEnabled = self.capacitance_body_enabled
self.obj.CapacitanceBody = self.capacitance_body
self.obj.ElectricFluxDensity = self.electric_flux_density
self.obj.Magnetic_re_1 = self.magnetic_re_1
self.obj.Magnetic_re_2 = self.magnetic_re_2
self.obj.Magnetic_re_3 = self.magnetic_re_3
self.obj.Magnetic_im_1 = self.magnetic_im_1
self.obj.Magnetic_im_2 = self.magnetic_im_2
self.obj.Magnetic_im_3 = self.magnetic_im_3
self.obj.EnableMagnetic_1 = self.magnetic_1_enabled
self.obj.EnableMagnetic_2 = self.magnetic_2_enabled
self.obj.EnableMagnetic_3 = self.magnetic_3_enabled
def init_parameter_widget(self):
self._get_params()
@@ -305,7 +379,7 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
self.parameter_widget.ckb_potential_constant.setChecked(self.potential_constant)
self.parameter_widget.ckb_electric_infinity.setChecked(self.electric_infinity)
self.parameter_widget.ckb_far_field.setChecked(self.far_field)
self.parameter_widget.ckb_capacitance_body.setChecked(self.capacitance_body_enabled)
self.parameter_widget.spb_capacitance_body.setProperty("value", self.capacitance_body)
@@ -320,6 +394,43 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
self.obj, "ElectricFluxDensity"
)
# magnetic flux density
self.parameter_widget.qsb_magnetic_re_1.setProperty("value", self.magnetic_re_1)
self.parameter_widget.qsb_magnetic_re_1.setEnabled(self.magnetic_1_enabled)
FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_magnetic_re_1).bind(
self.obj, "Magnetic_re_1"
)
self.parameter_widget.qsb_magnetic_re_2.setProperty("value", self.magnetic_re_2)
self.parameter_widget.qsb_magnetic_re_2.setEnabled(self.magnetic_2_enabled)
FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_magnetic_re_2).bind(
self.obj, "Magnetic_re_2"
)
self.parameter_widget.qsb_magnetic_re_3.setProperty("value", self.magnetic_re_3)
self.parameter_widget.qsb_magnetic_re_3.setEnabled(self.magnetic_3_enabled)
FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_magnetic_re_3).bind(
self.obj, "Magnetic_re_3"
)
self.parameter_widget.qsb_magnetic_im_1.setProperty("value", self.magnetic_im_1)
self.parameter_widget.qsb_magnetic_im_1.setEnabled(self.magnetic_1_enabled)
FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_magnetic_im_1).bind(
self.obj, "Magnetic_im_1"
)
self.parameter_widget.qsb_magnetic_im_2.setProperty("value", self.magnetic_im_2)
self.parameter_widget.qsb_magnetic_im_2.setEnabled(self.magnetic_2_enabled)
FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_magnetic_im_2).bind(
self.obj, "Magnetic_im_2"
)
self.parameter_widget.qsb_magnetic_im_3.setProperty("value", self.magnetic_im_3)
self.parameter_widget.qsb_magnetic_im_3.setEnabled(self.magnetic_3_enabled)
FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_magnetic_im_3).bind(
self.obj, "Magnetic_im_3"
)
self.parameter_widget.ckb_magnetic_1.setChecked(self.magnetic_1_enabled)
self.parameter_widget.ckb_magnetic_2.setChecked(self.magnetic_2_enabled)
self.parameter_widget.ckb_magnetic_3.setChecked(self.magnetic_3_enabled)
self.bc_enum = self.obj.getEnumerationsOfProperty("BoundaryCondition")
index = self.bc_enum.index(self.boundary_condition)
self.parameter_widget.cb_boundary_condition.addItems(self.bc_enum)
@@ -329,6 +440,10 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
if not (self.av_enabled or self.av_1_enabled or self.av_2_enabled or self.av_3_enabled):
self.parameter_widget.ckb_electromagnetic.setChecked(False)
# start with magnetic inputs hidden if no field is set
if not (self.magnetic_1_enabled or self.magnetic_2_enabled or self.magnetic_3_enabled):
self.parameter_widget.ckb_magnetic.setChecked(False)
def potential_changed(self, value):
self.potential = value
@@ -386,8 +501,8 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
def potential_constant_changed(self, value):
self.potential_constant = value
def electric_infinity_changed(self, value):
self.electric_infinity = value
def far_field_changed(self, value):
self.far_field = value
def capacitance_body_enabled_changed(self, value):
self.capacitance_body_enabled = value
@@ -408,3 +523,39 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
elif self.boundary_condition == "Neumann":
self.parameter_widget.gb_neumann.setEnabled(True)
self.parameter_widget.gb_dirichlet.setEnabled(False)
def magnetic_enabled_changed(self, value):
self.parameter_widget.gb_magnetic.setVisible(value)
def magnetic_1_enabled_changed(self, value):
self.magnetic_1_enabled = value
self.parameter_widget.qsb_magnetic_re_1.setEnabled(value)
self.parameter_widget.qsb_magnetic_im_1.setEnabled(value)
def magnetic_2_enabled_changed(self, value):
self.magnetic_2_enabled = value
self.parameter_widget.qsb_magnetic_re_2.setEnabled(value)
self.parameter_widget.qsb_magnetic_im_2.setEnabled(value)
def magnetic_3_enabled_changed(self, value):
self.magnetic_3_enabled = value
self.parameter_widget.qsb_magnetic_re_3.setEnabled(value)
self.parameter_widget.qsb_magnetic_im_3.setEnabled(value)
def magnetic_re_1_changed(self, value):
self.magnetic_re_1 = value
def magnetic_re_2_changed(self, value):
self.magnetic_re_2 = value
def magnetic_re_3_changed(self, value):
self.magnetic_re_3 = value
def magnetic_im_1_changed(self, value):
self.magnetic_im_1 = value
def magnetic_im_2_changed(self, value):
self.magnetic_im_2 = value
def magnetic_im_3_changed(self, value):
self.magnetic_im_3 = value