Télécharger ldmt2.eso

Retour à la liste

Numérotation des lignes :

ldmt2
  1. C LDMT2 SOURCE GOUNAND 24/11/12 21:15:06 12076
  2. SUBROUTINE LDMT2(ITRAV1,ITOPO1,INUIN1,IMINI1,MMMTRI,IPO1,INCTR1
  3. $ ,INCTR2,IITOP1,TRSUP,MENAGE,LDIAG,IITOPB,ITOPOB,IPODD,njtot
  4. $ ,INORMU)
  5.  
  6. CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
  7. C
  8. C **** SUBROUTINE POUR FAIRE L'ASSEMBLAGE DE MATRICES
  9. C
  10. C EN ENTREE:
  11. C **** ITRAV1 : POINTEUR OBJET MRIGIDITE
  12. C **** ITOPO1 : POINTEUR SEGMENT DE TRAVAIL ITOPO ( VOIR ASSEM1)
  13. C **** IITOP1 : POINTEUR SEGMENT DE TRAVAIL IITOP ( VOIR ASSEM1)
  14. C **** INUIN1 : POINTEUR SEGMENT DE TRAVAIL INUINV(VOIR ASSEM1)
  15. C **** IMINI1 : POINTEUR SEGMENT DE TRAVAIL IMINI (VOIR ASSEM1)
  16. C **** IPO1 : POINTEUR SEGMENT DE TRAVAIL IPOS (VOIR ASSEM1)
  17. C **** MMMTRI : POINTEUR OBJET MATRICE TRIANGULARISEE (NON MODIFIE)
  18. C (VOIR SMMATRI)
  19. C **** INORMU : =0 si on ne veut pas normaliser les multiplicateurs
  20. C de Lagrange, <>0 sinon
  21. C
  22. C Appelée par : LDMT1
  23. C
  24. C Auteur : Michel BULIK
  25. C
  26. C Date : Printemps '95
  27. C
  28. C Langage : ESOPE + FORTRAN77
  29. C
  30. CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
  31. IMPLICIT INTEGER(I-N)
  32. IMPLICIT REAL*8 (A-H,O-Z)
  33. -INC CCREEL
  34.  
  35. -INC PPARAM
  36. -INC CCOPTIO
  37. -INC SMELEME
  38. -INC SMRIGID
  39. -INC SMMATRI
  40.  
  41. SEGMENT,INUINV(NNGLOB)
  42. SEGMENT,ITOPO(IENNO)
  43. SEGMENT,ITOPOB(IENNO)
  44. SEGMENT,IITOP(NNOE+1)
  45. SEGMENT,IITOPB(NNOE+1)
  46. SEGMENT,IMINI(INC)
  47. SEGMENT,IPOS(NNOE1)
  48. SEGMENT,IPOD(NNOE1)
  49. SEGMENT,INCTRR(NIRI)
  50. SEGMENT,INCTRD(NIRI)
  51. SEGMENT,INCTRA(NLIGRE)
  52. SEGMENT,INCTRB(NLIGRE)
  53. SEGMENT,IPV(NNOE)
  54. SEGMENT,VMAX(INC)
  55. C
  56. C **** CES TABLEAUX SERVENT AU REPERAGE DE LA MATRICE POUR L'ASSEMBLAG
  57. C **** IL SERONT TOUS SUPPRIMES EN FIN D'ASSEMBLAGE.
  58. C
  59. SEGMENT,IVAL(NNN)
  60. SEGMENT,ITRA(NNN,2)
  61. SEGMENT TRATRA
  62. REAL*8 XTRA(INCRED,INCDIF)
  63. INTEGER LTRA(INC,INCDIF)
  64. INTEGER NTRA(INCRED,INCDIF)
  65. INTEGER MTRA(INCDIF)
  66. ENDSEGMENT
  67.  
  68. CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
  69. C
  70. C **** IVAL(I)=J : LA I EME LIGNE D'UNE PETITE MATRICE S'ASSEMBLE
  71. C DANS LA J EME DE LA GRANDE.
  72. C **** ITRAV(I,1)=J : LA IEME INCONNUE DU NOEUD EN COURS D'ASSEMBLAGE
  73. C ET QUI SE TROUVE DANS LA PETITE MATRICE SE TROUVE
  74. C EN J EME POSITION DE LA PETITE MATRICE.
  75. C **** ITRAV(I,2) : LA IEME INCONNUE DU NOEUD EN COURS D'ASSEMBLAGE
  76. C PRESENT DANS LA PETITE MATRICE EST EN JEME
  77. C POSITION DANS LA GRANDE
  78. C
  79. CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
  80.  
  81. SEGMENT,RA(N1,N1)*D
  82. SEGMENT JNOMUL
  83. LOGICAL INOMUL(NNR)
  84. ENDSEGMENT
  85. REAL*8 DMAX,COER,DDDD,DMAXY
  86. LOGICAL NOMUL
  87. LOGICAL TRSUP,MENAGE,LDIAG
  88.  
  89.  
  90. SAVE IPASG
  91. DATA IPASG/0/
  92.  
  93.  
  94. ** write(6,*) ' ldmt2 inormu ',inormu
  95. C
  96. C en cas de normalisation des variables.
  97. C
  98. C ... On a vérifié dans RESOU que dans le cas non-symétrique soit NORINC=NORIND=0,
  99. C soit les deux sont non-nuls, mais on se méfie quand même ...
  100. inwuit=0
  101. C write (6,*) ' NORINC NORIND LDIAG',norinc,norind,ldiag
  102. IF(NORINC.NE.0.AND.NORIND.NE.0 .AND. LDIAG) then
  103. CALL ASSEM0(ITRAV1,1,inwuit)
  104. endif
  105. C
  106. C PV ON ACTIVE UNE FOIS POUR TOUTES LES MELEME DESCR... DE LA RIGIDITE
  107. C ON EN PROFITE POUR CREER INOMUL
  108. C
  109. C **** RECHERCHE DE LA DIMENSION MAX DE IVAL,ET SEGINI DE IVAL ET ITRA
  110. C
  111. INCTRR=INCTR1
  112. SEGACT,INCTRR
  113. C ... dans le cas asymétrique on se doit de faire la même chose avec les vd ...
  114. INCTRD=INCTR2
  115. SEGACT,INCTRD
  116.  
  117. MRIGID=ITRAV1
  118. SEGACT,MRIGID
  119. NNR=IRIGEL(/2)
  120. C ... NNR = équivalent à NRIGEL (nb. de rigidités élémentaires) ...
  121. NNN=0
  122. SEGINI JNOMUL
  123. DO 1 IRI=1,NNR
  124. INCTRA=INCTRR(IRI)
  125. SEGACT INCTRA
  126. C ... dans le cas asymétrique on se doit de faire la même chose avec les vd ...
  127. INCTRB=INCTRD(IRI)
  128. SEGACT INCTRB
  129. DESCR=IRIGEL(3,IRI)
  130. SEGACT, DESCR
  131. IPT1=IRIGEL(1,IRI)
  132. SEGACT IPT1
  133. ipt2=IRIGEL(2,IRI)
  134. if (ipt2.ne.0) segact,ipt2
  135. xMATRI=IRIGEL(4,IRI)
  136. SEGACT xMATRI
  137. if (.not.trsup) then
  138. C ... NA = nb de variables primales ...
  139. NA=LISINC(/2)
  140. else
  141. C ... NA = nb de variables duales ...
  142. NA=LISDUA(/2)
  143. endif
  144. C ... NNN = max des nb de variables primales ...
  145. NNN=MAX(NA,NNN)
  146. C ... INOMUL (NOn MULtiplicateurs ?) dit s'il ne s'agit pas des CL ...
  147. INOMUL(IRI)=.TRUE.
  148. IF(IPT1.ITYPEL.EQ.49) INOMUL(IRI)=.FALSE.
  149. 1 CONTINUE
  150. C ... IVAL a la taille NNN ...
  151. SEGINI,IVAL
  152. C ... ITRA A LA TAILLE (NNN,2) ...
  153. SEGINI,ITRA
  154. C
  155. C **** ACTIVATION DES SEGMENTS DE TRAVAILS ET DE MMATRI
  156. C
  157. IF(.NOT.LDIAG) THEN
  158. ITOPO=ITOPO1
  159. IITOP=IITOP1
  160. IPOS=IPO1
  161. ELSE
  162. ITOPO=ITOPOB
  163. IITOP=IITOPB
  164. IPOS = IPODD
  165. ENDIF
  166. SEGACT,IITOP
  167. SEGACT,ITOPO
  168. SEGACT,IPOS
  169. C write(6,*) 'ipos', ( ipos(IU),IU=1,ipos(/1))
  170. C write(6,*) 'itopo', ( itopo(IU),IU=1,itopo(/1))
  171. C write(6,*) 'iitop', ( iitop(IU),IU=1,iitop(/1))
  172. INUINV=INUIN1
  173. SEGACT,INUINV
  174. SEGACT,IPOS
  175. C ... NNOE = nombre de noeuds impliqués ...
  176. NNOE=IPOS(/1)-1
  177. C ... INC = dimension de la matrice ...
  178. INC=IPOS(NNOE+1)
  179. MMATRI=MMMTRI
  180. SEGACT,MMATRI*MOD
  181. IF(LDIAG) THEN
  182. SEGINI,MDIAG
  183. IDIAG=MDIAG
  184. ELSE
  185. MDIAG=IDIAG
  186. SEGACT,MDIAG
  187. ENDIF
  188. SEGINI,MILIGN
  189. IF(TRSUP) THEN
  190. IILIGS=MILIGN
  191. ELSE
  192. IILIGN=MILIGN
  193. ENDIF
  194. MINCPO=IINCPO
  195. SEGACT,MINCPO
  196. C ... INCDIF = nb de variables primales différentes ...
  197. INCDIF=INCPO(/1)
  198. MIPO1=IDUAPO
  199. SEGACT,MIPO1
  200. casym(OK) ... on va prendre en compte aussi les vd pour déterminer
  201. c la taille de TRATRA ...
  202. INCDID=MIPO1.INCPO(/1)
  203. INCDIF=MAX(INCDIF,INCDID)
  204. *
  205. MIMIK=IIMIK
  206. SEGACT,MIMIK
  207. C ... IPV est de taille NNOE ...
  208. SEGINI IPV
  209. INCRED=0
  210. DO 80 INO =1,NNOE
  211. ICOMPT=0
  212. C ... MAXELE = nb d'éléments qui contiennent le noeud No INO ...
  213. MAXELE = (IITOP(INO+1)-IITOP(INO))/2
  214. C ... Boucle sur ces éléments ...
  215. DO 81 IELE=1,MAXELE
  216. C ... IIU = pointeur dans IITOP ...
  217. IIU=IITOP(INO) + IELE + IELE -2
  218. C ... IEL = numero de l'élément dans son maillage ...
  219. IEL=ITOPO(IIU)
  220. C ... IRI = numero du maillage (dans IRIGEL) de cet élément ...
  221. IRI=ITOPO(IIU+1)
  222. C ... On va chercher ce maillage dans IRIGEL ...
  223. meleme=IRIGEL(2,IRI)
  224. if (meleme.eq.0) meleme=IRIGEL(1,IRI)
  225. C ... Boucle sur les noeuds de cet élément ...
  226. DO 83 I=1,NUM(/1)
  227. C ... IP = numéro local du I-ème noeud de l'élément ...
  228. IP=INUINV(NUM(I,IEL))
  229. C ... La première condition = les "connections" sont symétriques ...
  230. IF (IP.GT.INO) GOTO 83
  231. C ... Le noeud IP a déjà vu ce noeud ...
  232. IF (IPV(IP).EQ.INO) GOTO 83
  233. C ... Ces deux opérations se font si (IP <= INO et IPV(IP) != INO) ...
  234. C ... IPV = N° max des noeuds "connectés" au noeud IP ...
  235. IPV(IP)=INO
  236. C ... ICOMPT = nombre de noeuds connectés (de numéro < ou =) au noeud INO ...
  237. ICOMPT=ICOMPT+1
  238. 83 CONTINUE
  239. 81 CONTINUE
  240. C ... INCRED = maximum des ICOMPT sur tous les noeuds impliqués ...
  241. INCRED=MAX(INCRED,ICOMPT)
  242. cdbg write(*,*) 'LDMT2 : Noeud ',INO,', ICOMPT = ',ICOMPT,
  243. cdbg & ' -> INCRED = ',INCRED
  244. 80 CONTINUE
  245. cdbg segprt,ipv
  246. SEGSUP IPV
  247. *
  248. INCRED=INCRED*INCDIF
  249. C ... La taille de TRATRA dépend de INC, INCRED et INCDIF ...
  250. SEGINI TRATRA
  251. segini vmax
  252. C
  253. C ... Coefficients de normalisation ...
  254. C -----------------------------
  255.  
  256. LLVNUL=0
  257. C ... On n'initialise plus IJMAX ici - ceci se fait un niveau au dessus ...
  258. C-OLD IJMAX=0
  259. C ... La taille de MDNOR est INC (nombre d'équations) ...
  260. MDNOR=0
  261. IF (LDIAG) THEN
  262. SEGINI MDNOR
  263. IDNORM=MDNOR
  264. C ... On a vérifié dans RESOU que dans le cas non-symétrique soit NORINC=NORIND=0,
  265. C soit les deux sont non-nuls ...
  266. SEGINI,MDNO1
  267. IDNORD=MDNO1
  268. DO 20 I=1,INC
  269. DNOR(I)=1.D0
  270. MDNO1.DNOR(I)=1.D0
  271. 20 CONTINUE
  272. else
  273. mdnor=idnorm
  274. segact mdnor
  275. mdno1=idnord
  276. segact mdno1
  277. ENDIF
  278.  
  279. C ... Si une normalisation est imposée, les valeurs dans MDNOR et MDNO1 seront modifiées par ASNS3 ...
  280. midua=iidua
  281. IF(NORINC.NE.0 .AND. NORIND.NE.0 .AND. LDIAG)
  282. & CALL ASNS3(MDNOR,MIMIK,MINCPO,mdno1,midua,mipo1)
  283.  
  284. C **** BOUCLE *100* SUR LES NUMEROS DE NOEUDS QUE L'ON ASSEMBLE
  285. C -------------------------------------------------------------
  286.  
  287. DO 100 INO=1,NNOE
  288. cdbg write(*,*) 'LDMT2: ----------------------------------'
  289. cdbg write(*,*) 'LDMT2: Noeud N° ',INO
  290. DO 101 IIT=1,INCDIF
  291. MTRA(IIT)=0
  292. 101 CONTINUE
  293.  
  294. C ... Attention à l'égalité des IPOS et IPOD qui est testée dans ASNS1 ...
  295.  
  296. C ... IPRE = N° de la première ligne (ou colonne) concernée par le noeud INO ...
  297. IPRE=IPOS(INO )+1
  298. C ... IDER = N° de la dernière ligne (ou colonne) concernée par le noeud INO ...
  299. IDER=IPOS(INO+1)
  300. cdbg write(*,*) 'LDMT2: Lignes de ',IPRE,' jusqu''à ',IDER
  301. LLVVA=0
  302. C
  303. C **** BOUCLE *99* SUR LES ELEMENTS TOUCHANT LE NOEUD INO
  304. C POUR LES ELEMNTS MULTIPLICATEUR ON NE FAIT PAS
  305. C L'ASSEMBLAGE
  306. C
  307. C ... MAXELE = nb d'éléments qui contiennent le noeud No INO ...
  308. MAXELE= (IITOP(INO+1) -IITOP(INO))/2
  309. DO 99 IELE=1,MAXELE
  310. cdbg write(*,*) 'LDMT2: - - - - - - - - - - - -'
  311. cdbg write(*,*) 'LDMT2: Elément N° ',IELE
  312. IIU=IITOP(INO) + IELE + IELE - 2
  313. C ... IEL = numero de l'élément dans son maillage ...
  314. IEL=ITOPO(IIU)
  315. C ... IRI = numero du maillage (dans IRIGEL) de cet élément ...
  316. IRI=ITOPO(IIU+1)
  317. C ... MELEME = pointeur vers ce maillage ...
  318. MELEME=IRIGEL(1,IRI)
  319. C ... DESCR = pointeur vers le segment DESCR concerné ...
  320. DESCR=IRIGEL(3,IRI)
  321. C ... INCTRA contient les indices (dans IMIK et IHAR) des descriptions
  322. C des DDL correspondants ...
  323. casym(OK) ... ici il faudra choisir en fonction de TRSUP si prendre INCTRR ou INCTRD ...
  324. INCTRA=INCTRR(IRI)
  325. INCTRB=INCTRD(IRI)
  326. C ... xMATRI = tableau de pointeurs vers les matrices élémentaires ...
  327. xMATRI=IRIGEL(4,IRI)
  328. C ... COER = coefficient multiplicateur ...
  329. COER=COERIG(IRI)
  330. C ... NOn MULtiplicateur ? ...
  331. NOMUL=INOMUL(IRI)
  332. C
  333. C **** NOMUL =.FALSE. IL EXISTE UN MULTIPLICATEUR
  334. C **** INITIALISATION DE IVAL. IVAL(I)=J VEUT DIRE QUE
  335. C **** LA I EME LIGNE DE LA PETITE MATRICE S'ASSEMBLE DANS
  336. C **** LA J EME DE LA GRANDE MATRICE.
  337. C
  338. C ... Maintenant, dans la boucle 96 (nouvelle par rapport à ASSEM2) on
  339. C va parcourir les lignes (colonnes) pour trouver celles, qui
  340. C s'appuyent sur le noeud INO, cas inférieur (supérieur) ...
  341.  
  342. NA=0
  343. IF(TRSUP) THEN
  344. NIN=LISINC(/2)
  345. ELSE
  346. NIN=LISDUA(/2)
  347. ENDIF
  348. DO 96 ICO=1,NIN
  349. IF(TRSUP) THEN
  350. IJA=INUINV(NUM(NOELEP(ICO),IEL))
  351. IJB=INCTRA(ICO)
  352. ELSE
  353. IJA=INUINV(NUM(NOELED(ICO),IEL))
  354. IJB=INCTRB(ICO)
  355. ENDIF
  356. C ... Si on a trouvé le bon noeud ...
  357. IF(IJA.EQ.INO) THEN
  358. C ... On incrémente NA (le nombre de DDL connectés au noeud INO ?) ...
  359. NA=NA+1
  360. cdbg write(*,*) 'LDMT2: IJA == INO => NA devient ',NA
  361. ITRA(NA,1)=ICO
  362. IF(TRSUP) THEN
  363. ITRA(NA,2)=INCPO(IJB,IJA)
  364. ELSE
  365. ITRA(NA,2)=MIPO1.INCPO(IJB,IJA)
  366. ENDIF
  367. ENDIF
  368. 96 CONTINUE
  369.  
  370. C ... Dans la boucle 98 on va remplir le tableau IVAL avec les numéros
  371. C de colonnes (lignes) pour tous les DDLs primaux (duaux) de la matrice,
  372. C ceci concerne le triangle inférieur (supérieur) ...
  373. casym(OK) ... la boucle devra se faire soit sur les duales soit sur les primales ...
  374.  
  375. IF(TRSUP) THEN
  376. NIN=LISDUA(/2)
  377. ELSE
  378. NIN=LISINC(/2)
  379. ENDIF
  380. C ... Boucle sur les variables primales (duales) de l'élément ...
  381. DO 98 ICO=1,NIN
  382. IF(TRSUP) THEN
  383. IJA=INUINV(NUM(NOELED(ICO),IEL))
  384. IJB=INCTRB(ICO)
  385. IVAL(ICO)=MIPO1.INCPO(IJB,IJA)
  386. cdbg write(*,*) 'LDMT2: vd locale N°',ICO,'-> vd globale N°',IJB
  387. cdbg write(*,*) 'LDMT2: => N° d''équation = ',IVAL(ICO)
  388. ELSE
  389. C ... IJA = numéro local du noeud-support du DDL ...
  390. casym(OK) ... ici il faudra choisir en fonction de TRSUP si prendre NOELEP ou NOELED ...
  391. IJA=INUINV(NUM(NOELEP(ICO),IEL))
  392. C ... IJB = indice du DDL ...
  393. casym(OK) ... INCTRA ou INCTRB ??? ...
  394. IJB=INCTRA(ICO)
  395. C ... On met dans IVAL(ICO) le N° de la colonne correspondant au noeud IJA
  396. C et DDL No IJB ...
  397. casym(OK) ... ici il faudra choisir en fonction de TRSUP si prendre MINCPO ou MIPO1 (?) ...
  398. IVAL(ICO)=INCPO(IJB,IJA)
  399. cdbg write(*,*) 'LDMT2: vp locale N°',ICO,'-> vp globale N°',IJB
  400. cdbg write(*,*) 'LDMT2: => N° de la colonne = ',IVAL(ICO)
  401. ENDIF
  402. 98 CONTINUE
  403.  
  404. C XMATRI=IMATTT(IEL)
  405. C SEGACT,XMATRI
  406. cdbg segprt,xmatri
  407. C
  408. C **** BOUCLE *95* SUR LES INCONNUES DE LA PETITE MATRICE
  409. C
  410. DO 95 INCC=1,NA
  411. C ... INCO = le N° de la ligne (cas inf.) ou colonne (cas sup.)
  412. C du DDL dual (primal) N° INCC du noeud INO ...
  413. casym(OK) ... ici il faudra choisir en fonction de TRSUP quoi prendre ...
  414. INCO=ITRA(INCC,2)
  415. C ... Boucle sur les DDL's du noeud INO ...
  416. DO 90 IK=1,NIN
  417. C ... IO = N° de la colonne (la ligne) correspondant au DDL N° IK de l'élément
  418. casym(OK) ... ici il faudra choisir en fonction de TRSUP quoi prendre ...
  419. IO=IVAL(IK)
  420. C ... Si IO > INCO on ne fait plus rien dans cette boucle ...
  421. C ... Car on ne parcourt que la moitié de la matrice !!! ...
  422. IF(IO.GT.INCO) GO TO 90
  423. C ... ILOC = N° de ligne relatif / IPRE du noeud INO ...
  424. ILOC=INCO-IPRE+1
  425. C ... JJ = N° (dans l'élément) de la ligne (de la colonne) correspondant au
  426. C DDL N° INCC du noeud INO ...
  427. casym(OK) ... attention à ce qui se passe ici ... !!!
  428. JJ=ITRA(INCC,1)
  429. C ... Ci-dessous on stockera les quelques lignes de la rigidité concernant le
  430. C noeud INO dans le segment TRATRA. Les coefficients vont dans XTRA, le deuxième
  431. C indice (ILOC) est le numéro relatif de la ligne, le premier (IMTT) n'a rien à voir avec le
  432. C numéro de la colonne. Celui-ci est stocké dans NTRA(IMTT,ILOC). L'information inverse
  433. C (IMTT en fonction de IO) se trouve dans LTRA(IO,ILOC). On met dans MTRA le nombre
  434. C de termes différents assemblés par ligne ...
  435. C ... ILTT doit contenir l'indice IMMTT en fonction du N° de la colonne; s'il est
  436. C nul, le terme n'a pas encore été assemblé, il faudra donc initialiser ...
  437. ILTT= LTRA(IO,ILOC)
  438. IF(ILTT.EQ.0) THEN
  439. C ... LLVVA est initialisé à 0 au début de la boucle 100 et sert à compter les
  440. C termes assemblés ...
  441. LLVVA=LLVVA+1
  442. C ... Les MTRA sont mis à 0 au début de la boucle 100 ...
  443. C ... Ici on incrémente MTRA(ILOC) et on met la nouvelle valeur dans IMMTT,
  444. C qui sera le premier indice dans différents tableaux de TRATRA ...
  445. IMMTT=MTRA(ILOC)+1
  446. MTRA(ILOC)=IMMTT
  447. C ... puis on initialise le nouveau terme ...
  448. XTRA(IMMTT,ILOC)=0.D0
  449. C ... son N° de colonne (cas inf.) ou ligne (cas supérieur) ...
  450. NTRA(IMMTT,ILOC)=IO
  451. C ... et l'information inverse ...
  452. LTRA(IO,ILOC)=IMMTT
  453. ILTT=IMMTT
  454. ENDIF
  455. C ... Si ce n'est pas une condition aux limites, on assemble ...
  456. IF(NOMUL) THEN
  457. C ... Attention ! Dans XTRA 1er indice est lié à la colonne, deuxième est le numéro
  458. C de la ligne, tandis que dans RE c'est l'inverse ...
  459. IF(TRSUP) THEN
  460. C write(6,*) ' iltt iloc ' , iltt,iloc
  461. C write(6,*) 'ik jj iel re coer ',ik,jj,iel,re(ik,jj,iel),coer
  462. XTRA(ILTT,ILOC)=XTRA(ILTT,ILOC)+RE(IK,JJ,iel)
  463. $ *COER
  464. cdbg write(*,*) 'LDMT2: On rajoute le terme L',IK,', C',JJ,' soit',
  465. cdbg & RE(IK,JJ),' à la col',IPRE+ILOC-1,' et lig',
  466. cdbg & NTRA(ILTT,ILOC)
  467. ELSE
  468. C write(6,*) ' iltt iloc ' , iltt,iloc
  469. C write(6,*) 'ik jj iel re coer ',ik,jj,iel,re(jj,ik,iel),coer
  470. XTRA(ILTT,ILOC)=XTRA(ILTT,ILOC)+RE(JJ,IK,iel)
  471. $ *COER
  472. cdbg write(*,*) 'LDMT2: On rajoute le terme L',JJ,', C',IK,' soit',
  473. cdbg & RE(JJ,IK),' à la lig',IPRE+ILOC-1,' et col',
  474. cdbg & NTRA(ILTT,ILOC)
  475. ENDIF
  476. ENDIF
  477. 90 CONTINUE
  478. 95 CONTINUE
  479. C SEGDES,XMATRI
  480. 99 CONTINUE
  481. C
  482. C *** COMPACTAGE DES LIGNES, EN MEME TEMPS CALCUL DE IJMAX QUI SERA
  483. C *** LA DIMENSION MAX D'UN SEGMENT LIGN.
  484. C *** LE SEGMENT ASSOCIE A UNE LIGNE (SEGMENT LLIGN) EST DE LA FORME :
  485. C *** IMMMM(NA) PERMET DE SAVOIR SI UN MOUVEMENT D'ENSEMBLE SUR LA
  486. C *** LIGNE EXISTE. IPPO(NA+1) DONNE LA POSITION DANS XXVA LA 1ERE
  487. C *** VALEUR DE LA LIGNE .XXVA VALEUR DE LA MATRICE.
  488. C *** LINC(I) DONNE LE NUMERO DE LA COLONNE DU IEME ELEM DE XXVA
  489. C
  490. C ... NA = nb de lignes concernant le noeud INO ...
  491. NA = IDER-IPRE+1
  492. C ... LLVNUL = somme cumulée des LLVVA ...
  493. LLVNUL=LLVNUL+LLVVA
  494. SEGINI,LLIGN
  495. ILIGN(INO)=LLIGN
  496. NBA=0
  497. C write(6,*) ' ider ipre llvnul ino ',ider,ipre,llvnul,ino
  498. C ... Boucle sur les DDL du noeud INO ...
  499. DO 120 JPA=1,NA
  500. C ... IIIN = N° de ligne du DDL N° JPA ...
  501. IIIN=IPRE+JPA -1
  502. C ... que l'on met au bon endroit dans IMMMM (faisant partie de LLIGN) ...
  503. IMMMM(JPA)=IIIN
  504. C ... IPPO(I)+1 = adresse du début (dans XXVA et LINC) des données relatives au DDL N° I ...
  505. IPPO(JPA)=NBA
  506. C ... Boucle sur les termes dans la ligne ...
  507. DO 121 IPAK = 1,MTRA(JPA)
  508. C ... IUNPAK = N° de la colonne du terme N° IPAK ...
  509. IUNPAK=NTRA(IPAK,JPA)
  510. C ... Pour les termes mis dans LLIGN on efface l'information sur la position dans XTRA ...
  511. LTRA(IUNPAK,JPA)=0
  512. C ... Compteur ++ ...
  513. NBA=NBA+1
  514. C ... Le N° de la colonne va dans LINC ...
  515. LINC(NBA)=IUNPAK
  516. C write(6,*) ' nba ipak jpa, ', nba ,ipak,jpa
  517. C ... Transfert du XTRA (segment TRATRA) vers XXVA (segment LLIGN) ...
  518. XXVA(NBA)=XTRA(IPAK,JPA)
  519. vmax(iiin)=max(abs(xxva(nba)),vmax(iiin))
  520. C ... Les termes diagonaux vont dans DIAG (segment MDIAG) ...
  521. IF(LDIAG) THEN
  522. C write(6,*) ' iiin nba xxva(nba)', iiin,nba,xxva(nba)
  523. IF(IIIN.EQ.IUNPAK) DIAG(IIIN)=XXVA(NBA)
  524. ENDIF
  525. 121 CONTINUE
  526. 120 CONTINUE
  527. C ... Le pointeur vers la fin de la dernière ligne ...
  528. IPPO(NA+1)= NBA
  529. NJMAX= 0
  530. C recherche du mini globale sur toutes les inconnues
  531. LPA=IPRE
  532. C ... Boucle sur les lignes relatives au noeud INO ...
  533. DO 126 JPA=IPRE,IDER
  534. C ... On met le N° du noeud dans IPNO (segment MILIGN) ...
  535. IPNO(JPA)=INO
  536. C ... IPDE et IPDF : début et fin des données relatives au DDL N° JPA dans XXVA et LINC ...
  537. IPDE=IPPO(JPA-IPRE+1)+1
  538. IPDF=IPPO(JPA-IPRE+2)
  539. C ... LPA = N° mini de la colonne avec des termes non nuls dans la ligne N° JPA ...
  540. DO 155 JHT=IPDE,IPDF
  541. LPA=MIN(LPA,LINC(JHT))
  542. 155 CONTINUE
  543. 126 CONTINUE
  544. DO 127 JPA=IPRE,IDER
  545. C ... On le met dans LDEB (segment LLIGN) ...
  546. LDEB(JPA-IPRE+1)=LPA
  547. C ... NNA = longueur de la "skyline" ...
  548. NNA= JPA- LPA +1
  549. C ... NJMAX = profil cumulé sur un noeud ...
  550. NJMAX=NJMAX+NNA
  551. 127 CONTINUE
  552. C ... NJTOT = profil total ...
  553. NJTOT=NJTOT+NJMAX
  554. C ... IJMAX = (profil / noeud) maxi ...
  555. IF(IJMAX.LT.NJMAX) IJMAX=NJMAX
  556. SEGDES,LLIGN
  557. 100 CONTINUE
  558. C ... Fin de la boucle sur les noeuds ...
  559. SEGSUP TRATRA
  560. C
  561. C **** ON REPREND TOUTE LES MATRICES CONTENANT LES MULTIPLICATEURS
  562. C **** POUR MULTIPLIER TOUS LEURS TERMES PAR UNE NORME ATTACHEE
  563. C **** A CHAQUE MULTIPLICATEUR. PUIS ON LES ASSEMBLE.
  564. C
  565. * d'abord etablir une norme generale pour le cas ou on n'arrive pas
  566. * a calculer la norme particuliere
  567. DMAXGE=xpetit
  568. DO 378 I=1,INC
  569. ** write (6,*) ' assem2 diag vmav ',diag(i),vmax(i)
  570. ** vmax(i)=max(vmax(i),abs(diag(i)))
  571. DMAXGE=MAX(DMAXGE,abs(vmax(i)))
  572. 378 CONTINUE
  573. if (iimpi.ne.0 )
  574. > write (6,*) ' nb inconnues facteur multiplicatif general ',
  575. > INC,DMAXGE
  576. if (dmaxge.lt.xpetit/xzprec*10) dmaxge=1.d0
  577. IENMU=0
  578. C ... ATTENTION ! Ici commence une boucle cachée (exécutée avec un GOTO 375) ...
  579. 375 IENMU1 = IENMU
  580. IENMU=0
  581. C ... Boucle sur les rigidités qui calcule le nombre de matrices de blocages ...
  582. DO 376 I=1,NNR
  583. IF(.NOT.INOMUL(I)) IENMU=IENMU+1
  584. 376 CONTINUE
  585. C ... S'il n'y en a pas on saute cette partie du code ...
  586. IF( IENMU.EQ.0) GO TO 3750
  587. C ... MIMIK contient les noms des variables primales ...
  588. MIMIK=IIMIK
  589. SEGACT,MIMIK
  590. C ... Boucle sur les rigidités ...
  591. DO 11 I=1,NNR
  592. C ... Si celle si n'est pas une matrice de blocage on passe à la suivante ...
  593. IF(INOMUL(I)) GO TO 11
  594. DESCR=IRIGEL(3,I)
  595. C ... N3 = nb de variables primales ...
  596. N3=LISINC(/2)
  597. COER=COERIG(I)
  598. MELEME=IRIGEL(1,I)
  599. INCTRA=INCTRR(I)
  600. xMATRI=IRIGEL(4,I)
  601. C ... N2 = nombre d'éléments dans le support géométrique ...
  602. N2=NUM(/2)
  603. C ... À quoi correspond ce cas ? (pas de matrices élémentaires) ...
  604. IF (re(/3).EQ.0) THEN
  605. INOMUL(I)=.TRUE.
  606. GOTO 11
  607. ENDIF
  608. C XMATRI=IMATTT(1)
  609. C SEGACT,XMATRI
  610. C ... N1 = nombre de variables duales ...
  611. C ... Pourquoi va-t-on chercher N3 dans DESCR et N1 dans RE ? ...
  612. N1=RE(/1)
  613. SEGINI,RA
  614. C ... Boucle sur les éléments ...
  615. DO 14 IEL=1,N2
  616. C ... Boucle sur les inconnues ...
  617. DO 15 ICO=1,N3
  618. C ... IJA = N° local du noeud-support de l'inconnue N° ICO ...
  619. IJA=INUINV(NUM(NOELEP(ICO),IEL))
  620. C ... IJB = N° de l'inconnue ...
  621. IJB=INCTRA(ICO)
  622. C ... IVAL contient la correspondance entre le N° local du DDL
  623. C et le N° d'équation (de ligne) correspondant ...
  624. IVAL(ICO)=INCPO(IJB,IJA)
  625. 15 CONTINUE
  626. C JCARDO => pour les fous qui veulent se passer de la
  627. C normalisation des mult. de Lagrange :)
  628. IF (INORMU.EQ.0) THEN
  629. DMAX=1.D0
  630. DMAXY=DMAX
  631. ELSE
  632. DDDD= xpetit
  633. C ... DMAX = max des valeurs absolues des termes diagonaux correspondants
  634. C au DDL de l'élément N° IEL ...
  635. DMAX=xpetit
  636. IF((.NOT.LDIAG).AND.(IDIAG.EQ.0)) THEN
  637. C write(*,*) 'Erreur interne dans LDMT2 : MDIAG pas encore',
  638. C & ' initialisé !!!'
  639. RETURN
  640. ENDIF
  641. * la boucle suivante demarre 3 car les deux premiers sont les multiplicateurs de lagrange
  642. DO 19 ICO=3,N3
  643. DMAX=MAX(DMAX,vmax(IVAL(ICO)),abs(diag(ival(ico))))
  644. 19 CONTINUE
  645.  
  646. C ... AUX FINS D'EVITER DES PROBLEMES DANS LA DECOMPOSITION
  647. if(iimpi.eq.1524) WRITE(IOIMP,7391) DMAX,DDDD,IENMU,
  648. & IENMU1,I,IEL
  649. 7391 FORMAT(' DMAX DDDD IENMU IENMU1 I IEL',2E12.5,4I3)
  650.  
  651. IF(DMAX.LE.xpetit.AND.IENMU.NE.IENMU1
  652. & .AND.IEL.EQ.1) GOTO 377
  653. IF(DMAX.LE.xzprec*dmaxge) DMAX = DMAXGE
  654. DMAX=DMAX*1.5D0
  655. C XMATRI=IMATTT(IEL)
  656. C SEGACT,XMATRI
  657. C ... DMAXY = maximum des termes dans la première colonne (les 2 premiers exclus) ...
  658. DMAXY=sqrt(xpetit)*1d5
  659. if (norinc.eq.0) dmaxy=1.d0
  660. * demarrage a 3 aussi. On a toujours 1 -1 sur les LX
  661. DO ICO=3,N1
  662. DMAXY = MAX ( DMAXY, ABS( RE(ICO,1,iel)))
  663. enddo
  664. * demarrage a 3 aussi. On a toujours 1 -1 sur les LX
  665. DO iko=3,N3
  666. DMAXY = MAX ( DMAXY, ABS( RE(1,iko,iel)))
  667. enddo
  668. DMAX = DMAX / DMAXY
  669. * Attention
  670. * on reprend le dmax du premier passage pour appliquer le meme facteur sur les lignes et les colonnes
  671. * car le max de la ligne n'est pas forcement celui de la colinne
  672. if (.not.ldiag) dmax=dnor(ival(1))
  673. ENDIF
  674. IF( IIMPI. EQ.1524 ) WRITE(IOIMP,7398) DMAX
  675. 7398 FORMAT(' facteur multiplicatif de norme ',e12.5)
  676. C ... Copie de la matrice élémentaire fois DMAX*COER dans RA ...
  677. DO 21 ICO=1,N1
  678. DO 2110 IKO=1,N3
  679. RA(ICO,IKO)=RE(ICO,IKO,iel)*DMAX*COER
  680. 2110 CONTINUE
  681. 21 CONTINUE
  682. C ... La sous-matrice de dimension 2 est multipliée par DMAXY ...
  683. ** si on ne booste pas l'egalite des mults on a des problemes de precision sur ceux ci
  684. if (norinc.eq.0) dmaxy=dmaxy*2.d0
  685. RA(1,1)=RA(1,1)*DMAXY
  686. RA(2,1)=RA(2,1)*DMAXY
  687. RA(1,2)=RA(1,2)*DMAXY
  688. RA(2,2)=RA(2,2)*DMAXY
  689. C ... Mise à DMAX des DNOR correspondant aux multiplicateurs ...
  690. IF(LDIAG) THEN
  691. DO 22 ICO=1,2
  692. DNOR(IVAL(ICO))=DMAX
  693. ** write (6,*) 'il dnor ',ival(ico),dnor(ival(ico))
  694. mdno1.DNOR(IVAL(ICO))=DMAX
  695. 22 CONTINUE
  696. ENDIF
  697. CMB ... Je suppose que l'on s'en servira pour multiplier les composantes
  698. C du second membre pour que les déplacements imposés soient corrects ...
  699. C ... Boucle sur les variables primales ...
  700. ** write(6,*) 'ldmt2 trsup ',trsup
  701. DO 24 ICO=1,N3
  702. C ... INO = N° local du noeud ...
  703. INO=INUINV(NUM(NOELEP(ICO),IEL))
  704. C ... IO = N° de ligne du DDL N° ICO ...
  705. IO=IVAL(ICO)
  706. if (ico.eq.1) io1=io
  707. if (ico.eq.2) io2=io
  708. C ... LLIGN contient les lignes liées aux noeud INO ...
  709. LLIGN=ILIGN(INO)
  710. SEGACT,LLIGN*MOD
  711. C ... On rajoute le terme diagonal au DIAG ...
  712. IF(LDIAG) DIAG(IO)=DIAG(IO)+RA(ICO,ICO)
  713. C ... IMMMM contient les N°s des lignes des DDL ...
  714. DO 132 JLIJ=1,IMMMM(/1)
  715. JLIJ1=JLIJ
  716. C ... On est censé trouver le bon N° de ligne et aller au 133 ...
  717. IF( IMMMM(JLIJ).EQ.IO) GO TO 133
  718. 132 CONTINUE
  719. IF(IIMPI.EQ.1524) WRITE(IOIMP,7354)
  720. 7354 FORMAT( ' PREMIERE ERREUR 5')
  721. CALL ERREUR(5)
  722. RETURN
  723. 133 CONTINUE
  724. C ... Deuxième niveau de boucle sur les variables primales ...
  725. DO 26 IRO=1,N1
  726. C ... IA = N° de colonne du DDL N° IRO ...
  727. IA=IVAL(IRO)
  728. C ... Cas symétrique !!! ...
  729. IF(IA.GT.IO) GO TO 26
  730. C ... JLD et JLT sont égaux au début et à la fin (dans XXVA et LINC)
  731. C des données relatives au DDL N° IRO ...
  732. JLT=IPPO(JLIJ1+1)
  733. JLD=IPPO(JLIJ1)+1
  734. C ... On cherche le bon N° de colonne dans LINC ...
  735. DO 134 JL=JLD,JLT
  736. JL1=JL
  737. IF(LINC(JL).EQ.IA) GO TO 135
  738. 134 CONTINUE
  739. IF(IIMPI.EQ.1524) WRITE(IOIMP,7355)
  740. 7355 FORMAT( ' DEUXIEME ERREUR 5')
  741. CALL ERREUR(5)
  742. RETURN
  743. 135 CONTINUE
  744. C ... On rajoute le coefficient dans RA au XXVA correspondant ...
  745. if(.not.trsup) then
  746. XXVA(JL1)=XXVA(JL1)+RA(ICO,IRO)
  747. else
  748. XXVA(JL1)=XXVA(JL1)+RA(IRO,ICO)
  749. endif
  750. 26 CONTINUE
  751. SEGDES,LLIGN
  752. 24 CONTINUE
  753. C on stocke dans ittr les couples de LX
  754. ittr(io1)=io2
  755. ittr(io2)=io1
  756. C SEGDES,XMATRI
  757. 14 CONTINUE
  758. C ... Après son assemblage, une matrice de blocage n'est plus stigmatisée comme telle ...
  759. INOMUL(I)=.TRUE.
  760. 377 CONTINUE
  761. SEGSUP,RA
  762. 11 CONTINUE
  763. C ... Fin de la boucle sur les rigidités ...
  764. GO TO 375
  765. C ... Fin de la boucle cachée ...
  766. 3750 CONTINUE
  767. ** do i = 1,inc
  768. ** if (ittr(i).eq.0.and.diag(i).ne.vmax(i))
  769. ** > write (6,*) 'diag vmax ',i,diag(i),vmax(i)
  770. ** enddo
  771. C ... C'est l'ménaage finaale ...
  772. DO 18 IK=1,NNR
  773. INCTRA=INCTRR(IK)
  774. IF(MENAGE) THEN
  775. SEGSUP,INCTRA
  776. ELSE
  777. SEGDES,INCTRA
  778. ENDIF
  779. 18 CONTINUE
  780. C PV ON DESACTIVE TOUT
  781. NNR=IRIGEL(/2)
  782. DO 2 IRI=1,NNR
  783. DESCR=IRIGEL(3,IRI)
  784. SEGDES DESCR
  785. IPT1=IRIGEL(1,IRI)
  786. * SEGDES IPT1
  787. xMATRI=IRIGEL(4,IRI)
  788. SEGDES xMATRI
  789. 2 CONTINUE
  790.  
  791. INTERR(1)=NJTOT
  792. c-old IF(IPASG.EQ.0) CALL ERREUR(-278)
  793. IF(MENAGE.AND.IPASG.EQ.0) CALL ERREUR(-278)
  794. IPASG=1
  795.  
  796. IF(IIMPI.EQ.1457) WRITE(IOIMP,4821) LLVNUL,NJTOT
  797. 4821 FORMAT(' NB DE VALEURS NON NULLES DANS LA MATRICE ',I9,/
  798. & ' NB DE VALEURS DANS LA MATRICE ',I9)
  799. SEGSUP,IITOP,ITOPO
  800. IF(MENAGE) THEN
  801. C SEGSUP,IITOP
  802. ccc SEGSUP,IMINI
  803. SEGSUP,INUINV
  804. C SEGSUP,ITOPO
  805. SEGSUP,INCTRR,INCTRD
  806. ELSE
  807. C SEGDES,IITOP
  808. ccc SEGDES,IMINI
  809. c SEGDES,INUINV
  810. C SEGDES,ITOPO
  811. c SEGDES,INCTRR
  812. ENDIF
  813. IF (MENAGE) THEN
  814. segact mrigid*mod
  815. NNR=IRIGEL(/2)
  816. DO IRI=1,NNR
  817. IPT2=IRIGEL(2,IRI)
  818. IF (IPT2.NE.0) THEN
  819. SEGSUP IPT2
  820. IRIGEL(2,IRI)=0
  821. ENDIF
  822. ENDDO
  823. segact mrigid*nomod
  824. ENDIF
  825. C write(6,*) ' diag'
  826. C write(6,*) ( diag(iou),iou=1,diag(/1))
  827. SEGDES,MDIAG
  828. SEGDES,MIMIK
  829. IF (MDNOR.NE.0) SEGDES,MDNOR
  830. SEGDES,MILIGN
  831. SEGDES,MMATRI
  832. MMMTRI=MMATRI
  833. SEGDES,MINCPO
  834. SEGDES,MIPO1
  835. SEGDES,IPOS
  836. SEGSUP,IVAL,ITRA,JNOMUL,vmax
  837. IF(NORINC.NE.0 .AND. MENAGE) THEN
  838. CALL ASSEM0(MRIGID,2,inwuit)
  839. SEGDES,MRIGID
  840. ELSE
  841. SEGDES,MRIGID
  842. ENDIF
  843. RETURN
  844. END
  845.  
  846.  

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