AkaiKKRで最急降下法

擬ポテンシャル法を用いた第一原理計算パッケージは、多くの場合、結晶構造の最適化機能を持っています。しかしAkaiKKRにはそのような機能はありません。そこで、最急降下法を用いて全エネルギーが最小となる結晶構造を探してみました。
対象として選んだのは六方最密充填構造(hcp)のコバルトです。

steepest.png
Fig.1: 全エネルギーのカラーマップと最急降下法探索による全エネルギー最小化



結晶構造の最適化


多くの第一原理計算パッケージには、結晶構造の最適化機能があります。これは多くの場合、原子にかかる力を計算して、その方向に原子を動かすことによって実現されています。しかしながらAkaiKKR(machikaneyama)では原子にかかる力の計算が出来ません。AkaiKKRでも、全エネルギーが最小になるようにすることで結晶構造の最適化が出来るはずですが、手動ですべてのパラメータの探索を行うのは大変です。そこで最急降下法を使って全エネルギーが最小になる構造を探して見ます。
Scilabで最急降下法 その1Scilabで最急降下法 その2では、簡単な関数f(x,y)に対して、最小値を探すことで最急降下法のアルゴリズムを確認しました。今回は f(x,y)の代わりに第一原理計算を行います。今回はテスト計算として六方最密充填構造(hcp)のコバルトの計算をします。具体的には以下の3つのステップを行います。
  1. マフィンティン半径の決定
  2. エネルギーマップの作成
  3. 最急降下法計算


マフィンティン半径の決定


AkaiKKRで全エネルギーを比較するときは、色々な計算条件が変化しないようにする必要があります。特にマフィンティン半径の設定には注意が必要です。AkaiKKRの入力ファイルでは、マフィンティン半径は格子定数 a で規格化されます。私の理解では「AkaiKKRでマフィンティン半径を固定する」というのは「原子の位置や計算セルのサイズを変更したときに、計算セルの体積に対する各マフィンティン球の体積の比が変化しないようにする」ということです。(これは他の計算手法、例えばAPW法などとは違うことに注意が必要です。)この条件を満たす範囲でマフィンティン半径を最大になるようにするのが最良であると理解しています。(AkaiKKRでBain機構 その1その2も参照。)

そこでまず、全エネルギー最小を探索する格子定数の範囲を決めます。次に、その範囲でrmt=1としたときの実際のマフィンティン球の体積比が一番小さくなってしまう条件を探します。この条件でのマフィンティン半径を全ての計算に用いれば、マフィンティン球が重なることなく、かつ、マフィンティン半径を固定することが出来ます。
決められたマフィンティン半径は、格子体積の1/3乗で規格化しておくのが後々の事を考えると便利なはずです。具体的には下記のようなシェルスクリプトを作成し、計算しました。1.60 ≦ c/a ≦ 1.70 の範囲では rMT/V1/3 = 0.439518 ぐらいのようです。
このスクリプトを走らせる際には、第一原理計算を収束させる必要はないので bzqlty=0maxitr=0としておきます。

#!/bin/csh -f
#setenv GFORTRAN_UNBUFFERED_ALL y

## *** パラメーター範囲 ***
set COA_LIST=( 1.60 1.61 1.62 1.63 1.64 1.65 1.66 1.67 1.68 1.69 1.70 )
set OMEGA_LIST=( 160 158 156 154 152 150 148 146 144 142 140 )

# set COA_LIST=( 1.63 )
# set OMEGA_LIST=( 150 )

## *** マフィンティン半径の計算 ***
set OMEGA=${OMEGA_LIST[1]}
set COA0=`echo $COA_LIST[1]`
set A0=`echo "e((1/3)*l(2*${OMEGA}/(sqrt(3)*${COA0})))" | bc -l`
if (`echo "${COA0} > 2*sqrt(2)/sqrt(3)" | bc -l` == 1) then
set RMTB0=`echo "${A0}/2" | bc -l`
else
set RMTB0=`echo "${A0}*sqrt(1/3+(${COA0}^2)/4)/2" | bc -l`
endif
set COA1=`echo $COA_LIST[$#COA_LIST]`
set A1=`echo "e((1/3)*l(2*${OMEGA}/(sqrt(3)*${COA1})))" | bc -l`
if (`echo "${COA1} > 2*sqrt(2)/sqrt(3)" | bc -l` == 1) then
set RMTB1=`echo "${A1}/2" | bc -l`
else
set RMTB1=`echo "${A1}*sqrt(1/3+(${COA1}^2)/4)/2" | bc -l`
endif
if (`echo "${RMTB0} < ${RMTB1}" | bc -l` == 1) then
set RMTB=`echo $RMTB0`
else
set RMTB=`echo $RMTB1`
endif
set RMTOMEGA=`echo "${RMTB}/e((1/3)*l(${OMEGA}))" | bc -l | sed -e 's/^\./0./g'`
echo ${RMTOMEGA}


なおhcp構造の場合はAkaiKKRでコバルトのc/a その2の方法でマフィンティン半径を決めることが出来るのですが、今回は将来的により複雑な構造をやることも考えてこのようにしました。

エネルギーマップの作成


必要ないはずの手順ですが、今回は最急降下法のテストでもあるので、考える体積・軸比の範囲の全ての全エネルギーを計算しておきます。この結果がFig.1のカラーコンターです。

Cシェルスクリプトには関数を実装することが出来ませんが、下請けのシェルスクリプトに変数を渡すことによって、それっぽい事は出来ます。
今回は という下請けのスクリプトを作成しました。これは、体積・軸比・マフィンティン半径の3つを引数として受け取り、第一原理計算を行って全エネルギーを返り値にします。

#!/bin/csh -f
##setenv GFORTRAN_UNBUFFERED_ALL y

## *** プロジェクト名 ***
set PROJECT="hcpCo"

## *** 実行ファイル ***
set EXEC="~/kkr/cpa2002v009c/specx"

## *** 標準入力から値を読み取る ***
## 格子体積
set OMEGA=$1
## c/a
set COA=$2
## RMT
set RMTOMEGA=$3

## ファイル名
set INFILE="in/${PROJECT}_go_${OMEGA}_${COA}.in"
set OUTFILE="out/${PROJECT}_go_${OMEGA}_${COA}.out"
set POTFILE="data/${PROJECT}_${OMEGA}_${COA}"
set POTBACK="data/${PROJECT}_${OMEGA}"

## 格子定数 a の計算
set ABOHR=`echo "scale=7; e((1/3)*l(2*${OMEGA}/(sqrt(3)*${COA})))" | bc -l | sed -e 's/^\./0./g'`
## マフィンティン半径の計算
set RMTA=`echo "scale=7; ${RMTOMEGA}*e((1/3)*l(${OMEGA}))/${ABOHR}" | bc -l | sed -e 's/^\./0./g'`

## テンプレートから入力ファイルを作成
sed 's/'OMEGA'/'${OMEGA}'/g' template/${PROJECT}_go_Template.in | sed 's/'ABOHR'/'${ABOHR}'/g' | sed 's/'COA'/'${COA}'/g' | sed 's/'RMTA'/'${RMTA}'/g' > ${INFILE}

## ポテンシャルファイルのコピー
if ( ! -e ${POTFILE} ) then
if ( -e ${POTBACK} ) then
cp ${POTBACK} ${POTFILE}
endif
endif

## 計算回数の初期化
set num=0
## 最大計算回数
set nummax=20
## 第一原理計算
${EXEC} < ${INFILE} > ${OUTFILE}
while ( ( ! { grep -q "err= -6." ${OUTFILE} } ) && ( $num < $nummax ) )
${EXEC} < ${INFILE} > ${OUTFILE}
@ num++
end

## ポテンシャルのバックアップ
cp ${POTFILE} ${POTBACK}

set ENE=`grep "total energy" ${OUTFILE} | sed -e s/total//g -e s/energy=//g`
echo ${ENE}


enemap.sh は下請けスクリプト dogo.sh を利用して 1.60 ≦ c/a ≦ 1.70, 140 ≦ V ≦ 160 の範囲で全エネルギーのマップを作ります。dogo.sh は最急降下法のシェルスクリプトでも利用します。

最急降下法


エネルギーのマップから最安定な格子定数が V = 150 Bohr3, c/a = 163 付近にあることが予想できます。とりあえず初期値を V = 156 Bohr3, c/a = 1.68 として計算してみます。その結果がFig.1上に白で示された経路です。最急降下法では、その関数の値の微分の方向に向かって次の入力パラメータを探します。今回の計算では、4回程度で格子定数の最適化が出来ている事が確認できます。

最急降下法のCシェルスクリプト steepest.sh は以下の通りです。

#!/bin/csh -f
#setenv GFORTRAN_UNBUFFERED_ALL y

## *** マフィンティン半径 ***
set RMTOMEGA=0.43951815598150528923

## *** 係数 ***
set KEISUU_OMEGA="10000.0"
set KEISUU_COA="0.5"

## *** 初期値 ***
set OMEGA=$1
set COA=$2

## *** 微分のステップ ***
set dOMEGA="1.0"
set dCOA="0.01"
set OMEGA_PLUS=`echo "${OMEGA}+${dOMEGA}" | bc -l`
set OMEGA_MINUS=`echo "${OMEGA}-${dOMEGA}" | bc -l`
set COA_PLUS=`echo "${COA}+${dCOA}" | bc -l`
set COA_MINUS=`echo "${COA}-${dCOA}" | bc -l`

## *** 第一原理計算 ***
set ENE=`./dogo.sh ${OMEGA} ${COA} ${RMTOMEGA}`
echo "Center energy:" ${ENE} "(Ry)"
set ENE_OMEGA_PLUS=`./dogo.sh ${OMEGA_PLUS} ${COA} ${RMTOMEGA}`
echo "Omega plus: " ${ENE_OMEGA_PLUS} "(Ry)"
set ENE_OMEGA_MINUS=`./dogo.sh ${OMEGA_MINUS} ${COA} ${RMTOMEGA}`
echo "Omega minus: " ${ENE_OMEGA_MINUS} "(Ry)"
set ENE_COA_PLUS=`./dogo.sh ${OMEGA} ${COA_PLUS} ${RMTOMEGA}`
echo "c/a plus: " ${ENE_COA_PLUS} "(Ry)"
set ENE_COA_MINUS=`./dogo.sh ${OMEGA} ${COA_MINUS} ${RMTOMEGA}`
echo "c/a minus: " ${ENE_COA_MINUS} "(Ry)"

## *** 数値微分(中心差分) ***
set dENEdOMEGA=`echo "(${ENE_OMEGA_PLUS}+(-1*${ENE_OMEGA_MINUS}))/(2*${dOMEGA})" | bc -l`
echo ${dENEdOMEGA}
set dENEdCOA=`echo "(${ENE_COA_PLUS}+(-1*${ENE_COA_MINUS}))/(2*${dCOA})" | bc -l`
echo ${dENEdCOA}

echo ${OMEGA} ${COA} ${ENE} >> analysis/steepest.txt

set OMEGA=`echo "scale=7; (${OMEGA}-${KEISUU_OMEGA}*${dENEdOMEGA})/1.0" | bc -l`
set COA=`echo "scale=7; (${COA}-${KEISUU_COA}*${dENEdCOA})/1.0" | bc -l`
echo "Next:"
echo "./steepest.sh" ${OMEGA} ${COA}


関連エントリ




参考URL




付録


このエントリで使用したファイルを添付します。ファイル名末尾の".txt"を削除して、"_"を"."に変更すれば使えるはずです。(参考:ねがてぃぶろぐの付録)


参考文献/使用機器




フィードバック



にほんブログ村 その他趣味ブログ 電子工作へ

 ↑ 電子工作ブログランキング参加中です。1クリックお願いします。


コメント・トラックバックも歓迎です。 ↓      


 ↓ この記事が面白かった方は「拍手」をお願いします。

tag: AkaiKKR machikaneyama Scilab KKR 強磁性 シェルスクリプト 

Scilabで最急降下法 その2

Scilabで最急降下法 その1では1変数の関数 f(x) に対して最急降下法を用いて最小値を求めました。今回は2変数の関数 f(x,y) について最小値を求めます。

001_20170509143114675.png
Fig.1: 最急降下法による最小値探査



具体的には二次元のガウス関数に-1を掛けた関数を f(x,y) とします。
\begin{equation}
f(x,y)=\frac{1}{2 \pi \sigma_1 \sigma_2 \sqrt{1-\rho^2}}\exp\left\{-\frac{1}{2(1-\rho^2)}\\
\times\left(\frac{(x-\mu_1)^2}{\sigma_1^2}-2\rho\frac{(x-\mu_1)(y-\mu_2)}{\sigma_1\sigma_2} +\frac{(y-\mu_2)^2}{\sigma_2^2}\right) \right\}
\end{equation}
ここで
\begin{equation}
\rho=\frac{\sigma_{12}}{\sigma_1\sigma_2}
\end{equation}

最急降下法の値の更新は二次元の場合は以下のように行います。
\begin{equation}
\begin{pmatrix}
x^{(k+1)}\\
y^{(k+1)}
\end{pmatrix}
=
\begin{pmatrix}
x^{(k)}\\
y^{(k)}
\end{pmatrix}
-\alpha
\begin{pmatrix}
\frac{\partial f(x^{(k)}, y^{(k)})}{\partial x}\\
\frac{\partial f(x^{(k)}, y^{(k)})}{\partial y}
\end{pmatrix}
\end{equation}
停止条件は ∂f/∂x < ε かつ ∂f/∂y < ε とすればよいと思います。

clear;

// *** 二次元ガウス分布 ***
mu1 = 3; mu2 = 1;
mu = [mu1; mu2];
sigma1 = sqrt(10); sigma2 = sqrt(10); sigma12 = 5;
SIGMA = [sigma1^2, sigma12; sigma12, sigma2^2];
rho = sigma12 / (sigma1 * sigma2);
function z = func(x, y)
z = -1 ./ (2 * %pi * sigma1 * sigma2 * sqrt(1 - rho)) ..
.* exp(-1 / (2 .* (1 - rho^2)) ..
.* ((x - mu1) .^ 2 ./ (sigma1 ^ 2) - 2 .* rho .* (x - mu1) .* (y - mu2) ./ (sigma1 * sigma2) + ((y - mu2) .^ 2) ./ (sigma2 ^ 2)))
endfunction


// *** 数値微分 ***
h = 1E-3;
function dzx = dfx(x, y)
dzx = (func((x+h), y) - func((x-h), y)) ./ (2 * h)
endfunction

function dzy = dfy(x, y)
dzy = (func(x, (y+h)) - func(x, (y-h))) ./ (2 * h)
endfunction

// *** グラフのプロット ***
x = linspace(-10,10);
y = linspace(-10,10);
[X,Y] = ndgrid(x,y);
Z = func(X,Y);
// 色の設定
//xset("colormap",jetcolormap(64))
// xset("colormap",graycolormap(64))
// Sgrayplot(x,y,Z)
xset("fpf"," "); // 等高線に値を表示しない
contour2d(x,y,Z,10);
xmin = min(X); xmax = max(X); ymin = min(Y); ymax = max(Y);
zoom_rect([xmin,ymin,xmax,ymax]);




// *** 最小値の計算 ***
// 停止条件
err = 1E-5;
a = 200;
// 初期値
x = -4; y = 4;
z = func(x, y);
dx = dfx(x, y);
dy = dfy(x, y);
plot(x, y, "xk");
// 最小値の計算
while ((abs(dx) > err) | (abs(dy) > err))
x = x - a * dx;
y = y - a * dy;
dx = dfx(x, y);
dy = dfy(x, y);
plot(x, y, ".r");
end
// 計算結果
x, y
plot(x, y, "xk");


関連エントリ




参考URL




付録


このエントリで使用したファイルを添付します。ファイル名末尾の".txt"を削除して、"_"を"."に変更すれば使えるはずです。(参考:ねがてぃぶろぐの付録)


参考文献/使用機器




フィードバック



にほんブログ村 その他趣味ブログ 電子工作へ

 ↑ 電子工作ブログランキング参加中です。1クリックお願いします。


コメント・トラックバックも歓迎です。 ↓      


 ↓ この記事が面白かった方は「拍手」をお願いします。

tag: Scilab 最適化 最小値 最大値 

Scilabで最急降下法 その1

Scilabで何らかの関数 f(x) の最小値(あるいは最大値)を計算することを考えます。関数の値を計算するのが簡単な場合は x の定義域全体で f(x) を計算した後 minmax を使うという方法もあります。しかしながら f(x) の計算にそれなりの時間がかかる場合や f(x, y) といったように引数がたくさんある場合は効率的ではないと思います。

そこで今回は最急降下法のアルゴリズムを利用して f(x) の最小値を求めるということをやってみます。

001_20170507020049254.png

Fig.1: 最急降下法での最小値探索。上が関数f(x)の値、下が微分値f'(x)



最小値を求める関数


さて、実際に最小値を求める関数 f(x) ですが、今回は単純にガウス関数に -1 を掛けたものにします。
\begin{equation}
f(x) = - \frac{1}{\sqrt{2\pi\sigma^2}} \exp \left( -\frac{(x-\mu)^2}{2\sigma^2}\right)
\end{equation}
当然ながら、f(x)が最小になるのは x = μ のときです。

最急降下法


高校の数学で習ったとおり f(x) が最大値や最小値(や極値)をとるときその微分は f'(x) = df(x)/dx = 0 となります。最急降下法は、関数の微分を計算しその傾きが大きいほうへ f'(x)=0 となる x を探すアルゴリズムです。具体的には以下の手続きを繰り返します。
  1. x の初期値 x(0) を決める
  2. f'(x) < ε なら終了
  3. x(k+1) = x(k) - αf'(x(k))
  4. 2.に戻る

実際には α や ε を上手に決めておく必要があります。αは勾配の方向にどの程度進むかを決めるパラメータ(下記Scilabスクリプトではa)で、εは計算の終了条件を決めるパラメータ(下記Scilabスクリプトではerr)です。

Scilabスクリプト


clear;

// *** 一次元ガウス分布 ***
function y = func(x)
mu = 3;
sigma = 1;
y = -1 / sqrt(2*%pi*sigma^2) * exp(-1 * ((x - mu) .^ 2) ./ (2*sigma^2))
// y = cos(x)
endfunction

// *** 数値微分 ***
function y = dfunc(x)
h = 1E-4;
y = (func(x+h) - func(x-h)) ./ (2*h)
endfunction

// *** グラフのプロット ***
X = linspace(0,6);
Y = func(X);
dY = dfunc(X);
subplot(2,1,1);
plot(X, Y);
subplot(2,1,2);
plot(X, dY);

// *** 最小値の計算 ***
// 停止条件
err = 1E-3;
a = 0.5;
// 初期値
x = 1;
y = func(x);
dx = dfunc(x);
subplot(2,1,1);
plot(x, y, ".r");
subplot(2,1,2);
plot(x, dx, ".r");

// *** 最小値の計算 ***
while abs(dx) > err
x = x - a * dx;
dx = dfunc(x);
y = func(x);
subplot(2,1,1);
plot(x, y, ".r");
subplot(2,1,2);
plot(x, dx, ".r");
end

// *** 計算結果 ***
x
subplot(2,1,1);
plot(x, y, "xk");


参考URL




付録


このエントリで使用したファイルを添付します。ファイル名末尾の".txt"を削除して、"_"を"."に変更すれば使えるはずです。(参考:ねがてぃぶろぐの付録)


参考文献/使用機器




フィードバック



にほんブログ村 その他趣味ブログ 電子工作へ

 ↑ 電子工作ブログランキング参加中です。1クリックお願いします。


コメント・トラックバックも歓迎です。 ↓      


 ↓ この記事が面白かった方は「拍手」をお願いします。

tag: Scilab 最適化 最小値 最大値 

Scilabで二重積分

Scilabを利用すると1変数の数値積分が簡単に計算できます。

\begin{equation}
\int_{x_0}^{x_1}f(x)\mathrm{d}x
\end{equation}

このブログでも数値積分タグにいくつかの例を見つけることができます。しかしながら、2変数の数値積分はこれまで行ってきませんでした。

\begin{equation}
\int\int f(x,y) \mathrm{d}x\mathrm{d}y
\end{equation}

Scilabには二重積分を計算することが可能な int2d が存在します。今回は高校数学の美しい物語で解析的に解かれている二重積分を数値的に計算してみます。


積分範囲が長方形領域の場合


積分範囲が長方形の領域の場合、すなわち以下のような式で表すことができる場合は、簡単に数値積分できます。

\begin{equation}
\int_{x_0}^{x_1}\int_{y_0}^{y_1}f(x,y)\mathrm{d}x\mathrm{d}y
\end{equation}

Scilabの int2d では長方形領域を2つの三角形のパッチワークとして与えます。
積分範囲を int2d に渡すために行列XとYを用意します。それぞれ2つの三角形の頂点のx座標とy座標を与えます。

\begin{equation}
X =
\begin{pmatrix}
x_{0} & x_{0} \\
x_{1} & x_{1} \\
x_{1} & x_{0} \\
\end{pmatrix},
Y =
\begin{pmatrix}
y_{0} & y_{0} \\
y_{0} & y_{1} \\
y_{1} & y_{1} \\
\end{pmatrix}
\end{equation}

001_20170423145553b2b.png
Fig.1: Scilabのint2dへの積分範囲の与え方


実際に以下の積分を計算して見ます。

\begin{equation}
\int_{0}^{\pi}\int_{0}^{R}x^4 \sin(y)\mathrm{d}x\mathrm{d}y
\end{equation}

clear;

r = 1;

// *** 積分する関数の定義 ***
function z = func(x,y)
z = (x .^ 4) * sin(y)
endfunction
// 積分範囲
x0 = 0; x1 = r;
y0 = 0; y1 = %pi;

// *** 二重積分 ***
X = [x0, x0;
x1, x1;
x1, x0];
Y = [y0, y0;
y0, y1;
y1, y1];
// 数値解
I = int2d(X, Y, func)
// 解析解
A = 2*(r^5)/5


数値化解と解析解が同じ値になることが確認できます。

積分範囲が三角形の組み合わせで表せる場合


積分範囲が長方形の場合は2つの三角形の組み合わせで表現されますが、より複雑な形状の場合も任意の個数の三角形の組み合わせで表現できるはずです。今回は逆に簡単になってしまいますが、1個の三角形で表現できる例を計算します。

\begin{equation}
\int \int_D xy^2 \mathrm{d}x\mathrm{y}
\end{equation}

jusekibun.png
Fig.2: 積分領域Dが三角形ひとつ分の例


積分領域が三角形ひとつ分なので、与える行列は3行1列になります。

\begin{equation}
X =
\begin{pmatrix}
x_{0} \\
x_{1} \\
x_{1} \\
\end{pmatrix},
Y =
\begin{pmatrix}
y_{1} \\
y_{0} \\
y_{1} \\
\end{pmatrix}
\end{equation}

この計算を行うScilabスクリプトは以下のようになります。

clear;

// *** 積分する関数の定義 ***
function z = func(x,y)
z = x .* (y .^ 2)
endfunction

// *** 二重積分 ***
X = [0;
1;
1];
Y = [1;
0;
1];
// 数値解
I = int2d(X, Y, func)
// 解析解
A = 3/20


このスクリプトも数値解と解析解が同じに値になることが分かります。

同様にしてN個の三角形の組み合わせで表現される積分範囲の場合3行N列の行列で指定することができます。

更に複雑な積分領域の場合


どんなに複雑な積分領域の形状であっても三角形のパッチワークで表現できるはずですが、現実的には大変です。そこでOctaveの精義―フリーの高機能数値計算ツールを使いこなすで紹介されている方法を試してみましたが、現状うまく行っていません。上手く行っていませんがとりあえず方法だけは紹介します。
具体的にはScilabの論理演算で条件分岐の考え方を使って積分領域外では値がゼロになるように被積分関数の定義を行います。

\begin{equation}
\int\int_D -\frac{1}{(2x + y + 1)^2}\mathrm{d}x\mathrm{d}y
\end{equation}

jusekibun2.png
Fig.3: 複雑な積分領域の例


clear;

// *** 積分する関数の定義 ***
function z = func(x,y)
region = y >= x .^ 2
z = - 1 ./ ((2 * x + y + 1) .^ 2) .* region
endfunction

// *** 二重積分 ***
X = [0;
1;
1];
Y = [0;
0;
1];
// 数値解
I = int2d(X, Y, func)
// 解析解
A = (1/3) * log(4) - 1/2


原理的にはこのスクリプトでよいはずですが、実際には正しく計算してくれません。Scilab 6.0ではエラーで停止します。Scilab 5.5.2ではそれっぽい値を返しますが、解析解の値とはかなりずれた値となっており、不正確です。

関連エントリ




参考URL




付録


このエントリで使用したファイルを添付します。ファイル名末尾の".txt"を削除して、"_"を"."に変更すれば使えるはずです。(参考:ねがてぃぶろぐの付録)


参考文献/使用機器




フィードバック



にほんブログ村 その他趣味ブログ 電子工作へ

 ↑ 電子工作ブログランキング参加中です。1クリックお願いします。


コメント・トラックバックも歓迎です。 ↓      


 ↓ この記事が面白かった方は「拍手」をお願いします。

tag: Scilab 数値積分 重積分 

デバイ模型

デバイ模型やデバイ温度といった言葉は、固体物理学の分野でたびたび目にします。
近似自体は、非常に単純なものなのですが、あらゆる物性に顔を出す反面、初歩的な教科書には比熱のことしか書いてなかったりするので、ときどき良く分からなくなったりします。
デバイ模型は、そもそも、フォノンの分散関係を近似的に表すための模型であり、そこから(格子比熱を含む)色々な物性を計算することができるようになります。
今回は、デバイ模型の仮定している近似についてまとめると共に、デバイ温度が現れる物性の計算式を列挙します。

001_201511080539137af.png

Fig.1: Quantum ESPRESSOで計算したダイヤモンドのフォノンの分散関係



フォノンの分散関係と物性値


結晶の格子振動(フォノン)にだけに依存する物性値は、フォノンの分散関係が分かればすべて計算できるということになっています。デバイ模型(Debye model)やアインシュタイン模型(Einstein model)は、単純に格子比熱を計算するためだけのモデルだと見做される事もありますが、本来はこの分散関係を近似的にあらわす模型です。したがって、デバイ模型を使えば格子比熱以外の物性も計算することができます。

フォノンの分散関係は、以下の式で表され、一般には複雑な形状をしています。

\begin{equation}
\omega = \omega(\vec{q})
\end{equation}

ここで$\omega$は角振動数で$\vec{q}$は波数ベクトルです。Fig.1に示したのは、Quantum ESPRESSOで計算したダイヤモンドのフォノンの分散関係です。音響フォノンと光学フォノンの両方を持っていること、異方性を持っていることなどが分かります。

デバイ模型の2つの仮定


そこで、デバイ模型では「分散関係をシンプルな形で表す」「異方性をなくす」という二つの方針で簡単な式に置き換えます。

仮定(1) 角振動数$\omega$は波数$q$に比例し、その比例定数を音速$v$とする
\begin{equation}
\omega = v q
\end{equation}

仮定(2) ブリュアンゾーン(BZ)を同じ体積の球で置き換える
\begin{equation}
q_D = \left( \frac{6 \pi^2 N}{\Omega} \right)^{\frac{1}{3}}
\end{equation}
ここで$q_D$はデバイ波数と呼ばれ、体積Ωとその中の原子の数Nのみで表すことができます。

この波数$q$は、$0 \leqq q \leqq q_D$の範囲に限られます。この$q_D$は、体積Ωと原子数Nだけで決まるので、デバイ模型を特徴付けるパラメータは、音速$v$のみということになります。しかしながら、音速$v$はこの用途にはあまり使われず、代わりにデバイ温度$\Theta_D$がよく使われます。音速$v$とデバイ温度$\Theta_D$は、いったんエネルギーの次元で考えた後、以下のように換算できます。
\begin{equation}
k_B \Theta_D = \hbar \omega_D = \hbar v q_D \\
\therefore v = \frac{k_B \Theta_D}{\hbar q_D}
\end{equation}

以降では、デバイ模型のパラメータであるデバイ温度 ΘD が出てくる物性値について列挙します。

熱力学


ヘルムホルツの自由エネルギー(ヘルムホルツエネルギー)は、以下のような式で、エネルギー E の項とエントロピー S の項から表されます。
\begin{equation}
F=E-TS
\end{equation}
エネルギーにせよエントロピーにせよ、色々な原因による項(磁性、配置のエントロピー、電子比熱によるエントロピーなど)がありますが、格子系のエネルギーとエントロピーをデバイ模型を用いて表します。(参考: AkaiKKRで金属の熱物性)

格子系のエネルギー
\begin{equation}
E_D = 3 N k_B T \left( \frac{T}{\Theta_D} \right)^3 \int_0^{\Theta_D / T} \frac{z^3}{\exp(z)-1} \mathrm{d}z + E_0
\end{equation}

ゼロ点エネルギー
\begin{equation}
E_0 = \frac{9}{8} N k_B \Theta_D
\end{equation}

格子系のエントロピー
\begin{equation}
S_D = 3 N k_B \left[ \frac{4}{3} \left( \frac{T}{\Theta_D} \right)^3 \int_0^{\Theta_D / T} \frac{z^3}{\exp(z) - 1} \mathrm{d}z \\ - \ln \left\{ 1 - \exp \left(- \frac{\Theta_D}{T} \right) \right\} \right]
\end{equation}

定積比熱は格子系のエネルギーを、温度で微分したものです。
\begin{equation}
C_V = \frac{\partial E_D}{\partial T} = 9 N k_B \left( \frac{T}{\Theta_D} \right)^3 \int_0^{\Theta_D / T} \frac{z^4 \exp(z)}{(\exp(z)-1)^2} \mathrm{d} z
\end{equation}

格子振動の大きさ


デバイワラー因子
\begin{equation}
M_D = \frac{6 h^2 T}{M k_B \Theta_D^2} \left( \frac{T}{\Theta_D} \int_0^{\Theta_D / T} \frac{z}{\exp(z)-1} \mathrm{d} z + \frac{\Theta_D}{4T} \right) \left( \frac{\sin \theta}{\lambda} \right)^2
\end{equation}

平均二乗変位
\begin{equation}
u_D^2 = \frac{3 \hbar T}{M k_B \Theta_D^2} \left( \frac{T}{\Theta_D} \int_0^{\Theta_D/T} \frac{z}{\exp(z)-1}\mathrm{d}z + \frac{\Theta_D}{4T} \right)
\end{equation}

原子の振幅が一定以上大きくなると、融解が起こるのではないかという考えから、振幅と融点の関係式が提案されました。当然ながら、かなりラフな推定ですが、少なくとも定性的には、デバイ温度の高い物質の融点が高いという関係が見られるようです。(参考: ザイマン 固体物性論の基礎)

リンデマンの融解公式
\begin{equation}
T_m = \frac{x_m^2}{9 \hbar} M k_B \Theta_D r_s^2
\end{equation}

電気抵抗率


金属の電気伝導は、格子系だけでは決まらないので、電子と格子の相互作用に起因するパラメータも必要となります。

電気抵抗率
\begin{equation}
\rho_D = A \left( \frac{T}{\Theta_D} \right)^5 \int_0^{\Theta_D / T} \frac{z^5}{(\exp(z)-1)(1-\exp(-z))} \mathrm{d} z
\end{equation}

BCS理論による超伝導転移温度
\begin{equation}
T_c = \Theta_D \exp \left( - \frac{1}{N(0)V} \right)
\end{equation}

つまりデバイ模型/デバイ温度とは何なのか?


結局のところ、デバイ温度とかデバイ模型とか言われるものは、いったい何なのでしょうか?
結晶の比熱を計算するための近似がデバイ模型であり、デバイ温度はその中のパラメータである、というのはひとつの答えです。
実際、ねがてぃぶろぐでもScilabで数値積分: 固体の比熱のエントリで比熱の計算をしています。

001_20130522024102.png
Fig.2: 銅の比熱の温度依存性(ΘD = 343.5 K)。青破線がアインシュタインモデル、赤実線がデバイモデルによる計算。


しかしながら、上記のように、比熱以外の色々な物理量の計算式に顔を出します。また、直接数式の中に出てこない場合でも、例えば「デバイ温度よりも充分高温のときだけ成り立つ」みたいな文脈で現れることもあります。あるいは「ダイヤモンドは固いのでデバイ温度が高い」のような記述が見つかるかもしれません。

温度がデバイ温度よりも高いかどうかを議論しているときは、格子振動を古典力学的に扱ってよいのか、量子力学的な効果を考慮しなければならないのかを問題にしている場合が多いです。例えばFig.2の銅の比熱の温度依存性では、低い温度では比熱が急激に変化していますが、高温ではほとんど変化しなくなります。高温での比熱の温度依存性がなくなることは、古典力学的から導かれ、デュロン・プティの法則として知られています。その一方で、低温の急激な温度依存性は、量子力学を考えなければ説明できません。
また、物質の硬さを議論しているときには、直感的に言えば、デバイ温度を原子同士をつなぐ「ばね定数」のようなものだと考えています。

そんなわけで、最初に書いたとおり「デバイ模型とは、結晶のフォノンの分散関係に対する最も簡単な近似のひとつ」で「デバイ温度は、デバイ模型の中で、その物質の個性を表す最も重要なパラメータ」が答えとなるわけですが、その近似が単純であるにもかかわらず、色々な応用が考えられるので、出くわすたびに、それまでもっていた理解とは、ほんの少し違う側面が見えることがあります。

関連エントリ




参考URL




参考文献/使用機器




フィードバック



にほんブログ村 その他趣味ブログ 電子工作へ

 ↑ 電子工作ブログランキング参加中です。1クリックお願いします。


コメント・トラックバックも歓迎です。 ↓      


 ↓ この記事が面白かった方は「拍手」をお願いします。

tag: デバイ模型 フォノン Scilab quantumESPRESSO 

FC2カウンター
カテゴリ
ユーザータグ

LTspiceAkaiKKRmachikaneyamaScilabKKRPSoC強磁性OPアンプPICCPA常微分方程式モンテカルロ解析ecaljodeトランジスタ状態密度インターフェースDOS定電流スイッチング回路PDS5022半導体シェルスクリプトレベルシフト乱数HP6632AR6452AI2C可変抵抗分散関係トランジスタ技術ブレッドボード温度解析反強磁性確率論バンドギャップセミナー数値積分熱設計非線形方程式ソルババンド構造絶縁偏微分方程式ISO-I2CLM358フォトカプラ三端子レギュレータカオスLEDシュミットトリガGW近似A/Dコンバータ発振回路PC817C直流動作点解析USBマフィンティン半径数値微分アナログスイッチTL43174HC4053カレントミラーサーボ量子力学単振り子チョッパアンプ補間2ちゃんねる開発環境bzqltyFFT電子負荷LDAイジング模型BSch基本並進ベクトルブラべ格子パラメトリック解析標準ロジックアセンブラ繰り返し六方最密充填構造SMPコバルトewidthFET仮想結晶近似QSGW不規則合金VCAMaximaGGA熱伝導cygwinスレーターポーリング曲線キュリー温度スイッチト・キャパシタ失敗談ランダムウォークgfortran抵抗相対論位相図スピン軌道相互作用VESTA状態方程式TLP621ラプラス方程式TLP552条件分岐NE555LM555TLP521マントル詰め回路MCUテスタFXA-7020ZR三角波過渡解析ガイガー管自動計測QNAPUPSWriter509ダイヤモンドデータロガー格子比熱熱力学awkブラウン運動起電力スーパーセル差し込みグラフ第一原理計算フェルミ面fsolveCIFxcrysden最大値最小値ubuntu最適化平均場近似OpenMPシュレディンガー方程式固有値問題井戸型ポテンシャル2SC1815TeX結晶磁気異方性OPA2277非線型方程式ソルバフラクタルFSM固定スピンモーメントc/agnuplotPGA全エネルギーfccマンデルブロ集合縮退正規分布キーボード初期値interp1multiplotフィルタ面心立方構造ウィグナーザイツ胞L10構造半金属二相共存ZnOウルツ鉱構造BaOSIC重積分磁気モーメント電荷密度化学反応クーロン散乱岩塩構造CapSenseノコギリ波デバイ模型ハーフメタルRealforceフォノンquantumESPRESSOルチル構造スワップ領域リジッドバンド模型edelt合金等高線凡例軸ラベル線種シンボルトラックボールグラフの分割MAS830LPIC16F785トランス入出力CK1026PC直流解析パラメータ・モデル等価回路モデル不規則局所モーメント関数フィッティング日本語ヒストグラムTS-112ExcelGimp円周率TS-110LMC662片対数グラフ三次元specx.fifortUbuntu文字列疎行列不純物問題ジバニャン方程式ヒストグラム確率論マテリアルデザインP-10境界条件連立一次方程式AACircuit熱拡散方程式HiLAPW両対数グラフ陰解法MBEナイキスト線図負帰還安定性Crank-Nicolson法EAGLE最小二乗法

最新コメント
リンク

にほんブログ村 その他趣味ブログ 電子工作へ