numopt
C NUMOPT SOURCE GOUNAND 25/05/15 21:15:10 12268
C RACINE DE LA NUMEROTATION POUR LA SORTIE SUR FAC
C
IMPLICIT INTEGER(I-N)
-INC PPARAM
-INC CCOPTIO
-INC CCPRECO
-INC SMELEME
-INC SMCOORD
CHARACTER*4 MVAL
DATA MVAL/'NOOP'/
SEGMENT MEMJT1(NKON)
SEGMENT MEMJT2(NKON)
SEGMENT IPOME(NODES+1)
SEGMENT JNT(NODES)
SEGMENT JMEM(NODES)
SEGMENT ICPR(nbpts)
SEGMENT ICPREN(nbpts)
SEGMENT IDCP(nbpts)
SEGMENT JOINT(NODES)
SEGMENT NEWJT(NODES)
icpren=0
segact meleme
* cas trivial ou le maillage est fait de points isoles
itypto=0
ipt1=meleme
do k=1,max(1,lisous(/1))
if (lisous(/1).ne.0) ipt1=lisous(k)
segact ipt1
itypto = itypto+ipt1.itypel-1
enddo
if (itypto.eq.0.or.iret.eq.1.or.nucrou.eq.-1) then
segact icpr*MOD
ia=0
ipt1=meleme
do k=1,max(1,lisous(/1))
if (lisous(/1).ne.0) ipt1=lisous(k)
segact ipt1
do j= ipt1.num(/2),1,-1
do i=1,ipt1.num(/1)
if (icpr(ipt1.num(i,j)).eq.0) then
ia=ia+1
icpr(ipt1.num(i,j))=ia
endif
enddo
enddo
enddo
nodes=ia
return
endif
nucro=0
* si plus de 4000 noeuds dans le meleme numérotation NS
segact icpr*mod
do i=1,icpr(/1)
icpr(i)=0
enddo
ia=0
ib=0
ipd=0
ipt1=meleme
ifrot=0
do 60 isous=1,max(1,lisous(/1))
if (lisous(/1).ne.0) ipt1=lisous(isous)
segact ipt1
if (ipt1.itypel.eq.-49) then
* write (6,*) ' frottement '
ifrot=1
endif
NBNN1=ipt1.num(/1)
NBEL1=ipt1.num(/2)
do i=1,NBEL1
do j=1,NBNN1
iel1=ipt1.num(j,i)
if (icpr(iel1).eq.0) then
ia=ia+1
icpr(iel1)=ia
endif
enddo
enddo
if (NBNN1.gt.ib .AND. NBEL1.GT.0.and.abs(ipt1.itypel).ne.49)
$ then
ib=NBNN1
ipd=icpr(ipt1.num(1,1))
endif
60 continue
if (ia.lt.ib*2 .and.ia.gt.100) then
** write (6,*) ' superelement detecte ',ia,ib
ia=1
else
ipd=0
endif
do i=1,icpr(/1)
icpr(i)=0
enddo
* choix de la numerotation en fonction du nombre de noeuds
** write(6,*) ' numopt ia ',ia
if (ia.gt.4000) nucro=2
if (ia.le.4000) nucro=0
* Reverse CM en iteratif
IF(NUCROU.EQ.1) nucro=0
IF(NUCROU.EQ.2) nucro=2
IF(NUCROU.EQ.3) nucro=3
* en cas de frottement forcément nested dissection pour placer correctement les mult de frot
* if (ifrot.eq.1) nucro=2
* ajuster le nombre de zero consecutif
if (nucro.eq.0) izrosf=16
if (nucro.eq.2) izrosf=48
if(ipd.ne.0) izrosf=48
if (iret.eq.0) then
* a t'on deja fait l'operation ???
segini icpren,idcp
incren=0
do isous=2,lisous(/1)
ipt3=lisous(isous)
segact ipt3
* SG 2011/10/07 on a échangé l'ordre des boucles pour le remettre dans
* l'ordre "usuel"
do j=1,ipt3.num(/2)
do i=1,ipt3.num(/1)
ip=ipt3.num(i,j)
if (icpren(ip).eq.0) then
incren=incren+1
icpren(ip)=incren
endif
enddo
enddo
enddo
do i=1,icpren(/1)
if (icpren(i).ne.0) idcp(icpren(i))=i
enddo
do 150 ip=1,npreco
if (prenum(ip).ne.0) then
ipt1=prenum(ip)
segact ipt1
* write (6,*) ' prenum ',ip,lisous(/1),ipt1.lisous(/1)
if (lisous(/1)+1.eq.ipt1.lisous(/1)) then
*SG Attention ! On a osé stocker le type de renumérotation qui avait été
*SG calculée dans le itypel
ipt2=ipt1.lisous(ipt1.lisous(/1))
segact ipt2
nucroa=ipt2.itypel
segdes ipt2
if (nucro.ne.nucroa) goto 11
* verif maillage identique
* write (6,*) ' maillage 1 ',lisous(/1)
* write (6,*) ' maillage 2 ',ipt1.lisous(/1)
do isous=2,lisous(/1)
ipt3=lisous(isous)
ipt4=ipt1.lisous(isous)
segact ipt3,ipt4
* write (6,*) ipt3.num(/1),ipt4.num(/1),ipt3.num(/2),ipt4.num(/2)
* write (6,*) ' itypel ',ipt3.itypel,ipt4.itypel
if (ipt3.itypel.ne.ipt4.itypel) goto 10
if (ipt3.num(/1).ne.ipt4.num(/1)) goto 10
if (ipt3.num(/2).ne.ipt4.num(/2)) goto 10
* SG 2011/10/07 on a échangé l'ordre des boucles pour le remettre dans
* l'ordre "usuel"
do j=1,ipt3.num(/2)
do i=1,ipt3.num(/1)
* write (6,*) i,j,ipt3.num(i,j),
* > icpren(ipt3.num(i,j)),ipt4.num(i,j)
if (icpren(ipt3.num(i,j)).ne.ipt4.num(i,j))
$ goto 10
enddo
enddo
segdes ipt3,ipt4
enddo
if (iimpi.eq.2022) write (6,*)
> ' preconditionnement de la numerotation ',ip,
> (prenum(i),i=1,30)
ipt2=ipt1.lisous(ipt1.lisous(/1))
segact ipt2
segact icpr*MOD
nodes=ipt2.num(/2)
* write (6,*) ' icpr(/1),nodes ',icpr(/1),nodes
do i=1,nodes
if (idcp(ipt2.num(1,i)).ne.0) icpr(idcp(ipt2.num(1
$ ,i)))=i
enddo
ia=nodes
segdes ipt1,ipt2
* write (6,*) ' apres precond dans numopt '
* write (6,*) (icpr(i),i=1,icpr(/1))
return
10 continue
segdes ipt3,ipt4
11 continue
endif
endif
150 continue
if (nucro.eq.1) then
goto 300
elseif (nucro.eq.2) then
if (iimpi.ne.0) write(ioimp,*)
$ 'Numerotation Nested Dissection'
goto 300
elseif (nucro.eq.3) then
if (iimpi.ne.0) write(ioimp,*) 'Numerotation Sloan'
call numop3(MELEME,ICPR,NODES)
goto 300
endif
endif
NODES=nbpts
SEGACT ICPR*MOD
SEGACT MELEME
DO I=1,ICPR(/1)
ICPR(I)=0
ENDDO
IPT1=MELEME
IKOU=0
DO 202 IO=1,MAX(1,LISOUS(/1))
IF (LISOUS(/1).NE.0) THEN
IPT1=LISOUS(IO)
SEGACT IPT1
ENDIF
DO 203 J=1,IPT1.NUM(/2)
* inversion car on reinverse a la fin
DO 204 I=1,IPT1.NUM(/1)
IJ=IPT1.NUM(I,J)
IF (ICPR(IJ).NE.0) GOTO 204
IKOU=IKOU+1
ICPR(IJ)=IKOU
204 CONTINUE
203 CONTINUE
202 CONTINUE
NODES=IKOU
SEGINI JNT,JMEM,NEWJT,JOINT,IPOME
IPT1=MELEME
DO 3 IO=1,MAX(1,LISOUS(/1))
IF (LISOUS(/1).NE.0) IPT1=LISOUS(IO)
DO J=1,IPT1.NUM(/2)
DO I=1,IPT1.NUM(/1)
JMEM(ICPR(IPT1.NUM(I,J)))=JMEM(ICPR(IPT1.NUM(I,J)))+1
enddo
enddo
3 CONTINUE
IPOME(1)=0
DO 6 I=1,NODES
IPOME(I+1)=IPOME (I) + JMEM(I)
6 CONTINUE
NKON=IPOME(NODES+1)
SEGINI MEMJT1,memjt2
DO J=1,NODES
JMEM(J)=0
enddo
IPT1=MELEME
DO 102 IPASS=1,1
DO 101 IO=1,MAX(1,LISOUS(/1))
IF (LISOUS(/1).NE.0) IPT1=LISOUS(IO)
** if (ipt1.itypel.eq.-49) then
** if (ipass.eq.1) goto 101
** else
** if (ipass.eq.2) goto 101
** endif
DO I=1,IPT1.NUM(/2)
DO J=1,IPT1.NUM(/1)
IND=ICPR(IPT1.NUM(J,I))
JMEM(IND)=JMEM(IND)+1
MEMJT1(IPOME(IND)+JMEM(IND))=I
MEMJT2(IPOME(IND)+JMEM(IND))=IO
enddo
enddo
101 CONTINUE
102 CONTINUE
IDIFF=1
if (iimpi.ne.0) write(ioimp,*)
$ 'Numerotation Reverse Cuthill McKee'
# ICPR,NODES,NOOPTI,ipd,nucro)
* ne pas inverse si superelement pour conserver sa numerotation
if (ipd.eq.0) then
DO 110 I=1,NODES
JNT(I)=NODES-JNT(I)+1
110 CONTINUE
endif
C PERMUTER LES COORDONNEES ET CORRIGER IPAD
DO 111 I=1,icpr(/1)
IF (ICPR(I).EQ.0) GOTO 111
ICPR(I)=JNT(ICPR(I))
111 CONTINUE
IF(NOOPTI .EQ.0) GO TO 116
IA=0
DO 115 I=1,icpr(/1)
IF(ICPR(I).EQ.0) GO TO 115
IA=IA+1
ICPR(I)=IA
115 CONTINUE
116 CONTINUE
SEGSUP MEMJT1,MEMJT2,JMEM,NEWJT,JOINT,IPOME
SEGSUP JNT
* Mise en commentaire du return par SG car comme cela on preconditionne
* aussi le Cuthill-McKee
* RETURN
300 continue
* sauver le resultat au cas ou on veuille recommencer
segini,ipt1=meleme
nbsous=ipt1.lisous(/1)+1
nbref=ipt1.lisref(/1)
nbnn=ipt1.num(/1)
nbelem=ipt1.num(/2)
segadj ipt1
nbnn=1
nbsous=0
nbref=0
nbelem=nodes
segini ipt2
*SG Attention ! On ose stocker le type de renumérotation qui a été
*SG calculée dans le itypel
ipt2.itypel=nucro
ia=0
do 120 i=1,icpr(/1)
if (icpr(i).gt.nodes.or.icpr(i).eq.0) goto 120
ia=ia+1
ipt2.num(1,icpr(i))=icpren(i)
120 continue
* call ecmail(ipt2)
ipt1.lisous(ipt1.lisous(/1))=ipt2
segdes ipt2
do 125 is=1,ipt1.lisous(/1)-1
ipt2=ipt1.lisous(is)
segini,ipt3=ipt2
segdes ipt2
* SG 2011/10/07 on a échangé l'ordre des boucles pour le remettre dans
* l'ordre "usuel"
do il=1,ipt3.num(/2)
do ip=1,ipt3.num(/1)
ipt3.num(ip,il)=icpren(ipt3.num(ip,il))
enddo
enddo
segdes ipt3
ipt1.lisous(is)=ipt3
125 continue
if (ipt1.lisous(/1).eq.1) goto 131
segdes ipt1
do 130 ip=npreco-1,1,-1
prenum(ip+1)=prenum(ip)
130 continue
prenum(1)=ipt1
131 continue
if (icpren.ne.0) segsup icpren,idcp
segact icpr*mod
* write (6,*) ' fin de numopt '
* write (6,*) (icpr(i),i=1,icpr(/1))
*
RETURN
END
					© Cast3M 2003 - Tous droits réservés.
					Mentions légales