OpenSees Blog 日本語 目次

最初に「このブログをみるためのガイド」をご覧ください。

Update中OpenSees コマンド 日本語解説 の 目次 OpenSeesコマンド はじめての方は「ここから
このblogで使用しているOpenSeesコマンド集は「ここ」 Update中
OpenSees のソースコード 解析に挑戦してみる 目次最初のページは「ソースコードのダウンロードとビルド」
Appendix:C言語での 「有限要素法における平面トラスの解析」目次最初のページは「Microsoft Visual Studioの導入方法」







目次の中で、更新したページにはNewがついています

このブログ内の単語を検索したい場合は、左上OpenSeesロゴの上に検索窓から検索できます。


2015年1月8日木曜日

FORTRAN77言語とC言語の基本的な相違点 (2)

FORTRAN77言語とC言語の基本的な相違点 (1) の各行についての解説です。


# Fortran C
1 bool MxM(double** M1, double** M2, double** Mout, int n);
Cでは、使うサブルーチンの宣言をあらかじめ行う必要があります。
もしこのサブルーチンが、複数のファイル(cpp)で使用される場合は、この宣言をヘッダーファイルとして作成します。そして
#include <xxxxx.h>
を、各ファイルの先頭に記載すれば、書き間違いのリスクを減らすことができます
2 DIMENSION A(2,2), B(2,2), C(2,2) int n=2;
double **A;
double **B;
double **C;
FortranではDimension をあらかじめ 2 と固定しています、Cでは Dimension であることのみを宣言して、大きさは指定していません。
Cでは、コンピュータのメモリを有効利用するために、Dimensionの大きさを可変に設定することができます。
そのため、プログラムの途中で、Dimensionの大きさが初めて決定するようなものでも、「とりあえず巨大にDimensionを取っておけば良いかな」ということで、使わないメモリ領域をあらかじめとっておく必要がなく、メモリが必要になったらその都度Dimensionの大きさを設定すればよいので、メモリ使用が経済的(ww)です
3 bool ret;
bool はbooleanで真(true)と偽(false)の2種類の値だけを扱います。
ここでは、MxMのサブルーチンの中で、Dimensionの大きさが0以下だった場合はfalseとしました。
4 A = (double **)(malloc (sizeof(double*) * n));
for (int i = 0; i < n; i++)
A[i] = (double )malloc(sizeof(double) * n);
2では シンボルAがDimensionであることを宣言していますが、その大きさを設定しているのがこの行です。
なお、ここで使用しているmalloc()関数は、最初のinclude文、
#include <malloc>
の中で宣言されています。
5 A(1,1)=1;
A(1,2)=2;
A(2,1)=3;
A(2,2)=4
A[0][0]=1;
A[0][1]=2;
A[1][0]=3;
A[1][1]=4;
ここではDimensionに値を入れていますが
の行列の入力の方法に注意をする必要があります。
FORTRANでは2の大きさのDimensionでは、1から2の成分となりますが、Cでは2の大きさのDimensionでは0から1の成分となります。
これはグラフのX,Y軸の使い方と同じで、0 origin と考えるとわかりやすいです。
6   DO l I=1,2
      DO 2 J=1,2
          C(I,J)=0.0;
2   CONTINUE
1 CONIINUE
for (int j = 0; j < n; j++) {
    for (int i = 0; i < n; i++) {
         C[j][i] = 0.0;
    }
}
FORTRANでのDOループは、Cでのfor文となります。
DOループでは、どこまでループさせるかを行番号とCONTINUで表示していますが、Cではfor文の範囲を{ }カギかっこで指定します。
また、FORTRANでは、I=1,2ということで、I を1から2まで変位させていますが、for文では、
for (int j = 0; j < n; j++)
integer宣言したj、初期値0を、jがnより小さい間だけ、jを1ずつ大きくしてゆく
  と、書きます。ここでnは、2なので、jは0,1 と変位することになります
7 CALL MXM(A, B, C, 2) ret=MxM(A, B, C, n);
FORTRANではサブルーチンを呼ぶときはCALL文を使用しますが、Cでは、そのままのfunctionとして使用します。
このfunctionは、1 で宣言されています
8 if (A) {
      for (int i = 0; i < n; i++) {
              if (A[i])
                  free(A[i]);
              }
        }
 free(A);
Cでは、いつでも自由にDimensionの大きさを設定できることを4で記載しましたが、使わなくなったDimension:メモリ空間を解放する必要があります。
なおプログラムが終了すれば、すべてのメモリ空間は解放されます。
プログラムの途中で使用しなくなったメモリ空間を解放できるので、プログラムのほかのシンボルが空いたメモリ空間を使用できるようにできるため、経済的(?)です。
大きなDimensionを使うプログラムでブルースクリーンになったり、プログラムが吹っ飛ぶのは、大概メモリの使い過ぎなので、これを使用して、こまめにメモリを解放してあげると、プログラムの安定性がでてきます。
なお、ここで使用しているfree()関数は、最初のinclude文、 #include の中で宣言されています。
9 // ------------SUB ROUTINE MXM -------
SUBROUTIN MXM(A,B,C,N)
DIMENSION A(N,N), B(N,N), C(N,N)
INTEGER I,J,K
DOUBLE PRECISION S

//A x B
DO l I=1,N
   DO 2 J=1,N
      S=0.0
      DO 6 K=1,N
         S=S+A(I,K) * B(K,J)
      3 CONTINUE
      C(I,J)=S
   2 CONTINUE
1 CONIINUE
RETURN
END
//----------------------------------------
// Sub routine M x M
//----------------------------------------
bool MxM(double** M1, double** M2, double** Mout, int n)
{
double s;
if(n<1)
 return false;
//M1 x M2
for (int i = 0; i < n; i++) {
 for (int j = 0; j < n; j++) {
  s=0.0;
  for (int k = 0; k < n; k++) {
   s=s + M1[i][k] * M2[k][j];
  }
  Mout[i][j]=s;
 }
}
return true;
}
サブルーチンについては、行列をポインタとして渡す(C言語)か、シンボルとして渡す(FORTRAN)かの他には、すでに説明した通りです







































































































次のページ →
C言語での特徴


「有限要素法における平面トラスの解析」プログラムをC言語で書いてみる : 目次

0 件のコメント:

コメントを投稿