program f90_FEM_HEAT !******************************************************* !2D unsteady heat conduction analysis !******************************************************* implicit none integer::i,j,k,n,nnn,ia,ja,ne,it real(8)::alpc1,alpc2,alpc3,alpc4 character(len=50)::ftinp !Input file name for temperature history character(len=100)::strcom !Comment integer::NODT !Number of nodes integer::NELT !Number of elements integer::MATEL !Number of material sets integer::KOT !Number of nodes with given temperature integer::KOC !Number of sides with the condition of heat transger boundary integer::nod=4 !Number of nodes per element integer::nhen=1 !Number of degree of freedom per node integer::nt !Number of degrees of freedom of all nodes (NODT x nhen) integer::mm !Number of degrees of freedom of reduced FE equation integer::ib !Band width of reduced matrix integer,allocatable::kakom(:,:) !Element connectivity real(8),allocatable::Ak(:) !Heat conductivity coefficient of element real(8),allocatable::Ac(:) !Specific heat of element real(8),allocatable::Arho(:) !Unit weight of element real(8),allocatable::Tk(:) !maximum temperature rise of element real(8),allocatable::Al(:) !Coefficient of heat release rate of element integer,allocatable::matno(:) !Material set number real(8),allocatable::wm(:,:) !work for material properties real(8),allocatable::x(:) !x-coordinate of node real(8),allocatable::y(:) !y-coordinate of node integer,allocatable::nokt(:) !Node number with given temperature integer,allocatable::nekc(:,:) !Element number and side number with the condition of heat transfer boundary real(8),allocatable::alphac(:) !Heat transfer rate of side of element real(8),allocatable::Tinp(:) !Temperature of given temperature node real(8),allocatable::Tcin1(:) !Temperature of heat transfer boundary node (previous) real(8),allocatable::Tcin2(:) !temperature of heat transfer boundary node (current) real(8)::alpc !work for heat transfer rate real(8)::tc !work for temperature of heat transfer boundary integer::kchen !work for side number of heat transfer boundary real(8)::dotq !work for heat generation rate real(8),allocatable::tck1(:,:) !Total coefficient matrix (previous) real(8),allocatable::tck2(:,:) !Total coefficient matrix (current) real(8),allocatable::rtck2(:,:) !Total coefficient matrix (current, reduced matrix) real(8)::ck1(4,4) !Element coefficient matrix (previous) real(8)::ck2(4,4) !Element coefficient matrix (current) real(8)::ht(4,4) !Element heat transfer matrix real(8)::fq(4) !Element heat generation rate vector real(8)::fc(4) !Element heat transfer vector real(8),allocatable::tempe0(:) !Initial temperatute real(8),allocatable::ftvec(:) !Heat flux vector real(8),allocatable::tempe(:) !Nodal temperature vector real(8),allocatable::reac(:) !work for nodal temperature integer,allocatable::mindex(:) !Index for treatment of given temperature nodes real(8)::delta !Time increment real(8)::ttime !Time integer::itmax !Number of time history step integer::nout !Number of temperature output nodes integer,allocatable::noout(:) !Node number of temperature output nodes integer::ntout !Frequency of output of all node's temperatures integer,allocatable::nntout(:) !Time step number of above real(8),allocatable::tempend(:,:)!Nodal temperature for output real(8)::fact0=1.0D-30 !0 judgement real(8)::elarea1 !Half area of element real(8)::elarea2 !Half area of element integer::io !Variable for finding 'EOF' character::fnameR*50,fnameW*50 !Input file name, output file name character::str*20 character :: linebuf*1000 character :: fmt1*200,fmt2*200 real(4) :: t1,t2 fmt1="(i5,2(',',e15.7),',',i2,',',e15.7)" !Node fmt2="(i5,4(',',i5),4(',',e15.7),5(',',e15.7),',',i5)" !Element properties call getarg(1,fnameR) !Input file name call getarg(2,fnameW) !Output file name !To start the measurement of calculation time t1=DIFT() !***************************************************** !Data input !***************************************************** open(11,file=fnameR,status='old') !-------------------------------------------------------------------------------------- !Comment !-------------------------------------------------------------------------------------- read(11,'(a)') strcom !-------------------------------------------------------------------------------------- !Input file name for temperature history !-------------------------------------------------------------------------------------- read(11,'(a)') ftinp !------------------------------------------------------------------------------------------ !Basic values for analysis !------------------------------------------------------------------------------------------ read(11,*) NODT,NELT,MATEL,KOT,KOC,delta !------------------------------------------------------------------------------------------ !To declare array size !------------------------------------------------------------------------------------------ nt=NODT*nhen allocate(kakom(1:NELT,1:4)) allocate(Ak(1:NELT)) allocate(Ac(1:NELT)) allocate(Arho(1:NELT)) allocate(Tk(1:NELT)) allocate(Al(1:NELT)) allocate(matno(1:NELT)) allocate(wm(1:MATEL,1:5)) allocate(x(1:NODT)) allocate(y(1:NODT)) allocate(nokt(1:KOT)) allocate(nekc(1:KOC,1:2)) allocate(alphac(1:KOC)) allocate(Tinp(1:KOT)) allocate(Tcin1(1:KOC)) allocate(Tcin2(1:KOC)) allocate(mindex(1:nt)) allocate(tck1(1:nt,1:nt)) allocate(tck2(1:nt,1:nt)) allocate(rtck2(1:nt,1:KOT)) allocate(tempe0(1:nt)) allocate(tempe(1:nt)) allocate(reac(1:nt)) allocate(ftvec(1:nt)) !------------------------------------------------------------------------------------------ !material properties (Ak,Ac,Arho,Tk,Al) !------------------------------------------------------------------------------------------ do i=1,MATEL read(11,*) wm(i,1),wm(i,2),wm(i,3),wm(i,4),wm(i,5) end do !------------------------------------------------------------------------------------------ !Element-nodes relationship, material set No. !------------------------------------------------------------------------------------------ do ne=1,NELT read(11,*) kakom(ne,1),kakom(ne,2),kakom(ne,3),kakom(ne,4),matno(ne) do i=1,MATEL if(i==matno(ne))then Ak(ne) =wm(i,1) Ac(ne) =wm(i,2) Arho(ne)=wm(i,3) Tk(ne) =wm(i,4) Al(ne) =wm(i,5) end if end do end do deallocate(wm) !------------------------------------------------------------------------------------------ !(x,y) coordinates, initial temperature of node !------------------------------------------------------------------------------------------ do i=1,NODT read(11,*) x(i),y(i),tempe0(i) end do !------------------------------------------------------------------------------------------ !Node number of given temperature nodes !------------------------------------------------------------------------------------------ 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) tck2(i,j)=tck2(ia,ja) end do end do !----------------------------------------------------- !calculation of band width and memory of band matrix !----------------------------------------------------- ib=IBAND(mm,tck2,fact0,nt) Call BAND(mm,ib,tck2,nt) !----------------------------------------------------- !To verify diagonal elements and to stop if necessary !----------------------------------------------------- do i=1,mm if(abs(tck2(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 !----------------------------------------------------- !Calculation of band !----------------------------------------------------- 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