5.離散化解析の変位計算

5-1 プログラム構造

 1次の変位場を有するHPMの弾性解の精度は,定ひずみ要素によるFEMの変位解と同程度の精度を有しており,弾性解析にも利用することはできる.しかし,HPMは進行型の破壊を扱う強材料非線問題に対する解析用のモデルであり,その特徴を理解するためには非線形解析法を含めて説明する必要がある.
 さて,本書におけるサンプル・プログラムは3.4節において説明した荷重増分法のうち,山田の方法を用いている.図5.1は解析のフローを示した図である.

$\hspace{0em}$図5.1 変位・応力計算のフロー標
弾性解析では,荷重増分に関する繰り返し計算やメカニズム・チェック,除荷の判定などが無く,要素剛性行列とペナルティ係数行列を作成しこれを解いて変位を求める.次いで,この結果を利用し単位面積当りの表面力や領域内応力を計算し,結果を出力して終了である.
 一方,材料非線形解析では各種の判定や,荷重増分に伴ういくつかの繰り返し計算が必要となる.図に示す荷重増分に関するループは本来なくてもよいもので,$r_{\rm min}$ が1になるまで繰り返し計算を行つていればよい.このようなループを設けた理由は,崩壊時近傍の荷重状態において $r_{\rm min}$ が1に収束しにくくなり,計算が暴走するのを防ぐためである.
 次に,連立一次方程式を解いて変位を求めるが,この方程式は,領域内の剛性行列と付帯条件によるペナルティ係数行列から構成されている.これらの行列は,3.2節,3.3節で説明したように,それぞれの破壊条件に対して,弾性状態と破壊状態に分けて考える必要がある.
 このようにして求まった連立一次方程式を解いて得られた変位は,山田の方法による荷重増分法では仮の増分変位で,求まった値に荷重増分率がかかった値が今回の増分変位となる.これは,3.4節で説明したように非線形問題を各荷重増分段階において線形に置換し,それぞれの荷重増分段階で線形計算を行つているためである.
 構造物が崩壊機構を形成すれば,連立方程式が解けなくなり,計算を終了させることができるが,そのような状態に至らないまでも変位が急増し,その後の計算にあまり意味がないような場合には計算を強制的に終了させた方がよい.このようなメカニズム・チェックの方法には最大変位を調べる方法や,荷重変位曲線の勾配を調べる方法などがあるが,本サンプルプログラムでは前者の最大変位をチェックしている.この方法を用いる場合は $r_{\rm min}$ 倍された後の全変位で行わない方がよい.これは,仮の増分変位が大きくても荷重増分率が極端に小さいと,両者を掛け合わせた今回の増分変位が小さくなり,前回の変位に増分変位を加えた全変位が前回とあまり変わらなくなるためである.崩壊荷重時近傍ではこのような現象がたびたび生じるため,メカニズム・チェックは何らかの方法で必ず組み込んでおいた方がよいであろう.
 非線形解析のもう一つの特徴として,除荷,負荷がある.この過程を設けていないと崩壊荷重や極限荷重が実際と異なって求まることがある.特にHPMではペナルティ境界辺を切断したりするため,除荷を認めておかないと,除荷が発生した場合,本来と異なった構造を解いていることになる.通常の単調載荷の場合にはあまり除荷は発生しないが,得られる解の信頼性を増すためにもこの過程は組み込んでおく必要がある.なお,本プログラムでは除荷発生後,ペナルティ関数を弾性状態に戻して再計算を行うようにしている.
 最後に,荷重増分率を計算し,全変位及び全表面力・全応力を求め,それを今回の値として破壊状態を調べる.荷重増分率の累計が1になったら,全荷重が作用し終わったものとして計算を終了させる.荷重増分率が1以下ならさらに載荷を行い上記と同様な手順を繰り返す.
 このような計算の流れをプログラム化したものがプログラム5.1である.個々の副プログラムについては付録に掲載しているので参考にされたい.なお,変数として(NonLinear%rmin)があるが,これは荷重増分率 を累積した値が設定されている.
プログラム5.1 変位表面力計算のコントロール(Analysis)
524 !========================================================================== 572 SUBROUTINE Analysis( Node, Element, Material, Spring, Load, Boundary, & 573 Nonlinear, Solver, File) 574 575 TYPE(typeNode), INTENT(IN) :: Node 576 TYPE(typeElement), INTENT(INOUT) :: Element 577 TYPE(typeMaterial), INTENT(IN) :: Material 578 TYPE(typeSpring), INTENT(INOUT) :: Spring 579 TYPE(typeLoad), INTENT(IN) :: Load 580 TYPE(typeBoundary), INTENT(INOUT) :: Boundary 581 TYPE(typeNonLinear),INTENT(INOUT) :: NonLinear 582 TYPE(typeBand), INTENT(INOUT) :: Solver 583 TYPE(typeFile), INTENT(IN) :: File 584 INTEGER :: iste,jramc,jramd,error 585 586 Nonlinear%rmin = 0.D0 587 CALL ClearArray(Element,Spring) 588 CALL formLoad(Node,Element,Material,Load,Boundary,Line) 589 iste = 0 590 Iteration : DO WHILE(.TRUE.) 591 iste = iste + 1 592 jramc = 0 593 jramd = 1 594 ! unloading & loading again iteration ===> 595 Unload : DO WHILE( jramd == 1) 596 Solver%stiff = 0.D0 597 Solver%load = Element%load 598 CALL formElemStiff(Node,Element,Material,Solver) 599 CALL formStiff(Node,Element,Material,Spring,Line,Solver) 600 CALL setBoundary(Node,Element,Spring,Boundary,Line,Solver) 601 CALL Solve(Solver%no,Solver%width,Solver%stiff,Solver%load,error) 602 Element%ddisp = Solver%load 603 IF(.not. MechanismCheck(Element,File,error)) RETURN 604 CALL ElementStress(Element,Material) 605 CALL SpringStress(Node,Element,Material,Spring,Line,jramc,jramd) 606 IF(jramd == 1) CYCLE Unload 607 CALL Reaction(Node,Element,Material,Load,Boundary,Line) 608 CALL incRatio(Element,Material,Spring,Nonlinear) 609 CALL totalValue(Element,Spring,Nonlinear) 610 CALL YieldCheck(Element,Material,Spring) 611 CALL Output(iste,Element,Spring,Nonlinear,File) 612 END DO Unload 613 IF(NonLinear%rmin > 0.998D0) EXIT 614 IF(iste == NonLinear%iteration) EXIT 615 END DO Iteration 616 END SUBROUTINE Analysis
 本章では,このような解析の流れのうち,全体係数行列を作成し,解析して変位を求める過程を中心として説明し,その後の領域内の応力や,領域境界間の表面力の計算については次章において詳細を説明する.

5-2 ペナルティ係数行列の作成

 HPMの離散化方程式には,2.4節で述べたように,小領域境界辺上の変位の連続性に関する付帯条件に伴う係数行列が含まれている.アルゴリズム的に眺めれば,これはRBSMのばね剛性行列とほぼ同一であり,極めて硬いばねを想定した状態と考えることができる.

$\hspace{0em}$図5.2 ペナルティ係数行列の作成フロー
図5.2は,この付帯条件によるペナルティ係数行列を作成し,全体係数行列に組み込むためのプロセスで,具体的にはプログラム5.2に示すサブルーチン(formStiff)で処理している.ここで,行列は2.4節で述べたように,座標の関数となっているため数値積分が必要になる.本サンプル・プログラムでは,積分点を3点とする線積分を行っている.積分点の情報は付録に示すリスト249行~254行に記載している.
プログラム5.2 ペナルティ係数行列の作成(formSpring)
818 !-------------------------------------------------------------------------- 819 SUBROUTINE formStiff( Node, Element, Material, Spring, Line, Solver) 820 821 TYPE(typeNode), INTENT(IN) :: Node 822 TYPE(typeElement), INTENT(IN) :: Element 823 TYPE(typeMaterial), INTENT(IN) :: Material 824 TYPE(typeSpring), INTENT(IN) :: Spring 825 TYPE(typeNumInteg), INTENT(IN) :: Line 826 TYPE(typeBand), INTENT(INOUT) :: Solver 827 REAL(8) :: sfm(12,12),bb(2,12),D(2,2),h,thick,wt 828 INTEGER :: is,ip,ie1,ie2,im1,im2 829 830 DO is = 1, Spring%no 831 sfm = 0.D0 832 ie1 = Spring%element(1,is) 833 ie2 = Spring%element(2,is) 834 im1 = Element%material(ie1) 835 im2 = Element%material(ie2) 836 h = Spring%hline(1,is) + Spring%hline(2,is) 837 thick = (Material%thick(im1)*Spring%hline(1,is) & 838 + Material%thick(im2)*Spring%hline(2,is))/h 839 CALL formSpring(is,Element,Material,Spring,D) 840 D = D*Spring%penalty 841 DO ip = 1, Line%no 842 CALL formB(is,ip,Node,Element,Spring,Line,bb) 843 wt = 0.5*Line%weight(ip)*Spring%length(is)/h*thick 844 sfm = sfm + MATMUL(MATMUL(TRANSPOSE(bb),D),bb)*wt 845 END DO 846 CALL Assemble(is,sfm,Spring,Solver) 847 END DO 848 END SUBROUTINE formStiff
 さて,数値積分に直接関係するのが式(2.34)で示した $\boldsymbol{B}$ 行列である.これを具体に成分で示すと以下のようになる.
\[ {\rm (5.1)}   \boldsymbol{B} = \left[ \begin{array}{cccccc|} -l_1 & -m_1 & (l_1 Y_1 - m_1 X_1) & -l_1 X_1 & -m Y_1 & -0.5(l_1 Y_1 + m_1 X_1) \\ -l_2 & -m_2 & (l_2 Y_1 - m_2 X_1) & -l_2 X_1 & -m Y_1 & -0.5(l_2 Y_1 + m_2 X_1) \end{array} \right. \]
\[\hspace{12em} \left. \begin{array}{|cccccc} l_1 & m_1 & -(l_1 Y_2 - m_1 X_2) & l_1 X_2 & m Y_2 & 0.5(l_1 Y_2 + m_1 X_2) \\ l_2 & m_2 & -(l_2 Y_2 - m_2 X_2) & l_2 X_2 & m Y_2 & 0.5(l_2 Y_2 + m_2 X_2) \end{array} \right] \]
ここで,$X_i=x - x_i$ であり,$x_i$ は図5.3に示す図心座標を表している.付帯条件による係数行列は,この $\boldsymbol{B}$ 行列を用いて,式(2.35)に示すように
\[ \int_{\Gamma} \boldsymbol{B}^t \boldsymbol{k} \boldsymbol{B} dS \]
といった線積分が必要になる.本サンプル・プログラムでは,この線積分を数値積分により行っている.

$\hspace{2em}$図5.3 線積分のための座標系
 いま,図5.3に示すように,辺 $\overline{34}$ に沿った $s$ 座標系と無次元化した $\eta$ 座標系の2つの座標系の間には以下の関係がある.
\[ {\rm (5.2)}   s = \frac{L}{2} \left( \eta + 1 \right) \]
ここで,$L=\sqrt{x_{43}^2+y_{43}^2}$ であり,$\left( x_{ij} = x_i - x_j \right)$ を意味している.したがって,以下の関係が得られる.
\[ {\rm (5.3)}   ds = \frac{L}{2} d\eta \]
 一方,$x-y$ 座標系と $\eta$ 座標系の間には以下の関係がある.
\[ {\rm (5.4)}   \left. \begin{array}{ll} x = -s \cdot \sin \alpha + x_3 &= s \cdot \displaystyle \frac{x_{43}}{L} + x_3 \\ y = s \cdot \cos \alpha + y_3 &= s \cdot \displaystyle \frac{y_{43}}{L} +y_3 \end{array} \right\} \]
これを $\eta$ 座標系で表すと以下のようになる.
\[ {\rm (5.5)}   \left. \begin{array}{l} x = \displaystyle \frac{1}{2} \left( x_{43} \eta + x_4 + x_3 \right) \\ y = \displaystyle \frac{1}{2} \left( y_{43} \eta + y_4 + y_3 \right) \end{array} \right\} \]
これらの関係を用いると,関数 $f(x)$ の $s$ に沿った線積分は関数 $f(\eta)$ に関する線積分に変換できる.
\[ {\rm (5.6)}   \int_s f(x) ds = \int_{-1}^{1} f(\eta) \cdot \left( \frac{L}{2} \right) d \eta \]
 いま,Gaussの数値積分を用いれば,関数 $fI\eta)$ の積分は以下のように表される.
\[ {\rm (5.7)}   \int_{-1}^{1} f(\eta) \cdot d \eta = \sum_{i=1}^n w_i f(\eta_i) \]
ここで,$w_i$ は重みで,本サンプル・プログラムでは数値積分にあたり,以下の表5.1に示すような3点積分を用いている.(付録の,249行~254行)
表5.1 数値積分における積分点(3点積分)
i 1 2 3
$\eta_i$ $-\sqrt{3/5}$ 0 $\sqrt{3/5}$
$w_i$ $5/9$ $8/9$ $5/9$
 これらの数値積分の関係を用いると,プログラム5.2の842行に示す $\boldsymbol{B}$ 行列を作成するための副プログラムは以下のようになる.配列 (bb) が $\boldsymbol{B}$ 行列である.
プログラム5.3 $\boldsymbol{B}$行列の作成(formB)
849 !-------------------------------------------------------------------------- 850 SUBROUTINE formB( is, ip, Node, Element, Spring, Line, bb ) 851 852 INTEGER, INTENT(IN) :: is 853 INTEGER, INTENT(IN) :: ip 854 TYPE(typeNode), INTENT(IN) :: Node 855 TYPE(typeElement), INTENT(IN) :: Element 856 TYPE(typeSpring), INTENT(IN) :: Spring 857 TYPE(typeNumInteg), INTENT(IN) :: Line 858 REAL(8), INTENT(OUT) :: bb(:,:) 859 860 INTEGER :: in1,in2,ie1,ie2,i 861 REAL(8) :: l(2),m(2),x35,y35,xg1,yg1,xg2,yg2,xeta1,yeta1,xeta2,yeta2 862 REAL(8) :: x5g1,x3g1,y5g1,y3g1,x5g2,x3g2,y5g2,y3g2 863 864 in1 = Spring%node(1,is) 865 in2 = Spring%node(2,is) 866 ie1 = Spring%element(1,is) 867 ie2 = Spring%element(2,is) 868 x35 = Node%coord(1,in2) - Node%coord(1,in1) 869 y35 = Node%coord(2,in2) - Node%coord(2,in1) 870 l(1) = y35/Spring%length(is) 871 l(2) = x35/Spring%length(is) 872 m(1) =-l(2) 873 m(2) = l(1) 874 xg1 = Element%center(1,ie1) 875 yg1 = Element%center(2,ie1) 876 xg2 = Element%center(1,ie2) 877 yg2 = Element%center(2,ie2) 878 x5g1 = Node%coord(1,in1) - xg1 879 x3g1 = Node%coord(1,in2) - xg1 880 y5g1 = Node%coord(2,in1) - yg1 881 y3g1 = Node%coord(2,in2) - yg1 882 x5g2 = Node%coord(1,in1) - xg2 883 x3g2 = Node%coord(1,in2) - xg2 884 y5g2 = Node%coord(2,in1) - yg2 885 y3g2 = Node%coord(2,in2) - yg2 886 xeta1 = 0.5*(x35*Line%point(ip)+x5g1+x3g1) 887 yeta1 = 0.5*(y35*Line%point(ip)+y5g1+y3g1) 888 xeta2 = 0.5*(x35*Line%point(ip)+x5g2+x3g2) 889 yeta2 = 0.5*(y35*Line%point(ip)+y5g2+y3g2) 890 DO i = 1, 2 891 bb(i, 1) = -l(i) 892 bb(i, 2) = -m(i) 893 bb(i, 3) = (l(i)*yeta1-m(i)*xeta1) 894 bb(i, 4) = -l(i)*xeta1 895 bb(i, 5) = -m(i)*yeta1 896 bb(i, 6) = -0.5*(l(i)*yeta1+m(i)*xeta1) 897 bb(i, 7) = -bb(i,1) 898 bb(i, 8) = -bb(i,2) 899 bb(i, 9) = -(l(i)*yeta2-m(i)*xeta2) 900 bb(i,10) = l(i)*xeta2 901 bb(i,11) = m(i)*yeta2 902 bb(i,12) = 0.5*(l(i)*yeta2+m(i)*xeta2) 903 END DO 904 END SUBROUTINE formB

5-3 付帯条件に対する塑性化後の構成行列

 本節では,プログラム5.2の839行で呼び出される,付帯条件から得られるペナルティ行列に対する構成方程式について説明する.本サンプル・プログラムでは,ペナルティ関数として,2.2節で述べた重みを付けたペナルティ関数を用いる.弾性状態の場合,このペナルティ関数は式(2.9)~(2.10)で示されている.これを再掲すると以下のとおりである.
\[ {\rm (5.8)}   \mathbf{(平面ひずみ状態)}\hspace{2em} \left. \begin{array}{rl} k_n & \displaystyle \!\!\!\!\! = \frac{(1-\nu)E'}{(1-2 \nu)(1+\nu)} \cdot \frac{1}{h_1+h_2} \\ k_s & \displaystyle \!\!\!\!\! = \frac{E'}{1+\nu} \cdot \frac{1}{h_1+h_2} \end{array} \right\} \]
\[ {\rm (5.9)}   \mathbf{(平面応力状態)}\hspace{3em} \left. \begin{array}{rl} k_n & \displaystyle \!\!\!\!\! = \frac{E'}{(1- \nu^2)} \cdot \frac{1}{h_1+h_2} \\ k_s & \displaystyle \!\!\!\!\! = \frac{E'}{1+\nu} \cdot \frac{1}{h_1+h_2} \\ \end{array} \right\} \]
ここで,$E'$ は以下のように,弾性係数$E$にペナルティ関数$p$をかけた値である.
\[ {\rm (5.10)}   E' = E \times p \]
この関係は,副プログラム(formSpring)の918行~932行にコーディングされている.
プログラム5.4 弾性状態のペナルティ行列に対する構成方程式
918 h = Spring%hline(1,is) + Spring%hline(2,is) 919 ie1 = Spring%element(1,is) 920 ie2 = Spring%element(2,is) 921 im1 = Element%material(ie1) 922 im2 = Element%material(ie2) 923 E = (Material%young(im1)*Spring%hline(1,is) & 924 + Material%young(im2)*Spring%hline(2,is))/h 925 P = (Material%poisson(im1)*Spring%hline(1,is) & 926 + Material%poisson(im2)*Spring%hline(2,is))/h 927 IF(Element%type == 0) THEN 928 D(1,1) = E*(1.0-P)/(1.0+P)/(1.0-2.0*P) 929 ELSE 930 D(1,1) = E/(1.0-P**2) 931 END IF 932 D(2,2) = E/(1.0+P)
ここで,923行~926行の弾性係数とポアソン比については,垂線の高さを重みとする隣接領域の値の平均値を用いる.なお,式(5.10)のペナルティ倍については,一旦,ペナルティ倍しない値による重みだけの係数行列を作成し,プログラム5.2に示すサブルーチン(formStiff)の840行において行っている.また,表面力計算などの便宜を考慮して,垂線による割り算も,同サブルーチンの843行において行っている.
3.2節で述べたように,小領域境界辺に設けたペナルティ関数に対し,非線形特性を導入することによって,すべり破壊などの不連続現象を表現する.いま,プログラム5.4で求めた弾性状態のペナルティ行列を $\boldsymbol{D}^{e}$ とする.このとき,3.2節で説明した塑性化後のペナルティ行列における構成方程式を求めてみよう.図5.4は,塑性化後の構成行列を求めるフローを示した図である.

$\hspace{0em}$図5.4 塑性状態のペナルティ行列に対する構成方程式
 弾性時の $\boldsymbol{D}^{e}$ を求める部分はプログラム5.4に示したとおりである.降伏しているペナルティ辺については,3.2節で展開した破壊条件に応じて,後述する $\boldsymbol{D}^{p}$ 行列を求め,$\boldsymbol{D}^{e}$ 行列から差し引くことで,塑性化後の構成方程式を求める.
 具体的なコードをプログラム5.5に示す.省略部分はプログラム5.4 で示した部分で弾性時の $\boldsymbol{D}^{e}$ 行列を作成している.933行は,ペナルティ辺が降伏しているか否か判定している部分で,降伏判定フラッグ(Spring%flag)が0の時は弾性とし,1の時はペナルティ辺が塑性化したものと考え,塑性化後の $\boldsymbol{D}^{p}$ 行列を作成している.
プログラム5.5 構成方程式Dの作成(formSpring)
905 !-------------------------------------------------------------------------- 906 SUBROUTINE formSpring( is, Element, Material, Spring, D ) 907 908 INTEGER, INTENT(IN) :: is 909 TYPE(typeElement), INTENT(IN) :: Element 910 TYPE(typeMaterial), INTENT(IN) :: Material 911 TYPE(typeSpring), INTENT(IN) :: Spring 912 REAL(8), INTENT(INOUT) :: D(:,:) 913 REAL(8) :: Dp(2,2),E,P,phi,h 914 INTEGER :: ie1,ie2,im1,im2 915 916 D = 0.D0 : : (弾性状態の構成行列 : プログラム5.4参照) : 933 IF(Spring%flag(is) == 1) THEN 934 IF(Element%type == 0) THEN 935 phi = (Material%phi(im1)*Spring%hline(1,is) & 936 + Material%phi(im2)*Spring%hline(2,is))/h 937 CALL MohrCoulomb(is,phi,Spring,D,Dp) 938 ELSE 939 CALL vonMises(is,Spring,D,Dp) 940 END IF 941 D = D - Dp 942 END IF 943 END SUBROUTINE formSpring
ここで,配列(Dp)は,$\boldsymbol{D}^{p}$ 行列であり,941行で $\boldsymbol{D}^{e}$ 行列から下記のごとく引いている.
\[ \boldsymbol{D} = \boldsymbol{D}^{e} - \boldsymbol{D}^{p} \]
 したがって,配列(D)は弾性状態の $\boldsymbol{D}^{e}$ から塑性化後の構成行列に変化する.なお,本プログラムでは強度定数も935行に示すよう,隣接する2要素の垂線を重みとして平均化した値を用いている.
 もし,本書で取り扱つているMohr-Coulombの条件やvonMisesの条件以外の破壊条件を利用したい場合はこのサブルーチン(formSpring)において他の破壊条件を選択できるように修正し,それに対応するサブルーチンを新たにに追加すればよい.
 次に,それぞれの破壊条件に対する $\boldsymbol{D}^{p}$ 行列の作成をプログラム5.6及びプログラム5.7に示す.プログラム5.6はMohr-Coulombの条件に対するプログラムである.
プログラム5.6 MohrCoulombの条件による 行列の作成(MohrCoulomb)
944 !-------------------------------------------------------------------------- 945 SUBROUTINE MohrCoulomb( is, phi, Spring, D, Dp ) 946 947 INTEGER, INTENT(IN) :: is 948 REAL(8), INTENT(IN) :: phi 949 TYPE(typeSpring), INTENT(IN) :: Spring 950 REAL(8), INTENT(IN) :: D(:,:) 951 REAL(8), INTENT(OUT) :: Dp(:,:) 952 INTEGER :: i,j 953 REAL(8) :: pt,f,D1,D2 954 REAL(8) :: PAI = 3.141592654D0 955 956 pt = DTAN(phi*PAI/180.D0) 957 D1 = D(1,1) 958 D2 = D(2,2) 959 f = 1.D0/(D2+D1*pt**2) 960 Dp(1,1) = (D1*pt)**2*f 961 Dp(2,2) = D2*D2*f 962 Dp(1,2) = D1*D2*pt*f 963 IF(Spring%stress(2,is) .LT. 0.D0) THEN 964 Dp(1,2) = -Dp(1,2) 965 END IF 966 Dp(2,1) = Dp(1,2) 967 END SUBROUTINE MohrCoulomb
963行ではせん断に関する表面力の符号をチェックしている.これは,3.2節で説明した塑性化後の構成式における非対角項
\[ D(1,2) = D(2,1) = k_n k_s \lambda_s ( C-\tan \phi \cdot \lambda_n) \tan \phi /F \]
\[\hspace{3em} F = k_s \cdot \lambda_s^2 + k_n \left\{ (c-\tan \phi \cdot \lambda_n) \tan \phi \right\}^2 \]
に対して,注目しているペナルティ辺が塑性化していれば,
\[ \lambda_s^2 = (C - \lambda_n \cdot \tan \phi )^2 \]
なる関係が成立するため,
\[ F = \lambda_s^2 \left( k_s + k_n \tan^2 \phi \right) \]
となり,結局,非対角項は
\[ \frac{ k_n k_s \lambda_s ( C - \lambda_n \cdot \tan \phi ) \tan \phi} { \lambda_s^2 \left( k_s + k_n \tan^2 \phi \right)} \]
となることから,$\lambda_s^2$ を省略することができる.すなわち,上式は
\[ \frac{ k_n k_s \lambda_s | \lambda_s | \tan \phi} { \lambda_s^2 \left( k_s + k_n \tan^2 \phi \right) } \]
となり,したがって
\[ \frac{\lambda_s | \lambda_s | }{ \lambda_s^2} \]
となることより,せん断力 $\lambda_s$ の正負によって1あるいは-1をとるからである.
プログラム5.7はvonMisesの条件に対する塑性化後の構成行列に対するプログラムである.
プログラム5.7 vonMisesの条件による 行列の作成(vonMises)
968 !-------------------------------------------------------------------------- 969 SUBROUTINE vonMises( is, Spring, D, Dp ) 970 971 INTEGER, INTENT(IN) :: is 972 TYPE(typeSpring), INTENT(IN) :: Spring 973 REAL(8), INTENT(IN) :: D(:,:) 974 REAL(8), INTENT(OUT) :: Dp(:,:) 975 REAL(8) :: sig,tau,f,D1,D2 976 INTEGER :: i,j 977 978 D1 = D(1,1) 979 D2 = D(2,2) 980 sig = Spring%stress(1,is) 981 tau = Spring%Stress(2,is) 982 f = 1.D0/(D1*sig*sig/4.D0 + 4.D0*D2*tau*tau) 983 Dp(1,1) = D1*D1*sig*sig/4.D0*f 984 Dp(2,2) = 4.D0*D2*D2*tau*tau*f 985 Dp(1,2) = D1*D2*sig*tau*f 986 Dp(2,1) = Dp(1,2) 987 END SUBROUTINE vonMises

5-4 ペナルティ係数行列の全体係数行列への組み込み

 本サンプル・プログラムでは全体係数行列をバンド法により解いている.メモリーを効率よく利用するためには全体係数行列を1次元配列にするとよく,このような方法はFEMにおいても頻繁に行われている.HPMの場合,ペナルティ係数行列を全体係数行列に組み込むことになるが,組み込み方法もFEMにおける節点及び要素を,それぞれ,HPMの小領域とペナルティ辺に対応させれば,組み込み方法はFEMの場合と全く同様となる.詳細については他の書物にゆずるとし,ここではどのように全体係数行列を1次元配列にセットするかについて説明する.
図5.5(b)の場合,行数は全自由度数だけ,また,列数はバンド幅だけ必要となる.通常,配列を宣言する場合,問題の大きさに依存しないよう,メモリーの効率化を計つておいた方がよい.もし,図5.5(b)のような2次元配列を用いると,行,列とも問題により変化するため,好ましくない.そこで,図5.6に示すよう,2次元配列を1次元配列に置き直して考える.

$\hspace{3em}$(a)全体剛性行列 $\hspace{6em}$(b)バンド化行列
$\hspace{5em}$図5.5 全体剛性行列のバンド化

$\hspace{6em}$図5.6 バンド行列の1次元化
 1次元化の方法についてはいろいろ考えられるが,本サンプル・プログラムでは図に示すよう, 行単位に順次後ろへ加える形としている.
 以上の考えをもとにプログラム化したものが,プログラム5.8に示すサブルーチン(Assemble)である.変数(sfm)がペナルティ係数行列で,これを1次元配列の全体係数行列(Solver%stiff)に組み込む.1018行に示す変数(lb)が,組み込むべき全体係数行列内の位置を表している.
プログラム5.8 全体係数行列への組み込み(Assemble)
988 !-------------------------------------------------------------------------- 989 SUBROUTINE Assemble( is, sfm, Spring, Solver) 990 991 INTEGER, INTENT(IN) :: is 992 REAL(8), INTENT(IN) :: sfm(:,:) 993 TYPE(typeSpring), INTENT(IN) :: Spring 994 TYPE(typeBand), INTENT(INOUT) :: Solver 995 996 INTEGER :: ie1,ie2,i,j,k,l,k1,ka,kb,la,lb 997 998 DO i = 1, 2 999 ie1 = Spring%element(i,is) 1000 DO j = i, 2 1001 ie2 = Spring%element(j,is) 1002 DO k = 1, Element%dof 1003 k1 = k 1004 IF(i /= j) THEN 1005 k1 = 1 1006 END IF 1007 DO l = k1, Element%dof 1008 ka = k + (i-1)*Element%dof 1009 kb = l + (j-1)*Element%dof 1010 la = k + (ie1-1)*Element%dof 1011 lb = l + (ie2-1)*Element%dof 1012 IF(lb .LT. la) THEN 1013 kb = k + (i-1)*Element%dof 1014 ka = l + (j-1)*Element%dof 1015 lb = k + (ie1-1)*Element%dof 1016 la = l + (ie2-1)*Element%dof 1017 END IF 1018 lb = lb + (la-1)*Solver%width - la + 1 1019 Solver%stiff(lb) = Solver%stiff(lb) + sfm(ka,kb) 1020 END DO 1021 END DO 1022 END DO 1023 END DO 1024 END SUBROUTINE Assemble
 本サプルーチンはバンド法のための全体係数行列を作成するものであり,連立方程式の解析法を,例えばスカイライン法など他の解法に変更する場合には本サブルーチンもそれに対応するよう取り替える必要がある.

5-5 領域の剛性行列の作成

 HPMでは領域内の剛性を評価することで,小領域の変形を表現している.本サンプル・プログラムでは,変位場として線形の変位場を用いているため,領域内のひずみは一定となる.これを考慮して各小領域内の剛性行列を誘導する.図5.7は剛性行列を作成するためのフローである.また,これに基づいて作成したプログラムをプログラム5.9に示す.

$\hspace{2em}$図5.7 領域毎の剛性行列の作成フロー
 747行はRBSMで用いられる境界用の要素がある場合に対応するもので,本サンプル・プログラムでは,境界用要素を組み込んでいないため無視してよい.749行は,式(1.8)式(1.9)で示した領域の弾性状態を表す構成行列 $\boldsymbol{D}^{e}$ を作成している副プログラムを呼び出している.また,750行は,式(2.26)で示したひずみと変位を関係づける $\boldsymbol{B}^{e}$ 行列を作成する副プログラムを呼び出している.領域毎の剛性行列は,式(2.25)のように,小領域における面積積分となるが,領域内のひずみが一定であるため,$\boldsymbol{D}^{e}$ も $\boldsymbol{B}^{e}$ も一定となり,752行のように,領域の面積をかけるだけですむ.小領域毎に得られた剛性行列は,754行において全体係数行列に組み込んでいる.
プログラム5.9 領域毎の剛性行列の作成と
$\hspace{10em}$全体係数行列への組み込み (formElemStiff)
735 !-------------------------------------------------------------------------- 736 SUBROUTINE formElemStiff( Node, Element, Material, Solver) 737 738 TYPE(typeNode), INTENT(IN) :: Node 739 TYPE(typeElement), INTENT(IN) :: Element 740 TYPE(typeMaterial), INTENT(IN) :: Material 741 TYPE(typeBand), INTENT(INOUT) :: Solver 742 743 REAL(8) :: sfm(6,6),D(3,3),bb(3,6),volume 744 INTEGER :: ie,im 745 746 DO ie = 1, Element%no 747 IF(Element%node(3,ie) /= 0) THEN 748 sfm = 0.D0 749 CALL formDmatrix(ie,Element,Material,D) 750 CALL formBelem(bb) 751 im = Element%material(ie) 752 volume = Element%area(ie)*Material%thick(im) 753 sfm = sfm + MATMUL(TRANSPOSE(bb),MATMUL(D,bb))*volume 754 CALL AssembleElement(ie,sfm,Solver) 755 END IF 756 END DO 757 END SUBROUTINE formElemStiff
 具体的な構成行列を作成しているプログラムをプログラム5.10に示す.774行の(Element%type)の値で平面ひずみ状態(=0)と平面応力状態(=1)を選択している.776行~781行が式(1.8)で示した平面ひずみ状態の構成行列 $\boldsymbol{D}^{e}$ を,783行~788行が式(1.9)で示した平面応力状態の構成行列 $\boldsymbol{D}^{e}$ を作成している.
プログラム5.10 領域毎の弾性構成行列 の作成(formDmatrix)
758 !-------------------------------------------------------------------------- 759 SUBROUTINE formDmatrix( ie, Element, Material, D) 760 761 INTEGER, INTENT(IN) :: ie 762 TYPE(typeElement), INTENT(IN) :: Element 763 TYPE(typeMaterial), INTENT(IN) :: Material 764 REAL(8), INTENT(OUT) :: D(:,:) 765 766 INTEGER :: im 767 REAL(8) :: e,p,ep 768 769 D = 0.D0 770 771 im = Element%material(ie) 772 e = Material%young(im) 773 p = Material%poisson(im) 774 SELECT CASE(Element%type) 775 CASE(0) ! 平面ひずみ 776 ep = e*(1.D0-p)/(1.D0+p)/(1.D0-2.D0*p) 777 D(1,1) = ep 778 D(1,2) = ep*p/(1.D0-p) 779 D(2,1) = D(1,2) 780 D(2,2) = ep 781 D(3,3) = 0.5*ep*(1.D0-2.D0*p)/(1.D0-p) 782 CASE(1) ! 平面応力 783 ep = e/(1.D0-p*p) 784 D(1,1) = ep 785 D(1,2) = ep*p 786 D(2,1) = ep*p 787 D(2,2) = ep 788 D(3,3) = 0.5*ep*(1.D0-p) 789 END SELECT 790 END SUBROUTINE formDmatrix
 本サンプル・プログラムでは,領域内の応力状態として弾性のみを仮定している.もし,領域内の材料非線形を考慮するなら,降伏した要素に対し,3.3節で述べた手順に従って求められた構成行列を適用すればよい.
 また,式(2.26)で表される,ひずみ-変位関係のための $\boldsymbol{B}^{e}$ 行列のプログラムをプログラム5.11に示す.領域内でひずみ一定の場合は,このように単純な行列となるが,2次の変位場など,高次の変位場を用いる場合には,ペナルティ係数行列の場合と同様,数値積分が必要となる.
プログラム5.11 ひずみ-変位関係行列 の作成(formBelem)
791 !-------------------------------------------------------------------------- 792 SUBROUTINE formBelem( bb ) 793 794 REAL(8), INTENT(OUT) :: bb(:,:) 795 796 bb = 0.D0 797 bb(1,4) = 1.D0 798 bb(2,5) = 1.D0 799 bb(3,6) = 1.D0 800 END SUBROUTINE formBelem
 最後に,領域毎に作成された剛性行列の全体係数行列への組み込みついて説明する.HPMの自由度は,線形変位場を仮定した場合,剛体変位 $\boldsymbol{d}^{(e)}$ とひずみ $\boldsymbol{\varepsilon}^{(e}$の,それぞれ3自由度,計6自由度となる.領域の変形特性を表す構成行列 $\boldsymbol{D}^{e}$は,ひずみの自由度のみ関係するため,プログラム5.9の753行で作成した剛性行列は
\[ {\rm sfm} = \left[ \begin{array}{cc} \boldsymbol{0} & \boldsymbol{0} \\ \boldsymbol{0} & \boldsymbol{D}^{(e)} \end{array} \right] \left\{ \begin{array}{c} \boldsymbol{d}^{(e)} \\ \boldsymbol{\varepsilon}^{(e)} \end{array} \right\} \] となる.プログラム5.12は,この考え方にもとづいて剛性行列(sfm)を全体係数行列に組み込む手順で作成されている.
プログラム5.12 剛性行列の全体係数行列への組み込み(AssembleElement)
801 !-------------------------------------------------------------------------- 802 SUBROUTINE AssembleElement( ie, sfm, Solver) 803 804 INTEGER, INTENT(IN) :: ie 805 REAL(8), INTENT(IN) :: sfm(:,:) 806 TYPE(typeBand), INTENT(INOUT) :: Solver 807 INTEGER :: i,j,ia,ib,ii 808 809 DO i = 1, Element%dof 810 DO j = i, Element%dof 811 ia = i + (ie-1)*Element%dof 812 ib = j + (ie-1)*Element%dof 813 ii = ib + (ia-1)*Solver%width - ia + 1 814 Solver%stiff(ii) = Solver%stiff(ii) + sfm(i,j) 815 END DO 816 END DO 817 END SUBROUTINE AssembleElement

5-6 ペナルティ関数を用いた拘束条件の処理

2.5節で述べたように,拘束条件の処理方法としては,自由度を直接拘束する方法とペナルティ関数を用いて近似的に拘束する方法の2種類がある.前者の方法の場合,境界用の線状の要素を作成し,その自由度を拘束する.この方法は,RBSMで用いられている方法で,HPMでも利用できるが,本サンプル・プログラムではこの方法ではなく,後者の方法で拘束条件を導入している.図2.5で示したように,ペナルティ関数を用いて拘束条件を導入する場合でも,小領域の節点(特定な点)を拘束する場合と小領域の境界辺を拘束する場合の2つの方法がある.本サンプル・プログラムでは,辺を拘束する方法のみが用いられている.
式(2.49)に示すように,ペナルティ関数を用いた拘束条件の処理方法の場合,以下の係数行列を全体係数行列に組み込むことで導入する.
\[ \boldsymbol{k}_u^{(e)} = p \int_{\Gamma_u} \left[ \begin{array}{cc} \left. \left( {}^t \boldsymbol{N}_d^{(e)} \boldsymbol{N}_d^{(e)} \right) \right|_{\Gamma_u} & \left. \left( {}^t \boldsymbol{N}_d^{(e)} \boldsymbol{N}_{\varepsilon}^{(e)} \right) \right|_{\Gamma_u} \\ \left. \left( {}^t \boldsymbol{N}_{\varepsilon}^{(e)} \boldsymbol{N}_d^{(e)} \right) \right|_{\Gamma_u} & \left. \left( {}^t \boldsymbol{$}_{\varepsilon}^{(e)} \boldsymbol{N}_{\varepsilon}^{(e)} \right) \right|_{\Gamma_u} \end{array} \right] dS \]
ここで,$p$はペナルティ関数,$\left. \boldsymbol{N}_d^{(e)} \right|_{\Gamma_u}$,$\left. \boldsymbol{N}_{\varepsilon}^{(e)} \right|_{\Gamma_u}$ は以下のとおりである.
\[ \left. \boldsymbol{N}_d^{(e)} \right|_{\Gamma_u} = \left[ \matrix{ 1 & 0 & -(y_u-y_{_P}) \cr 0 & 1 & (x_u-x_{_P}) } \right] \]
\[ \left. \boldsymbol{N}_\varepsilon^{(e)} \right|_{\Gamma_u} = \left[ \matrix{ (x_u-x_{_P}) & 0 & (y_u-y_{_P})/2 \cr 0 & (y_u-y_{_P}) & (x_u-x_{_P})/2 } \right] \]
 ただし, $(x_0, y_0)$ は拘束する境界辺を含む領域の図心座標(自由度位置)で, $(x_u. t_u)$は 拘束する境界辺の座標である.この境界辺の座標は一般的に変数であるので,$\boldsymbol{k}_u$ の積分に際しては,陽的な公式を用いるか,数値積分を行う必要がある.本サンプル・プログラムでは,3点の数値積分を行っている.図5.8は,拘束条件の導入フローを示した図である.

$\hspace{2em}$図5.8 拘束条件の導入フロー
 このフローに基づいて作成したプログラムをプログラム5.13に示す.1037行でペナルティ関数を設定している.拘束条件の処理では重みを付けず,単純なペナルティ関数を用いている.1049行では,$\left. \boldsymbol{N}_d^{(e)} \right|_{\Gamma_u}$ ,$\left. \boldsymbol{N}_{\varepsilon}^{(e)} \right|_{\Gamma_u}$ を作成する副プログラムを呼び出している.これを基に,1053行で,$\boldsymbol{k}_u^{(e)}$ を作成,1057行で全体係数行列に組み込んでいる.
プログラム5.13 拘束条件の処理(setBoundary)
1025 !-------------------------------------------------------------------------- 1026 SUBROUTINE setBoundary( Node, Element, Spring, Boundary, Line, Solver) 1027 1028 TYPE(typeNode), INTENT(IN) :: Node 1029 TYPE(typeElement), INTENT(IN) :: Element 1030 TYPE(typeSpring), INTENT(IN) :: Spring 1031 TYPE(typeBoundary), INTENT(IN) :: Boundary 1032 TYPE(typeNumInteg), INTENT(IN) :: Line 1033 TYPE(typeBand), INTENT(INOUT) :: Solver 1034 REAL(8) :: bsf(6,6),shape(2,6),D,t,length,wt 1035 INTEGER :: ib,e,d,n1,in2,m,p,i,j 1036 1037 D = MAXVAL( Material%young )*Spring%penalty 1038 DO ib = 1, Boundary%no 1039 bsf = 0.D0 1040 ie = Boundary%element(ib) 1041 id = Boundary%direction(ib) 1042 in1 = Boundary%node(1,ib) 1043 in2 = Boundary%node(2,ib) 1044 length = SQRT((Node%coord(1,in2)-Node%coord(1,in1))**2 & 1045 +(Node%coord(2,in2)-Node%coord(2,in1))**2) 1046 im = Element%material(ie) 1047 t = Material%thick(im) 1048 DO ip = 1, 3 1049 CALL formShape(ie,ip,in1,in2,Node,Element,Line,shape) 1050 wt = 0.5*Line%weight(ip)*length*t 1051 DO i = 1, Element%dof 1052 DO j = 1, Element%dof 1053 bsf(i,j) = bsf(i,j) + shape(id,i)*D*shape(id,j)*wt 1054 END DO 1055 END DO 1056 END DO 1057 CALL AssembleElement(ie,bsf,Solver) 1058 END DO 1059 END SUBROUTINE setBoundary
プログラム5.14は,$\left. \boldsymbol{N}_d^{(e)} \right|_{\Gamma_u}$,$\left. \boldsymbol{N}_{\varepsilon}^{(e)} \right|_{\Gamma_u}$ を作成しているプログラムで,5.2節で述べた数値積分の規則に従って作成している.この係数行列は $x-y$ 座標系で作成されており,したがって,拘束条件の指定も $x-y$ 座標系で行う必要がある.
プログラム5.14 拘束条件の処理(setBoundary)
703 !-------------------------------------------------------------------------- 704 SUBROUTINE formShape( ie, ip, in1, in2, Node, Element, Line, shape ) 705 706 INTEGER, INTENT(IN) :: ie 707 INTEGER, INTENT(IN) :: ip 708 INTEGER, INTENT(IN) :: in1 709 INTEGER, INTENT(IN) :: in2 710 TYPE(typeNode), INTENT(IN) :: Node 711 TYPE(typeElement), INTENT(IN) :: Element 712 TYPE(typeNumInteg), INTENT(IN) :: Line 713 REAL(8), INTENT(OUT) :: shape(:,:) 714 REAL(8) :: x35,y35,x5g,y5g,x3g,y3g,xeta,yeta 715 716 shape = 0.D0 717 718 x35 = Node%coord(1,in2)-Node%coord(1,in1) 719 y35 = Node%coord(2,in2)-Node%coord(2,in1) 720 x5g = Node%coord(1,in1) - Element%center(1,ie) 721 x3g = Node%coord(1,in2) - Element%center(1,ie) 722 y5g = Node%coord(2,in1) - Element%center(2,ie) 723 y3g = Node%coord(2,in2) - Element%center(2,ie) 724 xeta = 0.5*(x35*Line%point(ip)+x5g+x3g) 725 yeta = 0.5*(y35*Line%point(ip)+y5g+y3g) 726 shape(1,1) = 1.D0 727 shape(1,3) = -yeta 728 shape(1,4) = xeta 729 shape(1,6) = 0.5*yeta 730 shape(2,2) = 1.D0 731 shape(2,3) = xeta 732 shape(2,5) = yeta 733 shape(2,6) = 0.5*xeta 734 END SUBROUTINE formShape
 拘束する境界辺の拘束変位(強制変位)が0の場合はこの処理だけで良いが,強制変位が与えられる場合は,プログラム5.14の処理に加え,式(2.49)に示す強制変位量による荷重項を考慮しなければなならない.いま,この関係は
\[ \boldsymbol{p}_u^{(e)} = p \int_{\Gamma_u} \left\{ \begin{array}{l} \left. {}^t \boldsymbol{N}_d^{(e)} \right|_{\Gamma_u} \\ \left. {}^t \boldsymbol{N}_\varepsilon^{(e)} \right|_{\Gamma_u} \end{array} \right\} \; dS \hat{ \boldsymbol{u} } \]
で表される.ここで,$p$ はペナルティ関数,$\left. \boldsymbol{N}_d^{(e)} \right|_{\Gamma_u}$ ,$\left. \boldsymbol{N}_{\varepsilon}^{(e)} \right|_{\Gamma_u}$ は先述のとおりである.この処理は,633行から始まる,荷重項を作成する副プログラム(formLoad)の677行~701行で導入されている.該当部分をプログラム5.15に掲載する.686行でペナルティ関数を設定した後,693行で積分項の計算を行い,698行で強制変量をかけて,荷重項にセットしている.
プログラム5.15 強制変位による荷重項の処理(formLoad)
677 DO ib = 1, Boundary%no 678 IF(Boundary%disp(ib) /= 0.D0) THEN 679 pg = 0.D0 680 ie = Boundary%element(ib) 681 id = Boundary%direction(ib) 682 in1 = Boundary%node(1,ib) 683 in2 = Boundary%node(2,ib) 684 im = Element%material(ie) 685 t = Material%thick(im) 686 pt = Spring%penalty*MAXVAL( Material%young ) 687 length = SQRT((Node%coord(1,in2)-Node%coord(1,in1))**2 & 688 +(Node%coord(2,in2)-Node%coord(2,in1))**2) 689 DO ip = 1, 3 690 CALL formShape(ie,ip,in1,in2,Node,Element,Line,shape) 691 wt = 0.5*Line%weight(ip)*length*t 692 DO i = 1, Element%dof 693 pg(i) = pg(i) + shape(id,i)*pt*wt 694 END DO 695 END DO 696 DO i = 1, Element%dof 697 in = i + (ie-1)*Element%dof 698 Element%load(in) = Element%load(in) + pg(i)*Boundary%disp(ib) 699 END DO 700 END IF 701 END DO