|
Sierra Toolkit
Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* Copyright 2010, 2011 Sandia Corporation. */ 00003 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */ 00004 /* license for use of this work by or on behalf of the U.S. Government. */ 00005 /* Export of this program may require a license from the */ 00006 /* United States Government. */ 00007 /*------------------------------------------------------------------------*/ 00008 00009 #include <stk_util/unit_test_support/stk_utest_macros.hpp> 00010 #include <stk_util/parallel/Parallel.hpp> 00011 00012 #include <Ioss_ConcreteVariableType.h> 00013 #include <Ioss_Initializer.h> 00014 #include <Ioss_VariableType.h> 00015 #include <Ioss_Utils.h> 00016 00017 #include <Ioss_ElementTopology.h> 00018 00019 #include <stk_io/IossBridge.hpp> 00020 #include <Shards_CellTopology.hpp> 00021 00022 #include <assert.h> 00023 00024 namespace { 00025 template<typename T, typename U> 00026 int my_assert(T a, T b, U msg) { 00027 if (a != b) { 00028 std::cerr << "\tERROR: '" << msg << "' assertion failed: " << a << " is not equal to " << b << "\n"; 00029 return 1; 00030 } 00031 return 0; 00032 } 00033 } 00034 00035 namespace { 00036 int testElement(const std::string &name) 00037 { 00038 int errors = 0; 00039 Ioss::ElementTopology *element = Ioss::ElementTopology::factory(name); 00040 if (element == NULL) { 00041 std::cerr << "\tERROR: Element type '" << name << "' could not be constructed."; 00042 // Must return since we have a NULL pointer and can't do further tests... 00043 return 1; 00044 } 00045 if (element->name() != name) { 00046 // This is an alias. Don't run it through the rest of the tests 00047 std::cerr << "Element '" << name << "' is an alias for element '" << element->name() << "'\n"; 00048 return 0; 00049 } 00050 00051 std::cerr << "Testing element '" << name << "'\n"; 00052 // Currently not supported in shards: 00053 if (element->name() == "unknown") { 00054 std::cerr << "\tERROR (EXPECTED): No support for '" << element->name() << "'\n"; 00055 return 0; 00056 } 00057 00058 // Get the corresponding shards CellTopologyData* .. 00059 const CellTopologyData *cell_data = stk::io::map_topology_ioss_to_cell(element); 00060 if (cell_data == NULL) { 00061 std::cerr << "\tERROR: Could not find a shards CellTopology corresponding to the Ioss::ElementTopology element '" 00062 << name << "'."; 00063 // Must return since we have a NULL pointer and can't do further tests... 00064 return 1; 00065 } 00066 00067 // See if we get the same element back when converting from 00068 // CellTopologyData to Ioss::ElementToplogy 00069 std::string new_name = stk::io::map_topology_cell_to_ioss(cell_data, element->spatial_dimension()); 00070 Ioss::ElementTopology *new_element = Ioss::ElementTopology::factory(new_name); 00071 if (element->name() != new_element->name()) { 00072 std::cerr << "\tERROR: New name = '" << new_element->name() 00073 << "' doesn't match old name '" << element->name() 00074 << "'\n"; 00075 errors++; 00076 } 00077 00078 shards::CellTopology cell(cell_data); 00079 00080 // At this point, 'element' is the Ioss element topology and 00081 // 'cell' is the corresponding shards CellTopology data pointer. 00082 // Make sure that they agree on all subcell details... 00083 // Exceptions: 00084 // 1. An Ioss Node has 1 node per element; a shards Node has 0 nodes per element... 00085 00086 errors += my_assert(cell.getNodeCount(), 00087 static_cast<unsigned>(element->number_nodes()), 00088 "node count"); 00089 errors += my_assert(cell.getVertexCount(), 00090 static_cast<unsigned>(element->number_corner_nodes()), 00091 "vertex count"); 00092 00093 // NOTE: CellTopology and Ioss disagree on parametric dimension. 00094 int add_to = element->spatial_dimension() != element->parametric_dimension() && element->is_element() ? 1 : 0; 00095 errors += my_assert(cell.getDimension(), 00096 static_cast<unsigned>(element->parametric_dimension()+add_to), 00097 "parametric dimension"); 00098 errors += my_assert(cell.getEdgeCount(), 00099 static_cast<unsigned>(element->number_edges()), 00100 "edge count"); 00101 00102 // NOTE: Ioss counts edges and faces as boundaries for shell elements 00103 int add_boundary = 0; 00104 if (add_to == 1 && element->spatial_dimension() == 3 && element->parametric_dimension() == 2) 00105 add_boundary = cell.getEdgeCount(); 00106 00107 errors += my_assert(cell.getSideCount() + add_boundary, 00108 static_cast<unsigned>(element->number_boundaries()), 00109 "boundary count"); 00110 00111 00112 // Check face topologies for all elements... 00113 if (element->is_element()) { 00114 if (cell.getDimension() == 3) { 00115 int face_count = element->number_faces(); 00116 for (int i=0; i < face_count; i++) { 00117 Ioss::ElementTopology *face = element->face_type(i+1); 00118 const CellTopologyData *cell_face = cell.getCellTopologyData(cell.getDimension()-1,i); 00119 errors += my_assert(face->name(), 00120 stk::io::map_topology_cell_to_ioss(cell_face,face->spatial_dimension()), 00121 "face type"); 00122 00123 Ioss::IntVector fcon = element->face_connectivity(i+1); 00124 size_t node_count = fcon.size(); 00125 for (size_t j=0; j < node_count; j++) { 00126 std::ostringstream msg; 00127 msg << "face node connectivity for node " << j << " on face " << i; 00128 errors += my_assert(fcon[j], 00129 static_cast<int>(cell.getNodeMap(cell.getDimension()-1, i, j)), 00130 msg.str()); 00131 } 00132 } 00133 00134 int edge_count = element->number_edges(); 00135 for (int i=0; i < edge_count; i++) { 00136 00137 Ioss::IntVector fcon = element->edge_connectivity(i+1); 00138 size_t node_count = fcon.size(); 00139 for (size_t j=0; j < node_count; j++) { 00140 std::ostringstream msg; 00141 msg << "edge node connectivity for node " << j << " on edge " << i; 00142 errors += my_assert(fcon[j], 00143 static_cast<int>(cell.getNodeMap(cell.getDimension()-2, i, j)), 00144 msg.str()); 00145 } 00146 } 00147 } 00148 else if (cell.getDimension() == 2) { 00149 int edge_count = element->number_edges(); 00150 for (int i=0; i < edge_count; i++) { 00151 Ioss::ElementTopology *edge = element->edge_type(i+1); 00152 const CellTopologyData *cell_edge = cell.getCellTopologyData(cell.getDimension()-1,i); 00153 errors += my_assert(edge->name(), 00154 stk::io::map_topology_cell_to_ioss(cell_edge, edge->spatial_dimension()), 00155 "edge type"); 00156 00157 Ioss::IntVector econ = element->edge_connectivity(i+1); 00158 size_t node_count = econ.size(); 00159 for (size_t j=0; j < node_count; j++) { 00160 std::ostringstream msg; 00161 msg << "edge node connectivity for node " << j << " on edge " << i; 00162 errors += my_assert(econ[j], 00163 static_cast<int>(cell.getNodeMap(cell.getDimension()-1, i, j)), 00164 msg.str()); 00165 } 00166 } 00167 00168 } 00169 } 00170 return errors; 00171 } 00172 } 00173 00174 STKUNIT_UNIT_TEST(UnitTestTopology, testUnit) 00175 { 00176 Ioss::StorageInitializer initialize_storage; 00177 Ioss::Initializer initialize_topologies; 00178 00179 Ioss::NameList elements; 00180 int element_count = Ioss::ElementTopology::describe(&elements); 00181 00182 int errors = 0; 00183 for (int i=0; i < element_count; i++) { 00184 // FIXME: Need to totally skip tetra7 for now 00185 if (elements[i] == "tetra7") { 00186 continue; 00187 } 00188 00189 int current_error = testElement(elements[i]); 00190 if (elements[i] != "node" && 00191 elements[i] != "rod3d2" && 00192 elements[i] != "rod3d3" && 00193 elements[i] != "tri4a" /*FIXME?*/) { 00194 errors += current_error; 00195 } 00196 else { 00197 if (current_error > 0) 00198 std::cerr << "\t\tIGNORING " << elements[i] << " ERRORS...\n"; 00199 } 00200 } 00201 STKUNIT_ASSERT(errors == 0); 00202 } 00203 00204