6.離散化解析の応力・表面力計算

6-1 表面力の計算

 変位型のFEMでは,テンソル量としての要素内応力を求める.一方,HPMでは,FEMと同様,領域内においてテンソル量としての応力が求まるとともに,RBSMと同様,隣接する2領域間の境界辺上における単位面積当りの表面力を求めることができる.本節では,HPMの特徴でもある,表面力を求めるプログラムについて述べる.
図6.1は増分表面力計算の流れを示したものである.表面力は,ペナルティ関数が設定される小領域の境界辺で求められるため,全処理に渡るペナルティ数に関するループを図のように設ける.本来の表面力計算に関する部分は(*3)に示す点線で囲まれた部分であるが,同時に除荷や負荷の判定も行う.山田の方法による荷重増分法を用いて非線形計算を行う場合には,このような除荷や負荷の判定を行つておく必要がある.

$\hspace{3em}$図6.1 増分表面力の計算
 プログラムを簡単にし,理解しやすいようにするなら,(*3)に示す部分を取り出し,増分表面力計算の部分と除荷,負荷の部分を別なサブルーチンにより処理した方がよいが,ここでは,計算の効率化を考え,同一サブルーチン内で処理している.これは,除荷や負荷が生じた場合,今回の荷重増分計算を無効とし,剛性を変えて再計算するためである.本サンプルプログラムでは前回のペナルティ辺の状態が降伏状態で今回の増分計算により除荷が発生したならば,剛性を弾性状態に変えて再計算を行つている.また,除荷状態から負荷状態に変われば剛性を降伏状態に変えて再計算を行う.本書では簡単な降伏条件を用いているが,さらに複雜な降伏条件を用いるなら,当然この判定や剛性の考え方は変わってくる.除荷,負荷については次節にゆずるとし,ここでは,おおまかな計算の流れをもう少し説明する.
(*1)に示す判定文では増分計算あるいは再計算過程において除荷あるいは負荷が発生したペナルティ辺が存在するか否かのチェックを行つている.もし,一箇所以上のペナルティ辺に除荷もしくは負荷が発生していたなら,以後,降伏しているペナルティ辺についてのみ $\mu$ 計算のための増分計算をおこない,再計算を行う準備を行う.この降伏の判定文が(*2)である.除荷,負荷が発生していなければ通常の(*3)に示す増分計算を行う.
 以上の処理は,プログラム6.1に示すサブルーチン(SpringStress)で行っている.
プログラム6.1 増分表面力計算のコントロール(SpringStress)
1119 !-------------------------------------------------------------------------- 1120 SUBROUTINE SpringStress( Node, Element, Material, Spring, Line, jramc, jramd ) 1121 1122 TYPE(typeNode), INTENT(IN) :: Node 1123 TYPE(typeElement), INTENT(IN) :: Element 1124 TYPE(typeMaterial), INTENT(IN) :: Material 1125 TYPE(typeSpring), INTENT(INOUT) :: Spring 1126 TYPE(typeNumInteg), INTENT(IN) :: Line 1127 INTEGER, INTENT(INOUT) :: jramc 1128 INTEGER, INTENT(INOUT) :: jramd 1129 REAL(8) :: sig(2,3),D(2,2),ww 1130 INTEGER :: is,ip,jbit,i,j 1131 1132 jramd = 0 1133 1134 DO is = 1, Spring%no 1135 IF(jramd == 1 .AND. Spring%flag(is) == 0) CYCLE 1136 IF(jramd == 1 .AND. Spring%flag(is) == -2) CYCLE 1137 CALL Strain(is,Node,Element,Spring,Line ) 1138 CALL formSpring(is,Element,Material,Spring,D) 1139 D = D*Spring%penalty 1140 DO ip = 1, Line%no 1141 DO i = 1, 2 1142 ww = 0.0 1143 DO j = 1, 2 1144 ww = ww + D(i,j)*Spring%dstrain(j,is,ip) 1145 END DO 1146 sig(i,ip) = ww 1147 END DO 1148 END DO 1149 DO i = 1, 2 1150 ww = 0.D0 1151 DO ip = 1, Line%no 1152 ww = ww + sig(i,ip)*Line%weight(ip) 1153 END DO 1154 Spring%Dstress(i,is) = 0.5D0*ww 1155 END DO 1156 IF(jramc .LT. 2) THEN 1157 IF(Spring%flag(is) == 1 .OR. Spring%flag(is) == 2) THEN 1158 jbit = 0 1159 IF(Spring%flag(is) == 2) jbit = 1 1160 CALL Unload(is,Element,Material,Spring,D,jramd,jbit) 1161 END IF 1162 END IF 1163 END DO 1164 jramc = jramc + 1 1165 END SUBROUTINE SpringStress
変数(jramd)は通常0であり,いずれかのペナルティ辺に除荷や負荷が発生すると1になる.この変数によって,図6.1に示す(*1)の判定を行う.また,1158行に示す変数(jbit)は現在のペナルティ辺の状態を示すフラッグで,0の場合は降伏状態を,1のときは除荷状態を表している.
 1056行及び1164行に示す変数(jramc)は再計算回数を制限するカウンタである.数値計算上の誤差などの関係により,同じペナルティ辺において除荷と負荷が繰り返し発生することがある.このような場合,1056行に示すよう,再計算回数に関する制限を設けておかなければプログラムが暴走する可能性もある.本サンプル・プログラムでは再計算回数を2回までに制限している.したがって,前回降伏しているペナルティ辺については繰り返し状態になった場合,降伏状態のまま変化がないものとし,負荷の場合は,やはり負荷のままであると考えている.もちろん,この点に関しては,計算上のテクニックであるから変更しても差し支えない.
 次に,図6.1の点線で囲まれた部分について考えてみよう.詳細は後述するが,1137行では2領域間の相対変位を隣接する領域の垂線の高さの和 $h=h_1+h_2$ で除した仮想ひずみ増分 $\Delta \varepsilon_i$ を計算する副プログラム(Starain)を呼び出している.なお,本サンプル・プログラムでは,ペナルティ係数行列を求める際の積分点で相対変位を求めており,$\Delta \boldsymbol{\varepsilon}_i$ の $i$ は1~3の積分点番号を意味している.
 一方,1138行では,プログラム5.5で示したペナルティ辺の構成行列 $\boldsymbol{D}$ を求める副プログラム(formSpring)呼び出している.この構成行列は垂線の高さで除していない行列となっている.したがって,1144行のように,$\boldsymbol{D}$ と $\Delta \boldsymbol{\varepsilon}_i$ の積が増分表面力 $\Delta \boldsymbol{\lambda}_i$ となる.
 この増分表面力 $\Delta \boldsymbol{\lambda}_i$ も,積分点毎の仮想ひずみから求めるため,積分点毎の値となる.この表面力を利用して積分点毎に破壊の判定を行っても良いが,本サンプルプログラムでは応力評価を1点で行い破壊判定をする.そのため,1149行~1155行に示すように,数値積分の重み $w_i$ を用いた重み付き平均によって,以下のように応力を評価している.
\[ {\rm (6.1)}   \Delta \boldsymbol{\lambda} = \sum_{i=1}^3 \left( w_i \Delta \boldsymbol{\lambda}_i \right) / \sum_{i=1}^3 w_i \]
 さて,積分点毎の仮想ひずみの計算は
\[ {\rm (6.2)}   \Delta \boldsymbol{\varepsilon}_i = \frac{1}{h} \boldsymbol{B}_i \cdot \Delta \boldsymbol{u} \]
で計算する.ここで,$\Delta \boldsymbol{u}$ はペナルティ辺に関係する隣接領域の自由度を並べたベクトルである.また,$\boldsymbol{B}_i$ は,プログラム5.3に掲載した副プログラム(formB)で作成される積分点 $i$ におけるひずみ-変位関係の行列である.具体的なプログラムをプログラム6.2に示す.
プログラム6.2 増分仮想ひずみの計算(Strain)
1166 !-------------------------------------------------------------------------- 1167 SUBROUTINE Strain( is, Node, Element, Spring, Line ) 1168 1169 INTEGER, INTENT(IN) :: is 1170 TYPE(typeNode), INTENT(IN) :: Node 1171 TYPE(typeElement), INTENT(IN) :: Element 1172 TYPE(typeNumInteg), INTENT(IN) :: Line 1173 TYPE(typeSpring), INTENT(INOUT) :: Spring 1174 REAL(8) :: uu(2*Element%dof),bb(2,2*Element%dof),h,ww 1175 INTEGER :: ie,ip,i,j,ii,jj 1176 1177 ii = 0 1178 DO i = 1, 2 1179 ie = Spring%element(i,is) 1180 DO j = 1, Element%dof 1181 ii = ii + 1 1182 jj = j + (ie-1)*Element%dof 1183 uu(ii) = Element%ddisp(jj) 1184 END DO 1185 END DO 1186 h = Spring%hline(1,is) + Spring%hline(2,is) 1187 DO ip = 1, Line%no 1188 CALL formB(is,ip,Node,Element,Spring,Line,bb) 1189 DO i = 1, 2 1190 ww = 0.D0 1191 DO j = 1, 2*Element%dof 1192 ww = ww + bb(i,j)*uu(j) 1193 END DO 1194 Spring%dstrain(i,is,ip) = ww/h 1195 END DO 1196 END DO 1197 END SUBROUTINE Strain

6-2 除荷・負荷の判定

 単位面積当りの表面力を計算する過程において,除荷,負荷の判定が必要であることを前節で述べた.本節ではこのことについて説明する.
 完全弾塑性体を考えた場合,除荷は図6.2に示すような応力経路をたどる.

$\hspace{5em}$図6.2 除荷
このような除荷や負荷の判定を行うためには塑性仕事を計算し,その値によって判断しなければならない.本書では簡単のため,3.2節において説明したように,$\mu$ の計算によってそれを判定している.図6.3は除荷及び負荷過程に関する計算の流れを示したものである.

$\hspace{5em}$図6.3 除荷・負荷の判定フロー
 判定を行うに際し,まず除荷状態もしくは負荷状態のばねに対し $\mu$ の計算を行う.もし,前回までのペナルティ辺の状態が降伏状態(Spring%flag = 1)であるなら除荷の可能性があり,また,除荷状態(Spring%flag = 2)であるなら負荷の可能性がある.そこで,初めに $\mu$ の計算を行い,現在のペナルティ辺の状態を調べて $\mu$ の正負により降伏フラッグを立て直す.ペナルティ辺の前回の状態が降伏状態なら $\mu \lt 0$ のとき除荷が発生し,降伏フラッグをSpring%flag = 2とする.また,除荷状態なら $\mu > 0$ のとき負荷となり,フラッグをSpring%flag = 1に変更する.
  降伏状態 → $\mu \lt 0$ → 除荷発生 → Spring%flag = 2
  除荷状態 → $\mu \gt 0$ → 負荷発生 → Spring%flag = 1
以上の判定をプログラム化したものがプログラム6.3である.
プログラム6.3 除荷・負荷の判定(Unload)
1198 !-------------------------------------------------------------------------- 1199 SUBROUTINE Unload( is, Element, Material, Spring, D, jramd, jbit) 1200 1201 INTEGER, INTENT(IN) :: is 1202 TYPE(typeElement), INTENT(IN) :: Element 1203 TYPE(typeMaterial), INTENT(IN) :: Material 1204 TYPE(typeSpring), INTENT(INOUT) :: Spring 1205 REAL(8), INTENT(IN) :: D(:,:) 1206 INTEGER, INTENT(INOUT) :: jramd 1207 INTEGER, INTENT(IN) :: jbit 1208 REAL(8) :: lam 1209 1210 lam = Lambda(is,Element,Material,Spring,D) 1211 IF(jbit /= 1) THEN 1212 IF(lam < 0.D0) THEN 1213 Spring%flag(is) = 2 1214 jramd = 1 1215 END IF 1216 ELSE 1217 IF(lam > 0.D0) THEN 1218 Spring%flag(is) = 1 1219 jramd = 1 1220 END IF 1221 END IF 1222 END SUBROUTINE Unload
変数(jbit)は前節の表面力計算の項で説明したように,現在のペナルティ辺の状態が降伏状態なら0,除荷状態なら1の値を持つフラッグである.また,変数(jramd)は通常0であり,除荷や負荷が発生すると1の値を持つ.
 このサブルーチンに現れる $\mu$ の計算はプログラム6.4に示す関数(Lambda)で行われる.$\mu$ の計算式は3.2節に示してある.1238行~1241行がMohr-Coulombの条件に関する $\mu$ を,1243行,1244行がvonMisesの条件に対する $\mu$ の計算を行つている箇所である.
プログラム6.4 $\mu$ の計算(Lambda)
1223 !-------------------------------------------------------------------------- 1224 FUNCTION Lambda( is, Element, Material, Spring, D ) RESULT( lam ) 1225 1226 INTEGER, INTENT(IN) :: is 1227 TYPE(typeElement), INTENT(IN) :: Element 1228 TYPE(typeMaterial), INTENT(IN) :: Material 1229 TYPE(typeSpring), INTENT(IN) :: Spring 1230 REAL(8), INTENT(IN) :: D(:,:) 1231 REAL(8) :: lam 1232 REAL(8) :: cm,phi,pt 1233 REAL(8) :: PAI = 3.141592654D0 1234 1235 lam = 0.0 1236 1237 IF(Element%type == 0) THEN 1238 CALL strength(is,Element,Material,Spring,cm,phi) 1239 pt = DTAN(phi*PAI/180.D0) 1240 lam = D(2,2)*Spring%stress(2,is)*Spring%dstrain(2,is,2) & 1241 + D(1,1)*(cm-Spring%stress(1,is)*pt)*pt*Spring%dstrain(1,is,2) 1242 ELSE 1243 lam = 2.0*D(2,2)*Spring%stress(2,is)*Spring%dstrain(2,is,2) & 1244 + 0.5*D(1,1)*Spring%stress(1,is)*Spring%dstrain(1,is,2) 1245 END IF 1246 END FUNCTION Lambda
 Mohr-Coulombの条件の場合,$\mu$ の計算式に強度定数が含まれている.本書のサンプルプログラムでは,この強度定数に対しても垂線を重みとして平均値をとるよう考えている.この平均値の計算はプログラム6.5に示すサブルーチン(strength)により行つている.
プログラム6.5 強度定数の平均値計算(strength)
1247 !-------------------------------------------------------------------------- 1248 SUBROUTINE strength( is, Element, Material, Spring, cm, phi ) 1249 1250 INTEGER, INTENT(IN) :: is 1251 TYPE(typeElement), INTENT(IN) :: Element 1252 TYPE(typeMaterial), INTENT(IN) :: Material 1253 TYPE(typeSpring), INTENT(IN) :: Spring 1254 REAL(8), INTENT(OUT) :: cm 1255 REAL(8), INTENT(OUT) :: phi 1256 1257 REAL(8) :: h 1258 INTEGER :: ie1,ie2,im1,im2 1259 1260 h = Spring%hline(1,is) + Spring%hline(2,is) 1261 ie1 = Spring%element(1,is) 1262 ie2 = Spring%element(2,is) 1263 im1 = Element%material(ie1) 1264 im2 = Element%material(ie2) 1265 cm = (Material%c(im1)*Spring%hline(1,is) & 1266 + Material%c(im2)*Spring%hline(2,is))/h 1267 phi = (Material%phi(im1)*Spring%hline(1,is) & 1268 + Material%phi(im2)*Spring%hline(2,is))/h 1269 END SUBROUTINE strength
1265,1266行における変数(cm)がせん断強 $c$ に対する2要素の平均値,1267行,1268行に示す変数(phi)が内部摩擦角 $\phi$ に対する平均値である.強度定数の場合,必ずしもこのような平均値をとる方法が良いとはいえない場合もあるので,目的に応じて修正すればよい.

6-3 領域内の応力計算

 変位型のFEMでは,節点変位から要素内ひずみを求めた後,このひずみと構成行列から要素内の応力を計算している.一方,HPMにおいても領域内においてテンソル量としての応力を取り扱う.ただし,HPMでは,全体係数行列で示される連立方程式を解くことで,剛体変位とともに,領域内のひずみを直接求める.したがって,領域内の応力は,このひずみから求めることができる.
 具体的なプログラムをプログラム6.6に示す.1102行が,解の配列からひずみの解を取り出している箇所である.1104行で領域内の構成行列を作成し,1108行でこの構成行列とひずみの積から領域内の応力を計算している.
プログラム6.6 領域内の応力計算(ElementStress)
1090 !-------------------------------------------------------------------------- 1091 SUBROUTINE ElementStress( Element, Material ) 1092 1093 TYPE(typeElement), INTENT(IN) :: Element 1094 TYPE(typeMaterial), INTENT(IN) :: Material 1095 REAL(8) :: D(3,3),eps(3),sig(3),ww 1096 INTEGER :: ie,i,j,ii 1097 1098 DO ie = 1, Element%no 1099 IF(Element%node(3,ie) /= 0) THEN 1100 DO i = 1, 3 1101 ii = 3 + i + (ie-1)*Element%dof 1102 eps(i) = Element%ddisp(ii) 1103 END DO 1104 CALL formDmatrix(ie,Element,Material,D) 1105 DO i = 1, 3 1106 ww = 0.D0 1107 DO j = 1, 3 1108 ww = ww + D(i,j)*eps(j) 1109 END DO 1110 sig(i) = ww 1111 END DO 1112 DO i = 1, 3 1113 Element%dstrain(i,ie) = eps(i) 1114 Element%dstress(i,ie) = sig(i) 1115 END DO 1116 END IF 1117 END DO 1118 END SUBROUTINE ElementStress
 本サンプルプログラムでは,線形の変位場を用いているため,領域内のひずみは一定となり,したがって,応力も領域内において一定となっている.また,領域内降伏についても,3.3節で述べたように,FEMと同様な取り扱いで考慮することができる.ただし,本サンプルプログラムでは,領域内は弾性状態のみを仮定しており,材料非線形と取り扱いの詳細は省略する.

6-4 拘束箇所の反力計算

 HPMの拘束条件の処理方法には,自由度を直接拘束する方法と,ペナルティ関数を用いて間接的に拘束条件と取り込む方法がある.本サンプルプログラムでは,より一般的な処理が可能な後者の方法で拘束条件を導入している.本節では,のような方法で拘束した場合の反力の計算方法について説明する.
 ペナルティ関数を用いた拘束の方法については,2.5節に詳細が述べられていが,概略を述べると,拘束辺(点)上の変位が拘束変位(強制変位)量と等しくなるという付帯条件をLagrangeの未定乗数によりハイブリッド型仮想仕事に導入することで拘束条件を考慮する.このとき,Lagrangeの未定乗数 $\boldsymbol{\lambda}$ が物理的には表面力に相当することから,
\[ {\rm (6.3)}   \left. \boldsymbol{\lambda} \right|_{\Gamma_u} = \boldsymbol{k} \cdot \left. \boldsymbol{\delta} \right|_{\Gamma_u} \]
と仮定する.ここで,$\boldsymbol{k}$ はペナルティ関数で,$\left. \boldsymbol{\delta} \right|_{\Gamma_u}$ は,強制変位量 $\hat{\boldsymbol{u}}$ と領域内の変位場から求まる拘束辺(点)上の変位 $\left. \boldsymbol{u}^{(e)} \right|_{\Gamma_u}$ との差で以下のように表される.
\[ {\rm (6.4)}   \left. \boldsymbol{\delta} \right|_{\Gamma_u} = \hat{\boldsymbol{u}} - \left. \boldsymbol{u}^{(e)} \right|_{\Gamma_u} \]
ここで,反力は拘束点と小領域内の拘束点に該当する位置との間の表面力で表されるので,式(6.3)の $\left. \boldsymbol{\lambda} \right|_{\Gamma_u}$ が反力となる.
 以上の関係を基に作成したプログラムをプログラム6.7に示す.1290行で入力した強制変位量 $\hat{\boldsymbol{u}}$ をセットし,1305行で拘束位置での変位量 $\left. \boldsymbol{u}^{(e)} \right|_{\Gamma_u}$ を計算している.さらに1307行で,式(6.3)に基づき反力を計算している.本サンプルプログラムでは,拘束位置として領域境界辺のみを対象としているため,反力の計算にあたり,境界辺に関する数値積分(3点積分)を行い,合力としの反力を求めている.
プログラム6.7 反力計算(Reaction)
1270 !-------------------------------------------------------------------------- 1271 SUBROUTINE Reaction( Node, Element, Material, Load, Boundary, Line ) 1272 1273 TYPE(typeNode), INTENT(IN) :: Node 1274 TYPE(typeElement), INTENT(IN) :: Element 1275 TYPE(typeMaterial), INTENT(IN) :: Material 1276 TYPE(typeLoad), INTENT(IN) :: Load 1277 TYPE(typeBoundary), INTENT(INOUT) :: Boundary 1278 TYPE(typeNumInteg), INTENT(IN) :: Line 1279 1280 INTEGER :: ib,ie,id,in1,in2,im,in,ip,i 1281 REAL(8) :: f_disp,t,length,shape(2,6),disp(6),uu,reac,wt,pt 1282 1283 pt = Spring%penalty*MAXVAL( Material%young ) 1284 1285 DO ib = 1, Boundary%no 1286 ie = Boundary%element(ib) 1287 id = Boundary%direction(ib) 1288 in1 = Boundary%node(1,ib) 1289 in2 = Boundary%node(2,ib) 1290 f_disp = Boundary%disp(ib) 1291 DO i = 1, Element%dof 1292 in = i + (ie-1)*Element%dof 1293 disp(i) = Element%ddisp(in) 1294 END DO 1295 im = Element%material(ie) 1296 t = Material%thick(im) 1297 length = SQRT((Node%coord(1,in2)-Node%coord(1,in1))**2 & 1298 +(Node%coord(2,in2)-Node%coord(2,in1))**2) 1299 reac = 0.D0 1300 DO ip = 1, 3 1301 CALL formShape(ie,ip,in1,in2,Node,Element,Line,shape) 1302 wt = 0.5*Line%weight(ip)*length*t 1303 uu = 0.D0 1304 DO i = 1, Element%dof 1305 uu = uu + shape(id,i)*disp(i) 1306 END DO 1307 reac = reac + (uu - f_disp)*pt*wt 1308 END DO 1309 Boundary%dreaction(ib) = reac 1310 END DO 1311 END SUBROUTINE Reaction

6-5 荷重増分率の計算

 荷重増分法における山田の方法により増分計算を行う場合,荷重増分率はプログラム内部で自動的に計算される.本節では,このことについて若干の補足をする.
 塑性流れ則に従えば,すでに降伏しているペナルティ辺の表面力は,除荷が発生しない限り図6.4(a)に示すよう,降伏面上を移動する.したがって,どのような荷重増分量であれ,降伏条件を破ることはない.ところが,(b)に示すような弾性状態の場合,荷重増分率によっては降伏曲面を越えることもありうる.山田の方法は3.4節で示したように,弾性状態の表面力がちょうど降伏面上に載るような荷重増分率を計算している.

$\hspace{1em}$(a) 降伏曲面上の表面力 $\hspace{7em}$(b) 弾性状態
$\hspace{10em}$図6.4 表面力の移動
 このような,荷重増分率を計算する流れを示したものが図6.5である.すでに降伏しているペナルティ辺については荷重増分率を計算する必要がないため無視し,弾性状態及び除荷状態のペナルティ辺についてのみ荷重増分率の計算を行っている.また,強度定数については,6.2節における $\mu$ に関する計算の場合と同様,垂線を重みとして2要素の平均値を用いる.

$\hspace{8em}$図6.5 荷重増分率の計算フロー
3.4節で説明したように,荷重増分率を計算するためには2次方程式を解かなければならない.そこで,各々の破壊条件に対する2次方程式の係数 $A, B, C$ を求め,各ペナルティ辺に関する荷重増分率を計算する.これをすべてのペナルティ辺について計算し,最小の値を今回の荷重増分率(minStep)とする.今回までにどれだけの荷重が作用したかは,各荷重増分率の累計を以下のようにとればよい.
\[ {\rm (6.5)}   r_{\rm min} = r_{\rm min} + {\rm minStep} \]
荷重増分率の累計 $r_{\rm min}$ が1になったとき,想定していた荷重の100%が作用したことになる.
 これらの関係をプログラム化したものがプログラム6.8に示すサブルーチン(incRatio)である.1328行~1332行がMohr-Coulombの条件に対する2次方程式の係数を求めている箇所で,l334行~l338行がvonMisesの条件に対するものである.
プログラム6.8 荷重増分率の計算(incRatio)
1312 !-------------------------------------------------------------------------- 1313 SUBROUTINE incRatio( Element, Material, Spring, Nonlinear ) 1314 1315 TYPE(typeElement), INTENT(IN) :: Element 1316 TYPE(typeMaterial), INTENT(IN) :: Material 1317 TYPE(typeSpring), INTENT(IN) :: Spring 1318 TYPE(typeNonLinear),INTENT(INOUT) :: NonLinear 1319 INTEGER :: is 1320 REAL(8) :: minStep,step,cm,phi,pt,a,b,c 1321 REAL(8) :: PAI = 3.141592654D0 1322 1323 minStep = 9999.D0 1324 1325 DO is = 1, Spring%no 1326 CALL strength(is,Element,Material,Spring,cm,phi) 1327 IF(Element%type == 0) THEN 1328 pt = DTAN(phi*PAI/180.D0) 1329 a = Spring%dstress(2,is)**2 - (Spring%dstress(1,is)*pt)**2 1330 b = 2.D0*(Spring%stress(2,is)*Spring%dstress(2,is) & 1331 + (cm-Spring%stress(1,is)*pt)*Spring%dstress(1,is)*pt) 1332 c = Spring%stress(2,is)**2 - (cm-Spring%stress(1,is)*pt)**2 1333 ELSE 1334 a = (Spring%dstress(1,is)**2)/4.D0 + Spring%dstress(2,is)**2 1335 b = Spring%stress(1,is)*Spring%dstress(1,is)/2.D0 & 1336 + 2.D0*Spring%stress(2,is)*Spring%dstress(2,is) 1337 c = (Spring%stress(1,is)**2)/4.D0 + Spring%stress(2,is)**2 & 1338 - cm**2 1339 END IF 1340 step = ratio(a,b,c) 1341 IF(minStep > step) THEN 1342 minStep = step 1343 END IF 1344 END DO 1345 NonLinear%step = minStep 1346 NonLinear%rmin = NonLinear%rmin + minStep 1347 IF(NonLinear%rmin > 0.9998D0) THEN 1348 NonLinear%step = NonLinear%step - NonLinear%rmin + 1.D0 1349 NonLinear%rmin = 1.D0 1350 END IF 1351 END SUBROUTINE incRatio
 2次方程式の根はプログラム6.9に示す関数(ratio)で計算している.このようにして得られた荷重増分率は変数(step)に割り当てられ,すべてのペナルティ辺に関する最小荷重増分率(minStep)を1341行~1343行において設定している.この荷重増分率(minStep)が今回の収束計算における荷重増分率となる.荷重増分率の累計(NonLinear%rmin)は1345行~1350行において計算している.
 数値計算では丸め誤差など,各種の誤差が混入するため,厳密に荷重増分率の累計が1.0となることはまれである.そこで1347行に示すよう,倍精度計算の場合,NonLinear%rminが0.9998以上であればほぼ100%の荷重が作用したものとみなし,1349行のように強制的にNonLinear%rminを1にセットする.このとき,最後の荷重増分率(NonLinear%step)には多少の誤差を認め,1348行に示すよう残りの荷重量すベてが載荷するよう再セットする.
 なお,1340行における関数(ratio)は,2次方程式の根を求める関数で,詳細は付録の1353行~1390行に掲載している.
 以上のようにして荷重増分率が決定されたなら,今回までの全変位 $\boldsymbol{u}^{n+1}$,全ひずみ $\boldsymbol{\varepsilon}^{n+1}$,および全応力 $\boldsymbol{\sigma}^{n+1}$,全表面力 $\boldsymbol{\lambda}^{n+1}$,全反力 $\boldsymbol{R}^{n+1}$ が以下のように求められる.
\[ {\rm (6.6)}   \left. \begin{array}{l} \boldsymbol{u}^{n+1} = \boldsymbol{u}^{n} + \Delta \boldsymbol{u}^{n+1} \cdot {\rm step} \\[0.3em] \boldsymbol{\varepsilon}^{n+1} = \boldsymbol{\varepsilon}^{n} + \Delta \boldsymbol{\varepsilon}^{n+1} \cdot {\rm step} \\[0.3em] \boldsymbol{\sigma}^{n+1} = \boldsymbol{\sigma}^{n} + \Delta \boldsymbol{\sigma}^{n+1} \cdot {\rm step} \\[0.3em] \boldsymbol{\lambda}^{n+1} = \boldsymbol{\lambda}^{n} + \Delta \boldsymbol{\lambda}^{n+1} \cdot {\rm step} \\[0.3em] \boldsymbol{R}^{n+1} = \boldsymbol{R}^{n} + \Delta \boldsymbol{R}^{n+1} \cdot {\rm step} \end{array} \right\} \]
ここで上付きの(n)が前回までの全変位及び全表面力で(n+1)が今回の量であることを示す.
 この関係をもとにプログラム化したものがプログラム6.9に示すサブルーチン(totalValue)である.降伏していないペナルティ辺のうち,最も少ない荷重増分量により降伏するであろうと考えられるペナルティ辺より荷重増分率を決定しているため,上式のように得られた全てのペナルティ辺が所有している表面力は降伏曲面上にあるかもしくは弾性状態となり,決して降伏曲面を突き抜けることはない.
プログラム6.9 全変位・全表面力の計算(totalValue)
1391 !-------------------------------------------------------------------------- 1392 SUBROUTINE totalValue( Element, Spring, Nonlinear ) 1393 1394 TYPE(typeElement), INTENT(INOUT) :: Element 1395 TYPE(typeSpring), INTENT(INOUT) :: Spring 1396 TYPE(typeNonLinear),INTENT(IN) :: NonLinear 1397 1398 Element%disp = Element%disp + Element%ddisp*NonLinear%step 1399 Element%strain = Element%strain + Element%dstrain*NonLinear%step 1400 Element%stress = Element%stress + Element%dstress*NonLinear%step 1401 Spring%strain = Spring%strain + Spring%dstrain*NonLinear%step 1402 Spring%stress = Spring%stress + Spring%dstress*NonLinear%step 1403 Boundary%reaction = Boundary%reaction + Boundary%dreaction*NonLinear%step 1404 END SUBROUTINE totalValue
 本サンプル・プログラムでは,隣接する領域境界に設けられたペナルティ辺の降伏のみ考慮しており,引っ張りに伴うペナルティ辺の切断や,領域内の降伏は無視している.もし,これらの破壊要因を考慮するのであれば,それぞれの破壊要因について,本節で説明した荷重増分率を計算し,それらの中の最小値を荷重増分率とするように設定すればよい.

6-6 破壊判定

 山田の方法を用いた荷重増分計算では増分計算毎に塑性化したペナルティ係数行列や領域内剛性行列を作成し直す.このためには,前回のペナルティ辺や領域内の状態が弾性状態か塑性状態か,あるいは除荷状態か負荷状態かを把握しておく必要がある.本サンプルプログラムでは,ペナルティ辺に関する状態のみ考慮しており,図6.6は,その場合の判定の流れを示したものである.

$\hspace{9em}$図6.6 降伏判定のフロー
 ここで,この流れに現れる降伏フラッグの種類を整理しておこう
  Spring%flag = 0 : 弾性状態
  Spring%flag = 1 : 降伏状態
  Spring%flag = -2 : 除荷状態
 図に示す(*1)の判定は,すでに降伏状態にあるペナルティ辺か否かを判定している.降伏状態にあれば除荷が発生しない限り塑性状態を継続するものとしてフラッグの変更を行わない.もし,ペナルティ辺が降伏状態でなければ除荷状態か否かを判定し,除荷状態であれば以後弾性と見なし,フラッグをSpring%flag = -2にセットする.(*2)の判定文は今回の表面力が降伏しているか否かの判定で,もし,降伏していればフラッグを1とし,以後,塑性としての取り扱いをする.このフローをプログラム化したものがプログラム6.10に示すサブルーチン(YieldCheck)である.
プログラム6.10 降伏判定(YieldCheck)
1405 !------------------------------------------------------------------------- 1406 SUBROUTINE YieldCheck( Element, Material, Spring ) 1407 1408 TYPE(typeElement), INTENT(IN) :: Element 1409 TYPE(typeMaterial), INTENT(IN) :: Material 1410 TYPE(typeSpring), INTENT(IN) :: Spring 1411 INTEGER :: is 1412 REAL(8) :: cm,phi,pt,tau 1413 REAL(8) :: PAI = 3.141592654D0 1414 1415 DO is = 1, Spring%no 1416 IF(Spring%flag(is) /= 1) THEN 1417 IF(Spring%flag(is) ==2) THEN 1418 Spring%flag(is) = -2 1419 ELSE 1420 CALL strength(is,Element,Material,Spring,cm,phi) 1421 IF(Element%type == 0) THEN 1422 cm = cm*0.998D0 1423 pt = DTAN(phi*PAI/180.0) 1424 tau = ABS(Spring%stress(2,is))+Spring%stress(1,is)*pt 1425 IF(tau > cm) THEN 1426 Spring%flag(is) = 1 1427 END IF 1428 ELSE 1429 cm = cm**2*0.998D0 1430 tau = Spring%stress(1,is)**2/4.D0 + Spring%stress(2,is)**2 1431 IF(tau > cm) THEN 1432 Spring%flag(is) = 1 1433 END IF 1434 END IF 1435 END IF 1436 END IF 1437 END DO 1438 END SUBROUTINE YieldCheck
 この判定で注意してほしいことはl422行と1429行においてせん断強さに0.998を掛けていることである.厳密にはこのような処理を行う必要はないが,実数計算の場合,丸め誤差等により本来1となるべき解が0.99…となってしまうことが度々ある.前節で説明した全表面力の計算も実数計算であるから,表面力が降伏曲面上に完全に一致することは少ない.

$\hspace{2em}$図6.7 誤差の許容範囲
 そこで,図6.7に示すよう,ある程度許容範囲を設け,現在の表面力がそれ以上なら降伏とみなす方法をとる.山田の方法では一つ一つペナルティ辺を降伏させてゆくが,このような許容範囲を与えることで,降伏強度に非常に近い表面力を持つペナルティ辺が存在した場合,一度に何箇所か降伏することもありうる.しかし,あまり厳密に判定したとしても精度はそれほど上がらないことも多く,場合によっては解の収束性を損なうこともある.筆者らの経験では単精度の場合で0.98程度,倍精度の場合で0.998程度の設定によりあまり誤差の無い極限荷重を得ている.