Quick Start

Steps to define and solve a Problem

The main steps to define a problem are:

  1. Import the fedoo library

  2. Define the space dimension

  3. Create and/or import the geometry (mesh)

  4. Define one or many weak formulations (including constitutive equations)

  5. Create the Assembly associated to the weak formulations and the mesh

  6. Define the type of Problem (Static, Dynamic, …) and the solver

  7. Solve the Problem

  8. Analyse and export results (vizualisation with Paraview recommanded)

Import library

The first step is to import the fedoo library. Obvisously, fedoo needs to be installed.

import fedoo as fd #Import all the fedoo library
import numpy as np #Numpy is often usefull

Create the modeling space

In fedoo, most of objects are associated to a modeling space. The modeling space is a space in which the variables and coordinates are created. The dimension of the modeling space car be ‘3D’ or ‘2D’ (for planar problem). The dimension of the space may also be set to ‘2Dstress’ for planar problem based on the plane stress assumption.

fd.ModelingSpace("3D")

Create and/or import the geometry (mesh)

The module mesh contains several functions to build up simple meshes. For instance to build the mesh of a box (3d rectangle), we can use:

my_mesh = fd.mesh.box_mesh(nx=31, ny=21, nz=21, x_min=0, x_max=1000, y_min=0, y_max=100, z_min=0, z_max=100, elm_type = 'hex8')

You can also import a Mesh by using one of the following Mesh constructor fedoo.Mesh.read(), fedoo.Mesh.from_pyvista() or with the function fd.mesh.import_file (see Import/Export Fedoo Mesh object) that allow to import meshes from the VTK or GMSH format.

Create weak formulations

We need to define one or several equations to solve. In a finite element analyses, the equations are written using a weak formulations. In fedoo, the equation is defined by creating a WeakForm object.

The type of WeakForm may be related to a specific type of elements.

For instance, a beam weak formulation should be associated to beam elements. The module weakform list the available types of weak formulation. Most of weak formulations needs the definition of a material constitutive law. The module constitutivelaw list the available ConstitutiveLaw.

For instance a simple weak formulation may be defined by:

material = fd.constitutivelaw.ElasticIsotrop(200e3, 0.3)
my_weakform = fd.weakform.StressEquilibrium(material)

Create global matrix assemblies

Once mesh and weak formulations have been created, we can now proceed to the assembly of the global matrices. For each weak formulation associated to a mesh, an Assembly object needs to be created. To combine several assembly, there is a dedicated constructor fedoo.Assembly.sum().

For instance, a simple assembly for the previously defined weak formulation and mesh is:

my_assembly = fd.Assembly.create(my_weakform, my_mesh)

The Assembly object will automatically compute the assembled stiffness matrix using scipy sparse matrix format. To get the global stiffness matrix:

my_assembly.get_matrix().

Set the Problem and the solver

The problem should now be defined. Here a Linear problem is created based on the previously defined Assembly.

pb = fd.problem.Linear("MyAssembly")

The solver can be modified as follow:

pb.set_solver('cg') #for conjugate gradient solver

For direct solver, it is strongly recommanded to install the pypardiso that allow to use the pardiso linear system solver for drastically improved computation performance.

Boundary conditions

To apply the boundary conditions, we need to define some list of nodes indices for boundaries. The boundaries are automatically stored as set of nodes (‘left’, ‘right’, ‘top’, ‘bottom’, …) when the function Mesh.BoxMesh is used.

nodes_left = fd.Mesh['Domain'].node_sets["left"]
nodes_right = fd.Mesh['Domain'].node_sets["right"]

An easy way to get a set of nodes from the position of nodes is to use the fedoo.Mesh.find_nodes() method. For instance, to get the left and right list of nodes with a 1e-10 position tolerance:

nodes_left = Mesh['Domain'].find_nodes('X', mesh.bounding_box.xmin, tol=1e-10)
nodes_right = Mesh['Domain'].find_nodes('X', mesh.bounding_box.xmax, tol=1e-10)

Once the list of nodes have been defined, the boundary conditions can be added to the problem. The boundary conditions associated to a problem are stored in the attribute pb.bc. We can add two type of boundary conditions: ‘Dirichlet’ to prescribed dof values at given nodes or ‘Neumann’ (nodal force for mechanical problems).

pb.bc.add('Dirichlet',nodes_left, 'Disp', 0) #displacement vector set to 0 on the left

pb.bc.add('Dirichlet',nodes_right, 'DispY', -10) #displacement along y set to -10 on right

To apply the boundary conditions to the active problem use the command:

pb.apply_boundary_conditions()

Solve the Problem

pb.solve()

Analyse and export results

See the section Post-Processing