Divergence of Newton Solver for coupled Reaction-Diffusion Problem

Dear. Researchers
I am trying to model 2D oxidation problem using reaction-diffusion approach. To achieve this goal, I have utilized fully implicit backward Euler for time-discretization as well as physical parameters like diffusion coefficient (D), reaction kinetics parameter(eta) and molarity. In this problem we have two time scales one for diffusion and another for reaction. Based on the parameters, the reaction possesses fast kinetics compared with diffusion. Accordingly, I choose time-step lower than reaction time-scale to resole this process. Upon, running the code, newton solvers executes two steps successfully but afterwards it diverges. I will be really appreciate if someone assist me to resolve the issue. I will put the code in the following:

from dolfin import *
import numpy as np
import matplotlib.pyplot as plt

# -----------------------------
# Time parameters
# -----------------------------


num_steps = 10000
t = 0.0
t_end = 100

dt = t_end/num_steps
dt_var = Constant(dt)

BC_thickness = 295e-6
Oxide_thickness = 5e-6
Lx = 60e-6
Ly = 300e-6
# -----------------------------
# Geometry
# -----------------------------


nx, ny = 300,1000

mesh = RectangleMesh(Point(0,0), Point(Lx,Ly),nx,ny)


P1 = FiniteElement("Lagrange", mesh.ufl_cell(),1)
M = FunctionSpace(mesh,MixedElement([P1,P1]))

w = Function(M)
w_old = Function(M)
dw = TrialFunction(M)


c_new,n_new = split(w)
c_old, n_old = split(w_old)
v_c,v_n = TestFunctions(M)

# -----------------------------
# Parameters
# -----------------------------
D = Constant(2e-13)
eta = Constant(1e-5)
Molarity = Constant(1.11e5)


class K(UserExpression):
    def eval(self,values,x):
        ell = BC_thickness/100
        delta = np.sqrt(2)*ell
        values[0] = 0.0
        if x[1] >= BC_thickness:
            values[1] = 1.0
        else:
            values[1] = 0.0
        # delta = 5*mesh.hmin()
        # values[1] = 0.5*(1 + np.tanh((x[1] - BC_thickness)/delta))



    def value_shape(self):
        return(2,)

u_init = K(mesh)
w.interpolate(u_init)


file_1 = File("c_initial2D.pvd")
file_2 = File("n_initial2D.pvd")


file_1 << w.split(deepcopy= True)[0]
file_2 << w.split(deepcopy= True)[1]
w_old.assign(w)


def top(x,on_boundary):
    return on_boundary and near(x[1], Ly)
def bot(x,on_boundary):
    return on_boundary and near(x[1], 0.0)

c_bot = Constant(0.0)

c_top = Constant(1.55)

bc_c1 = DirichletBC(M.sub(0), c_top,top)
bc_c2 = DirichletBC(M.sub(0), c_bot,bot)

bcs_problem = [bc_c1,bc_c2]



# Form_c = ((c_new - c_old)/dt_var * v_c * dx
#           + D*inner(grad(c_new), grad(v_c))*dx
#           + Molarity*((n_new - n_old)/dt_var)*v_c*dx)


Form_c = ((c_new - c_old)/dt_var * v_c * dx
          + D*inner(grad(c_new), grad(v_c))*dx
          + Molarity*eta*(1-n_new)*c_new*v_c*dx)

Form_n = ((n_new - n_old)/dt_var * v_n * dx
          - eta*c_new*(1 - n_new)*v_n*dx)




Form_total = Form_c + Form_n



Gain = derivative(Form_total, w,dw)
# -----------------------------


problem = NonlinearVariationalProblem(Form_total, w, bcs_problem,J = Gain)
solver = NonlinearVariationalSolver(problem)

prm = solver.parameters["newton_solver"]
prm["absolute_tolerance"] = 1e-6
prm["relative_tolerance"] = 1e-5
prm["maximum_iterations"] = 50
prm["linear_solver"] = "mumps"
prm["relaxation_parameter"] = 0.5
prm["report"] = True


file_c = File("results2D1/c_fully_implicit2D1.pvd")
file_n = File("results2D1/n_fully_implicit2D1.pvd")
# -----------------------------
# Time loop
# -----------------------------




front_positions = []
time_values = []

for n in range(num_steps):
    t += dt
    
    # solve(Form_total == 0, w , bcs_problem, J = Gain)
   
    solver.solve()
    c_sol, n_sol = w.split(deepcopy= True)


    file_c << (c_sol,t)
    file_n << (n_sol,t)
    w_old.assign(w)

Could you provide the output of your code? For me it doesn’t diverge, but it starts converging after 0 iterations, meaning that the solution after 2 steps is a solution that is stationary for all further time-steps.

Thanks for your response. actually, in the code I set initial thickness of oxide layer equals oxide_thickness = 1 micrometer and expect to see the evolution of oxide thickness during oxidation. The physical parameters, dimensions and boundary conditions are borrowed from a paper(attached below). According to this paper the oxide thickness increase from 1 (initial thickness) based on the duration of oxidation(kindly see figure 5 of the paper). So basically I should not obtain a stationary solution since oxide evolves. please note that both c (concentration) and n(oxide volume fraction) should be positive.
import pkg_resources
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 8.048e+01 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton iteration 1: r (abs) = 4.024e+01 (tol = 1.000e-06) r (rel) = 5.000e-01 (tol = 1.000e-05)
Newton iteration 2: r (abs) = 2.012e+01 (tol = 1.000e-06) r (rel) = 2.500e-01 (tol = 1.000e-05)
Newton iteration 3: r (abs) = 1.006e+01 (tol = 1.000e-06) r (rel) = 1.250e-01 (tol = 1.000e-05)
Newton iteration 4: r (abs) = 5.030e+00 (tol = 1.000e-06) r (rel) = 6.250e-02 (tol = 1.000e-05)
Newton iteration 5: r (abs) = 2.515e+00 (tol = 1.000e-06) r (rel) = 3.125e-02 (tol = 1.000e-05)
Newton iteration 6: r (abs) = 1.258e+00 (tol = 1.000e-06) r (rel) = 1.562e-02 (tol = 1.000e-05)
Newton iteration 7: r (abs) = 6.288e-01 (tol = 1.000e-06) r (rel) = 7.812e-03 (tol = 1.000e-05)
Newton iteration 8: r (abs) = 3.144e-01 (tol = 1.000e-06) r (rel) = 3.906e-03 (tol = 1.000e-05)
Newton iteration 9: r (abs) = 1.572e-01 (tol = 1.000e-06) r (rel) = 1.953e-03 (tol = 1.000e-05)
Newton iteration 10: r (abs) = 7.859e-02 (tol = 1.000e-06) r (rel) = 9.766e-04 (tol = 1.000e-05)
Newton iteration 11: r (abs) = 3.930e-02 (tol = 1.000e-06) r (rel) = 4.883e-04 (tol = 1.000e-05)
Newton iteration 12: r (abs) = 1.965e-02 (tol = 1.000e-06) r (rel) = 2.441e-04 (tol = 1.000e-05)
Newton iteration 13: r (abs) = 9.824e-03 (tol = 1.000e-06) r (rel) = 1.221e-04 (tol = 1.000e-05)
Newton iteration 14: r (abs) = 4.912e-03 (tol = 1.000e-06) r (rel) = 6.104e-05 (tol = 1.000e-05)
Newton iteration 15: r (abs) = 2.456e-03 (tol = 1.000e-06) r (rel) = 3.052e-05 (tol = 1.000e-05)
Newton iteration 16: r (abs) = 1.228e-03 (tol = 1.000e-06) r (rel) = 1.526e-05 (tol = 1.000e-05)
Newton iteration 17: r (abs) = 6.140e-04 (tol = 1.000e-06) r (rel) = 7.629e-06 (tol = 1.000e-05)
Newton solver finished in 17 iterations and 17 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 6.140e-04 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton iteration 1: r (abs) = 3.070e-04 (tol = 1.000e-06) r (rel) = 5.000e-01 (tol = 1.000e-05)
Newton iteration 2: r (abs) = 1.535e-04 (tol = 1.000e-06) r (rel) = 2.500e-01 (tol = 1.000e-05)
Newton iteration 3: r (abs) = 7.675e-05 (tol = 1.000e-06) r (rel) = 1.250e-01 (tol = 1.000e-05)
Newton iteration 4: r (abs) = 3.838e-05 (tol = 1.000e-06) r (rel) = 6.250e-02 (tol = 1.000e-05)
Newton iteration 5: r (abs) = 1.919e-05 (tol = 1.000e-06) r (rel) = 3.125e-02 (tol = 1.000e-05)
Newton iteration 6: r (abs) = 9.594e-06 (tol = 1.000e-06) r (rel) = 1.562e-02 (tol = 1.000e-05)
Newton iteration 7: r (abs) = 4.797e-06 (tol = 1.000e-06) r (rel) = 7.812e-03 (tol = 1.000e-05)
Newton iteration 8: r (abs) = 2.399e-06 (tol = 1.000e-06) r (rel) = 3.906e-03 (tol = 1.000e-05)
Newton iteration 9: r (abs) = 1.199e-06 (tol = 1.000e-06) r (rel) = 1.953e-03 (tol = 1.000e-05)
Newton iteration 10: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 9.766e-04 (tol = 1.000e-05)
Newton solver finished in 10 iterations and 10 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 5.996e-07 (tol = 1.000e-06) r (rel) = 1.000e+00 (tol = 1.000e-05)
Newton solver finished in 0 iterations and 0 linear solver iterations.


https://www.sciencedirect.com/science/article/abs/pii/S0927025618305408

The problem is that you don’t rescale your mesh and the rest of your equation, i.e.

Is in itself a bit problematic, as it will cause each element to be of size ~1e-7**2, which is very small, and since you haven’t modified the convergence criteria of your newton algorithm, i.e. the tolerances for termination is:

You see that convergence at:

I would suggest rescaling your problem, for instance by following the strategies from

Before going down that route, you could try changing the above tolerances to something smaller, like 1e-10.
However, it might not be sufficient and it might be easier just scaling up your equation.

1 Like

To alleviate the divergence, I applied two changes to the model. First I refined the mesh around the interface and second nondimensionalized equations according to the contents provided in the book “Scaling of Differential Equations”. As a result of these manipulations, the newton solver converged.

1 Like