OOFem

not at all. you may undestood me wrong. My words where more in the direction of helping you coding than taking some pressure.

I wasn’t serious Bernd :wink:

:sunglasses:

A preview of where I am heading with the input file

    def write_OOFEM_input_file(self):
        
        timestart = time.clock()
        
        inpfile = open(self.file_name, 'a')        
        
        self.write_output_file_record(inpfile)
        ''' Filename String '''
        
        self.write_job_description_record(inpfile)
        ''' Job description string '''
        
        self.write_analysis_record(inpfile)
        '''*AnalysisType     nsteps # (in)
                            [renumber # (in) ]
                            [profileopt # (in) ]
                            attributes # (string)
                            [ninitmodules # (in) ]
                            [nmodules # (in) ]
                            [nxfemman # (in) ]
        
                            *StaticStructural
                            nsteps # (in)
                            [deltat # (...) ]
                            [prescribedtimes # (...) ]
                            [stiffmode # (...) ]
                            [nonlocalext # (...) ]
                            [sparselinsolverparams # (...) ]
                            
                            *LinearStability
                             nroot # (in)
                             rtolv # (rn)
                             [eigensolverparams # (...) ]
                             
                            *NonLinearStatic
                             [nmsteps # (in) ]
                             nsteps # (in)
                             [contextOutputStep # (in) ]
                             [sparselinsolverparams # (string) ]
                             [nonlinform # (in) ]
                             [nonlocstiff # (in) ]
                             [nonlocalext]
                             [loadbalancing]'''

        self.write_domain_record(inpfile)

        '''domain *domainType
                              *2dPlaneStress
                              *2d-Truss
                              *3d
                              *2dMindlinPlate
                              *3dShell
                              *2dBeam
        
        '''
        
        self.write_output_manager_record(inpfile)
        
        '''OutputManager
           [tstep all]
           [tstep step # (in) ]
           [tsteps out # (rl) ]
           [dofman all]
           [dofman output # (rl) ]
           [dofman except # (rl) ]
           [element all]
           [element output # (rl) ]
           [element except # (rl) ]
           ndofman # (in)
           nelem # (in)
           ncrosssect # (in)
           nmat # (in)
           nbc # (in)
           nic # (in)
           nltf # (in)
           [nbarrier # (in) ]'''
           
        self.write_dof_manager_record(inpfile)
           
        '''*DofManagerType
            (num#) (in)
            [load # (ra) ]
            [DofIDMask # (ia) ]
            [bc # (ia) ]
            [ic # (ia) ]
            [doftype # (ia) masterMask # (ia) ]
            [shared]i | h[remote]i | h[null]
            [partitions # (ia) ]
                                                 *Node coords # (ra)
                                                  [lcs # (ra) ]'''
                                                  
        self.write_element_record(inpfile)
           
        '''*ElementType
            (num#) (in)
            mat # (in) crossSect # (in) nodes # (ia)
            [bodyLoads # (ia) ] [boundaryLoads # (ia) ]
            [activityltf # (in) ] [lcs # (ra) ]
            [partitions # (ia) ] [remote]
                                                 *beam2d
                                                  2D beam element
                                                  [dofstocondense # (ia) ]
                                                 *beam3d
                                                  3D beam element
                                                  refnode # (in) [dofstocondense # (ia) ]
                                                 *planestress2d
                                                  4-noded 2D quadrilateral element for plane stress analysis
                                                  [NIP # (in) ]
                                                 *qplanestress2d
                                                  8-noded 2D quadrilateral element for plane stress analysis
                                                  [NIP # (in) ]
                                                 *trplanestress2d
                                                  3-noded 2D triangular element for plane stress analysis                                                 
                                                 *qtrplstr
                                                  6-noded 2D triangular element for plane stress analysis [NIP # (in) ]
                                                 *quad1planestrain
                                                  4-noded 2D quadrilateral element for plane strain analysis
                                                  [NIP # (in) ]
                                                 *trplanestrain
                                                  3-noded 2D triangular element for plane strain analysis
                                                 *lspace
                                                  Linear 8-node isoparametric brick element
                                                  [NIP # (in) ]
                                                 *qspace
                                                  Quadratic 20-node isoparametric brick element
                                                  [NIP # (in) ]
                                                 *LTRSpace
                                                  Linear 4-node tetrahedra element
                                                 *QTRSpace
                                                  Quadratic 10-node tetrahedra element
                                                  [NIP # (in) ] '''

        self.write_set_record(inpfile)
        
        '''Set (num#) (in)
           [elements # (ia) ] [elementranges # (rl) ] [allElements]
           [nodes # (ia) ] [noderanges # (rl) ] [allNodes]
           [elementboundaries # (ia) ] [elementedges # (ia) ] '''
           
        self.write_cross_section_record(inpfile)
        
        '''*CrossSectType (num#) (in)
                                        *SimpleCS [thick # (rn) ] [width # (rn) ] [area # (rn) ]
                                         [iy # (rn) ] [iz # (rn) ] [ik # (rn) ]
                                         [shearareay # (rn) ] [shearareaz # (rn) ] beamshearcoeff # (rn)
                                         
                                        *VariableCS [thick # (expr) ] [width # (expr) ] [area # (expr) ]
                                        [iy # (expr) ] [iz # (expr) ] [ik # (expr) ]
                                        [shearareay # (expr) ] [shearareaz # (expr) ]
                                        
                                        *LayeredCS nLayers # (in)
                                        LayerMaterials # (ia)
                                        Thicks # (ra) Widths # (ra)
                                        midSurf # (rn) '''

        self.write_material_type_record(inpfile)
        
        '''*MaterialType (num#) (in) d # (rn)
                                         Linear isotropic elastic material
                                        *IsoLE num (in) # d (rn) # E (rn) # n (rn) # tAlpha (rn) #
                                         Mooney-Rivlin
                                        *MooneyRivlin (in) # d (rn) # K (rn) # C1 (rn) # C2 (rn) #
                                         Large-strain master material material
                                        *LSmasterMat (in) # m (rn) # slavemat (in) #
                                         DP material
                                        *DruckerPrager num (in) # d (rn) # tAlpha (rn) # E (rn) # n (rn) # alpha (rn) # alphaPsi (rn) # ht (in) # iys (rn) # lys (rn) # hm (rn) # kc (rn) # [ yieldtol (rn) #]
                                         Mises plasticity model with isotropic hardening
                                        *MisesMat (in) # d (rn) # E (rn) # n (rn) # sig0 (rn) # H (rn) # omega crit (rn) #a (rn) #
                                         Rotating crack model for concrete
                                        *Concrete3 d (rn) # E (rn) # n (rn) # Gf (rn) # Ft (rn) # exp soft (in) # tAlpha (rn) #
                                         EC2CreepMat model for concrete creep and shrinkage
                                        *EC2CreepMat n (rn) # [ begOfTimeOfInterest (rn) #] [ end-OfTimeOfInterest (rn) #] relMatAge (rn) # [ timeFactor (rn) #] stiffnessFactor (rn) # [ tAlpha (rn) #] fcm28 (rn) # t0 (rn) # cem- Type (in) # [ henv (rn) #] h0 (rn) # shType (in) # [ spectrum ][ temperatureDependent ]'''
           
                   
        # footer
        self.write_footer(inpfile)
        inpfile.close()
        FreeCAD.Console.PrintMessage("Writing time input file: " + str(time.clock() - timestart) + ' \n\n')
        return self.file_name

The meta code in the comments is (a selection) from the OOFEM input manual. It gives an impression of the capability of OOFEM, but also indicates that there is still a bit of work required on the FC material object and solver object (data tab) to collect some of that information from the user.

I will first start with what is currently readily available from material, mesh and solver objects and (if time permits) later try to extend those objects to capture the information/parameters for the more exotic capabilities of OOFEM.

How is the progress going with this ?

I have made 0% progress since my last post.

Do you need any help or it just a matter of time and mood ?

Thanks. It’s just a matter of time and focus.

FreeCAD motto is: It’s done when it’s done! :smiley:

Bernd,

I am able to write the OOFEM input file to disk (replicating Z88 logic), but the mesh is empty.

I make the following call to importOOFEMMesh.write_OOFEM_mesh_to_file () in writer.py:

https://github.com/HarryvL/FreeCAD/blob/assess/src/Mod/Fem/femsolver/oofem/writer.py#L286

after which the following shows zero nodes and elements:

https://github.com/HarryvL/FreeCAD/blob/assess/src/Mod/Fem/feminout/importOOFEMMesh.py#L322-L340

I have not been able to trace back where self.femnodes_mesh and self.femelement_table get assigned … apart from the initiation here:

https://github.com/HarryvL/FreeCAD/blob/assess/src/Mod/Fem/femsolver/writerbase.py#L86-L87

and the assignment in the unrelated(?) method get_constraints_pressure_faces() here:

https://github.com/HarryvL/FreeCAD/blob/assess/src/Mod/Fem/femsolver/writerbase.py#L187-L201

In summary, I am lost on how to access node and element data for writing to file.

I will have a look.

They will be assigned if needed …

For example for the CalculiX mesh they are not needed. Thus for calculix they are only needed for constraints like force or pressure, thus they are assigned inside each constraint writer. For example on calculix frequency analysis without constraints they are not needed at all. Z88 needs them for mesh writing too. Means they are needed for any input file writing. Thus they are assigned just at start of writing. They are assigned here: https://github.com/HarryvL/FreeCAD/blob/assess/src/Mod/Fem/femsolver/z88/writer.py#L66-L69

Means for oofem your would copy the lines from above to https://github.com/HarryvL/FreeCAD/blob/assess/src/Mod/Fem/femsolver/oofem/writer.py#L75 if you need them in any file write (which will be true if you need them for mesh writing).

hope that helps bernd

Thanks. I will give it a try.

BTW: Does oofem has its own mesh format like Z88? If it would support any of the known standard mesh format FreeCAD supports already you would not need to write a mesh exporter for oofem in FreeCAD like I had to do it for Z88.

Bernd

AFAIK the mesh information is typed in the input file in a connectivity format (global node numbers by element) unique to OOFEM. The developers make available a converter script (unv2oofem) that turns UNV files into OOFEM format, but going via UNV would be a roundabout way to get to the required result. Not sure this answers your question.

PS: what standard mesh format does CCX use and how is this written to the input file?

ccx uses Abaqus inp file format. It is written here: https://github.com/berndhahnebach/FreeCAD_bhb/blob/e4b1cfc430a9420500ccd366c6bf9ad225db629f/src/Mod/Fem/femsolver/calculix/writer.py#L82 The writer ist done in C++ see https://github.com/berndhahnebach/FreeCAD_bhb/blob/e4b1cfc430a9420500ccd366c6bf9ad225db629f/src/Mod/Fem/App/FemMesh.cpp#L1185

Some Formats are done in C++ See https://github.com/berndhahnebach/FreeCAD_bhb/blob/e4b1cfc430a9420500ccd366c6bf9ad225db629f/src/Mod/Fem/App/FemMesh.cpp#L1575

to write a mesh in various formats just load the 3D example from Start WB

expath = '/home/hugo/Desktop/'
mesh = App.ActiveDocument.Box_Mesh.FemMesh

mesh.write(expath + 'mesh.inp')
mesh.write(expath + 'mesh.vtk')
mesh.write(expath + 'mesh.stl')
mesh.write(expath + 'mesh.unv')

for Z88 you would need to import the Python module first …

expath = '/home/hugo/Desktop/'
from feminout.importZ88Mesh import export as z88export
z88export([App.ActiveDocument.Box_Mesh], expath + 'mesh.txt')

The z88 one should be improved to be as easy as the c++ ones. But this is of low priority for me. Ahh element table and nodes are retrieved in the export def see: https://github.com/berndhahnebach/FreeCAD_bhb/blob/e4b1cfc430a9420500ccd366c6bf9ad225db629f/src/Mod/Fem/feminout/importZ88Mesh.py#L73-L75

similar to z88. They have a converter too. My first idea was use the converter, but than I realised to write an exporter just for nodes and tet10 elements is not difficult and just some lines of code. With this one can export lots of analysis already. All other element types where added step by step later on.

cheers bernd

That’s exactly the thought process I went through for OOFEM :smiley:

:sunglasses: