MOAB: Mesh Oriented datABase  (version 5.2.1)
MeshImplTest.cpp
Go to the documentation of this file.
00001 /* *****************************************************************
00002     MESQUITE -- The Mesh Quality Improvement Toolkit
00003 
00004     Copyright 2004 Sandia Corporation and Argonne National
00005     Laboratory.  Under the terms of Contract DE-AC04-94AL85000
00006     with Sandia Corporation, the U.S. Government retains certain
00007     rights in 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     diachin2@llnl.gov, djmelan@sandia.gov, mbrewer@sandia.gov,
00024     pknupp@sandia.gov, tleurent@mcs.anl.gov, tmunson@mcs.anl.gov,
00025     kraftche@cae.wisc.edu
00026 
00027   ***************************************************************** */
00028 /**
00029  *\file   MeshImplTest.hpp
00030  *\brief  Test MeshImpl class
00031  *
00032  * Test MeshImpl functionality.
00033  *
00034  * Note: there are additional tests for MeshImpl in the mis-named
00035  *       MeshInterfaceTest.cpp, VtkTest.cpp, and presumably ExodusTest.cpp.
00036  *
00037  *\author Jason Kraftcheck
00038  *\date   2007-10-18
00039  */
00040 
00041 #include "Mesquite.hpp"
00042 #include "MeshImpl.hpp"
00043 #include "MsqError.hpp"
00044 #include "MsqVertex.hpp"
00045 
00046 #include "UnitUtil.hpp"
00047 
00048 #include <iostream>
00049 #include <stdio.h>
00050 
00051 using namespace MBMesquite;
00052 
00053 const bool DUMP_MESH = false;
00054 
00055 class MeshImplTest : public CppUnit::TestFixture
00056 {
00057   public:
00058     CPPUNIT_TEST_SUITE( MeshImplTest );
00059     CPPUNIT_TEST( test_zero_length_data );
00060     CPPUNIT_TEST( skin_mesh_2D );
00061     CPPUNIT_TEST( skin_mesh_3D );
00062     CPPUNIT_TEST( skin_mesh_mixed );
00063     CPPUNIT_TEST( skin_mesh_higher_order );
00064     CPPUNIT_TEST_SUITE_END();
00065 
00066     void test_zero_length_data();
00067     void skin_mesh_2D();
00068     void skin_mesh_3D();
00069     void skin_mesh_mixed();
00070     void skin_mesh_higher_order();
00071 
00072     static void load_vtk( const char* file_data, MeshImpl& mesh, MsqError& err );
00073     static void dump_mesh( const char* filename, MeshImpl& data, MsqError& err );
00074 };
00075 
00076 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( MeshImplTest, "MeshImplTest" );
00077 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( MeshImplTest, "Unit" );
00078 
00079 void MeshImplTest::load_vtk( const char* file_data, MeshImpl& mesh, MsqError& err )
00080 {
00081     const char* fname = "MeshImplTest.vtk";
00082     FILE* f           = fopen( fname, "w" );
00083     if( !f )
00084     {
00085         MSQ_SETERR( err )( MsqError::FILE_ACCESS, "Cannot create temp file: %s\n", fname );
00086         return;
00087     }
00088 
00089     if( !fwrite( file_data, strlen( file_data ), 1, f ) )
00090     {
00091         MSQ_SETERR( err )( "I/O error while writing temporary file\n", MsqError::IO_ERROR );
00092         fclose( f );
00093         remove( fname );
00094         return;
00095     }
00096 
00097     fclose( f );
00098     mesh.read_vtk( fname, err );MSQ_CHKERR( err );
00099     remove( fname );
00100 
00101     mesh.mark_skin_fixed( err );MSQ_CHKERR( err );
00102 }
00103 
00104 void MeshImplTest::dump_mesh( const char* filename, MeshImpl& mesh, MsqError& err )
00105 {
00106     if( DUMP_MESH )
00107     {
00108         mesh.write_vtk( filename, err );
00109         if( MSQ_CHKERR( err ) ) std::cerr << err << std::endl;
00110     }
00111 }
00112 
00113 void MeshImplTest::test_zero_length_data()
00114 {
00115     const size_t num_vtx = 2, zero = 0;
00116     const double coords[3 * num_vtx] = { 0, 0, 0, 1, 1, 1 };
00117     const bool fixed[num_vtx]        = { false, false };
00118     std::vector< Mesh::ElementHandle > elems;
00119     std::vector< Mesh::VertexHandle > verts;
00120     MsqError err;
00121     const int conn[6]   = { 0, 1, 0, 1, 0, 1 };
00122     EntityTopology type = TRIANGLE;
00123 
00124     MeshImpl no_elem1( 2, 0, TRIANGLE, fixed, coords, 0 );
00125     verts.clear();
00126     no_elem1.get_all_vertices( verts, err );
00127     ASSERT_NO_ERROR( err );
00128     CPPUNIT_ASSERT_EQUAL( num_vtx, verts.size() );
00129     elems.clear();
00130     no_elem1.get_all_elements( elems, err );
00131     ASSERT_NO_ERROR( err );
00132     CPPUNIT_ASSERT_EQUAL( zero, elems.size() );
00133 
00134     MeshImpl no_elem2( 2, 0, 0, fixed, coords, 0 );
00135     verts.clear();
00136     no_elem2.get_all_vertices( verts, err );
00137     ASSERT_NO_ERROR( err );
00138     CPPUNIT_ASSERT_EQUAL( num_vtx, verts.size() );
00139     elems.clear();
00140     no_elem2.get_all_elements( elems, err );
00141     ASSERT_NO_ERROR( err );
00142     CPPUNIT_ASSERT_EQUAL( zero, elems.size() );
00143 
00144     MeshImpl no_elem3( 2, 0, TRIANGLE, fixed, coords, conn );
00145     verts.clear();
00146     no_elem3.get_all_vertices( verts, err );
00147     ASSERT_NO_ERROR( err );
00148     CPPUNIT_ASSERT_EQUAL( num_vtx, verts.size() );
00149     elems.clear();
00150     no_elem3.get_all_elements( elems, err );
00151     ASSERT_NO_ERROR( err );
00152     CPPUNIT_ASSERT_EQUAL( zero, elems.size() );
00153 
00154     MeshImpl no_elem4( 2, 0, &type, fixed, coords, conn );
00155     verts.clear();
00156     no_elem4.get_all_vertices( verts, err );
00157     ASSERT_NO_ERROR( err );
00158     CPPUNIT_ASSERT_EQUAL( num_vtx, verts.size() );
00159     elems.clear();
00160     no_elem4.get_all_elements( elems, err );
00161     ASSERT_NO_ERROR( err );
00162     CPPUNIT_ASSERT_EQUAL( zero, elems.size() );
00163 
00164     MeshImpl no_vert1( 0, 0, TRIANGLE, 0, 0, 0 );
00165     verts.clear();
00166     no_vert1.get_all_vertices( verts, err );
00167     ASSERT_NO_ERROR( err );
00168     CPPUNIT_ASSERT_EQUAL( zero, verts.size() );
00169     elems.clear();
00170     no_vert1.get_all_elements( elems, err );
00171     ASSERT_NO_ERROR( err );
00172     CPPUNIT_ASSERT_EQUAL( zero, elems.size() );
00173 
00174     MeshImpl no_vert2( 0, 0, 0, 0, 0, 0 );
00175     verts.clear();
00176     no_vert2.get_all_vertices( verts, err );
00177     ASSERT_NO_ERROR( err );
00178     CPPUNIT_ASSERT_EQUAL( zero, verts.size() );
00179     elems.clear();
00180     no_vert2.get_all_elements( elems, err );
00181     ASSERT_NO_ERROR( err );
00182     CPPUNIT_ASSERT_EQUAL( zero, elems.size() );
00183 
00184     MeshImpl no_vert3( 0, 0, TRIANGLE, fixed, coords, 0 );
00185     verts.clear();
00186     no_vert3.get_all_vertices( verts, err );
00187     ASSERT_NO_ERROR( err );
00188     CPPUNIT_ASSERT_EQUAL( zero, verts.size() );
00189     elems.clear();
00190     no_vert3.get_all_elements( elems, err );
00191     ASSERT_NO_ERROR( err );
00192     CPPUNIT_ASSERT_EQUAL( zero, elems.size() );
00193 
00194     MeshImpl no_vert4( 0, 0, 0, fixed, coords, 0 );
00195     verts.clear();
00196     no_vert4.get_all_vertices( verts, err );
00197     ASSERT_NO_ERROR( err );
00198     CPPUNIT_ASSERT_EQUAL( zero, verts.size() );
00199     elems.clear();
00200     no_vert4.get_all_elements( elems, err );
00201     ASSERT_NO_ERROR( err );
00202     CPPUNIT_ASSERT_EQUAL( zero, elems.size() );
00203 }
00204 
00205 void MeshImplTest::skin_mesh_2D()
00206 {
00207     MsqPrintError err( std::cerr );
00208     const char vtk_file[] = "#vtk DataFile Version 2.0\n"
00209                             "test data for MeshImplTest::skin_mesh_2D\n"
00210                             "ASCII\n"
00211                             "DATASET STRUCTURED_POINTS\n"
00212                             "DIMENSIONS 10 10 1\n"
00213                             "ORIGIN 0 0 0\n"
00214                             "SPACING 1 1 1\n";
00215 
00216     MeshImpl mesh;
00217     load_vtk( vtk_file, mesh, err );
00218     CPPUNIT_ASSERT( !err );
00219     dump_mesh( "MeshSkin2D.vtk", mesh, err );
00220 
00221     std::vector< Mesh::VertexHandle > verts;
00222     mesh.get_all_vertices( verts, err );
00223     CPPUNIT_ASSERT( !err );
00224 
00225     std::vector< Mesh::VertexHandle > elems;
00226     std::vector< size_t > offsets;
00227     std::vector< bool > fixed;
00228 
00229     for( unsigned i = 0; i < verts.size(); ++i )
00230     {
00231         elems.clear();
00232         offsets.clear();
00233         mesh.vertices_get_attached_elements( &verts[i], 1, elems, offsets, err );
00234         CPPUNIT_ASSERT( !err );
00235 
00236         mesh.vertices_get_fixed_flag( &verts[i], fixed, 1, err );
00237         CPPUNIT_ASSERT( !err );
00238 
00239         if( elems.size() == 4 )
00240             CPPUNIT_ASSERT( !fixed[0] );
00241         else
00242             CPPUNIT_ASSERT( fixed[0] );
00243     }
00244 }
00245 
00246 void MeshImplTest::skin_mesh_3D()
00247 {
00248     MsqPrintError err( std::cerr );
00249     const char vtk_file[] = "#vtk DataFile Version 2.0\n"
00250                             "test data for MeshImplTest::skin_mesh_3D\n"
00251                             "ASCII\n"
00252                             "DATASET STRUCTURED_POINTS\n"
00253                             "DIMENSIONS 10 10 10\n"
00254                             "ORIGIN 0 0 0\n"
00255                             "SPACING 1 1 1\n";
00256 
00257     MeshImpl mesh;
00258     load_vtk( vtk_file, mesh, err );
00259     CPPUNIT_ASSERT( !err );
00260     dump_mesh( "MeshSkin3D.vtk", mesh, err );
00261 
00262     std::vector< Mesh::VertexHandle > verts;
00263     mesh.get_all_vertices( verts, err );
00264     CPPUNIT_ASSERT( !err );
00265 
00266     std::vector< Mesh::VertexHandle > elems;
00267     std::vector< size_t > offsets;
00268     std::vector< bool > fixed;
00269 
00270     for( unsigned i = 0; i < verts.size(); ++i )
00271     {
00272         elems.clear();
00273         offsets.clear();
00274         mesh.vertices_get_attached_elements( &verts[i], 1, elems, offsets, err );
00275         CPPUNIT_ASSERT( !err );
00276 
00277         mesh.vertices_get_fixed_flag( &verts[i], fixed, 1, err );
00278         CPPUNIT_ASSERT( !err );
00279 
00280         if( elems.size() == 8 )
00281             CPPUNIT_ASSERT( !fixed[0] );
00282         else
00283             CPPUNIT_ASSERT( fixed[0] );
00284     }
00285 }
00286 
00287 // Make sure that if we have a volume mesh with one interior
00288 // face that the vertices on that face are not marked as fixed
00289 // due soley to the fact that there are no adjacent faces.
00290 // That is, the iterior face doesn't 'count' because it is the
00291 // side of a volume element.
00292 void MeshImplTest::skin_mesh_mixed()
00293 {
00294     MsqPrintError err( std::cerr );
00295     // define the mesh of a tetrahedron centered
00296     // at the origin as four tetrahedral elements
00297     // sharing a vertex at the origin.
00298     const char vtk_file[] = "#vtk DataFile Version 2.0\n"
00299                             "test data for MeshImplTest::skin_mesh_mixed\n"
00300                             "ASCII\n"
00301                             "DATASET UNSTRUCTURED_GRID\n"
00302                             "POINTS 5 float\n"
00303                             " 0  0  0\n"  // center vertex
00304                             " 2 -1 -1\n"
00305                             " 0  2 -1\n"
00306                             "-2 -1 -1\n"
00307                             " 0  0  2\n"
00308                             "CELLS 5 24\n"
00309                             "4 1 2 3 0\n"
00310                             "4 1 3 4 0\n"
00311                             "4 4 2 1 0\n"
00312                             "4 4 3 2 0\n"
00313                             "3 0 1 2\n"  // iterior triangle
00314                             "CELL_TYPES 5\n"
00315                             "10 10 10 10 5\n";
00316 
00317     MeshImpl mesh;
00318     load_vtk( vtk_file, mesh, err );
00319     CPPUNIT_ASSERT( !err );
00320     dump_mesh( "MeshSkinMixed.vtk", mesh, err );
00321 
00322     std::vector< Mesh::VertexHandle > verts;
00323     mesh.get_all_vertices( verts, err );
00324     CPPUNIT_ASSERT( !err );
00325     CPPUNIT_ASSERT_EQUAL( 5u, (unsigned)verts.size() );
00326     MsqVertex coords[5];
00327     mesh.vertices_get_coordinates( arrptr( verts ), coords, 5, err );
00328     CPPUNIT_ASSERT( !err );
00329     std::vector< bool > fixed;
00330     mesh.vertices_get_fixed_flag( arrptr( verts ), fixed, 5, err );
00331     CPPUNIT_ASSERT( !err );
00332     CPPUNIT_ASSERT_EQUAL( (size_t)5, fixed.size() );
00333 
00334     int free_idx = -1;
00335     for( int i = 0; i < 5; ++i )
00336     {
00337         if( !fixed[i] )
00338         {
00339             CPPUNIT_ASSERT_EQUAL( -1, free_idx );  // at most 1 free vertex
00340             free_idx = i;
00341         }
00342     }
00343     CPPUNIT_ASSERT( -1 != free_idx );  // at least one free vertex
00344 
00345     // free vertex must be at origin
00346     CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D( 0, 0, 0 ), coords[free_idx], DBL_EPSILON );
00347 }
00348 
00349 void MeshImplTest::skin_mesh_higher_order()
00350 {
00351     MsqPrintError err( std::cerr );
00352     // define a simple 2-quad mesh:
00353     //
00354     //  0    1    2    3    4
00355     //  o----o----o----o----o
00356     //  |         |         |
00357     //  |         |         |
00358     //  o5        o6        o7
00359     //  |         |         |
00360     //  |         |         |
00361     //  o----o----o----o----o
00362     //  8    9    10   11   12
00363     //
00364     // Expect all vertices but 6 to be fixed.
00365     // Position mesh such that vertex 6 is at the origin.
00366 
00367     const char vtk_file[] = "#vtk DataFile Version 2.0\n"
00368                             "test data for MeshImplTest::skin_mesh_mixed\n"
00369                             "ASCII\n"
00370                             "DATASET UNSTRUCTURED_GRID\n"
00371                             "POINTS 13 float\n"
00372                             "-2  1  0\n"
00373                             "-1  1  0\n"
00374                             " 0  1  0\n"
00375                             " 1  1  0\n"
00376                             " 2  1  0\n"
00377                             "-2  0  0\n"
00378                             " 0  0  0\n"
00379                             " 2  0  0\n"
00380                             "-2 -1  0\n"
00381                             "-1 -1  0\n"
00382                             " 0 -1  0\n"
00383                             " 1 -1  0\n"
00384                             " 2 -1  0\n"
00385                             "CELLS 2 18\n"
00386                             "8 0 8 10 2 5 9 6 1\n"
00387                             "8 2 10 12 4 6 11 7 3\n"
00388                             "CELL_TYPES 2\n"
00389                             "23 23\n";
00390 
00391     MeshImpl mesh;
00392     load_vtk( vtk_file, mesh, err );
00393     CPPUNIT_ASSERT( !err );
00394     dump_mesh( "MeshSkinHO.vtk", mesh, err );
00395 
00396     std::vector< Mesh::VertexHandle > verts;
00397     mesh.get_all_vertices( verts, err );
00398     CPPUNIT_ASSERT( !err );
00399     CPPUNIT_ASSERT_EQUAL( 13u, (unsigned)verts.size() );
00400     MsqVertex coords[13];
00401     mesh.vertices_get_coordinates( arrptr( verts ), coords, 13, err );
00402     CPPUNIT_ASSERT( !err );
00403     std::vector< bool > fixed;
00404     mesh.vertices_get_fixed_flag( arrptr( verts ), fixed, 13, err );
00405     CPPUNIT_ASSERT( !err );
00406     CPPUNIT_ASSERT_EQUAL( (size_t)13, fixed.size() );
00407 
00408     int free_idx = -1;
00409     for( int i = 0; i < 13; ++i )
00410     {
00411         if( !fixed[i] )
00412         {
00413             CPPUNIT_ASSERT_EQUAL( -1, free_idx );  // at most 1 free vertex
00414             free_idx = i;
00415         }
00416     }
00417     CPPUNIT_ASSERT( -1 != free_idx );  // at least one free vertex
00418 
00419     // free vertex must be at origin
00420     CPPUNIT_ASSERT_VECTORS_EQUAL( Vector3D( 0, 0, 0 ), coords[free_idx], DBL_EPSILON );
00421 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines