Here is a (more or less) minimal example of my code. A bar is clamped on one end with a traction T on the other end. I want to calculate the reaction forces on the clamped end (as shown in the link I posted above). This is just an example code to see if the reaction forces are calculated correctly, in my actual code I have a complex geometry and Dirichlet boundary conditions for the displacement instead of a traction force. If there is another way to calculate the reaction forces (other than integrating the stress field over my boundary, this is not exact enough) please give me an advise on how to do so.
Thanks again!
import numpy as np
from dolfinx.cpp.io import perm_gmsh, extract_local_entities
import dolfinx
import ufl
import dolfinx.io
from petsc4py import PETSc
def get_DirichletBC(V, subspace, coordinate, location, disp):
"""
Returns dolfinx.Dirichlet() condition
Input:
str V: Functionspace variable
int subspace: V.sub(0,1,2) spatial direction of function space
int coordinate: spatial direction of boundary
double location: value of boundary location in respective direction
double disp: prescribed displacement for respective boundary
"""
dofs = dolfinx.fem.locate_dofs_geometrical((V.sub(subspace), V.sub(subspace).collapse()),
lambda x: np.isclose(x[coordinate], location))
u_d = dolfinx.Function(V.sub(subspace).collapse())
with u_d.vector.localForm() as loc:
loc.set(disp)
dirichlet = dolfinx.DirichletBC(u_d, dofs, V.sub(subspace))
return dirichlet
# Green-Lagrange strain
def Epsilon():
return 0.5 * (F.T * F - I)
# 2nd Piola-Kirchhoff stress
def Sigma():
return lambda_ * ufl.tr(Epsilon())*I + 2 * mu * Epsilon()
mesh = dolfinx.BoxMesh(MPI.COMM_WORLD,[[0.0,0.0,-15.0], [1, 1, 15.0]], [5, 5, 150], dolfinx.cpp.mesh.CellType.hexahedron)
# create face-tags
boundaries = [(1, lambda x: np.isclose(x[2], -15.0)),
(2, lambda x: np.isclose(x[2], 15.0))]
facet_indices, facet_markers = [], []
fdim = mesh.topology.dim - 1
for (marker, locator) in boundaries:
facets = dolfinx.mesh.locate_entities(mesh, fdim, locator)
facet_indices.append(facets)
facet_markers.append(np.full(len(facets), marker))
facet_tag = dolfinx.MeshTags(mesh, fdim, np.array(np.hstack(facet_indices), dtype=np.int32),
np.array(np.hstack(facet_markers), dtype=np.int32)
# define measure for surface integration
ds = ufl.Measure("ds", domain=mesh, subdomain_data=facet_tag)
# create function space
V = dolfinx.VectorFunctionSpace(mesh, ("CG", 1))
#define material parameters
E = 44
nu = 0.4
lambda_ = nu * E / ((1 - 2 * nu) * (1 + nu))
mu = 0.5 * E / (1 + nu)
# define trial and test function
#u = ufl.TrialFunction(V) # for linear problem
u = dolfinx.Function(V) # for nonlinear problem
v = ufl.TestFunction(V)
# define volume forces f and traction forces T
f = dolfinx.Constant(mesh, (0.0, 0.0, 0.0))
T = dolfinx.Constant(mesh, (0.0, 0.0, 0.01))
#define kinematic quantities used in the problem
#spatial dimension
d = len(u)
#identity tensor
I = ufl.variable(ufl.Identity(d))
#Deformation gradient
F = ufl.variable(I + ufl.grad(u))
#right Cauchy-Green tensor
C = ufl.variable(F.T*F)
#Invariants of deformation tensors
Ic = ufl.variable(ufl.tr(C))
J = ufl.variable(ufl.det(F))
# Define form F (we want to find u such that F(u) = 0)
Form = ufl.inner(ufl.grad(v), Sigma())*ufl.dx - ufl.inner(v, f)*ufl.dx - ufl.inner(v, T)*ds(2)
# define Dirichlet bonudary conditions
clamped_x = get_DirichletBC(V, 0, 2, -15.0, 0.0)
clamped_y = get_DirichletBC(V, 1, 2, -15.0, 0.0)
clamped_z = get_DirichletBC(V, 2, 2, -15.0, 0.0)
top_x = get_DirichletBC(V, 0, 2, 15.0, 0.0)
top_y = get_DirichletBC(V, 1, 2, 15.0, 0.0)
bc = [clamped_x, clamped_y, clamped_z, top_x, top_y]
problem = dolfinx.fem.NonlinearProblem(Form, u, bc)
solver = dolfinx.NewtonSolver(MPI.COMM_WORLD, problem)
num_its, converged = solver.solve(u)
u.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD)
u.name = "Displacement"