The natural boundary condition is not working on the internal boundary.
Here is a simple test: uniform viscosity, 0 body force, traction boundary condition on internal boundary, no slip on other boundaries.
uw3
import underworld3 as uw
import numpy as np
import sympy
xmin, xmax = 0, 1
ymin, yint,ymax = 0,0.5,1
xres, yres = 32,32
yresa,yresb = 16,16
mesh = mesh = uw.meshing.BoxInternalBoundary(elementRes=(xres,yres),zelementRes=(yresa,yresb),minCoords=(xmin,ymin),maxCoords=(xmax, ymax),zintCoord=yint,degree=1,qdegree=2)
v = uw.discretisation.MeshVariable("V", mesh, mesh.dim, degree=2,continuous=True)
p = uw.discretisation.MeshVariable("P", mesh, 1, degree=1,continuous=True)
stokes = uw.systems.Stokes(mesh, velocityField=v, pressureField=p)
stokes.constitutive_model = uw.constitutive_models.ViscousFlowModel
stokes.bodyforce = sympy.Matrix([0., 0.])
stokes.constitutive_model.Parameters.shear_viscosity_0 = 1.0
stokes.saddle_preconditioner = 1.0 / stokes.constitutive_model.Parameters.shear_viscosity_0
for wall in ("Left", "Right", "Bottom", "Top"):
stokes.add_essential_bc((0.0, 0.0), wall)
stokes.add_natural_bc(sympy.Matrix([1.0, 0.0]), "Internal")
stokes.tolerance = 1.0e-6
stokes.petsc_options["ksp_rtol"] = 1.0e-6
stokes.petsc_options["ksp_atol"] = 1.0e-6
stokes.petsc_options["snes_converged_reason"] = None
stokes.petsc_options["snes_monitor_short"] = None
stokes.solve(zero_init_guess=False)
print("u just below y=0.5:", uw.function.evaluate(v,np.array([0.5,0.499])))
print("u just above y=0.5:", uw.function.evaluate(v,np.array([0.5,0.501])))
The solver did not converge.
same case using FEniCS
from dolfin import *
import numpy as np
mesh = UnitSquareMesh(32, 32)
OUTER = 1
INTERFACE = 2
boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0)
class OuterBoundary(SubDomain):
def inside(self, x, on_boundary):
return on_boundary
class Interface(SubDomain):
def inside(self, x, on_boundary):
return near(x[1], 0.5)
OuterBoundary().mark(boundaries, OUTER)
Interface().mark(boundaries, INTERFACE)
dx = Measure("dx", domain=mesh)
#ds = Measure("ds", domain=mesh, subdomain_data=boundaries) # exterior facets
dS = Measure("dS", domain=mesh, subdomain_data=boundaries) # interior facets
P2 = VectorElement("P", mesh.ufl_cell(), 2)
P1 = FiniteElement("P", mesh.ufl_cell(), 1)
W = FunctionSpace(mesh, MixedElement([P2, P1]))
(u, p) = TrialFunctions(W)
(v, q) = TestFunctions(W)
mu = Constant(1.0)
f = Constant((0.0, 0.0))
def eps(u):
return sym(grad(u))
a = (inner(2*mu*eps(u), eps(v))*dx
- p*div(v)*dx
- q*div(u)*dx )
L = inner(f, v)*dx
# Traction on interior interface y = 0.5
t = Constant((1.0, 0.0)) # horizontal shear traction
L += dot(t, v('+')) * dS(INTERFACE)
# No-slip on outer boundary
bc_noslip = DirichletBC(W.sub(0), Constant((0.0, 0.0)), boundaries, OUTER)
# remove the null space
bc_pressure = DirichletBC(W.sub(1), Constant(0.0),"x[0] < DOLFIN_EPS && x[1] < DOLFIN_EPS","pointwise")
bcs = [bc_noslip, bc_pressure]
w = Function(W)
solve(a == L, w, bcs,
solver_parameters={"linear_solver": "mumps"})
(u_sol, p_sol) = w.split(deepcopy=True)
print("u just below y=0.5:", u_sol(0.5, 0.499))
print("u just above y=0.5:", u_sol(0.5, 0.501))
The output is:
u just below y=0.5: [5.65310750e-02 6.15222229e-09]
u just above y=0.5: [5.65310750e-02 6.15222231e-09]
The natural boundary condition is not working on the internal boundary.
Here is a simple test: uniform viscosity, 0 body force, traction boundary condition on internal boundary, no slip on other boundaries.
uw3
The solver did not converge.
same case using FEniCS
The output is: