Sierra Toolkit  Version of the Day
UnitTestTopologyMap.cpp
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2010, 2011 Sandia Corporation. */
3 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */
4 /* license for use of this work by or on behalf of the U.S. Government. */
5 /* Export of this program may require a license from the */
6 /* United States Government. */
7 /*------------------------------------------------------------------------*/
8 
9 #include <stk_util/unit_test_support/stk_utest_macros.hpp>
10 #include <stk_util/parallel/Parallel.hpp>
11 
12 #include <Ioss_ConcreteVariableType.h>
13 #include <Ioss_Initializer.h>
14 #include <Ioss_VariableType.h>
15 #include <Ioss_Utils.h>
16 
17 #include <Ioss_ElementTopology.h>
18 
19 #include <stk_io/IossBridge.hpp>
20 #include <Shards_CellTopology.hpp>
21 
22 #include <assert.h>
23 
24 namespace {
25 template<typename T, typename U>
26 int my_assert(T a, T b, U msg) {
27  if (a != b) {
28  std::cerr << "\tERROR: '" << msg << "' assertion failed: " << a << " is not equal to " << b << "\n";
29  return 1;
30  }
31  return 0;
32 }
33 }
34 
35 namespace {
36 int testElement(const std::string &name)
37 {
38  int errors = 0;
39  Ioss::ElementTopology *element = Ioss::ElementTopology::factory(name);
40  if (element == NULL) {
41  std::cerr << "\tERROR: Element type '" << name << "' could not be constructed.";
42  // Must return since we have a NULL pointer and can't do further tests...
43  return 1;
44  }
45  if (element->name() != name) {
46  // This is an alias. Don't run it through the rest of the tests
47  std::cerr << "Element '" << name << "' is an alias for element '" << element->name() << "'\n";
48  return 0;
49  }
50 
51  std::cerr << "Testing element '" << name << "'\n";
52  // Currently not supported in shards:
53  if (element->name() == "unknown" ||
54  element->name() == "tetra7" || element->name() == "tetra11" ||
55  element->name() == "tetra14" || element->name() == "tetra15" ||
56  element->name() == "tri7" ||
57  element->name() == "trishell4" || element->name() == "trishell7" ||
58  element->name() == "wedge20" || element->name() == "wedge21" ||
59  element->name() == "wedge16") {
60  std::cerr << "\tERROR (EXPECTED): No support for '" << element->name() << "'\n";
61  return 0;
62  }
63 
64  // Get the corresponding shards CellTopologyData* ..
65  const CellTopologyData *cell_data = stk_classic::io::map_topology_ioss_to_cell(element);
66  if (cell_data == NULL) {
67  std::cerr << "\tERROR: Could not find a shards CellTopology corresponding to the Ioss::ElementTopology element '"
68  << name << "'.";
69  // Must return since we have a NULL pointer and can't do further tests...
70  return 1;
71  }
72 
73  // See if we get the same element back when converting from
74  // CellTopologyData to Ioss::ElementToplogy
75  std::string new_name = stk_classic::io::map_topology_cell_to_ioss(cell_data, element->spatial_dimension());
76  Ioss::ElementTopology *new_element = Ioss::ElementTopology::factory(new_name);
77  if (element->name() != new_element->name()) {
78  std::cerr << "\tERROR: New name = '" << new_element->name()
79  << "' doesn't match old name '" << element->name()
80  << "'\n";
81  errors++;
82  }
83 
84  shards::CellTopology cell(cell_data);
85 
86  // At this point, 'element' is the Ioss element topology and
87  // 'cell' is the corresponding shards CellTopology data pointer.
88  // Make sure that they agree on all subcell details...
89  // Exceptions:
90  // 1. An Ioss Node has 1 node per element; a shards Node has 0 nodes per element...
91 
92  errors += my_assert(cell.getNodeCount(),
93  static_cast<unsigned>(element->number_nodes()),
94  "node count");
95  errors += my_assert(cell.getVertexCount(),
96  static_cast<unsigned>(element->number_corner_nodes()),
97  "vertex count");
98 
99  // NOTE: CellTopology and Ioss disagree on parametric dimension.
100  int add_to = element->spatial_dimension() != element->parametric_dimension() && element->is_element() ? 1 : 0;
101  errors += my_assert(cell.getDimension(),
102  static_cast<unsigned>(element->parametric_dimension()+add_to),
103  "parametric dimension");
104  errors += my_assert(cell.getEdgeCount(),
105  static_cast<unsigned>(element->number_edges()),
106  "edge count");
107 
108  // NOTE: Ioss counts edges and faces as boundaries for shell elements
109  int add_boundary = 0;
110  if (add_to == 1 && element->spatial_dimension() == 3 && element->parametric_dimension() == 2)
111  add_boundary = cell.getEdgeCount();
112 
113  if (element->name() == "edge2" || element->name() == "edge3")
114  add_boundary += 2;
115 
116  errors += my_assert(cell.getSideCount() + add_boundary,
117  static_cast<unsigned>(element->number_boundaries()),
118  "boundary count");
119 
120 
121  // Check face topologies for all elements...
122  if (element->is_element()) {
123  if (cell.getDimension() == 3) {
124  int face_count = element->number_faces();
125  for (int i=0; i < face_count; i++) {
126  Ioss::ElementTopology *face = element->face_type(i+1);
127  const CellTopologyData *cell_face = cell.getCellTopologyData(cell.getDimension()-1,i);
128  errors += my_assert(face->name(),
129  stk_classic::io::map_topology_cell_to_ioss(cell_face,face->spatial_dimension()),
130  "face type");
131 
132  Ioss::IntVector fcon = element->face_connectivity(i+1);
133  size_t node_count = fcon.size();
134  for (size_t j=0; j < node_count; j++) {
135  std::ostringstream msg;
136  msg << "face node connectivity for node " << j << " on face " << i;
137  errors += my_assert(fcon[j],
138  static_cast<int>(cell.getNodeMap(cell.getDimension()-1, i, j)),
139  msg.str());
140  }
141  }
142 
143  int edge_count = element->number_edges();
144  for (int i=0; i < edge_count; i++) {
145 
146  Ioss::IntVector fcon = element->edge_connectivity(i+1);
147  size_t node_count = fcon.size();
148  for (size_t j=0; j < node_count; j++) {
149  std::ostringstream msg;
150  msg << "edge node connectivity for node " << j << " on edge " << i;
151  errors += my_assert(fcon[j],
152  static_cast<int>(cell.getNodeMap(cell.getDimension()-2, i, j)),
153  msg.str());
154  }
155  }
156  }
157  else if (cell.getDimension() == 2) {
158  int edge_count = element->number_edges();
159  for (int i=0; i < edge_count; i++) {
160  Ioss::ElementTopology *edge = element->edge_type(i+1);
161  const CellTopologyData *cell_edge = cell.getCellTopologyData(cell.getDimension()-1,i);
162  errors += my_assert(edge->name(),
163  stk_classic::io::map_topology_cell_to_ioss(cell_edge, edge->spatial_dimension()),
164  "edge type");
165 
166  Ioss::IntVector econ = element->edge_connectivity(i+1);
167  size_t node_count = econ.size();
168  for (size_t j=0; j < node_count; j++) {
169  std::ostringstream msg;
170  msg << "edge node connectivity for node " << j << " on edge " << i;
171  errors += my_assert(econ[j],
172  static_cast<int>(cell.getNodeMap(cell.getDimension()-1, i, j)),
173  msg.str());
174  }
175  }
176 
177  }
178  }
179  return errors;
180 }
181 }
182 
183 STKUNIT_UNIT_TEST(UnitTestTopology, testUnit)
184 {
185  Ioss::StorageInitializer initialize_storage;
186  Ioss::Initializer initialize_topologies;
187 
188  Ioss::NameList elements;
189  int element_count = Ioss::ElementTopology::describe(&elements);
190 
191  int errors = 0;
192  for (int i=0; i < element_count; i++) {
193  // FIXME: Need to totally skip tetra7 for now
194  if (elements[i] == "tetra7" ||
195  elements[i] == "tetra11" ||
196  elements[i] == "trishell4" ||
197  elements[i] == "trishell7") {
198  continue;
199  }
200 
201  int current_error = testElement(elements[i]);
202  if (elements[i] != "node" &&
203  elements[i] != "rod3d2" &&
204  elements[i] != "rod3d3" &&
205  elements[i] != "tri4a" /*FIXME?*/) {
206  errors += current_error;
207  }
208  else {
209  if (current_error > 0)
210  std::cerr << "\t\tIGNORING " << elements[i] << " ERRORS...\n";
211  }
212  }
213  STKUNIT_ASSERT(errors == 0);
214 }
215 
216 
std::string map_topology_cell_to_ioss(const CellTopologyData *cell_top, int spatial_dimension)
Definition: IossBridge.cpp:687
const CellTopologyData * map_topology_ioss_to_cell(const Ioss::ElementTopology *topology)
Definition: IossBridge.cpp:670