10 a1,a2=(axis+1)%3,(axis+2)%3; w=np.arange(N+1)*h-0.5; t1lo=np.arange(N)*h-0.5; t2lo=t1lo
11 rho2=R*R-(w-C0[axis])**2; O=np.ones((N+1,N,N)); c1,c2=C0[a1],C0[a2]
12 for k
in np.nonzero(rho2>0)[0]:
13 rho=np.sqrt(rho2[k]); j1=np.nonzero(np.abs(t1lo+h/2-c1)<rho+h)[0]; j2=np.nonzero(np.abs(t2lo+h/2-c2)<rho+h)[0]
14 if len(j1)==0
or len(j2)==0:
continue
15 J1,J2=np.meshgrid(j1,j2,indexing=
"ij"); lo1=t1lo[J1.ravel()]; lo2=t2lo[J2.ravel()]
16 t=lo1[:,
None]+(np.arange(256)[
None,:]+0.5)*(h/256); s2=rho*rho-(t-c1)**2; half=np.sqrt(np.maximum(s2,0))
17 zlo=np.maximum(c2-half,lo2[:,
None]); zhi=np.minimum(c2+half,lo2[:,
None]+h)
18 O[k,J1.ravel(),J2.ravel()]=1.0-np.clip(zhi-zlo,0,
None).mean(axis=1)/h
21 h=1.0/N; c=(np.arange(N)+0.5)*h-0.5; X,Y,Z=np.meshgrid(c,c,c,indexing=
"ij")
22 S=
sdf(X,Y,Z); fl=S>=0; U=np.where(fl,S,0.0)
26 om=np.moveaxis(om,[0,1,2],[a,(a+1)%3,(a+2)%3]); op=np.moveaxis(op,[0,1,2],[a,(a+1)%3,(a+2)%3])
27 o.append((om,op)); W.append(h*h*(om-op))
29 r=np.sqrt((X-C0[0])**2+(Y-C0[1])**2+(Z-C0[2])**2); nx=(X-C0[0])/r; ny=(Y-C0[1])/r; nz=(Z-C0[2])/r
31 faces=np.zeros((N,N,N))
33 om,op=o[a]; um=np.roll(U,+1,a); up=np.roll(U,-1,a)
34 faces+= h*(om*(U-um)+op*(U-up))
35 wall=sum(W[a]*nvec[a]
for a
in range(3))
36 Lvisc=MU*(faces - wall)
38 ns=6; off=(np.arange(ns)+0.5)/ns-0.5
40 cut=(np.abs(W[0])+np.abs(W[1])+np.abs(W[2]))>1e-9
41 ii,jj,kk=np.nonzero(cut)
42 for I,J,K
in zip(ii,jj,kk):
43 xs=c[I]+off*h; ys=c[J]+off*h; zs=c[K]+off*h
44 XX,YY,ZZ=np.meshgrid(xs,ys,zs,indexing=
"ij"); fld=
sdf(XX,YY,ZZ)>=0
45 ex[I,J,K]=-MU*np.sum(np.where(fld,
lap(XX,YY,ZZ),0.0))*(h/ns)**3
48 return np.sqrt(np.mean(res**2)), np.max(np.abs(res)), cut.sum()