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  @file FortranCPP.hpp
34 
35  @author Jean-Christophe Fabre <jean-christophe.fabre@supagro.inra.fr>
36 
37 
38  @see http://www-h.eng.cam.ac.uk/help/tpl/languages/mixinglanguages.html
39  @see http://www.neurophys.wisc.edu/comp/docs/notes/not017.html
40  @see http://www.yolinux.com/TUTORIALS/LinuxTutorialMixingFortranAndC.html
41  @see http://arnholm.org/software/cppf77/cppf77.htm
42  @see http://www.aei.mpg.de/~jthorn/c2f.html
43 
44  Below are examples of C++ simulators calling Fortran subroutines.
45 
46 
47  fortran source code:
48 @code
49 subroutine multrealvalue(value,mult,result)
50 
51 implicit none
52 real*8 value
53 real*8 mult
54 real*8 result
55 
56 result=value*mult
57 
58 return
59 
60 end
61 
62 
63 ! ==============================================================================
64 
65 
66 subroutine multintvalue(value,mult,result)
67 
68 implicit none
69 integer value
70 integer mult
71 integer result
72 
73 result=value*mult
74 
75 return
76 end
77 
78 
79 ! ==============================================================================
80 
81 
82 subroutine multrealmatrix(matrix,dim1,dim2,mult,result)
83 
84 implicit none
85 integer dim1
86 integer dim2
87 real*8 matrix(dim2,dim1)
88 integer mult
89 real*8 result(dim2,dim1)
90 integer i, j, k
91 subroutine multrealvalue(value,mult,result)
92 
93 implicit none
94 real*8 value
95 real*8 mult
96 real*8 result
97 
98 result=value*mult
99 
100 return
101 
102 end
103 
104 
105 ! ==============================================================================
106 
107 
108 subroutine multintvalue(value,mult,result)
109 
110 implicit none
111 integer value
112 integer mult
113 integer result
114 
115 result=value*mult
116 
117 return
118 end
119 
120 
121 ! ==============================================================================
122 
123 
124 subroutine multrealmatrix(matrix,dim1,dim2,mult,result)
125 
126 implicit none
127 integer dim1
128 integer dim2
129 real*8 matrix(dim2,dim1)
130 integer mult
131 real*8 result(dim2,dim1)
132 integer i, j, k
133 
134 do j=1,dim1
135  do i=1,dim2
136  result(i,j) = matrix(i,j) * mult
137  end do
138 end do
139 
140 
141 return
142 end
143 
144 do j=1,dim1
145  do i=1,dim2
146  result(i,j) = matrix(i,j) * mult
147  end do
148 end do
149 
150 
151 return
152 end
153 
154 @endcode
155 
156 
157 C++ code calling fortran subroutines:
158 @code
159 BEGIN_EXTERN_FORTRAN
160  EXTERN_FSUBROUTINE(multrealvalue)(FREAL8*,FREAL8*,FREAL8*);
161  EXTERN_FSUBROUTINE(multintvalue)(FINT*,FINT*,FINT*);
162  EXTERN_FSUBROUTINE(multrealmatrix)(FREAL8*,FINT*,FINT*,FINT*,FREAL8*);
163 END_EXTERN_FORTRAN
164 
165 // =====================================================================
166 // =====================================================================
167 
168 bool FortranFunction::runStep(const openfluid::base::SimulationStatus* SimStatus)
169 {
170  int i;
171 
172 
173  // ====== double ======
174 
175  double DValue, DMult, DResult;
176  DValue = 1.5436;
177  DMult = 2.5;
178  DResult = 0.0;
179 
180  CALL_FSUBROUTINE(multrealvalue)(&DValue,&DMult,&DResult);
181 
182  if (abs(DResult - (DValue*DMult)) > m_Precision)
183  OPENFLUID_RaiseError("tests.fortran","incorrect fortran call (multrealvalue)");
184 
185 
186  // ====== int ======
187 
188  int IValue, IMult, IResult;
189  IValue = 45;
190  IMult = 18;
191  IResult = 0;
192 
193  CALL_FSUBROUTINE(multintvalue)(&IValue,&IMult,&IResult);
194 
195  if (IResult != (IValue*IMult))
196  OPENFLUID_RaiseError("tests.fortran","incorrect fortran call (multintvalue)");
197 
198 
199  // ====== matrix of double ======
200 
201  int MMult, MDim1,MDim2;
202  double *MValue;
203  double *MResult;
204  MMult = 3;
205  MDim1 = 2;
206  MDim2 = 3;
207 
208 
209  MValue = new double[MDim1*MDim2];
210  MResult = new double[MDim1*MDim2];
211 
212  for (i=0; i < MDim1*MDim2;i++) MValue[i] = 1.5;
213  for (i=0; i < MDim1*MDim2;i++) MResult[i] = 0.0;
214 
215  CALL_FSUBROUTINE(multrealmatrix)(MValue,&MDim1,&MDim2,&MMult,MResult);
216 
217  for (i=0; i < MDim1*MDim2;i++)
218  {
219  if (abs(MResult[i] - (MValue[i] * MMult)) > m_Precision)
220  OPENFLUID_RaiseError("tests.fortran","incorrect fortran call (multrealmatrix)");
221  }
222 
223  return true;
224 }
225 
226 @endcode
227 
228 */
229 
230 
231 
232 
233 #ifndef __OPENFLUID_TOOLS_FORTRANCPP_HPP__
234 #define __OPENFLUID_TOOLS_FORTRANCPP_HPP__
235 
236 
237 #ifdef __cplusplus
238 # define BEGIN_EXTERN_FORTRAN \
239  extern "C" \
240  {
241 # define END_EXTERN_FORTRAN }
242 #else
243 # define BEGIN_EXTERN_FORTRAN
244 # define END_EXTERN_FORTRAN
245 #endif
246 
247 // =====================================================================
248 // =====================================================================
249 
250 
251 // calling function or subroutine from a F90 module
252 
253 /**
254  Macro for declaration of an external fortran function
255  @param[in] x the name of the function
256 */
257 #define EXTERN_FFUNCTION(x) x##_
258 
259 /**
260  Macro for calling an external fortran function
261  @param[in] x the name of the function
262 */
263 #define CALL_FFUNCTION(x) x##_
264 
265 /**
266  Macro for declaration of an external fortran subroutine
267  @param[in] x the name of the subroutine
268 */
269 #define EXTERN_FSUBROUTINE(x) void x##_
270 
271 /**
272  Macro for calling an external fortran subroutine
273  @param[in] x the name of the subroutine
274 */
275 #define CALL_FSUBROUTINE(x) x##_
276 
277 
278 // =====================================================================
279 // =====================================================================
280 
281 
282 /**
283  Macro for declaration of an external fortran90 function in a module
284  @param[in] x the name of the module
285  @param[in] y the name of the function
286 */
287 #define EXTERN_FMODFUNCTION(x,y) __##x##_MOD_##y
288 
289 /**
290  Macro for calling an external fortran90 function in a module
291  @param[in] x the name of the module
292  @param[in] y the name of the function
293 */
294 #define CALL_FMODFUNCTION(x,y) __##x##_MOD_##y
295 
296 /**
297  Macro for declaration of an external fortran90 subroutine in a module
298  @param[in] x the name of the module
299  @param[in] y the name of the subroutine
300 */
301 #define EXTERN_FMODSUBROUTINE(x,y) void __##x##_MOD_##y
302 
303 /**
304  Macro for calling an external fortran90 subroutine in a module
305  @param[in] x the name of the module
306  @param[in] y the name of the subroutine
307 */
308 #define CALL_FMODSUBROUTINE(x,y) __##x##_MOD_##y
309 
310 
311 // =====================================================================
312 // =====================================================================
313 
314 
315 // Numeric data handling
316 
317 /**
318  Macro for fortran REAL type in C++ (float)
319 */
320 #define FREAL float
321 
322 /**
323  Macro for fortran REAL type in C++ (double)
324 */
325 #define FREAL8 double
326 
327 #define FREAL16 long double
328 
329 /**
330  Macro for fortran INT type in C++ (int)
331 */
332 #define FINT int
333 
334 /**
335  Macro for fortran INT*2 type in C++ (short int)
336 */
337 #define FINT2 short int
338 
339 /**
340  Macro for fortran INT*8 type in C++ (long int)
341 */
342 #define FINT8 long int
343 
344 #define FLOGICAL int
345 #define FLOGICAL1 bool
346 
347 
348 // =====================================================================
349 // =====================================================================
350 
351 
352 // Character and string handling
353 
354 #define FCHARACTER char
355 
356 #define FSTRING char*
357 #define FSTRINGLEN int
358 
359 
360 // =====================================================================
361 // =====================================================================
362 
363 
364 // Conversion of std::string
365 
366 #define STD2FSTRING(str) strdup((str).c_str())
367 #define STD2FSTRINGLEN(str) strlen((str).c_str())
368 #define STD2FSTRINGFULL(str) strdup((str).c_str()),strlen((str).c_str())
369 
370 
371 #endif /* __OPENFLUID_TOOLS_FORTRANCPP_HPP__ */
372