Télécharger separm.eso

Retour à la liste

Numérotation des lignes :

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

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