tens1
C TENS1 SOURCE GOUNAND 24/09/27 21:15:21 12020 SUBROUTINE TENS1(ICHA,TYCHA,MLMOTS,IOTENS,ICHA1) IMPLICIT REAL*8 (A-H,O-Z) IMPLICIT INTEGER (I-N) C*********************************************************************** C NOM : TENS1 C DESCRIPTION : Opérations sur des tenseurs (unaires pour l'instant) C C C C LANGAGE : ESOPE C AUTEUR : Stephane GOUNAND (CEA/DES/ISAS/DM2S/SEMT/LTA) C mel : gounand@semt2.smts.cea.fr C*********************************************************************** C APPELES : C APPELES (E/S) : C APPELES (BLAS) : C APPELES (CALCUL) : C APPELE PAR : C*********************************************************************** C SYNTAXE GIBIANE : C ENTREES : C ENTREES/SORTIES : C SORTIES : C*********************************************************************** C VERSION : v1, 28/08/2024, version initiale C HISTORIQUE : v1, 28/08/2024, creation C HISTORIQUE : C HISTORIQUE : C*********************************************************************** -INC PPARAM -INC CCOPTIO -INC CCREEL -INC SMCHPOI -INC SMCHAML -INC SMLMOTS -INC TMTRAV SEGMENT MTRAV1.MTRAV SEGMENT MTRCML REAL*8 CC(NNIN,N1PTEL,N1EL) ENDSEGMENT CHARACTER*8 TYCHA,CCCOMP * C ENTREEES C A(3,3) = MATRICE A DIAGONALISER C SORTIES C D(3) = VALEURS PROPRES D(1) > D(2) ET D(3)=A(3,3) C R(3,3) = RESULTAT DES OPERATIONS TENSORIELLES DIMENSION A(3,3),D(3),R(3,3) DIMENSION IDXSYM(3,3,3) DIMENSION IDXGEN(3,3,3) DIMENSION INVSYM(2,6,3) DIMENSION INVGEN(2,9,3) DATA ((A(I,J),I=1,3),J=1,3) /9*0.D0/ DATA (D(I),I=1,3) /3*0.D0/ DATA ((R(I,J),I=1,3),J=1,3) /9*0.D0/ DATA (((IDXSYM(I,J,K),I=1,1),J=1,1),K=1,1) /1/ DATA (((IDXSYM(I,J,K),I=1,2),J=1,2),K=2,2) /1,2,2,3/ DATA (((IDXSYM(I,J,K),I=1,3),J=1,3),K=3,3) /1,2,4,2,3,5,4,5,6/ DATA (((IDXGEN(I,J,K),I=1,1),J=1,1),K=1,1) /1/ DATA (((IDXGEN(I,J,K),I=1,2),J=1,2),K=2,2) /1,2,3,4/ DATA (((IDXGEN(I,J,K),I=1,3),J=1,3),K=3,3) /1,2,3,4,5,6,7,8,9/ * DATA (((INVSYM(I,J,K),I=1,2),J=1,1),K=1,1) /1,1/ DATA (((INVSYM(I,J,K),I=1,2),J=1,3),K=2,2) /1,1,2,1,2,2/ DATA (((INVSYM(I,J,K),I=1,2),J=1,6),K=3,3) $ /1,1,2,1,2,2,3,1,3,2,3,3/ DATA (((INVGEN(I,J,K),I=1,2),J=1,1),K=1,1) /1,1/ DATA (((INVGEN(I,J,K),I=1,2),J=1,4),K=2,2) /1,1,1,2,2,1,2,2/ DATA (((INVGEN(I,J,K),I=1,2),J=1,9),K=3,3) $ /1,1,1,2,1,3,2,1,2,2,2,3,3,1,3,2,3,3/ * * DATA MOTENS/'NORM2','NORMINF','DET','TRACE','INVE','IDEN','LOG' * ,'EXP','INVS','ABS','SPECTRAL'/ * * Executable statements * SEGACT MLMOTS * Cas entrée scalaire ou vecteur, symétrique, ordre 2, général IF (NCOMP.EQ.1) THEN IKAS=1 ELSEIF (NCOMP.EQ.IDIM) THEN IKAS=2 ELSEIF (NCOMP*2.EQ.IDIM*(IDIM+1)) THEN IKAS=3 ELSEIF (NCOMP.EQ.IDIM*IDIM) THEN IKAS=4 ELSE GOTO 9997 ENDIF * Nombre de composantes du résultat IF (IOTENS.GE.1.AND.IOTENS.LE.4) THEN NCOM1=1 ELSEIF (IOTENS.EQ.11) THEN NCOM1=IDIM*(IDIM+1) ELSE NCOM1=NCOMP ENDIF IF (TYCHA.EQ.'CHPOINT ') THEN MCHPOI=ICHA * Transformation du CHPOINT entré en objet de travail IF (IERR.NE.0) RETURN SEGACT MTRAV*MOD NNNOE=IGEO(/1) IF (NCOM1.NE.NCOMP) THEN NNIN=NCOM1 SEGINI MTRAV1 IF (NCOM1.EQ.1) THEN MTRAV1.NHAR(1)=NHAR(1) ELSEIF (IOTENS.EQ.11) THEN ICMP=0 CCCOMP='SI' DO i=1,IDIM WRITE(CCCOMP(3:3),FMT='(I1)') I WRITE(CCCOMP(4:4),FMT='(I1)') I ICMP=ICMP+1 MTRAV1.NHAR(ICMP)=NHAR(1) ENDDO CCCOMP='CO' DO i=1,IDIM WRITE(CCCOMP(4:4),FMT='(I1)') I DO j=1,IDIM WRITE(CCCOMP(3:3),FMT='(I1)') J ICMP=ICMP+1 MTRAV1.NHAR(ICMP)=NHAR(1) ENDDO ENDDO ELSE write(ioimp,*) 'CHPO COMP ncom1=',ncom1,' ????' goto 9999 ENDIF DO INNOE=1,NNNOE MTRAV1.IGEO(INNOE)=IGEO(INNOE) ENDDO ENDIF ELSEIF (TYCHA.EQ.'MCHAML') THEN MCHELM=ICHA NOID=1 * Extrayons les composantes intéressantes IF (IERR.NE.0) RETURN SEGACT,MCHEL1*MOD ELSE GOTO 9998 ENDIF * segprt,mtrav * * write(ioimp,*) 'IOTENS=',IOTENS * * Un peu de gestion d'erreur avant la boucle... * * Seuls NORM2 et NORMINF disponibles pour les vecteurs IF (IKAS.EQ.2.AND.IOTENS.GT.2) THEN RETURN ENDIF MOTERR(1:8)=TYCHA * * La boucle sur les noeuds ou les éléments : on pourra paralléliser ici * IF (TYCHA.EQ.'CHPOINT ') THEN DO INNOE=1,NNNOE * Remplissage des tableaux de travail IF (IKAS.EQ.1.OR.IKAS.EQ.2) THEN DO I=1,NCOMP A(I,1)=BB(I,INNOE) ENDDO ELSEIF (IKAS.EQ.3) THEN DO J=1,IDIM DO I=1,IDIM A(I,J)=BB(IDXSYM(I,J,IDIM),INNOE) ENDDO ENDDO ELSEIF (IKAS.EQ.4) THEN DO J=1,IDIM DO I=1,IDIM A(I,J)=BB(IDXGEN(I,J,IDIM),INNOE) ENDDO ENDDO ELSE write(ioimp,*) 'ikas=',ikas,' ????' MOTERR(1:8)='TENS1' return endif * On prépare le message d'erreur 49 en cas de déterminant nul pour * l'inversion d'une matrice... IF (IOTENS.EQ.5) INTERR(1)=IGEO(INNOE) * * Faire les opérations tensorielles * CALL TENS2(IOTENS,IKAS,A,D,R) IF (IERR.NE.0) RETURN * IF (NCOM1.NE.NCOMP) THEN IF(NCOM1.EQ.1) THEN MTRAV1.BB(1,INNOE)=R(1,1) MTRAV1.IBIN(1,INNOE)=1 ELSEIF (IOTENS.EQ.11) THEN ICMP=0 DO i=1,IDIM ICMP=ICMP+1 MTRAV1.BB(ICMP,INNOE)=D(i) MTRAV1.IBIN(ICMP,INNOE)=1 ENDDO DO i=1,IDIM DO j=1,IDIM ICMP=ICMP+1 MTRAV1.BB(ICMP,INNOE)=R(j,i) MTRAV1.IBIN(ICMP,INNOE)=1 ENDDO ENDDO ELSE write(ioimp,*) 'CHPO VAL ncom1=',ncom1,' ????' goto 9999 ENDIF ELSE IF (IKAS.EQ.1.OR.IKAS.EQ.2) THEN DO I=1,NCOMP BB(I,INNOE)=R(I,1) IBIN(I,INNOE)=1 ENDDO ELSEIF (IKAS.EQ.3) THEN DO ICOMP=1,NCOMP I=INVSYM(1,ICOMP,IDIM) J=INVSYM(2,ICOMP,IDIM) BB(ICOMP,INNOE)=R(I,J) IBIN(ICOMP,INNOE)=1 ENDDO ELSEIF (IKAS.EQ.4) THEN DO ICOMP=1,NCOMP I=INVGEN(1,ICOMP,IDIM) J=INVGEN(2,ICOMP,IDIM) BB(ICOMP,INNOE)=R(I,J) IBIN(ICOMP,INNOE)=1 ENDDO ELSE write(ioimp,*) 'ikas=',ikas,' ????' goto 9999 endif ENDIF * Fin de la boucle sur les noeuds ENDDO * segprt,mtrav ELSEIF (TYCHA.EQ.'MCHAML ') THEN N1=ICHAML(/1) DO I1=1,N1 MCHAML=ICHAML(I1) SEGACT MCHAML N2=IELVAL(/1) IF (N2.NE.NCOMP) THEN * Composante inexistante RETURN ENDIF N1EL=0 N1PTEL=0 N2EL=0 N2PTEL=0 IF (TYPCHE(I1).NE.'REAL*8') THEN MOTERR(1:8)='MCHAML' MOTERR(9:16)=TYPCHE(I1) * 131 2 On n'attend pas un objet de type %m1:8 de sous-type %m9:16 RETURN ENDIF SEGACT MELVAL N1EL=MAX(N1EL,VELCHE(/2)) N1PTEL=MAX(N1PTEL,VELCHE(/1)) ENDDO IF (NCOM1.EQ.NCOMP) THEN SEGINI,MCHAM1=MCHAML ELSE N2=NCOM1 SEGINI,MCHAM1 IF(NCOM1.EQ.1) THEN MCHAM1.NOMCHE(1)='SCAL' MCHAM1.TYPCHE(1)='REAL*8' ELSEIF (IOTENS.EQ.11) THEN ICMP=0 CCCOMP='SI' DO i=1,IDIM ICMP=ICMP+1 WRITE(CCCOMP(3:3),FMT='(I1)') I WRITE(CCCOMP(4:4),FMT='(I1)') I ICMP=ICMP+1 MCHAM1.NOMCHE(ICMP)=CCCOMP MCHAM1.TYPCHE(ICMP)='REAL*8' ENDDO CCCOMP='CO' DO i=1,IDIM WRITE(CCCOMP(4:4),FMT='(I1)') I DO j=1,IDIM WRITE(CCCOMP(3:3),FMT='(I1)') J ICMP=ICMP+1 MCHAM1.NOMCHE(ICMP)=CCCOMP MCHAM1.TYPCHE(ICMP)='REAL*8' ENDDO ENDDO ELSE write(ioimp,*) 'CHAM COMP ncom1=',ncom1,' ????' goto 9999 ENDIF ENDIF NNIN=NCOMP SEGINI MTRCML J1PTEL=VELCHE(/1) J1EL=VELCHE(/2) DO I1EL=1,N1EL DO I1PTEL=1,N1PTEL $ ,MIN(I1EL,J1EL)) ENDDO ENDDO ENDDO * DO I1EL=1,N1EL DO I1PTEL=1,N1PTEL * Remplissage des tableaux de travail IF (IKAS.EQ.1.OR.IKAS.EQ.2) THEN DO I=1,NCOMP A(I,1)=CC(I,I1PTEL,I1EL) ENDDO ELSEIF (IKAS.EQ.3) THEN DO J=1,IDIM DO I=1,IDIM A(I,J)=CC(IDXSYM(I,J,IDIM),I1PTEL,I1EL) ENDDO ENDDO ELSEIF (IKAS.EQ.4) THEN DO J=1,IDIM DO I=1,IDIM A(I,J)=CC(IDXGEN(I,J,IDIM),I1PTEL,I1EL) ENDDO ENDDO ELSE write(ioimp,*) 'ikas=',ikas,' ????' GOTO 9999 endif * * Faire les opérations tensorielles * CALL TENS2(IOTENS,IKAS,A,D,R) IF (IERR.NE.0) RETURN * IF (NCOM1.NE.NCOMP) THEN IF(NCOM1.EQ.1) THEN CC(1,I1PTEL,I1EL)=R(1,1) ELSEIF (IOTENS.EQ.11) THEN ICMP=0 DO i=1,IDIM ICMP=ICMP+1 CC(ICMP,I1PTEL,I1EL)=D(i) ENDDO DO i=1,IDIM DO j=1,IDIM ICMP=ICMP+1 CC(ICMP,I1PTEL,I1EL)=R(j,i) ENDDO ENDDO ELSE write(ioimp,*) 'CHAM VAL ncom1=',ncom1,' ????' goto 9999 ENDIF ELSE IF (IKAS.EQ.1.OR.IKAS.EQ.2) THEN DO I=1,NCOMP CC(I,I1PTEL,I1EL)=R(I,1) ENDDO ELSEIF (IKAS.EQ.3) THEN DO ICOMP=1,NCOMP I=INVSYM(1,ICOMP,IDIM) J=INVSYM(2,ICOMP,IDIM) CC(ICOMP,I1PTEL,I1EL)=R(I,J) ENDDO ELSEIF (IKAS.EQ.4) THEN DO ICOMP=1,NCOMP I=INVGEN(1,ICOMP,IDIM) J=INVGEN(2,ICOMP,IDIM) CC(ICOMP,I1PTEL,I1EL)=R(I,J) ENDDO ELSE write(ioimp,*) 'ikas=',ikas,' ????' goto 9999 endif ENDIF * Fin de la boucle sur les noeuds et éléments ENDDO * Fin de la boucle sur les éléments ENDDO SEGINI MELVA1 DO I1EL=1,N1EL DO I1PTEL=1,N1PTEL ENDDO ENDDO ENDDO SEGSUP MTRCML MCHEL1.ICHAML(I1)=MCHAM1 * Fin de la boucle sur les sous-zones ENDDO ELSE GOTO 9998 ENDIF * * Transformation des objets de travail en champs * IF (TYCHA.EQ.'CHPOINT ') THEN IF (NCOM1.NE.NCOMP) THEN * Le résultat est dans MTRAV1 SEGSUP MTRAV1 ELSE ENDIF SEGSUP MTRAV ICHA1=MCHPO1 ELSEIF (TYCHA.EQ.'MCHAML ') THEN ICHA1=MCHEL1 ELSE GOTO 9998 ENDIF * * Normal termination * RETURN * * Format handling * * * Error handling * 9997 CONTINUE * 980 2 * L'objet %m1:8 n'a pas le bon nombre de composantes MOTERR(1:8)='LISTMOTS' RETURN 9998 CONTINUE * On ne veut pas d'objet de type %m1:8 MOTERR(1:8)=TYCHA RETURN 9999 CONTINUE MOTERR(1:8)='TENS1' return * * End of subroutine TENS1 * END
© Cast3M 2003 - Tous droits réservés.
Mentions légales