3.4. Detailed Specifications

Include files

The following header file is required in any file containing these library routines.

#include "global_extern.h"

And it references

#include "global_extern_proto.h"

Special note

Make sure you use the proper define in the global_extern.h header file, namely:

#define USERD_API_208

Also, make sure the API version in the USERD_get_reader_version routine is set to the desired version.

Basis of arrays

Unless explicitly stated otherwise, all arrays are zero based - in true C fashion.

Global variables

You will generally need to have a few global variables which are shared by the various library routines. The detailed specifications below have assumed the following are available. (Their names describe their purpose, and they will be used in helping describe the details of the routines below).

static int Numparts_available        = 0; 
static int Num_unstructured_parts    = 0; 
static int Num_structured_blocks     = 0;  
/* Note: Numparts_available = Num_unstructured_parts + Num_structured_blocks */  
static int Num_timesets              = 1; 
static int Current_timeset           = 1; 
static int Geom_timeset_number       = 1;  
static int Num_time_steps[Z_MAXSETS] = 1; 
static int Current_time_step         = 0; 
static int Num_variables             = 0; 
static int Num_dataset_files         = 0;  
static int Server_Number             = 1; 
static int Tot_Servers               = 1;   

Sample (or stub) routines

Those routines marked optional, need not be included in a reader. They are truly optional. All other routines for a given version number need to be included, but can often be sample routines - depending on what is returned for other related routines. As an example, if you always return that borders are not available in USERD_get_border_availability, then the USERD_get_border_elements_by_type routine can be a sample routine - because it will never be called.

The specifications for each routine in the API will now be given (routines are in alphabetical order):

/*--------------------------------------------------------------------

3.4.1. USERD_bkup

 *                                           (version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Used in the archive process.  Save or restore info relating to 
 *   your user defined reader. 
 * 
 *  (IN)  archive_file         = The archive file pointer 
 * 
 *  (IN)  backup_type          = Z_SAVE_ARCHIVE for saving archive 
 *                               Z_REST_ARCHIVE for restoring archive 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * Since EnSight's archive file is saved in binary form, it is 
 *    suggested that you also do any writing to it or reading from it 
 *    in binary. 
 * 
 *  * You should archive any variables, that will be needed for 
 *    future operations, that will not be read or computed again 
 *    before they will be needed.  These are typically global 
 *    variables. 
 * 
 *  * Make sure that the number of bytes that you write on a save and 
 *    the number of bytes that you read on a restore are identical!! 
 * 
 *  * And one last reminder.  If any of the variables you save are 
 *    allocated arrays, you must do the allocations before restoring 
 *    into them. 
 * 
 *  ================================= 
 *  * SPECIAL NOTE FOR WINDOWS ONLY: 
 *    Because our current implementation under windows needs to open and close files 
 *    from within the reader .dll, a special structure (named USERD_globals) needs to 
 *    be defined in the global space of your reader. This structure needs to be defined 
 *    like:             ------ ----- 
 * 
 *    #ifdef WIN32                         (which includes 32 bit and 64 bit windows) 
 *    W32EXPORT struct _USERD_globals { 
 *      char arch_filename[256]; 
 *      unsigned long arch_fileptr; 
 *    } USERD_globals; 
 *    #endif 
 * 
 *    This structure will be bound when the reader .dll is loaded and will be used to 
 *    store the archive file name and the current offset therein. 
 *    Again for windows only, you need to ignore the archive_file pointer in the 
 *    argument list and instead open and close the arch_filename file as well as keep 
 *    the arch_fileptr offset current in this routine. 
 * 
 *    So first define the USERD_globals structure at the beginning of your reader. 
 * 
 *    Then, when an archive is saved, the following needs to be done in this routine: 
 *      1. open USERD_globals.arch_filename for appending         (within #ifdef WIN32) 
 *      2. do your writes 
 *      3. close the file                                         (within #ifdef WIN32) 
 * 
 *    When an archive is restored, do the following in this routine: 
 *      1. open USERD_globals.arch_filename for reading, 
 *            and fseek to USERD_globals.arch_fileptr offset      (within #ifdef WIN32) 
 *      2. do your reads 
 *      3. save the new USERD_globals.arch_fileptr offset (using ftell), 
 *            and close the file                                  (within #ifdef WIN32) 
 *     
 *    Here is some pseudo code to illustrate: 
 *    --------------------------------------- 
 *    switch(baskup_type) { 
 *    case Z_SAVE_ARCHIVE: 
 * 
 *  #ifdef WIN32 
 *      archive_file = fopen(USERD_globals.arch_filename,"ab"); 
 *  #endif 
 * 
 *       . 
 *       . 
 *       . 
 *  #ifdef WIN32 
 *      fclose(archive_file) 
 *  #endif 
 * 
 *      break; 
 * 
 *    case Z_REST_ARCHIVE: 
 * 
 *  #ifdef WIN32 
 *      archive_file = fopen(USERD_globals.arch_filename,"rb"); 
 *      fseek(archive_file, USERD_globals.arch_fileptr, SEEK_SET); 
 *  #endif 
 * 
 *       . 
 *       . 
 *       . 
 * 
 *  #ifdef WIN32 
 *      USERD_globals.arch_fileptr = ftell(archive_file); 
 *      fclose(archive_file) 
 *  #endif 
 * 
 *      break; 
 *   } 
 * 
 *  And finally be aware of a current limitation of the 
 *  Windows implementation of this routine: 
 *  --------------------------------------- 
 *  Because the structure uses a long for the file offset, the archive restore 
 *  will not work when the offset to the information written in this routine 
 *  is greater than 2 Gb, on 32 bit windows. On 64 bit windows there is no such 
 *  limitation because the long is 64 bits.  
 *--------------------------------------------------------------------*/ 
int 
USERD_bkup(FILE *archive_file, 
           int backup_type) 
/*--------------------------------------------------------------------

3.4.2. USERD_exit_routine

 *                                            (version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Called when EnSight is exited for USERD, can be used to 
 *   clean up temporary files, etc. It is often simply a sample. 
 *--------------------------------------------------------------------*/ 
void 
USERD_exit_routine( void ) 
/*--------------------------------------------------------------------

3.4.3. USERD_get_block_coords_by_component

 *                                            (version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the coordinates of a given block, component at a time 
 * 
 *  (IN)  block_number            = The block number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                     1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id that is 
 *                                   loaded in USERD_get_gold_part_build_info) 
 * 
 *  (IN)  which_component         = Z_COMPX if x component wanted 
 *                                = Z_COMPY if y component wanted 
 *                                = Z_COMPZ if z component wanted 
 * 
 *  (OUT) coord_array             = 1D array containing x,y, or z 
 *                                   coordinate component of each node 
 * 
 *                                  (Array will have been allocated 
 *                                   i*j*k for the block long) 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 * 
 *  * Only called for structured "block" parts 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_block_coords_by_component(int block_number, 
                                    int which_component, 
                                    float *coord_array) 
/*--------------------------------------------------------------------

3.4.4. USERD_get_block_iblanking

 *                                            (version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the iblanking value at each node of a block - If Z_IBLANKED 
 * 
 *  (IN)  block_number            = The block number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                     1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id that is 
 *                                   loaded in USERD_get_gold_part_build_info) 
 * 
 *  (OUT) iblank_array            = 1D array containing iblank value 
 *                                   for each node. 
 * 
 *                                  (Array will have been allocated 
 *                                   i*j*k for the block long) 
 * 
 *          possible values are:   Z_EXT     = exterior (outside) 
 *                                 Z_INT     = interior (inside) 
 *                                 Z_BND     = boundary 
 *                                 Z_INTBND  = internal boundary 
 *                                 Z_SYM     = symmetry plane 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 * 
 *  * Not called unless Num_structured_blocks is > 0  and you have 
 *      some iblanked blocks 
 * 
 *  * Only called for structured "block" parts 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_block_iblanking(int block_number, 
                          int *iblank_array) 
/*--------------------------------------------------------------------

3.4.5. USERD_get_block_ghost_flags

 *                                            (version 2.01 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the ghost_flags value at each element of a block containg ghost cells. 
 * 
 *  (IN)  block_number            = The block number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                     1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id that is 
 *                                   loaded in USERD_get_gold_part_build_info) 
 * 
 *  (OUT) ghost_flags             = 1D array containing ghost flag value 
 *                                   for each block cell. 
 * 
 *                                  (Array will have been allocated 
 *                                   (i-1)*(j-1)*(k-1) for the block long) 
 * 
 *          possible values are:    0  = non-ghost cell  (normal cell) 
 *                                 >0  = ghost cell 
 * 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 * 
 *  * Only called for structured "block" parts that have some ghost cells 
 *    as indicated by the USERD_get_ghost_in_block_flag.  The model must 
 *    of course also have been indicated to have some ghost cells in the 
 *    USERD_get_ghost_in_model_flag routine. 
 *   
 *  * It is sufficient to set the value to be 1 to flag as a ghost cell, 
 *    but the value can be any non-zero value, so you could use it to 
 *    indicate which block or which server (for Server-of-server use) the 
 *    cell is actually in. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_block_ghost_flags(int block_number, 
                            int *ghost_flags) 
/*--------------------------------------------------------------------

3.4.6. USERD_get_border_availability

 *                                            (version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Finds out if border elements are provided by the reader for the 
 *   desired part, or will need to be computed internally by EnSight.
 *   The currently supported use-cases are that the reader either returns border 
 *   elements for ALL of the parts or NONE of the parts.
 * 
 *  (IN)  part_number             = The part number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                     1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id that is 
 *                                   loaded in USERD_get_gold_part_build_info) 
 * 
 *   (OUT) number_of_elements     = 2D array containing number of 
 *                                  each type of border element in 
 *                                  the part. 
 *                                  ------------ 
 *                                  Possible types are: 
 * 
 *                                  Z_POINT   =  point 
 *                                  Z_BAR02   =  2-noded bar 
 *                                  Z_BAR03   =  3-noded bar 
 *                                  Z_TRI03   =  3-noded triangle 
 *                                  Z_TRI06   =  6-noded triangle 
 *                                  Z_QUA04   =  4-noded quadrilateral 
 *                                  Z_QUA08   =  8-noded quadrilateral 
 * 
 *  Returns: 
 *  ------- 
 *  Z_OK  if border elements will be provided by the reader. 
 *         (number_of_elements array will be loaded and 
 *          USERD_get_border_elements_by_type will be called) 
 * 
 *  Z_ERR if border elements are not available - thus EnSight must compute. 
 *         (USERD_get_border_elements_by_type will not be called) 
 * 
 * 
 *  Notes: 
 *  ----- 
 *  * Only called if border representation is used. 
 * 
 *  * Will be based on Current_time_step 
 * 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_border_availability( int part_number, 
                               int number_of_elements[Z_MAXTYPE]) 
/*--------------------------------------------------------------------

3.4.7. USERD_get_border_elements_by_type

 *                                            (version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Provides border element connectivity and parent information.
 *   Note: The currently supported use-cases are that the reader either returns
 *   border elements for ALL of the parts or NONE of the parts. 
 * 
 *  (IN)  part_number             = The part number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                     1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id that is 
 *                                   loaded in USERD_get_gold_part_build_info) 
 * 
 *  (IN)  element_type            = One of the following (See global_extern.h) 
 *                                  Z_POINT    node point element 
 *                                  Z_BAR02    2 node bar 
 *                                  Z_BAR03    3 node bar 
 *                                  Z_TRI03    3 node triangle 
 *                                  Z_TRI06    6 node triangle 
 *                                  Z_QUA04    4 node quad 
 *                                  Z_QUA08    8 node quad 
 * 
 *  (OUT) conn_array              = 2D array containing connectivity 
 *                                  of each border element of the type. 
 * 
 *                                 (Array will have been allocated 
 *                                  num_of_elements of the type by 
 *                                  connectivity length of the type) 
 * 
 *                      ex) If number_of_elements[Z_TRI03] = 25 
 *                             number_of_elements[Z_QUA04] = 100 
 *                             number_of_elements[Z_QUA08] = 30 
 *                          as obtained in: 
 *                           USERD_get_border_availability 
 * 
 *                          Then the allocated dimensions available 
 *                          for this routine will be: 
 *                             conn_array[25][3]   when called with Z_TRI03 
 * 
 *                             conn_array[100][4]  when called with Z_QUA04 
 * 
 *                             conn_array[30][8]   when called with Z_QUA08 
 * 
 *  (OUT) parent_element_type   = 1D array containing element type of the 
 *                                parent element (the one that the border 
 *                                element is a face/edge of). 
 * 
 *                               (Array will have been allocated 
 *                                num_of_elements of the type long) 
 * 
 *  (OUT) parent_element_num   = 1D array containing element number of the 
 *                                parent element (the one that the border 
 *                                element is a face/edge of). 
 * 
 *                               (Array will have been allocated 
 *                                num_of_elements of the type long) 
 * 
 * 
 *  Returns: 
 *  ------- 
 *  Z_OK  if successful 
 *  Z_ERR if not successful 
 * 
 *  Notes: 
 *  ----- 
 *  * Only called if USERD_get_border_availability returned Z_OK 
 * 
 *  * Will be based on Current_time_step 
 * 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_border_elements_by_type( int part_number, 
                                   int element_type, 
                                   int **conn_array, 
                                   short *parent_element_type, 
                                   int *parent_element_num) 
/*--------------------------------------------------------------------

3.4.8. USERD_get_changing_geometry_status

 *                                            (version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Gets the changing geometry status 
 * 
 *  returns:  Z_STATIC        if geometry does not change 
 *            Z_CHANGE_COORDS if changing coordinates only 
 *            Z_CHANGE_CONN   if changing connectivity 
 *            Z_GEOM_PER_PART  allows the use the new changing geometry per  
 *                              part option in EnSight 
 * 
 *  Notes: 
 *   
 * EnSight does not support changing number of parts.  But the 
 *    coords and/or the connectivity of the parts can change. Note that 
 *    a part is allowed to be empty (number of nodes and elements equal 
 *    to zero). 
 * If you want to use  
 *  
 *--------------------------------------------------------------------*/ 
int 
USERD_get_changing_geometry_status( void ) 
  if(Geom_status_per_part) { 
    return(Z_GEOM_PER_PART); 
  } 
  else { 
    return(Geom_status); 
  }   
/*--------------------------------------------------------------------                            

3.4.9. USERD_get_changing_geometry_status_per_part

 *                                       returns the changing                              
 *                                            geometry status for part sent to it.              
 *                                            This status must not change over time.            
 *--------------------------------------------------------------------                             
 *  (IN)  part_number = The part number                                                            
 *                                                                                                 
 * returns changing geometry status of the part, which must be one of:                             
 *     Z_STATIC                                                                                    
 *     Z_COORD_CHANGE                                                                              
 *     Z_CONN_CHANGE                                                                               
 * 
 * Note: The status for a given part, is not allowed to change over time. 
 *       Once set to be Z_COORD_CHANGE, for example, it may not become 
 *       become Z_CONN_CHANGE or Z_STATIC at any other time. 
 * 
 * This routine will only be called if USERD_get_changing_geometry_status has 
 * returned a value of Z_GEOM_PER_PART. And it will be called right after the 
 * call to USERD_get_gold_part_build_info 
 *--------------------------------------------------------------------------*/ 
int 
USERD_get_changing_geometry_status_per_part(int part_number) 
{ 
  return(Geom_gcpp[part_number]); 
}   
/*--------------------------------------------------------------------

3.4.10. USERD_get_constant_val

 *                                            (version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the value of a constant at a time step 
 * 
 *  (IN)  which_var            = The variable number (1 to Num_variables) 
 * 
 *  (IN)  imag_data            = TRUE if want imaginary data value. 
 *                               FALSE if want real data value. 
 * 
 *  returns: value of the requested constant variable 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 *--------------------------------------------------------------------*/ 
float 
USERD_get_constant_val(int which_var, 
                       int imag_data) 
/*--------------------------------------------------------------------

3.4.11. USERD_get_dataset_query_file_info

 *                                            (version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the information about files in the dataset.  Used for the 
 *   dataset query option within EnSight. 
 * 
 *  (OUT) qfiles   = Structure containing information about each file 
 *                   of the dataset. The Z_QFILES structure is defined 
 *                   in the global_extern.h file 
 * 
 *                   (The structure will have been allocated 
 *                    num_dataset_files long, with 10 description 
 *                    lines per file). 
 *                    (See USERD_get_number_of_files_in_dataset) 
 * 
 *      qfiles[].name        = The name of the file 
 *                             (Z_MAXFILENP is the dimensioned length 
 *                              of the name) 
 * 
 *      qfiles[].sizeb       = The number of bytes in the file 
 *                             (Typically obtained with a call to the 
 *                              "stat" system routine) 
 * 
 *      qfiles[].timemod     = The time the file was last modified 
 *                             (Z_MAXTIMLEN is the dimesioned length 
 *                              of this string) 
 *                             (Typically obtained with a call to the 
 *                              "stat" system routine) 
 * 
 *      qfiles[].num_d_lines = The number of description lines you 
 *                              are providing from the file. Max = 10 
 * 
 *      qfiles[].f_desc[]    = The description line(s) per file, 
 *                              qfiles[].num_d_lines of them 
 *                              (Z_MAXFILENP is the allocated length of 
 *                               each line) 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * If num_dataset_files is 0, this routine will not be called. 
 *    (See USERD_get_number_of_files_in_dataset) 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_dataset_query_file_info(Z_QFILES *qfiles) 
/*--------------------------------------------------------------------

3.4.12. USERD_get_descrip_lines

 *                                            (version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get two description lines associated with geometry per time step, 
 *   or one description line associated with a variable per time step. 
 * 
 *  (IN)  which_type        = Z_GEOM for geometry 
 *                          = Z_VARI for variable 
 * 
 *  (IN)  which_var         = If it is a variable, which one. (1 to Num_variables) 
 *                            Ignored if geometry type. 
 * 
 *  (IN)  imag_data         = TRUE if want imaginary data file. 
 *                            FALSE if want real data file. 
 * 
 *  (OUT) line1             = The 1st geometry description line, 
 *                            or the variable description line. 
 * 
 *  (OUT) line2             = The 2nd geometry description line 
 *                            Not used if variable type. 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 * 
 *  * These are the lines EnSight can echo to the screen in 
 *    annotation mode. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_descrip_lines(int which_type, 
                        int which_var, 
                        int imag_data, 
                        char line1[Z_BUFL], 
                        char line2[Z_BUFL]) 
/*--------------------------------------------------------------------

3.4.13. USERD_get_element_label_status

 *                                            (version 2.00 and later) 
 *                               (Modified at 2.01 as indicated below) 
 *-------------------------------------------------------------------- 
 * 
 *  Answers the question as to whether element labels will be provided. 
 * 
 *  returns:  TRUE        if element labels will be provided 
 *            FALSE       if element labels will NOT be provided 
 * 
 *  Notes: 
 *  * These are needed in order to do any element querying, or 
 *    element labeling on-screen within EnSight. 
 * 
 *  * Will call USERD_get_part_element_ids_by_type for each type of 
 *    of each part if this routine returns TRUE. 
 * 
 *  * Prior to API 2.01: 
 *    ================= 
 *      For unstructured parts, you can read them from your file if 
 *      available, or can assign them, etc. They need to be unique 
 *      per part, and are often unique per model. 
 * 
 *      API 1.0: 
 *        USERD_get_element_ids_for_part is used to obtain the ids, 
 *        on a part by part basis, if TRUE status is returned here. 
 * 
 *      API 2.0: 
 *        USERD_get_part_element_ids_by_type is used to obtain the ids, 
 *        on an element type by part basis, if TRUE status is returned here. 
 * 
 *      For structured parts, EnSight will assign ids if you return a 
 *        status of TRUE here.  You cannot assign them youself!! 
 * 
 *   * Starting at API 2.01: 
 *     ==================== 
 *      For both unstructured and structured parts, you can read them 
 *      from your file if available, or can assign them, etc. They need 
 *      to be unique per part, and are often unique per model (especially 
 *      if you are dealing with a decomposed dataset). 
 * 
 *      USERD_get_part_element_ids_by_type is used to obtain the ids, 
 *      on an element type by part basis, if TRUE status is returned here. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_element_label_status( void ) 
/*--------------------------------------------------------------------------

3.4.14. USERD_get_extra_gui_defaults

 *                                       <optional> (version 2.00 and later) 
 *-------------------------------------------------------------------------- 
 * 
 *  This routine defines the Titles, status, List choices, strings, etc that 
 *  are fed up to the GUI. 
 * 
 *   (OUT) toggle_Title               = title for each toggle 
 *                                      array dimension is 
 *                                 [num_toggles] by [Z_LEN_GUI_TITLE_STR] long 
 * 
 *   (OUT) toggle_default_status      = Setting for each toggle (TRUE or FALSE) 
 *                                      array dimension is [num_toggles] long 
 * 
 *   (OUT) pulldown_Title             = title for each pulldown 
 *                                      array dimension is 
 *                                 [num_pulldowns] by [Z_LEN_GUI_TITLE_STR] long 
 * 
 *   (OUT) pulldown_number_in_list    = number of items in each pulldown 
 *                                      array dimension is [num_pulldowns] long 
 * 
 *   (OUT) pulldown_default_selection = item selection for each pulldown 
 *                                      array dimension is [num_pulldowns] long 
 * 
 *   (OUT) pulldown_item_strings      = pulldown item strings 
 *                                      array is [num_pulldowns] by 
 *                                             [Z_MAX_NUM_GUI_PULL_ITEMS] by 
 *                                             [Z_LEN_GUI_PULL_STR] long 
 * 
 *   (OUT) field_Title                = title for each field 
 *                                      array dimension is 
 *                                  [num_fields] by [Z_LEN_GUI_TITLE_STR] long 
 * 
 *   (OUT) field_user_string          = content of the field 
 *                                      array dimension is 
 *                                  [num_fields] by [Z_LEN_GUI_TITLE_STR] long 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * The library is loaded, this routine is called, 
 *    then the library is unloaded. 
 * 
 *  * Do not define globals in this routine as when the library is unloaded, 
 *    you'll lose them. 
 * ----------------------------------------------- */ 
int USERD_get_extra_gui_defaults(char **toggle_Title, 
                                 int *toggle_default_status, 
                                 char **pulldown_Title, 
                                 int *pulldown_number_in_list, 
                                 int *pulldown_default_selection, 
                                 char ***pulldown_item_strings, 
                                 char **field_Title, 
                                 char **field_user_string) 
/*--------------------------------------------------------------------

3.4.15. USERD_get_extra_gui_numbers

 *                                 <optional> (version 2.00 and later) 
 * ------------------------------------------------------------------- 
 * 
 *   The Enhanced GUI routines are added to allow the user to customize a 
 *   portion of the Data Reader dialog to pass in options to their user 
 *   defined reader. 
 * 
 *   This routine defines the numbers of toggles, pulldowns & fields 
 * 
 *   (OUT) num_Toggles    = number of toggles that will be provided 
 * 
 *   (OUT) num_pulldowns  = number of pulldowns that will be provided 
 * 
 *   (OUT) num_fields     = number of fields that will be provided 
 * 
 *   Notes: 
 *   * There are three routines that work together: 
 *         USERD_get_extra_gui_numbers 
 *         USERD_get_extra_gui_defaults (this one) 
 *         USERD_set_extra_gui_data 
 * 
 *     The existence of these routine indicates that 
 *     you wish to add customize entries to the 
 *     Data Reader dialog. 
 * 
 *     If you don't want the extra GUI features, 
 *     simply delete these routines, or change their 
 *     names to something such as 
 *     USERD_DISABLED_get_extra_gui_defaults 
 * 
 *     The presence of these routines 
 *     will ensure that EnSight will call them and 
 *     use their data to modify the Data Reader dialog 
 *     with some or all of the following: 
 *     toggles, pulldown menu and fields. 
 * 
 *     The user can then interact with the enhanced 
 *     GUI and then send their choices to 
 *     USERD_set_extra_gui_data 
 * 
 *     Therefore if USERD_get_extra_gui_numbers 
 *     exists then the other two must exist. 
 * 
 *     If none exist, then the GUI will be unchanged. 
 * 
 *     Toggle data will return an integer 
 *                               TRUE if checked 
 *                               FALSE if unchecked 
 * 
 *     Pulldown menu will return an integer representing 
 *                               the menu item selected 
 * 
 *     Field will return a string Z_LEN_GUI_FIELD_STR long. 
 * 
 *     If all the enhanced GUI features are enabled it 
 *     might look something like this 
 * 
 * 
 * 
 *     ===================================================== 
 * 
 *        [ ] Title 1 
 *        [X] Title 3 
 *        [X] Title 2 
 *        [X] Title 4 
 * 
 *        Pulldown Menu -> 
 *            Menu Choice 1 
 *            Menu Choice 2 
 *            Menu Choice 3 
 * 
 *        Data Field Title 1 ____________________________ 
 * 
 *        Data Field Title 2 ____________________________ 
 * 
 *     ===================================================== 
 * 
 * * The following are defined in the global_extern.h 
 *          Z_MAX_NUM_GUI_PULL_ITEMS max num GUI pulldowns 
 *          Z_LEN_GUI_PULL_STR  max length of GUI pulldown string 
 *          Z_LEN_GUI_FIELD_STR  max length of field string 
 *          Z_LEN_GUI_TITLE_STR   max length of title string 
 * 
 * * The library is loaded, this routine is called, 
 *   then the library is unloaded. 
 * 
 * * Do not define globals in this routine as when the library is unloaded, 
 *   you'll lose them. 
 *---------------------------------------------------------------------------*/ 
void USERD_get_extra_gui_numbers(int *num_Toggles, 
                                 int *num_pulldowns, 
                                 int *num_fields) 
/*--------------------------------------------------------------------

3.4.16. USERD_get_geom_timeset_number

 *                                            (version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *  Gets the timeset number to be used for geometry 
 * 
 *  It must be in the valid range of timeset numbers 
 *       For example,  If USERD_get_number_of_timesets 
 *                     returns 2, the valid timeset_number's 
 *                     would be 1 and 2. 
 * 
 *  Returns: 
 *  ------- 
 *  Geom_timeset_number = The timeset number that will be used for geometry.    
 *                        For example, if USERD_get_number_of timesets 
 *                        returns 2, the valid timeset numbers would be 
 *                        1 or 2. 
 * 
 *  Notes: 
 *  * If your model is static, which you indicated by returning a zero 
 *    in USERD_get_number_of_timesets, you can return a zero here as well. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_geom_timeset_number( void ) 
/*--------------------------------------------------------------------

3.4.17. USERD_get_gold_part_build_info

 *                                            (version 2.00 and later) 
 *                               (Modified at 2.01 as indicated below) 
 *                               (Modified at 2.03 as indicated below) 
 *-------------------------------------------------------------------- 
 *   Gets the info needed for part building process 
 * 
 *  (OUT) part_id                = Array containing the external part 
 *                                 ids for each of the model parts. 
 * 
 *                                 IMPORTANT: 
 *                                  External Part ids must be >= 1 because 
 *                                  of the way they are used in the GUI 
 * 
 *             ******************************************* 
 *              The ids provided here are the numbers by 
 *              which the parts will be referred to in the 
 *              GUI (if possible). They are basically 
 *              labels as far as you are concerned. 
 * 
 *              Note: The part numbers you pass to routines which receive a 
 *              part_number or block_number or which_part as and argument 
 *              are the 1-based table index of the parts! 
 * 
 *              example:  If Numparts_available = 3 
 * 
 *                        Table index        part_id 
 *                        -----------        ------- 
 *                         1                  13 
 *                         2                  57 
 *                         3                  125 
 * 
 *                         ^                   ^ 
 *                         |                   | 
 *                         |                    These are placed in: 
 *                         |                      part_id[0] = 13 
 *                         |                      part_id[1] = 57 
 *                         |                      part_id[2] = 125 
 *                         |                    for GUI labeling purposes. 
 *                         | 
 *                          These implied table indices are the part_number, 
 *                          block_number, or which_part numbers that you would 
 *                          pass to routines like: 
 * 
 *                      USERD_get_part_coords(int part_number,... 
 *                      USERD_get_part_node_ids(int part_number,... 
 *                      USERD_get_part_elements_by_type(int part_number,... 
 *                      USERD_get_part_element_ids_by_type(int part_number,... 
 *                      USERD_get_block_coords_by_component(int block_number,... 
 *                      USERD_get_block_iblanking(int block_number,... 
 *                      USERD_get_block_ghost_flags(int block_number,... 
 *                      USERD_get_ghosts_in_block_flag(int block_number) 
 *                      USERD_get_border_availability(int part_number,... 
 *                      USERD_get_border_elements_by_type(int part_number,... 
 *                      USERD_get_var_by_component(int which_variable, 
 *                                                 int which_part,... 
 *                      USERD_get_var_value_at_specific(int which_var, 
 *                                                      int which_node_or_elem, 
 *                                                      int which_part,... 
 *             ******************************************** 
 * 
 *                                  (Array will have been allocated 
 *                                   Numparts_available long) 
 * 
 *  (OUT) part_types             = Array containing one of the 
 *                                 following primary types for each model part: 
 * 
 *                                       Z_UNSTRUCTURED or 
 *                                       Z_STRUCTURED  or 
 *                                       Z_IBLANKED 
 * 
 *                                  (Array will have been allocated 
 *                                   Numparts_available long) 
 *        Advanced: 
 *         In addition to the three above options, EnSight can make use of  
 *           the following flags with the bitwise OR operator to add them 
 *           in with the above primary types to add nuanced behavior to  
 *           EnSight. 
 *            
 *           Z_STATIC_COORDS_HINT - do not update the coords at timestep change 
 *           Z_STATIC_CONN_HINT - do not update the connectivity at timestep 
 *                                change 
 *           Z_STATIC_COORDS_HINT | Z_STATIC_CONN_HINT - Static geometry 
 *            
 *           Z_UNIFORM_HINT - Structured data is uniform 
 *           Z_RECTILINEAR_HINT - Structured data is rectilinear 
 *          
 *        Why to apply these flags: 
 *         You would use these flags to hint something to EnSight to allow  
 *          the EnSight code to operate in a more efficient manner on this part. 
 *         For Example: 
 *         You might want to speed up your reader by telling the server that  
 *          this part is an unchanging geometry amidst other parts that are  
 *          changing connectivity to save the time of reloading the part  
 *          every timestep change. 
 *         Also, you might want to tell EnSight that the structured mesh of this  
 *          part is actually uniform in some way that might facilitate efficient 
 *          volume rendering. 
 * 
 *        How to apply these flags? 
 *         Simply use a bitwise OR function to add in the hint of interest 
 *         Z_STRUCTURED | Z_UNIFORM_HINT     - This structured part is uniform 
 *         Z_STRUCTURED | Z_RECTILINEAR_HINT - This structured part is rectilinear 
 * 
 *         Suppose that you returned Z_CHANGE_CONN in 
 *          USERD_get_changing_geom_status 
 *          Now all parts will be completely reloaded (coordinates and 
 *          connectivity) 
 *          with every timestep change. But a given part is static. Use the 
 *          following: 
 *           Z_UNSTRUCTURED | Z_STATIC_COORDS_HINT | Z_STATIC_CONN_HINT 
 *           - static geom 
 * 
 *          or a given part is only changing coords, then use the following:  
 *           Z_UNSTRUCTURED | Z_STATIC_CONN_HINT 
 * 
 * 
 * 
 *  (OUT) part_description       = Array containing a description 
 *                                 for each of the model parts 
 * 
 *                                  (Array will have been allocated 
 *                                   Numparts_available by Z_BUFL 
 *                                   long) 
 * 
 *  (OUT) number_of_nodes        = Number of unstructured nodes in the part 
 * 
 *                                  (Array will have been allocated 
 *                                   Numparts_available long) 
 * 
 *  (OUT) number_of_elements     = 2D array containing number of 
 *                                 each type of element for each 
 *                                 unstructured model part. 
 *                                 ------------ 
 *                                 Possible types are: 
 * 
 *                                Z_POINT   =  point 
 *                                Z_BAR02   =  2-noded bar 
 *                                Z_BAR03   =  3-noded bar 
 *                                Z_TRI03   =  3-noded triangle 
 *                                Z_TRI06   =  6-noded triangle 
 *                                Z_QUA04   =  4-noded quadrilateral 
 *                                Z_QUA08   =  8-noded quadrilateral 
 *                                Z_TET04   =  4-noded tetrahedron 
 *                                Z_TET10   = 10-noded tetrahedron 
 *                                Z_PYR05   =  5-noded pyramid 
 *                                Z_PYR13   = 13-noded pyramid 
 *                                Z_PEN06   =  6-noded pentahedron 
 *                                Z_PEN15   = 15-noded pentahedron 
 *                                Z_HEX08   =  8-noded hexahedron 
 *                                Z_HEX20   = 20-noded hexahedron 
 *   Starting at API 2.03         Z_NSIDED  = nsided polygon 
 *   Starting at API 2.03         Z_NFACED  = nfaced polyhedron 
 * 
 *   Starting at API 2.01: 
 *   ==================== 
 *                                Z_G_POINT    ghost node point element 
 *                                Z_G_BAR02    2 node ghost bar 
 *                                Z_G_BAR03    3 node ghost bar 
 *                                Z_G_TRI03    3 node ghost triangle 
 *                                Z_G_TRI06    6 node ghost triangle 
 *                                Z_G_QUA04    4 node ghost quad 
 *                                Z_G_QUA08    8 node ghost quad 
 *                                Z_G_TET04    4 node ghost tetrahedron 
 *                                Z_G_TET10   10 node ghost tetrahedron 
 *                                Z_G_PYR05    5 node ghost pyramid 
 *                                Z_G_PYR13   13 node ghost pyramid 
 *                                Z_G_PEN06    6 node ghost pentahedron 
 *                                Z_G_PEN15   15 node ghost pentahedron 
 *                                Z_G_HEX08    8 node ghost hexahedron 
 *                                Z_G_HEX20   20 node ghost hexahedron 
 *   Starting at API 2.03         Z_G_NSIDED  ghost nsided polygon 
 *   Starting at API 2.03         Z_G_NFACED  ghost nfaced polyhedron 
 * 
 *                               (Ignored unless Z_UNSTRUCTURED type) 
 * 
 *                                  (Array will have been allocated 
 *                                   Numparts_available by 
 *                                   Z_MAXTYPE long) 
 * 
 *  (OUT) ijk_dimensions         = 2D array containing ijk dimension info 
 *                                 for structured blocks 
 * 
 *                                 For Z_UNSTRUCTURED - is ignored 
 * 
 *                                 For Z_STRUCTURED or Z_IBLANKED 
 * 
 *       Prior to version 2.03: 
 *       ---------------------- 
 *                                  (Array will have been allocated 
 *                                   Numparts_available by 3 long) 
 * 
 *                             ijk_dimensions[][0] = I dimension 
 *                             ijk_dimensions[][1] = J dimension 
 *                             ijk_dimensions[][2] = K dimension 
 * 
 * 
 *       Starting at version 2.03: 
 *       ------------------------ 
 *                                  (Array will have been allocated 
 *                                   Numparts_available by 9 long) 
 * 
 *                             There are two ways to do this: 
 *                             ------------------------------ 
 *                             1. The simple one, without ranges. 
 * 
 *                                  This is good for all structured models 
 *                                  that will a) NOT be used in EnSight's 
 *                                  Server of Servers. or that will b) be used in  
 *                                  Server of Servers with EnSight's 
 *                                  autodistribute option. 
 * 
 *                                  Simply provide the ijk dimensions in the 
 *                                  first three slots and place a -1 in 
 *                                  the 4th slot.  (The remaining slots will 
 *                                  be ignored). 
 * 
 *                             Thus, 
 *                             ijk_dimensions[][0] = I dimension of block 
 *                             ijk_dimensions[][1] = J dimension of block 
 *                             ijk_dimensions[][2] = K dimension of block 
 *                             ijk_dimensions[][3] = -1 
 * 
 * 
 * 
 * 
 * 
 * 
 *                             example: (Model has one part, a simple 2D block) 
 * 
 *                       (J planes) 
 *                           4 *-------*-------* 
 *                             |       |       |    ijk_dimension[0][0] = 3 
 *                             |       |       |    ijk_dimension[0][1] = 4 
 *                             |       |       |    ijk_dimension[0][2] = 1 
 *                           3 *-------*-------* 
 *                             |       |       |    ijk_dimension[0][4] = -1 
 *                             |       |       | 
 *                             |       |       | 
 *                           2 *-------*-------* 
 *                             |       |       | 
 *                             |       |       | 
 *                             |       |       | 
 *                           1 *-------*-------* 
 *                             1       2       3  (I planes) 
 * 
 * 
 * 
 *                             2. Using ranges. 
 * 
 *                                 This one can be used anytime, but MUST 
 *                                 be used if EnSight's Server of Servers 
 *                                 is to be used without the autodistribute 
 *                                 option! 
 * 
 *                                 The first 3 slots contain the ijk dimension 
 *                                 of the complete block (of which this may be 
 *                                 a portion).  The last 6 slots contain the 
 *                                 ijk min and max ranges within the complete. 
 * 
 *                           Thus, 
 *                           ijk_dimensions[][0] = I dimension of complete block 
 *                           ijk_dimensions[][1] = J dimension of complete block 
 *                           ijk_dimensions[][2] = K dimension of complete block 
 * 
 *                           ijk_dimensions[][3] = Imin of portion (1-based) 
 *                           ijk_dimensions[][4] = Imax of portion (1-based) 
 *                           ijk_dimensions[][5] = Jmin of portion (1-based) 
 *                           ijk_dimensions[][6] = Jmax of portion (1-based) 
 *                           ijk_dimensions[][7] = Kmin of portion (1-based) 
 *                           ijk_dimensions[][8] = Kmax of portion (1-based) 
 * 
 *                           example1: (Model has one part, a simple 2D block, 
 *                                      and want whole thing) 
 * 
 *                       (J planes) 
 *                           4 *-------*-------* 
 *                             |       |       |    ijk_dimension[0][0] = 3 
 *                             |       |       |    ijk_dimension[0][1] = 4 
 *                             |       |       |    ijk_dimension[0][2] = 1 
 *                           3 *-------*-------* 
 *                             |       |       |    ijk_dimension[0][3] = 1 
 *                             |       |       |    ijk_dimension[0][4] = 3 
 *                             |       |       |    ijk_dimension[0][5] = 1 
 *                           2 *-------*-------*    ijk_dimension[0][6] = 4 
 *                             |       |       |    ijk_dimension[0][7] = 1 
 *                             |       |       |    ijk_dimension[0][8] = 1 
 *                             |       |       | 
 *                           1 *-------*-------* 
 *                             1       2       3  (I planes) 
 * * 
 * 
 *                             example2: (Want to have the block represented 
 *                                        in two portions - 2 parts) 
 * 
 *                       (J planes)                 top portion 
 *                           4 *-------*-------* 
 *                             |       |       |    ijk_dimension[0][0] = 3 
 *                             |       |       |    ijk_dimension[0][1] = 4 
 *                             |       |       |    ijk_dimension[0][2] = 1 
 *                           3 *-------*-------* 
 *                             .       .       .    ijk_dimension[0][3] = 1 
 *                             .       .       .    ijk_dimension[0][4] = 3 
 *                             .       .       .    ijk_dimension[0][5] = 3 
 *                           2 .................    ijk_dimension[0][6] = 4 
 *                             .       .       .    ijk_dimension[0][7] = 1 
 *                             .       .       .    ijk_dimension[0][8] = 1 
 *                             .       .       . 
 *                           1 ................. 
 *                             1       2       3  (I planes) 
 * 
 * 
 *                       (J planes)                 bottom portion 
 *                           4 ................. 
 *                             .       .       .    ijk_dimension[1][0] = 3 
 *                             .       .       .    ijk_dimension[2][1] = 4 
 *                             .       .       .    ijk_dimension[3][2] = 1 
 *                           3 *-------*-------* 
 *                             |       |       |    ijk_dimension[1][3] = 1 
 *                             |       |       |    ijk_dimension[1][4] = 3 
 *                             |       |       |    ijk_dimension[1][5] = 1 
 *                           2 *-------*-------*    ijk_dimension[1][6] = 3 
 *                             |       |       |    ijk_dimension[1][7] = 1 
 *                             |       |       |    ijk_dimension[1][8] = 1 
 *                             |       |       | 
 *                           1 *-------*-------* 
 *                             1       2       3  (I planes) 
 * 
 * 
 *       And note that if you were partioning this block yourself for 
 *       EnSight's Server of Servers, you would only have one part, 
 *       instead of two.  Each SOS server would return its appropriate 
 *       ranges in the last 6 slots. The first 3 slots would remain constant. 
 * 
 *       Just to be clear on the setting of ranges (ijk_dimension[1][3-8], 
 *         NON-SOS cases:  Ranges can be used to specify partial blocks if desired, or 
 *                         can be set to the complete block by specifying them, or 
 *                         by setting ijk_dimension[i][3] to -1 
 * 
 *         SOS cases, partitioning in the reader: Ranges must be set properly 
 *                                                in this routine, so that 
 *                                                each server has its portion. 
 * 
 *         SOS cases, EnSight's autodistribute will be used: Ranges must be set to the 
 *                                                           complete block for each 
 *                                                           server. You can use the -1 
 *                                                           in the ijk_dimension[i][3] 
 *                                                           slot to do this if desired. 
 * 
 * 
 *  (OUT) iblanking_options      = 2D array containing iblanking 
 *                                 options possible for each 
 *                                 structured model part. 
 *                                 ---------- 
 *                                 (Ignored unless Z_IBLANKED type) 
 * 
 *                                 (Array will have been allocated 
 *                                  Numparts_available by 6 long) 
 * 
 *      iblanking_options[][Z_EXT]     = TRUE if external (outside) 
 *                       [][Z_INT]     = TRUE if internal (inside) 
 *                       [][Z_BND]     = TRUE if boundary 
 *                       [][Z_INTBND]  = TRUE if internal boundary 
 *                       [][Z_SYM]     = TRUE if symmetry surface 
 * 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * If you haven't built a table of pointers to the different parts, 
 *    you might want to do so here as you gather the needed info. 
 * 
 *  * This will be based on Current_time_step 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_gold_part_build_info(int *part_id, 
                               int *part_types, 
                               char *part_description[Z_BUFL], 
                               int *number_of_nodes, 
                               int *number_of_elements[Z_MAXTYPE], 
                               int *ijk_dimensions[9], 
                               int *iblanking_options[6]) 
/*--------------------------------------------------------------------

3.4.18. USERD_get_gold_variable_info

 *                                            (version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the variable descriptions, types and filenames 
 * 
 *  (OUT) var_description      = Variable descriptions 
 * 
 *                               (Array will have been allocated 
 *                                Num_variables by Z_BUFL long) 
 * 
 *         variable description restrictions: 
 *         ---------------------------------- 
 *         1. Only first 19 characters used in EnSight prior to EnSight 8.2 
 *            Starting at EnSight 8.2, 49 characters will be used. 
 *         2. Leading and trailing whitespace will be removed by EnSight. 
 *         3. Illegal characters will be replaced by underscores. 
 *         4. They may not start with a numeric digit. 
 *         5. No two variables may have the same description. 
 * 
 *  (OUT) var_filename         = Variable real filenames 
 * 
 *                               (Array will have been allocated 
 *                                Num_variables by Z_BUFL long) 
 * 
 *  (OUT) var_type             = Variable type 
 * 
 *                               (Array will have been allocated 
 *                                Num_variables long) 
 * 
 *                               types are:  Z_CONSTANT 
 *                                           Z_CONSTANT_PER_PART 
 *                                           Z_SCALAR 
 *                                           Z_VECTOR 
 *                                           Z_TENSOR 
 *                                           Z_TENSOR9 
 * 
 *  (OUT) var_classify         = Variable classification 
 * 
 *                               (Array will have been allocated 
 *                                Num_variables long) 
 * 
 *                               types are:  Z_PER_NODE 
 *                                           Z_PER_ELEM 
 *                                           Z_PER_PART 
 * 
 *  (OUT) var_complex          = TRUE if complex, FALSE otherwise 
 * 
 *                               (Array will have been allocated 
 *                                Num_variables long) 
 * 
 *  (OUT) var_ifilename        = Variable imaginary filenames (if complex) 
 * 
 *                               (Array will have been allocated 
 *                                Num_variables by Z_BUFL long) 
 * 
 *  (OUT) var_freq             = complex frequency  (if complex) 
 * 
 *                               (Array will have been allocated 
 *                                Num_variables long) 
 * 
 * 
 *  (OUT) var_contran          = TRUE if constant changes per time step 
 *                               FALSE if constant truly same at all time steps 
 * 
 *                               (Array will have been allocated 
 *                                Num_variables long) 
 * 
 *  (OUT) var_timeset          = Timeset the variable will use (1 based). 
 *                               (For static models, set it to 1) 
 * 
 *                               (Array will have been allocated 
 *                                Num_variables long) 
 * 
 *                              For example:  If USERD_get_number_of_timesets 
 *                                            returns 2, the valid 
 *                                            timeset_number's would be 1 or 2. 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * The implied variable numbers apply, but be aware that the 
 *    arrays are zero based. 
 *    So for variable 1, will need to provide   var_description[0] 
 *                                              var_filename[0] 
 *                                              var_type[0] 
 *                                              var_classify[0] 
 *                                              var_complex[0] 
 *                                              var_ifilename[0] 
 *                                              var_freq[0] 
 *                                              var_contran[0] 
 *                                              var_timeset[0] 
 * 
 *       for variable 2, will need to provide   var_description[1] 
 *                                              var_filename[1] 
 *                                              var_type[1] 
 *                                              var_classify[1] 
 *                                              var_complex[1] 
 *                                              var_ifilename[1] 
 *                                              var_freq[1] 
 *                                              var_contran[1] 
 *                                              var_timeset[1] 
 *             etc. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_gold_variable_info(char **var_description, 
                             char **var_filename, 
                             int *var_type, 
                             int *var_classify, 
                             int *var_complex, 
                             char **var_ifilename, 
                             float *var_freq, 
                             int *var_contran, 
                             int *var_timeset) 
/*--------------------------------------------------------------------

3.4.19. USERD_get_ghosts_in_block_flag

 *                                            (version 2.01 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Gets whether ghost cells present in block or not 
 * 
 *  (IN) block_number      = The block part number 
 * 
 *                          (1-based index of part table, namely: 
 * 
 *                               1 ... Numparts_available. 
 * 
 *                           It is NOT the part_id that 
 *                           is loaded in USERD_get_gold_part_build_info) 
 * 
 *  returns: TRUE  if any ghost cells in this structured part 
 *           FALSE if no ghost cells in this structured part 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 * 
 *  * Intended for structured parts only, value will be ignored for 
 *    unstructured parts 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_ghosts_in_block_flag(int block_number) 
/*--------------------------------------------------------------------

3.4.20. USERD_get_ghosts_in_model_flag

 *                                            (version 2.01 and later) 
 *-------------------------------------------------------------------- 
 * 
 *  Answers the question as to whether any ghost cells in the model. 
 * 
 *  returns:  TRUE        if any ghost cells in the model 
 *            FALSE       if no ghost cells in the model 
 * 
 *  Notes: 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_ghosts_in_model_flag( void ) 
/*--------------------------------------------------------------------

3.4.21. USERD_get_matf_escalars_desc

 *                                            (version 2.10 and later) 
 *-------------------------------------------------------------------- 
 * 
 *  Gets the list of descriptions of scalar per element variables to be defined 
 *  as the specified materials.  This list of element scalar descriptions must be 
 *  given in the same order, or sequence as the listed material ids. 
 * 
 *  (IN)  set_index  = The material set index 
 * 
 *  (OUT) mesv_desc  = 2D array of per element scalar descriptions 
 *                     Array will have beeen allocated by: 
 *                     [Num_materials[set_index]] by [Z_BUFL] 
 * 
 *  returns: Z_OK    if no problems 
 *           Z_ERR   if an error 
 * 
 * 
 *  Notes: 
 *   * See USERD_get_number_of_material_sets header for explanatory example 
 *   * Will not be called unless the set_type in USERD_get_matf_set_type 
 *     is Z_MISET_VIA_ESCAL_VARS 
 *   * Use this in place of the sparse material list interfacing method, which 
 *     uses USERD_size_matf_data and USERD_load_matf_data 
 *   * This function does not work with material SPECIES, i.e. with the function 
 *     calls USERD_get_matsp_info and USERD_get_number_of_species 
 *   * The mesv_desc array is NOT the same as the mat_desc array given via the  
 *     function USERD_get_matf_var_info 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_matf_escalars_desc(int set_index, 
                             char **mesv_desc) 
/*--------------------------------------------------------------------

3.4.22. USERD_get_matf_set_info

 *                                            (version 2.03 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the material set ids and names 
 * 
 *  (OUT) mat_set_ids  = 1D material set ids array.  (A list of unique, non-zero, 
 *                                                    positive number ids to be 
 *                                                    associated with each material 
 *                                                    set) 
 * 
 *                               (Array will have been allocated 
 *                                Num_material_sets long) 
 * 
 *  (OUT) mat_set_name  = 2D material set name array 
 * 
 *                               (Array will have been allocated 
 *                                Num_material_sets by Z_BUFL long) 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * Will not be called if Num_material_sets is zero 
 *  * See USERD_get_number_of_material_sets header for explanatory example 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_matf_set_info(int *mat_set_ids, 
                        char **mat_set_name) 
/*--------------------------------------------------------------------

3.4.23. USERD_get_matf_set_type

 *                                            (version 2.10 and later) 
 *-------------------------------------------------------------------- 
 *  Gets the material set type 
 * 
 *  (IN)  set_index  = The material set index 
 * 
 *  returns: set_type   = Z_MISET_VIA_SPARSE_MIX (default) 
 *                        Z_MISET_VIA_ESCAL_VARS  
 * 
 *  Notes: 
 *  * See USERD_get_number_of_material_sets header for explanatory example 
 *  * Z_MISET_VIA_ESCAL_VARS does not work with the material species functions, i.e. 
 *    USERD_get_number_of_species and USERD_get_matsp_info 
 *  * Use Z_MISET_VIA_SPARSE_MIX to interface materials via sparse material id, 
 *    mixed id, and mixed value lists (see USERD_size_matf_data and 
 *    USRERD_load_matf_data). 
 *  * Use Z_MISET_VIA_ESCAL_VARS to interface materials via/as scalar per element 
 *    variables (see USERD_get_matf_escalars_desc). 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_matf_set_type(int set_index)  
/*--------------------------------------------------------------------

3.4.24. USERD_get_matf_var_info

 *                                            (version 2.03 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the material ids and descriptions for the material set 
 * 
 *  (IN)  set_index           = the material set index (zero based) 
 * 
 *  (OUT) mat_ids[set_index]  = 1D materials ids array (internal, non-zero, 
 *                              positive numeric id) 
 *                                                       
 *                               (Array will have been allocated 
 *                                Num_materials long) 
 * 
 *  (OUT) mat_desc[set_index] = 2D material descriptions array (description in GUI 
 *                                                              material list) 
 * 
 *                               (Array will have been allocated 
 *                                Num_materials by Z_BUFL long) 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * See USERD_get_number_of_material_sets header for explanatory example 
 * 
 *  * Will not be called if Num_material_sets is zero, or 
 *     Num_materials[set_index] is zero 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_matf_var_info(int set_index, 
                        int *mat_ids, 
                        char **mat_desc) 
/*--------------------------------------------------------------------

3.4.25. USERD_get_matsp_info

 *                                            (version 2.05 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the material species ids, descriptions, count per material, 
 *   and concatonated lists of species per material for the material set 
 * 
 *  (IN)  set_index          = Material set index (zero based) 
 * 
 *  (OUT) sp_ids[set_index]  = 1D material species ids array (non-zero, positive 
 *                                                            numeric id) 
 * 
 *                               (Array will have been allocated 
 *                                Num_species long) 
 * 
 *  (OUT) sp_desc[set_index] = 2D material species descriptions array 
 * 
 *                               (Array will have been allocated 
 *                                Num_species by Z_BUFL long) 
 * 
 *  (OUT) sp_per_mat_cnt[set_index] = 1D species per material count array 
 * 
 *                               (Array will have been allocated 
 *                                Num_materials long) 
 * 
 *  (OUT) sp_per_mat_lis[set_index] = 1D concatonated lists of species 
 *                                    per material array 
 * 
 *                               (Array will have been allocated 
 *                                Num_materials*Num_species long) 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * See USERD_get_number_of_material_sets header for explanatory example 
 * 
 *  * Will not be called if Num_material_sets is zero, or 
 *     Num_materials[set_index] is zero 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_matsp_info(int   set_index, 
                     int   *sp_ids, 
                     char **sp_desc, 
                     int   *sp_per_mat_cnt, 
                     int   *sp_per_mat_lis)

3.4.26. USERD_get_max_time_steps

/*-------------------------------------------------------------------- 
* USERD_get_max_time_steps - 
*-------------------------------------------------------------------- 
* 
*   Get the max number of time steps for a changing timestep model. 
*   You must use this routine if you want EnSight to consider a growing 
*   number of timesteps, for example, when coproccessing solution data 
*   that is output during post processing. 
* 
*   So its presence, and a maximum greater than 1 is needed to flag EnSight 
*   to actually do a rereading of the timesteps when prompted to do so. 
* 
*  returns: max number of time steps 
*  
*  Note that this maximum number of timesteps is used to allocate  
*   an upper bound on Timesets in EnSight and uses a minimal amount of  
*   memory. Therefore making this number conservatively large has  
*   little impact on the EnSight memory. Your consideration should  
*   primarily be your own reader memory requirements. 
*    
*--------------------------------------------------------------------*/ 
int 
USERD_get_max_time_steps( void ) 
/*--------------------------------------------------------------------

3.4.27. USERD_get_maxsize_info

 *                                            (version 2.00 and later) 
 *                                (Modified at 2.01 as decribed below) 
 *-------------------------------------------------------------------- 
 * 
 *   Gets maximum part sizes for efficient memory allocation. 
 * 
 *   Transient models (especially those that increase in size) can cause 
 *   reallocations, at time step changes, to keep chewing up more and 
 *   more memory.   The way to avoid this is to know what the maximum 
 *   size of such memory will be, and allocate for this maximum initially. 
 * 
 *   Accordingly, if you choose to provide this information (it is optional), 
 *   EnSight will take advantage of it. 
 * 
 *  (OUT) max_number_of_nodes    = Maximum number of unstructured nodes 
 *                                 that will be in the part (over all time). 
 * 
 *                                  (Array will have been allocated 
 *                                   Numparts_available long) 
 * 
 *  (OUT) max_number_of_elements = 2D array containing maximum number of 
 *                                 each type of element for each 
 *                                 unstructured model part (over all time). 
 *                                 ------------ 
 *                                 Possible types are: 
 * 
 *                                Z_POINT   =  point 
 *                                Z_BAR02   =  2-noded bar 
 *                                Z_BAR03   =  3-noded bar 
 *                                Z_TRI03   =  3-noded triangle 
 *                                Z_TRI06   =  6-noded triangle 
 *                                Z_QUA04   =  4-noded quadrilateral 
 *                                Z_QUA08   =  8-noded quadrilateral 
 *                                Z_TET04   =  4-noded tetrahedron 
 *                                Z_TET10   = 10-noded tetrahedron 
 *                                Z_PYR05   =  5-noded pyramid 
 *                                Z_PYR13   = 13-noded pyramid 
 *                                Z_PEN06   =  6-noded pentahedron 
 *                                Z_PEN15   = 15-noded pentahedron 
 *                                Z_HEX08   =  8-noded hexahedron 
 *                                Z_HEX20   = 20-noded hexahedron 
 * 
 *   Starting at API 2.01: 
 *   ==================== 
 *                                Z_G_POINT    ghost node point element 
 *                                Z_G_BAR02    2 node ghost bar 
 *                                Z_G_BAR03    3 node ghost bar 
 *                                Z_G_TRI03    3 node ghost triangle 
 *                                Z_G_TRI06    6 node ghost triangle 
 *                                Z_G_QUA04    4 node ghost quad 
 *                                Z_G_QUA08    8 node ghost quad 
 *                                Z_G_TET04    4 node ghost tetrahedron 
 *                                Z_G_TET10   10 node ghost tetrahedron 
 *                                Z_G_PYR05    5 node ghost pyramid 
 *                                Z_G_PYR13   13 node ghost pyramid 
 *                                Z_G_PEN06    6 node ghost pentahedron 
 *                                Z_G_PEN15   15 node ghost pentahedron 
 *                                Z_G_HEX08    8 node ghost hexahedron 
 *                                Z_G_HEX20   20 node ghost hexahedron 
 * 
 *                               (Ignored unless Z_UNSTRUCTURED type) 
 * 
 *                                  (Array will have been allocated 
 *                                   Numparts_available by 
 *                                   Z_MAXTYPE long) 
 * 
 *  (OUT) max_ijk_dimensions = 2D array containing maximum ijk dimensions 
 *                             for each structured model part (over_all_time). 
 *                                           ---------- 
 *                                (Ignored if Z_UNSTRUCTURED type) 
 * 
 *                                (Array will have been allocated 
 *                                 Numparts_available by 3 long) 
 * 
 *                             max_ijk_dimensions[][0] = maximum I dimension 
 *                             max_ijk_dimensions[][1] = maximum J dimension 
 *                             max_ijk_dimensions[][2] = maximum K dimension 
 * 
 * Originally: 
 *  returns: Z_OK  if supplying maximum data 
 *           Z_ERR if not supplying maximum data, or some error occurred 
 *                   while trying to obtain it. 
 * But as of EnSight 9.0.3(d): 
 *  returns: Z_OK  if supplying maximum data (and no largest time step) 
 *           largest_time_step + 2 if supplying maximum data and the zero-based 
 *                                 time step at which it occurred. 
 *                                (The +2 is needed to be able to distinguish this 
 *                                 properly from Z_OK or Z_ERR. It will be 
 *                                 subtracted again in EnSight.) 
 *           Z_ERR if not supplying maximum data, or some error occurred 
 *                   while trying to obtain it. 
 * 
 *  Notes: 
 *  * You need to have first called USERD_get_number_of_model_parts and 
 *    USERD_get_gold_part_build_info, so Numparts_available is known and 
 *    so EnSight will know what the type is (Z_UNSTRUCTURED, Z_STRUCTURED, 
 *    or Z_IBLANKED) of each part. 
 * 
 *  * This will NOT be based on Current_time_step - it is to be the maximum 
 *    values over all time!! 
 * 
 *  * This information is optional.  If you return Z_ERR, Ensight will still 
 *    process things fine, reallocating as needed, etc.  However, for 
 *    large transient models you will likely use considerably more memory 
 *    and take more processing time for the memory reallocations. So, if it 
 *    is possible to provide this information "up front", it is recommended 
 *    to do so. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_maxsize_info(int *max_number_of_nodes, 
                       int *max_number_of_elements[Z_MAXTYPE], 
                       int *max_ijk_dimensions[3]) 
/*--------------------------------------------------------------------

3.4.28. USERD_get_metadata

 *                                            (version 2.00 and later) 
 *                                 
 *-------------------------------------------------------------------- 
 *  
 * This provides a mechanism to provide the EnSight client extra 
 * information designed to customize EnSight directly from the reader 
 * Meta data is XML formatted string of chars sent up to EnSight in two 
 * sequential calls of this routine.  
 *  
 * Presumably you would open the dataset file(s) in USERD_set_filenames, 
 *  understand the dataset, the parts, and the variables, and assemble 
 *  together this array of metadata in an XML character string. 
 *  
 * The first call of this routine is designed to send the actual length 
 *   of the meta_char so EnSight can allocate the char container. 
 * (IN)  meta_char = (char *) NULL <- this indicates its the first call 
 * 
(OUT) actual len is the strlen(meta_char) 
 *  
 * The second call of this routine is designed to fetch the char array. 
 * (IN) actual_len - this is the length of the char array in bytes that EnSight 
 *                   has allocated, ready to receive your xml formatted chars 
 * (OUT) meta_char = (char *) pointer ready to be populated 
 * 
 * Here's a sample (without the asterisks): 
 * 
    <?xml version="1.0" encoding="UTF-8"?> 
    <CEImetadata version="1.0">  
      <parts> 
        <partlist> 
          <group name="simple group"> 
            <part name="anotherpart"></part> 
          </group> 
          <part name="mypart"></part> 
        </partlist> 
      </parts> 
      <vars> 
        <metatags> 
          <tag name="ENS_UNITS_LABEL" type="str"></tag> 
          <tag name="ENS_UNITS_DIMS" type="str">/</tag> 
        </metatags> 
        <varlist> 
          <var name="myvar" ENS_UNITS_LABEL="m s^-1" ENS_UNITS_DIMS="L/T"></var> 
          <var name="Coordinates" ENS_UNITS_LABEL="m" ENS_UNITS_DIMS="L"></var> 
          <var name="Time" ENS_UNITS_LABEL="s" ENS_UNITS_DIMS="T"></var> 
        </varlist> 
      </vars> 
      <xy_queries> 
        <metatags> 
          <tag name="ENS_UNITS_QUERY_X_VAR" type="str"></tag> 
          <tag name="ENS_UNITS_QUERY_Y_VAR" type="str"></tag> 
        </metatags> 
        <querylist> 
          <query name="myvar vs time" ENS_UNITS_QUERY_X_VAR="Time" 
            ENS_UNITS_QUERY_Y_VAR="myvar"></query> 
         <query name="myvar vs Re" ENS_UNITS_QUERY_X_VAR="myvar"     
            ENS_UNITS_QUERY_Y_VAR=""></query> 
        </querylist> 
      </xy_queries> 
      <case> 
        <metatags> 
          <tag name="ENS_UNITS_LABEL" type="flt">2.0</tag> 
          <tag name="ENS_UNITS_DIMS" type="flt">1.0</tag> 
          <tag name="ENS_UNITS_SYSTEM" type="flt">1.0</tag> 
          <tag name="ENS_UNITS_SYSTEM_NAME" type="str">SI</tag> 
        </metatags> 
      </case> 
    </CEImetadata> 
 *  
 * Note: some datasets may record this metadata into a separate file 
 *  which is a perfectly valid methodology for recording this data. 
 * The XML format is the same: this is done in EnSight Case Gold format. 
 * A user defined reader can just read the data in and pass it up 
 *  via this mechanism. 
 *  
 * There are sections for parts, variables, xy_queries  
 * (only used by user-defined readers that support xy queries)  
 * and the case.  Note that in each section, objects are matched to metadata  
 * using their name (the DESCRIPTION property on the corresponding EnSight  
 * Python object). Each section begins by defining the attributes to be  
 * defined for the objects in the section using a <metatags> section.   
 * It defines all the attributes and their type (flt=float, str=string).   
 * The value specified for the <tag> is the default attribute value that  
 * is assigned if an object does not specify the attribute.   
 * When debugging metadata files, it can be useful to review what  
 * EnSight sees.  The Python command: 
 * ensight.objs.core.CURRENTCASE[0].SERVERXML 
 * will return the XML metadata for the current case.  
 *  
 * In the example, the <parts> section just defines the grouping hierarchy  
 * that should be used when the dataset is loaded.  Spatial units for  
 * parts are defined by the (implicit) 'Coordinates' variable.  
 * In the <vars> section, ENS_UNITS_DIMS and ENS_UNITS_LABEL metatags  
 * are defined. In the example, the former is set to default to unit-less "/". 
 *  Each variable defined in the dataset is then listed in the <varlist>  
 * section with the appropriate values for ENS_UNITS_DIMS and ENS_UNITS_LABEL. 
 *    
 *  Note that label strings should have the format: {unit}[{^{power}]  
 * with spaces between individual units.  If the power is 1,  
 * the ^{power} can be dropped. If the unit is in the denominator,  
 * the power should be negative.  No '/' characters should be in the label  
 * and all positive powers should appear before negative powers. An example  
 * for m/s= "m s^-1" and for m2/s2= "m^2 s^-2". 
 * Always include the implicit "Coordinates" and "Time" variables. 
 *  
 * Queries are handled a little differently.   
 * The <xy_queries> should only be used by a user-defined reader that  
 * implements the USERD_get_num_xy_queries, USERD_get_xy_query_info and 
 *  USERD_get_xy_query_data functions. The two attributes:  
 * ENS_UNITS_QUERY_X_VAR and ENS_UNITS_QUERY_Y_VAR should be defined  
 * and set to the name of a variable in the dataset that has the same  
 * dimensions as the specified axis.  The units for that specific axis  
 * will be taken from the variables named by those attributes.  
 * Note: there is no requirement that the variable name provided is  
 * the variable in the query, only that the units of that variable  
 * match the units of the axis of the specific query. 
 *  
 * The <case> section serves to define two things. First, it defines the  
 * versions of the ENS_UNITS_LABEL, ENS_UNITS_DIM and ENS_UNITS_SYSTEM_NAME 
 * protocols.  These are all float values and should be set to 2.0, 1.0  
 * and 1.0 respectively as shown in the example (there is an earlier  
 * version of the ENS_UNITS_LABEL protocol, but it is not recommended  
 * for new development).  Second, the name of the unit system that  
 * all the data that will be returned by the user-defined reader or is  
 * stored in the case gold format files.   
 * The list of valid unit system names includes the system string values  
 * from this table: 
 *  
 * System name  	    System string	   Units: mass, length, time, temperature,  
 *                                  current, angle, intensity, substance amount	    
 *  
 * Metric SI	         SI	             kg, m, s, A, K, rad, mol, cd	    
 * Metric CGS   	     CGS	            g, cm, s, A, C, rad, mol, cd	    
 * US ft Consistent  	BFT            	slug, ft, s, A, F, rad, slugmol, cd	    
 * US in Consistent	  BIN	            slinch, in, s, A, F, rad, lbmmol, cd	    
 * Metric MKS        	MKS            	kg, m, s, A, C, rad, mol, cd	    
 * Metric MPA        	MPA            	tonne, mm, s, mA, C, rad, mol, cd	    
 * Metric uMKS	       uMKS           	kg, um, s, pA, C, rad, mol, cd	    
 * Metric CGSK	       CGSK           	g, cm, s, A, K, rad, mol, cd	    
 * Metric NMM	        NMM	            kg, mm, s, mA, C, rad, mol, cd	    
 * Metric uMKSS	      uMKSS          	kg, um, s, mA, C, rad, mol, cd	    
 * Metric NMMDAT     	NMMDAT         	decatonne, mm, s, mA, C, rad, mol, cd	    
 * Metric NMMTON     	NMMTON	         tonne, mm, s, mA, C, rad, mol, cd	    
 * US ft	             BFTS           	lbm, ft, s, A, F, rad, lbmmol, cd	    
 * US in             	BINS           	lbm, in, s, A, F, rad, lbmmol, cd	    
 * US Engineering	    USENG          	lb, in, s, A, R, rad, lbmmol, cd	  
 *  
 * It should be noted that for proper unit support in EnSight, only the  
 * ENS_UNITS_DIMS and ENS_UNITS_SYSTEM_NAME protocols need to be defined. 
 * The ENS_UNITS_LABEL protocol allows a dataset to specify a custom label  
 * to be used when a dataset is loaded in its natural unit system  
 * (for example, "Pa" for M/LTT dimensions instead of the generated "kg/(m·s2)"). 
 *  
 * EnSight will generate a valid unit label from the dimension string  
 * and the unit system if no label is specified, the current session  
 * unit system does not match the one in the dataset and for all  
 * computed variables. 
 *  
 * ------------------------------------------------- */  
int  
USERD_get_metadata(int *actual_len, char *meta_char)   
/*-------------------------------------------------------------------

3.4.29. USERD_get_model_extents

 *                                           (version 2.00 and later) 
 *------------------------------------------------------------------- 
 * 
 *   Gets the model bounding box extents.  If this routine supplys them 
 *   EnSight will not have to spend time doing so.  If this routine 
 *   returns Z_ERR, EnSight will have to take the time to touch all the 
 *   nodes and gather the extent info. 
 * 
 *  (OUT) extents[0] = min x 
 *               [1] = max x 
 *               [2] = min y 
 *               [3] = max y 
 *               [4] = min z 
 *               [5] = max z 
 * 
 *  returns: Z_ERR if no extents given (EnSight will read all coords and 
 *                                      calculate) 
 *           Z_OK if extents given 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_model_extents( float extents[6] ) 
/*--------------------------------------------------------------------

3.4.30. USERD_get_name_of_reader

 *                                            (version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *  Gets the name of your user defined reader.  The user interface will 
 *  ask for this and include it in the available reader list. 
 * 
 *  (OUT) reader_name          = the name of the reader (data format) 
 *                             (max length is Z_MAX_USERD_NAME, which 
 *                              is 20) 
 * 
 *  (OUT) *two_fields          = FALSE if only one data field is required 
 *                                     in the data dialog of EnSight. 
 *                               TRUE if two data fields required 
 * 
 *                              -1   if one field (Geom) required  
 *                                   and one field (Param) is optional 
 *                                   Param field can contain any text 
 *                                   for example a file name, modifiers, 
 *                                   etc. that can be used to modify the 
 *                                   reader's behavior. 
 *  
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * Always called.  Provide a name for your custom reader format 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_name_of_reader(char reader_name[Z_MAX_USERD_NAME], 
                         int *two_fields) 
/*--------------------------------------------------------------------

3.4.31. USERD_get_nfaced_conn

 *                                            (version 2.03 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Gets the array containing the connectivity of nsided faces of 
 *   nfaced elements 
 * 
 *  (IN)  part_number             = The part number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                     1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id that is 
 *                                    loaded in USERD_get_gold_part_build_info) 
 * 
 *  (OUT) nfaced_conn_array  = 1D array of nsided face connectivies of 
 *                             nfaced elements 
 * 
 *                             (int array will have been allocated 
 *                              long enough to hold all the nsided 
 *                              face connectivities. Which is the sum of 
 *                              all the nodes per face values in 
 *                              the nfaced_npf_array of 
 *                               USERD_get_nfaced_nodes_per_face) 
 * 
 *   Providing nfaced information to Ensight: 
 * 
 *   1. In USERD_get_gold_part_build_info, provide the number of nfaced 
 *      polyhedral elements in the part. 
 * 
 *   2. In USERD_get_part_elements_by_type, provide (in the conn_array), 
 *      the number of faces per nfaced element. (as if connectivity 
 *      length of an nfaced element is one) 
 * 
 *   3. In this routine, provide the streamed number of nodes per face 
 *      for each of the faces of the nfaced elements. 
 * 
 * 
 *   Simple example:         11        10   12 
 *                          +--------+-----+ 
 *   2 nfaced elements:    /|        |\   /| 
 *   (1 7-faced           / |        | \ / | 
 *    1 5-sided)         /  |        |  +9 | 
 *                      /   |        | /|  | 
 *                     /7   |      8 /  |  | 
 *                    +-----------+/ |  |  | 
 *                    |     |5    |  |4 |  |6 
 *                    |     +-----|--+--|--+ 
 *                    |    /      |   \ | / 
 *                    |   /       |    \|/3 
 *                    |  /        |     + 
 *                    | /         |    / 
 *                    |/1         |2 / 
 *                    +-----------+/ 
 * 
 * 
 * 
 * 
 * 
 *    1. In USERD_get_gold_part_build_info: 
 *            number_of_elements[Z_NFACED] = 2 
 *                                           . 
 *                                          /|\ 
 *                                           | 
 *    2. In USERD_get_part_elements_by_type: 
 *        length of conn_array will be:      2 x 1 
 *        for element_type of Z_NFACED: 
 *            conn_array[0][0] = 7           (for the 7-faced element) 
 *            conn_array[1][0] = 5           (for the 5-faced element) 
 * 
 *                              == 
 *                         Sum  12    <---------+ 
 *                                              | 
 *    3. In USERD_get_faced_nodes_per_face:     | 
 *         length of nfaced_npf_array will be:  12 
 * 
 *      nfaced_npf_array[0]  = 5  (5-noded top face of 7-faced element) 
 *      nfaced_npf_array[1]  = 5  (5-noded bot face of 7-faced element) 
 *      nfaced_npf_array[2]  = 4  (4-noded front face of 7-faced element) 
 *      nfaced_npf_array[3]  = 4  (4-noded left face of 7-faced element) 
 *      nfaced_npf_array[4]  = 4  (4-noded back face of 7-faced element) 
 *      nfaced_npf_array[5]  = 4  (4-noded right front face of 7-faced element) 
 *      nfaced_npf_array[6]  = 4  (4-noded right back face of 7-faced element) 
 * 
 *      nfaced_npf_array[7]  = 3  (3-noded top face of 5-faced element) 
 *      nfaced_npf_array[8]  = 3  (3-noded bot face of 5-faced element) 
 *      nfaced_npf_array[9]  = 4  (4-noded back face of 5-faced element) 
 *      nfaced_npf_array[10] = 4  (4-noded right face of 5-faced element) 
 *      nfaced_npf_array[11] = 4  (4-noded left front face of 5-faced element) 
 * 
 *                             == 
 *                       Sum   48   <-----------------+ 
 *                                                    | 
 *    4. In this function:                            | 
 *          length of the nfaced_conn_array will be:  48 
 * 
 *      nsided_conn_array[0] = 7   (conn of 5-noded top face of 7-faced elem) 
 *      nsided_conn_array[1] = 8 
 *      nsided_conn_array[2] = 9 
 *      nsided_conn_array[3] = 10 
 *      nsided_conn_array[4] = 11 
 * 
 *      nsided_conn_array[5] = 1   (conn of 5-noded bot face of 7-faced elem) 
 *      nsided_conn_array[6] = 5 
 *      nsided_conn_array[7] = 4 
 *      nsided_conn_array[8] = 3 
 *      nsided_conn_array[9] = 2 
 * 
 *      nsided_conn_array[10] = 1  (conn of 4-noded front face of 7-faced elem) 
 *      nsided_conn_array[11] = 2 
 *      nsided_conn_array[12] = 8 
 *      nsided_conn_array[13] = 7 
 * 
 *      nsided_conn_array[14] = 5  (conn of 4-noded left face of 7-faced elem) 
 *      nsided_conn_array[15] = 1 
 *      nsided_conn_array[16] = 7 
 *      nsided_conn_array[17] = 11 
 * 
 *      nsided_conn_array[18] = 4  (conn of 4-noded back face of 7-faced elem) 
 *      nsided_conn_array[19] = 5 
 *      nsided_conn_array[20] = 11 
 *      nsided_conn_array[21] = 10 
 * 
 *      nsided_conn_array[22] = 2  (conn of 4-noded right front face of 7-faced) 
 *      nsided_conn_array[23] = 3 
 *      nsided_conn_array[24] = 9 
 *      nsided_conn_array[25] = 8 
 * 
 *      nsided_conn_array[26] = 3  (conn of 4-noded right back face of 7-faced) 
 *      nsided_conn_array[27] = 4 
 *      nsided_conn_array[28] = 10 
 *      nsided_conn_array[29] = 9 
 * 
 *      nsided_conn_array[30] = 9  (conn of 3-noded top face of 5-faced elem) 
 *      nsided_conn_array[32] = 12 
 *      nsided_conn_array[32] = 10 
 * 
 *      nsided_conn_array[33] = 3  (conn of 3-noded bot face of 5-faced elem) 
 *      nsided_conn_array[34] = 4 
 *      nsided_conn_array[35] = 6 
 * 
 *      nsided_conn_array[36] = 6  (conn of 4-noded back face of 5-faced elem) 
 *      nsided_conn_array[37] = 4 
 *      nsided_conn_array[38] = 10 
 *      nsided_conn_array[39] = 12 
 * 
 *      nsided_conn_array[40] = 3  (conn of 4-noded right face of 5-faced elem) 
 *      nsided_conn_array[41] = 6 
 *      nsided_conn_array[42] = 12 
 *      nsided_conn_array[43] = 9 
 * 
 *      nsided_conn_array[44] = 4  (conn of 4-noded left front face of 5-faced) 
 *      nsided_conn_array[45] = 3 
 *      nsided_conn_array[46] = 9 
 *      nsided_conn_array[47] = 10 
 * 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * Will not be called unless there are some nfaced elements in the 
 *    the part 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_nfaced_conn(int part_number, 
                      int *nfaced_conn_array) 
/*--------------------------------------------------------------------

3.4.32. USERD_get_nfaced_conn_in_buffers

 *                                <optional>  (version 2.08 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Gets three arrays containing the number of faces per element, 
 *   number of nodes per face, and connectivity per face of nfaced 
 *   elements in buffers 
 * 
 *   This is one of several optional routines than can be added into any 
 *   API 2.* reader to be used by the Unstructured Auto Distribute capability 
 *   in EnSight 8.2 and later. 
 * 
 *   Unstructured Auto Distribute is a capability requiring Server of Servers 
 *   (SOS) that will partition an unstructured model for you automatically 
 *   across a set of servers. 
 * 
 *   If you do not implement this routine (and the other in_buffers routines) 
 *   in your reader, EnSight can still perform this operation but will require 
 *   much more memory on each server to read in the data (somewhat like each 
 *   server having to read the whole model). You will however, get the execution 
 *   advantage of having your model partitioned across multiple servers. 
 * 
 *   If you do implement this routine (and the other in_buffers routines) in 
 *   your reader (in a proper manner), you should be able to not only get the 
 *   execution advantages, but also memory usage on each server which is 
 *   proportional to the subset that it is assigned to deal with.  
 * 
 *   Note that this optional routine is functionally quite similar 
 *   to the USERD_get_nfaced_conn routine. And thus its implementation should 
 *   not be too difficult to add to any existing reader that has already 
 *   implemented the USERD_get_nfaced_conn routine. 
 * 
 * 
 *  (IN)  part_number      = The part number 
 * 
 *                           (1-based index of part table, namely: 
 * 
 *                              1 ... Numparts_available. 
 * 
 *                            It is NOT the part_id that 
 *                            is loaded in USERD_get_gold_part_build_info) 
 * 
 *  (IN)  first            = TRUE if first invocation of a buffered set. 
 *                           Will be FALSE for all subsequent invocations 
 *                           of the set.  This is so you can open files, 
 *                           get to the correct starting spot, 
 *                           initialize, etc. 
 * 
 *  (IN) e_beg             = Zero based, first element number 
 *                           of the buffered set 
 * 
 *  (IN) e_end             = Zero based, last element number 
 *                           of the buffered set 
 * 
 *                     Thus, for first five elements of a type: 
 *                       e_beg = 0 
 *                       e_end = 4 
 *                       total_number = (e_end - e_beg) + 1 = (4 - 0) + 1 = 5 
 * 
 * 
 *                     for second five elements of a type, would be: 
 *                       e_beg = 5 
 *                       e_end = 9 
 *                       total_number = (e_end - e_beg) + 1 = (9 - 5) + 1 = 5 
 * 
 *                     for all elements of the type of a part, would be: 
 *                       n_beg = 0 
 *                       n_end = num_elements_of_type - 1 
 * 
 *  (IN) buffer_size         = The size of the num_nodes_per_elem_array buffer. 
 *                             Namely: num_nodes_per_elem_array[buffer_size] 
 * 
 *  (OUT) nfaced_fpe_array   = 1D buffer array of the number of faces per nfaced 
 *                             element. 
 * 
 *                                (int array will have been allocated 
 *                                 buffer_size long) 
 * 
 *  (OUT) nfaced_npf_array   = 1D buffer array of the number of nodes per face 
 *                             for nfaced elements. 
 * 
 *                                (int array will have been allocated long 
 *                                 enough to hold a buffer's size of values) 
 * 
 *  (OUT) nfaced_conn_array  = 1D array of nsided face connectivies of 
 *                             nfaced elements 
 * 
 *                             (int array will have been allocated 
 *                              long enough to hold a buffer's worth of values) 
 * 
 *   Providing nfaced information to Ensight: 
 * 
 *   NOTE: for other nfaced operations you need these first two, but we 
 *         don't actually use them in this routine. 
 * 
 *   1. In USERD_get_gold_part_build_info, provide the number of nfaced 
 *      polyhedral elements in the part. 
 * 
 *   2. In USERD_get_part_elements_by_type, provide (in the conn_array), 
 *      the number of faces per nfaced element. (as if connectivity 
 *      length of an nfaced element is one) 
 * 
 *   We do use the following: 
 *   3. In this routine, provide the corresponding number of faces per nfaced 
 *      element, streamed number of nodes per face, and streamed face 
 *      connectivities for each of the faces of the nfaced elements in the 
 *      bufferred portion. 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 *   Simple example:         11        10   12 
 *                          +--------+-----+ 
 *   2 nfaced elements:    /|        |\   /| 
 *   (1 7-faced           / |        | \ / | 
 *    1 5-sided)         /  |        |  +9 | 
 *                      /   |        | /|  | 
 *                     /7   |      8 /  |  | 
 *                    +-----------+/ |  |  | 
 *                    |     |5    |  |4 |  |6 
 *                    |     +-----|--+--|--+ 
 *                    |    /      |   \ | / 
 *                    |   /       |    \|/3 
 *                    |  /        |     + 
 *                    | /         |    / 
 *                    |/1         |2 / 
 *                    +-----------+/ 
 * 
 *    Note, don't really use these first two here (See USERD_get_nfaced_conn) 
 * 
 *    1. In USERD_get_gold_part_build_info: 
 *            number_of_elements[Z_NFACED] = 2 
 *                                           . 
 *                                          /|\ 
 *                                           | 
 *    2. In USERD_get_part_elements_by_type: 
 *        length of conn_array will be:      2 x 1 
 *        for element_type of Z_NFACED: 
 *            conn_array[0][0] = 7           (for the 7-faced element) 
 *            conn_array[1][0] = 5           (for the 5-faced element) 
 *                              == 
 *                         Sum  12 
 * 
 * 
 *    But for our simple example, lets assume that that our buffer is just 1 
 *      so that we have multiple invocations.               ================ 
 *    3. In this routine: 
 * 
 *       first invocation: 
 *         first = TRUE 
 *         e_beg = 0 
 *         e_end = 1 
 *         buffer_size = 1 
 *         nfaced_fpe_array[1]            load it: nfaced_fpe_array[0] = 7 
 * 
 *         nfaced_npf_array[at least 7]   load it: nfaced_npf_array[0] = 5 
 *                                                 nfaced_npf_array[1] = 5 
 *                                                 nfaced_npf_array[2] = 4 
 *                                                 nfaced_npf_array[3] = 4 
 *                                                 nfaced_npf_array[4] = 4 
 *                                                 nfaced_npf_array[5] = 4 
 *                                                 nfaced_npf_array[6] = 4 
 * 
 *         nsided_conn_array[at least 30] load it: nsided_conn_array[0] = 7 
 *                                                 nsided_conn_array[1] = 8 
 *                                                 nsided_conn_array[2] = 9 
 *                                                 nsided_conn_array[3] = 10 
 *                                                 nsided_conn_array[4] = 11 
 * 
 *                                                 nsided_conn_array[5] = 1 
 *                                                 nsided_conn_array[6] = 5 
 *                                                 nsided_conn_array[7] = 4 
 *                                                 nsided_conn_array[8] = 3 
 *                                                 nsided_conn_array[9] = 2 
 * 
 *                                                 nsided_conn_array[10] = 1 
 *                                                 nsided_conn_array[11] = 2 
 *                                                 nsided_conn_array[12] = 8 
 *                                                 nsided_conn_array[13] = 7 
 * 
 *                                                 nsided_conn_array[14] = 5 
 *                                                 nsided_conn_array[15] = 1 
 *                                                 nsided_conn_array[16] = 7 
 *                                                 nsided_conn_array[17] = 11 
 * 
 *                                                 nsided_conn_array[18] = 4 
 *                                                 nsided_conn_array[19] = 5 
 *                                                 nsided_conn_array[20] = 11 
 *                                                 nsided_conn_array[21] = 10 
 * 
 *                                                 nsided_conn_array[22] = 2 
 *                                                 nsided_conn_array[23] = 3 
 *                                                 nsided_conn_array[24] = 9 
 *                                                 nsided_conn_array[25] = 8 
 * 
 *                                                 nsided_conn_array[26] = 3 
 *                                                 nsided_conn_array[27] = 4 
 *                                                 nsided_conn_array[28] = 10 
 *                                                 nsided_conn_array[29] = 9 
 *         *num_returned = 1; 
 *         return(0) 
 * 
 *       second invocation: 
 *         first = FALSE 
 *         e_beg = 0 
 *         e_end = 1 
 *         buffer_size = 1 
 *         nfaced_fpe_array[1]            load it: nfaced_fpe_array[0] = 5 
 * 
 *         nfaced_npf_array[at least 7]   load it: nfaced_npf_array[0] = 3 
 *                                                 nfaced_npf_array[1] = 3 
 *                                                 nfaced_npf_array[2] = 4 
 *                                                 nfaced_npf_array[3] = 4 
 *                                                 nfaced_npf_array[4] = 4 
 * 
 *         nsided_conn_array[at least 18] load it: nsided_conn_array[0] = 9 
 *                                                 nsided_conn_array[1] = 12 
 *                                                 nsided_conn_array[2] = 10 
 * 
 *                                                 nsided_conn_array[3] = 3 
 *                                                 nsided_conn_array[4] = 4 
 *                                                 nsided_conn_array[5] = 6 
 * 
 *                                                 nsided_conn_array[6] = 6 
 *                                                 nsided_conn_array[7] = 4 
 *                                                 nsided_conn_array[8] = 10 
 *                                                 nsided_conn_array[9] = 12 
 * 
 *                                                 nsided_conn_array[10] = 3 
 *                                                 nsided_conn_array[11] = 6 
 *                                                 nsided_conn_array[12] = 12 
 *                                                 nsided_conn_array[13] = 9 
 * 
 *                                                 nsided_conn_array[14] = 4 
 *                                                 nsided_conn_array[15] = 3 
 *                                                 nsided_conn_array[16] = 9 
 *                                                 nsided_conn_array[17] = 10 
 *         *num_returned = 1; 
 *         return(1) 
 * 
 * returns  0  if got some, more to do 
 *          1  if got some, done 
 *         -1  if an error 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 * 
 *  * Will not be called unless there are some nfaced elements in the 
 *    the part 
 * 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_nfaced_conn_in_buffers(int part_number, 
                                 int *nfaced_fpe_array, 
                                 int *nfaced_npf_array, 
                                 int *nfaced_conn_array, 
                                 int first, 
                                 int e_beg, 
                                 int e_end, 
                                 int buffer_size, 
                                 int *num_returned) 
/*--------------------------------------------------------------------

3.4.33. USERD_get_nfaced_nodes_per_face

 *                                            (version 2.03 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Gets the array containing the number of nodes per face for each face 
 *   of the nfaced elements. 
 * 
 *  (IN)  part_number      = The part number 
 * 
 *                           (1-based index of part table, namely: 
 * 
 *                              1 ... Numparts_available. 
 * 
 *                            It is NOT the part_id that 
 *                            is loaded in USERD_get_gold_part_build_info) 
 * 
 *  (OUT) nfaced_npf_array  = 1D array of nodes per face for all 
 *                            faces of nfaced elements 
 * 
 *                             (int array will have been allocated 
 *                              long enough to hold all the nodes per 
 *                              face values. Which is the sum of 
 *                              all the number of faces per element values in 
 *                              the conn_array of 
 *                              USERD_get_part_elements_by_type) 
 * 
 *  Providing nfaced information to Ensight: 
 * 
 *   1. In USERD_get_gold_part_build_info, provide the number of nfaced 
 *      polyhedral elements in the part. 
 * 
 *   2. In USERD_get_part_elements_by_type, provide (in the conn_array), 
 *      the number of faces per nfaced element. (as if connectivity 
 *      length of an nfaced element is one) 
 * 
 *   3. In this routine, provide the streamed number of nodes per face 
 *      for each of the faces of the nfaced elements. 
 * 
 * 
 *   Simple example:         11        10   12 
 *                          +--------+-----+ 
 *   2 nfaced elements:    /|        |\   /| 
 *   (1 7-faced           / |        | \ / | 
 *    1 5-sided)         /  |        |  +9 | 
 *                      /   |        | /|  | 
 *                     /7   |      8 /  |  | 
 *                    +-----------+/ |  |  | 
 *                    |     |5    |  |4 |  |6 
 *                    |     +-----|--+--|--+ 
 *                    |    /      |   \ | / 
 *                    |   /       |    \|/3 
 *                    |  /        |     + 
 *                    | /         |    / 
 *                    |/1         |2 / 
 *                    +-----------+/ 
 * 
 * 
 * 
 * 
 * 
 *    1. In USERD_get_gold_part_build_info: 
 *            number_of_elements[Z_NFACED] = 2 
 *                                           . 
 *                                          /|\ 
 *                                           | 
 *    2. In USERD_get_part_elements_by_type: 
 *        length of conn_array will be:      2 x 1 
 *        for element_type of Z_NFACED: 
 *            conn_array[0][0] = 7           (for the 7-faced element) 
 *            conn_array[1][0] = 5           (for the 5-faced element) 
 * 
 *                              == 
 *                         Sum  12    <---------+ 
 *                                              | 
 *    3. In this routine:                       | 
 *         length of nfaced_npf_array will be:  12 
 * 
 *      nfaced_npf_array[0]  = 5  (5-noded top face of 7-faced element) 
 *      nfaced_npf_array[1]  = 5  (5-noded bot face of 7-faced element) 
 *      nfaced_npf_array[2]  = 4  (4-noded front face of 7-faced element) 
 *      nfaced_npf_array[3]  = 4  (4-noded left face of 7-faced element) 
 *      nfaced_npf_array[4]  = 4  (4-noded back face of 7-faced element) 
 *      nfaced_npf_array[5]  = 4  (4-noded right front face of 7-faced element) 
 *      nfaced_npf_array[6]  = 4  (4-noded right back face of 7-faced element) 
 * 
 *      nfaced_npf_array[7]  = 3  (3-noded top face of 5-faced element) 
 *      nfaced_npf_array[8]  = 3  (3-noded bot face of 5-faced element) 
 *      nfaced_npf_array[9]  = 4  (4-noded back face of 5-faced element) 
 *      nfaced_npf_array[10] = 4  (4-noded right face of 5-faced element) 
 *      nfaced_npf_array[11] = 4  (4-noded left front face of 5-faced element) 
 * 
 *                             == 
 *                       Sum   48   <-----------------+ 
 *                                                    | 
 *    4. In USERD_get_nfaced_conn:                    | 
 *          length of the nfaced_conn_array will be:  48 
 * 
 *      nsided_conn_array[0] = 7   (conn of 5-noded top face of 7-faced elem) 
 *      nsided_conn_array[1] = 8 
 *      nsided_conn_array[2] = 9 
 *      nsided_conn_array[3] = 10 
 *      nsided_conn_array[4] = 11 
 * 
 *      nsided_conn_array[5] = 1   (conn of 5-noded bot face of 7-faced elem) 
 *      nsided_conn_array[6] = 5 
 *      nsided_conn_array[7] = 4 
 *      nsided_conn_array[8] = 3 
 *      nsided_conn_array[9] = 2 
 * 
 *      nsided_conn_array[10] = 1  (conn of 4-noded front face of 7-faced elem) 
 *      nsided_conn_array[11] = 2 
 *      nsided_conn_array[12] = 8 
 *      nsided_conn_array[13] = 7 
 * 
 *      nsided_conn_array[14] = 5  (conn of 4-noded left face of 7-faced elem) 
 *      nsided_conn_array[15] = 1 
 *      nsided_conn_array[16] = 7 
 *      nsided_conn_array[17] = 11 
 * 
 *      nsided_conn_array[18] = 4  (conn of 4-noded back face of 7-faced elem) 
 *      nsided_conn_array[19] = 5 
 *      nsided_conn_array[20] = 11 
 *      nsided_conn_array[21] = 10 
 * 
 *      nsided_conn_array[22] = 2  (conn of 4-noded right front face of 7-faced) 
 *      nsided_conn_array[23] = 3 
 *      nsided_conn_array[24] = 9 
 *      nsided_conn_array[25] = 8 
 * 
 *      nsided_conn_array[26] = 3  (conn of 4-noded right back face of 7-faced) 
 *      nsided_conn_array[27] = 4 
 *      nsided_conn_array[28] = 10 
 *      nsided_conn_array[29] = 9 
 * 
 *      nsided_conn_array[30] = 9  (conn of 3-noded top face of 5-faced elem) 
 *      nsided_conn_array[32] = 12 
 *      nsided_conn_array[32] = 10 
 * 
 *      nsided_conn_array[33] = 3  (conn of 3-noded bot face of 5-faced elem) 
 *      nsided_conn_array[34] = 4 
 *      nsided_conn_array[35] = 6 
 * 
 *      nsided_conn_array[36] = 6  (conn of 4-noded back face of 5-faced elem) 
 *      nsided_conn_array[37] = 4 
 *      nsided_conn_array[38] = 10 
 *      nsided_conn_array[39] = 12 
 * 
 *      nsided_conn_array[40] = 3  (conn of 4-noded right face of 5-faced elem) 
 *      nsided_conn_array[41] = 6 
 *      nsided_conn_array[42] = 12 
 *      nsided_conn_array[43] = 9 
 * 
 *      nsided_conn_array[44] = 4  (conn of 4-noded left front face of 5-faced) 
 *      nsided_conn_array[45] = 3 
 *      nsided_conn_array[46] = 9 
 *      nsided_conn_array[47] = 10 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * Will not be called unless there are some nfaced elements in the 
 *    the part 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_nfaced_nodes_per_face(int part_number, 
                                int *nfaced_npf_array) 
/*--------------------------------------------------------------------

3.4.34. USERD_get_node_label_status

 *                                            (version 2.00 and later) 
 *                               (Modified at 2.01 as described below) 
 *-------------------------------------------------------------------- 
 * 
 *  Answers the question as to whether node labels will be provided. 
 * 
 *  returns:  TRUE        if node labels will be provided 
 *            FALSE       if node labels will NOT be provided 
 * 
 *  Notes: 
 *  * These are needed in order to do any node querying, or node 
 *    labeling on-screen                               . 
 * 
 * * Will call USERD_get_part_node_ids for each part if this routine 
 *   returns TRUE. 
 * 
 *  * Prior to API 2.01: 
 *    ================= 
 *      For unstructured parts, you can read them from your file if 
 *      available, or can assign them, etc. They need to be unique 
 *      per part, and are often unique per model. They must also be 
 *      positive numbers greater than zero. 
 * 
 *        USERD_get_part_node_ids is used to obtain the ids, if the 
 *        status returned here is TRUE. 
 * 
 *        (Unlike API 1.0, where the connectivity of elements had to be 
 *         according to the node ids - API 2.0's element connectivities 
 *         are not affected either way by the status here.) 
 * 
 *      For structured parts, EnSight will assign ids if you return a 
 *        status of TRUE here.  You cannot assign them yourself!! 
 * 
 *  * Starting at API 2.01: 
 *    ==================== 
 *      For both unstructured and structured parts, you can read them 
 *      from your file if available, or can assign them, etc. They need 
 *      to be unique per part, and are often unique per model. They must 
 *      also be positive numbers greater than zero. 
 * 
 *        USERD_get_part_node_ids is used to obtain the ids, if the 
 *        status returned here is TRUE. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_node_label_status( void ) 
/*--------------------------------------------------------------------

3.4.35. USERD_get_nsided_conn

 *                                            (version 2.03 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Gets the array containing the connectivity of nsided elements 
 * 
 *  (IN)  part_number      = The part number 
 * 
 *                           (1-based index of part table, namely: 
 * 
 *                              1 ... Numparts_available. 
 * 
 *                            It is NOT the part_id that 
 *                            is loaded in USERD_get_gold_part_build_info) 
 * 
 *  (OUT) nsided_conn_array  = 1D array of nsided connectivies 
 * 
 *                             (int array will have been allocated 
 *                              long enough to hold all the nsided 
 *                              connectivities. Which is the sum of 
 *                              all the nodes per element values in 
 *                              the conn_array of 
 *                              USERD_get_part_elements_by_type) 
 * 
 *   Providing nsided information to Ensight: 
 * 
 *   1. In USERD_get_gold_part_build_info, provide the number of nsided 
 *      elements in the part. 
 * 
 *   2. In USERD_get_part_elements_by_type, provide (in the conn_array), 
 *      the number of nodes per nsided element. (as if connectivity 
 *      length of an nsided element is one) 
 * 
 *   3. In this routine, provide the streamed connectivities for each of the 
 *      nsided elements. 
 * 
 * 
 *   Simple example:         5        6 
 *                          +--------+ 
 *   3 nsided elements:    /|         \ 
 *   (1 4-sided           / |          \ 
 *    1 3-sided          /  |           \ 
 *    1 7-sided)        /   |            \ 7 
 *                     /3   |4            + 
 *                    +-----+             | 
 *                    |     |             | 
 *                    |     |             |8 
 *                    |     |             + 
 *                    |     |            / 
 *                    |     |           / 
 *                    |     |          / 
 *                    |1    |2        /9 
 *                    +-----+--------+ 
 * 
 * 
 * 
 * 
 * 
 * 
 * 
 *    1. In USERD_get_gold_part_build_info: 
 *            number_of_elements[Z_NSIDED] = 3 
 *                                           . 
 *                                          /|\ 
 *                                           | 
 *    2. In USERD_get_part_elements_by_type: 
 *        length of conn_array will be:      3 x 1 
 * 
 *        for element_type of Z_NSIDED: 
 *            conn_array[0][0] = 4           (for the 4-sided element) 
 *            conn_array[1][0] = 3           (for the 3-sided element) 
 *            conn_array[2][0] = 7           (for the 7-sided element) 
 * 
 *                         Sum  === 
 *                               14    <---------+ 
 *                                               | 
 *    3. In this routine:                        | 
 *         length of nsided_conn_array will be:  14 
 * 
 *            nsided_conn_array[0]  = 1      (connectivity of 4-sided element) 
 *            nsided_conn_array[1]  = 2 
 *            nsided_conn_array[2]  = 4 
 *            nsided_conn_array[3]  = 3 
 * 
 *            nsided_conn_array[4]  = 3      (connectivity of 3-sided element) 
 *            nsided_conn_array[5]  = 4 
 *            nsided_conn_array[6]  = 5 
 * 
 *            nsided_conn_array[7]  = 2      (connectivity of 7-sided element) 
 *            nsided_conn_array[8]  = 9 
 *            nsided_conn_array[9]  = 8 
 *            nsided_conn_array[10] = 7 
 *            nsided_conn_array[11] = 6 
 *            nsided_conn_array[12] = 5 
 *            nsided_conn_array[13] = 4 
 * 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * Will not be called unless there are some nsided elements in the 
 *    the part 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_nsided_conn(int part_number, 
                      int *nsided_conn_array) 
/*--------------------------------------------------------------------

3.4.36. USERD_get_nsided_conn_in_buffers

 *                                  <optional> (version 2.08 or later) 
 *-------------------------------------------------------------------- 
 *   Gets the two arrays containing the connectivity information 
 *   of nsided elements in buffers 
 * 
 *   This is one of several optional routines than can be added into any 
 *   API 2.* reader to be used by the Unstructured Auto Distribute 
 *   capability in EnSight 8.2 and later. 
 * 
 *   Unstructured Auto Distribute is a capability requiring Server of Servers 
 *   (SOS) that will partition an unstructured model for you automatically 
 *   across a set of servers. 
 * 
 *   If you do not implement this routine (and the other in_buffers routines) 
 *   in your reader, EnSight can still perform this operation but will require 
 *   much more memory on each server to read in the data (somewhat like each 
 *   server having to read the whole model). You will however, get the execution 
 *   advantage of having your model partitioned across multiple servers. 
 * 
 *   If you do implement this routine (and the other in_buffers routines) in 
 *   your reader (in a proper manner), you should be able to not only get the 
 *   execution advantages, but also memory usage on each server which is 
 *   proportional to the subset that it is assigned to deal with.  
 * 
 *   Note that this optional routine is functionally quite similar 
 *   to the USERD_get_nsided_conn routine. And thus its implementation should 
 *   not be too difficult to add to any existing reader that has already 
 *   implemented the USERD_get_nsided_conn routine. 
 * 
 *  (IN)  part_number      = The part number 
 * 
 *                           (1-based index of part table, namely: 
 * 
 *                              1 ... Numparts_available. 
 * 
 *                            It is NOT the part_id that 
 *                            is loaded in USERD_get_gold_part_build_info) 
 * 
 *  (IN)  first            = TRUE if first invocation of a buffered set. 
 *                           Will be FALSE for all subsequent invocations 
 *                           of the set.  This is so you can open files, 
 *                           get to the correct starting spot, 
 *                           initialize, etc. 
 * 
 *  (IN) e_beg             = Zero based, first element number 
 *                           of the buffered set 
 * 
 *  (IN) e_end             = Zero based, last element number 
 *                           of the buffered set 
 * 
 *                     Thus, for first five elements of a type: 
 *                       e_beg = 0 
 *                       e_end = 4 
 *                       total_number = (e_end - e_beg) + 1 = (4 - 0) + 1 = 5 
 * 
 *                     for second five elements of a type, would be: 
 *                       e_beg = 5 
 *                       e_end = 9 
 *                       total_number = (e_end - e_beg) + 1 = (9 - 5) + 1 = 5 
 * 
 *                     for all elements of the type of a part, would be: 
 *                       n_beg = 0 
 *                       n_end = num_elements_of_type - 1 
 * 
 *  (IN) buffer_size         = The size of the num_nodes_per_elem_array buffer. 
 *                             Namely: num_nodes_per_elem_array[buffer_size] 
 * 
 *  (OUT) num_nodes_per_elem_array = 1D buffer array of the number of nodes 
 *                                   per nsided element. 
 * 
 *  (OUT) nsided_conn_array  = 1D buffer array of nsided connectivies 
 * 
 *                             (int array will have been allocated 
 *                              long enough to hold all the nsided 
 *                              connectivities in the buffered chunk) 
 * 
 *  (OUT) *num_returned      = The number of elements whose connectivities 
 *                             are returned in the buffer. This will 
 *                             normally be equal to buffer_size except for 
 *                             that last buffer - which could be less than 
 *                             a full buffer. 
 * 
 *   Providing nsided information to Ensight: 
 * 
 *   NOTE: for other nsided operations you need these first two, but we 
 *         don't actually use them in this routine. 
 * 
 *   1. In USERD_get_gold_part_build_info, provide the number of nsided 
 *      elements in the part. 
 * 
 *   2. In USERD_get_part_elements_by_type, provide (in the conn_array), 
 *      the number of nodes per nsided element. (as if connectivity 
 *      length of an nsided element is one) 
 * 
 *   We do use the following: 
 *   3. In this routine, provide the corresponding num_nodes_per_element and 
 *      streamed connectivities for each of the nsided elements in this 
 *      buffered portion. 
 * 
 * 
 *   Simple example:         5        6 
 *                          +--------+ 
 *   3 nsided elements:    /|         \ 
 *   (1 4-sided           / |          \ 
 *    1 3-sided          /  |           \ 
 *    1 7-sided)        /   |            \ 7 
 *                     /3   |4            + 
 *                    +-----+             | 
 *                    |     |             | 
 *                    |     |             |8 
 *                    |     |             + 
 *                    |     |            / 
 *                    |     |           / 
 *                    |     |          / 
 *                    |1    |2        /9 
 *                    +-----+--------+ 
 * 
 * 
 * 
 * 
 *    NOTE, don't really use these first two here  (See USERD_get_nsided_conn) 
 * 
 *    1. In USERD_get_gold_part_build_info: 
 *            number_of_elements[Z_NSIDED] = 3 
 *                                           . 
 *                                          /|\ 
 *                                           | 
 *    2. In USERD_get_part_elements_by_type: 
 *        length of conn_array will be:      3 x 1 
 * 
 *        for element_type of Z_NSIDED: 
 *            conn_array[0][0] = 4           (for the 4-sided element) 
 *            conn_array[1][0] = 3           (for the 3-sided element) 
 *            conn_array[2][0] = 7           (for the 7-sided element) 
 * 
 *                         Sum  === 
 *                               14 
 * 
 *    But for our example, lets assume that that our buffer is just 2 
 *                                                   ================ 
 *    3. In this routine: 
 * 
 *       first invocation: 
 *         first = TRUE 
 *         e_beg = 0 
 *         e_end = 2 
 *         buffer_size = 2 
 *         num_nodes_per_elem_array[2]    load it: 
 *                                            num_nodes_per_elem_array[0] = 4 
 *                                            num_nodes_per_elem_array[1] = 3 
 * 
 *         nsided_conn_array[at least 7]  load it:   nsided_conn_array[0] = 1 
 *                                                   nsided_conn_array[1] = 2 
 *                                                   nsided_conn_array[2] = 4 
 *                                                   nsided_conn_array[3] = 3 
 * 
 *                                                   nsided_conn_array[4] = 3 
 *                                                   nsided_conn_array[5] = 4 
 *                                                   nsided_conn_array[6] = 5 
 *         *num_returned = 2 
 *         return(0)                       return this (indicates more to do) 
 * 
 *       second invocation: 
 *         first = FALSE 
 *         e_beg = 0 
 *         e_end = 2 
 *         buffer_size = 2 
 *         num_nodes_per_elem_array[2]    load it: 
 *                                            num_nodes_per_elem_array[0] = 7 
 * 
 *         nsided_conn_array[at least 7]  load it:   nsided_conn_array[0] = 2 
 *                                                   nsided_conn_array[1] = 9 
 *                                                   nsided_conn_array[2] = 8 
 *                                                   nsided_conn_array[3] = 7 
 *                                                   nsided_conn_array[4] = 6 
 *                                                   nsided_conn_array[5] = 5 
 *                                                   nsided_conn_array[6] = 4 
 *         *num_returned = 1 
 *         return(1)                       return this (indicates no more to do) 
 * 
 * 
 * returns  0  if got some, more to do 
 *          1  if got some, done 
 *         -1  if an error 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 * 
 *  * Will not be called unless there are some nsided elements in the 
 *    the part 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_nsided_conn_in_buffers(int part_number, 
                                 int *num_nodes_per_elem_array, 
                                 int *nsided_conn_array, 
                                 int first, 
                                 int e_beg, 
                                 int e_end, 
                                 int buffer_size, 
                                 int *num_returned) 
/*--------------------------------------------------------------------

3.4.37. USERD_get_num_of_time_steps

 *                                            (version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the number of time steps of data available for desired timeset. 
 * 
 *  (IN)  timeset_number       = the timeset number  (1 based) 
 * 
 *                               For example: If USERD_get_number_of_timesets 
 *                                            returns 2, the valid 
 *                                            timeset_number's would be 1 and 2. 
 * 
 *  returns: number of time steps (>0 if okay, <=0 if problems). 
 * 
 *  Notes: 
 *  * This should be >= 1       1 indicates a static timeset 
 *                             >1 indicates a transient problem 
 * 
 * 
 * SPECIAL NOTE: Normally this routine is called just once through the normal 
 *               pipeline. The timeset_number sent to it will be a positive 
 *               value. 
 * 
 *               However, if 1) a USERD_get_max_time_steps routine is implemented, 
 *                       and 2) the USERD_get_max_time_steps routine returns a 
 *                              value greater than 1, 
 *                       and 3) the user hits the GUI button that calls for 
                                time to be reloaded. 
 * 
 *                        Then the timeset_number sent to this routine will be 
 *                        the negative of the actual value. Indicating that it 
 *                        is being called for a reload purpose.  Basically a 
 *                        "co-processing" purpose. Then this routine must also do 
 *                        the following: 
 * 
 *                        a) Check for the negtive timeset_number, and reverse it. 
 *                        b) Go get the new current number of time steps. 
 *                        c) Ensure that when USERD_get_sol_times is called again, 
 *                           that the new solution times are included. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_num_of_time_steps( int timeset_number ) 
/*--------------------------------------------------------------------

3.4.38. USERD_get_num_xy_queries

 *                               <optional>   (version 2.08 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the total number of xy queries in the dataset. 
 * 
 *  returns: the total number of xy queries in the dataset 
 * 
 *  Notes: 
 *  * You can be as complete as you want about this.  If you don't 
 *    care about xy queries, return a value of 0 
 *    If you only want certain xy queries, you can just include them. But, 
 *    you will need to supply the info and data USERD_get_xy_query_info 
 *    and USERD_get_xy_query_data for each xy query you include here. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_num_xy_queries( void ) 
/*--------------------------------------------------------------------

3.4.39. USERD_get_number_of_files_in_dataset

 *                                            (version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the total number of files in the dataset.  Used for the 
 *   dataset query option. 
 * 
 *  returns: the total number of files in the dataset 
 * 
 *  Notes: 
 *  * You can be as complete as you want about this.  If you don't 
 *    care about the dataset query option, return a value of 0 
 *    If you only want certain files, you can just include them. But, 
 *    you will need to supply the info in USERD_get_dataset_query_file_info 
 *    for each file you include here. 
 * 
 *  * Num_dataset_files would be set here 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_number_of_files_in_dataset( void ) 
/*--------------------------------------------------------------------

3.4.40. USERD_get_number_of_material_sets

 *                                            (version 2.03 and later) 
 *-------------------------------------------------------------------- 
 *   Get the number of material sets in the model 
 * 
 *  returns: Num_material_sets = number of material sets 
 *                              (Zero would indicate that you have no materials 
 *                               to deal with in the model) 
 *               or 
 * 
 *           -1 if an error condition 
 *  Notes: 
 * 
 *  * You may want to keep this as a global for use in other routines. 
 * 
 *   ############################################################### 
 *   NOTE:  Since EnSight 7.6, only one material set is supported within EnSight 
 *          Thus the only valid returns here are: 
 *               0 (no materials) 
 *               1 (for the one material set allowed) 
 *          or  -1 (if an error) 
 * 
 *          If the casefile has more than this, this reader will read them, 
 *          but EnSight will issue an error message and choke on them! 
 *   ############################################################### 
 * 
 *  ================================================================ 
 *  A very simple explanatory example, to use as a reference for the materials 
 *  routines: 
 * 
 *  Given a 2D mesh composed of 9 quad (Z_QUA04) elements, with two materials. 
 *  Most of the model is material 1, but the top left corner is material 9 - 
 *  basically as shown: 
 * 
 *        *--------*--------*--------* 
 *        |        |   /    |        | 
 *        |     Mat 9 /     |        | 
 *        |        | /      |        | 
 *        |        |/       |        | 
 *        |  e7    /   e8   |   e9   | 
 *        |       /|        |        | 
 *        |      / |        |        | 
 *        |     /  |        |        | 
 *        *----/---*--------*--------* 
 *        |   /    |        |        | 
 *        |  /     |        |        | 
 *        | /      |      Mat 1      | 
 *        |/       |        |        | 
 *        |   e4   |   e5   |   e6   | 
 *        |        |        |        | 
 *        |        |        |        | 
 *        |        |        |        | 
 *        *--------*--------*--------* 
 *        |        |        |        | 
 *        |        |        |        | 
 *        |        |        |        | 
 *        |   e1   |   e2   |   e3   | 
 *        |        |        |        | 
 *        |        |        |        | 
 *        |        |        |        | 
 *        *--------*--------*--------* 
 * 
 *  Thus, in this routine, set: 
 *    Num_material_sets = 1 
 * 
 *  In USERD_get_matf_set_info, set: 
 *    mat_set_ids[0]    = 1 
 *    mat_set_name[0]   = "Material Set 1"  (or whatever name desired) 
 * 
 *  In USERD_get_number_of_materials, input would be set_index = 0, and 
 *  would need to set: 
 *    Num_materials[0] = 2 
 * 
 *  For simplicity, the ids and descriptions that would be returned in 
 *  USERD_get_matf_var_info could be: 
 *    mat_ids[0] = 1 
 *    mat_ids[1] = 9 
 *    mat_desc[0] = "mat 1"   (or whatever desired) 
 *    mat_desc[2] = "mat 9" 
 * 
 *  Note1: In USERD_get_matf_set_type, the input would be set_index = 0, and if 
 *         set_type = Z_MISET_VIA_SPARSE_MIX, the following 3 lists (material ids, 
 *         mixed-material ids, and mixed-material values) would be needed and 
 *         communicated by the following two USERD calls, 
 *         i.e. USERD_size_matf_data and USERD_load_matf_data. 
 * 
 *  The per element material ids list would need to be: 
 * 
 *     material ids: 
 *     ------------- 
 *     ids_list[0] = 1  (material id 1, for elem e1) 
 *     ids_list[1] = 1  (     "                  e2) 
 *     ids_list[2] = 1  (     "                  e3) 
 *     ids_list[3] = -1 (neg. of index into mixed-material id list, for elem e4) 
 *     ids_list[4] = 1  (material id 1, for elem e5) 
 *     ids_list[5] = 1  (     "                  e6) 
 *     ids_list[6] = -5 (neg. of index into mixed-material id list, for elem e7) 
 *     ids_list[7] = -9 (     "                                              e8) 
 *     ids_list[8] = 1  (material id 1, for elem e9) 
 * 
 *  Finally we need the mixed material ids list and the mixed materials 
 *  values list, which would need to be: 
 * 
 *       mixed-material ids: 
 *       ------------------- 
 *   ==> 1  ids_list[0]  =  2  (the -1 in the material variable points here, 
 *                                   2 indicates that two materials are present) 
 *       2  ids_list[1]  =  1  (1st material is 1) 
 *       3  ids_list[2]  =  9  (2nd material is 9) 
 *       4  ids_list[3]  = -1  (negative of index into mixed-material val_list) 
 *   ==> 5  ids_list[4]  =  2  (the -5 in the material variable points here, 
 *                                   2 indicates that two materials are present) 
 *       6  ids_list[5]  =  1  (1st material is 1) 
 *       7  ids_list[6]  =  9  (2nd material is 9) 
 *       8  ids_list[7]  = -3  (negative of index into mixed-material val_list) 
 *   ==> 9  ids_list[8]  =  2     etc. 
 *       10 ids_list[9]  =  1 
 *       11 ids_list[10] =  9 
 *       12 ids_list[11] = -5 
 * 
 *       mixed-material values: 
 *       ---------------------- 
 *   ==> 1 val_list[0] = 0.875 (the -1 in the  mixed-material ids_list points 
 *                                here, and this is the value for material 1) 
 *       2 val_list[1] = 0.125 (the value for material 9) 
 *   ==> 3 val_list[2] = 0.125 (the -3 in the mixed-materials ids_list points 
 *                                here) 
 *       4 val_list[3] = 0.875 
 *   ==> 5 val_list[4] = 0.875 (the -5 in the mixed-materials ids_list points 
 *                                here) 
 *       6 val_list[5] = 0.125 
 * 
 *  So, USERD_size_matf_data would need to return 
 *       matf_size = 8, when called with set_id    = 1 
 *                                       part_id   = 1 
 *                                       wtyp      = Z_QUA04 
 *                                       mat_type  = Z_MAT_INDEX 
 * 
 *       matf_size = 12, when called with set_id   = 1 
 *                                        part_id  = 1 
 *                                        mat_type = Z_MIX_INDEX 
 * 
 *                 = 6, when called with set_id   = 1 
 *                                       part_id  = 1 
 *                                       mat_type = Z_MIX_VALUE 
 * 
 *  And, USERD_load_matf_data would need to return: 
 *    the int array ids_list as shown above when called with: 
 *       set_id   = 1 
 *       part_id  = 1 
 *       wtyp     = Z_QUA04 
 *       mat_type = Z_MAT_INDEX (indicating id list). 
 * 
 *    the int array ids_list as shown above when called with: 
 *       set_id   = 1 
 *       part_id  = 1 
 *       mat_type = Z_MIX_INDEX (indicating id list). 
 * 
 *    the float array val_list as shown above when called with: 
 *       set_id   = 1 
 *       part_id  = 1 
 *       mat_type = Z_MIX_VALUE (indicating val list). 
 * 
 * Note2: In USERD_get_matf_set_type, the input would be set_index = 0, and if 
 *        set_type = Z_MISET_VIA_ESCAL_VARS, then only USERD_get_matf_escalars_desc 
 *        would be called. 
 * 
 *        In USERD_get_matf_escalars_desc, the input would be set_index = 0, and 
 *        the descriptions of the per element scalar variables assigned as 
 *        materials would need to be: 
 *           mesv_desc[0] = "Escalar_1" 
 *           mesv_desc[1] = "Escalar_9" 
 * 
 *        Then corresponding per element lists would be: 
 *           for list "Escalar_1" 
 *           escal1_lis[0] = 1    {elem scalar value for elem 1} 
 *           escal1_lis[1] = 1    {elem scalar value for elem 2} 
 *           escal1_lis[2] = 1    {elem scalar value for elem 3} 
 *           escal1_lis[3] = .875 {elem scalar value for elem 4} 
 *           escal1_lis[4] = 1    {elem scalar value for elem 5} 
 *           escal1_lis[5] = 1    {elem scalar value for elem 6} 
 *           escal1_lis[6] = .125 {elem scalar value for elem 7} 
 *           escal1_lis[7] = .875 {elem scalar value for elem 8} 
 *           escal1_lis[8] = 1    {elem scalar value for elem 9} 
 * 
 *           for list "Escalar_9" 
 *           escal1_lis[0] = 0    {elem scalar value for elem 1} 
 *           escal1_lis[1] = 0    {elem scalar value for elem 2} 
 *           escal1_lis[2] = 0    {elem scalar value for elem 3} 
 *           escal1_lis[3] = .125 {elem scalar value for elem 4} 
 *           escal1_lis[4] = 0    {elem scalar value for elem 5} 
 *           escal1_lis[5] = 0    {elem scalar value for elem 6} 
 *           escal1_lis[6] = .875 {elem scalar value for elem 7} 
 *           escal1_lis[7] = .125 {elem scalar value for elem 8} 
 *           escal1_lis[8] = 0    {elem scalar value for elem 9} 
 * 
 * Note3: Only Note1 or Note2 can be used; not both simultaneously. 
 *        Note1 should be used for readers that accommodate sparse material lists. 
 *        Note2 should be used for readers that have the materials defined as 
 *        per element scalar variables. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_number_of_material_sets( void ) 
/*--------------------------------------------------------------------

3.4.41. USERD_get_number_of_materials

 *                                            (version 2.03 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the number of materials in the material set 
 * 
 *  (IN) set_index             = the material set index (zero based) 
 * 
 *  returns: Num_materials[set_index] = number of materials in set 
 *                                     (Zero would indicate that you have 
 *                                      no materials to deal with in the 
 *                                      material set) 
 *               or 
 * 
 *           -1 if an error condition 
 * 
 *  Notes: 
 *  * See USERD_get_number_of_material_sets header for explanatory example 
 *  * Will not be called if Num_material_sets is zero 
 *  * You may want to keep this as a global for use in other routines. 
 *  * This function only works when USERD_get_matf_set_type returns 
 *    Z_MISET_VIA_SPARSE_MIX; and thus, is NOT available if 
 *    USERD_get_matf_set_type 
 *    returns Z_MISET_VIA_ESCAL_VARS. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_number_of_materials( int set_index ) 
/*-------------------------------------------------------------------

3.4.42. USERD_get_number_of_model_parts

 *                                           (version 2.00 and later) 
 *------------------------------------------------------------------- 
 * 
 *   Gets the total number of unstructured and structured parts 
 *   in the model, for which you can supply information. 
 * 
 *   This value is typically called:  Numparts_available 
 * 
 *  returns:  Numparts_available  (>0 if okay, <=0 if probs) 
 * 
 *  Notes: 
 *  * IMPORTANT!!  The part or block numbers that get passed to various 
 *                 routines in this API, will be the one-based table index 
 *                 of these parts. 
 * 
 *                 For example, if you have three parts, the part or block 
 *                 numbers of these parts will be:  1,2,3 
 * 
 *  * If going to have to read down through the parts in order to 
 *    know how many, you may want to build a table of pointers to 
 *    the various parts, so can easily get to particular parts in 
 *    later processes.  If you can simply read the number of parts 
 *    at the head of the file, then you would probably not build the 
 *    table at this time. 
 *-------------------------------------------------------------------*/ 
int 
USERD_get_number_of_model_parts( void ) 
/*--------------------------------------------------------------------

3.4.43. USERD_get_number_of_species

 *                                            (version 2.05 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the number of material species in the material set 
 * 
 *  (IN)  set_index           = the material set index (zero based) 
 * 
 *  returns: Num_species[set_index] = number of material species in set 
 *                                    (Zero would indicate that you have 
 *                                     no materials to deal with in the 
 *                                     material set) 
 *               or 
 * 
 *           -1 if an error condition 
 * 
 *  Notes: 
 *  * See USERD_get_number_of_material_sets header for explanatory example 
 *  * Will not be called if Num_material_sets is zero 
 *  * You may want to keep this as a global for use in other routines. 
 *  * This function only works when USERD_get_matf_set_type returns 
 *    Z_MISET_VIA_SPARSE_MIX; and is not available if USERD_get_matf_set_type 
 *    returns Z_MISET_VIA_ESCAL_VARS 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_number_of_species( int set_index ) 
/*--------------------------------------------------------------------

3.4.44. USERD_get_number_of_timesets

 *                                            (version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *  Gets the number of timesets used in the model. 
 * 
 *  returns: 
 *  If you have a static model, both geometry and variables, you should 
 *  return a value of zero. 
 * 
 *  If you have a transient model, then you should return one or more. 
 * 
 *  For example: 
 * 
 *     Geometry    Variables                                 No. of timesets 
 *     ---------   ------------------------------            --------------- 
 *     static      static                                      0 
 *     static      transient, all using same timeset           1 
 * 
 *     transient   transient, all using same timeset as geom   1 
 * 
 *     static      transient, using 3 different timesets       3 
 * 
 *     transient   transient, using 3 different timesets and 
 *                            none of them the same as the 
 *                            geometry timeset                 4 
 *         etc. 
 * 
 *  NOTE: ALL GEOMETRY MUST USE THE SAME TIMESET!!! You will have to provide 
 *                                                  the timeset number to use 
 *                                                  for geometry in: 
 *                                              USERD_get_geom_timeset_number 
 * 
 *        Variables can use the same timeset as the geometry, or can use 
 *        other timesets. More than one variable can use the same timeset. 
 * 
 *  example:  changing geometry at 5 steps, 0.0, 1.0, 2.0, 3.0, 4.0 
 *            variable 1 provided at these same five steps 
 *            variable 2 provided at 3 steps, 0.5, 1.25, 3.33 
 * 
 *       This routine should return a value of 2, because only 
 *       two different timesets are needed. Timeset 1 would be for the 
 *       geometry and variable 1 (they both use it). Timeset 2 would 
 *       be for variable 2, which needs its own in this case. 
 * 
 *  Notes: 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_number_of_timesets( void ) 
/*--------------------------------------------------------------------

3.4.45. USERD_get_number_of_variables

 *                                            (version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the number of variables (includes constant, scalar,  
 *   vector and tensor types), for which you will be providing info. 
 * 
 *  returns: number of variables (includes constant, scalar, vector, 
 *            and tensor types) 
 *            >=0 if okay 
 *            <0 if problem 
 * 
 *  Notes: 
 *   ***************************************************************** 
 *  * Variable numbers, by which references will be made, are implied 
 *    here. If you say there are 3 variables, the variable numbers 
 *    will be 1, 2, and 3. 
 *   ***************************************************************** 
 * 
 *  * Num_variables would be set here 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_number_of_variables( void ) 
/*--------------------------------------------------------------------

3.4.46. USERD_get_part_coords

 *                                            (version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the coordinates for an unstructured part. 
 * 
 *  (IN)  part_number             = The part number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                     1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id that is 
 *                                   loaded in USERD_get_gold_part_build_info) 
 * 
 *  (OUT) coord_array             = 2D float array which contains 
 *                                  x,y,z coordinates of each node. 
 * 
 *       (IMPORTANT: the second dimension of of this array is 1-based!!!) 
 * 
 *                                  (Array will have been allocated 
 *                                   3 by (number_of_nodes + 1) for the part 
 *                                   long - see USERD_get_gold_part_build_info) 
 * 
 *                       ex) If number_of_nodes = 100 
 *                           as obtained in: 
 *                             USERD_get_gold_part_build_info 
 * 
 *                           Then the allocated dimensions of the 
 *                           pointer sent to this routine will be: 
 *                             coord_array[3][101] 
 * 
 *                           Ignore the coord_array[0][0] 
 *                                      coord_array[1][0] 
 *                                      coord_array[2][0] locations and start 
 *                           the node coordinates at: 
 *                             coord_array[0][1] 
 *                             coord_array[1][1] 
 *                             coord_array[2][1] 
 * 
 *                             coord_array[0][2] 
 *                             coord_array[1][2] 
 *                             coord_array[2][2] 
 * 
 *                                   etc. 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 *  * Not called unless Num_unstructured_parts is > 0 
 *  * Not called unless number_of_nodes for the part > 0 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_part_coords(int part_number, 
                      float **coord_array) 
/*--------------------------------------------------------------------

3.4.47. USERD_get_part_coords_in_buffers

 *                                <optional>  (version 2.08 and later) 
 *-------------------------------------------------------------------- 
 *   Get the coordinates for an unstructured part in buffers. 
 * 
 *   This is one of several optional routines than can be added into any 
 *   API 2.* reader to be used by the Unstructured Auto Distribute 
 *   capability in EnSight 8.2 and later. 
 * 
 *   Unstructured Auto Distribute is a capability requiring Server of Servers 
 *   (SOS) that will partition an unstructured model for you automatically 
 *   across a set of servers. 
 * 
 *   If you do not implement this routine (and the other in_buffers routines) 
 *   in your reader, EnSight can still perform this operation but will require 
 *   much more memory on each server to read in the data (somewhat like each 
 *   server having to read the whole model). You will however, get the execution 
 *   advantage of having your model partitioned across multiple servers. 
 * 
 *   If you do implement this routine (and the other in_buffers routines) in 
 *   your reader (in a proper manner), you should be able to not only get the 
 *   execution advantages, but also memory usage on each server which is 
 *   proportional to the subset that it is assigned to deal with.  
 * 
 *   Note that this optional routine is functionally quite similar 
 *   to the USERD_get_part_coords routine. And thus its implementation should 
 *   not be too difficult to add to any existing reader that has already 
 *   implemented the USERD_get_part_coords routine. 
 * 
 *  (IN)  part_number             = The part number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                     1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id that is 
 *                                   loaded in USERD_get_gold_part_build_info) 
 * 
 *  (IN)  first                   = TRUE if first invocation of a buffered set. 
 *                                  Will be FALSE for all subsequent invocations 
 *                                  of the set.  This is so you can open files, 
 *                                  get to the correct starting spot, 
 *                                  initialize, etc. 
 * 
 *  (IN) n_beg                    = Zero based, first node index 
 *                                  of the buffered set 
 * 
 *  (IN) n_end                    = Zero based, last node index 
 *                                  of the buffered set 
 *                                       
 *                     Thus, for first five nodes: 
 *                       n_beg = 0 
 *                       n_end = 4 
 *                       total_number = (n_end - n_beg) + 1 = (4 - 0) + 1 = 5 
 * 
 *                     for second five nodes, would be:       
 *                       n_beg = 5 
 *                       n_end = 9 
 *                       total_number = (n_end - n_beg) + 1 = (9 - 5) + 1 = 5 
 * 
 *                     for all nodes of a part, would be: 
 *                       n_beg = 0 
 *                       n_end = num_nodes - 1 
 * 
 *  (IN)  buffer_size             = The size of the buffer. 
 *                                  Namely:   coord_array[3][buffer_size] 
 * 
 *  (OUT) coord_array             = 2D float buffer array which is set up to 
 *                                  hold x,y,z coordinates of nodes. 
 * 
 *       (IMPORTANT: the second dimension of of this array is 0-based!!!) 
 * 
 *       (IMPORTANT: in the sister routine (USERD_get_part_coords) - which 
 *                   does not use buffers. This array is 1-based. 
 *                   So pay attention.) 
 * 
 *                                  (Array will have been allocated 
 *                                   3 by buffer_size long 
 * 
 * Example, if we had a part with 645 nodes and the buffer size was set to 200 
 * 
 *  first invocation: 
 *    first = TRUE            Will be TRUE the first time!  
 *    n_beg = 0 
 *    n_end = 644 
 *    buffer_size = 200 
 *    coord_array[3][200]     fill with values for nodes 1 - 200 (zero-based) 
 *    *num_returned = 200     set this 
 *    return(0)               return this (indicates more to do) 
 * 
 *  second invocation:        which occurs because we returned a 0 last time 
 *    first = FALSE           will now be FALSE 
 *    n_beg = 0 
 *    n_end = 644 
 *    buffer_size = 200 
 *    coord_array[3][200]     fill with values for nodes 201 - 400 (zero-based) 
 *    *num_returned = 200     set this 
 *    return(0)               return this (indicates more to do) 
 * 
 *  third invocation:         which occurs because we returned a 0 last time 
 *    first = FALSE           will still be FALSE 
 *    n_beg = 0 
 *    n_end = 644 
 *    buffer_size = 200 
 *    coord_array[3][200]     fill with values for nodes 401 - 600 (zero-based) 
 *    *num_returned = 200     set this 
 *    return(0)               return this (indicates more to do) 
 * 
 *  fourth invocation:        which occurs because we returned a 0 last time 
 *    first = FALSE           will still be FALSE 
 *    n_beg = 0 
 *    n_end = 644 
 *    buffer_size = 200 
 *    coord_array[3][200]     fill with values for nodes 601 - 645 (zero-based) 
 *    *num_returned = 45      set this 
 *    return(1)               return this (indicates done!) 
 * 
 *  (OUT)  *num_returned  = The number of nodes whose coordinates are returned 
 *                          in the buffer. This will normally be equal to 
 *                          buffer_size except for that last buffer - 
 *                          which could be less than a full buffer.  
 * 
 * returns  0  if got some, more to do 
 *          1  if got some, done 
 *         -1  if an error 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 * 
 *  * Not called unless number_of_nodes for the part > 0 
 * 
 *  * Again, make sure each buffer is zero based. For our example above: 
 * 
 *                                                 Invocation: 
 *                                     1          2          3           4 
 *                                  -------    -------    --------    ------- 
 *      coord_array[0][0]    x  for node 1     node 201   node 401    node 601    
 *      coord_array[1][0]    y  for    "          "          "           "  
 *      coord_array[2][0]    z  for    "          "          "           "  
 * 
 *      coord_array[0][1]    x  for node 2     node 202   node 402    node 602 
 *      coord_array[1][1]    y  for    "          "          "           " 
 *      coord_array[2][1]    z  for    "          "          "           " 
 *  
 *      ... 
 * 
 *      coord_array[0][199]  x  for node 200   node 400   node 600    node 645 
 *      coord_array[1][199]  y  for    "          "          "           " 
 *      coord_array[2][199]  z  for    "          "          "           " 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_part_coords_in_buffers(int part_number, 
                                 float **coord_array, 
                                 int first, 
                                 int n_beg, 
                                 int n_end, 
                                 int buffer_size, 
                                 int *num_returned) 
/*--------------------------------------------------------------------

3.4.48. USERD_get_part_element_ids_by_type

 *                                            (version 2.00 and later) 
 *                               (Modified at 2.01 as described below) 
 *                               (Modified at 2.03 as described below) 
 *-------------------------------------------------------------------- 
 * 
 *   Prior to API 2.01: 
 *   ================== 
 *   Gets the ids for the elements of a particular type for an 
 *   unstructured part. 
 * 
 *   Starting at API 2.01: 
 *   ==================== 
 *   Gets the ids for the elements of a particular type for an 
 *   unstructured or structured part. 
 * 
 * 
 *  (IN)  part_number             = The part number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                     1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id that is 
 *                                   loaded in USERD_get_gold_part_build_info) 
 * 
 *  (IN)  element_type            = One of the following (See global_extern.h) 
 *                                  Z_POINT    node point element 
 *                                  Z_BAR02    2 node bar 
 *                                  Z_BAR03    3 node bar 
 *                                  Z_TRI03    3 node triangle 
 *                                  Z_TRI06    6 node triangle 
 *                                  Z_QUA04    4 node quad 
 *                                  Z_QUA08    8 node quad 
 *                                  Z_TET04    4 node tetrahedron 
 *                                  Z_TET10   10 node tetrahedron 
 *                                  Z_PYR05    5 node pyramid 
 *                                  Z_PYR13   13 node pyramid 
 *                                  Z_PEN06    6 node pentahedron 
 *                                  Z_PEN15   15 node pentahedron 
 *                                  Z_HEX08    8 node hexahedron 
 *                                  Z_HEX20   20 node hexahedron 
 *   Starting at API 2.03           Z_NSIDED  nsided polygon 
 *   Starting at API 2.03           Z_NFACED  nfaced polyhedron 
 * 
 *   Starting at API 2.01: 
 *   ==================== 
 *                                  Z_G_POINT    ghost node point element 
 *                                  Z_G_BAR02    2 node ghost bar 
 *                                  Z_G_BAR03    3 node ghost bar 
 *                                  Z_G_TRI03    3 node ghost triangle 
 *                                  Z_G_TRI06    6 node ghost triangle 
 *                                  Z_G_QUA04    4 node ghost quad 
 *                                  Z_G_QUA08    8 node ghost quad 
 *                                  Z_G_TET04    4 node ghost tetrahedron 
 *                                  Z_G_TET10   10 node ghost tetrahedron 
 *                                  Z_G_PYR05    5 node ghost pyramid 
 *                                  Z_G_PYR13   13 node ghost pyramid 
 *                                  Z_G_PEN06    6 node ghost pentahedron 
 *                                  Z_G_PEN15   15 node ghost pentahedron 
 *                                  Z_G_HEX08    8 node ghost hexahedron 
 *                                  Z_G_HEX20   20 node ghost hexahedron 
 *   Starting at API 2.03           Z_G_NSIDED  ghost nsided polygon 
 *   Starting at API 2.03           Z_G_NFACED  ghost nfaced polyhedron 
 * 
 *  (OUT) elemid_array            = 1D array containing id of each 
 *                                   element of the type. 
 * 
 *                                  (Array will have been allocated 
 *                                   number_of_elements of type long) 
 * 
 *                       ex) If number_of_elements[Z_TRI03] = 25 
 *                              number_of_elements[Z_QUA04] = 100 
 *                              number_of_elements[Z_HEX08] = 30 
 *                           as obtained in: 
 *                            USERD_get_gold_part_build_info 
 * 
 *                           Then the allocated dimensions available 
 *                           for this routine will be: 
 *                              elemid_array[25]    when called with Z_TRI03 
 * 
 *                              elemid_array[100]   when called with Z_QUA04 
 * 
 *                              elemif_array[30]    when called with Z_HEX08 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 * 
 *  Prior to API 2.01: 
 *  ================= 
 *  * Not called unless Num_unstructured_parts is > 0  and element 
 *    label status is TRUE 
 * 
 *  Starting at API 2.01: 
 *  ==================== 
 *  * Not called unless element label status is TRUE in 
 *    USERD_get_element_label_status 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_part_element_ids_by_type(int part_number, 
                                   int element_type, 
                                   int *elemid_array) 
/*--------------------------------------------------------------------

3.4.49. USERD_get_part_element_ids_by_type_in_buffers

 *                                 <optional>  (version 2.08 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Gets the ids for the elements of a particular type 
 *   in an unstructured part in buffers 
 * 
 *   This is one of several optional routines than can be added into any 
 *   API 2.* reader to be used by the Unstructured Auto Distribute 
 *   capability in EnSight 8.2 and later. 
 * 
 *   Unstructured Auto Distribute is a capability requiring Server of Servers 
 *   (SOS) that will partition an unstructured model for you automatically 
 *   across a set of servers. 
 * 
 *   If you do not implement this routine (and the other in_buffers routines) 
 *   in your reader, EnSight can still perform this operation but will 
 *   require much more memory on each server to read in the data (somewhat 
 *   like each server having to read the whole model). You will however, get 
 *   the execution advantage of having your model partitioned across multiple 
 *   servers. 
 * 
 *   If you do implement this routine (and the other in_buffers routines) 
 *   in your reader (in a proper manner), you should be able to not only get 
 *   the execution advantages, but also memory usage on each server which is 
 *   proportional to the subset that it is assigned to deal with.  
 * 
 *   Note that this optional routine is functionally quite similar 
 *   to the USERD_get_part_element_ids_by_type routine. And thus its 
 *   implementation should not be too difficult to add to any existing reader 
 *   that has already implemented the USERD_get_part_element_ids_by_type 
 *   routine. 
 * 
 *  (IN)  part_number             = The part number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                     1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id that is  
 *                                   loaded in USERD_get_gold_part_build_info) 
 * 
 *  (IN)  element_type            = One of the following (See global_extern.h) 
 *                                  Z_POINT    node point element 
 *                                  Z_BAR02    2 node bar 
 *                                  Z_BAR03    3 node bar 
 *                                  Z_TRI03    3 node triangle 
 *                                  Z_TRI06    6 node triangle 
 *                                  Z_QUA04    4 node quad 
 *                                  Z_QUA08    8 node quad 
 *                                  Z_TET04    4 node tetrahedron 
 *                                  Z_TET10   10 node tetrahedron 
 *                                  Z_PYR05    5 node pyramid 
 *                                  Z_PYR13   13 node pyramid 
 *                                  Z_PEN06    6 node pentahedron 
 *                                  Z_PEN15   15 node pentahedron 
 *                                  Z_HEX08    8 node hexahedron 
 *                                  Z_HEX20   20 node hexahedron 
 * 
 * 
 *   Starting at API 2.01: 
 *   ==================== 
 *                                  Z_G_POINT    ghost node point element 
 *                                  Z_G_BAR02    2 node ghost bar 
 *                                  Z_G_BAR03    3 node ghost bar 
 *                                  Z_G_TRI03    3 node ghost triangle 
 *                                  Z_G_TRI06    6 node ghost triangle 
 *                                  Z_G_QUA04    4 node ghost quad 
 *                                  Z_G_QUA08    8 node ghost quad 
 *                                  Z_G_TET04    4 node ghost tetrahedron 
 *                                  Z_G_TET10   10 node ghost tetrahedron 
 *                                  Z_G_PYR05    5 node ghost pyramid 
 *                                  Z_G_PYR13   13 node ghost pyramid 
 *                                  Z_G_PEN06    6 node ghost pentahedron 
 *                                  Z_G_PEN15   15 node ghost pentahedron 
 *                                  Z_G_HEX08    8 node ghost hexahedron 
 *                                  Z_G_HEX20   20 node ghost hexahedron 
 *                                  Z_NSIDED     n node ghost nsided polygon 
 *                                  Z_NFACED     n face ghost nfaced polyhedron 
 * 
 *   Starting at API 2.02: 
 *   ==================== 
 *                                  Z_NSIDED     n node nsided polygon 
 *                                  Z_NFACED     n face nfaced polyhedron 
 *                                  Z_G_NSIDED   n node ghost nsided polygon 
 *                                  Z_G_NFACED   n face ghost nfaced polyhedron 
 * 
 *  (IN)  first                   = TRUE if first invocation of a buffered set. 
 *                                  Will be FALSE for all subsequent invocations 
 *                                  of the set.  This is so you can open files, 
 *                                  get to the correct starting spot, 
 *                                  initialize, etc. 
 * 
 *  (IN) e_beg                    = Zero based, first element number 
 *                                  of the buffered set 
 * 
 *  (IN) e_end                    = Zero based, last element number 
 *                                  of the buffered set 
 * 
 *                     Thus, for first five elements of a type: 
 *                       e_beg = 0 
 *                       e_end = 4 
 *                       total_number = (e_end - e_beg) + 1 = (4 - 0) + 1 = 5 
 * 
 *                     for second five elements of a type, would be: 
 *                       e_beg = 5 
 *                       e_end = 9 
 *                       total_number = (e_end - e_beg) + 1 = (9 - 5) + 1 = 5 
 * 
 *                     for all elements of the type of a part, would be: 
 *                       n_beg = 0 
 *                       n_end = num_elements_of_type - 1 
 * 
 *  (IN) buffer_size              = The size of the buffer. 
 *                                  Namely:  elemid_array[buffer_size] 
 * 
 *  (OUT) elemid_array            = 1D buffer array which is set up to hold ids 
 *                                  of elements of the type. 
 * 
 *                                  (Array will have been allocated 
 *                                   buffer_size long) 
 * 
 *   * Example, (if 158 quad elements, and buffer size is 200) 
 * 
 *       (get all 158 quad4 ids in one invocation) 
 *          element_type = Z_QUA04 
 *          first = TRUE               Will be TRUE the first time! 
 *          e_beg  = 0                 (zero based, first element index) 
 *          e_end  = 157               (zero based, last element index) 
 *          buffer_size = 200 
 *          elemeid_array[200]         Use first 158 locations of the array 
 *          *num_returned = 158        set this 
 *          return(1)                  return this (indicates no more to do) 
 * 
 *   * Example, (if 158 quad elements, and buffer size is 75) 
 * 
 *        first invocation: 
 *          element_type = Z_QUA04 
 *          first = TRUE               Will be TRUE the first time! 
 *          e_beg  = 0 
 *          e_end  = 157 
 *          buffer_size = 75 
 *          elemid_array[75]           load in ids for elements 1 - 75 
 *          *num_returned = 75         set this 
 *          return(0)                  return this (indicates more to do) 
 * 
 *        second invocation: 
 *          element_type = Z_QUA04 
 *          first = TRUE               Will be TRUE the first time! 
 *          e_beg  = 0 
 *          e_end  = 157 
 *          buffer_size = 75 
 *          elemid_array[75]           load in ids for elements 76 - 150 
 *          *num_returned = 75         set this 
 *          return(0)                  return this (indicates more to do) 
 * 
 *        third invocation: 
 *          element_type = Z_QUA04 
 *          first = TRUE               Will be TRUE the first time! 
 *          e_beg  = 0 
 *          e_end  = 157 
 *          buffer_size = 75 
 *          elemid_array[75]           load in ids for elements 151 - 158 
 *          *num_returned = 8          set this 
 *          return(1)                  return this (indicates no more to do) 
 * 
 * 
 *  (OUT)  *num_returned       = The number of elements whose ids are returned 
 *                               in the buffer. This will normally be equal 
 *                               to buffer_size except for that last buffer 
 *                               - which could be less than a full buffer. 
 * 
 * returns  0  if got some, more to do 
 *          1  if got some, done 
 *         -1  if an error 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 * 
 *  * Again, make sure each buffer is zero based. 
 *    For our example using buffers above: 
 * 
 *                                                  Invocation: 
 *                                           1          2          3     
 *                                        -------    -------    -------- 
 *      elemid_array[0]       elem id  for quad 1    quad 76     quad 151 
 * 
 *      elemid_array[1]       elem id  for quad 2    quad 77     quad 152 
 * 
 *      ... 
 * 
 *      elemid_array[74]      elem id  for quad 75   quad 150    quad 158 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_part_element_ids_by_type_in_buffers(int part_number, 
                                              int element_type, 
                                              int *elemid_array, 
                                              int first, 
                                              int e_beg, 
                                              int e_end, 
                                              int buffer_size, 
                                              int *num_returned) 
/*--------------------------------------------------------------------

3.4.50. USERD_get_part_elements_by_type

 *                                            (version 2.00 and later) 
 *                               (Modified at 2.01 as described below) 
 *                               (Modified at 2.03 as described below) 
 *-------------------------------------------------------------------- 
 * 
 *   Gets the connectivities for the elements of a particular type 
 *   in an unstructured part 
 * 
 *  (IN)  part_number             = The part number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                     1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id that is  
 *                                   loaded in USERD_get_gold_part_build_info) 
 * 
 *  (IN)  element_type            = One of the following (See global_extern.h) 
 *                                  Z_POINT    node point element 
 *                                  Z_BAR02    2 node bar 
 *                                  Z_BAR03    3 node bar 
 *                                  Z_TRI03    3 node triangle 
 *                                  Z_TRI06    6 node triangle 
 *                                  Z_QUA04    4 node quad 
 *                                  Z_QUA08    8 node quad 
 *                                  Z_TET04    4 node tetrahedron 
 *                                  Z_TET10   10 node tetrahedron 
 *                                  Z_PYR05    5 node pyramid 
 *                                  Z_PYR13   13 node pyramid 
 *                                  Z_PEN06    6 node pentahedron 
 *                                  Z_PEN15   15 node pentahedron 
 *                                  Z_HEX08    8 node hexahedron 
 *                                  Z_HEX20   20 node hexahedron 
 *   Starting at API 2.03           Z_NSIDED  nsided polygon 
 *   Starting at API 2.03           Z_NFACED  nfaced polyhedron 
 * 
 *   Starting at API 2.01: 
 *   ==================== 
 *                                  Z_G_POINT    ghost node point element 
 *                                  Z_G_BAR02    2 node ghost bar 
 *                                  Z_G_BAR03    3 node ghost bar 
 *                                  Z_G_TRI03    3 node ghost triangle 
 *                                  Z_G_TRI06    6 node ghost triangle 
 *                                  Z_G_QUA04    4 node ghost quad 
 *                                  Z_G_QUA08    8 node ghost quad 
 *                                  Z_G_TET04    4 node ghost tetrahedron 
 *                                  Z_G_TET10   10 node ghost tetrahedron 
 *                                  Z_G_PYR05    5 node ghost pyramid 
 *                                  Z_G_PYR13   13 node ghost pyramid 
 *                                  Z_G_PEN06    6 node ghost pentahedron 
 *                                  Z_G_PEN15   15 node ghost pentahedron 
 *                                  Z_G_HEX08    8 node ghost hexahedron 
 *                                  Z_G_HEX20   20 node ghost hexahedron 
 *   Starting at API 2.03           Z_G_NSIDED  ghost nsided polygon 
 *   Starting at API 2.03           Z_G_NFACED  ghost nfaced polyhedron 
 * 
 * 
 * 
 * 
 *  (OUT) conn_array              = 2D array containing connectivity 
 *                                   of each element of the type. 
 * 
 *                                  (Array will have been allocated 
 *                                   number_of_elements of 
 *                                   the type by connectivity length 
 *                                   of the type) 
 * 
 *                       ex) If number_of_elements[Z_TRI03] = 25 
 *                              number_of_elements[Z_QUA04] = 100 
 *                              number_of_elements[Z_HEX08] = 30 
 *                           as obtained in: 
 *                            USERD_get_gold_part_build_info 
 * 
 *                           Then the allocated dimensions available 
 *                           for this routine will be: 
 *                              conn_array[25][3]   when called with Z_TRI03 
 * 
 *                              conn_array[100][4]  when called with Z_QUA04 
 * 
 *                              conn_array[30][8]   when called with Z_HEX08 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 *  * Not called unless Num_unstructured_parts is > 0 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_part_elements_by_type(int part_number, 
                                int element_type, 
                                int **conn_array) 
/*--------------------------------------------------------------------

3.4.51. USERD_get_part_elements_by_type_in_buffers

 *                                <optional>  (Version 2.08 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Gets the connectivities for the elements of a particular type 
 *   in an unstructured part in buffers 
 * 
 *   This is one of several optional routines than can be added into any 
 *   API 2.* reader to be used by the Unstructured Auto Distribute 
 *   capability in EnSight 8.2 and later. 
 * 
 *   Unstructured Auto Distribute is a capability requiring Server of Servers 
 *   (SOS) that will partition an unstructured model for you automatically 
 *   across a set of servers. 
 * 
 *   If you do not implement this routine (and the other in_buffers routines) 
 *   in your reader, EnSight can still perform this operation but will require 
 *   much more memory on each server to read in the data (somewhat like each 
 *   server having to read the whole model). You will however, get the execution 
 *   advantage of having your model partitioned across multiple servers. 
 * 
 *   If you do implement this routine (and the other in_buffers routines) in 
 *   your reader (in a proper manner), you should be able to not only get the 
 *   execution advantages, but also memory usage on each server which is 
 *   proportional to the subset that it is assigned to deal with.  
 * 
 *   Note that this optional routine is functionally quite similar 
 *   to the USERD_get_part_elements_by_type routine. And thus its 
 *   implementation should not be too difficult to add to any existing reader 
 *   that has already implemented the USERD_get_part_elements_by_type routine. 
 * 
 *  (IN)  part_number             = The part number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                     1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id that is 
 *                                   loaded in USERD_get_gold_part_build_info) 
 * 
 *  (IN)  element_type            = One of the following (See global_extern.h) 
 *                                  Z_POINT    node point element 
 *                                  Z_BAR02    2 node bar 
 *                                  Z_BAR03    3 node bar 
 *                                  Z_TRI03    3 node triangle 
 *                                  Z_TRI06    6 node triangle 
 *                                  Z_QUA04    4 node quad 
 *                                  Z_QUA08    8 node quad 
 *                                  Z_TET04    4 node tetrahedron 
 *                                  Z_TET10   10 node tetrahedron 
 *                                  Z_PYR05    5 node pyramid 
 *                                  Z_PYR13   13 node pyramid 
 *                                  Z_PEN06    6 node pentahedron 
 *                                  Z_PEN15   15 node pentahedron 
 *                                  Z_HEX08    8 node hexahedron 
 *                                  Z_HEX20   20 node hexahedron 
 * 
 * 
 * 
 * 
 *   Starting at API 2.01: 
 *   ==================== 
 *                                  Z_G_POINT    ghost node point element 
 *                                  Z_G_BAR02    2 node ghost bar 
 *                                  Z_G_BAR03    3 node ghost bar 
 *                                  Z_G_TRI03    3 node ghost triangle 
 *                                  Z_G_TRI06    6 node ghost triangle 
 *                                  Z_G_QUA04    4 node ghost quad 
 *                                  Z_G_QUA08    8 node ghost quad 
 *                                  Z_G_TET04    4 node ghost tetrahedron 
 *                                  Z_G_TET10   10 node ghost tetrahedron 
 *                                  Z_G_PYR05    5 node ghost pyramid 
 *                                  Z_G_PYR13   13 node ghost pyramid 
 *                                  Z_G_PEN06    6 node ghost pentahedron 
 *                                  Z_G_PEN15   15 node ghost pentahedron 
 *                                  Z_G_HEX08    8 node ghost hexahedron 
 *                                  Z_G_HEX20   20 node ghost hexahedron 
 *                                  Z_NSIDED     n node ghost nsided polygon 
 *                                  Z_NFACED     n face ghost nfaced polyhedron 
 * 
 *   Starting at API 2.02: 
 *   ==================== 
 *                                  Z_NSIDED     n node nsided polygon 
 *                                  Z_NFACED     n face nfaced polyhedron 
 *                                  Z_G_NSIDED   n node ghost nsided polygon 
 *                                  Z_G_NFACED   n face ghost nfaced polyhedron 
 * 
 *  (IN)  first                = TRUE if first invocation of a buffered set. 
 *                               Will be FALSE for all subsequent invocations 
 *                               of the set.  This is so you can open files, 
 *                               get to the correct starting spot, 
 *                               initialize, etc. 
 * 
 *  (IN) e_beg                 = Zero based, first element number of the buffered set 
 * 
 *  (IN) e_end                 = Zero based, last element number of the buffered set 
 * 
 *                     Thus, for first five elements of a type: 
 *                       e_beg = 0 
 *                       e_end = 4 
 *                       total_number = (e_end - e_beg) + 1 = (4 - 0) + 1 = 5 
 * 
 *                     for second five elements of a type, would be: 
 *                       e_beg = 5 
 *                       e_end = 9 
 *                       total_number = (e_end - e_beg) + 1 = (9 - 5) + 1 = 5 
 * 
 *                     for all elements of the type of a part, would be: 
 *                       n_beg = 0 
 *                       n_end = num_elements_of_type - 1 
 * 
 *  (IN) buffer_size           = The size of the buffer. 
 *                               Namely:  conn_array[buffer_size][element_size] 
 * 
 *  (OUT) conn_array           = 2D buffer array which is set up to hold 
 *                               connectivity of elements of the type. 
 * 
 *                               (Array will have been allocated 
 *                                buffer_size of the type by connectivity length 
 *                                of the type) 
 * 
 *                  ex) The allocated dimensions available 
 *                      for this routine will be: 
 *                         conn_array[buffer_size][3]   when called with Z_TRI03 
 * 
 *                         conn_array[buffer_size][4]   when called with Z_QUA04 
 * 
 *                         conn_array[buffer_size][8]   when called with Z_HEX08 
 * 
 *                         etc. 
 * 
 *   * Example, (if 158 quad elements, and buffer size is 200) 
 * 
 *       (get all 158 quad4s in one invocation) 
 *          element_type = Z_QUA04 
 *          first = TRUE               Will be TRUE the first time! 
 *          e_beg  = 0                 (zero based, first element index) 
 *          e_end  = 157               (zero based, last element index) 
 *          buffer_size = 200 
 *          conn_array[200][4]         Use first 158 locations of the array 
 *          *num_returned = 158        set this 
 *          return(1)                  return this (indicates no more to do) 
 * 
 *   * Example, (if 158 quad elements, and buffer size is 75) 
 * 
 *        first invocation: 
 *          element_type = Z_QUA04 
 *          first = TRUE               Will be TRUE the first time! 
 *          e_beg  = 0 
 *          e_end  = 157 
 *          buffer_size = 75 
 *          conn_array[75][4]          load in conn for elements 1 - 75 
 *          *num_returned = 75         set this 
 *          return(0)                  return this (indicates more to do) 
 * 
 *        second invocation: 
 *          element_type = Z_QUA04 
 *          first = TRUE               Will be TRUE the first time! 
 *          e_beg  = 0 
 *          e_end  = 157 
 *          buffer_size = 75 
 *          conn_array[75][4]          load in conn for elements 76 - 150 
 *          *num_returned = 75         set this 
 *          return(0)                  return this (indicates more to do) 
 * 
 *        third invocation: 
 *          element_type = Z_QUA04 
 *          first = TRUE               Will be TRUE the first time! 
 *          e_beg  = 0 
 *          e_end  = 157 
 *          buffer_size = 75 
 *          conn_array[75][4]          load in conn for elements 151 - 158 
 *          *num_returned = 8          set this 
 *          return(1)                  return this (indicates no more to do) 
 * 
 * 
 *  (OUT)  *num_returned          = The number of elements whose connectivities 
 *                                  are returned in the buffer. This will 
 *                                  normally be equal to buffer_size except for 
 *                                  that last buffer - which could be less than 
 *                                  a full buffer. 
 * 
 * returns  0  if got some, more to do 
 *          1  if got some, done 
 *         -1  if an error 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 * 
 *  * Again, make sure each buffer is zero based. 
 *    For our example using buffers above: 
 * 
 *                                                        Invocation: 
 *                                                  1          2          3     
 *                                               -------    -------    -------- 
 *      conn_array[0][0]       node 1 in conn for quad 1    quad 76     quad 151 
 *      conn_array[0][1]       node 2 in conn for quad 1    quad 76     quad 151 
 *      conn_array[0][2]       node 3 in conn for quad 1    quad 76     quad 151 
 *      conn_array[0][3]       node 4 in conn for quad 1    quad 76     quad 151 
 * 
 *      conn_array[1][0]       node 1 in conn for quad 2    quad 77     quad 152 
 *      conn_array[1][1]       node 2 in conn for quad 2    quad 77     quad 152 
 *      conn_array[1][2]       node 3 in conn for quad 2    quad 77     quad 152 
 *      conn_array[1][3]       node 4 in conn for quad 2    quad 77     quad 152 
 * 
 *      ... 
 * 
 *      conn_array[74][0]      node 1 in conn for quad 75    quad 150   quad 158 
 *      conn_array[74][1]      node 2 in conn for quad 75    quad 150   quad 158 
 *      conn_array[74][2]      node 3 in conn for quad 75    quad 150   quad 158 
 *      conn_array[74][3]      node 4 in conn for quad 75    quad 150   quad 158 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_part_elements_by_type_in_buffers(int part_number, 
                                           int element_type, 
                                           int **conn_array, 
                                           int first, 
                                           int e_beg, 
                                           int e_end, 
                                           int buffer_size, 
                                           int *num_returned) 
/*--------------------------------------------------------------------

3.4.52. USERD_get_part_node_ids

 *                                            (Version 2.00 and later) 
 *                               (Modified at 2.01 as described below) 
 *-------------------------------------------------------------------- 
 *   Prior to API 2.01: 
 *   ================== 
 *   Get the node ids of an unstructured part. 
 * 
 *   Starting at API 2.01: 
 *   ==================== 
 *   Get the node ids of an unstructured or structured part. 
 * 
 *  (IN)  part_number             = The part number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                     1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id that is 
 *                                   loaded in USERD_get_gold_part_build_info) 
 * 
 *  (OUT) nodeid_array            = 1D array containing node ids of 
 *                                   each node in the part. 
 * 
 *       (IMPORTANT: this array is 1-based!!!) 
 * 
 *                                  (Array will have been allocated 
 *                                   (number_of_nodes + 1) for the part long 
 *                                   see USERD_get_gold_part_build_info) 
 * 
 *                       ex) If number_of_nodes = 100 
 *                           as obtained in: 
 *                             USERD_get_gold_part_build_info 
 * 
 *                           Then the allocated dimensions of the 
 *                           pointer sent to this routine will be: 
 *                             nodeid_array[101] 
 * 
 *                           Ignore the nodeid_array[0] location and start 
 *                           the node ids at: 
 *                             nodeid_array[1] 
 * 
 *                             nodeid_array[2] 
 * 
 *                                   etc. 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 * 
 *  * Not called unless number_of_nodes for the part is > 0  and 
 *    node label status is TRUE, as returned from USERD_get_node_label_status 
 * 
 * * The ids are purely labels, used when displaying or querying node ids. 
 *   However, any node id < 0 will never be displayed 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_part_node_ids(int part_number, 
                        int *nodeid_array) 
/*--------------------------------------------------------------------

3.4.53. USERD_get_part_node_ids_in_buffers

 *                                 <optional>  (Version 2.08 an later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the node ids for an unstructured part in buffers. 
 * 
 *   This is one of several optional routines than can be added into any 
 *   API 2.* reader to be used by the Unstructured Auto Distribute 
 *   capability in EnSight 8.2 and later. 
 * 
 *   Unstructured Auto Distribute is a capability requiring Server of Servers 
 *   (SOS) that will partition an unstructured model for you automatically 
 *   across a set of servers. 
 * 
 *   If you do not implement this routine (and the other in_buffers routines) 
 *   in your reader, EnSight can still perform this operation but will require 
 *   much more memory on each server to read in the data (somewhat like each 
 *   server having to read the whole model). You will however, get the execution 
 *   advantage of having your model partitioned across multiple servers. 
 * 
 *   If you do implement this routine (and the other in_buffers routines) 
 *   in your reader (in a proper manner), you should be able to not only get 
 *   the execution advantages, but also memory usage on each server which is 
 *   proportional to the subset that it is assigned to deal with.  
 * 
 *   Note that this optional routine is functionally quite similar 
 *   to the USERD_get_part_node_ids routine. And thus its implementation should 
 *   not be too difficult to add to any existing reader that has already 
 *   implemented the USERD_get_part_node_ids routine. 
 * 
 *  (IN)  part_number      = The part number 
 * 
 *                           (1-based index of part table, namely: 
 * 
 *                              1 ... Numparts_available. 
 * 
 *                            It is NOT the part_id that is 
 *                            loaded in USERD_get_gold_part_build_info) 
 * 
 *  (IN)  first            = TRUE if first invocation of a buffered set. 
 *                           Will be FALSE for all subsequent invocations 
 *                           of the set.  This is so you can open files, get to 
 *                           the correct starting spot, initialize, etc. 
 * 
 *  (IN) n_beg             = Zero based, first node index 
 *                           of the buffered set 
 * 
 *  (IN) n_end             = Zero based, last node index 
 *                           of the buffered set 
 *                                       
 *                     Thus, for first five nodes: 
 *                       n_beg = 0 
 *                       n_end = 4 
 *                       total_number = (n_end - n_beg) + 1 = (4 - 0) + 1 = 5 
 * 
 *                     for second five nodes, would be:       
 *                       n_beg = 5 
 *                       n_end = 9 
 *                       total_number = (n_end - n_beg) + 1 = (9 - 5) + 1 = 5 
 * 
 *                     for all nodes of a part, would be: 
 *                       n_beg = 0 
 *                       n_end = num_nodes - 1 
 * 
 *  (IN)  buffer_size             = The size of the buffer. 
 *                                  Namely:   nodeid_array[buffer_size] 
 * 
 *  (OUT) nodeid_array            = 1D buffer array which is set up to hold 
 *                                  node ids of nodes 
 * 
 *       (IMPORTANT: this array is 0-based!!!) 
 * 
 *       (IMPORTANT: in the sister routine (USERD_get_part_node_ids) - which 
 *                   does not use buffers. This array is 1-based. 
 *                   So pay attention.) 
 * 
 *                                  (Array will have been allocated 
 *                                   buffer_size long) 
 * 
 * Example, if we had a part with 645 nodes and the buffer size was set to 200 
 * 
 *  first invocation: 
 *    first = TRUE            Will be TRUE the first time!  
 *    n_beg = 0 
 *    n_end = 644 
 *    buffer_size = 200 
 *    nodeid_array[200]       fill with values for nodes 1 - 200   (zero-based) 
 *    *num_returned = 200     set this 
 *    return(0)               return this (indicates more to do) 
 * 
 *  second invocation:        which occurs because we returned a 0 last time 
 *    first = FALSE           will now be FALSE 
 *    n_beg = 0 
 *    n_end = 644 
 *    buffer_size = 200 
 *    nodeid_array[200]       fill with values for nodes 201 - 400 (zero-based) 
 *    *num_returned = 200     set this 
 *    return(0)               return this (indicates more to do) 
 * 
 *  third invocation:         which occurs because we returned a 0 last time 
 *    first = FALSE           will still be FALSE 
 *    n_beg = 0 
 *    n_end = 644 
 *    buffer_size = 200 
 *    nodeid_array[200]       fill with values for nodes 401 - 600 (zero-based) 
 *    *num_returned = 200     set this 
 *    return(0)               return this (indicates more to do) 
 * 
 *  fourth invocation:        which occurs because we returned a 0 last time 
 *    first = FALSE           will still be FALSE 
 *    n_beg = 0 
 *    n_end = 644 
 *    buffer_size = 200 
 *    nodeid_array[200]       fill with values for nodes 601 - 645 (zero-based) 
 *    *num_returned = 45      set this 
 *    return(1)               return this (indicates done!) 
 * 
 *  (OUT)  *num_returned          = The number of nodes whose ids are returned 
 *                                  in the buffer. This will normally be equal 
 *                                  to buffer_size except for that last buffer 
 *                                  - which could be less than a full buffer.  
 * 
 * returns  0  if got some, more to do 
 *          1  if got some, done 
 *         -1  if an error 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 * 
 *  * Not called unless number_of_nodes for the part > 0 
 * 
 *  * Again, make sure each buffer is zero based. For our example above: 
 * 
 *                                                 Invocation: 
 *                                     1          2          3           4 
 *                                  -------    -------    --------    ------- 
 *      nodeid_array[0]    id   for node 1     node 201   node 401    node 601    
 * 
 *      nodeid_array[1]    id   for node 2     node 202   node 402    node 602 
 * 
 *      ... 
 * 
 *      nodeid_array[199]  id   for node 200   node 400   node 600    node 645 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_part_node_ids_in_buffers(int part_number, 
                                   int *nodeid_array, 
                                   int first, 
                                   int n_beg, 
                                   int n_end, 
                                   int buffer_size, 
                                   int *num_returned) 
/*--------------------------------------------------------------------

3.4.54. USERD_get_periodic_ghosts_num_pairs

 *                               <optional>   (Version 2.00 and later) 
  *-------------------------------------------------------------------- 
 * 
 *  (IN)  part_number      = The part number 
 * 
 *                           (1-based index of part table, namely: 
 * 
 *                              1 ... Numparts_available. 
 * 
 *                            It is NOT the part_id that 
 *                            is loaded in USERD_get_gold_part_build_info) 
 * 
 *         face            = The (zero-based) symmetry face number. This routine 
 *                           will be called the number of times as the number of 
 *                           faces declared in 
 *                           USERD_get_periodic_ghosts_num_symmety_faces. 
 * 
 *                           For translation and rotation, this routine will be 
 *                             called twice - once with face = 0, and once with 
 *                             face = 1; 
 *                           For mirroring, this routine can be called once, 
 *                             twice, or three times. Thus face will be 0, 0 and 
 *                             1, or 0,1,2. 
 * 
 *  returns: the number of node pairs for the symmetry face. 
 * 
 *  Notes: 
 *   You must have first called: 
 *      USERD_use_periodic_ghosts   (only need be done once for the model) 
 *      USERD_get_periodic_ghosts_num_symmetry_faces 
 * 
 *   and will need to call: 
 *      USERD_get_periodic_ghosts_pairs 
 * 
 *   See USERD_use_periodic_ghosts routine for examples. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_periodic_ghosts_num_pairs(int part_number, int face)   
/*--------------------------------------------------------------------

3.4.55. USERD_get_periodic_ghosts_num_symmetry_faces

 *                               <optional>   (Version 2.00 and later) 
  *-------------------------------------------------------------------- 
 * 
 *  (IN)  part_number      = The part number 
 * 
 *                           (1-based index of part table, namely: 
 * 
 *                              1 ... Numparts_available. 
 * 
 *                            It is NOT the part_id that 
 *                            is loaded in USERD_get_gold_part_build_info) 
 * 
 *  returns: The number of symmetry faces in the part, and for which the 
 *           pairs of matching nodes will be provided in: 
 *           USERD_get_periodic_ghosts_num_pairs 
 *           USERD_get_periodic_ghosts_pairs. 
 * 
 *           or the ijk information will be provided in: 
 *           USERD_get_periodic_ghosts_structured_face_info 
 * 
 *           Zero should be returned if this part has no symmetry faces. 
 * 
 *  Notes: 
 *   You must have first called: 
 *      USERD_use_periodic_ghosts   (only need be done once for the model) 
 * 
 *   and will afterwards need to call either: 
 *      USERD_get_periodic_ghosts_num_pairs    and 
 *      USERD_get_periodic_ghosts_pairs 
 * 
 *   or 
 *      USERD_get_periodic_ghosts_structured_face_info 
 * 
 * 
 *   See USERD_use_periodic_ghosts routine for examples. 
 * 
 *   For Translation, and rotation, the number should be 2 because there 
 *    should always be an opposite face. 
 * 
 *   For mirroring, the number can be 1, 2, or 3, depending on which of 
 *    the reflection faces are being used.  Namely, for mirror symmetry 
 *    the original instance can reflect across x, y, z, xy, yz, xz, or xyz 
 *    filling the appropriate other 7 quadrants. And the faces needing ghosts 
 *    depends on which are used. (x, xy, xz, xyz need x face, 
 *                                y, xy, yz, xyz need y face, 
 *                                z, xz, yz, xyz need z face) 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_periodic_ghosts_num_symmetry_faces(int part_number) 
/*--------------------------------------------------------------------

3.4.56. USERD_get_periodic_ghosts_pairs

 *                               <optional>   (Version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *  (IN)  part_number  = The part number 
 * 
 *                       (1-based index of part table, namely: 
 * 
 *                          1 ... Numparts_available. 
 * 
 *                        It is NOT the part_id that 
 *                        is loaded in USERD_get_gold_part_build_info) 
 * 
 *         face          = The (zero-based) symmetry face number. This routine 
 *                         will be called the number of times as the number 
 *                         of faces declared in 
 *                         USERD_get_periodic_ghosts_num_symmety_faces. 
 * 
 *                         For translation and rotation, this routine will be 
 *                           called twice - once with face = 0, and once with 
 *                           face = 1; 
 *                         For mirroring, this routine can be called once, 
 *                           twice, or three times. Thus face will be 0, 0 and 1, 
 *                           or 0,1,2. 
 * 
 *     providing_matrix  = TRUE if the reader is providing the matrix. And the 
 *                              m argument must contain that matrix. 
 * 
 *                         FALSE if EnSight should compute it from the node pairs. 
 *                               Thus  m argument is ignored. 
 * 
 *                          Note:  EnSight should be able to produce the m matrix 
 *                                 for you, except for the condition of planar 2D 
 *                                 with transformations out of plane. 
 * 
 *      m                = 4x4 transformation matrix. 
 *                         This will be used if providing_matrix flag is TRUE 
 * 
 *                         Note: this matrix will be used in the following fashion: 
 * 
 *                           {Ax Ay Az 1}|m11 m12 m13 m14| = {Bx By Bz 1} 
 *                               .       |m21 m22 m23 m24|       . 
 *                               .       |m31 m32 m33 m34|       . 
 *                               .       |m41 m42 m43 m44|       . 
 * 
 *                           where Ax Ay Az are the coords of node1 of a pair 
 *                                 Bx By Bz are the coords of node2 of a pair   
 * 
 *                           This matrix is generally thought of as: 
 * 
 *                              |              | 0|   r is the rotational, 
 *                              |      r       | 0|      shearing, reflection   
 *                              |              | 0|      portion  
 *                              |--------------|--| 
 *                              |      t       | 1|   t is the translational  
 *                                                       portion
 * 
 *  (OUT) pairs        = array of part node indicies that are periodic match pairs 
 *                       for the part and symmetry face. 
 * 
 *                       pairs[0] = node1 of 1st pair 
 *                            [1] = node2 of 1st pair 
 *                            [2] = node1 of 2nd pair 
 *                            [3] = node2 of 2nd pair 
 *                            [4] = node1 of 3rd pair 
 *                            [5] = node2 of 3rd pair 
 *                                   . 
 *                                   . 
 *                                   . 
 * 
 *                        it's length needs to be twice the num_pairs returned in 
 *                        USERD_get_periodic_ghosts_num_pairs. 
 * 
 *                        The nodes need to be the node indicies, not the ids. 
 * 
 *  returns: Z_OK    if all is well 
 *           Z_ERR   if an error 
 * 
 *  Notes: 
 *   You must have first called: 
 *     USERD_use_periodic_ghosts   (only need be done once for the model) 
 *     USERD_get_periodic_ghosts_num_symmetry_faces 
 *     USERD_get_periodic_ghosts_num_pairs 
 * 
 * 
 *   See USERD_use_periodic_ghosts routine for examples. 
 * 
 *   For translation and rotation, the pairs for face 1 will be the reverse 
 *     of those for face 0. 
 *   For mirroring, each pair will contain the same node index. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_periodic_ghosts_pairs(int part_number, 
                                int face, 
                                int *providing_matrix, 
                                double m[4][4], 
                                int *pairs)  
/*--------------------------------------------------------------------

3.4.57. USERD_get_periodic_ghosts_structured_face_info

 *                               <optional>   (Version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *  (IN)  part_number  = The part number 
 * 
 *                       (1-based index of part table, namely: 
 * 
 *                          1 ... Numparts_available. 
 * 
 *                        It is NOT the part_id that 
 *                        is loaded in USERD_get_gold_part_build_info) 
 * 
 *         face          = The (zero-based) symmetry face number. This routine will 
 *                         be called the number of times as the number of faces 
 *                         declared in USERD_get_periodic_ghosts_num_symmetry_faces. 
 * 
 *                         For translation and rotation, this routine will be 
 *                           called twice - once with face = 0, and once with 
 *                           face = 1; 
 *                         For mirroring, this routine can be called once, 
 *                           twice, or three times. Thus face will be 0, 0 and 1, 
 *                           or 0,1,2. 
 * 
 *     providing_matrix  = TRUE if the reader is providing the matrix. And the 
 *                              m argument must contain that matrix. 
 * 
 *                         FALSE if EnSight should compute it from the node pairs. 
 *                               Thus  m argument is ignored. 
 * 
 *                          Note:  EnSight should be able to produce the m matrix 
 *                                 for you. 
 *                                 Note that there is an issue with the 
 *                                 condition of planar 2D transformations out of 
 *                                 plane. The transformation matrix produced may 
 *                                 not be what you wanted - because there isn't 
 *                                 enough information provided.  However, even if 
 *                                 the transformation isn't exactly correct, 
 *                                 the ghost elements produced may still do their 
 *                                 job of proper interpolation across the boundary 
 *                                 (unless direction is critical).  So for scalars 
 *                                 you should be good - but for vectors you may 
 *                                 not be. 
 *                             
 * 
 *      m                = 4x4 transformation matrix. 
 *                         This will be used if providing_matrix flag is TRUE 
 * 
 *                         Note: this matrix will be used in the following fashion: 
 * 
 *                           {Ax Ay Az 1}|m11 m12 m13 m14| = {Bx By Bz 1} 
 *                               .       |m21 m22 m23 m24|       . 
 *                               .       |m31 m32 m33 m34|       . 
 *                               .       |m41 m42 m43 m44|       . 
 * 
 *                           where Ax Ay Az are the coords of node1 of a pair 
 *                                 Bx By Bz are the coords of node2 of a pair   
 * 
 *                           This matrix is generally thought of as: 
 * 
 *                              |              | 0|   r is the rotational, 
 *                              |      r       | 0|      shearing, reflection  
 *                              |              | 0|      portion
 *                              |--------------|--| 
 *                              |      t       | 1|   t is the translational  
 *                                                    portion
 * 
 *  (OUT) which_ijk    = 1 for i direction or axis 
 *                       2 for j direction or axis 
 *                       3 ofr k direction or axis 
 * 
 *        min_or_max    = 0 for min i,j, or k 
 *                        1 for max i,j, or k 
 * 
 *  returns: Z_OK    if all is well 
 *           Z_ERR   if an error 
 * 
 *  Notes: 
 *  You must first call: 
 *    USERD_use_periodic_ghosts   (only need be done once for the model) 
 *    USERD_get_periodic_ghosts_num_symmetry_faces 
 * 
 *   Simple Structured Examples: 
 * 
 *   periodic translation in i  (min i goes to max i) 
 *   ================================================ 
 * 
 *               j         (in terms of original elements) 
 *                 
 *     *- - - - -*---------*---------*---------*- - - - -* 
 *     .  ghost  |         |         |         |  ghost  . 
 *     .    8    |    6    |    7    |    8    |    6    . 
 *     .         |         |         |         |         . 
 *     *- - - - -*---------*---------*---------*- - - - -* 
 *     .  ghost  |         |         |         |  ghost  . 
 * near.    5    |    3    |    4    |    5    |    3    .  far 
 *     .         |         |         |         |         . 
 *     *- - - - -*---------*---------*---------*- - - - -* 
 *     .  ghost  |         |         |         |  ghost  . 
 *     .    2    |    0    |    1    |    2    |    0    . 
 *     .         |         |         |         |         . 
 *     *- - - - -*---------*---------*---------*- - - - -*   i 
 * 
 *              <===== translation direction =====> 
 * 
 *     num_symmetry_faces = 2; 
 *     for face 0: 
 *        which_ijk = 1 
 *        min_or_max = 0 
 *     for face 1: 
 *        which_ijk = 1 
 *        min_or_max = 1       
 * 
 * 
 *   periodic rotation of 90 degrees about k  (min j goes to max j) 
 *   ============================================================= 
 * 
 *                15          12            9                 
 *               *-----------*------------* 
 *               |                      . | 
 *               |         .          .   |           Not as easy to 
 *               |                  .     |           show! 
 *               |       .        .       | 
 *   far         |              .         | 
 *   face     14 |   11.    8 .           | 6 
 *  (max j)      *----*-----*             * 
 *               |   .    . |         .   | 
 *               |      .   | 5  .        | 
 *               |  . .     *             | 
 *               |  .   .   |             |     ^ 
 *               |..        | 2           | 3   | 
 *               *----------*-------------*     j 
 *       1,4,7,10,13 
 *               i -> 
 *                       near face (min j) 
 *                    
 *            rotates in plane about k     
 *           
 *     num_faces = 2 
 *     for face 0: 
 *        which_ijk = 2 
 *        min_or_max = 0 
 *     for face 1: 
 *        which_ijk = 2 
 *        min_or_max = 1       
 * 
 * 
 *   mirror in i, and j (so min i reflects, ans min j reflects) 
 *   ========================================================== 
 * 
 *               ^ 
 *               |             (in terms of original elements 
 *               j 
 *               
 *     *- - - - -*---------*---------*---------* 
 *     . ghost   |         |         |         | 
 *     .    6    |    6    |    7    |    8    | 
 *     .         |         |         |         |   
 *     *- - - - -*---------*---------*---------* 
 *     .  ghost  |         |         |         | 
 *     .    3    |    3    |    4    |    5    | 
 *     .         |         |        |         |  
 *     *- - - - -*---------*---------*---------* 
 *     .  ghost  |         |         |         | 
 *     .    0    |    0    |    1    |    2    | 
 *     .         |         |         |         |  
 *     *- - - - -*---------*---------*---------*  i --> 
 *     .  ghost  .  ghost  .  ghost  .  ghost  . 
 *     .    0    .    0    .    1    .    2    . 
 *     .         .         .         .         . 
 *     *- - - - -*- - - - -*- - - - -*- - - - -* 
 * 
 *     num_faces = 2 
 *     for face 0: 
 *        which_ijk = 1; 
 *        min_or_max = 0; 
 *     for face 1: 
 *        which_ijk = 2; 
 *        min_or_max = 0; 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_periodic_ghosts_structured_face_info(int part_number, 
                                               int face, 
                                               int *providing_matrix, 
                                               double m[4][4], 
                                               int *which_ijk, 
                                               int *min_or_max)   
/*--------------------------------------------------------------------

3.4.58. USERD_get_reader_descrip

 *                               <optional>   (Version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *  Gets the description of the reader, so gui can give more info 
 * 
 *  (OUT) reader_descrip       = the description of the reader 
 *                             (max length is MAXFILENP, which 
 *                              is 255) 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_reader_descrip(char descrip[Z_MAXFILENP]) 
/*--------------------------------------------------------------------

3.4.59. USERD_get_reader_release

 *                                <optional>  (Version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Gets the release string for the reader. 
 * 
 *   This release string is a free-format string which is for 
 *   informational purposes only.  It is often useful to increment 
 *   the release number/letter to indicate a change in the reader. 
 *   The given string will simply be output by the EnSight server 
 *   when the reader is selected. 
 * 
 *  (OUT) release_number       = the release number of the reader 
 *                             (max length is Z_MAX_USERD_NAME, which 
 *                              is 20) 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * Called when the reader is selected for use. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_reader_release(char version_number[Z_MAX_USERD_NAME]) 
/*--------------------------------------------------------------------

3.4.60. USERD_get_reader_version

 *                                            (Version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Gets the API version number of the user defined reader 
 * 
 *   The functions that EnSight will call depends on this API 
 *   version.  See the README files for more information. 
 * 
 *  (OUT) version_number       = the version number of the reader 
 *                             (max length is Z_MAX_USERD_NAME, which 
 *                              is 20) 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * Always called. 
 * 
 *  * This needs to be "2.000" or greater. Otherwise EnSight will assume 
 *    this reader is API 1.0 instead of 2.0 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_reader_version(char version_number[Z_MAX_USERD_NAME]) 
/*--------------------------------------------------------------------

3.4.61. USERD_get_sol_times

 *                                            (Version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the solution times associated with each time step for desired timeset. 
 * 
 *  (IN)  timeset_number     = the timeset number  (1 based) 
 * 
 *                             For example: If USERD_get_number_of_timesets 
 *                                          returns 2, the valid 
 *                                          timeset_number's would be 1 and 2. 
 * 
 *  (OUT) solution_times     = 1D array of solution times per time step 
 * 
 *                                  (Array will have been allocated 
 *                                   Num_time_steps[timeset_number] long) 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * These must be non-negative and increasing. 
 * 
 *  SPECIAL NOTE: Normally this routine is called just once through the normal 
 *                pipeline. 
 * 
 *                However, if 1) a USERD_get_max_time_steps routine is 
 *                               implemented, 
 *                        and 2) the USERD_get_max_time_steps routine returns a 
 *                               value greater than 1, 
 *                        and 3) the user hits the GUI button that calls for time 
 *                               to be reloaded. 
 * 
 *                        Then the number of time steps may have increased. (See 
 *                        USERD_get_num_of_time_steps) 
 *                        Thus the solution times returned here must include all 
 *                        current steps. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_sol_times(int timeset_number, 
                    float *solution_times) 
/*--------------------------------------------------------------------

3.4.62. USERD_get_structured_reader_cinching

 *                                            (Version 2.06 and later) 
 *-------------------------------------------------------------------- 
 * 
 *  Gets whether this reader will do structured cinching for block data 
 *  This means that it will handle the min, max, and step values for a 
 *  given block and return the coordinate components or variable components 
 *  in their "cinched" state when partial extraction or striding is used. 
 *  This is as opposed to returning the entire component (ignoring min, max 
 *  and stride) and letting Ensight pick out the values actually used. 
 * 
 *  returns: Z_OK    if the reader will handle the 
 *                   min, max, and stride and return 
 *                   the cinched values only. 
 * 
 *           Z_UNDEF or Z_ERR if will return entire component 
 *                            and rely on EnSight to cinch. 
 * 
 * Notes: 
 *  Unless you can actually pull out the desired min, max, and stride 
 *  without using a full component of memory, don't enable this feature. 
 * 
 * IMPORTANT!!  If your reader will be used for structured auto-distribute, 
 *              you must implement this feature, which includes this routine and 
 *              USERD_set_block_range_and_stride 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_structured_reader_cinching( void ) 
/*--------------------------------------------------------------------

3.4.63. USERD_get_timeset_description

 *                                            (Version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *  Get the description to associate with the desired timeset. 
 * 
 *  (IN)  timeset_number      = the timeset number 
 * 
 *                              For example: If USERD_get_number_of_timesets 
 *                                           returns 2, the valid 
 *                                           timeset_number's would be 1 and 2. 
 * 
 *  (OUT) timeset_description  = timeset description string 
 * 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * A string of NULLs is valid for timeset_description 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_timeset_description(int timeset_number, 
                              char timeset_description[Z_BUFL]) 
/*--------------------------------------------------------------------

3.4.64. USERD_get_uns_failed_params

 *                                            (Version 2.04 and later) 
 *-------------------------------------------------------------------- 
 * 
 * Provides the failure variable and and failure criteria for failed elements 
 * 
 * (OUT) fail_var_name         = Variable name to be used for failure. 
 *                               Must be a per-elem scalar! 
 * 
 * (OUT) threshold_val1        = 1st number for failure comparison 
 *                                Always used in the determination. 
 *                                If threshold_operator1 is Z_ELE_FAILED_EQUAL, 
 *                                then only this threshold value is used. 
 * 
 * (OUT) threshold_val2        = 2nd number for failure comparison 
 *                                 Will be used if threshold_operator1 is not 
 *                                 set to Z_ELE_FAILED_EQUAL and 
 *                                 logic_criteria2 is set to 
 *                                    Z_ELE_FAILED_LOGIC_AND or 
 *                                    Z_ELE_FAILED_LOGIC_OR 
 * 
 * (OUT) threshold_operator1   = 1st threshold operator 
 *                                   Z_ELE_FAILED_GREATER        - greater than 
 *                                   Z_ELE_FAILED_LESS           - less than 
 *                                   Z_ELE_FAILED_EQUAL          - equal 
 *                                   Z_ELE_FAILED_NOT_EQUAL      - not equal 
 *                                Sets the logic for use of threshold_val1 
 * 
 * (OUT) threshold_operator2   = 2nd threshold operator 
 *                                   Z_ELE_FAILED_GREATER        - greater than 
 *                                   Z_ELE_FAILED_LESS           - less than 
 *                                   Z_ELE_FAILED_EQUAL          - equal 
 *                                   Z_ELE_FAILED_NOT_EQUAL      - not equal 
 *                                Used if logic_criteria2 is set to 
 *                                  Z_ELE_FAILED_LOGIC_AND or 
 *                                  Z_ELE_FAILED_LOGIC_OR 
 *                                Sets the loginc for use of threshold_val2 
 * 
 * (OUT) logic_criteria2       = Determines if using second criteria and if it 
 *                               is an and or or condition 
 *                                    Z_ELE_FAILED_LOGIC_NONE 
 *                                    Z_ELE_FAILED_LOGIC_AND 
 *                                    Z_ELE_FAILED_LOGIC_OR 
 * 
 * returns: TRUE  if failed elements should be used 
 *          FALSE if not using failed elements 
 * 
 * 
 * Notes: 
 * 
 *   Example 1: 
 *       If variable "failure" is an element scalar that has values which 
 *       are either 0.0 (for not-failed) or 1.0 (for failed), then: 
 *          fail_var_name       = "failure" 
 *          threshold_val1      = 1.0 
 *          threshold_operator1 = Z_ELE_FAILED_EQUAL 
 *             **rest is ignored** 
 * 
 * 
 * 
 *   Example 2: 
 *       If variable "Stress" is an element scalar, and failure occurs 
 *       when the stress exceeds 3000.0 
 *          fail_var_name       = "Stress" 
 *          threshold_val1      = 3000.0 
 *          threshold_operator1 = Z_ELE_FAILED_GREATER 
 *          logic_criteria2     = Z_ELE_FAILED_LOGIC_NONE 
 * 
 *   Example 3: 
 *       If variable "Stress" is an element scalar, and failure occurs 
 *       when the value is less than -500, or greater than 400 
 *          fail_var_name       = "Stress" 
 *          threshold_val1      = -500.0 
 *          threshold_operator1 = Z_ELE_FAILED_LESS 
 *          threshold_val2      = 400.0 
 *          threshold_operator2 = Z_ELE_FAILED_GREATER 
 *          logic_criteria2     = Z_ELE_FAILED_LOGIC_OR 
 *-------------------------------------------------------------------*/ 
int USERD_get_uns_failed_params(char *fail_var_name, 
                                float *threshold_val1, 
                                float *threshold_val2, 
                                int *threshold_operator1, 
                                int *threshold_operator2, 
                                int *logic_criteria2) 
/*--------------------------------------------------------------------

3.4.65. USERD_get_var_by_component

 *                                            (Version 2.00 and later) 
 *                               (Modified at 2.01 as described below) 
 *-------------------------------------------------------------------- 
 * 
 *  Gets the values of a variable component.  Both unstructured and structured 
 *  parts use this routine. 
 * 
 *  if Z_PER_NODE: 
 *    Get the component value at each node for a given variable in the part. 
 * 
 *  or if Z_PER_ELEM: 
 *    Get the component value at each element of a specific part and type for 
 *    a given variable. 
 * 
 *  (IN)  which_variable          = The variable number (1 to Num_variables) 
 * 
 *  (IN)  which_part                Since EnSight Version 7.4 
 *                                  ------------------------- 
 *                                = The part number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                     1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id that is 
 *                                   loaded in USERD_get_gold_part_build_info) 
 * 
 *                                  Prior to EnSight Version 7.4 
 *                                  ---------------------------- 
 *                                = The part id   This is the part_id label 
 *                                                loaded in 
 *                                               USERD_get_gold_part_build_info. 
 *                                               It is NOT the part table index. 
 * 
 *  (IN)  var_type                = Z_SCALAR 
 *                                  Z_VECTOR 
 *                                  Z_TENSOR     ( symmetric tensor) 
 *                                  Z_TENSOR9    (asymmetric tensor) 
 * 
 *  (IN)  which_type 
 * 
 *           if Z_PER_NODE:         Not used 
 * 
 *           if Z_PER_ELEM:       = The element type 
 *                                  Z_POINT    node point element 
 *                                  Z_BAR02    2 node bar 
 *                                  Z_BAR03    3 node bar 
 *                                  Z_TRI03    3 node triangle 
 *                                  Z_TRI06    6 node triangle 
 *                                  Z_QUA04    4 node quad 
 *                                  Z_QUA08    8 node quad 
 *                                  Z_TET04    4 node tetrahedron 
 *                                  Z_TET10   10 node tetrahedron 
 *                                  Z_PYR05    5 node pyramid 
 *                                  Z_PYR13   13 node pyramid 
 *                                  Z_PEN06    6 node pentahedron 
 *                                  Z_PEN15   15 node pentahedron 
 *                                  Z_HEX08    8 node hexahedron 
 *                                  Z_HEX20   20 node hexahedron 
 * 
 *   Starting at API 2.01: 
 *   ==================== 
 *                                  Z_G_POINT    ghost node point element 
 *                                  Z_G_BAR02    2 node ghost bar 
 *                                  Z_G_BAR03    3 node ghost bar 
 *                                  Z_G_TRI03    3 node ghost triangle 
 *                                  Z_G_TRI06    6 node ghost triangle 
 *                                  Z_G_QUA04    4 node ghost quad 
 *                                  Z_G_QUA08    8 node ghost quad 
 *                                  Z_G_TET04    4 node ghost tetrahedron 
 *                                  Z_G_TET10   10 node ghost tetrahedron 
 *                                  Z_G_PYR05    5 node ghost pyramid 
 *                                  Z_G_PYR13   13 node ghost pyramid 
 *                                  Z_G_PEN06    6 node ghost pentahedron 
 *                                  Z_G_PEN15   15 node ghost pentahedron 
 *                                  Z_G_HEX08    8 node ghost hexahedron 
 *                                  Z_G_HEX20   20 node ghost hexahedron 
 * 
 *  (IN)  imag_data               = TRUE if imag component 
 *                                  FALSE if real component 
 * 
 *  (IN)  component               = The component: (0       if Z_SCALAR) 
 *                                                 (0 - 2   if Z_VECTOR) 
 *                                                 (0 - 5   if Z_TENSOR) 
 *                                                 (0 - 8   if Z_TENSOR9) 
 * 
 *                                * 6 Symmetric Indicies, 0:5    * 
 *                                * ---------------------------- * 
 *                                *     | 11 12 13 |   | 0 3 4 | * 
 *                                *     |          |   |       | * 
 *                                * T = |    22 23 | = |   1 5 | * 
 *                                *     |          |   |       | * 
 *                                *     |       33 |   |     2 | * 
 * 
 *                                * 9 General   Indicies, 0:8    * 
 *                                * ---------------------------- * 
 *                                *     | 11 12 13 |   | 0 1 2 | * 
 *                                *     |          |   |       | * 
 *                                * T = | 21 22 23 | = | 3 4 5 | * 
 *                                *     |          |   |       | * 
 *                                *     | 31 32 33 |   | 6 7 8 | * 
 * 
 * (OUT) var_array 
 * 
 *     ----------------------------------------------------------------------- 
 *     (IMPORTANT: this array is 1-based for both Z_PER_NODE and Z_PER_ELEM!!! 
 *     ----------------------------------------------------------------------- 
 * 
 *          if Z_PER_NODE:       = 1D array containing variable component value 
 *                                  for each node. 
 * 
 *                                 (Array will have been allocated 
 *                                  (number_of_nodes+1) long) 
 * 
 *              Info stored in this fashion: 
 *                   var_array[0] = not used 
 *                   var_array[1] = var component for node 1 of part 
 *                   var_array[2] = var component for node 2 of part 
 *                   var_array[3] = var component for node 3 of part 
 *                   etc. 
 * 
 *           if Z_PER_ELEM:      = 1d array containing variable component value 
 *                                 for each element of particular part & type. 
 * 
 *                            (Array will have been allocated 
 *                             (number_of_elements[which_part][which_type] + 1) 
 *                              long.  See USERD_get_gold_part_build_info) 
 * 
 *              Info stored in this fashion: 
 *                   var_array[1] = var component for elem 1 (of part and type) 
 *                   var_array[2] = var component for elem 2         " 
 *                   var_array[3] = var conponent for elem 3         " 
 *                   etc. 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *       or: Z_UNDEF if this variable is not defined on this part. In which 
 *                   case you need not load anything into the var_array. 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 * 
 *  * Not called unless Num_variables is > 0 
 * 
 *  * The per_node or per_elem classification must be obtainable from the 
 *    variable number (a var_classify array needs to be retained) 
 * 
 *  * If the variable is not defined for this part, simply return with a 
 *    value of Z_UNDEF.  EnSight will treat the variable as undefined for 
 *    this part. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_var_by_component(int which_variable, 
                           int which_part, 
                           int var_type, 
                           int which_type, 
                           int imag_data, 
                           int component, 
                           float *var_array) 
/*--------------------------------------------------------------------

3.4.66. USERD_get_var_by_component_given_coords

/*--------------------------------------------------------------------
USERD_get_var_by_component_given_coords(int which_variable,
                                       int which_part,
                                       int var_type,
                                       int which_type,
                                       int imag_data,
                                       int component,
                                       float **coord_array,  
                                       float *var_array)
* This routine is an optional replacement for 
* USERD_get_var_by_component,
* and will be called only if it is defined and present in the reader.
* 
* If this is present, USERD_get_var_by_component will not be called,
*  and this routine will be called in its place.
*
* The reason you would implement this routine is if you needed the
* coordinate array for the process of generating your variable 
* for example, for a coordinate transformation of a vector variable
* in order to supply the vector variable in cylindrical coordinates.
*
*
*--------------------------------------------------------------------
* (IN) handle               = The USERDHandle pointer
*                             created in USERD_reader_open
*
* Gets the values of a variable component. Both unstructured and structured
* parts use this routine.
*
* if Z_PER_NODE:
*    Get the component value at each node for a given variable in the part.
*
* or if Z_PER_ELEM:
*       Get the component value at each element of a specific part and type for a given variable.
*
* (IN) which_variable       = The variable number (1 to Num_variables)
*
* (IN) which_part             Since EnSight Version 7.4
*                             -------------------------
*                           = The part number
*
*                          (1-based index of part table, namely:
*
*                             1 ... Numparts_available.
*
*                           It is NOT the part_id that is
*                           loaded in USERD_get_gold_part_build_info)
*
*                           Prior to EnSight Version 7.4
*                           ----------------------------
*                         = The part id This is the part_id label
*                                       loaded in
*                                     USERD_get_gold_part_build_info.
*                                     It is NOT the part table index.
*
* (IN) var_type =             Z_SCALAR
*                             Z_VECTOR
*                             Z_TENSOR ( symmetric tensor)
*                             Z_TENSOR9 (asymmetric tensor)
*
* (IN) which_type
*
*         if Z_PER_NODE:      Not used
*
*         if Z_PER_ELEM:    = The element type
*                             Z_POINT node point element
*                             Z_BAR02 2 node bar
*                             Z_BAR03 3 node bar
*                             Z_TRI03 3 node triangle
*                             Z_TRI06 6 node triangle
*                             Z_QUA04 4 node quad
*                             Z_QUA08 8 node quad
*                             Z_TET04 4 node tetrahedron
*                             Z_TET10 10 node tetrahedron
*                             Z_PYR05 5 node pyramid
*                             Z_PYR13 13 node pyramid
*                             Z_PEN06 6 node pentahedron
*                             Z_PEN15 15 node pentahedron
*                             Z_HEX08 8 node hexahedron
*                             Z_HEX20 20 node hexahedron
*
*  Starting at API 2.01:
*  ====================
*                             Z_G_POINT ghost node point element
*                             Z_G_BAR02 2 node ghost bar
*                             Z_G_BAR03 3 node ghost bar
*                             Z_G_TRI03 3 node ghost triangle
*                             Z_G_TRI06 6 node ghost triangle
*                             Z_G_QUA04 4 node ghost quad
*                             Z_G_QUA08 8 node ghost quad
*                             Z_G_TET04 4 node ghost tetrahedron
*                             Z_G_TET10 10 node ghost tetrahedron
*                             Z_G_PYR05 5 node ghost pyramid
*                             Z_G_PYR13 13 node ghost pyramid
*                             Z_G_PEN06 6 node ghost pentahedron
*                             Z_G_PEN15 15 node ghost pentahedron
*                             Z_G_HEX08 8 node ghost hexahedron
*                             Z_G_HEX20 20 node ghost hexahedron
*
* (IN) imag_data             = TRUE if imag component
*                              FALSE if real component
*
* (IN) component             = The component: (0 if Z_SCALAR)
*                                             (0 - 2 if Z_VECTOR)
*                                             (0 - 5 if Z_TENSOR)
*                                             (0 - 8 if Z_TENSOR9)
*
 *                                * 6 Symmetric Indicies, 0:5    * 
 *                                * ---------------------------- * 
 *                                *     | 11 12 13 |   | 0 3 4 | * 
 *                                *     |          |   |       | * 
 *                                * T = |    22 23 | = |   1 5 | * 
 *                                *     |          |   |       | * 
 *                                *     |       33 |   |     2 | * 
 * 
 *                                * 9 General   Indicies, 0:8    * 
 *                                * ---------------------------- * 
 *                                *     | 11 12 13 |   | 0 1 2 | * 
 *                                *     |          |   |       | * 
 *                                * T = | 21 22 23 | = | 3 4 5 | * 
 *                                *     |          |   |       | * 
 *                                *     | 31 32 33 |   | 6 7 8 | * 
*
*
* (IN) float **coord_array,  /*  [xyz, i.e.  0,1,2][node # 1 based ] */
*      2D float array which contains x,y,z coordinates of each node.
*
* (IMPORTANT: the second dimension of of this array is 1-based!!!)
*
* (Array will have been allocated
* 3 by (number_of_nodes + 1) for the part
* long - see USERD_get_gold_part_build_info)
*
* ex) If number_of_nodes = 100
* as obtained in:
* USERD_get_gold_part_build_info
*
* Then the allocated dimensions of the
* pointer sent to this routine will be:
* coord_array[3][101]
*
* Ignore the coord_array[0][0]
*            coord_array[1][0]
*            coord_array[2][0] 
* the node coordinates begin at:
* coord_array[0][1]
* coord_array[1][1]
* coord_array[2][1]
*
* coord_array[0][2]
* coord_array[1][2]
* coord_array[2][2]
*
* etc.*
* (OUT) var_array
*
* -----------------------------------------------------------------------
* (IMPORTANT: this array is 1-based for both Z_PER_NODE and Z_PER_ELEM!!!
* -----------------------------------------------------------------------
*
* if Z_PER_NODE: = 1D array containing variable component value
* for each node.
*
* (Array will have been allocated
* (number_of_nodes+1) long)
*
* Info stored in this fashion:
* var_array[0] = not used
* var_array[1] = var component for node 1 of part
* var_array[2] = var component for node 2 of part
* var_array[3] = var component for node 3 of part
* etc.
*
* if Z_PER_ELEM: = 1d array containing variable component value
* for each element of particular part & type.
*
* (Array will have been allocated
* (number_of_elements[which_part][which_type] + 1)
* long. See USERD_get_gold_part_build_info)
*
* Info stored in this fashion:
* var_array[1] = var component for elem 1 (of part and type)
* var_array[2] = var component for elem 2 "
* var_array[3] = var conponent for elem 3 "
* etc.
*
* returns: Z_OK if successful
* Z_ERR if not successful
*
* or: Z_UNDEF if this variable is not defined on this part. In which
* case you need not load anything into the var_array.
*
* Notes:
* * This will be based on Current_time_step
*
* * Not called unless Num_variables is > 0
*
* * The per_node or per_elem classification must be obtainable from the
* variable number (a var_classify array needs to be retained)
*
* * If the variable is not defined for this part, simply return with a
* value of Z_UNDEF. EnSight will treat the variable as undefined for
* this part.
*--------------------------------------------------------------------*/


3.4.67. USERD_get_var_by_component_in_buffers

 *                                <optional>  (Version 2.08 and later) 
 *-------------------------------------------------------------------- 
 * 
 *  if Z_PER_NODE: 
 *    Get the component value at each node for a given variable in the part 
 *    in buffers. 
 * 
 *  or if Z_PER_ELEM: 
 *    Get the component value at each element of a specific part and type for 
 *    a given variable in buffers. 
 * 
 *   This is one of several optional routines than can be added into any 
 *   API 2.* reader to be used by the Unstructured Auto Distribute 
 *   capability in EnSight 8.2 and later. 
 * 
 *   Unstructured Auto Distribute is a capability requiring Server of Servers 
 *   (SOS) that will partition an unstructured model for you automatically 
 *   across a set of servers. 
 * 
 *   If you do not implement this routine (and the other in_buffers routines) 
 *   in your reader, EnSight can still perform this operation but will require 
 *   much more memory on each server to read in the data (somewhat like each 
 *   server having to read the whole model). You will however, get the execution 
 *   advantage of having your model partitioned across multiple servers. 
 * 
 *   If you do implement this routine (and the other in_buffers routines) in 
 *   your reader (in a proper manner), you should be able to not only get the 
 *   execution advantages, but also memory usage on each server which is 
 *   proportional to the subset that it is assigned to deal with.  
 * 
 *   Note that this optional routine is functionally quite similar 
 *   to the USERD_get_var_by_component routine. And thus its implementation 
 *   should not be too difficult to add to any existing reader that has already 
 *   implemented the USERD_get_var_by_component routine. 
 * 
 *  (IN)  which_variable          = The variable number (1 to Num_variables) 
 * 
 *  (IN)  which_part                Since EnSight Version 7.4 
 *                                  ------------------------- 
 *                                = The part number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                     1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id that is  
 *                                   loaded in USERD_get_gold_part_build_info) 
 * 
 *                                  Prior to EnSight Version 7.4 
 *                                  ---------------------------- 
 *                                = The part id   This is the part_id label 
 *                                                loaded in 
 *                                              USERD_get_gold_part_build_inf\o. 
 *                                              It is NOT the part table index. 
 * 
 *  (IN)  var_type                = Z_SCALAR 
 *                                  Z_VECTOR 
 *                                  Z_TENSOR     ( symmetric tensor) 
 *                                  Z_TENSOR9    (asymmetric tensor) 
 * 
 *  (IN)  which_type 
 * 
 *           if Z_PER_NODE:         Not used 
 * 
 *           if Z_PER_ELEM:       = The element type 
 *                                  Z_POINT    node point element 
 *                                  Z_BAR02    2 node bar 
 *                                  Z_BAR03    3 node bar 
 *                                  Z_TRI03    3 node triangle 
 *                                  Z_TRI06    6 node triangle 
 *                                  Z_QUA04    4 node quad 
 *                                  Z_QUA08    8 node quad 
 *                                  Z_TET04    4 node tetrahedron 
 *                                  Z_TET10   10 node tetrahedron 
 *                                  Z_PYR05    5 node pyramid 
 *                                  Z_PYR13   13 node pyramid 
 *                                  Z_PEN06    6 node pentahedron 
 *                                  Z_PEN15   15 node pentahedron 
 *                                  Z_HEX08    8 node hexahedron 
 *                                  Z_HEX20   20 node hexahedron 
 * 
 *                                  Z_G_POINT    ghost node point element 
 *                                  Z_G_BAR02    2 node ghost bar 
 *                                  Z_G_BAR03    3 node ghost bar 
 *                                  Z_G_TRI03    3 node ghost triangle 
 *                                  Z_G_TRI06    6 node ghost triangle 
 *                                  Z_G_QUA04    4 node ghost quad 
 *                                  Z_G_QUA08    8 node ghost quad 
 *                                  Z_G_TET04    4 node ghost tetrahedron 
 *                                  Z_G_TET10   10 node ghost tetrahedron 
 *                                  Z_G_PYR05    5 node ghost pyramid 
 *                                  Z_G_PYR13   13 node ghost pyramid 
 *                                  Z_G_PEN06    6 node ghost pentahedron 
 *                                  Z_G_PEN15   15 node ghost pentahedron 
 *                                  Z_G_HEX08    8 node ghost hexahedron 
 *                                  Z_G_HEX20   20 node ghost hexahedron 
 * 
 *                                  Z_NSIDED     n node nsided polygon 
 *                                  Z_NFACED     n face nfaced polyhedron 
 *                                  Z_G_NSIDED   n node ghost nsided polygon 
 *                                  Z_G_NFACED   n face ghost nfaced polyhedron 
 * 
 * 
 * 
 *  (IN)  imag_data               = TRUE if imag component 
 *                                  FALSE if real component 
 * 
 * 
 *  (IN)  component               = The component: (0       if Z_SCALAR) 
 *                                                 (0 - 2   if Z_VECTOR) 
 *                                                 (0 - 5   if Z_TENSOR) 
 *                                                 (0 - 8   if Z_TENSOR9) 
 * 
 * 
 * 
 *                                * 6 Symmetric Indicies, 0:5    * 
 *                                * ---------------------------- * 
 *                                *     | 11 12 13 |   | 0 3 4 | * 
 *                                *     |          |   |       | * 
 *                                * T = |    22 23 | = |   1 5 | * 
 *                                *     |          |   |       | * 
 *                                *     |       33 |   |     2 | * 
 * 
 *                                * 9 General   Indicies, 0:8    * 
 *                                * ---------------------------- * 
 *                                *     | 11 12 13 |   | 0 1 2 | * 
 *                                *     |          |   |       | * 
 *                                * T = | 21 22 23 | = | 3 4 5 | * 
 *                                *     |          |   |       | * 
 *                                *     | 31 32 33 |   | 6 7 8 | * 
 * 
 *  (IN) ne_beg 
 *          if Z_PER_NODE:  = Zero based, 1st node index of the buffered set 
 *          if Z_PER_ELEM:  = Zero based, 1st element index of the buffered set 
 * 
 *  (IN) ne_end 
 *          if Z_PER_NODE:  = Zero based, last node index of the buffered set 
 *          if Z_PER_ELEM:  = Zero based, last element index of the buffered set 
 * 
 *                     Thus, for first five elements or nodes: 
 *                       e_beg = 0 
 *                       e_end = 4 
 *                       total_number = (e_end - e_beg) + 1 = (4 - 0) + 1 = 5 
 * 
 *                     for second five elements or nodes, would be: 
 *                       e_beg = 5 
 *                       e_end = 9 
 *                       total_number = (e_end - e_beg) + 1 = (9 - 5) + 1 = 5 
 * 
 *                     for all elements or nodes of a part, would be: 
 *                       n_beg = 0 
 *                       n_end = num_elements_or_nodes - 1 
 * 
 * (IN) first                    = TRUE if first invocation of a buffered set. 
 *                                  Will be FALSE for all subsequent invocations 
 *                                  of the set.  This is so you can open files, 
 *                                  get to the correct starting spot, 
 *                                  initialize, etc. 
 * 
 * (IN) buffer_size              = The size of the buffer. 
 *                                  Namely:  var_array[buffer_size] 
 * 
 * (IN) leftside                 = TRUE if current time is at a timestep or 
 *                                      when getting the left side of a time 
 *                                      span that encloses the current time. 
 *                               = FALSE when getting the right side of a time 
 *                                       span that encloses the current time. 
 * 
 *  Timeline: 
 *   step1         step2          step3 
 *     |-------------|--------------|-------...  requires no interpolation 
 *                   ^                           get values at step2 
 *                   current time                   (leftside = TRUE) 
 * 
 * 
 * 
 *  Timeline: 
 *   step1         step2          step3 
 *     |-------------|--------------|-------...  requires interpolation 
 *              ^                        get values at step1 (leftside = TRUE) 
 *              current time         and get values at step2 (leftside = FALSE) 
 * 
 * 
 *  Note that it would generally be easier for this routine if EnSight got all 
 *       of the left side, then all of the right side, and then did its 
 *       interpolation. But, in the spirit of doing things in buffers (to save 
 *       memory) it gets a left side buffer (and the corresponding right side 
 *       buffer and interpolates these), if needed, before going to the next 
 *       buffer of the set.  Thus, you need to be able to handle that 
 *       situation. 
 * 
 *  Note also that EnSight will have called the routine to change the current 
 *       time step between the two invocations when interpolation is required. 
 *       And Ensight does the interpolating.  This variable is provided so 
 *       that you can deal with two different files or pointers between the 
 *       corresponding invocations for the two times 
 * 
 * (OUT) var_array 
 * 
 *     ----------------------------------------------------------------------- 
 *     (IMPORTANT: this array is 0-based for both Z_PER_NODE and Z_PER_ELEM!!! 
 *     ----------------------------------------------------------------------- 
 * 
 *          if Z_PER_NODE:       = 1D buffer array set up to hold a variable 
 *                                 component value for nodes. 
 * 
 *          if Z_PER_ELEM:       = 1D buffer array set up to hold a variable 
 *                                 component value for elements. 
 * 
 *                                 (Array will have been allocated 
 *                                  buffer_size long) 
 * 
 *              Info stored in this fashion: 
 *                   var_array[0] = var component for node or element 1 of part 
 *                   var_array[1] = var component for node or element 2 of part 
 *                   var_array[2] = var component for node or element 3 of part 
 *                   etc. 
 * 
 * 
 *   * Example, (if 158 quad elements with a real Z_PER_ELEM scalar, 
 *               current time is between steps, and buffer size is 75) 
 * 
 *        first invocation:            (for left side of time span) 
 *          var_type = Z_SCALAR 
 *          which_type = Z_PER_ELEM 
 *          imag_data = FALSE 
 *          component = 0 
 *          ne_beg = 0 
 *          ne_end = 157 
 *          first = TRUE               Will be TRUE the first time! 
 *          buffer_size = 75 
 *          leftside = TRUE            <== 
 *          var_array[75]              load in scalar value for elements 1 - 75 
 *          *num_returned = 75         set this 
 *          return(0)                  return this (indicates more to do) 
 * 
 * 
 *        second invocation:           (for right side of time span) 
 *          var_type = Z_SCALAR 
 *          which_type = Z_PER_ELEM 
 *          imag_data = FALSE 
 *          component = 0 
 *          ne_beg = 0 
 *          ne_end = 157 
 *          first = TRUE               Note: Will still be TRUE (because is 
 *                                                               right side) 
 *          buffer_size = 75 
 *          leftside = FALSE           <== 
 *          var_array[75]              load in scalar value for elements 1 - 75 
 *          *num_returned = 75         set this 
 *          return(0)                  return this (indicates more to do) 
 * 
 * ------------------------------- 
 *        third invocation:            (for left side of time span) 
 *          var_type = Z_SCALAR 
 *          which_type = Z_PER_ELEM 
 *          imag_data = FALSE 
 *          component = 0 
 *          ne_beg = 0 
 *          ne_end = 157 
 *          first = FALSE              Will be FALSE now 
 *          buffer_size = 75 
 *          leftside = TRUE            <== 
 *          var_array[75]              load in scalar value for 
 *                                             elements 76 - 150 
 *          *num_returned = 75         set this 
 *          return(0)                  return this (indicates more to do) 
 * 
 *        fourth invocation:           (for right side of time span) 
 *          var_type = Z_SCALAR 
 *          which_type = Z_PER_ELEM 
 *          imag_data = FALSE 
 *          component = 0 
 *          ne_beg = 0 
 *          ne_end = 157 
 *          first = FALSE              
 *          buffer_size = 75 
 *          leftside = FALSE           <== 
 *          var_array[75]              load in scalar value for 
 *                                             elements 76 - 150 
 *          *num_returned = 75         set this 
 *          return(0)                  return this (indicates more to do) 
 * 
 *------------------------------------ 
 *        fifth invocation:            (for left side of time span) 
 *          var_type = Z_SCALAR 
 *          which_type = Z_PER_ELEM 
 *          imag_data = FALSE 
 *          component = 0 
 *          ne_beg = 0 
 *          ne_end = 157 
 *          first = FALSE              Will still be FALSE 
 *          buffer_size = 75 
 *          leftside = TRUE            <== 
 *          var_array[75]              load in scalar value 
 *                                             for elements 151 - 158 
 *          *num_returned = 8          set this 
 *          return(1)                  return this (indicates no more to do) 
 * 
 *        sixth invocation:           (for right side of time span) 
 *          var_type = Z_SCALAR 
 *          which_type = Z_PER_ELEM 
 *          imag_data = FALSE 
 *          component = 0 
 *          ne_beg = 0 
 *          ne_end = 157 
 *          first = FALSE             
 *          buffer_size = 75 
 *          leftside = FALSE           <== 
 *          var_array[75]              load in scalar value 
 *                                             for elements 151 - 158 
 *          *num_returned = 8          set this 
 *          return(1)                  return this (indicates no more to do) 
 * 
 * 
 *  (OUT)  *num_returned       = The number of nodes or elements whose variable 
 *                               values are returned in the buffer. This will 
 *                               normally be equal to buffer_size except for 
 *                               that last buffer - which could be less than 
 *                               a full buffer 
 * 
 * returns  0  if got some, more to do 
 *          1  if got some, done 
 *         -1  if an error 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 * 
 *  * Again, make sure each buffer is zero based. 
 *    For our example using buffers above: 
 * 
 *                                        Invocation: 
 *               ----------------   ------------------   -------------------  
 *                  1        2         3          4          5          6 
 *               -------  -------   --------  --------   ---------  --------- 
 * var_array[0]  quad 1L  quad 1R   quad 76L  quad 76R   quad 151L  quad 151R 
 * 
 * var_array[1]  quad 2L  quad 2R   quad 77L  quad 77R   quad 152L  quad 152R 
 * 
 * ... 
 * 
 * var_array[74] quad 75L quad 75R  quad 150L quad 150R  quad 158L  quad 158R 
 * 
 *   Where:   L indicates left time step 
 *            R indicates right time step 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_var_by_component_in_buffers(int which_variable, 
                                      int which_part, 
                                      int var_type, 
                                      int which_type, 
                                      int imag_data, 
                                      int component, 
                                      float *var_array, 
                                      int first, 
                                      int ne_beg, 
                                      int ne_end, 
                                      int buffer_size, 
                                      int leftside, 
                                      int *num_returned)   
/*--------------------------------------------------------------------

3.4.68. USERD_get_constant_per_part_data

 *                                    This routine will be called for each of  
 *                                    variables whose part type is  
 *                                    Z_CONSTANT_PER_PART as defined in 
 *                                    USERD_get_gold_variable_info 
 * 
 *                                    This returns the desired constant per part 
 *                                    variable values, for the time step desired, 
 *                                    for the parts that have this variable type. 
 *-------------------------------------------------------------------- 
 *  (IN)  v         = The variable number 
 *  (IN)  imag_data = TRUE if want imaginary portion.  (not currently using) 
 *                    FALSE if want real portion 
 *  (IN) itstep     = Time step 
 *  (OUT) extparts  = Array to receive the external part numbers that have 
 *                    a value for this per_part constant. 
 *                    This is the part number used in the file (or the part label) 
 *                    The array is zero-based and will be Numparts_available long,
 *                    so all original parts will fit. It is initialized to an  
 *                    impossible part number (-1) for every entry in the array. 
 *                    You do not have to have values for all parts. 
 *  (OUT) values    = Array to receive the per_part constant value for the parts 
 *                    loaded in extparts. 
 *                    The array is zero-based and will be Numparts_available long. 
 *                    Each array entry is initialized to Z_UNDEF. 
 *  Notes: 
 *     Example:  Model with 5 parts 
 *               At the input itstep: 
 *                 part 1  has no value (is undefined for this part) 
 *                 part 4  has a value of 13.45 
 *                 part 5  has a value of 102.50 
 *                 part 23 had no value 
 *                 part 24 had a value of -4.75 
 *               Thus, 
 *                 extparts[0] = 4 
 *                 extparts[1] = 5 
 *                 extparts[2] = 24 
 *                 Note: extpats[3] and extpats[4] are their init values, -1 
 * 
 *                 values[0]   = 13.45 
 *                 values[1]   = 102.50 
 *                 values[2]   = -4.75 
 *                 Note: values[3] and values[4] are their init values of Z_UNDEF 
 * 
 *               Since there are two of the original parts (part 1 and part 23) 
 *               that do not have a defined value for this constant per part, 
 *               you should  leave their values to the init values in extparts 
 *               & values. So, extparts[3-4] & values[3-4] are -1 and Z_UNDEF, 
 *               respectively for proper interpretation by EnSight.  
 *     IMPORTANT: The constant per part variables are not treated like case 
 *                constant variables, but rather similar to scalars, vectors, 
 *                tensor variables so you must set their classification 
 *                and type in the USERD_get_gold_variable_info
 routine. 
 *                      var_type[ ] = Z_CONSTANT_PER_PART 
 *                      var_classify[ ] = Z_PER_PART 
 *  
 * The return is either Z_OK or Z_ERR.  
 * 
 * If all the per-part constants are undefined at the given timestep, simply  
 *  return Z_OK without setting anything in extparts nor values. 
 *--------------------------------------------------------------------------*/ 
int 
USERD_get_constant_per_part_data(int v, 
                                 int imag_data, 
                                 int itstep, 
                                 int *extparts, 
                                 float *values) {  
/*--------------------------------------------------------------------------

3.4.69. USERD_get_var_extract_gui_defaults

 *                                       <optional> (version 2.05 and later) 
 *-------------------------------------------------------------------------- 
 * 
 *  This routine defines the Titles, status, List choices, strings, etc that 
 *  are fed up to the GUI for that after read situation.  (It is very similar 
 *  to the USERD_get_extra_gui_defaults routine, which occurs before the read) 
 * 
 *   (OUT) toggle_Title               = title for each toggle 
 *                                      array dimension is 
 *                                 [num_toggles] by [Z_LEN_GUI_TITLE_STR] long 
 * 
 *   (OUT) toggle_default_status      = Setting for each toggle (TRUE or FALSE) 
 *                                      array dimension is [num_toggles] long 
 * 
 *   (OUT) pulldown_Title             = title for each pulldown 
 *                                      array dimension is 
 *                                 [num_pulldowns] by [Z_LEN_GUI_TITLE_STR] long 
 * 
 *   (OUT) pulldown_number_in_list    = number of items in each pulldown 
 *                                      array dimension is [num_pulldowns] long 
 * 
 *   (OUT) pulldown_default_selection = item selection for each pulldown 
 *                                      array dimension is [num_pulldowns] long 
 * 
 *   (OUT) pulldown_item_strings      = pulldown item strings 
 *                                      array is [num_pulldowns] by 
 *                                             [Z_MAX_NUM_GUI_PULL_ITEMS] by 
 *                                             [Z_LEN_GUI_PULL_STR] long 
 * 
 *   (OUT) field_Title                = title for each field 
 *                                      array dimension is 
 *                                 [num_fields] by [Z_LEN_GUI_TITLE_STR] long 
 * 
 *   (OUT) field_user_string          = content of the field 
 *                                      array dimension is 
 *                                 [num_fields] by [Z_LEN_GUI_TITLE_STR] long 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * The library is loaded, this routine is called, 
 *    then the library is unloaded. 
 * 
 *  * Do not define globals in this routine as when the library is unloaded, 
 *    you'll lose them. 
 * ----------------------------------------------- */ 
int USERD_get_var_extract_gui_defaults(char **toggle_Title, 
                                       int *toggle_default_status, 
                                       char **pulldown_Title, 
                                       int *pulldown_number_in_list, 
                                       int *pulldown_default_selection, 
                                       char ***pulldown_item_strings, 
                                       char **field_Title, 
                                       char **field_user_string) 
/*--------------------------------------------------------------------

3.4.70. USERD_get_var_extract_gui_numbers

 *                                 <optional> (version 2.05 and later) 
 * ------------------------------------------------------------------- 
 *   The Var_Extract GUI routines are added to allow the user to customize a 
 *   extraction parameters for variable "after" the file has been read. 
 *   These things can be modified and the variables will be updated/refreshed 
 *   according to the new parameters. 
 *   (It is similar to the USERD_get_extra_gui_numbers routine)  
 * 
 *   This routine defines the numbers of toggles, pulldowns & fields 
 * 
 *   (OUT) num_Toggles    = number of toggles that will be provided 
 * 
 *   (OUT) num_pulldowns  = number of pulldowns that will be provided 
 * 
 *   (OUT) num_fields     = number of fields that will be provided 
 * 
 *   Notes: 
 *   * There are three routines that work together: 
 *         USERD_get_var_extract_gui_numbers 
 *         USERD_get_var_extract_gui_defaults 
 *         USERD_set_var_extract_gui_data 
 * 
 *     The existence of these routine indicates that 
 *     you wish to have the Var Extract capability. 
 * 
 *     If you don't want the Var Extract GUI features, 
 *     simply delete these routines, or change their 
 *     names to something such as 
 *     USERD_DISABLED_get_var_extract_gui_defaults 
 * 
 *     The presence of these routines 
 *     will ensure that EnSight will call them and 
 *     use their data to modify the extraction parameters 
 *     with some or all of the following: 
 *     toggles, pulldown menu and fields. 
 * 
 *     The user can then interact with the var extract portion of the 
 *     GUI and then send their choices to 
 *     USERD_set_var_extract_gui_data 
 * 
 *     Therefore if USERD_get_var_extract_gui_numbers 
 *     exists then the other two must exist. 
 * 
 *     If none exist, then the GUI will be unchanged. 
 * 
 *     Toggle data will return an integer 
 *                               TRUE if checked 
 *                               FALSE if unchecked 
 * 
 *     Pulldown menu will return an integer representing 
 *                               the menu item selected 
 * 
 *     Field will return a string Z_LEN_GUI_FIELD_STR long. 
 * 
 * * The following are defined in the global_extern.h 
 *          Z_MAX_NUM_GUI_PULL_ITEMS max num GUI pulldowns 
 *          Z_LEN_GUI_PULL_STR  max length of GUI pulldown string 
 *          Z_LEN_GUI_FIELD_STR  max length of field string 
 *          Z_LEN_GUI_TITLE_STR   max length of title string 
 * 
 * * The library is loaded, this routine is called, 
 *   then the library is unloaded. 
 * 
 * *  Do not define globals in this routine as when the library is unloaded, 
 *    you'll lose them. 
 *-------------------------------------------------------------------------------*/ 
void USERD_get_var_extract_gui_numbers(int *num_Toggles, 
                                       int *num_pulldowns, 
                                       int *num_fields) 
/*--------------------------------------------------------------------

3.4.71. USERD_get_var_value_at_specific

 *                                            (Version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *  if Z_PER_NODE: 
 *    Get the value of a particular variable at a particular node in a 
 *    particular part at a particular time. 
 * 
 *  or if Z_PER_ELEM: 
 *    Get the value of a particular variable at a particular element of 
 *    a particular type in a particular part at a particular time. 
 * 
 *  (IN)  which_var   = Which variable (1 to Num_variables) 
 * 
 *  (IN)  which_node_or_elem 
 * 
 *                     If Z_PER_NODE: 
 *                       = The node number.  This is not the id, but is 
 *                                           the index of the node 
 *                                           list (1 based), or the block's 
 *                                           node list (1 based). 
 * 
 *                           Thus,  coord_array[1] 
 *                                  coord_array[2] 
 *                                  coord_array[3] 
 *                                       .      | 
 *                                       .      |which_node_or_elem index 
 *                                       .             ---- 
 * 
 * 
 *                     If Z_PER_ELEM: 
 *                       = The element number. This is not the id, but is 
 *                                             the element number index 
 *                                             of the number_of_element array 
 *                                        (see USERD_get_gold_part_build_info), 
 *                                             or the block's element list 
 *                                             (1 based). 
 * 
 *                           Thus,  for which_part: 
 *                                  conn_array[which_elem_type][0] 
 *                                  conn_array[which_elem_type][1] 
 *                                  conn_array[which_elem_type][2] 
 *                                       .                      | 
 *                                       .          (which_node_or_elem - 1) index 
 *                                       .                         ---- 
 * 
 * 
 * 
 *  (IN)  which_part                Since EnSight Version 7.4 
 *                                  ------------------------- 
 *                                = The part number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                     1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id that 
 *                                   is loaded in USERD_get_gold_part_build_info) 
 * 
 * 
 *                                  Prior to EnSight Version 7.4 
 *                                  ---------------------------- 
 *                                = The part id   This is the part_id label 
 *                                                loaded in 
 *                                             USERD_get_gold_part_build_info. 
 *                                             It is NOT the part table index. 
 * 
 *  (IN)  which_elem_type 
 * 
 *                       If Z_PER_NODE, or block part: 
 *                         = Not used 
 * 
 *                       If Z_PER_ELEM: 
 *                         = The element type.  This is the element type index 
 *                                              of the number_of_element array 
 *                                         (see USERD_get_gold_part_build_info) 
 * 
 *  (IN)  time_step   = Time step to use  (0 to Num_time_steps[the proper var timeset]) 
 * 
 *  (IN)  imag_data   = TRUE if want imaginary data file. 
 *                      FALSE if want real data file. 
 * 
 *  (OUT) values      = scalar or vector component value(s) 
 *                       values[0] = scalar or vector[0] 
 *                       values[1] = vector[1] 
 *                       values[2] = vector[2] 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 *           Z_NOT_IMPLEMENTED if not implemented and want to use the slower, 
 *                             complete update method within EnSight. 
 * 
 *  Notes: 
 *  * This routine is used in node querys over time (or element querys over 
 *    time for Z_PER_ELEM variables).  If these operations are not critical 
 *    to you, this can be a sample routine. 
 * 
 *  * The per_node or per_elem classification must be obtainable from the 
 *    variable number (a var_classify array needs to be retained) 
 * 
 *  * The time step given is for the proper variable timeset. Thus, it 
 *    must be obtainable from the variable number also. 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_var_value_at_specific(int which_var, 
                                int which_node_or_elem, 
                                int which_part, 
                                int which_elem_type, 
                                int time_step, 
                                float values[3], 
                                int imag_data) 
/*-----------------------------------------------------------------------------

3.4.72. USERD_get_var_value_at_xyz_specific

 *                                         <optional>  (Version 2.09 and later) 
 /*-------------------------------------------------------------------- 
* USERD_get_var_value_at_xyz_specific - 
*-------------------------------------------------------------------- 
* 
*  (IN)  which_var   = Which variable 
* 
*  (IN)  xyz[3]      = the xyz coordinates of the desired point. 
* 
*  (IN)  which_part                Since EnSight Version 7.4 
* ------------------------- 
*                                = The part number 
* 
*                                  (1-based index of part table, namely: 
* 
*                                     1 ... Numparts_available. 
* 
*                                   It is NOT the part_id that 
*                                   is loaded in USERD_get_gold_part_build_info) 
* 
*                                  Prior to EnSight Version 7.4 
* ---------------------------- 
*                                = The part id   This is the part_id label loaded 
*                                                in USERD_get_gold_part_build_info. 
*                                                It is NOT the part table index. 
* 
*  (IN)  time_step   = Time step to use 
* 
* 
*  (OUT) values      = scalar or vector component value(s) 
*                       values[0] = scalar or vector[0] 
*                       values[1] = vector[1] 
*                       values[2] = vector[2] 
*
*
*  (IN)  imag_data   = TRUE if want imaginary data file. 
*                      FALSE if want real data file. 
* 
*  returns: Z_OK  if xyz found in part provided. 
*           Z_UNDEF if not found in part provided 
*           Z_ERR if something terribly wrong 
* 
* Notes: 
*  * This routine is optional (if not provided, EnSight will do searches in 
*    each time step (which can be slow because it will have to update all 
*    results at each time step). 
* 
*  * This routine is used in xyz querys over time. 
*    So if you can provide this info efficiently, please do so. 
* 
*  * The time step given is for the proper variable timeset. Thus, it 
*    must be obtainable from the variable number also. 
*--------------------------------------------------------------------*/ 
int 
USERD_get_var_value_at_xyz_specific(int which_var, 
                                   float xyz[3], 
                                   int which_part, 
                                   int time_step, 
                                   float values[3], 
                                   int imag_data)  
/*-----------------------------------------------------------------------------

3.4.73. USERD_get_vglyph_counts

 *                                         <optional>  (Version 2.09 and later) 
 *----------------------------------------------------------------------------- 
 * 
 *  Gets the counts for the number of vector glyphs in the model 
 * 
 *  (OUT) num_vglyph_vectors   = The number of vector glyphs in the model. 
 *                               (Must be set to zero if none) 
 * 
 *  (OUT) num_vglyph_timelines = The number of vector glyph timelines 
 *                               in the model. (can be zero if all vector 
 *                               glyphs are static) 
 * 
 *  returns: Z_OK    if no problems 
 *           Z_ERR   if an error 
 * 
 *  Notes: 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_vglyph_counts(int *num_vglyph_vectors, 
                        int *num_vglyph_timelines) 
/*-----------------------------------------------------------------------------

3.4.74. USERD_get_vglyph_timeline_info

 *                                         <optional>  (Version 2.09 and later) 
 *----------------------------------------------------------------------------- 
 * 
 *  Gets the vector glyph timeline metadata. 
 * 
 *  (IN)  vtl        = The vector glyph timeline index 
 *                        0 ... (Num_VGLYPH_Timelines-1) 
 * 
 *  (OUT) id         = The vector glyph timeline id listed in the file 
 * 
 *  (OUT) numtimes   = The number of times in the vector glyph timeline 
 * 
 *  (OUT) before     = If EnSight time is before the first step in the 
 *                     vector glyph timeline, a value of 
 *                        VG_UNDEF  makes the glyph undefined 
 *                        VG_NEAREST makes it act as if it is at the first step 
 * 
 *  (OUT) amidst     = If EnSight time is between steps in the vector glyph 
 *                     timeline, VG_INTERPOLATE interpolates values linearly 
 *                     between them  VG_NEAREST snaps to the closest step 
 *                     for its values. 
 * 
 *  (OUT) after      = If EnSight time is after the last step in the 
 *                     vector glyph timeline, a value of 
 *                        VG_UNDEF  makes the glyph undefined 
 *                        VG_NEAREST makes it act as if it is at the last step 
 * 
 *  returns: Z_OK    if no problems 
 *           Z_ERR   if an error 
 * 
 *  Notes: 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_vglyph_timeline_info(int vtl, 
                               int *id, 
                               int *numtimes, 
                               int *before, 
                               int *amidst, 
                               int *after) 
/*-----------------------------------------------------------------------------

3.4.75. USERD_get_vglyph_timeline_times

 *                                         <optional>  (Version 2.09 and later) 
 *----------------------------------------------------------------------------- 
 * 
 *  Gets the vector glyph timeline times 
 * 
 *  (IN)  vtl        = The vector glyph timeline index 
 *                        0 ... (Num_VGLYPH_Timelines-1) 
 * 
 *  (OUT) times      = The array of times in the vector glyph timeline 
 * 
 *  returns: Z_OK    if no problems 
 *           Z_ERR   if an error 
 * 
 *  Notes: 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_vglyph_timeline_times(int vtl, 
                                float *times) 
/*-----------------------------------------------------------------------------

3.4.76. USERD_get_vglyph_vector_info

* <optional> (Version 2.09 and later)
*-----------------------------------------------------------------------------/*-----------------------------------------------------------------------------
*
*   Gets the vector glyph metadata
*
* 
* (IN) vg                             = The vector glyph index
*                                       0 ... (Num_VGLYPH_Vectors-1)
*
* (OUT) id                            = The vector glyph id number listed in the file
*
* (OUT) description                   = The vector glyph description.
*                                     *** Note: This is what a user will see in
*                                               the GUI to select the glyph
*
* (OUT) type                          = VG_FORCE or VG_MOMENT
*
* (OUT) time_condition                = VG_STATIC if vector glyph is always present,
*                                                 no timeline assiciated with it.
*                                       VG_TRANSIENT if vector glyph is associated 
*                                                    with a timeline
*
* (OUT) time_line                     = The external timeline index of the vector glyph,
*                                         used on if time_condition is VG_TRANSIENT
*
* (OUT) part                          = The part that the vector glyph is associated with
*
* (OUT) nidloc                        = The node id number where the vector glyph is located.
*                                        (must be -1 if not located at a node)
*
* (OUT) eidloc                        = The element id number where the vector glyph is
*                                       located. (must be -1 if not located at an element)
*
*
* returns: Z_OK if no problems
*          Z_ERR if an error
*
* Notes:
*     For vector glyphs located at an xyz location, make sure both nidloc and
*     eidloc are both set to -1
*--------------------------------------------------------------------*/
int
USERD_get_vglyph_vector_info(int vg,
                             int *id,
                             char *description,
                             int *type,
                             int *time_condition,
                             int *time_line,
                             int *part,
                             int *nidloc,
                             int *eidloc)

3.4.77. USERD_get_vglyph_vector_values

 *                                         <optional>  (Version 2.09 and later) 
 *----------------------------------------------------------------------------- 
 * 
 *  Gets the vector glyph vector component values 
 * 
 *  (IN)  vg         = The vector glyph index 
 *                      0 ... (Num_VGLYPH_Vectors-1) 
 * 
 *  (OUT) values     = The vector glyph component vector values 
 *                     (2D array, with 3 values per timestep) 
 * 
 *                     for VG_STATIC vector glyph, would be 1 x 3 array 
 *                       [xc, yc, zc] 
 * 
 *                     for VG_TRANSIENT vector glyph, with a timeline 
 *                       that has 5 time steps, would be 5 x 3 array 
 *                       [xc1, yc1, zc1] 
 *                       [xc2, yc2, zc2] 
 *                       [xc3, yc3, zc3] 
 *                       [xc4, yc4, zc4] 
 *                       [xc5, yc5, zc5] 
 *                              
 *  returns: Z_OK    if no problems 
 *           Z_ERR   if an error 
 * 
 *  Notes: 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_vglyph_vector_values(int vg, 
                               float **values) 
/*-----------------------------------------------------------------------------

3.4.78. USERD_get_vglyph_vector_xyzloc

 *                                         <optional>  (Version 2.09 and later) 
 *----------------------------------------------------------------------------- 
 * 
 *  Gets the vector glyph xyz locations 
 * 
 *  (IN)  vg         = The vector glyph index 
 *                      0 ... (Num_VGLYPH_Vectors-1) 
 * 
 *  (OUT) xyzloc     = The vector glyph xyz location(s) 
 *                     (2D array, with 3 values per timestep) 
 * 
 *                     for VG_STATIC vector glyph, would be 1 x 3 array 
 *                       [x, y, z] 
 * 
 *                     for VG_TRANSIENT vector glyph, with a timeline 
 *                       that has 5 time steps, would be 5 x 3 array 
 *                       [x1, y1, z1] 
 *                       [x2, y2, z2] 
 *                       [x3, y3, z3] 
 *                       [x4, y4, z4] 
 *                       [x5, y5, z5] 
 * 
 *  returns: Z_OK    if no problems 
 *           Z_ERR   if an error 
 * 
 *  Notes: 
 *--------------------------------------------------------------------*/ 
int 
USERD_get_vglyph_vector_xyzloc(int vg, 
                               float **xyzloc) 
/*-----------------------------------------------------------------------------

3.4.79. USERD_get_xy_query_data

 *                                         <optional>  (Version 2.08 and later) 
 *----------------------------------------------------------------------------- 
 * 
 * Gets the xy values for a particular xy_query 
 * 
 * (IN)  query_num            = query number (zero based) 
 *                              (0 to one less than the number of querys 
 *                               returned in USERD_get_num_xy_queries) 
 * 
 * (IN)  num_vals             = number of xy pairs in the query 
 * 
 * (OUT) xvals                = array of x values, dimensioned to num_vals 
 *                              (0 based) 
 * 
 * (OUT) yvals                = array of y values, dimensioned to num_vals 
 *                              (0 based) 
 * 
 * returns: Z_OK  if successful 
 *          Z_ERR if a problem 
 * 
 * Notes: 
 *----------------------------------------------------------------------------*/ 
int USERD_get_xy_query_data( 
        int query_num, 
        int num_vals, 
        float *xvals, 
        float *yvals) 
/*----------------------------------------------------------------------------

3.4.80. USERD_get_xy_query_info

 *                                        <optional>  (Version 2.08 and later) 
 *---------------------------------------------------------------------------- 
 * 
 * Gets name, axis titles, and number of xy pairs for a particular xy_query 
 * 
 * (IN)  query_num            = query number (zero based) 
 *                              (0 to one less than the number of querys 
 *                               returned in USERD_get_num_xy_queries) 
 * 
 * (OUT) query_name           = Name for the xy query. (80 chars long) 
 * 
 * (OUT) query_xtitle         = Title for x axis       (80 chars long) 
 * 
 * (OUT) query_ytitle         = Title for y axis       (80 chars long) 
 * 
 * (OUT) query_num_pairs      = number of xy pairs 
 * 
 * returns: Z_OK  if successful 
 *          Z_ERR if a problem 
 * 
 * Notes: 
 *---------------------------------------------------------------------------*/ 
int USERD_get_xy_query_info(int query_num, 
                            char *query_name, 
                            char *query_xtitle, 
                            char *query_ytitle, 
                            int *query_num_pairs ) 
/*--------------------------------------------------------------------

3.4.81. USERD_load_matf_data

 *                                            (Version 2.03 and later) 
 *-------------------------------------------------------------------- 
 *   Get the material id list, mixed-material id list, or 
 *   mixed-material values list for the given material set and part (and 
 *   element type if material id list) 
 * 
 *  (IN)  set_index         = the material set index (zero based) 
 * 
 *  (IN)  part_id           = the part number desired 
 * 
 *  (IN)  wtyp              = the element type     (used for Z_MAT_INDEX only) 
 * 
 *                                Z_POINT    node point element 
 *                                Z_BAR02    2 node bar 
 *                                Z_BAR03    3 node bar 
 *                                Z_TRI03    3 node triangle 
 *                                Z_TRI06    6 node triangle 
 *                                Z_QUA04    4 node quad 
 *                                Z_QUA08    8 node quad 
 *                                Z_TET04    4 node tetrahedron 
 *                                Z_TET10   10 node tetrahedron 
 *                                Z_PYR05    5 node pyramid 
 *                                Z_PYR13   13 node pyramid 
 *                                Z_PEN06    6 node pentahedron 
 *                                Z_PEN15   15 node pentahedron 
 *                                Z_HEX08    8 node hexahedron 
 *                                Z_HEX20   20 node hexahedron 
 *                                Z_NSIDED  nsided polygon 
 *                                Z_NFACED  nfaced polyhedron 
 * 
 *                                Z_G_POINT    ghost node point element 
 *                                Z_G_BAR02    2 node ghost bar 
 *                                Z_G_BAR03    3 node ghost bar 
 *                                Z_G_TRI03    3 node ghost triangle 
 *                                Z_G_TRI06    6 node ghost triangle 
 *                                Z_G_QUA04    4 node ghost quad 
 *                                Z_G_QUA08    8 node ghost quad 
 *                                Z_G_TET04    4 node ghost tetrahedron 
 *                                Z_G_TET10   10 node ghost tetrahedron 
 *                                Z_G_PYR05    5 node ghost pyramid 
 *                                Z_G_PYR13   13 node ghost pyramid 
 *                                Z_G_PEN06    6 node ghost pentahedron 
 *                                Z_G_PEN15   15 node ghost pentahedron 
 *                                Z_G_HEX08    8 node ghost hexahedron 
 *                                Z_G_HEX20   20 node ghost hexahedron 
 *                                Z_G_NSIDED  ghost nsided polygon 
 *                                Z_G_NFACED  ghost nfaced polyhedron 
 * 
 *  (IN)  mat_type          = Z_MAT_INDEX for material ids list 
 *                            Z_MIX_INDEX for mixed-material ids list 
 *                            Z_MIX_VALUE for mixed-material values list 
 *                            Z_SPE_VALUE for material species values list 
 * 
 *  (OUT) ids_list          = If mat_type is Z_MAT_INDEX: 
 *                            --------------------------- 
 *                             1D material id list 
 *                              (Int array will have been allocated 
 *                               the appropriate size, as returned in 
 *                               USERD_size_matf_data for mat_type Z_MAT_INDEX) 
 * 
 *                            If mat_type is Z_MIX_INDEX: 
 *                            --------------------------- 
 *                             1D mixed-material id list 
 *                              (Int array will have been allocated 
 *                               the appropriate size, as returned in 
 *                               USERD_size_matf_data for mat_type Z_MIX_INDEX) 
 * 
 *  (OUT) val_list          = 1D mixed-materials values list 
 *                            (only used if mat_type is Z_MIX_VALUE) 
 * 
 *                             (Float array will have been allocated 
 *                              the appropriate size, as returned in 
 *                              USERD_size_matf_data for mat_type Z_MIX_VALUE) 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * See USERD_get_number_of_material_sets header for explanatory example 
 *  * Will not be called if Num_material_sets is zero, 
 *     or Num_materials[set_index] is zero, 
 *     or the appropriate size from USERD_size_matf_data is zero 
 *  * This function is used only if USERD_get_matf_set_type returns 
 *     Z_MISET_VIA_SPARSE_MIX. 
 *  * This function is NOT used if USERD_get_matf_set_type returns 
 *     Z_MISET_VIA_ESCAL_VARS (and thus is incompatible with 
 *     USERD_get_matf_escalars_desc) 
 *--------------------------------------------------------------------*/ 
int 
USERD_load_matf_data( int set_index, 
                      int part_id, 
                      int wtyp, 
                      int mat_type, 
                      int *ids_list, 
                      float *val_list) 
/*--------------------------------------------------------------------

3.4.82. USERD_prefer_auto_distribute

 *                                 <optional> (Version 2.07 and later) 
 *-------------------------------------------------------------------- 
 * 
 * Returns whether the reader will do its own partitioning for SOS 
 * 
 * returns: TRUE  if reader prefers to do its own partitioning for SOS 
 *          FALSE if EnSight will be asked to do the partitioning 
 *                if an auto-distribute is specified 
 * 
 * Notes: 
 *-------------------------------------------------------------------*/ 
int 
USERD_prefer_auto_distribute(void) 
/*--------------------------------------------------------------------

3.4.83. USERD_rigidbody_existence

 *                                            (Version 2.05 and later) 
 *-------------------------------------------------------------------- 
 * 
 *  Gets the existence of rigid body values or not in the model 
 * 
 *  returns: Z_OK    if rigid body values exist for the model 
 *           Z_UNDEF if no rigid body values exist 
 *           Z_ERR   if an error 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 *--------------------------------------------------------------------*/ 
int 
USERD_rigidbody_existence( void ) 
/*--------------------------------------------------------------------

3.4.84. USERD_rigidbody_values

 *                                            (Version 2.05 and later) 
 *                               (Modified at 2.08 as described below) 
 *-------------------------------------------------------------------- 
 * 
 *  Gets the rigid body values for each part 
 * 
 *  (IN)  part_number             = The part number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                     1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id that is 
 *                                   loaded in USERD_get_gold_part_build_info) 
 * 
 *  (OUT) values             values[0] = IX   (x location) 
 *                           values[1] = IY   (y location) 
 *                           values[2] = IZ   (z location) 
 *                           values[3] = E0   (e0 euler value) 
 *                           values[4] = E1   (e1 euler value) 
 *                           values[5] = E2   (e2 euler value) 
 *                           values[6] = E3   (e3 euler value) 
 * 
 *                           The next 3 are for an optional cg offset. If none 
 *                           is needed or desired (namely the first 7 values 
 *                           above contain all that is needed), then these 
 *                           should be set to 0.0 
 * 
 *                           values[7]  = xoff   (initial cg x offset) 
 *                           values[8]  = yoff   (initial cg y offset) 
 *                           values[9]  = z0ff   (initial cg z offset) 
 * 
 *                          Stated differently, 
 *                          The translation values are 
 *                          tx, in values[0] 
 *                          ty, in values[1] 
 *                          tz, in values[2] 
 *                          And the euler rotational values are  
 *                                     e0, in values[4] 
 *                                     e1, in values[5] 
 *                                     e2, in values[6] 
 *                                     e3, in values[7] 
 *  
 * The order that these are applied is euler rotation first, followed by the 
 * translation. And the rotation will be about the global coordinate system. 
 *  
 * Whenever the part's desired center of rotation is not the global axis orig, 
 * then you need to do an initial translational offset using values 7-9. 
 * Namely, you must do a translation that will place the desired part center of 
 * rotation at the coordinate system origin, then do the rotation, then 
 * translate the  *  part back to where it should be. 
 * 
 * The initial translation can be done using values[7] through values[9], which 
 *  get applied before those indicated above. 
 * 
 * ORDER of OPERATIONS 
 * First the translations of values[7] through values[9] 
 * Then the euler rotations of values[4] through values[7] 
 * Then the translations of values[0] through values[2] 
 * So, perhaps a simple 2d example: 
 * ================================ 
 * Given a square at the location shown (centered on x=2, y=1).   
        Y 
        | 
        |        3            4 
        |        *------------* 
        |        |            | 
        |        |            | 
        |        |      .     |    Center is at (2,1) 
        |        |            | 
        |        |            | 
        |        *------------* 
        |        1            2 
        o----------------------------- x  
 * We desire to have it rotate 90 degrees about the z axis, 
 * and translate to x=3,y=0  
        Y 
        | 
        | 
        | 
        | 
        | 
        | 
        | 
        |            4 *------------* 2 
        |              |            | 
        |              |            | 
        0--------------|      .     |--- x    Center is now at (3,0) 
                       |            | 
                       |            | 
                     3 *------------* 1    
 * The values needed are: 
 *  
 * values[7] = -2          These are the initial translations to get center to the  
 *   origin 
 * values[8] = -1 
 * values[9] = 0 
 *  
 * values[3] = 0.7071      These are the euler parameters for the 90 degree 
 *                         rotation  
 * values[4] = 0.0         about the z axis.  Which will now occur about the part  
 *   center, because 
 * values[5] = 0.0         that center has been moved to the coordinate system
 *                         origin. 
 * values[6] = 0.7071 
 *  
 *  
 * values[0] = 3           These are the final translations to get the center 
 *                         from 
 * values[1] = 0           the origin to the desired final location. 
 * values[2] = 0 
 *  
 *  
 * So you can visualize this as moving the part to the origin, doing the rotation,
 * and them moving the part back out to where you want it to end up. 
 * 
 *  Starting at Version 2.08 
 *  ======================== 
 *                       The next 4 values are for and optional initial yaw, 
 *                       pitch, roll operation.  This is useful to get parts 
 *                       from one standard layout to a different standard 
 *                       layout. 
 *                       (example, flex body parts computed in an axis system 
 *                       different than that of rigid body parts manipulation) 
 *                       If not needed or desired, set these to 0.0 
 * 
 *                       values[10] = rot_order  (order the roations are applied 
 *                                                0.0  = no rotations 
 *                                                1.0  = xyz order 
 *                                                2.0  = xzy order 
 *                                                3.0  = yxz order 
 *                                                4.0  = yzx order 
 *                                                5.0  = zxy order 
 *                                                6.0  = zyx order) 
 *                       values[11] = xrot   (initial x rotation - degrees) 
 *                       values[12] = yrot   (initial y rotation - degrees) 
 *                       values[13] = zrot   (initial z rotation - degrees) 
 * 
 *  returns: Z_OK    if rigid body values sent for this part 
 *           Z_UNDEF if no rigid body values exist for this part 
 *           Z_ERR   if an error 
 * 
 * 
 *  Notes: 
 *  * This will be based on Current_time_step 
 *  * It will not be called unless USERD_rigidbody_existence indicates 
 *     that there are some values in the model by returning Z_OK. 
 *  * Order that transformations will be applied is: 
 *         1. The yaw,pitch,roll rotations, if present 
 *               (values[11] through values[13] 
 *                in the order specified in rot_order, values[10]) 
 *         2. The cg offsets, if present     (values[7] through values[9]) 
 *         3. The euler parameter rotations  (values[3] through values[6]) 
 *         4. The translations               (values[0] through values[2]) 
 * 
 *--------------------------------------------------------------------*/ 
int 
USERD_rigidbody_values(int part_number, 
                       float values[14])    /* Prior to Version 2.08, 
                                               float values[10] */  
/*--------------------------------------------------------------------

3.4.85. USERD_set_block_range_and_stride

 *                                            (Version 2.06 and later) 
 *-------------------------------------------------------------------- 
 *  Sets the min, max, and step values in each of the i, j, and k, directions 
 *  for the given part. 
 * 
 *  (IN)  part_number             = The part number 
 * 
 *                                  (1-based index of part table, namely: 
 * 
 *                                     1 ... Numparts_available. 
 * 
 *                                   It is NOT the part_id that is 
 *                                   loaded in USERD_get_gold_part_build_info) 
 * 
 *  (IN) mini        = min i plane desired  (zero based) 
 *       maxi        = max i plane desired  (zero based) 
 *       stepi       = i stride 
 *       minj        = min j plane desired  (zero based) 
 *       maxj        = max j plane desired  (zero based) 
 *       stepj       = j stride 
 *       mink        = min k plane desired  (zero based) 
 *       maxk        = max k plane desired  (zero based) 
 *       stepk       = k stride 
 * 
 * 
 *  returns: Z_OK    if no problems 
 *           Z_ERR   if an error 
 * 
 *  Notes: 
 *  * It will not be called unless USERD_get_structured_reader_cinching 
 *    indicates that this reader does structured cinching by returning 
 *    a Z_OK. 
 * 
 *  * It will actually be called before each geom component and before 
 *    each part variable - so if you are storing things locally, you should 
 *    make this routine be able to quickly check whether anything needs 
 *    updated or not. 
 * 
 *  * If the stride (step) does not hit right on the max, the last element 
 *    in each direction will be shortened appropriately. 
 *    For example, if a block had 0 to 12 in the i direction, 
 *                 and the user specified min = 1 
 *                                        max = 8 
 *                                        step = 3 
 * 
 *             0   1   2   3   4   5   6   7   8   9   10  11  12 
 *             |   |   |   |   |   |   |   |   |   |   |   |   | 
 * 
 *                 |           |           |   | 
 * 
 *      Namely, the coarser cell boundaries in this direction would be 
 *              at 1, 4, 7, and 8 
 * 
 * IMPORTANT!!  If your reader will be used for structured auto-distribute, 
 *              you must implement this feature, which includes this routine and 
 *              USERD_get_structured_reader_cinching 
 *--------------------------------------------------------------------*/ 
int 
USERD_set_block_range_and_stride(int part_number, 
                                 int mini, int maxi, int stepi, 
                                 int minj, int maxj, int stepj, 
                                 int mink, int maxk, int stepk) 
/*----------------------------------------------------------------------------

3.4.86. USERD_set_extra_gui_data

 *                                         <optional> (Version 2.00 and later) 
 *---------------------------------------------------------------------------- 
 * 
 *  Receives the toggle, pulldown and field_text from enhanced GUI. 
 * 
 *  (IN) toggle values   TRUE = toggle checked 
 *                       FALSE = toggle unchecked 
 *                       Is num_Toggles long, as set in 
 *                         USERD_get_extra_gui_numbers 
 * 
 *  (IN) pulldown value  from 0 to number of pulldown values 
 *                       Is num_pulldowns long, as set in 
 *                         USERD_get_extra_gui_numbers 
 * 
 *  (IN) field text      any text 
 *                      '\0' if inactivated or nothing entered 
 *                       Is num_fields by Z_LEN_GUI_FIELD_STR, as set in 
 *                       USERD_get_extra_gui_numbers 
 * 
 *  Notes: 
 *  This routine is called when the library is permanently 
 *   loaded to the EnSight session, so define your globals 
 *   in this and later routines. 
 * 
 *  It's up to you to change your reader behavior according to 
 *    user entries! 
 * -------------------------------------------------------------- */ 
void 
USERD_set_extra_gui_data(int *toggle, 
                         int *pulldown, 
                         char **field_text) 
/*--------------------------------------------------------------------

3.4.87. USERD_set_filename_button_labels

 *                                 <optional> (Version 2.07 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Returns the labels that the EnSight GUI will place on the buttons 
 *   in the Data Reader/Open dialog for Geometry and Results 
 * 
 *   (OUT) filename_label_1  = Label for the first button 
 *                             (Z_MAX_USERD_NAME long) 
 *                                (generally the geom file) 
 * 
 *   (OUT) filename_label_2  = Label for the second button 
 *                            (Z_MAX_USERD_NAME long) 
 *                                (generally the results file) 
 *                             Not needed (so can be null) if two_fields 
 *                             is FALSE in USERD_get_name_of_reader 
 * 
 *  Notes: 
 *---------------------------------------------------------------------*/ 
void 
USERD_set_filename_button_labels(char filename_label_1[Z_MAX_USERD_NAME], 
                                 char filename_label_2[Z_MAX_USERD_NAME]) 
/*--------------------------------------------------------------------

3.4.88. USERD_set_filenames

 *                                            (Version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Receives the geometry and result filenames entered in the data 
 *   dialog.  The user written code will have to store and use these 
 *   as needed.  The user written code must manage its own files!! 
 * 
 *  (IN) filename_1   = the filename entered into the geometry 
 *                         field of the data dialog. 
 *  
 *  (IN) filename_2   = the filename entered into the result 
 *                         field of the data dialog. 
 *                         (If the two_fields flag in USERD_get_name_of_reader 
 *                          is FALSE, this will be null string) 
 * 
 *                          If two_fields is TRUE, this is the  
 *                          mandatory results file entered  
 *                          into the result field of the data dialog. 
 *  
 *                          If two_fields is -1, then this contains 
 *                          optional text (filenames, modifiers, etc.) 
 *                          that can be parsed and used to modify  
 *                          reader 
 *  
 *  (IN) the_path     = the path info from the data dialog. 
 *                      Note: filename_1 and filename_2 have already 
 *                            had the path prepended to them.  This 
 *                            is provided in case it is needed for 
 *                            filenames contained in one of the files 
 *  
 *  (IN) swapbytes    = TRUE if should swap bytes when reading data. 
 *                    = FALSE normally 
 * 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * Since you must manage everything from the input that is entered in 
 *    these data dialog fields, this is an important routine! 
 * 
 *  * Since you manage these files, they can be whatever.  Perhaps 
 *    you will use only one, and have references to everything else 
 *    you need within it, like EnSight's case file does. 
 *--------------------------------------------------------------------*/ 
int 
USERD_set_filenames(char filename_1[], 
                    char filename_2[], 
                    char the_path[], 
                    int swapbytes) 
/*--------------------------------------------------------------------

3.4.89. USERD_set_right_side

 *                             <optional>     (Version 2.05 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Informs the reader that the time currently set is the right side of a time 
 *   span used for variable interpolation between time steps 
 * 
 *  Notes: 
 *  * Applies to Current_time_step 
 * 
 *  * This is called just before USERD_get_var_by_component 
 * 
 *  * This information is only needed if your reader must do its own 
 *    interpolation along a variable timeline.  This can occur when rigidbody 
 *    information has its own timeline, which is sent to EnSight as the 
 *    controlling time line, but the variables have a different timeline 
 *    known only to the reader. 
 *--------------------------------------------------------------------*/ 
void 
USERD_set_right_side( void ) 
/*--------------------------------------------------------------------

3.4.90. USERD_set_server_number

* (Version 2.00 and later)
*--------------------------------------------------------------------
* 
* Receives the server number of how many total servers if running in parallel
*   with multiple servers and EnSight has been informed that the reader is doing
*   its own decomposition of the data.
*
* (IN) cur_serv = the (1-based) current server.
*
* (IN) tot_servs = the total number of servers.
*
* 
* If EnSight is running using multiple servers,  
* e.g. Server of Servers (SOS) parallel 
* and USERD_prefer_auto_distribute returns TRUE
*  (which tells the server that the reader prefers
*  to do the distribution of the data itself) then
*  cur_serv will be the current server (1-based)
*  tot_servs will be the total number of servers running
* 
* Otherwise
* If EnSight is not running SOS, or USERD_prefer_auto_distribute
*  is not present or it returns FALSE, then
*  both cur_serv and tot_servs will be 1
*
* Notes:
* 
* Only useful if your user defined reader is being used with EnSight's
*  Server-of-Server capability and your data is already 
*  partitioned in some manner, such that you can quickly access the proper
*  portions for each server.
*
*
*--------------------------------------------------------------------*/
void
USERD_set_server_number(int cur_serv,
int tot_servs)
/*--------------------------------------------------------------------

3.4.91. USERD_set_time_set_and_step

 *                                            (Version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Set the current time step in the desired timeset.  All functions that 
 *   need time, and that do not explicitly pass it in, will use the timeset 
 *   and step set by this routine, if needed. 
 * 
 *  (IN) timeset_number  = the timeset number (1 based). 
 * 
 *                         For example:  If USERD_get_number_of_timesets 
 *                                       returns 2, the valid timeset_number's 
 *                                       would be 1 and 2. 
 * 
 *  (IN) time_step - The current time step 
 *                   (0 to Num_time_steps[timeset_number]) 
 * 
 *  Notes: 
 *  * Current_time_step and Current_timeset would be set here 
 *--------------------------------------------------------------------*/ 
void 
USERD_set_time_set_and_step(int timeset_number, 
                            int time_step) 
/*----------------------------------------------------------------------------

3.4.92. USERD_set_var_extract_gui_data

 *                                         <optional> (Version 2.05 and later) 
 *---------------------------------------------------------------------------- 
 * 
 *  Receives the toggle, pulldown and field_text from var extract input. 
 * 
 *  (IN) toggle values   TRUE = toggle checked 
 *                       FALSE = toggle unchecked 
 *                       Is num_Toggles long, as set in 
 *                         USERD_get_var_extract_gui_numbers 
 * 
 *  (IN) pulldown value  from 0 to number of pulldown values 
 *                       Is num_pulldowns long, as set in 
 *                         USERD_get_var_extract_gui_numbers 
 * 
 *  (IN) field text      any text 
 *                      '\0' if inactivated or nothing entered 
 *                       Is num_fields by Z_LEN_GUI_FIELD_STR, as set in 
 *                       USERD_get_var_extract_gui_numbers 
 * 
 *  Notes: 
 *  This routine is called when the library is permanently 
 *   loaded to the EnSight session, so define your globals 
 *   in this and later routines. 
 * 
 *  It's up to you to change your reader behavior according to 
 *    user entries! 
 * -------------------------------------------------------------- */ 
void 
USERD_set_var_extract_gui_data(int *toggle, 
                               int *pulldown, 
                               char **field_text) 
/*--------------------------------------------------------------------

3.4.93. USERD_size_matf_data

 *                                            (Version 2.03 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Get the length of the material id list, mixed-material id list, or 
 *   mixed-material values list for the given material set and part (and 
 *   element type if material id list) 
 * 
 *  (IN)  set_index         = the material set index (zero based) 
 * 
 *  (IN)  part_id           = the part number desired 
 * 
 *  (IN)  wtyp              = the element type (used for Z_MAT_INDEX only) 
 * 
 *                                Z_POINT    node point element 
 *                                Z_BAR02    2 node bar 
 *                                Z_BAR03    3 node bar 
 *                                Z_TRI03    3 node triangle 
 *                                Z_TRI06    6 node triangle 
 *                                Z_QUA04    4 node quad 
 *                                Z_QUA08    8 node quad 
 *                                Z_TET04    4 node tetrahedron 
 *                                Z_TET10   10 node tetrahedron 
 *                                Z_PYR05    5 node pyramid 
 *                                Z_PYR13   13 node pyramid 
 *                                Z_PEN06    6 node pentahedron 
 *                                Z_PEN15   15 node pentahedron 
 *                                Z_HEX08    8 node hexahedron 
 *                                Z_HEX20   20 node hexahedron 
 *                                Z_NSIDED  nsided polygon 
 *                                Z_NFACED  nfaced polyhedron 
 * 
 *                                Z_G_POINT    ghost node point element 
 *                                Z_G_BAR02    2 node ghost bar 
 *                                Z_G_BAR03    3 node ghost bar 
 *                                Z_G_TRI03    3 node ghost triangle 
 *                                Z_G_TRI06    6 node ghost triangle 
 *                                Z_G_QUA04    4 node ghost quad 
 *                                Z_G_QUA08    8 node ghost quad 
 *                                Z_G_TET04    4 node ghost tetrahedron 
 *                                Z_G_TET10   10 node ghost tetrahedron 
 *                                Z_G_PYR05    5 node ghost pyramid 
 *                                Z_G_PYR13   13 node ghost pyramid 
 *                                Z_G_PEN06    6 node ghost pentahedron 
 *                                Z_G_PEN15   15 node ghost pentahedron 
 *                                Z_G_HEX08    8 node ghost hexahedron 
 *                                Z_G_HEX20   20 node ghost hexahedron 
 *                                Z_G_NSIDED  ghost nsided polygon 
 *                                Z_G_NFACED  ghost nfaced polyhedron 
 * 
 *  (IN)  mat_type          = Z_MAT_INDEX for material ids list 
 *                            Z_MIX_INDEX for mixed-material ids list 
 *                            Z_MIX_VALUE for mixed-material values list 
 *                            Z_SPE_VALUE for material species values 
 * 
 *  (OUT) matf_size         = the length of the material id list, or 
 *                            mixed-material id list, or 
 *                            mixed-material values list 
 *                            for the given material set and part number 
 *                            (and element type if Z_MAT_INDEX) 
 * 
 *  returns: Z_OK  if successful 
 *           Z_ERR if not successful 
 * 
 *  Notes: 
 *  * See USERD_get_number_of_material_sets header for explanatory example 
 *  * Will not be called if Num_material_sets is zero, or 
 *     Num_materials[set_index] is zero 
 *  * This function is used only if USERD_get_matf_type returns 
 *     Z_MISET_VIA_SPARSE_MIX. 
 *  * This function is NOT usAed if USERD_get_matf_type returns 
 *     Z_MISET_VIA_ESCAL_VARS (and thus is incompatible with 
 *     USERD_get_matf_escalars_desc) 
 *--------------------------------------------------------------------*/ 
int 
USERD_size_matf_data( int set_index, 
                      int part_id, 
                      int wtyp, 
                      int mat_type, 
                      int *matf_size) 
/*--------------------------------------------------------------------

3.4.94. USERD_stop_part_building

 *                                            (Version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *   Called when part builder is closed for USERD, can be used to clean 
 *   up memory, etc that was only needed during the part building process. 
 *--------------------------------------------------------------------*/ 
void 
USERD_stop_part_building( void )  
/*--------------------------------------------------------------------

3.4.95. USERD_use_periodic_ghosts

 *                                 <optional>   (Version 2.00 and later) 
 *-------------------------------------------------------------------- 
 * 
 *  The existence of the this as well as the following routines, implies to  
 *    EnSight that the reader has the capability to read periodic models, and 
 *    a return value of TRUE from this routine tells EnSight that at least one 
 *    part has periodic symmetry faces and the following routines should be 
 *    called.  A return value of FALSE tells EnSight that no parts have 
 *    periodic symmetry faces and not to call the remaining routines. 
 *  
 *      USERD_get_periodic_ghosts_num_symmetry_faces 
 * 
 *      and for unstructured parts: 
 *      --------------------------- 
 *      USERD_get_periodic_ghosts_num_pairs 
 *      USERD_get_periodic_ghosts_pairs. 
 * 
 *      and for structured parts: 
 *      ------------------------- 
 *      USERD_get_periodic_ghosts_structured_face_info 
 * 
 * 
 *  returns: TRUE    If there is at least one part that needs to 
 *                   use the node pairing information (for unstructured parts), 
 *                   or the face ijk information (for structured parts), or 
 *                   supplied transformation matrices, to augment the initial 
 *                   periodic instance with the proper ghosts across the 
 *                   symmetry face(s). 
 * 
 *           FALSE   if no parts have periodic faces and don't call the other 
 *                   periodic routines. 
 * 
 * 
 *   Simple Examples: 
 * 
 *   periodic translation of 3 units in x model 
 *   ========================================== 
 *               y 
 *                13        14        15        16 
 *               *---------*---------*---------* 
 *               |         |         |         | 
 *               |    6    |    7    |    8    | 
 *               |9        |10       |11       |12 
 *               *---------*---------*---------* 
 *               |         |         |         | 
 *     face 0    |    3    |    4    |    5    |    face 1 
 *               |5        |6        |7        |8 
 *               *---------*---------*---------* 
 *               |         |         |         | 
 *               |    0    |    1    |    2    | 
 *               |1        |2        |3        |4 
 *               *---------*---------*---------*  x 
 * 
 *              <===== translation direction =====> 
 * 
 *               y 
 *      15        13        14        15        16        14 
 *     *- - - - -*---------*---------*---------*- - - - -* 
 *     .  ghost  |         |         |         |  ghost  . 
 *     .    8    |    6    |    7    |    8    |    6    . 
 *     .11       |9        |10       |11       |12       .10 
 *     *- - - - -*---------*---------*---------*- - - - -* 
 *     .  ghost  |         |         |         |  ghost  . 
 *     .    5    |    3    |    4    |    5    |    3    . 
 *     .7        |5        |6        |7        |8        .6 
 *     *- - - - -*---------*---------*---------*- - - - -* 
 *     .  ghost  |         |         |         |  ghost  . 
 *     .    2    |    0    |    1    |    2    |    0    . 
 *     .3        |1        |2        |3        |4        .2 
 *     *- - - - -*---------*---------*---------*- - - - -*  x 
 * 
 *  num_symmetry_faces = 2; 
 * 
 *    face 0 
 *    ------ 
 *     num_pairs = 4 
 *     pairs[0] = 1  node 1 moves to node 4 location 
 *     pairs[1] = 4 
 *     pairs[2] = 5  node 5 moves to node 8 location 
 *     pairs[3] = 8 
 *     pairs[4] = 9  node 9 moves to node 12 location 
 *     pairs[5] = 12 
 *     pairs[6] = 13 node 13 moves to node 16 location 
 *     pairs[7] = 16 
 * 
 *    face 1 
 *    ------ 
 *     num_pairs = 4 
 *     pairs[0] = 4  node 4 moves to node 1 location 
 *     pairs[1] = 1 
 *     pairs[2] = 8  node 8 moves to node 5 location 
 *     pairs[3] = 5 
 *     pairs[4] = 12 node 12 moves to node 9 location 
 *     pairs[5] = 9 
 *     pairs[6] = 16 node 16 moves to node 13 location 
 *     pairs[7] = 13 
 * 
 *------------------------------------------------------------------- 
 *   periodic rotation of 90 degrees about z axis 
 *   ============================================ 
 *               y 
 *                13        14        15        16 
 *               *---------*---------*---------* 
 *               |         |         |         | 
 *               |    6    |    7    |    8    | 
 *               |9        |10       |11       |12 
 *               *---------*---------*---------* 
 *               |         |         |         | 
 *    face 1     |    3    |    4    |    5    | 
 *               |5        |6        |7        |8 
 *               *---------*---------*---------* 
 *               |         |         |         | 
 *               |    0    |    1    |    2    | 
 *               |1        |2        |3        |4 
 *               *---------*---------*---------*  x 
 *              /            face 0 
 *             /       
 *            -- rotates in plane about node 1     
 *           
 * 
 *               y 
 *       8        13        14        15        16 
 *     *- - - - -*---------*---------*---------* 
 *     .  ghost  |         |         |         | 
 *     .    2    |    6    |    7    |    8    | 
 *     .7        |9        |10       |11       |12 
 *     *- - - - -*---------*---------*---------* 
 *     .  ghost  |         |         |         | 
 *     .    1    |    3    |    4    |    5    | 
 *     .6        |5        |6        |7        |8 
 *     *- - - - -*---------*---------*---------* 
 *     .  ghost  |         |         |         | 
 *     .    0    |    0    |    1    |    2    | 
 *     .5        |1        |2        |3        |4 
 *     *- - - - -*---------*---------*---------* 
 *               .  ghost  .  ghost  .  ghost  . 
 *               .    0    .    3    .    6    . 
 *               .2        .6        .10       .14 
 *               *- - - - -*- - - - -*- - - - -* 
 * 
 *  num_symmetry_faces = 2; 
 * 
 *    face 0 
 *    ------ 
 *     num_pairs = 4 
 *     pairs[0] = 1  node 1 rotates to node 1 location 
 *     pairs[1] = 1 
 *     pairs[2] = 2  node 2 rotates to node 5 location 
 *     pairs[3] = 5 
 *     pairs[4] = 3  node 3 rotates to node 9 location 
 *     pairs[5] = 9 
 *     pairs[6] = 4  node 4 rotates to node 13 location 
 *     pairs[7] = 13 
 * 
 *    face 1 
 *    ------ 
 *     num_pairs = 4 
 *     pairs[0] = 1  node 1 rotates to node 1 location 
 *     pairs[1] = 1 
 *     pairs[2] = 5  node 5 rotates to node 2 location 
 *     pairs[3] = 2 
 *     pairs[4] = 9  node 9 rotates to node 3 location 
 *     pairs[5] = 3 
 *     pairs[6] = 13 node 13 rotates to node 4 location 
 *     pairs[7] = 4 
 * 
 * 
 *-------------------------------------------------------------------------- 
 *   mirror in x 
 *   =========== 
 *               y 
 *                13        14        15        16 
 *               *---------*---------*---------* 
 *               |         |         |         | 
 *               |    6    |    7    |    8    | 
 *               |9        |10       |11       |12 
 *               *---------*---------*---------* 
 *               |         |         |         | 
 *     face 0    |    3    |    4    |    5    | 
 *               |5        |6        |7        |8 
 *               *---------*---------*---------* 
 *               |         |         |         | 
 *               |    0    |    1    |    2    | 
 *               |1        |2        |3        |4 
 *               *---------*---------*---------*  x 
 *    <===  mirror 
 * 
 *               y 
 *      14        13        14        15        16 
 *     *- - - - -*---------*---------*---------* 
 *     .  ghost  |         |         |         | 
 *     .    6    |    6    |    7    |    8    | 
 *     .10       |9        |10       |11       |12 
 *     *- - - - -*---------*---------*---------* 
 *     .  ghost  |         |         |         | 
 *     .    3    |    3    |    4    |    5    | 
 *     .6        |5        |6        |7        |8 
 *     *- - - - -*---------*---------*---------* 
 *     .  ghost  |         |         |         | 
 *     .    0    |    0    |    1    |    2    | 
 *     .2        |1        |2        |3        |4 
 *     *- - - - -*---------*---------*---------* 
 * 
 *  num_symmetry_faces = 1; 
 * 
 *    face 0 
 *    ------ 
 *     num_pairs = 4 
 *     pairs[0] = 1  node 1 reflects about node 1 
 *     pairs[1] = 1 
 *     pairs[2] = 5  node 5 reflects about node 5 
 *     pairs[3] = 5 
 *     pairs[4] = 9  node 9 reflects about node 9 
 *     pairs[5] = 9 
 *     pairs[6] = 13 node 13 reflects about node 13 
 *     pairs[7] = 13 
 *--------------------------------------------------------------------*/ 
int 
USERD_use_periodic_ghosts( void )