Basic usage¶
You should be familiar with FEniCSx before using fenics-constitutive. If you are not, please refer to the FEniCSx documentation or the FEniCSx tutorial.
This tutorial will show you how to use fenics-constitutive to define and solve a simple linear elasticity problem. Although, we do not recommend to use fenics-constitutive for simple problems like this (mainly because of the memory overhead due to storing all tangents), it is a good starting point to understand the basic usage of the library.
Initializing the constitutive model¶
First, we need to initialize the constitutive model. Note, that there is no prescribed way of passing parameters to the model. Some models may be implemented for all variants of StressStrainConstraint and therefore have the constraint as a parameter, but some models may only be implemented for 3D problems.
from fenics_constitutive.models import LinearElasticityModel
from fenics_constitutive import StressStrainConstraint
parameters = {"E": 42., "nu": 0.3}
model = LinearElasticityModel(parameters, StressStrainConstraint.PLANE_STRAIN)
--------------------------------------------------------------------------- ImportError Traceback (most recent call last) Cell In[1], line 2 1 from fenics_constitutive.models import LinearElasticityModel ----> 2 from fenics_constitutive import StressStrainConstraint 4 parameters = {"E": 42., "nu": 0.3} 6 model = LinearElasticityModel(parameters, StressStrainConstraint.PLANE_STRAIN) ImportError: cannot import name 'StressStrainConstraint' from 'fenics_constitutive' (/home/docs/checkouts/readthedocs.org/user_builds/fenics-constitutive/checkouts/latest/src/fenics_constitutive/__init__.py)
Defining the problem¶
Next, define the mesh and the boundary conditions. We will use a simple 2D mesh for this example.
from mpi4py import MPI
import dolfinx as df
import numpy as np
df.log.set_log_level(df.log.LogLevel.WARNING)
mesh = df.mesh.create_unit_square(MPI.COMM_WORLD, 10, 10, cell_type=df.mesh.CellType.quadrilateral)
V = df.fem.functionspace(mesh, ("CG", 2, (2,)))
u = df.fem.Function(V)
def bounary_left(x):
return np.isclose(x[0], 0.)
def bounary_right(x):
return np.isclose(x[0], 1.)
dofs_left = df.fem.locate_dofs_geometrical(V, bounary_left)
dofs_right = df.fem.locate_dofs_geometrical(V, bounary_right)
bc_left = df.fem.dirichletbc(np.array([0., 0.]), dofs_left, V)
bc_right = df.fem.dirichletbc(np.array([0.1, 0.]), dofs_right, V)
bcs = [bc_left, bc_right]
Defining the nonlinear problem¶
Finally, we define the nonlinear problem and solve it. The IncrSmallStrainProblem has similar parameters to the NonlinearProblem in FEniCSx. The main difference is that the IncrSmallStrainProblem requires the constitutive model as a parameter and the ufl form is not required. Furthermore, you need to supply the degree of the quadrature rule. You can choose to underintegrate by setting the quadrature degree to a lower value than the degree that is required by the weak form.
from fenics_constitutive import IncrSmallStrainProblem
from dolfinx.nls.petsc import NewtonSolver
problem = IncrSmallStrainProblem(model, u, bcs, 2)
solver = NewtonSolver(MPI.COMM_WORLD, problem)
solver.solve(u)
--------------------------------------------------------------------------- ImportError Traceback (most recent call last) Cell In[3], line 1 ----> 1 from fenics_constitutive import IncrSmallStrainProblem 2 from dolfinx.nls.petsc import NewtonSolver 3 problem = IncrSmallStrainProblem(model, u, bcs, 2) ImportError: cannot import name 'IncrSmallStrainProblem' from 'fenics_constitutive' (/home/docs/checkouts/readthedocs.org/user_builds/fenics-constitutive/checkouts/latest/src/fenics_constitutive/__init__.py)
Updating the solution¶
When solving multiple load steps, you need to update the solution and history variables after each load step. This is done by calling the update method of the IncrSmallStrainProblem. Although, linear elasticity does not have any history variables, we still need to call the update method to update the solution variable $u$.
problem.update()
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[4], line 1 ----> 1 problem.update() NameError: name 'problem' is not defined