previous up next print clean
Next: IMPLEMENTATION PROBLEMS: CAVEATS Up: BINDING C++ with FORTRAN90 Previous: C++ interface to a

C++ interface to a Fortran90 operator

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


previous up next print clean
Next: IMPLEMENTATION PROBLEMS: CAVEATS Up: BINDING C++ with FORTRAN90 Previous: C++ interface to a
Stanford Exploration Project
11/11/1997