Télécharger separm.eso

Retour à la liste

Numérotation des lignes :

separm
  1. C SEPARM SOURCE MB234859 25/01/03 21:15:30 12105
  2. SUBROUTINE SEPARM(MRIGID,RI1,RI2,NOUNIL,BDBLX,NELIM,IF)
  3. C----------------------------------------------------------------------
  4. C Distinguer dans le MRIGID les rigidites elementaires pouvant etre
  5. C eliminees et celles devant etre conservees.
  6. C
  7. C Entrees :
  8. C ---------
  9. C mrigid : pointeur sur la rigidite totale
  10. C nelim : ne rien eliminer lorsque vaut 0
  11. C bdblx : est vrai si les mult de Lagrange doivent etre dedoubles
  12. C if : numero de la passe d'elimination si elimination recursive
  13. C
  14. C Sorties :
  15. C ---------
  16. C ri1 : pointeur sur les rigidites elementaires a eliminer, i.e.
  17. C pouvant etre traitee comme des dependances
  18. C ri2 : pointeur sur les rigidites elementaires a conserver
  19. C
  20. C juillet 2003 passage aux simples multiplicateurs de Lagrange, mais
  21. C separm dualise ceux qu'il garde
  22. C----------------------------------------------------------------------
  23. IMPLICIT INTEGER(I-N)
  24. IMPLICIT REAL*8 (A-H,O-Z)
  25. C
  26. -INC PPARAM
  27. -INC CCOPTIO
  28. -INC CCREEL
  29. *-INC CCHAMP
  30. -INC SMRIGID
  31. -INC SMCOORD
  32. -INC SMELEME
  33. C
  34. INTEGER OOOVAL
  35. LOGICAL bdblx
  36. C
  37. segment trav1
  38. character*(lochpo) compp(lcomp1)
  39. endsegment
  40. segment trav2
  41. integer ielim(nbnoc,nbincp),iautr(nbnoc,nbincp)
  42. integer icomb(nbnoc,nbincp),ideja(nbnoc,nbincp)
  43. endsegment
  44. C Remplir posinc pour accelerer les tests sur les composantes
  45. segment trav3
  46. integer posinc(nligrp)
  47. endsegment
  48. segment trav4
  49. integer itrv1(nbprl)
  50. integer itrv2(nbprl)
  51. real*8 dtrv1(nbprl)
  52. real*8 dtrv2(nbprl)
  53. endsegment
  54. segment trav5
  55. integer idata(2,nligrp)
  56. endsegment
  57. segment icpr(nbpts)
  58. segment itemp(ntemp)
  59. character*(lochpo) co1
  60. character*(8) typmat
  61. integer ri1p,ri1s,ri1f,ri2f
  62. C
  63. ** write(ioimp,*) ' entree de separm '
  64. ** call ooodmp(0)
  65. ** nbav=oooval(2,1)
  66. * write (ioimp,*) ' dans separm nouinl ',nounil
  67. CC write (ioimp,*) ' matrice mrigid'
  68. CC call prrigi(mrigid,0)
  69. CC segact,mrigid
  70. nbdep=0
  71. nbpiv=0
  72. nbpvt=0
  73. iunil=0
  74. typmat='TEMPORAI'
  75. C -----------------------------------------------------------------
  76. C Distinguer ce qui peut etre elimine (ri4) et le reste (ri3)
  77. C -----------------------------------------------------------------
  78. if (nelim.ne.0) then
  79. nbno=nbpts
  80. segini icpr
  81. endif
  82. nbnoc=0
  83. segact mrigid
  84. nbrig=irigel(/2)
  85. ntemp=nbrig
  86. segini,itemp
  87. nrige3=0
  88. do 760 irig=1,nbrig
  89. if (irigel(6,irig).ne.0) iunil=1
  90. meleme=irigel(1,irig)
  91. segact meleme
  92. if ((itypel.ne.22.and.itypel.ne.28).or.
  93. & (irigel(7,irig).ne.0).or.(nelim.eq.0)) then
  94. itemp(irig)=1
  95. nrige3=nrige3+1
  96. endif
  97. C
  98. if (nelim.eq.0) goto 760
  99. C
  100. ** write(ioimp,*) '1 itypel dans separm',itypel
  101. do il=1,num(/2)
  102. do ip=1,num(/1)
  103. ipt=num(ip,il)
  104. if (icpr(ipt).eq.0) then
  105. nbnoc=nbnoc+1
  106. icpr(ipt)=nbnoc
  107. endif
  108. enddo
  109. enddo
  110. 760 continue
  111. C
  112. nrigel=nrige3
  113. segini,ri3
  114. ri3.iforig=iforig
  115. ri3.mtymat=mtymat
  116. nrige4=nbrig-nrige3
  117. nrigel=nrige4
  118. segini,ri4
  119. ri4.iforig=iforig
  120. ri4.mtymat=typmat
  121. i3=0
  122. i4=0
  123. do 555 jj=1,nbrig
  124. if (itemp(jj).eq.1) then
  125. i3=i3+1
  126. ii=i3
  127. ri5=ri3
  128. else
  129. i4=i4+1
  130. ii=i4
  131. ri5=ri4
  132. endif
  133. ri5.coerig(ii)=coerig(jj)
  134. do kk=1,8
  135. ri5.irigel(kk,ii)=irigel(kk,jj)
  136. enddo
  137. 555 continue
  138. segsup,itemp
  139. if (nelim.eq.0) then
  140. ri1=ri4
  141. ri2=ri3
  142. GOTO 2002
  143. endif
  144. C -----------------------------------------------------------------
  145. C Recuperer les noms de composantes (segment trav1)
  146. C -----------------------------------------------------------------
  147. lcomp1 = 50
  148. segini trav1
  149. nbincp=0
  150. do 10 irig=1,nrige4
  151. descr=ri4.irigel(3,irig)
  152. segact descr
  153. do 40 nligrp=2,lisinc(/2)
  154. C print *,'lisinc(',nligrp,'/',lisinc(/2),')=',lisinc(nligrp)
  155. do 50 inc=1,nbincp
  156. if (compp(inc).eq.lisinc(nligrp)) goto 40
  157. 50 continue
  158. nbincp=nbincp+1
  159. if (nbincp.GT.lcomp1) then
  160. lcomp1 = lcomp1 + 50
  161. segadj trav1
  162. endif
  163. compp(nbincp)=lisinc(nligrp)
  164. 40 continue
  165. 10 continue
  166. C -----------------------------------------------------------------
  167. C Quelles inconnues peuvent etre eliminees?
  168. C -----------------------------------------------------------------
  169. C Interdit d'eliminer les inconnues apparaissant dans des conditions
  170. C unilaterales lorsque nounil = 0.
  171. segini,trav2
  172. do 60 irig=1,nrige4
  173. meleme=ri4.irigel(1,irig)
  174. if(itypel.ne.28) then
  175. if (ri4.irigel(6,irig).eq.0.or.nounil.eq.1) goto 60
  176. endif
  177. C
  178. C Super-elements : si trop gros ce n'est pas avantageux
  179. C d'eliminer. Dans ce cas, idnetifier ses noeuds et ddl pour ne
  180. C pas les eliminer.
  181. if (itypel.ne.22.and.
  182. > (itypel.ne.28.or.num(/1).lt.255.or.if.lt.3)) goto 60
  183. C
  184. descr=ri4.irigel(3,irig)
  185. nld=2
  186. if(itypel.eq.28) nld=1
  187. C
  188. do 70 nligrp=nld,lisinc(/2)
  189. do 80 inc=1,nbincp
  190. C print *,'lisinc(',nligrp,'/',lisinc(/2),')=',lisinc(nligrp)
  191. C & ,' compp(',inc,')=',compp(inc)
  192. if (compp(inc).eq.lisinc(nligrp)) goto 90
  193. 80 continue
  194. *** write(ioimp,*) '- ',lisinc(nligrp),' non trouve dans trav1'
  195. goto 70
  196. 90 continue
  197. C
  198. C La composante lisinc(nligrp) ne doit pas etre eliminee pour
  199. C les noeuds num(ip,j)
  200. ip=noelep(nligrp)
  201. do 100 j=1,num(/2)
  202. C IF(num(ip,j).GT.ielim(/1).OR.inc.GT.ielim(/2).OR.
  203. C * num(ip,j).GT.iautr(/1).OR.inc.GT.iautr(/2))THEN
  204. C print *,'BUG DANS SEPARM : ',
  205. C & num(ip,j),'>',ielim(/1),iautr(/1),
  206. C & inc,'>',ielim(/2),iautr(/2)
  207. C ENDIF
  208. ielim(icpr(num(ip,j)),inc)=1
  209. iautr(icpr(num(ip,j)),inc)=1
  210. 100 continue
  211. 70 continue
  212. 60 continue
  213. C -----------------------------------------------------------------
  214. C Nombre de conditions associees a chaque ddl de chaque noeud
  215. C -----------------------------------------------------------------
  216. do 700 irig=1,nrige4
  217. if (ri4.irigel(6,irig).ne.0.and.nounil.eq.0) goto 700
  218. meleme=ri4.irigel(1,irig)
  219. if (itypel.ne.22) goto 700
  220. descr=ri4.irigel(3,irig)
  221. C
  222. nligrp=lisinc(/2)
  223. segini trav3
  224. do 730 inc=2,nligrp
  225. do 720 incp=1,nbincp
  226. if (lisinc(inc).eq.compp(incp)) then
  227. posinc(inc)=incp
  228. goto 730
  229. endif
  230. 720 continue
  231. call erreur(5)
  232. 730 continue
  233. C
  234. do 750 ince=2,lisinc(/2)
  235. incp=posinc(ince)
  236. do 740 j=1,num(/2)
  237. ip=num(noelep(ince),j)
  238. icomb(icpr(ip),incp)=icomb(icpr(ip),incp)+1
  239. 740 continue
  240. 750 continue
  241. segsup trav3
  242. 700 continue
  243. ipass=1
  244. C
  245. C -----------------------------------------------------------------
  246. 2000 CONTINUE
  247. nrigel=0
  248. segini,ri1
  249. ri1.iforig=iforig
  250. ri1.mtymat=typmat
  251. segini,ri2=ri4
  252. ri2.mtymat=mtymat
  253. C
  254. C Trier pour attaquer en premier les relations portant sur le moins
  255. C d'inconnues
  256. nbprl=ri4.irigel(/2)
  257. segini trav4
  258. do 765 irig=1,nbprl
  259. descr=ri4.irigel(3,irig)
  260. dtrv1(irig)= lisinc(/2)+(irig/(nbprl+1.))
  261. if(irigel(6,irig).ne.0) dtrv1(irig)=dtrv1(irig)+1000000
  262. if(irigel(6,irig).eq.2) dtrv1(irig)=dtrv1(irig)+1000000
  263. ** if(irigel(6,irig).eq.0) dtrv1(irig)=dtrv1(irig)+1000000
  264. ** itrv1(irig)=nbprl-irig+1
  265. itrv1(irig)= irig
  266. 765 continue
  267. call triflo(dtrv1,dtrv2,itrv1,itrv2,nbprl)
  268. C
  269. do 200 iri=1,nbprl
  270. irig=itrv1(iri)
  271. ** irig=iri
  272. ** if (ipass.eq.1) irig=itrv1(iri)
  273. if (ri4.irigel(6,irig).ne.0.and.nounil.eq.0) goto 190
  274. meleme=ri4.irigel(1,irig)
  275. if (itypel.ne.22) goto 190
  276. Xmatri=ri4.irigel(4,irig)
  277. segact Xmatri
  278. if (abs(re(1,1,1)).gt.1d-30) goto 190
  279. descr=ri4.irigel(3,irig)
  280. C
  281. nligrp=lisinc(/2)
  282. segini,trav3,trav5
  283. do 230 inc=2,nligrp
  284. do 220 incp=1,nbincp
  285. if (lisinc(inc).eq.compp(incp)) then
  286. posinc(inc)=incp
  287. goto 230
  288. endif
  289. 220 continue
  290. call erreur(5)
  291. 230 continue
  292. C
  293. segini,ipt8=meleme
  294. nbdepe=0
  295. do 210 j=1,num(/2)
  296. C
  297. C Cette matrice elementaire contient elle des inconnues
  298. if (noelep(/1).le.1) then
  299. ipt8.num(1,j)=0
  300. goto 210
  301. endif
  302. C
  303. C La matrice est elle augmentee
  304. if (abs(re(1,1,j)).gt.1d-5) then
  305. ipt8.num(1,j)=0
  306. goto 210
  307. endif
  308. C
  309. C Cette matrice elementaire contient-elle une inco. eliminee
  310. remax=abs(re(1,1,j))
  311. do 240 inc=2,nligrp
  312. incpp=posinc(inc)
  313. ipp=ipt8.num(noelep(inc),j)
  314. if (ielim(icpr(ipp),incpp).eq.1) then
  315. ipt8.num(1,j)=0
  316. goto 210
  317. endif
  318. remax=max(remax,abs(re(1,inc,j)))
  319. 240 continue
  320. C
  321. C Choix du pivot
  322. incf=0
  323. remaz=remax*0.9
  324. do 250 inc=2,nligrp
  325. incpp=posinc(inc)
  326. ipp=ipt8.num(noelep(inc),j)
  327. if (iautr(icpr(ipp),incpp).eq.1) goto 250
  328. if (abs(re(1,inc,j)).lt.remaz) goto 250
  329. * if (icomb(icpr(ipp),incpp).eq.1) then
  330. incf=inc
  331. goto 260
  332. * endif
  333. 250 continue
  334. 260 continue
  335. ince=incf
  336. if (incf.eq.0) ince=2
  337. C
  338. C Traitement de l'inconnue incp du noeud ip
  339. incp=posinc(ince)
  340. ip=ipt8.num(noelep(ince),j)
  341. C
  342. C Le pivot est il correct
  343. remax=remax*1d-2
  344. if (abs(re(1,ince,j)).le.remax) then
  345. ipt8.num(1,j)=0
  346. nbpiv=nbpiv+1
  347. goto 210
  348. endif
  349. C
  350. C Cette inconnue apparait-elle dans d'autres CL
  351. if (ipass.eq.1.and.icomb(icpr(ip),incp).ne.1) then
  352. ipt8.num(1,j)=0
  353. goto 210
  354. endif
  355. C
  356. C Cette inconnue apparait-elle dans une dependance
  357. if (iautr(icpr(ip),incp).eq.1) then
  358. ipt8.num(1,j)=0
  359. goto 210
  360. endif
  361. C
  362. C Cette inconnue apparait-elle deux fois dans la relation
  363. ideux=0
  364. do inc=2,nligrp
  365. if (ideja(icpr(ipt8.num(noelep(inc),j)),posinc(inc)).eq.1) then
  366. ideux=inc
  367. else
  368. ideja(icpr(ipt8.num(noelep(inc),j)),posinc(inc))=1
  369. endif
  370. enddo
  371. do inc=2,nligrp
  372. ideja(icpr(ipt8.num(noelep(inc),j)),posinc(inc))=0
  373. enddo
  374. if (ideux.ne.0) then
  375. moterr(1:4)=lisinc(ideux)
  376. interr(1)=ipt8.num(noelep(ideux),j)
  377. call erreur(-361)
  378. ipt8.num(1,j)=0
  379. goto 210
  380. endif
  381. C
  382. C Nouvelle dependance
  383. nbdepe=nbdepe+1
  384. nbdep=nbdep+1
  385. C write (ioimp,*) 'Elimination noeud,inco,posi',ip,lisinc(ince),ince
  386. C Reperer l'inconnue eliminee et le noeud
  387. ipt8.num(1,j)=ince
  388. idata(1,ince)=idata(1,ince)+1
  389. ielim(icpr(ip),incp)=1
  390. do 280 inc=2,nligrp
  391. iautr(icpr(ipt8.num(noelep(inc),j)),posinc(inc))=1
  392. 280 continue
  393. C
  394. 210 continue
  395. segsup trav3
  396. C
  397. C Creation de ri1 et ri2 pour scinder la sous-matrice irig
  398. C ---------------------------------------------------------------
  399. C Dimensions communes a RI1 et RI2
  400. nbnn=num(/1)
  401. nbsous=0
  402. nbref=0
  403. nligrd=re(/1)
  404. nligrp=re(/2)
  405. C
  406. C Creation de RI2 : rigidites elementaires a conserver
  407. nbelem=num(/2)-nbdepe
  408. if (nbelem.gt.0) then
  409. segini,ipt2
  410. ipt2.itypel=itypel
  411. nelrig=nbelem
  412. segini,xmatr2
  413. xmatr2.symre=symre
  414. ri2.irigel(1,irig)=ipt2
  415. ri2.irigel(3,irig)=descr
  416. ri2.irigel(4,irig)=xmatr2
  417. do iii=5,8
  418. ri2.irigel(iii,irig)=ri4.irigel(iii,irig)
  419. ENDDO
  420. ri2.coerig(irig)=ri4.coerig(irig)
  421. else
  422. ri2.irigel(1,irig)=0
  423. xmatr2=0
  424. endif
  425. C
  426. C Creation de RI1 : rigidites elementaires a eliminer.
  427. C L'inconnue a eliminer doit etre en 2eme position (apres LX)
  428. C Si l'inconnue a eliminer n'est pas celle apparaissant en
  429. C deuxieme position il faut pivoter la rigidite elementaire
  430. C et le descripteur associe
  431. ri1p=ri1
  432. nrigel=0
  433. do kkk=1,nligrp
  434. if (idata(1,kkk).gt.0) nrigel=nrigel+1
  435. enddo
  436. nbpvt=nbpvt+nrigel
  437. segini,ri1
  438. ri1.iforig=iforig
  439. ri1.mtymat=typmat
  440. icpt=0
  441. do 25 jjj=1,nligrp
  442. nelrig=idata(1,jjj)
  443. C Nombre d'elements elimines en choisissant la jjjeme inconnue
  444. if (nelrig.eq.0) goto 25
  445. nbelem=nelrig
  446. segini,ipt1
  447. ipt1.itypel=itypel
  448. segini,xmatr1
  449. xmatr1.symre=symre
  450. des1=descr
  451. if (jjj.ne.2) then
  452. segini,des1=descr
  453. co1=des1.lisinc(2)
  454. des1.lisinc(2)=des1.lisinc(jjj)
  455. des1.lisinc(jjj)=co1
  456. co1=des1.lisdua(2)
  457. des1.lisdua(2)=des1.lisdua(jjj)
  458. des1.lisdua(jjj)=co1
  459. noe=des1.noelep(2)
  460. des1.noelep(2)=des1.noelep(jjj)
  461. des1.noelep(jjj)=noe
  462. noe=des1.noeled(2)
  463. des1.noeled(2)=des1.noeled(jjj)
  464. des1.noeled(jjj)=noe
  465. endif
  466. C
  467. icpt=icpt+1
  468. ri1.irigel(1,icpt)=ipt1
  469. ri1.irigel(3,icpt)=des1
  470. ri1.irigel(4,icpt)=xmatr1
  471. do iii=5,7
  472. ri1.irigel(iii,icpt)=ri4.irigel(iii,irig)
  473. enddo
  474. ri1.irigel(8,icpt)=1
  475. ri1.coerig(icpt)=ri4.coerig(irig)
  476. C
  477. C Compteur des elements et identifiant de la rigidite elem
  478. idata(1,jjj)=1
  479. idata(2,jjj)=icpt
  480. 25 continue
  481. C
  482. C Remplir ri1 et ri2 en creant les xmatri/descr/maillages
  483. C ---------------------------------------------------------------
  484. idec=0
  485. do 300 j=1,num(/2)
  486. if (ipt8.num(1,j).eq.0) then
  487. idec=idec+1
  488. do 310 i=1,num(/1)
  489. ipt2.num(i,idec)=num(i,j)
  490. 310 continue
  491. do io=1,nligrp
  492. do iu=1,nligrd
  493. xmatr2.re(iu,io,idec)=re(iu,io,j)
  494. enddo
  495. enddo
  496. else
  497. ince=ipt8.num(1,j)
  498. iriel=idata(2,ince)
  499. ipt1=ri1.irigel(1,iriel)
  500. xmatr1=ri1.irigel(4,iriel)
  501. ielt=idata(1,ince)
  502. idata(1,ince)=idata(1,ince)+1
  503. do 320 i=1,num(/1)
  504. ipt1.num(i,ielt)=num(i,j)
  505. 320 continue
  506. do io=1,nligrp
  507. do iu=1,nligrd
  508. xmatr1.re(iu,io,ielt)=re(iu,io,j)
  509. enddo
  510. enddo
  511. C
  512. C Pivoter les lignes/colonnes ince et 2
  513. if (ince.ne.2) then
  514. do 1130 il=1,nligrd
  515. ret=xmatr1.re(il,2,ielt)
  516. xmatr1.re(il,2,ielt)=xmatr1.re(il,ince,ielt)
  517. xmatr1.re(il,ince,ielt)=ret
  518. 1130 continue
  519. do 1160 il=1,nligrp
  520. ret=xmatr1.re(2,il,ielt)
  521. xmatr1.re(2,il,ielt)=xmatr1.re(ince,il,ielt)
  522. xmatr1.re(ince,il,ielt)=ret
  523. 1160 continue
  524. endif
  525. C
  526. endif
  527. 300 continue
  528. C ---------------------------------------------------------------
  529. C
  530. call fusrig(ri1p,ri1,ri1f)
  531. ri1=ri1f
  532. if (xmatr2.ne.0) segdes,xmatr2
  533. segsup,trav5
  534. goto 200
  535. C
  536. 190 continue
  537. C
  538. C Sous-matrice irig a conserver integralement
  539. ri2.irigel(1,irig)=ri4.irigel(1,irig)
  540. ri2.irigel(3,irig)=ri4.irigel(3,irig)
  541. ri2.irigel(4,irig)=ri4.irigel(4,irig)
  542. do iii=5,7
  543. ri2.irigel(iii,irig)=ri4.irigel(iii,irig)
  544. enddo
  545. ri2.irigel(8,irig)=0
  546. ri2.coerig(irig)=ri4.coerig(irig)
  547. C
  548. 200 continue
  549. C -----------------------------------------------------------------
  550. segsup trav4
  551. C
  552. C Compression de ri2
  553. idec=0
  554. do 600 irig=1,nbprl
  555. meleme=ri2.irigel(1,irig)
  556. if (meleme.eq.0) then
  557. idec=idec+1
  558. else
  559. do 610 ir=1,8
  560. ri2.irigel(ir,irig-idec)=ri2.irigel(ir,irig)
  561. 610 continue
  562. ri2.coerig(irig-idec)=ri2.coerig(irig)
  563. endif
  564. 600 continue
  565. nrigel=nbprl-idec
  566. C write (ioimp,*) ' dimension de ri2 ',nrigel
  567. segadj,ri2
  568. C
  569. C On va voir si on ne peut pas faire pivoter ri2
  570. if (ipass.eq.2) goto 2001
  571. ri1s=ri1
  572. ri4=ri2
  573. nbpiv=0
  574. ipass=ipass+1
  575. goto 2000
  576. C
  577. 2001 CONTINUE
  578. C -----------------------------------------------------------------
  579. C
  580. C RI1 : rigidites elementaires a eliminer
  581. call fusrig(ri1s,ri1,ri1f)
  582. ri1=ri1f
  583. C RI2 : rigidites elementaires a conserver
  584. call fusrig(ri3,ri2,ri2f)
  585. ri2=ri2f
  586. C
  587. segsup trav1,trav2,icpr
  588. C
  589. if (iimpi.ne.0) then
  590. write(ioimp,*)'nombre de relations eliminees',nbdep
  591. write(ioimp,*)'nombre de relations gardees a cause du pivot',nbpiv
  592. write(ioimp,*)'nombre de relations gardees car non independantes',
  593. write(ioimp,*)'nombre de paquets pivotes',nbpvt
  594. endif
  595. C
  596. 2002 CONTINUE
  597. C
  598. C -----------------------------------------------------------------
  599. C Dualisation des multiplicateurs de Lagrange
  600. C -----------------------------------------------------------------
  601. C si on a des conditions unilaterales, on ne dualise pas, ce sera fait
  602. C dans le resou de unilater
  603. if ((iunil.eq.0.or.nounil.eq.1).and.bdblx) call dbblx(ri2)
  604. C
  605. CC write (ioimp,*) ' matrice ri1 '
  606. CC call prrigi(ri1,0)
  607. CC write (ioimp,*) ' matrice ri2 '
  608. CC call prrigi(ri2,0)
  609. CC segact,ri1,ri2
  610. CC write(ioimp,*) ' sortie de separm '
  611. ** call ooodmp(0)
  612. ** nbap=oooval(2,1)
  613. ** write(ioimp,*) 'nb segmts dans separm avant apres ',nbav,nbap
  614. END
  615.  
  616.  
  617.  

© Cast3M 2003 - Tous droits réservés.
Mentions légales