Many UDF tasks require repeated operations to be performed on nodes, cells, and threads in
a computational domain. For your convenience, Ansys Fluent has provided you with a set of
predefined macros to accomplish looping tasks. For example, to define a custom boundary
profile function you will need to loop over all the faces in a face thread using
begin..end_f_loop
looping macros. For operations where you want to
loop over all the faces or cells in a domain, you will need to nest a
begin..end_f_loop
or begin..end_c_loop
inside a thread_loop_f
or thread_loop_c
,
respectively.
The following general looping macros can be used for UDFs in single-phase or multiphase models in Ansys Fluent. Definitions for these macros are contained in the mem.h header file.
Important: You should not access a Scheme variable using any of the
RP_GET_...
functions from inside a cell or face looping macro
(c_loop or f_loop). This type of communication between the solver and cortex is very time
consuming and therefore should be done outside of loops.
For more information, see the following sections:
- 3.3.1. Looping Over Cell Threads in a Domain (thread_loop_c)
- 3.3.2. Looping Over Face Threads in a Domain (thread_loop_f)
- 3.3.3. Looping Over Cells in a Cell Thread (begin...end_c_loop)
- 3.3.4. Looping Over Faces in a Face Thread (begin...end_f_loop)
- 3.3.5. Looping Over Faces of a Cell (c_face_loop)
- 3.3.6. Looping Over Nodes of a Cell (c_node_loop)
- 3.3.7. Looping Over Nodes of a Face (f_node_loop)
- 3.3.8. Overset Mesh Looping Macros
- 3.3.9. Multiphase Looping Macros
- 3.3.10. Advanced Multiphase Macros
You can use thread_loop_c
when you want to loop over all cell
threads in a given domain. It consists of a single statement, followed by the operation(s)
to be performed on all cell threads in the domain enclosed within braces
as shown below. Note that
thread_loop_c
is similar in implementation to the
thread_loop_f
macro described below.
Domain *domain; Thread *c_thread; thread_loop_c(c_thread, domain) /*loops over all cell threads in domain*/ { }
You can use thread_loop_f
when you want to loop over all face
threads in a given domain. It consists of a single statement, followed by the operation(s)
to be performed on all face threads in the domain enclosed within braces
as shown below. Note that
thread_loop_f
is similar in implementation to the
thread_loop_c
macro described above.
Thread *f_thread; Domain *domain; thread_loop_f(f_thread, domain)/* loops over all face threads in a domain*/ { }
You can use begin_c_loop
and
end_c_loop
when you want to loop over all cells in a given cell
thread. It contains a begin
and end
loop
statement, and performs operation(s) on each cell in the cell thread as defined between the
braces
. This loop is usually nested within
thread_loop_c
when you want to loop over all cells in all cell
threads in a domain.
cell_t c; Thread *c_thread; begin_c_loop(c, c_thread) /* loops over cells in a cell thread */ { } end_c_loop(c, c_thread)
Example
/* Loop over cells in a thread to get information stored in cells. */ begin_c_loop(c, c_thread) { /* C_T gets cell temperature. The += will cause all of the cell temperatures to be added together. */ temp += C_T(c, c_thread); } end_c_loop(c, c_thread) }
You can use begin_f_loop
and
end_f_loop
when you want to loop over all faces in a given face
thread. It contains a begin
and end
loop
statement, and performs operation(s) on each face in the face thread as defined between the
braces
. This loop is usually nested within
thread_loop_f
when you want to loop over all faces in all face
threads in a domain.
face_t f; Thread *f_thread; begin_f_loop(f, f_thread) /* loops over faces in a face thread */ { } end_f_loop(f, f_thread)
Example
/* Loop over faces in a face thread to get the information stored on faces. */ begin_f_loop(f, f_thread) { /* F_T gets face temperature. The += will cause all of the face temperatures to be added together. */ temp += F_T(f, f_thread); } end_f_loop(f, f_thread)
The following looping function loops over all faces of a given cell. It consists of a single loop statement, followed by the action to be taken in braces.
cell_t c; Thread *t; face_t f; Thread *tf; int n; c_face_loop(c, t, n) /* loops over all faces of a cell */ { . . . f = C_FACE(c,t,n); tf = C_FACE_THREAD(c,t,n); . . . }
The argument n
is the local face index number. The local face
index number is used in the C_FACE
macro to obtain the global face
number (for example, f = C_FACE(c,t,n)
).
Another useful macro that is often used in c_face_loop
is
C_FACE_THREAD
. This macro is used to reference the associated
face thread (for example, tf = C_FACE_THREAD(c,t,n)
).
Refer to Miscellaneous Macros for other macros that are associated
with c_face_loop
.
c_node_loop(c,t,n)
is a function that loops over all nodes of a
given cell. It consists of a single loop statement, followed by the action to be taken in
braces {}
.
Example:
cell_t c; Thread *t; int n; Node *node; c_node_loop(c,t,n) { . . node = C_NODE(c,t,n); . . }
Here, n
is the local node index number. The index number can be
used with the C_NODE
macro to obtain the global cell node number
(for example, node = C_NODE(c,t,n)
).
f_node_loop(f,t,n)
is a function that loops over all nodes of a
given face. It consists of a single loop statement, followed by the action to be taken in
braces {}
.
Example
face_t f; Thread *t; int n; Node *node; f_node_loop(f,t,n) { . . . node = F_NODE(f,t,n); . . . }
Here, n
is the local node index number. The index number can be
used with the F_NODE
macro to obtain the global face node number
(for example, node = F_NODE(f,t,n)
).
See
DEFINE_GRID_MOTION
for an example of a UDF that uses
f_node_loop
.
This section contains descriptions of looping macros that can be used for cases that have overset meshes. For further information about overset meshes, see Overset Meshes in the User's Guide.
You can use thread_loop_overset_c
when you want to loop over
only the cell threads participating in the overset interfaces for a given domain (as
opposed to the thread_loop_c
function, which is for operations
that need to be performed across all cell threads in the domain). It consists of a single
statement, followed by the operations (enclosed within parentheses, as shown in the
example that follows) to be performed on all the cell threads related to the overset
interfaces in the domain.
Domain *domain; Thread *c_thread; thread_loop_overset_c(c_thread, domain) /*loops over all cell threads participating in overset */ /*interfaces in the domain */ { }
The cells in a domain with overset meshes may be classified into two broad categories: active cells and dead (inactive) cells. This classification is important with regards to the solver discretization (gradient evaluations, sources, AMG system, and so on) and the solution variables. Active cells may further be divided into solve cells and receptor (interpolation) cells (see Overset Field Functions in the User's Guide).
Therefore, a generalization of begin_c_loop
and
end_c_loop
for overset meshes is available. The two loops
are:
begin_c_loop_active
begin_c_loop_solve
The active function loops over all cells except dead (inactive) cells. The solve loop is restricted to active cells where no interpolation is performed (that is, receptor cells are excluded). It is recommended that you use overset specific loops when global operations are performed, such as the evaluation of minimum or maximum values in the cell thread, or the summation over cell threads. The choice to include receptor cells in these evaluations will determine the choice of loops, and is left to your discretion.
Note: Global summations over all active or solve cells in all cell threads may still introduce an error due to mesh overlap in an overset mesh. For details, see Overset Postprocessing Limitations.
You can use begin_c_loop_active
and
end_c_loop_active
or
begin_c_loop_solve
and
end_c_loop_solve
when you want to loop over all active or solve
cells, respectively, in a given cell thread. These functions contain a begin and end loop
statement, and perform operations (enclosed within parentheses, as shown in the example
that follows) on each cell in the cell thread. Such loops are usually nested within
thread_loop_overset_c
, so that they loop over cells in only the
cell threads participating in the overset interface in a domain; you may also nest them
under thread_loop_c
.
cell_t c; Thread *c_thread; begin_c_loop_active(c, c_thread) /* loops over solve + receptor cells in a cell thread, no dead cells */ { } end_c_loop_active(c, c_thread) cell_t c; Thread *c_thread; begin_c_loop_solve(c, c_thread) /* loops over solve cells in a cell thread, no receptor or dead cells */ { } end_c_loop_solve(c, c_thread)
/* Loop over solve cells in a thread and perform arithmetic averaging of Temperature. */ real no_solve_cells; real avg_temp_solve=0.0; begin_c_loop_solve(c, c_thread) { /* C_T gets cell temperature. The += causes all cell temperatures to be added together. */ avg_temp_solve += C_T(c, c_thread); no_solve_cells=no_solve_cells+1.0; } end_c_loop_solve(c, c_thread) } avg_temp_solve = avg_temp_solve/no_solve_cells;
/* Loop over active cells (solve + receptor) in a thread and perform arithmetic averaging of Temperature. */ real no_active_cells; real avg_temp_active=0.0; begin_c_loop_active(c, c_thread) { /* C_T gets cell temperature. The += causes all cell temperatures to be added together. */ avg_temp_active += C_T(c, c_thread); no_cells_active = no_cells_active+1.0; } end_c_loop_active(c, c_thread) } avg_temp_active = avg_temp_active/no_active_cells;
Similar to the cell loops, you can use begin_f_loop_active
and end_f_loop_active
when you want to loop over all of the faces
in a given face thread, excluding the overset interface and dead faces. The overset dead
faces are defined as faces that lie adjacent to a dead cell for a boundary thread and
between two dead cells when they are part of an interior face thread. The overset
interface face is defined as a face that
lies on an overset boundary thread adjacent to a receptor cell
separates active cells from dead cells (that is, between receptor and dead cells)
Figure 3.3: Overset Interface Example shows the overset interface before and after intersection (on the left and right side, respectively), so that the location of dead cells are apparent. The bottom row shows the overset cell type field contour plot for one of the component meshes (cyan = receptor, red = donor, yellow = solve). This figure illustrates that an overset interface face can lie either on the overset boundary thread or between receptor and dead cells.
This loop allows face-based operations from being adversely affected by dead or
inactive cells. It contains a begin and end loop statement, and performs operations
(enclosed within parentheses, as shown in the example that follows) on each face in the
face thread. This loop is usually nested within thread_loop_f
, so
that it loops over all of the faces in all face threads in a domain.
face_t f; Thread *f_thread; begin_f_loop_active(f, f_thread) /* loops over all active faces in a face thread */ { } end_f_loop_active(f, f_thread)
/* Loop over active faces in a face thread to get the information stored on faces. */ real no_active_faces; real avg_temp_active=0.0; begin_f_loop_active(f, f_thread) { /* F_T gets face temperature. The += causes all face temperatures to be added together. */ avg_temp_active += F_T(f, f_thread); no_active_faces = no_active_faces + 1.0; } end_f_loop_active(f, f_thread) avg_temp_active /= no_of_active_faces;
This section contains a description of looping macros that are to be used for multiphase UDFs only. They enable your function to loop over all cells and faces for given threads or domains. Refer to Multiphase-specific Data Types and, in particular, Figure 1.5: Domain and Thread Structure Hierarchy for a discussion on hierarchy of structures within Ansys Fluent.
The sub_domain_loop
macro loops over all phase domains
(subdomains) within the mixture domain. The macro steps through and provides each phase
domain pointer defined in the mixture domain as well as the corresponding
phase_domain_index
. As discussed in Multiphase-specific Data Types, the domain pointer is needed, in part, to gain
access to data within each phase. Note that sub_domain_loop
is
similar in implementation to the sub_thread_loop
macro described
below.
int phase_domain_index; /* index of subdomain pointers */ Domain *mixture_domain; Domain *subdomain; sub_domain_loop(subdomain, mixture_domain, phase_domain_index)
The variable arguments to sub_domain_loop
are
subdomain
, mixture_domain
, and
phase_domain_index
. subdomain
is a
pointer to the phase-level domain, and mixture_domain
is a
pointer to the mixture-level domain. The mixture_domain
is
automatically passed to your UDF by the Ansys Fluent solver when you use a
DEFINE
macro that contains a domain variable argument (for
example, DEFINE_ADJUST
) and your UDF is hooked to the mixture. If
mixture_domain
is not explicitly passed to your UDF, you will
need to use another utility macro to retrieve it (for example,
Get_Domain(1)
) before calling
sub_domain_loop
(see Domain Pointer (Get_Domain
)). phase_domain_index
is an index of subdomain pointers.
phase_domain_index
is 0
for the
primary phase, and is incremented by one for each secondary phase in the mixture. Note
that subdomain
and phase_domain_index
are set within the sub_domain_loop
macro.
Example
The following interpreted UDF patches an initial volume fraction for a particular
phase in a solution. It is executed once at the beginning of the solution process. The
function sets up a spherical volume centered at 0.5, 0.5, 0.5
with a radius of 0.25
. A secondary-phase volume fraction of
1
is then patched to the cells within the spherical volume,
while the volume fraction for the secondary phase in all other cells is set to
0
.
/***************************************************************** UDF for initializing phase volume fraction ******************************************************************/ #include "udf.h" /* domain pointer that is passed by INIT function is mixture domain */ DEFINE_INIT(my_init_function, mixture_domain) { int phase_domain_index; cell_t cell; Thread *cell_thread; Domain *subdomain; real xc[ND_ND]; /* loop over all subdomains (phases) in the superdomain (mixture) */ sub_domain_loop(subdomain, mixture_domain, phase_domain_index) { /* loop if secondary phase */ if (DOMAIN_ID(subdomain) == 3) /* loop over all cell threads in the secondary phase domain */ thread_loop_c (cell_thread,subdomain) { /* loop over all cells in secondary phase cell threads */ begin_c_loop (cell,cell_thread) { C_CENTROID(xc,cell,cell_thread); if (sqrt(ND_SUM(pow(xc[0] - 0.5,2.), pow(xc[1] - 0.5,2.), pow(xc[2] - 0.5,2.))) < 0.25) /* set volume fraction to 1 for centroid */ C_VOF(cell,cell_thread) = 1.; else /* otherwise initialize to zero */ C_VOF(cell,cell_thread) = 0.; } end_c_loop (cell,cell_thread) } } }
The sub_thread_loop
macro loops over all phase-level threads
(subthreads) associated with a mixture-level thread. The macro steps through and returns
the pointer to each subthread as well as the corresponding
phase_domain_index
. As discussed in Multiphase-specific Data Types, if the subthread pointer is associated with an
inlet zone, then the macro will provide the pointers to the face threads associated with
the inlet for each of the phases.
int phase_domain_index; Thread *subthread; Thread *mixture_thread; sub_thread_loop(subthread, mixture_thread, phase_domain_index)
The variable arguments to sub_thread_loop
are
subthread
, mixture_thread
, and
phase_domain_index
. subthread
is a
pointer to the phase thread, and mixture_thread
is a pointer to
the mixture-level thread. The mixture_thread
is automatically
passed to your UDF by the Ansys Fluent solver when you use a DEFINE
macro that contains a thread variable argument (for example,
DEFINE_PROFILE
) and your UDF is hooked to the mixture. If the
mixture_thread
is not explicitly passed to your UDF, you will
need to use a utility macro to retrieve it before calling
sub_thread_loop
. phase_domain_index
is
an index of subdomain pointers that can be retrieved using the
PHASE_DOMAIN_INDEX
macro. (See Phase Domain Index (PHASE_DOMAIN_INDEX
)
0
for the primary phase, and is incremented by one for each
secondary phase in the mixture. Note that subthread
and
phase_domain_index
are initialized within the
sub_thread_loop
macro definition.
The mp_thread_loop_c
macro loops through all cell threads (at
the mixture level) within the mixture domain and provides the pointers of the phase-level
(cell) threads associated with each mixture-level thread. This is nearly identical to the
thread_loop_c
macro (Looping Over Cell Threads in a Domain (thread_loop_c
)) when applied to the mixture domain. The difference is that, in addition to stepping
through each cell thread, the macro also returns a pointer array
(pt
) that identifies the corresponding phase-level threads. The
pointer to the cell thread for the ith phase is
pt[i]
, where i
is the
phase_domain_index
. pt[i]
can be used
as an argument to macros requiring the phase-level thread pointer.
phase_domain_index
can be retrieved using the
PHASE_DOMAIN_INDEX
macro. (See Phase Domain Index (PHASE_DOMAIN_INDEX
)
Thread **pt; Thread *cell_threads; Domain *mixture_domain; mp_thread_loop_c(cell_threads, mixture_domain, pt)
The variable arguments to mp_thread_loop_c
are
cell_threads
, mixture_domain
, and
pt
. cell_threads
is a pointer to the
cell threads, and mixture_domain
is a pointer to the
mixture-level domain. pt
is an array pointer whose elements
contain pointers to phase-level threads.
mixture_domain
is automatically passed to your UDF by the
Ansys Fluent solver when you use a DEFINE
macro that contains a
domain variable argument (for example, DEFINE_ADJUST
) and your
UDF is hooked to the mixture. If mixture_domain
is not explicitly
passed to your UDF, you will need to use another utility macro to retrieve it (for
example, Get_Domain(1)
, described in Domain Pointer (Get_Domain
)). Note that the values for
pt
and cell_threads
are set within the
looping function.
mp_thread_loop_c
is typically used along with
begin_c_loop
. begin_c_loop
loops over
cells in a cell thread. When begin_c_loop
is nested within
mp_thread_loop_c
, you can loop over all cells in all phase cell
threads within a mixture.
The mp_thread_loop_f
macro loops through all face threads (at
the mixture level) within the mixture domain and provides the pointers of the phase-level
(face) threads associated with each mixture-level thread. This is nearly identical to the
thread_loop_f
macro when applied to the mixture domain. The
difference is that, in addition to stepping through each face thread, the macro also
returns a pointer array (pt
) that identifies the corresponding
phase-level threads. The pointer to the face thread for the i
th phase is pt[i]
, where
i
is the phase_domain_index
.
pt[i]
can be used as an argument to macros requiring the
phase-level thread pointer. The phase_domain_index
can be
retrieved using the PHASE_DOMAIN_INDEX
macro. (See Phase Domain Index (PHASE_DOMAIN_INDEX
) for details.)
Thread **pt; Thread *face_threads; Domain *mixture_domain; mp_thread_loop_f(face_threads, mixture_domain, pt)
The variable arguments to mp_thread_loop_f
are
face_threads
, mixture_domain
, and
pt
. face_threads
is a pointer to the
face threads, and mixture_domain
is a pointer to the
mixture-level domain. pt
is an array pointer whose elements
contain pointers to phase-level threads.
mixture_domain
is automatically passed to your UDF by the
Ansys Fluent solver if you are using a DEFINE
macro that contains a
domain variable argument (for example, DEFINE_ADJUST
) and your
UDF is hooked to the mixture. If mixture_domain
is not explicitly
passed to your UDF, you may use another utility macro to retrieve it (for example,
Get_Domain(1)
, described in Domain Pointer (Get_Domain
)). Note that the values for
pt
and face_threads
are set within the
looping function.
mp_thread_loop_f
is typically used along with
begin_f_loop
. begin_f_loop
loops over
faces in a face thread. When begin_f_loop
is nested within
mp_thread_loop_f
, you can loop over all faces in all phase face
threads within a mixture.
For most standard UDFs written for multiphase models (for example, source term, material
property, profile functions), variables that your function needs (domain pointers, thread
pointers, and so on) are passed directly to your UDF as arguments by the solver in the
solution process. All you need to do is hook the UDF to your model and everything is taken
care of. For example, if your multiphase UDF defines a custom profile for a particular
boundary zone (using DEFINE_PROFILE
) and is hooked to the
appropriate phase or mixture in Ansys Fluent in the relevant boundary condition dialog box, then
appropriate phase or mixture variables will be passed to your function by the solver at run
time.
There may, however, be more complex functions you want to write that require a variable
that is not directly passed through its arguments.
DEFINE_ADJUST
and DEFINE_INIT
functions,
for example, are passed mixture domain variables only. If a UDF requires a phase domain
pointer, instead, then it will need to use macros presented in this section to retrieve it.
ON_DEMAND
UDFS are not directly passed any variables through
their arguments. Consequently, any on demand function that requires access to phase or
domain variables will also need to use macros presented in this section to retrieve
them.
Recall that when you are writing UDFs for multiphase models, you will need to keep in
mind the hierarchy of structures within Ansys Fluent (see Multiphase-specific Data Types for details). The particular domain or thread
structure that gets passed into your UDF from the solver depends on the
DEFINE
macro you are using, as well as the domain the function is
hooked to (either through the graphical user interface, or hardwired in the code). As
mentioned above, it also may depend on the multiphase model that you are using. Refer to
Multiphase-specific Data Types and, in particular, Figure 1.5: Domain and Thread Structure Hierarchy for a discussion on hierarchy of structures within
Ansys Fluent.
There are two ways you can get access to a specific phase (or subdomain) pointer
within the mixture domain. You can use either the
DOMAIN_SUB_DOMAIN
macro (described below) or
Get_Domain
, which is described below.
DOMAIN_SUB_DOMAIN
has two arguments:
mixture_domain
and phase_domain_index
.
The function returns the phase pointer subdomain
for the given
phase_domain_index
. Note that
DOMAIN_SUB_DOMAIN
is similar in implementation to the
THREAD_SUB_THREAD
macro described in Phase-Level Thread Pointer (THREAD_SUB_THREAD
).
int phase_domain_index = 0; /* primary phase index is 0 */ Domain *mixture_domain; Domain *subdomain = DOMAIN_SUB_DOMAIN(mixture_domain,phase_domain_index);
mixture_domain
is a pointer to the mixture-level domain. It is
automatically passed to your UDF by the Ansys Fluent solver when you use a
DEFINE
macro that contains a domain variable argument (for
example, DEFINE_ADJUST
) and your UDF is hooked to the mixture.
Otherwise, if the mixture_domain
is not explicitly passed to your
UDF, you will need to use another utility macro to retrieve it (for example,
Get_Domain(1)
) before calling
sub_domain_loop
.
phase_domain_index
is an index of subdomain pointers. It is an
integer that starts with 0
for the primary phase and is
incremented by one for each secondary phase. phase_domain_index
is automatically passed to your UDF by the Ansys Fluent solver when you use a
DEFINE
macro that contains a phase domain index argument
(DEFINE_EXCHANGE_PROPERTY
,
DEFINE_VECTOR_EXCHANGE_PROPERTY
) and your UDF is hooked to a
specific interaction phase. Otherwise, you will need to hard code the integer value of
phase_domain_index
to the
DOMAIN_SUB_DOMAIN
macro. If your multiphase model has only two
phases defined, then phase_domain_index
is
0
for the primary phase, and 1
for the
secondary phase. However, if you have more than one secondary phase defined for your
multiphase model, you will need to use the PHASE_DOMAIN_INDEX
utility to retrieve the corresponding phase_domain_index
for the
given domain. See Phase Domain Index (PHASE_DOMAIN_INDEX
) for details.
The THREAD_SUB_THREAD
macro can be used to retrieve the
phase-level thread (subthread) pointer, given the phase domain index.
THREAD_SUB_THREAD
has two arguments:
mixture_thread
and
phase_domain_index
.
The function returns the phase-level thread pointer for the given
phase_domain_index
. Note that
THREAD_SUB_THREAD
is similar in implementation to the
DOMAIN_SUB_DOMAIN
macro described in Phase Domain Pointer (DOMAIN_SUB_DOMAIN
).
int phase_domain_index = 0; /* primary phase index is 0 */ Thread *mixture_thread; /* mixture-level thread pointer */ Thread *subthread = THREAD_SUB_THREAD(mixture_thread,phase_domain_index);
mixture_thread
is a pointer to a mixture-level thread. It is
automatically passed to your UDF by the Ansys Fluent solver when you use a
DEFINE
macro that contains a variable thread argument (for
example, DEFINE_PROFILE
), and the function is hooked to the
mixture. Otherwise, if the mixture thread pointer is not explicitly passed to your UDF,
then you will need to use the Lookup_Thread
utility macro to
retrieve it (see Thread Pointer for Zone ID (Lookup_Thread
)).
phase_domain_index
is an index of subdomain pointers. It is an
integer that starts with 0
for the primary phase and is
incremented by one for each secondary phase. phase_domain_index
is automatically passed to your UDF by the Ansys Fluent solver when you use a
DEFINE
macro that contains a phase domain index argument
(DEFINE_EXCHANGE_PROPERTY
,
DEFINE_VECTOR_EXCHANGE_PROPERTY
) and your UDF is hooked to a
specific interaction phase. (See
DEFINE_EXCHANGE_PROPERTY
phase_domain_index
to the
THREAD_SUB_THREAD
macro.) If your multiphase model has only two
phases defined, then phase_domain_index
is
0
for the primary phase, and 1
for the
secondary phase. However, if you have more than one secondary phase defined for your
multiphase model, you will need to use the PHASE_DOMAIN_INDEX
utility to retrieve the corresponding phase_domain_index
for the
given domain. See Phase Domain Index (PHASE_DOMAIN_INDEX
) for details.
The THREAD_SUB_THREADS
macro can be used to retrieve the
pointer array, pt
, whose elements contain pointers to phase-level
threads (subthreads). THREAD_SUB_THREADS
has one argument,
mixture_thread
.
Thread *mixture_thread; Thread **pt; /* initialize pt */ pt = THREAD_SUB_THREADS(mixture_thread);
mixture_thread
is a pointer to a mixture-level thread which can
represent a cell thread or a face thread. It is automatically passed to your UDF by the
Ansys Fluent solver when you use a DEFINE
macro that contains a
variable thread argument (for example, DEFINE_PROFILE
), and the
function is hooked to the mixture. Otherwise, if the mixture thread pointer is not
explicitly passed to your UDF, then you will need to use another method to retrieve it.
For example you can use the Lookup_Thread
utility macro (see
Thread Pointer for Zone ID (Lookup_Thread
)).
pt[i]
, an element in the array, is a pointer to the corresponding
phase-level thread for the ith phase, where
i
is the phase_domain_index
. You can
use pt[i]
as an argument to some cell variable macros when you
want to retrieve specific phase information at a cell. For example,
C_R(c,pt[i])
can be used to return the density of the
i
th phase fluid at cell c
. The pointer
pt[i]
can also be retrieved using
THREAD_SUB_THREAD
, discussed in Phase-Level Thread Pointer (THREAD_SUB_THREAD
), using i
as an
argument. The phase_domain_index
can be retrieved using the
PHASE_DOMAIN_INDEX
macro. See Phase Domain Index (PHASE_DOMAIN_INDEX
) for details.
You can use DOMAIN_SUPER_DOMAIN
when your UDF has access to a
particular phase-level domain (subdomain) pointer, and you want to retrieve the
mixture-level domain pointer. DOMAIN_SUPER_DOMAIN
has one
argument, subdomain
. Note that
DOMAIN_SUPER_DOMAIN
is similar in implementation to the
THREAD_SUPER_THREAD
macro described in Mixture Thread Pointer (THREAD_SUPER_THREAD
).
Domain *subdomain; Domain *mixture_domain = DOMAIN_SUPER_DOMAIN(subdomain);
subdomain
is a pointer to a phase-level domain within the
multiphase mixture. It is automatically passed to your UDF by the Ansys Fluent solver when you
use a DEFINE
macro that contains a domain variable argument (for
example, DEFINE_ADJUST
), and the function is hooked to a primary
or secondary phase in the mixture. Note that in the current version of Ansys Fluent,
DOMAIN_SUPER_DOMAIN
will return the same pointer as
Get_Domain(1)
. Therefore, if a subdomain pointer is available
in your UDF, it is recommended that the DOMAIN_SUPER_DOMAIN
macro
be used instead of the Get_Domain
macro to avoid potential
incompatibility issues with future releases of Ansys Fluent.
You can use the THREAD_SUPER_THREAD
macro when your UDF has
access to a particular phase-level thread (subthread) pointer, and you want to retrieve
the mixture-level thread pointer. THREAD_SUPER_THREAD
has one
argument, subthread
.
Thread *subthread; Thread *mixture_thread = THREAD_SUPER_THREAD(subthread);
subthread
is a pointer to a particular phase-level thread within
the multiphase mixture. It is automatically passed to your UDF by the Ansys Fluent solver when
you use a DEFINE
macro that contains a thread variable argument
(for example, DEFINE_PROFILE
, and the function is hooked to a
primary or secondary phase in the mixture. Note that
THREAD_SUPER_THREAD
is similar in implementation to the
DOMAIN_SUPER_DOMAIN
macro described in Mixture Domain Pointer (DOMAIN_SUPER_DOMAIN
).
You can use DOMAIN_ID
when you want to access the
domain_id
that corresponds to a given phase-level domain
pointer. DOMAIN_ID
has one argument,
subdomain
, which is the pointer to a phase-level domain. The
default domain_id
value for the top-level domain (mixture) is
1
. That is, if the domain pointer that is passed to
DOMAIN_ID
is the mixture-level domain pointer, then the
function will return a value of 1
. Note that the
domain_id
that is returned by the macro is the same integer ID
that is displayed in the graphical user interface when you select the desired phase in the
Phases dialog box in Ansys Fluent.
Domain *subdomain; int domain_id = DOMAIN_ID(subdomain);
The PHASE_DOMAIN_INDEX
macro retrieves the
phase_domain_index
for a given phase-level domain (subdomain)
pointer.
PHASE_DOMAIN_INDEX
has one argument,
subdomain
, which is the pointer to a phase-level domain.
phase_domain_index
is an index of subdomain pointers. It is an
integer that starts with 0
for the primary phase and is
incremented by one for each secondary phase.
Domain *subdomain; int phase_domain_index = PHASE_DOMAIN_INDEX(subdomain);