Calling User Function from User Function

General discussion about Elmer

Calling User Function from User Function

Postby gos » 16 Apr 2012, 11:23

Hello,

Is it possible to call a User Function A from User Function B? I want both User Functions to be compiled in such a way that they may be used as regular UFs.

I have in vain tried to export a MyFunctionA from UF "A" using: !GCC$ ATTRIBUTES DLLEXPORT :: MyFunctionA
and then tried to import it into UF B using: !GCC$ ATTRIBUTES DLLIMPORT :: MyFunctionA

I have used ElmerGUI to compile, but with the commmand line options it uses, gcc simply ignores the Export and Import statements..

I am not experienced in Fortran 90, take that into account please...

gos
gos
 
Posts: 54
Joined: 13 Sep 2011, 21:22

Re: Calling User Function from User Function

Postby raback » 16 Apr 2012, 11:32

Hi gos

Maybe you want to have a module for function A as in
Code: Select all
http://elmerfem.svn.sourceforge.net/viewvc/elmerfem/trunk/fem/tests/bodydir2/Blowers.f90

-Peter
raback
Site Admin
 
Posts: 1917
Joined: 22 Aug 2009, 11:57
Location: Espoo, Finland

Re: Calling User Function from User Function

Postby gos » 16 Apr 2012, 12:25

Hello Peter,

Does this mean that I may include all my User Functions into one Module: Inside that Module they may of course call each other, but may I also use all of the User Functions defined in this Module in my SIF file ?

Code: Select all
Module A

Def For UF1
End UF1

Def For UF2:
  Calling UF1
End UF2

End Module A


Lets say I save this file as ModuleA.f90. I compile it using Elmer GUI and get a ModuleA.mod file and a ModuleA.dll file

How do I now refer to the separate Functions inside this Module from my SIF file? Like below?

Code: Select all
MYVar1 = Variable Temperature
  Real Procedure "ModuleA.dll"  "UF1"

  MYVar2 = Variable Temperature
  Real Procedure "ModuleA.dll"  "UF2"


gos
gos
 
Posts: 54
Joined: 13 Sep 2011, 21:22

Re: Calling User Function from User Function

Postby gos » 16 Apr 2012, 14:56

Hello,

The above does NOT work: It seems that the different functions within Module A is not visible this way.

Can someone please help me ?

gos
gos
 
Posts: 54
Joined: 13 Sep 2011, 21:22

Re: Calling User Function from User Function

Postby raback » 16 Apr 2012, 15:35

Hi gos

If you want to have just two subroutines in same file just put them there. The idea with the MODULE was that one could set there the common functionality of different UFs in case you want to avoid repetition.

-Peter
raback
Site Admin
 
Posts: 1917
Joined: 22 Aug 2009, 11:57
Location: Espoo, Finland

Re: Calling User Function from User Function

Postby gos » 16 Apr 2012, 15:49

Hello Peter,

Well, there is a lot of Fortran stuff that you now well that I don't and it need tp be correct, however, I got it working finally.

For the benefit of other users, I will post a message with the solution, but not right now, as my head is spinning after an intense period of trial and failure: I need a break...

gos
gos
 
Posts: 54
Joined: 13 Sep 2011, 21:22

Re: Calling User Function from User Function

Postby gos » 20 Apr 2012, 15:51

Hello,

A little late, but as promised, I hereby post my template on how to define User Functions in a DLL:
All User Functions may be used by Elmer, and all User Functions within the DLL may call each other.

I realize that this is not any "news" for seasoned Fortran programmers, but I guess there are other Elmer users, like me, that does not speak Fortran fluently... :-)

In "Initial Conditon", "Boundary Condition", "Material" etc statements in the Case.sif file, these user functions may be called using statements along the line:

Code: Select all
Material 1
  Heat Capacity = Variable Temperature
  Real Procedure "UserFunctions.dll" "geHeatCapacity"
End


Here is the User Function Template:

Code: Select all
! Module Definitions for Modules used by the User Functions: Omit if not needed!
MODULE A
USE DefUtils
IMPLICIT NONE
......
END MODULE A

MODULE B
USE DefUtils
IMPLICIT NONE
......
END MODULE B

! Module Containing the User Function Interface Definitions:
! All Definitions follow the Guidelines for a User Function
! All Definitions listed here, will be Exported out of the DLL and may
! be Used Inide Elmer as a User Function
MODULE UserFunctions
   FUNCTION Function_1( Model, n, NotUsed ) RESULT(Value)
      USE Types
      IMPLICIT None
      TYPE(Model_t) :: Model
      INTEGER :: n
      REAL(KIND=dp) :: NotUsed, ConstValue
   END FUNCTION
   
   FUNCTION Function_2( Model, n, NotUsed ) RESULT(Value)
      USE Types
      IMPLICIT None
      TYPE(Model_t) :: Model
      INTEGER :: n
      REAL(KIND=dp) :: NotUsed, ConstValue
   END FUNCTION   
   .........
END MODULE UserFunctions

! Fimally, outside any "scope" the Functions Decalared
! in the Interface above must be implemented
FUNCTION Function_1( Model, n, NotUsed ) RESULT(Value)
   ! modules needed
   USE DefUtils
   USE UserFunctions         ! Needed if this User Function wants to call another User Function
   IMPLICIT None
   ! variables in function header
   TYPE(Model_t) :: Model
   INTEGER :: n
   REAL(KIND=dp) :: NotUsed, ConstValue
   .......
END FUNCTION Function_1

FUNCTION Function_2( Model, n, NotUsed ) RESULT(Value)
   ! modules needed
   USE DefUtils
   USE UserFunctions         ! Needed if this User Function wants to call another User Function
   IMPLICIT None
   ! variables in function header
   TYPE(Model_t) :: Model
   INTEGER :: n
   REAL(KIND=dp) :: NotUsed, ConstValue
   .......
END FUNCTION Function_2
gos
 
Posts: 54
Joined: 13 Sep 2011, 21:22

Re: Calling User Function from User Function

Postby mzenker » 12 Jul 2012, 17:06

Hi,

I have had the same problem: I wanted to call a UDF from another one. I have found this thread and tried with the template given above, but for me it did not work that way. I digged further and found the solution. Here is a modified template that worked for me - the main difference is the INTERFACE statement in the module:
Code: Select all
! Module Containing the User Function Interface Definitions:
MODULE UserFunctions
   INTERFACE
     FUNCTION Function_1( Model, n, Var ) RESULT(Value)
        USE DefUtils ! or whatever modules are needed
        IMPLICIT None
        TYPE(Model_t) :: Model
        INTEGER :: n
        REAL(KIND=dp) :: Var, Value
     END FUNCTION Function_1
   
     FUNCTION Function_2( Model, n, Var ) RESULT(Value)
        USE DefUtils ! or whatever modules are needed
        IMPLICIT None
        TYPE(Model_t) :: Model
        INTEGER :: n
        REAL(KIND=dp) :: Var, Value
     END FUNCTION   
  END INTERFACE
END MODULE UserFunctions

! Fimally, outside any "scope" the Functions Decalared
! in the Interface above must be implemented
FUNCTION Function_1( Model, n, Var ) RESULT(Value)
   ! modules needed
   USE DefUtils
   USE UserFunctions         ! Needed if this User Function wants to call another User Function
   IMPLICIT None
   ! variables in function header
   TYPE(Model_t) :: Model
   INTEGER :: n
   REAL(KIND=dp) :: Var, Value
   ! function body with instructions
END FUNCTION Function_1

FUNCTION Function_2( Model, n, Var ) RESULT(Value)
   ! modules needed
   USE DefUtils
   USE UserFunctions         ! Needed if this User Function wants to call another User Function
   IMPLICIT None
   ! variables in function header
   TYPE(Model_t) :: Model
   INTEGER :: n
   REAL(KIND=dp) :: Var, Value
   ! function body with instructions
END FUNCTION Function_2


Matthias
mzenker
 
Posts: 665
Joined: 07 Dec 2009, 11:49


Return to General

Who is online

Users browsing this forum: No registered users and 1 guest

cron