Please can you help resolve this error in my code:
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"
Code:
from dolfin import *
import numpy as np
import matplotlib.pyplot as plt
==================== Nondimensional parameters ====================
alpha = 1.5
beta = 0.75
mu_phi = -np.pi
gamma_vals = [0.0, 0.1] # line tension (γ̄)
f_v = 1e-3 # traction force
kbar = 1.0 # bending rigidity
rho = 10.0 # domain radius
dt = 1e-3 # nondimensional time increment
times = [0.0, 0.91, 1.45] # times for profiles
Ns = 800
epsr = 5e-4
delta = 1e-4 # asymptotic origin shift
==================== Mesh and FunctionSpace ====================
mesh1d = IntervalMesh(Ns-1, delta, rho)
2nd-order Lagrange element and 7-field mixed element
P2 = FiniteElement(“CG”, “interval”, 2)
mixed_elem = MixedElement([P2] * 7)
W = FunctionSpace(mesh1d, mixed_elem)
print(“
Mixed space created — DOFs:”, W.dim())
Unknowns [r, z, ψ, M, L, a, λ] and test functions
Y = Function(W)
v = TestFunction(W)
r, z, psi, M, L, a, lam = split(Y)
vr, vz, vpsi, vM, vL, va, vlam = split(v)
x = SpatialCoordinate(mesh1d)[0]
==================== Protein distribution (σ̄ = exp(σ̃)) ====================
Vsig = FunctionSpace(mesh1d, “CG”, 1)
sigma_tilde = Function(Vsig)
sigma_tilde.vector()[:] = 0.0
sigma_bar = exp(sigma_tilde)
C = mu_phi * sigma_bar
r_safe = sqrt(r2 + epsr2)
==================== Governing equations====================
dr = r.dx(0)
dz = z.dx(0)
dpsi = 2*(M/kbar) - sin(psi)/r_safe + 2C
dM = M.dx(0)
L_def = L - rdM
Fv = (alphasigma_bar - beta)*2 + kbar(M/kbar - C)**2 + lam
- (2M/kbar - sin(psi)/r_safe + 2*C)*M
gamma_sym = Constant(0.0)
dL = r*((Fv - gamma_symcos(psi)/r_safe) *
(2M/kbar - sin(psi)/r_safe + 2C)
+ (Fv - gamma_symcos(psi)/r_safe)sin(psi)/r_safe
+ 2M*((M/kbar) - sin(psi)/r_safe + C)*sin(psi)/r_safe)
da = 2np.pir
dsigma = sigma_bar.dx(0)
dlam = 2*(mu_phiM - alpha(alpha*sigma_bar - beta))*dsigma
Weak form (residual)
F = (
(dr - cos(psi))*vr
- (dz - sin(psi))*vz
- (psi.dx(0) - dpsi)*vpsi
- L_def*vM
- (L.dx(0) - dL)*vL
- (a.dx(0) - da)*va
- (lam.dx(0) - dlam)*vlam
) * dx
==================== Boundary Condition====================
class Left(SubDomain):
def inside(self, x, on_boundary):
return near(x[0], delta)
class Right(SubDomain):
def inside(self, x, on_boundary):
return near(x[0], rho)
left = Left()
right = Right()
Apply BCs
bc_r0 = DirichletBC(W.sub(0), Constant(0.0), left) # r(0) = 0
bc_psi0 = DirichletBC(W.sub(2), Constant(0.0), left) # ψ(0) = 0
bc_L0 = DirichletBC(W.sub(4), Constant(0.0), left) # L(0) = 0
bc_a0 = DirichletBC(W.sub(5), Constant(0.0), left) # a(0) = 0
bc_zN = DirichletBC(W.sub(1), Constant(0.0), right) # z(ρ) = 0
bc_psiN = DirichletBC(W.sub(2), Constant(0.0), right) # ψ(ρ) = 0
bc_LN = DirichletBC(W.sub(4), Constant(0.0), right) # L(ρ) = 0
bc_aN = DirichletBC(W.sub(5), Constant(np.pi*rho**2), right) # a(ρ) = πρ²
bcs = [bc_r0, bc_psi0, bc_L0, bc_a0, bc_zN, bc_psiN, bc_LN, bc_aN]
==================== Jacobian and Nonlinear solver ====================
Automatic symbolic Jacobian of the residual
J = derivative(F, Y)
problem = NonlinearVariationalProblem(F, Y, bcs, J)
solver = NonlinearVariationalSolver(problem)
prm = solver.parameters
prm[“newton_solver”][“relative_tolerance”] = 1e-6
prm[“newton_solver”][“absolute_tolerance”] = 1e-8
prm[“newton_solver”][“maximum_iterations”] = 30
==================== Time stepping and results ====================
results = {}
for gamma in gamma_vals:
gamma_sym.assign(gamma)
print(f"\n=== Solving for γ̄ = {gamma} ===“)
results[gamma] =
for t in times:
print(f” t̄ = {t}")
solver.solve()
r_vals = Y.sub(0).vector().get_local()
z_vals = Y.sub(1).vector().get_local()
results[gamma].append((r_vals.copy(), z_vals.copy()))
# ---- Protein diffusion update (forward Euler) ----
s_nodes = mesh1d.coordinates().flatten()
sigma_old = np.exp(sigma_tilde.vector().get_local())
dsigma_num = np.gradient(sigma_old, s_nodes)
M_arr = Y.sub(3).vector().get_local()
dM_num = np.gradient(M_arr, s_nodes)
flux_inner = alpha**2*sigma_old*dsigma_num - mu_phi*dM_num
div_term = np.gradient(s_nodes*flux_inner, s_nodes)
rhs = 2.0/(np.sqrt(s_nodes**2 + epsr**2)*sigma_old)*div_term
sigma_new = np.maximum(sigma_old + dt*rhs, 1e-12)
sigma_tilde.vector()[:] = np.log(sigma_new)
sigma_tilde.vector()[-1] = np.log(beta/alpha)
==================== Axisymmetric surface plots====================
theta = np.linspace(0, 2np.pi, 200)
for gamma, shapes in results.items():
fig = plt.figure(figsize=(10, 4))
for (r_vals, z_vals), t in zip(shapes, times):
R, TH = np.meshgrid(r_vals, theta)
X = Rnp.cos(TH)
Yp = R*np.sin(TH)
Z = np.tile(z_vals, (len(theta), 1))
ax = fig.add_subplot(1, len(times), list(times).index(t)+1, projection=‘3d’)
ax.plot_surface(X, Yp, Z, color=‘salmon’, alpha=0.9, edgecolor=‘none’)
ax.set_title(f"γ̄={gamma}, t̄={t}“)
ax.set_axis_off()
plt.suptitle(f"Membrane Budding Evolution (γ̄={gamma})”)
plt.show()