Repository navigation
Expand file tree
/
Copy pathusage.html
More file actions
624 lines (516 loc) · 42.2 KB
/
Copy pathusage.html
File metadata and controls
624 lines (516 loc) · 42.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Formurae 使い方ガイド</title>
<style>
:root { --ink:#1c1e21; --sub:#5a6270; --line:#e3e6ea; --accent:#0b5fa5; }
* { box-sizing:border-box; }
body { margin:0; color:var(--ink); background:#f6f7f9;
font-family:"Hiragino Sans","Noto Sans JP",Helvetica,Arial,sans-serif; }
header { padding:28px 32px; background:#fff; border-bottom:1px solid var(--line); }
header h1 { margin:0 0 6px; font-size:22px; }
header p { margin:4px 0; max-width:980px; color:var(--sub); font-size:13.5px; }
main { max-width:920px; margin:auto; padding:12px 24px 80px; font-size:14px; line-height:1.8; }
h2 { margin:40px 0 10px; padding-left:10px; color:var(--accent);
border-left:4px solid var(--accent); font-size:17px; }
h3 { margin:24px 0 6px; font-size:14.5px; }
a { color:var(--accent); }
code { padding:1px 5px; border-radius:4px; background:#eef1f4;
font:12.5px "SF Mono",Menlo,Consolas,monospace; }
pre { overflow-x:auto; padding:12px 15px; border-radius:8px;
color:#dbe7f6; background:#0e1726;
font:12.5px/1.6 "SF Mono",Menlo,Consolas,monospace; }
pre .c { color:#6f8cac; }
table { width:100%; margin:10px 0; border-collapse:collapse; font-size:13px; }
th,td { padding:7px 10px; border:1px solid var(--line); background:#fff; text-align:left; }
th { background:#f0f3f7; }
.toc,.note { margin:18px 0; padding:11px 16px; border:1px solid var(--line);
border-radius:8px; background:#fff; font-size:13px; }
.note { background:#fff9e9; }
</style>
</head>
<body>
<header>
<h1>Formurae 使い方ガイド</h1>
<p>テンソル添字記法、微分形式、解析微分をEgisonで評価し、離散化だけをformurae-postで行って、
FormuraのMPI・temporal-blocking付きC codeへつなぐための手引きです。
実例は<a href="gallery.html">Formuraeギャラリー</a>と<a href="waves.html">波のシミュレーション</a>にあります。</p>
</header>
<main>
<div class="toc">
<b>目次:</b>
<a href="#pipeline">pipeline</a> / <a href="#setup">setup</a> /
<a href="#tutorial">tutorial</a> / <a href="#syntax">syntax</a> /
<a href="#operators">演算子の分類</a> / <a href="#derivative">微分と精度</a> /
<a href="#tensor">tensor・form</a> /
<a href="#geometry">geometry</a> / <a href="#artifacts">生成物と検証</a>
</div>
<h2 id="pipeline">1. 4段pipeline</h2>
<pre>model.fme Formurae source
│ formurae-pre: parse / scope / declaration / source map
model.egi Egison normalization unit
│ Egison: tensor/index algebra / analytic derivative / CAS
model.feir canonical Formurae Egison IR
│ formurae-post: placement / exact stencil / auxiliary fields / storage
model.fmr Formura source
│ Formura
model.c/.h MPI + temporal blocking C library</pre>
<p>pureな解析式で定義できる演算子はEgison、具体的な差分、格子配置、storageを含む離散意味は
opaque requestとformurae-post、loopと通信はFormuraが担当します。
成功時のEgison stdoutはFEIR 1個だけです。warningやtype/evaluation errorはmachine runnerが拒否します。</p>
<h2 id="setup">2. セットアップ</h2>
<pre><span class="c"># GHC 9.6系、cabal、stack(Formura用)、隣接する ../egison が必要</span>
make setup
cabal build
make diffusion3d
make all</pre>
<p class="note">FormuraeとEgisonはcabalでbuildします。Formura upstreamのbuildだけにstackを使います。
MPIがない環境向けに1-rank stubを同梱しています。</p>
<h2 id="tutorial">3. 拡散方程式</h2>
<pre>dimension 3
axes x, y, z
param κ = 1.0
param dt = 0.1*dx*dx
raw gauss = fun(x,y,z) exp(-((x-32*dx)/(5*dx))**2 - ...)
field u : scalar
init:
u = gauss(i*dx,j*dy,k*dz)
step:
u' = u + dt * κ * Δ u</pre>
<p><code>make diffusion3d</code>で4つの中間artifactを生成し、FormuraとC checkまで実行します。
<code>Δ</code>はcanonical scalar Laplacianで、離散化精度はmodel profileから選ばれます。</p>
<h2 id="syntax">4. 表層構文</h2>
<table>
<tr><th>構文</th><th>意味</th></tr>
<tr><td><code>dimension 1..3</code></td><td>Formura backendの次元</td></tr>
<tr><td><code>axes x, y, z</code></td><td>座標名とAxisId。必須</td></tr>
<tr><td><code>index a, b : 9</code></td><td>空間次元と独立した添字の成分数</td></tr>
<tr><td><code>param dt = ...</code></td><td>Formura parameter</td></tr>
<tr><td><code>extern exp</code></td><td>external scalar function</td></tr>
<tr><td><code>raw NAME = ...</code></td><td>verbatim Formura helper</td></tr>
<tr><td><code>Δ u</code></td><td>collocated scalarのcanonical Laplacian</td></tr>
<tr><td><code>field u : scalar</code></td><td>scalar state field</td></tr>
<tr><td><code>static field J : scalar := volume</code></td><td>初期化時に一度計算し、自動で保持する場</td></tr>
<tr><td><code>field E_i @ primal</code></td><td>variance付きrank-1 field</td></tr>
<tr><td><code>field σ{~i~j} @ primal</code></td><td>symmetric rank-2 field</td></tr>
<tr><td><code>field B : 2-form</code></td><td>differential form。既定policyはPrimal</td></tr>
<tr><td><code>let q = ...</code></td><td>step内のpure binding</td></tr>
<tr><td><code>local q_i @ primal = ...</code></td><td>型・variance・policyを持つstep-local grid field</td></tr>
<tr><td><code>u' = ...</code></td><td>next-time field update</td></tr>
</table>
<p><code>static field</code> は位置ごとに異なっても時間では変化しない場です。
型・添字・格子配置は通常の <code>field</code> と同じように指定します。
右辺には座標・パラメータ・計量・先に宣言した固定場を使えます。
通常の場への依存、自己参照、前方参照、次時刻の値への依存はエラーです。
<code>def</code> を経由した依存も検査します。
<code>init</code> への代入や <code>J' = J</code> は不要で、再初期化・更新は禁止します。</p>
<p>縮約は<code>contractWith</code>または<code>.</code>で明示します。同じ文字の上下添字が現れただけでは
surfaceで暗黙総和しません。唯一の例外は記号添字つき<code>∂</code>で、<b>微分が導入した添字</b>をoperandが
繰り返す場合に限り<code>contractWith (+)</code>を自動適用します(<code>∂_i X~i</code>は発散、
<code>∂_j σ~i~j</code>はvector)。<code>withSymbols</code>、<code>tensorMap</code>、<code>subrefs</code>、
<code>transpose</code>、<code>!.</code>はEgison tensor algebraへ渡されます。</p>
<h3>添字記号ごとの成分数</h3>
<pre>dimension 2
axes x, y
index a, b : 9
field f_a
field c_a_i
field M_a_b</pre>
<p><code>f</code> は9成分,<code>c</code> は9×2成分,<code>M</code> は9×9成分です。
未宣言の <code>i</code> などは空間方向を表し,1から <code>dimension</code> まで動きます。
<code>index</code> は場・関数の宣言より前に書き,サイズには正の整数を指定します。
場の形状は宣言時に固定されます。<code>f_b</code> として参照できますが,
<code>f_i</code> として2成分に読み替えることはできません。<code>f_9</code> は第9成分です。</p>
<p>固定場,添字付きの局所場・関数引数,縮約(添字について和を取る演算)にも同じ宣言を使います。
格子配置には空間方向の添字だけが影響します。<code>c_a_i @ primal</code> では,
すべての成分番号 <code>a</code> について <code>i</code> が指定する方向に半格子だけずらします。
成分番号は,サイズが空間次元と等しくても,微分方向や空間の計量の添字には使えません。
<code>index</code> 宣言があるモデルでは <code>local q_a_i = ...</code> のように局所場の添字を明示します。
<code>local q : tensor</code> の推論は空間方向だけを使うモデルで利用できます。
通常の添字付きの場は従来どおり2軸までです。</p>
<h2 id="operators">5. 演算子は「pureに短く定義できるか」で分ける</h2>
<p>「基本演算子か合成演算子か」ではなく、演算子の意味そのものを通常のEgison数式として
1行から数行で定義できるかで分けます。pureな演算子はtensor/index algebraと解析微分によって
FieldJetを含む式までEgisonが正規化し、その後のstencil選択だけをformurae-postに任せます。</p>
<h3>組み込みとライブラリの早見表</h3>
<p>「何が組み込みで何がライブラリ関数か」は次の4層で決まります。第1層だけがcompiler所有で、
ユーザは定義も上書きもできません。それ以外の名前はすべて通常のlexical shadowingに従い、
user定義は最下層と同じcompletion・placement経路を通ります。</p>
<table>
<tr><th>層</th><th>surface</th><th>意味の所有者</th><th>shadow</th></tr>
<tr><td>構文(primitive)</td>
<td><code>∂/∂ e a</code>・<code>∂_a</code>・<code>∂^m_a</code>・<code>∂'^m_a</code>・
バッククォートchain(2段以上)・<code>boundary a : sbp|periodic|ghost v</code>・
境界外挿<code>sbpx_a</code>とSATマクロ<code>satDirichlet_a</code>/<code>satNeumann_a</code>・
<code>resample</code>・成分射影<code>q_x</code>・添字/variance記法・
<code>let</code>/<code>local</code>と<code>@</code>policy</td>
<td>formurae-preの構文解析+Egisonの<code>∂/∂</code>(未知の微分則はerror)+opaque manifest。
解析微分は<code>∂/∂</code>だけ。添字つき<code>∂</code>は常に離散で、
素の一階(軸・記号とも)はplacement誘導radius-1差分(記号添字は軸ごとに並べ
導入した添字の反復を自動縮約)、次数・プライム付きはexplicit-radius中心stencil
(collocated: radius = クォート数 + 1、staggered奇数階: 半整数radius = クォート数 + 1/2)。
境界は軸の宣言<code>boundary</code>が持ち、sbp軸では素の∂がSBP閉包つきに降下(§6)。
添字が宣言済み軸名なら具体成分・それ以外は記号(∂と場の参照で共通の規則)</td>
<td>不可</td></tr>
<tr><td>ambient束縛</td>
<td><code>dimension</code>・<code>coordinates</code>・<code>volume</code>・<code>epsilon</code>・
<code>metric</code>・<code>inverseMetric</code>(+宣言した計量名)</td>
<td>formurae-preがmodelごとに一度束縛</td>
<td>modelスコープで予約</td></tr>
<tr><td>canonical keyword</td>
<td><code>d</code>・<code>hodge</code>・<code>δ</code>・<code>Δ</code>・<code>Δ_H</code></td>
<td>意味論は可視のライブラリ合成そのもの。名前は正規化前に解決され静的kind検査に使われ、
variable metricの<code>δ</code>・<code>Δ</code>だけ内部離散planへlowerする</td>
<td>可</td></tr>
<tr><td>ライブラリ関数</td>
<td><code>grad</code>・<code>dGrad</code>・<code>divg</code>・<code>curl</code>・
<code>hessian</code>・<code>lap</code></td>
<td><a href="../../lib/formurae-operators.egi"><code>lib/formurae-operators.egi</code></a>の通常の定義</td>
<td>可(user defと同一経路)</td></tr>
</table>
<p><code>∂</code>族はprimitive層の見えている綴りで、ユーザが定義できない唯一の演算子です
(FieldJetを作る側だからです)。<code>contractWith</code>・<code>.</code>・<code>withSymbols</code>は
Egison自身の記法機構で、そのままEgisonコードとして通ります。
以下の小節は、この区分を「定義元」と「必要なambient値」の視点から詳細化したものです。</p>
<h3>Egisonと同レベルで簡潔に定義できる演算子</h3>
<p>次の三分法は、<code>.fme</code>の名前がどの定義へ解決されるかと、生成時に
<code>coordinates</code>・<code>dimension</code>・metricなどのmodel ambient値が必要かで分ける。
数学的な座標不変性そのものではなく、Formuraeでの定義・束縛に必要な文脈による分類である。</p>
<h4>1. Egison標準ライブラリからロードする関数(およびcore構文)</h4>
<table>
<tr><th>関数・構文</th><th>定義元</th><th>意味</th></tr>
<tr><td><code>.</code>、<code>.'</code>、<code>contractWith</code></td><td><a href="../../../egison/lib/math/algebra/tensor.egi"><code>algebra/tensor.egi</code></a></td><td>明示的なtensor縮約</td></tr>
<tr><td><code>trace</code>、<code>sym</code>、<code>antisym</code></td><td><a href="../../../egison/lib/math/algebra/matrix.egi"><code>algebra/matrix.egi</code></a></td><td>rank-2 tensorのtrace・対称部・反対称部</td></tr>
<tr><td><code>wedge</code>、<code>∧</code></td><td><a href="../../../egison/lib/math/geometry/differential-form.egi"><code>geometry/differential-form.egi</code></a></td><td>微分形式のwedge積</td></tr>
<tr><td><code>!.</code></td><td>Egison core tensor algebra</td><td>tensor product構文。named functionではない</td></tr>
<tr><td><code>∂/∂</code>、四則演算、<code>sin</code>、<code>exp</code>、<code>sqrt</code>など</td><td><a href="../../../egison/lib/math/analysis/derivative.egi"><code>analysis/derivative.egi</code></a> とEgison標準math library</td><td>解析微分の規則とscalar algebra。未知の微分則は0でなくerror</td></tr>
</table>
<p>これらはFormuraeが同名定義を持たずに読み込む。Egisonにも<code>grad</code>はあるが、
Formurae表層の<code>grad</code>は下のoperand-only関数へ解決され、座標はambient環境から参照するため、
この区分には含めない。</p>
<h4>2. Formuraeライブラリで定義するが座標系に依存しない関数</h4>
<table>
<tr><th>関数</th><th>定義元</th><th>意味</th></tr>
<tr><td><code>norm2</code></td><td><a href="../../lib/formurae-tensor.egi"><code>lib/formurae-tensor.egi</code></a></td><td>全rankで全成分を縮約するtensorの二乗ノルム</td></tr>
</table>
<p>現在、通常の<code>.fme</code>表層演算子としてこの区分にあるのは<code>norm2</code>だけである。
同じlibraryにある<code>FE.canonicalFormTensor</code>、<code>FE.tensorComponentAt</code>、
<code>FE.formBasis</code>、<code>FE.formComponents</code>は、Formurae固有の微分形式表現utilityであり、
座標系には依存しないがsurface演算子としては公開しない。</p>
<h4>3. Formuraeライブラリで定義し、座標系に依存する関数(canonical keywordを含む)</h4>
<p class="note">添字つき<code>∂</code>はこの表から外しました — ライブラリ関数ではなく
構文(早見表の第1層)です。この表のうち<code>d</code>・<code>hodge</code>・<code>δ</code>・
<code>Δ</code>・<code>Δ_H</code>はcanonical keyword(shadow可、正規化前に名前解決)、
<code>grad</code>以下は純粋に通常のライブラリ関数です。</p>
<table>
<tr><th>surface演算子</th><th>必要なambient値</th><th>短い定義で表す意味</th></tr>
<tr><td><code>grad</code>、<code>dGrad</code>、<code>divg</code>、<code>hessian</code>、<code>lap</code></td><td><code>coordinates</code></td><td>微分添字のvarianceを保つ微分・縮約の合成</td></tr>
<tr><td><code>curl</code></td><td><code>coordinates</code>、<code>dimension</code>、<code>epsilon</code></td><td>Levi-Civita tensorと解析微分の合成</td></tr>
<tr><td><code>d</code></td><td><code>coordinates</code></td><td>外微分</td></tr>
<tr><td><code>hodge</code></td><td><code>dimension</code>、geometry scale</td><td>基底補集合とmetric係数によるHodge star</td></tr>
<tr><td><code>δ</code></td><td><code>coordinates</code>、<code>dimension</code>、geometry scale</td><td>余微分。constant geometryでは<code>d</code>と<code>hodge</code>のpureな合成。宣言幾何ではpreludeマクロとして<code>dFluxWeights</code>/<code>dFluxScale</code>/<code>dFluxDiv</code>に展開され、係数はinit凍結のstate配列になる</td></tr>
<tr><td><code>Δ</code></td><td><code>coordinates</code>、<code>dimension</code>、geometry scale</td><td>collocated scalarのcanonical Laplacian。constant geometryでは<code>−δ(d u)</code>=<code>divg (grad u)</code>のpureな合成。宣言幾何では<code>−δ(dExterior u)</code>のpreludeマクロ展開(保存形flux)</td></tr>
<tr><td><code>Δ_H</code></td><td><code>coordinates</code>、<code>dimension</code>、geometry scale</td><td>constant geometry上のHodge--de Rham Laplacian <code>d (δ A) + δ (d A)</code></td></tr>
<tr><td><code>dExterior</code></td><td><code>dimension</code></td><td>placement誘導grid∂の交代和による離散外微分(解析jetを作らない)</td></tr>
<tr><td><code>dFlux</code></td><td><code>volume</code>、<code>inverseMetric</code></td><td>重みつきflux w<sub>I</sub> = V·∏g<sup>ii</sup>·A<sub>I</sub>(添字集合を保ち、staggered parityと整合)</td></tr>
<tr><td><code>dFluxDiv</code></td><td><code>volume</code>、<code>metric</code></td><td>符号込み随伴発散 −(∏g<sub>kk</sub>/V)·Σ<sub>i</sub>∂<sub>i</sub>w<sub>iK</sub>。<code>dFlux</code>との合成が余微分</td></tr>
<tr><td><code>dHodge</code></td><td><code>volume</code>、<code>inverseMetric</code></td><td>重みつきHodge star(成分が補集合basisへ移るため、materialize用ではなく診断・flat用)</td></tr>
</table>
<p><code>metric</code>、<code>inverseMetric</code>、<code>volume</code>、<code>epsilon</code>自体は関数ではなく、
model宣言から生成されるambient tensor/valueである。なお、数学的には座標不変な<code>d</code>も、
現在のFormurae実装ではその成分を<code>∂/∂</code>で計算するためambient <code>coordinates</code>を参照する。</p>
<p><code>d</code>、<code>hodge</code>、<code>δ</code>、<code>Δ_H</code>はform値に、
canonical <code>Δ</code>はscalarに使います。
<code>curl</code>はambientな<code>epsilon</code>と<code>coordinates</code>を使う短い定義へ解決されます。</p>
<p>したがって、user operatorも数学の形を保ったまま書けます。ライブラリ演算子の合成に加えて、
<code>∂/∂</code>をambientの<code>coordinates</code>ベクトル(添字なし・添字つき)へ適用すれば
解析テンソル微分そのものが書け、いずれも解析(FieldJet)のままprofileが離散化します。</p>
<pre>def symmetricGrad X = sym (dGrad X)
def bilaplacian u = lap (lap u)
def gradLike u = ∂/∂ u coordinates <span class="c">-- 解析gradient(微分軸はanonymous)</span>
def curlLike X =
withSymbols [i, j, k]
(epsilon_i~j~k . ∂/∂ X_k coordinates~j) <span class="c">-- 解析curl(library curlと同じ本体)</span>
metric g
field u : scalar
field q_i
field A_i
field X~i
step:
q' = gradLike u
X'~i = withSymbols [j] (g~i~j . A_j)
A'_i = withSymbols [j] (g_i_j . X~j)</pre>
<p>同じ演算子を添字つき<code>∂</code>(<code>withSymbols [i] (∂_i u)</code>など)で書くと、
離散要求(placement誘導radius-1差分)のテンソルを組み立てる演算子になり、profileには
従いません(maxwell3dのcurlは意図的にこの離散形で、既定profileでは解析経由と同じCに落ちる
ことを実測済み)。</p>
<h3>macro — 文列に展開されるテンプレート</h3>
<p><code>def</code>が「式」(Egisonが値に評価)なのに対し、<code>macro</code>は「文列」
(formurae-preが展開)を定義します。本体は<code>local</code>束縛の列と<code>in</code>式で、
呼び出しはstep式の中に書けます:</p>
<pre>macro Δc u =
local q~i @ primal = withSymbols [j] (volume * (inverseMetric~i~j . ∂_j u))
in (divg q) / volume
step:
u' = u + dt * Δc u</pre>
<p>展開はparse直後・全解析の前に行われ、<code>local</code>は fresh 名で呼び出し元stepの
直前へ持ち上げられ(let-insertion)、呼び出し位置には<code>in</code>式が入ります。
下流の効果・placement・kind検査は展開結果にそのまま働きます。上の<code>Δc</code>は
宣言された直交計量の保存形Laplacianそのもので、生成される.fmrは手書き展開形と
一致します(tests/pre_macro_expansion.sh で検査)。マクロはstep式専用で、
init・def・幾何宣言内での使用はエラーです。</p>
<p>静的検査はscalar/tensorの区別だけを行い、微分形式の次数は値自身
(<code>dfOrder</code>)が正規化時に運びます。<code>local w : tensor @ primal = …</code>と
宣言した<b>遅延local</b>は、rank・variance・次数を書かず、materializeされた値から
FEIR宣言を組み立てます。この上で、重みつきflux <code>dFlux</code>
(w<sub>I</sub> = V·∏<sub>i∈I</sub>g<sup>ii</sup>·A<sub>I</sub>)と符号込み随伴発散
<code>dFluxDiv</code>((δw)<sub>K</sub> = −(∏<sub>k∈K</sub>g<sub>kk</sub>/V)·Σ<sub>i</sub>∂<sub>i</sub>w<sub>iK</sub>)、
placement誘導grid∂の交代和 <code>dExterior</code> を使うと、
<b>codifferentialが次数によらない1本のマクロ</b>になります:</p>
<pre>macro δc A =
local w : tensor @ primal = dFlux A
in dFluxDiv w</pre>
<p>同じ定義が、staggeredトーラス上のスカラーLaplacian
(<code>u' = u + dt * (0 - δc (dExterior u))</code>が手書き保存形とlocal名を除いて
.fmr一致)にも、flat Yee格子上のMaxwell
(<code>E' = E + dt * δc B</code>、2-form操作数!が組み込みδとC実行bit一致)にも
使えます(tests/pre_generic_codiff.sh で検査)。次数分岐はどこにも現れません —
ライブラリ関数が<code>dfOrder</code>を読み、遅延localがその次数で実体化します。</p>
<p><code>gradLike</code>を出たanonymous rank-1軸にはfreshな下添字が補われます。
formurae-preはfunction名やbodyからresult varianceを推論せず、ordinary covectorのequation targetへ
直接代入したときだけ、そのanonymous down軸をtargetの下添字へ対応付けます。
したがって<code>E_i + gradLike u</code>のanonymous軸を既存の<code>i</code>へ暗黙に統合しません。
同じ軸で合成する意図は、<code>withSymbols [i] (E_i + (gradLike u)..._i)</code>のように、
またはEgisonと同じ<code>(gradLike u)_i</code>の綴りで
call siteで下添字を明示します。</p>
<p>Formuraeはuser function本体の式構造や計算履歴を解析してresult signatureを付けません。
EgisonがRHSを評価した後、equationまたはindexed <code>local</code>へ格納するときに、宣言targetの
shape・logical variance・<code>dfOrder</code>と実際の値だけを照合します。添字の上げ下げは、上の
<code>X'~i</code>と<code>A'_i</code>のように計量との縮約をindexed targetへ直接書くのを標準形とします。
Formuraeは関数headの結果添字も、public operatorとしての<code>flat</code> / <code>sharp</code>も
提供しません。</p>
<p><code>dimension</code>、<code>coordinates</code>、<code>metric</code>、<code>inverseMetric</code>、
<code>volume</code>、<code>epsilon</code>はmodelから束縛されるambient値です。
<code>metric g</code>を宣言すると、同じ計量を共変な<code>g_i_j</code> / <code>g_#_#</code>と
反変な<code>g~i~j</code>から参照できます。反変viewはindexed equation/localで直接使います。
hidden contextをuser operatorの引数として渡す必要はありません。</p>
<h3>格子意味を伴うsurface</h3>
<p>数式にstencil、絶対格子位置、保存flux、または一時storageが必要な場合は、
次のsurfaceが意図を構造的に保持します。必要な部分だけがopaque requestとしてFEIRへ残ります。</p>
<table>
<tr><th>surface</th><th>格子上の意味</th></tr>
<tr><td><code>∂_x expr</code>・<code>∂_i expr</code>(記号添字)</td><td>式全体へのplacement誘導radius-1差分。記号添字は軸ごとに並べ、導入添字の反復を自動縮約</td></tr>
<tr><td><code>∂^m_x expr</code>・<code>∂'^m_x expr</code></td><td>式全体へのexplicit-radius中心stencil(radius = クォート数 + 1)。profileをbypass</td></tr>
<tr><td><code>`(∂_y (`(∂_x expr)))</code></td><td>内側からの軸順と重複を保つ離散微分chain(2段以上。単発のクォートはエラー)</td></tr>
<tr><td><code>resample(value, bit...)</code></td><td>補間先の絶対placement</td></tr>
<tr><td><code>local q_i @ primal = ...</code></td><td>中間grid fieldの型、component placement、lifetime、schedule</td></tr>
<tr><td>geometry付き<code>Δ</code> / <code>δ</code></td><td>preludeマクロ展開: 実体化した重み(init凍結)・flux localとwhole-operand差分</td></tr>
</table>
<p class="note">canonical <code>Δ</code>はcollocated scalar、<code>Δ_H</code>はDEC form専用です。
<code>δ</code>は定曲率geometryではDEC form専用ですが、宣言幾何ではpreludeマクロに
なるため(要求時代のmode gateは消滅)collocatedでも書けます。宣言幾何の
<code>δ</code>とscalar <code>Δ</code>はpreludeマクロ展開で保存流束形に下ります。
general variable-metric <code>Δ_H</code>は現IRでは表せないためcompile-time errorとし、
constant geometryのみ<code>d δ + δ d</code>のpureな合成として扱います。</p>
<p>座標非依存の縮約は<a href="../../../egison/lib/math/algebra/tensor.egi"><code>egison/lib/math/algebra/tensor.egi</code></a>、
rank-2演算は<a href="../../../egison/lib/math/algebra/matrix.egi"><code>egison/lib/math/algebra/matrix.egi</code></a>、
<code>wedge</code>は<a href="../../../egison/lib/math/geometry/differential-form.egi"><code>egison/lib/math/geometry/differential-form.egi</code></a>を唯一の定義元とします。
解析微分のcoreは<a href="../../../egison/lib/math/analysis/derivative.egi"><code>egison/lib/math/analysis/derivative.egi</code></a>、
model-local calculus・form・geometry定義は<a href="../../lib/formurae-operators.egi"><code>lib/formurae-operators.egi</code></a>にあります。
opaque operatorの権威的一覧は<a href="../../spec/feir-primitives.sexp"><code>spec/feir-primitives.sexp</code></a>、
格子programへのloweringは<a href="../../src/Formurae/Post/Compile.hs"><code>Compile.hs</code></a>と
<a href="../../src/Formurae/Post/BackendPlan.hs"><code>BackendPlan.hs</code></a>にあります。</p>
<h2 id="derivative">6. 微分と離散化精度</h2>
<h3>解析微分</h3>
<pre>∂/∂ (u * u) x <span class="c">-- 2*u*FieldJet(u,{x:1})、離散化はprofileが決める</span>
∂/∂ (∂/∂ u x) x <span class="c">-- FieldJet(u,{x:2})</span>
∂/∂ u coordinates <span class="c">-- 微分軸を持つテンソル(軸はanonymous、= gradの中身)</span></pre>
<p>解析微分は<code>∂/∂ e a</code>(Egisonと同じ綴り)だけです。Egisonが
product/quotient/chain ruleを適用し、導関数はFunctionDataのuser indexから
FEIRのFieldJet multi-indexへ変換され、stencilはmodel profileが選びます。
<code>grad</code>・<code>curl</code>・<code>Δ</code>などのライブラリ演算子は
この<code>∂/∂</code>の解析合成なので、profileの精度切替はそれら全てに一括で効きます。</p>
<h3>添字つき∂ = 離散微分</h3>
<pre>∂_x (u * u) <span class="c">-- 式全体に半径1の差分(placement誘導つき、展開しない)</span>
∂^2_x u <span class="c">-- 3点2階の中心stencil(radius 1)</span>
∂'^2_x u <span class="c">-- 5点2階の中心stencil(radius 2 = クォート数 + 1)</span>
∂'_x q <span class="c">-- staggered場では実効radius 3/2 = FDTD(2,4)の4点(±9/8, ∓1/24)</span>
∂''_x q <span class="c">-- 同、radius 5/2の6点6次</span>
∂_i X~i <span class="c">-- 軸ごとのplacement誘導radius-1差分を自動縮約(= 離散div)</span>
∂_j σ~i~j <span class="c">-- 同上。staggered場では半セルYee差分がplacementから導出される</span></pre>
<p>添字つき<code>∂</code>は添字の種類によらず離散要求です。<b>素の一階</b>は
placement誘導のradius-1差分(<code>derivative.grid-whole</code>)で、collocatedでは
中心差分、staggeredでは半セルYee差分になります。記号添字はこれを軸ごとに並べた
テンソルで、微分が導入した添字をoperandが繰り返す場合に限り
<code>contractWith (+)</code>を自動適用します。<b>次数・プライム付き</b>は
explicit-radiusの中心stencil(<code>derivative.coordinate-wide</code>、
model profileと独立にformurae-postがTaylor moment条件からexact rational係数を解く)。
幅の規則は「素の形 = 格子の最小stencil、プライム1個 = +1リング」で全格子一様です:
collocatedではradius = クォート数 + 1、staggeredの奇数階では結果が双対部分格子に
着地するため<b>半整数の実効radius = クォート数 + 1/2</b>(ターゲット中心
±1/2 … ±(2k−1)/2 の対称stencil)になります。許される半径は
2r ≡ m (mod 2)(パリティ整合)・点数 2r+1・形式精度 2r − m + 2。
<b>半整数半径そのものは書きません</b>: 表層にもFEIRにも分数は現れず
(radius属性は正整数のまま)、formurae-postが「staggered×奇数階なら
実効radius = 属性 − 1/2」と解釈するだけです。プライムはパリティ中立な
「+1リング」で、半分ずれるかどうかは格子が供給するため、
「collocatedに3/2」のようなパリティ不整合はそもそも表現できません —
placementを宣言でなく(policy, 添字構造)から導出するのと同じ原則です。
既定profile(accuracy 2)ではこれらは<code>∂/∂</code>経由と同じstencilに落ちます
(elastic3d/maxwell3d/diffusion1d等で生成C byte一致を確認)。</p>
<h3>model profile</h3>
<pre>discretization collocated derivative 2 centered accuracy 4
u' = u + dt * Δ u
discretization staggered yee accuracy 4 <span class="c">-- staggered場のΔ・grad・divgも4次に</span></pre>
<p>精度は演算子本文と独立です。formurae-postがformal accuracyを満たす最小radiusを探索し、
Taylor moment条件からexact rational coefficientを解きます。上の例はcompact 5点二階差分になります。
staggered/yee側のm階則は<b>精度2kの1階半整数stageのm重自己合成</b>で、
Δ = divg∘grad・∂³ = grad∘Δ・∂⁴ = Δ∘Δ が全次数・全精度で恒等的に成立します
(accuracy 2ではYee対と[1,−2,1]に退化して従来と一致)。最小幅では合成 = 直接解の
縮退が全次数で成り立ちます。</p>
<h3>順序つき微分chain</h3>
<pre>`(∂_y (`(∂_x (`(∂_x q)))) <span class="c">-- x, x, yの順に適用</span></pre>
<p>バッククォートは2段以上の微分chain専用です。軸の適用順と重複をそのまま
1個のopaque requestとして保存し(Schwarz正準化を適用しない)、model profileを
bypassします。単発のクォート<code>`(∂_x e)</code>は素の<code>∂_x e</code>と
同義になるためエラーです。</p>
<p>解析的な式の中のバッククォート(<code>`(x - cx)</code> など、格子微分を含まないもの)は
Egison への指示で、くくった部分式を展開せずに一つの原子として扱います。生成されるプログラムには
中身の式がそのまま入ります。座標変換の写像を <code>∂/∂</code> で微分するとき、中心をずらした座標を
原子にしておくと正規化が数分から 1 分程度になります(<code>examples/transformation_optics</code>)。</p>
<h3>boundary宣言 — SBP境界閉包(幅は演算子、境界は宣言)</h3>
<pre>boundary x : sbp <span class="c">-- 物理境界: x軸の全微分がSBP閉包つきに</span>
<span class="c">-- boundary y : periodic -- 既定(宣言なし = 周期 = 従来互換)</span>
<span class="c">-- boundary z : ghost 0.0 -- fork の ghost 充填 idiom の明示化</span>
field u : scalar @ primal
param sat = τ*κ*sbpHinvX/dx <span class="c">-- 宣言が供給する逆境界ノルム(2/dx)を合成</span>
step:
local q @ dual = κ * ∂_x u <span class="c">-- D⁺: 閉包不要(全行が域内)</span>
u' = u + dt * (∂_x q <span class="c">-- D⁻: 両端1行だけSBP閉包行に置換</span>
+ satDirichlet_x(u, 0.0, sat)) <span class="c">-- 両壁のDirichletペナルティ(マクロ)</span>
u' = u + dt * (∂_x q + satNeumann_x(q, 0.0, 0.0)) <span class="c">-- 断熱壁: 境界流束の厳密置換</span>
u' = u + dt * κ * ∂^2_x u <span class="c">-- 合成2階(= 閉包つきD⁻∘D⁺)を直接書く形</span></pre>
<p>境界の扱いは個々の微分適用の属性ではなく<b>領域(軸)の属性</b>です:
<code>boundary x : sbp</code>を宣言すると、その軸に沿う<b>素の</b><code>∂_x</code>・
<code>∂^2_x</code>に加え、<b>プライム幅<code>∂'_x</code>(全半径の1階)と
profile全accuracyの1–2階</b>もそのまま境界対応になります(k≥2のSBP対は
Q=H·D線形化の厳密解として自動構成され、境界次数はk)。内部は通常の
staggered差分のまま、境界に最も近い行だけsummation-by-parts閉包行に
index guard(<code>if i == 0 then … else …</code>)で置換するため、
どのサンプルも領域外を読みません。閉包はノルム行列Hとの組で
離散部分積分 H_d D⁺ + (H_p D⁻)ᵀ = d_N e_Nᵀ − d₀ e₀ᵀ を<b>厳密に</b>満たすよう選ばれ、
formurae-postが有限Nの行列恒等式として毎回検証します(エネルギー法の安定性の根拠)。
エネルギー安定性は「モデル内の全微分が同じ境界扱いを共有する」大域的性質なので、
宣言があるからこそ<b>sbp軸に閉包なし経路が混ざったら静的エラー</b>にできます:
幅広の明示2階<code>∂'^2</code>(compactステンシルはD⁻D⁺合成と別物でSBP分解が無い)・
3階以上・collocated operand・ordered chain横断・half→integerのresampleは
compile-time errorです。旧<code>sbpd_x</code>/<code>sbpd2_x</code>綴りは退役し、移行診断が
宣言+素の∂への書き換えを案内します。
境界条件はSAT(penalty項)で、<b>sbp宣言が名前つき定数を供給します</b>:
壁しきい値<code>sbpLoX</code>/<code>sbpHiX</code>と逆境界ノルム
<code>sbpHinvX</code>(= 1/(h_p,0 dx)、最小対で2/dx;<code>∂'</code>や
profile accuracy 4を使うモデルには<code>sbpHinv4X</code> = 18/(7dx)も。
軸名は先頭大文字で連結 — underscoreはEgisonの添字に読まれるため)。
係数はこれらを合成した<code>param</code>に置き(dxがCAS側で非束縛のため)、
定型は軸ごとのpreludeマクロ<code>satDirichlet_x(u, g, coef)</code>・
<code>satNeumann_x(flux, glo, ghi)</code>で展開します。Neumannと特性SATが
要する境界値は<b>境界外挿<code>sbpx_x e</code></b>(SBP対のd₀/d_Nで
dual配置の式を壁行へ外挿、内部は0)が与え、特性SAT
(透過境界: 左壁<code>sbpHinvX*(p + sbpx_x v')</code>・
右壁<code>sbpHinvX*(p - sbpx_x v')</code>)は方程式内容なので表層で明示します。
1階はhalf→integerの向きで両端閉包、
integer→halfはk=1のみ閉包不要、2階はinteger配置限定です。実測は
<code>examples/sbp_diffusion1d</code>(2.02次収束+エネルギー単調)・
<code>sbp_wave1d</code>(pressure-release、1周期回帰)・
<code>sbp_diffusion2d</code>(軸ごとの加法で角が自動成立)・
<code>sbp_highorder4</code>(内部4次の<code>∂'</code>両方向、実測3.03次収束)・
<code>sbp_neumann</code>(断熱壁、熱量ドリフト3.4e-15の厳密保存+実測2.04次)・
<code>sbp_wave_open</code>(透過境界、エネルギー無成長+mid-flight実測1.98次)。</p>
<h3>配置と中間storage</h3>
<pre>resample(q, 0, 1) <span class="c">-- 絶対placementへ線形補間</span>
field u : scalar @ primal
step:
local q_i @ primal = [| -κ * ∂_x u, -κ * ∂_y u |]_i
u' = u - dt * divg q</pre>
<p><code>resample</code>は暗黙補間を避けて絶対placementを明示するときだけ使います。
中間fieldは型付き<code>local</code>で宣言します。上の<code>q_i @ primal</code>は成分ごとのface flux、
<code>divg q</code>はcellへ戻る保存差分です。telescopingの保存保証は周期境界、
またはfluxと整合するghost/boundary処理の下で成り立ちます。
物理境界条件はFormura側のYAML・boundary設定(ghost充填)が権威で、
有界領域で境界まで含めた保証が要る場合は上のSBP+SATを使います。</p>
<p>面の両側の値を個別に選ぶには,次の操作を使います.<code>q</code> が整数点にある場合,
小さい/大きい計算座標側のセル値を,補間せず選びます.</p>
<pre>sampleLower(q, 1, 0) <span class="c">-- x方向の面の小さい座標側</span>
sampleUpper(q, 1, 0) <span class="c">-- x方向の面の大きい座標側</span></pre>
<p>ビットは軸順の絶対配置(0が整数点,1が半整数点)です.元の配置と先の配置は
ちょうど1軸で異なる必要があります.同じ配置,複数軸の同時変更,配置のない式はエラーです.
係数を含む式全体を選んだ元の位置で評価します.共通化には <code>macro</code> を使います.
SBP境界での半整数点から整数点への操作は未対応です.</p>
<h2 id="tensor">7. Tensor、form、placement</h2>
<p><code>Collocated</code>はcell位置を保ちます。<code>Primal</code>/<code>Dual</code>では、policyとcomponent basisの
parityから各軸の半セルbitを求めます。微分は自然なtarget placementへ移り、異なるplacementを
加算すると明示errorになります。暗黙補間はしません。</p>
<h3>成分射影 — q_x と q_i</h3>
<pre>boundary x : sbp
boundary y : sbp
field q_i @ primal
step:
local w_i @ primal = [| κ * ∂_x u, κ * ∂_y u |]_i
u' = u + dt * (∂_x w_x + ∂_y w_y) <span class="c">-- w_x = wのx成分(x面に住むスカラー)</span></pre>
<p>添字の判定規則は<code>∂</code>と同じです: <b>宣言済みの軸名なら具体成分、
それ以外は記号添字</b>。<code>q_x</code>は宣言済みの添字つきfield/localのx成分を
スカラーとして取り出し(<code>T_x_y</code>はrank-2の具体成分)、placementは従来どおり
(policy, 成分basis)から導出されます — 上の<code>w_x</code>は[½, 0]に住み、
sbp軸の<code>∂_x</code>がhalf→integerの閉包つきの向きを自動選択します。対称・反対称の鏡像成分は
束縛テンソル値が符号・零対角込みで持つため、<code>ω_y_x</code>も正しく負値を読みます。
varianceは宣言と一致が必要(<code>q_i</code>宣言に対する<code>q~x</code>はerror、
上下の付け替えは計量との縮約を明示で)。混合添字<code>T_x_j</code>と
ランク不一致はcompile-time errorです。射影はRHS専用で、更新はwhole-field targetのままです。</p>
<pre>dimension 3
axes x, y, z
field E : 1-form
field B : 2-form
step:
E' = E + dt * δ B
B' = B - dt * d E'</pre>
<p>form fieldでは<code>d</code>、<code>hodge</code>、<code>δ</code>、<code>Δ_H</code>を使います。
constant geometryの<code>Δ_H</code>は<code>d (δ A) + δ (d A)</code>、宣言幾何の<code>δ</code>は
preludeマクロとして実体化localと公開演算子へ展開されます(§7)。
general variable-metric <code>Δ_H</code>は現時点でcompile-time errorです。
<code>d(d A) = 0</code>は演算子ライブラリの定理としてcompiler suiteが検査し、
離散的な<code>div B = 0</code>の保存はcheck driverが実測します。</p>
<h2 id="geometry">8. 直交geometryとcanonical Δ</h2>
<pre>axes θ, φ, z
embedding [ `(2 + cos θ) * cos φ, `(2 + cos θ) * sin φ, sin θ, z ]
u' = u + dt * Δ u</pre>
<p>座標線が直交しない座標系では、<code>metric tensor [[...], [...]]</code>で計量を成分で宣言します
(省略できる<code>metric volume EXPR</code>で体積要素を与えます)。Egisonが対称性を検査して逆計量と
sqrt(det g)を導き、<code>g~i~j</code>・<code>g_i_j</code>・<code>volume</code>が使えます。
直交性を前提とするcanonicalな<code>Δ</code>・<code>δ</code>・<code>hodge</code>はこの幾何ではエラーになるので、
流束形を明示的に書きます(例: <code>examples/excitable_torus/excitable_torus_twisted.fme</code>)。</p>
<p><code>metric scale [...]</code>ではLamé factorを直接指定し、<code>embedding [...]</code>ではEgisonが
induced metricを導出して直交性をgateします。metric、inverse、scale、volumeはGeometryNFへ入ります。</p>
<p>geometry付きのcanonical <code>Δ</code>は係数サンプリング、cell-to-face gradient、保存されるflux、
face-to-cell divergence、volume除算を必要とします。宣言幾何では<code>Δ</code>/<code>δ</code>が
preludeマクロとして実体化local+公開演算子(<code>dFluxWeights</code>/<code>dFluxScale</code>/<code>dFluxDiv</code>)へ
展開され(§7)、幾何のみの係数localはformurae-postが凍結してinit一回+恒等carryのstate配列にします。</p>
<h2 id="artifacts">9. 生成artifactと検証</h2>
<p><code>.fme</code>が編集対象です。FME exampleではreview用に次を追跡します。</p>
<ol>
<li><code>.egi</code>: formurae-pre output</li>
<li><code>.feir</code>: Egison normalization result</li>
<li><code>.fmr</code>: formurae-post output</li>
</ol>
<pre>python3 gallery/tools/embed_src.py <span class="c"># galleryへ4段sourceを再埋め込み</span>
make all <span class="c"># 全exampleのC numerical check</span>
make gallery-assets <span class="c"># 実計算frameから静止画とH.264動画を再生成(ffmpegが必要)</span></pre>
<p>FEIR codec/fingerprint、source diagnostic、effect、operator、placement、Taylor stencil、geometry-aware <code>Δ</code>/<code>δ</code>、
end-to-end pipelineをfocused testで検査します。Egison本体を変更した場合はrepresentative math samples、
mini-test全件、<code>cabal test</code>も実行します。</p>
<p>責務境界、FEIR protocol、検証方法は
<a href="../../README.md">README</a>のcompiler pipelineとrepository構成を参照してください。</p>
</main>
</body>
</html>