All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FortranCPP.hpp
Go to the documentation of this file.
1 /*
2 
3  This file is part of OpenFLUID software
4  Copyright(c) 2007, INRA - Montpellier SupAgro
5 
6 
7  == GNU General Public License Usage ==
8 
9  OpenFLUID is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  OpenFLUID is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with OpenFLUID. If not, see <http://www.gnu.org/licenses/>.
21 
22 
23  == Other Usage ==
24 
25  Other Usage means a use of OpenFLUID that is inconsistent with the GPL
26  license, and requires a written agreement between You and INRA.
27  Licensees for Other Usage of OpenFLUID may use this file in accordance
28  with the terms contained in the written agreement between You and INRA.
29 
30 */
31 
32 
33 
34 /**
35  @file
36 
37  @author JC.Fabre <fabrejc@supagro.inra.fr>, C.Dagès <dages@supagro.inra.fr>
38 
39 
40  @see http://www-h.eng.cam.ac.uk/help/tpl/languages/mixinglanguages.html
41  @see http://www.neurophys.wisc.edu/comp/docs/notes/not017.html
42  @see http://www.yolinux.com/TUTORIALS/LinuxTutorialMixingFortranAndC.html
43  @see http://arnholm.org/software/cppf77/cppf77.htm
44  @see http://www.aei.mpg.de/~jthorn/c2f.html
45 
46  Below are examples of C++ simulators calling Fortran subroutines.
47 
48 
49  fortran source code:
50  @code
51 subroutine multrealvalue(value,mult,result)
52 
53 implicit none
54 real*8 value
55 real*8 mult
56 real*8 result
57 
58 result=value*mult
59 
60 return
61 
62 end
63 
64 
65 ! ==============================================================================
66 
67 
68 subroutine multintvalue(value,mult,result)
69 
70 implicit none
71 integer value
72 integer mult
73 integer result
74 
75 result=value*mult
76 
77 return
78 end
79 
80 
81 ! ==============================================================================
82 
83 
84 subroutine multrealmatrix(matrix,dim1,dim2,mult,result)
85 
86 implicit none
87 integer dim1
88 integer dim2
89 real*8 matrix(dim2,dim1)
90 integer mult
91 real*8 result(dim2,dim1)
92 integer i, j, k
93 subroutine multrealvalue(value,mult,result)
94 
95 implicit none
96 real*8 value
97 real*8 mult
98 real*8 result
99 
100 result=value*mult
101 
102 return
103 
104 end
105 
106 
107 ! ==============================================================================
108 
109 
110 subroutine multintvalue(value,mult,result)
111 
112 implicit none
113 integer value
114 integer mult
115 integer result
116 
117 result=value*mult
118 
119 return
120 end
121 
122 
123 ! ==============================================================================
124 
125 
126 subroutine multrealmatrix(matrix,dim1,dim2,mult,result)
127 
128 implicit none
129 integer dim1
130 integer dim2
131 real*8 matrix(dim2,dim1)
132 integer mult
133 real*8 result(dim2,dim1)
134 integer i, j, k
135 
136 do j=1,dim1
137  do i=1,dim2
138  result(i,j) = matrix(i,j) * mult
139  end do
140 end do
141 
142 
143 return
144 end
145 
146 do j=1,dim1
147  do i=1,dim2
148  result(i,j) = matrix(i,j) * mult
149  end do
150 end do
151 
152 
153 return
154 end
155 
156 @endcode
157 
158 
159 C++ code calling fortran subroutines:
160 @code
161 BEGIN_EXTERN_FORTRAN
162  EXTERN_FSUBROUTINE(multrealvalue)(FREAL8*,FREAL8*,FREAL8*);
163  EXTERN_FSUBROUTINE(multintvalue)(FINT*,FINT*,FINT*);
164  EXTERN_FSUBROUTINE(multrealmatrix)(FREAL8*,FINT*,FINT*,FINT*,FREAL8*);
165 END_EXTERN_FORTRAN
166 
167 // =====================================================================
168 // =====================================================================
169 
170 bool FortranFunction::runStep(const openfluid::base::SimulationStatus* SimStatus)
171 {
172  int i;
173 
174 
175  // ====== double ======
176 
177  double DValue, DMult, DResult;
178  DValue = 1.5436;
179  DMult = 2.5;
180  DResult = 0.0;
181 
182  CALL_FSUBROUTINE(multrealvalue)(&DValue,&DMult,&DResult);
183 
184  if (abs(DResult - (DValue*DMult)) > m_Precision)
185  OPENFLUID_RaiseError("tests.fortran","incorrect fortran call (multrealvalue)");
186 
187 
188  // ====== int ======
189 
190  int IValue, IMult, IResult;
191  IValue = 45;
192  IMult = 18;
193  IResult = 0;
194 
195  CALL_FSUBROUTINE(multintvalue)(&IValue,&IMult,&IResult);
196 
197  if (IResult != (IValue*IMult))
198  OPENFLUID_RaiseError("tests.fortran","incorrect fortran call (multintvalue)");
199 
200 
201  // ====== matrix of double ======
202 
203  int MMult, MDim1,MDim2;
204  double *MValue;
205  double *MResult;
206  MMult = 3;
207  MDim1 = 2;
208  MDim2 = 3;
209 
210 
211  MValue = new double[MDim1*MDim2];
212  MResult = new double[MDim1*MDim2];
213 
214  for (i=0; i < MDim1*MDim2;i++) MValue[i] = 1.5;
215  for (i=0; i < MDim1*MDim2;i++) MResult[i] = 0.0;
216 
217  CALL_FSUBROUTINE(multrealmatrix)(MValue,&MDim1,&MDim2,&MMult,MResult);
218 
219  for (i=0; i < MDim1*MDim2;i++)
220  {
221  if (abs(MResult[i] - (MValue[i] * MMult)) > m_Precision)
222  OPENFLUID_RaiseError("tests.fortran","incorrect fortran call (multrealmatrix)");
223  }
224 
225  return true;
226 }
227 
228 @endcode
229 
230 */
231 
232 
233 
234 
235 #ifndef __FORTRAN2CPP_HPP__
236 #define __FORTRAN2CPP_HPP__
237 
238 
239 #ifdef __cplusplus
240 # define BEGIN_EXTERN_FORTRAN \
241  extern "C" \
242  {
243 # define END_EXTERN_FORTRAN }
244 #else
245 # define BEGIN_EXTERN_FORTRAN
246 # define END_EXTERN_FORTRAN
247 #endif
248 
249 // =====================================================================
250 // =====================================================================
251 
252 
253 // calling function or subroutine from a F90 module
254 
255 /**
256  Macro for declaration of an external fortran function
257  @param[in] x the name of the function
258 */
259 #define EXTERN_FFUNCTION(x) x##_
260 
261 /**
262  Macro for calling an external fortran function
263  @param[in] x the name of the function
264 */
265 #define CALL_FFUNCTION(x) x##_
266 
267 /**
268  Macro for declaration of an external fortran subroutine
269  @param[in] x the name of the subroutine
270 */
271 #define EXTERN_FSUBROUTINE(x) void x##_
272 
273 /**
274  Macro for calling an external fortran subroutine
275  @param[in] x the name of the subroutine
276 */
277 #define CALL_FSUBROUTINE(x) x##_
278 
279 
280 // =====================================================================
281 // =====================================================================
282 
283 
284 /**
285  Macro for declaration of an external fortran90 function in a module
286  @param[in] x the name of the module
287  @param[in] y the name of the function
288 */
289 #define EXTERN_FMODFUNCTION(x,y) __##x##__##y
290 
291 /**
292  Macro for calling an external fortran90 function in a module
293  @param[in] x the name of the module
294  @param[in] y the name of the function
295 */
296 #define CALL_FMODFUNCTION(x,y) __##x##__##y
297 
298 /**
299  Macro for declaration of an external fortran90 subroutine in a module
300  @param[in] x the name of the module
301  @param[in] y the name of the subroutine
302 */
303 #define EXTERN_FMODSUBROUTINE(x,y) void __##x##__##y
304 
305 /**
306  Macro for calling an external fortran90 subroutine in a module
307  @param[in] x the name of the module
308  @param[in] y the name of the subroutine
309 */
310 #define CALL_FMODSUBROUTINE(x,y) __##x##__##y
311 
312 // =====================================================================
313 // =====================================================================
314 
315 
316 // Numeric data handling
317 
318 /**
319  Macro for fortran REAL type in C++ (float)
320 */
321 #define FREAL float
322 
323 /**
324  Macro for fortran REAL type in C++ (double)
325 */
326 #define FREAL8 double
327 
328 #define FREAL16 long double
329 
330 /**
331  Macro for fortran INT type in C++ (int)
332 */
333 #define FINT int
334 
335 /**
336  Macro for fortran INT*2 type in C++ (short int)
337 */
338 #define FINT2 short int
339 
340 /**
341  Macro for fortran INT*8 type in C++ (long int)
342 */
343 #define FINT8 long int
344 
345 #define FLOGICAL int
346 #define FLOGICAL1 bool
347 
348 // =====================================================================
349 // =====================================================================
350 
351 // Character and string handling
352 
353 #define FCHARACTER char
354 
355 #define FSTRING char*
356 #define FSTRINGLEN int
357 
358 // =====================================================================
359 // =====================================================================
360 
361 
362 // Conversion of std::string
363 
364 #define STD2FSTRING(str) strdup((str).c_str())
365 #define STD2FSTRINGLEN(str) strlen((str).c_str())
366 #define STD2FSTRINGFULL(str) strdup((str).c_str()),strlen((str).c_str())
367 
368 
369 #endif /*__FORTRAN2CPP_H__*/
370