Chapter 4. Creating a Component from an Existing Library

$Revision: 1.34 $

$Date: 2004/08/26 16:41:26 $

Table of Contents

4.1. The legacy Fortran integrator
4.2. The FunctionModule wrapper.
4.3. Implementing the integrators.Midpoint component
4.4. SIDL definition of the Midpoint component
4.5. Fortran 90 implementation of the Midpoint integrator
4.5.1. The Midpoint module implementation
4.5.2. Defining the constructor and destructor
4.5.3. The setServices implementation
4.5.4. The integrate implementation
4.6. Building the Fortran 90 implementation of the integrators.Midpoint component.
4.7. Using your new integrators.Midpoint component

In this exercise, you will wrap an existing (“legacy”) software library as a CCA component (i.e. “componentize” it). The CCA is designed to make it as easy as possible to componentize existing software, and a significant fraction of CCA components are created in this way. While this specific example is minimal, the techniques used to produce a component that uses an existing library with minimal or no modifications to legacy code is applicable for large legacy codes.

The integrator components are Fortran90 wrappers over an existing legacy integrator library. For the purposes of this exercise, the legacy library is located in the student-src/legacy/f90 directory. The Integrator.f90 code implements a midpoint rule integration approach. Our goal is to create an integrator component that uses the legacy implementation to compute the integral of a function.

4.1. The legacy Fortran integrator

Our Fortran legacy library (in student-src/legacy/f90) contains an integration algorithm, which can be invoked as follows:

    call integrate_mp(functionParams, lowBound, upBound, count)

where functionParams is a variable of type FunctionParams_t. This type is used to store various function-specific attributes, such as the constant coefficients. The definition of this type is in the FunctionModule module, in the LegacyFunctionModule.f90 file:

file: student-src/legacy/f90/LegacyFunctionModule.f90
module FunctionModule
  implicit none

  type FunctionParams_t
     private
     real, dimension(3) :: coef 
  end type FunctionParams_t
    
contains

  subroutine init(params, coefficients)
    ! !INPUT PARAMETERS:
    type(FunctionParams_t), intent(INOUT) :: params
    real, dimension(:), intent(IN) :: coefficients
    
    integer :: i
    
    do i = 1 ,3
       params%coef(i) = coefficients(i)
    end do
    
  end subroutine init

  real function eval(params, x)

    ! !INPUT PARAMETERS:
    type(FunctionParams_t), intent(IN) :: params
    real, intent(IN)                   :: x
       
    eval = 2 * x

  end function eval  

end module FunctionModule

The legacy integrator (in Integrator.f90) uses the midpoint integration algorithm to integrate an arbitrary function that has an eval function and uses FunctionParams_t to store its state. The complete code for the legacy integrator follows.

file: student-src/legacy/f90/Integrator.f90
module Integrator
  use FunctionModule                                       (1)
  implicit none
    
contains
  
  real function integrate_mp(functionParams, lowBound, upBound, count)
    implicit none
    
    ! !INPUT PARAMETERS:
    
    type(FunctionParams_t),intent(IN) :: functionParams    (2)
    real,                  intent(IN) :: lowBound
    real,                  intent(IN) :: upBound
    integer,               intent(IN) :: count

    ! !LOCAL VARIABLES:
    real :: sum, h, x, dcount, func_val
    integer :: i

    integrate_mp = -1

    ! Compute integral
    sum = 0.0
    h = (upBound - lowBound) / count
           
    do i = 0, count 
       x = lowBound + h * (i + 0.5)
       func_val = eval(functionParams, x)                  (3)
       sum = sum + func_val
    end do
        
    integrate_mp = sum * h

  end function integrate_mp

end module Integrator

Notes on the Integrator.f90 file

1

The Integrator module uses the FunctionModule, which means that the integrator can only evaluate functions defined in this FunctionModule, or other Fortran modules that "extend" it.

2

The functionParamsargument of the integrator is the only way function parameters can be passed through to the function being evaluated.

3

This evaluates the function given the parameters passed into the Integrator.