仮想世界の温度(分子の運動エネルギー)を測定する

物質の温度

物質の温度は、物質を構成する分子の運動の激しさを表しています。
具体的には、理想気体において

  \displaystyle \langle \varepsilon_{\rm trans} \rangle = \frac{3}{2} k_{\rm B} T  

というように、分子の運動エネルギー(速度ではない)の平均値が絶対温度と比例します。

よって、シミュレーションセル内の分子の運動エネルギーの平均値を算出すれば、セル内の温度を決められることになります。

コンピュータ上の分子の速さ

ここで、前回までに作った分子の運動プログラムに戻りましょう。
(どこまでやったか忘れた!という人はこのプログラムを使ってください。
できれば自作のプログラムを使ってください)

各分子のコンピュータ上での速さについて考えます。
これは簡単で

  v = \sqrt{v_x^2+v_y^2}  

とすれば計算できます。

従って、フォントの設定をしたうえで
Particleクラス内のdisplay()に

  void display(){ //粒子の表示
    if(visible > 0){
      fill(R, G, B, visible);
      ellipse( x, y, r, r);
      String speed;
      speed = nf(sqrt(vx*vx+vy*vy), 1, 3);
      text(speed, x+r/2, y-r/2);
    }
  }

のように処理を加えれば、各分子の速さが表示されることとなります。

フォントの設定

PFont font;

font = loadFont("AngsanaUPC-Bold-48.vlw"); //フォントファイル名は上で作ったものを指定
textFont(font); //フォントの指定

第1週目でやりました。PFontの定義をグローバル変数に、下の2行をsetup()に加えてください。

クラスの外部(例えばメインルーチンdraw())から速度を知りたい場合もあるでしょう。

外部から粒子の速度を知るために、Particleクラスに次のメソッドを加えます。

  float speed(){
    return(sqrt(vx*vx+vy*vy));
  }

speedの前にある float は、戻り値の型を指定しており、
float型のデータを返しますよー、ということを示しています。

メソッド内のreturn文が戻り値を実際に戻している部分です。

今まで言っていませんでしたが、setup や draw の前につけていた
void は、「戻り値はありません」ということを示す命令でした。

なお、return文が実行されると、その関数の処理は停止します。
(return文以降は書いてあっても無視される)

平均値の算出と表示

さらに、全粒子の平均値を算出、表示することを考えましょう。

メインループ(draw)に次のような処理を加えます。

void draw(){
  background(0);
  int num = 0;
  float speed_sum = 0;
  float speed_ave = 0;
  for(int i=0; i<particle_number; i++){
    particle[i].display();
    particle[i].move();
    particle[i].reflect();
    particle[i].collide();
    if(particle[i].visible>0){
      speed_sum += particle[i].speed();
      num++;
    }
  }
  if(num!=0){speed_ave = speed_sum/num;}
  text("average = " + nf(speed_ave, 1, 3), 30, 30);
}

numは表示されている分子の個数、(3行目)
speed_sumは速度の総和、(4行目)、
speed_aveは速度の平均値です。(5行目)

forループで分子をすべて表示させていくとき、(6行目)
paritcle[i].visibleが0以上の分子について、(11行目、visibleが0の分子は「まだ生成されていない」分子なので処理を行わない)
speed_sumに、先ほど作成したpartcle[i].speed()を利用し、各分子の速さを加算していきます。(12行目)
numに1を加えます。(13行目)

ループ終了後、speed_sum(全分子の速さの総和)をnumで割り、speed_ave(速さの平均値)に代入します(15行目)。

numが0の場合、0で割るとspeed_aveが無限大になってしまうので、0の時は処理を省いています。

その後、平均値を画面に表示しています。(16行目)

+=は代入文の一種で、「左辺の変数の今までの値に右辺を加える」演算子です。
/=は「左辺の変数の今までの値を右辺で割る」演算子です。
他、*=と-=があります。