MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 #include "BoundedCylinderDomain.hpp" 00002 #include "MsqError.hpp" 00003 #include "MeshImpl.hpp" 00004 #include "MsqVertex.hpp" 00005 #include <cppunit/extensions/HelperMacros.h> 00006 #include <vector> 00007 #include <algorithm> 00008 #include <cstdlib> 00009 #include <cstdio> 00010 #include <iostream> 00011 00012 const double EPSILON = 1e-6; 00013 #define ASSERT_VECTORS_EQUAL( A, B ) CPPUNIT_ASSERT( ( ( A ) - ( B ) ).length() < EPSILON ) 00014 00015 using namespace MBMesquite; 00016 00017 class BoundedCylinderDomainTest : public CppUnit::TestFixture 00018 { 00019 private: 00020 CPPUNIT_TEST_SUITE( BoundedCylinderDomainTest ); 00021 CPPUNIT_TEST( test_domain_DoF ); 00022 CPPUNIT_TEST( test_z_snap_to ); 00023 CPPUNIT_TEST( test_x_snap_to ); 00024 CPPUNIT_TEST( test_create_curve_from_mesh ); 00025 CPPUNIT_TEST_SUITE_END(); 00026 00027 public: 00028 BoundedCylinderDomainTest() {} 00029 00030 void setUp() {} 00031 void tearDown() {} 00032 00033 void test_domain_DoF(); 00034 00035 void test_z_snap_to(); 00036 void test_x_snap_to(); 00037 00038 void test_create_curve_from_mesh(); 00039 }; 00040 00041 void BoundedCylinderDomainTest::test_domain_DoF() 00042 { 00043 MsqError err; 00044 const Mesh::EntityHandle list[] = { (void*)5, (void*)9, (void*)1, (void*)2, (void*)3 }; 00045 const size_t len = sizeof( list ) / sizeof( list[0] ); 00046 00047 BoundedCylinderDomain d( 1000 ); 00048 std::vector< Mesh::EntityHandle > handles; 00049 std::copy( list, list + len, std::back_inserter( handles ) ); 00050 d.create_curve( 10, handles ); 00051 00052 const Mesh::EntityHandle list2[] = { (void*)1, (void*)2, (void*)3, (void*)4, (void*)5, 00053 (void*)6, (void*)7, (void*)8, (void*)9, (void*)10 }; 00054 const size_t len2 = sizeof( list2 ) / sizeof( list2[0] ); 00055 unsigned short dof_list[len2]; 00056 d.domain_DoF( list2, dof_list, len2, err ); 00057 CPPUNIT_ASSERT( !err ); 00058 00059 for( size_t i = 0; i < len2; ++i ) 00060 { 00061 Mesh::EntityHandle handle = list2[i]; 00062 const Mesh::EntityHandle* f = std::find( list, list + len, handle ); 00063 unsigned short expected_dim = ( f < list + len ) ? 1 : 2; 00064 CPPUNIT_ASSERT_EQUAL( expected_dim, dof_list[i] ); 00065 } 00066 } 00067 00068 void BoundedCylinderDomainTest::test_z_snap_to() 00069 { 00070 const Mesh::EntityHandle HANDLE = (void*)20; 00071 const double ZPLANE = 5; 00072 00073 // Define a circle in the Z=5 plane, centered at (0,0,5) 00074 // with a radius of 10. 00075 std::vector< Mesh::EntityHandle > handles( 1 ); 00076 handles[0] = HANDLE; 00077 BoundedCylinderDomain d( 10 ); 00078 d.create_curve( ZPLANE, handles ); 00079 00080 Vector3D point; 00081 00082 // try a point inside and below the circle 00083 point.set( 5, 5, 2 ); 00084 d.snap_to( HANDLE, point ); 00085 CPPUNIT_ASSERT_DOUBLES_EQUAL( ZPLANE, point.z(), EPSILON ); 00086 CPPUNIT_ASSERT_DOUBLES_EQUAL( point.x(), point.y(), EPSILON ); 00087 point[2] = 0.0; 00088 CPPUNIT_ASSERT_DOUBLES_EQUAL( d.radius(), point.length(), EPSILON ); 00089 00090 // try a point outside and above the circle 00091 point.set( 50, 50, 50 ); 00092 d.snap_to( HANDLE, point ); 00093 CPPUNIT_ASSERT_DOUBLES_EQUAL( ZPLANE, point.z(), EPSILON ); 00094 CPPUNIT_ASSERT_DOUBLES_EQUAL( point.x(), point.y(), EPSILON ); 00095 point[2] = 0.0; 00096 CPPUNIT_ASSERT_DOUBLES_EQUAL( d.radius(), point.length(), EPSILON ); 00097 00098 // try a point on the circle 00099 Vector3D on_circ( d.radius(), 0, ZPLANE ); 00100 point = on_circ; 00101 d.snap_to( HANDLE, point ); 00102 ASSERT_VECTORS_EQUAL( on_circ, point ); 00103 00104 // try a point at the center of the circle 00105 point.set( d.radius(), 0, ZPLANE ); 00106 d.snap_to( HANDLE, point ); 00107 CPPUNIT_ASSERT_DOUBLES_EQUAL( ZPLANE, point.z(), EPSILON ); 00108 point[2] = 0.0; 00109 CPPUNIT_ASSERT_DOUBLES_EQUAL( d.radius(), point.length(), EPSILON ); 00110 00111 // try a different handle to make sure a handle not 00112 // on the the circle results in a point not on the circle 00113 double pplane = ZPLANE - 5; 00114 point.set( 0, 0, pplane ); 00115 d.snap_to( (void*)( (size_t)HANDLE + 1 ), point ); 00116 CPPUNIT_ASSERT_DOUBLES_EQUAL( pplane, point.z(), EPSILON ); 00117 } 00118 00119 void BoundedCylinderDomainTest::test_x_snap_to() 00120 { 00121 const Mesh::EntityHandle HANDLE = 0; 00122 const double XPLANE = -3; 00123 00124 // Define a circle in the X=-3 plane, centered at (-3,1,1) 00125 // with a radius of 1 00126 std::vector< Mesh::EntityHandle > handles( 1 ); 00127 handles[0] = HANDLE; 00128 BoundedCylinderDomain d( 1, Vector3D( 1, 0, 0 ), Vector3D( 0, 1, 1 ) ); 00129 d.create_curve( XPLANE, handles ); 00130 00131 Vector3D point, center( -3, 1, 1 ); 00132 00133 // try a point inside and below the circle 00134 point.set( XPLANE - 2, 1.5, 1.5 ); 00135 d.snap_to( HANDLE, point ); 00136 CPPUNIT_ASSERT_DOUBLES_EQUAL( XPLANE, point.x(), EPSILON ); 00137 CPPUNIT_ASSERT_DOUBLES_EQUAL( point.y(), point.z(), EPSILON ); 00138 point -= center; 00139 CPPUNIT_ASSERT_DOUBLES_EQUAL( d.radius(), point.length(), EPSILON ); 00140 00141 // try a point outside and above the circle 00142 point.set( XPLANE + 20, 50, 50 ); 00143 d.snap_to( HANDLE, point ); 00144 CPPUNIT_ASSERT_DOUBLES_EQUAL( XPLANE, point.x(), EPSILON ); 00145 CPPUNIT_ASSERT_DOUBLES_EQUAL( point.y(), point.z(), EPSILON ); 00146 point -= center; 00147 CPPUNIT_ASSERT_DOUBLES_EQUAL( d.radius(), point.length(), EPSILON ); 00148 00149 // try a point on the circle 00150 Vector3D on_circ( XPLANE, d.radius(), 0 ); 00151 point = on_circ; 00152 d.snap_to( HANDLE, point ); 00153 ASSERT_VECTORS_EQUAL( on_circ, point ); 00154 00155 // try a point at the center of the circle 00156 point = center; 00157 d.snap_to( HANDLE, point ); 00158 CPPUNIT_ASSERT_DOUBLES_EQUAL( XPLANE, point.x(), EPSILON ); 00159 point -= center; 00160 CPPUNIT_ASSERT_DOUBLES_EQUAL( d.radius(), point.length(), EPSILON ); 00161 00162 // try a different handle to make sure a handle not 00163 // on the the circle results in a point not on the circle 00164 double pplane = XPLANE + 5; 00165 point.set( pplane, 0, 0 ); 00166 d.snap_to( (void*)( (size_t)HANDLE + 1 ), point ); 00167 CPPUNIT_ASSERT_DOUBLES_EQUAL( pplane, point.x(), EPSILON ); 00168 } 00169 00170 // define a VDK file containing four quads quartering a 00171 // square with corners at ( +/-1, +/-1, 0 ) 00172 const char vtk_file[] = "# vtk DataFile Version 2.0\n" 00173 "Mesquite Mesh\n" 00174 "ASCII\n" 00175 "DATASET UNSTRUCTURED_GRID\n" 00176 "POINTS 9 float\n" 00177 " 0 0 0\n" 00178 " 1 0 0\n" 00179 " 1 1 0\n" 00180 " 0 1 0\n" 00181 "-1 1 0\n" 00182 "-1 0 0\n" 00183 "-1 -1 0\n" 00184 " 0 -1 0\n" 00185 " 1 -1 0\n" 00186 "CELLS 4 20\n" 00187 "4 0 1 2 3\n" 00188 "4 0 3 4 5\n" 00189 "4 0 5 6 7\n" 00190 "4 0 7 8 1\n" 00191 "CELL_TYPES 4\n" 00192 "9 9 9 9\n"; 00193 00194 void BoundedCylinderDomainTest::test_create_curve_from_mesh() 00195 { 00196 // create the input file to read 00197 char filename[] = "BCDTestTMP"; 00198 FILE* file = fopen( filename, "w" ); 00199 size_t s = fwrite( vtk_file, sizeof( vtk_file ), 1, file ); 00200 if( !s ) 00201 { 00202 remove( filename ); 00203 CPPUNIT_ASSERT( s ); 00204 } 00205 fclose( file ); 00206 00207 // read the file into a Mesh object 00208 MsqPrintError err( std::cout ); 00209 MeshImpl mesh; 00210 mesh.read_vtk( filename, err ); 00211 remove( filename ); 00212 CPPUNIT_ASSERT( !err ); 00213 00214 // create a domain such that the four corner vertices 00215 // of the 4-quad square mesh lie on the bounding curves 00216 // of the cylinder. 00217 BoundedCylinderDomain d( 1, Vector3D( 0, 1, 0 ) ); 00218 d.create_curve( 1, &mesh, EPSILON, err ); 00219 CPPUNIT_ASSERT( !err ); 00220 d.create_curve( -1, &mesh, EPSILON, err ); 00221 CPPUNIT_ASSERT( !err ); 00222 00223 // Get list of vertex coordinates from mesh 00224 std::vector< Mesh::VertexHandle > handles; 00225 mesh.get_all_vertices( handles, err ); 00226 CPPUNIT_ASSERT( !err ); 00227 CPPUNIT_ASSERT_EQUAL( handles.size(), (size_t)9 ); 00228 std::vector< MsqVertex > vertices( handles.size() ); 00229 mesh.vertices_get_coordinates( arrptr( handles ), arrptr( vertices ), handles.size(), err ); 00230 CPPUNIT_ASSERT( !err ); 00231 00232 // Get the dimension of the geometry each vertex is bound to 00233 std::vector< unsigned short > dims( handles.size() ); 00234 d.domain_DoF( arrptr( handles ), arrptr( dims ), handles.size(), err ); 00235 CPPUNIT_ASSERT( !err ); 00236 00237 // Check that the four corner vertices are on the curves 00238 // and all others are not 00239 for( size_t i = 0; i < handles.size(); ++i ) 00240 { 00241 if( fabs( vertices[i].x() ) < EPSILON || fabs( vertices[i].y() ) < EPSILON ) 00242 CPPUNIT_ASSERT_EQUAL( (unsigned short)2, dims[i] ); 00243 else 00244 CPPUNIT_ASSERT_EQUAL( (unsigned short)1, dims[i] ); 00245 } 00246 } 00247 00248 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( BoundedCylinderDomainTest, "BoundedCylinderDomainTest" ); 00249 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( BoundedCylinderDomainTest, "Unit" );