To operate on the Fortran90 data structures we must write our
operators in Fortran90 and provide them with a C++ encapsulation. As
an example of a C++/Fortran90 interface, consider the public
definitions of the IGF90_LinInterpOp class header:
#include "HCL_LinearOp.h"
class IGF90_LinInterpOp: public HCL_LinearOp {
public:
IGF90_LinInterpOp( IGF90Space *dom, IGF90Space *ran,
int ky1=1, int ky2=2 );
~IGF90_LinInterpOp();
HCL_VectorSpace & Domain() const;
HCL_VectorSpace & Range() const;
virtual void Image( const HCL_Vector & xx, HCL_Vector & yy ) const;
... // I/O
};
An instance of this class is constructed from a domain and a range
vector spaces, and from two header keys, along which the linear
interpolation will take place. The member functions Domain()
and Range()
return a pointer to the operator's domain and range
vector spaces respectively. The Image()
member function is a
virtual function inherited from the base class HCL_LinearOp. It
implements the forward mapping of the operator, by calling a Fortran90
subroutine, as shown below:
#include "IGF90_LinInterpOp.h"
extern "C" f90_linear_interp2d_(int &adjf, HANDLE, HANDLE,
const int &key1, const int &key2) ;
extern "C" int sep90_simple_check_(HANDLE, HANDLE);
void IGF90_LinInterpOp::Image( const HCL_Vector & xx,HCL_Vector & yy ) const
{
if (sep90_simple_check_( ((IGF90 &) xx).GetOpaque(),
((IGF90Space &) Domain()).GetOpaque() ) != 1 ) {
cerr << "ERROR: LinInterpOp: IGF90 vector is not in domain" <<endl;
exit(1);
}
IGF90 & x = (IGF90&) xx;
if (sep90_simple_check_( ((IGF90 &) yy).GetOpaque(),
((IGF90Space &) Range()).GetOpaque() ) != 1 ) {
cerr << "ERROR: LinInterpOp: IGF90 vector is not in range" <<endl;
exit(1);
}
IGF90 & y = (IGF90&) yy;
int adjf =0;
f90_linear_interp2d_( adjf, x.GetOpaque(), y.GetOpaque(), key1, key2 );
}
The Image()
member function checks the vector spaces of the
input and output vectors being passed versus the domain and range
vector spaces given at construction time. The member function
GetOpaque()
returns the opaque_f90_handle
pointers to
the Fortran90 data structures. The Fortran90 subroutine
sep90_simple_check
does the space comparisons. Finally, we
provide a Fortran90 wrapper, f90_linear_interp2d
, that makes
the appropiate calls to the the Fortran90 linear_interp2d_mod
module.
Clapp and Crawley (1996):
subroutine f90_linear_interp2d(adj,model,data,key1_in,key2_in)
use linear_interp2d_mod
integer :: adj
type(sep_90),pointer :: model, data
integer :: key1_in, key2_in
call interp2dinitn(model,data,key1_in, key2_in)
call linear_interp2d(adj==1, model, data)
return
end subroutine