! fem_checke_la.f90 Galerkin FEM ! solve u'(x)=e^x u(0)=1, u(1)=e 0 < x < 1 ! initial try 10 points ! investigate gauss-legendre, adaptive, and trapezoidal integration ! solve for Uj ! sum j=0,9 int x=0,1 phip(x,j)*phi(x,i) dx = int x=0,1 f(x)*phi(x,i)dx ! k(i,j) = int x=0,1 phip(x,j)*phi(x,i) dx (not i==0 or i==9, boundary) ! f(i) = int x=0,1 exp(x)*phi(x,i) dx ! k * U = f, solve simultaneous equations for U module global implicit none integer, parameter :: n=10 double precision, dimension(n,n) :: k ! (i,j) Gauss-Legendre integration double precision, dimension(n,n) :: ks ! simple trapazoidal integration double precision, dimension(n,n) :: kd! adaptive integration double precision, dimension(n) :: xg double precision, dimension(n) :: f double precision, dimension(n) :: u double precision, dimension(n) :: fs double precision, dimension(n) :: us double precision, dimension(n) :: fd double precision, dimension(n) :: ud double precision, dimension(n) :: Ua double precision :: xmin = 0.0 double precision :: xmax = 1.0 double precision :: h, a, b double precision, dimension(100) :: xx ! for Gauss-Legendre double precision, dimension(100) :: ww double precision :: val, err, avgerr, maxerr double precision :: eps = 1.0e-6 integer :: p, np interface function FF(x) result(y) ! forcing function double precision, intent(in) :: x double precision :: y end function FF function uana(x) result(y) ! analytic solution and boundary double precision, intent(in) :: x double precision :: y end function uana subroutine simeq(n, sz, A, Y, X) integer, intent(in) :: n ! number of equations integer, intent(in) :: sz ! dimension of arrays double precision, dimension(sz,sz), intent(in) :: A double precision, dimension(sz), intent(in) :: Y double precision, dimension(sz), intent(out) :: X end subroutine simeq subroutine gaulegf(x1, x2, x, w, n) integer, intent(in) :: n double precision, intent(in) :: x1, x2 double precision, dimension(n), intent(out) :: x, w end subroutine gaulegf function aquad3e(f, xmin, xmax, eps, i, j) result(integral) double precision, intent(in) :: xmin, xmax, eps integer, intent(in) :: i,j double precision :: integral interface function f(x,i,j) result(y) double precision, intent(in) :: x integer, intent(in) :: i,j double precision :: y end function f end interface end function aquad3e end interface end module global ! functions called by program function FF(x) result(y) ! forcing function implicit none double precision, intent(in) :: x double precision :: y y = exp(x) end function FF function uana(x) result(y) ! analytic solution and boundary implicit none double precision, intent(in) :: x double precision :: y y = exp(x) end function uana function galk(x, i, j) result(y) ! Galerkin k stiffness function for this specific problem use global use laphi implicit none double precision, intent(in) :: x integer, intent(in) :: i, j double precision :: y y = phip(x,j,n,xg)*phi(x,i,n,xg) end function galk function galf(x, i, j) result(y) ! Galerkin f function use global use laphi implicit none double precision, intent(in) :: x integer, intent(in) :: i, j ! j unused yet needed due to galk double precision :: y y = FF(x)*phi(x,i,n,xg) end function galf program fem_checke_la use global use laphi implicit none integer :: i, j interface function galk(x, i, j) result(y) double precision, intent(in) :: x integer, intent(in) :: i, j double precision :: y end function galk function galf(x, i, j) result(y) double precision, intent(in) :: x integer, intent(in) :: i, j double precision :: y end function galf end interface print *, 'fem_checke_la.f90 running' print *, 'Given du/dx = exp(x) 0maxerr) then maxerr = err end if avgerr = avgerr + err print *, 'u(',i,')=',u(i),', Ua=',Ua(i),', err=',(u(i)-Ua(i)) end do print *, ' maxerr=',maxerr,', avgerr=',avgerr/n print *, ' ' print *, 'kd computed adaptive stiffness matrix' do i=1,n do j=1,n print *, 'i=',i,', j=',j,', kd(i,j)=',kd(i,j) end do end do print *, ' ' print *, 'fd computed forcing function' do i=1,n print *, 'fd(',i,')=',fd(i) end do print *, ' ' call simeq(n, n, kd, fd, ud) avgerr = 0.0 maxerr = 0.0 print *, 'ud computed Galerkin, Ua analytic, error' do i=1,n err = abs(ud(i)-Ua(i)) if(err>maxerr) then maxerr = err end if avgerr = avgerr + err print *, 'ud(',i,')=',ud(i),', Ua=',Ua(i),', err=',(ud(i)-Ua(i)) end do print *, ' maxerr=',maxerr,', avgerr=',avgerr/n print *, ' ' print *, 'ks computed simple stiffness matrix' do i=1,n do j=1,n print *, 'i=',i,', j=',j,', ks(i,j)=',ks(i,j) end do end do print *, ' ' print *, 'fs computed forcing function' do i=1,n print *, 'fs(',i,')=',fs(i) end do print *, ' ' call simeq(n, n, ks, fs, us) avgerr = 0.0 maxerr = 0.0 print *, 'us computed Galerkin, Ua analytic, error' do i=1,n err = abs(us(i)-Ua(i)) if(err>maxerr) then maxerr = err end if avgerr = avgerr + err print *, 'us(',i,')=',us(i),', Ua=',Ua(i),', err=',(us(i)-Ua(i)) end do print *, ' maxerr=',maxerr,', avgerr=',avgerr/n print *, ' ' end program fem_checke_la