Macro Mesh Data

About the development of the FEM module/workbench.

Moderator: bernd

User avatar
bernd
Posts: 8204
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

Re: Macro Mesh Data

Postby bernd » Sat Jan 26, 2019 9:04 pm

I had to change your code slightly to get it working for me. Is this still what you want ... just start FreeCAD and run the code ...

Code: Select all

doc = FreeCAD.open(FreeCAD.ConfigGet("AppHomePath") + 'data/examples/FemCalculixCantilever3D.FCStd')

import FemGui
FemGui.setActiveAnalysis(doc.Analysis)

import femtools.ccxtools as tools
ft = tools.FemToolsCcx()

from femsolver.calculix.writer import FemInputWriterCcx as iw
fiwc = iw(
    ft.analysis, ft.solver, ft.mesh, ft.materials_linear,
    None, None, None, None, None, None, None, None,
    None, None, None, None, None, None, None, None, None
)
fiwc.get_material_elements()

elmat = []

for object in fiwc.material_objects:
    E = object['Object'].Material['YoungsModulus']
    Nu = object['Object'].Material['PoissonRatio']
    for el in object['FEMElements']:
        elmat.append([el, E, Nu])

print (elmat)
User avatar
bernd
Posts: 8204
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

Re: Macro Mesh Data

Postby bernd » Sat Jan 26, 2019 9:44 pm

or without the ccxtools ...

Code: Select all

doc = FreeCAD.open(FreeCAD.ConfigGet("AppHomePath") + 'data/examples/FemCalculixCantilever3D.FCStd')

from femtools.femutils import get_several_member as gsm
materials_lin = gsm(doc.Analysis, 'Fem::Material')

from femsolver.calculix.writer import FemInputWriterCcx as iw
fiwc = iw(
    doc.Analysis, doc.CalculiXccxTools, doc.Box_Mesh, materials_lin,
    None, None, None, None, None, None, None, None,
    None, None, None, None, None, None, None, None, None
)
fiwc.get_material_elements()

elmat = []

for object in fiwc.material_objects:
    E = object['Object'].Material['YoungsModulus']
    Nu = object['Object'].Material['PoissonRatio']
    for el in object['FEMElements']:
        elmat.append([el, E, Nu])

print (elmat)
User avatar
bernd
Posts: 8204
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

Re: Macro Mesh Data

Postby bernd » Sat Jan 26, 2019 9:52 pm

it gets even simpler if a development branch of my repo is used ... This moves the the member collecting inside the writer class https://github.com/berndhahnebach/FreeC ... diff=split in branch https://github.com/berndhahnebach/FreeC ... bercollect I did not do a PR so far because I did not know if it was the way to go ...

Code: Select all

doc = FreeCAD.open(FreeCAD.ConfigGet("AppHomePath") + 'data/examples/FemCalculixCantilever3D.FCStd')

from femsolver.calculix.writer import FemInputWriterCcx as iw
fiwc = iw(doc.Analysis, doc.CalculiXccxTools, doc.Box_Mesh)

fiwc.get_material_elements()

elmat = []

for object in fiwc.material_objects:
    E = object['Object'].Material['YoungsModulus']
    Nu = object['Object'].Material['PoissonRatio']
    for el in object['FEMElements']:
        elmat.append([el, E, Nu])

print (elmat)
User avatar
HarryvL
Posts: 1042
Joined: Sat Jan 06, 2018 7:38 pm

Re: Macro Mesh Data

Postby HarryvL » Sun Jan 27, 2019 1:16 am

Fantastic, thanks Bernd. Let me study all of this.

By the way, I see you installed WiFi in your Iglu.
User avatar
HarryvL
Posts: 1042
Joined: Sat Jan 06, 2018 7:38 pm

Re: Macro Mesh Data

Postby HarryvL » Sun Jan 27, 2019 1:35 am

While doing all of this I thought there might be a more efficient (solver-independent) way to store information ahead of writing input files, i.e. by individual mesh element (vertex, edge, face, volume). Kind of what I end up with in my macro, but then 4 lists (for element vertex, edge, face and volume, respectively) and each containing all relevant geometrical and physical info. You can then add to that as FEM workbench develops and new geometrical and material options become available. The step to FEA input files would be a small one. It would leave the topo storage (by part, volume, face, edge etc) unchanged, but is just an intermediate step before writing solver input files.
Last edited by HarryvL on Sun Jan 27, 2019 1:55 am, edited 1 time in total.
User avatar
HarryvL
Posts: 1042
Joined: Sat Jan 06, 2018 7:38 pm

Re: Macro Mesh Data

Postby HarryvL » Sun Jan 27, 2019 1:53 am

... or better even by mesh element -> mesh nodes, so you can even include field variables (eg from previous calculation steps or position dependent loads or materials). You can think of various applications: non-linear buckling (as in my knee joint elasto-plastic buckling post), where initial imperfection comes from an elastic buckling step; the distributed face loads UR_ developed and Thomas used for hydrostatic pressure; initial stress dependent soil parameters, like Young’s modulus and Undrained shear strength (yield stress / 2). I could go on and on. The options and engineering applications are limitless.
User avatar
HarryvL
Posts: 1042
Joined: Sat Jan 06, 2018 7:38 pm

Re: Macro Mesh Data

Postby HarryvL » Sun Jan 27, 2019 4:09 am

Moving on and trying to better organise my macro before I extend it. I want to move function definitions into a module, hitting a newby issue:

dummyMacro.FCMacro:

Code: Select all

import dummyModule as dm
dm.dummy()
dummyModule.py:

Code: Select all

def dummy():
    print("Hello from dummyModule")
Both files are in the ~/.FreeCAD/Macro directory. Nothing happens and when I do this with my actual spaghetti code I get "global name App is not defined', even if App is not referenced anywhere.
User avatar
HarryvL
Posts: 1042
Joined: Sat Jan 06, 2018 7:38 pm

Re: Macro Mesh Data

Postby HarryvL » Sun Jan 27, 2019 4:37 am

Ideally, this is how clean I want to keep my fcFEM.FCMacro:

Code: Select all

import femTools as ft

# extract information from FreeCAD objects
doc, mesh, analysis, solvDummy, res = ft.setUpAnalysis()

# prepare finite element input
elNodes, noCoord, dispFaces, loadfFaces, elMat = ft.setUpInput(doc, mesh, analysis, solvDummy)

# caculate the global stiffness matrix
globalStiffnessMatrix = ft.calcGSM(elnodes, noCoord, elMat)

# modify the global stiffness matrix for displacement boundary conditions
globalStiffnessMatrix = ft.bcGSM(globalStiffnessMatrix, dispFaces)

# calculate the global load vector for pressure loads on faces
globalLoadVector = ft.calcGLV(loadFaces)

# solve the global siffness matrix equation
displacements = ft.calcDisp (globalStiffnessMatrix, globalLoadVector)

# calculate stresses from displacements
stresses = ft.calcStresses(elnodes, noCoord, elMat, displacements)

# paste results into the FEM result object
ft.pasteResults()
The first, second and last functions are working. The others require a bit more work ;)
User avatar
bernd
Posts: 8204
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

Re: Macro Mesh Data

Postby bernd » Sun Jan 27, 2019 11:19 am

you are totally right ... We need to think about this. BTW: It works totally independent from ccx code already ... But this is not smart ...

Code: Select all

doc = FreeCAD.open(FreeCAD.ConfigGet("AppHomePath") + 'data/examples/FemCalculixCantilever3D.FCStd')

from femtools.femutils import get_several_member as gsm
materials_lin = gsm(doc.Analysis, 'Fem::Material')

from femsolver.writerbase import FemInputWriter as iw
fiwc = iw(
    doc.Analysis, doc.CalculiXccxTools, doc.Box_Mesh, materials_lin,
    None, None, None, None, None, None, None, None,
    None, None, None, None, None, None, None, None, None
)
fiwc.get_material_elements()

elmat = []

for object in fiwc.material_objects:
    E = object['Object'].Material['YoungsModulus']
    Nu = object['Object'].Material['PoissonRatio']
    for el in object['FEMElements']:
        elmat.append([el, E, Nu])

print (elmat)

About your problem I will have a look.
User avatar
HarryvL
Posts: 1042
Joined: Sat Jan 06, 2018 7:38 pm

Re: Macro Mesh Data

Postby HarryvL » Sun Jan 27, 2019 4:19 pm

HarryvL wrote:
Sun Jan 27, 2019 4:09 am
Moving on and trying to better organise my macro before I extend it. I want to move function definitions into a module, hitting a newby issue:

dummyMacro.FCMacro:

Code: Select all

import dummyModule as dm
dm.dummy()
dummyModule.py:

Code: Select all

def dummy():
    print("Hello from dummyModule")
Both files are in the ~/.FreeCAD/Macro directory. Nothing happens and when I do this with my actual spaghetti code I get "global name App is not defined', even if App is not referenced anywhere.
I decided to try "Macro>Macros>dummyMacro.FCMacro>Execute" instead of "Macro>Macros>dummyMacro.FCMacro>Edit>Run" and then it works. Now I am trying to replicate the earlier behavior and I can't. Let me try my fcFEM macro