mixed-poisson.py 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. """Solving Poisson equation using
  2. a mixed (two-field) formulation."""
  3. # https://fenicsproject.org/docs/dolfin/2018.1.0/python/demos/mixed-poisson
  4. from dolfin import *
  5. # Create mesh
  6. mesh = UnitSquareMesh(30, 30)
  7. # Define finite elements spaces and build mixed space
  8. BDM = FiniteElement("BDM", mesh.ufl_cell(), 1)
  9. DG = FiniteElement("DG", mesh.ufl_cell(), 0)
  10. W = FunctionSpace(mesh, BDM * DG)
  11. # Define trial and test functions
  12. (sigma, u) = TrialFunctions(W)
  13. (tau, v) = TestFunctions(W)
  14. # Define source function
  15. f = Expression("10*exp(-(pow(x[0]-0.5, 2) + pow(x[1]-0.5, 2))/0.02)", degree=2)
  16. # Define variational form
  17. a = (dot(sigma, tau) + div(tau) * u + div(sigma) * v) * dx
  18. L = -f * v * dx
  19. # Define function G such that G \cdot n = g
  20. class BoundarySource(UserExpression):
  21. def __init__(self, mesh, **kwargs):
  22. self.mesh = mesh
  23. super().__init__(**kwargs)
  24. def eval_cell(self, values, x, ufc_cell):
  25. cell = Cell(self.mesh, ufc_cell.index)
  26. n = cell.normal(ufc_cell.local_facet)
  27. g = sin(5 * x[0])
  28. values[0] = g * n[0]
  29. values[1] = g * n[1]
  30. def value_shape(self):
  31. return (2,)
  32. G = BoundarySource(mesh, degree=2)
  33. # Define essential boundary
  34. def boundary(x):
  35. return x[1] < DOLFIN_EPS or x[1] > 1.0 - DOLFIN_EPS
  36. bc = DirichletBC(W.sub(0), G, boundary)
  37. # Compute solution
  38. w = Function(W)
  39. solve(a == L, w, bc)
  40. (sigma, u) = w.split()
  41. ########################################################### vedo
  42. from vedo.dolfin import plot
  43. # Plot solution on mesh, and warp z-axis by the scalar value
  44. plot(u, warp_zfactor=0.8, legend='u', text=__doc__)