diff --git a/src/Mod/Fem/Gui/Resources/ui/ElectrostaticPotential.ui b/src/Mod/Fem/Gui/Resources/ui/ElectrostaticPotential.ui index 0e0338008c..fd83f7d508 100644 --- a/src/Mod/Fem/Gui/Resources/ui/ElectrostaticPotential.ui +++ b/src/Mod/Fem/Gui/Resources/ui/ElectrostaticPotential.ui @@ -6,8 +6,8 @@ 0 0 - 317 - 303 + 357 + 593 @@ -15,602 +15,690 @@ - - - - - Potential: - - - - - - - Qt::Horizontal - - - - 20 - 20 - - - - - - - - false - - - - 100 - 20 - - - - Electric potential - - - true - - - V - - - -1000000000000000000000.000000000000000 - - - 1000000000000000000000.000000000000000 - - - 1.000000000000000 - - - 1.000000000000000 - - - - - - - unspecified - - - true - - - - - - - - - To define a vector field - + - Vector Field + Dirichlet true + + BCtypeBG + - - - - true + + + + Neumann - - Imaginary part is only used for equations -with a harmonic/oscillating driving force + + BCtypeBG + + + + + + + false - - false - - - - + + + true - - Real - - - - - - - true - - - Imaginary - - - - - - - true - - - Scalar - - - - - - - false - - - - 100 - 20 - - - Potential as specified above - - - true - - - true - - - V - - - -1000000000000000000000.000000000000000 - - - 1000000000000000000000.000000000000000 - - - 1.000000000000000 - - - 1.000000000000000 - - - - - - - true - - - - 100 - 20 - - - - Imaginary part of scalar potential - - - true - - - V - - - -1000000000000000000000.000000000000000 - - - 1000000000000000000000.000000000000000 - - - 1.000000000000000 - - - 1.000000000000000 - - - - - - - unspecified + Whether the boundary condition defines a farfield potential - + Farfield / Electric infinity + + + + + + + + + false + + + Electric potential + + + true + + + + + + -1000000000000000000000.000000000000000 + + + 1000000000000000000000.000000000000000 + + + 1.000000000000000 + + + 1.000000000000000 + + + + + + + Potential: + + + + + + + unspecified + + + true + + + + + + + Qt::Horizontal + + + + 20 + 20 + + + + + + + + + + Whether the boundary condition defines a constant potential + + + Potential Constant - + true - - x - - - - - - - true - - - - 100 - 20 - - - Real part of potential x-component + Imaginary part is only used for equations +with a harmonic/oscillating driving force + + + false + + + false + + + + + + true + + + Real + + + + + + + true + + + Imaginary + + + + + + + true + + + Scalar + + + + + + + false + + + + 100 + 20 + + + + Potential as specified above + + + true + + + true + + + V + + + -1000000000000000000000.000000000000000 + + + 1000000000000000000000.000000000000000 + + + 1.000000000000000 + + + 1.000000000000000 + + + + + + + true + + + + 100 + 20 + + + + Imaginary part of scalar potential + + + true + + + V + + + -1000000000000000000000.000000000000000 + + + 1000000000000000000000.000000000000000 + + + 1.000000000000000 + + + 1.000000000000000 + + + + + + + unspecified + + + + + + + + + + true + + + x + + + + + + + true + + + + 100 + 20 + + + + Real part of potential x-component Note: has no effect if a solid was selected - - - true - - - V - - - -1000000000000000000000.000000000000000 - - - 1000000000000000000000.000000000000000 - - - 1.000000000000000 - - - 1.000000000000000 - - - - - - - unspecified - - - - - - - - - - true - - - - 100 - 20 - - - - Imaginary part of potential x-component + + + true + + + V + + + -1000000000000000000000.000000000000000 + + + 1000000000000000000000.000000000000000 + + + 1.000000000000000 + + + 1.000000000000000 + + + + + + + unspecified + + + + + + + + + + true + + + + 100 + 20 + + + + Imaginary part of potential x-component Note: has no effect if a solid was selected - - - true - - - V - - - -1000000000000000000000.000000000000000 - - - 1000000000000000000000.000000000000000 - - - 1.000000000000000 - - - 1.000000000000000 - - - - - - - unspecified - - - - - - - - - - true - - - y - - - - - - - true - - - - 100 - 20 - - - - Real part of potential y-component + + + true + + + V + + + -1000000000000000000000.000000000000000 + + + 1000000000000000000000.000000000000000 + + + 1.000000000000000 + + + 1.000000000000000 + + + + + + + unspecified + + + + + + + + + + true + + + y + + + + + + + true + + + + 100 + 20 + + + + Real part of potential y-component Note: has no effect if a solid was selected - - - true - - - V - - - -1000000000000000000000.000000000000000 - - - 1000000000000000000000.000000000000000 - - - 1.000000000000000 - - - 1.000000000000000 - - - - - - - unspecified - - - - - - - - - - true - - - - 100 - 20 - - - - Imaginary part of potential y-component + + + true + + + V + + + -1000000000000000000000.000000000000000 + + + 1000000000000000000000.000000000000000 + + + 1.000000000000000 + + + 1.000000000000000 + + + + + + + unspecified + + + + + + + + + + true + + + + 100 + 20 + + + + Imaginary part of potential y-component Note: has no effect if a solid was selected - - - true - - - V - - - -1000000000000000000000.000000000000000 - - - 1000000000000000000000.000000000000000 - - - 1.000000000000000 - - - 1.000000000000000 - - - - - - - unspecified - - - - - - - - - - true - - - z - - - - - - - true - - - - 100 - 20 - - - - Real part of potential z-component + + + true + + + V + + + -1000000000000000000000.000000000000000 + + + 1000000000000000000000.000000000000000 + + + 1.000000000000000 + + + 1.000000000000000 + + + + + + + unspecified + + + + + + + + + + true + + + z + + + + + + + true + + + + 100 + 20 + + + + Real part of potential z-component Note: has no effect if a solid was selected - - - true - - - V - - - -1000000000000000000000.000000000000000 - - - 1000000000000000000000.000000000000000 - - - 1.000000000000000 - - - 1.000000000000000 - - - - - - - unspecified - - - - - - - - - - true - - - - 100 - 20 - - - - Imaginary part of potential z-component + + + true + + + V + + + -1000000000000000000000.000000000000000 + + + 1000000000000000000000.000000000000000 + + + 1.000000000000000 + + + 1.000000000000000 + + + + + + + unspecified + + + + + + + + + + true + + + + 100 + 20 + + + + Imaginary part of potential z-component Note: has no effect if a solid was selected + + + true + + + V + + + -1000000000000000000000.000000000000000 + + + 1000000000000000000000.000000000000000 + + + 1.000000000000000 + + + 1.000000000000000 + + + + + + + unspecified + + + + + + + + + + + + + + + Capacitance Body: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + unspecified + + + true + + + + + + + + 55 + 16777215 + + + + Counter of the body (or face) with a capacitance + + + 1 + + + 1 + + + + + + + + + To define a vector field - + + Vector Field + + true - - V - - - -1000000000000000000000.000000000000000 - - - 1000000000000000000000.000000000000000 - - - 1.000000000000000 - - - 1.000000000000000 - - - + + - unspecified + Whether the boundary condition is for the electric force - + Calculate Electric Force - - - - Whether the boundary condition defines a constant potential + + + + - - Potential Constant + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + Surface Charge Density: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Surface Charge density + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + - - - - true - - - Whether the boundary condition defines a farfield potential - - - Farfield / Electric infinity - - - - - - - Whether the boundary condition is for the electric force - - - Calculate Electric Force - - - - - - - - - Capacity Body: - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - unspecified - - - true - - - - - - - - 55 - 16777215 - - - - Counter of the body (or face) with a capacitance - - - 1 - - - 1 - - - - - @@ -783,4 +871,7 @@ Note: has no effect if a solid was selected + + + diff --git a/src/Mod/Fem/femobjects/constraint_electrostaticpotential.py b/src/Mod/Fem/femobjects/constraint_electrostaticpotential.py index e3e9554531..749d12cf62 100644 --- a/src/Mod/Fem/femobjects/constraint_electrostaticpotential.py +++ b/src/Mod/Fem/femobjects/constraint_electrostaticpotential.py @@ -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 diff --git a/src/Mod/Fem/femsolver/elmer/equations/electrostatic_writer.py b/src/Mod/Fem/femsolver/elmer/equations/electrostatic_writer.py index 5014df97ff..1751c9b78b 100644 --- a/src/Mod/Fem/femsolver/elmer/equations/electrostatic_writer.py +++ b/src/Mod/Fem/femsolver/elmer/equations/electrostatic_writer.py @@ -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: diff --git a/src/Mod/Fem/femtaskpanels/task_constraint_electrostaticpotential.py b/src/Mod/Fem/femtaskpanels/task_constraint_electrostaticpotential.py index da268a8b3b..f7a7e12f26 100644 --- a/src/Mod/Fem/femtaskpanels/task_constraint_electrostaticpotential.py +++ b/src/Mod/Fem/femtaskpanels/task_constraint_electrostaticpotential.py @@ -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)"