Let us first eliminate all solver errors by using direct solvers:
# Solver for step 1
solver1 = PETSc.KSP().create(mesh.comm)
solver1.setOperators(A1)
solver1.setType(PETSc.KSP.Type.PREONLY)
pc1 = solver1.getPC()
pc1.setType(PETSc.PC.Type.LU)
pc1.setFactorSolverType("mumps")
# Solver for step 2
solver2 = PETSc.KSP().create(mesh.comm)
solver2.setOperators(A2)
solver2.setType(PETSc.KSP.Type.PREONLY)
pc2 = solver2.getPC()
pc2.setType(PETSc.PC.Type.LU)
pc2.setFactorSolverType("mumps")
# Solver for step 3
solver3 = PETSc.KSP().create(mesh.comm)
solver3.setOperators(A3)
solver3.setType(PETSc.KSP.Type.PREONLY)
pc3 = solver3.getPC()
pc3.setType(PETSc.PC.Type.LU)
pc3.setFactorSolverType("mumps")
With num_steps=500
I get:
nx=ny=10
Time 10.00, L2-error 5.79e-08, Max error 3.17e-07
nx=ny=20
Time 10.00, L2-error 2.56e-06, Max error 2.42e-05
nx=ny=40
Time 10.00, L2-error 9.17e-06, Max error 1.17e-04
nx=ny=80
Time 10.00, L2-error 4.49e-06, Max error 4.39e-05
However, if we increase num_steps
to 1000
, we get
nx=ny=10
Time 10.00, L2-error 1.28e-13, Max error 6.10e-13
nx=ny=20
Time 10.00, L2-error 8.42e-09, Max error 7.02e-08
nx=ny=40
Time 10.00, L2-error 6.21e-07, Max error 9.66e-06
nx=ny=80
Time 10.00, L2-error 8.52e-07, Max error 1.41e-05
and with 2000 steps I get
Nx=ny=10
Time 10.00, L2-error 1.44e-14, Max error 2.29e-14
nx=ny=20
Time 10.00, L2-error 3.04e-14, Max error 1.43e-13
nx=ny=40
Time 10.00, L2-error 1.31e-09, Max error 1.61e-08
nx=ny=80
Time 10.00, L2-error 7.52e-08, Max error 1.76e-06
I.e. you observe that the error is drastically reduced when dt
is decreased as well. The ratio between spatial and temporal discretization links to the CFL condition, which is required to be bounded for stability: Courant–Friedrichs–Lewy condition - Wikipedia
Several other things to note, is that:
- Splitting schemes are not great for pressure conditions, as imposed in this tutorial.
- Splitting schemes are not good for steady flow.