Skip to content

User’s Guide

This guide introduces the components and commands that define the configuration file required to execute an analysis using MYFEMPY. Depending on the problem setup, adjustments may be necessary; please refer to the help or API documentation for details. Additional Tutorials are provided at the end of this guide.

Presentation

The myfempy project was developed as a finite element solver for multi-physics simulations, intended for academic and research use. Originating from the author’s doctoral thesis, the project has matured into a robust computational framework. Its primary goal is to provide an accessible yet powerful environment for simulation setup and execution, minimizing the need for advanced prior knowledge of numerical methods while maintaining flexibility for expert users.

At its core, myfempy implements a finite element processor that drives the numerical analysis. The workflow is organized into three principal stages:

Pre-processing
- Configuration is performed through API commands.
- Users specify material properties, element types, and boundary conditions.
- Mesh generation is managed via Gmsh, which supplies both geometry and discretization data.

Processing
- The solver core executes finite element computations according to the defined physics and constraints.
- Multi-physics coupling is supported, enabling integration of multiple physical domains within a single simulation.

Post-processing
- Results are exported in formats compatible with visualization tools.
- Output data is structured as VTK files, which can be analyzed and visualized using ParaView.

This architecture emphasizes modularity, extensibility, and interoperability with established open-source tools, positioning myfempy as a versatile platform for computational mechanics and multi-physics research. A typical analysis workflow involves submitting requests (Python dictionaries) through a specific script pattern. The user imports the desired solver, configures the problem by defining materials, finite elements, and geometry, and generates a mesh via Gmsh. Loads and boundary conditions are applied, and the solver computes the solution. Results are exported and visualized in ParaView.

graph LR
U[User] --> MyfempyAPI
MyfempyAPI --> A[Gmsh]
A[Gmsh] --> B[MyfempyCore]
B --> C[Paraview]

style A fill:#006400, stroke:#333, stroke-width:2px
style B fill:#006400, stroke:#333, stroke-width:2px
style C fill:#00008B, stroke:#333, stroke-width:2px

To ensure organized execution, myfempy employs a hierarchical code structure that integrates user requests into a processing pipeline. Input data is validated through controllers in the I/O interface. If commands and data are consistent, they are passed to the solver core, where pre-processing, solution, and post-processing occur. The processed data is then returned through the I/O filters and exported as visualization-ready files (VTK).

graph
  U[InputData] --> B{IO}
  B -->|Yes| C[PreProcess]
  C --> R[CoreSolver]
  R --> D[PostProcess]
  D --> B;
  B -----> O[OutputData]
  B ----->|No| E[ReturnERROR]

style C fill:#006400, stroke:#333, stroke-width:2px
style R fill:#006400, stroke:#333, stroke-width:2px
style D fill:#006400, stroke:#333, stroke-width:2px
style O fill:#00008B, stroke:#333, stroke-width:2px
style E fill:#8B0000,stroke:#333,stroke-width:2px;

How it Works

myfempy is implemented using an object-oriented paradigm, structured around the Bridge design pattern. The system is composed of multiple classes, with user interaction facilitated through APIs that orchestrate the execution of the solver.

The project adopts a black-box architecture: users provide input data, the solver executes the numerical routines, and the system returns output data along with logs for validation.

graph LR
UserInput --> BLACK-BOX
BLACK-BOX --> OutputData

The main API provides direct access to the core components of the project, enabling construction of the Model, definition of Physics, and execution of the Solution.

graph LR
User --> API
API --> Model
API --> Physics
API --> Solve
API --> Results

Model --> Element
Model --> Shape
Model --> Mesh
Model --> Material
Model --> Geometry

Physics --> Loads
Physics --> BoundCond
Physics --> Coupling

Results --> PostProcess

Solve --> Assembler
Solve --> Solver

Pre-Process

API and Solver

# ==============================================================================
# import newAnalysis to set a new problem
# ==============================================================================
from myfempy import newAnalysis
# ==============================================================================
# import a solver to running and analysis the problem set, e.g. SteadyStateLinear
# ==============================================================================
from myfempy import Solver
# ==============================================================================
# now, fea is the API to running the Solver Analysis
# ==============================================================================
fea = newAnalysis(Solver)

Solvers

# ==============================================================================
# currently available solvers for import into the myfempy library
# ==============================================================================
# >see: Table 3 - Solvers List to more informations
# solver options
"SteadyStateLinear"                 # Steady State Linear Solver Class
"SteadyStateLinearIterative"        # Steady State Linear Iterative Solver Class
"DynamicEigenLinear"                # Dynamic Eigen (modal problem) Linear Solver Class
"DynamicHarmonicResponseLinear"     # Dynamic Harmonic Response Forced System Steady State Linear Solver Class

# [adv]
"StaticLinearCyclicSymmPlane"       # Static Linear Cyclic Symmetry Plane Solver Class
"PhononicCrystalInPlane"            # Phononic Crystal In-Plane Solver Class
"HomogenPlane"                      # Homogenization Plane Solver Class

Model

# ==============================================================================
# modeldata is a Python dictionary that contains the commands for model set
# ==============================================================================
modeldata = dict()

Material

# ==============================================================================
# config. material
# ==============================================================================
modeldata["MATERIAL"] = dict()
keys
"MAT":str()               # material set
      # >see: Table 4 - Material List to more informations
      # options
      'lumped'              # lumped material
      'uniaxialstress'  # axial{rod, beams...} behavior material
      'planestress'       # plane stress behavior
      'planestrain'       # plane strain behavior
      'solidelastic'        # solid behavior material
      'heatplane'             # heat behavior material
      'heatsolid'             # heat behavior material

      # [dev]
      'fluid'

"TYPE":str()                  # material behavior
      # options
      'isotropic'             # isotropic stress/strain material
      'usermaterial'        # user config. material

"PROPMAT":list[mat_set_1:dict(),..., mat_set_n:dict()] # material properties
      # options
      "NAME": str()         # material name def
      # isotropic solid parameters
      # >see: Appendix: Table 5 - Consistent Units to more informations
      "EXX": float()        # elasticity modulus in x direction 
      "VXY": float()        # poisson's ratio in x direction  
      "GXY": float()        # shear modulus in x direction  
      "RHO": float()        # density of material

      # anisotropic solid parameters
      "EYY": float()
      "VYZ": float()
      "GYZ": float()
      "EZZ": float()
      "VZX": float()
      "GZX": float()

      # heat parameters
      "KXX": float()      # thermal conductivity in x direction
      "KYY": float()      # thermal conductivity in y direction
      "KZZ": float()      # thermal conductivity in z direction
      "CTE": float()      # coefficients thermal expansion

      # [dev] fluid parameters 
      "VIS": float()      # viscosity            
      "RHO": float()          # density of fluid

      # lumped model
      "STIF": float()         # stiffness lumped
      "DAMP": float()         # damping lumped

# [adv]
"CLASS": class()          # user new class defined
      #-----------------------
      # example:
      #-----------------------
      # from myfempy import PlaneStress
      # ===============================================================================
      #                    SET NEW MATERIAL <ORTHOTROPIC ELASTIC>
      # ===============================================================================
      # class UserNewMaterial(PlaneStress):
      #     def __init__(self):
      #         super().__init__()
      #     def getMaterialSet():
      #         matset = {
      #             "mat": "planestress",
      #             "type": "orthotropic",
      #         }
      #         return matset
      #     def getElasticTensor(tabmat, inci, element_number, a=None, b=None):
      #         # # material elasticity
      #         EXX = tabmat[int(inci[element_number, 2]) - 1]["EXX"]
      #         EYY = tabmat[int(inci[element_number, 2]) - 1]["EYY"]
      #         # material poisson ratio
      #         VXY = tabmat[int(inci[element_number, 2]) - 1]["VXY"]
      #         VYZ = tabmat[int(inci[element_number, 2]) - 1]["VYZ"]  
      #         # EXX = 45E3       # N/mm^2 --> MPa
      #         # EYY = 12E3       # N/mm^2 --> MPa
      #         # VXY = 0.23
      #         # VYX = 0.66
      #         S00 = EXX/(1-VXY*VYZ)   
      #         S01 = (VYZ*EXX)/(1-VXY*VYZ)
      #         S10 = (VXY*EYY)/(1-VXY*VYZ)
      #         S11 = EYY/(1-VXY*VYZ)
      #         S22 = (EXX*EYY)/(EXX+EYY+2.0*EYY*VXY)     
      #         D = np.zeros((3, 3), dtype=np.float64)
      #         D[0, 0] = S00
      #         D[0, 1] = S01
      #         D[1, 0] = S10
      #         D[1, 1] = S11
      #         D[2, 2] = S22
      #         return D
      #     def getFailureCriteria(stress):
      #         stress
      #         return super().getFailureCriteria()
      # ===============================================================================

Geometry

# ==============================================================================
# config. geometry
# ==============================================================================
modeldata["GEOMETRY"] = dict()
keys
"GEO":str()           # geometry type
      # options
      'solid'                 # solid 3D geo.
      'thickness'           # planes geometries, e.g. plane stress, plates ...
      'frame'                 # rods, beams and frames geometries 

"SECTION":str()     # geometry beam cross section set
      # options
      # >see:  Appendix: Cross Section Dimensions to more informations
      'rectangle'           
      'rectangle_tube'         
      'circle'  
      'circle_tube'
      'isection'
      'tsection'
      'csection'
      'lsection'
      'userdefined'         

"PROPGEO":list[geo_set_1:dict(),..., geo_set_n:dict()] # geometry properties
      # options
      "NAME": str()           # geometry name def

      # parameters defined from the user's cross-section
      "AREACS": float() # area cross section
      "INERXX":float()  # inercia x diretion 
      "INERYY":float()  # inercia y diretion 
      "INERZZ":float()  # inercia z diretion 
      "THICKN":float()  # thickness of plane/plate

      # user set section dimensions
      # >see: Appendix: Cross Section Dimensions to more informations
      "DIM":dict()          # dimensional beam cross section
      {
          "b":float()         # b size
          "h":float()         # h size
          "t":float()         # t size
          "d":float()     # d size
      }

      # user set Center of Gravity coord. section
      "CG":dict()         # center of gravity of beam cross section
      {
          "y_max":float(),
          "y_min":float(),
          "z_max":float(),
          "z_min":float(),
          "r_max":float()
      }     

Element

# ==============================================================================
# config. element
# ==============================================================================
modeldata["ELEMENT"] = dict()
keys
"TYPE": str()                 # finite element 
      # options
      # >see: Table 1 - Elements List to more informations
      'structbeam'            # Beam Structural
      'structplane'           # Plane Structural
      'structsolid'                 # Solid Structural
      'heatplane'                   # Plane Heat
      'heatsolid'                   # Solid Heat

      # [dev]
      'structplate'       
      'fluid2d'        
      'fluid3d'

'SHAPE': str()
      # options
      # >see: Table 2 - Mesh List to more informations
      'line2'             # Line 2-Node
      'line3'             # Line 3-Node
      'tria3'             # Triangular 3-Node
      'tria6'             # Triangular 6-Node
      'quad4'             # Quadrilateral 4-Node
      'quad8'             # Quadrilateral 8-Node
      'hexa8'             # Hexaedron 8-Node
      'tetr4'             # Tetrahedron 4-Node
      'usershape'         # User Defined Shape

# optional
'INTGAUSS': int()         # number of points to integrations the mesh
# >see: Table 2 - Mesh List to more informations

Mesh

# ==============================================================================
# config. mesh
# ==============================================================================
modeldata["MESH"] = dict()
Manual Mesh Options
'TYPE': 'manual'
'COORD': nodes_coord_array
      # [
      # [node_number_1:int, coord_x_node_1:float, coord_y_node_1:float, coord_z_node_1:float]
      # ...
      # [node_number_N:int, coord_x_node_N:float, coord_y_node_N:float, coord_z_node_N:float]
      # ]
      #-----------------------
      # example:
      #-----------------------
      # >>nodes_coord_array =
      # [
      # [1, 0, 0, 0]
      # [2, 1, 0, 0]
      # [3, 0, 1, 0]
      # ]
'INCI': mesh_incidence_array
      # [
      # [elem_number_n:int, mat_type:int, geo_type:int, nodes_list_conec_1,...nodes_list_conec_n]
      # ...
      # ]
      #-----------------------
      # example:
      #-----------------------
      # >>mesh_incidence_array =
      # [[1, 1, 1, 1, 2, 3, 4]]
Legacy Mesh Options
'TYPE': 'legacy'
'LX': float()               # set a length in x diretion
'LY': float()               # set a length in y diretion
'NX': int()                 # set a number of elements in x diretion    
'NY': int()                 # set a number of elements in y diretion
Gmsh Mesh Options [adv]

logo2

'TYPE': 'gmsh',   
'meshimport':dict{}     # opt. to import a external gmsh mesh
      # option
      'object':str(object name [.msh2]) # file .msh2 only, mesh from gmsh [current version]

'cadimport':dict{}      # opt. to import a cad model from any cad program
      # option                                                                                      
      'object':str(object name [.step]) # file .step/.stp only [current version]

# Options to build a self model in .geo file (from gmsh)
'filename':str()            # names of the output files generated by the internal gmsh generator (.geo, .msh2)

'pointlist': list[]     # poinst coord. list
# set
# [
# [coord_x_point_1:float, coord_y_point_1:float, coord_z_point_1:float]
# ...
# ]

#  y
#  |
#  |
# (1)----x
#   \
#    \
#     z

#-----------------------
# example:
#-----------------------
# points = [
#     [0, 0, 0],
#     [10, 0, 0],
#     [10, 20, 0],
#     [0, 20, 0]
# ]

'linelist': list[]    # lines points conec., counterclockwise count         
# set
# [
# [point_i_line_1:int, point_j_line_1:int]
# ...
# ]

# (i)-----{1}-----(j)

#-----------------------
# example:
#-----------------------
# lines = [
#   [1, 2],
#   [2, 3],
#   [3, 4],
#   [4, 1],
# ]

'circle':list[]                 # circle line, counterclockwise count
# set
# [
# [R,[CX,CY,CZ],[A0, A1]] # arc_1
# ...
# ]

#       A1    ^
#       |    /
#       |   /
#       |  R
#       | /
#       |/
# (i:CX,CY,CZ)------A0

      # options
      R:float()                         # circle radius
      CX:float()                        # point i center x coord.
      CY:float()                        # point i center y coord.
      CZ:float()                        # point i center z coord.
      A0:str(e.g. val.='0')     # angle begin [rad]
      A1:str(e.g. val.='Pi/2')  # angle end [rad]

#-----------------------
# example:
#-----------------------
# circle = [[30, [100, 100, 0], ['0', '2*Pi']]

# circles have priority numbering over arcs; pay attention to the plane numbering.
# see the generated model (.geo) in gmsh for correct setting
'arc': list[]             # arc 3 points needed
# set
# [
# [point_i_begin:int, point_j_midle:int, , point_k_end:int]
# ...
# ]

#-----------------------
# example:
#-----------------------
# points = [
#     [0, 0, 0],    # ponto 1
#     [200, 0, 0],  # ponto 2
#     [200, 40, 0], # ponto 3   
#     [100, 40, 0], # ponto 4
#     [90, 30, 0],  # ponto 5
#     [0, 30, 0],   # ponto 6
#     [90, 40, 0],  # ponto 7
# ]
# lines = [
#     [1, 2],       # linha 1
#     [2, 3],       # linha 2
#     [3, 4],       # linha 3
#     [5, 6],       # linha 4
#     [6, 1],       # linha 5
#          ]
# arcs = [
#     [5, 7, 4],    # arco, adiciona uma nova linha 6
#          ]
# plane = [
#     [1, 2, 3, 6, 4, 5], # plane 1, sequencia das linhas
#          ]

# You can add a list of lines to form a plan.
# To remove a plan within another, add the "-" symbol to the number.
# If the same number is followed by another sequence with a positive value,
# the program will remove and add a plan, creating a new material.
'planelist': list[]     # planes lines conec., counterclockwise count
# set                                                         
# [                                                         
# [line_1_plane_1:int, ..., line_n_plane_1:int]             
# ...                                                               
# ]             

# (l)-----{3}-----(k)
#  |               |
#  |               |
# {4}     [1]     {2}
#  |               |
#  |               |
# (i)-----{1}-----(j)

#-----------------------
# example:
#-----------------------
# plane = [[1, 2, 3, 4]]              add a new plane with the lines 1, 2, 3, 4
# plane = [[1, 2, 3, 4], [-5]]        remove the line 5 ('circle') from the main plane with the lines 1, 2, 3, 4
# plane = [[1, 2, 3, 4], [-5], [5]]   remove the line 5 ('circle') and add a new plane 5 ('circle') from the main plane with the lines 1, 2, 3, 4

'meshconfig':dict{}                     # mesh configuration inputs
      # options
      'mesh': str()                   # !!! mandatory option !!! set a type of mesh used in analysis
      'sizeelement':float()               # size min. of elements
      'numbernodes':int()               # select a number of nodes in line, only to 'line2/ line3' >see: Table 2 - Mesh List to more informations
      'extrude':float()                   # extrude dimensional, in z diretion, from a xy plane
      'meshmap':dict{}                    # gen. a mapped structured mesh
            # option
            'on': bool()                # turn on(true/ false)
                  True
                  False
            'edge': [                           # select edge(lines) to map (only in 'on':True)         
                  'all' 
                  or
                  TAGS NUMB:list[int()]       # select all edge or a specific edge
            ]
            'numbernodes':list[int()]         # select a number of nodes in each edge
            #-----------------------
            # example:
            #-----------------------
            # 'meshmap': {'on': True,
            #     'edge': [[1, 2, 3], [4, 5, 6, 7]] or 'all',
            #     "numbernodes": [12, 8],
      # [ adv ]
      # Developed a robust Gmsh script that reorders nodes based on spatial coordinates (Z-Y-X)
      # while preserving all physical groups and entity metadata for optimized FEM assembly.
      # It is not compatible with 'meshmap'.
      'reordermesh': bool()         # turn on(true/ false)
                  True
                  False
# ==============================================================================
# Finally, pass the modeldata to the Model constructor API with the configured data and commands.
# ==============================================================================
fea.Model(modeldata)

Physics Setting

# ==============================================================================
# physicdata is a Python dictionary that contains the commands for physics set
# ==============================================================================
physicdata = dict()
# ==============================================================================
# physic set
# ==============================================================================
physicdata["PHYSIC"] = dict()

Domain

# ==============================================================================
# set the domain
# ==============================================================================
physicdata["PHYSIC"]["DOMAIN"]: str()
      # options
      'structural'
      'thermal'

      # [dev]
      'fluid'

Loads

# ==============================================================================
# configuration of loads applied to physics
# ==============================================================================
physicdata["PHYSIC"]["LOAD"] = list[load_set_1:dict(),..., load_set_n:dict()]
keys
"TYPE":str()                  # type force n def.
      # options
      'forcenode'                   # force in nodes, concentrated load
      'forceedge'                   # force in edge, distributed load
      'forcesurf'                   # force in surface, distributed load
      'forcebeam'                   # force in beam only opt., distributed load

      # [adv]
      'forcebody'
      'strainzero'

      # heat options
      'heatfluxedge'
      'heatfluxsurf'
      'convectionedge'
      'convectionsurf'
      'heatgeneration'

"DOF":str()                       # dof direction of force n
      # options
      'fx'                            # force in x dir.
      'fy'                            # force in y dir.
      'fz'                            # force in z dir.
      'pressure'            # pressure app. in normal direction
      'tx'                            # torque/moment in x dir.
      'ty'                            # torque/moment in y dir.
      'tz'                            # torque/moment in z dir.
      'masspoint'                     # mass concentrated applied in node/point 
      'spring2ground'               # spring connected node to ground/fixed end
      'damper2ground'               # damper connected node to ground/fixed end

# ----- OPT. WITH LOC SEEKERS 
"DIR":str()                       # set direction >see: Axis Diretions
      # options
      'node'                            # node in mesh
      'lengthx'                     # length line in x dir., beam only option [legacy version]
      'lengthy'                     # length line in y dir., beam only option [legacy version]
      'lengthz'                     # length line in z dir., beam only option [legacy version]
      'edgex'                           # edge def in x dir. >'LOC': {'x':float(coord. x nodes), 'y':999(select all node in y dir.), 'z':float(coord. z nodes)}
      'edgey'                           # edge def in y dir.
      'edgez'                           # edge def in z dir.
      'surfxy'                      # surf def in xy plane >'LOC': {'x':999, 'y': 999, 'z':float(coord. z nodes)}
      'surfyz'                      # surf def in yz plane
      'surfzx'                      # surf def in zx plane

"LOC":dict()                        # coord. node locator >see: Axis Diretions
      'x':float()                   # x coord. node
      'y':float()                   # y coord. node
      'z':float()           # z coord. node

# ----- OPT. WITH TAG SEEKERS
"DIR":str()                       # set direction >see: Axis Diretions
      # options
      'point'                           # point number in tag list
      'edge'                            # edge number in tag list
      'surf'                            # surface number in tag list

"TAG":int()                         # tag number of regions type, used with gmsh mesh gen, view list

#  look up the corresponding node number in the Paraview, and add 1.
#  For example: node_paraview = 0 --> 0 + 1 --> MESHNODE = [1]
"MESHNODE": list[int()]     # select the node ([1]) or nodes list([1, 2, 3, ...]) number directly from the mesh

"VAL":list()                        # value list of force on steps, signal +/- is the direction

Boundary Conditions

# ==============================================================================
# configuration of boundary conditions applied to physics
# ==============================================================================
physicdata["PHYSIC"]["BOUNDCOND"] = list[bc_set_1:dict(),..., bc_set_n:dict()]
keys
"TYPE":str()                    # type force n def.
      # options
      'fixed'                             # fixed boundary condition u=0. More in 
      'displ'                             # displ boundary condition u!=0.

      # [adv]
      'cycsym'
      'bloch'

      # heat options
      'insulated'
      'temperature'

"DOF":str()                     # dof direction of force n
      # options
      'ux'                              # displ in x dir.
      'uy'                              # displ in y dir.
      'uz'                              # displ in z dir.
      'rx'                              # rotation in x dir.
      'ry'                              # rotation in y dir.
      'rz'                              # rotation in z dir.
      'full'                              # full dof

# ----- OPT. WITH LOC SEEKERS 
"DIR":str()                       # set direction >see: Axis Diretions
      # options
      'node'                              # node in mesh
      'edgex'                             # edge def in x dir. >'LOC': {'x':float(coord. x nodes), 'y':999(select all node in y dir.), 'z':float(coord. z nodes)}
      'edgey'                             # edge def in y dir.
      'edgez'                             # edge def in z dir.
      'surfxy'                        # surf def in xy plane >'LOC': {'x':999, 'y': 999, 'z':float(coord. z nodes)}
      'surfyz'                        # surf def in yz plane
      'surfzx'                        # surf def in zx plane

"LOC":dict()
      # options                     # coord. node locator >see: Axis Diretions
      'x':float()                   # x coord. node
      'y':float()                   # y coord. node
      'z':float()           # z coord. node

# ----- OPT. WITH TAG SEEKERS
"DIR":str()                       # set direction >see: Axis Diretions
      # options
      'point'                             # point number in tag list
      'edge'                              # edge number in tag list
      'surf'                              # surface number in tag list

"TAG":int()                         # tag number of regions type, used with gmsh mesh gen, view list

#  look up the corresponding node number in the Paraview, and add 1.
#  For example: node_paraview = 0 --> 0 + 1 --> MESHNODE = [1]
"MESHNODE": list[int()]     # select the node ([1]) or nodes list([1, 2, 3, ...]) number directly from the mesh

"VAL":list()                        # value list of dislp on steps

Coupling

# ==============================================================================
# configuration of coupling applied to physics
# ==============================================================================
physicdata["COUPLING"] = dict()
keys
"TYPE": 
      # options
      'thermalstress',       # CouplSolver

      # [dev]
      'fsi'

# To perform a coupled analysis, the same model is used, and the post-processing
# data from the first simulation is passed as input to the coupled simulation.
"POST": [PostProcessData]   # post-processing data from the previous simulation
#                          myfempy solver blackbox structure
#                               Fist Simulation [1]

# input                                API                 outputs

# Model [1]                      +---------------+        
# BounCond + Loads [1]   -->     | FistSolver    |  -->    PostProcessData [1]
# SolverSet [1]                  +---------------+        


#                               Coupled Simulation [2]

# input                                API                 outputs

# Model [1]                     +---------------+        
# BounCond + Loads [2]  -->     | CouplSolver   |  -->     PostProcessData [2]
# PostProcessData [1]           +---------------+        
# SolverSet [2]                   
# ==============================================================================
# Finally, pass the physicdata to the Physic constructor API with the configured data and commands
# ==============================================================================
fea.Physic(physicdata)

Preview analysis

# ==============================================================================
# Preview set
# ==============================================================================
previewset = {'RENDER': 
{
'filename': str(),

'show': bool()
# options
    True
    False

'scale': int(),

'savepng': bool(),
# options
    True
    False

'lines': bool(),   # wireframe lines
# options
    True
    False

'plottags': {
# options
    'point': True/ False
    'line':  True/ False
    'surf':  True/ False
}

# beam cross-section view optinos
'cs': True,    
},
}
fea.PreviewAnalysis(previewset)

Solver Set

# ==============================================================================
# solver set
# ==============================================================================
solverset = {"STEPSET": 
{
'type': str()
    # options
    'table',      # tabulated values, e.g. [step0, step1, ..., stepN]
    'mode',       # vibration modes 
    'freq',       # frequency scale, np.linspace
    'time',       # time scale, np.linspace
'start': int(),   
'end': int(),
'step': int(),
    },

'SYMM': bool(),   # matrix symmetric assembler
# options
    True
    False

# [ adv ]
'IBZ': np.array(  # Brillouin zone
  [[0.0, 0.0],    # O 
   [np.pi, 0.0],  # A
   [np.pi, np.pi],# B
   [0.0, 0.0]]),  # O

#             (B)
#             /^
#            / |
#           /  |
#          /   |
#         /    |
#        /     |
#      </      |
#      (O)--->(A)    

# [ dev ]
'MP': bool(),     # multi processing 
# options
    True
    False
}
solverdata = fea.Solve(solverset)

Post-Process

# ==============================================================================
# post-process set
# ==============================================================================
postprocset = {
"SOLVERDATA": solverdata,

"COMPUTER": {
'structural': {
    'displ': True/ False, 
    'stress': True/ False}

'thermal': {
    'temp': True/ False,
    'heatflux': True/ False}

# [dev]
'fluid',
},

"PLOTSET": {
'show': True/ False, 
'filename': str(), 
'savepng': True/ False},

"OUTPUT": {
'log': True/ False, 
'get':{
    'nelem': True/ False,     # number of elements in the mesh
    'nnode': True/ False,     # number of nodes in the mesh
    'inci': True/ False,      # list of elements
    'coord':True/ False,      # list of nodes coodinate
    'tabmat':True/ False,     # list of material property
    'tabgeo':True/ False,     # list of geometry property
    'bc_list':True/ False,    # list of constraints (boundary conditions)
    'lo_list':True/ False,    # list of loads 
    'u_list':True/ False,     # list of solutions
    'numpy_decimals': int(),  # decimals to print, e.g. 8
}
}}
postprocdata = fea.PostProcess(postprocset)

Tutorials

The main objective of these tutorials is to help the user explore the various modeling and simulation options that the project allows.

This tutorial was developed during the initial implementation of the project; therefore, the information contained herein is not 100% up-to-date with the latest version of myfempy. See the API documentation for a more modern version.

Mesh

Manual Mesh

'''

Geração da malha manual

'''

# Imports

from myfempy import ModelGen
from myfempy import Solver
from myfempy import PostProcess
from myfempy import postproc_plot
from myfempy import preview_plot

# Definição do material, geometria 

mat = {
    "NAME": "material",
    "VXX": 0.25,
    "EXX": 200E6,
    "MAT": 'isotropic',
    "DEF": 'planestress'
    }

geo = {
    "NAME": "geometria",
    "THICKN": 1.0
    }

force = {
    'DEF': 'forceedge',
    'DOF': 'fx',
    'DIR': 'edgex',
    'LOC': {'x': 0, 'y': 999, 'z': 0},
    'VAL': [1.0],
    }

bondcond = {
    'DEF': 'fixed',
    'DOF': 'all',
    'DIR': 'edgey',
    'LOC': {'x': 999, 'y': 0, 'z': 0},
    }

# Retangulo estado plano (malha quad 4) 100 x 50 mm

elementos = [[1,"plane41","material","geometria",[1, 2, 3, 4]]]


coordenadas = [[1, 0, 0, 0],
               [2, 100, 0, 0],
               [3, 100, 50, 0],
               [4, 0, 50, 0]]


meshdata = {"ADD121": elementos,
            "NODELIST": coordenadas,
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            # "FORCES": [force],
            # "BOUNDCOND": [bondcond],
            # "QUADRATURE":{'meth':'gaussian','npp':8},
            }

modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_01a', 'show': True, 'scale': 1, 'savepng': True, 'lines': True},
              }

preview_plot(previewset, modelinfo)

# Retangulo estado plano (malha tria 4) 50 x 50 mm/ teste de qualidade 'Aspect Ratio'

elementos = [[1,"plane31","material","geometria",[1, 2, 4]],
             [2,"plane31","material","geometria",[2, 3, 4]]]


coordenadas = [[1, 0, 0, 0],
               [2, 50, 0, 0],
               [3, 50, 40, 0],
               [4, 0, 50, 0]]


meshdata = {"ADD121": elementos,
            "NODELIST": coordenadas,
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            # "FORCES": [force],
            # "BOUNDCOND": [bondcond],
            # "QUADRATURE":{'meth':'gaussian','npp':8},
            }

modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_01b', 'show': True, 'scale': 1, 'savepng': True, 'lines': True},
              'QUALITY': {'show': True, 'method': 1, 'scale': 0.1},
              }

preview_plot(previewset, modelinfo)

# Solido 100 x 100 x 100 mm

mat2 = {
    "NAME": "material2",
    "VXX": 0.25,
    "EXX": 200E6,
    "MAT": 'isotropic',
    "DEF": 'solid'
    }

geo2 = {
    "NAME": "geometria2",
    "THICKN": 0.0
    }

elementos = [[1,"solid81","material2","geometria2",[1, 2, 3, 4, 5, 6, 7, 8]]]

coordenadas = [[1, 0, 0, 0],
               [2, 100, 0, 0],
               [3, 100, 100, 0],
               [4, 0, 100, 0],
               [5, 0, 0, 100],
               [6, 100, 0, 100],
               [7, 100, 100, 100],
               [8, 0, 100, 100]]

meshdata = {"ADD121": elementos,
            "NODELIST": coordenadas,
            "PROPMAT": [mat2],
            "PROPGEO": [geo2],
            # "FORCES": [force],
            # "BOUNDCOND": [bondcond],
            # "QUADRATURE":{'meth':'gaussian','npp':8},
            }

modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_01c', 'show': True, 'scale': 1, 'savepng': True, 'lines': True},
              'LABELS': {'show': True, 'lines': True, 'scale': 10},
              }

preview_plot(previewset, modelinfo)

Legacy Mesh

'''

Geração da malha por meio da opção legacy

'''

# Imports

from myfempy import ModelGen
from myfempy import Solver
from myfempy import PostProcess
from myfempy import postproc_plot
from myfempy import preview_plot
from math import pi

import sys

# Definição do material, geometria 

mat = {
    "NAME": "material",
    "VXX": 0.25,
    "EXX": 200E6,
    "MAT": 'isotropic',
    "DEF": 'axial'
    }


geo = {
    "NAME": "geo",
    "SEC":"I",
    'DIM':{'b':100,'h':150,'t':5,'d':5}}

# Linha (malha beam 2) 500 mm

meshdata = {"LEGACY": {'lx': 400, 'mesh': 'line2', 'elem': 'beam21', 'nx': 2},
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            # "FORCES": [force],
            # "BOUNDCOND": [bondcond],
            # "QUADRATURE": {'meth': 'gaussian', 'npp': 4},
            # "DOMAIN":'structural'
            }


modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_02a', 'show': True, 'scale': 1, 'savepng': True, 'lines': True, 'cs': True},
              }

preview_plot(previewset, modelinfo)

# Definição do material, geometria 

mat = {
    "NAME": "material",
    "VXX": 0.25,
    "EXX": 200E6,
    "MAT": 'isotropic',
    "DEF": 'planestress'
    }

geo = {
    "NAME": "geometria",
    "THICKN": 1.0
    }


# Retangulo estado plano (malha quad 4) 100 x 50 mm

meshdata = {"LEGACY": {'lx': 100, 'ly': 50, 'mesh': 'quad4', 'elem': 'plane41', 'nx': 10, 'ny': 5},
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            # "FORCES": [force],
            # "BOUNDCOND": [bondcond],
            # "QUADRATURE": {'meth': 'gaussian', 'npp': 4},
            # "DOMAIN":'structural'
            }


modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_02b', 'show': True, 'scale': 1, 'savepng': True, 'lines': True},
              }

preview_plot(previewset, modelinfo)


# Retangulo estado plano (malha tria 3) 100 x 50 mm

meshdata = {"LEGACY": {'lx': 100, 'ly': 50, 'mesh': 'tria3', 'elem': 'plane31', 'nx': 10, 'ny': 5},
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            # "FORCES": [force],
            # "BOUNDCOND": [bondcond],
            # "QUADRATURE": {'meth': 'gaussian', 'npp': 4},
            # "DOMAIN":'structural'
            }


modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_02c', 'show': True, 'scale': 1, 'savepng': True, 'lines': True},
              }

preview_plot(previewset, modelinfo)

GMSH Mesh Basic

'''
Geração da malha com gmsh

Necessario instalação prévia do gmsh (não nativo do myfempy)

'''

# Imports

from myfempy import ModelGen
from myfempy import Solver
from myfempy import PostProcess
from myfempy import postproc_plot
from myfempy import preview_plot

# Definição do material, geometria 

mat = {
    "NAME": "material",
    "VXX": 0.25,
    "EXX": 200E6,
    "MAT": 'isotropic',
    "DEF": 'planestress'
    }

geo = {
    "NAME": "geometria",
    "THICKN": 1.0
    }


# Retangulo estado plano (malha quad 4) 100 x 50 mm


points = [[0, 0, 0],
          [100, 0, 0],
          [100, 50, 0],
          [0, 50, 0]]

lines = [[1, 2],
         [2, 3],
         [3, 4],
         [4, 1]]

plane = [[1, 2, 3, 4]]

meshdata = {"GMSH": {'filename': 'tutorial_03',
                     'pointlist': points,
                     'linelist': lines,
                     'planelist': plane,
                     'meshconfig': {
                         'mesh': 'tria3',   #quad4
                         'elem': 'plane31', #plane41
                         'sizeelement': 5,
                         'meshmap': {'on': True,
                                     'edge': [1, 2], #'all'
                                     "numbernodes": 10,
                                     }
                         }
                     },
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            }

modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_03',
                         'show': True, 'scale': 10,
                         'savepng': True,
                         'lines': True,
                         'plottags': {'point': True,
                                      'edge': True}},
              }

preview_plot(previewset, modelinfo)

# Placa L estado plano (malha quad 4) 100 x 100 mm

points = [[0, 0, 0],
          [100, 0, 0],
          [100, 50, 0],
          [50, 50, 0],
          [50, 100, 0],
          [0, 100, 0],
          ]

lines = [[1, 2],
         [2, 3],
         [3, 4],
         [4, 5],
         [5, 6],
         [6, 1],
         ]

plane = [[1, 2, 3, 4, 5, 6]]

meshdata = {"GMSH": {'filename': 'tutorial_03',
                     'pointlist': points,
                     'linelist': lines,
                     'planelist': plane,
                     'meshconfig': {
                         'mesh': 'quad4',   #tria3
                         'elem': 'plane41', #plane31
                         'sizeelement': 5,
                         'meshmap': {'on': True,
                                     'edge': 'all',
                                    #  "numbernodes": 10,
                                     }
                         }
                     },
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            }

modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_03',
                         'show': True,
                         'scale': 10,
                         'savepng': True,
                         'lines': True,
                         'plottags': {'point': True,
                                      'edge': True}},
              }

preview_plot(previewset, modelinfo)

# Placa H estado plano (malha quad 4) 100 x 100 mm
points = [
    [0, 0, 0],
    [20, 0, 0],
    [20, 30, 0],
    [80, 30, 0],
    [80, 0, 0],
    [100, 0, 0],
    [100, 100, 0],
    [80, 100, 0],
    [80, 70, 0],
    [20, 70, 0],
    [20, 100, 0],
    [0, 100, 0],
    ]

lines = [[1, 2],
         [2, 3],
         [3, 4],
         [4, 5],
         [5, 6],
         [6, 7],
         [7, 8],
         [8, 9],
         [9, 10],
         [10, 11],
         [11, 12],
         [12, 1],
         ]

plane = [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]]

meshdata = {"GMSH": {'filename': 'tutorial_03',
                     'pointlist': points,
                     'linelist': lines,
                     'planelist': plane,
                     'meshconfig': {
                         'mesh': 'quad4',   #tria3
                         'elem': 'plane41', #plane31
                         'sizeelement': 5,
                         'meshmap': {'on': True,
                                     'edge': 'all',
                                    #  "numbernodes": 10,
                                     }
                         }
                     },
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            }

modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_03',
                         'show': True,
                         'scale': 10,
                         'savepng': True,
                         'lines': True,
                         'plottags': {
                            'point': True,
                            # 'edge': True
                            }
                        },
              }

preview_plot(previewset, modelinfo)

GMSH Mesh Advanced

'''
Geração da malha com gmsh/ criação de curvas e furos e áreas compostas

Necessario instalação prévia do gmsh (não nativo do myfempy)

'''

# Imports

from myfempy import ModelGen
from myfempy import Solver
from myfempy import PostProcess
from myfempy import postproc_plot
from myfempy import preview_plot

import sys

# Definição do material, geometria 

mat = {
    "NAME": "material",
    "VXX": 0.25,
    "EXX": 200E6,
    "MAT": 'isotropic',
    "DEF": 'planestress'
    }

geo = {
    "NAME": "geometria",
    "THICKN": 1.0
    }

# 1/4 de placa com furo central (dia. 100 mm) estado plano (malha quad 4) 200 x 200 mm

points = [
    [100, 0, 0],
    [100, 100, 0],
    [0, 100, 0],
]

circle = [[50, [0, 0, 0], ['0', 'Pi/2']]]

lines = [[1, 2],
         [2, 3],
         [3, 5],
         [4, 1],
         ]

plane = [[1, 2, 3, 4, 5]]

meshdata = {"GMSH": {'filename': 'tutorial_04a',
                     'pointlist': points,
                     'linelist': lines,
                     'planelist': plane,
                     'circle': circle,
                     'meshconfig': {
                         'mesh': 'quad4',   #quad4
                         'elem': 'plane41', #plane41
                         'sizeelement': 5,
                         'meshmap': {'on': True,
                                     'edge': 'all', #'all'
                                    #  "numbernodes": 10,
                                     }
                         }
                     },
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            }

modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_04a',
                         'show': True, 'scale': 10,
                         'savepng': True,
                         'lines': True,
                         'plottags': {'point': True,
                                      'edge': True}},
              }

preview_plot(previewset, modelinfo)

# Placa completa multiplos furos (dia. 10, 10, 30 mm) estado plano (malha quad 4) 200 x 200 mm

points = [
    [0, 0, 0],
    [200, 0, 0],
    [200, 200, 0],
    [0, 200, 0],
]


lines = [[1, 2], # line 1
         [2, 3], # line 2
         [3, 4], # line 3
         [4, 1], # line 4
         ]

circle = [[30, [150, 100, 0], ['0', '2*Pi']], # line 5
        [10, [30, 150, 0], ['0', '2*Pi']],  # line 6
        [10, [30, 50, 0], ['0', '2*Pi']],   # line 7
        ]

plane = [[1, 2, 3, 4],
        [-5],
        [-6],
        [-7],
        [5],
        [6],
        [7]
        ]

meshdata = {"GMSH": {'filename': 'tutorial_04b',
                     'pointlist': points,
                     'linelist': lines,
                     'circle': circle,
                     'planelist': plane,
                     'meshconfig': {
                         'mesh': 'quad4',   #quad4
                         'elem': 'plane41', #plane41
                         'sizeelement': 10,
                        #  'meshmap': {'on': True,
                        #              'edge': [5], #'all'
                        #              "numbernodes": 60,
                        #              }
                         }
                     },
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            }


modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_04b',
                         'show': True, 'scale': 10,
                         'savepng': True,
                         'lines': True,
                         'plottags': {
                            # 'point': True,
                            # 'edge': True,
                            'surf': True
                                      }},
            'LABELS': {'show': True, 'lines': True, 'scale': 0.2},
              }

preview_plot(previewset, modelinfo)

# Placa completa furo quadrado central (dia. 50 mm) estado plano (malha quad 4) 200 x 200 mm

points = [
    [0, 0, 0],
    [200, 0, 0],
    [200, 100, 0],
    [0, 100, 0],
    [75, 25, 0],
    [125, 25, 0],
    [125, 75, 0],
    [75, 75, 0],
    ]


lines = [[1, 2], # line 1
         [2, 3], # line 2
         [3, 4], # line 3
         [4, 1], # line 4
         [5, 6], # line 5
         [6, 7], # line 6
         [7, 8], # line 7
         [8, 5], # line 8
         ]


plane = [[1, 2, 3, 4],
        [-5, -6, -7, -8],
        # [5, 6, 7, 8]
        ]

meshdata = {"GMSH": {'filename': 'tutorial_04c',
                     'pointlist': points,
                     'linelist': lines,
                     'planelist': plane,
                     'meshconfig': {
                         'mesh': 'quad4',   #quad4
                         'elem': 'plane41', #plane41
                         'sizeelement': 2,
                         'meshmap': {'on': True,
                                     'edge': 'all', #'all'
                                    #  "numbernodes": 10,
                                     }
                         }
                     },
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            }


modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_04c',
                         'show': True, 'scale': 10,
                         'savepng': True,
                         'lines': True,
                         'plottags': {
                            'point': True,
                            # 'edge': True,
                            # 'surf': True
                            }},
              }

preview_plot(previewset, modelinfo)

# Duas Placa composta estado plano (malha quad 4) 200 x 200 mm

points = [
    [0, 0, 0],     # point 1
    [100, 0, 0],   # point 2
    [100, 100, 0], # point 3
    [0, 100, 0],   # point 4
    [200, 0, 0],   # point 5
    [200, 100, 0], # point 6
    ]


lines = [[1, 2], # line 1
         [2, 3], # line 2
         [3, 4], # line 3
         [4, 1], # line 4
         [2, 5], # line 5
         [5, 6], # line 6
         [6, 3], # line 7
         ]


plane = [[1, 2, 3, 4], # plane 1
        [5, 6, 7, 2],  # plane 2
        ]

meshdata = {"GMSH": {'filename': 'tutorial_04d',
                     'pointlist': points,
                     'linelist': lines,
                     'planelist': plane,
                     'meshconfig': {
                         'mesh': 'quad4',   #quad4
                         'elem': 'plane41', #plane41
                         'sizeelement': 5,
                         'meshmap': {'on': True,
                                     'edge': [2, 6], #'all'
                                     "numbernodes": 10,
                                     }
                         }
                     },
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            }


modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_04d',
                         'show': True, 'scale': 10,
                         'savepng': True,
                         'lines': True,
                         'plottags': {
                            # 'point': True,
                            'edge': True,
                            # 'surf': True
                            }},
              }

preview_plot(previewset, modelinfo)


# Duas Placa composta com furo em 0,0,0 (dia. 50 mm) estado plano (malha quad 4) 200 x 200 mm

points = [
    [100, 0, 0],   # point 1
    [100, 100, 0], # point 2
    [0, 100, 0],   # point 3
    [200, 0, 0],   # point 4
    [200, 100, 0], # point 5
    ]


lines = [
    [6, 1], # line 1
    [1, 2], # line 2
    [2, 3], # line 3
    [3, 7], # line 4
    [1, 4], # line 5
    [4, 5], # line 6
    [5, 2], # line 7
    ]   

circle = [[50, [0, 0, 0], ['0', 'Pi/2']], # line 8
        ]

plane = [[1, 2, 3, 4, 8], # plane 1
        [5, 6, 7, 2],  # plane 2
        ]

meshdata = {"GMSH": {'filename': 'tutorial_04e',
                     'pointlist': points,
                     'linelist': lines,
                     'circle': circle,
                     'planelist': plane,
                     'meshconfig': {
                         'mesh': 'tria3',   #quad4
                         'elem': 'plane31', #plane41
                         'sizeelement': 10,
                         'meshmap': {'on': True,
                                     'edge': [8], #'all'
                                     "numbernodes": 20,
                                     }
                         }
                     },
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            }


modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_04e',
                         'show': True, 'scale': 10,
                         'savepng': True,
                         'lines': True,
                         'plottags': {
                            # 'point': True,
                            'edge': True,
                            # 'surf': True
                            }},
              }

preview_plot(previewset, modelinfo)


# disco (dia. 200 mm) com furo central (dia. 100 mm) estado plano (malha quad 4)

points = [
    # [100, 0, 0],
    # [100, 100, 0],
    # [0, 100, 0],
]

lines = [
    # [1, 2],
    # [2, 3],
    # [3, 5],
    # [4, 1],
         ]

circle = [[200, [0, 0, 0], ['0', '2*Pi']],[100, [0, 0, 0], ['0', '2*Pi']]]

plane = [[1],[-2]]

meshdata = {"GMSH": {'filename': 'tutorial_04f',
                     'pointlist': points,
                     'linelist': lines,
                     'planelist': plane,
                     'circle': circle,
                     'meshconfig': {
                         'mesh': 'tria3',   #quad4
                         'elem': 'plane31', #plane41
                         'sizeelement': 40,
                         'meshmap': {'on': True,
                                     'edge': 'all', #'all'
                                    #  "numbernodes": 80,
                                     }
                         }
                     },
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            }

modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_04f',
                         'show': True, 'scale': 10,
                         'savepng': True,
                         'lines': True,
                         'plottags': {
                            'edge': True,
                            # 'surf': True
                            }},
            # 'LABELS': {'show': True, 'lines': True, 'scale': 10},
              }

preview_plot(previewset, modelinfo)


# 1/4 de placa com bara no furo central (dia. 100 mm) estado plano (malha quad 4) 200 x 200 mm

points = [
    [100, 0, 0],
    [100, 100, 0],
    [0, 100, 0],
    [0, 0, 0],
]

lines = [[1, 2],
         [2, 3],
         [3, 6],
         [5, 1],
         [4, 5],
         [6, 4],
         ]

circle = [[50, [0, 0, 0], ['0', 'Pi/2']]]

plane = [[1, 2, 3, 4, 7],[5, 6, 7]]

meshdata = {"GMSH": {'filename': 'tutorial_04g',
                     'pointlist': points,
                     'linelist': lines,
                     'planelist': plane,
                     'circle': circle,
                     'meshconfig': {
                         'mesh': 'quad4',   #quad4
                         'elem': 'plane41', #plane41
                         'sizeelement': 10,
                         'meshmap': {'on': True,
                                     'edge': [7], #'all'
                                    #  "numbernodes": 10,
                                     }
                         }
                     },
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            }

modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_04g',
                         'show': True, 'scale': 10,
                         'savepng': True,
                         'lines': True,
                         'plottags': {
                                # 'point': True,
                                # 'edge': True,
                                'surf': True,
                                }},
              }

preview_plot(previewset, modelinfo)


#-----------------------------------------------------

# 1/4 de placa com furo central (dia. 100 mm) estado plano (malha quad 4) 200 x 200 mm malha mapeada

points = [
    [100, 0, 0],
    [100, 100, 0],
    [0, 100, 0],
]

lines = [[1, 2], # 1
         [2, 3], # 2
         [3, 7], # 3
         [4, 1], # 4
         [2, 5], # 5
         ]

circle = [[50, [0, 0, 0], ['0', 'Pi/4']],    # 6
        [50, [0, 0, 0], ['Pi/4', 'Pi/2']]] # 7

plane = [[1, 5, 6, 4],
         [5, 2, 3, 7]]

meshdata = {"GMSH": {'filename': 'tutorial_04h',
                     'pointlist': points,
                     'linelist': lines,
                     'planelist': plane,
                     'circle': circle,
                     'meshconfig': {
                         'mesh': 'quad4',   #quad4
                         'elem': 'plane41', #plane41
                         'sizeelement': 10,
                         'meshmap': {'on': True,
                                     'edge': 'all', #'all'
                                     "numbernodes": 10,
                                     }
                         }
                     },
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            }

modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_04h',
                         'show': True, 'scale': 10,
                         'savepng': True,
                         'lines': True,
                         'plottags': {
                            'point': True,
                            # 'edge': True
                            }},
            # 'LABELS': {'show': True, 'lines': True, 'scale': 0.5},   
              }

preview_plot(previewset, modelinfo)

GMSH Mesh Solids

'''

Geração da malha com gmsh/ solidos

Necessario instalação prévia do gmsh (não nativo do myfempy)

'''

# Imports

from myfempy import ModelGen
from myfempy import Solver
from myfempy import PostProcess
from myfempy import postproc_plot
from myfempy import preview_plot

import sys

# Definição do material, geometria 

mat = {
    "NAME": "material",
    "VXX": 0.25,
    "EXX": 200E6,
    "MAT": 'isotropic',
    "DEF": 'planestress'
    }

geo = {
    "NAME": "geometria",
    "THICKN": 1.0
    }

# 1/4 de placa com furo central (dia. 100 mm) estado plano (malha quad 4) 200 x 200 mm, espessura da placa de 20 mm

points = [
    [100, 0, 0],
    [100, 100, 0],
    [0, 100, 0],
]

lines = [[1, 2],
         [2, 3],
         [3, 5],
         [4, 1],
         ]

arcs = [[50, [0, 0, 0], ['0', 'Pi/2']]]

plane = [[1, 2, 3, 4, 5]]

meshdata = {"GMSH": {'filename': 'tutorial_05a',
                     'pointlist': points,
                     'linelist': lines,
                     'planelist': plane,
                     'arc': arcs,
                     'meshconfig': {
                         'mesh': 'tetr4',   #tetr4 hexa8
                         'elem': 'solid41', #solid41 solid81
                         'sizeelement': 5,
                         'extrude': 20,
                         'meshmap': {'on': True,
                                     'edge': 'all', #'all'
                                    #  "numbernodes": 10,
                                     }
                         }
                     },
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            }

modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_05a',
                         'show': True, 'scale': 10,
                         'savepng': True,
                         'lines': True,
                         'plottags': {'point': True,
                                      'edge': True}},
              }

preview_plot(previewset, modelinfo)

# Placa completa multiplos furos (dia. 10, 10, 30 mm) estado plano (malha quad 4) 200 x 200 mm, espessura da placa de 20 mm

points = [
    [0, 0, 0],
    [200, 0, 0],
    [200, 200, 0],
    [0, 200, 0],
]


lines = [[1, 2], # line 1
         [2, 3], # line 2
         [3, 4], # line 3
         [4, 1], # line 4
         ]

arcs = [[30, [150, 100, 0], ['0', '2*Pi']], # line 5
        [10, [30, 150, 0], ['0', '2*Pi']],  # line 6
        [10, [30, 50, 0], ['0', '2*Pi']],   # line 7
        ]

plane = [[1, 2, 3, 4],
        [-5],
        [-6],
        [-7],
        # [5],
        # [6],
        # [7]
        ]

meshdata = {"GMSH": {'filename': 'tutorial_05b',
                     'pointlist': points,
                     'linelist': lines,
                     'arc': arcs,
                     'planelist': plane,
                     'meshconfig': {
                         'mesh': 'tetr4',   #tetr4 hexa8
                         'elem': 'solid41', #solid41 solid81
                         'sizeelement': 5,
                         'extrude': 20,
                         'meshmap': {'on': True,
                                     'edge': 'all', #'all'
                                    #  "numbernodes": 10,
                                     }
                         }
                     },
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            }


modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_05b',
                         'show': True, 'scale': 10,
                         'savepng': True,
                         'lines': True,
                         'plottags': {
                            # 'point': True,
                            # 'edge': True,
                            'surf': True
                                      }},
              }

preview_plot(previewset, modelinfo)

# Placa completa furo quadrado central (dia. 50 mm) estado plano (malha quad 4) 200 x 200 mm, espessura da placa de 20 mm

points = [
    [0, 0, 0],
    [200, 0, 0],
    [200, 100, 0],
    [0, 100, 0],
    [75, 25, 0],
    [125, 25, 0],
    [125, 75, 0],
    [75, 75, 0],
    ]


lines = [[1, 2], # line 1
         [2, 3], # line 2
         [3, 4], # line 3
         [4, 1], # line 4
         [5, 6], # line 5
         [6, 7], # line 6
         [7, 8], # line 7
         [8, 5], # line 8
         ]


plane = [[1, 2, 3, 4],
        [-5, -6, -7, -8],
        # [5, 6, 7, 8]
        ]

meshdata = {"GMSH": {'filename': 'tutorial_05c',
                     'pointlist': points,
                     'linelist': lines,
                     'planelist': plane,
                     'meshconfig': {
                         'mesh': 'hexa8',   #tetr4 hexa8
                         'elem': 'solid81', #solid41 solid81
                         'sizeelement': 5,
                         'extrude': 20,
                         'meshmap': {'on': True,
                                     'edge': 'all', #'all'
                                    #  "numbernodes": 10,
                                     }
                         }
                     },
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            }


modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_05c',
                         'show': True, 'scale': 10,
                         'savepng': True,
                         'lines': True,
                         'plottags': {
                            'point': True,
                            # 'edge': True,
                            # 'surf': True
                            }},
              }

preview_plot(previewset, modelinfo)

# Duas Placa composta estado plano (malha quad 4) 200 x 200 mm, espessura da placa de 20 mm

points = [
    [0, 0, 0],     # point 1
    [100, 0, 0],   # point 2
    [100, 100, 0], # point 3
    [0, 100, 0],   # point 4
    [200, 0, 0],   # point 5
    [200, 100, 0], # point 6
    ]


lines = [[1, 2], # line 1
         [2, 3], # line 2
         [3, 4], # line 3
         [4, 1], # line 4
         [2, 5], # line 5
         [5, 6], # line 6
         [6, 3], # line 7
         ]


plane = [[1, 2, 3, 4], # plane 1
        [5, 6, 7, 2],  # plane 2
        ]

meshdata = {"GMSH": {'filename': 'tutorial_05d',
                     'pointlist': points,
                     'linelist': lines,
                     'planelist': plane,
                     'meshconfig': {
                         'mesh': 'tetr4',   #tetr4 hexa8
                         'elem': 'solid41', #solid41 solid81
                         'sizeelement': 5,
                         'extrude': 20,
                         'meshmap': {'on': True,
                                     'edge': [2, 6], #'all'
                                     "numbernodes": 10,
                                     }
                         }
                     },
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            }


modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_05d',
                         'show': True, 'scale': 10,
                         'savepng': True,
                         'lines': True,
                         'plottags': {
                            # 'point': True,
                            'edge': True,
                            # 'surf': True
                            }},
              }

preview_plot(previewset, modelinfo)


# ------------------------------------------------------

# Duas Placa composta com furo em 0,0,0 (dia. 50 mm) estado plano (malha quad 4) 200 x 200 mm, espessura da placa de 20 mm

points = [
    [100, 0, 0],   # point 1
    [100, 100, 0], # point 2
    [0, 100, 0],   # point 3
    [200, 0, 0],   # point 4
    [200, 100, 0], # point 5
    ]


lines = [
    [6, 1], # line 1
    [1, 2], # line 2
    [2, 3], # line 3
    [3, 7], # line 4
    [1, 4], # line 5
    [4, 5], # line 6
    [5, 2], # line 7
    ]   

arcs = [[50, [0, 0, 0], ['0', 'Pi/2']], # line 8
        ]

plane = [[1, 2, 3, 4, 8], # plane 1
        [5, 6, 7, 2],  # plane 2
        ]

meshdata = {"GMSH": {'filename': 'tutorial_05e',
                     'pointlist': points,
                     'linelist': lines,
                     'arc': arcs,
                     'planelist': plane,
                     'meshconfig': {
                         'mesh': 'tetr4',   #tetr4 hexa8
                         'elem': 'solid41', #solid41 solid81
                         'sizeelement': 5,
                         'extrude': 20,
                         'meshmap': {'on': False,
                                     'edge': 'all',
                                     "numbernodes": 20,
                                     }
                         }
                     },
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            }


modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_05e',
                         'show': True, 'scale': 10,
                         'savepng': True,
                         'lines': True,
                         'plottags': {
                            # 'point': True,
                            # 'edge': True,
                            'surf': True
                            }},
              }

preview_plot(previewset, modelinfo)

GMSH Mesh Importing CAD models (.stp/.step)

'''

Geração da malha com gmsh/ importação de modelos cad (.stp/ .step)

Necessario instalação prévia do gmsh (não nativo do myfempy)

'''

# Imports

from myfempy import ModelGen
from myfempy import Solver
from myfempy import PostProcess
from myfempy import postproc_plot
from myfempy import preview_plot

import sys

# Definição do material, geometria 

mat = {
    "NAME": "material",
    "VXX": 0.25,
    "EXX": 200E6,
    "MAT": 'isotropic',
    "DEF": 'planestress'
    }

geo = {
    "NAME": "geometria",
    "THICKN": 1.0
    }

# import cad .stp

meshdata = {"GMSH": {'filename': 'tutorial_06a',
                     'cadimport': {'object': 'tutorial_06_cad.stp'},
                     'meshconfig': {'mesh': 'tetr4', 'elem': 'solid41', 'sizeelement': 10}},
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            }

modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_06a',
                         'show': True, 'scale': 10,
                         'savepng': True,
                         'lines': True,
                         'plottags': {'point': False,
                                      'edge': False}},
              }

preview_plot(previewset, modelinfo)

GMSH Mesh Importing mesh files (.msh2)

'''

Geração da malha com gmsh/ importação de malha (.vtk) externa

Necessario instalação prévia do gmsh (não nativo do myfempy)

'''

# Imports

from myfempy import ModelGen
from myfempy import Solver
from myfempy import PostProcess
from myfempy import postproc_plot
from myfempy import preview_plot

import sys

# Definição do material, geometria 

mat = {
    "NAME": "material",
    "VXX": 0.25,
    "EXX": 200E6,
    "MAT": 'isotropic',
    "DEF": 'planestress'
    }

geo = {
    "NAME": "geometria",
    "THICKN": 1.0
    }


# import mesh .msh2

meshdata = {"GMSH": {'filename': 'tutorial_06b',
                     'meshimport':{'object':'tutorial_06_mesh'},
                     'meshconfig': {'mesh': 'tetr4', 'elem': 'solid41', 'sizeelement': 10}},
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            }

modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_06b',
                         'show': True, 'scale': 10,
                         'savepng': True,
                         'lines': True,
                         'plottags': {'point': False,
                                      'surf': True}},
              }

preview_plot(previewset, modelinfo)

Simulations

Structural Static

'''

Simulação estática com malha manual

'''

# Imports

from myfempy import ModelGen
from myfempy import Solver
from myfempy import PostProcess
from myfempy import postproc_plot
from myfempy import preview_plot

# Definição do material, geometria 

mat = {
    "NAME": "material",
    "VXX": 0.25,
    "EXX": 200E6,
    "MAT": 'isotropic',
    "DEF": 'planestress'
    }

geo = {
    "NAME": "geometria",
    "THICKN": 1.0
    }

# Retangulo estado plano (malha manual quad 4) 100 x 50 mm com forcas e bc. nodais

f1 = {
    'DEF': 'forcenode',
    'DOF': 'fy',
    'DIR': 'node',
    'LOC': {'x': 100, 'y': 0, 'z': 0},
    'VAL': [-1000.0],
    }

f2 = {
    'DEF': 'forcenode',
    'DOF': 'fy',
    'DIR': 'node',
    'LOC': {'x': 100, 'y': 50, 'z': 0},
    'VAL': [-1000.0],
    }

bc1 = {
    'DEF': 'fixed',
    'DOF': 'all',
    'DIR': 'node',
    'LOC': {'x': 0, 'y': 0, 'z': 0},
    }

bc2 = {
    'DEF': 'fixed',
    'DOF': 'ux',
    'DIR': 'node',
    'LOC': {'x': 0, 'y': 50, 'z': 0},
    }


elementos = [[1,"plane41","material","geometria",[1, 2, 3, 4]]]


coordenadas = [[1, 0, 0, 0],
               [2, 100, 0, 0],
               [3, 100, 50, 0],
               [4, 0, 50, 0]]


meshdata = {"ADD121": elementos,
            "NODELIST": coordenadas,
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            "FORCES": [f1,f2],
            "BOUNDCOND": [bc1,bc2],
            "QUADRATURE":{'meth':'gaussian','npp':4},
            }

modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_01a', 'show': True, 'scale': 10, 'savepng': True, 'lines': True},
              'LABELS': {'show': True, 'lines': True, 'scale': 10},
              }

preview_plot(previewset, modelinfo)

# Retangulo estado plano (malha manual quad 4) 100 x 50 mm com forcas distribuida e bc. nodais

f1 = {
    'DEF': 'forceedge',
    'DOF': 'fy',
    'DIR': 'edgex',
    'LOC': {'x': 100, 'y': 999, 'z': 0},
    'VAL': [-1000.0],
    }

bc1 = {
    'DEF': 'fixed',
    'DOF': 'all',
    'DIR': 'node',
    'LOC': {'x': 0, 'y': 0, 'z': 0},
    }

bc2 = {
    'DEF': 'fixed',
    'DOF': 'ux',
    'DIR': 'node',
    'LOC': {'x': 0, 'y': 50, 'z': 0},
    }


elementos = [[1,"plane41","material","geometria",[1, 2, 3, 4]]]


coordenadas = [[1, 0, 0, 0],
               [2, 100, 0, 0],
               [3, 100, 50, 0],
               [4, 0, 50, 0]]


meshdata = {"ADD121": elementos,
            "NODELIST": coordenadas,
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            "FORCES": [f1],
            "BOUNDCOND": [bc1,bc2],
            "QUADRATURE":{'meth':'gaussian','npp':4},
            }

modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_01b', 'show': True, 'scale': 10, 'savepng': True, 'lines': True},
              'LABELS': {'show': True, 'lines': True, 'scale': 10},
              }

preview_plot(previewset, modelinfo)

# Retangulo estado plano (malha legacy quad 4 10x5) 100 x 50 mm com forcas e bc distribuida

f1 = {
    'DEF': 'forceedge',
    'DOF': 'fy',
    'DIR': 'edgey',
    'LOC': {'x': 999, 'y': 50, 'z': 0},
    'VAL': [-1000.0],
    }

bc1 = {
    'DEF': 'fixed',
    'DOF': 'ux',
    'DIR': 'edgex',
    'LOC': {'x': 0, 'y': 999, 'z': 0},
    }

bc2 = {
    'DEF': 'fixed',
    'DOF': 'all',
    'DIR': 'node',
    'LOC': {'x': 100, 'y': 0, 'z': 0},
    }

meshdata = {"LEGACY": {'lx': 100, 'ly': 50, 'mesh': 'quad4', 'elem': 'plane41', 'nx': 10, 'ny': 5},
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            "FORCES": [f1],
            "BOUNDCOND": [bc1,bc2],
            "QUADRATURE": {'meth': 'gaussian', 'npp': 4},
            # "DOMAIN":'structural'
            }

modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_01c', 'show': True, 'scale': 10, 'savepng': True, 'lines': True},
              'LABELS': {'show': True, 'lines': True, 'scale': 10},
              }

preview_plot(previewset, modelinfo)


# Retangulo estado plano (malha manual quad 4) 100 x 50 mm com massa e mola concentrada

f1 = {
    'DEF': 'forcenode',
    'DOF': 'spring2ground',
    'DIR': 'node',
    'LOC': {'x': 100, 'y': 0, 'z': 0},
    'VAL': [100.0],
    }

f2 = {
    'DEF': 'forcenode',
    'DOF': 'damper2ground',
    'DIR': 'node',
    'LOC': {'x': 100, 'y': 50, 'z': 0},
    'VAL': [100.0],
    }

f3 = {
    'DEF': 'forcenode',
    'DOF': 'masspoint',
    'DIR': 'node',
    'LOC': {'x': 100, 'y': 50, 'z': 0},
    'VAL': [1.0],
    }

bc1 = {
    'DEF': 'fixed',
    'DOF': 'all',
    'DIR': 'node',
    'LOC': {'x': 0, 'y': 0, 'z': 0},
    }

bc2 = {
    'DEF': 'fixed',
    'DOF': 'ux',
    'DIR': 'node',
    'LOC': {'x': 0, 'y': 50, 'z': 0},
    }


elementos = [[1,"plane41","material","geometria",[1, 2, 3, 4]]]


coordenadas = [[1, 0, 0, 0],
               [2, 100, 0, 0],
               [3, 100, 50, 0],
               [4, 0, 50, 0]]


meshdata = {"ADD121": elementos,
            "NODELIST": coordenadas,
            "PROPMAT": [mat],
            "PROPGEO": [geo],
            "FORCES": [f1,f2,f3],
            "BOUNDCOND": [bc1,bc2],
            "QUADRATURE":{'meth':'gaussian','npp':4},
            }

modelinfo = ModelGen.get_model(meshdata)

previewset = {'RENDER': {'filename': 'tutorial_01a', 'show': True, 'scale': 10, 'savepng': True, 'lines': True},
            #   'LABELS': {'show': True, 'lines': True, 'scale': 10},
              }

preview_plot(previewset, modelinfo)

# Retangulo estado plano dois materiais (malha manual quad 4) 200 x 100 mm com forcas e bc. nodais

mat2 = {
    "NAME": "material2",
    "VXX": 0.25,
    "EXX": 200E6,
    "MAT": 'isotropic',
    "DEF": 'planestress'
    }

geo2 = {
    "NAME": "geometria2",
    "THICKN": 1.0
    }

f1 = {
    'DEF': 'forcenode',
    'DOF': 'fy',
    'DIR': 'node',
    'LOC': {'x': 0, 'y': 100, 'z': 0},
    'VAL': [-100.0],
    }

f2 = {
    'DEF': 'forcenode',
    'DOF': 'fy',
    'DIR': 'node',
    'LOC': {'x': 100, 'y': 100, 'z': 0},
    'VAL': [-100.0],
    }

f3 = {
    'DEF': 'forcenode',
    'DOF': 'fy',
    'DIR': 'node',
    'LOC': {'x': 200, 'y': 100, 'z': 0},
    'VAL': [-100.0],
    }

bc1 = {
    'DEF': 'fixed',
    'DOF': 'all',
    'DIR': 'node',
    'LOC': {'x': 200, 'y': 0, 'z': 0},
    }

bc2 = {
    'DEF': 'fixed',
    'DOF': 'ux',
    'DIR': 'node',
    'LOC': {'x': 0, 'y': 0, 'z': 0},
    }

bc3 = {
    'DEF': 'fixed',
    'DOF': 'ux',
    'DIR': 'node',
    'LOC': {'x': 0, 'y': 100, 'z': 0},
    }


elementos = [[1,"plane41","material","geometria",[1, 2, 3, 4]],
             [2,"plane41","material2","geometria2",[2, 5, 6, 3]]]


coordenadas = [[1, 0, 0, 0],
               [2, 100, 0, 0],
               [3, 100, 100, 0],
               [4, 0, 100, 0],
               [5, 200, 0, 0],
               [6, 200, 100, 0]]


meshdata = {"ADD121": elementos,
            "NODELIST": coordenadas,
            "PROPMAT": [mat,mat2],
            "PROPGEO": [geo,geo2],
            "FORCES": [f1,f2,f3],
            "BOUNDCOND": [bc1,bc2,bc3],
            "QUADRATURE":{'meth':'gaussian','npp':4},
            }

modelinfo = ModelGen.get_model(meshdata)

print(modelinfo['inci'])

previewset = {'RENDER': {'filename': 'tutorial_01a', 'show': True, 'scale': 10, 'savepng': True, 'lines': True},
              'LABELS': {'show': True, 'lines': True, 'scale': 10},
              }

preview_plot(previewset, modelinfo)

Structural Static Solid Gmsh API

'''

Simulação estática em sólido com geração de malha com gmsh

Necessario instalação prévia do gmsh (não nativo do myfempy)

'''
# from os import environ
# environ['OMP_NUM_THREADS'] = '1'        #win
import numpy as np
import matplotlib.pyplot as plt

from myfempy import newAnalysis
from myfempy import SteadyStateLinear, SteadyStateLinearIterative

from time import time

# ===============================================================================
#                                   FEA
# ===============================================================================
fea = newAnalysis(SteadyStateLinear) # StaticLinearIterative FASTER THEN StaticLinear
# MODEL SET
mat1 = {
    "NAME": "aco",
    "VXY": 0.33,
    "EXX": 71E3,
    # "RHO": 1,    # kg/mm^2
    }

geo2 = {"NAME": "secao1",}

# MODEL SET
# mesh tetra 4
nodes = [[1, 0, 0, 0],
         [2, 1, 0, 0],
         [3, 0, 1, 0],
         [4, 0, 0, 1]]

# nodes = [[1, 500.,  500.,    0.],
#         [2,   0.,  500.,  250.],
#         [3,   0., 1000.,    0.],
#         [4,   0.,    0.,    0.]]
conec = [[1, 1, 1, 1, 2, 3, 4]]


# mesh hexa 8
nodes = [
    [1, 0, 0, 0],  # Nó 1
    [2, 1, 0, 0],  # Nó 2
    [3, 1, 1, 0],  # Nó 3
    [4, 0, 1, 0],  # Nó 4
    [5, 0, 0, 1],  # Nó 5
    [6, 1, 0, 1],  # Nó 6
    [7, 1, 1, 1],  # Nó 7
    [8, 0, 1, 1]   # Nó 8
]   
conec = [[1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8]]

# # gmsh config
LX = 200
LY = 20
LZ = 20

points = [
    [0, 0, 0],
    [LX, 0, 0],
    [LX, LY, 0],
    [0, LY, 0],
]

lines = [[1, 2],
         [2, 3],
         [3, 4],
         [4, 1],
         ]

plane = [[1, 2, 3, 4]]

modeldata = {
    # "MESH": {
    #     'TYPE': 'manual',
    #     'COORD': nodes,
    #     'INCI': conec,
    #     },

   "MESH": {
        'TYPE': 'gmsh',
        'filename': 'data_mesh',
        'pointlist': points,
        'linelist': lines,
        'planelist': plane,
        'meshconfig': {
            'mesh': 'hexa8',
            # "numbernodes": 21,
            'sizeelement': 10,
            'extrude': LZ,
            'meshmap': {'on': True,
                        'edge': 'all',
                        "numbernodes": [20],
            }
            }
    },

    "ELEMENT": {
        'TYPE': 'structsolid',
        'SHAPE': 'hexa8',
        # 'INTGAUSS': 4,
    },

    "MATERIAL": {
        "MAT": 'solidelastic',
        "TYPE": 'isotropic',
        "PROPMAT": [mat1],
    },

    "GEOMETRY": {
        "GEO": 'solid',
        "PROPGEO": [geo2],
    },
}
fea.Model(modeldata)

inci = fea.getInci()
coord = fea.getCoord()
# tabmat = fea.getTabmat()
# tabgeo = fea.getTabgeo()
# intgauss = fea.getIntGauss()
# print(intgauss)

# vol = fea.getElementVolume(inci, coord, tabgeo)
# print('Volume ',np.sum(vol))

# reg = fea.getRegions()
# print(reg)


# sys.exit()

# element_number = 0
# st = time()
# ke = fea.getElemStifLinearMat(inci, coord, tabmat, tabgeo, intgauss, element_number)
# print('time KE ', time() - st)
# print(np.array2string(ke, separator=', '))
# print(np.allclose(ke, ke.T, rtol=1e-05, atol=1e-08))
# print(np.all(np.linalg.eigvals(ke)))


# st = time()
# kg = fea.getGlobalMatrix(inci, coord, tabmat, tabgeo, intgauss, SYMM=False)
# t_kg = time()-st
# print('time numpy sym ', t_kg)
# kg = kg['stiffness'].todense()
# print(kg.todense())
# print('kg is sym ', scipy.linalg.issymmetric(kg, atol = 1e-09))

# plt.figure(2)
# plt.spy(kg, markersize=4)
# plt.show()

# sys.exit()

f1 = {
    'TYPE': 'forcenode',
    'DOF': 'fx',
    'DIR': 'node',
    'LOC': {'x': 0, 'y': 0, 'z': 0},
    'VAL': [1],
    }

f1 = {
    'TYPE': 'forcenode',
    'DOF': 'fx',
    'DIR': 'surfyz',
    'LOC': {'x': LX, 'y': 999, 'z': 999},
    'VAL': [1],
    }

f2 = {
    'TYPE': 'forcesurf',
    'DOF': 'fx',
    'DIR': 'surfyz',
    'LOC': {'x': LX, 'y': 999, 'z': 999},
    'VAL': [1],
    }

f2b = {
    'TYPE': 'forcesurf',
    'DOF': 'fy',
    'DIR': 'plane',
    'TAG': 4,
    'VAL': [-1.0],
    }

f3 = {
    'TYPE': 'forcesurf',
    'DOF': 'pressure',
    'DIR': 'surfyz',
    'LOC': {'x': LX, 'y': 999, 'z': 999},
    'VAL': [1],
    }

f3pt = {
    'TYPE': 'forcesurf',
    'DOF': 'pressure',
    'DIR': 'plane',
    'TAG': 4,
    'VAL': [-1.0],
    }

bc_node = {
    'TYPE': 'fixed',
    'DOF': 'full',
    'DIR': 'node',
    'LOC': {'x': 1, 'y': 1, 'z': 1},
    }

bc = {
    'TYPE': 'fixed',
    'DOF': 'full',
    'DIR': 'surfyz',
    'LOC': {'x': 0, 'y': 999, 'z': 999},
    }


physicdata = {
    "PHYSIC": {"DOMAIN": "structural", # 'fluid' 'thermal'; "COUPLING": 'fsi'
               "LOAD": [f2b],
               "BOUNDCOND": [bc],
    },
}
fea.Physic(physicdata)

# regions = fea.getRegions()
# print(regions)

# loadaply = fea.getLoadApply()
# # bcaply = fea.getBCApply()
# print(loadaply) 
# # print(bcaply)
# # print(fea.getLoadArray(loadaply))
# # print(fea.getDirichletNH(bcaply))
# print('forca total [N]', np.sum(loadaply[:,2]))

# sys.exit()

previewset = {'RENDER': {'filename': 'beam', 'show': True, 'scale': 2, 'savepng': True, 'lines': True,
                         'plottags': {'point': True}
                         },
            #   'LABELS': {'show': True, 'lines': True, 'scale': 1},
              }
fea.PreviewAnalysis(previewset)

# sys.exit()

# #-------------------------------- SOLVER -------------------------------------#
solverset = {"STEPSET": {'type': 'table',  # mode, freq, time ...
                        'start': 0,
                        'end': 1,
                        'step': 1},
             'SYMM':False,
            #  'MP':True,
            }
solverdata = fea.Solve(solverset)

print(max(abs(solverdata['solution']['U'])))

postprocset = {"SOLVERDATA": solverdata,
                "COMPUTER": {'structural': {'displ': True, 'stress': True}},
                "PLOTSET": {'show': True, 'filename': 'test_shakedown', 'savepng': True},
                # "TRACKER": {'point': {'x': 0, 'y': 0, 'z': 0, 'dof':1}},
                "OUTPUT": {'log': True, 'get': {'nelem': True, 'nnode': True}},
            }
postprocdata = fea.PostProcess(postprocset)

# print(postprocdata["solution"])

Structural Vibration

'''

Simulação de vibração modal

'''
import sys
# setting path
sys.path.append('../myfempy')
import sys
import numpy as np
import matplotlib.pyplot as plt

from myfempy import newAnalysis
from myfempy import DynamicEigenLinear

import time

#===============================================================================
#                                   FEA
#===============================================================================
fea = newAnalysis(DynamicEigenLinear)

mat1 = {
    "NAME": "mat1",
    "VXY": 0.3,
    "EXX": 210E6,
    "RHO": 7850,
    }

mat2 = {
    "NAME": "mat2",
    "VXX": 0.3,
    "EXX": 1E6,
    "RHO": 1,
    }

geo = {
    "NAME": "espessura1",
    "THICKN": 0.1,
    # "DIM": [b, h, t, d],
    }

# MODEL SET

# nelx = 10
# nely = 5

# nodes = [[1, 0, 0, 0],
#          [2, nelx, 0, 0],
#          [3, nelx, nely, 0],
#          [4, 0, nely, 0],
#         #  [5, 1, 1, 0],
#         #  [6, 0, 1, 0],
#          ]

# conec = [[1, 1, 1, 1, 2, 3, 4],
#         #  [2, 2, 1, 2, 3, 4, 5],
#          ]

# MODEL SET
LX = 8 # 80
LY = 8 # 60

nelx = 4 # 40 # 80 # 160
nely = 4 # 30 # 60 # 120

# esize = 0.25

# # gmsh config
# points = [
#     [0, 0, 0],
#     [LX, 0, 0],
#     [LX, LY, 0],
#     [0, LY, 0]
# ]

# lines = [[1, 2],
#          [2, 3],
#          [3, 4],
#          [4, 1],
#          ]

# plane = [[1, 2, 3, 4]]

modeldata = {
    # "MESH": {
    #     'TYPE': 'add',
    #     'COORD': nodes,
    #     'INCI': conec,
    # },

    "MESH": {
        'TYPE': 'legacy',
        'LX': LX,
        'LY': LY,
        'NX': nelx,
        'NY': nely,
        },

    # "MESH": {
    #         'TYPE': 'gmsh',
    #         'filename': 'test_mfoop_gmsh_01',
    #         # "meshimport": 'object_dir',
    #         'pointlist': points,
    #         'linelist': lines,
    #         'planelist': plane,
    #         # 'arc': arcs,
    #         'meshconfig': {
    #             'mesh': 'quad4',   #quad4
    #             'sizeelement': 2 * esize,
    #             # 'extrude': 20,
    #             'meshmap': {'on': True,
    #                         'edge': 'all', #'all'
    #                     #  "numbernodes": 10,
    #             }}
    #     },

    "ELEMENT": {
        'TYPE': 'structplane',
        'SHAPE': 'quad4',
        'INTGAUSS': 4,
    },

    "MATERIAL": {
        "MAT": 'planestress',
        "TYPE": 'isotropic',
        "PROPMAT": [mat2],
    },

    "GEOMETRY": {
        "GEO": 'thickness',
        "PROPGEO": [geo],
    },
}
fea.Model(modeldata)

forcespring_left = {
    'TYPE': 'forcenode',
    'DOF': 'spring2ground',
    'DIR': 'point',
    'TAG': 1,
    'VAL': [1000.0],
    }

forcespring_right = {
    'TYPE': 'forcenode',
    'DOF': 'spring2ground',
    'DIR': 'point',
    'TAG': 2,
    'VAL': [1000.0],
    }

massadd = {
    'TYPE': 'forcenode',
    'DOF': 'masspoint',
    'DIR': 'node', #'point', #'node',
    'LOC': {'x': LX/2, 'y': LY/2, 'z': 0},
    'VAL': [1.4],
    }

bc_node_left = {
    'TYPE': 'fixed',
    'DOF': 'full',
    'DIR': 'node',                 # node
    'LOC': {'x': 0, 'y': LY/2, 'z': 0},
    }

bc_node_right = {
    'TYPE': 'fixed',
    'DOF': 'full',
    'DIR': 'node',
    'LOC': {'x': LX, 'y': LY/2, 'z': 0},
    }

physicdata = {
    "PHYSIC": {"DOMAIN": "structural",
                "LOAD": [],
                "BOUNDCOND": [],
    },
    }
fea.Physic(physicdata)

# loadaply = fea.getLoadApply()
# # bcaply = fea.getBCApply()
# print(loadaply)
# print(bcaply)
# print(fea.getLoadArray(loadaply))
# print(fea.getDirichletNH(bcaply))
# print('forca total [N]', np.sum(loadaply[:,2]))

previewset = {'RENDER': {'filename': 'squad', 'show': True, 'scale': 10, 'savepng': True, 'lines': False,
                        # 'plottags': {
                        # # 'line': True
                        # 'point': True
                        #       }
                         },
            #   'LABELS': {'show': True, 'lines': True, 'scale': 1},
              }
fea.PreviewAnalysis(previewset)

# sys.exit()

# #-------------------------------- SOLVER -------------------------------------#
solverset = {"STEPSET": {'type': 'mode',  # mode, freq, time ...
                        'start': 0,
                        'end': 10,
                        'step': 1},
             'SYMM':False,
            #  'MP':True,
            }
solverdata = fea.Solve(solverset)

print(solverdata['solution']['FREQ'])

postprocdata = {"SOLVERDATA": solverdata,
                "COMPUTER": {
                    'structural': {'modes': True},
                    # 'structural': {'frf': True}
                    },
                "PLOTSET": {'filename': 'test_dynamic', 'savepng': True},
                # "TRACKER": {'frf': {'x': 16, 'y': 1, 'z': 0, 'dof':0}},
                "OUTPUT": {'log': True, 'get': {'nelem': True, 'nnode': True}},           
                }

postporc_result = fea.PostProcess(postprocdata)

Heat

'''

Simulação com tranferencia de calor em sólidos

Necessario instalação prévia do gmsh (não nativo do myfempy)

'''

from myfempy import newAnalysis
from myfempy import SteadyStateLinear, SteadyStateLinearIterative

from time import time

# ===============================================================================
#                                   FEA
# ===============================================================================

fea = newAnalysis(SteadyStateLinearIterative)

mat1 = {
    "NAME": "aco",
    "KXX": 0.0605,  # W/mm·°C
    "KYY": 0.0605,
    }

geo = {
    "NAME": "espessura",
    "THICKN": 0.5, # mm
    # "DIM": [b, h, t, d],
    }

# MODEL SET
LX = 20 # 80   # mm
LY = 20 # 60
nelx = 80 # 40 # 80 # 160
nely = 80 # 30 # 60 # 120

# esize = 1 #LX/nelx

# MODEL SET
# example 10.4 Logan
# nodes = [[1, 0, 0, 0],
#          [2, LX, 0, 0],
#          [3, LX, LY, 0],
#          [4, 0, LY, 0]]

# conec = [[1, 1, 1, 1, 2, 3, 4]]

# gmsh config
points = [
    [0, 0, 0],
    [20, 0, 0],
    [20, 20, 0],
    [0, 20, 0]
]

lines = [[1, 2],
         [2, 3],
         [3, 4],
         [4, 1],
         ]

plane = [[1, 2, 3, 4]]

modeldata = {
    # "MESH": {
    #     'TYPE': 'add',
    #     'COORD': nodes,
    #     'INCI': conec,
    #     },

    # "MESH": {
    #     'TYPE': 'legacy',
    #     'LX': LX,
    #     'LY': LY,
    #     'NX': nelx,
    #     'NY': nely,
    #     },

   "MESH": {
        'TYPE': 'gmsh',
        'filename': 'test_line_force_x',
        # "meshimport": 'object_dir',
        'pointlist': points,
        'linelist': lines,
        'planelist': plane,
        # 'arc': arcs,
        'meshconfig': {
            'mesh': 'quad4',   #quad4
            'sizeelement': 2,
            # 'extrude': 5,
            'meshmap': {'on': True,
                        'edge': 'all', #'all'
                        "numbernodes": 4,
            }
            }
    },

    "ELEMENT": {
        'TYPE': 'heatplane',
        'SHAPE': 'quad4',
        # 'INTGAUSS': 8,
    },

    "MATERIAL": {
        "MAT": 'heatplane',
        "TYPE": 'isotropic',
        "PROPMAT": [mat1],
    },

    "GEOMETRY": {
        "GEO": 'thickness',
        "PROPGEO": [geo],
    },
}
fea.Model(modeldata)

# inci = fea.getInci()
# coord = fea.getCoord()
# tabmat = fea.getTabmat()
# tabgeo = fea.getTabgeo()
# intgauss = fea.getIntGauss()

# element_number = 0
# st = time()
# ke = fea.getElemStifLinearMat(inci, coord, tabmat, tabgeo, intgauss, element_number)
# print('time KE ', time() - st)
# print(np.array2string(ke, separator=', '))
# # sys.exit()

# kg = fea.getGlobalMatrix(inci, coord, tabmat, tabgeo, intgauss)
# kg = kg['stiffness']
# print(kg.todense())

# import matplotlib.pylab as plt
# import scipy

# print('kg is sym ', scipy.linalg.issymmetric(kg.todense(), atol = 1e-09))
# # print('kg_cy is close to kg ',np.allclose(kg.todense(), kg_cy.todense()))

# plt.figure(2)
# plt.spy(kg.todense(), markersize=4)
# plt.show()

# sys.exit()
q = 1.0 #1
Q = 0.2         # W/mm3
h = 0.000005    # W/mm2.ºC
Tinf = 1000

heatflux = {
    'TYPE': 'heatfluxedge',
    'DOF': 'heatflux',
    'DIR': 'edgey',
    'LOC': {'x': 999, 'y': 0, 'z': 0},
    'VAL': [q],
    }

heatgen = {
    'TYPE': 'heatgeneration',
    'DOF': 'heatflux',
    'DIR': 'node',
    # 'LOC': {'x': 0, 'y': 999, 'z': 0},
    'VAL': [Q],
    }

convc_s1 = {
    'TYPE': 'convectionedge',
    'DOF': 'convection',
    'DIR': 'edgex',
    'LOC': {'x': LX, 'y': 999, 'z': 0},
    'VAL': [h*Tinf],
    }

convc_s2 = {
    'TYPE': 'convectionedge',
    'DOF': 'convection',
    'DIR': 'edgey',
    'LOC': {'x': 999, 'y': 0, 'z': 0},
    'VAL': [h*Tinf],
    }

convc_s3 = {
    'TYPE': 'convectionedge',
    'DOF': 'convection',
    'DIR': 'edgey',
    'LOC': {'x': 999, 'y': LY, 'z': 0},
    'VAL': [h*Tinf],
    }

bc1 = {
    'TYPE': 'insulated',  
    'DOF': 'full',
    'DIR': 'edgex',
    'LOC': {'x': 0, 'y': 999, 'z': 0},
    }

bc2 = {
    'TYPE': 'insulated',
    'DOF': 'full',
    'DIR': 'edgey',
    'LOC': {'x': 999, 'y': 0, 'z': 0},
    }

bc3 = {
    'TYPE': 'insulated',
    'DOF': 'full',
    'DIR': 'edgex',
    'LOC': {'x': LX, 'y': 999, 'z': 0},
    }

bcNH1 = {
    'TYPE': 'temperature',
    'DOF': 't',
    'DIR': 'edgex',
    'LOC': {'x': 0, 'y': 999, 'z': 0},
    'VAL': [180.0],
    }

bcNH2 = {
    'TYPE': 'temperature',
    'DOF': 't',
    'DIR': 'edgey',
    'LOC': {'x': 999, 'y': LY, 'z': 0},
    'VAL': [1.0],
    }

physicdata = {
    "PHYSIC": {"DOMAIN": "thermal",           # 'fluid' 'thermal'; "COUPLING": 'fsi'
               "LOAD": [convc_s1, heatflux],
               "BOUNDCOND": [bcNH2],
    }
}
fea.Physic(physicdata)

loadaply = fea.getLoadApply()
bcaply = fea.getBCApply()
print(loadaply)
print(bcaply)

previewset = {'RENDER': {'filename': 'heat_transfer', 'show': True, 'scale': 10, 'savepng': True, 'lines': False,
                        #  'plottags': {'line': True}
                         },
            #   'LABELS': {'show': True, 'lines': True, 'scale': 1},
              }
fea.PreviewAnalysis(previewset)

# nodes = fea.getNodesFromRegions(1, 'plane')
# print(nodes)
# elem = fea.getElementFromNodesList(nodes)
# print(elem)

# #-------------------------------- SOLVER -------------------------------------#
solverset = {"STEPSET": {'type': 'table',  # mode, freq, time ...
                        'start': 0,
                        'end': 1,
                        'step': 1},
             'SYMM':True,
            #  'MP':True,
            }
solverdata = fea.Solve(solverset)

postprocset = {"SOLVERDATA": solverdata,
                "COMPUTER": {'thermal': {'temp': True, 'heatflux': True}},
                "PLOTSET": {'show': True, 'filename': 'test_shakedown', 'savepng': True},
                # "TRACKER": {'point': {'x': 0, 'y': 0, 'z': 0, 'dof':1}},
                "REPORT": {'log': True, 'get':{
                        'nelem': True,
                        'nnode': True,
                        'inci': True,
                        'coord':True,
                        'tabmat':True,
                        'tabgeo':True,
                        'bc_list':True,
                        'lo_list':True,
                        'u_list': True,
                    }
            }}
postprocdata = fea.PostProcess(postprocset)

Thermo Mechanical Coupling

'''

Simulação com iteração termo-mecânico em sólido 3D

'''
from os import environ
environ['OMP_NUM_THREADS'] = '1'        #win
import numpy as np
import matplotlib.pyplot as plt

from myfempy import newAnalysis
from myfempy import SteadyStateLinear, SteadyStateLinearIterative

from time import time

# ===============================================================================
#                                   FEA
# ===============================================================================

fea = newAnalysis(SteadyStateLinear)

steel = {
    "NAME": "steel",
    "KXX": 0.0605,      # W/mm·°C  
    "KYY": 0.0605,
    "KZZ": 0.0605,
    "VXY": 0.30,
    "EXX": 200E3,       # N/mm^2 --> MPa
    "RHO": 7.85E-06,    # kg/mm^3
    "CTE": 12E-6        # (mm/mm) /°C
    }

copper = {
    "NAME": "copper",
    "KXX": 0.4230,      # W/mm·°C  
    "KYY": 0.4230,
    "KZZ": 0.4230,
    "VXY": 0.33,
    "EXX": 110E3,       # N/mm^2 --> MPa
    "RHO": 7.85E-06,    # kg/mm^3
    "CTE": 17E-6        # (mm/mm) /°C
    }

geo = {
    "NAME": "espessura",
    "THICKN": 5, # mm
    }

points = [
    [0, 0, 0],
    [200, 0, 0],
    [0, 10, 0],
    [200, 10, 0],
    [0, 20, 0],
    [200, 20, 0]
]

lines = [[1, 2],
         [2, 4],
         [3, 4],
         [3, 1],
         [6, 4],
         [5, 6],
         [5, 3],
         ]

plane = [[1, 2, 3, 4], [3, 5, 6, 7]]

modeldata = {
   "MESH": {
        'TYPE': 'gmsh',
        'filename': 'test_line_force_x',
        # "meshimport": 'object_dir',
        'pointlist': points,
        'linelist': lines,
        'planelist': plane,
        # 'arc': arcs,
        'meshconfig': {
            'mesh': 'hexa8',   #quad4
            'sizeelement': 4,
            'extrude': 20,
            'meshmap': {'on': True,
                        'edge': 'all', #'all'
                        "numbernodes": [10],
            }
            }
    },

    "ELEMENT": {
        'TYPE': 'heatsolid',
        'SHAPE': 'hexa8',
        # 'INTGAUSS': 7,
    },

    "MATERIAL": {
        "MAT": 'heatsolid',
        "TYPE": 'isotropic',
        "PROPMAT": [copper, steel],
    },

    "GEOMETRY": {
        "GEO": 'thickness',
        "PROPGEO": [geo, geo],
    },
}
fea.Model(modeldata)

# inci = fea.getInci()
# coord = fea.getCoord()
# tabmat = fea.getTabmat()
# tabgeo = fea.getTabgeo()
# intgauss = fea.getIntGauss()

# vol = fea.getElementVolume(inci, coord, tabgeo, intgauss)
# print(np.sum(vol))



# # sys.exit()
q = -0.1 #1      # W/mm2
# Q = 0.2         # W/mm3
h = 0.000005    # W/mm2.ºC 0.000005 (air)
Tinf = 20       # ºC

heatflux = {
    'TYPE': 'heatfluxsurf',
    'DOF': 'heatflux',
    'DIR': 'edgex',
    'LOC': {'x': 200, 'y': 999, 'z': 0},
    'VAL': [0*q],
    }

# heatgen = {
#     'TYPE': 'heatgeneration',
#     'DOF': 'heatflux',
#     'DIR': 'node',
#     # 'LOC': {'x': 0, 'y': 999, 'z': 0},
#     'VAL': [Q],
#     }

convc_s1 = {
    'TYPE': 'convectionedge',
    'DOF': 'convection',
    'DIR': 'edgey',
    'LOC': {'x': 999, 'y': 0, 'z': 0},
    'VAL': [-h*Tinf],
    }

convc_s2 = {
    'TYPE': 'convectionedge',
    'DOF': 'convection',
    'DIR': 'edgey',
    'LOC': {'x': 999, 'y': 20, 'z': 0},
    'VAL': [-h*Tinf],
    }

# convc_s3 = {
#     'TYPE': 'convectionedge',
#     'DOF': 'convection',
#     'DIR': 'edgey',
#     'LOC': {'x': 999, 'y': LY, 'z': 0},
#     'VAL': [h*Tinf],
#     }

# bc1 = {
#     'TYPE': 'insulated',  
#     'DOF': 'full',
#     'DIR': 'edgex',
#     'LOC': {'x': 0, 'y': 999, 'z': 0},
#     }

# bc2 = {
#     'TYPE': 'insulated',
#     'DOF': 'full',
#     'DIR': 'edgey',
#     'LOC': {'x': 999, 'y': 0, 'z': 0},
#     }

# bc3 = {
#     'TYPE': 'insulated',
#     'DOF': 'full',
#     'DIR': 'edgex',
#     'LOC': {'x': LX, 'y': 999, 'z': 0},
#     }

bcNH1 = {
    'TYPE': 'temperature',
    'DOF': 't',
    'DIR': 'surfyz',
    'LOC': {'x': 0, 'y': 999, 'z': 999},
    'VAL': [200.0],
    }

bcNH2 = {
    'TYPE': 'temperature',
    'DOF': 't',
    'DIR': 'edgex',
    'LOC': {'x': 200, 'y': 999, 'z': 0},
    'VAL': [200.0],
    }

# bcNH3 = {
#     'TYPE': 'temperature',
#     'DOF': 't',
#     'DIR': 'edgey',
#     'LOC': {'x': 999, 'y': 0, 'z': 0},
#     'VAL': [100.0],
#     }

physicdata = {
    "PHYSIC": {"DOMAIN": "thermal",           # 'fluid' 'thermal'; "COUPLING": 'fsi'
               "LOAD": [],
               "BOUNDCOND": [bcNH1],
    }
}
fea.Physic(physicdata)


previewset = {'RENDER': {'filename': 'heat_transfer', 'show': True, 'scale': 5, 'savepng': True, 'lines': True,
                        #  'plottags': {'line': True}
                         },
            #   'LABELS': {'show': True, 'lines': True, 'scale': 1},
              }
fea.PreviewAnalysis(previewset)


# #-------------------------------- SOLVER -------------------------------------#
solverset = {"STEPSET": {'type': 'table',  # mode, freq, time ...
                        'start': 0,
                        'end': 1,
                        'step': 1},
             'SYMM':True,
            #  'MP':True,
            }
solverdata = fea.Solve(solverset)

# print(solverdata['solution']['U'])


postprocset = {"SOLVERDATA": solverdata,
                "COMPUTER": {'thermal': {'temp': True, 'heatflux': True}},
                "PLOTSET": {'show': True, 'filename': 'SIM_TIRA_BIMETALICA_HEAT', 'savepng': True},
                # "TRACKER": {'point': {'x': 0, 'y': 0, 'z': 0, 'dof':1}},
                "OUTPUT": {'log': True, 'get': {'nelem': True, 'nnode': True}},
            }
postprocdata = fea.PostProcess(postprocset)

### sova simulação, aplicando os valores do campo de calor da simulação anterior para gerar expansão termica no sólido

modeldata = {
   "MESH": {
        'TYPE': 'gmsh',
        'filename': 'test_line_force_x',
        # "meshimport": 'object_dir',
        'pointlist': points,
        'linelist': lines,
        'planelist': plane,
        # 'arc': arcs,
        'meshconfig': {
            'mesh': 'hexa8',   #quad4
            'sizeelement': 4,
            'extrude': 20,
            'meshmap': {'on': True,
                        'edge': 'all', #'all'
                        "numbernodes": [10],
            }
            }
    },

    "ELEMENT": {
        'TYPE': 'structsolid',
        'SHAPE': 'hexa8',
        # 'INTGAUSS': 7,
    },

    "MATERIAL": {
        "MAT": 'solidelastic',
        "TYPE": 'isotropic',
        "PROPMAT": [copper, steel],
    },

    "GEOMETRY": {
        "GEO": 'thickness',
        "PROPGEO": [geo, geo],
    },
}
fea.Model(modeldata)

# fc = {
#     'TYPE': 'forcenode',
#     'DOF': 'fy',
#     'DIR': 'node',
#     'LOC': {'x': 200, 'y': LY, 'z': 0},
#     'VAL': [0.0],
#     }

fc = {
    'TYPE': 'forcenode',
    'DOF': 'fy',
    'DIR': 'edgex',
    'LOC': {'x': 200, 'y': 999, 'z': 0},
    'VAL': [0.0],
    }

# bcb = {
#     'TYPE': 'fixed',
#     'DOF': 'uy',
#     'DIR': 'edgey',
#     'LOC': {'x': 999, 'y': 0, 'z': 0},
#     }

bcl = {
    'TYPE': 'fixed',
    'DOF': 'full',
    'DIR': 'surfyz',
    'LOC': {'x': 0, 'y': 999, 'z': 999},
    }

# bcr = {
#     'TYPE': 'fixed',
#     'DOF': 'full',
#     'DIR': 'edgex',
#     'LOC': {'x': LX, 'y': 999, 'z': 0},
#     }

physicdata = {
    "PHYSIC": {"DOMAIN": "structural",
               "LOAD": [],
               "BOUNDCOND": [bcl],
    },
    "COUPLING": {"TYPE": 'thermalstress', # fsi asi
                 "POST": [postprocdata]
    },
    }
fea.Physic(physicdata)

previewset = {'RENDER': {'filename': 'structural', 'show': True, 'scale': 10, 'savepng': True, 'lines': False,
                        #  'plottags': {'line': True}
                         },
            #   'LABELS': {'show': True, 'lines': True, 'scale': 1},
              }
fea.PreviewAnalysis(previewset)

# #-------------------------------- SOLVER -------------------------------------#
solverset = {"STEPSET": {'type': 'table',  # mode, freq, time ...
                        'start': 0,
                        'end': 1,
                        'step': 1},
             'SYMM':True,
            #  'MP':True,
            }
solverdata = fea.Solve(solverset)

postprocset = {"SOLVERDATA": solverdata,
                "COMPUTER": {'structural': {'displ': True, 'stress': True}},
                "PLOTSET": {'show': True, 'filename': 'SIM_TIRA_BIMETALICA_DISP', 'savepng': True},
                # "TRACKER": {'point': {'x': 0, 'y': 0, 'z': 0, 'dof':1}},
                "OUTPUT": {'log': True, 'get': {'nelem': True, 'nnode': True}},
            }
postprocdata = fea.PostProcess(postprocset)

SET NEW MATERIAL: ORTHOTROPIC ELASTIC

SET NEW MATERIAL ORTHOTROPIC ELASTIC

import numpy as np

from myfempy import newAnalysis
from myfempy import SteadyStateLinear, SteadyStateLinearIterative
from myfempy import Material, PlaneStress

# ===============================================================================
#                                   FEA
# ===============================================================================
fea = newAnalysis(SteadyStateLinear)

# #-------------------------------- PRE -------------------------------------#
mat = {
    "NAME": "fibra_vidro", # Fonte: CALLISTER
    "EXX": 45E3,       # N/mm^2 --> MPa
    "EYY": 10E3,       # N/mm^2 --> MPa
    "VXY": 0.3,
    "VYZ": 0.4,
    }

geo = {
    "NAME": "espessura",
    "THICKN": 5, # mm
    }

# ===============================================================================
#                    SET NEW MATERIAL <ORTHOTROPIC ELASTIC>
# ===============================================================================
class UserNewMaterial(PlaneStress):
    def __init__(self):
        super().__init__()

    def getMaterialSet():
        matset = {
            "mat": "planestress",
            "type": "orthotropic",
        }
        return matset

    def getElasticTensor(Model, element_number):

        # # material elasticity
        EXX = Model.tabmat[int(Model.inci[element_number, 2]) - 1]["EXX"]
        EYY = Model.tabmat[int(Model.inci[element_number, 2]) - 1]["EYY"]
        # material poisson ratio
        VXY = Model.tabmat[int(Model.inci[element_number, 2]) - 1][ "VXY"]
        VYZ = Model.tabmat[int(Model.inci[element_number, 2]) - 1][ "VYZ"]  

        # EXX = 45E3       # N/mm^2 --> MPa
        # EYY = 12E3       # N/mm^2 --> MPa
        # VXY = 0.23
        # VYX = 0.66

        S00 = EXX/(1-VXY*VYZ)   
        S01 = (VYZ*EXX)/(1-VXY*VYZ)
        S10 = (VXY*EYY)/(1-VXY*VYZ)
        S11 = EYY/(1-VXY*VYZ)
        S22 = (EXX*EYY)/(EXX+EYY+2.0*EYY*VXY)     

        D = np.zeros((3, 3), dtype=np.float64)
        D[0, 0] = S00
        D[0, 1] = S01
        D[1, 0] = S10
        D[1, 1] = S11
        D[2, 2] = S22
        return D

    # def getFailureCriteria(stress):
    #     stress
    #     return super().getFailureCriteria()
# ===============================================================================

# config model geometry --> mesh(gmsh)
points = [
    [0, 0, 0],
    [200, 0, 0],
    [0, 10, 0],
    [200, 10, 0],
    [0, 20, 0],
    [200, 20, 0]
]

lines = [[1, 2],
         [2, 4],
         [3, 4],
         [3, 1],
         [6, 4],
         [5, 6],
         [5, 3],
         ]

plane = [[1, 2, 3, 4], [3, 5, 6, 7]]

# #-------------------------------- THERMAL SIM -------------------------------------#

modeldata = dict()
modeldata["MESH"] = {
        'TYPE': 'gmsh',
        'filename': 'test_line_force_x',
        'pointlist': points,
        'linelist': lines,
        'planelist': plane,
        # 'arc': arcs,
        'meshconfig': {
            'mesh': 'quad4',   #quad4
            'sizeelement': 1,
            'meshmap': {'on': True,
                        'edge': [[1,3,6], [2,4,5,7]], #'all'
                        "numbernodes": [20, 10],
            }
        }
    }

modeldata["ELEMENT"] = {
        'TYPE': 'structplane',
        'SHAPE': 'quad4',
        'INTGAUSS': 4,
    }

modeldata["MATERIAL"] = {
        "MAT": 'planestress',
        "TYPE": 'usermaterial',
        "PROPMAT": [mat, mat],
        "CLASS": UserNewMaterial,

    }

modeldata["GEOMETRY"] =  {
        "GEO": 'thickness',
        "PROPGEO": [geo, geo],
    }

fea.Model(modeldata)


f1 = {
    'TYPE': 'forcenode',
    'DOF': 'fx',
    'DIR': 'edgex',
    'LOC': {'x': 200, 'y': 999, 'z': 0},
    'VAL': [10.0],
    }

bc1 = {
    'TYPE': 'fixed',
    'DOF': 'full',
    'DIR': 'edgex',
    'LOC': {'x': 0, 'y': 999, 'z': 0},
    }  

physicdata = {
    "PHYSIC": {"DOMAIN": "structural",
               "LOAD": [f1],
               "BOUNDCOND": [bc1],
    },
    }
fea.Physic(physicdata)


previewset = {'RENDER': {'filename': 'model_preview', 'show': True, 'scale': 2, 'savepng': True, 'lines': False,
                         'plottags': {'line': True}
                         },
            #   'LABELS': {'show': True, 'lines': True, 'scale': 1},
              }
fea.PreviewAnalysis(previewset)

# sys.exit()

# #-------------------------------- SOLVER -------------------------------------#
solverset = {"STEPSET": {'type': 'table',
                        'start': 0,
                        'end': 1,
                        'step': 1},
             'SYMM':False,
             }
solverdata = fea.Solve(solverset)

# print(solverdata['solution']['U'])

postprocset = {"SOLVERDATA": solverdata,
                "COMPUTER": {'structural': {'displ': True, 'stress': True}},
                "PLOTSET": {'show': True, 'filename': 'solution', 'savepng': True},
                "OUTPUT": {'log': True, 'get': {'nelem': True, 'nnode': True}},
            }
postprocdata = fea.PostProcess(postprocset)

Appendix

GMSH FreeCAD Python NumPy SciPy Computer-aided design Finite element method Young's modulus Poisson's ratio Shear modulus Density List of moments of inertia Boundary value problem Gaussian quadrature International System of Units

Axis Diretions

#        |
#        [Y]
#        |      P1 -- principal plane
#        |      P2 -- secondary plane
#        |__edgey__
#       /|         |
#      / |   P1    |
#     /  | surfxy  edgex
#    /  f|         |
#   /  r |_________|____________[X]__
#  | u  /          /
#  |s z/   P2     /
#  | y/  surfzx  edgez
#  | /          /
#  |/__________/        
#  /         
# [Z]
#/

Cross Section Dimensions

Geometric Cross-Section Libraries

#                       :
#                       [Y]
#                       :
#  ___       ___________:___________
#   |       |_______    :    _______|   
#   |               |   :   |
#   |            -->|   :   |<-------------(t)
#   |               |   :   |
#   |               |   :   |
#   |               |   :   |
#   (h)             |  (CG).|..........[Z]..
#   |               |       |
#   |               |       |
#   |               |       |
#   |               |       |
#   |        _______|       |_______    ___  
#  _|_      |_______________________|   _|_(d)


#           |-----------(b)---------|                       

Table 1 - Elements List

element id description
block 11 Spring + Mass 1D-space 1-node_dofs
structbeam 16 Beam Structural Element 1D-space 6-node_dofs
structplane 22 Plane Structural Element 2D-space 2-node_dofs
structsolid 33 Solid Structural Element 3D-space 3-node_dofs
heatplane 21 Plane Heat Element 2D-space 1-node_dof
heatsolid 31 Solid Heat Element 3D-space 1-node_dofs

Table 2 - Shape (Mesh) List

mesh id description Gauss Points Opt.
line2 21 Line 2-Node Shape 2-nodes_conec 1-interpol_order 1/ 2/ 4/ 8
line3 32 Line 3-Node Shape 3-nodes_conec 2-interpol_order 1/ 2/ 4/ 8
tria3 31 Triangular 3-Node Shape 3-nodes_conec 1-interpol_order 1/ 3/ 7
tria6 62 Triangular 6-Node Shape 6-nodes_conec 2-interpol_order 1/ 3/ 7
quad4 41 Quadrilateral 4-Node Shape 4-nodes_conec 1-interpol_orde 1/ 2/ 3/ 4/ 8/ 9
quad8 82 Quadrilateral 8-Node Shape 8-nodes_conec 2-interpol_order 1/ 2/ 3/ 4/ 8/ 9
hexa8 81 Hexaedron 8-Node Shape 8-nodes_conec 1-interpol_order 1/ 2/ 3/ 4/ 8/ 9
tetr4 41 Tetrahedron 4-Node Shape 4-nodes_conec 1-interpol_orde 1/ 3/ 5

Table 3 - Solvers List

solver id description mandatory parameters optional parameters
SteadyStateLinear Steady State Linear Solver Class (Static Linear) Model, Assembly: [stiffness, loads], ConstrainsDof: [freedof, constdof] Assembly: [bcdirnh], Solverset: [nsteps]
SteadyStateLinearIterative Steady State Linear Iterative Solver Class (Static Linear) Model, Assembly: [stiffness, loads], ConstrainsDof: [freedof, constdof] Assembly: [bcdirnh], Solverset: [nsteps, tol, maxiter]
DynamicEigenLinear Dynamic Eigen (modal problem) Linear Solver Class Model, Assembly: [stiffness, mass], ConstrainsDof: [freedof] Solverset: [modeEnd:nsteps]
DynamicHarmonicResponseLinear Dynamic Harmonic Response Forced System Steady State Linear Solver Clas Model, Assembly: [stiffness, mass, loads], ConstrainsDof: [freedof] Solverset: [freqStart:start, freqEnd:end,freqStep:nsteps]
[ dev ] TransientLinear
[ adv ] StaticLinearCyclicSymmPlane Static Linear Cyclic Symmetry Plane Solver Class Model, Physic, Assembly: [stiffness, loads], ConstrainsDof: [freedof, fixedof(leftdof, rightdof, interdof)*] Solverset: [nsteps]
[ adv ] HomogenizationPlane Homogenization Plane Solver Class Model, Assembly: [stiffness, loads], ConstrainsDof: [freedof, fixedof(strain)*]
[ adv ] PhononicCrystalInPlane Phononic Crystal In-Plane Solver Class Model, Assembly: [stiffness, mass], ConstrainsDof: [freedof, constdof(bloch)*] Solverset: [nsteps, IBZ*]
[ dev ] TopologyOptimization

*Note: See Solver Set

Legends

  • [ Model ]: Model object of analysis
  • [ Physic ]: Physic object of analysis
  • [ Assembly ]: Dictionary with the algebraic matrices
    • [ stiffness ]: linear stiffness
    • [ mass ]: mass matrix
    • [ loads ]: vector of loads of the degrees of freedom
    • [ bcdirnh ]: vector with Dirichlet boundary conditions (non-homogeneous)
  • [ ConstrainsDof ]: dictionary with the problem's restrictions
    • [ freedof ]: free d.o.f.
    • [ fixeddof ]: fixed d.o.f.
    • [ constdof ]: restricted d.o.f.
  • [ Solverset ]: dictionary with commands for the solver
    • [ nsteps ]: number of solver steps
    • [ start ]: first step number
    • [ end ]: last step number
    • [ IBZ ]: Brillouin zone rad/s

Table 4 - Material List

material id description
UniAxialStress Uni-Axial Stress Isotropic Material Class
PlaneStress Plane Stress Isotropic Material Class
PlaneStrain Plane Strain Isotropic Material Class
SolidElastic Solid Stress Isotropic Material Class
HeatPlane Heat Plane Isotropic Material Class
HeatSolid Heat Solid Isotropic Material Class
UserNewMaterial User Defined Material API

Table 5 - Consistent Units

Quantity SI(m) SI(mm)
length m mm
mass kg tonne
time s s
temperature °C °C
rotation rad rad
acceleration/ gravity m/s^2 mm/s^2
density kg/m^3 tonne/mm^3
force N(kg⋅m⋅s^−2) N
moment N-m N-mm
frequency Hz(s^-1) = (rad/s)/(2.pi) Hz
pressure/ stress Pa(N/m^2) MPa(N/mm^2)
energy J(kg⋅m^2⋅s^−2) mJ(tonne⋅mm^2⋅s^−2)
power W(kg⋅m^2⋅s^-3) mW(tonne⋅mm^2⋅s^-3)
thermal conductivity W/(m.°C) mW/(mm·°C)
thermal expansion (m/m)/°C (mm/mm)/°C
heat flux W/m^2 W/mm^2
viscosity Pa.s MPa.s

See International System of Units

Tag Legends

  • [ adv ]: Inputs advanced options or external package
  • [ dev ]: Inputs options in development (next update)
  • [ old ]: Inputs of legacy/old version