#add code here
from dolfinx import log, default_scalar_type
from dolfinx.fem.petsc import NonlinearProblem
from dolfinx.nls.petsc import NewtonSolver
import numpy as np
import ufl
import basix
from mpi4py import MPI
from dolfinx import fem, mesh, plot
L = 10.0
#############For 3D case#######################
# domain = mesh.create_box(MPI.COMM_WORLD, [[0.0, 0.0, 0.0], [L, 1, 1]], [1, 1, 1], mesh.CellType.hexahedron)
# B = fem.Constant(domain, default_scalar_type((0, 0,0)))
# T = fem.Constant(domain, default_scalar_type((0, 0,0)))
#############For 2D case#######################
domain = mesh.create_rectangle(comm=MPI.COMM_WORLD, points=((0.0, 0.0), (10.0,1.0)), n=(20,5), cell_type=mesh.CellType.quadrilateral)
B = fem.Constant(domain, default_scalar_type((0, 0)))
T = fem.Constant(domain, default_scalar_type((0, 0)))
#element = ufl.vectorelement("Lagrange", domain.ufl_cell(),1)
#V=fem.FunctionSpace(domain, element)
#V = fem.VectorFunctionSpace(mesh, "Lagrange", 1)
element = basix.ufl.element("Lagrange", basix.CellType.quadrilateral, 1)
mesh = mesh.create_rectangle(comm=MPI.COMM_WORLD, points=((0.0, 0.0), (10.0,1.0)), n=(20,5), cell_type=mesh.CellType.quadrilateral) #dolfinx.mesh.create_rectangle(MPI.COMM_WORLD, 1, 1, 1, cell_type=dolfinx.mesh.CellType.hexahedron)
V = dolfinx.fem.functionspace(domain, element)
def left(x):
return np.isclose(x[0], 0)
fdim = domain.topology.dim - 1
left_facets = dolfinx.mesh.locate_entities_boundary(domain, fdim, left)
# Concatenate and sort the arrays based on facet indices. Left facets marked with 1, right facets with two
marked_facets = np.hstack([left_facets])
marked_values = np.hstack([np.full_like(left_facets, 1)])
sorted_facets = np.argsort(marked_facets)
facet_tag = dolfinx.mesh.meshtags(domain, fdim, marked_facets[sorted_facets], marked_values[sorted_facets])
u_bc = np.array((0,) * domain.geometry.dim, dtype=default_scalar_type)
left_dofs = fem.locate_dofs_topological(V, facet_tag.dim, facet_tag.find(1))
bcs = [fem.dirichletbc(u_bc, left_dofs, V)]
v = ufl.TestFunction(V)
u = fem.Function(V)
# Identity tensor
I = ufl.variable(ufl.Identity(3))
# Deformation gradient
def grad_3D(u):
return ufl.as_matrix([[u[0].dx(0), u[0].dx(1), 0],
[u[1].dx(0), u[1].dx(1), 0],
[0, 0, 0]])
F = ufl.variable(I + grad_3D(u))
# 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))
# Elasticity parameters
E = default_scalar_type(1.0e4)
nu = default_scalar_type(0.3)
mu = fem.Constant(domain, E / (2 * (1 + nu)))
lmbda = fem.Constant(domain, E * nu / ((1 + nu) * (1 - 2 * nu)))
# Stored strain energy density (compressible neo-Hookean model)
psi = ((mu/2) * (((J**(-2./3.)) * Ic) - 3)) + ((lmbda/2) * (((J**2.) /2) - (1/2) - ufl.ln(J)) )
ee=-1.5*mu
dd=mu
#psi = (mu/2*fem.inner(F, F) + ee - dd*fem.ln(J))*fem.dx - rho_0*J*fem.dot(b, u)*fem.dx + surface_def*fe.inner(g, u)*ds(1) #psi = (aa*fe.inner(F, F) + ee - dd*fe.ln(J))*fe.dx - rho_0*J*fe.dot(b, u)*fe.dx + surface_def*fe.inner(g, u)*ds(1)
# Stress
# Hyper-elasticity
P = ufl.diff(psi, F)
metadata = {"quadrature_degree": 4}
ds = ufl.Measure('ds', domain=domain, metadata=metadata)
dx = ufl.Measure("dx", domain=domain, metadata=metadata)
# Define form F (we want to find u such that F(u) = 0)
F = ufl.inner(grad_3D(v), P) * dx - ufl.inner(v, B) * dx - ufl.inner(v, T) * ds
problem = NonlinearProblem(F, u, bcs)
solver = NewtonSolver(domain.comm, problem)
# Set Newton solver options
solver.atol = 1e-8
solver.rtol = 1e-8
solver.convergence_criterion = "incremental"
solver.solve(u)
I’m trying to solve the hyperelasticity example for a 2d case, this is my code, but I’m having several issues, starting from the dirichlet BCs where I receive this error message:
RuntimeError: Rank mis-match between Constant and function space in DirichletBC
could you please check my code.
Thank you