diff options
Diffstat (limited to 'src/AVSreadHLL.cc')
-rw-r--r-- | src/AVSreadHLL.cc | 768 |
1 files changed, 768 insertions, 0 deletions
diff --git a/src/AVSreadHLL.cc b/src/AVSreadHLL.cc new file mode 100644 index 0000000..f55e32e --- /dev/null +++ b/src/AVSreadHLL.cc @@ -0,0 +1,768 @@ +/*-----------------------------------------------------* + * AVSreadHLL: Reads Tom's libHLL data into AVS UCD * + * format. This is based on the AVS readUCD.cc * + * code snippet. * + *-----------------------------------------------------*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <avs/avs.h> +#include <avs/geom.h> +#include <avs/ucd_defs.h> +#include "IO.hh" +#include "IEEEIO.hh" +#include "WriteHLL.hh" + +#define buffer_size 200 +#define NUM_CELL_TYPES 8 + +extern char *AVSstatic; + +typedef struct _ucd_stats { + int size; + } Ucd_Stats_Type; + +typedef struct _ctype_struct { + int id, mat, n, cell_type; + } Ctype; + +typedef struct _ntype_struct { + int n, node_list[20]; + } Ntype; + +typedef struct _model_stats { + char node_data_labels[100], cell_data_labels[100], model_data_labels[100], + node_data_units[100], cell_data_units[100], model_data_units[100]; + + int num_nodes, num_cells, num_node_data, num_cell_data, num_model_data, + node_active_list[20], cell_active_list[20], model_active_list[20], + num_node_comp, node_comp_list[20], num_cell_comp, cell_comp_list[20], + num_model_comp, model_comp_list[20], num_nlist_nodes; + } Mtype; + +/* ANSI-C/C++ expect functions to be declared before being used and checks + argument compatibility */ + +AVS_STATIC(void add_cell, (UCD_structure **model, int cell, int ucd_cell_type, int n, + int *rnode_list, int mat_id)); +AVS_STATIC(int read_binary, (const char *file_name, Ctype **pcells, int **pcell_nlists, + Mtype *model, float **pxc, float **pyc, float **pzc, + float **pnode_data, float **pcell_data, float **pmodel_data, + float **pmin_node_data, float **pmax_node_data, + float **pmin_cell_data, float **pmax_cell_data, + float **pmin_model_data, float **pmax_model_data)); + +int read_hll( UCD_structure** output, + const char* file_name, + int cell_con, /* Not used! */ + const char* td1, /* Not used! */ + const char* contour, /* Not used! */ + const char* td2, /* Not used! */ + const char* cell_sel, /* Not used! */ + const char* td3, /* Not used! */ + const char* model_sel /* Not used! */ ) + { + + char string[40], *model_name, tmp_str[80]; + + float x, y, z, + xmin = 0.0, xmax = 0.0, ymin = 0.0, ymax = 0.0, zmin = 0.0, zmax = 0.0, + min_extent[3], max_extent[3]; + + int node, cell, n, i, util_flag, j, ucd_flags, cell_tsize, node_csize; + + Ctype *cells; + + float *xc, *yc, *zc, *node_data, *cell_data, *model_data, + *min_node_data, *max_node_data, *min_cell_data, + *max_cell_data, *min_model_data, *max_model_data; + + int num_nodes, num_cells, num_node_data, num_cell_data, num_model_data, + *bcell_nlists; + + Mtype model_stats; + + Ntype *cell_nlists; + + static int clist[] = {1, 2, 3, 4}; + + Ucd_Stats_Type *ucd_stats; + + /************** + *** body *** + **************/ + + if (!file_name) + return(1); + + if (AVSstatic == NULL) { + ucd_stats = (Ucd_Stats_Type *)malloc(sizeof(Ucd_Stats_Type)); + AVSstatic = (char *) ucd_stats; + } + else + ucd_stats = (Ucd_Stats_Type *)AVSstatic; + + if (AVSparameter_changed("read file")) { + if (*output) UCDstructure_free (*output); + + cell_nlists = NULL; + bcell_nlists = NULL; + + + /* check to see if file is binary or ascii. */ + + if (!read_binary (file_name, &cells, &bcell_nlists, &model_stats, &xc, + &yc, &zc, &node_data, &cell_data, &model_data, + &min_node_data, &max_node_data, &min_cell_data, + &max_cell_data, &min_model_data, &max_model_data)) { + AVSerror (" Error in read_hll: can't open bin file. \n"); + return (0); + } + + + + /* set the model statistics: + + num_nodes - the number of nodes in the model. + + num_cells - the number of cells (elements) in the model. + + num_node_data - the total number of data values per node. if you + wanted to store three scalars and one 3-vector per + node then num_node_data would be set to six. + + num_cell_data - the total number of data values per cell. + + num_model_data - model data is used for values which apply to the + the model as a whole, not just nodes or cells. + for example, the locations of loads could be stored + here. + + + */ + util_flag = 0; + num_nodes = model_stats.num_nodes; + num_cells = model_stats.num_cells; + num_node_data = model_stats.num_node_data; + num_cell_data = model_stats.num_cell_data; + num_model_data = model_stats.num_model_data; + strcpy (tmp_str, file_name); + + model_name = (char *)(strrchr(tmp_str, '/')); + + if (model_name) model_name++; /* go to the next character */ + + for (i = strlen(model_name); model_name[i] != '.'; i--); + model_name[i] = '\0'; + + + /* 'cell_tsize' is the size of all of the cell topology (number of + nodes per cell) lists. it is used to allocate space for the node + lists for each cell. if all the cells were hexahedra (without + mid-edge nodes) then this would be set to num_cells*eight, if all + the cells were tetrahedra (without mid-edge nodes) then this would + be set to num_cells*four. + + 'node_csize' is the size all of the node connectivity lists (the list + of cells connected to a node). for a model constructed from all + hexahedra this would be less than num_cells*eight. + + both 'cell_tsize' and 'node_csize' are computed when the model is + read (in the read_ascii or the read_bin functions) and are always + equal. + + 'ucd_flags' specifies how labels for cells and nodes will be stored + and whether material id's and cell types will be stored for each cell. + the following is a list of flags which can be or'ed together: + + UCD_MATERIAL_IDS - material id's for each cell will be stored. + UCD_NODE_NAMES - node names will be stored. + UCD_CELL_NAMES - cell names will be stored. + UCD_CELL_TYPES - user defined cell type will be stored. + UCD_MID_EDGES - cells will have mid-side edges. + UCD_CHAR - node/cell labels are character strings. + UCD_INT - node/cell labels are integers. */ + + cell_tsize = node_csize = model_stats.num_nlist_nodes; + ucd_stats->size = cell_tsize; + + ucd_flags = UCD_INT | UCD_MATERIAL_IDS | UCD_NODE_NAMES | UCD_CELL_NAMES | + UCD_CELL_TYPES | UCD_MID_EDGES; + + *output = (UCD_structure *)UCDstructure_alloc (model_name, + num_model_data, ucd_flags, num_cells, cell_tsize, + num_cell_data, num_nodes, node_csize, num_node_data, util_flag); + + + /* store nodal coordinates. */ + + for (node = 0; node < num_nodes; node++) { + x = xc[node], y = yc[node], z = zc[node]; + + if (node) { + xmin = (x < xmin ? x : xmin), xmax = (x > xmax ? x : xmax); + ymin = (y < ymin ? y : ymin), ymax = (y > ymax ? y : ymax); + zmin = (z < zmin ? z : zmin), zmax = (z > zmax ? z : zmax); + } + else { + xmin = xmax = x; + ymin = ymax = y; + zmin = zmax = z; + } + + if (!UCDnode_set_information (*output, node, (char *) (node + 1), 0, clist)) { + AVSerror ("Error in read_hll: can't set node %d info.\n", node); + return (0); + } + } + + UCDstructure_set_node_positions (*output, xc, yc, zc); + + + /* store the model's extent (max/min dimensions). */ + + min_extent[0] = xmin, min_extent[1] = ymin, min_extent[2] = zmin; + max_extent[0] = xmax, max_extent[1] = ymax, max_extent[2] = zmax; + + UCDstructure_set_extent (*output, min_extent, max_extent); + + + /* store cell type, topology. */ + + if (bcell_nlists) { /* if read in as binary file. */ + for (cell = 0, j = 0; cell < num_cells; cell++, j += n) { + n = cells[cell].n; + + add_cell (output, cell, cells[cell].cell_type, n, &bcell_nlists[j], + cells[cell].mat); + } + } + else + for (cell = 0; cell < num_cells; cell++) + add_cell (output, cell, cells[cell].cell_type, cell_nlists[cell].n, + cell_nlists[cell].node_list, cells[cell].mat); + + + /* store nodal data. + + data at nodes is separated into components. successive nodes of a + component are stored contiguously. for example, if you wish to + store two scalars and one 3-vector then this would be three + components and would be stored as (given n nodes in the model): + + 0 node 0, component 1 + 1 node 1, component 1 + . + . + . + n node n, component 1 + n+1 node 0, component 2 + n+2 node 1, component 2 + . + . + . + 2n node n, component 2 + 2n+1 node 0, component 3, 1st vector component + 2n+2 node 0, component 3, 2nd vector component + 2n+3 node 0, component 3, 3rd vector component + 2n+4 node 1, component 3, 1st vector component + + 2n+5 node 1, component 3, 2nd vector component + 2n+6 node 1, component 3, 3rd vector component + . + . + . + 5n-2 node n, component 3, 1st vector component + 5n-1 node n, component 3, 2nd vector component + 5n node n, component 3, 3rd vector component + + + the node component list has an entry for each compoment. each + entry specifies the dimensionality for each component. for example, + a scalar component would have an entry of one and a 3-vector would + have an entry of three. + + the node active list can be used to specify which data type is + currently active (being used to display results). the list has + an entry for each data component. if that entry is not zero + then it is active. currently, this functionality is not used by + any modules. + + node labels specify the user defined name of each data component. + + node units specify the user defined units of each data component. + + node minmax specifies the maximum and minimum values for each + data component. this has no meaning for vector components although + the max/min magnitude of the vector could be used. + + */ + + if (num_node_data) { + UCDstructure_set_node_components (*output, model_stats.node_comp_list, + model_stats.num_node_comp); + + + UCDstructure_set_node_active (*output, model_stats.node_active_list); + + UCDstructure_set_node_labels (*output, model_stats.node_data_labels, "."); + + UCDstructure_set_node_units (*output, model_stats.node_data_units, "."); + + if (model_stats.num_node_comp > 1) { + for (i = 0; model_stats.node_data_labels[i] != '.'; i++) + string[i] = model_stats.node_data_labels[i]; + string[i] = '\0'; + } + else + strcpy (string, model_stats.node_data_labels); + + AVSmodify_parameter ("Node Type", AVS_MINVAL | AVS_VALUE, string, + model_stats.node_data_labels, "."); + + UCDstructure_set_node_minmax (*output, min_node_data, max_node_data); + + if (!UCDstructure_set_node_data (*output, node_data)) { + AVSerror ("Error in read_hll: can't set node data.\n"); + return (0); + } + } + else + AVSmodify_parameter ("Node Type", AVS_MINVAL | AVS_VALUE, " ", + "<no data>", "."); + + + /* store cell data. */ + + if (num_cell_data) { + UCDstructure_set_cell_components (*output, model_stats.cell_comp_list, + model_stats.num_cell_comp); + + UCDstructure_set_cell_active (*output, model_stats.cell_active_list); + + UCDstructure_set_cell_labels (*output, model_stats.cell_data_labels, "."); + + for (i = 0; model_stats.cell_data_labels[i] != '.'; i++) + string[i] = model_stats.cell_data_labels[i]; + string[i] = '\0'; + + AVSmodify_parameter ("Cell Type", AVS_MINVAL | AVS_VALUE, string, + model_stats.cell_data_labels, "."); + + if (!UCDstructure_set_cell_data (*output, cell_data)) { + AVSerror ("Error in read_hll: can't set cell data.\n"); + return (0); + } + } + else { + AVSmodify_parameter ("Cell Type", AVS_MINVAL | AVS_VALUE, " ", + "<no data>", "."); + } + + + /* store model data. */ + + if (num_model_data) { + UCDstructure_set_data_labels (*output, model_stats.model_data_labels, "."); + + for (i = 0; model_stats.model_data_labels[i] != '.'; i++) + string[i] = model_stats.model_data_labels[i]; + string[i] = '\0'; + + AVSmodify_parameter ("Model Type", AVS_MINVAL | AVS_VALUE, string, + model_stats.model_data_labels, "."); + + if (!UCDstructure_set_data (*output, model_data)) { + AVSerror ("Error in read_hll: can't set model data.\n"); + return (0); + } + } + else + AVSmodify_parameter ("Model Type", AVS_MINVAL | AVS_VALUE, " ", + "<no data>", "."); + + if (*output) { + free (xc); + free (yc); + free (zc); + + if (num_node_data) { + free (node_data); + free (min_node_data); + free (max_node_data); + } + + if (num_cell_data) { + free (cell_data); + free (min_cell_data); + free (max_cell_data); + } + + if (num_model_data) { + free (model_data); + free (min_model_data); + free (max_model_data); + } + + free (cells); + + if (cell_nlists) + free (cell_nlists); + + if (bcell_nlists) + free (bcell_nlists); + } + } + return(1); + } + + +/*-----------------------------------------------------* + * * + * **** add_cell **** * + * * + * add a cell topology to the ucd structure. * + *-----------------------------------------------------*/ + +static void add_cell( UCD_structure** model, int cell, int ucd_cell_type, int n, + int* rnode_list, int mat_id ) + { + + static char *cell_type[] = {"pt", "line", "tri", "quad", "tet", + "pyr", "prism", "hex"}; + + int i, num_me_nodes, num_nodes, /* Not used: cell_found, */ + me_flag, node_list[40]; + + /************** + *** body *** + **************/ + + if (ucd_cell_type < NUM_CELL_TYPES) { + me_flag = 0; + num_nodes = UCD_num_nodes[ucd_cell_type]; + + + /* if the number of nodes read (n) is equal to the number of + nodes without mid-side nodes then send the read node list. + else set the mid-edge flag to indicate which edges have + mide-edge nodes. */ + + for (i = 0; i < num_nodes; i++) + node_list[i] = rnode_list[i] - 1; + + if (n != num_nodes) { + for (i = num_nodes, num_me_nodes = 0; i < n; i++) + if (rnode_list[i] != 0) { + node_list[num_nodes + num_me_nodes] = rnode_list[i] - 1; + me_flag = me_flag | (0x1 << (i - num_nodes)); + num_me_nodes++; + } + } + + UCDcell_set_information (*model, cell, (char *) (cell + 1), + cell_type[ucd_cell_type], + mat_id - 1, ucd_cell_type, me_flag, node_list); + } + } + + +/*-----------------------------------------------------* + * * + * **** read_binary **** * + * * + * read a ucd binary file. * + *-----------------------------------------------------*/ + +static int read_binary( const char* file_name, + Ctype** pcells, + int** pcell_nlists, + Mtype* model, + float** pxc, + float** pyc, + float** pzc, + float** pnode_data, + float** pcell_data, + float** pmodel_data, + float** pmin_node_data, + float** pmax_node_data, + float** pmin_cell_data, + float** pmax_cell_data, + float** pmin_model_data, + float** pmax_model_data ) + { + + //char magic; + + Ctype *cells; + + // FILE *fp; + + float *xc, *yc, *zc, *node_data, *cell_data, *model_data, + *min_node_data, *max_node_data, *min_cell_data, *max_cell_data, + *min_model_data, *max_model_data; + + int num_nodes, num_cells, num_node_data, + num_cell_data, num_model_data, *cell_nlists, num_nlist_nodes; + + /************** + *** body *** + **************/ + + node_data = cell_data = model_data = NULL; + max_cell_data = min_cell_data =max_model_data=min_model_data=NULL; + + //if (!(fp = fopen (file_name, "r"))) + // return (0); + + IEEEIO *file = new IEEEIO(file_name,IObase::Read); + if(!file->isValid()) + return (0); + ReadHLL *hll = new ReadHLL(*file); + int ndims, cellsz, celltype; + model->num_cell_data=model->num_node_data=model->num_model_data=0; + hll->selectDataset(0/*index*/, + ndims, + model->num_nodes,model->num_cells,model->num_node_data); + model->num_nlist_nodes=8*model->num_cells; // hexahedral cells + + switch(ndims){ + case 0: + cellsz=1; + celltype=UCD_POINT; + break; + case 1: + cellsz=2; + celltype=UCD_LINE; + break; + case 2: + cellsz=4; + celltype=UCD_QUADRILATERAL; + break; + case 3: + cellsz=8; + celltype=UCD_HEXAHEDRON; + break; + } + model->num_nlist_nodes=cellsz*model->num_cells; // hexahedral cells + // fill out basic parameters + num_nodes = model->num_nodes; + num_cells = model->num_cells; + num_node_data = model->num_node_data; + num_cell_data = model->num_cell_data; + num_model_data = model->num_model_data; + num_nlist_nodes = model->num_nlist_nodes; + + cells = (Ctype *)malloc(sizeof(Ctype) * num_cells); + cell_nlists = (int *)malloc(sizeof(int) * num_nlist_nodes); + + //fread ((char *)cells, sizeof(Ctype), num_cells, fp); + for(int i=0;i<num_cells;i++){ + cells[i].id=i+1; + cells[i].mat=1; + cells[i].n=cellsz; + cells[i].cell_type=celltype; + } + //fread ((char *)cell_nlists, sizeof(int), num_nlist_nodes, fp); + hll->readConnectivity(cell_nlists); + + xc = (float *)malloc(sizeof(float) * num_nodes); + yc = (float *)malloc(sizeof(float) * num_nodes); + zc = (float *)malloc(sizeof(float) * num_nodes); + + //fread ((char *)xc, sizeof(float), num_nodes, fp); + //fread ((char *)yc, sizeof(float), num_nodes, fp); + //fread ((char *)zc, sizeof(float), num_nodes, fp); + hll->readCoords(xc,yc,zc); + + if (num_node_data) { + int nm=0; + // Now read in information about the node data + char **names=new char*[num_node_data]; + for(nm=0;nm<num_node_data;nm++) names[nm]=new char[32]; // limit names to 32chars + IObase::DataType *datatypes=new IObase::DataType[num_node_data]; + int *veclens = new int[num_node_data]; + hll->readDataInfo(names,datatypes,veclens); + + node_data = (float *)malloc(sizeof(float) * num_nodes * num_node_data); + min_node_data = (float *)malloc(sizeof(float) * num_node_data); + max_node_data = (float *)malloc(sizeof(float) * num_node_data); + for(nm=0;nm<num_node_data;nm++){ + if(veclens[nm]>1) { + printf("node_data[%u] has veclen %u which is too large to store in this implementation\n", + nm,veclens[nm]); + continue; + } + switch(datatypes[nm]){ + case IObase::Float32: + hll->readData(names[nm],node_data+(nm*num_nodes)); + break; + case IObase::Float64: + { double *data=new double[num_nodes]; + hll->readData(names[nm],data); + for(int idx=0,offset=num_nodes*nm;idx<num_nodes;idx++) + node_data[idx+offset]=(float)(data[idx]); + delete data; + } break; + case IObase::Int32: + { int *data=new int[num_nodes]; + hll->readData(names[nm],data); + for(int idx=0,offset=num_nodes*nm;idx<num_nodes;idx++) + node_data[idx+offset]=(float)(data[idx]); + delete data; + } break; + case IObase::Int64: + { long long *data=new long long[num_nodes]; + hll->readData(names[nm],data); + for(int idx=0,offset=num_nodes*nm;idx<num_nodes;idx++) + node_data[idx+offset]=(float)(data[idx]); + delete data; + } break; + case IObase::Byte: + { char *data=new char[num_nodes]; + hll->readData(names[nm],data); + for(int idx=0,offset=num_nodes*nm;idx<num_nodes;idx++) + node_data[idx+offset]=(float)(data[idx]); + delete data; + } break; + default: + printf("unknown datatype %d for node_data[%u]\n",(int)(datatypes[nm]),nm); + break; + } + // convert data to float (avs only knows floats) + // scan for min + // scan for max + float min,max; + min=max=node_data[nm*num_nodes]; + for(int idx=1,offset=nm*num_nodes;idx<num_nodes;idx++){ + float pt=node_data[idx+offset]; + if(pt>max) max=pt; + if(pt<min) min=pt; + } + min_node_data[nm]=min; + max_node_data[nm]=max; + } + //fread ((char *)min_node_data, sizeof(float), num_node_data, fp); + //fread ((char *)max_node_data, sizeof(float), num_node_data, fp); + //fread ((char *)node_data, sizeof(float), num_node_data * num_nodes, fp); + for(nm=0;nm<num_node_data;nm++) delete names[nm]; + delete names; + delete datatypes; + delete veclens; + } + + *pxc = xc, *pyc = yc, *pzc = zc; + *pcells = cells; + *pcell_nlists = cell_nlists; + *pnode_data = node_data; + *pcell_data = cell_data; + *pmodel_data = model_data; + + model->num_nodes = num_nodes; + model->num_cells = num_cells; + model->num_node_data = num_node_data; + model->num_cell_data = num_cell_data; + model->num_model_data = num_model_data; + + *pmax_node_data = max_node_data; + *pmin_node_data = min_node_data; + *pmax_cell_data = max_cell_data; + *pmin_cell_data = min_cell_data; + *pmax_model_data = max_model_data; + *pmin_model_data = min_model_data; + + // fclose (fp); + delete hll; + delete file; + + return(1); + } + +/*-----------------------------------------------------* + * * + * **** read_hll_init **** * + * * + *-----------------------------------------------------*/ + +static void +read_hll_init() + { + AVSstatic = (char *)0; + } + + +/*-----------------------------------------------------* + * * + * **** read_hll_finis **** * + * * + *-----------------------------------------------------*/ + +static void +read_hll_finis() + { + if (AVSstatic == NULL) return; + + free (AVSstatic); + } + + +static void +read_hll_desc() + { + int param; + + static char *choices = "<data 1>.<data 2>.<data 3>.<data 4>.<data 5>"; + + /************** + *** body *** + **************/ + + AVSset_module_name ("Read HLL", MODULE_DATA); + + AVScreate_output_port ("tet output", "ucd"); + + param = AVSadd_parameter ("read file", "string", 0, 0, ".inp"); + AVSconnect_widget (param, "browser"); + + AVSadd_parameter("Cell Connect", "boolean", 0, 0, 1); + + param = AVSadd_parameter("Node Data", "string", "Node Data", "Node Data", + NULL); + AVSconnect_widget(param, "text"); + + AVSadd_parameter ("Node Type", "choice", "<data 1>", choices, "."); + + param = AVSadd_parameter("Cell Data", "string", "Cell Data", "Cell Data", + NULL); + AVSconnect_widget (param, "text"); + + AVSadd_parameter ("Cell Type", "choice", "<data 1>", choices, "."); + + param = AVSadd_parameter("Model Data", "string", "Model Data", "Model Data", + NULL); + AVSconnect_widget (param, "text"); + + AVSadd_parameter ("Model Type", "choice", "<data 1>", choices, "."); + + AVSset_init_proc ((AVS_FNCP) read_hll_init); + + AVSset_destroy_proc ((AVS_FNCP) read_hll_finis); + + AVSset_compute_proc ((AVS_FNCP) read_hll); + } + +#if __cplusplus +extern "C" { +#endif + +void +AVSinit_modules() + { + AVSmodule_from_desc ((AVS_FNCP) read_hll_desc); + } + +#if __cplusplus +} +#endif + |