module defconst implicit none real(8),parameter::ggg=9.8D0 real(8),parameter::pi=3.14159265358979323846D0 end module defconst program f90_FEM_V2DIM !***************************************************************** !2D Stress Time History Response Analysis !***************************************************************** use defconst implicit none integer::i,j,k,l,m,kk,ne,n,ia,ja,iii character::strcom*50 !Comment integer::NSTRES !0: Plane strain, 1: plane stress integer::NODT !Number of nodes integer::NELT !Number of elements integer::MATEL !Number of material sets integer::KOX !Number of restricted nodes in x-direction integer::KOY !Number of restricted nodes in y-direction integer::NF !Number of loaded nodes integer,allocatable::kakom(:,:) !Element connectivity integer,allocatable::matno(:) !Material set number real(8),allocatable::wm(:,:) !work for material properties real(8),allocatable::t(:) !Thickness of element real(8),allocatable::Em(:) !Elastic modulus of element real(8),allocatable::po(:) !Poisson's ratio of element real(8),allocatable::gamma(:) !Unit weight of element real(8),allocatable::zetaM(:) !Constant for damping (proportional term to mass) real(8),allocatable::zetaK(:) !Constant for damping (proportional term to stiffness) real(8),allocatable::x(:) !x-coordinate of node real(8),allocatable::y(:) !y-coordinate od node integer,allocatable::nokx(:) !restricted node number in x-direction integer,allocatable::noky(:) !restricted node number in y-direction real(8),allocatable::f(:) !External force vector integer,allocatable::mindex(:) !Index for treatment of restricted nodes real(8),allocatable::ak(:,:) !Element stiffness matrix real(8),allocatable::am(:,:) !Element mass matrix real(8),allocatable::ac(:,:) !Element damping matrix real(8),allocatable::tak(:,:) !Total stiffness matrix real(8),allocatable::tam(:,:) !Total mass matrix real(8),allocatable::tac(:,:) !Total damping matrix real(8),allocatable::tlm(:,:) !Total left hand side matrix real(8),allocatable::acc2(:) !Current nodal acceleration real(8),allocatable::vel2(:) !Current nodal velocity real(8),allocatable::dis2(:) !Current nodal displacement real(8),allocatable::acc1(:) !Previous nodal acceleration real(8),allocatable::vel1(:) !Previous nodal velocity real(8),allocatable::dis1(:) !Previous nodal displacement real(8),allocatable::strsave(:,:) !Stresses of element integer::ndata !Number of time history data real(8)::dt !Time increment real(8),allocatable::accinp(:) !Time history data of accekeration real(8)::betaN=1.0D0/4.0D0 !coefficient of Newmark-beta-method (average acceleration method) integer::kprnod,kprfre !Node number and displacement degree number for output real(8),allocatable::prdis(:) !Memory of displacement for output real(8),allocatable::prstr(:,:) !Memory of stresses for output real(8)::dismax !work for search for Max.displacement integer::kpriii !Memory of Max.disp. step real(8)::sigx,sigy,tauxy,ps1,ps2,ang real(8)::xg,yg real(8),allocatable::ftvec(:) !Load vector real(8),allocatable::reac(:) !work array real(8),allocatable::wva(:) !work array real(8),allocatable::wvb(:) !work array real(8),allocatable::wk1(:) !work array real(8),allocatable::wk2(:) !work array integer::nt !Number of degrees of freedom of all nodes (NODT x nhen) integer::nod !Number of nodes per element integer::nhen=2 !Number of degree of freedom per node integer::mm !Number of degrees of freedom of reduced FE equation integer::ib !Band width of reduced matrix real(8)::fact0=1.0D-30 !0 judgement character::fnameR*50,fnameW*50,fnameA*50 !Input & output & acceleration input file name integer::numnd,numsr !Number of displacement degrees and stress for output of time history data integer,allocatable::nndnum(:,:) !Node number and displacement degree number for output of time history data integer,allocatable::nsrnum(:,:) !Element number and stress degree number for output of time history data character :: linebuf*1000,dummy*200 character :: fmt1*200,fmt23*200,fmt24*200,fmt3*200,fmt4*200 real(4) :: t1,t2 fmt1="(i5,2(',',e15.7),2(',',e15.7),2(',',i2))" !Node fmt23="(i5,3(',',i5),6(',',e15.7),',',i5)" !Element fmt24="(i5,4(',',i5),6(',',e15.7),',',i5)" !Element fmt3="(i5,2(',',e15.7),2(',',e15.7))" !Displacement fmt4="(i5,2(',',e15.7),3(',',e15.7),3(',',e15.7),',',i5)" !Stress call getarg(1,fnameR) !Input file name (structure data) call getarg(2,fnameW) !Output file name call getarg(3,fnameA) !Input file name for acceleration time history data !To start the measurement of calculation time t1=DIFT() !*************************** !data input !*************************** open(11,file=fnameR,status='old') !/*--------------------------------------------------------------------------------------*/ !/*Comment*/ !/*--------------------------------------------------------------------------------------*/ read(11,'(a)') strcom !------------------------------------------------------------------------------------------ !1Basic values for analysis !------------------------------------------------------------------------------------------ read(11,*) nod,NODT,NELT,MATEL,KOX,KOY,NF,NSTRES !------------------------------------------------------------------------------------------ !To declare array size !------------------------------------------------------------------------------------------ nt=NODT*nhen allocate(kakom(1:NELT,1:nod)) allocate(matno(1:NELT)) allocate(wm(1:MATEL,1:6)) allocate(t(1:NELT)) allocate(Em(1:NELT)) allocate(po(1:NELT)) allocate(gamma(1:NELT)) allocate(zetaM(1:NELT)) allocate(zetaK(1:NELT)) allocate(x(1:NODT)) allocate(y(1:NODT)) if(1<=KOX)allocate(nokx(1:KOX)) if(1<=KOY)allocate(noky(1:KOY)) allocate(f(1:nt)) allocate(mindex(1:nt)) allocate(ak(1:nod*nhen,1:nod*nhen)) allocate(am(1:nod*nhen,1:nod*nhen)) allocate(ac(1:nod*nhen,1:nod*nhen)) allocate(tak(1:nt,1:nt)) allocate(tam(1:nt,1:nt)) allocate(tac(1:nt,1:nt)) allocate(tlm(1:nt,1:nt)) allocate(acc2(1:nt)) allocate(vel2(1:nt)) allocate(dis2(1:nt)) allocate(acc1(1:nt)) allocate(vel1(1:nt)) allocate(dis1(1:nt)) allocate(strsave(1:NELT,1:3)) allocate(ftvec(1:nt)) allocate(reac(1:nt)) allocate(wva(1:nt)) allocate(wvb(1:nt)) allocate(wk1(1:nt)) allocate(wk2(1:nt)) allocate(prdis(1:nt)) allocate(prstr(1:NELT,1:3)) !------------------------------------------------------------------------------------------ !Material properties (t,Em,po,gamma,zetaM,zetaK) !------------------------------------------------------------------------------------------ do i=1,MATEL read(11,*) wm(i,1),wm(i,2),wm(i,3),wm(i,4),wm(i,5),wm(i,6) end do !------------------------------------------------------------------------------------------ !Element-nodes relationship, material set number !------------------------------------------------------------------------------------------ do ne=1,NELT read(11,*) (kakom(ne,j),j=1,nod),matno(ne) do i=1,MATEL if(i==matno(ne))then t(ne) =wm(i,1) Em(ne) =wm(i,2) po(ne) =wm(i,3) gamma(ne)=wm(i,4) zetaM(ne)=wm(i,5) zetaK(ne)=wm(i,6) end if end do end do deallocate(wm) !------------------------------------------------------------------------------------------ !(x,y) coordinates of node !------------------------------------------------------------------------------------------ do i=1,NODT read(11,*) x(i),y(i) end do !------------------------------------------------------------------------------------------ !Restricted node number !------------------------------------------------------------------------------------------ if(00)then mm=mm+1 mindex(mm)=i end if end do do i=1,mm ia=mindex(i) do j=1,mm ja=mindex(j) tlm(i,j)=tlm(ia,ja) end do end do !----------------------------------------------------- !To memory band matrix !----------------------------------------------------- ib=IBAND(mm,tlm,fact0,nt) call BAND(mm,ib,tlm,nt) !----------------------------------------------------- !To verify diagonal elements & stop if necessary !----------------------------------------------------- do i=1,mm if(abs(tlm(i,1))0.0D0)ang=45.0D0 if(tauxy<0.0D0)ang=135.0D0 if(tauxy==0.0D0)ang=0.0D0 else ang=0.5D0*atan(2.0D0*tauxy/(sigx-sigy)) ang=180.0D0/pi*ang if(sigx>sigy.and.tauxy>=0.0D0)ang=ang if(sigx>sigy.and.tauxy<0.0D0)ang=ang+180.0D0 if(sigxm1)then mm=m1 else mm=n1-i+1 end if do j=1,mm z=array(i,j) if(j/=m1)then if(m1-j+11)then array(i,j)=z/array(i,1) else array(i,1)=sqrt(z) end if else array(i,j)=z/array(i,1) end if end do end do end subroutine CHBAND10 subroutine CHBAND11(n1,m1,array,vector,nt) integer,intent(in)::n1,m1,nt real(8),intent(in)::array(1:nt,1:nt) real(8),intent(out)::vector(nt) integer :: i,j,mm real(8) :: z vector(1)=vector(1)/array(1,1) do i=2,n1 z=vector(i) if(i>m1)then mm=m1 else mm=i end if do j=2,mm z=z-array(i-j+1,j)*vector(i-j+1) end do vector(i)=z/array(i,1) end do vector(n1)=vector(n1)/array(n1,1) do i=n1-1,1,-1 z=vector(i) do j=2,m1 if(i+j-1>n1)exit z=z-array(i,j)*vector(i+j-1) end do vector(i)=z/array(i,1) end do end subroutine CHBAND11 integer function IBAND(mm,array,fact0,nt) integer,intent(in)::mm,nt real(8),intent(in)::array(1:nt,1:nt),fact0 integer :: i,j IBAND=1 do i=1,mm-1 do j=mm,i+1,-1 if(fact0<=abs(array(i,j)))exit end do if(IBAND<=j-i+1)IBAND=j-i+1 end do if(mm