avgJoe
avgJoe

Reputation: 842

How to work around GMSH and Calculix GUI in FreeCAD to automate Finite Element Analysis using Macro?

I created a macro (python script) in FreeCAD that generates a cantilever beam, creates an Analysis, selects a material, and applies constraints to the body.

How do I now extend the script, so I can generate the mesh (using GMSH) and run the analysis with Calculix all in the same script?

Please see below my code:

import FreeCAD
import PartDesign
import PartDesignGui
import Sketcher
import FemGui
import ObjectsFem
import Fem

# Open new Document
exec(open('/usr/share/freecad/Mod/Start/StartPage/LoadNew.py').read())
App.setActiveDocument("Unnamed")
App.ActiveDocument=App.getDocument("Unnamed")

#
# generate cantilever beam
#

# Start new part design
App.activeDocument().addObject('PartDesign::Body','Body')
App.activeDocument().Body.newObject('Sketcher::SketchObject','Sketch')
App.activeDocument().Sketch.Support = (App.activeDocument().XY_Plane, [''])
App.activeDocument().Sketch.MapMode = 'FlatFace'
App.ActiveDocument.recompute()

# create cross section sketch
geoList = []
geoList.append(Part.LineSegment(App.Vector(-10,  9,0),App.Vector( 10,  9,0)))
geoList.append(Part.LineSegment(App.Vector( 10,  9,0),App.Vector( 10,-10,0)))
geoList.append(Part.LineSegment(App.Vector( 10,-10,0),App.Vector(-10,-10,0)))
geoList.append(Part.LineSegment(App.Vector(-10,-10,0),App.Vector(-10,  9,0)))
App.ActiveDocument.Sketch.addGeometry(geoList,False)
conList = []
conList.append(Sketcher.Constraint('Coincident',0,2,1,1))
conList.append(Sketcher.Constraint('Coincident',1,2,2,1))
conList.append(Sketcher.Constraint('Coincident',2,2,3,1))
conList.append(Sketcher.Constraint('Coincident',3,2,0,1))
conList.append(Sketcher.Constraint('Horizontal',0))
conList.append(Sketcher.Constraint('Horizontal',2))
conList.append(Sketcher.Constraint('Vertical',1))
conList.append(Sketcher.Constraint('Vertical',3))
App.ActiveDocument.Sketch.addConstraint(conList)

# Pad the cross section to create beam
App.getDocument('Unnamed').recompute()
App.activeDocument().Body.newObject("PartDesign::Pad","Pad")
App.activeDocument().Pad.Profile = App.activeDocument().Sketch
App.activeDocument().Pad.Length = 10.0
App.ActiveDocument.recompute()
App.ActiveDocument.recompute()
App.ActiveDocument.Pad.Length = 200.000000
App.ActiveDocument.Pad.Length2 = 100.000000
App.ActiveDocument.Pad.Type = 0
App.ActiveDocument.Pad.UpToFace = None
App.ActiveDocument.Pad.Reversed = 0
App.ActiveDocument.Pad.Midplane = 0
App.ActiveDocument.Pad.Offset = 0.000000
App.ActiveDocument.recompute()

#
# Start FEM process
#

# make analysis
ObjectsFem.makeAnalysis(FreeCAD.ActiveDocument, 'Analysis')
FemGui.setActiveAnalysis(FreeCAD.ActiveDocument.ActiveObject)
ObjectsFem.makeSolverCalculixCcxTools(FreeCAD.ActiveDocument)
FemGui.getActiveAnalysis().addObject(FreeCAD.ActiveDocument.ActiveObject)
# Select Material
FemGui.getActiveAnalysis().addObject(ObjectsFem.makeMaterialSolid(FreeCAD.ActiveDocument, 'SolidMaterial'))
FreeCADGui.ActiveDocument.setEdit(FreeCAD.ActiveDocument.ActiveObject.Name)
# Add Fixed Constraint
App.activeDocument().addObject("Fem::ConstraintFixed","FemConstraintFixed")
App.activeDocument().FemConstraintFixed.Scale = 1
App.activeDocument().Analysis.addObject(App.activeDocument().FemConstraintFixed)
for amesh in App.activeDocument().Objects:
    if "FemConstraintFixed" == amesh.Name:
        amesh.ViewObject.Visibility = True
    elif "Mesh" in amesh.TypeId:
        aparttoshow = amesh.Name.replace("_Mesh","")
        for apart in App.activeDocument().Objects:
            if aparttoshow == apart.Name:
                apart.ViewObject.Visibility = True
        amesh.ViewObject.Visibility = False

App.ActiveDocument.recompute()
App.ActiveDocument.FemConstraintFixed.Scale = 1
App.ActiveDocument.FemConstraintFixed.References = [(App.ActiveDocument.Pad,"Face5")]
App.ActiveDocument.recompute()

# Add Force Constraint
App.activeDocument().addObject("Fem::ConstraintForce","FemConstraintForce")
App.activeDocument().FemConstraintForce.Force = 1.0
App.activeDocument().FemConstraintForce.Reversed = False
App.activeDocument().FemConstraintForce.Scale = 1
App.activeDocument().Analysis.addObject(App.activeDocument().FemConstraintForce)
for amesh in App.activeDocument().Objects:
    if "FemConstraintForce" == amesh.Name:
        amesh.ViewObject.Visibility = True
    elif "Mesh" in amesh.TypeId:
        aparttoshow = amesh.Name.replace("_Mesh","")
        for apart in App.activeDocument().Objects:
            if aparttoshow == apart.Name:
                apart.ViewObject.Visibility = True
        amesh.ViewObject.Visibility = False

App.ActiveDocument.recompute()
App.ActiveDocument.FemConstraintForce.Force = 1
App.ActiveDocument.FemConstraintForce.Direction = None
App.ActiveDocument.FemConstraintForce.Reversed = False
App.ActiveDocument.FemConstraintForce.Scale = 1
App.ActiveDocument.FemConstraintForce.References = [(App.ActiveDocument.Pad,"Face6")]
App.ActiveDocument.recompute()

# Generate Mesh
ObjectsFem.makeMeshGmsh(FreeCAD.ActiveDocument, 'FEMMeshGmsh')
FreeCAD.ActiveDocument.ActiveObject.Part = FreeCAD.ActiveDocument.Pad
FemGui.getActiveAnalysis().addObject(FreeCAD.ActiveDocument.ActiveObject)
FreeCADGui.ActiveDocument.setEdit(FreeCAD.ActiveDocument.ActiveObject.Name)

When I run my code, I get the fully setup analysis with constraints applied and material select. FreeCAD shows me the "FEM mesh by Gmsh" view, where I can select parameters and press a button to generate the mesh file. I would like to push that button in code.

Similarly, I can double click on my Calculix Solver and get the "Mechanical Analysis" view, which allows me to select an analysis type, generate the .inp file, and run the analysis. How do I perform these steps in code.

I am open to calling other script files from within my python file that are written in other languages. But I need it to be automatable, s.t. I could run through various analyses in a for-loop.

Upvotes: 2

Views: 893

Answers (0)

Related Questions