Through a call to Zoltan_Set_Fn, the function user_return_owned_nodes is registered as the ZOLTAN_OBJ_LIST_FN query function. It returns global and local identifiers for each node owned by a processor.
The function user_return_coords is registered as a ZOLTAN_GEOM_FN query function. Given the global and local identifiers for a node, this function returns the node's coordinates. All the examples exploit the local identifier to quickly locate nodal data. If such an identifier is not available in an application, a search using the global identifier can be performed.
The Basic Example includes the simplest implementation of the query routines. In the query routines, it uses global application data structures and a local numbering scheme for the local identifiers. The User-Defined Data Pointer Example uses only local application data structures; this model is useful if the application does not have global data structures or if objects from more than one data structure are to be passed to Zoltan. Differences between the latter example and the Basic Example are shown in red.
/* in application's program
file */
#include "zoltan.h" /* Declare a global Mesh data structure. */
main()
/* Register query functions.
*/
void user_return_owned_nodes(void *data,
void user_return_coords(void *data,
|
! in application's program
file
module Global_Mesh_Data
program query_example_1
! Register query functions.
subroutine user_return_owned_nodes(data, &
subroutine user_return_coords(data, num_gid_entries, num_lid_entries,
&
|
This model is useful when the application does not have a global data
structure that can be accessed by the query functions. It can also
be used for operations on different data structures. For example,
if an application had more than one mesh, load balancing could be performed
separately on each mesh without having different query routines for each
mesh. Calls to Zoltan_Set_Fn
would define which mesh should be balanced, and the query routines would
access the mesh currently designated by the Zoltan_Set_Fn
calls.
/* in application's program
file */
#include "zoltan.h" main()
/* Register query functions.
*/
void user_return_owned_nodes(void *data,
/* return global node numbers as global_ids.
*/
void user_return_coords(void *data,
/* cast data pointer to type Mesh_Type.
*/
/* use local_id to address the requested node.
*/
|
/* included in file
zoltan_user_data.f90 */
! User defined data type as wrapper for Mesh type Zoltan_User_Data_1 type(Mesh_type), pointer :: ptr end type Zoltan_User_Data_1
! in application's program file program query_example_3
! Register query functions.
subroutine user_return_owned_nodes(data, &
! extract the mesh from the
User_Data argument
! return global node numbers as global_ids.
subroutine user_return_coords(data, global_id, local_id, &
! extract the mesh from the
User_Data argument
! use local_id to index into the Nodes array.
|
These query routines are simple because the application does not dynamically
allocate memory for each node. Such dynamic allocation would have
to be accounted for in the ZOLTAN_OBJ_SIZE_FN,
ZOLTAN_PACK_OBJ_FN,
and ZOLTAN_UNPACK_OBJ_FN routines.
main()
{ ... /* Register migration query functions. */ /* Do not register a data pointer with the functions; */ /* the global Mesh data structure will be used. */ Zoltan_Set_Fn(zz, ZOLTAN_OBJ_SIZE_FN_TYPE, (void (*)()) user_size_node, NULL); Zoltan_Set_Fn(zz, ZOLTAN_PACK_OBJ_FN_TYPE, (void (*)()) user_pack_node, NULL); Zoltan_Set_Fn(zz, ZOLTAN_UNPACK_OBJ_FN_TYPE, (void (*)()) user_unpack_node, NULL); ... } int user_size_node(void *data,
void user_pack_node(void *data,
*ierr = ZOLTAN_OK;
void user_unpack_node(void *data, int num_gid_entries,
*ierr = ZOLTAN_OK;
|