poisson.py¶
In this script we solve Poisson’s equation Δu = 1 subject to boundary constraints, using the fact that the solution to the strong form minimizes the functional ∫ .5 ‖∇u‖² - u. The domain is a unit square, and the solution is constrained to zero along the entire boundary.
8from nutils import mesh, function, solver, export, cli, testing
9
10
11def main(nelems: int):
12 '''
13 Poisson's equation on a unit square.
14
15 .. arguments::
16
17 nelems [10]
18 Number of elements along edge.
19 '''
20
21 domain, x = mesh.unitsquare(nelems, etype='square')
22 u = function.dotarg('udofs', domain.basis('std', degree=1))
23 g = u.grad(x)
24 J = function.J(x)
25 cons = solver.optimize('udofs',
26 domain.boundary.integral(u**2 * J, degree=2), droptol=1e-12)
27 udofs = solver.optimize('udofs',
28 domain.integral((g @ g / 2 - u) * J, degree=1), constrain=cons)
29 bezier = domain.sample('bezier', 3)
30 x, u = bezier.eval([x, u], udofs=udofs)
31 export.triplot('u.png', x, u, tri=bezier.tri, hull=bezier.hull)
32
33 return udofs
If the script is executed (as opposed to imported), nutils.cli.run()
calls the main function with arguments provided from the command line. To
keep with the default arguments simply run python3 poisson.py
(view log).
40if __name__ == '__main__':
41 cli.run(main)
Once a simulation is developed and tested, it is good practice to save a few
strategic return values for regression testing. The nutils.testing
module, which builds on the standard unittest
framework, facilitates
this by providing nutils.testing.TestCase.assertAlmostEqual64()
for the
embedding of desired results as compressed base64 data.
50class test(testing.TestCase):
51
52 def test_default(self):
53 udofs = main(nelems=10)
54 self.assertAlmostEqual64(udofs, '''
55 eNp9zrENwCAMBEBGYQJ444o2ozAAYgFmYhLEFqxAmye1FUtf+PSy7Jw9J6yoKGiMYsUTrq44kaVKZ7JM
56 +lWlDdlymEFXXC2o3H1C8mmzXz5t6OwhPfTDO+2na9+1f7D/teYFdsk5vQ==''')