Anexo I

Anuncio
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
Descargar