stokes-iterative.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. """
  2. Stokes equations with an iterative solver.
  3. """
  4. # https://fenicsproject.org/docs/dolfin/2018.1.0/python/demos/
  5. # stokes-iterative/demo_stokes-iterative.py.html
  6. from dolfin import *
  7. mesh = UnitCubeMesh(10, 10, 10)
  8. # Build function space
  9. P2 = VectorElement("Lagrange", mesh.ufl_cell(), 2)
  10. P1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1)
  11. TH = P2 * P1
  12. W = FunctionSpace(mesh, TH)
  13. # Boundaries
  14. def right(x, on_boundary):
  15. return x[0] > (1.0 - DOLFIN_EPS)
  16. def left(x, on_boundary):
  17. return x[0] < DOLFIN_EPS
  18. def top_bottom(x, on_boundary):
  19. return x[1] > 1.0 - DOLFIN_EPS or x[1] < DOLFIN_EPS
  20. # No-slip boundary condition for velocity
  21. noslip = Constant((0.0, 0.0, 0.0))
  22. bc0 = DirichletBC(W.sub(0), noslip, top_bottom)
  23. # Inflow boundary condition for velocity
  24. inflow = Expression(("-sin(x[1]*pi)", "0.0", "0.0"), degree=2)
  25. bc1 = DirichletBC(W.sub(0), inflow, right)
  26. # Define variational problem
  27. (u, p) = TrialFunctions(W)
  28. (v, q) = TestFunctions(W)
  29. f = Constant((0.0, 0.0, 0.0))
  30. a = inner(grad(u), grad(v)) * dx + div(v) * p * dx + q * div(u) * dx
  31. L = inner(f, v) * dx
  32. # Form for use in constructing preconditioner matrix
  33. b = inner(grad(u), grad(v)) * dx + p * q * dx
  34. # Assemble system
  35. A, bb = assemble_system(a, L, [bc0, bc1])
  36. # Assemble preconditioner system
  37. P, btmp = assemble_system(b, L, [bc0, bc1])
  38. # Create Krylov solver and AMG preconditioner
  39. if has_krylov_solver_method("minres"):
  40. krylov_method = "minres"
  41. elif has_krylov_solver_method("tfqmr"):
  42. krylov_method = "tfqmr"
  43. solver = KrylovSolver(krylov_method, "amg")
  44. # Associate operator (A) and preconditioner matrix (P)
  45. solver.set_operators(A, P)
  46. # Solve
  47. U = Function(W)
  48. solver.solve(U.vector(), bb)
  49. # Get sub-functions
  50. u, p = U.split()
  51. pressures = p.compute_vertex_values(mesh)
  52. #################################################### vedo
  53. from vedo.dolfin import plot
  54. # Plot u and p solutions on N=2 synced renderers
  55. plot(u, mode='mesh arrows', at=0, N=2, legend='velocity',
  56. scale=0.1, wireframe=1, lw=0.03, alpha=0.5, scalarbar=False).close()
  57. plot(p, mode='mesh').close()