自然現象の...
TRANSCRIPT
2001年度青山学院大学理工学部物理学科 卒業論文
研究題目
自然現象の
フラクタルパターン
林 るみ子羽田野研究室
青山学院大学 理工学部物理学科 卒業論文
自然現象のフラクタルパターン
林 るみ子 著
自然現象のフラクタルパターン
林るみ子羽田野研究室
平成 14 年 2 月 20 日
概 要
我々が身近に目にすることのできる自然現象には、フラクタルという性質(特徴的な長さを持たず、自己相似性がある形)を持つものが多く存在する。その中で自然界における樹枝状のフラクタル性の起源を明らかにする鍵をみつけるべく、その性質をもつ現象のひとつである稲妻とひび割れをモデル化し、シュミレーションにより再現した。その結果からそれぞれのフラクタル次元を求めた。
1
目 次
1 はじめに 3
2 フラクタル 3
2.1 フラクタルの性質とその図形 : : : : : : : : : : : : : : : : 3
2.2 フラクタル次元 : : : : : : : : : : : : : : : : : : : : : : : : 5
3 フラクタル性をもつ自然現象のモデル化 5
3.1 モデル化 : : : : : : : : : : : : : : : : : : : : : : : : : : : : 6
3.2 稲妻のシミュレーション結果 : : : : : : : : : : : : : : : : 8
3.3 ひび割れのシミュレーション結果 : : : : : : : : : : : : : : 8
4 フラクタル次元 11
4.1 稲妻 : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : 11
4.2 ひび割れ : : : : : : : : : : : : : : : : : : : : : : : : : : : : 11
5 結果と考察 13
5.1 稲妻とひび割れとの比較 : : : : : : : : : : : : : : : : : : : 13
6 まとめ 14
A 稲妻シミュレーション 16
B 稲妻シミュレーション (ループ回数指定) 24
C ひび割れシミュレーション 32
2
1 はじめに我々が身近に目にすることのできる自然現象には、フラクタル性(特
徴的な長さを持たず、自己相似性がある形)という特殊な性質を持つものが多く存在する。本研究ではそれらフラクタル性をもつ自然現象の 1つである稲妻(電気的破壊)とひび割れ(脆性破壊)の形について取り上げ、その類似点・相違点に注意しながら解析する。注目すべき点は、この2つの自然現象が 1つの簡単な方程式
r � (�r�) = 0
から再現できるという点である。ここで稲妻を電気的破壊の形(ひび割れを脆性破壊の形)と考え、�を電位(変位)、�を空気中の電気伝導度(対象物の剛性率)とした。現在この方程式からシミュレーションできる自然現象はこの 2つが明ら
かにされているが、他にも微粒子の凝集体とヴィスカスフィンガーとの関連もこの方程式を満足させるということがわかってきた [1]。このように、基本的でよく知られた方程式の自発的に対称性の破れた解を研究することは、自然界に存在する多くの樹枝状のフラクタル構造(例えば、川や血管や植物など)の起源を明らかにする重要な鍵であると考えられる。本研究の結果を以下で説明していく。2章ではまずフラクタルの概念に
ついて説明する。3章で実際に稲妻とひび割れのシミュレーション結果を示し、その結果から4章でフラクタル図形の次元を得る。5章、6章ではこれらの結果について考察を述べる。
2 フラクタルフラクタル (Fractal)という言葉は、マンデルブロ (Mandelbrot,1924-)
が、1975年に新しく作った言葉で、語源はラテン語の形容詞 fractus(物が壊れて不規則な破片になった状態を表わしている)である [1]。この生まれたばかりの言葉の持つ意味や性質について、実際にフラクタル図形を例に出して説明する。
2.1 フラクタルの性質とその図形
フラクタルとは次の 2つの性質を持つものである:
3
図 1: コッホ曲線
� 特徴的な長さを持たない。
� 自己相似性がある。
ここで特徴的な長さとは、例えば球を考えるならその半径、また人間の形を考えるならば身長というように、その形を特徴づけるような長さを指す。フラクタル図形はそのような長さを持たない。また自己相似性とは、ある図形の一部分を拡大すると元の図形の全体(あるいは、より大きな部分)と同じような形になるということである。では、この 2つの性質を持つものとはどのような形なのか。例として、図 1に代表的なフラクタル図形であるコッホ曲線を示す。コッホ曲線は以下のように作られる:
(i) 1つの直線を 3等分に区切った中央の部分を切り取る。(ii) 切り取った部分に対し正三角形になるように辺を付け加える。(iii) 手順 (i)(ii)を無限に繰り返す。
このようなフラクタル図形を初めて目にする人には非常に複雑で理解し難い図形のように思えるかもしれない。しかしこれらの特徴は不思議なものではない。なぜなら我々が小さい頃から見慣れている自然界の風景の大部分がフラクタル図形そのものだからである。具体的には、海岸線や山の起伏や川の形などがそうである。
4
2.2 フラクタル次元
我々は経験的に点は 0次元、線は 1次元、面は 2次元、空間は 3次元であるということを知っている。このような経験的次元は、すべて整数であり、その数字は独立に選べる変数の数、自由度と一致する。しかしフラクタル図形は、整数で表わされる次元におさめることができない。ではフラクタル図形の次元 (フラクタル次元)はどのように定義できるだろうか。フラクタル次元は、測度の関係より求める方法・粗視化の度合いを変える方法・相関関数より求める方法など、さまざまな角度から求めることができるのだが、ここでは実際に用いた測度の関係より求める方法について説明する [1]。この方法は、フラクタル図形が非整数次元の測度を持つことを利用して次元を定義する。立方体の1辺の長さを2倍にすると、2次元測度である表面積は、22倍になり、3次元測度である体積は 23倍になる。したがって、もし単位長さを2倍にしたときに、2D倍になるような量があったとすれば、その量はD次元的であるといってもよいだろう。再び図 1のコッホ曲線を例にとって考えてみる。この場合に非整数次元の測度を持つ量は、曲線の長さである。実際コッホ曲線を3倍に拡大したとき曲線の長さはもとの 4 = 3log3 4倍になる。つまり、この曲線の長さは log3 4 = 1:2618・・・次元の特性をもっているわけである。一般に、長さを L、面積を S、体積を V としたとき、次の関係式が成
り立っている:
L / S1=2/ V 1=3: (1)
この関係式の意味は、Lを k 倍にすると S1=2も V 1=3も k 倍になるということである。D次元測度をもつ量をXとすると、式 (1)は次のように一般化できる:
L / S1=2/ V 1=3
/ X1=D: (2)
本研究では、この関係を用いてフラクタル次元Dを定義する。
3 フラクタル性をもつ自然現象のモデル化本研究では、フラクタル性をもつ自然現象の中でも稲妻(電気的破壊)
とひび割れ(脆性破壊)に着目し、そのフラクタルパターンのモデル化を
5
行なった [2]。モデル化には、簡単のため 2次元の正方格子を用いた。つまり、稲妻を写真で撮った形、あるいは平板に力を加えてできたひび割れを想定した。3.1節でモデル化の計算手順を説明し、3.2節、3.3節で稲妻とひび割れそれぞれの結果を示す。
3.1 モデル化
フラクタル性をもつ自然現象のひとつである稲妻とひび割れを導く式は
r � (�r�) = 0 (3)
で与えられる。ここで稲妻のシミュレーションにおいては、�を電位、�を空気中の電気伝導度とする。一方、ひび割れのシミュレーションでは、�を変位、�を対象物の剛性率とする。式 (3)は基本的な保存の方程式である。稲妻の場合には、Kirchho�の第 1・第 2法則とオームの法則から、ひび割れの場合には板に垂直な方向の力のつり合いより導かれる。シミュレーションは式 (3)を離散近似して行なう。式 (3)を 2次元において離散化すると次のようになる。
�(x+�x;y)��(x;y)�x
�(x+ �x2; y)� �(x;y)��(x��x;y)
�x�(x� �x
2; y)
�x
+
�(x;y+�y)��(x;y)�y
�(x; y + �y2)� �(x;y)��(x;y��y)
�y�(x; y � �y
2)
�y= 0 (4)
ここで�xと�yが離散化した際の格子間隔である。簡単のため�x = �y = 1とすると、式 (4)は
��(x; y)��(x+
�x
2; y) + �(x�
�x
2; y) + �(x; y +
�y
2) + �(x; y �
�y
2)�
+ �(x +�x; y)�(x+�x
2; y) + �(x��x; y)�(x�
�x
2; y)
+�(x; y+�y)�(x; y+�y
2)+�(x; y��y)�(x; y�
�y
2) = 0
(5)
と書き直せる。この式を用いて計算を進める。手順は次の通りである。
6
(i) 初期条件として、�の境界値と �の初期値(乱数)を与える。(ii) 格子状にとった領域の、格子点に �、ボンドに �をとり、離散化した式 (4)から各 �を求める。(x方向は周期的境界条件をとる。)
(iii) 隣り合わせの �の差��を調べ、�� > �r(臨界値)ならば破壊したものとみなし、そのボンドの �の値を変化させる。但し、一度破壊した部分は 2回目以上は壊れないとものとする。
(iv) 手順 (iii)で変化させた �を式 (5)に代入し、手順 (ii)、(iii)を繰り返す。
(v) 手順 (iii)で破壊するところがなければ終了する。
手順 (ii)で決めるそれぞれの格子点の �には、四方に隣り合う �の値と、そのそれぞれをつなぎ合わせる4つのボンド �の値が影響を与えることが式 (5)からわかる。そこで本研究では初期条件から決まる値より、行列の計算を使い �を決定した。手順 (iii)に破壊したボンドの値を変化させるとあるが、ボンドとは、稲
妻の場合には電気伝導度を意味するので破壊後は増加させ、稲妻の場合には剛性率を意味するので破壊後は減少させた。手順 (v)で、破壊するところがなければ終了するとしたが、稲妻のシ
ミュレーションでは一旦破壊が始まってしまった場合、上面と下面(実現象でいう雲と地面のこと)が稲妻でつながってもそこで破壊が止まることはなく、格子全体を破壊で埋め尽くすまで破壊し続ける。そのため、稲妻のフラクタル性を調べるためには上と下が破壊でつながった時点で手順 (ii)・(iii)のループを止め、終了させる必要がある。そこで、本研究では手順 (v)のような終了の指定をしたプログラムとは別に、ループをする回数を指定して終了させるプログラムを用意した。そして、上と下が破壊でつながったループの回でできた破壊の形を結果として採用した。ここで、シミュレーション結果がフラクタルを示すのに重要なのは、�の境界条件と �の初期値のバランスである。上面の電位 �が大きすぎると稲妻は縦の破壊が強くなり、雨のように稲妻が降る現象になる。逆に、上面の電位 �が小さすぎると稲妻は起こらずに終わってしまう。そのため、境界条件 �は破壊が起こるか起こらないかの臨界点を有効数字2桁までで探し、その値を用いた。
7
3.2 稲妻のシミュレーション結果
稲妻のシミュレーションでは、電気伝導度 �の乱数の範囲を [0; 2]、破壊するときの電気伝導度の臨界値を �r = 1に固定し、数種類のスケールで行なった。その一部として格子 40�40と 50�50でシミュレーションした結果を図 2に示す。格子 40� 40の場合の上面と下面の電位差は 33:10
とし、50� 50の場合の電位差は 40:30とした。図 2の破壊したボンドのうち、赤線で表示してある部分が稲妻として
認められる破壊である。破壊した場所がつながって上面と下面が1本の線でつながったものを基準とし、その線に接して伸びている線を含めて1つの稲妻とした。
3.3 ひび割れのシミュレーション結果
ひび割れのシミュレーションでは、剛性率の乱数の範囲を [0; 2]破壊するときの剛性率の臨界値を �r = 1に固定し、数種類のスケールで行なった。その一部として格子 40� 40と 50� 50でシミュレーションした結果を図 3に示す。格子 40 � 40の場合の上面と下面の電位差は 32:82とし、50� 50の場合の電位差は 40:01とした。図 3の破壊したボンドのうち、赤線で表示してある部分がひび割れと
して認められる破壊である。破壊した場所に対し交差するように線を引き、その線が左と右を1本でつながったものを基準とし、その線に接して伸びているものも含めた線上のボンドを 1つのひび割れとした。
8
0 10 20 30 400
10
20
30
40
(a)
0 10 20 30 40 500
10
20
30
40
50
(b)
図 2: 格子上にできた稲妻の形:(a)格子 40� 40;(b)格子 50� 50。
9
0 10 20 30 400
10
20
(a)
0 10 20 30 40 505
15
25
(b)
図 3: 格子上にできたひび割れの形:(a)格子 40� 40;(b)格子 50� 50。
10
4 フラクタル次元シミュレーションを格子の大きさを変えて数回実行した結果から、式
(2)を用いてフラクタル次元Dを導く。シュミレーションを行った格子の一辺の長さを Lとし、破壊して稲妻やひび割れの形になった部分の格子の数をNcとすると、式 (2)は
Nc / LD (6)
と解釈し直すことができる。これを用いてフラクタル次元Dを求めた。
4.1 稲妻
稲妻のシミュレーション結果をまとめたグラフを図4に示す。グラフの近似直線の傾きがフラクタル次元を指している。最小二乗法によって傾きを求めた結果、稲妻シミュレーションのフラクタル次元DはD = 1:72�0:09
であった。
4.2 ひび割れ
ひび割れのシミュレーション結果をまとめたグラフを図 5 に示す。稲妻のグラフ同様、グラフの近似直線の傾きがフラクタル次元を指している。最小二乗法によって傾きを求めた結果、ひび割れシミュレーションのフラクタル次元DはD = 1:779� 0:002であった。
11
L
Nc 100
1000
1010 100
図 4: 稲妻における LとNcの対数プロット
10
100
10L
Nc
1000
100
図 5: ひび割れにおける LとNcの対数プロット
12
5 結果と考察
5.1 稲妻とひび割れとの比較
稲妻とひび割れのシミュレーションには、次のような類似点と相違点が挙げられる。
(i)類似点
�基本式が同じである。
�与えた初期値 (電気伝導度と剛性率)、また破壊の起こる境界値が一致している。
�必要な境界条件 (上面と下面の電位と変位)の値がほぼ同じである。
(ii)相違点
�破壊がおきたときのボンドの変化の増減が異なる。
�シミュレーションを行なったとき、稲妻は全てを破壊し尽くすまで止まらないが、ひび割れは左右がひび割れとしてつながるとそこで破壊が止まる。
�亀裂の入り方が縦横で異なる。
同一の方程式から、稲妻・ひび割れ、各々の特徴を持ち合わせた異なった形を得た。しかし、フラクタル次元はほぼ一致するということがシミュレーションよりわかった。稲妻において、シミュレーション結果と実現象として我々が見る稲妻
の形とを比較したとき、シミュレーション結果のほうが広がりが大きく、枝別れの先が四方八方に飛び散っていることが見て取れる。原因として、実現象では雲から地上に電流が通る際、最短距離に流量が集中し、流れの方向性が異なる道へは電流が流れやすい抵抗率であっても電流はほとんど流れないのではないかということが考えられる。これに対し、今回のシミュレーションでは、どの道にどれだけの電流が流れているかの重みが全くかかっていない。なぜなら一度壊れた格子は 2回以上壊れない、というルールを与えているからである。改善策として、このルールを取り除き、最終的に格子が何回壊れたかによって格子の太さを変え、ある一定の太さ以上のところだけを稲妻と認める、というルールに変えるという策が提案できる。
13
また、稲妻シミュレーションにおいて、プログラム中でのループの終了させる方法について前述したが、このようにループの回数を指定するプログラムを別に作り実行させることは二度手間になっている。これは先のプログラム中で「境界が破壊でつながったらループを終了させる」という条件を付け加えるほうが得策である。今回、この条件を付け加えることを試みたが、時間の都合でプログラムを完成することができず、二度手間をかけることになってしまった。
6 まとめ本研究により、簡単な方程式から、樹枝状のフラクタル性を持った2つ
の自然現象をモデル化することができた。そして、フラクタル次元はどちらも 1:7 � 1:8程度であるということがわかった。実験系の論文で発表された放電現象のフラクタル次元 [3]もこれとほぼ一致した値を示している。これは現実に近い結果が得られたと考えられる。このことから、式(3)を他にも存在する樹枝状のフラクタル性をもった自然現象へ応用できると期待される。今後の更なる自然現象の解明への方法として、いくつかの進路が考え
られる。まず、今回の稲妻のシミュレーションを3次元で再現すること。これにより、より現実に近いモデルが得られることが期待される。次に、稲妻やひび割れ以外の現象の再現である。現在では微粒子の凝集体とヴィスカスフィンガーが方程式 (3)から再現できることがわかっている。多くのフラクタル性をもつ自然現象が再現されることで、今まで知られていなかった自然現象の新たな仕組みが解明されることを期待する。
14
謝辞今年 1年間卒業研究を進めるにあたり、羽田野研究室の先輩方や学部生
に様々な面で大変お世話になりました。そして誰よりも、わからないことばかりの私をいつも温かく見守り、一から丁寧に御指導下さいました羽田野先生には心より感謝しております。この場をお借りしまして、皆様に深くお礼を申し上げます。
参考文献[1] 高安秀樹『フラクタル』(朝倉書店、1986)
[2] H. Takayasu, Phys. Rev. Lett. 54 (1985) 1099
[3] L. Niemeyer, L. Pietronero and H.J. Wiesmann, Phys. Rev. Lett. 52
(1984) 1003
15
A 稲妻シミュレーション#include<stdio.h>
#include<math.h>
#define SIMPLE_SPRNG
#include "sprng.h"
#define _n_r 59
#define _n_c 60
#define _max 2.0
#define syoki_M 0.0
#define phi_x 1.1
#define zoukaritsu 0.01
#define kyoukai 1.0
#define G(a,b) G[b*_n_r*_n_c+a]
#define _dim_(i_row,i_col) (i_row)*_n_c+(i_col)
int ConjugateGradient(double b[],double x[],
double G_diag[],
double sigma_row[][_n_c],double sigma_col[][_n_c],
double r[],double p[],double Ap[],
int n_dim,int n_iteration,double eps);
double DotProduct(double a[],double b[],int n_dim);
void multiply(double vold[],double vnew[],
double G_diag[],
double sigma_row[][_n_c],double sigma_col[][_n_c]);
main(){
FILE *datafile;
16
int i,j,m,k,flag,roop,i_row,i_col,idim;
static int Fr[(_n_r+2)*_n_c],Fc[(_n_r+2)*_n_c];
static double sigma_r[_n_r+2][_n_c],dphi_r[_n_r+2][_n_c];
static double sigma_c[_n_r+1][_n_c],dphi_c[_n_r+1][_n_c];
static double syoki_m,p[_n_r*_n_c],phi[_n_r+2][_n_c];
int seed=12345;
static double G_diag[_n_r*_n_c],solution[_n_r*_n_c];
static double work1[_n_r*_n_c],work2[_n_r*_n_c],work3[_n_r*_n_c];
int info,n_iteration;
double eps;
static double vnew[_n_r*_n_c];
static double vec[_n_r*_n_c];
datafile=fopen("ina.dat","w");
printf("deni"); scanf("%lf", &syoki_m);
m=_n_r*_n_c;
for(i=0; i<_n_c; i++){
phi[0][i]=syoki_m;
phi[_n_r+1][i]=syoki_M;
}
init_sprng(DEFAULT_RNG_TYPE,seed,SPRNG_DEFAULT);
for(j=0; j<=_n_r+1; j++){
for(i=0; i<_n_c; i++){
sigma_r[j][i]=1/(2.0+sprng()*_max);
}
}
for(j=0; j<=_n_r; j++){
for(i=0; i<_n_c; i++){
sigma_c[j][i]=1/(2.0+sprng()*_max);
}
}
17
for(k=0; k<(_n_r+2)*_n_c; k++){
Fr[k]=0;
Fc[k]=0;
}
roop=0;
do{
roop++;
flag=0;
for(j=0; j<m; j++){
if(j<_n_c){
p[j]=-phi[0][j]*sigma_c[0][j];
}
else if(j>=m-_n_c){
p[j]=-phi[_n_r+1][j%_n_c]*sigma_c[_n_r][j%_n_c];
}
else{
p[j]=0.0;
}
}
for(i_row=0;i_row<_n_r;i_row++){
for(i_col=0;i_col<_n_c;i_col++){
idim=_dim_(i_row,i_col);
G_diag[idim]=-(sigma_c[i_row+1][i_col]
+sigma_c[i_row][i_col]
+sigma_r[i_row+1][i_col]
+sigma_r[i_row+1][(i_col+_n_c-1)%_n_c]);
}
}
multiply(p,vec,G_diag,sigma_r,sigma_c);
18
n_iteration=10000;
eps=1.0e-15;
info=ConjugateGradient(p,solution,
G_diag,sigma_r,sigma_c,
work1,work2,work3,
m,n_iteration,eps);
printf("INFO=%d\n",info);
for(j=0; j<m; j++){
phi[j/_n_c+1][j%_n_c]=solution[j];
}
for(j=0; j<=_n_r+1; j++){
for(i=0; i<_n_c; i++){
if(i!=_n_c-1){
dphi_r[j][i]=(phi[j][i]-phi[j][i+1])*(phi[j][i]-phi[j][i+1]);
if(dphi_r[j][i]>phi_x && Fr[j*_n_c+i]!=1){
sigma_r[j][i]=sigma_r[j][i]/zoukaritsu;
fprintf(datafile," %d %d\n %d %d\n &\n",i,-j,i+1,-j);
Fr[j*_n_c+i]=1;
flag=1;
}
}
else{
dphi_r[j][i]=(phi[j][i]-phi[j][0])*(phi[j][i]-phi[j][0]);
if(dphi_r[j][i]>phi_x && Fr[j*_n_c+i]!=1){
sigma_r[j][i]=sigma_r[j][i]/zoukaritsu;
fprintf(datafile," %d %d\n %d %d\n &\n",i,-j,_n_c,-j);
Fr[j*_n_c+i]=1;
flag=1;
19
}
}
}
}
for(j=0; j<=_n_r; j++){
for(i=0; i<_n_c; i++){
dphi_c[j][i]=(phi[j][i]-phi[j+1][i])*(phi[j][i]-phi[j+1][i]);
if(dphi_c[j][i]>phi_x && Fc[j*_n_c+i]!=1){
sigma_c[j][i]=sigma_c[j][i]/zoukaritsu;
fprintf(datafile," %d %d\n %d %d\n &\n",i,-j,i,-j-1);
Fc[j*_n_c+i]=1;
flag=1;
}
}
}
}while(flag!=0);
printf("%d\n",roop-1);
fclose(datafile);
}
int ConjugateGradient(double b[],double x[],
double G_diag[],
double sigma_row[][_n_c],double sigma_col[][_n_c],
double r[],double p[],double Ap[],
int n_dim,int n_iteration,double eps)
{
int i_dim,i_iteration;
double remnant_old,remnant_new,alpha,beta;
for(i_dim=0;i_dim<n_dim;i_dim++){
r[i_dim]=b[i_dim];
x[i_dim]=0.0;
20
p[i_dim]=r[i_dim];
}
for(i_iteration=0;i_iteration<n_iteration;i_iteration++){
remnant_new=DotProduct(r,r,n_dim);
if(remnant_new < eps){
printf("Iteration in Conjuage Gradient Converged.\n");
return 0;
break;
}
if(i_iteration>0){
beta=remnant_new/remnant_old;
for(i_dim=0;i_dim<n_dim;i_dim++)
{
p[i_dim]=r[i_dim]+beta*p[i_dim];
}
}
multiply(p,Ap,G_diag,sigma_row,sigma_col);
alpha=remnant_new/DotProduct(p,Ap,n_dim);
for(i_dim=0;i_dim<n_dim;i_dim++){
x[i_dim]+=alpha*p[i_dim];
r[i_dim]-=alpha*Ap[i_dim];
}
remnant_old=remnant_new;
}
if(i_iteration==n_iteration){
printf("Iteration in Conjuage Gradient Time Over.\n");
return 1;
}
}
21
double DotProduct(double a[],double b[],int n_dim){
int i_dim;
double product=0.0;
for(i_dim=0;i_dim<n_dim;i_dim++){
product+=a[i_dim]*b[i_dim];
}
return product;
}
void multiply(double vold[],double vnew[],
double G_diag[],
double sigma_row[][_n_c],double sigma_col[][_n_c])
{
int i_row,i_col,idim0,idim1,idim2,idim3,idim4;
for(i_row=0;i_row<_n_r;i_row++){
for(i_col=0;i_col<_n_c;i_col++){
idim0=_dim_(i_row,i_col);
vnew[idim0]=G_diag[idim0]*vold[idim0];
if(i_row<_n_r-1){
idim1=_dim_(i_row+1,i_col);
vnew[idim0]+=sigma_col[i_row+1][i_col]*vold[idim1];
}
if(i_row>0){
idim2=_dim_(i_row-1,i_col);
vnew[idim0]+=sigma_col[i_row][i_col]*vold[idim2];
}
22
idim3=_dim_(i_row,(i_col+1)%_n_c);
vnew[idim0]+=sigma_row[i_row+1][i_col]*vold[idim3];
idim4=_dim_(i_row,(i_col-1+_n_c)%_n_c);
vnew[idim0]+=sigma_row[i_row+1][(i_col-1+_n_c)%_n_c]*vold[idim4];
}
}
}
23
B 稲妻シミュレーション (ループ回数指定)#include<stdio.h>
#include<math.h>
#define SIMPLE_SPRNG
#include "sprng.h"
#define _n_r 59
#define _n_c 60
#define _max 2.0
#define syoki_M 0.0
#define phi_x 1.1
#define zoukaritsu 0.01
#define kyoukai 1.0
#define G(a,b) G[b*_n_r*_n_c+a]
#define _dim_(i_row,i_col) (i_row)*_n_c+(i_col)
int ConjugateGradient(double b[],double x[],
double G_diag[],
double sigma_row[][_n_c],double sigma_col[][_n_c],
double r[],double p[],double Ap[],
int n_dim,int n_iteration,double eps);
double DotProduct(double a[],double b[],int n_dim);
void multiply(double vold[],double vnew[],
double G_diag[],
double sigma_row[][_n_c],double sigma_col[][_n_c]);
main()
{
FILE *datafile;
24
int i,j,m,k,flag,roop,i_row,i_col,idim;
static int Fr[(_n_r+2)*_n_c],Fc[(_n_r+2)*_n_c];
static double sigma_r[_n_r+2][_n_c],dphi_r[_n_r+2][_n_c];
static double sigma_c[_n_r+1][_n_c],dphi_c[_n_r+1][_n_c];
static double syoki_m,p[_n_r*_n_c],phi[_n_r+2][_n_c];
int seed=12345;
static double G_diag[_n_r*_n_c],solution[_n_r*_n_c];
static double work1[_n_r*_n_c],work2[_n_r*_n_c],work3[_n_r*_n_c];
int info,n_iteration;
double eps;
static double vnew[_n_r*_n_c];
static double vec[_n_r*_n_c];
datafile=fopen("ransu.dat","w");
printf("deni"); scanf("%lf", &syoki_m);
m=_n_r*_n_c;
for(i=0; i<_n_c; i++){
phi[0][i]=syoki_m;
phi[_n_r+1][i]=syoki_M;
}
init_sprng(DEFAULT_RNG_TYPE,seed,SPRNG_DEFAULT);
for(j=0; j<=_n_r+1; j++){
for(i=0; i<_n_c; i++){
sigma_r[j][i]=1/(2.0+sprng()*_max);
}
}
for(j=0; j<=_n_r; j++){
for(i=0; i<_n_c; i++){
sigma_c[j][i]=1/(2.0+sprng()*_max);
}
25
}
for(k=0; k<(_n_r+2)*_n_c; k++){
Fr[k]=0;
Fc[k]=0;
}
flag=0;
roop=0;
do{
for(j=0; j<m; j++){
if(j<_n_c){
p[j]=-phi[0][j]*sigma_c[0][j];
}
else if(j>=m-_n_c){
p[j]=-phi[_n_r+1][j%_n_c]*sigma_c[_n_r][j%_n_c];
}
else{
p[j]=0.0;
}
}
for(i_row=0;i_row<_n_r;i_row++){
for(i_col=0;i_col<_n_c;i_col++){
idim=_dim_(i_row,i_col);
G_diag[idim]=-(sigma_c[i_row+1][i_col]
+sigma_c[i_row][i_col]
+sigma_r[i_row+1][i_col]
+sigma_r[i_row+1][(i_col+_n_c-1)%_n_c]);
}
}
multiply(p,vec,G_diag,sigma_r,sigma_c);
26
n_iteration=10000;
eps=1.0e-15;
info=ConjugateGradient(p,solution,
G_diag,sigma_r,sigma_c,
work1,work2,work3,
m,n_iteration,eps);
printf("INFO=%d\n",info);
flag++;
roop++;
for(j=0; j<m; j++){
phi[j/_n_c+1][j%_n_c]=solution[j];
}
for(j=0; j<=_n_r+1; j++){
for(i=0; i<_n_c; i++){
if(i!=_n_c-1){
dphi_r[j][i]=(phi[j][i]-phi[j][i+1])*(phi[j][i]-phi[j][i+1]);
if(dphi_r[j][i]>phi_x && Fr[j*_n_c+i]!=1){
sigma_r[j][i]=sigma_r[j][i]/zoukaritsu;
fprintf(datafile," %d %d\n %d %d\n &\n",i,j,i+1,j);
Fr[j*_n_c+i]=1;
}
}
else{
dphi_r[j][i]=(phi[j][i]-phi[j][0])*(phi[j][i]-phi[j][0]);
if(dphi_r[j][i]>phi_x && Fr[j*_n_c+i]!=1){
sigma_r[j][i]=sigma_r[j][i]/zoukaritsu;
fprintf(datafile," %d %d\n %d %d\n &\n",i,j,_n_c,j);
Fr[j*_n_c+i]=1;
}
}
}
27
}
for(j=0; j<=_n_r; j++){
for(i=0; i<_n_c; i++){
dphi_c[j][i]=(phi[j][i]-phi[j+1][i])*(phi[j][i]-phi[j+1][i]);
if(dphi_c[j][i]>phi_x && Fc[j*_n_c+i]!=1){
sigma_c[j][i]=sigma_c[j][i]/zoukaritsu;
fprintf(datafile," %d %d\n %d %d\n &\n",i,j,i,j+1);
Fc[j*_n_c+i]=1;
}
}
}
}while(flag<=5);
printf("%d\n",roop-1);
fclose(datafile);
}
int ConjugateGradient(double b[],double x[],
double G_diag[],
double sigma_row[][_n_c],double sigma_col[][_n_c],
double r[],double p[],double Ap[],
int n_dim,int n_iteration,double eps)
{
int i_dim,i_iteration;
double remnant_old,remnant_new,alpha,beta;
for(i_dim=0;i_dim<n_dim;i_dim++){
r[i_dim]=b[i_dim];
x[i_dim]=0.0;
p[i_dim]=r[i_dim];
}
for(i_iteration=0;i_iteration<n_iteration;i_iteration++){
28
remnant_new=DotProduct(r,r,n_dim);
if(remnant_new < eps){
printf("Iteration in Conjuage Gradient Converged.\n");
return 0;
break;
}
if(i_iteration>0){
beta=remnant_new/remnant_old;
for(i_dim=0;i_dim<n_dim;i_dim++){
p[i_dim]=r[i_dim]+beta*p[i_dim];
}
}
multiply(p,Ap,G_diag,sigma_row,sigma_col);
alpha=remnant_new/DotProduct(p,Ap,n_dim);
for(i_dim=0;i_dim<n_dim;i_dim++){
x[i_dim]+=alpha*p[i_dim];
r[i_dim]-=alpha*Ap[i_dim];
}
remnant_old=remnant_new;
}
if(i_iteration==n_iteration){
printf("Iteration in Conjuage Gradient Time Over.\n");
return 1;
}
}
double DotProduct(double a[],double b[],int n_dim){
int i_dim;
double product=0.0;
29
for(i_dim=0;i_dim<n_dim;i_dim++){
product+=a[i_dim]*b[i_dim];
}
return product;
}
void multiply(double vold[],double vnew[],
double G_diag[],
double sigma_row[][_n_c],double sigma_col[][_n_c])
{
int i_row,i_col,idim0,idim1,idim2,idim3,idim4;
for(i_row=0;i_row<_n_r;i_row++){
for(i_col=0;i_col<_n_c;i_col++){
idim0=_dim_(i_row,i_col);
vnew[idim0]=G_diag[idim0]*vold[idim0];
if(i_row<_n_r-1){
idim1=_dim_(i_row+1,i_col);
vnew[idim0]+=sigma_col[i_row+1][i_col]*vold[idim1];
}
if(i_row>0){
idim2=_dim_(i_row-1,i_col);
vnew[idim0]+=sigma_col[i_row][i_col]*vold[idim2];
}
idim3=_dim_(i_row,(i_col+1)%_n_c);
vnew[idim0]+=sigma_row[i_row+1][i_col]*vold[idim3];
idim4=_dim_(i_row,(i_col-1+_n_c)%_n_c);
vnew[idim0]+=sigma_row[i_row+1][(i_col-1+_n_c)%_n_c]*vold[idim4];
30
}
}
}
31
C ひび割れシミュレーション#include<stdio.h>
#include<math.h>
#define SIMPLE_SPRNG
#include "sprng.h"
#define _n_r 59
#define _n_c 60
#define _max 2.0
#define syoki_M 0.0
#define phi_x 1.1
#define zoukaritsu 0.01
#define kyoukai 1.0
#define G(a,b) G[b*_n_r*_n_c+a]
#define _dim_(i_row,i_col) (i_row)*_n_c+(i_col)
int ConjugateGradient(double b[],double x[],
double G_diag[],
double sigma_row[][_n_c],double sigma_col[][_n_c],
double r[],double p[],double Ap[],
int n_dim,int n_iteration,double eps);
double DotProduct(double a[],double b[],int n_dim);
void multiply(double vold[],double vnew[],
double G_diag[],
double sigma_row[][_n_c],double sigma_col[][_n_c]);
main(){
FILE *datafile;
32
int i,j,m,k,flag,roop,i_row,i_col,idim;
static int Fr[(_n_r+2)*_n_c],Fc[(_n_r+2)*_n_c];
static double sigma_r[_n_r+2][_n_c],dphi_r[_n_r+2][_n_c];
static double sigma_c[_n_r+1][_n_c],dphi_c[_n_r+1][_n_c];
static double syoki_m,p[_n_r*_n_c],phi[_n_r+2][_n_c];
int seed=1009;
static double G_diag[_n_r*_n_c],solution[_n_r*_n_c];
static double work1[_n_r*_n_c],work2[_n_r*_n_c],work3[_n_r*_n_c];
int info,n_iteration;
double eps;
static double vnew[_n_r*_n_c];
static double vec[_n_r*_n_c];
datafile=fopen("zeisei.dat","w");
printf("deni"); scanf("%lf", &syoki_m);
m=_n_r*_n_c;
for(i=0; i<_n_c; i++){
phi[0][i]=syoki_m;
phi[_n_r+1][i]=syoki_M;
}
init_sprng(DEFAULT_RNG_TYPE,seed,SPRNG_DEFAULT);
for(j=0; j<=_n_r+1; j++){
for(i=0; i<_n_c; i++){
sigma_r[j][i]=1/(2.0+sprng()*_max);
}
}
for(j=0; j<=_n_r; j++){
for(i=0; i<_n_c; i++){
sigma_c[j][i]=1/(2.0+sprng()*_max);
}
}
33
for(k=0; k<(_n_r+2)*_n_c; k++){
Fr[k]=0;
Fc[k]=0;
}
roop=0;
do{
roop++;
flag=0;
for(j=0; j<m; j++){
if(j<_n_c){
p[j]=-phi[0][j]*sigma_c[0][j];
}
else if(j>=m-_n_c){
p[j]=-phi[_n_r+1][j%_n_c]*sigma_c[_n_r][j%_n_c];
}
else{
p[j]=0.0;
}
}
for(i_row=0;i_row<_n_r;i_row++){
for(i_col=0;i_col<_n_c;i_col++){
idim=_dim_(i_row,i_col);
G_diag[idim]=-(sigma_c[i_row+1][i_col]
+sigma_c[i_row][i_col]
+sigma_r[i_row+1][i_col]
+sigma_r[i_row+1][(i_col+_n_c-1)%_n_c]);
}
}
multiply(p,vec,G_diag,sigma_r,sigma_c);
34
n_iteration=10000;
eps=1.0e-15;
info=ConjugateGradient(p,solution,
G_diag,sigma_r,sigma_c,
work1,work2,work3,
m,n_iteration,eps);
printf("INFO=%d\n",info);
for(j=0; j<m; j++){
phi[j/_n_c+1][j%_n_c]=solution[j];
}
for(j=0; j<=_n_r+1; j++){
for(i=0; i<_n_c; i++){
if(i!=_n_c-1){
dphi_r[j][i]=(phi[j][i]-phi[j][i+1])*(phi[j][i]-phi[j][i+1]);
if(dphi_r[j][i]>phi_x && Fr[j*_n_c+i]!=1){
sigma_r[j][i]=sigma_r[j][i]*zoukaritsu;
fprintf(datafile," %d %d\n %d %d\n &\n",i,j,i+1,j);
Fr[j*_n_c+i]=1;
flag=1;
}
}
else{
dphi_r[j][i]=(phi[j][i]-phi[j][0])*(phi[j][i]-phi[j][0]);
if(dphi_r[j][i]>phi_x && Fr[j*_n_c+i]!=1){
sigma_r[j][i]=sigma_r[j][i]*zoukaritsu;
fprintf(datafile," %d %d\n %d %d\n &\n",i,j,_n_c,j);
Fr[j*_n_c+i]=1;
flag=1;
35
}
}
}
}
for(j=0; j<=_n_r; j++){
for(i=0; i<_n_c; i++){
dphi_c[j][i]=(phi[j][i]-phi[j+1][i])*(phi[j][i]-phi[j+1][i]);
if(dphi_c[j][i]>phi_x && Fc[j*_n_c+i]!=1){
sigma_c[j][i]=sigma_c[j][i]*zoukaritsu;
fprintf(datafile," %d %d\n %d %d\n &\n",i,j,i,j+1);
Fc[j*_n_c+i]=1;
flag=1;
}
}
}
}while(flag!=0);
printf("%d\n",roop-1);
fclose(datafile);
}
int ConjugateGradient(double b[],double x[],
double G_diag[],
double sigma_row[][_n_c],double sigma_col[][_n_c],
double r[],double p[],double Ap[],
int n_dim,int n_iteration,double eps)
{
int i_dim,i_iteration;
double remnant_old,remnant_new,alpha,beta;
for(i_dim=0;i_dim<n_dim;i_dim++){
r[i_dim]=b[i_dim];
x[i_dim]=0.0;
36
p[i_dim]=r[i_dim];
}
for(i_iteration=0;i_iteration<n_iteration;i_iteration++){
remnant_new=DotProduct(r,r,n_dim);
if(remnant_new < eps){
printf("Iteration in Conjuage Gradient Converged.\n");
return 0;
break;
}
if(i_iteration>0){
beta=remnant_new/remnant_old;
for(i_dim=0;i_dim<n_dim;i_dim++){
p[i_dim]=r[i_dim]+beta*p[i_dim];
}
}
multiply(p,Ap,G_diag,sigma_row,sigma_col);
alpha=remnant_new/DotProduct(p,Ap,n_dim);
for(i_dim=0;i_dim<n_dim;i_dim++){
x[i_dim]+=alpha*p[i_dim];
r[i_dim]-=alpha*Ap[i_dim];
}
remnant_old=remnant_new;
}
if(i_iteration==n_iteration){
printf("Iteration in Conjuage Gradient Time Over.\n");
return 1;
}
}
37
double DotProduct(double a[],double b[],int n_dim){
int i_dim;
double product=0.0;
for(i_dim=0;i_dim<n_dim;i_dim++){
product+=a[i_dim]*b[i_dim];
}
return product;
}
void multiply(double vold[],double vnew[],
double G_diag[],
double sigma_row[][_n_c],double sigma_col[][_n_c]){
int i_row,i_col,idim0,idim1,idim2,idim3,idim4;
for(i_row=0;i_row<_n_r;i_row++){
for(i_col=0;i_col<_n_c;i_col++){
idim0=_dim_(i_row,i_col);
vnew[idim0]=G_diag[idim0]*vold[idim0];
if(i_row<_n_r-1){
idim1=_dim_(i_row+1,i_col);
vnew[idim0]+=sigma_col[i_row+1][i_col]*vold[idim1];
}
if(i_row>0){
idim2=_dim_(i_row-1,i_col);
vnew[idim0]+=sigma_col[i_row][i_col]*vold[idim2];
}
idim3=_dim_(i_row,(i_col+1)%_n_c);
vnew[idim0]+=sigma_row[i_row+1][i_col]*vold[idim3];
38
idim4=_dim_(i_row,(i_col-1+_n_c)%_n_c);
vnew[idim0]+=sigma_row[i_row+1][(i_col-1+_n_c)%_n_c]*vold[idim4];
}
}
}
39