Hello to everyone! I’m using fenics legacy version to solve a nonlinear system of partial differential equations with time evolution, but I’m struggling with some problems. I’ll post the code here:
from fenics import *
import matplotlib.pyplot as plt
import numpy as np
import time
combined_file = XDMFFile("combined_solution.xdmf")
combined_file.parameters["flush_output"] = True # Ensure data is written immediately
T = 10.0 # final time
num_steps = 201 # number of time steps
dt = T / num_steps # time step size
tol = 1E-14; eta = 1*10E-7; eps = 4*10E-2; delta = 0.5; Alternate_tol = 1*10E-5
G_c = 1
mesh = UnitSquareMesh(5,5)
mesh_h = UnitSquareMesh(5,5)
V = FunctionSpace(mesh, "Lagrange", 1)
V_h = FunctionSpace(mesh_h, "Lagrange", 1)
g_t = Expression('t', degree=1, t=0)
def boundary_D(x, on_boundary):
return on_boundary and near(x[0], 0, tol) and (x[1] > eps) and (x[1] < 5 + eps)
bc = DirichletBC(V, g_t, boundary_D)
u = Function(V)
v = Function(V)
v.assign(Constant(1.0)) # Initialize v as a constant value
u1 = TestFunction(V)
v1 = TestFunction(V)
F1 = (v**2 + eta)*u*u1*dx
F2 = ((grad(u)**2)*v*v1 + 2*G_c*(v-1)*v1/(4*eps) - eps*inner(grad(v), grad(v1)))*dx
v.interpolate(Constant(1.0)) # Initialize v0 as 1.0
u = Function(V)
v_previous = Function(V)
for t in range(num_steps):
# Update the projection of u at the beginning of each time step
u_n = project(g_t, V)
check_tol = False
i = 0
while not check_tol:
u.assign(u_n) # Set u to the projected value
# Solve for u
solve(F1 == 0, u, bc)
# Solve for v using the previous time step's solution as an upper bound
solve(F2 == 0, v, bc)
# Apply constraints for v not to be smaller than the previous time step
v.vector().set_local(np.maximum(v.vector().get_local(), v_previous.vector().get_local()))
# Calculate the maximum norm of the difference between consecutive v solutions
if(i >0):
maxnorm = norm(v - v_previous, 'linf')
if maxnorm < Alternate_tol:
check_tol = True
else:
i += 1
v_previous.assign(v) # Update the previous solution of v for the next iteration
# Update for the next time step
t += dt
g_t.t = t
combined_file.write(u, t) # Save solution of u
combined_file.write(v, t) # Save solution of v
# Assign current solutions for the next iteration
u_n.assign(u)
v_previous.assign(v)
combined_file.close()
The error that is appearing, is:
No Jacobian form specified for nonlinear variational problem.
Differentiating residual form F to obtain Jacobian J = F'.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 0.000e+00 (tol = 1.000e-10) r (rel) = -nan (tol = 1.000e-09)
Newton solver finished in 0 iterations and 0 linear solver iterations.
No Jacobian form specified for nonlinear variational problem.
Differentiating residual form F to obtain Jacobian J = F'.
Solving nonlinear variational problem.
Newton iteration 0: r (abs) = 4.406e+00 (tol = 1.000e-10) r (rel) = 1.000e+00 (tol = 1.000e-09)
Newton iteration 1: r (abs) = 9.545e-16 (tol = 1.000e-10) r (rel) = 2.166e-16 (tol = 1.000e-09)
Newton solver finished in 1 iterations and 1 linear solver iterations.
Traceback (most recent call last):
File "/home/philip/Documents/math-programming/MATH code/First FEM approx/brittle_9999.py", line 64, in <module>
if maxnorm < Alternate_tol:
NameError: name 'maxnorm' is not defined
I’m struggling with the fact that I need to guarantee that at each time step, the function v is less than the previous time step and, inside the arguments, I need to solve for u such that the Dirichlet conditions are being satisfied (This one I think that I’m done successfully) and I need to do it until the max norm of the difference between v at iteration I and I - 1 is lesser than Alternate_tol. I tried to do this in the code, but I don’t know why it’s not working, and I thought that max norm is defined in fenics, but it’s not working. Does anyone have any tips that could help me please?