Beispiel #1
0
  void VtkTest::test_read_quadratic( const char* filename )
  {
    const size_t NUM_ELEM = 8;
  
    MeshImpl mesh;
    MsqPrintError err(cout);
    
    mesh.read_vtk( filename, err );
    ASSERT_NO_ERROR(err);
    
    std::vector<Mesh::ElementHandle> elems(NUM_ELEM);
    mesh.get_all_elements( elems, err );
    ASSERT_NO_ERROR(err);
    CPPUNIT_ASSERT_EQUAL(elems.size(), NUM_ELEM );
    
    std::vector<Mesh::VertexHandle> conn;
    std::vector<size_t> offsets;
    mesh.elements_get_attached_vertices( arrptr(elems), elems.size(), conn, offsets, err );
    ASSERT_NO_ERROR(err);
    CPPUNIT_ASSERT_EQUAL( conn.size(), (size_t)108 );
    
    EntityTopology types[NUM_ELEM];
    mesh.elements_get_topologies( arrptr(elems), types, NUM_ELEM, err );
    ASSERT_NO_ERROR(err);

    static const double hex_corners[] = 
     {  1.0, -1.0, -1.0, 
        1.0,  1.0, -1.0, 
       -1.0,  1.0, -1.0, 
       -1.0, -1.0, -1.0,
        1.0, -1.0,  1.0, 
        1.0,  1.0,  1.0, 
       -1.0,  1.0,  1.0, 
       -1.0, -1.0,  1.0 };
    static const double tet_corners[] = 
     {  1.0, -1.0, -1.0,
        1.0,  1.0, -1.0,
       -1.0,  0.0, -1.0,
        0.0,  0.0,  1.0 };
    static const double pyr_corners[] = 
     {  1.0, -1.0, -1.0, 
        1.0,  1.0, -1.0, 
       -1.0,  1.0, -1.0, 
       -1.0, -1.0, -1.0,
        0.0,  0.0,  1.0 };
    static const double pri_corners[] = 
      { -1.0, -1.0, -1.0,
         1.0,  1.0, -1.0,
        -1.0,  1.0, -1.0,
        -1.0, -1.0,  1.0,
         1.0,  1.0,  1.0,
        -1.0,  1.0,  1.0 };
    static const unsigned hex_edges[] =
     { 0, 1, 
       1, 2, 
       2, 3,
       3, 0,
       0, 4,
       1, 5,
       2, 6,
       3, 7,
       4, 5,
       5, 6,
       6, 7,
       7, 4 };
    static const unsigned tet_edges[] = 
     { 0, 1,
       1, 2, 
       2, 0,
       0, 3,
       1, 3, 
       2, 3 };
    static const unsigned pri_edges[] =
     { 0, 1, 
       1, 2, 
       2, 0,
       0, 3,
       1, 4,
       2, 5,
       3, 4,
       4, 5,
       5, 3 };
    static const unsigned pyr_edges[] =
     { 0, 1, 
       1, 2, 
       2, 3,
       3, 0,
       0, 4,
       1, 4,
       2, 4,
       3, 4 };
    static const unsigned hex_faces[] = 
    { 4, 0, 1, 5, 4,
      4, 1, 2, 6, 5,
      4, 2, 3, 7, 6,
      4, 3, 0, 4, 7,
      4, 3, 2, 1, 0,
      4, 4, 5, 6, 7
    };
    static const struct {
      EntityTopology topology;
      unsigned num_corners;
      unsigned num_edges;
      unsigned num_faces; // if non-zero expect mid-face nodes
      unsigned num_region; // if non-zero expect mid-region node
      const double* corners;
      const unsigned* edges;
      const unsigned* faces;
    } expected_elems[NUM_ELEM] = {
      { Mesquite::HEXAHEDRON,    8, 12, 0, 0, hex_corners, hex_edges, hex_faces },
      { Mesquite::HEXAHEDRON,    8, 12, 6, 1, hex_corners, hex_edges, hex_faces },
      { Mesquite::TETRAHEDRON,   4,  6, 0, 0, tet_corners, tet_edges, 0 },
      { Mesquite::QUADRILATERAL, 4,  4, 0, 0, hex_corners, hex_edges, 0 },
      { Mesquite::QUADRILATERAL, 4,  4, 0, 1, hex_corners, hex_edges, 0 },
      { Mesquite::TRIANGLE,      3,  3, 0, 0, tet_corners, tet_edges, 0 },
      { Mesquite::PRISM,         6,  9, 0, 0, pri_corners, pri_edges, 0 },
      { Mesquite::PYRAMID,       5,  8, 0, 0, pyr_corners, pyr_edges, 0 } };
    
    MsqVertex have;
    std::vector<Mesh::VertexHandle>::iterator v_it = conn.begin();
    for (unsigned i = 0; i < NUM_ELEM; ++i)
    {
      CPPUNIT_ASSERT_EQUAL( expected_elems[i].topology, types[i] );

      size_t vtx_start = offsets[i];
      size_t vtx_end = offsets[i+1];
      size_t conn_len = expected_elems[i].num_corners 
                      + expected_elems[i].num_edges
                      + expected_elems[i].num_faces
                      + expected_elems[i].num_region;
      CPPUNIT_ASSERT_EQUAL( conn_len, vtx_end - vtx_start );
      
      for (unsigned c = 0; c < expected_elems[i].num_corners; ++c, ++v_it)
      {
        Vector3D expected(expected_elems[i].corners + 3*c);
        mesh.vertices_get_coordinates( &*v_it, &have, 1, err );
        ASSERT_NO_ERROR(err);
        expected -= have;
        CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, expected.length(), DBL_EPSILON );
      }
      
      for (unsigned m = 0; m < expected_elems[i].num_edges; ++m, ++v_it)
      {
        unsigned start_idx = expected_elems[i].edges[2*m];
        unsigned end_idx = expected_elems[i].edges[2*m+1];
        Vector3D start( expected_elems[i].corners + 3*start_idx );
        Vector3D end( expected_elems[i].corners + 3*end_idx );
        Vector3D expected = 0.5 * (start + end);
        
        mesh.vertices_get_coordinates( &*v_it, &have, 1, err );
        ASSERT_NO_ERROR(err);
        
        expected -= have;
        CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, expected.length(), DBL_EPSILON );
      }

      const unsigned* f_it = expected_elems[i].faces;
      for (unsigned m = 0; m < expected_elems[i].num_faces; ++m, ++v_it)
      {
        Vector3D expected(0,0,0);
        const unsigned face_size = *f_it; ++f_it;
        CPPUNIT_ASSERT( face_size == 3u || face_size == 4u );
        for (unsigned f = 0; f < face_size; ++f, ++f_it) 
          expected += Vector3D( expected_elems[i].corners + 3 * *f_it );
        expected /= face_size;
        
        mesh.vertices_get_coordinates( &*v_it, &have, 1, err );
        ASSERT_NO_ERROR(err);
        
        expected -= have;
        CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, expected.length(), DBL_EPSILON );
      }
      
      if (expected_elems[i].num_region) {
        CPPUNIT_ASSERT_EQUAL( 1u, expected_elems[i].num_region );

        Vector3D expected(0,0,0);
        for (unsigned m = 0; m < expected_elems[i].num_corners; ++m)
          expected += Vector3D( expected_elems[i].corners + 3*m );
        expected /= expected_elems[i].num_corners;

        mesh.vertices_get_coordinates( &*v_it, &have, 1, err );
        ASSERT_NO_ERROR(err);

        expected -= have;
        CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, expected.length(), DBL_EPSILON );

        ++v_it;
      }
    }
  }
Beispiel #2
0
// Routine to create initial mesh for test.
// o Marks vertices at a greater topological depth than the specified
//   value as slaved.  
// o Perturbs higher-order vertices on skin towards element center
// o Marks skin vertices as fixed
int main( int argc, char* argv[] )
{
  if (argc != 4)
    usage(argv[0]);
  
  char* endptr = 0;
  const long n = strtol( argv[1], &endptr, 0 );
  if (*endptr || n < 0) 
    usage(argv[0]);
  
    // read input mesh
  MeshImpl mesh;
  MsqPrintError err(std::cerr);
  mesh.read_vtk( argv[2], err );
  if (err) return 1;
  
    // get skin vertices
  mesh.mark_skin_fixed( err, true );
  if (err) return 1;
  std::vector<Mesh::VertexHandle> verts;
  mesh.get_all_vertices( verts, err );
  if (err) return 1;
  std::vector<bool> fixed;
  mesh.vertices_get_fixed_flag( arrptr(verts), fixed, verts.size(), err );
  if (err) return 1;
  std::vector<Mesh::VertexHandle> skin;
  for (size_t i = 0; i < verts.size(); ++i)
    if (fixed[i])
      skin.push_back( verts[i] );
  
    // create map for vertex depth, and initialize to 0 for skin vertices
  std::map<Mesh::VertexHandle,int> depth;
  std::map<Mesh::VertexHandle,int>::iterator d_iter;
  for (size_t i = 0; i < skin.size(); ++i)
    depth[skin[i]] = 0;
  
    // get all elements
  std::vector<Mesh::ElementHandle> curr, next;
  std::vector<Mesh::ElementHandle> conn;
  std::vector<size_t> off;
  mesh.get_all_elements( next, err );

    // build sorted list of higher-order vertices
  std::vector<Mesh::VertexHandle> higher_order;
  for (size_t i = 0; i < next.size(); ++i) {
    Mesh::ElementHandle elem = next[i];
    conn.clear();
    mesh.elements_get_attached_vertices( &elem, 1, conn, off, err );
    if (err) return 1;
    EntityTopology type;
    mesh.elements_get_topologies( &elem, &type, 1, err );
    std::copy( conn.begin() + TopologyInfo::corners(type), conn.end(), 
               std::back_inserter( higher_order ) );
  }
  std::sort( higher_order.begin(), higher_order.end() );
  higher_order.erase( std::unique( higher_order.begin(), higher_order.end() ), 
                      higher_order.end() );

    // build depth map for all vertices
  while (!next.empty()) {
    curr.swap( next );
    next.clear();
    while (!curr.empty()) {
      Mesh::ElementHandle elem = curr.back();
      curr.pop_back();
      
      conn.clear();
      mesh.elements_get_attached_vertices( &elem, 1, conn, off, err );
      if (err) return 1;
      
      int min = std::numeric_limits<int>::max();
      for (size_t i = 0; i < conn.size(); ++i) {
        d_iter = depth.find( conn[i] );
        if (d_iter != depth.end() && d_iter->second < min)
          min = d_iter->second;
      }
      
      if (min == std::numeric_limits<int>::max()) {
        next.push_back( elem );
        continue;
      }
      
      for (size_t i = 0; i < conn.size(); ++i) {
        d_iter = depth.find( conn[i] );
      
        if (d_iter == depth.end() || d_iter->second > min+1)
          depth[conn[i]] = min+1;
      }
    }
  }
  
    // write depth map to tag for debugging purposes
  std::vector<int> depth_vals(verts.size());
  for (size_t i = 0; i < verts.size(); ++i)
    depth_vals[i] = depth[verts[i]];
  TagHandle tag = mesh.tag_create( "depth", Mesh::INT, 1, 0, err );
  if (err) return 1;
  mesh.tag_set_vertex_data( tag, verts.size(), arrptr(verts), arrptr(depth_vals), err );
  if (err) return 1;
  
  
    // set tag specifying slaved vertices
  for (size_t i = 0; i < verts.size(); ++i)
    if (std::binary_search( higher_order.begin(), higher_order.end(), verts[i] ))
      depth_vals[i] = depth[verts[i]] > n;
    else
      depth_vals[i] = 0;
  tag = mesh.tag_create( "slaved", Mesh::INT, 1, 0, err );
  if (err) return 1;
  mesh.tag_set_vertex_data( tag, verts.size(), arrptr(verts), arrptr(depth_vals), err );
  if (err) return 1;
  
    // perturb mid-edge nodes along boundary
  std::vector<MsqVertex> coords;
  for (size_t i = 0; i < skin.size(); ++i) {
    if (!std::binary_search( higher_order.begin(), higher_order.end(), skin[i]))
      continue;
  
    curr.clear();
    mesh.vertices_get_attached_elements( &skin[i], 1, curr, off, err );
    if (err) return 1;
    assert(curr.size() == 1);
    conn.clear();
    mesh.elements_get_attached_vertices( arrptr(curr), 1, conn, off, err );
    if (err) return 1;
    
    // estimate element center
    coords.resize( conn.size() );
    mesh.vertices_get_coordinates( arrptr(conn), arrptr(coords), conn.size(), err );
    if (err) return 1;
    
    Vector3D mean(0.0);
    for (size_t j = 0; j < coords.size(); ++j)
      mean += coords[j];
    mean /= coords.size();
    
    size_t idx = std::find( conn.begin(), conn.end(), skin[i] ) - conn.begin();
    assert(idx < conn.size());
    Vector3D init = coords[idx];
    Vector3D pos = (1 - PERTURB_FRACT) * init + PERTURB_FRACT * mean;
    mesh.vertex_set_coordinates( skin[i], pos, err );
    if (err) return 1;
  }
  
  mesh.write_vtk( argv[3], err );
  if (err) return 1;
  
  return 0;
}
Beispiel #3
0
void SlaveBoundaryVerticesTest::test_slaved_common( unsigned depth, unsigned boundary )
{
  MeshImpl mesh;
  DomainClassifier domain;
  make_mesh( mesh, domain, 2*depth+2 );

  MsqPrintError err(std::cerr);
  std::vector< std::vector<Mesh::VertexHandle> > depths(depth+1);
  std::set<Mesh::VertexHandle> non_slave;
  std::set<Mesh::VertexHandle>::iterator p;

    // find boundary vertices
  std::vector<Mesh::VertexHandle> verts;
  mesh.get_all_vertices( verts, err ); ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT(!verts.empty());
  if (boundary >= 4) {
    std::vector<bool> flags;
    mesh.vertices_get_fixed_flag( arrptr(verts), flags, verts.size(), err );
    ASSERT_NO_ERROR(err);
    for (size_t i = 0; i < verts.size(); ++i)
      if (flags[i]) {
        depths[0].push_back( verts[i] );
        non_slave.insert( verts[i] );
      }
  }
  else {
    std::vector<unsigned short> dim(verts.size());
    domain.domain_DoF( arrptr(verts), arrptr(dim), verts.size(), err );
    ASSERT_NO_ERROR(err);
    for (size_t i = 0; i < verts.size(); ++i)
      if (dim[i] <= boundary) {
        depths[0].push_back( verts[i] );
        non_slave.insert( verts[i] );
      }
  }
  
    // check that our input is usable for this test
  CPPUNIT_ASSERT( !verts.empty() );
  
    // find all vertices up to specified depth
  for (unsigned d = 0; d < depth; ++d) {
    for (size_t i = 0; i < depths[d].size(); ++i) {
      std::vector<Mesh::ElementHandle> adj;
      std::vector<size_t> junk;
      mesh.vertices_get_attached_elements( &depths[d][i], 1, adj, junk, err );
      ASSERT_NO_ERROR(err);
      for(size_t j = 0; j < adj.size(); ++j) {
        junk.clear();
        std::vector<Mesh::VertexHandle> conn;
        mesh.elements_get_attached_vertices( &adj[j], 1, conn, junk, err );
        ASSERT_NO_ERROR(err);
        for (size_t k = 0; k < conn.size(); ++k) {
          p = non_slave.find(conn[k]);
          if (p == non_slave.end()) {
            non_slave.insert( p, conn[k] );
            depths[d+1].push_back( conn[k] );
          }
        }
      }
    }
  }
  
    // Check that our input is usable for this test:
    // Should have some vertices that are not within the specified depth of 
    // the boundary.
  CPPUNIT_ASSERT( non_slave.size() < verts.size() );
  
    // Now build a map of all higher-order nodes in the mesh
  std::set<Mesh::VertexHandle> higher_order;
  std::vector<Mesh::ElementHandle> elems;
  mesh.get_all_elements( elems, err ); 
  ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT(!elems.empty());
  std::vector<EntityTopology> types(elems.size());
  mesh.elements_get_topologies( arrptr(elems), arrptr(types), elems.size(), err );
  ASSERT_NO_ERROR(err);
  for (size_t i = 0; i < elems.size(); ++i) {
    std::vector<Mesh::VertexHandle> conn;
    std::vector<size_t> junk;
    mesh.elements_get_attached_vertices( &elems[i], 1, conn, junk, err );
    ASSERT_NO_ERROR(err);
    for (size_t j = TopologyInfo::corners( types[i] ); j < conn.size(); ++j)
      higher_order.insert( conn[j] );
  }
  
    // Check that our input is usable for this test:
    // Should have some higher-order vertices
  CPPUNIT_ASSERT( !higher_order.empty() );
  
    // Now build a map of all fixed vertices
  std::set<Mesh::VertexHandle> fixed_vertices;
  std::vector<bool> fixed;
  mesh.vertices_get_fixed_flag( arrptr(verts), fixed, verts.size(), err );
  ASSERT_NO_ERROR(err);
  for (size_t i = 0; i < verts.size(); ++i)
    if (fixed[i])
      fixed_vertices.insert( verts[i] );

    // Now actually run the tool
  Settings settings;
  settings.set_slaved_ho_node_mode( Settings::SLAVE_CALCULATED );
  SlaveBoundaryVertices tool( depth, boundary );
  tool.loop_over_mesh( &mesh, &domain, &settings, err );
  ASSERT_NO_ERROR(err);
  
    // Now verify the results
  std::vector<unsigned char> bytes( verts.size() );
  mesh.vertices_get_byte( arrptr(verts), arrptr(bytes), verts.size(), err );
  ASSERT_NO_ERROR(err);
  for (size_t i = 0; i < verts.size(); ++i) {
    bool in_non_slave = (non_slave.find( verts[i] ) != non_slave.end());
    bool in_fixed = (fixed_vertices.find( verts[i] ) != fixed_vertices.end());
    bool in_higher_order = (higher_order.find( verts[i] ) != higher_order.end());
    if (bytes[i] & MsqVertex::MSQ_DEPENDENT) { // if slave node
        // must not be within 'depth' of boundary
      CPPUNIT_ASSERT( !in_non_slave );
        // must be a higher-order vertex
      CPPUNIT_ASSERT( in_higher_order );
        // must not be fixed
      CPPUNIT_ASSERT( !in_fixed );
    }
    else {
        // there are three reasons that a vertex isn't slaved
      bool in_non_slave = (non_slave.find( verts[i] ) != non_slave.end());
      bool in_fixed = (fixed_vertices.find( verts[i] ) != fixed_vertices.end());
      bool in_higher_order = (higher_order.find( verts[i] ) != higher_order.end());
      CPPUNIT_ASSERT( in_fixed || !in_higher_order || in_non_slave );
    }
  }
}