module defconst implicit none real(8),parameter::ggg=9.8D0 end module defconst program f90_FEM_VFRM !***************************************************************** !2D Frame 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::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::KOZ !Number of restricted nodes in rotation 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::Em(:) !Elasyic mudulus of element real(8),allocatable::AA(:) !Section area of element real(8),allocatable::AI(:) !Moment of inertia 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 of node integer,allocatable::nokx(:) !Restricted node number in x-direction integer,allocatable::noky(:) !Restricted node number in y-direction integer,allocatable::nokz(:) !Restricted node number in rotation real(8),allocatable::f(:) !External load 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::hen(:,:) !Transform 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::sresul(:,:) !Resultant force of element integer::ndata !Number of time history data real(8)::dt !Time increment real(8),allocatable::accinp(:) !Acceleration time histroy data 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::prsresul(:,:) !Memory of stress resultant for output real(8)::dismax !work for search of Max.displacement integer::kpriii !Memory for Max.disp step real(8),allocatable::ftvec(:) !Total 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=2 !Number of nodes per element integer::nhen=3 !Number of degrees 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 time history input data file name integer::numnd,numsr !Number of displacement degree and stress resultant 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 resultant degree number for output of time history data character :: linebuf*1000,dummy*200 character :: fmt1*200,fmt2*200,fmt3*200,fmt4*200 real(4) :: t1,t2 fmt1="(i5,2(',',e15.7),3(',',e15.7),3(',',i2))" !Node fmt2="(i5,2(',',i5),6(',',e15.7),',',i5)" !Element fmt3="(i5,2(',',e15.7),3(',',e15.7))" !Displacement, reaction fmt4="(i5,3(',',e15.7),3(',',e15.7))" !Stress resultant call getarg(1,fnameR) !Input data file (structure data) call getarg(2,fnameW) !Output data file call getarg(3,fnameA) !Acceleration time history data input file !To start the measurement of calculation time t1=DIFT() !*************************** !data input !*************************** open(11,file=fnameR,status='old') !/*--------------------------------------------------------------------------------------*/ !/*Comment*/ !/*--------------------------------------------------------------------------------------*/ read(11,'(a)') strcom !------------------------------------------------------------------------------------------ !Basic data for analysis !------------------------------------------------------------------------------------------ read(11,*) NODT,NELT,MATEL,KOX,KOY,KOZ,NF !------------------------------------------------------------------------------------------ !To declare array size !------------------------------------------------------------------------------------------ nt=NODT*nhen allocate(kakom(1:NELT,1:nod)) allocate(matno(1:NELT)) allocate(wm(1:MATEL,1:6)) allocate(Em(1:NELT)) allocate(AA(1:NELT)) allocate(AI(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)) if(1<=KOZ)allocate(nokz(1:KOZ)) 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(hen(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(sresul(1:NELT,1:nod*nhen)) 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(prsresul(1:NELT,1:nod*nhen)) !------------------------------------------------------------------------------------------ !Material properties (Em,AA,AI,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 (node-1, node-2, matno) !------------------------------------------------------------------------------------------ do ne=1,NELT read(11,*) kakom(ne,1),kakom(ne,2),matno(ne) do i=1,MATEL if(i==matno(ne))then Em(ne) =wm(i,1) AA(ne) =wm(i,2) AI(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 !------------------------------------------------------------------------------------------ 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 & to stop if necessary !----------------------------------------------------- do i=1,mm if(abs(tlm(i,1))m1)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