38 dx, dy, dz = x - C0[0], y - C0[1], z - C0[2]
39 r2 = dx * dx + dy * dy + dz * dz
40 r = np.sqrt(np.maximum(r2, 1e-300))
41 A = 3.0 * R_SPH / (4.0 * r)
42 B = R_SPH ** 3 / (4.0 * r ** 3)
44 return 1.0 - A * (1.0 + dx * dx / r2) - B * (1.0 - 3.0 * dx * dx / r2)
45 d1 = (dy, dz)[comp - 1]
46 return -(A - 3.0 * B) * dx * d1 / r2
54 """Exact open-area flux and the planar aperture for faces whose centres are `fc` (3, M)."""
55 t = [k
for k
in range(3)
if k != a]
56 off = (np.arange(KQ) + 0.5) / KQ - 0.5
57 P, Q = np.meshgrid(off * h, off * h, indexing=
"ij")
58 pts = [fc[k][
None, :] + 0.0
for k
in range(3)]
59 pts[t[0]] = fc[t[0]][
None, :] + P.ravel()[:,
None]
60 pts[t[1]] = fc[t[1]][
None, :] + Q.ravel()[:,
None]
64 exact = (h * h / (KQ * KQ)) * np.where(openm, ua, 0.0).sum(axis=0)
65 alpha = openm.mean(axis=0)
71 c = (np.arange(N) + 0.5) * h - 0.5
72 X, Y, Z = np.meshgrid(c, c, c, indexing=
"ij")
74 uc = [np.where(S >= 0.0,
stokes_u(X, Y, Z, k), 0.0)
for k
in range(3)]
75 uc_nm = [
stokes_u(X, Y, Z, k)
for k
in range(3)]
77 sel = (S >= 0.0) & (np.abs(S) < band * h)
78 sel[:2, :, :] = sel[-2:, :, :] =
False
79 sel[:, :2, :] = sel[:, -2:, :] =
False
80 sel[:, :, :2] = sel[:, :, -2:] =
False
81 idx = np.array(np.nonzero(sel))
86 res = {k: np.zeros(M)
for k
in (
"exact",
"stag",
"col",
"col_nm")}
91 fc = [c[j[k]]
if k != a
else c[j[a]] - 0.5 * h
for k
in range(3)]
92 fc = [np.asarray(v)
for v
in fc]
94 nb = idx.copy(); nb[a] += 2 * side - 1
95 ui = uc[a][tuple(idx)]
97 ui_n = uc_nm[a][tuple(idx)]
98 uj_n = uc_nm[a][tuple(nb)]
99 uf_c = 0.5 * (ui + uj)
100 uf_n = 0.5 * (ui_n + uj_n)
102 sgn = 1.0
if side == 1
else -1.0
103 res[
"exact"] += sgn * ex
104 res[
"stag"] += sgn * al * h * h * uf_s
105 res[
"col"] += sgn * al * h * h * uf_c
106 res[
"col_nm"] += sgn * al * h * h * uf_n
108 Q = np.pi * R_SPH ** 2
109 out = dict(N=N, hR=h / R_SPH, ncell=M,
110 quad=float(np.abs(res[
"exact"]).sum() / Q))
111 for k
in (
"stag",
"col",
"col_nm"):
112 d = res[k] - res[
"exact"]
113 out[k] = float(np.abs(d).sum() / Q)
114 out[k +
"_net"] = float(d.sum() / Q)