1 C 这是一个采用平面四边形八节点等参单元的平面有限元分析程序。 2 PROGRAM PLANEFEM 3 IMPLICIT REAL*8(A-H,O-Z) 4 CHARACTER*80 LINECHAR,NEWLINECHAR 5 COMMON A(30000),L(4000) 6 COMMON /SOL/NPOIN,NELEM,NTYPE,NMATS 7 OPEN(5,FILE='FEMDATA',STATUS='OLD') 8 OPEN(6,FILE='FEMOUT',STATUS='UNKNOWN') 9 C 以下进行的是从数据文件FEMDATA中读入数据文件主标题信息。 10 READ(5,5000) LINECHAR 11 LOCATECHAR=INDEX(LINECHAR,'输入') 12 IF(LOCATECHAR.NE.0) THEN 13 LINECHAR(LOCATECHAR:LOCATECHAR+3)='输出' 14 ENDIF 15 WRITE(6,5100) LINECHAR 16 5000 FORMAT(A) 17 5100 FORMAT(80('*')/A/80('*')/) 18 C 以下进行的是先读入一行字符,然后从字符中读入网格单元总数NELEM。 19 READ(5,5000) LINECHAR 20 WRITE(6,5000) LINECHAR 21 LOCATECHAR=INDEX(LINECHAR,'=') 22 LOCATECHAR=LOCATECHAR+1 23 NEWLINECHAR=LINECHAR(LOCATECHAR:80) 24 READ(NEWLINECHAR,5200) NELEM 25 5200 FORMAT(I5) 26 C 以下进行的是先读入一行字符,然后从字符中读入单元节点总数NPOIN。 27 READ(5,5000) LINECHAR 28 WRITE(6,5000) LINECHAR 29 LOCATECHAR=INDEX(LINECHAR,'=') 30 LOCATECHAR=LOCATECHAR+1 31 NEWLINECHAR=LINECHAR(LOCATECHAR:80) 32 READ(NEWLINECHAR,5200) NPOIN 33 C 以下进行的是先读入一行字符,然后从字符中读入问题类型编号NTYPE。 34 READ(5,5000) LINECHAR 35 WRITE(6,5000) LINECHAR 36 LOCATECHAR=INDEX(LINECHAR,'=') 37 LOCATECHAR=LOCATECHAR+1 38 NEWLINECHAR=LINECHAR(LOCATECHAR:80) 39 READ(NEWLINECHAR,5200) NTYPE 40 C 以下进行的是先读入一行字符,然后从字符中读入材料类型总数NMATS。 41 READ(5,5000) LINECHAR 42 WRITE(6,5000) LINECHAR 43 LOCATECHAR=INDEX(LINECHAR,'=') 44 LOCATECHAR=LOCATECHAR+1 45 NEWLINECHAR=LINECHAR(LOCATECHAR:80) 46 READ(NEWLINECHAR,5200) NMATS 47 C 以下进行的是根据以输入的控制参数确定虚拟数组在实数组中的起始位置。 48 N1=1 49 N2=N1+NPOIN*2 50 N3=N2+NMATS*3 51 N4=N3+NPOIN*2 52 NN2=N1+NELEM*8 53 NN3=NN2+NPOIN 54 NN4=NN3+NELEM 55 NN5=NN4+NELEM 56 C 以下进行的是调用子程序进行有限元分析计算。 57 CALL INPUT(A(N1),A(N2),L(N1),L(NN2),L(NN3)) 58 CALL STIF(A(N1),A(N2),L(N1),L(NN3)) 59 CALL LOAD(A(N1),L(N1),L(NN4)) 60 CALL ASEM(A(N3),A(N4),L(N1),L(NN2),L(NN4),L(NN5)) 61 CALL SOLVE(A(N3),A(N4),L(NN5)) 62 CALL STRE(A(N1),A(N2),A(N3),L(N1),L(NN3)) 63 WRITE(*,5300) 64 5300 FORMAT(////////////////) 65 STOP ' *** 程序正常运行结束 ***' 66 END 67 C***************************************************************************** 68 C 这是一个进行数据输入并进行数据检验的子程序。 * 69 C***************************************************************************** 70 SUBROUTINE INPUT(COORD,PROPS,LNODS,IFPRE,MATNO) 71 IMPLICIT REAL*8(A-H,O-Z) 72 CHARACTER*80 LINECHAR,NEWLINECHAR,CHARCOMP 73 LOGICAL NOTREADCHAR 74 DIMENSION COORD(2,1),PROPS(3,1),LNODS(8,1),IFPRE(1),MATNO(1) 75 DIMENSION NEROR(6) 76 COMMON/SOL/NPOIN,NELEM,NTYPE,NMATS 77 CHARCOMP='aa(这个字符常量在ASCII序列中介于数字和字符之间)' 78 NNODE=8 79 C 以下进行的是对材料类型编号赋初值。 80 I=1 81 DO WHILE (I.LE.NELEM) 82 MATNO(I)=1 83 I=I+1 84 ENDDO 85 C 以下进行的是输入材料类型编号信息标题。 86 READ(5,5000) LINECHAR 87 WRITE(6,5000) LINECHAR 88 5000 FORMAT(A) 89 C 以下进行的是输入材料类型编号。 90 DO WHILE (NMATS.GT.1) 91 NUMBERREAD=1 92 DO WHILE (NUMBERREAD.LE.NMATS) 93 READ(5,*) I,MATNO(I) 94 NUMBERREAD=NUMBERREAD+1 95 ENDDO 96 ENDDO 97 C 以下进行的是输出材料类型编号。 98 I=1 99 DO WHILE (I.LE.NELEM) 100 WRITE(6,6000) I,MATNO(I) 101 I=I+1 102 ENDDO 103 6000 FORMAT(2X,'单元编号为:',I4,10X,'材料类型编号为:'I6) 104 C 以下进行的是输入单元节点总体编号标题。 105 READ(5,5000) LINECHAR 106 LOCATECHAR=INDEX(LINECHAR,'输入') 107 IF(LOCATECHAR.NE.0) THEN 108 LINECHAR(LOCATECHAR:LOCATECHAR+3)='输出' 109 ENDIF 110 WRITE(6,5000) LINECHAR 111 C 以下进行的是输入单元节点总体编号。 112 NOTREADCHAR=.TRUE. 113 DO WHILE (NOTREADCHAR) 114 READ(5,5000) LINECHAR 115 IF (LINECHAR(1:2).LT.CHARCOMP(1:2)) THEN 116 READ(LINECHAR,6100) IELEM,(LNODS(I,IELEM),I=1,NNODE) 117 J=1 118 DO WHILE (J.LE.10) 119 KELEM=IELEM+J 120 IF (KELEM.GT.NELEM) GOTO 100 121 K=1 122 DO WHILE (K.LE.8) 123 LNODS(K,KELEM)=LNODS(K,IELEM)+J 124 K=K+1 125 ENDDO 126 100 J=J+1 127 ENDDO 128 ELSE 129 NOTREADCHAR=.FALSE. 130 END IF 131 ENDDO 132 6100 FORMAT(9I5) 133 C 以下进行的是输出单元节点总体编号。 134 IELEM=1 135 DO WHILE (IELEM.LE.NELEM) 136 WRITE(6,6200) IELEM,(LNODS(I,IELEM),I=1,NNODE) 137 IELEM=IELEM+1 138 ENDDO 139 6200 FORMAT(2X,'单元编号为:',I4,' 节点总体编号为:',8I5) 140 C 以下进行的是输出单元节点的直角坐标信息标题。 141 LOCATECHAR=INDEX(LINECHAR,'输入') 142 IF(LOCATECHAR.NE.0) THEN 143 LINECHAR(LOCATECHAR:LOCATECHAR+3)='输出' 144 ENDIF 145 WRITE(6,5000) LINECHAR 146 C 以下进行的是输入单元节点的直角坐标信息。 147 NOTREADCHAR=.TRUE. 148 DO WHILE (NOTREADCHAR) 149 READ(5,5000) LINECHAR 150 IF (LINECHAR(1:2).LT.CHARCOMP(1:2)) THEN 151 READ(LINECHAR,6300) IPOIN,(COORD(J,IPOIN),J=1,2) 152 ELSE 153 NOTREADCHAR=.FALSE. 154 END IF 155 ENDDO 156 6300 FORMAT(I5,2F15.5) 157 C 以下进行的是输出单元节点的极坐标信息标题。 158 LOCATECHAR=INDEX(LINECHAR,'输入') 159 IF(LOCATECHAR.NE.0) THEN 160 LINECHAR(LOCATECHAR:LOCATECHAR+3)='输出' 161 ENDIF 162 WRITE(6,5000) LINECHAR 163 C 以下进行的是输入单元节点的极坐标信息。 164 PI=DATAN(1.D0)*4.D0 165 NOTREADCHAR=.TRUE. 166 DO WHILE (NOTREADCHAR) 167 READ(5,5000) LINECHAR 168 IF (LINECHAR(1:2).LT.CHARCOMP(1:2)) THEN 169 READ(LINECHAR,6300) IPOIN,R,ANGLE 170 ANGLE=ANGLE/180.D0*PI 171 COORD(1,IPOIN)=R*DCOS(ANGLE) 172 COORD(2,IPOIN)=R*DSIN(ANGLE) 173 NUMBERREAD=NUMBERREAD+1 174 ELSE 175 NOTREADCHAR=.FALSE. 176 END IF 177 ENDDO 178 C 以下进行的是根据输入信息计算出单元节点的坐标。 179 I=1 180 DO WHILE (I.LE.NELEM) 181 INODE=1 182 DO WHILE (INODE.LE.NNODE) 183 NODST =LNODS(INODE,I) 184 IGASH=INODE+2 185 IF(IGASH.GT.NNODE) IGASH=1 186 NDOFN=LNODS(IGASH,I) 187 MIDPT=INODE+1 188 NODMD=LNODS(MIDPT,I) 189 J=1 190 DO WHILE (J.LE.2) 191 IF(DABS(COORD(J,NODMD)).LT.1.E-6) THEN 192 COORD(J,NODMD)=(COORD(J,NDOFN)+COORD(J,NODST))/2.0 193 ENDIF 194 J=J+1 195 ENDDO 196 INODE=INODE+2 197 ENDDO 198 I=I+1 199 ENDDO 200 C 以下进行的是输出单元节点的坐标信息。 201 WRITE(6,6400) 202 I=1 203 DO WHILE (I.LE.NPOIN) 204 WRITE(6,6500) I,(COORD(J,I),J=1,2) 205 I=I+1 206 ENDDO 207 6400 FORMAT(4X,'节点编号',10X,'X坐标',16X,'Y坐标') 208 6500 FORMAT(2X,I10,F16.5,6X,F16.5) 209 C 以下进行的是输出单元节点约束代码信息标题。 210 LOCATECHAR=INDEX(LINECHAR,'输入') 211 IF(LOCATECHAR.NE.0) THEN 212 LINECHAR(LOCATECHAR:LOCATECHAR+3)='输出' 213 ENDIF 214 WRITE(6,5000) LINECHAR 215 C 以下进行的是输入单元节点约束代码信息。 216 NOTREADCHAR=.TRUE. 217 DO WHILE (NOTREADCHAR) 218 READ(5,5000) LINECHAR 219 IF (LINECHAR(1:2).LT.CHARCOMP(1:2)) THEN 220 READ(LINECHAR,6600) I,IFPRE(I) 221 ELSE 222 NOTREADCHAR=.FALSE. 223 END IF 224 ENDDO 225 6600 FORMAT(2I5) 226 C 以下进行的是输出单元节点约束代码信息。 227 LINECHAR='节点约束代码信息为一个两位数的阿拉伯数字,其中,' 228 WRITE(6,5000) LINECHAR 229 LINECHAR='十位数表示X方向的约束状况,' 230 NEWLINECHAR='个位数表示Y方向的约束状况,' 231 LOCATECHAR=LEN_TRIM(LINECHAR) 232 LOCATECHAR=LOCATECHAR+1 233 LINECHAR(LOCATECHAR:)=NEWLINECHAR(1:LOCATECHAR) 234 WRITE(6,5000) LINECHAR 235 LINECHAR='具体的,0表示自由,1表示固定,2表示给定非零位移。' 236 WRITE(6,5000) LINECHAR 237 I=1 238 DO WHILE (I.LE.NPOIN) 239 WRITE(6,6700) I,IFPRE(I) 240 I=I+1 241 ENDDO 242 6700 FORMAT(2X,'节点编号为:',I4,13X,'约束代码为:',I4) 243 C 以下进行的是输入材料的特性参数信息标题。 244 LINECHAR='以下输出的是材料特性参数(格式为:' 245 NEWLINECHAR='材料类型编号NMATS,弹性模量E,泊松比μ,厚度t)' 246 LOCATECHAR=LEN_TRIM(LINECHAR) 247 LOCATECHAR=LOCATECHAR+1 248 LINECHAR(LOCATECHAR:)=NEWLINECHAR(1:46) 249 WRITE(6,5000) LINECHAR 250 C 以下进行的是输入材料的特性参数。 251 NUMBERREAD=1 252 DO WHILE (NUMBERREAD.LE.NMATS) 253 READ(5,*) I,(PROPS(J,I),J=1,3) 254 WRITE(6,6800) I 255 WRITE(6,6900) (PROPS(J,I),J=1,3) 256 NUMBERREAD=NUMBERREAD+1 257 ENDDO 258 6800 FORMAT(2X,'材料类型编号为:',I2,' 的特性参数为:') 259 6900 FORMAT(2X,1PE13.3,1PE13.3,1PE13.3) 260 C 以下进行的是对输入和计算出的数据进行检验。 261 IERROR=1 262 DO WHILE (IERROR.LE.6) 263 NEROR(IERROR)=0 264 IERROR=IERROR+1 265 ENDDO 266 C 以下进行的是对输入和计算出的单元节点坐标进行检验。 267 IPOIN=1 268 DO WHILE (IPOIN.LE.NPOIN) 269 KPOIN=IPOIN-1 270 JPOIN=1 271 DO WHILE (JPOIN.LE.KPOIN) 272 J=1 273 DO WHILE (J.LE.2) 274 IF(COORD(J,IPOIN).NE.COORD(J,JPOIN)) GOTO 200 275 J=J+1 276 ENDDO 277 NEROR(1)=NEROR(1)+1 278 WRITE(6,7000) IPOIN,JPOIN 279 JPOIN=JPOIN+1 280 ENDDO 281 200 CONTINUE 282 IPOIN=IPOIN+1 283 ENDDO 284 7000 FORMAT(2X,'坐标错误!节点编号为',I4,' 的坐标等于',I4,' 的坐标') 285 C 以下进行的是对输入和计算出的材料类型编号进行检验。 286 I=1 287 DO WHILE (I.LE.NELEM) 288 IF(MATNO(I).LE.0.OR.MATNO(I).GT.NMATS) THEN 289 NEROR(2)=NEROR(2)+1 290 END IF 291 I=I+1 292 ENDDO 293 IF(NEROR(2).NE.0) THEN 294 WRITE(6,7100) NEROR(2) 295 END IF 296 7100 FORMAT(2X,' 材料类型编号错误,错误个数为',I2,' 个') 297 C 以下进行的是对输入和计算出的单元节点总体编号进行检验。 298 I=1 299 DO WHILE (I.LE.NELEM) 300 J=1 301 DO WHILE (J.LE.8) 302 IF(LNODS(J,I).LE.0.OR.LNODS(J,I).GT.NPOIN) THEN 303 NEROR(3)=NEROR(3)+1 304 END IF 305 J=J+1 306 ENDDO 307 I=I+1 308 ENDDO 309 IF(NEROR(3).NE.0) THEN 310 WRITE(6,7200) NEROR(3) 311 END IF 312 7200 FORMAT(2X,'单元节点总体编号错误,错误个数为',I5,' 个') 313 C 以下进行的是对输入和计算出的单元节点编号进行检验。 314 I=1 315 DO WHILE (I.LE.NPOIN) 316 KSTAR=0 317 IELEM=1 318 DO WHILE (IELEM.LE.NELEM) 319 KZERO=0 320 J=1 321 DO WHILE(J.LE.8) 322 IF(LNODS(J,IELEM).EQ.I) THEN 323 KZERO=KZERO+1 324 KSTAR=IELEM 325 END IF 326 J=J+1 327 ENDDO 328 IF(KZERO.GT.1) THEN 329 NEROR(4)=NEROR(4)+1 330 WRITE(6,7300) I,IELEM 331 END IF 332 IELEM=IELEM+1 333 ENDDO 334 IF(KSTAR.EQ.0)THEN 335 NEROR(5)=NEROR(5)+1 336 WRITE(6,7400) I 337 END IF 338 I=I+1 339 ENDDO 340 7300 FORMAT(2X,'节点编号',I5,' 在单元',I5,' 中重复。') 341 7400 FORMAT(2X,'总体节点编号',I5,' 在单元中从未出现') 342 C 以下进行的是对输入的单元节点约束代码进行检验。 343 I=1 344 DO WHILE (I.LE.NPOIN) 345 IF(IFPRE(I).LT.0) THEN 346 NEROR(6)=NEROR(6)+1 347 END IF 348 IF(IFPRE(I).GT.22) THEN 349 NEROR(6)=NEROR(6)+1 350 END IF 351 I=I+1 352 ENDDO 353 IF(NEROR(6).NE.0) THEN 354 WRITE(6,7500) NEROR(6) 355 END IF 356 7500 FORMAT(2X,'总体节点编号为',I5,' 的节点约束代码出现错误。') 357 C 以下进行的是判断出错类型。 358 KEROR=0 359 IERROR=1 360 DO WHILE (IERROR.LE.6) 361 IF(NEROR(IERROR).NE.0) THEN 362 WRITE(6,7600) IERROR 363 KEROR=KEROR+1 364 END IF 365 IERROR=IERROR+1 366 ENDDO 367 7600 FORMAT(2X,'出现第 ',I1,' 类错误。') 368 C 以下进行的是判断是否出错,如出错,则中断程序运行,否则返回调用主程序。 369 7700 FORMAT(2X,'*****在输入数据文件中发现错误。程序运行中断*****') 370 IF(KEROR.NE.0) THEN 371 WRITE(6,7700) 372 STOP '*** 程序运行被中断,这是由于输入数据出现错误引起的。***' 373 END IF 374 RETURN 375 END 376 C***************************************************************************** 377 C 这是一个形成单元刚度矩阵的子程序。 * 378 C***************************************************************************** 379 SUBROUTINE STIF(COORD,PROPS,LNODS,MATNO) 380 IMPLICIT REAL*8(A-H,O-Z) 381 DIMENSION COORD(2,1),PROPS(3,1),LNODS(8,1),MATNO(1) 382 DIMENSION POSGP(3),WEIGP(3),ESTIF(136),ELCOD(2,8),DBMAT(3) 383 COMMON/SOL/NPOIN,NELEM,NTYPE,NMATS 384 COMMON/GCOD/GPCOD(2,9) 385 COMMON/BMDMP/BMATX(3,16),DMATX(3,3) 386 OPEN(7,FILE='ESTIF',FORM='UNFORMATTED') 387 C 以下进行的是高斯积分点位置赋值。 388 POSGP(1)=-DSQRT(0.6D0) 389 POSGP(2)=0.0 390 POSGP(3)=DSQRT(0.6D0) 391 C 以下进行的是加权系数赋值。 392 WEIGP(1)=5.0/9.0 393 WEIGP(2)=8.0/9.0 394 WEIGP(3)=5.0/9.0 395 C 以下进行的是应力分量个数赋值。 396 NSTRE=3 397 C 以下进行的是形成弹性矩阵[D]。 398 DO 90 IELEM=1,NELEM 399 WRITE(6,615) IELEM 400 615 FORMAT(2X,'网格单元编号为:',I5) 401 LPROP=MATNO(IELEM) 402 DO 10 I=1,8 403 LNODE=LNODS(I,IELEM) 404 DO 10 J=1,2 405 10 ELCOD(J,I)=COORD(J,LNODE) 406 YOUNG=PROPS(1,LPROP) 407 POISS=PROPS(2,LPROP) 408 THICK=PROPS(3,LPROP) 409 CALL MODPS(YOUNG,POISS) 410 C 以下进行的是存放[K]的一维数组赋初值零。 411 KEVAB=0 412 DO 20 I=1,16 413 DO 20 J=1,I 414 KEVAB=KEVAB+1 415 ESTIF(KEVAB)=0.0 416 20 CONTINUE 417 C 以下进行的是计算积分点处形函数及其导数之值以及对整体坐标的偏导数之值。 418 KGASP=0 419 DO 80 IGAUS=1,3 420 DO 80 JGAUS=1,3 421 KGASP=KGASP+1 422 EXISP=POSGP(IGAUS) 423 ETASP=POSGP(JGAUS) 424 WRITE(6,705) KGASP 425 705 FORMAT(6X,'高斯积分点编号为:',I5) 426 CALL SFR2(EXISP,ETASP) 427 CALL JACOB2(IELEM,DJACB,KGASP,ELCOD) 428 DVOLU=DJACB*WEIGP(IGAUS)*WEIGP(JGAUS)*THICK 429 CALL BMATPS 430 C 以下进行的是弹性矩阵[D]赋初值零。 431 KEVAB=0 432 DO 70 IEVAB=1,16 433 DO 40 ISTRE=1,NSTRE 434 DBMAT(ISTRE)=0.0 435 DO 30 JSTRE=1,NSTRE 436 DBMAT(ISTRE)=DBMAT(ISTRE)+BMATX(JSTRE,IEVAB)*DMATX(JSTRE,ISTRE) 437 30 CONTINUE 438 40 CONTINUE 439 DO 60 JEVAB=1,IEVAB 440 KEVAB=KEVAB+1 441 BTDBM=0.0 442 DO 50 ISTRE=1,NSTRE 443 BTDBM=BTDBM+DBMAT(ISTRE)*BMATX(ISTRE,JEVAB) 444 50 CONTINUE 445 ESTIF(KEVAB)=ESTIF(KEVAB)+BTDBM*DVOLU 446 60 CONTINUE 447 70 CONTINUE 448 80 CONTINUE 449 WRITE(7) ESTIF 450 90 CONTINUE 451 REWIND 7 452 RETURN 453 END 454 C***************************************************************************** 455 C 这是一个形成弹性矩阵的子程序。 * 456 C***************************************************************************** 457 SUBROUTINE MODPS(Y,P) 458 IMPLICIT REAL*8(A-H,O-Z) 459 COMMON/SOL/NPOIN,NELEM,NTYPE,NMATS 460 COMMON/BMDMP/BMATX(3,16),DMATX(3,3) 461 DO 100 I=1,3 462 DO 100 J=1,3 463 DMATX(I,J)=0.0 464 100 CONTINUE 465 C 如果NTYPE=1,表示为平面应力问题。 466 IF(NTYPE.EQ.1) THEN 467 CONST=Y/(1.0-P*P) 468 DMATX(1,1)=CONST 469 DMATX(2,2)=CONST 470 DMATX(1,2)=CONST*P 471 DMATX(2,1)=CONST*P 472 DMATX(3,3)=CONST*(1.0-P)/2.0 473 ENDIF 474 C 如果NTYPE=2,表示为平面应变问题。 475 IF(NTYPE.EQ.2) THEN 476 CONST=Y*(1.0-P)/((1.0+P)*(1.0-2.0*P)) 477 DMATX(1,1)=CONST 478 DMATX(2,2)=CONST 479 DMATX(1,2)=CONST*P/(1.0-P) 480 DMATX(2,1)=CONST*P/(1.0-P) 481 DMATX(3,3)=Y/(2.0*(1.0+P)) 482 ENDIF 483 RETURN 484 END 485 C***************************************************************************** 486 C 这是一个计算形函数当前积分点及形函数对局部坐标的导数值的子程序。 * 487 C***************************************************************************** 488 SUBROUTINE SFR2(S,T) 489 IMPLICIT REAL*8(A-H,O-Z) 490 COMMON/SD/SHAPE(8),DERIV(2,8) 491 C 以下进行的是为简化表达式定义一些变量。 492 S2=S*2.0 493 T2=T*2.0 494 SS=S*S 495 TT=T*T 496 ST=S*T 497 STT=S*T*T 498 SST=S*S*T 499 ST2=S*T*2.0 500 C 以下进行的是给形函数赋值。 501 SHAPE(1)=(-1.0+ST+SS+TT-SST-STT)/4.0 502 SHAPE(2)=(1.0-T-SS+SST)/2.0 503 SHAPE(3)=(-1.0-ST+SS+TT-SST+STT)/4.0 504 SHAPE(4)=(1.0+S-TT-STT)/2.0 505 SHAPE(5)=(-1.0+ST+SS+TT+SST+STT)/4.0 506 SHAPE(6)=(1.0+T-SS-SST)/2.0 507 SHAPE(7)=(-1.0-ST+SS+TT+SST-STT)/4.0 508 SHAPE(8)=(1.0-S-TT+STT)/2.0 509 C 以下进行的是给形函数对局部坐标的导数赋值。 510 DERIV(1,1)=(T+S2-ST2-TT)/4.0 511 DERIV(1,2)=-S+ST 512 DERIV(1,3)=(-T+S2-ST2+TT)/4.0 513 DERIV(1,4)=(1.0-TT)/2.0 514 DERIV(1,5)=(T+S2+ST2+TT)/4.0 515 DERIV(1,6)=-S-ST 516 DERIV(1,7)=(-T+S2+ST2-TT)/4.0 517 DERIV(1,8)=(-1.0+TT)/2.0 518 DERIV(2,1)=(S+T2-SS-ST2)/4.0 519 DERIV(2,2)=(-1.0+SS)/2.0 520 DERIV(2,3)=(-S+T2-SS+ST2)/4.0 521 DERIV(2,4)=-T-ST 522 DERIV(2,5)=(S+T2+SS+ST2)/4.0 523 DERIV(2,6)=(1.0-SS)/2.0 524 DERIV(2,7)=(-S+T2+SS-ST2)/4.0 525 DERIV(2,8)=-T+ST 526 RETURN 527 END 528 C***************************************************************************** 529 C 这是一个形成雅可比矩阵的子程序。 * 530 C***************************************************************************** 531 SUBROUTINE JACOB2(IELEM,DJACB,KGASP,ELCOD) 532 IMPLICIT REAL*8(A-H,O-Z) 533 DIMENSION XJACM(2,2),XJACI(2,2),ELCOD(2,8) 534 COMMON/SD/SHAPE(8),DERIV(2,8) 535 COMMON/CAR/CARTD(2,8) 536 COMMON/GCOD/GPCOD(2,9) 537 C 以下进行的是计算当前积分点的整体坐标。 538 DO 100 I=1,2 539 GPCOD(I,KGASP)=0.0 540 DO 100 J=1,8 541 GPCOD(I,KGASP)=GPCOD(I,KGASP)+ELCOD(I,J)*SHAPE(J) 542 100 CONTINUE 543 C 以下进行的是形成雅可比矩阵[J]的各元素。 544 DO 200 I=1,2 545 DO 200 J=1,2 546 XJACM(I,J)=0.0 547 DO 200 K=1,8 548 XJACM(I,J)=XJACM(I,J)+DERIV(I,K)*ELCOD(J,K) 549 200 CONTINUE 550 C 以下进行的是计算雅可比行列式┃J┃的值。 551 DJACB=XJACM(1,1)*XJACM(2,2)-XJACM(1,2)*XJACM(2,1) 552 WRITE(6,6000) DJACB 553 6000 FORMAT(14X,'雅可比行列式┃J┃的值为:',F12.5) 554 IF(DJACB.LT.1.E-6)THEN 555 WRITE(6,6100) IELEM 556 6100 FORMAT('单元编号为:',I4,' 的雅可比行列式的值小于或等于零!') 557 STOP '****** 程序运行被中断于子程序JACOB2 ******' 558 END IF 559 C 以下进行的是形成雅可比矩阵[J]的逆矩阵的各元素。 560 XJACI(1,1)=XJACM(2,2)/DJACB 561 XJACI(2,2)=XJACM(1,1)/DJACB 562 XJACI(1,2)=-XJACM(1,2)/DJACB 563 XJACI(2,1)=-XJACM(2,1)/DJACB 564 C 以下进行的是计算形函数对整体坐标的导数。 565 DO 300 I=1,2 566 DO 300 K=1,8 567 CARTD(I,K)=0.0 568 DO 300 J=1,2 569 CARTD(I,K)=CARTD(I,K)+XJACI(I,J)*DERIV(J,K) 570 300 CONTINUE 571 RETURN 572 END 573 C***************************************************************************** 574 C 这是一个形成应变矩阵的子程序。 * 575 C***************************************************************************** 576 SUBROUTINE BMATPS 577 IMPLICIT REAL*8(A-H,O-Z) 578 COMMON/CAR/CARTD(2,8) 579 COMMON/SD/SHAPE(8),DERIV(2,8) 580 COMMON/BMDMP/BMATX(3,16),DMATX(3,3) 581 COMMON/SOL/NPOIN,NELEM,NTYPE,NMATS 582 COMMON/GCOD/GPCOD(2,9) 583 C 以下进行的是应变矩阵[B]赋初值零。 584 DO 100 I=1,16 585 DO 100 J=1,3 586 100 BMATX(J,I)=0.0 587 C 以下进行的是形成应变矩阵[B]。 588 NGASH=0 589 DO 200 I=1,8 590 MGASH=NGASH+1 591 NGASH=MGASH+1 592 BMATX(1,MGASH)=CARTD(1,I) 593 BMATX(1,NGASH)=0.0 594 BMATX(2,MGASH)=0.0 595 BMATX(2,NGASH)=CARTD(2,I) 596 BMATX(3,MGASH)=CARTD(2,I) 597 BMATX(3,NGASH)=CARTD(1,I) 598 200 CONTINUE 599 RETURN 600 END 601 C***************************************************************************** 602 C 这是一个计算等效节点载荷的子程序。 * 603 C***************************************************************************** 604 SUBROUTINE LOAD(COORD,LNODS,NLOAD) 605 IMPLICIT REAL*8(A-H,O-Z) 606 CHARACTER*80 LINECHAR,NEWLINECHAR 607 DIMENSION COORD(2,1),LNODS(8,1),NLOAD(1) 608 DIMENSION ELCOD(2,3),ELOAD(16),POSGP(3),WEIGP(3),NOPRS(3) 609 DIMENSION PRESS(3,2),PGASH(2),DGASH(2) 610 COMMON/SOL/NPOIN,NELEM,NTYPE,NMATS 611 COMMON/SD/SHAPE(8),DERIV(2,8) 612 OPEN(8,FILE='ELOAD',FORM='UNFORMATTED') 613 C 以下进行的是高斯积分点位置赋值。 614 POSGP(1)=-DSQRT(0.6D0) 615 POSGP(2)=0.0 616 POSGP(3)=DSQRT(0.6D0) 617 C 以下进行的是加权系数赋值。 618 WEIGP(1)=5.0/9.0 619 WEIGP(2)=8.0/9.0 620 WEIGP(3)=5.0/9.0 621 C 以下进行的是输入两行单元受载信息标题。 622 READ(5,5000) LINECHAR 623 LOCATECHAR=INDEX(LINECHAR,'输入') 624 IF(LOCATECHAR.NE.0) THEN 625 LINECHAR(LOCATECHAR:LOCATECHAR+3)='输出' 626 ENDIF 627 WRITE(6,5000) LINECHAR 628 READ(5,5000) LINECHAR 629 LOCATECHAR=INDEX(LINECHAR,'输入') 630 IF(LOCATECHAR.NE.0) THEN 631 LINECHAR(LOCATECHAR:LOCATECHAR+3)='输出' 632 ENDIF 633 WRITE(6,5000) LINECHAR 634 LOCATECHAR=INDEX(LINECHAR,'=') 635 LOCATECHAR=LOCATECHAR+1 636 NEWLINECHAR=LINECHAR(LOCATECHAR:80) 637 READ(NEWLINECHAR,5200) NUMBER 638 5000 FORMAT(A) 639 5200 FORMAT(I5) 640 C 以下进行的是单元受载边数赋初值零。 641 DO 10 I=1,NELEM 642 10 NLOAD(I)=0 643 C 以下进行的是输入受载网格单元的编号及其受载边数。 644 755 FORMAT(2X,'网格单元编号为:',I4,', 单元受载边数为:',I3) 645 DO 20 I=1,NUMBER 646 READ(5,*) KEL,NEDGE 647 NLOAD(KEL)=NEDGE 648 WRITE(6,755) KEL,NLOAD(KEL) 649 20 CONTINUE 650 DO 200 IELEM=1,NELEM 651 NEDGE=NLOAD(IELEM) 652 C 如果当前单元受载边数为零,则转移到循环的终端语句进行下一个网格单元。 653 IF(NEDGE.EQ.0) GO TO 200 654 C 以下进行的是输入单元受载信息标题。 655 READ(5,5000) LINECHAR 656 LOCATECHAR=INDEX(LINECHAR,'输入') 657 IF(LOCATECHAR.NE.0) THEN 658 LINECHAR(LOCATECHAR:LOCATECHAR+3)='输出' 659 ENDIF 660 WRITE(6,5000) LINECHAR 661 C 以下进行的是单元等效节点载荷列阵赋初值零。 662 DO 50 I=1,16 663 ELOAD(I)=0.0 664 50 CONTINUE 665 C 以下进行的是输入受载边三个节点的总体编号及当前受载边均布载荷σ和τ。 666 DO 160 IEDGE=1,NEDGE 667 READ(5,*) (NOPRS(I),I=1,3) 668 READ(5,*) SGMAR,TAU 669 C 如果均布载荷为零,则输入三个节点的法向载荷σ(1,2,3)及切向载荷τ(1,2,3)。 670 IF(ABS(SGMAR).LT.1.D-8.AND.ABS(TAU).LT.1.D-8) THEN 671 READ(5,*) ((PRESS(J,I),J=1,3),I=1,2) 672 ELSE 673 C 如果均布载荷不为零,则给三个节点赋值。 674 DO 60 I=1,3 675 PRESS(I,1)=SGMAR 676 PRESS(I,2)=TAU 677 60 CONTINUE 678 END IF 679 C 给当前受载边三个节点坐标赋值。 680 DO 100 I=1,3 681 LNODE=NOPRS(I) 682 DO 100 J=1,2 683 ELCOD(J,I)=COORD(J,LNODE) 684 100 CONTINUE 685 T=-1.0 686 DO 150 IGAUS=1,3 687 S=POSGP(IGAUS) 688 CALL SFR2(S,T) 689 DO 110 J=1,2 690 PGASH(J)=0.0 691 DGASH(J)=0.0 692 C 以下进行的是计算当前积分点的σ和τ及偏导数在当前积分点的值。 693 DO 110 I=1,3 694 PGASH(J)=PGASH(J)+PRESS(I,J)*SHAPE(I) 695 DGASH(J)=DGASH(J)+ELCOD(J,I)*DERIV(1,I) 696 110 CONTINUE 697 DVOLU=WEIGP(IGAUS) 698 PXCOM=DGASH(1)*PGASH(2)-DGASH(2)*PGASH(1) 699 PYCOM=DGASH(1)*PGASH(1)+DGASH(2)*PGASH(2) 700 C 查找当前受载边的第I个节点是当前单元的第几个节点,查找结果为第I个节点。 701 DO 120 I=1,8 702 NLOCA=LNODS(I,IELEM) 703 IF(NLOCA.EQ.NOPRS(1)) GO TO 130 704 120 CONTINUE 705 130 J=I+2 706 KOUNT=0 707 DO 140 K=I,J 708 KOUNT=KOUNT+1 709 N=(K-1)*2+1 710 M=N+1 711 C 如果单元节点局部编号大于8,则应等于1。 712 IF(K.GT.8)THEN 713 N=1 714 M=2 715 END IF 716 C 以下进行的是累加得到当前单元的等效节点载荷。 717 ELOAD(N)=ELOAD(N)+SHAPE(KOUNT)*PXCOM*DVOLU 718 ELOAD(M)=ELOAD(M)+SHAPE(KOUNT)*PYCOM*DVOLU 719 140 CONTINUE 720 150 CONTINUE 721 160 CONTINUE 722 WRITE(6,795) ELOAD 723 795 FORMAT(2X,'单元等效载荷列阵为:'/4(1P4E15.5/)) 724 WRITE(8)ELOAD 725 200 CONTINUE 726 RETURN 727 END 728 C***************************************************************************** 729 C 这是一个形成整体刚度矩阵和整体载荷列阵的单元组集子程序。 * 730 C***************************************************************************** 731 SUBROUTINE ASEM(V,A,LNODS,IFPRE,NLOAD,MAXA) 732 IMPLICIT REAL*8(A-H,O-Z) 733 DIMENSION V(1),A(1) 734 DIMENSION LNODS(8,1),IFPRE(1),NLOAD(1),MAXA(1) 735 DIMENSION NCODF(2),ESTIF(136),ELOAD(16) 736 COMMON/SOL/NPOIN,NELEM,NTYPE,NMATS 737 MAXA(1)=1 738 DO 100 IPOIN=1,NPOIN 739 KMIN=NPOIN+1 740 DO 40 IELEM=1,NELEM 741 DO 10 I=1,8 742 LNODE=LNODS(I,IELEM) 743 IF(LNODE.EQ.IPOIN)GO TO 20 744 10 CONTINUE 745 GO TO 40 746 20 CONTINUE 747 DO 30 I=1,8 748 LNODE=LNODS(I,IELEM) 749 IF(LNODE.GE.KMIN)GO TO 30 750 KMIN=LNODE 751 30 CONTINUE 752 40 CONTINUE 753 KHIGH=(IPOIN-KMIN)*2 754 DO 60 J=1,2 755 KDOFN=(IPOIN-1)*2+J+1 756 MAXA(KDOFN)=MAXA(KDOFN-1)+KHIGH+J 757 60 CONTINUE 758 100 CONTINUE 759 NN=NPOIN*2 760 NNM=NN+1 761 NWK=MAXA(NNM)-1 762 WRITE(6,735) NWK 763 735 FORMAT(2X,'剖面元素之和=',I7) 764 DO 120 IWK=1,NWK 765 A(IWK)=0.0 766 120 CONTINUE 767 DO 130 IN=1,NN 768 130 V(IN)=0.0 769 DLARG=1.0D+15 770 REWIND 8 771 DO 300 IELEM=1,NELEM 772 WRITE(6,135) IELEM 773 135 FORMAT(2X,'网格单元编号为:',I5) 774 READ(7) ESTIF 775 IF(NLOAD(IELEM).GT.0)THEN 776 READ(8) ELOAD 777 END IF 778 DO 280 INODE=1,8 779 LNODI=LNODS(INODE,IELEM) 780 ICODF=IFPRE(LNODI) 781 NCODF(1)=ICODF/10 782 NCODF(2)=ICODF-NCODF(1)*10 783 DO 260 IDOFN=1,2 784 IEVAB=(INODE-1)*2+IDOFN 785 ICOLN=(LNODI-1)*2+IDOFN 786 DO 240 JNODE=1,8 787 LNODJ=LNODS(JNODE,IELEM) 788 DO 220 JDOFN=1,2 789 JEVAB=(JNODE-1)*2+JDOFN 790 JROW=(LNODJ-1)*2+JDOFN 791 IF(JROW.GT.ICOLN)GO TO 220 792 IF(JEVAB.GT.IEVAB)THEN 793 KEVAB=JEVAB*(JEVAB-1)/2+IEVAB 794 ELSE 795 KEVAB=IEVAB*(IEVAB-1)/2+JEVAB 796 END IF 797 LDIS=MAXA(ICOLN)+(ICOLN-JROW) 798 A(LDIS)=A(LDIS)+ESTIF(KEVAB) 799 220 CONTINUE 800 240 CONTINUE 801 IF(NLOAD(IELEM).GT.0)THEN 802 V(ICOLN)=V(ICOLN)+ELOAD(IEVAB) 803 END IF 804 IF(NCODF(IDOFN).EQ.0)GO TO 260 805 KEVAB=IEVAB*(IEVAB+1)/2 806 LDIS=MAXA(ICOLN) 807 A(LDIS)=A(LDIS)+DLARG*ESTIF(KEVAB) 808 260 CONTINUE 809 280 CONTINUE 810 300 CONTINUE 811 C******* 812 C ENTER GIVED DISPLACEMENTS 813 C******* 814 DO 400 I=1,NPOIN 815 ICODF=IFPRE(I) 816 NCODF(1)=ICODF/10 817 NCODF(2)=ICODF-NCODF(1)*10 818 DO 320 J=1,2 819 IF(NCODF(J).EQ.2)THEN 820 C******* 821 READ(5,*) X 822 C******* 823 ICOLN=(I-1)*2+J 824 LDIS=MAXA(ICOLN) 825 V(ICOLN)=A(LDIS)*X 826 END IF 827 320 CONTINUE 828 400 CONTINUE 829 RETURN 830 END 831 C***************************************************************************** 832 C 这是一个求解结构平衡方程组的子程序。 * 833 C***************************************************************************** 834 SUBROUTINE SOLVE(V,A,MAXA) 835 IMPLICIT REAL*8(A-H,O-Z) 836 DIMENSION V(1),A(1),MAXA(1) 837 COMMON/SOL/NPOIN,NELEM,NTYPE,NMATS 838 K=0 839 NN=NPOIN*2 840 NNM=NN+1 841 NWK=MAXA(NNM)-1 842 DO 640 N=1,NN 843 KN=MAXA(N) 844 KL=KN+1 845 KU=MAXA(N+1)-1 846 KH=KU-KL 847 IF(KH)610,590,550 848 550 K=N-KH 849 IC=0 850 KLT=KU 851 DO 580 J=1,KH 852 IC=IC+1 853 KLT=KLT-1 854 KI=MAXA(K) 855 ND=MAXA(K+1)-KI-1 856 IF(ND)580,580,560 857 560 KK=MIN(IC,ND) 858 C=0 859 DO 570 L=1,KK 860 M1=KI+L 861 M2=KLT+L 862 570 C=C+A(M1)*A(M2) 863 A(KLT)=A(KLT)-C 864 580 K=K+1 865 590 K=N 866 B=0.0 867 DO 600 KK=KL,KU 868 K=K-1 869 KI=MAXA(K) 870 C=A(KK)/A(KI) 871 B=B+C*A(KK) 872 600 A(KK)=C 873 A(KN)=A(KN)-B 874 610 IF(A(KN)) 620,620,640 875 620 WRITE(6,2000) N,A(KN) 876 STOP 877 640 CONTINUE 878 C******** 879 C REDUCE RIGHT--HAND--SIDE LOAD VECTOR 880 C******** 881 650 CONTINUE 882 DO 680 N=1,NN 883 KL=MAXA(N)+1 884 KU=MAXA(N+1)-1 885 KUL=KU-KL 886 IF(KUL)680,660,660 887 660 K=N 888 C=0.0 889 DO 670 KK=KL,KU 890 K=K-1 891 670 C=C+A(KK)*V(K) 892 V(N)=V(N)-C 893 680 CONTINUE 894 C******* 895 C BACK-SUBSTITUTE 896 C******** 897 DO 700 N=1,NN 898 K=MAXA(N) 899 V(N)=V(N)/A(K) 900 700 CONTINUE 901 IF(NN.EQ.1)GO TO 740 902 N=NN 903 DO 730 L=2,NN 904 KL=MAXA(N)+1 905 KU=MAXA(N+1)-1 906 KUL=KU-KL 907 IF(KUL)730,710,710 908 710 K=N 909 DO 720 KK=KL,KU 910 K=K-1 911 720 V(K)=V(K)-A(KK)*V(N) 912 730 N=N-1 913 740 CONTINUE 914 2000 FORMAT(//10X,'***** 停止运行!系数矩阵非正定!*****'//'NON 915 + POSITIVE PIVOT FOR EQUATION'I4//' PIVOT=',E20.12) 916 C******** 917 C OUTPUT DISPLACEMENT 918 C******** 919 WRITE(6,903) 920 903 FORMAT(//80('=')/36X,'移动输出'/80('=')//) 921 WRITE(6,905) 922 905 FORMAT(32X,'X方向',10X,'Y方向') 923 M2=0 924 DO 1000 I=1,NPOIN 925 M1=M2+1 926 M2=M1+1 927 1000 WRITE(6,915)I,(V(J),J=M1,M2) 928 915 FORMAT(2X,'高斯积分点编号为:',I5,1PE16.5,1PE16.5) 929 RETURN 930 END 931 C***************************************************************************** 932 C 这是一个计算单元应力的子程序。 * 933 C***************************************************************************** 934 SUBROUTINE STRE(COORD,PROPS,V,LNODS,MATNO) 935 IMPLICIT REAL*8(A-H,O-Z) 936 CHARACTER*80 LINECHAR 937 DIMENSION COORD(2,1),PROPS(3,1),V(1),LNODS(8,1),MATNO(1) 938 DIMENSION POSGP(3),ELCOD(2,8) 939 DIMENSION ELDIS(16),BE(3),S(3),SP(2) 940 COMMON/SOL/NPOIN,NELEM,NTYPE,NMATS 941 COMMON/BMDMP/BMATX(3,16),DMATX(3,3) 942 COMMON/GCOD/GPCOD(2,9) 943 POSGP(1)=-DSQRT(0.6D0) 944 POSGP(2)=0.0 945 POSGP(3)=DSQRT(0.6D0) 946 WRITE(6,616) 947 616 FORMAT(80('=')/26X,'以下是高斯积分点的应力输出'/80('=')/) 948 DO 90 IELEM=1,NELEM 949 WRITE(6,636) IELEM 950 636 FORMAT(2X,'网格单元编号为:',I5) 951 LPROP=MATNO(IELEM) 952 DO 20 I=1,8 953 LNODE=LNODS(I,IELEM) 954 LDOFN=LNODE*2-2 955 DO 10 J=1,2 956 IEVAB=I*2-2+J 957 MDOFN=LDOFN+J 958 ELDIS(IEVAB)=V(MDOFN) 959 ELCOD(J,I)=COORD(J,LNODE) 960 10 CONTINUE 961 20 CONTINUE 962 YOUNG=PROPS(1,LPROP) 963 POISS=PROPS(2,LPROP) 964 THICK=PROPS(3,LPROP) 965 CALL MODPS(YOUNG,POISS) 966 KGASP=0 967 DO 80 IGAUS=1,3 968 DO 80 JGAUS=1,3 969 KGASP=KGASP+1 970 EXISP=POSGP(IGAUS) 971 ETASP=POSGP(JGAUS) 972 CALL SFR2(EXISP,ETASP) 973 CALL JACOB2(IELEM,DJACB,KGASP,ELCOD) 974 CALL BMATPS 975 DO 40 I=1,3 976 BE(I)=0.0 977 DO 30 J=1,16 978 BE(I)=BE(I)+BMATX(I,J)*ELDIS(J) 979 30 CONTINUE 980 40 CONTINUE 981 DO 60 L=1,3 982 S(L)=0.0 983 DO 50 J=1,3 984 S(L)=S(L)+DMATX(L,J)*BE(J) 985 50 CONTINUE 986 60 CONTINUE 987 WRITE(6,755) KGASP 988 755 FORMAT(/2X,'高斯积分点的编号为:',I2) 989 LINECHAR='高斯积分点的坐标为:' 990 WRITE(6,775) LINECHAR,GPCOD(1,KGASP),GPCOD(2,KGASP) 991 775 FORMAT(2X,A26,' X=',F9.3,5X,'Y=',F9.3) 992 C ***** 993 XA=(S(1)+S(2))*0.5 994 XI=(S(1)-S(2))*0.5 995 XE=S(3) 996 X0=DSQRT(XI*XI+XE*XE) 997 SP(1)=XA+X0 998 SP(2)=XA-X0 999 C ****** 1000 WRITE(6,815) 1001 815 FORMAT(14X,'正应力σx',6X,'正应力σy',7X,'剪应力τ') 1002 WRITE(6,835) S 1003 835 FORMAT(10X,1PE13.4,2X,1PE13.4,2X,1PE13.4) 1004 WRITE(6,855) 1005 855 FORMAT(14X,'主应力σ1',6X,'主应力σ2') 1006 WRITE(6,875) SP 1007 875 FORMAT(10X,1PE13.4,2X,1PE13.4) 1008 80 CONTINUE 1009 90 CONTINUE 1010 RETURN 1011 END 1012