Anexo I: Subrutinas de material de usuario (UMAT) 145 ANEXO I-a: UMAT general usando el criterio de fractura de hueso de Cowin UMAT.f C **************************************************** C SUBRUTINA DE MATERIAL OSEO BASADO EN UNA LEY DE DANO C **************************************************** C SUBROUTINE UMAT(STRESS,STATEV,DDSDDE,SSE,SPD,SCD, 1RPL,DDSDDT,DRPLDE,DRPLDT, 2STRAN,DSTRAN,TIME,DTIME,TEMP,DTEMP,PREDEF,DPRED,CMNAME, 3NDI,NSHR,NTENS,NSTATV,PROPS,NPROPS,COORDS,DROT,PNEWDT, 4CELENT,DFGRD0,DFGRD1,NOEL,NPT,LAYER,KSPT,KSTEP,KINC) C INCLUDE 'ABA_PARAM.INC' C PARAMETER (EPS=1E-7) CHARACTER*8 CMNAME DIMENSION STRESS(NTENS), STATEV(NSTATV), 1DDSDDE(NTENS,NTENS),DDSDDT(NTENS),DRPLDE(NTENS), 2STRAN(NTENS),DSTRAN(NTENS),TIME(2),PREDEF(1),DPRED(1), 3PROPS(NPROPS),COORDS(3),DROT(3,3),DFGRD0(3,3),DFGRD1(3,3) C real*8 H(3,3),d(6,6),Hdot(3,3),Hcuadrado(3,3) dimension smat(3,3),defmat(3,3),stran2(NTENS) real*8 Yform(3,3),Yresor(3,3),Yresorinver(3,3) real*8 flag,aux,invers,kappa real*8 emexp,rho0,rhoc,psicAS,ratecon1,ratecon2,ratecon3,ratecon4 real*8 beta,factorB,factorA,rhoi,gform,gresor integer i, j, nsd real*8 rho_inicial real*8 EPS2,width,cycles,rhot real*8 rho,young,pois0 real*8 dano C nsd = 3 rho = props(1) young = props(2) pois0 = props (3) do i=1,3 do j=1,3 H(i,j)=0.0 Hcuadrado(i,j)=0.0 Hdot(i,j)=0.0 smat(i,j)=0.0 defmat(i,j)=0.0 Yresor(i,j)=0.0 Yresorinver(i,j)=0.0 Yform(i,j)=0.0 enddo enddo gform=0.0 gresor=0.0 dano=0.0 rho_inicial=rho H(1,1)=1.0 H(2,2)=1.0 H(3,3)=1.0 C ... 146 C ... C Se convierten las tensiones y las deformaciones en forma matricial call smatrix(smat,stress,ntens,ndi,nshr) stran2(1)=stran(1) stran2(2)=stran(2) stran2(3)=stran(3) stran2(4)=stran(4)/2. stran2(5)=stran(5)/2. stran2(6)=stran(6)/2. C Idem para formar la matriz de deformacion call smatrix(defmat,stran2,ntens,ndi,nshr) C Al no tener remodelación, la densidad va ser siempre la misma statev(1)=rho C--------------------------------------------------------------------------C LLAMAMOS A LA SUBRUTINA CRITERIO DE FRACTURA. EN ESTE CASO EL CRITERIO QUE C USAMOS ES EL DE COWIN, PERO TAMBIÉN LO HEMOS HECHO PARA EL CASO DEL C CRITERIO DE TENSIÓN MÁXIMA. ASÍ OBTENDREMOS EL DAÑO. C--------------------------------------------------------------------------call criterio_fractura(nsd,stress,ntens,ndi,nshr,props, 1nprops,statev,nstatev,H,rhot,noel,dano) C Asignamos a la statev(5) el dano calculado en criterio_fractura if (dano.lt.0.99) then statev(5)=dano else statev(5)=0.99 endif C SE EVALÚA LA MATRIZ DE RIGIDEZ call evaluadn(d,H,nsd,ntens,ndi,nshr,props,nprops,noel,dano) eps2=1E-17 flag = INVERS(6,d,eps2,-1) if (flag.le.0.0) then endif C UTILIZAMOS LA MATRIZ DE RIGIDEZ PARA EVALUAR LA NUEVA TENSIÓN do i=1,ntens stress(i) = 0. do j=1,ntens stress(i)=stress(i)+d(i,j)*(stran(j)+dstran(j)) enddo enddo C DEVUELVE LA MATRIZ TANGENTE do i=1,ntens do j=1,ntens ddsdde(i,j) = d(i,j) enddo enddo C print*,'AVISO 7' C CONSTRUIMOS EL VECTOR DE LA ENERGIA ESPECÍFICA DE DEFORMACIÓN sse=0.0 do i=1,ntens sse=sse+0.5*stress(i)*(stran(i)+dstran(i)) enddo C print*,'AVISO 8' return end C---------------------------------------------------------------------------C FIN DEFINICIÓN UMAT, AHORA SE DEFINEN LAS FUNCIONES Y LAS SUBRUTINAS USADAS C---------------------------------------------------------------------------C ... 147 C ... C-----------------------------C DEFINIMOS LA FUNCIÓN "invers" C-----------------------------function invers (n,a,eps,indic) implicit none real*8 eps,invers,simul integer n,indic,i,j real*8 a(n,n),b(n,n) C if (n.ge.6) then invers = simul(n,a,eps,indic) else do i=1,n do j=1,n b(i,j) = a(i,j) enddo enddo invers = simul(n,b,eps,indic) do i=1,n do j=1,n a(i,j) = b(i,j) enddo enddo end if return end C C-----------------------------C DEFINIMOS LA FUNCIÓN "simul" C-----------------------------function simul (n,a,eps,indic) implicit real*8(a-h,o-z) real*8 A, eps,simul dimension irow(50), jcol(50),jord(50),y(50),a(n,n) C max=n if (indic.ge.0) max = n + 1 C C Si n es mayor de 50 C if (n.le.50) go to 5 simul = 0. return C C Comienzo del proceso de eliminacion C 5 deter = 1. do 18 k=1,n km1 = k -1 C C Busqueda del elemento-pivote C pivot = 0. do 11 i=1,n do 11 j=1,n C C ... 148 C ... C Rastreo de los conjuntos irow y jcol C para localizar subindices de pivotes no validos C if (k.eq.1) go to 9 do 8 iscan=1,km1 do 8 jscan=1,km1 if (i.eq.irow(iscan)) go to 11 if (j.eq.jcol(jscan)) go to 11 8 continue 9 if (dabs(a(i,j)).le.dabs(pivot) ) go to 11 pivot = a(i,j) irow(k) = i jcol(k) = j 11 continue C C Comprobacion de que el pivote elegido es superior que eps C if ( dabs(pivot).gt.eps ) go to 13 simul = 0. return C C Actualizacion del valor del determinante C 13 irowk = irow(k) jcolk = jcol(k) deter = deter*pivot C C Normalizacion de los elementos de la fila del pivot C do 14 j=1,max 14 a(irowk,j) = a(irowk,j)/pivot C C Proceso de eliminacion y desarrollo de la inversa C a(irowk,jcolk) = 1./pivot do 18 i=1,n aijck = a(i,jcolk) if (i.eq.irowk) go to 18 a(i,jcolk) = -aijck/pivot do 17 j=1,max 17 if (j.ne.jcolk) a(i,j) = a(i,j) - aijck*a(irowk,j) 18 continue C C Reordenar los valores de la solucion C (si existe) y originar el conjunto jord C do 20 i=1,n irowi = irow(i) jcoli = jcol(i) 20 jord(irowi) = jcoli C C ... 149 C ... C Ajuste del signo del determinante C intch = 0 nm1 = n - 1 do 22 i=1, nm1 ip1 = i + 1 do 22 j=ip1,n if (jord(j).ge.jord(i)) go to 22 jtemp = jord(j) jord(j) = jord(i) jord(i) = jtemp intch = intch + 1 22 continue if (intch/2*2.ne.intch) deter = -deter C C Si indic es positivo, devolver resultados C if (indic.le.0) go to 26 simul = deter return C C Si indic resulta ser o cero o negativo, se C reordena la inversa primero por filas C 26 do 28 j=1,n do 27 i=1,n irowi = irow(i) jcoli = jcol(i) 27 y(jcoli) = a(irowi,j) do 28 i=1,n 28 a(i,j) = y(i) C C Y luego por columnas C do 30 i=1,n do 29 j=1,n irowj = irow(j) jcolj = jcol(j) 29 y(irowj) = a(i,jcolj) do 30 j=1,n 30 a(i,j) = y(j) simul = deter return end C C ... 150 C ... C--------------------------------C DEFINIMOS LA SUBRUTINA "smatrix" C--------------------------------subroutine smatrix(stressm,stress,ntens,ndi,nshr) C implicit none integer ntens,ndi,nshr,i,j real*8 stressm(3,3),stress(ntens) do i=1,3 do j=1,3 stressm(i,j) = 0.0 enddo enddo stressm(1,1) = stress(1) stressm(2,2) = stress(2) stressm(3,3) = stress(3) stressm(1,2) = stress(4) stressm(2,1) = stress(4) C C Si hay mas de 4 terminos en el vector tension, se asume C que tenemos un 3D elemento y ponemos los 6 terminos C if (ntens.gt.4) then stressm(1,3) = stress(5) stressm(3,1) = stress(5) stressm(2,3) = stress(6) stressm(3,2) = stress(6) endif return end C C---------------------------------C DEFINIMOS LA SUBRUTINA "evaluadn" C---------------------------------subroutine evaluadn(dxyz,H,nsd,ntens,ndi,nshr,props, *nprops,noel,dano) C implicit none integer nsd,ntens,ndi,nshr,nprops,i,j,ierr,noel real*8 props(nprops) real*8 dxyz(6,6),H(3,3),d(6,6),Hxyz(3,3) real*8 eval(3),evec(3,3) real*8 young1,cexp1,cexp2,rhotrans,young2,rhoi,rhomax real*8 young0,pois0,A1,A2,A3,B12,B23,B13,C12,C23,C13 real*8 aux,rhot real*8 rho,young real*8 dano C rho = props(1) young = props(2) pois0 = props(3) do i=1,6 do j=1,6 dxyz(i,j)=0. d(i,j)=0. enddo enddo C C ... 151 C ... C do i=1,3 eval(i)=0. do j=1,3 Hxyz(i,j)=H(i,j) evec(i,j)=0. enddo enddo C call RS(3,3,Hxyz,eval,evec,ierr) if (ierr.lt.0) then endif C-----------------------------------------------------------------------C El módulo de young se irá modificando según una determinada ley de daño C que depende exclusivamente del valor que tome la variable ‘daño’. En C esta UMAT hemos tomado ésta ley de daño lineal. C-----------------------------------------------------------------------young0=(young)*(1-dano) A1=(1./young0)*(1./(eval(1)*eval(1)*eval(1)*eval(1))) A2=(1./young0)*(1./(eval(2)*eval(2)*eval(2)*eval(2))) A3=(1./young0)*(1./(eval(3)*eval(3)*eval(3)*eval(3))) B12=(-pois0/young0)*(1./(eval(1)*eval(1)*eval(2)*eval(2))) B13=(-pois0/young0)*(1./(eval(1)*eval(1)*eval(3)*eval(3))) B23=(-pois0/young0)*(1./(eval(2)*eval(2)*eval(3)*eval(3))) C12=((1+pois0)/young0)*(1./(eval(1)*eval(1)*eval(2)*eval(2))) C23=((1+pois0)/young0)*(1./(eval(3)*eval(3)*eval(2)*eval(2))) C13=((1+pois0)/young0)*(1./(eval(1)*eval(1)*eval(3)*eval(3))) C Inicializo la matriz de flexibilidad do i=1,6 do j=1,6 dxyz(i,j)=0.0 d(i,j)=0.0 enddo enddo C Evaluo la matriz de flexibilidad d(1,1)=A1 d(1,2)=B12 d(2,1)=d(1,2) d(1,3)=B13 d(3,1)=d(1,3) d(2,2)=A2 d(2,3)=B23 d(3,2)=d(2,3) d(3,3)=A3 d(4,4)=2.*C12 d(5,5)=2.*C13 d(6,6)=2.*C23 C Sustituyo los valores obtenidos do i=1,6 do j=1,6 dxyz(i,j)=d(i,j) enddo enddo return end C C ... 152 C ... C---------------------------C DEFINIMOS LA SUBRUTINA "RS" C---------------------------subroutine RS(NDIMA,N,B,EIGEN,T,ierr) C-----------------------------------------------C Se utiliza el METODO JACOBI C Donde: NDIMA=Dimension de la matriz C N = el numero de autovalores a calcular C-----------------------------------------------implicit real*8(a-h,o-z) dimension B(NDIMA,NDIMA),eigen(NDIMA),T(NDIMA,NDIMA) dimension A(6,6) dimension AIK(6) integer FLAG C ...COPIO B EN A ... do i=1,ndima do j=1,ndima A(i,j) = B(i,j) enddo enddo C ...INICIALIZA ... ITMAX = 20 EPS1 = 0.1E-5 EPS2 = 0.1E-5 EPS3 = 0.1E-5 NM1 = N - 1 ierr = 1 do i=1,NDIMA do j=1,NDIMA if (i.eq.j) then T(i,j) = 1.0 else T(i,j) = 0.0 endif enddo enddo do i=1,NDIMA EIGEN(i)=0.0 enddo C Chequeo si la matriz es la nula, porque si es así la rutina no funciona FLAG=0 do i=1,NDIMA do j=1,NDIMA if (dabs(A(i,j)).gt.0.0001) then FLAG=1 endif enddo enddo if (FLAG.EQ.0) then do i=1,NDIMA do j=1,NDIMA if (i.eq.j) then T(i,j) = 1.0 else T(i,j) = 0.0 endif enddo enddo C ... 153 C ... iter=1 GOTO 300 endif C C ....MATRIZ INICIAL T,CALCULO SIGMA1 y S.... S = 0.0 SIGMA1=0.0 OFFDSQ = 0.0 DO 50 I=1,N SIGMA1 = SIGMA1 + A(I,I)**2 T(I,I) = 1.0 IP1 = I + 1 IF (I.GE.N) GO TO 60 DO 50 J=IP1,N 50 OFFDSQ = OFFDSQ + A(I,J)**2 60 S = 2.0*OFFDSQ + SIGMA1 C C ....COMIENZO ITERACIONES JACOBI.... DO 260 ITER=1,ITMAX DO 2000 I=1,NM1 IP1 = I+1 DO 2000 J=IP1,N Q = DABS(A(I,I) - A(J,J)) C C ....CALCULO DEL SENO Y COSENO DEL ANGULO DE ROTACION ... IF (Q.LE.EPS1) GO TO 90 IF (DABS(A(I,J)).LE.EPS2) GO TO 2000 P = 2.0*A(I,J)*Q/(A(I,I)-A(J,J) ) SPQ = DSQRT(P*P + Q*Q) CSA = DSQRT((1.0+Q/SPQ)/2.0) SNA = P/(2.0*CSA*SPQ) GO TO 100 90 CSA = 1.0/DSQRT(2.0D0) SNA = CSA 100 CONTINUE C C ....ACTUALIZACION COLUMNAS I Y J DE T - EQUIVALENTE A C MULTIPLICAR POR LA MATRIZ DE ANULACION .... DO 110 K=1,N HOLDKI = T(K,I) T(K,I) = HOLDKI*CSA + T(K,J)*SNA 110 T(K,J) = HOLDKI*SNA - T(K,J)*CSA C C ....CALCULO DE NUEVOS ELEMENTOS DE A EN FILAS I Y J.... DO 160 K=I,N IF (K.GT.J) GO TO 150 AIK(K) = A(I,K) A(I,K) = CSA*AIK(K)+SNA*A(K,J) IF (K.NE.J) GO TO 140 A(J,K) = SNA*AIK(K) - CSA*A(J,K) 140 GO TO 160 150 HOLDIK = A(I,K) A(I,K) = CSA*HOLDIK + SNA*A(J,K) A(J,K) = SNA*HOLDIK - CSA*A(J,K) 160 CONTINUE C C ....CALCULO DE NUEVOS ELEMENTOS DE A EN COLUMNAS I Y J .... AIK(J) = SNA*AIK(I) - CSA*AIK(J) C ... 154 C ... C ....SI K ES MAYOR QUE I DO 190 K=1,J IF (K.LE.I) GO TO 180 A(K,J) = SNA*AIK(K) - CSA*A(K,J) GO TO 190 180 HOLDKI = A(K,I) A(K,I) = CSA*HOLDKI + SNA*A(K,J) A(K,J) = SNA*HOLDKI - CSA*A(K,J) 190 CONTINUE 2000 A(I,J) = 0.0 C C ...CALCULO DE SIGMA2 PARA LA MATRIZ A TRANSFORMADA Y COMPROC CION DE CONVERGENCIA .... SIGMA2 = 0.0 DO 210 I=1,N EIGEN(I) = A(I,I) 210 SIGMA2 = SIGMA2 + EIGEN(I)**2 IF (1.0 - SIGMA1/SIGMA2.LT.EPS3) THEN GOTO 300 ENDIF 260 SIGMA1 = SIGMA2 C 300 IF ( ITER.GT.ITMAX) THEN C IF ( ITER.GT.ITMAX) THEN ierr = -1 ENDIF return END C C ... 155 C ... C-----------------------------------------------------------------------C DEFINIMOS LA SUBRUTINA CRITERIO_FRACTURA. ÉSTA SUBRUTINA SERÁ DISTINTA C SEGÚN EL CRITERIO DE FRACTURA QUE USEMOS. AQUÍ DESARROLLAMOS EL DE C COWIN, EN CASO DE SER OTRO CRITERIO, ELIMINAMOS LA SUBRUTINA LLAMADA C ‘criterio_cowin’ E INTRODUCIMOS LA QUE SEA, POR EJEMPLO ‘sig_max’ EN EL C CASO QUE SE USE EL CRITERIO DE LA TENSIÓN MÁXIMA C-----------------------------------------------------------------------C %%%%%%%%%%%%%%%%%%%%% C CRITERIOS DE FRACTURA C %%%%%%%%%%%%%%%%%%%%% subroutine criterio_fractura(nsd,stress,ntens,ndi,nshr,props, 1 nprops,statev,nstatev,Hgorro,rhot,noel,dano) implicit none integer ntens,ndi,nshr,i,n,nprops,nstatev,ierr,noel,nsd,j real*8 smat(3,3),stress(ntens),props(nprops),statev(nstatev) real*8 sval(3),svec(3,3),str(ntens),Hgorro(3,3),rhot real*8 rho real*8 dano C Sólo se introduce en el caso de osteoporosis con pérdida de masa ósea C no constante. Nosotros no lo tendremos en cuenta en principio. if (statev(1).LT.1.2) then statev(1)=0.8*statev(1) else statev(1)=0.95*statev(1) end if C Sólo se inroduce en el caso de osteoporosis con pérdida de masa ósea C constante. Nosotros tampoco lo tendremos en cuenta en principio. statev(1)=0.8*statev(1) C C Llamamos a las funciones y subrutinas correspondientes para poder C desarrollar la subrutina del criterio de fractura call smatrix(smat,stress,ntens,ndi,nshr) call RS(3,3,smat,sval,svec,ierr) do i=1,ndi str(i)=sval(i) end do do i=4,ntens str(i)=0 end do call tension_max(props,nprops,statev,nstatev,noel) call criterio_cowin(nsd,str,ntens,ndi,nshr,props,nprops, 1 statev,nstatev,Hgorro,rhot,svec,noel,dano) return end C C --------------------------------------------------------------C Calculo la tensión máxima a compresión permitida en el material C --------------------------------------------------------------subroutine tension_max(props,nprops,statev,nstatev,noel) real*8 props(nprops),statev(nstatev),gi integer nprops,nstatev,noel statev(2)=((statev(1)/0.448041)**1.8)*15.8 statev(3)=0.2 return end C C ... 156 C ... C C C -----------------------------------------------------------Criterio de Cowin modificado usando porosidad direccional -----------------------------------------------------------subroutine criterio_cowin(nsd,str,ntens,ndi,nshr,props,nprops, 1 statev,nstatev,Hgorro,rhot,svec,noel,dano) implicit none integer ntens,ndi,nshr,i,j,nprops,nstatev,noel,nsd real*8 term1,str(ntens),statev(nstatev),G(3),sult(3,3) real*8 props(nprops),sma(3,3),F(3,3),Hgorro(3,3),svec(3,3) real*8 aux,rhot,gi real*8 beta,dano C C Llamamos a la subrutina que nos calcula las tensiones últimas. Le damos C el valor de las tensiones según según los parámetros que se desarrollan C en las referencias teóricas del Criterio de Cowin. C call mult(nsd,str,ntens,ndi,nshr,props,nprops,statev,nstatev,sult, 1 gi,Hgorro,rhot,svec,noel,dano) do i=1,3 if (sult(i,i).EQ.0) then G(i)=0 else G(i)=(1-statev(3))/(sult(i,i)*statev(3)) endif end do do i=1,3 do j=1,3 if (sult(i,j).EQ.0) then F(i,j)=0 else if (i.EQ.j) then F(i,j)=1/(sult(i,i)*sult(j,j)*statev(3)) else F(i,j)=0.5*(1/(statev(3)*sult(i,i)*sult(i,i))+1/(statev(3)*sult(j,j) 1 *sult(j,j))-1/(2*(sult(i,j)*sult(i,j)))) end if end if end do end do C call smatrix(sma,str,ntens,ndi,nshr) aux=0 do i=1,3 do j=1,3 aux=(G(i)*sma(i,i)/3)+aux aux=F(i,j)*sma(i,i)*sma(j,j)+aux end do end do statev(4)=(abs(aux))**0.5 beta=statev(4) C Nos aseguramos de que el valor de beta sea siempre menor o igual que 1 if (beta.lt.0.99) then dano=beta else dano=0.99 endif return end C C ... 157 C ... C--------------------------------------------------------C DEFINIMOS LA SUBRUTINA QUE CALCULA LAS TENSIONES ÚLTIMAS C--------------------------------------------------------subroutine mult(nsd,str,ntens,ndi,nshr,props,nprops,statev,nstatev, 1 sult,gi,Hgorro,rhot,svec,noel,dano) implicit none integer nstatev,noel,nprops,i,j,k,m,n,ntens,ndi,nshr,nsd real*8 statev(nstatev),LO(3),svet(3,3),Hgorpr(3,3),sult(3,3) real*8 props(nprops),str(3),Hgorro(3,3),svec(3,3),Hin(3,3) real*8 gi,ngorro,rhot,aux,det,invers real*8 dano do i=1,3 do j=1,3 if (i.EQ.j) then do k=1,3 if (k.EQ.j) then LO(k)=1 else LO(k)=0 endif end do else do k=1,3 if ((k.EQ.j).OR.(k.EQ.i)) then LO(k)=1/(2**0.5) else LO(k)=0 end if end do end if C C Determino la matriz inversa de una dada para hallar el Fabric Tensor de la C porosidad que tengamos C C*************************************************************************** C Hgorro, Fabric Tensor, en ejes principales de tensión. Hay que tener en C cuenta que nosotros, al suponer comportamiento isótropo, tendremos un C fabric tensor igual a la matriz identidad. De momento lo que vamos a C hacer es cambiar el "aux" del comando que nos da "statev(2)" por la C densidad normal(statev(1)) C*************************************************************************** det=invers(3,Hgorro,1E-17,-1) call mult_matri(Hgorro,svec,Hin) call traspuesta(svec,svet) call mult_matri(svet,Hin,Hgorpr) aux=0 ngorro=0 do n=1,3 do m=1,3 aux=(statev(1)*Hgorpr(n,m)*LO(n)*LO(m))+aux end do end do ngorro=1-aux/rhot sult(i,j)=(((abs(aux)/0.448041)**1.8)*15.8)*(1-dano) end do end do statev(3)=0.2 gi=1.2 return end 158 C ... C---------------------------------------------------------------------------C SUBRUTINA QUE MULTIPLICA DOS MATRICES (A,B) Y EL RESULTADO LO ALMACENA EN C C---------------------------------------------------------------------------subroutine mult_matri(A,B,C) implicit none integer i,j,k real*8 aux real*8 A(3,3),B(3,3),C(3,3) do j=1,3 do k=1,3 do i=1,3 aux=A(j,i)*B(i,k)+aux end do C(j,k)=aux aux=0 end do end do return end C Subrutina que devuelve la matriz traspuesta. subroutine traspuesta(A,Atras) implicit none integer i,j real*8 A(3,3),Atras(3,3) do i=1,3 do j=1,3 Atras(i,j)=A(j,i) end do end do return end C C ... 159 C ... C-------------------------------------------------------------------------C INTRODUCIMOS SUBRUTINAS DE LA BIBLIOTECA DE ABAQUS. SON NECESARIAS, SI NO C A LA HORA DE SIMULAR NOS VAN A APARECER ERRORES C-------------------------------------------------------------------------SUBROUTINE URDFIL(LSTOP,LOVRWRT,KSTEP,KINC,DTIME,TIME) INCLUDE 'ABA_PARAM.INC' DIMENSION ARRAY(6000),JRRAY(NPRECD,6000) EQUIVALENCE(ARRAY(1),JRRAY(1,1)) CONV1=0.0 CONV2=0.0 CONV3=0.0 CONV4=0.0 TOTVOLUMEN=0.0 CALL POSFIL(KSTEP,KINC,ARRAY,JRCD) DO K1=1,999999 CALL DBFILE(0,ARRAY,JRCD) IF (JRCD.NE.0) GO TO 110 KEY=JRRAY(1,2) IF (KEY.EQ.5) THEN CONV1=CONV1+ARRAY(19) CONV2=CONV2+ARRAY(20) CONV3=CONV3+ARRAY(21) CONV4=CONV4+ARRAY(22) TOTVOLUMEN=TOTVOLUMEN+ARRAY(23) ENDIF ENDDO 110 CONTINUE write(6,*) 'PORCENTAJE1',conv1/TOTVOLUMEN write(6,*) 'PORCENTAJE2',conv2/TOTVOLUMEN write(6,*) 'PORCENTAJE3',conv3/TOTVOLUMEN write(6,*) 'PORCENTAJE4',conv4/TOTVOLUMEN return end C SUBROUTINE USDFLD(FIELD,STATEV,PNEWDT,DIRECT,T,CELENT, 1TIME,DTIME,CMNAME,ORNAME,NFIELD,NSTATV,NOEL,NPT,LAYER, 2KSPT,KSTEP,KINC,NDI,NSHR,COORD,JMAC,JMATYP,MATLAYO,LACCFLA) INCLUDE 'ABA_PARAM.INC' CHARACTER*8 CMNAME,ORNAME,FLGRAY(15) DIMENSION FIELD(NFIELD),STATEV(NSTATV),DIRECT(3,3),T(3,3),TIME(2) DIMENSION ARRAY(15),JARRAY(15) CALL GETVRM('IVOL',ARRAY,JARRAY,FLGRAY,JRCD,JMAC,JMATYP,MATLAYO, 1LACCFLA) FIELD(1)=ARRAY(1) STATEV(6)=FIELD(1) RETURN END C C ************************ FIN DE LA UMAT ***************************** 160 ANEXO I-b: Subrutina que nos define el criterio de la Tensión Máxima C-----------------------------C Criterio de la Tensión máxima C-----------------------------subroutine sig_max(nsd,str,ntens,ndi,nshr,props,nprops, 1 statev,nstatev,noel,dano) implicit none integer ntens,ndi,nshr,nprops,nstatev,noel,nsd real*8 str(ntens),statev(nstatev) real*8 props(nprops) real*8 s1,s2,s3,aux1,aux2 real*8 beta,dano s1=max(str(1),str(2),str(3)) s3=min(str(1),str(2),str(3)) aux1=abs(s3/statev(2)) aux2=abs(s1/(statev(3)*statev(2))) statev(4)=max(aux1,aux2) beta=statev(4) C-----------------------------------------------------------------------C Tenemos que asegurarnos de que el valor de beta sea siempre menor o C igual que 1, ya que si fuese mayor, el módulo de Young que asignaríamos C con la ley de daño que tenemos sería negativo. C-----------------------------------------------------------------------if (beta.lt.0.99) then dano=beta else dano=0.99 endif return end C ************************ FIN SUBRUTINA ***************************** 161 ANEXO I-c: Modificación de la ley de daño que imponemos C---------------------------------------------------------------------------C DEFINIMOS LA SUBRUTINA "evaluadn" PERO CAMBIANDO LA LEY DE DAÑO. ROMPEMOS C LA LINEALIDAD QUE TENÍA ANTES ELEVANDO EL TÉRMINO “(1-dano)” A UN EXPONENTE C ‘n’ QUE ELIJAMOS. EN ESTE CASO VAMOS A USAR UN EXPONENTE n=0.25. C---------------------------------------------------------------------------subroutine evaluadn(dxyz,H,nsd,ntens,ndi,nshr,props, *nprops,noel,dano) implicit none integer nsd,ntens,ndi,nshr,nprops,i,j,ierr,noel real*8 props(nprops) real*8 dxyz(6,6),H(3,3),d(6,6),Hxyz(3,3) real*8 eval(3),evec(3,3) real*8 young1,cexp1,cexp2,rhotrans,young2,rhoi,rhomax real*8 young0,pois0,A1,A2,A3,B12,B23,B13,C12,C23,C13 real*8 aux,rhot real*8 rho,young real*8 dano rho = props(1) young = props(2) pois0 = props(3) do i=1,6 do j=1,6 dxyz(i,j)=0. d(i,j)=0. enddo enddo C do i=1,3 eval(i)=0. do j=1,3 Hxyz(i,j)=H(i,j) evec(i,j)=0. enddo enddo C call RS(3,3,Hxyz,eval,evec,ierr) if (ierr.lt.0) then endif C-----------------------------------------------------------------------C El módulo de young se irá modificando según una determinada ley de daño C que depende exclusivamente del valor que tome la variable ‘daño’. En C esta UMAT hemos tomado ésta ley de daño lineal. C-----------------------------------------------------------------------young0=(young)*(1-dano) A1=(1./young0)*(1./(eval(1)*eval(1)*eval(1)*eval(1))) A2=(1./young0)*(1./(eval(2)*eval(2)*eval(2)*eval(2))) A3=(1./young0)*(1./(eval(3)*eval(3)*eval(3)*eval(3))) B12=(-pois0/young0)*(1./(eval(1)*eval(1)*eval(2)*eval(2))) B13=(-pois0/young0)*(1./(eval(1)*eval(1)*eval(3)*eval(3))) B23=(-pois0/young0)*(1./(eval(2)*eval(2)*eval(3)*eval(3))) C12=((1+pois0)/young0)*(1./(eval(1)*eval(1)*eval(2)*eval(2))) C23=((1+pois0)/young0)*(1./(eval(3)*eval(3)*eval(2)*eval(2))) C13=((1+pois0)/young0)*(1./(eval(1)*eval(1)*eval(3)*eval(3))) C ... 162 C... C Inicializo la matriz de flexibilidad do i=1,6 do j=1,6 dxyz(i,j)=0.0 d(i,j)=0.0 enddo enddo C Evaluo la matriz de flexibilidad d(1,1)=A1 d(1,2)=B12 d(2,1)=d(1,2) d(1,3)=B13 d(3,1)=d(1,3) d(2,2)=A2 d(2,3)=B23 d(3,2)=d(2,3) d(3,3)=A3 d(4,4)=2.*C12 d(5,5)=2.*C13 d(6,6)=2.*C23 C Sustituyo los valores obtenidos do i=1,6 do j=1,6 dxyz(i,j)=d(i,j) enddo enddo return end C ************************ FIN SUBRUTINA ***************************** 163