You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1006 lines
36 KiB
1006 lines
36 KiB
/*
|
|
* Copyright (c) 1994 Sandia Corporation. Under the terms of Contract
|
|
* DE-AC04-94AL85000 with Sandia Corporation, the U.S. Governement
|
|
* retains certain rights in this software.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the following
|
|
* disclaimer in the documentation and/or other materials provided
|
|
* with the distribution.
|
|
*
|
|
* * Neither the name of Sandia Corporation nor the names of its
|
|
* contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
/*****************************************************************************
|
|
*
|
|
* excn2s - ex_cvt_nodes_to_sides: convert nodes to sides
|
|
*
|
|
* author - Sandia National Laboratories
|
|
* Vic Yarberry - Original
|
|
*
|
|
*
|
|
* environment - UNIX
|
|
*
|
|
* entry conditions -
|
|
* input parameters:
|
|
* int exoid exodus file id
|
|
* int *num_elem_per_set number of element per set
|
|
* int *num_nodes_per_set number of nodes per set
|
|
* int *side_sets_elem_index index array of elements into elem list
|
|
* int *side_sets_node_index index array of nodes
|
|
* int *side_sets_elem_list array of elements
|
|
* int *side_sets_node_list array of nodes
|
|
*
|
|
* exit conditions -
|
|
* int *side_sets_side_list array of sides/faces
|
|
*
|
|
* revision history -
|
|
*
|
|
* $Id: excn2s.c,v 1.4 2005/07/19 23:40:10 andy Exp $
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include "exodusII.h"
|
|
#include "exodusII_int.h"
|
|
|
|
/*
|
|
* This routine is designed to take the results from retrieving the ExodusI
|
|
* style concatenated side sets to the Exodus II V 2.0 definition
|
|
* uses the element id to get the coordinate node list, element block
|
|
* connectivity, element type to
|
|
* convert the side set node list to a side/face list.
|
|
|
|
Algorithm:
|
|
|
|
Read elem_block_ids --> elem_blk_id[array]
|
|
|
|
Read element block parameters --> elem_blk_parms[array]
|
|
|
|
Determine total number of elements in side set by summing num_elem_per_set
|
|
|
|
Build side set element to side set node list index --> ss_elem_node_ndx[array]
|
|
|
|
For each element in the side_set_elem_list
|
|
{
|
|
If Jth element is not in current element block (e.g. J>elem_ctr)
|
|
{
|
|
get element block parameters (num_elem_in_blk, ...)
|
|
|
|
elem_ctr += num_elem_in_blk
|
|
|
|
|
|
free old connectity array space
|
|
|
|
allocate connectivity array: size=num_elem_in_blk*num_nodes_per_elem
|
|
|
|
get connectivity array
|
|
}
|
|
|
|
If Jth element is in current element block (e.g. J<=elem_ctr)
|
|
{
|
|
For each node in element (linear search of up to num_nodes_per_elem)
|
|
{
|
|
If side set element node[1] == element node[i]
|
|
{
|
|
Case element type = Hex
|
|
{
|
|
If side set element node[2] == element node[Hex_table[i,1]]
|
|
|
|
Jth side = Hex_table[i,2]
|
|
|
|
break
|
|
}
|
|
Case element type = Wedge
|
|
{
|
|
If side set element node[2] == element node[Wedge_table[i,1]]
|
|
|
|
Jth side = Wedge_table[i,2]
|
|
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
int ex_cvt_nodes_to_sides(int exoid,
|
|
int *num_elem_per_set,
|
|
int *num_nodes_per_set,
|
|
int *side_sets_elem_index,
|
|
int *side_sets_node_index,
|
|
int *side_sets_elem_list,
|
|
int *side_sets_node_list,
|
|
int *side_sets_side_list)
|
|
{
|
|
int i, j, k, m, n;
|
|
int num_side_sets, num_elem_blks;
|
|
int tot_num_elem = 0, tot_num_ss_elem = 0, elem_num = 0, ndim;
|
|
int *elem_blk_ids, *connect;
|
|
int *ss_elem_ndx, *ss_elem_node_ndx, *ss_parm_ndx;
|
|
int elem_ctr, node_ctr, elem_num_pos;
|
|
int num_elem_in_blk, num_nodes_per_elem, num_node_per_side, num_attr;
|
|
int *same_elem_type, el_type;
|
|
float fdum;
|
|
char *cdum, elem_type[MAX_STR_LENGTH+1];
|
|
|
|
struct elem_blk_parm
|
|
{
|
|
char elem_type[MAX_STR_LENGTH+1];
|
|
int elem_blk_id;
|
|
int num_elem_in_blk;
|
|
int num_nodes_per_elem;
|
|
int num_nodes_per_side;
|
|
int num_attr;
|
|
int elem_ctr;
|
|
int elem_type_val;
|
|
} *elem_blk_parms;
|
|
|
|
/* node to side translation tables -
|
|
These tables are used to look up the side number based on the
|
|
first and second node in the side/face list. The side node order
|
|
is found in the original Exodus document, SAND87-2997. The element
|
|
node order is found in the ExodusII document, SAND92-2137. These
|
|
tables were generated by following the right-hand rule for determining
|
|
the outward normal. Note: Only the more complex 3-D shapes require
|
|
these tables, the simple shapes are trivial - the first node found
|
|
is also the side number.
|
|
*/
|
|
|
|
/* 1 2 3 4 node 1 */
|
|
static int shell_table[2][8] = {
|
|
{2,4, 3,1, 4,2, 1,3}, /* node 2 */
|
|
{1,2, 1,2, 1,2, 1,2} /* side # */
|
|
};
|
|
|
|
/* 1 2 3 4 node 1 */
|
|
static int shell_edge_table[2][8] = {
|
|
{2,4, 3,1, 4,2, 1,3}, /* node 2 */
|
|
{3,6, 4,3, 5,4, 6,5} /* side # */
|
|
};
|
|
|
|
/* 1 2 3 node 1 */
|
|
static int trishell_table[2][6] = {
|
|
{2,3, 3,1, 1,2}, /* node 2 */
|
|
{1,2, 1,2, 1,2} /* side # */
|
|
};
|
|
|
|
/* 1 2 3 4 node 1 */
|
|
static int tetra_table[2][12] = {
|
|
{2,3,4, 1,3,4, 4,1,2, 1,2,3}, /* node 2 */
|
|
{1,4,3, 4,2,1, 2,3,4, 1,2,3} /* side # */
|
|
};
|
|
|
|
#if 0
|
|
static int wedge_table[2][18] = {
|
|
/* 1 2 3 4 5 6 node 1 */
|
|
{2,4,3, 5,1,3, 6,1,2, 1,6,5, 6,2,4, 4,3,5}, /* node 2 */
|
|
{1,3,4, 1,4,2, 2,3,4, 1,3,5, 5,2,1, 5,3,2} /* side # */
|
|
};
|
|
#endif
|
|
|
|
static int hex_table[2][24] = {
|
|
/* 1 2 3 4 5 6 7 8 node 1 */
|
|
{4,2,5, 1,3,6, 7,4,2, 3,1,8, 6,8,1, 5,2,7, 8,6,3, 7,5,4},/* node 2 */
|
|
{5,1,4, 5,2,1, 2,3,5, 5,4,3, 6,4,1, 1,2,6, 6,2,3, 3,6,4} /* side # */
|
|
};
|
|
|
|
char errmsg[MAX_ERR_LENGTH];
|
|
|
|
(void)side_sets_node_index;
|
|
(void)side_sets_elem_index;
|
|
|
|
exerrval = 0; /* clear error code */
|
|
|
|
cdum = 0; /* initialize even though it is not used */
|
|
|
|
/* first check if any side sets are specified */
|
|
/* inquire how many side sets have been stored */
|
|
|
|
if ((ex_inquire(exoid, EX_INQ_SIDE_SETS, &num_side_sets, &fdum, cdum)) == -1)
|
|
{
|
|
sprintf(errmsg,
|
|
"Error: failed to get number of side sets in file id %d",exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
return(EX_FATAL);
|
|
}
|
|
|
|
if (num_side_sets == 0)
|
|
{
|
|
sprintf(errmsg,
|
|
"Warning: no side sets defined in file id %d",exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,EX_WARN);
|
|
return(EX_WARN);
|
|
}
|
|
|
|
if ((ex_inquire(exoid, EX_INQ_ELEM_BLK, &num_elem_blks, &fdum, cdum)) == -1)
|
|
{
|
|
sprintf(errmsg,
|
|
"Error: failed to get number of element blocks in file id %d",exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
return(EX_FATAL);
|
|
}
|
|
|
|
if ((ex_inquire(exoid, EX_INQ_ELEM, &tot_num_elem, &fdum, cdum)) == -1)
|
|
{
|
|
sprintf(errmsg,
|
|
"Error: failed to get total number of elements in file id %d",exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
return(EX_FATAL);
|
|
}
|
|
|
|
/* get the dimensionality of the coordinates; this is necessary to
|
|
distinguish between 2d TRIs and 3d TRIs */
|
|
|
|
if ((ex_inquire(exoid, EX_INQ_DIM, &ndim, &fdum, cdum)) == -1)
|
|
{
|
|
sprintf(errmsg,
|
|
"Error: failed to get dimensionality in file id %d",exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
return(EX_FATAL);
|
|
}
|
|
|
|
/* First count up # of elements in the side sets*/
|
|
for (i=0;i<num_side_sets;i++)
|
|
tot_num_ss_elem += num_elem_per_set[i];
|
|
|
|
/* Allocate space for the ss element index array */
|
|
if (!(ss_elem_ndx=malloc(tot_num_ss_elem*sizeof(int))))
|
|
{
|
|
exerrval = EX_MEMFAIL;
|
|
sprintf(errmsg,
|
|
"Error: failed to allocate space for side set elem sort array for file id %d",
|
|
exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
return (EX_FATAL);
|
|
}
|
|
|
|
/* Sort side set element list into index array - non-destructive */
|
|
for (i=0;i<tot_num_ss_elem;i++)
|
|
ss_elem_ndx[i] = i; /* init index array to current position */
|
|
|
|
ex_iqsort(side_sets_elem_list, ss_elem_ndx,tot_num_ss_elem);
|
|
|
|
|
|
/* Allocate space for the element block ids */
|
|
if (!(elem_blk_ids=malloc(num_elem_blks*sizeof(int))))
|
|
{
|
|
free(ss_elem_ndx);
|
|
exerrval = EX_MEMFAIL;
|
|
sprintf(errmsg,
|
|
"Error: failed to allocate space for element block ids for file id %d",
|
|
exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
return (EX_FATAL);
|
|
}
|
|
|
|
if (ex_get_elem_blk_ids(exoid, elem_blk_ids))
|
|
{
|
|
free(elem_blk_ids);
|
|
free(ss_elem_ndx);
|
|
sprintf(errmsg,
|
|
"Error: failed to get element block ids in file id %d",
|
|
exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,EX_MSG);
|
|
return(EX_FATAL);
|
|
}
|
|
|
|
/* Allocate space for the element block params */
|
|
if (!(elem_blk_parms=malloc(num_elem_blks*sizeof(struct elem_blk_parm))))
|
|
{
|
|
free(elem_blk_ids);
|
|
free(ss_elem_ndx);
|
|
exerrval = EX_MEMFAIL;
|
|
sprintf(errmsg,
|
|
"Error: failed to allocate space for element block params for file id %d",
|
|
exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
return (EX_FATAL);
|
|
}
|
|
elem_ctr = 0;
|
|
for (i=0; i<num_elem_blks; i++)
|
|
{
|
|
/* read in an element block parameter */
|
|
if ((ex_get_elem_block (exoid,
|
|
elem_blk_ids[i],
|
|
elem_type,
|
|
&num_elem_in_blk,
|
|
&num_nodes_per_elem,
|
|
&num_attr)) == -1)
|
|
{
|
|
free(elem_blk_parms);
|
|
free(elem_blk_ids);
|
|
free(ss_elem_ndx);
|
|
sprintf(errmsg,
|
|
"Error: failed to get element block %d parameters in file id %d",
|
|
elem_blk_ids[i], exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,EX_MSG);
|
|
return(EX_FATAL);
|
|
}
|
|
|
|
elem_blk_parms[i].num_elem_in_blk = num_elem_in_blk;
|
|
elem_blk_parms[i].num_nodes_per_elem = num_nodes_per_elem;
|
|
elem_blk_parms[i].num_attr = num_attr;
|
|
|
|
for (m=0; (size_t)m < strlen(elem_type); m++)
|
|
elem_blk_parms[i].elem_type[m] =
|
|
(char)toupper((int)elem_type[m]);
|
|
elem_blk_parms[i].elem_type[m] = '\0';
|
|
|
|
if (strncmp(elem_blk_parms[i].elem_type,"CIRCLE",3) == 0)
|
|
{
|
|
elem_blk_parms[i].elem_type_val = CIRCLE;
|
|
/* set side set node stride */
|
|
elem_blk_parms[i].num_nodes_per_side = 1;
|
|
}
|
|
else if (strncmp(elem_blk_parms[i].elem_type,"SPHERE",3) == 0)
|
|
{
|
|
elem_blk_parms[i].elem_type_val = SPHERE;
|
|
/* set side set node stride */
|
|
elem_blk_parms[i].num_nodes_per_side = 1;
|
|
}
|
|
else if (strncmp(elem_blk_parms[i].elem_type,"QUAD",3) == 0)
|
|
{
|
|
elem_blk_parms[i].elem_type_val = QUAD;
|
|
/* determine side set node stride */
|
|
if (elem_blk_parms[i].num_nodes_per_elem == 4)
|
|
elem_blk_parms[i].num_nodes_per_side = 2;
|
|
else if (elem_blk_parms[i].num_nodes_per_elem == 5)
|
|
elem_blk_parms[i].num_nodes_per_side = 2;
|
|
else
|
|
elem_blk_parms[i].num_nodes_per_side = 3;
|
|
}
|
|
else if (strncmp(elem_blk_parms[i].elem_type,"TRIANGLE",3) == 0)
|
|
{
|
|
elem_blk_parms[i].elem_type_val = TRIANGLE;
|
|
/* determine side set node stride */
|
|
if (ndim == 2) /* 2d TRIs */
|
|
{
|
|
if (elem_blk_parms[i].num_nodes_per_elem == 3)
|
|
elem_blk_parms[i].num_nodes_per_side = 2;
|
|
else
|
|
elem_blk_parms[i].num_nodes_per_side = 3;
|
|
}
|
|
else if (ndim == 3) /* 3d TRIs */
|
|
{
|
|
elem_blk_parms[i].elem_type_val = TRISHELL;
|
|
elem_blk_parms[i].num_nodes_per_side =
|
|
elem_blk_parms[i].num_nodes_per_elem;
|
|
}
|
|
}
|
|
else if (strncmp(elem_blk_parms[i].elem_type,"SHELL",3) == 0)
|
|
{
|
|
elem_blk_parms[i].elem_type_val = SHELL;
|
|
/* determine side set node stride */
|
|
if (elem_blk_parms[i].num_nodes_per_elem == 2)
|
|
{
|
|
/* 2d SHELL; same as BEAM or TRUSS or BAR */
|
|
elem_blk_parms[i].num_nodes_per_side = 2;
|
|
elem_blk_parms[i].elem_type_val = BEAM;
|
|
}
|
|
else if (elem_blk_parms[i].num_nodes_per_elem == 4)
|
|
elem_blk_parms[i].num_nodes_per_side = 4;
|
|
else
|
|
elem_blk_parms[i].num_nodes_per_side = 8;
|
|
}
|
|
else if (strncmp(elem_blk_parms[i].elem_type,"HEX",3) == 0)
|
|
{
|
|
elem_blk_parms[i].elem_type_val = HEX;
|
|
/* determine side set node stride */
|
|
if (elem_blk_parms[i].num_nodes_per_elem == 8)
|
|
elem_blk_parms[i].num_nodes_per_side = 4;
|
|
else if (elem_blk_parms[i].num_nodes_per_elem == 9)
|
|
elem_blk_parms[i].num_nodes_per_side = 4;
|
|
else if (elem_blk_parms[i].num_nodes_per_elem == 12) /* HEXSHELL */
|
|
elem_blk_parms[i].num_nodes_per_side = 4;
|
|
else if (elem_blk_parms[i].num_nodes_per_elem == 27)
|
|
elem_blk_parms[i].num_nodes_per_side = 9;
|
|
else
|
|
elem_blk_parms[i].num_nodes_per_side = 8;
|
|
}
|
|
else if (strncmp(elem_blk_parms[i].elem_type,"TETRA",3) == 0)
|
|
{
|
|
elem_blk_parms[i].elem_type_val = TETRA;
|
|
/* determine side set node stride */
|
|
if (elem_blk_parms[i].num_nodes_per_elem == 4)
|
|
elem_blk_parms[i].num_nodes_per_side = 3;
|
|
else if (elem_blk_parms[i].num_nodes_per_elem == 8)
|
|
elem_blk_parms[i].num_nodes_per_side = 4;
|
|
else
|
|
elem_blk_parms[i].num_nodes_per_side = 6;
|
|
}
|
|
else if (strncmp(elem_blk_parms[i].elem_type,"WEDGE",3) == 0)
|
|
{
|
|
elem_blk_parms[i].elem_type_val = WEDGE;
|
|
/* determine side set node stride */
|
|
if (elem_blk_parms[i].num_nodes_per_elem == 6)
|
|
elem_blk_parms[i].num_nodes_per_side = 4;
|
|
else
|
|
elem_blk_parms[i].num_nodes_per_side = 8;
|
|
sprintf(errmsg,
|
|
"Warning: WEDGE%d is assumed to have %d nodes per face",
|
|
elem_blk_parms[i].num_nodes_per_elem,
|
|
elem_blk_parms[i].num_nodes_per_side);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,EX_MSG);
|
|
}
|
|
else if (strncmp(elem_blk_parms[i].elem_type,"PYRAMID",3) == 0)
|
|
{
|
|
elem_blk_parms[i].elem_type_val = PYRAMID;
|
|
/* determine side set node stride */
|
|
if (elem_blk_parms[i].num_nodes_per_elem == 5)
|
|
elem_blk_parms[i].num_nodes_per_side = 4;
|
|
else
|
|
elem_blk_parms[i].num_nodes_per_side = 8;
|
|
sprintf(errmsg,
|
|
"Warning: PYRAMID%d is assumed to have %d nodes per face",
|
|
elem_blk_parms[i].num_nodes_per_elem,
|
|
elem_blk_parms[i].num_nodes_per_side);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,EX_MSG);
|
|
}
|
|
else if (strncmp(elem_blk_parms[i].elem_type,"BEAM",3) == 0)
|
|
{
|
|
elem_blk_parms[i].elem_type_val = BEAM;
|
|
/* determine side set node stride */
|
|
if (elem_blk_parms[i].num_nodes_per_elem == 2)
|
|
elem_blk_parms[i].num_nodes_per_side = 2;
|
|
else
|
|
elem_blk_parms[i].num_nodes_per_side = 3;
|
|
}
|
|
else if ( (strncmp(elem_blk_parms[i].elem_type,"TRUSS",3) == 0) ||
|
|
(strncmp(elem_blk_parms[i].elem_type,"BAR",3) == 0) ||
|
|
(strncmp(elem_blk_parms[i].elem_type,"EDGE",3) == 0) )
|
|
{
|
|
elem_blk_parms[i].elem_type_val = TRUSS;
|
|
/* determine side set node stride */
|
|
if (elem_blk_parms[i].num_nodes_per_elem == 2)
|
|
elem_blk_parms[i].num_nodes_per_side = 2;
|
|
else
|
|
elem_blk_parms[i].num_nodes_per_side = 3;
|
|
}
|
|
else if (strncmp(elem_blk_parms[i].elem_type,"NULL",3) == 0)
|
|
{
|
|
elem_blk_parms[i].elem_type_val = '\0';
|
|
/* set side set node stride */
|
|
elem_blk_parms[i].num_nodes_per_side = 0;
|
|
}
|
|
else
|
|
{ /* unsupported element type; no problem if no sides specified for
|
|
this element block */
|
|
elem_blk_parms[i].elem_type_val = UNK;
|
|
elem_blk_parms[i].num_nodes_per_side = 0;
|
|
}
|
|
elem_blk_parms[i].elem_blk_id = elem_blk_ids[i]; /* save id */
|
|
elem_ctr += elem_blk_parms[i].num_elem_in_blk;
|
|
elem_blk_parms[i].elem_ctr = elem_ctr; /* save elem number max */
|
|
}
|
|
|
|
|
|
/* Allocate space for the ss element to element block parameter index array */
|
|
if (!(ss_parm_ndx=malloc(tot_num_ss_elem*sizeof(int))))
|
|
{
|
|
free(elem_blk_parms);
|
|
free(elem_blk_ids);
|
|
free(ss_elem_ndx);
|
|
exerrval = EX_MEMFAIL;
|
|
sprintf(errmsg,
|
|
"Error: failed to allocate space for side set elem parms index for file id %d"
|
|
,
|
|
exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
return (EX_FATAL);
|
|
}
|
|
|
|
|
|
/* Allocate space for the ss element to node list index array */
|
|
if (!(ss_elem_node_ndx=malloc((tot_num_ss_elem+1)*sizeof(int))))
|
|
{
|
|
free(ss_parm_ndx);
|
|
free(elem_blk_parms);
|
|
free(elem_blk_ids);
|
|
free(ss_elem_ndx);
|
|
exerrval = EX_MEMFAIL;
|
|
sprintf(errmsg,
|
|
"Error: failed to allocate space for side set elem to node index for file id %d",
|
|
exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
return (EX_FATAL);
|
|
}
|
|
|
|
/* determine if each side set has uniform element types; this will
|
|
be used to help determine the stride through the node list
|
|
*/
|
|
|
|
/* Allocate space for same element type flag array*/
|
|
if (!(same_elem_type=malloc(num_side_sets*sizeof(int))))
|
|
{
|
|
free(ss_elem_ndx);
|
|
exerrval = EX_MEMFAIL;
|
|
sprintf(errmsg,
|
|
"Error: failed to allocate space for element type flag array for file id %d",
|
|
exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
return (EX_FATAL);
|
|
}
|
|
|
|
elem_ctr = num_elem_per_set[0];
|
|
same_elem_type[0] = TRUE;
|
|
for (i=0,k=0;i<tot_num_ss_elem;i++)
|
|
{
|
|
for (j=0; j<num_elem_blks; j++)
|
|
{
|
|
if (side_sets_elem_list[i] <= elem_blk_parms[j].elem_ctr) break;
|
|
}
|
|
|
|
if (i==0) {
|
|
el_type = elem_blk_parms[j].elem_type_val;
|
|
}
|
|
|
|
/* determine which side set this element is in; assign to kth side set */
|
|
if (i >= elem_ctr) {
|
|
elem_ctr += num_elem_per_set[++k];
|
|
el_type = elem_blk_parms[j].elem_type_val;
|
|
same_elem_type[k] = TRUE;
|
|
}
|
|
|
|
if (el_type != elem_blk_parms[j].elem_type_val) same_elem_type[k] = FALSE;
|
|
|
|
}
|
|
|
|
/* Build side set element to node list index and side set element
|
|
parameter index.
|
|
*/
|
|
node_ctr = 0;
|
|
elem_ctr = num_elem_per_set[0];
|
|
for (i=0,k=0;i<tot_num_ss_elem;i++)
|
|
{
|
|
for (j=0; j<num_elem_blks; j++)
|
|
{
|
|
if (side_sets_elem_list[i] <= elem_blk_parms[j].elem_ctr)
|
|
{
|
|
ss_parm_ndx[i] = j; /* assign parameter block index */
|
|
break;
|
|
}
|
|
}
|
|
ss_elem_node_ndx[i] = node_ctr; /* assign node list index */
|
|
|
|
/* determine which side set this element is in; assign to kth side set */
|
|
if (i >= elem_ctr) {
|
|
/* skip over NULL side sets */
|
|
while (num_elem_per_set[++k] == 0);
|
|
elem_ctr += num_elem_per_set[k];
|
|
}
|
|
|
|
/* determine number of nodes per side */
|
|
if (((num_nodes_per_set[k] % num_elem_per_set[k]) == 0) &&
|
|
(same_elem_type[k])) { /* all side set elements are same type */
|
|
node_ctr += num_nodes_per_set[k] /num_elem_per_set[k];
|
|
} else {
|
|
node_ctr += elem_blk_parms[j].num_nodes_per_side;
|
|
}
|
|
}
|
|
|
|
ss_elem_node_ndx[i] = node_ctr; /* assign node list index */
|
|
|
|
/* All setup, ready to go ... */
|
|
|
|
elem_ctr=0;
|
|
|
|
for (j=0; j < tot_num_ss_elem; j++)
|
|
{
|
|
|
|
if (side_sets_elem_list[ss_elem_ndx[j]] > elem_ctr)
|
|
{
|
|
/* release connectivity array space and get next one */
|
|
if (elem_ctr > 0)
|
|
free(connect);
|
|
|
|
/* Allocate space for the connectivity array for new element block */
|
|
if (!(connect=
|
|
malloc(elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].num_elem_in_blk*
|
|
elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].num_nodes_per_elem*
|
|
sizeof(int))))
|
|
{
|
|
exerrval = EX_MEMFAIL;
|
|
sprintf(errmsg,
|
|
"Error: failed to allocate space for connectivity array for file id %d",
|
|
exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
free(ss_elem_node_ndx);
|
|
free(ss_parm_ndx);
|
|
free(elem_blk_parms);
|
|
free(elem_blk_ids);
|
|
free(ss_elem_ndx);
|
|
return (EX_FATAL);
|
|
}
|
|
|
|
/* get connectivity array */
|
|
if (ex_get_elem_conn(
|
|
exoid,
|
|
elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_blk_id,
|
|
connect) == -1)
|
|
{
|
|
sprintf(errmsg,
|
|
"Error: failed to get connectivity array for elem blk %d for file id %d",
|
|
elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_blk_id,
|
|
exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
free(connect);
|
|
free(ss_elem_node_ndx);
|
|
free(ss_parm_ndx);
|
|
free(elem_blk_parms);
|
|
free(elem_blk_ids);
|
|
free(ss_elem_ndx);
|
|
return (EX_FATAL);
|
|
}
|
|
elem_ctr = elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_ctr;
|
|
}
|
|
/* For the first node of each side in side set, using a linear search
|
|
(of up to num_nodes_per_elem) of the connectivity array,
|
|
locate the node position in the element. The first node position
|
|
and the second node position are used with a element type specific
|
|
table to determine the side. */
|
|
|
|
elem_num = side_sets_elem_list[ss_elem_ndx[j]]-1;/* element number 0-based*/
|
|
/* calculate the relative element number position in it's block*/
|
|
elem_num_pos = elem_num -
|
|
(elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_ctr -
|
|
elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].num_elem_in_blk);
|
|
/* calculate the beginning of the node list for this element by
|
|
using the ss_elem_node_ndx index into the side_sets_node_index
|
|
and adding the element number position * number of nodes per elem */
|
|
|
|
num_nodes_per_elem =
|
|
elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].num_nodes_per_elem;
|
|
for (n=0; n<num_nodes_per_elem; n++)
|
|
{
|
|
/* find node in connectivity array that matches first node in side set */
|
|
if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]] ==
|
|
connect[num_nodes_per_elem*(elem_num_pos)+n])
|
|
{
|
|
switch (elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_type_val)
|
|
{
|
|
case CIRCLE:
|
|
case SPHERE:
|
|
{
|
|
/* simple case: 1st node number is same as side # */
|
|
side_sets_side_list[ss_elem_ndx[j]] = n+1;
|
|
break;
|
|
}
|
|
case QUAD:
|
|
case TRIANGLE:
|
|
case TRUSS:
|
|
case BEAM:
|
|
{
|
|
/* simple case: 1st node number is same as side # */
|
|
side_sets_side_list[ss_elem_ndx[j]] = n+1;
|
|
break;
|
|
}
|
|
case TRISHELL:
|
|
{
|
|
/* use table to find which node to compare to next */
|
|
num_node_per_side = ss_elem_node_ndx[ss_elem_ndx[j]+1] -
|
|
ss_elem_node_ndx[ss_elem_ndx[j]];
|
|
|
|
if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] ==
|
|
connect[num_nodes_per_elem*(elem_num_pos)+
|
|
(trishell_table[0][2*n]-1)])
|
|
{
|
|
/* Assume only front or back, no edges... */
|
|
side_sets_side_list[ss_elem_ndx[j]] = trishell_table[1][2*n];
|
|
}
|
|
else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] ==
|
|
connect[num_nodes_per_elem*(elem_num_pos)+
|
|
(trishell_table[0][2*n+1]-1)])
|
|
{
|
|
/* Assume only front or back, no edges... */
|
|
side_sets_side_list[ss_elem_ndx[j]] = trishell_table[1][2*n+1];
|
|
}
|
|
else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] ==
|
|
connect[num_nodes_per_elem*(elem_num_pos)+
|
|
(trishell_table[0][2*n+2]-1)])
|
|
{
|
|
/* Assume only front or back, no edges... */
|
|
side_sets_side_list[ss_elem_ndx[j]] = trishell_table[1][2*n+2];
|
|
}
|
|
else
|
|
{
|
|
exerrval = EX_BADPARAM;
|
|
sprintf(errmsg,
|
|
"Error: failed to find TRIANGULAR SHELL element %d, node %d in connectivity array %d for file id %d",
|
|
side_sets_elem_list[ss_elem_ndx[j]],
|
|
side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1],
|
|
elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_blk_id,
|
|
exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
free(connect);
|
|
free(ss_elem_node_ndx);
|
|
free(ss_parm_ndx);
|
|
free(elem_blk_parms);
|
|
free(elem_blk_ids);
|
|
free(ss_elem_ndx);
|
|
return (EX_FATAL);
|
|
}
|
|
break;
|
|
|
|
}
|
|
case SHELL:
|
|
{
|
|
/* use table to find which node to compare to next */
|
|
|
|
num_node_per_side = ss_elem_node_ndx[ss_elem_ndx[j]+1] -
|
|
ss_elem_node_ndx[ss_elem_ndx[j]];
|
|
|
|
if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] ==
|
|
connect[num_nodes_per_elem*(elem_num_pos)+
|
|
(shell_table[0][2*n]-1)])
|
|
{
|
|
if (num_node_per_side >= 4)
|
|
/* 4- or 8-node side (front or back face) */
|
|
side_sets_side_list[ss_elem_ndx[j]] = shell_table[1][2*n];
|
|
else
|
|
/* 2- or 3-node side (edge of shell) */
|
|
side_sets_side_list[ss_elem_ndx[j]] = shell_edge_table[1][2*n];
|
|
}
|
|
else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] ==
|
|
connect[num_nodes_per_elem*(elem_num_pos)+
|
|
(shell_table[0][2*n+1]-1)])
|
|
{
|
|
if (num_node_per_side >= 4)
|
|
/* 4- or 8-node side (front or back face) */
|
|
side_sets_side_list[ss_elem_ndx[j]] = shell_table[1][2*n+1];
|
|
else
|
|
/* 2- or 3-node side (edge of shell) */
|
|
side_sets_side_list[ss_elem_ndx[j]]=shell_edge_table[1][2*n+1];
|
|
}
|
|
else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] ==
|
|
connect[num_nodes_per_elem*(elem_num_pos)+
|
|
(shell_table[0][2*n+2]-1)])
|
|
{
|
|
if (num_node_per_side >= 4)
|
|
/* 4- or 8-node side (front or back face) */
|
|
side_sets_side_list[ss_elem_ndx[j]] = shell_table[1][2*n+2];
|
|
else
|
|
/* 2- or 3-node side (edge of shell) */
|
|
side_sets_side_list[ss_elem_ndx[j]]=shell_edge_table[1][2*n+2];
|
|
}
|
|
else
|
|
{
|
|
exerrval = EX_BADPARAM;
|
|
sprintf(errmsg,
|
|
"Error: failed to find SHELL element %d, node %d in connectivity array %d for file id %d",
|
|
side_sets_elem_list[ss_elem_ndx[j]],
|
|
side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1],
|
|
elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_blk_id,
|
|
exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
free(connect);
|
|
free(ss_elem_node_ndx);
|
|
free(ss_parm_ndx);
|
|
free(elem_blk_parms);
|
|
free(elem_blk_ids);
|
|
free(ss_elem_ndx);
|
|
return (EX_FATAL);
|
|
}
|
|
break;
|
|
|
|
}
|
|
case HEX:
|
|
{
|
|
/* use table to find which node to compare to next */
|
|
|
|
if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] ==
|
|
connect[num_nodes_per_elem*(elem_num_pos)+
|
|
(hex_table[0][3*n]-1)])
|
|
side_sets_side_list[ss_elem_ndx[j]] = hex_table[1][3*n];
|
|
else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] ==
|
|
connect[num_nodes_per_elem*(elem_num_pos)+
|
|
(hex_table[0][3*n+1]-1)])
|
|
side_sets_side_list[ss_elem_ndx[j]] = hex_table[1][3*n+1];
|
|
else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] ==
|
|
connect[num_nodes_per_elem*(elem_num_pos)+
|
|
(hex_table[0][3*n+2]-1)])
|
|
side_sets_side_list[ss_elem_ndx[j]] = hex_table[1][3*n+2];
|
|
else
|
|
{
|
|
exerrval = EX_BADPARAM;
|
|
sprintf(errmsg,
|
|
"Error: failed to find HEX element %d, node %d in connectivity array %d for file id %d",
|
|
side_sets_elem_list[ss_elem_ndx[j]],
|
|
side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1],
|
|
elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_blk_id,
|
|
exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
free(connect);
|
|
free(ss_elem_node_ndx);
|
|
free(ss_parm_ndx);
|
|
free(elem_blk_parms);
|
|
free(elem_blk_ids);
|
|
free(ss_elem_ndx);
|
|
return (EX_FATAL);
|
|
}
|
|
break;
|
|
}
|
|
case TETRA:
|
|
{
|
|
/* use table to find which node to compare to next */
|
|
|
|
if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] ==
|
|
connect[num_nodes_per_elem*(elem_num_pos)+
|
|
(tetra_table[0][3*n]-1)])
|
|
side_sets_side_list[ss_elem_ndx[j]] = tetra_table[1][3*n];
|
|
else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] ==
|
|
connect[num_nodes_per_elem*(elem_num_pos)+
|
|
(tetra_table[0][3*n+1]-1)])
|
|
side_sets_side_list[ss_elem_ndx[j]] = tetra_table[1][3*n+1];
|
|
else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] ==
|
|
connect[num_nodes_per_elem*(elem_num_pos)+
|
|
(tetra_table[0][3*n+2]-1)])
|
|
side_sets_side_list[ss_elem_ndx[j]] = tetra_table[1][3*n+2];
|
|
else
|
|
{
|
|
exerrval = EX_BADPARAM;
|
|
sprintf(errmsg,
|
|
"Error: failed to find TETRA element %d, node %d in connectivity array %d for file id %d",
|
|
side_sets_elem_list[ss_elem_ndx[j]],
|
|
side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1],
|
|
elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_blk_id,
|
|
exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
free(connect);
|
|
free(ss_elem_node_ndx);
|
|
free(ss_parm_ndx);
|
|
free(elem_blk_parms);
|
|
free(elem_blk_ids);
|
|
free(ss_elem_ndx);
|
|
return (EX_FATAL);
|
|
}
|
|
break;
|
|
}
|
|
case PYRAMID:
|
|
{
|
|
/* NOTE: PYRAMID elements in side set node lists are currently not supported */
|
|
exerrval = EX_BADPARAM;
|
|
sprintf(errmsg,
|
|
"ERROR: unsupported PYRAMID element found in side set node list in file id %d",
|
|
exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
free(connect);
|
|
free(ss_elem_node_ndx);
|
|
free(ss_parm_ndx);
|
|
free(elem_blk_parms);
|
|
free(elem_blk_ids);
|
|
free(ss_elem_ndx);
|
|
return (EX_FATAL);
|
|
}
|
|
case WEDGE:
|
|
{
|
|
#if 1
|
|
/* NOTE: WEDGE elements in side set node lists are currently not supported */
|
|
exerrval = EX_BADPARAM;
|
|
sprintf(errmsg,
|
|
"ERROR: unsupported WEDGE element found in side set node list in file id %d",
|
|
exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
free(connect);
|
|
free(ss_elem_node_ndx);
|
|
free(ss_parm_ndx);
|
|
free(elem_blk_parms);
|
|
free(elem_blk_ids);
|
|
free(ss_elem_ndx);
|
|
return (EX_FATAL);
|
|
|
|
#else
|
|
/* use wedge_table to find which node to compare to next */
|
|
|
|
/* This section is commented out because Wedges are no longer supported !!!*/
|
|
|
|
if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] ==
|
|
connect[num_nodes_per_elem*(elem_num_pos)+
|
|
(wedge_table[0][3*n]-1)])
|
|
side_sets_side_list[ss_elem_ndx[j]] = wedge_table[1][3*n];
|
|
else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] ==
|
|
connect[num_nodes_per_elem*(elem_num_pos)+
|
|
(wedge_table[0][3*n+1]-1)])
|
|
side_sets_side_list[ss_elem_ndx[j]] = wedge_table[1][3*n+1];
|
|
else if (side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1] ==
|
|
connect[num_nodes_per_elem*(elem_num_pos)+
|
|
(wedge_table[0][3*n+2]-1)])
|
|
side_sets_side_list[ss_elem_ndx[j]] = wedge_table[1][3*n+2];
|
|
else
|
|
{
|
|
exerrval = EX_BADPARAM;
|
|
sprintf(errmsg,
|
|
"Error: failed to find WEDGE element %d, node %d in connectivity array %d for file id %d",
|
|
side_sets_elem_list[ss_elem_ndx[j]],
|
|
side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]+1],
|
|
elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_blk_id,
|
|
exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
free(connect);
|
|
free(ss_elem_node_ndx);
|
|
free(ss_parm_ndx);
|
|
free(elem_blk_parms);
|
|
free(elem_blk_ids);
|
|
free(ss_elem_ndx);
|
|
return (EX_FATAL);
|
|
}
|
|
break;
|
|
#endif
|
|
}
|
|
default:
|
|
{
|
|
exerrval = EX_BADPARAM;
|
|
sprintf(errmsg,
|
|
"Error: %s is an unsupported element type",
|
|
elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_type);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
return(EX_FATAL);
|
|
}
|
|
}
|
|
break; /* done with this element */
|
|
}
|
|
}
|
|
if (n >= num_nodes_per_elem) /* did we find the node? */
|
|
{
|
|
exerrval = EX_BADPARAM;
|
|
sprintf(errmsg,
|
|
"Error: failed to find element %d, node %d in element block %d for file id %d",
|
|
side_sets_elem_list[ss_elem_ndx[j]],
|
|
side_sets_node_list[ss_elem_node_ndx[ss_elem_ndx[j]]],
|
|
elem_blk_parms[ss_parm_ndx[ss_elem_ndx[j]]].elem_blk_id,
|
|
exoid);
|
|
ex_err("ex_cvt_nodes_to_sides",errmsg,exerrval);
|
|
free(connect);
|
|
free(ss_elem_node_ndx);
|
|
free(ss_parm_ndx);
|
|
free(elem_blk_parms);
|
|
free(elem_blk_ids);
|
|
free(ss_elem_ndx);
|
|
return (EX_FATAL);
|
|
}
|
|
|
|
}
|
|
|
|
/* All done: release connectivity array space, element block ids array,
|
|
element block parameters array, and side set element index array */
|
|
free(connect);
|
|
free(ss_elem_node_ndx);
|
|
free(ss_parm_ndx);
|
|
free(elem_blk_parms);
|
|
free(elem_blk_ids);
|
|
free(ss_elem_ndx);
|
|
|
|
return (EX_NOERR);
|
|
}
|
|
|
|
|