tools/FortranCPP.hpp
Go to the documentation of this file.
00001 /*
00002 
00003   This file is part of OpenFLUID software
00004   Copyright(c) 2007, INRA - Montpellier SupAgro
00005 
00006 
00007  == GNU General Public License Usage ==
00008 
00009   OpenFLUID is free software: you can redistribute it and/or modify
00010   it under the terms of the GNU General Public License as published by
00011   the Free Software Foundation, either version 3 of the License, or
00012   (at your option) any later version.
00013 
00014   OpenFLUID is distributed in the hope that it will be useful,
00015   but WITHOUT ANY WARRANTY; without even the implied warranty of
00016   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017   GNU General Public License for more details.
00018 
00019   You should have received a copy of the GNU General Public License
00020   along with OpenFLUID. If not, see <http://www.gnu.org/licenses/>.
00021 
00022 
00023  == Other Usage ==
00024 
00025   Other Usage means a use of OpenFLUID that is inconsistent with the GPL
00026   license, and requires a written agreement between You and INRA.
00027   Licensees for Other Usage of OpenFLUID may use this file in accordance
00028   with the terms contained in the written agreement between You and INRA.
00029   
00030 */
00031 
00032 
00033 
00034 /**
00035   @file
00036 
00037   @author JC.Fabre <fabrejc@supagro.inra.fr>, C.Dagès <dages@supagro.inra.fr>
00038 
00039 
00040   @see http://www-h.eng.cam.ac.uk/help/tpl/languages/mixinglanguages.html
00041   @see http://www.neurophys.wisc.edu/comp/docs/notes/not017.html
00042   @see http://www.yolinux.com/TUTORIALS/LinuxTutorialMixingFortranAndC.html
00043   @see http://arnholm.org/software/cppf77/cppf77.htm
00044   @see http://www.aei.mpg.de/~jthorn/c2f.html
00045 
00046   Below are examples of C++ simulators calling Fortran subroutines.
00047 
00048 
00049   fortran source code:
00050   @code
00051 subroutine multrealvalue(value,mult,result)
00052 
00053 implicit none
00054 real*8 value
00055 real*8 mult
00056 real*8 result
00057 
00058 result=value*mult
00059 
00060 return
00061 
00062 end
00063 
00064 
00065 ! ==============================================================================
00066 
00067 
00068 subroutine multintvalue(value,mult,result)
00069 
00070 implicit none
00071 integer value
00072 integer mult
00073 integer result
00074 
00075 result=value*mult
00076 
00077 return
00078 end
00079 
00080 
00081 ! ==============================================================================
00082 
00083 
00084 subroutine multrealmatrix(matrix,dim1,dim2,mult,result)
00085 
00086 implicit none
00087 integer dim1
00088 integer dim2
00089 real*8 matrix(dim2,dim1)
00090 integer mult
00091 real*8 result(dim2,dim1)
00092 integer i, j, k
00093 subroutine multrealvalue(value,mult,result)
00094 
00095 implicit none
00096 real*8 value
00097 real*8 mult
00098 real*8 result
00099 
00100 result=value*mult
00101 
00102 return
00103 
00104 end
00105 
00106 
00107 ! ==============================================================================
00108 
00109 
00110 subroutine multintvalue(value,mult,result)
00111 
00112 implicit none
00113 integer value
00114 integer mult
00115 integer result
00116 
00117 result=value*mult
00118 
00119 return
00120 end
00121 
00122 
00123 ! ==============================================================================
00124 
00125 
00126 subroutine multrealmatrix(matrix,dim1,dim2,mult,result)
00127 
00128 implicit none
00129 integer dim1
00130 integer dim2
00131 real*8 matrix(dim2,dim1)
00132 integer mult
00133 real*8 result(dim2,dim1)
00134 integer i, j, k
00135 
00136 do j=1,dim1
00137   do i=1,dim2
00138     result(i,j) = matrix(i,j) * mult
00139   end do
00140 end do
00141 
00142 
00143 return
00144 end
00145 
00146 do j=1,dim1
00147   do i=1,dim2
00148     result(i,j) = matrix(i,j) * mult
00149   end do
00150 end do
00151 
00152 
00153 return
00154 end
00155 
00156 @endcode
00157 
00158 
00159 C++ code calling fortran subroutines:
00160 @code
00161 BEGIN_EXTERN_FORTRAN
00162   EXTERN_FSUBROUTINE(multrealvalue)(FREAL8*,FREAL8*,FREAL8*);
00163   EXTERN_FSUBROUTINE(multintvalue)(FINT*,FINT*,FINT*);
00164   EXTERN_FSUBROUTINE(multrealmatrix)(FREAL8*,FINT*,FINT*,FINT*,FREAL8*);
00165 END_EXTERN_FORTRAN
00166 
00167 // =====================================================================
00168 // =====================================================================
00169 
00170 bool FortranFunction::runStep(const openfluid::base::SimulationStatus* SimStatus)
00171 {
00172   int i;
00173 
00174 
00175   // ====== double ======
00176 
00177   double DValue, DMult, DResult;
00178   DValue = 1.5436;
00179   DMult = 2.5;
00180   DResult = 0.0;
00181 
00182   CALL_FSUBROUTINE(multrealvalue)(&DValue,&DMult,&DResult);
00183 
00184   if (abs(DResult - (DValue*DMult)) > m_Precision)
00185     OPENFLUID_RaiseError("tests.fortran","incorrect fortran call (multrealvalue)");
00186 
00187 
00188   // ====== int ======
00189 
00190   int IValue, IMult, IResult;
00191   IValue = 45;
00192   IMult = 18;
00193   IResult = 0;
00194 
00195   CALL_FSUBROUTINE(multintvalue)(&IValue,&IMult,&IResult);
00196 
00197   if (IResult != (IValue*IMult))
00198     OPENFLUID_RaiseError("tests.fortran","incorrect fortran call (multintvalue)");
00199 
00200 
00201   // ====== matrix of double ======
00202 
00203   int MMult, MDim1,MDim2;
00204   double *MValue;
00205   double *MResult;
00206   MMult = 3;
00207   MDim1 = 2;
00208   MDim2 = 3;
00209 
00210 
00211   MValue = new double[MDim1*MDim2];
00212   MResult = new double[MDim1*MDim2];
00213 
00214   for (i=0; i < MDim1*MDim2;i++) MValue[i] = 1.5;
00215   for (i=0; i < MDim1*MDim2;i++) MResult[i] = 0.0;
00216 
00217   CALL_FSUBROUTINE(multrealmatrix)(MValue,&MDim1,&MDim2,&MMult,MResult);
00218 
00219   for (i=0; i < MDim1*MDim2;i++)
00220   {
00221     if (abs(MResult[i] - (MValue[i] * MMult)) > m_Precision)
00222       OPENFLUID_RaiseError("tests.fortran","incorrect fortran call (multrealmatrix)");
00223   }
00224 
00225   return true;
00226 }
00227 
00228 @endcode
00229 
00230 */
00231 
00232 
00233 
00234 
00235 #ifndef __FORTRAN2CPP_HPP__
00236 #define __FORTRAN2CPP_HPP__
00237 
00238 
00239 #ifdef __cplusplus
00240 #  define BEGIN_EXTERN_FORTRAN \
00241    extern "C" \
00242    {
00243 #  define END_EXTERN_FORTRAN }
00244 #else
00245 #  define BEGIN_EXTERN_FORTRAN
00246 #  define END_EXTERN_FORTRAN
00247 #endif
00248 
00249 // =====================================================================
00250 // =====================================================================
00251 
00252 
00253 // calling function or subroutine from a F90 module
00254 
00255 /**
00256   Macro for declaration of an external fortran function
00257   @param[in] x the name of the function
00258 */
00259 #define EXTERN_FFUNCTION(x) x##_
00260 
00261 /**
00262   Macro for calling an external fortran function
00263   @param[in] x the name of the function
00264 */
00265 #define CALL_FFUNCTION(x) x##_
00266 
00267 /**
00268   Macro for declaration of an external fortran subroutine
00269   @param[in] x the name of the subroutine
00270 */
00271 #define EXTERN_FSUBROUTINE(x) void x##_
00272 
00273 /**
00274   Macro for calling an external fortran subroutine
00275   @param[in] x the name of the subroutine
00276 */
00277 #define CALL_FSUBROUTINE(x) x##_
00278 
00279 
00280 // =====================================================================
00281 // =====================================================================
00282 
00283 
00284 /**
00285   Macro for declaration of an external fortran90 function in a module
00286   @param[in] x the name of the module
00287   @param[in] y the name of the function
00288 */
00289 #define EXTERN_FMODFUNCTION(x,y) __##x##__##y
00290 
00291 /**
00292   Macro for calling an external fortran90 function in a module
00293   @param[in] x the name of the module
00294   @param[in] y the name of the function
00295 */
00296 #define CALL_FMODFUNCTION(x,y) __##x##__##y
00297 
00298 /**
00299   Macro for declaration of an external fortran90 subroutine in a module
00300   @param[in] x the name of the module
00301   @param[in] y the name of the subroutine
00302 */
00303 #define EXTERN_FMODSUBROUTINE(x,y) void __##x##__##y
00304 
00305 /**
00306   Macro for calling an external fortran90 subroutine in a module
00307   @param[in] x the name of the module
00308   @param[in] y the name of the subroutine
00309 */
00310 #define CALL_FMODSUBROUTINE(x,y) __##x##__##y
00311 
00312 // =====================================================================
00313 // =====================================================================
00314 
00315 
00316 // Numeric data handling
00317 
00318 /**
00319   Macro for fortran REAL type in C++ (float)
00320 */
00321 #define FREAL float
00322 
00323 /**
00324   Macro for fortran REAL type in C++ (double)
00325 */
00326 #define FREAL8 double
00327 
00328 #define FREAL16 long double
00329 
00330 /**
00331   Macro for fortran INT type in C++ (int)
00332 */
00333 #define FINT int
00334 
00335 /**
00336   Macro for fortran INT*2 type in C++ (short int)
00337 */
00338 #define FINT2 short int
00339 
00340 /**
00341   Macro for fortran INT*8 type in C++ (long int)
00342 */
00343 #define FINT8 long int
00344 
00345 #define FLOGICAL int
00346 #define FLOGICAL1 bool
00347 
00348 // =====================================================================
00349 // =====================================================================
00350 
00351 // Character and string handling
00352 
00353 #define FCHARACTER char
00354 
00355 #define FSTRING char*
00356 #define FSTRINGLEN int
00357 
00358 // =====================================================================
00359 // =====================================================================
00360 
00361 
00362 // Conversion of std::string
00363 
00364 #define STD2FSTRING(str) strdup((str).c_str())
00365 #define STD2FSTRINGLEN(str) strlen((str).c_str())
00366 #define STD2FSTRINGFULL(str) strdup((str).c_str()),strlen((str).c_str())
00367 
00368 
00369 #endif /*__FORTRAN2CPP_H__*/
00370 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines