diff --git a/src/Mod/Fem/Gui/Resources/ui/ElectrostaticPotential.ui b/src/Mod/Fem/Gui/Resources/ui/ElectrostaticPotential.ui index fd83f7d508..de85084c5d 100644 --- a/src/Mod/Fem/Gui/Resources/ui/ElectrostaticPotential.ui +++ b/src/Mod/Fem/Gui/Resources/ui/ElectrostaticPotential.ui @@ -13,56 +13,46 @@ Analysis feature properties - - - - - Dirichlet + + + + + - - true - - - BCtypeBG - - - - - - - Neumann - - - BCtypeBG - + + + + + Boundary Condition: + + + + + + + - + - + Dirichlet false - - - - true - - - Whether the boundary condition defines a farfield potential - - - Farfield / Electric infinity - - - - - + + + + Potential: + + + + + false @@ -73,13 +63,7 @@ true - - - - -1000000000000000000000.000000000000000 - - - 1000000000000000000000.000000000000000 + V 1.000000000000000 @@ -89,45 +73,18 @@ - - - - Potential: - - - - - - - unspecified - - - true - - - - - - - Qt::Horizontal - - - - 20 - 20 - - - - - - + + - Whether the boundary condition defines a constant potential + To define scalar potential and magnetic vector potential - Potential Constant + Electromagnetic Potential + + + true @@ -147,7 +104,7 @@ with a harmonic/oscillating driving force false - + true @@ -157,7 +114,7 @@ with a harmonic/oscillating driving force - + true @@ -178,16 +135,20 @@ with a harmonic/oscillating driving force - + + + unspecified + + + + + + + + false - - - 100 - 20 - - Potential as specified above @@ -200,12 +161,6 @@ with a harmonic/oscillating driving force V - - -1000000000000000000000.000000000000000 - - - 1000000000000000000000.000000000000000 - 1.000000000000000 @@ -215,16 +170,20 @@ with a harmonic/oscillating driving force - + + + unspecified + + + + + + + + true - - - 100 - 20 - - Imaginary part of scalar potential @@ -234,12 +193,6 @@ with a harmonic/oscillating driving force V - - -1000000000000000000000.000000000000000 - - - 1000000000000000000000.000000000000000 - 1.000000000000000 @@ -248,16 +201,6 @@ with a harmonic/oscillating driving force - - - - unspecified - - - - - - @@ -269,16 +212,20 @@ with a harmonic/oscillating driving force - + + + unspecified + + + + + + + + true - - - 100 - 20 - - Real part of potential x-component Note: has no effect if a solid was selected @@ -287,13 +234,7 @@ Note: has no effect if a solid was selected true - V - - - -1000000000000000000000.000000000000000 - - - 1000000000000000000000.000000000000000 + Wb/m 1.000000000000000 @@ -303,8 +244,8 @@ Note: has no effect if a solid was selected - - + + unspecified @@ -313,17 +254,11 @@ Note: has no effect if a solid was selected - - + + true - - - 100 - 20 - - Imaginary part of potential x-component Note: has no effect if a solid was selected @@ -332,13 +267,7 @@ Note: has no effect if a solid was selected true - V - - - -1000000000000000000000.000000000000000 - - - 1000000000000000000000.000000000000000 + Wb/m 1.000000000000000 @@ -348,16 +277,6 @@ Note: has no effect if a solid was selected - - - - unspecified - - - - - - @@ -369,16 +288,20 @@ Note: has no effect if a solid was selected - + + + unspecified + + + + + + + + true - - - 100 - 20 - - Real part of potential y-component Note: has no effect if a solid was selected @@ -387,13 +310,7 @@ Note: has no effect if a solid was selected true - V - - - -1000000000000000000000.000000000000000 - - - 1000000000000000000000.000000000000000 + Wb/m 1.000000000000000 @@ -403,8 +320,8 @@ Note: has no effect if a solid was selected - - + + unspecified @@ -413,17 +330,11 @@ Note: has no effect if a solid was selected - - + + true - - - 100 - 20 - - Imaginary part of potential y-component Note: has no effect if a solid was selected @@ -432,13 +343,7 @@ Note: has no effect if a solid was selected true - V - - - -1000000000000000000000.000000000000000 - - - 1000000000000000000000.000000000000000 + Wb/m 1.000000000000000 @@ -448,16 +353,6 @@ Note: has no effect if a solid was selected - - - - unspecified - - - - - - @@ -469,16 +364,20 @@ Note: has no effect if a solid was selected - + + + unspecified + + + + + + + + true - - - 100 - 20 - - Real part of potential z-component Note: has no effect if a solid was selected @@ -487,13 +386,7 @@ Note: has no effect if a solid was selected true - V - - - -1000000000000000000000.000000000000000 - - - 1000000000000000000000.000000000000000 + Wb/m 1.000000000000000 @@ -503,8 +396,8 @@ Note: has no effect if a solid was selected - - + + unspecified @@ -513,17 +406,11 @@ Note: has no effect if a solid was selected - - + + true - - - 100 - 20 - - Imaginary part of potential z-component Note: has no effect if a solid was selected @@ -532,13 +419,7 @@ Note: has no effect if a solid was selected true - V - - - -1000000000000000000000.000000000000000 - - - 1000000000000000000000.000000000000000 + Wb/m 1.000000000000000 @@ -548,62 +429,62 @@ Note: has no effect if a solid was selected - - - - unspecified - - - - - - + + + + true + + + Whether the boundary condition defines a farfield potential + + + Farfield / Electric infinity + + + + + + + Whether the boundary condition defines a constant potential + + + Potential Constant + + + + + + + Whether the boundary condition is for the electric force + + + Calculate Electric Force + + + - + - Capacitance Body: + Capacitance Body: + + + Enabled by 'Calculate Capacity Matrix' in Electrostatic equation - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - unspecified - - - true - - - - - - - - 55 - 16777215 - - + Counter of the body (or face) with a capacitance + + false + 1 @@ -614,87 +495,31 @@ Note: has no effect if a solid was selected - - - - To define a vector field - - - Vector Field - - - true - - - - - - - Whether the boundary condition is for the electric force - - - Calculate Electric Force - - - - - + + - + Neumann - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - + - - - - - Surface Charge Density: - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Surface Charge density - - - - - - - + + + Surface Charge Density: + + - - - - Qt::Vertical + + + + Surface charge density - - - 20 - 40 - + + C/m^2 - + @@ -709,168 +534,6 @@ Note: has no effect if a solid was selected - - - capacitanceBodyBox - toggled(bool) - capacitanceBody_spinBox - setDisabled(bool) - - - 262 - 116 - - - 323 - 116 - - - - - potentialBox - toggled(bool) - potentialQSB - setDisabled(bool) - - - 301 - 19 - - - 206 - 19 - - - - - potentialQSB - valueChanged(Base::Quantity) - realScalarQSB - setValue(Base::Quantity) - - - 126 - 19 - - - 103 - 98 - - - - - reZunspecBox - toggled(bool) - realZQSB - setDisabled(bool) - - - 179 - 178 - - - 103 - 176 - - - - - reYunspecBox - toggled(bool) - realYQSB - setDisabled(bool) - - - 179 - 148 - - - 103 - 150 - - - - - imXunspecBox - toggled(bool) - imagXQSB - setDisabled(bool) - - - 339 - 128 - - - 258 - 127 - - - - - reXunspecBox - toggled(bool) - realXQSB - setDisabled(bool) - - - 179 - 128 - - - 103 - 124 - - - - - imZunspecBox - toggled(bool) - imagZQSB - setDisabled(bool) - - - 339 - 178 - - - 258 - 179 - - - - - imYunspecBox - toggled(bool) - imagYQSB - setDisabled(bool) - - - 339 - 148 - - - 258 - 153 - - - - - imScalarunspecBox - toggled(bool) - imagScalarQSB - setDisabled(bool) - - - 339 - 98 - - - 258 - 101 - - - - diff --git a/src/Mod/Fem/femobjects/constraint_electrostaticpotential.py b/src/Mod/Fem/femobjects/constraint_electrostaticpotential.py index 749d12cf62..f1e7f595ec 100644 --- a/src/Mod/Fem/femobjects/constraint_electrostaticpotential.py +++ b/src/Mod/Fem/femobjects/constraint_electrostaticpotential.py @@ -2,6 +2,7 @@ # * Copyright (c) 2017 Markus Hovorka * # * Copyright (c) 2020 Bernd Hahnebach * # * Copyright (c) 2023 Uwe Stöhr * +# * Copyright (c) 2024 Mario Passaglia * # * * # * This file is part of the FreeCAD CAx development system. * # * * @@ -24,7 +25,7 @@ # *************************************************************************** __title__ = "FreeCAD FEM constraint electrostatic potential document object" -__author__ = "Markus Hovorka, Bernd Hahnebach, Uwe Stöhr" +__author__ = "Markus Hovorka, Bernd Hahnebach, Uwe Stöhr, Mario Passaglia" __url__ = "https://www.freecad.org" ## @package constraint_electrostaticpotential @@ -33,6 +34,8 @@ __url__ = "https://www.freecad.org" from . import base_fempythonobject +_PropHelper = base_fempythonobject._PropHelper + class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject): @@ -40,178 +43,243 @@ class ConstraintElectrostaticPotential(base_fempythonobject.BaseFemPythonObject) def __init__(self, obj): super().__init__(obj) - self.add_properties(obj) + + for prop in self._get_properties(): + prop.add_to_object(obj) + + def _get_properties(self): + prop = [] + + prop.append( + _PropHelper( + type="App::PropertyElectricPotential", + name="Potential", + group="Parameter", + doc="Electric Potential", + value="1 V", + ) + ) + prop.append( + _PropHelper( + type="App::PropertyBool", + name="PotentialEnabled", + group="Parameter", + doc="Enable electric potential", + value=True, + ) + ) + prop.append( + _PropHelper( + type="App::PropertyElectromagneticPotential", + name="AV_re_1", + group="Vector Potential", + doc="Real part of potential x-component", + value="0 Wb/m", + ) + ) + prop.append( + _PropHelper( + type="App::PropertyElectromagneticPotential", + name="AV_re_2", + group="Vector Potential", + doc="Real part of potential y-component", + value="0 Wb/m", + ) + ) + prop.append( + _PropHelper( + type="App::PropertyElectromagneticPotential", + name="AV_re_3", + group="Vector Potential", + doc="Real part of potential z-component", + value="0 Wb/m", + ) + ) + prop.append( + _PropHelper( + type="App::PropertyElectromagneticPotential", + name="AV_im_1", + group="Vector Potential", + doc="Imaginary part of potential x-component", + value="0 Wb/m", + ) + ) + prop.append( + _PropHelper( + type="App::PropertyElectromagneticPotential", + name="AV_im_2", + group="Vector Potential", + doc="Imaginary part of potential y-component", + value="0 Wb/m", + ) + ) + prop.append( + _PropHelper( + type="App::PropertyElectromagneticPotential", + name="AV_im_3", + group="Vector Potential", + doc="Imaginary part of potential z-component", + value="0 Wb/m", + ) + ) + prop.append( + _PropHelper( + type="App::PropertySurfaceChargeDensity", + name="SurfaceChargeDensity", + group="Parameter", + doc="Free surface charge density", + value="0 C/m^2", + ) + ) + prop.append( + _PropHelper( + type="App::PropertyEnumeration", + name="BoundaryCondition", + group="Parameter", + doc="Set boundary condition type", + value=["Dirichlet", "Neumann"], + ) + ) + prop.append( + _PropHelper( + type="App::PropertyElectricPotential", + name="AV_im", + group="Parameter", + doc="Imaginary part of scalar potential", + value="0 V", + ) + ) + prop.append( + _PropHelper( + type="App::PropertyBool", + name="AV_re_1_Disabled", + group="Vector Potential", + doc="", + value=True, + ) + ) + prop.append( + _PropHelper( + type="App::PropertyBool", + name="AV_re_2_Disabled", + group="Vector Potential", + doc="", + value=True, + ) + ) + prop.append( + _PropHelper( + type="App::PropertyBool", + name="AV_re_3_Disabled", + group="Vector Potential", + doc="", + value=True, + ) + ) + prop.append( + _PropHelper( + type="App::PropertyBool", + name="AV_im_1_Disabled", + group="Vector Potential", + doc="", + value=True, + ) + ) + prop.append( + _PropHelper( + type="App::PropertyBool", + name="AV_im_2_Disabled", + group="Vector Potential", + doc="", + value=True, + ) + ) + prop.append( + _PropHelper( + type="App::PropertyBool", + name="AV_im_3_Disabled", + group="Vector Potential", + doc="", + value=True, + ) + ) + prop.append( + _PropHelper( + type="App::PropertyBool", + name="AV_im_Disabled", + group="Vector Potential", + doc="", + value=True, + ) + ) + prop.append( + _PropHelper( + type="App::PropertyBool", + name="PotentialConstant", + group="Parameter", + doc="", + value=False, + ) + ) + prop.append( + _PropHelper( + type="App::PropertyBool", + name="ElectricInfinity", + group="Parameter", + doc="Electric Infinity", + value=False, + ) + ) + + prop.append( + _PropHelper( + type="App::PropertyBool", + name="ElectricForcecalculation", + group="Parameter", + doc="Electric force calculation", + value=False, + ) + ) + prop.append( + _PropHelper( + type="App::PropertyInteger", + name="CapacitanceBody", + group="Parameter", + doc="Capacitance body", + value=0, + ) + ) + prop.append( + _PropHelper( + type="App::PropertyBool", + name="CapacitanceBodyEnabled", + group="Parameter", + doc="Capacitance body enabled", + value=False, + ) + ) + + return prop def onDocumentRestored(self, obj): - self.add_properties(obj) + # update old project with new properties + for prop in self._get_properties(): + try: + obj.getPropertyByName(prop.name) + except Base.PropertyError: + prop.add_to_object(obj) - def add_properties(self, obj): - if not hasattr(obj, "Potential"): - obj.addProperty( - "App::PropertyElectricPotential", "Potential", "Parameter", "Electric Potential" - ) - obj.setPropertyStatus("Potential", "LockDynamic") - # setting 1 V assures that the unit does not switch to mV - # and the constraint holds usually Volts - obj.Potential = "1 V" - - if not hasattr(obj, "AV_re_1"): - obj.addProperty( - "App::PropertyElectricPotential", - "AV_re_1", - "Vector Potential", - "Real part of potential x-component", - ) - obj.setPropertyStatus("AV_re_1", "LockDynamic") - obj.AV_re_1 = "0 V" - if not hasattr(obj, "AV_re_2"): - obj.addProperty( - "App::PropertyElectricPotential", - "AV_re_2", - "Vector Potential", - "Real part of potential y-component", - ) - obj.setPropertyStatus("AV_re_2", "LockDynamic") - obj.AV_re_2 = "0 V" - if not hasattr(obj, "AV_re_3"): - obj.addProperty( - "App::PropertyElectricPotential", - "AV_re_3", - "Vector Potential", - "Real part of potential z-component", - ) - obj.setPropertyStatus("AV_re_3", "LockDynamic") - obj.AV_re_3 = "0 V" - if not hasattr(obj, "AV_im"): - obj.addProperty( - "App::PropertyElectricPotential", - "AV_im", - "Vector Potential", - "Imaginary part of scalar potential", - ) - obj.setPropertyStatus("AV_im", "LockDynamic") - obj.AV_im = "0 V" - if not hasattr(obj, "AV_im_1"): - obj.addProperty( - "App::PropertyElectricPotential", - "AV_im_1", - "Vector Potential", - "Imaginary part of potential x-component", - ) - obj.setPropertyStatus("AV_im_1", "LockDynamic") - obj.AV_im_1 = "0 V" - if not hasattr(obj, "AV_im_2"): - obj.addProperty( - "App::PropertyElectricPotential", - "AV_im_2", - "Vector Potential", - "Imaginary part of potential y-component", - ) - obj.setPropertyStatus("AV_im_2", "LockDynamic") - obj.AV_im_2 = "0 V" - if not hasattr(obj, "AV_im_3"): - obj.addProperty( - "App::PropertyElectricPotential", - "AV_im_3", - "Vector Potential", - "Imaginary part of potential z-component", - ) - obj.setPropertyStatus("AV_im_3", "LockDynamic") - obj.AV_im_3 = "0 V" - - # now the enable bools - if not hasattr(obj, "PotentialEnabled"): - obj.addProperty( - "App::PropertyBool", "PotentialEnabled", "Parameter", "Potential Enabled" - ) - obj.setPropertyStatus("PotentialEnabled", "LockDynamic") - obj.PotentialEnabled = True - if not hasattr(obj, "AV_re_1_Disabled"): - obj.addProperty("App::PropertyBool", "AV_re_1_Disabled", "Vector Potential", "") - obj.setPropertyStatus("AV_re_1_Disabled", "LockDynamic") - obj.AV_re_1_Disabled = True - if not hasattr(obj, "AV_re_2_Disabled"): - obj.addProperty("App::PropertyBool", "AV_re_2_Disabled", "Vector Potential", "") - obj.setPropertyStatus("AV_re_2_Disabled", "LockDynamic") - obj.AV_re_2_Disabled = True - if not hasattr(obj, "AV_re_3_Disabled"): - obj.addProperty("App::PropertyBool", "AV_re_3_Disabled", "Vector Potential", "") - obj.setPropertyStatus("AV_re_3_Disabled", "LockDynamic") - obj.AV_re_3_Disabled = True - if not hasattr(obj, "AV_im_Disabled"): - obj.addProperty("App::PropertyBool", "AV_im_Disabled", "Vector Potential", "") - obj.setPropertyStatus("AV_im_Disabled", "LockDynamic") - obj.AV_im_Disabled = True - if not hasattr(obj, "AV_im_1_Disabled"): - obj.addProperty("App::PropertyBool", "AV_im_1_Disabled", "Vector Potential", "") - obj.setPropertyStatus("AV_im_1_Disabled", "LockDynamic") - obj.AV_im_1_Disabled = True - if not hasattr(obj, "AV_im_2_Disabled"): - obj.addProperty("App::PropertyBool", "AV_im_2_Disabled", "Vector Potential", "") - obj.setPropertyStatus("AV_im_2_Disabled", "LockDynamic") - obj.AV_im_2_Disabled = True - if not hasattr(obj, "AV_im_3_Disabled"): - obj.addProperty("App::PropertyBool", "AV_im_3_Disabled", "Vector Potential", "") - obj.setPropertyStatus("AV_im_3_Disabled", "LockDynamic") - obj.AV_im_3_Disabled = True - - if not hasattr(obj, "PotentialConstant"): - obj.addProperty( - "App::PropertyBool", "PotentialConstant", "Parameter", "Potential Constant" - ) - obj.setPropertyStatus("PotentialConstant", "LockDynamic") - obj.PotentialConstant = False - - if not hasattr(obj, "ElectricInfinity"): - obj.addProperty( - "App::PropertyBool", "ElectricInfinity", "Parameter", "Electric Infinity" - ) - obj.setPropertyStatus("ElectricInfinity", "LockDynamic") - obj.ElectricInfinity = False - - if not hasattr(obj, "ElectricForcecalculation"): - obj.addProperty( - "App::PropertyBool", - "ElectricForcecalculation", - "Parameter", - "Electric Force Calculation", - ) - obj.setPropertyStatus("ElectricForcecalculation", "LockDynamic") - obj.ElectricForcecalculation = False - - if not hasattr(obj, "CapacitanceBody"): - obj.addProperty( - "App::PropertyInteger", "CapacitanceBody", "Parameter", "Capacitance Body" - ) - obj.setPropertyStatus("CapacitanceBody", "LockDynamic") - obj.CapacitanceBody = 0 - - if not hasattr(obj, "CapacitanceBodyEnabled"): - obj.addProperty( - "App::PropertyBool", - "CapacitanceBodyEnabled", - "Parameter", - "Capacitance Body Enabled", - ) - 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 + # convert old potential float to Volt + if prop.name == "Potential": + prop.handle_change_type( + obj, + old_type="App::PropertyFloat", + convert_old_value=lambda x: "{} V".format(1e6 * x), + ) + # fix unit for magnetic vector potential properties + if prop.name in ("AV_re_1", "AV_re_2", "AV_re_3", "AV_im_1", "AV_im_2", "AV_im_3"): + prop.handle_change_type( + obj, + old_type="App::PropertyElectricPotential", + convert_old_value=lambda x: "{} Wb/m".format(x.getValueAs("V").Value), + ) diff --git a/src/Mod/Fem/femsolver/elmer/equations/electrostatic_writer.py b/src/Mod/Fem/femsolver/elmer/equations/electrostatic_writer.py index 1751c9b78b..6ffba76461 100644 --- a/src/Mod/Fem/femsolver/elmer/equations/electrostatic_writer.py +++ b/src/Mod/Fem/femsolver/elmer/equations/electrostatic_writer.py @@ -125,26 +125,17 @@ class ESwriter: # output the FreeCAD label as comment if obj.Label: self.write.boundary(name, "! FreeCAD Name", obj.Label) - if obj.Dirichlet: + if obj.BoundaryCondition == "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) + self.write.boundary( + name, "Potential", obj.Potential.getValueAs("V").Value + ) + elif obj.BoundaryCondition == "Neumann": + self.write.boundary( + name, + "Surface Charge Density", + obj.SurfaceChargeDensity.getValueAs("C/m^2").Value, + ) if obj.PotentialConstant: self.write.boundary(name, "Potential Constant", True) if obj.ElectricInfinity: @@ -152,8 +143,7 @@ class ESwriter: if obj.ElectricForcecalculation: self.write.boundary(name, "Calculate Electric Force", True) if obj.CapacitanceBodyEnabled: - if hasattr(obj, "CapacitanceBody"): - self.write.boundary(name, "Capacitance Body", obj.CapacitanceBody) + self.write.boundary(name, "Capacitance Body", obj.CapacitanceBody) self.write.handled(obj) diff --git a/src/Mod/Fem/femtaskpanels/task_constraint_electrostaticpotential.py b/src/Mod/Fem/femtaskpanels/task_constraint_electrostaticpotential.py index f7a7e12f26..33a17dcff2 100644 --- a/src/Mod/Fem/femtaskpanels/task_constraint_electrostaticpotential.py +++ b/src/Mod/Fem/femtaskpanels/task_constraint_electrostaticpotential.py @@ -2,6 +2,7 @@ # * Copyright (c) 2017 Markus Hovorka * # * Copyright (c) 2020 Bernd Hahnebach * # * Copyright (c) 2023 Uwe Stöhr * +# * Copyright (c) 2024 Mario Passaglia * # * * # * This file is part of the FreeCAD CAx development system. * # * * @@ -24,7 +25,7 @@ # *************************************************************************** __title__ = "FreeCAD FEM constraint electrostatic potential task panel for the document object" -__author__ = "Markus Hovorka, Bernd Hahnebach, Uwe Stöhr, André Kapelrud" +__author__ = "Markus Hovorka, Bernd Hahnebach, Uwe Stöhr, André Kapelrud, Mario Passaglia" __url__ = "https://www.freecad.org" ## @package task_constraint_electrostaticpotential @@ -46,10 +47,9 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel): def __init__(self, obj): super().__init__(obj) - self._paramWidget = FreeCADGui.PySideUic.loadUi( + self.parameter_widget = FreeCADGui.PySideUic.loadUi( FreeCAD.getHomePath() + "Mod/Fem/Resources/ui/ElectrostaticPotential.ui" ) - self._initParamWidget() # geometry selection widget # start with Solid in list! @@ -58,7 +58,7 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel): ) # form made from param and selection widget - self.form = [self._paramWidget, self._selectionWidget] + self.form = [self.parameter_widget, self._selectionWidget] analysis = obj.getParentGroup() self._mesh = None @@ -81,22 +81,138 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel): and self.obj.AV_im_3_Disabled ): self._vectorField_visibility(False) - self._paramWidget.vectorFieldBox.setChecked(False) + self.parameter_widget.vectorFieldBox.setChecked(False) + QtCore.QObject.connect( - self._paramWidget.vectorFieldBox, + self.parameter_widget.vectorFieldBox, QtCore.SIGNAL("toggled(bool)"), self._vectorField_visibility, ) + QtCore.QObject.connect( + self.parameter_widget.cb_boundary_condition, + QtCore.SIGNAL("currentIndexChanged(int)"), + self.boundary_condition_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.ckb_potential, + QtCore.SIGNAL("toggled(bool)"), + self.potential_enabled_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.qsb_potential, + QtCore.SIGNAL("valueChanged(Base::Quantity)"), + self.potential_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.ckb_av_re, + QtCore.SIGNAL("toggled(bool)"), + self.av_re_enabled_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.ckb_av_re_1, + QtCore.SIGNAL("toggled(bool)"), + self.av_re_1_enabled_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.qsb_av_re_1, + QtCore.SIGNAL("valueChanged(Base::Quantity)"), + self.av_re_1_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.ckb_av_re_2, + QtCore.SIGNAL("toggled(bool)"), + self.av_re_2_enabled_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.qsb_av_re_2, + QtCore.SIGNAL("valueChanged(Base::Quantity)"), + self.av_re_2_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.ckb_av_re_3, + QtCore.SIGNAL("toggled(bool)"), + self.av_re_3_enabled_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.qsb_av_re_3, + QtCore.SIGNAL("valueChanged(Base::Quantity)"), + self.av_re_3_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.ckb_av_im, + QtCore.SIGNAL("toggled(bool)"), + self.av_im_enabled_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.qsb_av_im, + QtCore.SIGNAL("valueChanged(Base::Quantity)"), + self.av_im_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.ckb_av_im_1, + QtCore.SIGNAL("toggled(bool)"), + self.av_im_1_enabled_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.qsb_av_im_1, + QtCore.SIGNAL("valueChanged(Base::Quantity)"), + self.av_im_1_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.ckb_av_im_2, + QtCore.SIGNAL("toggled(bool)"), + self.av_im_2_enabled_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.qsb_av_im_2, + QtCore.SIGNAL("valueChanged(Base::Quantity)"), + self.av_im_2_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.ckb_av_im_3, + QtCore.SIGNAL("toggled(bool)"), + self.av_im_3_enabled_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.qsb_av_im_3, + QtCore.SIGNAL("valueChanged(Base::Quantity)"), + self.av_im_3_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.ckb_capacitance_body, + QtCore.SIGNAL("toggled(bool)"), + self.capacitance_body_enabled_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.spb_capacitance_body, + QtCore.SIGNAL("valueChanged(int)"), + self.capacitance_body_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.ckb_potential_constant, + QtCore.SIGNAL("toggled(bool)"), + self.potential_constant_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.ckb_electric_infinity, + QtCore.SIGNAL("toggled(bool)"), + self.electric_infinity_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.ckb_electric_forcecalculation, + QtCore.SIGNAL("toggled(bool)"), + self.electric_forcecalculation_changed, + ) + QtCore.QObject.connect( + self.parameter_widget.qsb_surface_charge_density, + QtCore.SIGNAL("valueChanged(Base::Quantity)"), + self.surface_charge_density_changed, + ) - 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) + self.init_parameter_widget() def _vectorField_visibility(self, visible): - self._paramWidget.vectorFieldGB.setVisible(visible) + self.parameter_widget.vectorFieldGB.setVisible(visible) def open(self): if self._mesh is not None and self._part is not None: @@ -113,7 +229,7 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel): def accept(self): if self.obj.References != self._selectionWidget.references: self.obj.References = self._selectionWidget.references - self._applyWidgetChanges() + self._set_params() self._selectionWidget.finish_selection() self._restoreVisibility() return super().accept() @@ -129,64 +245,222 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel): else: self._part.ViewObject.hide() - def _initParamWidget(self): - self._paramWidget.potentialQSB.setProperty("value", self.obj.Potential) - FreeCADGui.ExpressionBinding(self._paramWidget.potentialQSB).bind(self.obj, "Potential") - self._paramWidget.potentialBox.setChecked(not self.obj.PotentialEnabled) + def _get_params(self): + self.potential = self.obj.Potential + self.potential_enabled = self.obj.PotentialEnabled + + self.av_re_1 = self.obj.AV_re_1 + self.av_re_2 = self.obj.AV_re_2 + self.av_re_3 = self.obj.AV_re_3 + self.av_im = self.obj.AV_im + self.av_im_1 = self.obj.AV_im_1 + self.av_im_2 = self.obj.AV_im_2 + self.av_im_3 = self.obj.AV_im_3 + + self.av_re_enabled = not self.obj.PotentialEnabled + self.av_re_1_enabled = not self.obj.AV_re_1_Disabled + self.av_re_2_enabled = not self.obj.AV_re_2_Disabled + self.av_re_3_enabled = not self.obj.AV_re_3_Disabled + self.av_im_enabled = not self.obj.AV_im_Disabled + self.av_im_1_enabled = not self.obj.AV_im_1_Disabled + self.av_im_2_enabled = not self.obj.AV_im_2_Disabled + self.av_im_3_enabled = not self.obj.AV_im_3_Disabled + + self.boundary_condition = self.obj.BoundaryCondition + self.potential_constant = self.obj.PotentialConstant + self.electric_infinity = self.obj.ElectricInfinity + self.electric_forcecalculation = self.obj.ElectricForcecalculation + self.capacitance_body_enabled = self.obj.CapacitanceBodyEnabled + self.capacitance_body = self.obj.CapacitanceBody + + self.surface_charge_density = self.obj.SurfaceChargeDensity + + def _set_params(self): + self.obj.Potential = self.potential + self.obj.PotentialEnabled = self.potential_enabled + + self.obj.AV_re_1 = self.av_re_1 + self.obj.AV_re_2 = self.av_re_2 + self.obj.AV_re_3 = self.av_re_3 + self.obj.AV_im = self.av_im + self.obj.AV_im_1 = self.av_im_1 + self.obj.AV_im_2 = self.av_im_2 + self.obj.AV_im_3 = self.av_im_3 + + self.obj.AV_re_1_Disabled = not self.av_re_1_enabled + self.obj.AV_re_2_Disabled = not self.av_re_2_enabled + self.obj.AV_re_3_Disabled = not self.av_re_3_enabled + self.obj.AV_im_Disabled = not self.av_im_enabled + self.obj.AV_im_1_Disabled = not self.av_im_1_enabled + self.obj.AV_im_2_Disabled = not self.av_im_2_enabled + self.obj.AV_im_3_Disabled = not self.av_im_3_enabled + + self.obj.BoundaryCondition = self.boundary_condition + self.obj.PotentialConstant = self.potential_constant + self.obj.ElectricInfinity = self.electric_infinity + self.obj.ElectricForcecalculation = self.electric_forcecalculation + self.obj.CapacitanceBodyEnabled = self.capacitance_body_enabled + self.obj.CapacitanceBody = self.capacitance_body + + self.obj.SurfaceChargeDensity = self.surface_charge_density + + def init_parameter_widget(self): + self._get_params() + + self.parameter_widget.qsb_potential.setProperty("value", self.potential) + FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_potential).bind( + self.obj, "Potential" + ) + self.parameter_widget.ckb_potential.setChecked(self.potential_enabled) # the vector potentials - # realScalarQSB always the same value as potentialQSB - self._paramWidget.realScalarQSB.setProperty("value", self.obj.Potential) - FreeCADGui.ExpressionBinding(self._paramWidget.realScalarQSB).bind(self.obj, "Potential") - self._paramWidget.realXQSB.setProperty("value", self.obj.AV_re_1) - FreeCADGui.ExpressionBinding(self._paramWidget.realXQSB).bind(self.obj, "AV_re_1") - self._paramWidget.realYQSB.setProperty("value", self.obj.AV_re_2) - FreeCADGui.ExpressionBinding(self._paramWidget.realYQSB).bind(self.obj, "AV_re_2") - self._paramWidget.realZQSB.setProperty("value", self.obj.AV_re_3) - FreeCADGui.ExpressionBinding(self._paramWidget.realZQSB).bind(self.obj, "AV_re_3") - self._paramWidget.imagScalarQSB.setProperty("value", self.obj.AV_im) - FreeCADGui.ExpressionBinding(self._paramWidget.imagScalarQSB).bind(self.obj, "AV_im") - self._paramWidget.imagXQSB.setProperty("value", self.obj.AV_im_1) - FreeCADGui.ExpressionBinding(self._paramWidget.imagXQSB).bind(self.obj, "AV_im_1") - self._paramWidget.imagYQSB.setProperty("value", self.obj.AV_im_2) - FreeCADGui.ExpressionBinding(self._paramWidget.imagYQSB).bind(self.obj, "AV_im_2") - self._paramWidget.imagZQSB.setProperty("value", self.obj.AV_im_3) - FreeCADGui.ExpressionBinding(self._paramWidget.imagZQSB).bind(self.obj, "AV_im_3") + self.parameter_widget.qsb_av_re.setProperty("value", self.potential) + self.parameter_widget.qsb_av_re.setEnabled(self.av_re_enabled) + FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_av_re).bind(self.obj, "Potential") - self._paramWidget.reXunspecBox.setChecked(self.obj.AV_re_1_Disabled) - self._paramWidget.reYunspecBox.setChecked(self.obj.AV_re_2_Disabled) - self._paramWidget.reZunspecBox.setChecked(self.obj.AV_re_3_Disabled) - self._paramWidget.imScalarunspecBox.setChecked(self.obj.AV_im_Disabled) - self._paramWidget.imXunspecBox.setChecked(self.obj.AV_im_1_Disabled) - self._paramWidget.imYunspecBox.setChecked(self.obj.AV_im_2_Disabled) - self._paramWidget.imZunspecBox.setChecked(self.obj.AV_im_3_Disabled) + self.parameter_widget.qsb_av_re_1.setProperty("value", self.av_re_1) + self.parameter_widget.qsb_av_re_1.setEnabled(self.av_re_1_enabled) + FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_av_re_1).bind(self.obj, "AV_re_1") + self.parameter_widget.qsb_av_re_2.setProperty("value", self.av_re_2) + self.parameter_widget.qsb_av_re_2.setEnabled(self.av_re_2_enabled) + FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_av_re_2).bind(self.obj, "AV_re_2") + self.parameter_widget.qsb_av_re_3.setProperty("value", self.av_re_3) + self.parameter_widget.qsb_av_re_3.setEnabled(self.av_re_3_enabled) + FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_av_re_3).bind(self.obj, "AV_re_3") + self.parameter_widget.qsb_av_im.setProperty("value", self.av_im) + self.parameter_widget.qsb_av_im.setEnabled(self.av_im_enabled) + FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_av_im).bind(self.obj, "AV_im") + self.parameter_widget.qsb_av_im_1.setProperty("value", self.av_im_1) + self.parameter_widget.qsb_av_im_1.setEnabled(self.av_im_1_enabled) + FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_av_im_1).bind(self.obj, "AV_im_1") + self.parameter_widget.qsb_av_im_2.setProperty("value", self.av_im_2) + self.parameter_widget.qsb_av_im_2.setEnabled(self.av_im_2_enabled) + FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_av_im_2).bind(self.obj, "AV_im_2") + self.parameter_widget.qsb_av_im_3.setProperty("value", self.av_im_3) + self.parameter_widget.qsb_av_im_3.setEnabled(self.av_im_3_enabled) + FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_av_im_3).bind(self.obj, "AV_im_3") - self._paramWidget.potentialConstantBox.setChecked(self.obj.PotentialConstant) + self.parameter_widget.ckb_av_re_1.setChecked(self.av_re_1_enabled) + self.parameter_widget.ckb_av_re_2.setChecked(self.av_re_2_enabled) + self.parameter_widget.ckb_av_re_3.setChecked(self.av_re_3_enabled) + self.parameter_widget.ckb_av_im.setChecked(self.av_im_enabled) + self.parameter_widget.ckb_av_im_1.setChecked(self.av_im_1_enabled) + self.parameter_widget.ckb_av_im_2.setChecked(self.av_im_2_enabled) + self.parameter_widget.ckb_av_im_3.setChecked(self.av_im_3_enabled) - self._paramWidget.electricInfinityBox.setChecked(self.obj.ElectricInfinity) + self.parameter_widget.ckb_potential_constant.setChecked(self.potential_constant) - self._paramWidget.electricForcecalculationBox.setChecked(self.obj.ElectricForcecalculation) + self.parameter_widget.ckb_electric_infinity.setChecked(self.electric_infinity) - self._paramWidget.capacitanceBodyBox.setChecked(not self.obj.CapacitanceBodyEnabled) - self._paramWidget.capacitanceBody_spinBox.setValue(self.obj.CapacitanceBody) - self._paramWidget.capacitanceBody_spinBox.setEnabled( - not self._paramWidget.capacitanceBodyBox.isChecked() + self.parameter_widget.ckb_electric_forcecalculation.setChecked( + self.electric_forcecalculation ) - # 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.parameter_widget.ckb_capacitance_body.setChecked(self.capacitance_body_enabled) + self.parameter_widget.spb_capacitance_body.setValue(self.capacitance_body) - self._paramWidget.surfacechargedensityQSB.setProperty( - "value", self.obj.SurfaceChargeDensity + self.parameter_widget.qsb_surface_charge_density.setProperty( + "value", self.surface_charge_density ) - FreeCADGui.ExpressionBinding(self._paramWidget.surfacechargedensityQSB).bind( + FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_surface_charge_density).bind( self.obj, "SurfaceChargeDensity" ) + self.bc_enum = self.obj.getEnumerationsOfProperty("BoundaryCondition") + self.parameter_widget.cb_boundary_condition.addItems(self.bc_enum) + index = self.bc_enum.index(self.boundary_condition) + self.parameter_widget.cb_boundary_condition.setCurrentIndex(index) + self.boundary_condition_changed(index) + + def potential_changed(self, value): + self.potential = value + + def potential_enabled_changed(self, value): + self.potential_enabled = value + self.parameter_widget.qsb_potential.setEnabled(value) + + def av_re_enabled_changed(self, value): + self.av_re_enabled = value + self.parameter_widget.qsb_av_re.setEnabled(value) + + def av_re_1_enabled_changed(self, value): + self.av_re_1_enabled = value + self.parameter_widget.qsb_av_re_1.setEnabled(value) + + def av_re_2_enabled_changed(self, value): + self.av_re_2_enabled = value + self.parameter_widget.qsb_av_re_2.setEnabled(value) + + def av_re_3_enabled_changed(self, value): + self.av_re_3_enabled = value + self.parameter_widget.qsb_av_re_3.setEnabled(value) + + def av_im_enabled_changed(self, value): + self.av_im_enabled = value + self.parameter_widget.qsb_av_im.setEnabled(value) + + def av_im_1_enabled_changed(self, value): + self.av_im_1_enabled = value + self.parameter_widget.qsb_av_im_1.setEnabled(value) + + def av_im_2_enabled_changed(self, value): + self.av_im_2_enabled = value + self.parameter_widget.qsb_av_im_2.setEnabled(value) + + def av_im_3_enabled_changed(self, value): + self.av_im_3_enabled = value + self.parameter_widget.qsb_av_im_3.setEnabled(value) + + def av_re_1_changed(self, value): + self.av_re_1 = value + + def av_re_2_changed(self, value): + self.av_re_2 = value + + def av_re_3_changed(self, value): + self.av_re_3 = value + + def av_im_changed(self, value): + self.av_im = value + + def av_im_1_changed(self, value): + self.av_im_1 = value + + def av_im_2_changed(self, value): + self.av_im_2 = value + + def av_im_3_changed(self, value): + self.av_im_3 = value + + def potential_constant_changed(self, value): + self.potential_constant = value + + def electric_infinity_changed(self, value): + self.electric_infinity = value + + def electric_forcecalculation_changed(self, value): + self.electric_forcecalculation = value + + def capacitance_body_enabled_changed(self, value): + self.capacitance_body_enabled = value + self.parameter_widget.spb_capacitance_body.setEnabled(value) + + def capacitance_body_changed(self, value): + self.capacitance_body = value + self.parameter_widget.spb_capacitance_body.setValue(value) + + def surface_charge_density_changed(self, value): + self.surface_charge_density = value + + def boundary_condition_changed(self, index): + self.boundary_condition = self.bc_enum[index] + if self.boundary_condition == "Dirichlet": + self.parameter_widget.gb_neumann.setEnabled(False) + self.parameter_widget.gb_dirichlet.setEnabled(True) + elif self.boundary_condition == "Neumann": + self.parameter_widget.gb_neumann.setEnabled(True) + self.parameter_widget.gb_dirichlet.setEnabled(False) + def _applyPotentialChanges(self, enabledBox, potentialQSB): enabled = enabledBox.isChecked() potential = None @@ -202,56 +476,37 @@ class _TaskPanel(base_femtaskpanel._BaseTaskPanel): def _applyWidgetChanges(self): # apply the voltages and their enabled state - self.obj.PotentialEnabled, self.obj.Potential = self._applyPotentialChanges( - self._paramWidget.potentialBox, self._paramWidget.potentialQSB - ) self.obj.AV_re_1_Disabled, self.obj.AV_re_1 = self._applyPotentialChanges( - self._paramWidget.reXunspecBox, self._paramWidget.realXQSB + self.parameter_widget.reXunspecBox, self.parameter_widget.realXQSB ) self.obj.AV_re_2_Disabled, self.obj.AV_re_2 = self._applyPotentialChanges( - self._paramWidget.reYunspecBox, self._paramWidget.realYQSB + self.parameter_widget.reYunspecBox, self.parameter_widget.realYQSB ) self.obj.AV_re_3_Disabled, self.obj.AV_re_3 = self._applyPotentialChanges( - self._paramWidget.reZunspecBox, self._paramWidget.realZQSB + self.parameter_widget.reZunspecBox, self.parameter_widget.realZQSB ) self.obj.AV_im_Disabled, self.obj.AV_im = self._applyPotentialChanges( - self._paramWidget.imScalarunspecBox, self._paramWidget.imagScalarQSB + self.parameter_widget.imScalarunspecBox, self.parameter_widget.imagScalarQSB ) self.obj.AV_im_1_Disabled, self.obj.AV_im_1 = self._applyPotentialChanges( - self._paramWidget.imXunspecBox, self._paramWidget.imagXQSB + self.parameter_widget.imXunspecBox, self.parameter_widget.imagXQSB ) self.obj.AV_im_2_Disabled, self.obj.AV_im_2 = self._applyPotentialChanges( - self._paramWidget.imYunspecBox, self._paramWidget.imagYQSB + self.parameter_widget.imYunspecBox, self.parameter_widget.imagYQSB ) self.obj.AV_im_3_Disabled, self.obj.AV_im_3 = self._applyPotentialChanges( - self._paramWidget.imZunspecBox, self._paramWidget.imagZQSB + self.parameter_widget.imZunspecBox, self.parameter_widget.imagZQSB ) # because this is an enable the others are disabled, reverse self.obj.PotentialEnabled = not self.obj.PotentialEnabled - self.obj.PotentialConstant = self._paramWidget.potentialConstantBox.isChecked() + self.obj.PotentialConstant = self.parameter_widget.potentialConstantBox.isChecked() - self.obj.ElectricInfinity = self._paramWidget.electricInfinityBox.isChecked() + self.obj.ElectricInfinity = self.parameter_widget.electricInfinityBox.isChecked() - calc_is_checked = self._paramWidget.electricForcecalculationBox.isChecked() + calc_is_checked = self.parameter_widget.electricForcecalculationBox.isChecked() self.obj.ElectricForcecalculation = calc_is_checked # two lines because max line length - self.obj.CapacitanceBodyEnabled = not self._paramWidget.capacitanceBodyBox.isChecked() - 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)" + self.obj.SurfaceChargeDensity = self.parameter_widget.surfacechargedensityQSB.property( + "value" + )