23def couette(harmonic, rot=None, chi=1.0, dt=20.0, N=32, steps=4000, tol=1e-9):
25 mu1, mu2, U = 1.0, 0.1, 1.0
26 s = F.Solver(N, N, nz)
27 s.set_rho(1.0); s.set_mu(mu1); s.set_dt(dt)
28 s.set_domain_bc(2, 1, 0.0, 0.0, 0.0)
29 s.set_domain_bc(3, 2, U, 0.0, 0.0)
30 s.set_pressure_geometry(np.asfortranarray(np.full((N, N, nz), 10.0)))
32 muy = np.where(y < N // 2, mu1, mu2).astype(np.float64)
34 s.set_field(
"mu", np.asfortranarray(np.repeat(muy[
None, :,
None], N, 0).repeat(nz, 2)))
35 s.set_property_mode(
"variable", harmonic)
37 s.set_variable_rotational(rot, chi)
39 for it
in range(steps):
41 if np.isnan(s.get_u()).any():
42 return float(
"nan"), -(it + 1)
44 u = s.get_u(); um = np.abs(u).max()
45 if prev
is not None and np.abs(u - prev).max() / (um + 1e-30) < tol:
49 u = s.get_u()[N // 2, :, 0]
50 ui = U * mu2 / (mu1 + mu2)
52 exact = np.where(yc < 0.5, ui * yc / 0.5, ui + (U - ui) * (yc - 0.5) / 0.5)
53 return np.max(np.abs(u - exact)) / U, conv