[FEM] add current density constraint

- also add corresponding App::PropertyCurrentDensity

- also fix a typo in test_object.py
This commit is contained in:
Uwe
2023-02-04 08:07:13 +01:00
parent 1f7ab06160
commit 65eb154eac
18 changed files with 625 additions and 17 deletions

View File

@@ -1914,6 +1914,7 @@ void Application::initTypes()
App::PropertyAcceleration ::init();
App::PropertyForce ::init();
App::PropertyPressure ::init();
App::PropertyCurrentDensity ::init();
App::PropertyElectricPotential ::init();
App::PropertyVacuumPermittivity ::init();
App::PropertyInteger ::init();

View File

@@ -20,9 +20,7 @@
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <cfloat>
#endif
@@ -88,7 +86,6 @@ Base::Quantity PropertyQuantity::createQuantityFromPy(PyObject *value)
return quant;
}
void PropertyQuantity::setPyObject(PyObject *value)
{
// Set the unit if Unit object supplied, else check the unit
@@ -140,7 +137,6 @@ const boost::any PropertyQuantity::getPathValue(const ObjectIdentifier & /*path*
TYPESYSTEM_SOURCE(App::PropertyQuantityConstraint, App::PropertyQuantity)
void PropertyQuantityConstraint::setConstraints(const Constraints* sConstrain)
{
_ConstStruct = sConstrain;
@@ -151,7 +147,6 @@ const char* PropertyQuantityConstraint::getEditorName() const
return "Gui::PropertyEditor::PropertyUnitConstraintItem";
}
const PropertyQuantityConstraint::Constraints* PropertyQuantityConstraint::getConstraints() const
{
return _ConstStruct;
@@ -253,6 +248,18 @@ PropertyDistance::PropertyDistance()
setUnit(Base::Unit::Length);
}
//**************************************************************************
//**************************************************************************
// PropertyCurrentDensity
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TYPESYSTEM_SOURCE(App::PropertyCurrentDensity, App::PropertyQuantity)
PropertyCurrentDensity::PropertyCurrentDensity()
{
setUnit(Base::Unit::CurrentDensity);
}
//**************************************************************************
//**************************************************************************
// PropertyElectricPotential

View File

@@ -172,6 +172,19 @@ public:
~PropertyDistance() override = default;
};
/** CurrentDensity property
* This is a property for electric current densities. It is basically a float
* property. On the Gui it has a quantity of Ampere/m^2.
*/
class AppExport PropertyCurrentDensity: public PropertyQuantity
{
TYPESYSTEM_HEADER_WITH_OVERRIDE();
public:
PropertyCurrentDensity();
~PropertyCurrentDensity() override = default;
};
/** ElectricPotential property
* This is a property for electric potentials. It is basically a float
* property. On the Gui it has a quantity of Volt.

View File

@@ -169,6 +169,7 @@ SET(FemObjects_SRCS
femobjects/constant_vacuumpermittivity.py
femobjects/constraint_bodyheatsource.py
femobjects/constraint_centrif.py
femobjects/constraint_currentdensity.py
femobjects/constraint_electrostaticpotential.py
femobjects/constraint_flowvelocity.py
femobjects/constraint_initialflowvelocity.py
@@ -565,6 +566,7 @@ SET(FemGuiTaskPanels_SRCS
femtaskpanels/__init__.py
femtaskpanels/task_constraint_bodyheatsource.py
femtaskpanels/task_constraint_centrif.py
femtaskpanels/task_constraint_currentdensity.py
femtaskpanels/task_constraint_electrostaticpotential.py
femtaskpanels/task_constraint_flowvelocity.py
femtaskpanels/task_constraint_initialflowvelocity.py
@@ -603,6 +605,7 @@ SET(FemGuiViewProvider_SRCS
femviewprovider/view_constant_vacuumpermittivity.py
femviewprovider/view_constraint_bodyheatsource.py
femviewprovider/view_constraint_centrif.py
femviewprovider/view_constraint_currentdensity.py
femviewprovider/view_constraint_electrostaticpotential.py
femviewprovider/view_constraint_flowvelocity.py
femviewprovider/view_constraint_initialflowvelocity.py

View File

@@ -375,6 +375,7 @@ SET(FemGuiPythonUI_SRCS
Resources/ui/ConstraintCentrif.ui
Resources/ui/ConstraintTie.ui
Resources/ui/ConstraintSectionPrint.ui
Resources/ui/CurrentDensity.ui
Resources/ui/ElectrostaticPotential.ui
Resources/ui/ElementFluid1D.ui
Resources/ui/ElementGeometry1D.ui

View File

@@ -1127,6 +1127,113 @@ bool CmdFemCreateNodesSet::isActive()
}
//===========================================================================
// FEM_CompEmConstraints (dropdown toolbar button for Electromagnetic constraints)
//===========================================================================
DEF_STD_CMD_ACL(CmdFemCompEmConstraints)
CmdFemCompEmConstraints::CmdFemCompEmConstraints()
: Command("FEM_CompEmConstraints")
{
sAppModule = "Fem";
sGroup = QT_TR_NOOP("Fem");
sMenuText = QT_TR_NOOP("Electromagnetic constraints...");
sToolTipText = QT_TR_NOOP("Electromagnetic constraints");
sWhatsThis = "";
sStatusTip = sToolTipText;
}
void CmdFemCompEmConstraints::activated(int iMsg)
{
Gui::CommandManager& rcCmdMgr = Gui::Application::Instance->commandManager();
if (iMsg == 0)
rcCmdMgr.runCommandByName("FEM_ConstraintElectrostaticPotential");
else if (iMsg == 1)
rcCmdMgr.runCommandByName("FEM_ConstraintCurrentDensity");
else
return;
// Since the default icon is reset when enabling/disabling the command we have
// to explicitly set the icon of the used command.
Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction);
QList<QAction*> a = pcAction->actions();
assert(iMsg < a.size());
pcAction->setIcon(a[iMsg]->icon());
}
Gui::Action* CmdFemCompEmConstraints::createAction()
{
Gui::ActionGroup* pcAction = new Gui::ActionGroup(this, Gui::getMainWindow());
pcAction->setDropDownMenu(true);
applyCommandData(this->className(), pcAction);
QAction* cmd0 = pcAction->addAction(QString());
cmd0->setIcon(Gui::BitmapFactory().iconFromTheme("FEM_ConstraintElectrostaticPotential"));
QAction* cmd1 = pcAction->addAction(QString());
cmd1->setIcon(Gui::BitmapFactory().iconFromTheme("FEM_ConstraintCurrentDensity"));
_pcAction = pcAction;
languageChange();
pcAction->setIcon(cmd0->icon());
int defaultId = 0;
pcAction->setProperty("defaultAction", QVariant(defaultId));
return pcAction;
}
void CmdFemCompEmConstraints::languageChange()
{
Command::languageChange();
if (!_pcAction)
return;
Gui::CommandManager& rcCmdMgr = Gui::Application::Instance->commandManager();
Gui::ActionGroup* pcAction = qobject_cast<Gui::ActionGroup*>(_pcAction);
QList<QAction*> a = pcAction->actions();
Gui::Command* ConstraintElectrostaticPotential =
rcCmdMgr.getCommandByName("FEM_ConstraintElectrostaticPotential");
if (ConstraintElectrostaticPotential) {
QAction* cmd0 = a[0];
cmd0->setText(QApplication::translate("FEM_ConstraintElectrostaticPotential",
ConstraintElectrostaticPotential->getMenuText()));
cmd0->setToolTip(QApplication::translate("FEM_ConstraintElectrostaticPotential",
ConstraintElectrostaticPotential->getToolTipText()));
cmd0->setStatusTip(QApplication::translate("FEM_ConstraintElectrostaticPotential",
ConstraintElectrostaticPotential->getStatusTip()));
}
Gui::Command* ConstraintCurrentDensity =
rcCmdMgr.getCommandByName("FEM_ConstraintCurrentDensity");
if (ConstraintCurrentDensity) {
QAction* cmd1 = a[1];
cmd1->setText(QApplication::translate("FEM_ConstraintCurrentDensity",
ConstraintCurrentDensity->getMenuText()));
cmd1->setToolTip(QApplication::translate("FEM_ConstraintCurrentDensity",
ConstraintCurrentDensity->getToolTipText()));
cmd1->setStatusTip(QApplication::translate("FEM_ConstraintCurrentDensity",
ConstraintCurrentDensity->getStatusTip()));
}
}
bool CmdFemCompEmConstraints::isActive()
{
// only if there is an active analysis
Fem::FemAnalysis* ActiveAnalysis =
FemGui::ActiveAnalysisObserver::instance()->getActiveObject();
if (!ActiveAnalysis
|| !ActiveAnalysis->getTypeId().isDerivedFrom(Fem::FemAnalysis::getClassTypeId()))
return false;
return true;
}
//================================================================================================
//================================================================================================
// commands vtk post processing
@@ -1906,6 +2013,7 @@ void CreateFemCommands()
rcCmdMgr.addCommand(new CmdFemConstraintTemperature());
rcCmdMgr.addCommand(new CmdFemConstraintTransform());
rcCmdMgr.addCommand(new CmdFemConstraintSpring());
rcCmdMgr.addCommand(new CmdFemCompEmConstraints());
// mesh
rcCmdMgr.addCommand(new CmdFemCreateNodesSet());

View File

@@ -13,6 +13,7 @@
<file>icons/FEM_ConstraintBodyHeatSource.svg</file>
<file>icons/FEM_ConstraintCentrif.svg</file>
<file>icons/FEM_ConstraintContact.svg</file>
<file>icons/FEM_ConstraintCurrentDensity.svg</file>
<file>icons/FEM_ConstraintDisplacement.svg</file>
<file>icons/FEM_ConstraintElectrostaticPotential.svg</file>
<file>icons/FEM_ConstraintFixed.svg</file>
@@ -158,6 +159,7 @@
<file>ui/ConstraintCentrif.ui</file>
<file>ui/ConstraintSectionPrint.ui</file>
<file>ui/ConstraintTie.ui</file>
<file>ui/CurrentDensity.ui</file>
<file>ui/ElectrostaticPotential.ui</file>
<file>ui/ElementFluid1D.ui</file>
<file>ui/ElementGeometry1D.ui</file>

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="64px" height="64px" id="svg2860" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs id="defs2862">
<marker style="overflow:visible" id="Arrow2" refX="0" refY="0" orient="auto" markerWidth="4.583333" markerHeight="3.333333" viewBox="0 0 7.7 5.6" preserveAspectRatio="xMidYMid">
<path transform="scale(0.7)" d="M -2,-4 L 9,0 L -2,4 C 0,1.67 0,-1.66 -2,-4 Z" style="fill:context-stroke;fill-rule:evenodd;stroke:none" id="arrow2L" />
</marker>
<linearGradient id="linearGradient3929">
<stop style="stop-color:#a40000;stop-opacity:1" offset="0" id="stop3931" />
<stop style="stop-color:#ef2929;stop-opacity:1" offset="1" id="stop3933" />
</linearGradient>
<radialGradient xlink:href="#linearGradient3377" id="radialGradient3703" gradientUnits="userSpaceOnUse" cx="135.38333" cy="97.369568" fx="135.38333" fy="97.369568" r="19.467436" gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)" />
<linearGradient id="linearGradient3377">
<stop id="stop3379" offset="0" style="stop-color:#faff2b;stop-opacity:1" />
<stop id="stop3381" offset="1" style="stop-color:#ffaa00;stop-opacity:1" />
</linearGradient>
<radialGradient xlink:href="#linearGradient3377" id="radialGradient3705" gradientUnits="userSpaceOnUse" cx="148.88333" cy="81.869568" fx="148.88333" fy="81.869568" r="19.467436" gradientTransform="matrix(1.3852588,-0.05136783,0.03705629,0.9993132,-60.392403,7.7040438)" />
<radialGradient xlink:href="#linearGradient3377-4" id="radialGradient3703-8" gradientUnits="userSpaceOnUse" cx="135.38333" cy="97.369568" fx="135.38333" fy="97.369568" r="19.467436" gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)" />
<linearGradient id="linearGradient3377-4">
<stop id="stop3379-3" offset="0" style="stop-color:#faff2b;stop-opacity:1" />
<stop id="stop3381-0" offset="1" style="stop-color:#ffaa00;stop-opacity:1" />
</linearGradient>
<linearGradient xlink:href="#linearGradient3851-7-2" id="linearGradient3367" gradientUnits="userSpaceOnUse" gradientTransform="translate(-19.999999,-5.9999984)" spreadMethod="reflect" x1="-11" y1="26" x2="-18" y2="14" />
<linearGradient id="linearGradient3851-7-2">
<stop style="stop-color:#c4a000;stop-opacity:1" offset="0" id="stop3853-9-4" />
<stop style="stop-color:#fce94f;stop-opacity:1" offset="1" id="stop3855-8-4" />
</linearGradient>
<linearGradient xlink:href="#linearGradient3838-1" id="linearGradient3371" gradientUnits="userSpaceOnUse" x1="2802.9631" y1="538.36249" x2="2859.7263" y2="786.05646" />
<linearGradient id="linearGradient3838-1">
<stop style="stop-color:#34e0e2;stop-opacity:1" offset="0" id="stop3840-2" />
<stop style="stop-color:#06989a;stop-opacity:1" offset="1" id="stop3842-0" />
</linearGradient>
<linearGradient xlink:href="#linearGradient3859-3-8" id="linearGradient3369" gradientUnits="userSpaceOnUse" x1="32.557789" y1="32.917992" x2="26.30212" y2="12.206754" />
<linearGradient id="linearGradient3859-3-8">
<stop style="stop-color:#edd400;stop-opacity:1" offset="0" id="stop3861-1-7" />
<stop style="stop-color:#fce94f;stop-opacity:1" offset="1" id="stop3863-2-4" />
</linearGradient>
<linearGradient xlink:href="#linearGradient3929" id="linearGradient3935" x1="9.6000004" y1="60.799999" x2="4.8000002" y2="51.200001" gradientUnits="userSpaceOnUse" />
<marker style="overflow:visible" id="Arrow2-9" refX="0" refY="0" orient="auto" markerWidth="4.583333" markerHeight="3.3333333" viewBox="0 0 7.7 5.6" preserveAspectRatio="xMidYMid">
<path transform="scale(0.7)" d="M -2,-4 L 9,0 L -2,4 C 0,1.67 0,-1.66 -2,-4 Z" style="fill:context-stroke;fill-rule:evenodd;stroke:none" id="arrow2L-1" />
</marker>
<marker style="overflow:visible" id="Arrow2-1" refX="0" refY="0" orient="auto" markerWidth="4.583333" markerHeight="3.333333" viewBox="0 0 7.7 5.6" preserveAspectRatio="xMidYMid">
<path transform="scale(0.7)" d="M -2,-4 L 9,0 L -2,4 C 0,1.67 0,-1.66 -2,-4 Z" style="fill:context-stroke;fill-rule:evenodd;stroke:none" id="arrow2L-8" />
</marker>
<marker style="overflow:visible" id="Arrow2-9-1" refX="0" refY="0" orient="auto" markerWidth="4.583333" markerHeight="3.3333333" viewBox="0 0 7.7 5.6" preserveAspectRatio="xMidYMid">
<path transform="scale(0.7)" d="M -2,-4 L 9,0 L -2,4 C 0,1.67 0,-1.66 -2,-4 Z" style="fill:context-stroke;fill-rule:evenodd;stroke:none" id="arrow2L-1-1" />
</marker>
</defs>
<metadata id="metadata2865">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:creator>
<cc:Agent>
<dc:title>[vdwalts]</dc:title>
</cc:Agent>
</dc:creator>
<dc:date>2016-08-01</dc:date>
<dc:relation>http://www.freecadweb.org/wiki/index.php?title=Artwork</dc:relation>
<dc:publisher>
<cc:Agent>
<dc:title>FreeCAD</dc:title>
</cc:Agent>
</dc:publisher>
<dc:identifier>FreeCAD/src/Mod/</dc:identifier>
<dc:rights>
<cc:Agent>
<dc:title>FreeCAD LGPL2+</dc:title>
</cc:Agent>
</dc:rights>
<cc:license>https://www.gnu.org/copyleft/lesser.html</cc:license>
<dc:contributor>
<cc:Agent>
<dc:title>[agryson] Alexander Gryson</dc:title>
</cc:Agent>
</dc:contributor>
</cc:Work>
</rdf:RDF>
</metadata>
<g id="g2526" transform="matrix(1.1212306,0,0,1.2065378,-5.1041043,-4.481143)" style="stroke-width:0.85977">
<path style="fill:none;stroke:black;stroke-width:0.85977;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow2);marker-end:url(#Arrow2)" d="M 7.5590551,7.5590551 C 7.5590551,7.5590551 19.79465,13.835118 26.456693,15.11811 C 30.168024,15.832847 34.083945,15.832847 37.795276,15.11811 C 44.457319,13.835118 56.692913,7.5590551 56.692913,7.5590551" id="path8680" />
<path style="fill:none;stroke:black;stroke-width:0.85977;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow2-9);marker-end:url(#Arrow2-9)" d="M 7.5590551,18.897638 C 7.5590551,18.897638 19.79465,21.394173 26.456693,22.677165 C 30.168024,23.391902 34.083945,23.391902 37.795276,22.677165 C 44.457319,21.394173 56.692913,18.897638 56.692913,18.897638" id="path8680-0" />
<path style="fill:none;stroke:black;stroke-width:0.85977;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow2);marker-end:url(#Arrow2)" d="M 7.5590551,30.23622 H 56.692913" id="path10367" />
<path style="fill:none;stroke:black;stroke-width:0.85977;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow2-1);marker-end:url(#Arrow2-1)" d="M 7.5590551,52.913386 C 7.5590551,52.913386 19.79465,46.637323 26.456693,45.354331 C 30.168024,44.639594 34.083945,44.639594 37.795276,45.354331 C 44.457319,46.637323 56.692913,52.913386 56.692913,52.913386" id="path8680-5" />
<path style="fill:none;stroke:black;stroke-width:0.85977;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow2-9-1);marker-end:url(#Arrow2-9-1)" d="M 7.5590548,41.574803 C 7.5590548,41.574803 19.79465,39.078268 26.456693,37.795276 C 30.168024,37.080539 34.083945,37.080539 37.795276,37.795276 C 44.457319,39.078268 56.692913,41.574803 56.692913,41.574803" id="path8680-0-1" />
<path style="fill:#a40000;fill-opacity:1;stroke:black;stroke-width:0.429885;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1" d="M 26.456693,7.5590551 L 37.699397,8.7498528 V 52.437686 L 26.456693,52.913386 Z" id="path7856" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>350</width>
<height>40</height>
</rect>
</property>
<property name="windowTitle">
<string>Constraint Properties</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="pressureLbl">
<property name="text">
<string>Current density:</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>130</width>
<height>19</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Gui::QuantitySpinBox" name="currentDensityQSB">
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>20</height>
</size>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="keyboardTracking">
<bool>true</bool>
</property>
<property name="minimum">
<double>-1000000000000000000000.000000000000000</double>
</property>
<property name="maximum">
<double>1000000000000000000000.000000000000000</double>
</property>
<property name="singleStep">
<double>100.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Gui::QuantitySpinBox</class>
<extends>QWidget</extends>
<header>Gui/QuantitySpinBox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -114,10 +114,10 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
<< "FEM_ElementGeometry2D"
<< "FEM_ElementFluid1D";
Gui::ToolBarItem* electrostat = new Gui::ToolBarItem(root);
electrostat->setCommand("Electrostatic Constraints");
*electrostat
<< "FEM_ConstraintElectrostaticPotential";
Gui::ToolBarItem* electromag = new Gui::ToolBarItem(root);
electromag->setCommand("Electromagnetic Constraints");
*electromag
<< "FEM_CompEmConstraints";
Gui::ToolBarItem* fluid = new Gui::ToolBarItem(root);
fluid->setCommand("Fluid Constraints");
@@ -244,9 +244,10 @@ Gui::MenuItem* Workbench::setupMenuBar() const
<< "FEM_ElementFluid1D";
Gui::MenuItem* elec = new Gui::MenuItem;
elec->setCommand("&Electrostatic Constraints");
elec->setCommand("&Electromagnetic Constraints");
*elec
<< "FEM_ConstraintElectrostaticPotential";
<< "FEM_ConstraintElectrostaticPotential"
<< "FEM_ConstraintCurrentDensity";
Gui::MenuItem* fluid = new Gui::MenuItem;
fluid->setCommand("&Fluid Constraints");

View File

@@ -113,6 +113,21 @@ def makeConstraintCentrif(
return obj
def makeConstraintCurrentDensity(
doc,
name="ConstraintCurrentDensity"
):
"""makeConstraintCurrentDensity(document, [name]):
makes a Fem CurrentDensity object"""
obj = doc.addObject("Fem::ConstraintPython", name)
from femobjects import constraint_currentdensity
constraint_currentdensity.ConstraintCurrentDensity(obj)
if FreeCAD.GuiUp:
from femviewprovider import view_constraint_currentdensity
view_constraint_currentdensity.VPConstraintCurrentDensity(obj.ViewObject)
return obj
def makeConstraintContact(
doc,
name="ConstraintContact"

View File

@@ -209,6 +209,23 @@ class _ConstraintCentrif(CommandManager):
self.is_active = "with_analysis"
self.do_activated = "add_obj_on_gui_set_edit"
class _ConstraintCurrentDensity(CommandManager):
"The FEM_ConstraintCurrentDensity command definition"
def __init__(self):
super(_ConstraintCurrentDensity, self).__init__()
self.pixmap = "FEM_ConstraintCurrentDensity"
self.menutext = Qt.QT_TRANSLATE_NOOP(
"FEM_ConstraintCurrentDensity",
"Constraint current density"
)
self.tooltip = Qt.QT_TRANSLATE_NOOP(
"FEM_ConstraintCurrentDensity",
"Creates a FEM constraint current density"
)
self.is_active = "with_analysis"
self.do_activated = "add_obj_on_gui_set_edit"
class _ConstraintElectrostaticPotential(CommandManager):
"The FEM_ConstraintElectrostaticPotential command definition"
@@ -1112,6 +1129,10 @@ FreeCADGui.addCommand(
"FEM_ConstraintCentrif",
_ConstraintCentrif()
)
FreeCADGui.addCommand(
"FEM_ConstraintCurrentDensity",
_ConstraintCurrentDensity()
)
FreeCADGui.addCommand(
"FEM_ConstraintElectrostaticPotential",
_ConstraintElectrostaticPotential()

View File

@@ -0,0 +1,54 @@
# ***************************************************************************
# * Copyright (c) 2023 Uwe Stöhr <uwestoehr@lyx.org> *
# * *
# * This file is part of the FreeCAD CAx development system. *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * This program 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 Library General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with this program; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * *
# ***************************************************************************
__title__ = "FreeCAD FEM constraint current density document object"
__author__ = "Uwe Stöhr"
__url__ = "https://www.freecadweb.org"
## @package constraint_currentdensity
# \ingroup FEM
# \brief constraint body heat source object
from . import base_fempythonobject
class ConstraintCurrentDensity(base_fempythonobject.BaseFemPythonObject):
Type = "Fem::ConstraintCurrentDensity"
def __init__(self, obj):
super(ConstraintCurrentDensity, self).__init__(obj)
self.add_properties(obj)
def onDocumentRestored(self, obj):
self.add_properties(obj)
def add_properties(self, obj):
if not hasattr(obj, "CurrentDensity"):
obj.addProperty(
"App::PropertyCurrentDensity",
"CurrentDensity",
"Parameter",
"Current Density"
)
obj.CurrentDensity = 0.0

View File

@@ -0,0 +1,123 @@
# ***************************************************************************
# * Copyright (c) 2023 Uwe Stöhr <uwestoehr@lyx.org> *
# * *
# * This file is part of the FreeCAD CAx development system. *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * This program 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 Library General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with this program; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * *
# ***************************************************************************
__title__ = "FreeCAD FEM constraint current density task panel for the document object"
__author__ = "Uwe Stöhr"
__url__ = "https://www.freecadweb.org"
## @package task_constraint_currentdensity
# \ingroup FEM
# \brief task panel for constraint current density object
import FreeCAD
import FreeCADGui
from femguiutils import selection_widgets
from femtools import femutils
from femtools import membertools
class _TaskPanel(object):
def __init__(self, obj):
self._obj = obj
self._paramWidget = FreeCADGui.PySideUic.loadUi(
FreeCAD.getHomePath() + "Mod/Fem/Resources/ui/CurrentDensity.ui")
self._initParamWidget()
# geometry selection widget
# start with Solid in list!
self._selectionWidget = selection_widgets.GeometryElementsSelection(
obj.References,
["Solid", "Face"],
True,
False
)
# form made from param and selection widget
self.form = [self._paramWidget, self._selectionWidget]
analysis = obj.getParentGroup()
self._mesh = None
self._part = None
if analysis is not None:
self._mesh = membertools.get_single_member(analysis, "Fem::FemMeshObject")
if self._mesh is not None:
self._part = femutils.get_part_to_mesh(self._mesh)
self._partVisible = None
self._meshVisible = None
def open(self):
if self._mesh is not None and self._part is not None:
self._meshVisible = self._mesh.ViewObject.isVisible()
self._partVisible = self._part.ViewObject.isVisible()
self._mesh.ViewObject.hide()
self._part.ViewObject.show()
def reject(self):
self._restoreVisibility()
FreeCADGui.ActiveDocument.resetEdit()
return True
def accept(self):
if self._obj.References != self._selectionWidget.references:
self._obj.References = self._selectionWidget.references
self._applyWidgetChanges()
self._obj.Document.recompute()
FreeCADGui.ActiveDocument.resetEdit()
self._restoreVisibility()
return True
def _restoreVisibility(self):
if self._mesh is not None and self._part is not None:
if self._meshVisible:
self._mesh.ViewObject.show()
else:
self._mesh.ViewObject.hide()
if self._partVisible:
self._part.ViewObject.show()
else:
self._part.ViewObject.hide()
def _initParamWidget(self):
self._paramWidget.currentDensityQSB.setProperty(
'value', self._obj.CurrentDensity)
FreeCADGui.ExpressionBinding(
self._paramWidget.currentDensityQSB).bind(self._obj, "CurrentDensity")
self._paramWidget.currentDensityQSB.setProperty(
'value', self._obj.CurrentDensity)
def _applyWidgetChanges(self):
currentdensity = None
try:
currentdensity = self._paramWidget.currentDensityQSB.property('value')
except ValueError:
FreeCAD.Console.PrintMessage(
"Wrong input. Not recognised input: '{}' "
"Current density has not been set.\n"
.format(self._paramWidget.currentDensityQSB.text())
)
if currentdensity is not None:
self._obj.CurrentDensity = currentdensity

View File

@@ -173,6 +173,10 @@ class TestObjectType(unittest.TestCase):
"Fem::ConstraintContact",
type_of_obj(ObjectsFem.makeConstraintContact(doc))
)
self.assertEqual(
"Fem::ConstraintCurrentDensity",
type_of_obj(ObjectsFem.makeConstraintCurrentDensity(doc))
)
self.assertEqual(
"Fem::ConstraintDisplacement",
type_of_obj(ObjectsFem.makeConstraintDisplacement(doc))
@@ -398,6 +402,10 @@ class TestObjectType(unittest.TestCase):
ObjectsFem.makeConstraintContact(doc),
"Fem::ConstraintContact"
))
self.assertTrue(is_of_type(
ObjectsFem.makeConstraintCurrentDensity(doc),
"Fem::ConstraintCurrentDensity"
))
self.assertTrue(is_of_type(
ObjectsFem.makeConstraintDisplacement(doc),
"Fem::ConstraintDisplacement"
@@ -678,18 +686,33 @@ class TestObjectType(unittest.TestCase):
"Fem::ConstraintContact"
))
# ConstraintDisplacement
constraint_dicplacement = ObjectsFem.makeConstraintDisplacement(doc)
# ConstraintCurrentDensity
constraint_currentdensity = ObjectsFem.makeConstraintCurrentDensity(doc)
self.assertTrue(is_derived_from(
constraint_dicplacement,
constraint_currentdensity,
"App::DocumentObject"
))
self.assertTrue(is_derived_from(
constraint_dicplacement,
constraint_currentdensity,
"Fem::ConstraintPython"
))
self.assertTrue(is_derived_from(
constraint_currentdensity,
"Fem::ConstraintCurrentDensity"
))
# ConstraintDisplacement
constraint_displacement = ObjectsFem.makeConstraintDisplacement(doc)
self.assertTrue(is_derived_from(
constraint_displacement,
"App::DocumentObject"
))
self.assertTrue(is_derived_from(
constraint_displacement,
"Fem::Constraint"
))
self.assertTrue(is_derived_from(
constraint_dicplacement,
constraint_displacement,
"Fem::ConstraintDisplacement"
))
@@ -1431,13 +1454,19 @@ class TestObjectType(unittest.TestCase):
)
self.assertTrue(
ObjectsFem.makeConstraintBodyHeatSource(
doc).isDerivedFrom("Fem::ConstraintPython")
doc
).isDerivedFrom("Fem::ConstraintPython")
)
self.assertTrue(
ObjectsFem.makeConstraintContact(
doc
).isDerivedFrom("Fem::ConstraintContact")
)
self.assertTrue(
ObjectsFem.makeConstraintCurrentDensity(
doc
).isDerivedFrom("Fem::ConstraintPython")
)
self.assertTrue(
ObjectsFem.makeConstraintDisplacement(
doc
@@ -1696,6 +1725,7 @@ def create_all_fem_objects_doc(
analysis.addObject(ObjectsFem.makeConstraintBearing(doc))
analysis.addObject(ObjectsFem.makeConstraintBodyHeatSource(doc))
analysis.addObject(ObjectsFem.makeConstraintContact(doc))
analysis.addObject(ObjectsFem.makeConstraintCurrentDensity(doc))
analysis.addObject(ObjectsFem.makeConstraintDisplacement(doc))
analysis.addObject(ObjectsFem.makeConstraintElectrostaticPotential(doc))
analysis.addObject(ObjectsFem.makeConstraintFixed(doc))

View File

@@ -168,6 +168,9 @@ class TestObjectOpen(unittest.TestCase):
self,
doc
):
import ObjectsFem
from femtools.femutils import type_of_obj
# see comments at file end, the code was created by some python code
"""
# see code lines after comment block for the smarter version
@@ -183,6 +186,11 @@ class TestObjectOpen(unittest.TestCase):
doc.ConstraintBodyHeatSource.Proxy.__class__
)
self.assertEqual(
"Fem::ConstraintCurrentDensity",
type_of_obj(ObjectsFem.makeConstraintCurrentDensity(doc))
)
from femobjects.constraint_electrostaticpotential import ConstraintElectrostaticPotential
self.assertEqual(
ConstraintElectrostaticPotential,

View File

@@ -148,6 +148,9 @@ class TestObjectOpen(unittest.TestCase):
self,
doc
):
import ObjectsFem
from femtools.femutils import type_of_obj
# see comments at file end, the code was created by some python code
from femviewprovider.view_constraint_bodyheatsource import VPConstraintBodyHeatSource
@@ -156,6 +159,11 @@ class TestObjectOpen(unittest.TestCase):
doc.ConstraintBodyHeatSource.ViewObject.Proxy.__class__
)
self.assertEqual(
"Fem::ConstraintCurrentDensity",
type_of_obj(ObjectsFem.makeConstraintCurrentDensity(doc))
)
from femviewprovider.view_constraint_electrostaticpotential \
import VPConstraintElectroStaticPotential
self.assertEqual(

View File

@@ -0,0 +1,44 @@
# ***************************************************************************
# * Copyright (c) 2023 Uwe Stöhr <uwestoehr@lyx.org> *
# * *
# * This file is part of the FreeCAD CAx development system. *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * This program 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 Library General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with this program; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * *
# ***************************************************************************
__title__ = "FreeCAD FEM constraint current density ViewProvider for the document object"
__author__ = "Uwe Stöhr"
__url__ = "https://www.freecadweb.org"
## @package view_constraint_currentdensity
# \ingroup FEM
# \brief view provider for the constraint current density object
from femtaskpanels import task_constraint_currentdensity
from . import view_base_femconstraint
class VPConstraintCurrentDensity(view_base_femconstraint.VPBaseFemConstraint):
def setEdit(self, vobj, mode=0):
view_base_femconstraint.VPBaseFemConstraint.setEdit(
self,
vobj,
mode,
task_constraint_currentdensity._TaskPanel
)