void TagVertexMeshTest::test_reference_mesh()
{
  MsqPrintError err( std::cerr );
  TagVertexMesh tag_mesh( err, realMesh, true );
  ASSERT_NO_ERROR(err);
  
  std::vector<Mesh::VertexHandle> vertices;
  realMesh->get_all_vertices( vertices, err );
  ASSERT_NO_ERROR(err);
  
    // copy real mesh coordinates into tag data in TagVertexMesh
  InstructionQueue q;
  q.add_tag_vertex_mesh( &tag_mesh, err );
  ASSERT_NO_ERROR(err);
  q.run_instructions( realMesh, err );
  ASSERT_NO_ERROR(err);
  
    // Check that initial position for vertex matches that of real mesh
  Mesh::VertexHandle vertex = vertices[0];
  MsqVertex get_coords;
  Vector3D orig_coords, real_coords, tag_coords;
  realMesh->vertices_get_coordinates( &vertex, &get_coords, 1, err );
  ASSERT_NO_ERROR(err);
  orig_coords = get_coords;
  tag_mesh.vertices_get_coordinates( &vertex, &get_coords, 1, err );
  ASSERT_NO_ERROR(err);
  tag_coords = get_coords;
  CPPUNIT_ASSERT_VECTORS_EQUAL( orig_coords, tag_coords, DBL_EPSILON );
  
    // Check that modified vertex coords show up in real mesh but not
    // tag mesh.
  realMesh->vertices_get_coordinates( &vertex, &get_coords, 1, err );
  ASSERT_NO_ERROR(err);
  orig_coords = get_coords;
  Vector3D new_coords(5,5,5);
  realMesh->vertex_set_coordinates( vertex, new_coords, err );
  ASSERT_NO_ERROR(err);
  tag_mesh.vertices_get_coordinates( &vertex, &get_coords, 1, err );
  ASSERT_NO_ERROR(err);
  tag_coords = get_coords;
  CPPUNIT_ASSERT_VECTORS_EQUAL( orig_coords, tag_coords, DBL_EPSILON );
    // restore realMesh to initial state
  realMesh->vertex_set_coordinates( vertex, orig_coords, err );
  ASSERT_NO_ERROR(err);
}
Exemple #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;
}
Exemple #3
0
int main( int argc, char* argv[] )
{
  const char* deformed_file = 0;
  const char* smoothed_file = 0;
  const char* tag_file = 0;
  struct { const char* flag; const char** name_ptr; } flags[] = 
    { { "-d", &deformed_file },
      { "-t", &tag_file      },
      { "-f", &smoothed_file },
      { 0, 0 } };
  
  for (int i = 1; i < argc; ++i) {
    int j;
    for (j = 0; flags[j].flag && strcmp( flags[j].flag, argv[i] ); ++j);
    if (!flags[j].flag) {
      std::cerr << "Invalid argument: \"" << argv[i] << '"' << std::endl;
      usage(argv[0]);
    }
    else if (++i == argc) {
      std::cerr << "Expected argument following \"" << argv[i-1] << '"' << std::endl;
      usage(argv[0]);
    }
    *(flags[j].name_ptr) = argv[i];
  }
  
    // load mesh
  MsqPrintError err(std::cerr);
  MeshImpl mesh;
  mesh.read_vtk( INPUT_FILE, err ); 
  if (MSQ_CHKERR(err)) return 1;
  
    // find boundary vertices
  std::vector<Mesh::VertexHandle> curves[4];
  Mesh::VertexHandle corners[4];
  classify_boundary( &mesh, corners, curves, err );
  if (MSQ_CHKERR(err)) return 1;
  
    // new, "deformed" domain will be an 2HDx2HD planar square
  const double corner_coords[][3] = { {-HD,-HD, Z},
                                      { HD,-HD, Z},
                                      { HD, HD, Z},
                                      {-HD, HD, Z} };
  LineDomain lines[4] = { 
    LineDomain( Vector3D(corner_coords[0]), Vector3D( 1, 0, 0) ),
    LineDomain( Vector3D(corner_coords[1]), Vector3D( 0, 1, 0) ),
    LineDomain( Vector3D(corner_coords[2]), Vector3D(-1, 0, 0) ),
    LineDomain( Vector3D(corner_coords[3]), Vector3D( 0,-1, 0) ) };
  PlanarDomain surface( PlanarDomain::XY, Z );
  
    // save initial mesh state
  DeformingCurveSmoother curve_tool;
  for (int i = 0; i < 4; ++i) {
    curve_tool.store_initial_mesh( &mesh, &curves[i][0], curves[i].size(), &lines[i], err );
    if (MSQ_CHKERR(err)) return 1;
  }
  DeformingDomainWrapper wrapper;
  wrapper.store_initial_mesh( &mesh, err );
  if (MSQ_CHKERR(err)) return 1;
  
  cond_write_file( mesh, tag_file );
  
    // move corner vertices to new location
  for (int i = 0; i < 4; ++i) {
    Vector3D vect(corner_coords[i]);
    mesh.vertex_set_coordinates( corners[i], vect, err );
    if (MSQ_CHKERR(err)) return 1;
  }
  std::vector<bool> fixed(4,true);
  mesh.vertices_set_fixed_flag( corners, fixed, 4, err );
  if (MSQ_CHKERR(err)) return 1;
  
    // smooth curves
  for (int i = 0; i < 4; ++i) {
    curve_tool.smooth_curve( &mesh, &curves[i][0], curves[i].size(), &lines[i],
                             DeformingCurveSmoother::PROPORTIONAL, err );
    if (MSQ_CHKERR(err)) return 1;
    fixed.resize(curves[i].size(),true);
    mesh.vertices_set_fixed_flag( &curves[i][0], fixed, curves[i].size(), err );
    if (MSQ_CHKERR(err)) return 1;
  }
  
  cond_write_file( mesh, deformed_file );
  
    // smooth surface mesh
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &surface);
  wrapper.run_instructions( &mesh_and_domain, err );
  if (MSQ_CHKERR(err)) return 1;
  
  cond_write_file( mesh, smoothed_file );
  return wrapper.quality_assessor().invalid_elements();
}
Exemple #4
0
void BCDTest::compare_bcd( ObjectiveFunction* OF, string name, const char* mesh_file )
{
  MsqPrintError err(cout);
  size_t i;
  vector<MsqVertex> initial_coords, global_coords, bcd_coords;
  vector<Mesh::VertexHandle> vertex_list;
  
    // set up a smoother
  TerminationCriterion iterations, vertex_movement;
  iterations.add_iteration_limit( 2 );
  vertex_movement.add_absolute_vertex_movement( 1e-3 );

  SolverType global_solver( OF );
  SolverType bcd_solver( OF );
  global_solver.use_global_patch();
  bcd_solver.use_element_on_vertex_patch();
  bcd_solver.do_block_coordinate_descent_optimization();
  global_solver.set_inner_termination_criterion( &vertex_movement );
  bcd_solver.set_inner_termination_criterion( &iterations );
  bcd_solver.set_outer_termination_criterion( &vertex_movement );

  QualityAssessor qa;
  qa.add_quality_assessment( &mMetric );

  InstructionQueue global_q, bcd_q;
  global_q.add_quality_assessor( &qa, err );
  global_q.set_master_quality_improver( &global_solver, err );
  global_q.add_quality_assessor( &qa, err );
  bcd_q.set_master_quality_improver( &bcd_solver, err );
  bcd_q.add_quality_assessor( &qa, err );
  
    // read mesh
  MeshImpl mesh;
  mesh.read_vtk( mesh_file, err ); ASSERT_NO_ERROR(err);
  mesh.get_all_vertices( vertex_list, err ); ASSERT_NO_ERROR(err);
  CPPUNIT_ASSERT(!vertex_list.empty());
  initial_coords.resize( vertex_list.size() );
  mesh.vertices_get_coordinates( arrptr(vertex_list), arrptr(initial_coords), vertex_list.size(), err );
  ASSERT_NO_ERROR(err);
  
    // run global smoother
  global_q.run_instructions( &mesh, err ); 
  ASSERT_NO_ERROR(err);
  mesh.write_vtk( (name + "-gbl.vtk").c_str(), err );
  global_coords.resize( vertex_list.size() );
  mesh.vertices_get_coordinates( arrptr(vertex_list), arrptr(global_coords), vertex_list.size(), err );
  ASSERT_NO_ERROR(err);
  
    // restore initial vertex positions
  for (i = 0; i < vertex_list.size(); ++i) {
    mesh.vertex_set_coordinates( vertex_list[i], initial_coords[i], err );
    ASSERT_NO_ERROR(err);
  }
  
    // run local smoother
  bcd_q.run_instructions( &mesh, err );
  ASSERT_NO_ERROR(err);
  mesh.write_vtk( (name + "-bcd.vtk").c_str(), err );
  bcd_coords.resize( vertex_list.size() );
  mesh.vertices_get_coordinates( arrptr(vertex_list), arrptr(bcd_coords), vertex_list.size(), err );
  ASSERT_NO_ERROR(err);
  
    // compare results
  for (i = 0; i < bcd_coords.size(); ++i)
    CPPUNIT_ASSERT_VECTORS_EQUAL( global_coords[i], bcd_coords[i], 1e-2 );
}