Hi fenics community,
I use the mixed dimensional branch of @cdaversin and try to solve a time-dependent problem with the following reduced code:
from dolfin import *
from ufl.algorithms import expand_derivatives
# Create mesh
L = 0.20
H = 0.01
mesh = RectangleMesh(Point(0., 0.), Point(L, H), 160, 8, "right")
# Define boundaries and boundary conditions
marker = MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0)
marker.set_all(99)
class BoundaryLeft(SubDomain):
def inside(self, x, on_boundary):
return on_boundary and near(x[0], 0 + DOLFIN_EPS)
class BoundaryRight(SubDomain):
def inside(self, x, on_boundary):
return on_boundary and near(x[0], L - DOLFIN_EPS) # H-h
boundary_left = BoundaryLeft()
boundary_left.mark(marker, 1)
boundary_mesh_left = MeshView.create(marker, 1)
boundary_right = BoundaryRight()
boundary_right.mark(marker, 2)
dV = Measure("dx", domain=mesh)
dS_l = Measure("dx", domain=boundary_mesh_left)
dS_r = Measure("ds", domain=mesh, subdomain_data=marker)
tau = Expression(('0.', 't <= tc ? 2*t/tc : 0'), t=0, tc=0.01, degree=1)
nue = Expression(('0', '0'), degree=1)
# Define function space
V_v = VectorElement('CG', mesh.ufl_cell(), 1, dim=2)
V_S = TensorElement('DG', mesh.ufl_cell(), 0, shape=(2, 2), symmetry=True)
MX_elem = MixedElement([V_v, V_S])
MX = FunctionSpace(mesh, MX_elem)
LM_left = VectorFunctionSpace(boundary_mesh_left, 'CG', 1, dim=2)
W = MixedFunctionSpace(MX, LM_left)
# Define trial and test functions
w_ = Function(W)
mx, l_left = w_.split()
v, S = split(mx)
dmx, dl_left = TestFunctions(W)
dv, dS = split(dmx)
# Variables of current time step
w_n = Function(W)
mx_n, l_left_n = w_n.split()
v_n, S_n = split(mx_n)
# Time-stepping parameters
T = 0.1
n = 1000
dt = float(T / n)
# Time-stepping
for i in range(n):
print("Time: ", dt * (i + 1))
# Update Neumann boundary conditions
tau.t = float(dt * (i + 1 / 2))
# Residual
v_mid = (v + v_n) / 2
S_mid = (S + S_n) / 2
l_left_mid = (l_left + l_left_n) / 2
R0 = dot(dv, (v - v_n) / dt) * dV + \
inner(grad(dv).T, S_mid) * dV - \
dot(dv, (l_left - l_left_n) / dt) * dS_l - dot(dv, tau) * dS_r(2)
R1 = dot(dl_left, (v - v_n) / dt) * dS_l - dot(dl_left, nue) * dS_l
R2 = inner(dS, (S - S_n) / dt) * dV - inner(dS, grad(v_mid)) * dV
R = R0 + R1 + R2
# Solve for next step
F_blocks = extract_blocks(R)
Jacobi = []
for Fi in F_blocks:
for ui in w_.split():
d = derivative(Fi, ui)
d = expand_derivatives(d)
Jacobi.append(d)
problem = MixedNonlinearVariationalProblem(F_blocks, w_.split(), [], J=Jacobi)
solver = MixedNonlinearVariationalSolver(problem)
solver.solve()
# Update field
mx_n.assign(w_.sub(0))
l_left_n.assign(w_.sub(1))
Unfortunately, the program crashes after a few time iterations and generates a RuntimeError in solver.solve() with the error message:
*** -------------------------------------------------------------------------
*** Error: Unable to evaluate function at point.
*** Reason: The point is not inside the domain. Consider calling “Function::set_allow_extrapolation(true)” on this Function to allow extrapolation.
*** Where: This error was encountered inside Function.cpp.
*** Process: 0
*** DOLFIN version: 2019.2.0.dev0
*** Git changeset: 68d9ed51bee6723163e7c4fbfffe31e6e3079bca
*** -------------------------------------------------------------------------
It is very strange, because the error does not appear every time and sometimes the code works fine. I wonder why the error occurs randomly.
I appreciate any kind of help to solve my problem