SSブログ

[境界要素法プログラムを設計する(入力部の実装)] [境界要素法]

[境界要素法プログラムを設計する(入力部の実装)]

 

bem9-fig-001.png

bem9-fig-002.png

1.なぜ入力部からなのか?

 なぜ入力部から作るんでしょうか?。開発環境のコンパイラーにしてみれば、エラーが出ない限り、どっから手を付けられたってオッケーなはずです。だからこれは、人間の都合なんですよ。

 

 一つは[入力部]→[計算部]→[出力部]の順に作って行くと、プログラムが完成した暁の実際の動作をプログラミング中にシミュレートする事になり、人間としては大変に考えやすい(^^)

 二つ目はテストのやりやすさです。[入力部]→[計算部]と作って行けば、[計算部]が上がった時点で一応のテストが可能になります。「開発サイクルは出来るだけ短く」です(^^)。それに一番間違えやすそうなのは、[計算部]に決まってます。[計算部]はできるだけ早くテストしたいし、ここがほとんどプログラムの核心です。そのテストの具合によっては[入力部]の仕様変更だってありえます。

 

 以上は三層開発モデルの考え方に近いです。そこでは[入力部][計算部][出力部]は、[インターフェイス層][ビジネスルール層][データベース層]と難しそうに名を変えますが、結局やる事は同じなんですよ。

 オブジェクトプログラミングの基本作法とか称して、三層開発モデルみたいな小難しいものに出会った事があるかも知れませんが、言ってる事はものすごく当たり前の事です。当たり前の事を誰も素直にやろうとしないから、そういう開発モデルが提唱されただけなんです。それはISOも同じです(^^;)

 

 余談ですが業務アプリの開発では、[入力部][計算部][出力部]を同時並行に開発する事もあります。エッ?できるの?って気もしますが(^^;)、例えば[計算部]にとって[入力部]は一種の外部環境です。そこでモックと呼ばれる仮想オブジェクトを作り、[入力部]の仕様をモックでシミュレートして[入力部]が作ったかのような外部データを[計算部]に渡しテストする訳です。ただこれは、相当な金と時間とマンパワー(と優秀な人材)がないと、ほとんど実現不可能です。ここではやらないのが無難ですな(^^;)

 

 ちなみにプログラムを書くことを実装と言います。実装で行われる作業全体の事を製造と言ったりします。

 

 

2.入力部の実装

 前回の[メモ欄][宣言部]を参照しつつ、[入力部]の冒頭に書いてある事を読みます。その冒頭には、

 

REM境界要素数B_Countと領域要素数R_Countは、事前に与えられると仮定する。

REM 境界要素と領域要素データは、要素ごとに節点番号が与えられると仮定する。

REM 与えられる節点番号は、左回りに順序付けられたものが与えられると仮定する。

 

とあり、その直後には、

 

REM 境界要素を要素番号kで読み込むLoop

REM  Loop内で要素ごとの節点番号を読み、境界要素-節点対応表EN_B(k2)をセット

 

とあります。

 

 いま本当に具体的な入力ルーティンは書けないのですが、最初の仮定通りのものが既にあるのなら、EN_B(k2)のセットは、以下です。ただし代入文のLETは省略してます(面倒なので)。後で補充して下さい(^^;)

 

For k = 1 to B_Count

EN_B(k1) =

EN_B(k2) =

Next k

 

となります。ここで「?」は、最初の仮定により与えられる値です。でも図-1を見れば、EN_B(k1) = kEN_B(k2) = k+1k = B_Countの時はEN_B(k2) = 1、ってのがわかります。こういう風に与えてもOKなんですが個人的には、事前にちゃんと「?」のデータを作る事をお奨めします。

 

 

次の、

 

REM 領域要素を要素番号kで読み込むLoop

REM  Loop内で要素ごとの節点番号を読み、領域要素-節点対応表EN_R(k4)をセット

 

も同様です。これは図-2のように、領域要素が4角形要素を想定したケースです。

 

For k = 1 to R_Count

For j = 1 to 4

EN_R(kj) =

Next j

Next k

 

 

 後も同様なので、直接[入力部]にコードを書き込んで、今回は終了します。

REM [メモ欄]

 

REM B_Count:境界要素数

REM EN_B(k2):境界要素-節点対応表,k=1B_Count

REM (k1):要素kの始端の節点No.(k2):終端の節点No.

 

REM R_Count:領域要素数,Region Elements Countの略

REM EN_R(k4):領域要素-節点対応表,k=1R_Count

REM (kj)j=14jに従って要素kの要素節点No.を左回りに格納

 

REM BN_Count:境界節点数

REM BN(j2):境界節点座標,j=1BN_Count(j1):節点jx座標,(j2)y座標

REM RN_Count:領域節点数

REM RN(j2):領域節点座標,j=1RN_Count(j1):節点jx座標,(j2)y座標

 

REM BN_BP(j2):節点の境界条件の有無,j=1BN_Count

REM (j1):節点jψjが既知なら1、そうでないなら0

REM (j2):節点jqjが既知なら1、そうでないなら0

 

REM BN_BV(j2):境界条件の値,j=1BN_Count

REM (j1):節点jψjに与える値

REM (j2):節点jqjに与える値

 

REM z(i):未知ベクトル,i=12*BN_Count

REM BN_Z(j2):節点-未知数対応表,j=1BN_Count

REM (j1)ψjzの中の位置,(j2)qjzの中の位置

REM 節点j→ψj→z(j),節点j→qj→z(BN_Count+j)

 

 

REM [宣言部]

REM 配列寸法の上限は1000

 

REM B_Count:境界要素数

REM R_Count:領域要素数

Dim EN_B(10002) REM 境界要素-節点対応表,k=1B_Count

Dim EN_R(10004) REM 領域要素-節点対応表,k=1R_Count

 

REM BN_Count:境界節点数

REM RN_Count:領域節点数

Dim BN(10002) REM 境界節点座標,j=1BN_Count

Dim RN(10002) REM 領域節点座標,j=1RN_Count

 

Dim BN_BP(10002) REM 節点の境界条件の有無,j=1BN_Count

Dim BN_BV(10002) REM 境界条件の値,j=1BN_Count

 

Dim BN_Z(10002) REM 節点-未知数対応表,j=1BN_Count

 

Dim z(1000) REM 未知ベクトル,i=12*BN_Count

 

 

REM [入力部]

 

REM境界要素数B_Countと領域要素数R_Countは、事前に与えられると仮定する。

REM 境界要素と領域要素データは、要素ごとに節点番号が与えられると仮定する。

REM 与えられる節点番号は、左回りに順序付けられたものが与えられると仮定する。

 

REM 境界要素を要素番号kで読み込むLoop

REM  Loop内で要素ごとの節点番号を読み、境界要素-節点対応表EN_B(k2)をセット

 

For k = 1 to B_Count

EN_B(k1) =

EN_B(k2) =

Next k

 

REM 領域要素を要素番号kで読み込むLoop

REM  Loop内で要素ごとの節点番号を読み、領域要素-節点対応表EN_R(k4)をセット

 

For k = 1 to R_Count

For j = 1 to 4

EN_R(kj) =

Next j

Next k

 

REM境界節点数BN_Countと領域節点数RN_Countは、事前に与えられると仮定する。

 

REM 境界節点を節点番号jで読み込むLoop

REM   Loop内で境界節点座標を読み、BN(j2)をセット

 

For j = 1 to BN_Count

BN(j1) =

BN(j2) =

Next j

 

REM 領域節点を節点番号jで読み込むLoop

REM   Loop内で領域節点座標を読み、RN(j2)をセット

 

For j = 1 to RN_Count

RN(j1) =

RN(j2) =

Next j

 

 

REM 境界条件の場所を節点番号jで読み込むLoop

REM  Loop内で節点jの境界条件の有無を読み、BN_BP(j2)をセット

 

For j = 1 to BN_Count

BN_BP(j1) =

BN_BP(j2) =

Next j

 

REM 境界条件の値を節点番号jで読み込むLoop

REM  Loop内で節点jの境界条件の値を読み、BN_BV(j2)をセット

 

For j = 1 to BN_Count

BN_BV(j1) =

BN_BV(j2) =

Next j

 

REM 節点番号jLoopで、節点-未知数対応表BN_Z(j2)をセット

REM (j1)ψjzの中の位置,(j2)qjzの中の位置

REM 対応は、節点j→ψj→z(j),節点j→qj→z(BN_Count+j)

 

For j = 1 to BN_Count

BN_Z(j1) = j

BN_Z(j2) = BN_Count + j

Next j

 

 

REM [計算部]

 

REM 境界要素番号kで境界積分を行うLoop

REM  要素番号kからEN_B(k2)に従い節点を特定し、要素ごとに境界積分を実行

REM  上記結果に基づき、係数マトリックスBHを作成

 

REM 領域要素番号kで領域積分を行うLoop

REM  要素番号kからEN_R(k4)に従い節点を特定し、要素ごとに領域積分を実行

REM  上記結果に基づき、既知ベクトルwを作成

 

REM 境界節点番号jで境界条件位置を指定するLoop

REM  節点番号jからBN_BP(j2)BN_Z(j2) に従い、(D1 D2)ブロックを作成

REM  節点番号jに従いBN_BV(j2)の値をwブロックの後に並べ、(d1 d2)ブロックを作成

 

REM 全体係数行列が出来たので、Gaussの掃き出し法にかけ、未知ベクトルzを求める

 

 

REM [出力部]

 

REM BN_Z(j2) に従いz(j)から値を読み出し、出力

 

(執筆 ddt³さん)

 


nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。