00001 #include "DoubleVector.h" 00002 #include "VectorFunction.h" 00003 00004 #ifndef __FORTRAN_ODE_FUNCTION__ 00005 #define __FORTRAN_ODE_FUNCTION__ 00006 // 00007 //##################################################################### 00008 // fortranODEfunction.h 00009 //##################################################################### 00010 // 00011 // Class fortranODEfunction Declaration 00012 // 00013 //##################################################################### 00014 /** 00015 \class fortranODEfunction 00016 00017 \brief A wrapper class for a VectorFunction instance that 00018 allows its evaluate(...) method to be accessed using a 00019 function prototype of the form <code> int (*f)(double*t, double*y, double*yp)</code>. 00020 00021 <p> 00022 This function prototype is that required by the f2c translation of 00023 rkf45, a Runge-Kutta-Fehlberg 45 implementation. 00024 00025 <p>Since the VectorFunction class has no explicit t dependence, the t argument 00026 is ignored in the evaluation process. 00027 00028 <p> yp is determined from y using the evaluate member function 00029 of the associated VectorFunction. 00030 00031 <p> 00032 <p> Typical use: <br> 00033 <OL> 00034 <LI> Set the dimension </LI> 00035 <LI> Set the associated VectorFunction (or class derived from VectorFunction)</LI> 00036 <LI> Pass the function fortranODEfunction::f to the external routine.</LI> 00037 </OL> 00038 00039 <p> Samples of setting the dimension and setting the function are 00040 <pre> 00041 fortranODEfunction::setDimension(2); 00042 fortranODEfunction::setFunction(&F); 00043 </pre> 00044 00045 <p> The function fortranODEfunction::f has type 00046 <code> int (*f)(double*, double*, double*) </code> and so 00047 00048 <pre> fortranODEfunction::f </pre> 00049 00050 may be passed to function whose argument is a function pointer of that type. 00051 00052 <p> Fortran routines require that the member function of a 00053 class passed into it be a static member function, hence there can only one 00054 instance of this class in use in a specific program. 00055 00056 */ 00057 //##################################################################### 00058 // Chris Anderson (C) UCLA Jan. 22, 2009 00059 //##################################################################### 00060 // 00061 class fortranODEfunction 00062 { 00063 public : 00064 00065 static VectorFunction* fODE; 00066 00067 static int f(double* /* t */, double*y, double*yp) 00068 { 00069 static long i; 00070 00071 for(i =0; i < Vin.getSize(); i++) // pack y data into Vin 00072 {Vin(i) = y[i];} 00073 00074 Vout = fODE->evaluate(Vin); // evaluate 00075 00076 for(i =0; i < Vout.getSize(); i++)// pack Vout data into yp 00077 {yp[i] = Vout(i);} 00078 00079 return 0; 00080 } 00081 00082 /// Sets the dimension of the VectorFunction argument. 00083 00084 static void setDimension(long idim) 00085 {Vin.initialize(idim); Vout.initialize(idim);} 00086 00087 /// Sets the VectorFunction instance whose evaluate(...) member function will be called. 00088 static void setFunction(VectorFunction* Fptr) 00089 {fODE = Fptr;} 00090 00091 static DoubleVector Vin; 00092 static DoubleVector Vout; 00093 }; 00094 #endif