docs(thermal): bound convergence cost and certify oracle errors
This commit is contained in:
@@ -13,7 +13,7 @@ from pathlib import Path
|
||||
import re
|
||||
p = Path('docs/shell-transient-heat-transfer/numerical-oracle-scratch.md')
|
||||
blocks = re.findall(r'```python\n(.*?)```', p.read_text(encoding='utf-8-sig'), re.S)
|
||||
assert len(blocks) == 4
|
||||
assert len(blocks) == 5
|
||||
scope = {}
|
||||
for block in blocks:
|
||||
exec(compile(block, str(p), 'exec'), scope)
|
||||
@@ -172,23 +172,6 @@ for name,X in cases.items():
|
||||
rows.append([rel(a[0],b[0]),rel(a[1],b[1]),rv(a[2],b[2]),max(math.sqrt(dot([x-y for x,y in zip(q,r)],[x-y for x,y in zip(q,r)]))for q,r in zip(a[3],b[3]))/max(math.sqrt(dot(r,r))for r in b[3])])
|
||||
ans[name]=rows
|
||||
print(json.dumps({"quadrature":ans},indent=2))
|
||||
# Independent uniform Q1 Neumann mode and continuum error by high-order integral.
|
||||
def spatial(n):
|
||||
h=1/n;lam=6*(1-math.cos(math.pi/n))/(h*h*(2+math.cos(math.pi/n)))
|
||||
t=.1;af=math.exp(-lam*t);ae=math.exp(-math.pi**2*t);et=eg=0
|
||||
for i in range(n):
|
||||
for s,w in gauss(12):
|
||||
x=(i+(s+1)/2)*h
|
||||
T=af*((1-s)*math.cos(math.pi*i/n)+(1+s)*math.cos(math.pi*(i+1)/n))/2
|
||||
G=af*(math.cos(math.pi*(i+1)/n)-math.cos(math.pi*i/n))/h
|
||||
et+=(T-ae*math.cos(math.pi*x))**2*w*h/2
|
||||
eg+=(G+math.pi*ae*math.sin(math.pi*x))**2*w*h/2
|
||||
return math.sqrt(et),math.sqrt(eg)
|
||||
ss=[spatial(n)for n in [8,16,32,64]]
|
||||
print(json.dumps({"spatial_errors":ss,"orders":[[math.log(a/b,2)for a,b in zip(ss[i],ss[i+1])]for i in range(3)]},indent=2))
|
||||
print(json.dumps({"time_orders":[math.log(abs((1+1/n)**(-n)-math.exp(-1))/abs((1+1/(2*n))**(-2*n)-math.exp(-1)),2)for n in [16,32,64,128]]}))
|
||||
|
||||
|
||||
def direct54(X):
|
||||
C=zeros(20);K=zeros(20)
|
||||
for xi,wx in gauss(3):
|
||||
@@ -219,33 +202,43 @@ orth=fn([[v-float(i==j)for j,v in enumerate(row)]for i,row in enumerate(mm(mm(tr
|
||||
print("slab eigen residual",res,"C orthogonality",orth)
|
||||
assert res<1e-12 and orth<1e-12
|
||||
|
||||
def spatial_full(n,ng):
|
||||
h=1/n;t=.1;steps=16*n*n
|
||||
l=6*(1-math.cos(math.pi/n))/(h*h*(2+math.cos(math.pi/n)))
|
||||
|
||||
def spatial_bounded(n,steps=32,t=.001,ng=12):
|
||||
h=1/n;l=6*(1-math.cos(math.pi/n))/(h*h*(2+math.cos(math.pi/n)))
|
||||
af=math.exp(-steps*math.log1p(l*t/steps));ase=math.exp(-l*t);ae=math.exp(-math.pi**2*t)
|
||||
et=eg=etime=0
|
||||
et=eg=etime=ese=0.
|
||||
for i in range(n):
|
||||
for s,w in gauss(ng):
|
||||
x=(i+(s+1)/2)*h
|
||||
x=(i+(s+1)/2)*h;measure=w*h/2
|
||||
v=((1-s)*math.cos(math.pi*i/n)+(1+s)*math.cos(math.pi*(i+1)/n))/2
|
||||
G=af*(math.cos(math.pi*(i+1)/n)-math.cos(math.pi*i/n))/h
|
||||
et+=(af*v-ae*math.cos(math.pi*x))**2*w*h/2
|
||||
eg+=(G+math.pi*ae*math.sin(math.pi*x))**2*w*h/2
|
||||
etime+=((af-ase)*v)**2*w*h/2
|
||||
return math.sqrt(et),math.sqrt(eg),math.sqrt(etime)
|
||||
sbe=[]
|
||||
g=(math.cos(math.pi*(i+1)/n)-math.cos(math.pi*i/n))/h
|
||||
et+=(af*v-ae*math.cos(math.pi*x))**2*measure
|
||||
eg+=(af*g+math.pi*ae*math.sin(math.pi*x))**2*measure
|
||||
etime+=((af-ase)*v)**2*measure
|
||||
ese+=(ase*v-ae*math.cos(math.pi*x))**2*measure
|
||||
return math.sqrt(et),math.sqrt(eg),math.sqrt(etime),math.sqrt(ese)
|
||||
rows=[]
|
||||
for n in [8,16,32,64]:
|
||||
a=spatial_full(n,12);b=spatial_full(n,16)
|
||||
er=spatial(n)[0];ratio=a[2]/er
|
||||
quadr=max(abs(x-y)/abs(x)for x,y in zip(a,b))
|
||||
assert ratio<=1/32 and quadr<=1e-8
|
||||
sbe.append(a)
|
||||
print("spatial BE",n,"time/spatial",ratio,"12/16 relative change",quadr)
|
||||
for i in range(3):
|
||||
pt=math.log(sbe[i][0]/sbe[i+1][0],2);pg=math.log(sbe[i][1]/sbe[i+1][1],2)
|
||||
a=spatial_bounded(n);b=spatial_bounded(n,ng=16)
|
||||
ratio=a[2]/a[3];quad=max(abs(x-y)/abs(x)for x,y in zip(a,b))
|
||||
assert ratio<1/32 and quad<1e-8
|
||||
rows.append(a)
|
||||
fluxbytes=n*n*24*3*32*8
|
||||
tempbytes=(n+1)**2*5*33*8
|
||||
print("bounded space",n,"T,grad,time,semi",a,"time/space",ratio,"quad",quad,"historybytes",fluxbytes+tempbytes)
|
||||
for a,b in zip(rows,rows[1:]):
|
||||
pt=math.log(a[0]/b[0],2);pg=math.log(a[1]/b[1],2)
|
||||
assert 1.95<=pt<=2.05 and .98<=pg<=1.03
|
||||
print("spatial BE order",pt,pg)
|
||||
print("bounded order",pt,pg)
|
||||
|
||||
time_orders=[]
|
||||
for n in [16,32,64,128]:
|
||||
e1=abs(math.exp(-n*math.log1p(1/n))-math.exp(-1))
|
||||
e2=abs(math.exp(-2*n*math.log1p(1/(2*n)))-math.exp(-1))
|
||||
order=math.log(e1/e2,2)
|
||||
assert .97<=order<=1.02
|
||||
time_orders.append(order)
|
||||
print("fixed spatial time orders",time_orders)
|
||||
|
||||
```
|
||||
|
||||
@@ -423,3 +416,89 @@ t=math.nextafter(.9,math.inf);d=.3;m=3
|
||||
print("specific .9 upper:",float(F(t)-m*F(d)),rad(t)+m*rad(d),"input-cell overlap",abs(F(t)-m*F(d))<=F(rad(t))+m*F(rad(d)))
|
||||
|
||||
```
|
||||
|
||||
## E. Library ULP 가정 없는 Fourier interval oracle
|
||||
|
||||
고정 dyadic 320-bit outward enclosure, Machin π, Taylor sin/cos/exp와 analytic
|
||||
remainder를 사용한다. Python Fraction은 검증 generator 전용이다. 출력 interval의
|
||||
outward binary64 hex endpoints를 C++ fixture에 고정할 수 있다. FESA solver와
|
||||
C++ std::sin/std::exp의 ULP 보장을 가정하지 않는다.
|
||||
|
||||
```python
|
||||
|
||||
from fractions import Fraction as F
|
||||
import math
|
||||
BITS=320;SCALE=1<<BITS
|
||||
def down(x):return F((x*SCALE).numerator//(x*SCALE).denominator,SCALE)
|
||||
def up(x):return -down(-x)
|
||||
def interval(a,b=None):return (down(F(a)),up(F(a if b is None else b)))
|
||||
def add(a,b):return down(a[0]+b[0]),up(a[1]+b[1])
|
||||
def neg(a):return -a[1],-a[0]
|
||||
def sub(a,b):return add(a,neg(b))
|
||||
def mul(a,b):
|
||||
v=[x*y for x in a for y in b];return down(min(v)),up(max(v))
|
||||
def div(a,b):
|
||||
assert b[0]>0 or b[1]<0
|
||||
return mul(a,(F(1)/b[1],F(1)/b[0]))
|
||||
def scale(a,c):return mul(a,interval(c))
|
||||
def atan_bounds(q):
|
||||
a=sum((F(-1)**j)*q**(2*j+1)/(2*j+1) for j in range(64))
|
||||
tail=q**129/129
|
||||
return a,a+tail
|
||||
a,b=atan_bounds(F(1,5)),atan_bounds(F(1,239))
|
||||
PI=interval(16*a[0]-4*b[1],16*a[1]-4*b[0])
|
||||
assert PI[1]-PI[0]<F(2)**-295
|
||||
def exneg(x):
|
||||
assert x[0]>=0
|
||||
if x[0]>=512:return interval(0,F(2)**-512)
|
||||
assert x[1]<=512
|
||||
y=scale(x,F(1,1024));term=interval(1);s=term
|
||||
for j in range(1,65):
|
||||
term=scale(mul(term,neg(y)),F(1,j));s=add(s,term)
|
||||
tail=F(1,2)**65/math.factorial(65)
|
||||
s=add(s,interval(-tail,tail))
|
||||
for _ in range(10):s=mul(s,s)
|
||||
return s
|
||||
def sincos_pi8(k):
|
||||
k%=16;quad=(k+2)//4;rem=k-4*quad
|
||||
x=scale(PI,F(rem,8));x2=mul(x,x)
|
||||
st=x;ss=x;ct=interval(1);cs=ct
|
||||
for j in range(1,32):
|
||||
st=scale(mul(st,neg(x2)),F(1,2*j*(2*j+1)));ss=add(ss,st)
|
||||
ct=scale(mul(ct,neg(x2)),F(1,(2*j-1)*2*j));cs=add(cs,ct)
|
||||
ss=add(ss,interval(-F(1,math.factorial(65)),F(1,math.factorial(65))))
|
||||
cs=add(cs,interval(-F(1,math.factorial(64)),F(1,math.factorial(64))))
|
||||
q=quad%4
|
||||
return [(ss,cs),(cs,neg(ss)),(neg(ss),neg(cs)),(neg(cs),ss)][q]
|
||||
def series_interval(t):
|
||||
Ts=[interval(1)for _ in range(5)];qs=[interval(0)for _ in range(5)];E=interval(1)
|
||||
for m in range(80):
|
||||
odd=2*m+1
|
||||
x=scale(mul(PI,PI),F(t)*odd*odd/4);dec=exneg(x)
|
||||
for j in range(5):
|
||||
si,co=sincos_pi8(odd*j)
|
||||
Ts[j]=sub(Ts[j],scale(div(mul(si,dec),PI),F(4,odd)))
|
||||
qs[j]=add(qs[j],scale(mul(co,dec),2))
|
||||
E=sub(E,scale(div(dec,mul(PI,PI)),F(8,odd*odd)))
|
||||
assert max(hi-lo for lo,hi in Ts+qs+[E])<F(2)**-270
|
||||
# Uniform analytic tail bound, using safe r upper at minimum time.
|
||||
beta=scale(mul(PI,PI),F(t)/4)
|
||||
first=exneg(scale(beta,161*161))
|
||||
rr=exneg(scale(beta,8*81))
|
||||
tailq=div(scale(first,2),sub(interval(1),rr))[1]
|
||||
tailt=div(scale(first,4),scale(mul(PI,sub(interval(1),rr)),161))[1]
|
||||
Ts=[add(v,interval(-tailt,tailt))for v in Ts]
|
||||
qs=[add(v,interval(-tailq,tailq))for v in qs]
|
||||
E=add(E,interval(-tailt,tailt))
|
||||
return Ts,qs,E,tailt,tailq
|
||||
for t in [.001,.01,.05,.1,.5,1.]:
|
||||
Ts,qs,ee,tt,tq=series_interval(t)
|
||||
assert tt<F(1,10**27) and tq<F(1,10**27)
|
||||
# Certified brackets can be exported as outward binary64 hex endpoints for C++ fixtures.
|
||||
width=max(float(hi-lo)for lo,hi in Ts+qs+[ee])
|
||||
assert width<1e-26
|
||||
print("Fourier certified",t,"max-width",width,"tailT",float(tt),"tailq",float(tq),
|
||||
"E bracket",math.nextafter(float(ee[0]),-math.inf).hex(),math.nextafter(float(ee[1]),math.inf).hex())
|
||||
print("FOURIER INTERVAL ASSERTIONS PASSED")
|
||||
|
||||
```
|
||||
|
||||
@@ -151,24 +151,71 @@ Constant T=2, 면내/두께선형도 각각 검사한다. 회전 후 q는 같은
|
||||
normal 반전 후 station a↔6−a와 조건까지 재매핑한다. RᵀR=I,detR=+1.
|
||||
Trace state(0,0,0,1,2)는 q3(0−)=0,q3(0+)=−4k/h이며 평균하지 않는다.
|
||||
|
||||
### 3.3 Free solve와 conditioning
|
||||
### 3.3 Free solve, certified residual과 forward 전파
|
||||
|
||||
n=free DOF 수,A=A_ff,b=같은 δ와 full old state로 만든 RHS다.
|
||||
Full residual의 free 성분 및 독립 A T_f−b를 확인한다.
|
||||
|
||||
β=||r_f||∞/(||A||∞||T_f||∞+||b||∞),
|
||||
β_limit=nγ_(n+1)+γ_(2n+4)+γ_(4n+8).
|
||||
|
||||
첫 항은 Cholesky의 |L||L|ᵀ bound와 || |L||L|ᵀ ||∞≤n||A||∞에서,
|
||||
나머지는 triangular solves 및 residual 평가의 dot-product bound에서 나온다.
|
||||
Backend가 전제를 충족하지 못하면 더 엄밀한 backward-error evidence가 필요하며
|
||||
β_limit를 늘리지 않는다. n=0이면 free solve/β를 생략하고 full reaction·수지를 검사한다.
|
||||
나머지는 triangular solves 및 residual 평가의 dot-product bound에서 나온 보수적인
|
||||
**허용 상한**이다. Backend가 전제를 충족하지 못하면 더 엄밀한 backward-error
|
||||
evidence가 필요하며 이 상한을 늘리지 않는다. n=0은 free 검사 대신 full reaction·수지를
|
||||
검사한다. 큰 n의 상한을 실제 오차로 가정하여 forward budget에 넣지 않는다.
|
||||
|
||||
κ∞(A)β_limit<1일 때 forward relative-error bound는
|
||||
κ∞(A)β_limit/(1−κ∞(A)β_limit).
|
||||
κ는 작은 fixture의 독립 dense inverse norm 또는 검증된 condition estimator의
|
||||
상계로 구한다. 이 상계가 유효하지 않으면 backward PASS를 온도 정확도 PASS로
|
||||
바꾸지 않는다. 참값 비교에도 이 forward bound와 coefficient interval을 전파한다.
|
||||
실제 sparse 행 i의 nonzero 수 ν_i로 독립 r_tilde=fl(A T_f−b)를 평가하고
|
||||
|
||||
E_r,i=γ_(2ν_i+2)(Σ_j|A_ij||T_f,j|+|b_i|),
|
||||
R_cert=upper(|| |r_tilde|+E_r ||∞),
|
||||
D_lower=lower(||A||∞||T_f||∞+||b||∞),
|
||||
β_cert=upper(R_cert/D_lower).
|
||||
|
||||
모든 scale sum/norm은 outward interval로 계산하며 underflow 항도 §2 enclosure로
|
||||
보존한다. D_lower=0은 exact-zero numerator/denominator를 별도 확인한다.
|
||||
**β_cert≤β_limit**가 residual 판정이다. Full C dT/δ+KT−Q 평가에도 자신의 실제
|
||||
row count·signed term absolute scale로 같은 의미를 검산한다. 구체적으로
|
||||
E_r,full,i=γ_(2ν_C,i+2ν_K,i+6)(Σ|C_ij||dT_j|/δ+Σ|K_ij||Tnew_j|+|Q_i|)
|
||||
+γ_1Σ|C_ij|(|Tnew_j|+|Told_j|)/δ로 둔다.
|
||||
관측 residual에 roundoff enclosure를 더하므로 우연히 작은 computed residual을 그대로
|
||||
정확한 잔차라고 가정하지 않는다.
|
||||
|
||||
n≤100의 소형 fixture는 독립 dense inverse로 Z≈A^-1를 구하고
|
||||
θ=upper(||I−ZA||∞)<1을 확인한다. 그러면
|
||||
upper(||A^-1||∞)≤upper(||Z||∞)/(1−θ)가 rigorous inverse-norm bound다.
|
||||
κ∞(A)β_cert<1일 때 relative forward bound는
|
||||
2κ∞(A)β_cert/(1−κ∞(A)β_cert).
|
||||
정확 coefficient의 E_A/E_b도 numerator에 E_A||T_f||∞+E_b로 더한다.
|
||||
이때 stored A의 inverse 상계를 J라 하면 J E_A<1을 확인하고 정확 A*의 inverse는
|
||||
J/(1−J E_A)로 넓힌다. 따라서 absolute forward bound는
|
||||
[J/(1−J E_A)](R_cert+E_A||T_f||∞+E_b)다(E_A/E_b는 ∞ norm bound).
|
||||
이 denominator의 조건을 증명하지 못하면 inconclusive이며 clamp/상한 확대는 금지다.
|
||||
|
||||
큰 **구조화된 convergence fixture**는 inverse나 최악 β_limit 없이 다음 C-norm
|
||||
전파를 사용한다. 정확 oracle C*,K*에 대한 증분 residual의 component enclosure를
|
||||
|
||||
R_n=|r_tilde|+E_r+E_C|dT|/δ+E_K|Tnew|+E_Q
|
||||
|
||||
로 둔다(E_C/E_K는 성분별 절댓값 오차 상계). 단열 homogeneous error의
|
||||
(C*+δK*)^-1C*는 C* norm에서 contraction이므로
|
||||
|
||||
B_T^n=B_T^(n−1)+δ||R_n||2/sqrt(λ_lower(C*))
|
||||
|
||||
가 온도 C-norm error의 사전 고정된 누적 상계다. 초기 nodal cos의 interval 오차를
|
||||
B_T^0에 포함한다. Normalized k=rho=c=h=1 fixture에서는 이 C-norm이 실제
|
||||
product-volume temperature L2다. Sampling/오차 norm 적분의 interval도 더한다.
|
||||
|
||||
n×n unit square의 tensor mass는 Mx⊗My⊗Cz다.
|
||||
Uniform Q1 1D mass의 Gershgorin lower는 1/(6n), 두 길이1/2 P2 segment의
|
||||
Cz lower는 1/60이므로 **λ_lower(C*)=1/(2160n²)**.
|
||||
K generalized upper는 면내 12n²+12n² 및 thickness
|
||||
||Kz||∞/λ_lower(Cz)=(64/3)/(1/60)=1280으로
|
||||
**λ_upper(K*,C*)=24n²+1280**.
|
||||
따라서 gradient L2 solver budget은 sqrt(24n²+1280) B_T^n이다.
|
||||
이 analytic bounds는 §6의 unit affine tensor fixture 전용이며 일반 mesh의 condition
|
||||
보증으로 확대하지 않는다. 큰 fixture에 production sparse inverse를 요구하지 않는다.
|
||||
§4 에너지 roundoff 상계의 β_limit는 보수적인 acceptance로 유지할 수 있지만,
|
||||
§6–7의 oracle 차이/관찰 order budget에는 β_cert 또는 위 R_n 전파를 사용한다.
|
||||
|
||||
## 4. 에너지, 반력과 BE 소산
|
||||
|
||||
@@ -264,27 +311,43 @@ log(1+x)의 전개에서 e_N=e^-1/(2N)+O(N^-2)이며 N≥16의 독립 값으로
|
||||
### 6.2 Fourier rectangle의 면내2차/gradient1차
|
||||
|
||||
Unit square,h=1,k=rho=c=1,noBC/noQ,T0=cos(πx)를 모든 station에 동일하게 둔다.
|
||||
τ=.1에서 연속 T=cos(πx)exp(−π²t),∇T=(-πsin(πx)exp(−π²t),0,0)와 비교한다.
|
||||
Affine n×n,n=8,16,32,64; norm은 product-volume temperature 및 global gradient L2.
|
||||
평가 적분은 cell별12×12 Gauss×exact thickness다. 12→16점 oracle 변화가
|
||||
해당 오차의 1e-8 이하인지 확인한다(관찰 order 영향1e-7 미만의 적분 budget).
|
||||
**τ=.001,N=32,δ=τ/32,INC=32**로 고정한다. 연속해는
|
||||
T=cos(πx)exp(−π²t),∇T=(-πsin(πx)exp(−π²t),0,0).
|
||||
Affine n×n,n=8,16,32,64를 모두 유지한다. Norm은 product-volume temperature와
|
||||
global gradient L2다. 평가 적분은 cell별12×12 Gauss×exact thickness이며
|
||||
12→16점 oracle 변화≤해당 오차의1e-8을 확인한다.
|
||||
|
||||
기본 공간 oracle는 독립 mode의 exp(-λ_hτ)다. 실제 BE run은
|
||||
N=16n²,δ=τ/N,INC=N으로 고정하고 같은 mode의 BE-exponential temperature L2 차이가
|
||||
continuum 온도 오차의 **1/32 이하**임을 확인한다. 시간오차를 공간수렴으로 오인하지
|
||||
않으며 동일 mesh의 finite-N modal oracle도 함께 비교한다.
|
||||
독립 exp(-λ_hτ) spatial oracle와 finite-N modal BE oracle를 동시에 사용한다.
|
||||
BE-exponential 온도 L2 차이는 continuum semidiscrete 오차의 **1/32 이하**여야 한다.
|
||||
작은 시간과 bounded N은 이 시간오차 분리를 유지하면서 모든 accepted frame을 저장한다.
|
||||
별도 시간1차 검사는 §6.1에 그대로 남긴다.
|
||||
|
||||
| n | Semidiscrete temperature L2 | Gradient L2 |
|
||||
| ---: | ---: | ---: |
|
||||
| 8 | 6.832505333e-3 | 9.419553867e-2 |
|
||||
| 16 | 1.720379027e-3 | 4.697214677e-2 |
|
||||
| 32 | 4.308592308e-4 | 2.346997504e-2 |
|
||||
| 64 | 1.077625665e-4 | 1.173296293e-2 |
|
||||
| n | Semidiscrete T L2 | BE T L2 | BE gradient L2 | Time/spatial ratio |
|
||||
| ---: | ---: | ---: | ---: | ---: |
|
||||
| 8 | 9.903629946e-3 | 9.902647628e-3 | 2.487150504e-1 | .0001089543 |
|
||||
| 16 | 2.482303232e-3 | 2.481327028e-3 | 1.245973612e-1 | .0004305809 |
|
||||
| 32 | 6.209759342e-4 | 6.200013808e-4 | 6.232870148e-2 | .0017171164 |
|
||||
| 64 | 1.552689976e-4 | 1.542952827e-4 | 3.116810477e-2 | .0068632659 |
|
||||
|
||||
모든 pair에서 T p는 **[1.95,2.05]**,gradient p는 **[.98,1.03]**.
|
||||
독립 T order=(1.98969,1.99744,1.99936),gradient=(1.00385,1.00099,1.00025).
|
||||
Q1 smooth interpolation O(h²)/O(h),λ_h=π²+O(h²)의 전개 및 위 fixture의
|
||||
독립 계산에 근거한다. 집중 source의 특이 해에 이 smooth order를 요구하지 않는다.
|
||||
모든 pair의 기존 허용구간을 유지한다: T p **[1.95,2.05]**,gradient p **[.98,1.03]**.
|
||||
독립 finite-N 기대값은 T=(1.9967024,2.0007686,2.0065775),
|
||||
gradient=(.9972203,.9993050,.9998262).
|
||||
Q1 smooth interpolation O(h²)/O(h),λ_h=π²+O(h²)와 위 독립 계산에 근거한다.
|
||||
12/16점 변화 최대1.30e-13이며 criterion1e-8보다 작다.
|
||||
§3의 실제 residual 기반 B_T 및 gradient budget이 측정 오차의1/1000 이하여야
|
||||
order 판정을 사용한다. 집중 source의 특이 해에 이 smooth order를 요구하지 않는다.
|
||||
|
||||
**실행 예산:** n=64에서도 sparse solve32회다. Mandatory flux와 initial 포함
|
||||
temperature raw doubles는
|
||||
4096×24×3×32×8 + 4225×5×33×8 = **81,074,472 bytes(약77.3MiB)**.
|
||||
모든4개 mesh의 같은 payload 합은107,772,960 bytes(약102.8MiB), solve총128회다.
|
||||
Model의 local frames는 시간마다 중복하지 않는 승인 schema이므로 largest mesh에서
|
||||
추가4096×4×9×8=1,179,648 bytes다. Identity/HDF5 overhead와 실제 peak memory를
|
||||
evidence에 별도 기록한다. 이 예산은 history/flux 생략이나 제품 출력 변경을 전제하지 않는다.
|
||||
|
||||
초기 문서의 τ=.1,N=16n²는 n64에서 flux만 약154.6GB인 과도한 fixture였으므로
|
||||
**kernel 구현 전** 독립 계산으로 위 설계로 대체했다. Production 결과에 맞춘 tolerance
|
||||
완화가 아니며 기존 공간 order·시간오차 분리·모든 frame 계약을 그대로 유지한다.
|
||||
|
||||
## 7. 고정5점 slab: 허용 이산 오차와 plateau
|
||||
|
||||
@@ -304,9 +367,38 @@ E/R은 absolute error다. Station 상대오차나 near-zero floor를 만들지
|
||||
4exp[-β(2M+1)²]/[π(2M+1)(1-r)],flux/reaction tail≤
|
||||
2exp[-β(2M+1)²]/(1-r),energy tail≤temperature tail.
|
||||
최소 시간에서도 모든 무차원 tail은 **1e-27 미만**이다.
|
||||
1−r는 -expm1(-8β(M+1))로 계산한다. Summation roundoff는
|
||||
γ_(8M+16)×absolute term sum으로 전파하며 transcendental 평가의 interval 또는
|
||||
확인한 library error bound도 더한다.
|
||||
1−r는 -expm1 표현과 수학적으로 동등한 exact interval subtraction으로 평가한다.
|
||||
**Oracle 산술은 다음 방식으로 고정**하며 C++17 libm의 막연한 1ULP 보장을 가정하지 않는다.
|
||||
Appendix E가 실제 실행 가능한 표준 라이브러리 generator다.
|
||||
|
||||
1. π=16 atan(1/5)−4 atan(1/239), 각 alternating arctan을 j=0…63까지 exact
|
||||
유리수로 합한다. 첫 생략항 q^129/129로 양쪽 enclosure를 만든다.
|
||||
2. 이후 모든 interval endpoint는 격자 2^-320으로 floor/ceil하여 outward 보존한다.
|
||||
원래 π enclosure 폭은2^-295 미만이다.
|
||||
3. Slab station의 phase는 정수 kπ/8이다. 정수 quadrant reduction으로 |r|≤π/4에
|
||||
옮긴 뒤 sin/cos Taylor 각각32항을 쓴다. Remainder는 보수적으로1/65!,1/64!다.
|
||||
4. exp(-x),0≤x≤512는 y=x/1024의64차 Taylor,
|
||||
remainder≤(1/2)^65/65!를 더하고 interval squaring10회로 복구한다.
|
||||
x≥512이면 0≤exp(-x)≤2^-512(e>2)을 사용한다.
|
||||
5. M=80 series를 위 interval로 합한다. Tail을 더하기 전 각 quantity enclosure 폭은
|
||||
**2^-270 미만**이어야 한다. 여기에 앞의 analytic Fourier tail을 더한다.
|
||||
필요한 binary64 fixture는 lower를 float 변환 후 nextafter(-∞),upper를 변환 후
|
||||
nextafter(+∞)하여 export한다. 이 endpoint 차이가 B_oracle이며 별도 floor가 없다.
|
||||
|
||||
실제 generator에서 최소 시간의 tailT=1.658661e-30,tailq=4.194724e-28,
|
||||
최종 enclosure 최대 폭8.389448e-28이었다. 나머지 시각의 폭은8.93e-89 이하였다.
|
||||
이 방식은 테스트 oracle generator 전용이며 production arbitrary-precision dependency가
|
||||
아니다. Spectral oracle의 exp도 동일 enclosure를 적용하고 eigenpair/coefficients의
|
||||
backward-error interval을 함께 전파한다. Appendix A의 통상 math 계산은 표 수치의
|
||||
간단한 재현용이며 interval E가 transcendental correctness의 근거다.
|
||||
|
||||
T10은 generator의 T/q/E/R interval을 outward binary64 fixture로 고정하여 사용할 수
|
||||
있다. 또는 binary64 outward Taylor가 동일한 최종 B_oracle 및 §6–7의 오차 budget을
|
||||
증명하면 그 경로도 가능하다. 2^-270은 고정 고정밀 generator의 내부 검사이며 production
|
||||
정밀도 요구가 아니다. 무차원 interval error를 실제 단위로 옮길 때 T는 |ΔT|,
|
||||
q는 k|ΔT|/h,E는 rho c area h|ΔT|,R은 k area|ΔT|/h를 곱한다.
|
||||
온도 기준 이동은 interval 폭을 바꾸지 않는다. 선형 sampling/trace/energy/reaction row L은
|
||||
성분별 |L| times input error로 전파하며 signed 값 자체를 절댓값으로 바꾸지 않는다.
|
||||
|
||||
독립1D P2 FE는 길이1/2인 두 segment를 조립한다.
|
||||
C_seg=(1/2)/30 [[4,2,-1],[2,16,2],[-1,2,4]],
|
||||
@@ -485,6 +577,8 @@ scratch로 전환했다. [Appendix](numerical-oracle-scratch.md)의 명령은 Py
|
||||
최종 재현 명령은 appendix 첫 PowerShell block이며 exit 0,
|
||||
마지막 출력은 ALL SCRATCH BLOCKS COMPLETED였다. Input-cell 독립 비교는
|
||||
10,000/10,000 및 CURRENT TIME GRID ASSERTIONS PASSED를 출력했다.
|
||||
실행 예산 보완 뒤 five-block 재검산도 exit 0이었다. Bounded-space order/time ratio,
|
||||
FOURIER INTERVAL ASSERTIONS PASSED 및 최종 완료 출력을 확인했다.
|
||||
상대 링크 파일 존재/Markdown 표 열 수 정적 검사도 exit 0(8 links,2 files),
|
||||
두 소유 파일만 대상으로 한 git diff --check는 exit 0이었다.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user