32def build(G, k, fc=True, wall="quad"):
35 idx = -np.ones((n, n), int); idx[valid] = np.arange(valid.sum())
37 rows, cols, vals = [], [], []
39 rows.append(r); cols.append(c); vals.append(v)
42 s = np.sqrt(max(R**2 - G.xe[i] ** 2, 0)); y0, y1 = G.ye[j], G.ye[j + 1]
43 lo, hi = max(y0, -s), min(y1, s)
44 return (0.5 * (lo + hi) - G.yc[j]) / h
46 s = np.sqrt(max(R**2 - G.ye[j] ** 2, 0)); x0, x1 = G.xe[i], G.xe[i + 1]
47 lo, hi = max(x0, -s), min(x1, s)
48 return (0.5 * (lo + hi) - G.xc[i]) / h
52 if a <= 0
or idx[i - 1, j] < 0
or idx[i, j] < 0:
54 terms = [((i, j), 1 / h), ((i - 1, j), -1 / h)]
57 jj = j + (1
if d > 0
else -1)
58 if 0 <= jj < n
and G.ax[i, jj] > 0
and idx[i - 1, jj] >= 0
and idx[i, jj] >= 0:
60 terms = [(c, (1 - f) * v)
for c, v
in terms] + \
61 [((i, jj), f / h), ((i - 1, jj), -f / h)]
65 if a <= 0
or idx[i, j - 1] < 0
or idx[i, j] < 0:
67 terms = [((i, j), 1 / h), ((i, j - 1), -1 / h)]
70 ii = i + (1
if d > 0
else -1)
71 if 0 <= ii < n
and G.ay[ii, j] > 0
and idx[ii, j - 1] >= 0
and idx[ii, j] >= 0:
73 terms = [(c, (1 - f) * v)
for c, v
in terms] + \
74 [((ii, j), f / h), ((ii, j - 1), -f / h)]
77 for i, j
in zip(*np.nonzero(valid)):
79 for (a, terms, sgn)
in (flux_x(i + 1, j) + (+1,), flux_x(i, j) + (-1,),
80 flux_y(i, j + 1) + (+1,), flux_y(i, j) + (-1,)):
82 add(r, idx[c], -sgn * a * h * v / h**2)
83 if G.Aw[i, j] <= 1e-14 * h
or np.isinf(k)
and False:
85 if G.Aw[i, j] > 1e-14 * h
and k > 0:
87 cx, cy = G.cx[i, j], G.cy[i, j]
88 rr = np.hypot(cx, cy); xw = np.array([cx, cy]) * R / rr
90 ax_ = 0
if abs(nn[0]) >= abs(nn[1])
else 1
91 sg = 1
if nn[ax_] > 0
else -1
96 col = i + sg * m; s = (G.xc[col] - xw[0]) / nn[0]
97 py = xw[1] + s * nn[1]; jn = int(round((py - G.yc[0]) / h))
98 cand = [(col, jn - 1), (col, jn), (col, jn + 1)]; coords = [G.yc[q]
for _, q
in cand]; t = py
100 row = j + sg * m; s = (G.yc[row] - xw[1]) / nn[1]
101 px = xw[0] + s * nn[0]; im = int(round((px - G.xc[0]) / h))
102 cand = [(im - 1, row), (im, row), (im + 1, row)]; coords = [G.xc[q]
for q, _
in cand]; t = px
103 ok = all(idx[c] >= 0
for c
in cand)
106 pts.append((s, cand,
lagr(np.array(coords), t)))
107 if wall.startswith(
"probe"):
109 c = float(wall[6:]
or 1.1) * 0.5 * (abs(nn[0]) + abs(nn[1]))
111 c = (max(0.3, (G.kap[i, j]**2 - 0.25) / (2 * G.kap[i, j]))
if wall[5:] ==
"K"
112 else float(wall[5:]
or 1.0))
115 fi = (p[0] - G.xc[0]) / h; fj = (p[1] - G.yc[0]) / h
116 i0, j0 = int(np.floor(fi)), int(np.floor(fj)); tx, ty = fi - i0, fj - j0
117 cand = [(i0, j0), (i0 + 1, j0), (i0, j0 + 1), (i0 + 1, j0 + 1)]
118 ww = [(1 - tx) * (1 - ty), tx * (1 - ty), (1 - tx) * ty, tx * ty]
119 okm = [idx[q] >= 0
for q
in cand]
122 wsum = sum(wv
for o_, wv
in zip(okm, ww)
if o_)
124 raise RuntimeError(
"probe hits invalid cells")
125 cand = [q
for q, o_
in zip(cand, okm)
if o_]
126 ww = [wv / wsum
for wv, o_
in zip(ww, okm)
if o_]
127 reach = max(max(abs(q[0] - i), abs(q[1] - j))
for q
in cand)
128 REACH[0] = max(REACH[0], reach)
129 pts = [(sp_, cand, np.array(ww))]
130 use_quad = (wall ==
"quad" and len(pts) == 2)
132 raise RuntimeError(
"no interpolation point")
135 (d1, c1, w1), (d2, c2, w2) = pts
136 den = d1 * d2 * (d2 - d1)
137 S = [(c, d2 * d2 * w / den)
for c, w
in zip(c1, w1)] + \
138 [(c, -d1 * d1 * w / den)
for c, w
in zip(c2, w2)]
139 beta = (d1 + d2) / (d1 * d2)
141 (d1, c1, w1) = pts[0]
142 S = [(c, w / d1)
for c, w
in zip(c1, w1)]; beta = 1 / d1
145 fac = 1.0
if np.isinf(k)
else k / (k + beta)
148 add(r, idx[c], fac * G.Aw[i, j] * v / h**2)
149 K = sp.csr_matrix((vals, (rows, cols)), shape=(N, N))
150 return K, G.kap[valid]