Fem: Add electric charge density object

This commit is contained in:
marioalexis
2025-03-27 10:18:16 -03:00
committed by Benjamin Nauck
parent a8372c1f55
commit 10426ca011
15 changed files with 1119 additions and 3 deletions

View File

@@ -180,6 +180,7 @@ SET(FemObjects_SRCS
femobjects/constraint_bodyheatsource.py
femobjects/constraint_centrif.py
femobjects/constraint_currentdensity.py
femobjects/constraint_electricchargedensity.py
femobjects/constraint_electrostaticpotential.py
femobjects/constraint_flowvelocity.py
femobjects/constraint_initialflowvelocity.py
@@ -582,6 +583,7 @@ SET(FemGuiTaskPanels_SRCS
femtaskpanels/task_constraint_bodyheatsource.py
femtaskpanels/task_constraint_centrif.py
femtaskpanels/task_constraint_currentdensity.py
femtaskpanels/task_constraint_electricchargedensity.py
femtaskpanels/task_constraint_electrostaticpotential.py
femtaskpanels/task_constraint_flowvelocity.py
femtaskpanels/task_constraint_initialflowvelocity.py
@@ -627,6 +629,7 @@ SET(FemGuiViewProvider_SRCS
femviewprovider/view_constraint_bodyheatsource.py
femviewprovider/view_constraint_centrif.py
femviewprovider/view_constraint_currentdensity.py
femviewprovider/view_constraint_electricchargedensity.py
femviewprovider/view_constraint_electrostaticpotential.py
femviewprovider/view_constraint_flowvelocity.py
femviewprovider/view_constraint_initialflowvelocity.py

View File

@@ -369,6 +369,7 @@ SET(FemGuiIcon_SVG
SET(FemGuiSymbol_IV
Resources/symbols/ConstraintContact.iv
Resources/symbols/ConstraintDisplacement.iv
Resources/symbols/ConstraintElectricChargeDensity.iv
Resources/symbols/ConstraintElectrostaticPotential.iv
Resources/symbols/ConstraintCurrentDensity.iv
Resources/symbols/ConstraintFixed.iv
@@ -405,6 +406,7 @@ SET(FemGuiPythonUI_SRCS
Resources/ui/ConstraintSectionPrint.ui
Resources/ui/CurrentDensity.ui
Resources/ui/DlgSettingsNetgen.ui
Resources/ui/ElectricChargeDensity.ui
Resources/ui/ElectrostaticPotential.ui
Resources/ui/ElementFluid1D.ui
Resources/ui/ElementGeometry1D.ui

View File

@@ -1416,6 +1416,9 @@ void CmdFemCompEmConstraints::activated(int iMsg)
else if (iMsg == 2) {
rcCmdMgr.runCommandByName("FEM_ConstraintMagnetization");
}
else if (iMsg == 3) {
rcCmdMgr.runCommandByName("FEM_ConstraintElectricChargeDensity");
}
else {
return;
}
@@ -1441,6 +1444,8 @@ Gui::Action* CmdFemCompEmConstraints::createAction()
cmd1->setIcon(Gui::BitmapFactory().iconFromTheme("FEM_ConstraintCurrentDensity"));
QAction* cmd2 = pcAction->addAction(QString());
cmd2->setIcon(Gui::BitmapFactory().iconFromTheme("FEM_ConstraintMagnetization"));
QAction* cmd3 = pcAction->addAction(QString());
cmd3->setIcon(Gui::BitmapFactory().iconFromTheme("FEM_ConstraintElectricChargeDensity"));
_pcAction = pcAction;
languageChange();
@@ -1502,6 +1507,20 @@ void CmdFemCompEmConstraints::languageChange()
cmd2->setStatusTip(QApplication::translate("FEM_ConstraintMagnetization",
ConstraintMagnetization->getStatusTip()));
}
Gui::Command* ConstraintElectricChargeDensity =
rcCmdMgr.getCommandByName("FEM_ConstraintElectricChargeDensity");
if (ConstraintElectricChargeDensity) {
QAction* cmd3 = a[3];
cmd3->setText(QApplication::translate("FEM_ConstraintElectricChargeDensity",
ConstraintElectricChargeDensity->getMenuText()));
cmd3->setToolTip(
QApplication::translate("FEM_ConstraintElectricChargeDensity",
ConstraintElectricChargeDensity->getToolTipText()));
cmd3->setStatusTip(
QApplication::translate("FEM_ConstraintElectricChargeDensity",
ConstraintElectricChargeDensity->getStatusTip()));
}
}
bool CmdFemCompEmConstraints::isActive()

View File

@@ -15,6 +15,7 @@
<file>icons/FEM_ConstraintContact.svg</file>
<file>icons/FEM_ConstraintCurrentDensity.svg</file>
<file>icons/FEM_ConstraintDisplacement.svg</file>
<file>icons/FEM_ConstraintElectricChargeDensity.svg</file>
<file>icons/FEM_ConstraintElectrostaticPotential.svg</file>
<file>icons/FEM_ConstraintFixed.svg</file>
<file>icons/FEM_ConstraintFlowVelocity.svg</file>
@@ -127,6 +128,7 @@
<file>ui/ConstraintTie.ui</file>
<file>ui/CurrentDensity.ui</file>
<file>ui/DlgSettingsNetgen.ui</file>
<file>ui/ElectricChargeDensity.ui</file>
<file>ui/ElectrostaticPotential.ui</file>
<file>ui/ElementFluid1D.ui</file>
<file>ui/ElementGeometry1D.ui</file>

View File

@@ -0,0 +1,430 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
id="svg3052"
height="64px"
width="64px"
sodipodi:docname="FEM_ConstraintElectricChargeDensity.svg"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
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/">
<sodipodi:namedview
id="namedview71"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="4.6182912"
inkscape:cx="24.034864"
inkscape:cy="40.382902"
inkscape:window-width="1920"
inkscape:window-height="1039"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg3052" />
<title
id="title930">FEM_ConstraintElectrostaticPotential</title>
<defs
id="defs3054">
<linearGradient
id="linearGradient3047"
inkscape:swatch="solid">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3045" />
</linearGradient>
<linearGradient
id="linearGradient1007"
inkscape:swatch="solid">
<stop
style="stop-color:#2e3436;stop-opacity:1;"
offset="0"
id="stop1005" />
</linearGradient>
<linearGradient
id="linearGradient1464">
<stop
id="stop1460"
offset="0"
style="stop-color:#ef2929;stop-opacity:1" />
<stop
id="stop1462"
offset="1"
style="stop-color:#a40000;stop-opacity:1" />
</linearGradient>
<linearGradient
id="linearGradient1403">
<stop
id="stop1399"
offset="0"
style="stop-color:#ef2929;stop-opacity:1" />
<stop
id="stop1401"
offset="1"
style="stop-color:#a40000;stop-opacity:1" />
</linearGradient>
<linearGradient
id="linearGradient1267">
<stop
id="stop1263"
offset="0"
style="stop-color:#ef2929;stop-opacity:1" />
<stop
id="stop1265"
offset="1"
style="stop-color:#a40000;stop-opacity:1" />
</linearGradient>
<linearGradient
id="linearGradient876">
<stop
id="stop872"
offset="0"
style="stop-color:#4e9a06;stop-opacity:1" />
<stop
id="stop874"
offset="1"
style="stop-color:#8ae234;stop-opacity:1" />
</linearGradient>
<linearGradient
id="linearGradient4032">
<stop
id="stop4034"
offset="0"
style="stop-color:#71b2f8;stop-opacity:1" />
<stop
id="stop4036"
offset="1"
style="stop-color:#002795;stop-opacity:1" />
</linearGradient>
<radialGradient
gradientTransform="matrix(1.6244669,-0.05136783,0.04345521,0.9993132,-102.99033,7.7040438)"
r="19.467436"
fy="81.869568"
fx="148.88333"
cy="81.869568"
cx="148.88333"
gradientUnits="userSpaceOnUse"
id="radialGradient3705"
xlink:href="#linearGradient3377" />
<linearGradient
id="linearGradient3377">
<stop
style="stop-color:#4bff54;stop-opacity:1"
offset="0"
id="stop3379" />
<stop
style="stop-color:#00b800;stop-opacity:1"
offset="1"
id="stop3381" />
</linearGradient>
<radialGradient
gradientTransform="matrix(0.87904684,0.2250379,-0.41709097,2.0016728,56.73751,-127.99883)"
r="19.467436"
fy="97.369568"
fx="135.38333"
cy="97.369568"
cx="135.38333"
gradientUnits="userSpaceOnUse"
id="radialGradient3703"
xlink:href="#linearGradient3206" />
<linearGradient
id="linearGradient3199">
<stop
style="stop-color:#faff2b;stop-opacity:1"
offset="0"
id="stop3201" />
<stop
style="stop-color:#ffaa00;stop-opacity:1"
offset="1"
id="stop3203" />
</linearGradient>
<radialGradient
gradientUnits="userSpaceOnUse"
r="19.467436"
fy="28.869568"
fx="45.883327"
cy="28.869568"
cx="45.883327"
id="radialGradient3692"
xlink:href="#linearGradient3377" />
<linearGradient
id="linearGradient3206">
<stop
style="stop-color:#faff2b;stop-opacity:1"
offset="0"
id="stop3208" />
<stop
style="stop-color:#ffaa00;stop-opacity:1"
offset="1"
id="stop3210" />
</linearGradient>
<radialGradient
r="19.467436"
fy="81.869568"
fx="148.88333"
cy="81.869568"
cx="148.88333"
gradientTransform="matrix(1.260164,-0.05136783,0.03370995,0.9993132,-43.139781,7.2044077)"
gradientUnits="userSpaceOnUse"
id="radialGradient4030"
xlink:href="#linearGradient4032" />
<linearGradient
id="linearGradient3836-0-6-92-4-6">
<stop
id="stop3838-2-7-06-8-7"
offset="0"
style="stop-color:#a40000;stop-opacity:1" />
<stop
id="stop3840-5-5-8-7-5"
offset="1"
style="stop-color:#ef2929;stop-opacity:1" />
</linearGradient>
<linearGradient
id="linearGradient3836-0-6-92-4-6-5">
<stop
id="stop3838-2-7-06-8-7-3"
offset="0"
style="stop-color:#a40000;stop-opacity:1" />
<stop
id="stop3840-5-5-8-7-5-5"
offset="1"
style="stop-color:#ef2929;stop-opacity:1" />
</linearGradient>
<linearGradient
gradientUnits="userSpaceOnUse"
y2="6.7979431"
x2="74.693367"
y1="43.547943"
x1="95.806496"
id="linearGradient878"
xlink:href="#linearGradient876" />
<linearGradient
y2="57.854782"
x2="33.467113"
y1="46.315926"
x1="27.71979"
gradientUnits="userSpaceOnUse"
id="linearGradient3291-8"
xlink:href="#linearGradient3873" />
<linearGradient
id="linearGradient3873">
<stop
style="stop-color:#729fcf;stop-opacity:1"
offset="0"
id="stop3875" />
<stop
style="stop-color:#204a87;stop-opacity:1"
offset="1"
id="stop3877" />
</linearGradient>
<linearGradient
gradientTransform="matrix(1.4482473,0,0,1.4426984,3.8621569,-43.045828)"
y2="57.854782"
x2="33.467113"
y1="46.315926"
x1="27.71979"
gradientUnits="userSpaceOnUse"
id="linearGradient1084"
xlink:href="#linearGradient3873" />
<linearGradient
gradientTransform="matrix(0.86997005,0,0,0.86663677,-38.085519,-77.218368)"
xlink:href="#linearGradient1267"
id="linearGradient1084-6"
gradientUnits="userSpaceOnUse"
x1="27.71979"
y1="46.315926"
x2="33.467113"
y2="57.854782" />
<linearGradient
gradientTransform="matrix(1.2926501,0,0,1.2876974,-21.92397,-34.99464)"
xlink:href="#linearGradient1403"
id="linearGradient1084-2"
gradientUnits="userSpaceOnUse"
x1="27.71979"
y1="46.315926"
x2="33.467113"
y2="57.854782" />
<linearGradient
xlink:href="#linearGradient1464"
id="linearGradient1084-9"
gradientUnits="userSpaceOnUse"
x1="27.71979"
y1="46.315926"
x2="33.467113"
y2="57.854782"
gradientTransform="matrix(1.4482473,0,0,1.4426984,-26.818279,-43.080958)" />
</defs>
<metadata
id="metadata3057">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>FEM_ConstraintElectrostaticPotential</dc:title>
<dc:creator>
<cc:Agent>
<dc:title>[bitacovir]</dc:title>
</cc:Agent>
</dc:creator>
<dc:title>PartDesign_MoveTip</dc:title>
<dc:date>12-02-2021</dc:date>
<dc:relation>https://www.freecad.org/wiki/index.php?title=Artwork</dc:relation>
<dc:publisher>
<cc:Agent>
<dc:title>FreeCAD</dc:title>
</cc:Agent>
</dc:publisher>
<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 />
</cc:Agent>
</dc:contributor>
<dc:subject>
<rdf:Bag />
</dc:subject>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1">
<path
style="display:none;fill:none;stroke:#280000;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 11.959992,29.955113 c 0.63218,19.246015 7.322788,28.869818 19.975766,29.023977"
id="path1147-0-0-6" />
<path
id="path1147-7-21-8-4"
d="m 11.959992,29.955114 c 0.63218,19.246014 7.322788,28.869817 19.975766,29.023976"
style="display:none;fill:none;stroke:#ef2929;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path1147-0-2"
d="M 11.957052,34.012155 C 12.589232,14.76614 19.27984,5.142337 31.932818,4.988178"
style="display:none;fill:none;stroke:#280000;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="display:none;fill:none;stroke:#ef2929;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 11.957052,34.012154 C 12.589232,14.76614 19.27984,5.142337 31.932818,4.988178"
id="path1147-7-21-1" />
<path
id="path1147-0-0"
d="M 51.905644,29.955113 C 51.273464,49.201128 44.582856,58.824931 31.929878,58.97909"
style="display:none;fill:none;stroke:#0b1521;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="display:none;fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 51.905644,29.955114 C 51.273464,49.201128 44.582856,58.824931 31.929878,58.97909"
id="path1147-7-21-8" />
<path
style="display:none;fill:none;stroke:#0b1521;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 51.908584,34.012155 C 51.276404,14.76614 44.585796,5.142337 31.932818,4.988178"
id="path1147-0" />
<path
id="path1147-7-21"
d="M 51.908584,34.012154 C 51.276404,14.76614 44.585796,5.142337 31.932818,4.988178"
style="display:none;fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<circle
r="11.652966"
id="path3024-39-1-4-4"
style="fill:none;stroke:#0b1521;stroke-width:6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dasharray:none;stroke-dashoffset:20.4;stroke-opacity:1"
cx="47.336685"
cy="32.09763" />
<circle
id="path3024-3-54-9-4-6"
style="fill:url(#linearGradient1084);fill-opacity:1;stroke:#729fcf;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dasharray:none;stroke-dashoffset:20.4;stroke-opacity:1"
cx="47.336685"
cy="32.09763"
r="11.652966" />
<path
id="path1362"
d="M 55.662124,32.083027 H 38.853773"
style="fill:none;stroke:#ffffff;stroke-width:4.48148;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<circle
cy="32.0625"
cx="16.65625"
style="fill:none;stroke:#280000;stroke-width:6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dasharray:none;stroke-dashoffset:20.4;stroke-opacity:1"
id="path3024-39-1-4-4-97"
r="11.652966" />
<circle
cy="32.0625"
cx="16.65625"
style="fill:url(#linearGradient1084-9);fill-opacity:1;stroke:#ef2929;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.5;stroke-dasharray:none;stroke-dashoffset:20.4;stroke-opacity:1"
id="path3024-3-54-9-4-6-08"
r="11.652966" />
<path
style="fill:none;stroke:#ffffff;stroke-width:4.48148;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 24.981688,32.047897 H 8.1733378"
id="path1362-1" />
<path
id="path1362-1-4"
d="m 16.6875,23.689575 v 16.80835"
style="fill:none;stroke:#ffffff;stroke-width:4.48148;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<path
id="path32"
style="color:#000000;display:inline;fill:#eeeeec;stroke:#2e3436;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;paint-order:normal;stroke-opacity:1;fill-opacity:1;stroke-dashoffset:0"
d="m 22.821522,18.583876 c 4.136192,-4.926446 9.357899,-8.55819 15.02902,-4.234325 l -2.170965,2.395604 8.041282,1.098848 -1.136018,-7.9743113 -2.11852,2.1974053 C 34.84843,7.4562876 27.697773,7.5276756 19.278502,17.42179 Z"
sodipodi:nodetypes="cccccccc" />
<path
id="path32-7"
style="color:#000000;display:inline;fill:#eeeeec;fill-opacity:1;stroke:#2e3436;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
d="M 11.205215,18.494929 C 11.15016,12.71645 7.4424904,11.966311 6.5744873,11.412565 L 4.9796834,14.22479 1.4167534,6.9326563 9.3454901,5.5130512 7.9224732,8.2133732 C 11.660494,10.326403 14.204236,12.732592 14.46443,17.506567 Z"
sodipodi:nodetypes="cccccccc" />
<path
id="path32-7-2"
style="color:#000000;display:inline;fill:#eeeeec;fill-opacity:1;stroke:#2e3436;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
d="m 11.201182,45.496256 c -0.05506,5.778479 -3.7586922,6.621931 -4.6266952,7.175677 l -1.594804,-2.812225 -3.56293,7.292134 7.928737,1.419605 -1.423017,-2.700322 c 3.7380212,-2.11303 6.2817632,-4.519219 6.5419572,-9.293194 z"
sodipodi:nodetypes="cccccccc" />
<path
id="path32-7-6"
style="color:#000000;display:inline;fill:#eeeeec;fill-opacity:1;stroke:#2e3436;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
d="m 62.457538,8.8598078 c -5.150104,0.619191 -6.053281,3.1068772 -6.58859,4.2598362 l 2.67724,1.812291 -7.551155,2.974854 -0.787883,-8.0161948 2.579278,1.6321888 c 1.625553,-3.4019779 5.218277,-5.5146755 9.10389,-5.608676 z"
sodipodi:nodetypes="cccccccc" />
<path
id="path32-7-6-9"
style="color:#000000;display:inline;fill:#eeeeec;fill-opacity:1;stroke:#2e3436;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
d="m 62.457538,55.34996 c -5.150104,-0.619191 -6.053281,-3.106877 -6.58859,-4.259836 l 2.67724,-1.812291 -7.551155,-2.974854 -0.787883,8.016195 2.579278,-1.632189 c 1.625553,3.401978 5.218277,5.514676 9.10389,5.608676 z"
sodipodi:nodetypes="cccccccc" />
<path
id="path32-5"
style="color:#000000;display:inline;fill:#eeeeec;fill-opacity:1;stroke:#2e3436;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
d="m 22.821522,45.690992 c 4.136192,4.926446 9.357899,8.55819 15.02902,4.234325 l -2.170965,-2.395604 8.041282,-1.098848 -1.136018,7.974311 -2.11852,-2.197405 C 34.84843,56.81858 27.697773,56.747192 19.278502,46.853078 Z"
sodipodi:nodetypes="cccccccc" />
<path
id="path32-62"
style="color:#000000;display:none;fill:#eeeeec;stroke:#2e3436;stroke-width:0.770751;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;paint-order:normal"
d="m 22.08608,45.945675 c 3.669227,5.201991 10.73504,9.911628 16.311009,4.335658 l -1.1097,-1.310292 6.479752,-2.660806 -2.125302,6.674593 -1.589474,-1.465125 c -5.617891,4.610809 -11.400241,4.890544 -19.819512,-5.003571 z" />
<path
id="path32-62-7"
style="color:#000000;display:none;fill:#eeeeec;stroke:#2e3436;stroke-width:0.770751;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;paint-order:normal"
d="M 62.408339,58.041868 C 58.632857,55.31634 57.160914,53.722937 55.721521,51.292636 l 1.373749,-1.030104 -5.724018,-4.03766 0.584725,6.980344 1.87596,-1.074148 c 2.138285,2.867756 3.129007,4.157809 7.289159,7.182083 z" />
<path
id="path32-62-7-9"
style="color:#000000;display:none;fill:#eeeeec;stroke:#2e3436;stroke-width:0.770751;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;paint-order:normal"
d="M 13.050374,17.986026 C 10.571556,14.058886 8.7296825,12.498175 6.364712,11.368247 l -1.030104,1.373748 -4.03766,-5.7240169 6.980344,0.584725 -1.074148,1.87596 c 3.081377,2.1908629 4.893384,3.6521729 7.746645,8.2749139 z" />
<path
id="path32-62-7-9-6"
style="color:#000000;display:none;fill:#eeeeec;stroke:#2e3436;stroke-width:0.770751;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;paint-order:normal"
d="m 13.050374,46.536665 c -2.478818,3.92714 -4.3206917,5.487851 -6.6856617,6.617779 l -1.030104,-1.373748 -4.0376597,5.724017 6.9803437,-0.584725 -1.074148,-1.87596 c 3.0813767,-2.190863 4.8933837,-3.652173 7.7466447,-8.274914 z" />
<path
id="path32-62-7-3"
style="color:#000000;display:none;fill:#eeeeec;stroke:#2e3436;stroke-width:0.770751;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;paint-order:normal"
d="M 62.444196,6.1690684 C 58.668714,8.8945964 57.196771,10.487999 55.757378,12.9183 l 1.373749,1.030104 -5.724018,4.03766 0.584725,-6.980344 1.87596,1.074148 c 2.138285,-2.8677561 3.129007,-4.1578086 7.289159,-7.1820826 z" />
</svg>

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -0,0 +1,74 @@
#Inventor V2.1 ascii
# SPDX-License-Identifier: LGPL-2.1-or-later
#/***************************************************************************
# * Copyright (c) 2025 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
# * *
# * This file is part of FreeCAD. *
# * *
# * FreeCAD is free software: you can redistribute it and/or modify it *
# * under the terms of the GNU Lesser General Public License as *
# * published by the Free Software Foundation, either version 2.1 of the *
# * License, or (at your option) any later version. *
# * *
# * FreeCAD is distributed in the hope that it will be useful, but *
# * WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
# * Lesser General Public License for more details. *
# * *
# * You should have received a copy of the GNU Lesser General Public *
# * License along with FreeCAD. If not, see *
# * <https://www.gnu.org/licenses/>. *
# * *
# **************************************************************************
Separator {
Separator {
Translation {
translation 0 0.5 0
}
Sphere {
radius 0.5
}
Translation {
translation 0 2.0 0
}
BaseColor {
rgb 0.17 0.46 1.0
}
Sphere {
radius 0.5
}
Translation {
translation 0 -1.375 0
}
BaseColor {
rgb 1 1 1
}
Cylinder {
radius 0.1
height 0.75
}
Translation {
translation 0 .625 0
}
Cone {
bottomRadius 0.25
height 0.5
}
}
}

View File

@@ -0,0 +1,187 @@
<?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>Analysis feature properties</string>
</property>
<layout class="QVBoxLayout" name="horizontalLayout">
<item>
<widget class="QGroupBox" name="gpb_electric_charge_density">
<layout class="QVBoxLayout" name="vlt_Layout">
<item>
<layout class="QFormLayout" name="flt_electric_charge_density">
<item row="0" column="0">
<widget class="QLabel" name="lbl_mode">
<property name="text">
<string>Mode:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="cb_mode"/>
</item>
</layout>
</item>
<item>
<widget class="QStackedWidget" name="sw_mode">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="page_0">
<layout class="QVBoxLayout" name="verticalLayout_0">
<item>
<layout class="QFormLayout" name="formLayout_0">
<property name="toolTip">
<string>Free surface charge density</string>
</property>
<item row="0" column="0">
<widget class="QLabel" name="lbl_interface_charge_density">
<property name="text">
<string>Density:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::QuantitySpinBox" name="qsb_interface_charge_density">
<property name="enabled">
<bool>true</bool>
</property>
<property name="unit" stdset="0">
<string notr="true">C/mm^2</string>
</property>
<property name="alignment">
<set>Qt::AlignLeft|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="keyboardTracking">
<bool>true</bool>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<property name="currentIndex">
<number>1</number>
</property>
<widget class="QWidget" name="page_1">
<layout class="QVBoxLayout" name="verticalLayout_1">
<item>
<layout class="QFormLayout" name="formLayout_1">
<property name="toolTip">
<string>Free volume charge density</string>
</property>
<item row="0" column="0">
<widget class="QLabel" name="lbl_source_charge_density">
<property name="text">
<string>Density:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::QuantitySpinBox" name="qsb_source_charge_density">
<property name="enabled">
<bool>true</bool>
</property>
<property name="unit" stdset="0">
<string notr="true">C/mm^3</string>
</property>
<property name="alignment">
<set>Qt::AlignLeft|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="keyboardTracking">
<bool>true</bool>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<property name="currentIndex">
<number>2</number>
</property>
<widget class="QWidget" name="page_2">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QFormLayout" name="formLayout_2">
<property name="toolTip">
<string>Free total charge</string>
</property>
<item row="0" column="0">
<widget class="QLabel" name="lbl_total_charge">
<property name="text">
<string>Total Charge:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Gui::QuantitySpinBox" name="qsb_total_charge">
<property name="enabled">
<bool>true</bool>
</property>
<property name="unit" stdset="0">
<string notr="true">C</string>
</property>
<property name="alignment">
<set>Qt::AlignLeft|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="keyboardTracking">
<bool>true</bool>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</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

@@ -246,7 +246,8 @@ Gui::MenuItem* Workbench::setupMenuBar() const
elec->setCommand("&Electromagnetic boundary conditions");
*elec << "FEM_ConstraintElectrostaticPotential"
<< "FEM_ConstraintCurrentDensity"
<< "FEM_ConstraintMagnetization";
<< "FEM_ConstraintMagnetization"
<< "FEM_ConstraintElectricChargeDensity";
Gui::MenuItem* fluid = new Gui::MenuItem;
fluid->setCommand("&Fluid boundary conditions");

View File

@@ -132,6 +132,20 @@ def makeConstraintDisplacement(doc, name="ConstraintDisplacement"):
return obj
def makeConstraintElectricChargeDensity(doc, name="ElectricChargeDensity"):
"""makeConstraintElectricChargeDensity(document, [name]):
makes a Fem ElectricChargeDensity object"""
obj = doc.addObject("Fem::ConstraintPython", name)
from femobjects import constraint_electricchargedensity
constraint_electricchargedensity.ConstraintElectricChargeDensity(obj)
if FreeCAD.GuiUp:
from femviewprovider import view_constraint_electricchargedensity
view_constraint_electricchargedensity.VPConstraintElectricChargeDensity(obj.ViewObject)
return obj
def makeConstraintElectrostaticPotential(doc, name="ConstraintElectrostaticPotential"):
"""makeConstraintElectrostaticPotential(document, [name]):
makes a Fem ElectrostaticPotential object"""

View File

@@ -221,6 +221,22 @@ class _ConstraintCurrentDensity(CommandManager):
self.do_activated = "add_obj_on_gui_set_edit"
class _ConstraintElectricChargeDensity(CommandManager):
"The FEM_ConstraintElectricChargeDensity command definition"
def __init__(self):
super().__init__()
self.pixmap = "FEM_ConstraintElectricChargeDensity"
self.menutext = Qt.QT_TRANSLATE_NOOP(
"FEM_ConstraintElectricChargeDensity", "Electric charge density"
)
self.tooltip = Qt.QT_TRANSLATE_NOOP(
"FEM_ConstraintElectricChargeDensity", "Creates a electric charge density"
)
self.is_active = "with_analysis"
self.do_activated = "add_obj_on_gui_set_edit"
class _ConstraintElectrostaticPotential(CommandManager):
"The FEM_ConstraintElectrostaticPotential command definition"
@@ -1171,6 +1187,7 @@ FreeCADGui.addCommand("FEM_ConstantVacuumPermittivity", _ConstantVacuumPermittiv
FreeCADGui.addCommand("FEM_ConstraintBodyHeatSource", _ConstraintBodyHeatSource())
FreeCADGui.addCommand("FEM_ConstraintCentrif", _ConstraintCentrif())
FreeCADGui.addCommand("FEM_ConstraintCurrentDensity", _ConstraintCurrentDensity())
FreeCADGui.addCommand("FEM_ConstraintElectricChargeDensity", _ConstraintElectricChargeDensity())
FreeCADGui.addCommand("FEM_ConstraintElectrostaticPotential", _ConstraintElectrostaticPotential())
FreeCADGui.addCommand("FEM_ConstraintFlowVelocity", _ConstraintFlowVelocity())
FreeCADGui.addCommand("FEM_ConstraintInitialFlowVelocity", _ConstraintInitialFlowVelocity())

View File

@@ -0,0 +1,87 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# ***************************************************************************
# * Copyright (c) 2025 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
# * *
# * This file is part of FreeCAD. *
# * *
# * FreeCAD is free software: you can redistribute it and/or modify it *
# * under the terms of the GNU Lesser General Public License as *
# * published by the Free Software Foundation, either version 2.1 of the *
# * License, or (at your option) any later version. *
# * *
# * FreeCAD is distributed in the hope that it will be useful, but *
# * WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
# * Lesser General Public License for more details. *
# * *
# * You should have received a copy of the GNU Lesser General Public *
# * License along with FreeCAD. If not, see *
# * <https://www.gnu.org/licenses/>. *
# * *
# ***************************************************************************
__title__ = "FreeCAD FEM constraint electric charge density document object"
__author__ = "Mario Passaglia"
__url__ = "https://www.freecad.org"
## @package constraint_electricchargedensity
# \ingroup FEM
# \brief constraint electric charge density object
from . import base_fempythonobject
_PropHelper = base_fempythonobject._PropHelper
class ConstraintElectricChargeDensity(base_fempythonobject.BaseFemPythonObject):
Type = "Fem::ConstraintElectricChargeDensity"
def __init__(self, obj):
super().__init__(obj)
for prop in self._get_properties():
prop.add_to_object(obj)
def _get_properties(self):
prop = []
prop.append(
_PropHelper(
type="App::PropertyVolumeChargeDensity",
name="SourceChargeDensity",
group="Electric Charge Density",
doc="Free electric charge per unit volume at the sources",
value="0 C/mm^3",
)
)
prop.append(
_PropHelper(
type="App::PropertySurfaceChargeDensity",
name="InterfaceChargeDensity",
group="Electric Charge Density",
doc="Free electric charge per unit surface at the boundaries",
value="0 C/mm^2",
)
)
prop.append(
_PropHelper(
type="App::PropertyElectricCharge",
name="TotalCharge",
group="Electric Charge Density",
doc="Total free electric charge",
value="0 C",
)
)
prop.append(
_PropHelper(
type="App::PropertyEnumeration",
name="Mode",
group="Electric Charge Density",
doc="Switch quantity input mode",
value=["Interface", "Source", "Total Interface", "Total Source"],
)
)
return prop

View File

@@ -30,6 +30,8 @@ __url__ = "https://www.freecad.org"
## \addtogroup FEM
# @{
from FreeCAD import Units
from .. import sifio
@@ -133,8 +135,8 @@ class ESwriter:
elif obj.BoundaryCondition == "Neumann":
self.write.boundary(
name,
"Surface Charge Density",
obj.SurfaceChargeDensity.getValueAs("C/m^2").Value,
"Electric Flux",
obj.ElectricFluxDensity.getValueAs("C/m^2").Value,
)
if obj.PotentialConstant:
self.write.boundary(name, "Potential Constant", True)
@@ -146,5 +148,60 @@ class ESwriter:
self.write.boundary(name, "Capacitance Body", obj.CapacitanceBody)
self.write.handled(obj)
for obj in self.write.getMember("Fem::ConstraintElectricChargeDensity"):
if obj.Mode not in ["Interface", "Total Interface"]:
continue
size = 0
items = []
for feat, sub_elem in obj.References:
for name in sub_elem:
sub = feat.getSubObject(name)
if sub.ShapeType == "Face":
size += sub.Area
items.append(name)
elif sub.ShapeType == "Edge":
size += sub.Length
items.append(name)
if items:
if obj.Mode == "Interface":
density = obj.InterfaceChargeDensity.getValueAs("C/m^2").Value
elif obj.Mode == "Total Interface":
area = Units.Quantity(f"{size} mm^2")
density = (obj.TotalCharge / area).getValueAs("C/m^2").Value
for name in items:
self.write.boundary(name, "! FreeCAD Name", obj.Label)
self.write.boundary(name, "Surface Charge Density", round(density, 6))
self.write.handled(obj)
def handleElectrostaticBodyForces(self):
for obj in self.write.getMember("Fem::ConstraintElectricChargeDensity"):
if obj.Mode not in ["Source", "Total Source"]:
continue
size = 0
items = []
for feat, sub_elem in obj.References:
for name in sub_elem:
sub = feat.getSubObject(name)
if sub.ShapeType == "Solid":
size += sub.Volume
items.append(name)
elif sub.ShapeType == "Face":
size += sub.Area
items.append(name)
if items:
if obj.Mode == "Source":
density = obj.SourceChargeDensity.getValueAs("C/m^3").Value
elif obj.Mode == "Total Source":
vol = Units.Quantity(f"{size} mm^3")
density = (obj.TotalCharge / vol).getValueAs("C/m^3").Value
for name in items:
self.write.bodyForce(name, "! FreeCAD Name", obj.Label)
self.write.bodyForce(name, "Charge Density", round(density, 6))
self.write.handled(obj)
## @}

View File

@@ -471,6 +471,7 @@ class Writer:
if activeIn:
ESW.handleElectrostaticConstants()
ESW.handleElectrostaticBndConditions()
ESW.handleElectrostaticBodyForces()
ESW.handleElectrostaticMaterial(activeIn)
# -------------------------------------------------------------------------------------------

View File

@@ -0,0 +1,171 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# ***************************************************************************
# * Copyright (c) 2025 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
# * *
# * This file is part of FreeCAD. *
# * *
# * FreeCAD is free software: you can redistribute it and/or modify it *
# * under the terms of the GNU Lesser General Public License as *
# * published by the Free Software Foundation, either version 2.1 of the *
# * License, or (at your option) any later version. *
# * *
# * FreeCAD is distributed in the hope that it will be useful, but *
# * WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
# * Lesser General Public License for more details. *
# * *
# * You should have received a copy of the GNU Lesser General Public *
# * License along with FreeCAD. If not, see *
# * <https://www.gnu.org/licenses/>. *
# * *
# ***************************************************************************
__title__ = "FreeCAD FEM constraint electric charge density task panel"
__author__ = "Mario Passaglia"
__url__ = "https://www.freecad.org"
## @package task_constraint_electricchargedensity
# \ingroup FEM
# \brief task panel for constraint electric charge density object
from PySide import QtCore
import FreeCAD
import FreeCADGui
from femguiutils import selection_widgets
from femtools import membertools
from . import base_femtaskpanel
class _TaskPanel(base_femtaskpanel._BaseTaskPanel):
def __init__(self, obj):
super().__init__(obj)
self.parameter_widget = FreeCADGui.PySideUic.loadUi(
FreeCAD.getHomePath() + "Mod/Fem/Resources/ui/ElectricChargeDensity.ui"
)
self.init_parameter_widget()
QtCore.QObject.connect(
self.parameter_widget.qsb_source_charge_density,
QtCore.SIGNAL("valueChanged(Base::Quantity)"),
self.source_charge_density_changed,
)
QtCore.QObject.connect(
self.parameter_widget.qsb_interface_charge_density,
QtCore.SIGNAL("valueChanged(Base::Quantity)"),
self.interface_charge_density_changed,
)
QtCore.QObject.connect(
self.parameter_widget.qsb_total_charge,
QtCore.SIGNAL("valueChanged(Base::Quantity)"),
self.total_charge_changed,
)
QtCore.QObject.connect(
self.parameter_widget.cb_mode,
QtCore.SIGNAL("currentIndexChanged(int)"),
self.mode_changed,
)
# geometry selection widget
# start with Solid in list!
self.selection_widget = selection_widgets.GeometryElementsSelection(
obj.References, ["Solid", "Face", "Edge"], False, False
)
# form made from param and selection widget
self.form = [self.parameter_widget, self.selection_widget]
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 = self._mesh.Shape
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.restore_visibility()
self.selection_widget.finish_selection()
return super().reject()
def accept(self):
self.obj.References = self.selection_widget.references
self.obj.SourceChargeDensity = self.source_charge_density
self.obj.InterfaceChargeDensity = self.interface_charge_density
self.obj.TotalCharge = self.total_charge
self.obj.Mode = self.mode
self.selection_widget.finish_selection()
self.restore_visibility()
return super().accept()
def restore_visibility(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 init_parameter_widget(self):
self.source_charge_density = self.obj.SourceChargeDensity
self.interface_charge_density = self.obj.InterfaceChargeDensity
self.total_charge = self.obj.TotalCharge
FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_source_charge_density).bind(
self.obj, "SourceChargeDensity"
)
self.parameter_widget.qsb_source_charge_density.setProperty(
"value", self.source_charge_density
)
FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_interface_charge_density).bind(
self.obj, "InterfaceChargeDensity"
)
self.parameter_widget.qsb_interface_charge_density.setProperty(
"value", self.interface_charge_density
)
FreeCADGui.ExpressionBinding(self.parameter_widget.qsb_total_charge).bind(
self.obj, "TotalCharge"
)
self.parameter_widget.qsb_total_charge.setProperty("value", self.total_charge)
self.mode = self.obj.Mode
self.mode_enum = self.obj.getEnumerationsOfProperty("Mode")
self.parameter_widget.cb_mode.addItems(self.mode_enum)
index = self.mode_enum.index(self.mode)
self.parameter_widget.cb_mode.setCurrentIndex(index)
self.mode_changed(index)
def source_charge_density_changed(self, base_quantity_value):
self.source_charge_density = base_quantity_value
def interface_charge_density_changed(self, base_quantity_value):
self.interface_charge_density = base_quantity_value
def total_charge_changed(self, base_quantity_value):
self.total_charge = base_quantity_value
def mode_changed(self, index):
self.mode = self.mode_enum[index]
if self.mode in ["Total Interface", "Total Source"]:
index = 2
self.parameter_widget.sw_mode.setCurrentIndex(index)

View File

@@ -0,0 +1,51 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# ***************************************************************************
# * Copyright (c) 2025 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
# * *
# * This file is part of FreeCAD. *
# * *
# * FreeCAD is free software: you can redistribute it and/or modify it *
# * under the terms of the GNU Lesser General Public License as *
# * published by the Free Software Foundation, either version 2.1 of the *
# * License, or (at your option) any later version. *
# * *
# * FreeCAD is distributed in the hope that it will be useful, but *
# * WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
# * Lesser General Public License for more details. *
# * *
# * You should have received a copy of the GNU Lesser General Public *
# * License along with FreeCAD. If not, see *
# * <https://www.gnu.org/licenses/>. *
# * *
# ***************************************************************************
__title__ = "FreeCAD FEM constraint electric charge view provider"
__author__ = "Mario Passaglia"
__url__ = "https://www.freecad.org"
## @package view_constraint_electricchargedensity
# \ingroup FEM
# \brief view provider for the constraint electric charge density object
from femtaskpanels import task_constraint_electricchargedensity
from . import view_base_femconstraint
class VPConstraintElectricChargeDensity(view_base_femconstraint.VPBaseFemConstraint):
def __init__(self, vobj):
super().__init__(vobj)
mat = vobj.ShapeAppearance[0]
mat.DiffuseColor = (1.0, 0.0, 0.2, 0.0)
vobj.ShapeAppearance = mat
def setEdit(self, vobj, mode=0):
return view_base_femconstraint.VPBaseFemConstraint.setEdit(
self, vobj, mode, task_constraint_electricchargedensity._TaskPanel
)
def attach(self, vobj):
super().attach(vobj)
vobj.loadSymbol(self.resource_symbol_dir + "ConstraintElectricChargeDensity.iv")