Variational formulation for hyperelastic material based on spectral decomposition

Hi, all. I’m trying to solve a problem of a neo-hookean hyperelastic model based on the spectral decompostion, but I get the error message
*** Error: Unable to solve nonlinear system with NewtonSolver.
*** Reason: Newton solver did not converge because maximum number of iterations reached.
*** Where: This error was encountered inside NewtonSolver.cpp.
*** Process: 0
Can you tell me where I’m wrong and how I can change it? Thanks a lot in advance!
The code is attached below
from future import division
from dolfin import *
from mshr import *
from scipy import optimize

# ----------------------------------------------------------------------------
# Parameters for DOLFIN and SOLVER
# ----------------------------------------------------------------------------
set_log_level(LogLevel.WARNING)  # 20, // information of general interest
# set some dolfin specific parameters
# ----------------------------------------------------------------------------
parameters["form_compiler"]["representation"]="uflacs"
parameters["form_compiler"]["optimize"]=True
parameters["form_compiler"]["cpp_optimize"]=True
parameters["form_compiler"]["quadrature_degree"]=4
info(parameters,True)

ut      = 1.0 # reference value for the loading (imposed displacement)

# Numerical parameters of the alternate minimization
maxiteration = 2000
AM_tolerance = 1e-4

# Mesh generation
mesh = UnitSquareMesh.create(1,1, CellType.Type.quadrilateral)

#define function space
W=VectorFunctionSpace(mesh,'CG',1)#displacement

u,v=TrialFunction(W),TestFunction(W)
u_new=Function(W)
u_old=Function(W)


E=10
nu=0.3
mu=Constant(E/(2*(1 + nu)))
K0=Constant(E/(3*(1-2*nu)))

#define boundary condition
support = CompiledSubDomain("on_boundary && near(x[1], 0, tol)", tol=1e-14)
force_face = CompiledSubDomain("on_boundary && near(x[1], 1, tol)", tol=1e-14)
applied_disp = Expression("disp", disp=0.0, degree=2)
# --------------------------------------------------------------------------
bc_bot = DirichletBC(W, Constant((0.0, 0.0)), support)
bc_top = DirichletBC(W.sub(1), applied_disp, force_face)
bcu = [bc_bot, bc_top]

boundaries=MeshFunction("size_t",mesh,mesh.topology().dim()-1)
boundaries.set_all(0)
force_face.mark(boundaries,1)
ds=Measure("ds")(subdomain_data=boundaries)

#define some continuum formulation
d=len(u_new)
I=Identity(d)

# Kinematics
d = len(u_new)
I = Identity(d)
# Identity tensor
def DeformationGradient(u):
    return variable(I + grad(u))

def Jacobian(u):
    F = DeformationGradient(u)
    return variable(det(F))

def RightCauchyGreen(u):
    F = DeformationGradient(u)
    return variable(F.T * F)

def delta_E(v,u):
    F = DeformationGradient(u)
    return (dot(F.T,grad(v))+dot(grad(v).T,F))/2

def eigv_eigw_epsilon(e): #calculate the eigenvalue and eigenvector of a tensor
    tr_e  = tr(e)
    det_e = det(e)
    v1    = 0.5*tr_e + sqrt(tr_e*tr_e/4.0 - det_e)
    v2    = 0.5*tr_e - sqrt(tr_e*tr_e/4.0 - det_e)
    w1    = conditional(gt(abs(e[0,1]),1E-10), as_vector([v1-e[1,1], e[0,1]]), as_vector([1.0, 0.0]))
    w2    = conditional(gt(abs(e[0,1]),1E-10), as_vector([v2-e[1,1], e[0,1]]), as_vector([0.0, 1.0]))
    norm1 = sqrt(dot(w1,w1))
    norm2 = sqrt(dot(w2,w2))
    w1    = w1/norm1
    w2    = w2/norm2
    return v1, v2, w1, w2

#energy density of compressible neo-hookean solid
#W=mu*(I1-3-2ln(J))/2+0.5*K0*(ln(J))^2
# where I1=tr(F.T*F),J=det(F)

def pk2(u,K0,mu):  #calculate the 2nd piola-kirchhoff stress tensor
    C = RightCauchyGreen(u)
    J = Jacobian(u)
    C1=inv(C)
    eig12,eig22,w1,w2=eigv_eigw_epsilon(C)
    piola2=mu*(1-1/eig12)*outer(w1,w1)+mu*(1-1/eig22)*outer(w2,w2)+K0*ln(J)*C1
    return piola2

F_u=inner(pk2(u_new,K0,mu),delta_E(v,u_new))*dx
J_u=derivative(F_u,u_new,u)

# Variational problem for the displacement
problem_u = NonlinearVariationalProblem(F_u, u_new, bcu, J=J_u)
# Set up the solvers
solver_u  = NonlinearVariationalSolver(problem_u)

t=0
ur=1
deltaT=0.1
tol=1e-4
conc_f=File("./hyperelastic1/u.pvd")
fname=open('F_D_curve1.txt','w')
outfile=XDMFFile("output1.xdmf")

#staggered scheme
while t<=1.0:
    t+=deltaT
    if t>=0.4:
        deltaT=0.1
    applied_disp.disp=t*ur
    iter=0
    err=1
    while err>AM_tolerance and iter<maxiteration:
        iter +=1
        solver_u.solve()
        u_err = u_new.vector() - u_old.vector()
        err = u_err.norm('linf')
        u_old.assign(u_new)
        if err<tol:
            print('Iterations:',iter,',Total time',t)
            conc_f << u_new
            outfile.write(u_new, t)


print('simulation completed')
print(u_new.vector()[:])
1 Like