Télécharger separm.eso

Retour à la liste

Numérotation des lignes :

separm
  1. C SEPARM SOURCE PV090527 23/09/13 21:15:03 11739
  2. subroutine separm(mrigid,ri1,ri2,nounil,lagdua,nelim,if)
  3. IMPLICIT INTEGER(I-N)
  4. IMPLICIT REAL*8 (A-H,O-Z)
  5. integer oooval
  6. -INC SMRIGID
  7. -INC SMCOORD
  8. -INC SMELEME
  9.  
  10. -INC PPARAM
  11. -INC CCOPTIO
  12. -INC CCREEL
  13. * extrait de mrigid dans ri1 la partie des relations pouvant etre
  14. * traitees comme des dependances (elimination des inconnues)
  15. * il faut que la premiere inconnue d'une dependance n'apparaisse pas
  16. * dans les autres dependances
  17. * juillet 2003 passage aux simples multiplicateurs de Lagrange, mais
  18. * separm dualise ceux qu'il garde
  19. *-INC CCHAMP
  20. segment trav1
  21. character*(lochpo) compp(lcomp1)
  22. C* character*4 compp(nbincp)
  23. endsegment
  24. segment trav2
  25. integer ielim(nbnoc,nbincp),iautr(nbnoc,nbincp)
  26. integer icomb(nbnoc,nbincp),ideja(nbnoc,nbincp)
  27. endsegment
  28. segment trav3
  29. integer posinc(nligrp)
  30. endsegment
  31. segment trav4
  32. integer itrv1(nbprl)
  33. integer itrv2(nbprl)
  34. real*8 dtrv1(nbprl)
  35. real*8 dtrv2(nbprl)
  36. endsegment
  37. segment icpr(nbpts)
  38. character*(lochpo) co1
  39. integer ri1s,ri2s,ri1f
  40. ** write(6,*) ' entree de separm '
  41. ** call ooodmp(0)
  42. ** nbav=oooval(2,1)
  43. * write (6,*) ' dans separm nouinl ',nounil
  44. nbdep=0
  45. nbpiv=0
  46. nbpvt=0
  47. nbno=nbpts
  48. segini icpr
  49. nbnoc=0
  50. segact mrigid
  51. do 760 irig=1,irigel(/2)
  52. meleme=irigel(1,irig)
  53. segact meleme
  54. ** write(6,*) '1 itypel dans separm',itypel
  55. do il=1,num(/2)
  56. do ip=1,num(/1)
  57. ipt=num(ip,il)
  58. if (icpr(ipt).eq.0) then
  59. nbnoc=nbnoc+1
  60. icpr(ipt)=nbnoc
  61. endif
  62. enddo
  63. enddo
  64. 760 continue
  65.  
  66. * remplissage du segment trav1 (liste des noms de composantes)
  67. lcomp1 = 50
  68. segini trav1
  69. nbincp=0
  70. do 10 irig=1,irigel(/2)
  71. *** if (irigel(6,irig).ne.0.and.irigel(6,irig).ne.2
  72. *** & .and.nounil.eq.0) goto 10
  73. if (irigel(6,irig).ne.0.and.nounil.eq.0) goto 10
  74. meleme=irigel(1,irig)
  75. segact meleme
  76. if (itypel.ne.22.and.itypel.ne.28) goto 20
  77. if (irigel(7,irig).ne.0) goto 20
  78. descr=irigel(3,irig)
  79. segact descr
  80. do 40 nligrp=2,lisinc(/2)
  81. C print *,'lisinc(',nligrp,'/',lisinc(/2),')=',lisinc(nligrp)
  82. do 50 inc=1,nbincp
  83. if (compp(inc).eq.lisinc(nligrp)) goto 40
  84. 50 continue
  85. nbincp=nbincp+1
  86. if (nbincp.GT.lcomp1) then
  87. lcomp1 = lcomp1 + 50
  88. segadj trav1
  89. endif
  90. compp(nbincp)=lisinc(nligrp)
  91. 40 continue
  92. segdes,descr
  93. 20 continue
  94. 10 continue
  95. c* lcomp1 = nbincp
  96. c* segadj trav1
  97. * on construit ri1 et ri2 en notant dans le segment trav2 ce qu'on fait
  98. * write(6,*) 'separm nbno nbnoc ',nbno,nbnoc
  99. segini trav2
  100. * on interdit d'eliminer les inconnues apparaissant dans des conditions unilaterales
  101. * ainsi qur toutes si on est el elim 0
  102. do 60 irig=1,irigel(/2)
  103. meleme=irigel(1,irig)
  104. if (nelim.ne.0) then
  105. if(itypel.ne.28) then
  106. if (irigel(6,irig).eq.0.or.nounil.eq.1) goto 60
  107. endif
  108. endif
  109. ** write(6,*) 'itypel dans separm',itypel
  110. segact meleme
  111. ** if(itypel.eq.28) write(6,*) 'taille super el ',num(/1)
  112. if (itypel.ne.22.and.
  113. > (itypel.ne.28.or.num(/1).lt.255.or.if.lt.3)) goto 60
  114. if (irigel(7,irig).ne.0) goto 60
  115. descr=irigel(3,irig)
  116. segact descr
  117. nld=2
  118. if(itypel.eq.28) then
  119. nld=1
  120. ** write(6,*) 'taille super el ',num(/1)
  121. endif
  122. do 70 nligrp=nld,lisinc(/2)
  123. do 80 inc=1,nbincp
  124. C print *,'lisinc(',nligrp,'/',lisinc(/2),')=',lisinc(nligrp)
  125. C & ,' compp(',inc,')=',compp(inc)
  126. if (compp(inc).eq.lisinc(nligrp)) goto 90
  127. 80 continue
  128. *** write(ioimp,*) '- ',lisinc(nligrp),' non trouve dans trav1'
  129. goto 70
  130. 90 continue
  131. ip=noelep(nligrp)
  132. do 100 j=1,num(/2)
  133. C IF(num(ip,j).GT.ielim(/1).OR.inc.GT.ielim(/2).OR.
  134. C * num(ip,j).GT.iautr(/1).OR.inc.GT.iautr(/2))THEN
  135. C print *,'BUG DANS SEPARM : ',
  136. C & num(ip,j),'>',ielim(/1),iautr(/1),
  137. C & inc,'>',ielim(/2),iautr(/2)
  138. C ENDIF
  139. ielim(icpr(num(ip,j)),inc)=1
  140. iautr(icpr(num(ip,j)),inc)=1
  141. 100 continue
  142. 70 continue
  143. segdes descr
  144. 60 continue
  145. 61 continue
  146. *
  147. do 700 irig=1,irigel(/2)
  148. if (irigel(6,irig).ne.0.and.nounil.eq.0) goto 690
  149. meleme=irigel(1,irig)
  150. descr=irigel(3,irig)
  151. xmatri=irigel(4,irig)
  152. segact meleme
  153. if (itypel.ne.22) goto 690
  154. if (irigel(7,irig).ne.0) goto 690
  155. segact descr
  156. * remplir posinc pour accelerer les tests sur les composantes
  157. nligrp=lisinc(/2)
  158. segini trav3
  159. do 730 inc=2,nligrp
  160. do 720 incp=1,nbincp
  161. if (lisinc(inc).eq.compp(incp)) then
  162. posinc(inc)=incp
  163. goto 730
  164. endif
  165. 720 continue
  166. call erreur(5)
  167. 730 continue
  168. do 750 ince=2,lisinc(/2)
  169. incp=posinc(ince)
  170. do 740 j=1,num(/2)
  171. ip=num(noelep(ince),j)
  172. icomb(icpr(ip),incp)=icomb(icpr(ip),incp)+1
  173. 740 continue
  174. 750 continue
  175. segsup trav3
  176. 690 continue
  177. 700 continue
  178. ipass=1
  179. 2000 continue
  180. segini,ri1=mrigid
  181. segini,ri2=mrigid
  182. * quelques preparatifs
  183. * on remplit le segment qui sert a trier les relations
  184. * trier pour attaquer en premier les relations portant sur le moins de noeud
  185. nbprl=irigel(/2)
  186. segini trav4
  187. do 765 irig=1,nbprl
  188. descr=irigel(3,irig)
  189. segact descr
  190. dtrv1(irig)= lisinc(/2)+0.1
  191. if(irigel(6,irig).ne.0) dtrv1(irig)=dtrv1(irig)+1000000
  192. if(irigel(6,irig).eq.2) dtrv1(irig)=dtrv1(irig)+1000000
  193. ** if(irigel(6,irig).eq.0) dtrv1(irig)=dtrv1(irig)+1000000
  194. ** itrv1(irig)=nbprl-irig+1
  195. itrv1(irig)= irig
  196. 765 continue
  197. call triflo(dtrv1,dtrv2,itrv1,itrv2,nbprl)
  198. do 200 iri=1,irigel(/2)
  199. irig=itrv1(iri)
  200. ** irig=iri
  201. ** if (ipass.eq.1) irig=itrv1(iri)
  202. * write(6,*) ' boucle 200 irig iri nbprl ',irig,iri,nbprl
  203. if (irigel(6,irig).ne.0.and.nounil.eq.0) goto 190
  204. meleme=irigel(1,irig)
  205. descr=irigel(3,irig)
  206. Xmatri=irigel(4,irig)
  207. segact meleme
  208. if (itypel.ne.22) goto 190
  209. if (irigel(7,irig).ne.0) goto 190
  210. segact descr,Xmatri
  211. if (abs(re(1,1,1)).gt.1d-30) goto 190
  212. * remplir posinc pour accelerer les tests sur les composantes
  213. nligrp=lisinc(/2)
  214. segini trav3
  215. do 230 inc=2,nligrp
  216. do 220 incp=1,nbincp
  217. if (lisinc(inc).eq.compp(incp)) then
  218. posinc(inc)=incp
  219. goto 230
  220. endif
  221. 220 continue
  222. call erreur(5)
  223. 230 continue
  224. nbdepe=0
  225. * pour arriver à eliminer, il est interessant de faire pivoter les matrices
  226. * on va le faire en se basant sur le milieu du paquet
  227. iel=num(/2)/2+1
  228. incf=0
  229. do 1000 ince=2,lisinc(/2)
  230. ipp=num(noelep(ince),iel)
  231. incpp=posinc(ince)
  232. * cette inconnue apparait elle dejà dans une autre relation
  233. if (iautr(icpr(ipp),incpp).eq.1) goto 1000
  234. * cette matrice touche t elle une autre relation
  235. do 1240 inc=2,lisinc(/2)
  236. if (inc.eq.ince) goto 1240
  237. incp=posinc(inc)
  238. ip=num(noelep(inc), iel)
  239. if (ielim(icpr(ip),incp).eq.1) goto 1000
  240. 1240 continue
  241. * le pivot est il correct
  242. remax=abs(re(1,1,iel))
  243. do 1270 ilig=2,re(/2)
  244. remax=max(remax,abs(re(1,ilig,iel)))
  245. 1270 continue
  246. remax=remax*0.9
  247. if (abs(re(1,ince,iel)).lt.remax) goto 1000
  248. * ok on pivote si il y a lieu
  249. * write (6,*) ' ipp incpp icomb ',ipp,incpp,icomb(icpr(ipp),incpp)
  250. if (icomb(icpr(ipp),incpp).eq.1) goto 1010
  251. if (incf.eq.0) incf=ince
  252. incf=ince
  253. goto 1000
  254. 1000 continue
  255. ince=2
  256. if (incf.ne.0) ince=incf
  257. 1010 continue
  258. inm=0
  259. if (ince.ne.2) then
  260. * on pivote 2 et ince
  261. * write (6,*) ' on pivote avec la ligne ',ince
  262. nbpvt=nbpvt+1
  263. incp=posinc(ince)
  264. posinc(ince)=posinc(2)
  265. posinc(2)=incp
  266. segini,des1=descr
  267. segdes descr
  268. descr=des1
  269. ri1.irigel(3,irig)=descr
  270. ri2.irigel(3,irig)=descr
  271. * write (6,*) noelep(2),noelep(ince),lisinc(2),lisinc(ince)
  272. co1=lisinc(2)
  273. lisinc(2)=lisinc(ince)
  274. lisinc(ince)=co1
  275. co1=lisdua(2)
  276. lisdua(2)=lisdua(ince)
  277. lisdua(ince)=co1
  278. noe=noelep(2)
  279. noelep(2)=noelep(ince)
  280. noelep(ince)=noe
  281. noe=noeled(2)
  282. noeled(2)=noeled(ince)
  283. noeled(ince)=noe
  284. inm=1
  285. segini,Xmatr1=Xmatri
  286. segdes Xmatri
  287. Xmatri=Xmatr1
  288. ri1.irigel(4,irig)=Xmatri
  289. ri2.irigel(4,irig)=Xmatri
  290. do 1100 im=1,re(/3)
  291. do 1130 il=1,re(/1)
  292. ret=re(il,2,im)
  293. re(il,2,im)=re(il,ince,im)
  294. re(il,ince,im)=ret
  295. 1130 continue
  296. do 1160 il=1,re(/2)
  297. ret=re(2,il,im)
  298. re(2,il,im)=re(ince,il,im)
  299. re(ince,il,im)=ret
  300. 1160 continue
  301. * segdes xmatri
  302. 1100 continue
  303. endif
  304. * peut etre une dependance
  305. segini,ipt1=meleme
  306. if(inm.eq.0) then
  307. segini,xmatr1=xmatri
  308. else
  309. xmatr1=xmatri
  310. endif
  311. * write(6,*) 'separm xmatr1 ipt1 ipt1.itypel ',
  312. * > xmatr1,ipt1,ipt1.itypel
  313. do 210 j=1,num(/2)
  314. ip=ipt1.num(noelep(2),j)
  315. * cette matrice contient t elle des inconnues
  316. if (noelep(/1).le.1) then
  317. ipt1.num(1,j)=0
  318. goto 210
  319. endif
  320. incp=posinc(2)
  321. if (ipass.eq.1.and.icomb(icpr(ip),incp).ne.1) then
  322. ipt1.num(1,j)=0
  323. goto 210
  324. endif
  325. if (iautr(icpr(ip),incp).eq.1) then
  326. ipt1.num(1,j)=0
  327. goto 210
  328. endif
  329. * cette matrice touche t elle une autre relation
  330. do 240 inc=2,lisinc(/2)
  331. incp=posinc(inc)
  332. ip=ipt1.num(noelep(inc),j)
  333. if (ielim(icpr(ip),incp).eq.1) then
  334. ipt1.num(1,j)=0
  335. goto 210
  336. endif
  337. 240 continue
  338. * le pivot est il correct
  339. remax=xpetit*1d4
  340. do 270 ilig=2,re(/2)
  341. remax=max(remax,abs(re(1,ilig,j)))
  342. 270 continue
  343. remax=remax*1d-2
  344. if (abs(re(1,2,j)).le.remax) then
  345. ipt1.num(1,j)=0
  346. nbpiv=nbpiv+1
  347. goto 210
  348. endif
  349. * Y a t'il deux fois la meme inconnue?
  350. ideux=0
  351. do inc=2,lisinc(/2)
  352. if (ideja(icpr(ipt1.num(noelep(inc),j)),posinc(inc)).eq.1) then
  353. ideux=inc
  354. else
  355. ideja(icpr(ipt1.num(noelep(inc),j)),posinc(inc))=1
  356. endif
  357. enddo
  358. do inc=2,lisinc(/2)
  359. ideja(icpr(ipt1.num(noelep(inc),j)),posinc(inc))=0
  360. enddo
  361. if (ideux.ne.0) then
  362. moterr(1:4)=lisinc(ideux)
  363. interr(1)=ipt1.num(noelep(ideux),j)
  364. call erreur(-361)
  365. ipt1.num(1,j)=0
  366. goto 210
  367. endif
  368. * la matrice est elle augmentee
  369. if (abs(re(1,1,j)).gt.1d-5) then
  370. ipt1.num(1,j)=0
  371. goto 210
  372. endif
  373. * segdes xmatri
  374. * ok on la prend en dependance
  375. nbdepe=nbdepe+1
  376. nbdep=nbdep+1
  377. * write (6,*) ' inconnu eliminee ',ipt1.num(noelep(2),j),
  378. * > lisinc(2)
  379. ielim(icpr(ipt1.num(noelep(2),j)),posinc(2))=1
  380. do 280 inc=2,lisinc(/2)
  381. iautr(icpr(ipt1.num(noelep(inc),j)),posinc(inc))=1
  382. 280 continue
  383. 210 continue
  384. segsup trav3
  385. * il faut maintenant tasser ipt1 et creer ipt2
  386. nbnn=num(/1)
  387. nbelem=num(/2)-nbdepe
  388. ** if(nbelem.eq.0) write(6,*) ' separm nbelem ',nbelem
  389. ** write(6,*) ' nombre d elements crees pour ipt2 ',nbelem
  390. nbsous=0
  391. nbref=0
  392. segini ipt2
  393. ipt2.itypel=itypel
  394. nelrig=nbelem
  395. nligrd=re(/1)
  396. nligrp=re(/2)
  397. segini xmatr2
  398. xmatr2.symre=symre
  399. idec=0
  400. do 300 j=1,num(/2)
  401. if (ipt1.num(1,j).eq.0) then
  402. idec=idec+1
  403. do 310 i=1,num(/1)
  404. ipt2.num(i,idec)=num(i,j)
  405. 310 continue
  406. do io=1,nligrp
  407. do iu=1,nligrd
  408. xmatr2.re(iu,io,idec)=re(iu,io,j)
  409. enddo
  410. enddo
  411. * imatr2.imattt(idec)=imattt(j)
  412. else
  413. do 320 i=1,num(/1)
  414. ipt1.num(i,j-idec)=num(i,j)
  415. 320 continue
  416. do io=1,nligrp
  417. do iu=1,nligrd
  418. xmatr1.re(iu,io,j-idec)=re(iu,io,j)
  419. enddo
  420. enddo
  421. * imatr1.imattt(j-idec)=imattt(j)
  422. endif
  423. 300 continue
  424.  
  425. nbelem=nbdepe
  426. segadj ipt1
  427. nelrig=nbelem
  428. segadj xmatr1
  429. ri1.irigel(1,irig)=ipt1
  430. ri2.irigel(1,irig)=ipt2
  431. ri1.irigel(4,irig)=xmatr1
  432. ri2.irigel(4,irig)=xmatr2
  433. segdes xmatr1,xmatr2
  434. goto 200
  435. 190 continue
  436. * pas une dependance
  437. ri1.irigel(1,irig)=0
  438. 200 continue
  439. segsup trav4
  440. * compression de ri1
  441. idec=0
  442. do 500 irig=1,irigel(/2)
  443. meleme=ri1.irigel(1,irig)
  444. if (meleme.eq.0) then
  445. idec=idec+1
  446. else
  447. segact meleme
  448. if (num(/2).eq.0) then
  449. idec=idec+1
  450. segsup meleme
  451. xmatri=ri1.irigel(4,irig)
  452. segsup xmatri
  453. else
  454. do 510 ir=1,irigel(/1)
  455. ri1.irigel(ir,irig-idec)=ri1.irigel(ir,irig)
  456. 510 continue
  457. ri1.coerig(irig-idec)=ri1.coerig(irig)
  458. endif
  459. endif
  460. 500 continue
  461. nrige=max(irigel(/1),8)
  462. nrigel=irigel(/2)-idec
  463. * write (6,*) ' dimension de ri1 ',nrige,nrigel
  464. segadj ri1
  465. do irig=1,nrigel
  466. ri1.irigel(8,irig)=1
  467. enddo
  468. * compression de ri2
  469. idec=0
  470. do 600 irig=1,irigel(/2)
  471. meleme=ri2.irigel(1,irig)
  472. if (meleme.eq.0) then
  473. idec=idec+1
  474. else
  475. segact meleme
  476. if (num(/2).eq.0) then
  477. idec=idec+1
  478. segsup meleme
  479. xmatri=ri2.irigel(4,irig)
  480. segsup xmatri
  481. else
  482. do 610 ir=1,irigel(/1)
  483. ri2.irigel(ir,irig-idec)=ri2.irigel(ir,irig)
  484. 610 continue
  485. ri2.coerig(irig-idec)=ri2.coerig(irig)
  486. endif
  487. endif
  488. 600 continue
  489. nrige=max(irigel(/1),8)
  490. nrigel=irigel(/2)-idec
  491. * write (6,*) ' dimension de ri2 ',nrige,nrigel
  492. segadj ri2
  493. do irig=1,nrigel
  494. ri2.irigel(8,irig)=0
  495. enddo
  496. * On va voir si on ne peut pas faire pivoter ri2
  497. if (ipass.eq.2) goto 2001
  498. ri1s=ri1
  499. ri2s=ri2
  500. mrigis=mrigid
  501. mrigid=ri2
  502. nbpiv=0
  503. ipass=ipass+1
  504. goto 2000
  505. 2001 continue
  506. mrigid=mrigis
  507. call fusrig(ri1s,ri1,ri1f)
  508. ri1=ri1f
  509. segsup trav1,trav2,icpr
  510. if (iimpi.ne.0) then
  511. write (6,*) ' nombre de relations éliminées ',nbdep
  512. write (6,*) ' nombre de relations gardées à cause du pivot ',
  513. > nbpiv
  514. write (6,*) ' nombre de relations gardées car non indépendantes ',
  515. write (6,*) ' nombre de paquets pivotés ',
  516. > nbpvt
  517. endif
  518. * dualisation des multiplicateurs de Lagrange dans ri2
  519. * si on a des conditions unilatérales, on ne dualise pas, ce sera fait
  520. * dans le resou de unilater
  521. iunil=0
  522. segact ri2
  523. do ir=1,ri2.irigel(/2)
  524. if (ri2.irigel(6,ir).ne.0) iunil=1
  525. enddo
  526. if ((iunil.eq.0.or.nounil.eq.1).and.lagdua.ge.0)
  527. $ call dbblx(ri2,lagdua)
  528. * write(6,*) ' dans separm lagdua ',lagdua
  529. * write (6,*) ' matrice ri1 '
  530. * call prrigi(ri1)
  531. * write (6,*) ' matrice ri2 '
  532. * call prrigi(ri2)
  533. ** write(6,*) ' sortie de separm '
  534. ** call ooodmp(0)
  535. ** nbap=oooval(2,1)
  536. ** write(6,*) 'nb segmts dans separm avant apres ',nbav,nbap
  537.  
  538. end
  539.  
  540.  
  541.  
  542.  
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549.  
  550.  
  551.  
  552.  
  553.  
  554.  
  555.  
  556.  

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