CFX用户手册-User Fortran
User Fortran
Introduction
The chapter discusses:
, User CEL Functions and Routines
, User Junction Box Routines
, Shared Libraries
, User Parameters
, Utility Routines for User Functions
, ANSYS CFX Memory Management System (MMS)
, User CEL Examples
, User Junction Box Examples
, Using CFX-4 Routines in ANSYS CFX
To allow you to add additional features and physical models to ANSYS CFX, you can write your own subroutines in Fortran and have the ANSYS CFX-Solver call these routines through a source code interface. You may also wish to implement customized physical models which would never be available in ANSYS CFX due to confidentiality considerations.
ANSYS CFX supports user subroutines written in Fortran 77 or Fortran 90. A list of supported compilers for each platform is available. Using Fortran 77 whenever possible is recommended.
Two different kinds of user routines are available in ANSYS CFX: CFX可以利用两种不同的方式应用用户子程序
, User defined CEL (CFX Expression Language) functions can be used
within a CEL expression, following the standard CEL rules. For
details, see User CEL Functions and Routines.
用户定义CEL(User defined CEL)函数可以在CEL表达式中使用
, Junction box routines can be used at several places in the ANSYS
CFX-Solver to execute user code. For details, see User Junction Box
Routines.
Junction box routines可以在ANSYS CFX-Solver中执行用户代码
The following tasks can be accomplished with user subroutines in ANSYS CFX:
通过用户程序可以在CFX中完成以下
:
, Input of user data (e.g., data required for profile boundary
conditions or externally generated sources).
, User-specified boundary conditions (e.g., profile boundary
conditions).
, User-specified initial conditions (e.g., externally generated flow
fields, random distribution or disturbance of existing solutions).
, User-specified source terms (e.g., externally generated body
forces or general additional source terms used to implement new
physical models).
, Junction box routines called every timestep which acts as a general
interface between the ANSYS CFX-Solver and other software (e.g.,
structure mechanic codes). Junction boxes also offer an interface
for advanced monitoring and solution output.
, User particle routines are used to specify sources of momentum, heat
and mass transfer, and can also be used to specify injection regions
for particles. The structure of particle user routines is the same.
An example of this functionality is available.
For details, see Structure of User CEL Functions.
For details, see Particle User Sources.
For details, see User Defined.
Note that ANSYS CFX includes features such as advanced monitoring of solution variables or global values and extended CEL functionality, which may reduce your need for user subroutines.
To use junction box routines, you will need to be familiar with the ANSYS CFX MMS (Memory Management System) to set up and pass around user data for access in any subroutine. For details, see ANSYS CFX Memory Management System (MMS).
Shared libraries allow subroutines to be re-used without recompilation for successive ANSYS CFX-Solver runs or even for different applications. The location of a shared library is specified in ANSYS CFX-Pre. During execution of the ANSYS CFX-Solver, the user subroutines are loaded from the specified shared libraries. For details, see Shared Libraries.
User CEL Functions and Routines
User CEL functions allow you to create your own functions in addition to the predefined CEL functions (e.g., sin, cos, step, etc.). You can then use these functions in any expression where a CEL function can be used. A user CEL function passes an argument list to a subroutine that you have written, and then uses the returned values from the subroutine to set values for the quantity of interest. The figure below demonstrates the concept.
All variables that are available for use in standard CEL expressions are also available for use in User CEL Expressions. A list of these variables is available. For details, see Variables Available for use in CEL Expressions.
Details on creating user CEL functions in ANSYS CFX-Pre and defining quantities via an expression with an argument list are available.
, For details, see User Routine Details View.
, For details, see User Functions.
Details on creating shared libraries and compiling subroutines are available. For details, see Shared Libraries.
Examples of using user CEL functions are available. For details, see User
CEL Examples.
Structure of User CEL Functions
A User Fortran file may contain several user routines that can be called from the ANSYS CFX-Solver, as well as any secondary routines that are called only from other routines in this file.
In addition to any comments and declarations that you may wish to add, the basic structure of a user CEL function is:
#include "cfx5ext.h"
dllexport(
)
SUBROUTINE (
& NLOC, NRET, NARG, RET, ARGS, CRESLT, CZ,DZ,IZ,LZ,RZ ) C
INTEGER NLOC,NARG,NRET
CHARACTER CRESLT*(*)
REAL ARGS(NLOC,NARG), RET(NLOC,NRET)
C
INTEGER IZ(*)
CHARACTER CZ(*)*(1)
DOUBLE PRECISION DZ(*)
LOGICAL LZ(*)
REAL RZ(*)
C
.... executable statements
END
The dllexport() macro is used to ensure that a calling name is known externally on those platforms that require it for successful runtime linking. The macro is defined in an include file so #include "cfx5ext.h" should be the first line of the Fortran file.
One dllexport() should be specified for every routine that the ANSYS CFX-Solver can call in the Fortran file.
Each dllexport() must precede the SUBROUTINE statement that it refers to and must start in column 1. The argument of the dllexport macro should be the name of the subroutine in lower case and should not contain spaces. User CEL functions have a fixed argument list which contains the following data fields:
, NLOC: Number of locations in space over which the calculations have
to be performed.
, NARG: Number of arguments passed to the function.
, ARGS(1:NLOC,1:NARG): Arguments passed to the function (at each
point in space).
, NRET: Number of return variables. This is always 1 in ANSYS CFX,
but is included to allow future extensions.
, RET(1:NLOC,1:NRET): Return variables (at each point in space).
, CZ(*), DZ(*), IZ(*), LZ(*), RZ(*): CHARACTER, DOUBLE PRECISION,
INTEGER, LOGICAL and REAL stacks.
The length (NLOC) of the arguments (ARGS) and the return value (RET) of user CEL functions is determined by the locale for which the routine is called. For example, for a boundary element group, NLOC is the number of faces in the group, and for vertices, NLOC is the number of vertices in the current zone.
Note that, in general, your user CEL function will be called several times during each iteration and the value of NLOC will be different for each call. This is because the ANSYS CFX-Solver will split the specified region (e.g., a boundary condition region) into a number of smaller ‘pieces' and call your function for each piece. Your user subroutine should be coded to deal with this.
The stacks are required if the information specified on the right side of the CEL expression (e.g., B*C and D in A = UR(B*C, D)) is not sufficient to calculate A. It might be necessary to pick up additional data (e.g., user input data, data at other locales, gradients, etc). For details, see
Utility Routines for User Functions. This data is accessed from the ANSYS
CFX Memory Management System and requires the global stacks. Therefore, the global stacks are added to the argument list. For details, see ANSYS
CFX Memory Management System (MMS).
A template user CEL function Fortran file named ucf_template.F can be found in /examples/.
Note that all strings used in User Fortran are case sensitive.
User CEL Function Units
On entry into a user CEL function routine, the arguments are automatically converted into the units specified in the Argument List list in the User Function Editor (labelled Argument List in the definition for the function in the CCL file LIBRARY section).
On exit, the results are automatically converted from the Result Units into the solution units used by the ANSYS CFX-Solver.
This ability to choose the working units for the routine with automatic conversion may be useful for creating interfaces between the ANSYS CFX-Solver and third-party data or applications.
User CEL Example 1: User Defined Momentum Source
Problem Setup
A common application of user CEL functions is the specification of user defined source terms. In the following example, a constant source term for the y-component of the momentum equation has to be applied on two rectangular boxes characterized by their extension in the x and y coordinate direction.
Creating the User CEL Function
Additional information on creating user CEL functions in ANSYS CFX-Pre is available. For details, see User Functions.
First, you should first create a user routine with the following settings:
, Routine Name: UserSourceRoutine
, Option: User CEL Function
, Calling Name: user_source
, Library Name: MomentumSource1
, Library Path: /home/cfxuser/shared_libraries
Next, you should create a User Function with the following settings:
, Function Name: UserSource
, Option: User Function
, User Routine Name:
, Argument List: [m], [m]
, Result Units: [kg m^-2 s^-2]
In this example, the compiled code for the user subroutine MomentumSource1.F is stored in the shared library libMomentumSource1.so (the prefix and suffix may vary depending on your platform), which can be found under the /home/cfxuser/shared_libraries/ directory. If there is a problem linking the shared library to the ANSYS CFX-Solver, you can check that it has been created, but you will usually not need to know about this library.
The new user CEL function can now be used to set the momentum source components within the subdomain as follows:
, Momentum x-comp: 0.0
, Momentum y-comp: UserSource(X,Y)
, Momentum z-comp: 0.0
These values are set on the Subdomain Sources form. For details, see
Sources Tab.
User Fortran Routine
Source terms for the momentum equations can be specified in CEL for a given subdomain. Since the user CEL routine defined the extent of the source, the source subdomain can be defined to cover the entire flow domain. The subroutine was developed from the template routine ucf_template.F available in /examples/. Note that some commented sections of the routine have not been included here. The routine MomentumSource1.F has the following form:
#include "cfx5ext.h"
dllexport(user_source)
SUBROUTINE USER_SOURCE (
& NLOC,NRET,NARG,RET,ARGS,CRESLT,CZ,DZ,IZ,LZ,RZ)
C
C .....
C
C ------------------------------
C Argument list
C ------------------------------
C
INTEGER NLOC, NRET, NARG
CHARACTER CRESLT*(*)
REAL RET(1:NLOC,1:NRET), ARGS(1:NLOC,1:NARG)
C
INTEGER IZ(*)
CHARACTER CZ(*)*(1)
DOUBLE PRECISION DZ(*)
LOGICAL LZ(*)
REAL RZ(*)
C
C .....
C
C ------------------------------
C Executable statements
C ------------------------------
C
C--------------------------------------------------------- C SOURCE = RET(1:NLOC,1)
C X = ARGS(1:NLOC,1)
C Y = ARGS(1:NLOC,2)
C--------------------------------------------------------- C
C---- Low level user routine
CALL USER_SOURCE_SUB (NLOC,RET(1,1),ARGS(1,1),ARGS(1,2)) C
CRESLT = 'GOOD'
END
SUBROUTINE USER_SOURCE_SUB (NLOC,SOURCE,X,Y) C
C .....
C
C ------------------------------
C Local Variables
C ------------------------------
INTEGER NLOC, ILOC
REAL SOURCE(NLOC), X(NLOC), Y(NLOC) C--------------------------------------------------------- C - 0.5 SOURCE = 1000.0 C - 3.5 SOURCE = -1000.0 C--------------------------------------------------------- C ---------------------------
C Executable Statements
C ---------------------------
DO ILOC=1,NLOC
SOURCE(ILOC) = 0.0
IF (X(ILOC).GE.0.5 .AND. X(ILOC).LE.1.5 .AND.
& Y(ILOC).GE.1.25 .AND. Y(ILOC).LE.1.75) THEN
SOURCE(ILOC) = 1000.0
ELSE IF (X(ILOC).GE.3.5 .AND. X(ILOC).LE.4.5 .AND.
& Y(ILOC).GE.1.25 .AND. Y(ILOC).LE.1.75) THEN
SOURCE(ILOC) = -1000.0
END IF
END DO
C
END
User CEL Example 2: Using Gradients for an Additional Variable Source
For some applications, the source terms for the transport equations might depend on local gradients. Gradients are currently not supported directly within CEL. However, gradients of most variables can still be accessed in CEL expressions through the use of user CEL functions. This is achieved by calling the utility USER_GETVAR with the ‘Gradient' operator attached to the variable name.
The following example shows the use of a source term depending on gradients of one additional variable, , in the transport equation of another
additional variable, .
Equation 1.
Equation 2.
For this demonstration density is constant, the flow is uniform and is a simple algebraic variable:
Equation 3.
so that the solution along a streamline can be trivially verified as:
Equation 4.
where is the distance from the inlet and is the flow speed. A user CEL function is given the coefficient as an argument and computes the whole of the source term, . The variables and
have dimensions of length, so their gradients are therefore dimensionless.
The coefficient has the same dimensions as the source term, which are those of density times velocity.
Problem Setup
Creating the Additional Variables
Before creating a domain define two additional variables:
, Create an additional variable called phi1 of Type Unspecified with
Units of [m]
, Create an additional variable called phi2 of Type Specific with
Units of [m]
Creating the Domain
Create a domain that includes both additional variables phi1 and phi2:
, Declare phi1 of Type Algebraic, and type in the expression to
define it
, Declare phi2 of Type Transport Equation. Do not set a Kinematic
Diffusivity
Create a domain that includes both additional variables, solved using a transport equation. Do not set a kinematic diffusivity. Creating the User CEL Routine and Function
In ANSYS CFX-Pre, you should create a User Routine and then a User Function. For details, see User Routine Details View. Additional information on
creating User CEL Function in ANSYS CFX-Pre is available. For details,
see User Functions.
The User Routine takes the following form:
, Routine Name: UserSource2Routine
, Option: User CEL Function
, Calling Name: user_source2
, Library Name: AdVarSource
, Library Path: /home/cfxuser/shared_libraries
and the User Function is set up as follows:
, Function Name: UserSource2
, Option: User Function
, User Routine Name: UserSource2Routine
, Argument List: [kg m^-2 s^-1]
, Result Units: [kg m^-2 s^-1]
In this example, the user subroutine AdVarSource.F is stored in the shared library libAdVarSource.so (the prefix and suffix may vary depending on your platform) which can be found under the
/home/cfxuser/shared_libraries/ directory. Defining the Source Term
The new User CEL Function can now be used to set the additional variable source within the subdomain as follows:
, Create a subdomain and set the Additional Variable Source Value as:
UserSource2(1000 [kg m^-2 s^-1]).
This is accessed from the Subdomain Sources form. For details, see Sources
Tab.
The coefficient a in the non-linear source term has been set to a constant value of 1000 [kg m^-2 s^-1].
User Fortran Routine
The subroutine was developed from the template routine ucf_template.F available in /examples/. Note that some commented sections of the routine have not been included here. This routine contains a call to USER_GETVAR to access variable data. For details, see Utility Routines
for User Functions. Note that USER_GETVAR requires the fluid prefix for user-supplied variable names. For a one-off application it is possible simply to call USER_GETVAR with an assumed name for the working fluid, e.g., for a single phase problem using ‘Water':
CALL USER_GETVAR (‘Water,phi1.Gradient', CRESLT, pGRAD_PHI,
& CZ,DZ,IZ,LZ,RZ)
However, to make it applicable in general, the example given here uses USER_ASSEMBLE_INFO to extract the equation and principal names, and GET_PHASE_FROM_VAR followed by CONVERT_NAME_S2U to extract the user's phase name. Hence, it works on any problem, independently of the choice of fluids.
, USER_ASSEMBLE_INFO
, GET_PHASE_FROM_VAR
, CONVERT_NAME_S2U
The routine AdVarSource.F has the following form:
#include "cfx5ext.h"
dllexport(user_source2)
SUBROUTINE USER_SOURCE2 (
& NLOC,NRET,NARG,RET,ARGS,CRESLT,CZ,DZ,IZ,LZ,RZ)
C--------------------
C Details
C --------------------
C ARGS(1:NLOC,1) holds parameter 'a' evaluated at all locations
C RET(1:NLOC,1) will hold return result C ------------------------------ C Preprocessor includes
C ------------------------------ #include "MMS.h"
#include "stack_point.h"
C ------------------------------ C Argument list
C ------------------------------
INTEGER NLOC,NARG,NRET
CHARACTER CRESLT*(*)
REAL ARGS(NLOC,NARG), RET(NLOC,NRET)
INTEGER IZ(*)
CHARACTER CZ(*)*(1)
DOUBLE PRECISION DZ(*)
LOGICAL LZ(*)
REAL RZ(*)
C ------------------------------ C External routines
C ------------------------------
INTEGER LENACT
EXTERNAL LENACT
C ------------------------------ C Local Variables
C ------------------------------
CHARACTER*(MXDNAM) ACTION,CGROUP,CEQN,CTERM,CPVAR,
& CLVAR,CPATCH,CRESLOC,CPHASE
CHARACTER*120 User_Phase_Name, User_Variable_Name
C ------------------------------ C Stack pointers
C ------------------------------
__stack_point__ pGRAD_PHI
C ---------------------------
C Executable Statements
C ---------------------------
C Initialise success flag.
CRESLT = 'GOOD'
C Initialise RET to zero.
CALL SET_A_0 ( RET, NLOC*NRET )
C
C---- Determine user's phase name for use in USER_GETVAR C
C Use USER_ASSEMBLE_INFO to determine solver equation and principal C variable names CEQN, CPVAR.
ACTION = 'GET'
CALL USER_ASSEMBLE_INFO (ACTION,CGROUP,CEQN,CTERM,CPVAR,
& CLVAR,CPATCH,CRESLOC,
& CZ,DZ,IZ,LZ,RZ)
IF (CRESLOC.NE.'GOOD' .AND. CRESLOC.NE.'SOME') THEN
CRESLT = 'FAIL'
GO TO 999
ENDIF
C Extract phase name from principal variable
CALL GET_PHASE_FROM_VAR (CPVAR, CPHASE)
C Convert solver phase name to user phase name.
CALL CONVERT_NAME_S2U('Phase',CPHASE,' ',User_Phase_Name,
& CRESLT, CZ,DZ,IZ,LZ,RZ)
IF (CRESLT .NE. 'GOOD') GO TO 999
C
C---- Obtain grad(phi1)
C in array shape GRAD_PHI(1:3,1:NLOC) located at RZ(pGRAD_PHI) C
User_Variable_Name = User_Phase_Name(1:LENACT(User_Phase_Name))
& // '.phi1.Gradient'
CALL USER_GETVAR (User_Variable_Name, CRESLT, pGRAD_PHI,
& CZ,DZ,IZ,LZ,RZ)
IF (CRESLT .NE. 'GOOD') GO TO 999
C
C---- Calculate source expression in RET(1:NLOC,1) C
CALL USER_SOURCE_CAL( RET(1,1), ARGS(1,1), RZ(pGRAD_PHI), NLOC ) C
999 CONTINUE
C
C Send any diagnostics or stop requests via master processor
IF (CRESLT .NE. 'GOOD') THEN
CALL MESAGE( 'BUFF', 'USER_SOURCE2 returned error:' )
CALL MESAGE( 'BUFF', CRESLT )
CALL MESAGE( 'BUFF-OUT', ' ' )
END IF
C
C====================================================================
===
END
SUBROUTINE USER_SOURCE_CAL (SOURCE, A, GRAD_PHI, NLOC)
C
C Purpose: Source = a * grad(phi).grad(phi) C
C Inputs
INTEGER NLOC
REAL A(NLOC), GRAD_PHI(3,NLOC) C Outputs
REAL SOURCE(NLOC)
C Locals
INTEGER ILOC
C
DO ILOC = 1, NLOC
SOURCE(ILOC) = A(ILOC) * ( GRAD_PHI(1,ILOC)**2
& + GRAD_PHI(2,ILOC)**2
& + GRAD_PHI(3,ILOC)**2 )
END DO
C
END
User CEL Example 3: Integrated Quantity Boundary Conditions Problem Setup
One application of the integrated quantity functions would be to set a boundary inlet temperature based on some average outflow values from a domain. In this way, you could set up a boundary condition, which acts like a thermostat control for a room. This requires the use of a User CEL Function to set the inflow temperature, and one of the arguments, which is passed to the subroutine, is the average outflow temperature. Creating the User Function
Further information on creating User CEL Function in ANSYS CFX-Pre is available. For details, see User Functions.
First, you should first create a User Routine with the following settings:
, Routine Name: INLET T
, Option: User CEL Function
, Calling Name: inlet_t
, Library Name: InletTemperature
, Library Path: /home/cfxuser/shared_libraries
Next, you should create a User Function with the following settings.
, Function Name: INLET T
, User Routine Name: INLET T
, Argument List: [K], [Pa]
, Result Units: [K]
In this example, the user subroutine InletTemperature.F is stored in the shared library libInletTemperature.so (the prefix and suffix may vary depending on your platform) which can be found under the /home/cfxuser/shared_libraries/ directory. The new User CEL Function can now be used to set the feedback loop for the inlet temperature as follows:
, On the Inlet Boundary Condition Values form set the Heat Transfer
option to Static Temperature and enter the expression:
INLET_T(areaAve(T)@Outflow,areaAve(p)@Outflow)
Note that the integrated quantity is passed into the inlet temperature function as an argument. The ANSYS CFX-Solver recalculates these values during the coefficient loop so that the value is always up to date. For
details, see Boundary Details: Inlet.
User Fortran Routine
The routine InletTemperature.F has the following form (note that this is not a complete routine, the purpose of this example is to demonstrate the quantities that can be passed to the subroutine).
#include "cfx5ext.h"
dllexport(inlet_t)
SUBROUTINE INLET_T
(NLOC,NRET,NARG,RET,ARGS,CRESLT,CZ,DZ,IZ,LZ,RZ)
C
C ------------------------------
C Argument list
C ------------------------------
INTEGER NLOC, NRET, NARG
CHARACTER CRESLT*(*)
REAL RET(1:NLOC,1:NRET), ARGS(1:NLOC,1:NARG)
C
C------------------------------------------------------------------ C ‘Static Temperature‘ is stored in RET(1:NLOC,1)
C ‘areaAve(T@Outflow)‘ is stored in ARGS(1:NLOC,1)
C ‘areaAve(p@Outflow)‘ is stored in ARGS(1:NLOC,2)
C------------------------------------------------------------------ C
C ------------------------------
C Executable statements
C ------------------------------
C
...
END