Coverage for pySDC / projects / StroemungsRaum / sweepers / imex_1st_order_mass_NSE.py: 92%
25 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-27 07:06 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-27 07:06 +0000
1from pySDC.implementations.sweeper_classes.imex_1st_order_mass import imex_1st_order_mass
4class imex_1st_order_mass_NSE(imex_1st_order_mass):
5 """
6 This sweeper extends imex_1st_order_mass for a projection-based discretization of the incompressible
7 Navier–Stokes equations. This requires passing the zero-to-node step size at each collocation
8 node and handling the update of the velocity and the pressure within `solve_system`
10 """
12 def update_nodes(self):
13 """
14 Update the u- and f-values at the collocation nodes -> corresponds to a single sweep over all nodes
16 Returns:
17 None
18 """
19 # get current level and problem description
20 L = self.level
21 P = L.prob
23 # only if the level has been touched before
24 assert L.status.unlocked
26 # get number of collocation nodes for easier access
27 M = self.coll.num_nodes
29 # gather all terms which are known already (e.g. from the previous iteration)
30 # this corresponds to u0 + QF(u^k) - QIFI(u^k) - QEFE(u^k) + tau
32 # get QF(u^k)
33 integral = self.integrate()
35 # This is somewhat ugly, but we have to apply the mass matrix on u0 only on the finest level
36 if L.level_index == 0:
37 u0 = P.apply_mass_matrix(L.u[0])
38 else:
39 u0 = L.u[0]
41 for m in range(M):
42 # subtract QIFI(u^k)_m + QEFE(u^k)_m
43 for j in range(M + 1):
44 integral[m] -= L.dt * (self.QI[m + 1, j] * L.f[j].impl + self.QE[m + 1, j] * L.f[j].expl)
45 # add initial value
46 integral[m] += u0
47 # add tau if associated
48 if L.tau[m] is not None:
49 integral[m] += L.tau[m]
51 # do the sweep
52 for m in range(0, M):
53 # build rhs, consisting of the known values from above and new values from previous nodes (at k+1)
54 rhs = P.dtype_u(integral[m])
55 for j in range(m + 1):
56 rhs += L.dt * (self.QI[m + 1, j] * L.f[j].impl + self.QE[m + 1, j] * L.f[j].expl)
58 L.u[m + 1], P.pn = P.solve_system(
59 rhs,
60 L.dt * self.QI[m + 1, m + 1],
61 L.u[m + 1],
62 L.time + L.dt * self.coll.nodes[m],
63 L.dt * self.coll.nodes[m],
64 )
66 # update function values
67 L.f[m + 1] = P.eval_f(L.u[m + 1], L.time + L.dt * self.coll.nodes[m])
69 # indicate presence of new values at this level
70 L.status.updated = True
71 return None