@dokken I am running FEniCSx
DOLFINx version: 0.9.0 on ubuntu
ufl version: 2024.2.0
basix version: 0.9.0
I have this simplified version of the Hyperelasticity tutorial: Hyperelasticity — FEniCSx tutorial
from dolfinx import fem, mesh, default_scalar_type
from dolfinx.fem.petsc import NonlinearProblem
from dolfinx.nls.petsc import NewtonSolver
import numpy as np
import ufl
from mpi4py import MPI
L = 20.0
domain = mesh.create_rectangle(MPI.COMM_WORLD, [[0.0, 0.0], [L, 1]], [20, 5], mesh.CellType.quadrilateral)
V = fem.functionspace(domain, ("Lagrange", 2, (domain.geometry.dim, )))
def left(x): return np.isclose(x[0], 0)
def right(x): return np.isclose(x[0], L)
fdim = domain.topology.dim - 1
left_facets = mesh.locate_entities_boundary(domain, fdim, left)
right_facets = mesh.locate_entities_boundary(domain, fdim, right)
# Concatenate and sort the arrays based on facet indices. Left facets marked with 1, right facets with two
marked_facets = np.hstack([left_facets, right_facets])
marked_values = np.hstack([np.full_like(left_facets, 1), np.full_like(right_facets, 2)])
sorted_facets = np.argsort(marked_facets)
facet_tag = 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)]
# Traction
T = fem.Constant(domain, default_scalar_type((0, -1.0)))
v = ufl.TestFunction(V)
u = fem.Function(V)
# Identity tensor
I = ufl.variable(ufl.Identity(len(u)))
# 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) * (Ic - 3) - mu * ufl.ln(J) + (lmbda / 2) * (ufl.ln(J))**2
# PK1 stress
P = ufl.diff(psi, F)
# Define custom quadrature
points = [0.5 - 0.5*np.sqrt(3./5.), 0.5, 0.5 + 0.5*np.sqrt(3./5.)]
points_X, points_Y = np.meshgrid(points, points)
points_2D = np.column_stack((points_X.flatten(), points_Y.flatten()))
weights = [0.5*5./9. , 0.5*8./9., 0.5*5./9.]
weights_2D = np.outer(weights,weights)
metadata={"quadrature_rule": "custom","quadrature_points": points_2D, "quadrature_weights": weights_2D[:]} # This doens't work
#metadata={"quadrature_scheme": "custom","quadrature_points": points_2D, "quadrature_weights": weights_2D[:]} # This works
#metadata = {"quadrature_degree": 5}
ds = ufl.Measure('ds', domain=domain, subdomain_data=facet_tag, metadata=metadata)
dx = ufl.Measure("dx", domain=domain, metadata=metadata)
F = ufl.inner(ufl.grad(v), P) * dx - ufl.inner(v, T) * ds(2)
problem = NonlinearProblem(F, u, bcs)
solver = NewtonSolver(domain.comm, problem)
solver.atol = 1e-8
solver.rtol = 1e-8
solver.convergence_criterion = "incremental"
num_its, _ = solver.solve(u)
print(f"Number of iterations {num_its}, Load {T.value}")
When using:
metadata={"quadrature_rule": "custom","quadrature_points": points_2D, "quadrature_weights": weights_2D[:]}
I get an assertion error from the NonlinearProblem, but:
metadata={"quadrature_scheme": "custom","quadrature_points": points_2D, "quadrature_weights": weights_2D[:]}
Works