c User subroutine UEL XFEM subroutine uel(rhs,amatrx,svars,energy,ndofel,nrhs,nsvars, 1 props,nprops,coords,mcrd,nnode,u,du,v,a,jtype,time,dtime, 1 kstep,kinc,jelem,params,ndload,jdltyp,adlmag,predef,npredf, 1 lflags,mlvarx,ddlmag,mdload,pnewdt,jprops,njprop,period) c include 'aba_param.inc' c ABAQUS defined variables: dimension rhs(mlvarx,*), amatrx(ndofel,ndofel), props(*), 1 svars(nsvars), energy(8), coords(mcrd,nnode), u(ndofel), 1 du(mlvarx,*), v(ndofel), a(ndofel), time(2), params(*), 1 jdltyp(mdload,*), adlmag(mdload,*), ddlmag(mdload,*), 1 predef(2,npredf,nnode), lflags(*), jprops(*) c character*256 outdir integer lenoutdir integer i,j,k,pss,orderq(3),gint,flag,dimens integer ncracks,maxncp,nelmx,nnodx,typexe(nnode),ix(nnode) integer,parameter :: mpg=1650 integer,allocatable:: typex(:,:),ncp(:) real*8 e, nu real*8 f(ndofel) real*8 sg(3,mpg),xypg(2,mpg),xe(8),ye(8),xyc0(2),xycprev(2) real*8, allocatable:: xyc(:,:,:),dist(:,:),elemgg(:,:) real*8, allocatable:: batg(:,:),dbatg(:,:),jatg(:) c c Read real and integer properties set at the ABAQUS input file e = props(1) nu = props(2) pss = jprops(1) orderq(1) = jprops(2) orderq(2) = jprops(3) orderq(3) = jprops(4) dimens = jprops(5) c Read the working directory call getoutdir(outdir,lenoutdir) c read number of cracks, max number of crack path points, c number of enriched elements and enriched nodes. open(68,file=outdir(1:lenoutdir)//’\files\gginfox’) read(68,*) ncracks,maxncp,nelmx,nnodx close(68) c Allocate dimensions allocate (typex(nnodx,2), ncp(ncracks)) allocate (xyc(ncracks,maxncp,2), dist(nnodx,3), elemgg(nelmx,10)) c read coordinates of path points for each crack open(68,file=outdir(1:lenoutdir)//’\files\ggxyc’) do i=1,ncracks read(68,*) ncp(i) do j=1,ncp(i) read(68,*) (xyc(i,j,k),k=1,2) end do end do close(68) c Read list of enriched nodes, type of enrichment and distances open(68,file=outdir(1:lenoutdir)//’\files\ggnodex’) do i=1,nnodx read(68,*) (typex(i,j),j=1,2),(dist(i,j),j=2,3) dist(i,1)=typex(i,1) end do close(68) c read list of enriched elements, type of enrichment and intersection points open(68,file=outdir(1:lenoutdir)//’\files\ggelemx’) do i=1,nelmx read(68,*) (elemgg(i,j),j=1,10) end do close(68) c call initializing routines for matrix and vectors call initializem(rhs,ndofel,nrhs) call initializem(amatrx,ndofel,ndofel) call initializev(energy,8) call initializev(svars,nsvars) c verification of element type (type=12 for enriched element) if (jtype.eq.12) then c ************************************** c * 4 node enriched element with * c * up to 12 dof/node for x-fem * c ************************************** if (lflags(1).eq.71) then c coupled thermal-stress, steady state analysis if (lflags(3).eq.1) then c Routine that defines the location of integration points according to c the appropriate subdivision. This enables to know the total number of c integration points for the current element, stored in gint, and whether c the element is subdivided for integration (flag=1) or not. CALL int2d_X(JELEM,NelmX,ElemGG,MCRD,NNODE,COORDS,orderQ, 1 NCracks,maxNCP,NCP,XYC,gint,sg,Xe,Ye,flag,mpg,xypg, 1 XYC0,XYCPrev) c Allocate dimensions once the total number of integration points gint is known allocate(batg(3*gint,ndofel),dbatg(3*gint,ndofel),jatg(gint)) call initializem(batg,3*gint,ndofel) call initializem(dbatg,3*gint,ndofel) call initializev(jatg,gint) c Search of the enrichment type for the nodes of the current element. c The keys to the enrichment types are stored in the element vector TypeXe call typexelement(outdir,lenoutdir,jelem,nnode,nelmx,ix,typexe) c element stiffness matrix computation, stored in amatrx call k_u12(e,nu,amatrx,ndofel,nnode,dimens,mcrd, coords,pss,nnodx,ix,typexe,dist,xyc0,xycprev, gint,sg,xe,ye,flag,batg,dbatg,jatg) c Routine that multiplies AMATRX times U to obtain the force vector F c at the end of the current increment call mult_v(amatrx,ndofel,ndofel,u,f,ndofel) c compute the residual force vector do i=1,ndofel rhs(i,1) = rhs(i,1) - f(i) end do c Compute stresses at Gauss points for post-processing purposes c Store them as SVARS for output to the results file (.fil) call svars_u12(jtype,jelem,svars,nsvars,u,ndofel,batg, 1 dbatg,jatg,gint,mpg,xypg) end if end if end if return end C Element stiffness matrix. Subroutine: K U12 subroutine k_u12(e,nu,amatrx,ndofel,nnode,dimens,mcrd, 1 COORDS,PSS,NnodX,ix,TypeXe,Dist,XYC0,XYCPrev, 1 gint,sg,Xe,Ye,flag,BatG,DBatG,JatG) implicit none integer ndofel,nnode,dimens,mcrd,pss,nnodx,gint,flag,pos integer l,i,j,kk,typexe(nnode),ix(nnode) real*8 e,nu,dist(nnodx,3),sg(3,*) real*8 amatrx(ndofel,ndofel),xyc0(2),xycprev(2) real*8 xe(2*nnode),ye(2*nnode),coords(mcrd,nnode),xl(dimens,nnode) real*8 xsj(gint),shp(3,4) real*8 dnf(nnode,2,4),fnode(nnode,4),h,hnode(nnode) real*8 b(3,ndofel), db(3,ndofel), bt(ndofel,3), d(3,3) real*8 batg(3*gint,ndofel),dbatg(3*gint,ndofel),jatg(gint) logical nodetype1,nodetype2 c NOTES: c Routine shapef2D is called to compute standard shape functions, c derivatives and jacobian at integration points. This routine outputs: c shp(3,*) - Shape functions and derivatives at point c shp(1,i) = dN_i/dx = dN_i/dx1 c shp(2,i) = dN_i/dy = dN_i/dx2 c shp(3,i) = N_i c xsj - Jacobian determinant at point c Local coordinates of integration points are passed in sg(1,*), sg(2,*) c Integration weights are passed in sg(3,*) c Initialize AMATRX and logical variables call initializem(amatrx,ndofel,ndofel) NodeType1=.false. NodeType2=.false. c Reduce info passed thru COORDS (3D) to xl (2D) do i=1,dimens do j=1,nnode xl(i,j)=coords(i,j) end do end do c Define constitutive stress-strain elastic matrix call calc_d(pss,d,e,nu) c Specify the type of nodal enrichment do i=1,nnode if (typexe(i).eq.1) then nodetype1=.true. elseif (typexe(i).eq.2) then nodetype2=.true. end if end do c Numerical integration loop over gint integration points DO l = 1,gint c Compute shape functions, derivatives and jacobian at integration point call shapef2d(sg(1,l),xl,shp,xsj(l),dimens,nnode,ix,.false.) if (flag.eq.1) then !element is subdivided for integration xsj(l) = sg(3,l) !the integration weight includes the jacobian else !element is not subdivided. standard integration xsj(l) = xsj(l)*sg(3,l) endif c Value of the Heaviside function at integration point c (This call is also used to store the values of H c at nodes of the element for modified enrichment) if (nodetype1) then call heaviside(nnodx,dist,nnode,ix,shp,h,hnode) endif c Derivatives of shape functions Ni times enrichment functions Fj at integration point c (This call is also used to compute the derivatives of shape functions Ni times c enrichment functions Fj at nodes of the element for modified enrichment) if (nodetype2) then call fcracktip(xyc0,xycprev,shp,xe,ye,dnf,fnode) endif c STIFFNESS MATRIX COMPUTATION: c Assembly of element matrix B (denoted as B) at integration point call initializem(b,3,ndofel) pos=1 c loop over nodes do i= 1,nnode c Contribution to B of derivatives of standard shape functions B(1,Pos) = shp(1,i) B(2,Pos+1)= shp(2,i) B(3,Pos) = shp(2,i) B(3,Pos+1)= shp(1,i) c Contribution to B of derivatives of shape functions times Heaviside function if (typexe(i).eq.1) then b(1,2+pos) = shp(1,i)*(h-hnode(i)) b(2,3+pos) = shp(2,i)*(h-hnode(i)) b(3,2+pos) = shp(2,i)*(h-hnode(i)) b(3,3+pos) = shp(1,i)*(h-hnode(i)) c Contribution to B of derivatives of shape functions times crack tip functions elseif(typexe(i).eq.2) then do kk= 1,4 b(1,2*kk+2+pos)= dnf(i,1,kk)-shp(1,i)*fnode(i,kk) b(2,2*kk+3+pos)= dnf(i,2,kk)-shp(2,i)*fnode(i,kk) b(3,2*kk+2+pos)= dnf(i,2,kk)-shp(2,i)*fnode(i,kk) b(3,2*kk+3+pos)= dnf(i,1,kk)-shp(1,i)*fnode(i,kk) end do end if Pos=Pos+12 !Each node has 12 dof end do ! i = end loop over element nodes db=matmul(d,b) ! matrix d*b bt=transpose(b) ! b transpose c Integration of BT*D*B amatrx= amatrx + matmul(bt,db)*xsj(l) c store information at each integration point for further post-processing do i=1,3 do j=1,ndofel batg(3*(l-1)+i,j)=b(i,j) dbatg(3*(l-1)+i,j)=db(i,j) end do end do jatg(l)=xsj(l) end do ! l = end loop for each integration point return end c SUBROUTINE SVARS_U12(JTYPE,JELEM,SVARS,NSVARS,U,Dof,BatG,DBatG, * JatG,gint,mpg,xypg) c Calculates and/or stores the following magnitudes at the element integration points, c storing them in SVARS: strains, stresses, strain energy density, dv/dx, du/dy, jacobian, c dNi/dx, dNi/dy, global coordinates of integration points. IMPLICIT NONE INTEGER i,j,k,NSVARS, Dof, gint, JTYPE,JELEM,mpg REAL*8 SVARS(NSVARS), U(Dof),BatG(3*gint,Dof),DBatG(3*gint,Dof) REAL*8 JatG(gint),B(3,Dof),DB(3,Dof),Bdvdx(3,Dof),Bdudy(3,Dof) REAL*8 EPS(3),SIG(3),W,dvdx(3),dudy(3),JAC,xypg(2,mpg) c &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 39 c &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& c First value stored in SVARS is the total number of integration points c of the enriched element SVARS(1)=gint DO i=1,gint JAC=JatG(i) DO k=1,3 DO j=1,Dof B(k,j)=BatG(3*(i-1)+k,j) Bdvdx(k,j)=B(k,j) ! For computation of dv/dx Bdudy(k,j)=B(k,j) ! For computation of du/dy DB(k,j)=DBatG(3*(i-1)+k,j) END DO END DO CALL MULT_V(B,3,Dof,U,EPS,3) ! Compute strains EPS CALL MULT_V(DB,3,Dof,U,SIG,3) ! Compute stresses SIG W=0.5d0*(EPS(1)*SIG(1)+EPS(2)*SIG(2)+EPS(3)*SIG(3)) c Computation of dv/dx & du/dy c Set to zero positions in the 3rd row of B associated with dN/dy DO j=1,Dof,2 Bdvdx(3,j)=0.0d0 END DO CALL MULT_V(Bdvdx,3,Dof,U,dvdx,3) !compute dv/dx, stored in dvdx(3) c Set to zero positions in the 3rd row of B associated with dN/dx DO j=2,Dof,2 Bdudy(3,j)=0.0d0 END DO CALL MULT_V(Bdudy,3,Dof,U,dudy,3) !compute du/dy, stored in dudy(3) c Store in SVARS the following information at integration points SVARS(1+20*(i-1)+1)=EPS(1) SVARS(1+20*(i-1)+2)=EPS(2) SVARS(1+20*(i-1)+3)=EPS(3) SVARS(1+20*(i-1)+4)=SIG(1) SVARS(1+20*(i-1)+5)=SIG(2) SVARS(1+20*(i-1)+6)=SIG(3) SVARS(1+20*(i-1)+7)=W SVARS(1+20*(i-1)+8)=dvdx(3) SVARS(1+20*(i-1)+9)=dudy(3) SVARS(1+20*(i-1)+10)=JAC ! Jacobian includes integration weight c Store in SVARS the shape functions derivatives dNi/dx, dNi/dy for external computation c of dq/dx, dq/dy (used in domain interaction integrals). c (we take them from the positions associated with the standard dofs) SVARS(1+20*(i-1)+11)=B(1,1) SVARS(1+20*(i-1)+12)=B(1,13) SVARS(1+20*(i-1)+13)=B(1,25) SVARS(1+20*(i-1)+14)=B(1,37) SVARS(1+20*(i-1)+15)=B(2,2) SVARS(1+20*(i-1)+16)=B(2,14) SVARS(1+20*(i-1)+17)=B(2,26) SVARS(1+20*(i-1)+18)=B(2,38) Store in SVARS the global coordinates of integration points SVARS(1+20*(i-1)+19)=xypg(1,i) SVARS(1+20*(i-1)+20)=xypg(2,i) END DO !i loop over all integration points of the element RETURN END