I’m trying to implement a RANS simulation on a periodic hill (using the k-epsilon turbulence model)
However it seems like I’m unable to apply the BC to the speed ad the pressure when I’m using the NonLinear solver of dolfinx_mpc.
(I’m using the following versions of dolfinx and dolfinx_mpc:
dolfinx_mpc —> Version: 0.10.0
fenics-dolfinx —> Version: 0.10.0)
(Also for the non_linear solver I took inspiration from to code: dolfinx_mpc/python/demos/demo_stokes_nonlinear_nest.py at main · jorgensd/dolfinx_mpc · GitHub)
Can someone spot what am I doing wrong?
This is a short version of the important part of the code:
# Construct function spaces
cellname = mesh.basix_cell()
Ve = basix.ufl.element(basix.ElementFamily.P, cellname, 2, shape=(gdim,), dtype=default_real_type) # Lagrange 2 function space
Qe = basix.ufl.element(basix.ElementFamily.P, cellname, 1, dtype=default_real_type) # Legrange 1 function space
el_k = basix.ufl.element("Lagrange", mesh.basix_cell(), 1)
V = functionspace(mesh, Ve)
Q = functionspace(mesh, Qe)
W = ufl.MixedFunctionSpace(V, Q)
# Costruct the boundary conditions:
bcu = []
bcp = []
bcw = [] # bcu+bcp
# Reminder of the facet markers:
# 1 ---> inlet
# 2 ---> outlet
# 3 ---> top
# 4 ---> bottom
def periodic_relation(x):
out_x = np.zeros(x.shape)
out_x[0] = x[0] - Lx
out_x[1] = x[1]
return out_x
#---------------------- DIREHLET BC -----------------------#
# Velocity (ux, uy)
# Top or bottom walls
u_no_slip= Function(V)
u_no_slip.x.array[:]=0
u_no_slip.x.scatter_forward() # <-- updates ghost values
# Pressure:
p_inlet = Constant(mesh, dolfinx.default_scalar_type(2.0))
p_outlet = Constant(mesh, dolfinx.default_scalar_type(0.0))
# k-epsilon:
# Top and bottom walls:
k_walls = Constant(mesh, dolfinx.default_scalar_type(0.0))
# VELOCITY (ux,uy):
# Top and bottom walls
dofs_top_u = locate_dofs_topological(V, fdim, ft.find(3))
dofs_bottom_u = locate_dofs_topological(V, fdim, ft.find(4))
bc_top_u = dirichletbc(u_no_slip, dofs_top_u)
bc_bottom_u = dirichletbc(u_no_slip, dofs_bottom_u)
bcu.append(bc_top_u)
bcu.append(bc_bottom_u)
# Pressure(p)
dofs_in_p = locate_dofs_topological(Q, fdim, ft.find(1))
dofs_out_p = locate_dofs_topological(Q, fdim, ft.find(2))
bc_in_p = dirichletbc(p_inlet, dofs_in_p, Q)
bc_out_p = dirichletbc(p_outlet, dofs_out_p, Q)
bcp.append(bc_in_p)
bcp.append(bc_out_p)
bcw = np.concatenate((bcu, bcp))
#-------
# Defining the mpc:
mpc_u = MultiPointConstraint(V)
mpc_u.create_periodic_constraint_topological(V, ft, 2, periodic_relation, bcu) # or bcw?
mpc_u.finalize()
mpc_p = MultiPointConstraint(Q) # or, should I apply bcp????
mpc_p.finalize()
# Initialise the functions
Wh = ufl.MixedFunctionSpace(mpc_u.function_space, mpc_p.function_space)
u0 = dolfinx.fem.Function(mpc_u.function_space)
p0 = dolfinx.fem.Function(mpc_p.function_space)
u1 = dolfinx.fem.Function(mpc_u.function_space)
p1 = dolfinx.fem.Function(mpc_p.function_space)
(v, q) = ufl.TestFunctions(W)
# SOLVING THE NS:
# (these are actually solved in a loop, since they are "linearised")
FW = dot(dot(u0, nabla_grad(u1)), v)*dx\
+ (nu + nu_t) * inner(nabla_grad(u1), nabla_grad(v))*dx \
- div(v)*p1*dx \
- div(u1)*q*dx \
- dot(force, v)*dx \
# Surface terms of the NS equation:
FW+= dot(p1*normal, v)*ds - dot((nu + nu_t)*nabla_grad(u1)*normal, v)*ds
tol = 1e-7
problem_ns = dolfinx_mpc.NonlinearProblem(
ufl.extract_blocks(FW),
[u1, p1],
mpc=[mpc_u, mpc_p],
bcs=bcw,
kind="nest",
petsc_options={
"snes_type": "newtonls",
"snes_atol": 1e-7,
"snes_rtol": 1e-7,
#"snes_monitor": None,
"ksp_type": "preonly", # the linear solver just solves the linear system (no iterations)
"pc_type": "lu", # LU factorization for the pre-conditioning
}
)
start_ns = time.time()
_, converged, num_iterations = problem_ns.solve()
These are the velocity and pressure field!
(first image the velocity magnitude, second image the pressure field)
They are both zero! Since no deltaP is being applied:




