Introduction
In this step, we will try to solve the linear elasticity problem.
The stress equilibrium equation
The problem we want to solve is the equation of stress equilibrium (without body force and acceleration) that reads as follows: $$ \begin{equation} \mathbf{\nabla}\cdot\mathbf{\sigma}=\mathbf{0} \label{eq:stress-eq} \tag{1} \end{equation} $$ where \(\mathbf{\sigma}\) denotes Cauchy stress tensor. Below are the constitutive laws for stress and strain in the case of small deformations: $$ \begin{equation} \mathbf{\sigma}=\mathbb{C}:\mathbf{\epsilon} \label{eq:stress} \tag{2} \end{equation} $$ and $$ \begin{equation} \mathbf{\epsilon}=\frac{1}{2}(\nabla\mathbf{u}+\nabla \mathbf{u}^{T}) \label{eq:dirichlet} \tag{3} \end{equation} $$ where \(\mathbf{u}\) is the displacement vector. \(\mathbb{C}\) represents the elasticity tensor, which is a function of the Youngs modulus \(E\) and Poisson ratio \(\nu\).
The related boundary conditions can be read as: $$ \begin{equation} \mathbf{t}\cdot\vec{n}=0\qquad\mathrm{on}\quad\partial\Omega_{N} \label{eq:traction} \tag{4} \end{equation} $$ and $$ \begin{equation} \mathbf{u}=\mathbf{u}_{0}\qquad\mathrm{on}\quad\partial\Omega_{D} \label{eq:disp} \tag{5} \end{equation} $$ where the traction free condition is assumed in Eq.\(\eqref{eq:traction}\)
Define a mesh
We will be using a rectangular domain for our calculations. To define this domain, we use the mesh
block, which can be expressed as follows:
"mesh":{
"type":"asfem",
"dim":2,
"nx":50,
"ny":50,
"xmax":5.0,
"ymax":5.0,
"meshtype":"quad4",
"savemesh":true
},
where a \(50\times50\) mesh is defined.
Define the DoFs
In this step, the displacement vector is used as the degree of freedom, specifically \(u_{x}\) and \(u_{y}\). The dofs
block can be expressed as follows:
"dofs":{
"names":["ux","uy"]
}
Element for stress equilibrium equation
The model given in Eq.\(\eqref{eq:stress-eq}\) can be implemented using the following lines:
"elements":{
"elmt1":{
"type":"mechanics",
"dofs":["ux","uy"],
"material":{
"type":"linearelastic",
"parameters":{
"E":1.0e3,
"nu":0.3
}
}
}
}
The "type":"mechanics"
option in the above lines specifies the element to be used for the solid mechanics problem. Additionally, since we will be using linear elasticity material properties, the related material definition will be provided in the material
block.
Linear elasticity material
The following lines within the material
block can be used to define the linear elasticity material:
"material":{
"type":"linearelastic",
"parameters":{
"E":1.0e3,
"nu":0.3
}
}
where "type":"linearelastic"
specifies linear elasticity material model. parameters
defines the Youngs modulus (\(E=100GPa\)) and Poisson ratio (\(\nu=0.3\)).
It is worth noting that AsFem does not enforce any specific unit system or interpret results in a particular unit. Therefore, the user must ensure that the input parameters and result interpretation are consistent with their intended application..
Boundary conditions
The boundary conditions mentioned in Eq.\(\eqref{eq:disp}\) can be implemented using the bcs
block. In this case, since the traction boundary condition in Eq.\(\eqref{eq:traction}\) is zero, we only need to consider the displacement boundary condition.
"bcs":{
"fix":{
"type":"dirichlet",
"dofs":["ux","uy"],
"bcvalue":0.0,
"side":["bottom"]
},
"load":{
"type":"dirichlet",
"dofs":["uy"],
"bcvalue":0.1,
"side":["top"]
}
}
where we fix \(u_{x}\) and \(u_{y}\) to be zero at the bottom edge of the domain, while \(u_{y}=0.1\) is applied at the top edge.
Static analysis
To start the FEM calculation, we need to use the job
block. The following lines can be used for this purpose:
"job":{
"type":"static",
"print":"dep"
}
Projection
Wait for a second, where are the stresses and strain? How can I output them?
Noooo worries, the projection
block can be used to project the quantities from each Gauss point
to the Nodal point
of your mesh. To visualize the vonMises stress, \(\sigma_{xx}\), \(\sigma_{yy}\), and \(\sigma_{xy}\), you can use the following code:
"projection":{
"type":"default",
"scalarmate":["vonMises-stress"],
"rank2mate":["stress","strain"]
}
The default option for the projection
block ("type":"default"
) will execute the simplified least squares projection algorithm.
Explanation of projection
The projection
block is not a magic tool. If you examine the LinearElasticMaterial.cpp file in the MateSystem class, you will find the following code:
mate.ScalarMaterial("vonMises-stress")=sqrt(1.5*m_devStress.doubledot(m_devStress));
mate.Rank2Material("strain")=m_strain;
mate.Rank2Material("stress")=m_stress;
The material properties, which include scalar, vector, and tensor materials, are stored in the material class and can be easily accessed using their respective material names. Users only need to provide the names of the output material properties in the projection
block. Additionally, the general tensor form used in this block is designed to work for all dimensions, from 1D to 3D.
Run it in AsFem
To try the third example in AsFem, create a new text file and name it step3.json
or any other name you prefer. Then, copy and paste the following lines into your input file:
{
"mesh":{
"type":"asfem",
"dim":2,
"nx":50,
"ny":50,
"xmax":5.0,
"ymax":5.0,
"meshtype":"quad4",
"savemesh":true
},
"dofs":{
"names":["ux","uy"]
},
"elements":{
"elmt1":{
"type":"mechanics",
"dofs":["ux","uy"],
"material":{
"type":"linearelastic",
"parameters":{
"E":1.0e3,
"nu":0.3
}
}
}
},
"projection":{
"type":"default",
"scalarmate":["vonMises-stress"],
"rank2mate":["stress","strain"]
},
"nlsolver":{
"type":"newton",
"solver":"gmres",
"maxiters":50,
"abs-tolerance":5.0e-7,
"rel-tolerance":5.0e-10,
"s-tolerance":0.0,
"preconditioner":"lu"
},
"output":{
"type":"vtu",
"interval":1
},
"bcs":{
"fix":{
"type":"dirichlet",
"dofs":["ux","uy"],
"bcvalue":0.0,
"side":["bottom"]
},
"load":{
"type":"dirichlet",
"dofs":["uy"],
"bcvalue":0.1,
"side":["top"]
}
},
"qpoints":{
"bulk":{
"type":"gauss-legendre",
"order":2
}
},
"job":{
"type":"static",
"print":"dep"
}
}
It's worth noting that if the "preconditioner":"lu"
option in the nlsolver
block doesn't work, you may need to either change lu
to jacobi
, or install MUMPS or SuperLU for your PETSc.
You can also find the complete input file in examples/tutorial/step3-2d.json
.
If everything goes well, you can see the following images in your Paraview: