Hello everyone,
i am currently writing my first python package for modeling a hyperelastic problem. Therefor I want to write the different material laws and kinematic quantities in separate files and call them from a central file.
Unfortunately, the solution does not converge if the ufl variables for the kinematic quantities are not defined directly at the weak form of the problem itself.
Since the problem cannot be easily translated into a short MWE, I’ll try the following example.
I assume that I have fundamentally misunderstood or misapplied something here and the error can be easily detected by someone more experienced than me.
Code that works:
# FILE A: material_models
import ufl
from dolfinx import fem
from petsc4py.PETSc import ScalarType
def neo_hooke(domain, u):
I = ufl.variable(ufl.Identity(len(u)))
F = ufl.variable(I + ufl.grad(u))
C = ufl.variable(F.T * F)
I_1 = ufl.variable(ufl.tr(C))
J = ufl.variable(ufl.det(F))
E = ScalarType(1.0e4)
nu = ScalarType(0.3)
mu = fem.Constant(domain, E/(2*(1 + nu)))
lmbda = fem.Constant(domain, E*nu/((1 + nu)*(1 - 2*nu)))
psi = (mu / 2) * (I_1 - 3) - mu * ufl.ln(J) + (lmbda / 2) * (ufl.ln(J))**2
P = ufl.diff(psi, F)
S = 2 * ufl.diff(psi, C)
return P, S
Code that does not work:
# FILE A: material_models
import ufl
from dolfinx import fem
from petsc4py.PETSc import ScalarType
from kinematics import *
def neo_hooke(domain, u):
E = ScalarType(1.0e4)
nu = ScalarType(0.3)
mu = fem.Constant(domain, E/(2*(1 + nu)))
lmbda = fem.Constant(domain, E*nu/((1 + nu)*(1 - 2*nu)))
psi = (mu / 2) * (I1(u) - 3) - mu * ufl.ln(jacobian_defgrad(u)) + (lmbda / 2) * (ufl.ln(jacobian_defgrad(u)))**2
P = ufl.diff(psi, deformation_gradient(u))
S = 2 * ufl.diff(psi, right_cauchygreen(u))
return P, S
# FILE B: kinematics
import ufl
import numpy as np
def identity_tensor(u):
d = len(u)
return ufl.variable(ufl.Identity(d))
def deformation_gradient(u):
I = identity_tensor(u)
return ufl.variable(I + ufl.grad(u))
def jacobian_defgrad(u):
F = deformation_gradient(u)
return ufl.variable(ufl.det(F))
def right_cauchygreen(u):
F = deformation_gradient(u)
return ufl.variable(F.T * F)
def I1(u):
C = right_cauchygreen(u)
I1 = ufl.tr(C)
return ufl.variable(I1)
Thanks in advance!