はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 . . 第 7 章 有限要素法のプログラミング 畔上 秀幸 名古屋大学 情報科学研究科 複雑系科学専攻 December 18, 2014 . . . . . . 1 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.1 はじめに (目標) 2 次元 Poisson 問題を有限要素法で解くためのプログラムの 構成について理解する. . . . . . . 2 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.2 有限要素法プログラムの構成 有限要素法プログラムの具体例をみてみよう.授業のウェブページに あるファイル femfp.c は,テキスト [1] のプログラムを基にして作成さ れた.図のような関数で構成されている. main( ) input( ) assem( ) ecm( ) solve( ) gs{solve( ) f( ) output( ) . . . . . . 3 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.3 ファイル入出力関数 . fopen() . #include <stdio.h> FILE *fopen(char *fname, char *mode); • fname のファイルを mode (下表) にしたがって開く. • 返却値は,成功したときファイルの番号,失敗したとき NULL と なる. mode r r+ w w+ a a . 作用 テキストの読み込み テキストの読み書き テキストの書き込み テキストの読み書き テキストの追加書き込み テキストの読み書き mode rb rb+ wb wb+ ab ab+ 作用 バイナリの読み込み バイナリファイルの読み書き バイナリの書き込み バイナリの読み書き バイナリの追加書き込み バイナリの読み書き . . . . . . 4 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.3 ファイル入出力関数 (cnt.) . fclose() . #include <stdio.h> int fclose(FILE *fp); • fopen で開いたファイル fp を閉じる. . • 返却値は,成功したとき 0,失敗したとき EOF となる. . fprintf() . include <stdio.h> int fprintf(FILE *fp, char *fmt,...); • ファイル fp に対して,書式付き文字列 fmt を書き込む. • 返却値は,成功したとき出力した文字数,失敗したときは負の数と . なる. . . . . . . 5 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.3 ファイル入出力関数 (cnt.) . fputs() . #include <stdio.h> int fputs(char *string, FILE *fp); • ファイル fp に対して,文字列 string を書き込む. . • 返却値は,成功したとき 0,失敗したとき EOF となる. . fgets() . #include <stdio.h> char *fgets(char *string, int n, FILE *fp); • ファイル fp に対して,文字列 string を読み込む. . • 返却値は,成功したとき 0,失敗したとき EOF となる. . . . . . . 6 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム 具体的な記述をみてみよう. . main() . /* The Finite Element Method for the Poisson Equation */ /* Full Matrix Version */ /* The Gauss Elimination Method */ #include <stdio.h> #include <stdlib.h> #include <math.h> #define NDIM1 200 #define NDIM2 400 . . . . . . . 7 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . void input(int *nnode, int *nelmt, int *nbc, int ielmt[][3], double x[], double y[], int ibc[]); void assem(int nnode, int nelmt, int nbc, int ielmt[][3], double x[], double y[], int ibc[], double am[][NDIM1], double fm[]); void ecm(int ielmt[][3], double x[], double y[], int ie, double ae[][3], double fe[]); void solve(int m, double a[][NDIM1], double f[]); void gs_solve(int m, double a[][NDIM1], double f[]); void output(double fm[], int nnode, double x[], double y[]); double f(double x, double y); . . . . . . . 8 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . /* Main Program */ int main() { int nnode, nelmt, nbc, ielmt[NDIM2][3], ibc[NDIM1]; double am[NDIM1][NDIM1], fm[NDIM1], x[NDIM1], y[NDIM1]; input(&nnode, &nelmt, &nbc, ielmt, x, y, ibc); assem(nnode, nelmt, nbc, ielmt, x, y, ibc, am, fm); solve(nnode, am, fm); //gs_solve(nnode, am, fm); output(fm, nnode, x, y); return(EXIT_SUCCESS); } . テキスト [1] からの修正: • void output(double fm[], int nnode, double x[], double y[]); • output(fm, nnode, x, y); . . . . . . 9 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . input() . /* Input */ void input(int *nnode, int *nelmt, int *nbc, int ielmt[][3], double x[], double y[], int ibc[]) { int j; FILE *fpin, *fpout; . if((fpin=fopen("indata.txt","r")) == NULL){ printf("入力データファイルが見つかりません.\n"); exit(EXIT_FAILURE); } if((fpout=fopen("outdata.txt","w")) == NULL){ fclose(fpin); printf("出力データファイルが作成できません.\n"); exit(EXIT_FAILURE); } . . . . . . 10 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . . /* Input of Data */ printf("Input (nnode, nelmt, nbc): "); fscanf(fpin, "%d%d%d", nnode, nelmt, nbc); printf("\nInput(x,y) of node i: \n"); for(j=0; j<*nnode; j++){ printf(" for i=%d: \n", j+1); fscanf(fpin, "%lg%lg", &(x[j]), &(y[j])); } printf("Input(1st, 2nd, 3rd) nodes of element i: \n"); for(j=0; j<*nelmt; j++){ printf(" for i=%d: \n", j+1); fscanf(fpin, "%d%d%d", &(ielmt[j][0]), &(ielmt[j][1]), &(ielmt[j][2])); } . . . . . . 11 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . . if(*nbc>0){ printf("Input nodes with zero Dirichlet data"); printf(" for i=1 to %d: ", *nbc); for(j=0; j<*nbc; j++) fscanf(fpin, "%d", &(ibc[j])); } printf("\n"); printf("Nodes of elements \n"); for(j=0; j<2; j++) printf(" i i1 i2 i3 "); printf("\n"); for(j=0; j<*nelmt; j+=2){ printf("*%4d*%4d%4d%4d ", j+1, ielmt[j][0], ielmt[j][1], ielmt[j][2]); if(j<*nelmt-1) printf("*%4d*%4d%4d%4d", j+2, ielmt[j+1][0], ielmt[j+1][1], ielmt[j+1][2]); printf("\n"); } . . . . . . 12 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . if(*nbc>0){ printf("Nodes with zero Dirichlet data \n"); for(j=0; j<*nbc; j++) printf("%4d", ibc[j]); printf("\n"); } } . テキスト [1] からの修正: • FILE *fpin, *fpout; ... • 入力ファイル名: indata.txt, 出力ファイル名: outdata.txt • fscanf(fpin, ... . . . . . . 13 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . assem() . /* The Direct Stiffness Method */ void assem(int nnode, int nelmt, int nbc, int ielmt[][3], double x[], double y[], int ibc[], double am[NDIM1][NDIM1], double fm[]) { int i, j, ie, ii, jj; double ae[3][3], fe[3]; . /* Initial Clear */ for(i=0; i<nnode; i++){ fm[i]=0.0; for(j=0; j<nnode; j++) am[i][j]=0.0; } . . . . . . 14 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . . /* Assemblage of Total Matrix and Vector */ for(ie=0; ie<nelmt; ie++){ ecm(ielmt, x, y, ie, ae, fe); for(i=0; i<3; i++){ ii=ielmt[ie][i]-1; fm[ii]+=fe[i]; for(j=0; j<3; j++){ jj=ielmt[ie][j]-1; am[ii][jj]+=ae[i][j]; } } } . . . . . . 15 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . /* The Homogeneous Dirichlet Condition */ if (nbc!=0){ for(i=0;i<nbc; i++){ ii=ibc[i]-1; fm[ii]=0.0; for(j=0; j<nnode;j++){ am[ii][j]=0.0; am[j][ii]=0.0; } am[ii][ii]=1.0; } } } . . . . . . . 16 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . ecm() . /* Element Coeffcient Matrix and Free Vector */ void ecm(int ielmt[][3], double x[], double y[], int ie, double ae[][3], double fe[]) { int i, j, k; double d, s, xe[3], ye[3], b[3], c[3]; . for(i=0; i<3;i++){ j=ielmt[ie][i]-1; xe[i]=x[j]; ye[i]=y[j]; } d=xe[0]*(ye[1]-ye[2])+xe[1]*(ye[2]-ye[0]) +xe[2]*(ye[0]-ye[1]); s=fabs(d)/2.0; . . . . . . 17 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . /* Calculation of Element Coefficient Matrix */ for(i=0; i<3; i++){ j=i+1; if(i==2) j=0; k=i-1; if(i==0) k=2; b[i]=(ye[j]-ye[k])/d; c[i]=(xe[k]-xe[j])/d; } for(i=0; i<3; i++){ for(j=0; j<3; j++) ae[i][j]=s*(b[j]*b[i]+c[j]*c[i]); } /* Calculation of Element Free Vector */ for(i=0; i<3; i++) fe[i]=s*f(xe[i], ye[i])/3.0; } . . . . . . . 18 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . solve() . /* The Gauss Elimination Method */ void solve(int m, double a[][NDIM1], double f[]) /* m=number of unknowns */ { int i, j, k; double aa; . /* Forward Elimination */ for(i=0; i<m-1; i++){ for(j=i+1; j<m; j++){ aa=a[j][i]/a[i][i]; f[j]-=aa*f[i]; for(k=i+1; k<m; k++) a[j][k]-=aa*a[i][k]; } } . . . . . . 19 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . /* Backward Substitution */ f[m-1]/=a[m-1][m-1]; for(i=m-2; i>=0; i--){ for(j=i+1; j<m; j++) f[i]-=a[i][j]*f[j]; f[i]/=a[i][i]; } } . . . . . . . 20 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) テキスト [1] からの修正: gs solve() を追加 . gs solve() . /* The Gauss Seidel Method */ void gs_solve(int m, double a[][NDIM1], double f[]) { int i, j, k; double aa = 0.0; double u[NDIM1],u_old[NDIM1]; double max_delta=0.0, max_delta_old; double max_u=0.0; int count = 0; for(i=0; i<m; i++){ u[i] = 0.0; } . . . . . . . 21 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . do{ max_delta_old = max_delta; for(i=0; i<m; i++){ u_old[i] = u[i]; } . for(i=0; i<m; i++){ aa = 0.0; for(j=0; j<m; j++){ if(i != j){ aa += a[i][j]*u[j]; } } u[i]=(f[i] - aa)/a[i][i]; } . . . . . . 22 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . max_delta = fabs(u[0] - u_old[0]); for(i=1; i<m; i++){ if(max_delta < fabs(u[i] - u_old[i])){ max_delta = fabs(u[i] - u_old[i]); } } . max_u = fabs(u[0]); for(i=1; i<m; i++){ if(max_u < fabs(u[i])){ max_u = fabs(u[i]); } } . . . . . . 23 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . count++; }while(fabs((max_delta - max_delta_old)/max_u) >= 1.0E-5); printf("count = %d\n",count); for(i=0; i<m; i++){ f[i] = u[i]; } } . . . . . . . 24 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . output() . /* 0utput of Approximate Nodal Values of u */ void output(double fm[], int nnode, double x[], double y[]) { int j,m; FILE *fpout; . if((fpout=fopen("outdata.txt","a")) == NULL){ printf("出力データファイルが作成できません.\n"); exit(EXIT_FAILURE); } . . . . . . 25 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . fprintf(fpout, "\nNodal values of u\n"); fprintf(fpout, " i u \n"); for(j=0; j<nnode; j++) fprintf(fpout, "%4d%12.3e\n", j+1, fm[j]); fprintf(fpout, "\nMathematica 6 Data\n"); fprintf(fpout, "ListPlot3D[{\n"); for(j=0; j<nnode-1; j++){ fprintf(fpout, "{%f, %f, %f},\n", x[j], y[j], fm[j]); } fprintf(fpout, "{%f, %f, %f}\n}, Mesh -> All]\n", x[j], y[j], fm[j]); fclose(fpout); } . テキスト [1] からの修正: FILE *fpout; ... . . . . . . 26 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.4 有限要素法プログラム (cnt.) . f() . /* Function for Free Term */ double f(double x, double y) { return(1.0); } . . . . . . . 27 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.5 入出力データ . indata.txt . 9 8 5 0 0 0 0.5 0 1 0.5 0 0.5 0.5 0.5 1 1 0 1 0.5 1 1 1 4 5 1 5 2 2 5 6 2 6 3 4 7 8 4 8 5 5 8 9 5 9 6 1 . 2 3 4 7 . outdata.txt . Basic data nnode = 9 nelmt = 8 nbc = 5 x,y-coordinates of nodes i x(i) y(i) 1 0.0000 0.0000 2 0.0000 0.5000 3 0.0000 1.0000 4 0.5000 0.0000 5 0.5000 0.5000 6 0.5000 1.0000 7 1.0000 0.0000 8 1.0000 0.5000 . 9 1.0000 1.0000 . Nodes of elements i i1 i2 i3 1 1 4 5 2 1 5 2 3 2 5 6 4 2 6 3 5 4 7 8 6 4 8 5 7 5 8 9 5 9 6 . 8 . . . . . . 28 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.5 入出力データ (cnt.) . Nodes with zero Dirichlet data 1 2 3 4 7 Nodal i 1 2 3 4 5 6 7 8 . 9 values of u u 0.000e+000 0.000e+000 0.000e+000 0.000e+000 1.771e-001 2.292e-001 0.000e+000 2.292e-001 3.125e-001 . Mathematica 6 Data ListPlot3D[{ {0.000000, 0.000000, {0.000000, 0.500000, {0.000000, 1.000000, {0.500000, 0.000000, {0.500000, 0.500000, {0.500000, 1.000000, {1.000000, 0.000000, {1.000000, 0.500000, {1.000000, 1.000000, }, . Mesh -> All] . . . 0.000000}, 0.000000}, 0.000000}, 0.000000}, 0.177083}, 0.229167}, 0.000000}, 0.229167}, 0.312500} . . . 29 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.5 入出力データ (cnt.) Mathematica を立ち上げ,outdata.txt の ListPlot3D[...] を貼り付け, Shift + Enter により,近似関数を可視化できる. 0.3 1.0 0.2 0.1 0.0 0.5 0.0 0.5 1.0 0.0 . . . . . . 30 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.6 演習問題 1. 教材のプログラムを用いて 2 次元 Poisson 問題の数値解を計算し, Mathematica を用いて結果を図示せよ.ただし,図のような要素分 割を用いよ.基本境界条件と自然境界条件は任意に設定してよい. . . . . . . 31 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.6 演習問題 (cnt.) 2. 授業のウェブページにあるファイル indata 105.txt は,メッシュ作 成プログラムによって,図のようなメッシュを作成し,femfp.c の 入力形式に合わせたデータである.femfp.c で解析し,結果を確認 せよ. . . . . . . 32 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 §7.7 まとめ 2 次元 Poisson 問題を有限要素法で解くためのプログラムの構成につ いてみてきた. 1. 2. 3. 4. C 言語で書かれたプログラムは,コンパイル,リンクの手続きによ り実行可能なプログラムが作成される. C プログラムの一般形式は関数で構成される. 有限要素法プログラムは,入力,要素係数行列の作成,全体係数行 列の作成,既知項ベクトルの作成,連立 1 次方程式のソルバー,出 力の関数で構成される. 有限要素法プログラムの入力データ形式に合わせて入力ファイルを 作成し,有限要素法プログラムの実行ファイルを走らせて,数値解 が得られることを確認した. . . . . . . 33 / 34 はじめに 有限要素法プログラムの構成 ファイル入出力関数 有限要素法プログラム 入出力データ 演習問題 まとめ 参考文献 参考文献 [1] 菊地文雄. 有限要素法概説 : 理工学における基礎と応用. サイエンス社, 1980. . . . . . . 34 / 34
© Copyright 2024 ExpyDoc