After the Fortran 90 code has been generated by Babel, in student-src/components/integrators/f90, edit the Fortran module definition to define data that will be stored in each instance of this component:
file: student-src/components/integrators/f90/integrators_Midpoint_Mod.F90 #include"integrators_Midpoint_fAbbrev.h" module integrators_Midpoint_impl ! DO-NOT-DELETE splicer.begin(integrators.Midpoint.use) ! Insert use statements here... ! CCA framework services module use gov_cca_Services ! Use a "wrapper" module for the legacy FunctionModule module use FunctionModule! Use legacy Integrator module use Integrator
! DO-NOT-DELETE splicer.end(integrators.Midpoint.use) type integrators_Midpoint_priv sequence ! DO-NOT-DELETE splicer.begin(integrators.Midpoint.private_data) ! Handle to framework Services object type(gov_cca_Services_t) :: frameworkServices
! Function parameters (required by legacy integrator) type(FunctionParams_t) :: funcParams
! DO-NOT-DELETE splicer.end(integrators.Midpoint.private_data) end type integrators_Midpoint_priv type integrators_Midpoint_wrap sequence type(integrators_Midpoint_priv), pointer :: d_private_data end type integrators_Midpoint_wrap end module integrators_Midpoint_impl
Notes on the integrators_Midpoint_Mod.F90 file
![]() |
The integrators_Midpoint module uses the FunctionModule, which means that the integrator can only evaluate functions defined in this FunctionModule, or other Fortran modules that "extend" it. |
![]() |
This component stores a handle to the framework's Services object, equivalently to the way the Driver component was implemented in Step 2. |
![]() |
The legacy Integrator module is included. |
![]() |
The integrators.Midpoint component, like the legacy integrator (see Integrator.f90) requires that the function whose integral is to be computed provides its state via the FunctionParams_t type. |
In the same directory (student-src/components/integrators/f90), edit the integrators_Midpoint_Impl.F90 and insert the code between splicer blocks of the integrators_Midpoint__ctor_mi, integrators_Midpoint__dtor_mi, and setServices subroutines:
file: student-src/components/integrators/f90/integrators_Midpoint_Impl.F90 ... ! ! Class constructor called when the class is created. ! recursive subroutine integrators_Midpoint__ctor_mi(self) use integrators_Midpoint use integrators_Midpoint_impl ! DO-NOT-DELETE splicer.begin(integrators.Midpoint._ctor.use) ! Insert use statements here... ! DO-NOT-DELETE splicer.end(integrators.Midpoint._ctor.use) implicit none type(integrators_Midpoint_t) :: self ! in ! DO-NOT-DELETE splicer.begin(integrators.Midpoint._ctor) ! Insert the implementation here... ! Access private data type(integrators_Midpoint_wrap) :: dp ! Allocate memory and initialize allocate(dp%d_private_data) call set_null(dp%d_private_data%frameworkServices) call integrators_Midpoint__set_data_m(self, dp) ! DO-NOT-DELETE splicer.end(integrators.Midpoint._ctor) end subroutine integrators_Midpoint__ctor_mi ! ! Class destructor called when the class is deleted. ! recursive subroutine integrators_Midpoint__dtor_mi(self) use integrators_Midpoint use integrators_Midpoint_impl ! DO-NOT-DELETE splicer.begin(integrators.Midpoint._dtor.use) ! Insert use statements here... ! DO-NOT-DELETE splicer.end(integrators.Midpoint._dtor.use) implicit none type(integrators_Midpoint_t) :: self ! in ! DO-NOT-DELETE splicer.begin(integrators.Midpoint._dtor) ! Insert the implementation here... ! Access private data and deallocate storage type(integrators_Midpoint_wrap) :: dp call integrators_Midpoint__get_data_m(self, dp) ! Decrement reference count for framework services handle if (not_null(dp%d_private_data%frameworkServices)) then call deleteRef(dp%d_private_data%frameworkServices) end if deallocate(dp%d_private_data) ! DO-NOT-DELETE splicer.end(integrators.Midpoint._dtor) end subroutine integrators_Midpoint__dtor_mi
In this step we continue to edit the student-src/components/integrators/f90/integrators_Midpoint_Impl.F90 file, adding the implementation of the setServices subroutine, which is part of the gov.cca.Component. Note that in order to accommodate identifier length restriction in Fortran (31 characters), the name of the subroutine was automatically shortened by Babel. The unmangled name is always visible in the comment preceding the subroutine in the Fortran generated code.
...
recursive subroutine Midpoi_setServices6_m9htaw4m_mi(self, services, &
exception)
use sidl_BaseInterface
use integrators_Midpoint
use gov_cca_Services
use gov_cca_CCAException
use integrators_Midpoint_impl
! DO-NOT-DELETE splicer.begin(integrators.Midpoint.setServices.use)
! Insert use statements here...
use gov_cca_TypeMap
use gov_cca_Port
use SIDL_BaseInterface
! DO-NOT-DELETE splicer.end(integrators.Midpoint.setServices.use)
implicit none
type(integrators_Midpoint_t) :: self ! in
type(gov_cca_Services_t) :: services ! in
type(sidl_BaseInterface_t) :: exception ! out
! DO-NOT-DELETE splicer.begin(integrators.Midpoint.setServices)
! Insert the implementation here...
type(gov_cca_TypeMap_t) :: myTypeMap
type(gov_cca_Port_t) :: integratorPort
type(SIDL_BaseInterface_t) :: excpt
! Access private data
type(integrators_Midpoint_wrap) :: dp
call integrators_Midpoint__get_data_m(self, dp)
! Set my reference to the services handle
dp%d_private_data%frameworkServices = services
call addRef(services)
! Create a TypeMap with my properties
call createTypeMap(dp%d_private_data%frameworkServices, myTypeMap, excpt)
call checkExceptionMid(excpt, 'setServices createTypeMap call')
call cast(self, integratorPort)
! Register my provides port
call addProvidesPort(dp%d_private_data%frameworkServices, integratorPort, &
'IntegratorPort', 'integrator.IntegratorPort', &
myTypeMap, excpt)
call checkExceptionMid(excpt, 'setServices addProvidesPort: IntegratorPort')
! The ports I use
call registerUsesPort(dp%d_private_data%frameworkServices, &
'FunctionPort', 'function.FunctionPort', &
myTypeMap, excpt)
call checkExceptionMid(excpt, 'setServices registerUsesPort: FunctionPort')
call deleteRef(myTypeMap)
! DO-NOT-DELETE splicer.end(integrators.Midpoint.setServices)
end subroutine Midpoi_setServices6_m9htaw4m_mi
Continuing your edits in the integrators_Midpoint_Impl.F90 file, fill in the implementation of the integrator.IntegratorPort interface component, inserting the call to the legacy integrator in the integrate method.
file: student-src/components/integrators/f90/integrators_Midpoint_Impl.F90
recursive subroutine Midpoint_integrateekg4n6wqha_mi(self, lowBound, upBound, &
count, retval)
use integrators_Midpoint
use integrators_Midpoint_impl
! DO-NOT-DELETE splicer.begin(integrators.Midpoint.integrate.use)
! Insert use statements here...
use function_FunctionPort
use randomgen_RandomGeneratorPort
use gov_cca_Services
use gov_cca_Port
use sidl_BaseInterface
use Integrator ! Legacy integrator module
use FunctionModule ! Legacy function module wrapper
! DO-NOT-DELETE splicer.end(integrators.Midpoint.integrate.use)
implicit none
type(integrators_Midpoint_t) :: self ! in
real (selected_real_kind(15, 307)) :: lowBound ! in
real (selected_real_kind(15, 307)) :: upBound ! in
integer (selected_int_kind(9)) :: count ! in
real (selected_real_kind(15, 307)) :: retval ! out
! DO-NOT-DELETE splicer.begin(integrators.Midpoint.integrate)
! Insert the implementation here...
type(gov_cca_Port_t) :: generalPort
type(function_FunctionPort_t) :: functionPort
type(randomgen_RandomGeneratorPort_t) :: randomPort
type(SIDL_BaseInterface_t) :: excpt
! Legacy types and wrappers:
type(FunctionParams_t) :: funParams
! Private data reference
type(integrators_Midpoint_wrap) :: dp
! Copies of base type arguments to the integrate method
real :: lbnd, ubnd
integer :: cnt
real (selected_real_kind(15, 307)) :: sum, width, x, func
integer (selected_int_kind(9)) :: i
! Access private data
call integrators_Midpoint__get_data_m(self, dp)
retval = -1
if (not_null(dp%d_private_data%frameworkServices)) then
! Obtain a handle to a FunctionPort
call getPort(dp%d_private_data%frameworkServices, &
'FunctionPort', generalPort, excpt)
if (is_null(excpt)) then
call cast(generalPort, functionPort)
if (not_null(functionPort)) then
! Set the function port in the FunctionModule wrapper
call setFunctionPort(funParams, functionPort)
! Invoke legacy integrator algorithm to compute integral
lbnd = lowBound
ubnd = upBound
cnt = count
retval = integrate_mp(funParams, lbnd, ubnd, cnt)
else ! functionPort is null
write(*,*) 'Exception: Midpoint: incompatible FunctionPort'
endif
! Free ports
call releasePort(dp%d_private_data%frameworkServices, &
'FunctionPort', excpt)
call checkExceptionMid(excpt, 'releasePort(''FunctionPort'')')
else ! excpt is not null
call checkExceptionMid(excpt, 'getPort(''FunctionPort'')')
endif
else ! frameworkServices is null
write(*,*) 'Error: Midpoint: integrate called before setServices'
endif
! DO-NOT-DELETE splicer.end(integrators.Midpoint.integrate)
end subroutine Midpoint_integrateekg4n6wqha_mi
Finally, in the integrators_Midpoint_Impl.F90 file, find the very last splicer block (labeled _miscellaneous_code_end) and add the following helper subroutine:
file: student-src/components/integrators/f90/integrators_Midpoint_Impl.F90
!
! Small routine (not part of the SIDL interface) for
! checking the exception and printing the message passed as
! and argument
!
subroutine checkExceptionMid(excpt, msg)
use SIDL_BaseInterface
use gov_cca_CCAException
implicit none
type(sidl_BaseInterface_t), intent(inout) :: excpt
character (len=*) :: msg ! in
if (not_null(excpt)) then
write(*, *) 'integrators.Midpoint Exception: ', msg
call deleteRef(excpt)
end if
end subroutine checkExceptionMid