⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p510.f90

📁 有限元编程第三版附带源代码。实用程序多
💻 F90
字号:
program p510         
!------------------------------------------------------------------------------
!      program 5.10 three dimensional analysis of an elastic
!      solid using 20-node brick elements
!      preconditioned conjugate gradient solver ;  only integrate one element
!      diagonal preconditioner diag_precon
!------------------------------------------------------------------------------
 use new_library  ;   use  geometry_lib     ;       implicit none
 integer::nxe,nze,neq,nn,nr,nip,nodof=3,nod=20,nst=6,ndof,loaded_nodes,      &
          i,k,m,ndim=3,iters,limit,iel,nels   
 real::aa,bb,cc,e,v,det,tol,up,alpha,beta 
 character(len=15)::element= 'hexahedron';    logical :: converged          
!-------------------------- dynamic arrays-------------------------------------
 real    ,allocatable :: points(:,:),dee(:,:),coord(:,:), weights(:),        &
                         g_coord(:,:), jac(:,:), der(:,:), deriv(:,:),       &
                         bee(:,:), km(:,:),eld(:),eps(:),sigma(:),           &
                         diag_precon(:),p(:),r(:),x(:),xnew(:),              &
                         u(:),pmul(:),utemp(:),d(:)
 integer, allocatable :: nf(:,:), g(:), num(:), g_num(:,:)  , g_g(:,:)         
!-------------------------input and initialisation-----------------------------
  open (10,file='p510.dat',status=    'old',action='read')
  open (11,file='p510.res',status='replace',action='write')              
  read (10,*) nels,nxe,nze,nn,nip,aa,bb,cc,e,v,   tol,limit ;  ndof=nod*nodof   
  allocate ( nf(nodof,nn), points(nip,ndim),dee(nst,nst),coord(nod,ndim),    &
            jac(ndim,ndim),der(ndim,nod),deriv(ndim,nod),                    &
            bee(nst,ndof),km(ndof,ndof),eld(ndof),eps(nst),sigma(nst),       &  
            g(ndof),pmul(ndof),utemp(ndof), g_coord(ndim,nn),                &
            g_num(nod,nels),weights(nip),num(nod),g_g(ndof,nels))
   nf=1; read(10,*) nr ; if(nr>0) read(10,*)(k,nf(:,k),i=1,nr)
         call formnf(nf);neq=maxval(nf)   
  allocate(p(0:neq),r(0:neq),x(0:neq),xnew(0:neq),u(0:neq),&
           diag_precon(0:neq),d(0:neq))
             r=0.; p=0.; x=0.; xnew=0.  ; diag_precon=0.          
   call deemat(dee,e,v);   call sample(element,points,weights)     
!---------- element stiffness integration and build the preconditioner---------
             iel=1
             call geometry_20bxz(iel,nxe,nze,aa,bb,cc,coord,num)
             km=0.0                                          
      gauss_pts_1:  do i=1,nip
                call shape_der (der,points,i) ; jac = matmul(der,coord)
                det = determinant(jac); call invert(jac)
                deriv = matmul(jac,der) ;call beemat (bee,deriv) 
                km=km+matmul(matmul(transpose(bee),dee),bee)*det*weights(i)   
      end do gauss_pts_1
     elements_1: do iel = 1,nels
                  call geometry_20bxz(iel,nxe,nze,aa,bb,cc,coord,num)
                  g_num(:,iel) = num; g_coord(:,num) = transpose(coord) 
                  call num_to_g ( num, nf, g ) ; g_g(: , iel) = g
                do m=1,ndof;diag_precon(g(m))=diag_precon(g(m))+km(m,m);end do 
     end do elements_1   
    write(11,'(a)') "Global coordinates "
    do k=1,nn;write(11,'(a,i5,a,3e12.4)')"Node",k,"       ",g_coord(:,k);end do
    write(11,'(a)') "Global node numbers "
    do k = 1 , nels; write(11,'(a,i5,a,27i3)')                                 &
                              "Element ",k,"    ",g_num(:,k); end do  
       write(11,'(a,i5)') "The number of unknowns is",neq        
!--------------------invert the preconditioner and get starting r--------------
         read(10,*) loaded_nodes,(k,r(nf(:,k)),i=1,loaded_nodes)
         write(11,'(a,e12.4)') "The total load is", sum(r)  
        diag_precon(1:neq)=1./ diag_precon(1:neq)  ; diag_precon(0) = .0
                 d=diag_precon*r  ; p = d
!--------------------preconditioned c. g. iterations---------------------------
       iters = 0
     iterations  :      do 
             iters = iters + 1     ;    u = 0.
       elements_2 : do iel = 1, nels
                      g = g_g( : , iel )  ;    pmul = p(g)
                      utemp = matmul(km,pmul); u(g) = u(g)+ utemp 
       end do elements_2
!--------------------------pcg equation solution-------------------------------
           up=dot_product(r,d); alpha= up/ dot_product(p,u)
           xnew = x + p* alpha ; r=r - u*alpha;  d = diag_precon*r
           beta=dot_product(r,d)/up; p=d+p*beta
           converged = (maxval(abs(xnew-x))/maxval(abs(x)) < tol );  x=xnew
           if(converged .or. iters==limit) exit
     end do iterations
       write(11,'(a,i5)')"The number of iterations to convergence was  ",iters 
       write(11,'(a)')   "The nodal displacements are   :"
   do k=1,22; write(11,'(i5,a,3e12.4)') k,"    ",xnew(nf(:,k)); end do
!-------------------recover stresses at centroidal gauss-point-----------------
  nip=1;  deallocate(points,weights); allocate(points(nip,ndim),weights(nip))
  elements_3:do iel = 1, nels
                 num = g_num(: ,iel)  ; coord =transpose( g_coord(:,num)) 
                 g = g_g( : , iel )  ;     eld=xnew(g)
                 write(11,'(a,i5,a)')                                          &
                      "The Centroid point stresses for element",iel,"  are :"  
     gauss_pts_2: do i= 1 , nip 
       call shape_der(der,points,i); jac= matmul(der,coord)
       call invert (jac);   deriv= matmul(jac,der) ; call beemat(bee,deriv)
       eps   = matmul (bee,eld)  ; sigma = matmul (dee,eps)
       write(11,'(a,i5)') "Point  ",i   ; write(11,'(6e12.4)')  sigma
     end do gauss_pts_2 
  end do elements_3
 end program p510

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -