MODULE int_procs USE local IMPLICIT NONE PUBLIC :: trap_simple, trap_int, romb_int REAL(r8), PUBLIC :: inte, a, b INTERFACE FUNCTION func(x) USE local IMPLICIT NONE REAL(r8) :: func REAL(r8), INTENT(IN) :: x END FUNCTION func END INTERFACE CONTAINS SUBROUTINE trap_simple(k) ! ! This routine calculates the kth refinement of the trapezoidal rule. ! USE local IMPLICIT NONE INTEGER(i8) :: i, i_max INTEGER(i4), INTENT(IN) :: k REAL(r8) :: sum, h_k_1, x ! Calculate new_sum to be averaged with the old RETURN END SUBROUTINE trap_simple SUBROUTINE trap_int(eps) ! ! This routine calculates the composite trapezoidal rule using the ! integrand func and the lower and upper limits of integration ! a and b until convergence set by eps is satisfied. ! USE local IMPLICIT NONE INTEGER(i4) :: i, max_div = 30 REAL(r8), INTENT(IN) :: eps REAL(r8) :: old_int ! Loop over successive approximations and check convergence old_int = 1.e-30 DO i=1,max_div CALL trap_simple(i) IF(abs(inte-old_int).le.eps*abs(old_int).or. & (abs(inte).lt.eps.and.i.gt.15)) RETURN old_int = inte END DO RETURN END SUBROUTINE trap_int SUBROUTINE romb_int(eps) ! ! This routine does Romberg integration using the integrand func and ! the lower and upper limits of integration a and b until convergence ! set by eps is satisfied. ! IMPLICIT NONE INTEGER(i4), PARAMETER :: max_div = 20 ! maximum divisions of [a,b] INTEGER(i4) :: k, m REAL(r8), INTENT(IN) :: eps REAL(r8), DIMENSION(max_div) :: h, int_arr REAL(r8) :: error, zero, r_int ! Outer loop yields next composite trapezoidal rule estimate DO k = 1,max_div ! Inner loop produces entire row of Romberg tableau DO i=1,k-1 IF(abs(error).le.eps*abs(r_int).or. & (abs(r_int).lt.eps.and.k.gt.15)) THEN inte = r_int RETURN ENDIF ENDDO ENDDO RETURN END SUBROUTINE romb_int END MODULE int_procs