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@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 
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 #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 
252 // calling function or subroutine from a F90 module
253 
254 /**
255  Macro for declaration of an external fortran function
256  @param[in] x the name of the function
257 */
258 #define EXTERN_FFUNCTION(x) x##_
259 
260 /**
261  Macro for calling an external fortran function
262  @param[in] x the name of the function
263 */
264 #define CALL_FFUNCTION(x) x##_
265 
266 /**
267  Macro for declaration of an external fortran subroutine
268  @param[in] x the name of the subroutine
269 */
270 #define EXTERN_FSUBROUTINE(x) void x##_
271 
272 /**
273  Macro for calling an external fortran subroutine
274  @param[in] x the name of the subroutine
275 */
276 #define CALL_FSUBROUTINE(x) x##_
277 
278 
279 // =====================================================================
280 // =====================================================================
281 
282 
283 /**
284  Macro for declaration of an external fortran90 function in a module
285  @param[in] x the name of the module
286  @param[in] y the name of the function
287 */
288 #define EXTERN_FMODFUNCTION(x,y) __##x##_MOD_##y
289 
290 /**
291  Macro for calling an external fortran90 function in a module
292  @param[in] x the name of the module
293  @param[in] y the name of the function
294 */
295 #define CALL_FMODFUNCTION(x,y) __##x##_MOD_##y
296 
297 /**
298  Macro for declaration of an external fortran90 subroutine in a module
299  @param[in] x the name of the module
300  @param[in] y the name of the subroutine
301 */
302 #define EXTERN_FMODSUBROUTINE(x,y) void __##x##_MOD_##y
303 
304 /**
305  Macro for calling an external fortran90 subroutine in a module
306  @param[in] x the name of the module
307  @param[in] y the name of the subroutine
308 */
309 #define CALL_FMODSUBROUTINE(x,y) __##x##_MOD_##y
310 
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 
352 
353 // Character and string handling
354 
355 #define FCHARACTER char
356 
357 #define FSTRING char*
358 #define FSTRINGLEN int
359 
360 
361 // =====================================================================
362 // =====================================================================
363 
364 
365 // Conversion of std::string
366 
367 #define STD2FSTRING(str) strdup((str).c_str())
368 #define STD2FSTRINGLEN(str) strlen((str).c_str())
369 #define STD2FSTRINGFULL(str) strdup((str).c_str()),strlen((str).c_str())
370 
371 
372 #endif /* __OPENFLUID_TOOLS_FORTRANCPP_HPP__ */
373