Télécharger separm.eso

Retour à la liste

Numérotation des lignes :

separm
  1. C SEPARM SOURCE MB234859 26/07/06 21:15:13 12591
  2. SUBROUTINE SEPARM(MRIGID,RI1,RI2,NOUNIL,BDBLX,NELIM,IPE)
  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 ipe : 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. typmat='TEMPORAI'
  74. C -----------------------------------------------------------------
  75. C Distinguer ce qui peut etre elimine (ri4) et le reste (ri3)
  76. C -----------------------------------------------------------------
  77. if (nelim.ne.0) then
  78. nbno=nbpts
  79. segini icpr
  80. endif
  81. nbnoc=0
  82. segact mrigid
  83. nbrig=irigel(/2)
  84. ntemp=nbrig
  85. segini,itemp
  86. nrige3=0
  87. do 760 irig=1,nbrig
  88. meleme=irigel(1,irig)
  89. segact meleme
  90. if ((itypel.ne.22.and.itypel.ne.28).or.
  91. & (irigel(7,irig).ne.0).or.(nelim.eq.0)) then
  92. itemp(irig)=1
  93. nrige3=nrige3+1
  94. endif
  95. C
  96. if (nelim.eq.0) goto 760
  97. C
  98. ** write(ioimp,*) '1 itypel dans separm',itypel
  99. do il=1,num(/2)
  100. do ip=1,num(/1)
  101. ipt=num(ip,il)
  102. if (icpr(ipt).eq.0) then
  103. nbnoc=nbnoc+1
  104. icpr(ipt)=nbnoc
  105. endif
  106. enddo
  107. enddo
  108. 760 continue
  109. C
  110. nrigel=nrige3
  111. segini,ri3
  112. ri3.iforig=iforig
  113. ri3.mtymat=mtymat
  114. nrige4=nbrig-nrige3
  115. nrigel=nrige4
  116. segini,ri4
  117. ri4.iforig=iforig
  118. ri4.mtymat=typmat
  119. i3=0
  120. i4=0
  121. do 555 jj=1,nbrig
  122. if (itemp(jj).eq.1) then
  123. i3=i3+1
  124. ii=i3
  125. ri5=ri3
  126. else
  127. i4=i4+1
  128. ii=i4
  129. ri5=ri4
  130. endif
  131. ri5.coerig(ii)=coerig(jj)
  132. do kk=1,8
  133. ri5.irigel(kk,ii)=irigel(kk,jj)
  134. enddo
  135. 555 continue
  136. segsup,itemp
  137. if (nelim.eq.0) then
  138. ri1=ri4
  139. ri2=ri3
  140. GOTO 2002
  141. endif
  142. C -----------------------------------------------------------------
  143. C Recuperer les noms de composantes (segment trav1)
  144. C -----------------------------------------------------------------
  145. lcomp1 = 50
  146. segini trav1
  147. nbincp=0
  148. do 10 irig=1,nrige4
  149. descr=ri4.irigel(3,irig)
  150. segact descr
  151. do 40 nligrp=2,lisinc(/2)
  152. C print *,'lisinc(',nligrp,'/',lisinc(/2),')=',lisinc(nligrp)
  153. do 50 inc=1,nbincp
  154. if (compp(inc).eq.lisinc(nligrp)) goto 40
  155. 50 continue
  156. nbincp=nbincp+1
  157. if (nbincp.GT.lcomp1) then
  158. lcomp1 = lcomp1 + 50
  159. segadj trav1
  160. endif
  161. compp(nbincp)=lisinc(nligrp)
  162. 40 continue
  163. 10 continue
  164. C -----------------------------------------------------------------
  165. C Quelles inconnues peuvent etre eliminees?
  166. C -----------------------------------------------------------------
  167. C Interdit d'eliminer les inconnues apparaissant dans des conditions
  168. C unilaterales lorsque nounil = 0.
  169. segini,trav2
  170. do 60 irig=1,nrige4
  171. MELEME=RI4.IRIGEL(1,IRIG)
  172. C
  173. IF (ITYPEL.NE.28) THEN
  174. IF (ITYPEL.NE.22) GOTO 60
  175. IF (RI4.IRIGEL(6,IRIG).EQ.0 .OR. NOUNIL.EQ.1) GOTO 60
  176. nld=2
  177. ELSE
  178. C Super-elements : si trop gros ce n'est pas avantageux d'eliminer
  179. C -> identifier ses noeuds et ddls pour ne pas les eliminer.
  180. IF (NUM(/1).LT.255) GOTO 60
  181. IF (IPE.LT.3) GOTO 60
  182. nld=1
  183. ENDIF
  184. C
  185. descr=ri4.irigel(3,irig)
  186. do 70 nligrp=nld,lisinc(/2)
  187. do 80 inc=1,nbincp
  188. C print *,'lisinc(',nligrp,'/',lisinc(/2),')=',lisinc(nligrp)
  189. C & ,' compp(',inc,')=',compp(inc)
  190. if (compp(inc).eq.lisinc(nligrp)) goto 90
  191. 80 continue
  192. *** write(ioimp,*) '- ',lisinc(nligrp),' non trouve dans trav1'
  193. goto 70
  194. 90 continue
  195. C
  196. C La composante lisinc(nligrp) ne doit pas etre eliminee pour
  197. C les noeuds num(ip,j)
  198. ip=noelep(nligrp)
  199. do 100 j=1,num(/2)
  200. C IF(num(ip,j).GT.ielim(/1).OR.inc.GT.ielim(/2).OR.
  201. C * num(ip,j).GT.iautr(/1).OR.inc.GT.iautr(/2))THEN
  202. C print *,'BUG DANS SEPARM : ',
  203. C & num(ip,j),'>',ielim(/1),iautr(/1),
  204. C & inc,'>',ielim(/2),iautr(/2)
  205. C ENDIF
  206. ielim(icpr(num(ip,j)),inc)=1
  207. iautr(icpr(num(ip,j)),inc)=1
  208. 100 continue
  209. 70 continue
  210. 60 continue
  211. C -----------------------------------------------------------------
  212. C Nombre de conditions associees a chaque ddl de chaque noeud
  213. C -----------------------------------------------------------------
  214. do 700 irig=1,nrige4
  215. if (ri4.irigel(6,irig).ne.0.and.nounil.eq.0) goto 700
  216. meleme=ri4.irigel(1,irig)
  217. if (itypel.ne.22) goto 700
  218. descr=ri4.irigel(3,irig)
  219. C
  220. nligrp=lisinc(/2)
  221. segini trav3
  222. do 730 inc=2,nligrp
  223. do 720 incp=1,nbincp
  224. if (lisinc(inc).eq.compp(incp)) then
  225. posinc(inc)=incp
  226. goto 730
  227. endif
  228. 720 continue
  229. call erreur(5)
  230. 730 continue
  231. C
  232. do 750 ince=2,lisinc(/2)
  233. incp=posinc(ince)
  234. do 740 j=1,num(/2)
  235. ip=num(noelep(ince),j)
  236. icomb(icpr(ip),incp)=icomb(icpr(ip),incp)+1
  237. 740 continue
  238. 750 continue
  239. segsup trav3
  240. 700 continue
  241. ipass=1
  242. C
  243. C -----------------------------------------------------------------
  244. 2000 CONTINUE
  245. nrigel=0
  246. segini,ri1
  247. ri1.iforig=iforig
  248. ri1.mtymat=typmat
  249. segini,ri2=ri4
  250. ri2.mtymat=mtymat
  251. C
  252. C Trier pour attaquer en premier les relations portant sur le moins
  253. C d'inconnues
  254. nbprl=ri4.irigel(/2)
  255. segini trav4
  256. do 765 irig=1,nbprl
  257. descr=ri4.irigel(3,irig)
  258. dtrv1(irig)= lisinc(/2)+(irig/(nbprl+1.))
  259. if(ri4.irigel(6,irig).ne.0) dtrv1(irig)=dtrv1(irig)+1000000
  260. if(ri4.irigel(6,irig).eq.2) dtrv1(irig)=dtrv1(irig)+1000000
  261. ** if(ri4.irigel(6,irig).eq.0) dtrv1(irig)=dtrv1(irig)+1000000
  262. ** itrv1(irig)=nbprl-irig+1
  263. itrv1(irig)= irig
  264. 765 continue
  265. call triflo(dtrv1,dtrv2,itrv1,itrv2,nbprl)
  266. C
  267. do 200 iri=1,nbprl
  268. irig=itrv1(iri)
  269. ** irig=iri
  270. ** if (ipass.eq.1) irig=itrv1(iri)
  271. if (ri4.irigel(6,irig).ne.0.and.nounil.eq.0) goto 190
  272. meleme=ri4.irigel(1,irig)
  273. if (itypel.ne.22) goto 190
  274. Xmatri=ri4.irigel(4,irig)
  275. segact Xmatri
  276. if (abs(re(1,1,1)).gt.1d-30) goto 190
  277. descr=ri4.irigel(3,irig)
  278. C
  279. nligrp=lisinc(/2)
  280. segini,trav3,trav5
  281. do 230 inc=2,nligrp
  282. do 220 incp=1,nbincp
  283. if (lisinc(inc).eq.compp(incp)) then
  284. posinc(inc)=incp
  285. goto 230
  286. endif
  287. 220 continue
  288. call erreur(5)
  289. 230 continue
  290. C
  291. segini,ipt8=meleme
  292. nbdepe=0
  293. do 210 j=1,num(/2)
  294. C
  295. C Cette matrice elementaire contient elle des inconnues
  296. if (noelep(/1).le.1) then
  297. ipt8.num(1,j)=0
  298. goto 210
  299. endif
  300. C
  301. C La matrice est elle augmentee
  302. if (abs(re(1,1,j)).gt.1d-5) then
  303. ipt8.num(1,j)=0
  304. goto 210
  305. endif
  306. C
  307. C Cette matrice elementaire contient-elle une inco. eliminee
  308. remax=abs(re(1,1,j))
  309. do 240 inc=2,nligrp
  310. incpp=posinc(inc)
  311. ipp=ipt8.num(noelep(inc),j)
  312. if (ielim(icpr(ipp),incpp).eq.1) then
  313. ipt8.num(1,j)=0
  314. goto 210
  315. endif
  316. remax=max(remax,abs(re(1,inc,j)))
  317. 240 continue
  318. C
  319. C Choix du pivot
  320. incf=0
  321. remaz=remax*0.9
  322. do 250 inc=2,nligrp
  323. incpp=posinc(inc)
  324. ipp=ipt8.num(noelep(inc),j)
  325. if (iautr(icpr(ipp),incpp).eq.1) goto 250
  326. if (abs(re(1,inc,j)).lt.remaz) goto 250
  327. * if (icomb(icpr(ipp),incpp).eq.1) then
  328. incf=inc
  329. goto 260
  330. * endif
  331. 250 continue
  332. 260 continue
  333. ince=incf
  334. if (incf.eq.0) ince=2
  335. C
  336. C Traitement de l'inconnue incp du noeud ip
  337. incp=posinc(ince)
  338. ip=ipt8.num(noelep(ince),j)
  339. C
  340. C Le pivot est il correct
  341. remax=remax*1d-2
  342. if (abs(re(1,ince,j)).le.remax) then
  343. ipt8.num(1,j)=0
  344. nbpiv=nbpiv+1
  345. goto 210
  346. endif
  347. C
  348. C Cette inconnue apparait-elle dans d'autres CL
  349. if (ipass.eq.1.and.icomb(icpr(ip),incp).ne.1) then
  350. ipt8.num(1,j)=0
  351. goto 210
  352. endif
  353. C
  354. C Cette inconnue apparait-elle dans une dependance
  355. if (iautr(icpr(ip),incp).eq.1) then
  356. ipt8.num(1,j)=0
  357. goto 210
  358. endif
  359. C
  360. C Cette inconnue apparait-elle deux fois dans la relation
  361. ideux=0
  362. do inc=2,nligrp
  363. if (ideja(icpr(ipt8.num(noelep(inc),j)),posinc(inc)).eq.1) then
  364. ideux=inc
  365. else
  366. ideja(icpr(ipt8.num(noelep(inc),j)),posinc(inc))=1
  367. endif
  368. enddo
  369. do inc=2,nligrp
  370. ideja(icpr(ipt8.num(noelep(inc),j)),posinc(inc))=0
  371. enddo
  372. if (ideux.ne.0) then
  373. moterr(1:4)=lisinc(ideux)
  374. interr(1)=ipt8.num(noelep(ideux),j)
  375. call erreur(-361)
  376. ipt8.num(1,j)=0
  377. goto 210
  378. endif
  379. C
  380. C Nouvelle dependance
  381. nbdepe=nbdepe+1
  382. nbdep=nbdep+1
  383. C write (ioimp,*) 'Elimination noeud,inco,posi',ip,lisinc(ince),ince
  384. C Reperer l'inconnue eliminee et le noeud
  385. ipt8.num(1,j)=ince
  386. idata(1,ince)=idata(1,ince)+1
  387. ielim(icpr(ip),incp)=1
  388. do 280 inc=2,nligrp
  389. iautr(icpr(ipt8.num(noelep(inc),j)),posinc(inc))=1
  390. 280 continue
  391. C
  392. 210 continue
  393. segsup trav3
  394. C
  395. C Creation de ri1 et ri2 pour scinder la sous-matrice irig
  396. C ---------------------------------------------------------------
  397. C Dimensions communes a RI1 et RI2
  398. nbnn=num(/1)
  399. nbsous=0
  400. nbref=0
  401. nligrd=re(/1)
  402. nligrp=re(/2)
  403. C
  404. C Creation de RI2 : rigidites elementaires a conserver
  405. nbelem=num(/2)-nbdepe
  406. if (nbelem.gt.0) then
  407. segini,ipt2
  408. ipt2.itypel=itypel
  409. nelrig=nbelem
  410. rigrel=0
  411. segini,xmatr2
  412. xmatr2.symre=symre
  413. ri2.irigel(1,irig)=ipt2
  414. ri2.irigel(3,irig)=descr
  415. ri2.irigel(4,irig)=xmatr2
  416. do iii=5,8
  417. ri2.irigel(iii,irig)=ri4.irigel(iii,irig)
  418. ENDDO
  419. ri2.coerig(irig)=ri4.coerig(irig)
  420. else
  421. ri2.irigel(1,irig)=0
  422. xmatr2=0
  423. endif
  424. C
  425. C Creation de RI1 : rigidites elementaires a eliminer.
  426. C L'inconnue a eliminer doit etre en 2eme position (apres LX)
  427. C Si l'inconnue a eliminer n'est pas celle apparaissant en
  428. C deuxieme position il faut pivoter la rigidite elementaire
  429. C et le descripteur associe
  430. ri1p=ri1
  431. nrigel=0
  432. do kkk=1,nligrp
  433. if (idata(1,kkk).gt.0) nrigel=nrigel+1
  434. enddo
  435. nbpvt=nbpvt+nrigel
  436. segini,ri1
  437. ri1.iforig=iforig
  438. ri1.mtymat=typmat
  439. icpt=0
  440. do 25 jjj=1,nligrp
  441. nelrig=idata(1,jjj)
  442. C Nombre d'elements elimines en choisissant la jjjeme inconnue
  443. if (nelrig.eq.0) goto 25
  444. nbelem=nelrig
  445. segini,ipt1
  446. ipt1.itypel=itypel
  447. rigrel=0
  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 Dualisation des multiplicateurs de Lagrange
  599. C -----------------------------------------------------------------
  600. C si on a des conditions unilaterales, on ne dualise pas, ce sera fait
  601. C dans le resou de unilater
  602. IF (BDBLX) CALL DBBLX(RI2)
  603. C
  604. CC write (ioimp,*) ' matrice ri1 '
  605. CC call prrigi(ri1,0)
  606. CC write (ioimp,*) ' matrice ri2 '
  607. CC call prrigi(ri2,0)
  608. CC segact,ri1,ri2
  609. CC write(ioimp,*) ' sortie de separm '
  610. ** call ooodmp(0)
  611. ** nbap=oooval(2,1)
  612. ** write(ioimp,*) 'nb segmts dans separm avant apres ',nbav,nbap
  613. END
  614.  
  615.  

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