Tutorium FEM Gleichung hinzufügen

From FreeCAD Documentation
Revision as of 06:41, 22 October 2020 by Maker (talk | contribs) (Created page with "In diesem Schritt werden wir die folgenden Dateien modifizieren:")
Tutorium
Thema
FEM Gleichung hinzufügen
Niveau
Zeit zum Abschluss
Autoren
M42kus
FreeCAD-Version
Beispieldateien
Siehe auch
None

In diesem Tutorium werden wir die Fließgeschwindigkeit zu FreeCAD hinzufügen und die Unterstützung für den Elmer Löser einführen. Bitte stelle sicher, dass du Extend FEM Module gelesen und verstanden hast, bevor du dieses Tutorium liest.

Die Aufgabe kann in vier Teile aufgeteilt werden. Der erste Schritt besteht darin, den FEM Arbeitsbereich auf einen neuen Gleichungstyp aufmerksam zu machen. Dieser Schritt muss nur durchgeführt werden, wenn die Gleichung in FreeCAD jetzt nicht existiert (im Gegensatz zu einer Gleichung, die bereits in FreeCAD existiert, aber vom Ziellöser nicht unterstützt wird). Der zweite Schritt besteht darin, ein konkretes Dokumentobjekt hinzuzufügen, das die Elmer spezifische Gleichung repräsentiert. Der dritte Schritt besteht darin, dem Löserobjekt von elmer Unterstützung für die neue Gleichung hinzuzufügen. Danach muss der Analyseexport von elmer erweitert werden, um den neuen Gleichungstyp zu unterstützen.

Neuer Gleichungstyp

In diesem Schritt werden wir die folgenden Dateien modifizieren:

  • src/Mod/Fem/femsolver/equationbase.py
  • src/Mod/Fem/femcommands/commands.py
  • src/Mod/Fem/Gui/Workbench.cpp
  • src/Mod/Fem/Gui/Resources/Fem.qrc

The equation type is shared among all equation objects of the different solver. Each type has a string specifier (e.g. "Heat") and a dedicated command that adds the equation to the selected solver. This allows for a simpler GUI where we have only one button for the heat equation which is used for all supported solver.

First add the new equation to the equationbase.py module. Each equation requires two classes. A document proxy and a view proxy. Just copy-paste them from an existing equation type and adjust the icon path inside getIcon(self) of the view proxy.

class FlowProxy(BaseProxy):
    pass

class FlowViewProxy(BaseViewProxy):
    def getIcon(self):
        return ":/icons/FEM_EquationFlow.svg"

Those two classes will later be used as base classes for the Elmer specific equation classes. In addition to those base classes we have to create a new command class that adds a flow equation to the selected solver object. Additionally, the new .svg image has to be registered for the GUI-button with <file>icons/FEM_EquationFlow.svg</file> in Fem.qrc (in /Gui/Resources/). The related .svg has to be put into /Gui/Resources/icons/.

Next, the command/equation has to be added to the femcommands/commands.py module. Just copy an existing command and adjust the icon, menu text and tool-tip in __init__(self). Don't forget to register the command at the bottom of the module file by using the addCommand(...) method. Please see the discussion in the forum at https://forum.freecadweb.org/viewtopic.php?f=18&t=46693&start=10#p402004 if icons are involed.

class _EquationFlow(CommandManager):
    "The FEM_EquationFlow command definition"

    def __init__(self):
        super(_EquationFlow, self).__init__()
        self.menuetext = "Flow equation"
        self.tooltip = "Creates a FEM equation for flow"
        self.is_active = "with_solver_elmer"
        self.do_activated = "add_obj_on_gui_selobj_noset_edit"
...
FreeCADGui.addCommand(
    "FEM_EquationFlow",
    _EquationFlow()
)


Our newly created command still needs to be made accessible via the GUI of the FEM workbench. To add it to the toolbar search for the following code snippet in /Gui/Workbench.cpp and add the new command to the rest of the equation commands.

 
     Gui::ToolBarItem* solve = new Gui::ToolBarItem(root);
     solve->setCommand("Solve");
     *solve << "FEM_SolverCalculixCxxtools"
           << "FEM_SolverCalculiX"
           << "FEM_SolverElmer"
           << "Separator"
           << "FEM_EquationElasticity"
           << "FEM_EquationElectrostatic"
+          << "FEM_EquationFlow"
           << "FEM_EquationFluxsolver"
           << "FEM_EquationElectricforce"
           << "FEM_EquationHeat"
           << "Separator"
           << "FEM_SolverControl"
           << "FEM_SolverRun";

We are also going to add the flow equation command to the solve menu of the FEM workbench. To do this insert our equation into the following code snippet in Workbench.cpp.

 
    Gui::MenuItem* solve = new Gui::MenuItem;
    root->insertItem(item, solve);
    solve->setCommand("&Solve");
    *solve << "FEM_SolverCalculixCxxtools"
           << "FEM_SolverCalculiX"
           << "FEM_SolverElmer"
           << "FEM_SolverZ88"
           << "Separator"
           << "FEM_EquationElasticity"
           << "FEM_EquationElectrostatic"
+          << "FEM_EquationFlow"
           << "FEM_EquationFluxsolver"
           << "FEM_EquationElectricforce"
           << "FEM_EquationHeat"
           << "Separator"
           << "FEM_SolverControl"
           << "FEM_SolverRun";


Elmers Gleichungs Objekt

In diesem Schritt werden wir die folgenden Dateien modifizieren:

  • src/Mod/Fem/CMakeLists.txt

und die folgende neue Datei hinzufügen:

  • src/Mod/Fem/femsolver/elmer/equations/flow.py

Lets start with the module that implements the document object. In can be copied from an existing equation. If the new equation only supports keywords for linear systems copy the femsolver/elmer/equations/elasticity.py module. If it supports non-linear keywords too copy femsolver/elmer/equations/heat.py. The flow equation in Elmer is a potentially non-linear equation. This means that we are going to base our work on heat.py.

After copying heat.py to flow.py adjust - the name argument of the create module function, - the Type attribute of the Proxy class, - the base classes of the Proxy and the ViewProxy classes, - and the properties added via the obj.addProperty(..) function to those needed by the equation.

def create(doc, name="Flow"):
    return femutils.createObject(
        doc, name, Proxy, ViewProxy)


class Proxy(nonlinear.Proxy, equationbase.FlowProxy):

    Type = "Fem::EquationElmerFlow"

    def __init__(self, obj):
        super(Proxy, self).__init__(obj)
        obj.Priority = 10


class ViewProxy(nonlinear.ViewProxy, equationbase.FlowViewProxy):
    pass

At the moment of writing this tutorial Elmer flow equation doesn't have any special properties. See Elmer elasticity equation for an example with properties.

Last but not least register the new module file (flow.py) in src/Mod/Fem/CMakeLists.txt the way described in Extend FEM Module. The suitable lists can be easily found by searching for existing equation modules files of Elmer.

Finally one hast to register a makeEquationStatcurrent definition in ObjectsFem.py by duplicating an available entry.


Löser Objekt erweitern

In diesem Schritt werden wir die folgenden Dateien modifizieren:

  • src/Mod/Fem/femsolver/elmer/solver.py

Right now we made FreeCAD aware that there is a new type of equation and even added a command that adds this equation to the selected solver object. We also implemented a concrete equation object for Elmer. Whats left to do now it to make the connection between Elmer and the flow equation. This must be done directly in Elmer solver object.

Register the module in which we just implemented our new equation object (flow.py) with the equation specifier from step 1 ("Flow") in the _EQUATIONS list in elmer/solver.py.

from .equations import electrostatic
+from .equations import flow

...

_EQUATIONS = {
    "Heat": heat,
    "Elasticity": elasticity,
+    "Flow": flow,
}

Analyse Export erweitern

In diesem Schritt werden wir die folgenden Dateien modifizieren:

  • src/Mod/Fem/femsolver/elmer/writer.py

This is the most demanding part of implementing a new equation. This file contains the Writer class which exports the analysis into Elmer sif format.

For every supported equation there are a series of methods handling the export of the respective equation. Just copy all of them from an existing equation and adjust them to your needs. Our flow equation uses the following methods:

  • _handleFlow
  • _getFlowSolver
  • _handleFlowConstants
  • _handleFlowMaterial
  • _handleFlowInitialVelocity
  • _handleFlowBndConditions
  • _handleFlowEquation