module fem use precision implicit none integer,private :: ndof=-1 !! -1 is flag for uninitialized real(PREC),allocatable :: Mat(:,:),Mat1(:,:),Mat2(:,:),Mat3(:,:),rhs(:) real(PREC),allocatable :: mesh(:) real(PREC),private :: dx real(PREC),private,parameter :: zero=0._PREC,one=1._PREC contains subroutine makemat(nin) integer,intent(in) :: nin integer :: n if (allocated(mesh)) stop 'fem: already allocated!' if (ndof>0) stop 'fem: n already defined!' ndof=nin allocate(mesh(ndof),Mat(ndof,ndof),Mat1(ndof,ndof),Mat2(ndof,ndof),Mat3(ndof,ndof)) dx=1.0_PREC/(ndof+1) mesh=(/ (dx*n,n=1,ndof) /) !! generate matrices do n=1,ndof Mat1(n,n)=-gaussquad(phip,n,phip,n,max(zero,(n-2)*dx),min(one,(n+2)*dx)); Mat2(n,n)=gaussquad(phi,n,phip,n,max(zero,(n-2)*dx),min(one,(n+2)*dx)); Mat3(n,n)=gaussquad(phi,n,phi,n,max(zero,(n-2)*dx),min(one,(n+2)*dx)); if (n0' xleft=a; xright=min(a+dx,b); len=xright-xleft; gaussquad=0; do if (len<= 100.0_PREC*epsilon(dx)*dx) exit xb=(xleft+xright)/2.0_PREC; xa=xb-len*quadpt; xc=xb+len*quadpt; gaussquad=gaussquad+ len*(wa*f1(k1,xa)*f2(k2,xa) + & & wb*f1(k1,xb)*f2(k2,xb) + & & wc*f1(k1,xc)*f2(k2,xc) ); xleft=xright; xright=min(xleft+dx,b); len=xright-xleft; enddo end function gaussquad end module fem