数値計算結果汎用ビューア「物理シミュレーションビューア(1次元版)」

文責:遠藤 理平 (2012年8月11日)

C言語などのプログラミング言語で数値計算した結果を描画するには、gnuplot など優れたフリーのソフトが多数存在します。 一方、物理量の時間発展などの物理シミュレーションの結果を連続描画(アニメーション)しようとした場合、gnuplot で gif アニメーションの作成や、OpenGL で出力した画像データから MPEG動画を作成するなどを行う必要があります。 「natural science 仮想物理実験室」では、数値計算結果を連続描画(アニメーション)できる汎用ビューア「物理シミュレーションビューア(1次元版)」を公開します。

本ビューアはウェブページ記述言語の最新規格である HTML5 と Javascript を利用して開発されているため、 コンピュータの環境に依らず、HTML5 が閲覧可能なウェブブラウザ上で実行可能です。 本稿では、簡単な使い方について記述します。

特徴

  • ・HTML5 対応ウェブブラウザ上で実行するため、インストール作業が不要
  • ・Javascript 言語で制御しているため、細やかな改変が可能

本ツールで利用している Javascript ライブラリ

以下のJavascript ライブラリを利用させていただいております。 この場にて勝手に御礼申し上げます。

  • ■グラフ作成:Flotr2
  • ■インターフェース:jQuery
  • ■フレームレート確認:stats.js

実行結果

本ビューアは、C言語などで出力された連番ファイル名を読み込んで、グラフを連続描画することでパラパラ漫画のようなアニメーションを実現することができます。実行結果を以下に示します。

本稿で取り扱う動作確認用のデモは、ポテンシャル障壁における電子パルスのシミュレーション (E=10eV, V1=0eV, V2=10eV)で、電子パルスの「時間発展」と「透過スペクトル」を描画します。 「時間発展」は「-200~500」までの701枚、「透過スペクトル」は1枚です。

ダウンロード

PhysicalSimulationResultsViewer_ver1.1.3.zip(zip形式 3.97MB)

中身には HTML ファイル「PhysicalSimulationResultsViewer_ver1.1.3.html」と動作確認用の数値計算結果のデータフォルダ「pulse3_E=10eV_V1=0eV_V2=10eV」しか入っていません。 GoogleChrome か Firefox で「PhysicalSimulationResultsViewer_ver1.1.3.html」をダブルクリックしてください。必要な Javascript はウェブ上からダウンロードされます。

GoogleChrome を利用時の注意点

ローカル環境にある外部ファイルを読み込む場合、セキュリティの関係からエラーが発生する場合があります。 もし、「PhysicalSimulationResultsViewer_ver1.1.3.html」をウェブブラウザで確認しても「ポテンシャル障壁における電子パルスのシミュレーション (E=10eV, V1=0eV, V2=10eV)」のように表示されない場合、 GoogleChrome 起動オプションを付け加えてください。

--allow-file-access-from-files

起動オプションの設定は簡単です。GoogleChromeのショートカットを右クリックし、「プロパティ」を選択します。 「リンク先」に実行ファイル(.exe)へのパスが記載さているところに、上の文字列をコピーします。

~\chrome.exe --allow-file-access-from-files

として下の「OK」ボタンを押します。ショートカットをダブルクリックすることで、起動オプションをふまえてブラウザが起動します。

「物理シミュレーションビューア(1次元版)」の使い方

本ツールは HTML5 + Javascript で作成されています。 各種設定は HTML ファイルの Javascript を編集することできます。 ソースの「<script>」と「</script>」の間が Javascript 部です。 Javascript の簡単な説明をします。

Javascript の設定

window.onload

window.onload  = function() {
	timeEvolution();
	transmittance();
	checkReady();
}

「window.onload = function() {~}」は、HTML文書の読み込みが終了した際に呼び出されるグローバル関数です。 その中にある「timeEvolution()」「transmittance()」「checkReady()」は、後に定義される関数です。 本稿のデモで用意しているのが「時間発展」と「透過スペクトル」の2つを描画するので、それぞれの関数名を「timeEvolution()」と「transmittance()」としました。 関数名は任意につけることができます。

グラフ描画用グローバル変数

グラフ描画を行うために必要なプロパティやメソッドを保存するためのグローバル変数を宣言します。

var gp1, gp2;

2つあるのは「時間発展」と「透過スペクトル」用です。 この変数名も任意につけることができます。

描画の準備1:「timeEvolution()」の定義

「timeEvolution()」の定義を見てみます。 「PhysicalSimulationResultsViewer_ver1.1.3.html」ソースの Javascript を順番に説明します。

function timeEvolution(){
	~
}

この関数の中で、描画の際に必要なパラメータの設定をすべて行います。

  var fn_start  = -200;     //連番はじめの番号
  var fn_end    =  500;     //連番終わりの番号

ここでは描画するために必要な数値計算結果のデータファイルの読み込みます。 ダウンロードファイルに同包されているフォルダ「pulse3_E=10eV_V1=0eV_V2=10eV」の中身を見てください。 「s○.data」と「○」に数字が連番で-200から500まで701枚用意してあります。 これが各時間ステップごとのデータとなります。 「fn_start」と「fn_start」がそれぞれ連番のはじめの番号と終わりの番号に対応します。

  var fpsViewer = true;     //フレームレート確認ツールの利用
  var files     = [];

コメントにも記載していますが、「fpsViewer」を「true」にするとウェブブラウザのフレームレートグラフィカルに描画できるライブラリ「Stats.js」を利用します。 フレームレートを確認したい場合は「true」にしてください。 「files」は連番数値データを保存するための配列型変数です。 for文で連番ファイル名を指定し配列に代入します。

  for(var i=fn_start; i<=fn_end; i++){
    files.push("pulse3_E=10eV_V1=0eV_V2=10eV/s" + i + ".data");
  }

「pulse3_E=10eV_V1=0eV_V2=10eV」がフォルダ名で、「/」以下がファイル名となります。 次に数値データの取り扱いを指定します。 本稿で用意したデータ形式は、「4列スペース区切り」です。

-2500 -1.269e-008 -1.205e-010 1.269e-008
-2490 3.958e-009 8.43e-010 4.047e-009
-2480 1.474e-008 -2.239e-010 1.474e-008
-2470 -7.091e-009 4.663e-010 7.106e-009
・・・

1列目から「x座標」「波動関数の実数部」「波動関数の虚数部」「波動関数の絶対値」となります。 次に、どの列を利用するかの指定と凡例を記述します。

var horizontalAxis = 0;                    //グラフの横軸に利用する列( 0:1列目)
var legends =[                             //凡例
    {row:1, label:"波動関数の実部"   },
    {row:2, label:"波動関数の虚部"   },
    {row:3, label:"波動関数の絶対値" }
  ];

「horizontalAxis」はグラフを描画する際の横軸とするデータ列を指定します。 「0」は1列目となる点に注意が必要です。 「legends」には描画する列とそれに対する凡例を記述した連想配列で配列化してあります。 具体的には「{row:1, label:"波動関数の実部"}」は、2列目のデータを描画して「波動関数の実部」とグラフ上に凡例を記述します。 つまり、列の数がたくさんあったとしてもここで記述した「{row:○, label:"〇〇"}」だけが描画されます。

  var IDs = {                                //HTML文書に設置した id 
    frameID            : "frame1",            //グラフ描画用 canvas を設置する div 
    startButtonID      : "startButton1",      //スタートボタン
    resetButtonID      : "resetButton1",      //リセットボタン
    xAxisSelectorID    : "xAxisSelector1",    //横軸スケールバー
    yAxisSelectorID    : "yAxisSelector1",    //縦軸スケールバー
    intervalSelectorID : "intervalSelector1", //読込時間間隔セレクター
    thinSelectorID     : "thinSelector1",     //描画ファイル間引数セレクター
    fnSelectorID       : "timeSelector1",     //描画ファイル番号セレクター
    xAxis_maxID        : "xAxis_max1",        //横軸スケールバーの最大値書き出し
    xAxis_minID        : "xAxis_min1",        //横軸スケールバーの最小値書き出し
    yAxis_maxID        : "yAxis_max1",        //縦軸スケールバーの最大値書き出し
    yAxis_minID        : "yAxis_min1",        //縦軸スケールバーの最小値書き出し
    thinID             : "thin1",             //データ間引数書き出し
    intervalID         : "interval1",         //読込時間間隔書き出し
    fn_minID           : "time_min1",         //描画ファイル番号の最小値書き出し
    fn_maxID           : "time_max1",         //描画ファイル番号の最大値書き出し
    fnID               : "time1",             //現在の描画ファイル番号
    rowID              : "row1_",              //描画列選択用 checkbox
    progressID         : "progress1"           //ダウンロード進捗バー
  }

これは、HTML文書に設置した id 名を本ツールに知らせるための連想配列です。 例えば、「frameID: "frame1"」は、グラフを描画する領域(div)の ID名を「frame1」としています。 つまり、HTML文書内の「<div id="frame1"> </div>」にグラフ描画することを表します。 ちなみに、描画サイズはHTML文書の見せ方を指定するスタイルシート「drowAnimation_ver1.0.css」ファイル内の「#frame1」で指定しています。 もし、

  //xAxis_maxID   : "xAxis_max1",        //横軸スケールバーの最大値書き出し

のようにコメントアウトした場合、横軸スケールバーの最大値は書きだされません。 また、ID名は任意です。

最後にこれまで設定したパラメータをひとまとめにして、本ツールへセットします。

  var parameters = {
    files          : files,
    fn_start       : fn_start,
    fn_end         : fn_end,
    fpsViewer      : fpsViewer,
    horizontalAxis : horizontalAxis,
    legends        : legends,
    IDs            : IDs,
    y2axis         : {max :20, min : -20, title: "[eV]"},
    yaxis          : {title: "Ψ"},
    xaxis          : {title: "10^{-11} [m]"}
  };
  gp1 = new DrowGraph();
  gp1.set(parameters);

上記の下2行が実際にグラフ描画クラスのインスタンスを宣言してパラメータをセットしているところです。 さらに、本稿ではを縦の2軸目(右軸)を利用してポテンシャルエネルギーも描画しています。

  var d1 = {data:[[-2500,0], [0,0], [0,10], [500,10], [500,0.0], [2500,0.0]], 
            label:"ポテンシャルエネルギー",
            yaxis: 2};
  gp1.superimpose(d1);

上記の「data:[~~]」で指定した座標を直線で結びます。 その際の凡例を「label:"〇〇"」で指定することができます。 「yaxis: 2」は、縦の2軸目(右軸)を利用するという意味で、 もし縦の1軸目を利用する場合には「1」とします。 最後の「gp1.superimpose(d1);」で、具体的にグラフにセットします。

各種設定が終わった後に、

  gp1.start();

を呼び出すことで、実際のファイル読み込みから描画までの準備を行います。

描画の準備2:「transmittance()」の定義

「transmittance()」は透過スペクトルを描画用に用意した関数です。内容は「timeEvolution()」と同じです。 透過スペクトルは時間発展しない1枚データなので、アニメーションする必要がありません。 必要のないパラメータをコメントアウトしてます。

  function transmittance(){
    var fn_start  = 0;
    var fn_end    = 0;
    var fpsViewer = false;    
    var files     = [];
    files.push("pulse3_E=10eV_V1=0eV_V2=10eV/RT.data");
    var horizontalAxis = 0;                    //グラフの横軸に利用する列( 0:1列目)
    var legends =[                             //凡例
        {row:1, label:"反射率"},
        {row:2, label:"透過率"},
        {row:3, label:"エネルギー分布"}
      ];
    var IDs = {                                //HTML文書に設置した id 
      frameID            : "frame2",            //グラフ描画用 canvas を設置する div 
      //startButtonID      : "startButton",      //スタートボタン
      //resetButtonID      : "resetButton",      //リセットボタン
      xAxisSelectorID    : "xAxisSelector2",    //横軸スケールバー
      yAxisSelectorID    : "yAxisSelector2",    //縦軸スケールバー
      //intervalSelectorID : "intervalSelector", //読込時間間隔セレクター
      //thinSelectorID     : "thinSelector",     //描画ファイル間引数セレクター
      //fnSelectorID       : "timeSelector",     //描画ファイル番号セレクター
      xAxis_maxID        : "xAxis_max2",        //横軸スケールバーの最大値書き出し
      xAxis_minID        : "xAxis_min2",        //横軸スケールバーの最小値書き出し
      yAxis_maxID        : "yAxis_max2",        //縦軸スケールバーの最大値書き出し
      yAxis_minID        : "yAxis_min2",        //縦軸スケールバーの最小値書き出し
      //thinID             : "thin",             //データ間引数書き出し
      //intervalID         : "interval",         //読込時間間隔書き出し
      //fn_minID           : "time_min",         //描画ファイル番号の最小値書き出し
      //fn_maxID           : "time_max",         //描画ファイル番号の最大値書き出し
      //fnID               : "time",             //現在の描画ファイル番号
      rowID              : "row2_"               //描画列選択用 checkbox
    }
    var parameters = {
      files          : files,
      fn_start       : fn_start,
      fn_end         : fn_end,
      fpsViewer      : fpsViewer,
      horizontalAxis : horizontalAxis,
      legends        : legends,
      IDs            : IDs,
      y2axis         : {max :20, min : -20, title: "[eV]"},
      yaxis          : {min : -0.01},
      xaxis          : {title: "[eV]"}
    };
    gp2 = new DrowGraph();
    gp2.set(parameters);
    //var d1 = {data:[[0,0], [10,0], [10,0.5], [20,0.5]], label:"エネルギー分布"};  
    //gp.superimpose(d1);
    gp2.start();
  }

描画の準備3:「checkReady()」の定義

jQueryを利用したインターフェースを利用する際、グラフ描画の準備のすべてが完了した後にイベント設定する必要があるため、 準備が完了したかどうかを知る必要があります。 データファイルを読み込むには、データ量に応じて時間が必要となりますが、準備が完了するとプロパティ「gp1.ready」と「gp2.ready」が「true」となります。

  function checkReady(){
    if(gp2.ready && gp1.ready){
      console.log("ok");
      $('#tabs').tabs({ selected: 0, fx: { opacity: 'toggle',duration: 100 } });
      addEv($id("tabList").getElementsByTagName("a").item(0), "click", stopDrow); //jQueryタブ
      addEv($id("tabList").getElementsByTagName("a").item(1), "click", stopDrow); //jQueryタブ
    }else{
      setTimeout(checkReady, 10);
    }
    function stopDrow(){
      gp1.stop();
      gp2.stop();
    }
  }

この「checkReady()」はグローバル関数である「setTimeout」関数を利用して準備が完了するまで呼び出され続けます。

画面の見方

本ビューアの見え方は次のとおりです。

  • 1. 描画切り替えタブ
  • 2,3,4 は複数連番ファイルによるアニメーションを作成した際の「2. はじめの番号」「3.終わりの番号」「4.現在の番号」
  • 5,6 はそれぞれ縦軸の最大値と最小値
  • 7,8 はそれぞれ横軸の最大値と最小値
  • 9,10 アニメーションの「スタート」ボタンと「ストップボタン」
  • 11. ウェブブラウザによる連番ファイル読み込み時間間隔
  • 12. 連番ファイル読み込み時の間引き数
  • 13. 描画するデータ選択
  • 14. 「stats.js」を利用したウェブブラウザの実際のフレームレート(※2)

※1 各パラメータはスライドバーを移動することで変更することができます。
※2 「stats.js」は、Javascript ソース内で「fpsViewer = true」とすることで利用可能となります。

コメントする

コメントはユーザ登録なしに、どなたでも行うことができます。
入力頂いたコメントは、管理者の承認後公開されます。

※必須(公開)

※必須(非公開)


更新情報