Fem: Add Neumann boundary condition for electrostatic potential

This commit is contained in:
André Kapelrud
2025-01-06 16:57:18 -03:00
committed by marioalexis
parent 39a5fdc315
commit 10ad2ec955
4 changed files with 716 additions and 565 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -195,3 +195,23 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject)
)
obj.setPropertyStatus("CapacitanceBodyEnabled", "LockDynamic")
obj.CapacitanceBodyEnabled = False
if not hasattr(obj, "SurfaceChargeDensity"):
obj.addProperty(
"App::PropertySurfaceChargeDensity",
"SurfaceChargeDensity",
"Parameter",
"(free) Surface Charge Density",
)
obj.setPropertyStatus("SurfaceChargeDensity", "LockDynamic")
obj.SurfaceChargeDensity = "0.0 s*A/mm^2"
if not hasattr(obj, "Dirichlet"):
obj.addProperty(
"App::PropertyBool",
"Dirichlet",
"Parameter",
"Dirichlet (true) or Neumann (false) type BC",
)
obj.setPropertyStatus("Dirichlet", "LockDynamic")
obj.Dirichlet = True

View File

@@ -125,22 +125,26 @@ class ESwriter:
# output the FreeCAD label as comment
if obj.Label:
self.write.boundary(name, "! FreeCAD Name", obj.Label)
if obj.PotentialEnabled:
if hasattr(obj, "Potential"):
# Potential was once a float and scaled not fitting SI units
if isinstance(obj.Potential, float):
savePotential = obj.Potential
obj.removeProperty("Potential")
obj.addProperty(
"App::PropertyElectricPotential",
"Potential",
"Parameter",
"Electric Potential",
)
# scale to match SI units
obj.Potential = savePotential * 1e6
potential = float(obj.Potential.getValueAs("V"))
self.write.boundary(name, "Potential", potential)
if obj.Dirichlet:
if obj.PotentialEnabled:
if hasattr(obj, "Potential"):
# Potential was once a float and scaled not fitting SI units
if isinstance(obj.Potential, float):
savePotential = obj.Potential
obj.removeProperty("Potential")
obj.addProperty(
"App::PropertyElectricPotential",
"Potential",
"Parameter",
"Electric Potential",
)
# scale to match SI units
obj.Potential = savePotential * 1e6
potential = float(obj.Potential.getValueAs("V"))
self.write.boundary(name, "Potential", potential)
elif not obj.Dirichlet and hasattr(obj, "SurfaceChargeDensity"):
sc_density = float(obj.SurfaceChargeDensity.getValueAs("A*s/m^2"))
self.write.boundary(name, "Surface Charge Density", sc_density)
if obj.PotentialConstant:
self.write.boundary(name, "Potential Constant", True)
if obj.ElectricInfinity:

View File

@@ -24,7 +24,7 @@
# ***************************************************************************
__title__ = "FreeCAD FEM constraint electrostatic potential task panel for the document object"
__author__ = "Markus Hovorka, Bernd Hahnebach, Uwe Stöhr"
__author__ = "Markus Hovorka, Bernd Hahnebach, Uwe Stöhr, André Kapelrud"
__url__ = "https://www.freecad.org"
## @package task_constraint_electrostaticpotential
@@ -88,6 +88,13 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
self._vectorField_visibility,
)
def _BCtype_clicked(self, button):
self._BCtype(button == self._paramWidget.dirichletBC_RB)
def _BCtype(self, isDirichlet):
self._paramWidget.neumannGB.setEnabled(not isDirichlet)
self._paramWidget.dirichletGB.setEnabled(isDirichlet)
def _vectorField_visibility(self, visible):
self._paramWidget.vectorFieldGB.setVisible(visible)
@@ -166,6 +173,20 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
not self._paramWidget.capacitanceBodyBox.isChecked()
)
# neumann/dirichlet radiogroup selection
self._paramWidget.BCtypeBG.buttonClicked.connect(self._BCtype_clicked)
if self.obj.Dirichlet:
self._paramWidget.dirichletBC_RB.click()
else:
self._paramWidget.neumannBC_RB.click()
self._paramWidget.surfacechargedensityQSB.setProperty(
"value", self.obj.SurfaceChargeDensity
)
FreeCADGui.ExpressionBinding(self._paramWidget.surfacechargedensityQSB).bind(
self.obj, "SurfaceChargeDensity"
)
def _applyPotentialChanges(self, enabledBox, potentialQSB):
enabled = enabledBox.isChecked()
potential = None
@@ -219,3 +240,18 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
if self.obj.CapacitanceBodyEnabled:
self._paramWidget.capacitanceBody_spinBox.setEnabled(True)
self.obj.CapacitanceBody = self._paramWidget.capacitanceBody_spinBox.value()
self.obj.Dirichlet = self._paramWidget.dirichletBC_RB.isChecked()
try:
self.obj.SurfaceChargeDensity = self._paramWidget.surfacechargedensityQSB.property(
"value"
)
except ValueError:
FreeCAD.Console.PrintMessage(
"Wrong input. Not recognised input: '{}' "
"SurfaceChargeDensity has not been set.\n".format(
self._paramWidget.surfacechargedensityQSB.text()
)
)
self.obj.SurfaceChargeDensity = "0.0 s*A/(mm^2)"