CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > OpenFOAM Programming & Development

How to interface a Fortran thermodynamic tool with OpenFOAM?

Register Blogs Members List Search Today's Posts Mark Forums Read

Like Tree1Likes

Reply
 
LinkBack Thread Tools Display Modes
Old   March 9, 2011, 13:45
Default mixing Fortran with OpenFOAM, Towards to a unified solution
  #21
New Member
 
Evren
Join Date: Mar 2010
Posts: 19
Rep Power: 5
pbe_cfd is on a distinguished road


So, I came up with a solution to my prototype problem. Calling an external Fortran90 subroutine from an OpenFoam application.

STEPS
1) Declare an interface C function in the main file or in .H file and include it

extern "C"
{
void fortfunc_(int *ii, double *ff); // underscore is important (gfortran linux)!
}

When mixing Fortran with C++, name mangling must be prevented. You may use "objdump -t <file>" file: object or library files. In this example the subroutine named as fortfunc in the Fortran 90 code. But it's referred as fortfunc_

2) Compile your Fortran code and obtain object files "*.o". You may link the object files or you may create a static library form object files as follows,

ar rc myPbeLib.a fortfunc.o other.o object.o files.o // specific to Linux system

3) In your solver folder Make/options append -lgfortran (runtime fortran libraries) and your object or library files. If your fortran subroutine call some other routines from other libraries, add them as well. (Last case is not tested. )

EXE_LIBS = -lfiniteVolume\
-lgfortran\
$(FOAM_USER_LIBBIN)/fortfunc.o

4) Build your executable with wmake in solver folder.

This approach worked for my prototype problem. However I don't know if this is the best way, most probably NOT. Cyp's suggestion sounds really cool. But, I had a problem with obtaining the shared object files (*.so). I had done it before for a C++ code for boundary conditions. There it had worked very nicely. But with Fortran code I had problems. It doesn't compile the fortran code. If someone can describe how to obtain shared object files for Fortran codes, it will be really cool. Then, we can close this thread with a happy end ;-)

All the best;
Evren
hz283 likes this.
pbe_cfd is offline   Reply With Quote

Old   May 6, 2011, 13:46
Arrow
  #22
New Member
 
Nicolas
Join Date: May 2011
Posts: 4
Rep Power: 4
Nicolas Périnet is on a distinguished road
Dear all,

I have posted in this thread because it is the closest to the topic of my problem.

I want to code a Hookstep-Newton-Krylov algorithm to find peculiar solutions of the flow with some symmetry properties in a rotating annulus. This algorithm involves OpenFOAM for solving Navier-Stokes equations and additional routines in FORTRAN 90, especially from linear algebra libraries.

I have created a main program in C++ which calls the fortran fsubroutines (here a test case nothing.h. Some of these fortran subroutines call OpenFOAM. I am trying to make interact the main program with the fortran subroutines and OpenFOAM.

I have made a test case where:
-the main program is "icoDHRAFoamEssai.C"
-it calls the fortran function "nothing in "nothing.f90"
-which calls at its turn "integration" in "integration.C" that gathers all the OpenFOAM functions that are dedicated to solve Navier-Stokes equations in my case.

Here you can find some parts of my code.
First the main function in "icoDHRAFoamEssai.C"

Code:
#include "fvCFD.H"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

extern "C" { void nothing_(double* AA, int &lengthAA,int* argvLength, int &argc,char* argvChar, int& argv1StrLength); } 
void integration_(double* AA, int* lengthAA, int& argc);

int main(int argc, char* argv[])
{
      //commands that I didn't attach here

      nothing_(AA, lengthAA, argvLength, argc, argvChar, argv1StrLength); 

      //some other commands
}
the subroutine "nothing" is as follows:

Code:
subroutine nothing(AA, lengthAA, argvLength, argc, argvChar, argv1StrLength)
	  
integer lengthAA
real*8  AA(lengthAA)
integer argc
integer argvLength(argc)
integer argv1StrLength
character argvChar(argv1StrLength+1)

!some fortran instructions
      
call integration(AA, lengthAA, argc)

return
end
And then "integration" in "integration.C"

Code:
void Integration_(double* AA, int* lengthAA,int& argc)
{
      #   include "setRootCase.H"
      #   include "createTime.H"
      #   include "createMesh.H"
      #   include "readEnvironmentalProperties.H"
      #   include "createFields.H"
      #   include "initContinuityErrs.H"

      Info<< "\nStarting time loop\n" << endl;
	
      #   include "readPISOControls.H"
      #   include "CourantNo.H"

      //some instructions that I added
      
      for (runTime++; !runTime.end(); runTime++)
      {
             //OpenFOAM instructions
      }

      Info<< "End\n" << endl;

      //other instructions

}
I have first compiled it using the commands:

Code:
gfortran -c nothing.f90 -o nothing.o
To link "nothing" with the main code I changed the "Make/options" file in the directory of my project to:

Code:
EXE_INC = \
    -I$(LIB_SRC)/finiteVolume/lnInclude

EXE_LIBS = \
    -lfiniteVolume\
	/usr/lib64/libgfortran.so.1\	
	$(HOME)/OpenFOAM/nperinet-1.4.1/applications/solvers/icoDHRAFoamEssai/nothing.o
As stated in this thread, I just added the two last lines.
I compile with "wmake"; if I don't call the function "integration" in "nothing.f90", everything goes well. When I call it, I get the error message:

Code:
In function `nothing_':
:undefined reference to `integration_'
Then it is most likely because I don't link "integration" to "nothing" and the main program, but I can mistake (I am beginner in OpenFOAM and C++ as well). The problem is that I absolutely don't know how to do this (which commands I have to add to which file to make this work, etc...).

I would be very grateful to anyone who may supply any suggestion.

Nicolas Périnet
Nicolas Périnet is offline   Reply With Quote

Old   May 30, 2011, 13:14
Default Differences in Library Linking
  #23
New Member
 
Join Date: Sep 2010
Posts: 29
Rep Power: 4
anfho is on a distinguished road
Dear All,

I am also going to call a whole list of FORTRAN 90 subroutines from OF (in my case 1.7.1 though). I do this by adding the *.o files to the "objectFiles".

Apparently, as I am reading through this really helpful thread, it seems like there are different methods to do this: static library, dynamic library, static objects, dynamic objects, shared objects, objects, ...

I would appreciate, if someone could comment on the differences of these strategies (efficiency, ease of use, ...). This question came up earlier in the thread but has not been answered.

Thanks guys. Best regards,
Andreas
anfho is offline   Reply With Quote

Old   June 29, 2011, 14:51
Default link OF to fortran reading an input file
  #24
New Member
 
Join Date: Sep 2010
Posts: 29
Rep Power: 4
anfho is on a distinguished road
Hi All,
did anyone try to link OF with fortran to read from an input file, something like:

integer temp
open(unit=10,file='input.dat')
read(10,*,end=100)temp
100 continue
close(10)

where the input file simply contains an integer, e.g.: "1",
and calling this from an OF application?

If I do this, I am getting a random output for "temp". It does work however, if I link a separate c++ main program and a fortran subroutine... so not sure why OF is causing trouble there...

Any help is appreciated.
Thanks, Andreas
anfho is offline   Reply With Quote

Old   July 30, 2012, 01:45
Default please tell me ???
  #25
Member
 
vahid
Join Date: Feb 2012
Location: Mashhad-Iran
Posts: 80
Rep Power: 2
vahid.najafi is an unknown quantity at this point
Hi Dear Nima again:
I want to add surface tension(sigma) in one solver,for this reason I added :
#include ''fvCFD.H''
fvc::interpolate(interface.sigma())

in this code:
Foam::tmp<Foam::volScalarField>
Foam:haseChangeTwoPhaseMixtures::SchnerrSauer: Coeff
(
const volScalarField& p
) const
{
volScalarField limitedAlpha1(min(max(alpha1_, scalar(0)), scalar(1)));
volScalarField rho
(
limitedAlpha1*rho1() + (scalar(1) - limitedAlpha1)*rho2()
);
return

//......I want to change it( <<sigma>> surface tension multiple in it):
(3*rho1()*rho2())*sqrt(2/(3*rho1()))* (fvc::interpolate(interface.sigma()))
*rRb(limitedAlpha1)/(rho*sqrt(mag(p - pSat()) + 0.01*pSat()));
//.................................................. ......
}
dont successful wmake, and seen(was not declared ):
phaseChangeTwoPhaseMixtures/SchnerrSauer/SchnerrSauer.C:113: error: 'interface' was not declared in this scope
make: *** [Make/linux64GccDPOpt/SchnerrSauer.o] Error 1
please help me,and tell me ,How to correct this problem???
vahid.najafi is offline   Reply With Quote

Old   July 30, 2012, 03:46
Default
  #26
Senior Member
 
Nima Sam
Join Date: Sep 2009
Location: Tehran, Iran
Posts: 680
Blog Entries: 1
Rep Power: 9
nimasam is on a distinguished road
Send a message via Yahoo to nimasam
dear vahid, instead of multiple posts of the same question, in different place, open new thread! with appropriate title,ask your question there!

it is an inappropriate to ask non-related issue under a post!
and about your problem, i told you here (Adding a new term in momentum equation of Interfoam).
you need a background of C++, look at here:
"http://cplus.about.com/od/learning1/ss/cppobjects.htm"
nimasam is offline   Reply With Quote

Old   July 30, 2012, 03:53
Default Thanks
  #27
Member
 
vahid
Join Date: Feb 2012
Location: Mashhad-Iran
Posts: 80
Rep Power: 2
vahid.najafi is an unknown quantity at this point
ok.mr nima.
Thanks
vahid.najafi is offline   Reply With Quote

Old   May 7, 2013, 11:56
Default
  #28
Senior Member
 
Join Date: Nov 2012
Posts: 137
Rep Power: 2
hz283 is on a distinguished road
Hi pge_cfd,

I am reading your thread and but this solution work well for my testing. But I did not run the following command as you mentioned:

ar rc myPbeLib.a fortfunc.o other.o object.o files.o // specific to Linux system

The coupled code can run well (but this is my simple test and so there is no complex in the fortran code). Could you please tell me what is the role for the
creation of the library?

Thanks.

Quote:
Originally Posted by pbe_cfd View Post


So, I came up with a solution to my prototype problem. Calling an external Fortran90 subroutine from an OpenFoam application.

STEPS
1) Declare an interface C function in the main file or in .H file and include it

extern "C"
{
void fortfunc_(int *ii, double *ff); // underscore is important (gfortran linux)!
}

When mixing Fortran with C++, name mangling must be prevented. You may use "objdump -t <file>" file: object or library files. In this example the subroutine named as fortfunc in the Fortran 90 code. But it's referred as fortfunc_

2) Compile your Fortran code and obtain object files "*.o". You may link the object files or you may create a static library form object files as follows,

ar rc myPbeLib.a fortfunc.o other.o object.o files.o // specific to Linux system

3) In your solver folder Make/options append -lgfortran (runtime fortran libraries) and your object or library files. If your fortran subroutine call some other routines from other libraries, add them as well. (Last case is not tested. )

EXE_LIBS = -lfiniteVolume\
-lgfortran\
$(FOAM_USER_LIBBIN)/fortfunc.o

4) Build your executable with wmake in solver folder.

This approach worked for my prototype problem. However I don't know if this is the best way, most probably NOT. Cyp's suggestion sounds really cool. But, I had a problem with obtaining the shared object files (*.so). I had done it before for a C++ code for boundary conditions. There it had worked very nicely. But with Fortran code I had problems. It doesn't compile the fortran code. If someone can describe how to obtain shared object files for Fortran codes, it will be really cool. Then, we can close this thread with a happy end ;-)

All the best;
Evren
hz283 is offline   Reply With Quote

Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Call Fortran program from OpenFoam tsjb00 OpenFOAM Running, Solving & CFD 6 April 22, 2013 15:26
2D Mesh Generation Tutorial for GMSH aeroslacker Open Source Meshers: Gmsh, Netgen, CGNS, ... 12 January 19, 2012 03:52
Native OpenFOAM interface in Pointwise Chris Sideroff Main CFD Forum 0 January 16, 2009 12:37
Convective Heat Transfer - Heat Exchanger Mark CFX 6 November 15, 2004 15:55
Replace periodic by inlet-outlet pair lego CFX 3 November 5, 2002 20:09


All times are GMT -4. The time now is 22:42.