MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2007 Sandia National Laboratories. Developed at the 00005 University of Wisconsin--Madison under SNL contract number 00006 624796. The U.S. Government and the University of Wisconsin 00007 retain certain rights to this software. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 (lgpl.txt) along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 (2009) [email protected] 00024 00025 ***************************************************************** */ 00026 00027 /** \file SlaveBoundaryVerticesTest.cpp 00028 * \brief Test SlaveBoundaryVertices class 00029 * \author Jason Kraftcheck 00030 */ 00031 00032 #include "Mesquite.hpp" 00033 #include "UnitUtil.hpp" 00034 #include "meshfiles.h" 00035 #include "Settings.hpp" 00036 #include "MsqError.hpp" 00037 #include "SlaveBoundaryVertices.hpp" 00038 00039 #include "MsqVertex.hpp" 00040 #include "DomainClassifier.hpp" 00041 #include "PlanarDomain.hpp" 00042 #include "MeshDomain1D.hpp" 00043 #include "MeshImpl.hpp" 00044 00045 #include <vector> 00046 #include <set> 00047 #include <algorithm> 00048 #include <fstream> 00049 #include <iostream> 00050 00051 using namespace MBMesquite; 00052 00053 class SlaveBoundaryVerticesTest : public CppUnit::TestFixture 00054 { 00055 private: 00056 CPPUNIT_TEST_SUITE( SlaveBoundaryVerticesTest ); 00057 CPPUNIT_TEST( test_fail_if_slaves_not_calculated ); 00058 CPPUNIT_TEST( test_one_depth_from_fixed ); 00059 CPPUNIT_TEST( test_two_depth_from_fixed ); 00060 CPPUNIT_TEST( test_zero_depth_from_surface ); 00061 CPPUNIT_TEST( test_one_depth_from_surface ); 00062 CPPUNIT_TEST( test_two_depth_from_surface ); 00063 CPPUNIT_TEST( test_zero_depth_from_curve ); 00064 CPPUNIT_TEST( test_one_depth_from_curve ); 00065 CPPUNIT_TEST( test_two_depth_from_curve ); 00066 CPPUNIT_TEST_SUITE_END(); 00067 00068 void test_slaved_common( unsigned depth, unsigned boundary ); 00069 00070 void make_mesh( MeshImpl& mesh, DomainClassifier& domain, const int intervals ); 00071 00072 public: 00073 void test_fail_if_slaves_not_calculated(); 00074 void test_one_depth_from_fixed() 00075 { 00076 test_slaved_common( 1, 4 ); 00077 } 00078 void test_two_depth_from_fixed() 00079 { 00080 test_slaved_common( 2, 4 ); 00081 } 00082 void test_zero_depth_from_surface() 00083 { 00084 test_slaved_common( 0, 2 ); 00085 } 00086 void test_one_depth_from_surface() 00087 { 00088 test_slaved_common( 1, 2 ); 00089 } 00090 void test_two_depth_from_surface() 00091 { 00092 test_slaved_common( 2, 2 ); 00093 } 00094 void test_zero_depth_from_curve() 00095 { 00096 test_slaved_common( 0, 1 ); 00097 } 00098 void test_one_depth_from_curve() 00099 { 00100 test_slaved_common( 1, 1 ); 00101 } 00102 void test_two_depth_from_curve() 00103 { 00104 test_slaved_common( 2, 1 ); 00105 } 00106 }; 00107 00108 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SlaveBoundaryVerticesTest, "SlaveBoundaryVerticesTest" ); 00109 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( SlaveBoundaryVerticesTest, "Unit" ); 00110 00111 void SlaveBoundaryVerticesTest::test_fail_if_slaves_not_calculated() 00112 { 00113 MsqError err; 00114 00115 Settings settings; 00116 settings.set_slaved_ho_node_mode( Settings::SLAVE_ALL ); 00117 SlaveBoundaryVertices tool( 1 ); 00118 00119 MeshImpl mesh; 00120 DomainClassifier domain; 00121 make_mesh( mesh, domain, 2 ); 00122 00123 MeshDomainAssoc mesh_and_domain = MeshDomainAssoc( &mesh, &domain ); 00124 tool.loop_over_mesh( &mesh_and_domain, &settings, err ); 00125 CPPUNIT_ASSERT( err ); 00126 err.clear(); 00127 } 00128 00129 void SlaveBoundaryVerticesTest::make_mesh( MeshImpl& mesh, DomainClassifier& domain, const int intervals ) 00130 { 00131 MsqPrintError err( std::cerr ); 00132 const char input_file[] = MESH_FILES_DIR "3D/vtk/quadratic/6x6x6-hex20.vtk"; 00133 00134 const Vector3D min( -3, -3, -3 ); 00135 const Vector3D max( 3, 3, 3 ); 00136 const Vector3D space = ( max - min ) * 1.0 / ( intervals ); 00137 00138 mesh.clear(); 00139 mesh.read_vtk( input_file, err ); 00140 ASSERT_NO_ERROR( err ); 00141 00142 const Vector3D corners[8] = { Vector3D( min[0], min[1], min[2] ), Vector3D( max[0], min[1], min[2] ), 00143 Vector3D( max[0], max[1], min[2] ), Vector3D( min[0], max[1], min[2] ), 00144 Vector3D( min[0], min[1], max[2] ), Vector3D( max[0], min[1], max[2] ), 00145 Vector3D( max[0], max[1], max[2] ), Vector3D( min[0], max[1], max[2] ) }; 00146 00147 MeshDomain* subdomains[26] = { new PlanarDomain( PlanarDomain::XZ, min[1] ), 00148 new PlanarDomain( PlanarDomain::YZ, max[0] ), 00149 new PlanarDomain( PlanarDomain::XZ, max[1] ), 00150 new PlanarDomain( PlanarDomain::YZ, min[0] ), 00151 new PlanarDomain( PlanarDomain::XY, min[2] ), 00152 new PlanarDomain( PlanarDomain::XY, max[2] ), 00153 new LineDomain( corners[0], corners[1] - corners[0] ), 00154 new LineDomain( corners[1], corners[2] - corners[1] ), 00155 new LineDomain( corners[2], corners[3] - corners[2] ), 00156 new LineDomain( corners[3], corners[0] - corners[3] ), 00157 new LineDomain( corners[0], corners[4] - corners[0] ), 00158 new LineDomain( corners[1], corners[5] - corners[1] ), 00159 new LineDomain( corners[2], corners[6] - corners[0] ), 00160 new LineDomain( corners[3], corners[7] - corners[1] ), 00161 new LineDomain( corners[4], corners[5] - corners[4] ), 00162 new LineDomain( corners[5], corners[6] - corners[5] ), 00163 new LineDomain( corners[6], corners[7] - corners[6] ), 00164 new LineDomain( corners[7], corners[4] - corners[7] ), 00165 new PointDomain( corners[0] ), 00166 new PointDomain( corners[1] ), 00167 new PointDomain( corners[2] ), 00168 new PointDomain( corners[3] ), 00169 new PointDomain( corners[4] ), 00170 new PointDomain( corners[5] ), 00171 new PointDomain( corners[6] ), 00172 new PointDomain( corners[7] ) }; 00173 const int subdims[26] = { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; 00174 DomainClassifier::classify_skin_geometrically( domain, &mesh, 1e-6, subdomains, subdims, 26, err ); 00175 domain.delete_sub_domains( true ); 00176 ASSERT_NO_ERROR( err ); 00177 } 00178 00179 void SlaveBoundaryVerticesTest::test_slaved_common( unsigned depth, unsigned boundary ) 00180 { 00181 MeshImpl mesh; 00182 DomainClassifier domain; 00183 make_mesh( mesh, domain, 2 * depth + 2 ); 00184 00185 MsqPrintError err( std::cerr ); 00186 std::vector< std::vector< Mesh::VertexHandle > > depths( depth + 1 ); 00187 std::set< Mesh::VertexHandle > non_slave; 00188 std::set< Mesh::VertexHandle >::iterator p; 00189 00190 // find boundary vertices 00191 std::vector< Mesh::VertexHandle > verts; 00192 mesh.get_all_vertices( verts, err ); 00193 ASSERT_NO_ERROR( err ); 00194 CPPUNIT_ASSERT( !verts.empty() ); 00195 if( boundary >= 4 ) 00196 { 00197 std::vector< bool > flags; 00198 mesh.vertices_get_fixed_flag( arrptr( verts ), flags, verts.size(), err ); 00199 ASSERT_NO_ERROR( err ); 00200 for( size_t i = 0; i < verts.size(); ++i ) 00201 if( flags[i] ) 00202 { 00203 depths[0].push_back( verts[i] ); 00204 non_slave.insert( verts[i] ); 00205 } 00206 } 00207 else 00208 { 00209 std::vector< unsigned short > dim( verts.size() ); 00210 domain.domain_DoF( arrptr( verts ), arrptr( dim ), verts.size(), err ); 00211 ASSERT_NO_ERROR( err ); 00212 for( size_t i = 0; i < verts.size(); ++i ) 00213 if( dim[i] <= boundary ) 00214 { 00215 depths[0].push_back( verts[i] ); 00216 non_slave.insert( verts[i] ); 00217 } 00218 } 00219 00220 // check that our input is usable for this test 00221 CPPUNIT_ASSERT( !verts.empty() ); 00222 00223 // find all vertices up to specified depth 00224 for( unsigned d = 0; d < depth; ++d ) 00225 { 00226 for( size_t i = 0; i < depths[d].size(); ++i ) 00227 { 00228 std::vector< Mesh::ElementHandle > adj; 00229 std::vector< size_t > junk; 00230 mesh.vertices_get_attached_elements( &depths[d][i], 1, adj, junk, err ); 00231 ASSERT_NO_ERROR( err ); 00232 for( size_t j = 0; j < adj.size(); ++j ) 00233 { 00234 junk.clear(); 00235 std::vector< Mesh::VertexHandle > conn; 00236 mesh.elements_get_attached_vertices( &adj[j], 1, conn, junk, err ); 00237 ASSERT_NO_ERROR( err ); 00238 for( size_t k = 0; k < conn.size(); ++k ) 00239 { 00240 p = non_slave.find( conn[k] ); 00241 if( p == non_slave.end() ) 00242 { 00243 non_slave.insert( p, conn[k] ); 00244 depths[d + 1].push_back( conn[k] ); 00245 } 00246 } 00247 } 00248 } 00249 } 00250 00251 // Check that our input is usable for this test: 00252 // Should have some vertices that are not within the specified depth of 00253 // the boundary. 00254 CPPUNIT_ASSERT( non_slave.size() < verts.size() ); 00255 00256 // Now build a map of all higher-order nodes in the mesh 00257 std::set< Mesh::VertexHandle > higher_order; 00258 std::vector< Mesh::ElementHandle > elems; 00259 mesh.get_all_elements( elems, err ); 00260 ASSERT_NO_ERROR( err ); 00261 CPPUNIT_ASSERT( !elems.empty() ); 00262 std::vector< EntityTopology > types( elems.size() ); 00263 mesh.elements_get_topologies( arrptr( elems ), arrptr( types ), elems.size(), err ); 00264 ASSERT_NO_ERROR( err ); 00265 for( size_t i = 0; i < elems.size(); ++i ) 00266 { 00267 std::vector< Mesh::VertexHandle > conn; 00268 std::vector< size_t > junk; 00269 mesh.elements_get_attached_vertices( &elems[i], 1, conn, junk, err ); 00270 ASSERT_NO_ERROR( err ); 00271 for( size_t j = TopologyInfo::corners( types[i] ); j < conn.size(); ++j ) 00272 higher_order.insert( conn[j] ); 00273 } 00274 00275 // Check that our input is usable for this test: 00276 // Should have some higher-order vertices 00277 CPPUNIT_ASSERT( !higher_order.empty() ); 00278 00279 // Now build a map of all fixed vertices 00280 std::set< Mesh::VertexHandle > fixed_vertices; 00281 std::vector< bool > fixed; 00282 mesh.vertices_get_fixed_flag( arrptr( verts ), fixed, verts.size(), err ); 00283 ASSERT_NO_ERROR( err ); 00284 for( size_t i = 0; i < verts.size(); ++i ) 00285 if( fixed[i] ) fixed_vertices.insert( verts[i] ); 00286 00287 // Now actually run the tool 00288 Settings settings; 00289 settings.set_slaved_ho_node_mode( Settings::SLAVE_CALCULATED ); 00290 SlaveBoundaryVertices tool( depth, boundary ); 00291 MeshDomainAssoc mesh_and_domain = MeshDomainAssoc( &mesh, &domain ); 00292 tool.loop_over_mesh( &mesh_and_domain, &settings, err ); 00293 ASSERT_NO_ERROR( err ); 00294 00295 // Now verify the results 00296 std::vector< unsigned char > bytes( verts.size() ); 00297 mesh.vertices_get_byte( arrptr( verts ), arrptr( bytes ), verts.size(), err ); 00298 ASSERT_NO_ERROR( err ); 00299 for( size_t i = 0; i < verts.size(); ++i ) 00300 { 00301 bool in_non_slave = ( non_slave.find( verts[i] ) != non_slave.end() ); 00302 bool in_fixed = ( fixed_vertices.find( verts[i] ) != fixed_vertices.end() ); 00303 bool in_higher_order = ( higher_order.find( verts[i] ) != higher_order.end() ); 00304 if( bytes[i] & MsqVertex::MSQ_DEPENDENT ) 00305 { // if slave node 00306 // must not be within 'depth' of boundary 00307 CPPUNIT_ASSERT( !in_non_slave ); 00308 // must be a higher-order vertex 00309 CPPUNIT_ASSERT( in_higher_order ); 00310 // must not be fixed 00311 CPPUNIT_ASSERT( !in_fixed ); 00312 } 00313 else 00314 { 00315 // there are three reasons that a vertex isn't slaved 00316 bool in_non_slave = ( non_slave.find( verts[i] ) != non_slave.end() ); 00317 bool in_fixed = ( fixed_vertices.find( verts[i] ) != fixed_vertices.end() ); 00318 bool in_higher_order = ( higher_order.find( verts[i] ) != higher_order.end() ); 00319 CPPUNIT_ASSERT( in_fixed || !in_higher_order || in_non_slave ); 00320 } 00321 } 00322 }