/*-----------------------------------------------------* * AVSreadHLL: Reads Tom's libHLL data into AVS UCD * * format. This is based on the AVS readUCD.cc * * code snippet. * *-----------------------------------------------------*/ #include #include #include #include #include #include #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, " ", "", "."); /* 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, " ", "", "."); } /* 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, " ", "", "."); 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;ireadConnectivity(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;nmreadDataInfo(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;nm1) { 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;idxreadData(names[nm],data); for(int idx=0,offset=num_nodes*nm;idxreadData(names[nm],data); for(int idx=0,offset=num_nodes*nm;idxreadData(names[nm],data); for(int idx=0,offset=num_nodes*nm;idxmax) max=pt; if(ptnum_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 = "...."; /************** *** 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", "", choices, "."); param = AVSadd_parameter("Cell Data", "string", "Cell Data", "Cell Data", NULL); AVSconnect_widget (param, "text"); AVSadd_parameter ("Cell Type", "choice", "", choices, "."); param = AVSadd_parameter("Model Data", "string", "Model Data", "Model Data", NULL); AVSconnect_widget (param, "text"); AVSadd_parameter ("Model Type", "choice", "", 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