NECR2D2 — VAX Fortranから1981年のNEC2を蘇らせる
1997年になってもまだ、防衛関連ではPDP-11が現役で使われており、私自身VMSを使っていました。1980年代後半には多くの大学がまだVAXミニコンピュータを使っており、90年代初頭まではSunのサーバも健在でした——Linuxが実用段階に達するまでは、Sunがこの市場を本当に牛耳っていました。私は幸運にもその時代の終わりを目撃することができました。毎週金曜にVMS上でテープバックアップを取り、LinuxやWindowsサーバが台頭する前にSPARCstationが導入されていくのを見ていたのです。この記事では、オリジナルのFortran 66/77で書かれたNEC2エンジンを取得し、修正を加え、現代の64ビットツールチェーンでコンパイルして動かします。今でも十分に実力のあるシミュレータですが、そのルーツはとても長い年月を遡ることになります。
昔ながらのやり方でNEC2を入手する
今日はNEC2を、インターネット——ウェブではなく、インターネットそのもの——から取得することで復活させます。ウェブが登場する前は、印刷されたFTPやTelnetのアドレス一覧を見ながらナビゲートしたもので、たいていの国には同じように閲覧できる学術ネットワークがありました。NEC2のソースは今でもそのうちの1つ、今なお稼働しているftp.funet.fi(フィンランド大学ネットワーク)に置かれています。
cd pub、cd ham、cd antenna、cd NECとたどっていくと、100個以上のアンテナモデルとアーカイブ済みのNECユーティリティが並ぶディレクトリの中に、目当てのnec2_src.tar.Zが見つかります。このコピーにはまだVAXへの参照が焼き込まれているので古い系統のものだとわかります。必ずしも最初のリリースそのものではないでしょうが、かなり近いものであり、そもそもNEC1自体、大学や国立研究所に届くよりずっと前に、民間で書かれた政府契約の成果物として始まっています(詳細は後述)。バイナリモードに切り替えてファイルをgetすると、2つのファイルに展開されます:
nec2d.f 249,243 bytes -- the entire Fortran 66/77 source
NEC2DPAR.INC 43 bytes -- one line: array size limits
この.INCファイルは、その時代を思い出させてくれる良い例です。中身はPARAMETER (MAXSEG=1000, MAXMAT=1000)という1行だけ。Fortran 66/77には動的に確保できる配列がなかったため、セグメント数や行列サイズの上限はコンパイル時に実行ファイルへ焼き込む必要がありました——数字を大きくして再コンパイルすれば、より大きな問題を扱えるようになる、という具合です。4NEC2のようなツールが、サイズの異なる複数のビルド済みバイナリを用意しているのは、まさにこのためです。
ツールチェーン:gfortranと独学用の教本
FortranはWindows向けビルドも含めGCCツールセットの一部なので、コンパイラを入手すること自体は難しくありません。難しいのは、1970年代の8000行を超えるFortranコードを、途中で挫折せずに読み通すことです。幸い、Archive.orgにはArthur S. Radford著Computer Programming in FORTRANが無料で貸し出されており、Fortran 66と77の両方をカバーする「独学用」の入門書として、まさにこのソースコードにぴったりの年代のものです。
壁にぶつかる:1970年代のFortran 対 2020年代のコンパイラ
最初の試み——gfortran nec2d.f -fno-automatic -o nec2d.exe——では数百件の警告が出ますが、そのほとんどは2種類のどちらかです。ホレリス定数(テキストを数値変数に詰め込む古い方式、例えばDATA HPOL/6HLINEAR,5HRIGHT,4HLEFT/)と、算術IF文やEND DO以外のループ終端など、Fortran 2018で廃止された機能です。警告を無効にしてエラーだけを見ると、はるかに短く、はるかに興味深いリストに絞り込まれます:
Error: READONLY at (1) is a DEC extension, enable with '-fdec'
Error: Invalid character in name at (1) -- TYPE 1,MSG(...) (VAX's TYPE, not standard Fortran)
Error: BOZ constant at (1) uses nonstandard postfix syntax -- '0407'X, a VAX hex literal
Error: 'time' argument of 'second' intrinsic at (1) must be of kind 4
Error: Type mismatch in argument 't' at (1); passed REAL(4) to REAL(8)
さらに20件あまりのエラーは、最後のカテゴリが繰り返し出ているだけだとわかります。素の0.リテラル(単精度)を、REAL(8)(倍精度)を期待するルーチンに渡している、というものです。古いVAXコンパイラの暗黙の型変換ではまったく問題ありませんでしたが、現代のコンパイラではそうはいきません。このパターンに気づいてしまえば、エラーリスト全体は怖くなくなります。予約語1つ(SECOND)、VAX/DEC固有の構文がいくつか、そして同じ単精度→倍精度のミスマッチが大量に、という内訳です。十分に直せる範囲です。
パッチ(このページ下部からダウンロード可能、本文には掲載せず)
この修正は標準的なdiffパッチで、1行の変更、1行の追加、1つの関数の中身の置き換えが、8000行のファイル全体にわたって十数回繰り返されているだけです。まだいくつか手を加えたい点が残っているため、ここに全文を掲載する代わりに、このページの下部にプレーンテキストのダウンロードとして用意しています。概要としては、次の4つのことを行っています。VAX専用のREADONLYファイルオープン拡張を削除する、倍精度の引数に渡される素の0.リテラルをすべて0.0D0に格上げする、VAXのTYPE文を標準のWRITE(*,...)に置き換える、そして%LOC()と自作の16進オペコードを使ってVMSのプロセス情報ブロックを直接覗いていたVAX固有のSECOND(CPU時間計測)ルーチンを、単に0を返すだけの移植性のあるスタブに置き換える、というものです。NEC2は正しい結果を出すのに実時間の計測を必要とはしておらず、実行にかかった時間を表示するためだけに使っていました。
ついに成功
パッチを適用し、再コンパイルします:
gfortran necR2D2.f -fno-automatic -w -o necR2D2.exe
エラーなし。1981年のソースコードから、40年以上経った今、Windows上に真新しい64ビットのnecR2D2.exeができあがりました。実行すると、NEC2がいつも表示していたのと同じプロンプトにそのまま入ります:
ENTER NAME OF INPUT FILE >
14MHz、20メートル半波長ダイポール用に、簡単な入力デッキを用意しました——「デッキ」や「カード」という用語自体、パンチカード時代そのままの名残であることに注目してください:
CE 14MHz HALF-WAVE DIPOLE ANTENNA
GW 1 21 0. 0. -5.35 0. 0. 5.35 0.001
GE
FR 0 1 0 0 14.0
EX 0 1 11 0 1.
RP 0 181 1 1000 0. 0. 1. 0.
RP 0 1 361 1000 90. 0. 0. 1.
EN
これを入力し、出力ファイル名を指定すると、NEC2はプレーンテキストの結果ファイルを書き出します——NECの入出力にバイナリは一切登場しません。生の数値を読むのではなく、パターンをグラフ表示するための小さなJavaビューアを自作しました:
NEC 対 MININEC:同じ問題への、語り口の異なる2つの答え
どちらのコードも根底にある同じ問題——細線モーメント法——を解いており、どちらも同じスポンサーの世界から生まれています(詳細は後述)。両者を実際に分けているのは、それぞれが動作対象のマシンについてどこまで前提を置けたか、という点に尽きます。
カーネル。 MININECのカーネル処理についてはMININEC v2のページで詳しく書きました。細線カーネルの近傍界特異点を、楕円積分に対する固定の有理式+対数近似を使って解析的に差し引くことで、各行列要素の計算コストを数十回の浮動小数点演算に抑えており、浮動小数点演算ハードウェアを持たないマイコン上のBASICでも十分安価です。一方NECは、現場のマイコンではなくCDC 6600やVAX上で動くため、そのような近道を必要としません。細線カーネルをはるかに厳密に評価し、さらにワイヤと面の接合部や大きな導体板を含む構造に対しては、数値グリーン関数と、面パッチに対する磁界積分方程式を追加しています。どちらもMININECには対応するものが一切ありません。MININECはワイヤのみですが、NECは同じモデルの中でワイヤと面を混在させることができます。
大地の扱い。 このサイトの他のページで扱っているバリアントでのMININECの大地の扱いは、自由空間か完全導体の鏡像面のどちらかで、形状の鏡像を使うだけの安価な方法であり、損失のある大地の物理は一切扱いません。NECは実際の損失のある大地に対して、誘電率、導電率、放射状の接地スクリーンを含む、完全なSommerfeld/Norton法を実装しています。波が実際の土壌に一部反射し一部結合するという、本物の物理現象です。これはかなり手強い数値計算の問題であり(Sommerfeld積分には閉形式が存在しません)、まさに、MININECが数年後にターゲットとしたマシンの手には到底負えない類の計算でした。
平たく言えば、NECはより精度が高くより汎用的なツールであり、その分より大きなコンピュータを要求することでそれを実現しています。MININECは「予算がミニコンピュータではなくマイコンだったら、これのどれだけを残せるか」と問われたときに出てくるものです——そしてこれこそ、NEC-2の登場から数年後にNOSCが自らに課した課題そのものでした。
簡潔な歴史:ロケット拳銃メーカーから国立研究所へ
NECの系譜は、調べてみるまで思いもよらなかった場所から始まります。MBAssociatesという、カリフォルニアの小さな防衛関連企業で、おそらくはまったく別の発明品——1960年代のロケット推進式拳銃「Gyrojet」——の方でよく知られている会社です。1970年代初頭、米空軍のSpace and Missile Systems Centerとの契約のもと、MBAssociatesはBRACTを書きました。これはCDC 6600上で動く、自由空間中の均一なワイヤ構造のための純粋なモーメント法コードで、大地の影響のモデリングは一切なく、衛星や航空機には十分でしたが、地上に置かれるものには使えませんでした。
2件目の契約は、今度はNaval Research LaboratoryとUSAF Rome Air Development Centerからのもので、BRACTはAMP(Antenna Modeling Program)へと発展し、接地面の影響が追加され、パンチカードからディスクベースのテキスト入力へと移行しました。続いてAMP2が登場し、反射鏡のような広がりを持つ閉曲面をモデル化できるようになりました。
そこから作業はローレンス・リバモア国立研究所へと移り、Naval Ocean Systems CenterとAir Force Weapons Laboratoryの共同資金提供のもと、Gerald BurkeとAndrew PoggioがAMP2をNEC-1へと発展させ、電流計算と太いワイヤの扱いを改善しました。1981年にはNEC-2が続き、数値グリーン関数と改良された損失大地モデリングが加わりました。そして今日に至るまで、これがライセンスなしでパブリックドメインとして入手できる最も新しいバージョンのNECであり続けています——まさに、この記事全体で復活させてきたバージョンです。
NEC-3では、地中や地表近くに埋設されたワイヤに対するSommerfeldモデリングが追加され、NEC-4では小型アンテナのモデリングと電流源が改善されましたが、ライセンス契約制へと移行し、ローレンス・リバモア研究所とカリフォルニア大学の所有物のままとなっています。そして混合ポテンシャル積分方程式の定式化に基づくNEC-5は、2021年のGerald Burke氏の逝去の少し前に登場しましたが、現在活発に保守されてはいません。歴史的に、NEC-3とNEC-4は「軍事重要技術」の輸出規制区分も課されており、NEC自身の保守担当者たちも、いずれ解除されることを望んでいると折に触れて述べていました。
まとめ
というわけで、ロケット拳銃メーカーの空軍契約が、海軍とリバモア研究所を経て、フィンランドのFTPサーバー上のパブリックドメインFortranファイルとして今も残り、2026年になっても、十数行のパッチだけで64ビットのWindowsマシン上できれいにコンパイルできる、というのがこの物語です。NECとMININECは、当時のハードウェアがどこまで許容できるかについてまったく異なる哲学を持ちながら、同じ方程式を解いています——そして40年経った今も、両方とも、書いた本人たちにとってはSFのように思えたであろうマシンの上で、今なお動き続けています。