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.
2457 lines
65 KiB
2457 lines
65 KiB
/*
|
|
* Copyright(C) 1999-2020, 2023 National Technology & Engineering Solutions
|
|
* of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
|
|
* NTESS, the U.S. Government retains certain rights in this software.
|
|
*
|
|
* See packages/seacas/LICENSE for details
|
|
*/
|
|
|
|
#include "elb_elem.h"
|
|
#include "elb_err.h" // for error_report, Gen_Error
|
|
#include "elb_util.h" // for in_list
|
|
#include <cstddef> // for size_t
|
|
#include <cstdlib> // for exit
|
|
#include <cstring> // for strncasecmp
|
|
#include <fmt/ostream.h>
|
|
#include <vector> // for vector
|
|
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
namespace {
|
|
template <typename INT>
|
|
inline int numbermatch(INT *sidenodes, size_t i, size_t j, size_t k, size_t value)
|
|
{
|
|
if ((size_t)sidenodes[(i + j) % k] == value) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
} // namespace
|
|
|
|
/*****************************************************************************/
|
|
/* Function get_elem_type() begins:
|
|
*----------------------------------------------------------------------------
|
|
* This function returns the type of element based on the ExodusII element
|
|
* string and number of nodes.
|
|
*
|
|
* Need the number of dimensions in order to distinguish between
|
|
* TRI elements in a 2d mesh from TRI elements in a 3d mesh.
|
|
*****************************************************************************/
|
|
const char *elem_name_from_enum(const E_Type elem_type)
|
|
{
|
|
static const char *elem_names[NULL_EL] = {
|
|
"SPHERE", "BAR2", "BAR3", "QUAD4", "QUAD8", "QUAD9", "SHELL4",
|
|
"SHELL8", "SHELL9", "TRI3", "TRI4", "TRI6", "TRI7", "TSHELL3",
|
|
"TSHELL4", "TSHELL6", "TSHELL7", "HEX8", "HEX16", "HEX20", "HEX27",
|
|
"HEXSHELL", "TET4", "TET10", "TET8", "TET14", "TET15", "WEDGE6",
|
|
"WEDGE12", "WEDGE15", "WEDGE16", "WEDGE20", "WEDGE21", "PYRAMID5", "PYRAMID13",
|
|
"PYRAMID14", "PYRAMID18", "PYRAMID19", "SHELL2", "SHELL3"};
|
|
return elem_names[elem_type];
|
|
}
|
|
|
|
E_Type get_elem_type(const char *elem_name, const int num_nodes, const int num_dim)
|
|
{
|
|
|
|
E_Type answer = NULL_EL;
|
|
switch (elem_name[0]) {
|
|
case 'h':
|
|
case 'H':
|
|
if (strncasecmp(elem_name, "HEX", 3) == 0) {
|
|
switch (num_nodes) {
|
|
case 8: answer = HEX8; break;
|
|
case 12: answer = HEXSHELL; break;
|
|
case 16: answer = HEX16; break;
|
|
case 20: answer = HEX20; break;
|
|
case 27: answer = HEX27; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unsupported HEX element");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'c':
|
|
case 'C':
|
|
if (strncasecmp(elem_name, "CIRCLE", 6) == 0) {
|
|
answer = SPHERE;
|
|
}
|
|
break;
|
|
|
|
case 's':
|
|
case 'S':
|
|
if (strncasecmp(elem_name, "SPHERE", 6) == 0) {
|
|
answer = SPHERE;
|
|
}
|
|
else if (strncasecmp(elem_name, "SHELL", 5) == 0) {
|
|
switch (num_nodes) {
|
|
case 2:
|
|
if (num_dim == 2) {
|
|
answer = SHELL2;
|
|
}
|
|
else {
|
|
Gen_Error(0, "fatal: unsupported SHELL element");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
case 3:
|
|
if (num_dim == 2) {
|
|
answer = SHELL3;
|
|
}
|
|
else {
|
|
Gen_Error(0, "fatal: unsupported SHELL element");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
case 4: answer = SHELL4; break;
|
|
case 8: answer = SHELL8; break;
|
|
case 9: answer = SHELL9; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unsupported SHELL element");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'b':
|
|
case 'B':
|
|
case 't':
|
|
case 'T':
|
|
case 'r':
|
|
case 'R':
|
|
if (strncasecmp(elem_name, "BEAM", 4) == 0 || strncasecmp(elem_name, "TRUSS", 5) == 0 ||
|
|
strncasecmp(elem_name, "ROD", 3) == 0 || strncasecmp(elem_name, "BAR", 3) == 0) {
|
|
switch (num_nodes) {
|
|
case 2: answer = BAR2; break;
|
|
case 3: answer = BAR3; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unsupported BAR/BEAM/TRUSS element");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
}
|
|
else if (strncasecmp(elem_name, "TRI", 3) == 0) {
|
|
switch (num_nodes) {
|
|
case 3:
|
|
if (num_dim == 2) {
|
|
answer = TRI3;
|
|
}
|
|
else {
|
|
answer = TSHELL3;
|
|
}
|
|
break;
|
|
case 4:
|
|
if (num_dim == 2) {
|
|
answer = TRI4;
|
|
}
|
|
else {
|
|
answer = TSHELL4;
|
|
}
|
|
break;
|
|
case 6:
|
|
if (num_dim == 2) {
|
|
answer = TRI6;
|
|
}
|
|
else {
|
|
answer = TSHELL6;
|
|
}
|
|
break;
|
|
case 7:
|
|
if (num_dim == 2) {
|
|
answer = TRI7;
|
|
}
|
|
else {
|
|
answer = TSHELL7;
|
|
}
|
|
break;
|
|
default:
|
|
Gen_Error(0, "fatal: unsupported TRI element");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
}
|
|
else if (strncasecmp(elem_name, "TET", 3) == 0) {
|
|
switch (num_nodes) {
|
|
case 4: answer = TET4; break;
|
|
case 8: answer = TET8; break;
|
|
case 10: answer = TET10; break;
|
|
case 14: answer = TET14; break;
|
|
case 15: answer = TET15; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unsupported TET element");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'q':
|
|
case 'Q':
|
|
if (strncasecmp(elem_name, "QUAD", 4) == 0) {
|
|
switch (num_nodes) {
|
|
case 4:
|
|
if (num_dim == 2) {
|
|
answer = QUAD4;
|
|
}
|
|
else {
|
|
answer = SHELL4;
|
|
}
|
|
break;
|
|
case 8:
|
|
if (num_dim == 2) {
|
|
answer = QUAD8;
|
|
}
|
|
else {
|
|
answer = SHELL8;
|
|
}
|
|
break;
|
|
case 9:
|
|
if (num_dim == 2) {
|
|
answer = QUAD9;
|
|
}
|
|
else {
|
|
answer = SHELL9;
|
|
}
|
|
break;
|
|
default:
|
|
Gen_Error(0, "fatal: unsupported QUAD element");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'w':
|
|
case 'W':
|
|
if (strncasecmp(elem_name, "WEDGE", 5) == 0) {
|
|
switch (num_nodes) {
|
|
case 6: answer = WEDGE6; break;
|
|
case 12: answer = WEDGE12; break;
|
|
case 15: answer = WEDGE15; break;
|
|
case 16: answer = WEDGE16; break;
|
|
case 20: answer = WEDGE20; break;
|
|
case 21: answer = WEDGE21; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unsupported WEDGE element");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'p':
|
|
case 'P':
|
|
if (strncasecmp(elem_name, "PYR", 3) == 0) {
|
|
switch (num_nodes) {
|
|
case 5: answer = PYRAMID5; break;
|
|
case 13: answer = PYRAMID13; break;
|
|
case 14: answer = PYRAMID14; break;
|
|
case 18: answer = PYRAMID18; break;
|
|
case 19: answer = PYRAMID19; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unsupported PYRAMID element");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default: break;
|
|
}
|
|
|
|
if (answer == NULL_EL) {
|
|
std::string errstr;
|
|
errstr = fmt::format("fatal: unknown element type '{}' read", elem_name);
|
|
Gen_Error(0, errstr);
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
|
|
return answer;
|
|
|
|
} /*---------------------------End get_elem_type()---------------------------*/
|
|
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
/* Convenience functions for code readability
|
|
*****************************************************************************/
|
|
int is_hex(E_Type etype)
|
|
{
|
|
return static_cast<int>(etype == HEX8 || etype == HEX27 || etype == HEX20 || etype == HEXSHELL);
|
|
}
|
|
|
|
int is_tet(E_Type etype)
|
|
{
|
|
return static_cast<int>(etype == TET4 || etype == TET10 || etype == TET8 || etype == TET14 ||
|
|
etype == TET15);
|
|
}
|
|
|
|
int is_wedge(E_Type etype)
|
|
{
|
|
return static_cast<int>(etype == WEDGE6 || etype == WEDGE15 || etype == WEDGE16 ||
|
|
etype == WEDGE20 || etype == WEDGE21);
|
|
}
|
|
|
|
int is_pyramid(E_Type etype)
|
|
{
|
|
return static_cast<int>(etype == PYRAMID5 || etype == PYRAMID13 || etype == PYRAMID14 ||
|
|
etype == PYRAMID18 || etype == PYRAMID19);
|
|
}
|
|
|
|
int is_3d_element(E_Type etype)
|
|
{
|
|
return static_cast<int>((is_hex(etype) != 0) || (is_tet(etype) != 0) || (is_wedge(etype) != 0) ||
|
|
(is_pyramid(etype) != 0));
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
/* Function get_elem_info() begins:
|
|
*----------------------------------------------------------------------------
|
|
* This function returns various information about the input element type.
|
|
*****************************************************************************/
|
|
int get_elem_info(const int req, const E_Type etype)
|
|
{
|
|
|
|
int answer = 0;
|
|
|
|
switch (etype) /* Switch over the element type */
|
|
{
|
|
case BAR2:
|
|
switch (req) {
|
|
case NNODES: answer = 2; break;
|
|
case NSIDE_NODES: answer = 2; break;
|
|
case NSIDES: answer = 1; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 1; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case SHELL2:
|
|
switch (req) {
|
|
case NNODES: answer = 2; break;
|
|
case NSIDE_NODES: answer = 2; break;
|
|
case NSIDES: answer = 1; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 1; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case SHELL3:
|
|
switch (req) {
|
|
case NNODES: answer = 3; break;
|
|
case NSIDE_NODES: answer = 2; break;
|
|
case NSIDES: answer = 1; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 1; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case BAR3:
|
|
switch (req) {
|
|
case NNODES: answer = 3; break;
|
|
case NSIDE_NODES: answer = 2; break;
|
|
case NSIDES: answer = 1; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 1; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case SPHERE:
|
|
switch (req) {
|
|
case NNODES: answer = 1; break;
|
|
case NSIDE_NODES: answer = 0; break;
|
|
case NSIDES: answer = 0; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
}
|
|
break;
|
|
|
|
case QUAD4: /* First order quad */
|
|
switch (req) /* select type of information required*/
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 4; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 2; break;
|
|
case NSIDE_NODES: answer = 2; break;
|
|
case NSIDES: answer = 4; break;
|
|
default:
|
|
Gen_Error(0, "fatal:unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case QUAD8: /* 2nd order serendipity quad */
|
|
switch (req) /* select type of information required */
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 8; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 2; break;
|
|
case NSIDE_NODES: answer = 3; break;
|
|
case NSIDES: answer = 4; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case QUAD9: /* biquadratic quadrilateral */
|
|
switch (req) /* select type of information required */
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 9; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 2; break;
|
|
case NSIDE_NODES: answer = 3; break;
|
|
case NSIDES: answer = 4; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
/* NOTE: cannot determine NSIDE_NODES for SHELL element */
|
|
case SHELL4:
|
|
switch (req) {
|
|
case NNODES: answer = 4; break;
|
|
case NSIDES: answer = 6; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 2; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case SHELL8:
|
|
switch (req) {
|
|
case NNODES: answer = 8; break;
|
|
case NSIDES: answer = 6; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 2; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case SHELL9:
|
|
switch (req) {
|
|
case NNODES: answer = 9; break;
|
|
case NSIDES: answer = 6; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 2; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case TRI3:
|
|
switch (req) /* select type of information required */
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 3; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 2; break;
|
|
case NSIDE_NODES: answer = 2; break;
|
|
case NSIDES: answer = 3; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case TRI4:
|
|
switch (req) /* select type of information required */
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 4; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 2; break;
|
|
case NSIDE_NODES: answer = 2; break;
|
|
case NSIDES: answer = 3; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case TRI6:
|
|
switch (req) /* select type of information required */
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 6; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 2; break;
|
|
case NSIDE_NODES: answer = 3; break;
|
|
case NSIDES: answer = 3; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case TRI7:
|
|
switch (req) /* select type of information required */
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 7; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 2; break;
|
|
case NSIDE_NODES: answer = 3; break;
|
|
case NSIDES: answer = 3; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
/* NOTE: cannot determine NSIDE_NODES for TSHELL element */
|
|
case TSHELL3:
|
|
switch (req) /* select type of information required */
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 3; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 2; break;
|
|
case NSIDES: answer = 5; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case TSHELL4:
|
|
switch (req) /* select type of information required */
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 4; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 2; break;
|
|
case NSIDES: answer = 5; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case TSHELL6:
|
|
switch (req) /* select type of information required */
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 6; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 2; break;
|
|
case NSIDES: answer = 5; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case TSHELL7:
|
|
switch (req) /* select type of information required */
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 7; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 2; break;
|
|
case NSIDES: answer = 5; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case HEX8: /* trilinear hexahedron */
|
|
switch (req) /* select type of information required */
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 8; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
case NSIDE_NODES: answer = 4; break;
|
|
case NSIDES: answer = 6; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case HEX16: /* localization element NSNODES is not consistent... */
|
|
switch (req) {
|
|
case NNODES: /* number of nodes */ answer = 16; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
case NSIDES: answer = 6; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case HEX20: /* serendipity triquadratic hexahedron */
|
|
switch (req) /* select type of information required */
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 20; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
case NSIDE_NODES: answer = 8; break;
|
|
case NSIDES: answer = 6; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case HEX27: /* triquadratic hexahedron */
|
|
switch (req) /* select type of information required*/
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 27; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
case NSIDE_NODES: answer = 9; break;
|
|
case NSIDES: answer = 6; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
/* NOTE: cannot determine NSIDE_NODES for HEXSHELL element */
|
|
case HEXSHELL:
|
|
switch (req) {
|
|
case NNODES: answer = 12; break;
|
|
case NSIDES: answer = 6; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case TET4: /* trilinear tetrahedron */
|
|
switch (req) /* select type of information required*/
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 4; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
case NSIDE_NODES: answer = 3; break;
|
|
case NSIDES: answer = 4; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case TET10: /* triquadradic tetrahedron */
|
|
switch (req) /* select type of information required */
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 10; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
case NSIDE_NODES: answer = 6; break;
|
|
case NSIDES: answer = 4; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case TET14:
|
|
switch (req) /* select type of information required */
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 14; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
case NSIDE_NODES: answer = 7; break;
|
|
case NSIDES: answer = 4; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case TET15:
|
|
switch (req) /* select type of information required */
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 15; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
case NSIDE_NODES: answer = 7; break;
|
|
case NSIDES: answer = 4; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case TET8: /* 8-node (midface nodes) tetrahedron */
|
|
switch (req) /* select type of information required */
|
|
{
|
|
case NNODES: /* number of nodes */ answer = 8; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
case NSIDE_NODES: answer = 4; break;
|
|
case NSIDES: answer = 4; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
/* NOTE: cannot determine NSIDE_NODES for WEDGE elements */
|
|
case WEDGE6:
|
|
switch (req) {
|
|
case NNODES: answer = 6; break;
|
|
case NSIDES: answer = 5; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case WEDGE12:
|
|
switch (req) {
|
|
case NNODES: answer = 12; break;
|
|
case NSIDES: answer = 5; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case WEDGE15:
|
|
switch (req) {
|
|
case NNODES: answer = 15; break;
|
|
case NSIDES: answer = 5; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case WEDGE16:
|
|
switch (req) {
|
|
case NNODES: answer = 16; break;
|
|
case NSIDES: answer = 5; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case WEDGE20:
|
|
switch (req) {
|
|
case NNODES: answer = 20; break;
|
|
case NSIDES: answer = 5; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case WEDGE21:
|
|
switch (req) {
|
|
case NNODES: answer = 21; break;
|
|
case NSIDES: answer = 5; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
/* NOTE: cannot determine NSIDE_NODES for PYRAMID element */
|
|
case PYRAMID5:
|
|
switch (req) {
|
|
case NNODES: answer = 5; break;
|
|
case NSIDES: answer = 5; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case PYRAMID13:
|
|
switch (req) {
|
|
case NNODES: answer = 13; break;
|
|
case NSIDES: answer = 5; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case PYRAMID14:
|
|
switch (req) {
|
|
case NNODES: answer = 14; break;
|
|
case NSIDES: answer = 5; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case PYRAMID18:
|
|
switch (req) {
|
|
case NNODES: answer = 18; break;
|
|
case NSIDES: answer = 5; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
case PYRAMID19:
|
|
switch (req) {
|
|
case NNODES: answer = 19; break;
|
|
case NSIDES: answer = 5; break;
|
|
case NDIM: /* number of physical dimensions */ answer = 3; break;
|
|
default:
|
|
Gen_Error(0, "fatal: unknown quantity");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
Gen_Error(0, "fatal: unknown or unimplemented element type");
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
|
|
return answer;
|
|
|
|
} /*---------------------------End get_elem_info()---------------------------*/
|
|
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
/* Function get_side_id() begins:
|
|
*----------------------------------------------------------------------------
|
|
* This function returns the Side ID (as used in ExodusII) given a list of
|
|
* nodes on that side.
|
|
*
|
|
* Changed so that it is now order dependent, but independent of starting
|
|
* node for 3-D sides. On 2-D sides (lines), the starting node is important.
|
|
*
|
|
* Now supoports degenerate faces in HEX elements.
|
|
*****************************************************************************/
|
|
template int get_side_id(const E_Type etype, const int *connect, const int nsnodes,
|
|
int side_nodes[], const int skip_check, const int partial_adj);
|
|
template int get_side_id(const E_Type etype, const int64_t *connect, const int nsnodes,
|
|
int64_t side_nodes[], const int skip_check, const int partial_adj);
|
|
|
|
template <typename INT>
|
|
int get_side_id(const E_Type etype, const INT *connect, const int nsnodes, INT side_nodes[],
|
|
const int skip_check, const int partial_adj)
|
|
{
|
|
int dup;
|
|
int location[9];
|
|
int count;
|
|
/* min_match for hex elements means that min_match+1 nodes
|
|
on a face of a hex must match to return the side of the
|
|
hex on which the nodes exist, i.e., if 3/4 nodes of a hex
|
|
match, then it might be considered connected. If it is
|
|
connected, then min_match states if 3/4 nodes is considered a face of
|
|
a hex or not */
|
|
|
|
/* Default for min_match is 3, 2 is trial and error stuff */
|
|
|
|
const int min_match = 3;
|
|
/* const int min_match = 2; */
|
|
|
|
/* check if this is a degenerate face */
|
|
dup = 0;
|
|
for (int i = 0; i < (nsnodes - 1); i++) {
|
|
for (int j = (i + 1); j < nsnodes; j++) {
|
|
if (side_nodes[i] == side_nodes[j]) {
|
|
location[dup++] = i; /* location of duplicated node */
|
|
}
|
|
}
|
|
}
|
|
|
|
int nnodes = get_elem_info(NNODES, etype);
|
|
|
|
/* Find all of the side nodes in the connect table */
|
|
int num = 0;
|
|
for (int i = 0; i < nnodes; i++) {
|
|
for (int j = 0; j < nsnodes; j++) {
|
|
if (connect[i] == side_nodes[j]) {
|
|
num++;
|
|
break;
|
|
}
|
|
}
|
|
if (num == nsnodes) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* I commented out the conditional statement causing the
|
|
error if 2 hexes only share 3 out of 4 nodes. I replaced
|
|
this with what is seen below. It works, but only for
|
|
this particular case */
|
|
|
|
/* the following ifdef is used to determine face adjacency
|
|
old way: numnodes on face must match on both elements
|
|
new way: only 3/4 of hex nodes have to match to be face adjacent */
|
|
|
|
if (((partial_adj == 1) && (num < nsnodes - 1) && (num >= 2)) ||
|
|
((partial_adj != 1) && (num != nsnodes))) {
|
|
if (skip_check) {
|
|
if (skip_check == 1) /* print only if skip_check is 1 (not > 1) */
|
|
Gen_Error(0, "warning: not all side nodes in connect table for element");
|
|
}
|
|
else {
|
|
Gen_Error(0, "fatal: not all side nodes in connect table for element");
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if ((partial_adj == 1) && (num != nsnodes)) {
|
|
return 0;
|
|
}
|
|
|
|
/* Find the side ID */
|
|
switch (etype) {
|
|
case BAR2:
|
|
case BAR3:
|
|
case SHELL2:
|
|
case SHELL3:
|
|
/* SIDE 1 */
|
|
if (side_nodes[0] == connect[0] && side_nodes[1] == connect[1]) {
|
|
return 1;
|
|
}
|
|
break;
|
|
case QUAD4:
|
|
case QUAD8:
|
|
case QUAD9:
|
|
/* SIDE 1 */
|
|
if (side_nodes[0] == connect[0] && side_nodes[1] == connect[1]) {
|
|
return 1;
|
|
}
|
|
|
|
/* SIDE 2 */
|
|
if (side_nodes[0] == connect[1] && side_nodes[1] == connect[2]) {
|
|
return 2;
|
|
}
|
|
|
|
/* SIDE 3 */
|
|
if (side_nodes[0] == connect[2] && side_nodes[1] == connect[3]) {
|
|
return 3;
|
|
}
|
|
|
|
/* SIDE 4 */
|
|
if (side_nodes[0] == connect[3] && side_nodes[1] == connect[0]) {
|
|
return 4;
|
|
}
|
|
|
|
break;
|
|
|
|
case TRI3:
|
|
case TRI4:
|
|
case TRI6:
|
|
case TRI7:
|
|
/* SIDE 1 */
|
|
if (side_nodes[0] == connect[0] && side_nodes[1] == connect[1]) {
|
|
return 1;
|
|
}
|
|
|
|
/* SIDE 2 */
|
|
if (side_nodes[0] == connect[1] && side_nodes[1] == connect[2]) {
|
|
return 2;
|
|
}
|
|
|
|
/* SIDE 3 */
|
|
if (side_nodes[0] == connect[2] && side_nodes[1] == connect[0]) {
|
|
return 3;
|
|
}
|
|
|
|
break;
|
|
|
|
case TET4:
|
|
case TET10:
|
|
case TET14:
|
|
case TET15:
|
|
case TET8:
|
|
/* check the # of side nodes */
|
|
if (nsnodes < 3) {
|
|
return 0;
|
|
}
|
|
|
|
/* SIDE 1, 3, or 4 */
|
|
if ((num = in_list(connect[0], nsnodes, side_nodes)) >= 0) {
|
|
if (side_nodes[(1 + num) % 3] == connect[1] && side_nodes[(2 + num) % 3] == connect[3]) {
|
|
return 1;
|
|
}
|
|
if (side_nodes[(1 + num) % 3] == connect[3] && side_nodes[(2 + num) % 3] == connect[2]) {
|
|
return 3;
|
|
}
|
|
if (side_nodes[(1 + num) % 3] == connect[2] && side_nodes[(2 + num) % 3] == connect[1]) {
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
/* SIDE 2 */
|
|
if ((num = in_list(connect[1], nsnodes, side_nodes)) >= 0) {
|
|
if (side_nodes[(1 + num) % 3] == connect[2] && side_nodes[(2 + num) % 3] == connect[3]) {
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case HEX8:
|
|
case HEX16:
|
|
case HEX20:
|
|
case HEX27:
|
|
case HEXSHELL: /* this should be the same as a HEX element */
|
|
/* check the # of side nodes */
|
|
if (nsnodes < 4) {
|
|
return 0;
|
|
}
|
|
|
|
/* SIDE 1 */
|
|
if ((num = in_list(connect[0], nsnodes, side_nodes)) >= 0) {
|
|
count = 0;
|
|
count += numbermatch(side_nodes, 1, num, 4, connect[1]);
|
|
count += numbermatch(side_nodes, 2, num, 4, connect[5]);
|
|
count += numbermatch(side_nodes, 3, num, 4, connect[4]);
|
|
if (count >= min_match) {
|
|
return 1;
|
|
}
|
|
|
|
/* if this is the duplicated node, then find the next occurrence */
|
|
if (dup) {
|
|
for (int i = 0; i < dup; i++) {
|
|
if (connect[0] == side_nodes[location[i]]) {
|
|
num = in_list(connect[0], (nsnodes - num), &(side_nodes[num + 1])) + location[i] + 1;
|
|
count = 0;
|
|
count += numbermatch(side_nodes, 1, num, 4, connect[1]);
|
|
count += numbermatch(side_nodes, 2, num, 4, connect[5]);
|
|
count += numbermatch(side_nodes, 3, num, 4, connect[4]);
|
|
if (count >= min_match) {
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* SIDE 2 */
|
|
if ((num = in_list(connect[1], nsnodes, side_nodes)) >= 0) {
|
|
count = 0;
|
|
count += numbermatch(side_nodes, 1, num, 4, connect[2]);
|
|
count += numbermatch(side_nodes, 2, num, 4, connect[6]);
|
|
count += numbermatch(side_nodes, 3, num, 4, connect[5]);
|
|
if (count >= min_match) {
|
|
return 2;
|
|
}
|
|
|
|
/* if this is the duplicated node, then find the next occurrence */
|
|
if (dup) {
|
|
for (int i = 0; i < dup; i++) {
|
|
if (connect[1] == side_nodes[location[i]]) {
|
|
num = in_list(connect[1], (nsnodes - num), &(side_nodes[num + 1])) + location[i] + 1;
|
|
count = 0;
|
|
count += numbermatch(side_nodes, 1, num, 4, connect[2]);
|
|
count += numbermatch(side_nodes, 2, num, 4, connect[6]);
|
|
count += numbermatch(side_nodes, 3, num, 4, connect[5]);
|
|
if (count >= min_match) {
|
|
return 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* SIDE 3 */
|
|
if ((num = in_list(connect[2], nsnodes, side_nodes)) >= 0) {
|
|
count = 0;
|
|
count += numbermatch(side_nodes, 1, num, 4, connect[3]);
|
|
count += numbermatch(side_nodes, 2, num, 4, connect[7]);
|
|
count += numbermatch(side_nodes, 3, num, 4, connect[6]);
|
|
if (count >= min_match) {
|
|
return 3;
|
|
}
|
|
|
|
/* if this is the duplicated node, then find the next occurrence */
|
|
if (dup) {
|
|
for (int i = 0; i < dup; i++) {
|
|
if (connect[2] == side_nodes[location[i]]) {
|
|
num = in_list(connect[2], (nsnodes - num), &(side_nodes[num + 1])) + location[i] + 1;
|
|
count = 0;
|
|
count += numbermatch(side_nodes, 1, num, 4, connect[3]);
|
|
count += numbermatch(side_nodes, 2, num, 4, connect[7]);
|
|
count += numbermatch(side_nodes, 3, num, 4, connect[6]);
|
|
if (count >= min_match) {
|
|
return 3;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* SIDE 4 */
|
|
if ((num = in_list(connect[3], nsnodes, side_nodes)) >= 0) {
|
|
count = 0;
|
|
count += numbermatch(side_nodes, 1, num, 4, connect[0]);
|
|
count += numbermatch(side_nodes, 2, num, 4, connect[4]);
|
|
count += numbermatch(side_nodes, 3, num, 4, connect[7]);
|
|
if (count >= min_match) {
|
|
return 4;
|
|
}
|
|
|
|
/* if this is the duplicated node, then find the next occurrence */
|
|
if (dup) {
|
|
for (int i = 0; i < dup; i++) {
|
|
if (connect[3] == side_nodes[location[i]]) {
|
|
num = in_list(connect[3], (nsnodes - num), &(side_nodes[num + 1])) + location[i] + 1;
|
|
count = 0;
|
|
count += numbermatch(side_nodes, 1, num, 4, connect[0]);
|
|
count += numbermatch(side_nodes, 2, num, 4, connect[4]);
|
|
count += numbermatch(side_nodes, 3, num, 4, connect[7]);
|
|
if (count >= min_match) {
|
|
return 4;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* SIDE 5 */
|
|
if ((num = in_list(connect[0], nsnodes, side_nodes)) >= 0) {
|
|
count = 0;
|
|
count += numbermatch(side_nodes, 1, num, 4, connect[3]);
|
|
count += numbermatch(side_nodes, 2, num, 4, connect[2]);
|
|
count += numbermatch(side_nodes, 3, num, 4, connect[1]);
|
|
if (count >= min_match) {
|
|
return 5;
|
|
}
|
|
|
|
/* if this is the duplicated node, then find the next occurrence */
|
|
if (dup) {
|
|
for (int i = 0; i < dup; i++) {
|
|
if (connect[0] == side_nodes[location[i]]) {
|
|
num = in_list(connect[0], (nsnodes - num), &(side_nodes[num + 1])) + location[i] + 1;
|
|
count = 0;
|
|
count += numbermatch(side_nodes, 1, num, 4, connect[3]);
|
|
count += numbermatch(side_nodes, 2, num, 4, connect[2]);
|
|
count += numbermatch(side_nodes, 3, num, 4, connect[1]);
|
|
if (count >= min_match) {
|
|
return 5;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* SIDE 6 */
|
|
if ((num = in_list(connect[4], nsnodes, side_nodes)) >= 0) {
|
|
count = 0;
|
|
count += numbermatch(side_nodes, 1, num, 4, connect[5]);
|
|
count += numbermatch(side_nodes, 2, num, 4, connect[6]);
|
|
count += numbermatch(side_nodes, 3, num, 4, connect[7]);
|
|
if (count >= min_match) {
|
|
return 6;
|
|
}
|
|
|
|
/* if this is the duplicated node, then find the next occurrence */
|
|
if (dup) {
|
|
for (int i = 0; i < dup; i++) {
|
|
if (connect[4] == side_nodes[location[i]]) {
|
|
num = in_list(connect[4], (nsnodes - num), &(side_nodes[num + 1])) + location[i] + 1;
|
|
count = 0;
|
|
count += numbermatch(side_nodes, 1, num, 4, connect[5]);
|
|
count += numbermatch(side_nodes, 2, num, 4, connect[6]);
|
|
count += numbermatch(side_nodes, 3, num, 4, connect[7]);
|
|
if (count >= min_match) {
|
|
return 6;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case SHELL4:
|
|
case SHELL8:
|
|
case SHELL9:
|
|
|
|
/* 2D sides */
|
|
if (nsnodes == 2 || nsnodes == 3) {
|
|
/* SIDE 3 */
|
|
if (side_nodes[0] == connect[0] && side_nodes[1] == connect[1]) {
|
|
return 3;
|
|
}
|
|
|
|
/* SIDE 4 */
|
|
if (side_nodes[0] == connect[1] && side_nodes[1] == connect[2]) {
|
|
return 4;
|
|
}
|
|
|
|
/* SIDE 5 */
|
|
if (side_nodes[0] == connect[2] && side_nodes[1] == connect[3]) {
|
|
return 5;
|
|
}
|
|
|
|
/* SIDE 6 */
|
|
if (side_nodes[0] == connect[3] && side_nodes[1] == connect[0]) {
|
|
return 6;
|
|
}
|
|
}
|
|
|
|
/* 3D faces */
|
|
else if (nsnodes == 4 || nsnodes == 8 || nsnodes == 9) {
|
|
|
|
/* SIDE 1 */
|
|
if ((num = in_list(connect[0], nsnodes, side_nodes)) >= 0) {
|
|
if (side_nodes[(1 + num) % 4] == connect[1] && side_nodes[(2 + num) % 4] == connect[2] &&
|
|
side_nodes[(3 + num) % 4] == connect[3]) {
|
|
return 1;
|
|
}
|
|
if (side_nodes[(1 + num) % 4] == connect[3] && side_nodes[(2 + num) % 4] == connect[2] &&
|
|
side_nodes[(3 + num) % 4] == connect[1]) {
|
|
return 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case WEDGE6:
|
|
case WEDGE12:
|
|
case WEDGE15:
|
|
case WEDGE16:
|
|
case WEDGE20:
|
|
case WEDGE21:
|
|
|
|
/* quad sides */
|
|
if (nsnodes == 4 || nsnodes == 8 || nsnodes == 9) {
|
|
if ((num = in_list(connect[0], nsnodes, side_nodes)) >= 0) {
|
|
if (side_nodes[(1 + num) % 4] == connect[1] && side_nodes[(2 + num) % 4] == connect[4] &&
|
|
side_nodes[(3 + num) % 4] == connect[3]) {
|
|
return 1;
|
|
}
|
|
if (side_nodes[(1 + num) % 4] == connect[3] && side_nodes[(2 + num) % 4] == connect[5] &&
|
|
side_nodes[(3 + num) % 4] == connect[2]) {
|
|
return 3;
|
|
}
|
|
}
|
|
|
|
if ((num = in_list(connect[1], nsnodes, side_nodes)) >= 0) {
|
|
if (side_nodes[(1 + num) % 4] == connect[2] && side_nodes[(2 + num) % 4] == connect[5] &&
|
|
side_nodes[(3 + num) % 4] == connect[4]) {
|
|
return 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* triangle sides */
|
|
else if (nsnodes == 3 || nsnodes == 6 || nsnodes == 7) {
|
|
if ((num = in_list(connect[0], nsnodes, side_nodes)) >= 0) {
|
|
if (side_nodes[(1 + num) % 3] == connect[2] && side_nodes[(2 + num) % 3] == connect[1]) {
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
if ((num = in_list(connect[3], nsnodes, side_nodes)) >= 0) {
|
|
if (side_nodes[(1 + num) % 3] == connect[4] && side_nodes[(2 + num) % 3] == connect[5]) {
|
|
return 5;
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case TSHELL3:
|
|
case TSHELL4:
|
|
case TSHELL6:
|
|
case TSHELL7:
|
|
|
|
/* 2D sides */
|
|
if (nsnodes == 2 || (etype == TSHELL6 && nsnodes == 3) || (etype == TSHELL7 && nsnodes == 3)) {
|
|
/* SIDE 3 */
|
|
if (side_nodes[0] == connect[0] && side_nodes[1] == connect[1]) {
|
|
return 3;
|
|
}
|
|
|
|
/* SIDE 4 */
|
|
if (side_nodes[0] == connect[1] && side_nodes[1] == connect[2]) {
|
|
return 4;
|
|
}
|
|
|
|
/* SIDE 5 */
|
|
if (side_nodes[0] == connect[2] && side_nodes[1] == connect[0]) {
|
|
return 5;
|
|
}
|
|
}
|
|
|
|
/* 3D faces */
|
|
else if (nsnodes == 3 || nsnodes == 4 || nsnodes == 6 || nsnodes == 7) {
|
|
if ((num = in_list(connect[0], nsnodes, side_nodes)) >= 0) {
|
|
if (side_nodes[(1 + num) % 3] == connect[1] && side_nodes[(2 + num) % 3] == connect[2]) {
|
|
return 1;
|
|
}
|
|
if (side_nodes[(1 + num) % 3] == connect[2] && side_nodes[(2 + num) % 3] == connect[1]) {
|
|
return 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case PYRAMID5:
|
|
case PYRAMID13:
|
|
case PYRAMID14:
|
|
case PYRAMID18:
|
|
case PYRAMID19:
|
|
/* triangular sides */
|
|
if (nsnodes == 3 || nsnodes == 6 || nsnodes == 7) {
|
|
/* SIDE 1 */
|
|
if ((num = in_list(connect[0], nsnodes, side_nodes)) >= 0) {
|
|
if (side_nodes[(1 + num) % 3] == connect[1] && side_nodes[(2 + num) % 3] == connect[4]) {
|
|
return 1;
|
|
}
|
|
if (side_nodes[(1 + num) % 3] == connect[4] && side_nodes[(2 + num) % 3] == connect[3]) {
|
|
return 4;
|
|
}
|
|
}
|
|
|
|
/* SIDE 2 */
|
|
if ((num = in_list(connect[1], nsnodes, side_nodes)) >= 0) {
|
|
if (side_nodes[(1 + num) % 3] == connect[2] && side_nodes[(2 + num) % 3] == connect[4]) {
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
/* SIDE 3 */
|
|
if ((num = in_list(connect[2], nsnodes, side_nodes)) >= 0) {
|
|
if (side_nodes[(1 + num) % 3] == connect[3] && side_nodes[(2 + num) % 3] == connect[4]) {
|
|
return 3;
|
|
}
|
|
}
|
|
}
|
|
|
|
else if (nsnodes == 4 || nsnodes == 8 || nsnodes == 9) {
|
|
/* SIDE 5 */
|
|
if ((num = in_list(connect[0], nsnodes, side_nodes)) >= 0) {
|
|
if (side_nodes[(1 + num) % 4] == connect[3] && side_nodes[(2 + num) % 4] == connect[2] &&
|
|
side_nodes[(3 + num) % 4] == connect[1]) {
|
|
return 5;
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case SPHERE: break;
|
|
|
|
default: {
|
|
std::string err_buff;
|
|
err_buff = fmt::format("fatal: unknown element type {} in function {}", static_cast<int>(etype),
|
|
__func__);
|
|
Gen_Error(0, err_buff);
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
} /* End "switch(etype)" */
|
|
|
|
return 0;
|
|
} /*---------------------------End get_side_id()-----------------------------*/
|
|
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
/* Function get_side_id_hex_tet() begins:
|
|
*----------------------------------------------------------------------------
|
|
* This function returns the Side ID (as used in ExodusII) of a HEX element
|
|
* given a list of at least 3 nodes on that side. This function works on
|
|
* the fact that any three nodes define a side of a hex. When a tet is
|
|
* connected to a side of a hex, there are only three nodes connecting
|
|
* the two. In this case a side id can be found.
|
|
*****************************************************************************/
|
|
template int get_side_id_hex_tet(const E_Type etype, const int *connect, int nsnodes,
|
|
const int side_nodes[]);
|
|
template int get_side_id_hex_tet(const E_Type etype, const int64_t *connect, int nsnodes,
|
|
const int64_t side_nodes[]);
|
|
|
|
template <typename INT>
|
|
int get_side_id_hex_tet(const E_Type etype, /* The element type */
|
|
const INT *connect, /* The element connectivity */
|
|
int nsnodes, /* The number of side nodes */
|
|
const INT side_nodes[]) /* The list of side node IDs */
|
|
{
|
|
int nnodes;
|
|
int lcnt;
|
|
int i1;
|
|
int i2;
|
|
std::vector<int> loc_node_ids(MAX_SIDE_NODES);
|
|
|
|
nnodes = get_elem_info(NNODES, etype);
|
|
|
|
/* Find the local node numbers for nodes forming the side */
|
|
lcnt = 0;
|
|
for (i1 = 0; i1 < nnodes; i1++) {
|
|
for (i2 = 0; i2 < nsnodes; i2++) {
|
|
if (connect[i1] == side_nodes[i2]) {
|
|
loc_node_ids[lcnt++] = i1 + 1;
|
|
break;
|
|
}
|
|
}
|
|
if (lcnt == nsnodes) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch (etype) {
|
|
case TET4:
|
|
case TET10:
|
|
case TET8:
|
|
case TET14:
|
|
case TET15: {
|
|
auto il1 = in_list(1, lcnt, loc_node_ids.data()) >= 0;
|
|
auto il2 = in_list(2, lcnt, loc_node_ids.data()) >= 0;
|
|
auto il3 = in_list(3, lcnt, loc_node_ids.data()) >= 0;
|
|
auto il4 = in_list(4, lcnt, loc_node_ids.data()) >= 0;
|
|
|
|
if (il1 && il2 && il4) {
|
|
return 1;
|
|
}
|
|
|
|
if (il2 && il3 && il4) {
|
|
return 2;
|
|
}
|
|
|
|
if (il1 && il3 && il4) {
|
|
return 3;
|
|
}
|
|
|
|
if (il1 && il2 && il3) {
|
|
return 4;
|
|
}
|
|
} break;
|
|
|
|
case HEX8:
|
|
case HEX16:
|
|
case HEX20:
|
|
case HEX27: {
|
|
auto il1 = in_list(1, lcnt, loc_node_ids.data()) >= 0 ? 1 : 0;
|
|
auto il2 = in_list(2, lcnt, loc_node_ids.data()) >= 0 ? 1 : 0;
|
|
auto il3 = in_list(3, lcnt, loc_node_ids.data()) >= 0 ? 1 : 0;
|
|
auto il4 = in_list(4, lcnt, loc_node_ids.data()) >= 0 ? 1 : 0;
|
|
auto il5 = in_list(5, lcnt, loc_node_ids.data()) >= 0 ? 1 : 0;
|
|
auto il6 = in_list(6, lcnt, loc_node_ids.data()) >= 0 ? 1 : 0;
|
|
auto il7 = in_list(7, lcnt, loc_node_ids.data()) >= 0 ? 1 : 0;
|
|
auto il8 = in_list(8, lcnt, loc_node_ids.data()) >= 0 ? 1 : 0;
|
|
|
|
if (il1 + il2 + il5 + il6 > 2) {
|
|
return 1;
|
|
}
|
|
|
|
if (il2 + il3 + il6 + il7 > 2) {
|
|
return 2;
|
|
}
|
|
|
|
if (il3 + il4 + il7 + il8 > 2) {
|
|
return 3;
|
|
}
|
|
|
|
if (il1 + il4 + il5 + il8 > 2) {
|
|
return 4;
|
|
}
|
|
|
|
if (il1 + il2 + il3 + il4 > 2) {
|
|
return 5;
|
|
}
|
|
|
|
if (il5 + il6 + il7 + il8 > 2) {
|
|
return 6;
|
|
}
|
|
} break;
|
|
|
|
default: {
|
|
std::string err_buff;
|
|
err_buff = fmt::format("fatal: unknown element type {} in function {}", static_cast<int>(etype),
|
|
__func__);
|
|
Gen_Error(0, err_buff);
|
|
error_report();
|
|
exit(1);
|
|
}
|
|
|
|
} /* End "switch(etype)" */
|
|
|
|
return 0;
|
|
} /*-------------------------End get_side_id_hex()---------------------------*/
|
|
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
/* Function ss_to_node_list() begins:
|
|
*----------------------------------------------------------------------------
|
|
* This function returns the list of nodes in a side of an element given
|
|
* the element type, and the side id. It also returns the number of nodes
|
|
* in that side.
|
|
*****************************************************************************/
|
|
template int ss_to_node_list(const E_Type etype, const int *connect, int side_num,
|
|
int ss_node_list[]);
|
|
template int ss_to_node_list(const E_Type etype, const int64_t *connect, int side_num,
|
|
int64_t ss_node_list[]);
|
|
|
|
template <typename INT>
|
|
int ss_to_node_list(const E_Type etype, /* The element type */
|
|
const INT *connect, /* The element connectivity */
|
|
int side_num, /* The element side number */
|
|
INT ss_node_list[]) /* The list of side node IDs */
|
|
{
|
|
int i = 0;
|
|
|
|
/*
|
|
* This function returns a list of global node numbers forming a
|
|
* side set.
|
|
*/
|
|
|
|
/* triangle */
|
|
static int tri_table[3][3] = {
|
|
{1, 2, 4}, // side 1
|
|
{2, 3, 5}, // side 2
|
|
{3, 1, 6} // side 3
|
|
};
|
|
|
|
/* tshell */
|
|
static int tshell_table[2][7] = {
|
|
{1, 2, 3, 4, 5, 6, 7}, // side 1
|
|
{1, 3, 2, 6, 5, 4, 7} // side 2
|
|
};
|
|
|
|
/* quad */
|
|
static int quad_table[4][3] = {
|
|
{1, 2, 5}, // side 1
|
|
{2, 3, 6}, // side 2
|
|
{3, 4, 7}, // side 3
|
|
{4, 1, 8} // side 4
|
|
};
|
|
|
|
/* shell */
|
|
static int shell_table[2][9] = {
|
|
{1, 2, 3, 4, 5, 6, 7, 8, 9}, // side 1
|
|
{1, 4, 3, 2, 8, 7, 6, 5, 9} // side 2
|
|
};
|
|
|
|
/* tetra */
|
|
static int tetra_table[4][7] = {
|
|
{1, 2, 4, 5, 9, 8, 14}, /* Side 1 nodes */
|
|
{2, 3, 4, 6, 10, 9, 12}, /* Side 2 nodes */
|
|
{1, 4, 3, 8, 10, 7, 13}, /* Side 3 nodes */
|
|
{1, 3, 2, 7, 6, 5, 11} /* Side 4 nodes */
|
|
};
|
|
|
|
/* wedge */
|
|
/* wedge 6 or 7 */
|
|
static int wedge6_table[5][4] = {
|
|
{1, 2, 5, 4}, /* Side 1 nodes -- quad */
|
|
{2, 3, 6, 5}, /* Side 2 nodes -- quad */
|
|
{1, 4, 6, 3}, /* Side 3 nodes -- quad */
|
|
{1, 3, 2, 0}, /* Side 4 nodes -- triangle */
|
|
{4, 5, 6, 0} /* Side 5 nodes -- triangle */
|
|
};
|
|
|
|
/* wedge 12 */
|
|
static int wedge12_table[5][6] = {
|
|
{1, 2, 5, 4, 7, 10}, /* Side 1 nodes -- quad4 */
|
|
{2, 3, 6, 5, 8, 11}, /* Side 2 nodes -- quad4 */
|
|
{3, 1, 4, 6, 9, 12}, /* Side 3 nodes -- quad4 */
|
|
{1, 3, 2, 9, 8, 7}, /* Side 4 nodes -- triangle6 */
|
|
{4, 5, 6, 10, 11, 12} /* Side 5 nodes -- triangle6 */
|
|
};
|
|
|
|
/* wedge 15 or 16 */
|
|
static int wedge15_table[5][8] = {
|
|
{1, 2, 5, 4, 7, 11, 13, 10}, /* Side 1 nodes -- quad */
|
|
{2, 3, 6, 5, 8, 12, 14, 11}, /* Side 2 nodes -- quad */
|
|
{1, 4, 6, 3, 10, 15, 12, 9}, /* Side 3 nodes -- quad */
|
|
{1, 3, 2, 9, 8, 7, 0, 0}, /* Side 4 nodes -- triangle */
|
|
{4, 5, 6, 13, 14, 15, 0, 0} /* Side 5 nodes -- triangle */
|
|
};
|
|
|
|
/* wedge 20 */
|
|
static int wedge20_table[5][9] = {
|
|
{1, 2, 5, 4, 7, 11, 13, 10, 20}, /* Side 1 nodes -- quad */
|
|
{2, 3, 6, 5, 8, 12, 14, 11, 18}, /* Side 2 nodes -- quad */
|
|
{1, 4, 6, 3, 10, 15, 12, 9, 19}, /* Side 3 nodes -- quad */
|
|
{1, 3, 2, 9, 8, 7, 16, 0, 0}, /* Side 4 nodes -- triangle */
|
|
{4, 5, 6, 13, 14, 15, 17, 0, 0} /* Side 5 nodes -- triangle */
|
|
};
|
|
|
|
/* wedge 21 */
|
|
static int wedge21_table[5][9] = {
|
|
{1, 2, 5, 4, 7, 11, 13, 10, 21}, /* Side 1 nodes -- quad */
|
|
{2, 3, 6, 5, 8, 12, 14, 11, 19}, /* Side 2 nodes -- quad */
|
|
{1, 4, 6, 3, 10, 15, 12, 9, 20}, /* Side 3 nodes -- quad */
|
|
{1, 3, 2, 9, 8, 7, 17, 0, 0}, /* Side 4 nodes -- triangle */
|
|
{4, 5, 6, 13, 14, 15, 18, 0, 0} /* Side 5 nodes -- triangle */
|
|
};
|
|
|
|
/* hex */
|
|
static int hex_table[6][9] = {
|
|
{1, 2, 6, 5, 9, 14, 17, 13, 26}, /* side 1 */
|
|
{2, 3, 7, 6, 10, 15, 18, 14, 25}, /* side 2 */
|
|
{3, 4, 8, 7, 11, 16, 19, 15, 27}, /* side 3 */
|
|
{1, 5, 8, 4, 13, 20, 16, 12, 24}, /* side 4 */
|
|
{1, 4, 3, 2, 12, 11, 10, 9, 22}, /* side 5 */
|
|
{5, 6, 7, 8, 17, 18, 19, 20, 23} /* side 6 */
|
|
};
|
|
|
|
/* hex16 */
|
|
static int hex16_table[6][9] = {
|
|
{1, 2, 6, 5, 9, 13, 0, 0}, /* side 1 */
|
|
{2, 3, 7, 6, 10, 14, 0, 0}, /* side 2 */
|
|
{3, 4, 8, 7, 11, 15, 0, 0}, /* side 3 */
|
|
{4, 1, 5, 8, 4, 12, 16, 0}, /* side 4 */
|
|
{1, 4, 3, 2, 12, 11, 10, 9}, /* side 5 */
|
|
{5, 6, 7, 8, 13, 14, 15, 16} /* side 6 */
|
|
};
|
|
|
|
/* hexshell */
|
|
static int hexshell_table[6][6] = {
|
|
{1, 2, 6, 5, 10, 9}, // side 1
|
|
{2, 3, 7, 6, 11, 10}, // side 2
|
|
{3, 4, 8, 7, 12, 11}, // side 3
|
|
{4, 1, 5, 8, 9, 12}, // side 4
|
|
{1, 4, 3, 2, 0, 0}, // side 5
|
|
{5, 6, 7, 8, 0, 0} // side 6
|
|
};
|
|
|
|
/* pyramid */
|
|
static int pyramid_table[5][9] = {
|
|
{1, 2, 5, 6, 11, 10, 15, 0, 0}, // side 1 (tri)
|
|
{2, 3, 5, 7, 12, 11, 16, 0, 0}, // side 2 (tri)
|
|
{3, 4, 5, 8, 13, 12, 17, 0, 0}, // side 3 (tri)
|
|
{4, 1, 5, 9, 10, 13, 18, 0, 0}, // side 4 (tri)
|
|
{1, 4, 3, 2, 9, 8, 7, 6, 14} // side 5 (quad)
|
|
};
|
|
|
|
static int bar_table[1][3] = {{1, 2, 3}};
|
|
|
|
/* Locally decrement side_num */
|
|
side_num--;
|
|
|
|
/* Switch over the element type. */
|
|
switch (etype) {
|
|
case BAR2:
|
|
case SHELL2:
|
|
/* Bar1 has 1 side */
|
|
for (i = 0; i < 2; i++) {
|
|
ss_node_list[i] = connect[(bar_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
case BAR3:
|
|
case SHELL3:
|
|
/* Bar has 1 side */
|
|
for (i = 0; i < 3; i++) {
|
|
ss_node_list[i] = connect[(bar_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
case QUAD4:
|
|
for (i = 0; i < 2; i++) {
|
|
ss_node_list[i] = connect[(quad_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
case QUAD8:
|
|
case QUAD9:
|
|
for (i = 0; i < 3; i++) {
|
|
ss_node_list[i] = connect[(quad_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
case SHELL4:
|
|
switch (side_num) {
|
|
case 0:
|
|
case 1:
|
|
for (i = 0; i < 4; i++) {
|
|
ss_node_list[i] = connect[(shell_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
/*
|
|
* sides 3, 4, 5, & 6 correspond to sides 1, 2, 3, & 4
|
|
* of the quad element.
|
|
*/
|
|
for (i = 0; i < 2; i++) {
|
|
ss_node_list[i] = connect[(quad_table[(side_num - 2)][i] - 1)];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case SHELL8:
|
|
switch (side_num) {
|
|
case 0:
|
|
case 1:
|
|
for (i = 0; i < 8; i++) {
|
|
ss_node_list[i] = connect[(shell_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
/*
|
|
* sides 3, 4, 5, & 6 correspond to sides 1, 2, 3, & 4
|
|
* of the quad element.
|
|
*/
|
|
for (i = 0; i < 3; i++) {
|
|
ss_node_list[i] = connect[(quad_table[(side_num - 2)][i] - 1)];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case SHELL9:
|
|
switch (side_num) {
|
|
case 0:
|
|
case 1:
|
|
for (i = 0; i < 9; i++) {
|
|
ss_node_list[i] = connect[(shell_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
/*
|
|
* sides 3, 4, 5, & 6 correspond to sides 1, 2, 3, & 4
|
|
* of the quad element.
|
|
*/
|
|
for (i = 0; i < 3; i++) {
|
|
ss_node_list[i] = connect[(quad_table[(side_num - 2)][i] - 1)];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case TRI3:
|
|
case TRI4:
|
|
for (i = 0; i < 2; i++) {
|
|
ss_node_list[i] = connect[(tri_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
case TRI6:
|
|
case TRI7:
|
|
for (i = 0; i < 3; i++) {
|
|
ss_node_list[i] = connect[(tri_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
case TSHELL3:
|
|
case TSHELL4:
|
|
switch (side_num) {
|
|
case 0:
|
|
case 1:
|
|
for (i = 0; i < 3; i++) {
|
|
ss_node_list[i] = connect[(tshell_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
/*
|
|
* sides 3, 4 & 5 correspond to sides 1, 2 & 3
|
|
* of the tri element.
|
|
*/
|
|
for (i = 0; i < 2; i++) {
|
|
ss_node_list[i] = connect[(tri_table[(side_num - 2)][i] - 1)];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case TSHELL6:
|
|
case TSHELL7:
|
|
switch (side_num) {
|
|
case 0:
|
|
case 1:
|
|
for (i = 0; i < 6; i++) {
|
|
ss_node_list[i] = connect[(tshell_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
/*
|
|
* sides 3, 4 & 5 correspond to sides 1, 2 & 3
|
|
* of the tri element.
|
|
*/
|
|
for (i = 0; i < 3; i++) {
|
|
ss_node_list[i] = connect[(tri_table[(side_num - 2)][i] - 1)];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case HEX8:
|
|
for (i = 0; i < 4; i++) {
|
|
ss_node_list[i] = connect[(hex_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
case HEX16:
|
|
switch (side_num) {
|
|
case 4:
|
|
case 5:
|
|
for (i = 0; i < 8; i++) {
|
|
ss_node_list[i] = connect[(hex16_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 6; i++) {
|
|
ss_node_list[i] = connect[(hex16_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case HEX20:
|
|
for (i = 0; i < 8; i++) {
|
|
ss_node_list[i] = connect[(hex_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
case HEX27:
|
|
for (i = 0; i < 9; i++) {
|
|
ss_node_list[i] = connect[(hex_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
case TET4:
|
|
for (i = 0; i < 3; i++) {
|
|
ss_node_list[i] = connect[(tetra_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
case TET10:
|
|
for (i = 0; i < 6; i++) {
|
|
ss_node_list[i] = connect[(tetra_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
case TET14:
|
|
case TET15:
|
|
for (i = 0; i < 7; i++) {
|
|
ss_node_list[i] = connect[(tetra_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
case TET8:
|
|
for (i = 0; i < 4; i++) {
|
|
ss_node_list[i] = connect[(tetra_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
case WEDGE6:
|
|
switch (side_num) {
|
|
case 3:
|
|
case 4:
|
|
for (i = 0; i < 3; i++) {
|
|
ss_node_list[i] = connect[(wedge6_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 4; i++) {
|
|
ss_node_list[i] = connect[(wedge6_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WEDGE12:
|
|
for (i = 0; i < 6; i++) {
|
|
ss_node_list[i] = connect[(wedge12_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
case WEDGE15:
|
|
case WEDGE16:
|
|
switch (side_num) {
|
|
case 3:
|
|
case 4:
|
|
for (i = 0; i < 6; i++) {
|
|
ss_node_list[i] = connect[(wedge15_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 8; i++) {
|
|
ss_node_list[i] = connect[(wedge15_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WEDGE20:
|
|
switch (side_num) {
|
|
case 3:
|
|
case 4:
|
|
for (i = 0; i < 7; i++) {
|
|
ss_node_list[i] = connect[(wedge20_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 9; i++) {
|
|
ss_node_list[i] = connect[(wedge20_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WEDGE21:
|
|
switch (side_num) {
|
|
case 3:
|
|
case 4:
|
|
for (i = 0; i < 7; i++) {
|
|
ss_node_list[i] = connect[(wedge21_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 9; i++) {
|
|
ss_node_list[i] = connect[(wedge21_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case HEXSHELL:
|
|
switch (side_num) {
|
|
case 4:
|
|
case 5:
|
|
for (i = 0; i < 4; i++) {
|
|
ss_node_list[i] = connect[(hexshell_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 6; i++) {
|
|
ss_node_list[i] = connect[(hexshell_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case PYRAMID5:
|
|
switch (side_num) {
|
|
case 4:
|
|
for (i = 0; i < 4; i++) {
|
|
ss_node_list[i] = connect[(pyramid_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 3; i++) {
|
|
ss_node_list[i] = connect[(pyramid_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case PYRAMID13:
|
|
switch (side_num) {
|
|
case 4:
|
|
for (i = 0; i < 8; i++) {
|
|
ss_node_list[i] = connect[(pyramid_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 6; i++) {
|
|
ss_node_list[i] = connect[(pyramid_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case PYRAMID14:
|
|
switch (side_num) {
|
|
case 4:
|
|
for (i = 0; i < 9; i++) {
|
|
ss_node_list[i] = connect[(pyramid_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 6; i++) {
|
|
ss_node_list[i] = connect[(pyramid_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case PYRAMID18:
|
|
case PYRAMID19: /* Pyramid18 with mid-volume node */
|
|
switch (side_num) {
|
|
case 4:
|
|
for (i = 0; i < 9; i++) {
|
|
ss_node_list[i] = connect[(pyramid_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 7; i++) {
|
|
ss_node_list[i] = connect[(pyramid_table[side_num][i] - 1)];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case SPHERE: /* SHPERE's have no side sets */
|
|
case NULL_EL: i = 0; break;
|
|
|
|
} /* End "switch (etype)" */
|
|
|
|
/* the variable "i" should be the number of positions that I filled */
|
|
return (i);
|
|
|
|
} /*-------------------------End ss_to_node_list()---------------------------*/
|
|
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
/* Function get_ss_mirror() begins:
|
|
*----------------------------------------------------------------------------
|
|
* This function returns the node list for the mirror of the list
|
|
* given. This will be the node list of a face that is connected
|
|
* to this element on this face.
|
|
*****************************************************************************/
|
|
template int get_ss_mirror(const E_Type etype, const int *ss_node_list, int side_num,
|
|
int mirror_node_list[]);
|
|
template int get_ss_mirror(const E_Type etype, const int64_t *ss_node_list, int side_num,
|
|
int64_t mirror_node_list[]);
|
|
|
|
template <typename INT>
|
|
int get_ss_mirror(const E_Type etype, /* The element type */
|
|
const INT *ss_node_list, /* The list of side node IDs */
|
|
int side_num, /* The element side number */
|
|
INT mirror_node_list[] /* The list of the mirror side node IDs */
|
|
)
|
|
{
|
|
int i = 0;
|
|
|
|
/*
|
|
* the following arrays are the conversion from the side to
|
|
* an opposing face
|
|
*/
|
|
|
|
/* line (1-d) */
|
|
static const int line_table[3] = {1, 0, 2};
|
|
|
|
/* square (2-d) */
|
|
static const int sqr_table[9] = {0, 3, 2, 1, 7, 6, 5, 4, 8};
|
|
|
|
/* square hexshell (2-d) */
|
|
static const int hs_table[6] = {0, 3, 2, 1, 5, 4};
|
|
|
|
/* triangle (2-d) */
|
|
static const int tri_table[7] = {1, 0, 2, 3, 5, 4, 6};
|
|
|
|
/***************************** execution begins ******************************/
|
|
|
|
/* Switch over the element type. */
|
|
switch (etype) {
|
|
case BAR2:
|
|
case SHELL2:
|
|
for (i = 0; i < 2; i++) {
|
|
mirror_node_list[i] = ss_node_list[line_table[i]];
|
|
}
|
|
break;
|
|
case BAR3:
|
|
case SHELL3:
|
|
for (i = 0; i < 3; i++) {
|
|
mirror_node_list[i] = ss_node_list[line_table[i]];
|
|
}
|
|
break;
|
|
case QUAD4:
|
|
for (i = 0; i < 2; i++) {
|
|
mirror_node_list[i] = ss_node_list[line_table[i]];
|
|
}
|
|
break;
|
|
|
|
case QUAD8:
|
|
case QUAD9:
|
|
for (i = 0; i < 3; i++) {
|
|
mirror_node_list[i] = ss_node_list[line_table[i]];
|
|
}
|
|
break;
|
|
|
|
case SHELL4:
|
|
switch (side_num) {
|
|
case 1:
|
|
case 2:
|
|
for (i = 0; i < 4; i++) {
|
|
mirror_node_list[i] = ss_node_list[sqr_table[i]];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 2; i++) {
|
|
mirror_node_list[i] = ss_node_list[line_table[i]];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case SHELL8:
|
|
switch (side_num) {
|
|
case 1:
|
|
case 2:
|
|
for (i = 0; i < 8; i++) {
|
|
mirror_node_list[i] = ss_node_list[sqr_table[i]];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 3; i++) {
|
|
mirror_node_list[i] = ss_node_list[line_table[i]];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case SHELL9:
|
|
switch (side_num) {
|
|
case 1:
|
|
case 2:
|
|
for (i = 0; i < 9; i++) {
|
|
mirror_node_list[i] = ss_node_list[sqr_table[i]];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 3; i++) {
|
|
mirror_node_list[i] = ss_node_list[line_table[i]];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case TRI3:
|
|
case TRI4:
|
|
for (i = 0; i < 2; i++) {
|
|
mirror_node_list[i] = ss_node_list[line_table[i]];
|
|
}
|
|
break;
|
|
|
|
case TRI6:
|
|
case TRI7:
|
|
for (i = 0; i < 3; i++) {
|
|
mirror_node_list[i] = ss_node_list[line_table[i]];
|
|
}
|
|
break;
|
|
|
|
case TSHELL3:
|
|
switch (side_num) {
|
|
case 1:
|
|
case 2:
|
|
for (i = 0; i < 3; i++) {
|
|
mirror_node_list[i] = ss_node_list[tri_table[i]];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 2; i++) {
|
|
mirror_node_list[i] = ss_node_list[line_table[i]];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case TSHELL4:
|
|
switch (side_num) {
|
|
case 1:
|
|
case 2:
|
|
for (i = 0; i < 4; i++) {
|
|
mirror_node_list[i] = ss_node_list[tri_table[i]];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 2; i++) {
|
|
mirror_node_list[i] = ss_node_list[line_table[i]];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case TSHELL6:
|
|
switch (side_num) {
|
|
case 1:
|
|
case 2:
|
|
for (i = 0; i < 6; i++) {
|
|
mirror_node_list[i] = ss_node_list[tri_table[i]];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 3; i++) {
|
|
mirror_node_list[i] = ss_node_list[line_table[i]];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case TSHELL7:
|
|
switch (side_num) {
|
|
case 1:
|
|
case 2:
|
|
for (i = 0; i < 7; i++) {
|
|
mirror_node_list[i] = ss_node_list[tri_table[i]];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 3; i++) {
|
|
mirror_node_list[i] = ss_node_list[line_table[i]];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case HEX8:
|
|
for (i = 0; i < 4; i++) {
|
|
mirror_node_list[i] = ss_node_list[sqr_table[i]];
|
|
}
|
|
break;
|
|
|
|
case HEX16:
|
|
switch (side_num) {
|
|
case 4:
|
|
case 5:
|
|
for (i = 0; i < 8; i++) {
|
|
mirror_node_list[i] = ss_node_list[sqr_table[i]];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 6; i++) {
|
|
mirror_node_list[i] = ss_node_list[sqr_table[i]];
|
|
}
|
|
}
|
|
break;
|
|
|
|
case HEX27:
|
|
for (i = 0; i < 9; i++) {
|
|
mirror_node_list[i] = ss_node_list[sqr_table[i]];
|
|
}
|
|
break;
|
|
|
|
case HEX20:
|
|
for (i = 0; i < 8; i++) {
|
|
mirror_node_list[i] = ss_node_list[sqr_table[i]];
|
|
}
|
|
break;
|
|
|
|
case TET4:
|
|
for (i = 0; i < 3; i++) {
|
|
mirror_node_list[i] = ss_node_list[tri_table[i]];
|
|
}
|
|
break;
|
|
|
|
case TET8:
|
|
for (i = 0; i < 4; i++) {
|
|
mirror_node_list[i] = ss_node_list[tri_table[i]];
|
|
}
|
|
break;
|
|
|
|
case TET10:
|
|
for (i = 0; i < 6; i++) {
|
|
mirror_node_list[i] = ss_node_list[tri_table[i]];
|
|
}
|
|
break;
|
|
|
|
case TET14:
|
|
case TET15:
|
|
for (i = 0; i < 7; i++) {
|
|
mirror_node_list[i] = ss_node_list[tri_table[i]];
|
|
}
|
|
break;
|
|
|
|
case WEDGE6:
|
|
switch (side_num) {
|
|
case 4:
|
|
case 5:
|
|
for (i = 0; i < 3; i++) {
|
|
mirror_node_list[i] = ss_node_list[tri_table[i]];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 4; i++) {
|
|
mirror_node_list[i] = ss_node_list[sqr_table[i]];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WEDGE12:
|
|
for (i = 0; i < 6; i++) {
|
|
mirror_node_list[i] = ss_node_list[tri_table[i]];
|
|
}
|
|
break;
|
|
|
|
case WEDGE15:
|
|
case WEDGE16:
|
|
switch (side_num) {
|
|
case 4:
|
|
case 5:
|
|
for (i = 0; i < 6; i++) {
|
|
mirror_node_list[i] = ss_node_list[tri_table[i]];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 8; i++) {
|
|
mirror_node_list[i] = ss_node_list[sqr_table[i]];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WEDGE20:
|
|
case WEDGE21:
|
|
switch (side_num) {
|
|
case 4:
|
|
case 5:
|
|
for (i = 0; i < 7; i++) {
|
|
mirror_node_list[i] = ss_node_list[tri_table[i]];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 9; i++) {
|
|
mirror_node_list[i] = ss_node_list[sqr_table[i]];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case HEXSHELL:
|
|
switch (side_num) {
|
|
case 5:
|
|
case 6:
|
|
for (i = 0; i < 4; i++) {
|
|
mirror_node_list[i] = ss_node_list[sqr_table[i]];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 6; i++) {
|
|
mirror_node_list[i] = ss_node_list[hs_table[i]];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case PYRAMID5:
|
|
switch (side_num) {
|
|
case 5:
|
|
for (i = 0; i < 4; i++) {
|
|
mirror_node_list[i] = ss_node_list[sqr_table[i]];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 3; i++) {
|
|
mirror_node_list[i] = ss_node_list[tri_table[i]];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case PYRAMID13:
|
|
switch (side_num) {
|
|
case 5:
|
|
for (i = 0; i < 8; i++) {
|
|
mirror_node_list[i] = ss_node_list[sqr_table[i]];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 6; i++) {
|
|
mirror_node_list[i] = ss_node_list[tri_table[i]];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case PYRAMID14:
|
|
switch (side_num) {
|
|
case 5:
|
|
for (i = 0; i < 9; i++) {
|
|
mirror_node_list[i] = ss_node_list[sqr_table[i]];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 6; i++) {
|
|
mirror_node_list[i] = ss_node_list[tri_table[i]];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case PYRAMID18:
|
|
case PYRAMID19:
|
|
switch (side_num) {
|
|
case 5:
|
|
for (i = 0; i < 9; i++) {
|
|
mirror_node_list[i] = ss_node_list[sqr_table[i]];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
for (i = 0; i < 7; i++) {
|
|
mirror_node_list[i] = ss_node_list[tri_table[i]];
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case SPHERE: /* SHPERE's have no side sets */
|
|
case NULL_EL: i = 0; break;
|
|
|
|
} /* End "switch (etype)" */
|
|
|
|
/* the variable "i" should be the number of positions that I filled */
|
|
return (i);
|
|
|
|
} /*-------------------------Ed get_ss_mirror()---------------------------*/
|
|
|