Commit 856f45a9 authored by Mark OLESEN's avatar Mark OLESEN
Browse files

Merge remote-tracking branch 'origin/master' into develop

parents 812fa22d aa4f81ff
EXE = $(FOAM_USER_APPBIN)/ensightFoamReader-udr_checker
udr_checker.c is a routine that can be used to debug EnSight User-defined
readers. It exists because of the difficulty of debugging dynamic shared
libraries when you don't have the source for the calling program (EnSight).
If udr_checker.c is compiled and linked with your reader source code (including
access to any libraries needed, and the global_extern.h file), it will exercise
most options of you reader, giving feedback as it goes. The resulting
executable can be debugged using your favorite debugger. And if you have
memory/bounds checking software (such as purify), you can (and should) run it
with this executable to make sure that you are not overwriting things. Readers
that bash memory will cause problems when run with EnSight!
You will note that the Makefile provided with the readers in the EnSight
distribution have a "checker" object. If you do a "make checker" instead of
just a "make", the "checker"executable will be produced. You may need to
modify these makefiles slightly if the locations of your reader files are
different than the normal.
Once the "checker" executable exists, you can run the checker program by simply
invoking it:
> checker
And you will be prompted for the type of information that you provide in the
EnSight Data Reader dialog, namely:
The path
[filename_2] Only if your reader uses two fields
swapbytes flag
<toggle flags> Only if your reader implements extra GUI
<pulldown flags> one flag value per line
<field contents> one field string per line
There are certain command line options that you can use to control some aspects
of the checker program. One of the more useful is the ability to provide the
input just described in a file. This is done in this fashion:
> checker -p <playfile>
And <playfile> would be a simple ascii file with 3 [0r 4] lines:
line 1: the path
line 2: filename_1
line 3: [filename_2] (if two_fields is TRUE)
line 3 or 4: 0 or 1, for swapbytes (0 is FALSE, 1 is TRUE)
remaining lines 0 or 1 for toggle disable enabled
one line for each toggle
0 - num_pulldown_values for pulldown choice
one line for each pulldown
one line for each field
example playfile for an EnSight Gold reader casefile (entitled
could look something like the following: (Note: two_fields is FALSE)
And you would invoke checker as:
> checker -p
Another example playfile
with swapbytes 0,
two enabled toggles,
three pulldowns with the value 0 chosen
and a single field "sample field value"
could look something like the following::
sample field value
Other command line arguments are:
-server_number For checking server number routines. If you use this
option, you will be prompted for the total number of
servers and the current server number. These will then be
used in the calls to the server number routines.
-gts # For specifying the geometry timestep to test. The default
is step 0.
The # is the (zero based) time step to read for geometry.
-vts # For specifying the variable timestep to test. The default
is step 0.
The # is the (zero based) time step to read for variables.
Testing optional routines using #defines
For optional routines, such as the extra_gui, or var_extract_gui routines, you
must uncomment the proper #define in udr_checker.c
Currently the ones available are:
#define _EGS for extra gui routines
#define _VES for var extract gui routines
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration |
# \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
# \\/ M anipulation |
# License
# This file is part of OpenFOAM.
# OpenFOAM is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
# You should have received a copy of the GNU General Public License
# along with OpenFOAM. If not, see <>.
# Script
# ensightFoamReaderTest
# Description
# start ensightFoamReader-udr_checker
usage() {
while [ "$#" -ge 1 ]; do echo "$1"; shift; done
usage: ${0##*/} [OPTION]
-case dir specify alternative case directory
* start ensightFoamReader-udr_checker
exit 1
# parse options
while [ "$#" -gt 0 ]
case "$1" in
-h | -help)
[ "$#" -ge 2 ] || usage "'$1' option requires an argument"
cd "$2" 2>/dev/null || usage "directory does not exist: '$2'"
shift 2
usage "unknown option/argument: '$*'"
# check existence of essential files
for check in system/controlDict system/fvSchemes system/fvSolution
[ -s "$check" ] || usage "file does not exist: '$check'"
# export values that might be needed
export FOAM_CASENAME=${PWD##*/}
trap "rm -f $playFile 2>/dev/null; exit 0" EXIT TERM INT
cat << PLAY_FILE > $playFile
echo "ensightFoamReader-udr_checker -p $playFile"
ensightFoamReader-udr_checker -p $playFile
\ No newline at end of file
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
\ No newline at end of file
cd ${0%/*} || exit 1 # Run from this directory
. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
wmake $targetType
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/browser/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-lOpenFOAM \
-lfiniteVolume \
-lmeshTools \
-lgenericPatchFields \
-llagrangian \
This document exists to help those who already have a working user defined
reader (using the 1.0 API) to change it into the 2.0 API format - if desired.
Note that you do not have to update your (1.0 API) user defined reader if it
is already working fine for you.
You should consider it if:
- efficieny gains are needed or
- you need access to complex variables or
- you need access to tensor variables or
- you need multiple timeset capability or
- you want to provide your own "border" elements (as opposed to EnSight's
computation of them)
As an indication of the differences that might be realized in efficency,
consider the following comparison on an unstructured model consisting of:
1,639,058 nodes
7,079,211 elements 240530 tria3
3984 quad4
5927663 tetra4
653 pyramid5
906381 penta6
12 parts
The same model was represented in EnSight6 and EnSight Gold format.
EnSight6 format into: EnSight Gold format into:
------------------------------------ -------------------------
EnSight7.1 |Ensight7.2 |Ensight 7.1 |EnSight7.2 |Ensight7.2
internal |internal |userd reader |internal |userd reader
reader |reader |(API 1.0) |reader |(API 2.0)
| | | |
Time | Mem |Time | Mem |Time | Mem |Time | Mem |Time | Mem
(sec)| (Mb) |(sec)| (Mb) |(sec)| (Mb) |(sec)| (Mb) |(sec)| (Mb)
----------- |----------- |----------- |----------- |-----------
@ part 4.3 27.6 | 3.5 28.4 | 4.0 27.6 | 3.3 8.8 | 3.3 8.9
loader | | | |
| | | |
after 14.0 243.4 |12.8 244.3 |49.8 475.8 | 6.0 211.5 | 6.2 211.6
loading all | | | |
12 parts | | | |
(non-visual) | | | |
| | | |
after 16.8 263.2 |16.0 264.2 |52.8 490.7 | 9.1 236.2 | 9.5 236.2
activate of | | | |
a vector. | | | |
^ ^
/|\ /|\
| |
| |
| |
Compare these two!
Significant is the inefficiency of the 1.0 API, and the fact that the
2.0 API has the same improved efficiency (both in speed and memory) as
the gold internal reader!
Note: Structured data will not show much difference between the two API's,
but it was more efficient initially.
A note on philosophical differences between the two API's:
API 1.0 deals with:
-> global coordinate array & corresponding
-> global node id array
-> global nodal variables
-> for each part:
-> local element connectivities (grouped by type) & corresponding
-> local element ids
-> local elemental variables
The element connectivities, within parts, reference the global coordinate
array. If node ids are provided, the element connectivities have to be in
terms of the node ids. If node ids are not provided, the connectivities are in
terms of the (one-based) index number of each node in the global coordinate
array. Thus, node ids are more than labels - they are a part of the
connectivity referencing scheme. Element ids are purely labels.
This API was originally setup to try to make the interface to other codes as
straightforward as possible. Efficiency was not the major consideration.
EnSight must do a fair amount of work to get data provided in the manner
described above into the form that it uses internally. There is mapping that
has to be setup and maintained between the global arrays and the local part
arrays so that updating over time can be accomplished efficiently. There is
hashing that is required in order to deal efficently with node ids.
All of this leads to a considerable amount of temporary memory and processing,
in order to get a model read into EnSight.
API 2.0 deals with:
-> for each part:
-> part coordinates & corresponding
-> part node ids
-> part nodal variables
-> part element connectivities (grouped by type) & corresponding
-> part element ids
-> part elemental variables
API 2.0 requires that the coordinates and corresponding nodal variables be
provided per part. This eliminates the global to local mapping with all its
associated temporary memory and processing time. The connectivity of the
elements in each part reference the node indicies of its own (one-based) part
coordinate array. The connectivity of the elements do not reference the nodes
according to node ids. Node ids (and element ids for that matter) are purely
labels for screen display and for query operations within EnSight. This
eliminates the need for node id hashing as a model is read.
The 2.0 API has been created for those needing more efficiency - both in terms
of memory use and speed. The increased efficiency is possible because data is
requested in a manner which more closely represents the way that EnSight
stores and manipulates information internally. The new API requests size
information and allocates the actual internal structures and arrays
accordingly. Pointers to these arrays are passed directly to you in the
routines which gather data, thus eliminating a considerable amount of
temporary memory (and allocation time) that is needed in the old
API. Depending on what you must do to get your data into the form required,
the memory savings and the speed improvement when loading models can be quite
Additionally, the ability to handle tensor and complex variables has been
added to the new API, and support for multiple timesets is provided.
So, with that said, if you determine that you want to convert your existing
reader to the new API format, The following may be helpful.
First the Good News! The following routines are identical in both API's!!
==================== ----------------------------------------------------
Second, pretty Good News! The following routines have minor changes,
======================== namely a slight name change and the addition
of arguments related to complex data, constant
(Note, the name changes type, or self contained parts vs global coords.
are needed so both
API's can exist together) The arguments must be added, but depending on
your situation, many might simply be place
A) Changes related to imaginary flag for complex data
If you don't deal with complex variables, simply add
this flag to your argument list and ignore its value.
API 1.0 API 2.0
------- -------
USERD_get_constant_value USERD_get_constant_val
( (
int which var int which_var,
int imag_data
) )
USERD_get_description_lines USERD_get_descrip_lines
( (
int which_type, int which_type,
int which_var, int which_var,
int imag_data,
char line1[Z_BUFL], char line1[Z_BUFL],
char line2[Z_BUFL] char line2[Z_BUFL]
) )
USERD_get_variable_value_at_specific USERD_get_var_value_at_specific
( (
int which_var, int which_var,
int which_node_or_elem, int which_node_or_elem,
int which_part, int which_part,
int which_elem_type, int which_elem_type,
int time_step, int time_step,
float values[3] float values[3],
int imag_data
) )
B) Changes related to complex data info, and constant type
(and some of the multiple timeset support)
If you don't deal with complex variables, simply add the
arguments for var_complex, var_ifilename, and var_freq
and assign var_complex to be FALSE.
The argument var_contran needs to be added, and set
appropriately if you have constant variables, to indicate
if the constant variable is fixed for all time or varies
over time.
The argument var_timeset needs to be added, and set
API 1.0 API 2.0
------- -------
USERD_get_variable_info USERD_get_gold_variable_info
( (
char **var_description, char **var_description,
char **var_filename, char **var_filename,
int *var_type, int *var_type,
int *var_classify int *var_classify,
int *var_complex,
char **var_ifilename,
float *var_freq,
int *var_contran,
int *var_timeset
) )
C) Changes related to self contained part coordinates
The number_of_nodes argument needs to be added and
set for each part. This one is critical for you to do.
API 1.0 API 2.0
------- -------
USERD_get_part_build_info USERD_get_gold_part_build_info
( (
int *part_numbers, int *part_types,
int *part_types, int *part_types,
char *part_description[Z_BUFL], char *part_description[Z_BUFL],
int *number_of_nodes,
int *number_of_elements[Z_MAXTYPE], int *number_of_elements[Z_MAXTYPE],
int *ijk_dimensions[3], int *ijk_dimensions[3],
int *iblanking_options[6] int *iblanking_options[6]
) )
D) Changes related to multiple timeset support
The timeset_number argument needs to be added for the
following three routines.
The multiple timeset support also includes the change
in B) above for USERD_get_gold_variable_info and the
last three new routines in the third section of this
readme file.
API 1.0 API 2.0
------- -------
USERD_get_number_of_time_steps USERD_get_num_of_time_steps
( (
void int timeset_number
) )
USERD_get_solution_times USERD_get_sol_times
( (
int timeset_number,
float *solution_times float *solution_times
) )
USERD_set_time_step USERD_set_time_set_and_step
( (
int timeset_number,
int time_step int time_step
) )
E) Changes related to global_extern.h
Be sure to include the updated global_extern.h file that comes
with the EnSight 7.2 release (not the one from previous releases).
Third, deleted and new routines. (Here is where the work lies)
Several old routines are gone. You will have to create the new
routines that replace them. I think you will find in most cases
that your old routines will form the basis of the new routines,
and that it isn't too difficult to provide the information in
the new way.
The detailed specifications for these new routines can be found
in README_USERD_2.0 (or the headers in libuserd.c of the
dummy_gold or ensight_gold readers).
API 1.0 API 2.0
------- -------
These routines: replaced by the single routine:
--------------------------- -------------------------------
USERD_get_block_scalar_values USERD_get_var_by_component
These global coordinate routines: replaced by part coord routines:
--------------------------------- --------------------------------
USERD_get_global_coords USERD_get_part_coords
USERD_get_global_node_ids USERD_get_part_node_ids