예제 #1
0
    // Test reading Vtk vector attribute
  void VtkTest::test_read_vector_attrib()
  {
    MeshImpl mesh;
    MsqPrintError err(cout);
    
    FILE* file = fopen( temp_file_name, "w+" );
    fputs( structured_3d_points_data, file );
    fputs( simple_vector_attrib, file );
    fclose( file );
    
    mesh.read_vtk( temp_file_name, err );
    remove( temp_file_name );
    ASSERT_NO_ERROR(err);
    
    std::vector<Mesh::ElementHandle> elems;
    mesh.get_all_elements( elems, err );
    CPPUNIT_ASSERT( !err );
    CPPUNIT_ASSERT_EQUAL( elems.size(), (size_t)8 );
   
    void* th = mesh.tag_get( "hexvect", err );
    CPPUNIT_ASSERT( !err );

    std::string name;
    Mesh::TagType type;
    unsigned tagsize;
    mesh.tag_properties( th, name, type, tagsize, err );
    CPPUNIT_ASSERT( !err && type == Mesh::DOUBLE && tagsize == 3 );
    
    double elem_data[24];
    mesh.tag_get_element_data( th, 8, arrptr(elems), elem_data, err );
    CPPUNIT_ASSERT( !err );
    
    for (int i = 0; i < 8; ++i)
      CPPUNIT_ASSERT( Vector3D( elem_data+3*i ) == Vector3D( i+1, i+1, i+1 ) );
  }
예제 #2
0
  void VtkTest::check_field_attrib( const char* temp_file_name )
  {
    MeshImpl mesh;
    MsqPrintError err(cout);
    
    mesh.read_vtk( temp_file_name, err );
    remove( temp_file_name );
    ASSERT_NO_ERROR(err);
    
    std::vector<Mesh::ElementHandle> elems;
    mesh.get_all_elements( elems, err );
    CPPUNIT_ASSERT( !err );
    CPPUNIT_ASSERT_EQUAL( elems.size(), (size_t)8 );
   
    std::string name;
    Mesh::TagType type;
    unsigned tagsize;


    void* th = mesh.tag_get( "test_field elem_vects", err );
    CPPUNIT_ASSERT( !err );

    mesh.tag_properties( th, name, type, tagsize, err );
    CPPUNIT_ASSERT( !err && type == Mesh::DOUBLE && tagsize == 3 );
    
    double elem_data[24];
    mesh.tag_get_element_data( th, 8, arrptr(elems), elem_data, err );
    CPPUNIT_ASSERT( !err );
    
    for (int i = 0; i < 8; ++i)
      CPPUNIT_ASSERT( Vector3D( elem_data+3*i ) == Vector3D( i+1, i+1, i+1 ) );
   
    
    th = mesh.tag_get( "test_field elem_ids", err );
    CPPUNIT_ASSERT( !err );

    mesh.tag_properties( th, name, type, tagsize, err );
    CPPUNIT_ASSERT( !err && type == Mesh::INT && tagsize == 1 );
    
    int elem_ids[8];
    mesh.tag_get_element_data( th, 8, arrptr(elems), elem_ids, err );
    CPPUNIT_ASSERT( !err );
    
    for (int i = 0; i < 8; ++i)
      CPPUNIT_ASSERT( elem_ids[i] == i+1 );
   
    
    th = mesh.tag_get( "field1", err );
    CPPUNIT_ASSERT( !err );

    mesh.tag_properties( th, name, type, tagsize, err );
    CPPUNIT_ASSERT( !err && type == Mesh::INT && tagsize == 1 );
    
    int values[8];
    mesh.tag_get_element_data( th, 8, arrptr(elems), values, err );
    CPPUNIT_ASSERT( !err );
    
    for (int i = 0; i < 8; ++i)
      CPPUNIT_ASSERT( values[i] == 8-i );
  }
예제 #3
0
void TagVertexMeshTest::setUp()
{
  const char vtk_data[] = 
    "# vtk DataFile Version 2.0\n"
    "test mesh\n"
    "ASCII\n"
    "DATASET UNSTRUCTURED_GRID\n"
    "POINTS 3 float\n"
    "0 0 0\n"
    "1 0 0\n"
    "0 1 0\n"
    "CELLS 1 4\n"
    "3 0 1 2\n"
    "CELL_TYPES 1\n"
    "5\n";
  
  FILE* file = fopen( TEMP_FILE_NAME, "w" );
  CPPUNIT_ASSERT( !!file );
  size_t r = fwrite( vtk_data, sizeof(vtk_data)-1, 1, file );
  fclose( file );
  CPPUNIT_ASSERT( r == 1 );
  
  MsqPrintError err( std::cerr );
  realMesh = new MeshImpl;
  realMesh->read_vtk( TEMP_FILE_NAME, err );
  remove( TEMP_FILE_NAME );
  ASSERT_NO_ERROR(err);
}
예제 #4
0
void SlaveBoundaryVerticesTest::make_mesh( MeshImpl& mesh,
                                           DomainClassifier& domain,
                                           const int intervals )
{
  MsqPrintError err(std::cerr);
  const char input_file[] = MESH_FILES_DIR "3D/VTK/6x6x6-hex20.vtk";
  
  const Vector3D min( -3, -3, -3 );
  const Vector3D max(  3,  3,  3 );
  const Vector3D space = (max - min) * 1.0/(intervals);
  
  mesh.clear();
  mesh.read_vtk( input_file, err );
  ASSERT_NO_ERROR(err);
  
  const Vector3D corners[8] = { Vector3D(min[0],min[1],min[2]),
                                Vector3D(max[0],min[1],min[2]),
                                Vector3D(max[0],max[1],min[2]),
                                Vector3D(min[0],max[1],min[2]),
                                Vector3D(min[0],min[1],max[2]),
                                Vector3D(max[0],min[1],max[2]),
                                Vector3D(max[0],max[1],max[2]),
                                Vector3D(min[0],max[1],max[2]) };
  
  MeshDomain* subdomains[26] = { 
                    new PlanarDomain( PlanarDomain::XZ, min[1] ),
                    new PlanarDomain( PlanarDomain::YZ, max[0] ),
                    new PlanarDomain( PlanarDomain::XZ, max[1] ),
                    new PlanarDomain( PlanarDomain::YZ, min[0] ),
                    new PlanarDomain( PlanarDomain::XY, min[2] ),
                    new PlanarDomain( PlanarDomain::XY, max[2] ),
                    new LineDomain( corners[0], corners[1] - corners[0] ),
                    new LineDomain( corners[1], corners[2] - corners[1] ),
                    new LineDomain( corners[2], corners[3] - corners[2] ),
                    new LineDomain( corners[3], corners[0] - corners[3] ),
                    new LineDomain( corners[0], corners[4] - corners[0] ),
                    new LineDomain( corners[1], corners[5] - corners[1] ),
                    new LineDomain( corners[2], corners[6] - corners[0] ),
                    new LineDomain( corners[3], corners[7] - corners[1] ),
                    new LineDomain( corners[4], corners[5] - corners[4] ),
                    new LineDomain( corners[5], corners[6] - corners[5] ),
                    new LineDomain( corners[6], corners[7] - corners[6] ),
                    new LineDomain( corners[7], corners[4] - corners[7] ),
                    new PointDomain( corners[0] ),
                    new PointDomain( corners[1] ),
                    new PointDomain( corners[2] ),
                    new PointDomain( corners[3] ),
                    new PointDomain( corners[4] ),
                    new PointDomain( corners[5] ),
                    new PointDomain( corners[6] ),
                    new PointDomain( corners[7] ) };
  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 };
  DomainClassifier::classify_skin_geometrically( domain, &mesh, 1e-6,
                                                 subdomains, subdims, 26,
                                                 err );
  domain.delete_sub_domains(true);
  ASSERT_NO_ERROR(err);
}
예제 #5
0
    // Test reading Vtk simple (one-component) scalar attribute
  void VtkTest::test_read_simple_scalar_attrib()
  {
    MeshImpl mesh;
    MsqPrintError err(cout);
   
    FILE* file = fopen( temp_file_name, "w+" );
    fputs( structured_3d_points_data, file );
    fputs( simple_scalar_attrib, file );
    fclose( file );
    
    mesh.read_vtk( temp_file_name, err );
    remove( temp_file_name );
    ASSERT_NO_ERROR(err);
    
    std::vector<Mesh::ElementHandle> elems;
    mesh.get_all_elements( elems, err );
    CPPUNIT_ASSERT( !err );
    CPPUNIT_ASSERT_EQUAL( elems.size(), (size_t)8 );
   
    void* th = mesh.tag_get( "global_id", err );
    CPPUNIT_ASSERT( !err );

    std::string name;
    Mesh::TagType type;
    unsigned tagsize;
    mesh.tag_properties( th, name, type, tagsize, err );
    CPPUNIT_ASSERT( !err && type == Mesh::INT && tagsize == 1 );
    
    int elem_data[8];
    mesh.tag_get_element_data( th, 8, arrptr(elems), elem_data, err );
    CPPUNIT_ASSERT( !err );
    
    for (int i = 0; i < 8; ++i)
      CPPUNIT_ASSERT( elem_data[i] == (1+i) );
  }
예제 #6
0
   // Test writing VTK unstructured mesh
 void VtkTest::test_write()
 {
   MeshImpl mesh;
   MsqPrintError err(cout);
   
     // Create file containing unstructured mesh test case
   FILE* file = fopen( temp_file_name, "w+" );
   CPPUNIT_ASSERT(file);
   int rval = fputs( mixed_unstructured_data, file );
   fclose( file );
   if (rval == EOF) remove(temp_file_name);
   CPPUNIT_ASSERT(rval != EOF);
   
     // Read unstructured mesh file
   mesh.read_vtk( temp_file_name, err );
   remove(temp_file_name);
   ASSERT_NO_ERROR(err);
   
     // Write unstructured mesh file back out
   mesh.write_vtk( temp_file_name, err );
   if (err)  remove( temp_file_name );
   ASSERT_NO_ERROR(err);
   
     // Check if file contained expected mesh
   test_read_unstructured( temp_file_name );
   remove( temp_file_name );
 }
예제 #7
0
void get_planar_example( const char* filename,
                         DomainClassifier& geom,
                         MeshImpl& mesh,
                         MsqError& err )
{
  static PlanarDomain z(PlanarDomain::XY);
  mesh.read_vtk(filename, err); MSQ_ERRRTN(err);
  mesh.mark_skin_fixed(err); MSQ_ERRRTN(err);
  DomainClassifier::DomainSet set(&z);
  mesh.get_all_vertices( set.vertices, err ); MSQ_ERRRTN(err);
  mesh.get_all_elements( set.elements, err ); MSQ_ERRRTN(err);
  DomainClassifier::classify_by_handle( geom, &mesh, &set, 1, err ); MSQ_ERRRTN(err);
}
예제 #8
0
   // Test reading 3D Vtk rectilinear-grid mesh
 void VtkTest::test_read_rectilinear_grid()
 {
   MeshImpl mesh;
   MsqPrintError err(cout);
   
   FILE* file = fopen( temp_file_name, "w+" );
   fputs( rectilinear_grid_data, file );
   fclose( file );
   
   mesh.read_vtk( temp_file_name, err );
   remove( temp_file_name );
   ASSERT_NO_ERROR(err);
   
   check_8hex_structured( mesh );
 }
예제 #9
0
   // Test reading 2D Vtk structured-points mesh
 void VtkTest::test_read_structured_2d_points()
 {
   MeshImpl mesh;
   MsqPrintError err(cout);
  
   FILE* file = fopen( temp_file_name, "w+" );
   fputs( structured_2d_points_data, file );
   fclose( file );
   
   mesh.read_vtk( temp_file_name, err );
   remove( temp_file_name );
   ASSERT_NO_ERROR(err);
   
   check_4quad_structured( mesh );
 }
예제 #10
0
  void VtkTest::test_elements()
  {
    Mesquite::MsqPrintError err(cout);
    MeshImpl mMesh;
    mMesh.read_vtk(MESH_FILES_DIR "2D/vtk/tris/untangled/equil_tri2.vtk", err);
    ASSERT_NO_ERROR(err);
    Mesquite::MeshDomainAssoc mesh_and_domain = Mesquite::MeshDomainAssoc(&mMesh, 0);
    Mesquite::Instruction::initialize_vertex_byte( &mesh_and_domain, 0, err );
    ASSERT_NO_ERROR(err);
    
      // Retrieve a patch
    Mesquite::PatchData pd;
    pd.set_mesh( &mMesh );
    VertexPatches patch_set;
    patch_set.set_mesh( &mMesh );
    PatchIterator patches( &patch_set );
    patches.get_next_patch( pd, err );
    ASSERT_NO_ERROR(err);
    
    int free_vtx = pd.num_free_vertices(); 
//    std::cout << "nb of free vertices: " << free_vtx << std::endl;
    CPPUNIT_ASSERT( free_vtx == 1 );
    
    Mesquite::MsqMeshEntity* element_array =  pd.get_element_array(err); ASSERT_NO_ERROR(err);
    size_t num_elements = pd.num_elements();
    CPPUNIT_ASSERT( num_elements == 6 );
    
    const Mesquite::MsqVertex* vtx_array = pd.get_vertex_array(err); ASSERT_NO_ERROR(err);
    size_t num_vertices = pd.num_nodes();
    CPPUNIT_ASSERT( num_vertices == 7 );
    
    CPPUNIT_ASSERT( tri_check_validity(element_array, num_elements, vtx_array, num_vertices) == 1 );
    
    patches.get_next_patch( pd, err ); ASSERT_NO_ERROR(err);
    
    element_array =  pd.get_element_array(err); ASSERT_NO_ERROR(err);
    num_elements = pd.num_elements();
    CPPUNIT_ASSERT( num_elements == 6 );
    
    vtx_array = pd.get_vertex_array(err); ASSERT_NO_ERROR(err);
    num_vertices = pd.num_nodes();
    CPPUNIT_ASSERT( num_vertices == 7 );
    
    CPPUNIT_ASSERT( tri_check_validity(element_array, num_elements, vtx_array, num_vertices) == 1 );
  }
예제 #11
0
    // Test reading MeshImpl boundary-vertex bit
    // from Vtk scalar attribute.
  void VtkTest::test_read_fixed_attrib()
  {
    MeshImpl mesh;
    MsqPrintError err(cout);
    
    FILE* file = fopen( temp_file_name, "w+" );
    fputs( structured_3d_points_data, file );
    fputs( fixed_vertex_attrib, file );
    fclose( file );
    
    mesh.read_vtk( temp_file_name, err );
    remove( temp_file_name );
    ASSERT_NO_ERROR(err);

    std::vector<Mesh::ElementHandle> elems;
    mesh.get_all_elements( elems, err );
    CPPUNIT_ASSERT( !err );
    CPPUNIT_ASSERT_EQUAL( elems.size(), (size_t)8 );
    
    std::vector<Mesh::VertexHandle> verts;
    std::vector<size_t> offsets;
    mesh.elements_get_attached_vertices( arrptr(elems), elems.size(), verts, offsets, err );
    ASSERT_NO_ERROR(err);
    
    // get unique list of vertices
    std::vector<Mesh::VertexHandle>::iterator new_end;
    std::sort( verts.begin(), verts.end() );
    new_end = std::unique( verts.begin(), verts.end() );
    verts.resize( new_end - verts.begin() );
    CPPUNIT_ASSERT_EQUAL( verts.size(), (size_t)27 );

    // get fixed flag
    std::vector<bool> fixed;
    mesh.vertices_get_fixed_flag( arrptr(verts), fixed, verts.size(), err );
    ASSERT_NO_ERROR(err);
    CPPUNIT_ASSERT_EQUAL( verts.size(), fixed.size() );
    
    for (int i = 0; i < 27; ++i)
    {
      bool should_be_fixed = (i != 13);
      CPPUNIT_ASSERT_EQUAL( should_be_fixed, (bool)fixed[i] );
    }
  }
예제 #12
0
std::string get_sphere_cylinder_example( DomainClassifier& geom, MeshImpl& mesh, MsqError& err )
{
  const char filename[] = SRCDIR "sphereCylinder_1194_inv.vtk";

  const Vector3D vec_k(0,0,8), vec_nk(0,0,-8);
  const Vector3D vec_c(0,0,5);

  //++ 0D domains ++

  //++ 1D domains ++

  //top circle
  static CircleDomain cr_to(vec_k,vec_k,8.0), cr_ti(vec_k,vec_k,4.0);
  //bottom circle
  static CircleDomain cr_bo(vec_nk,vec_nk,8.0);

  //++ 2D domains ++

  static PlanarDomain sf_t(vec_k,vec_k), sf_b(vec_nk,vec_nk);
  static CylinderDomain cy(8.0,vec_k,vec_k);
  static SphericalDomain sp(vec_c,5.0);

  MeshDomain* base_domains[] = {
    &cr_to, &cr_ti, &cr_bo,
    &sf_t, &sf_b, &cy, &sp
  };
  const int NDOM = sizeof(base_domains)/sizeof(base_domains[0]);

  int dim_array[NDOM] = {
    1, 1, 1, 
    2, 2, 2, 2
  };

  //++ MESH & DOMAIN ++

  mesh.read_vtk(filename, err); MSQ_ERRZERO(err);
  DomainClassifier::classify_skin_geometrically (geom, &mesh, 0.001, base_domains, dim_array, NDOM, err);
  MSQ_ERRZERO(err);
  mesh.set_skin_flags( false, false, true, err ); MSQ_ERRZERO(err);
  
  return filename;
}
예제 #13
0
파일: main.cpp 프로젝트: 00liujj/trilinos
void create_input_mesh( const MeshParams& p, 
                        bool all_fixed,
                        MeshImpl& mesh, MsqError& err )
{
  const double z = 0;
  const int F = all_fixed;
  std::ofstream vtkfile( temp_file );
  double bx = all_fixed ? 0.5 * p.w : p.x;
  double by = all_fixed ? 0.5 * p.h : p.y;
  vtkfile << "# vtk DataFile Version 3.0" << std::endl
          << "Mesquite High Aspect Ratio test" << std::endl
          << "ASCII" << std::endl
          << "DATASET UNSTRUCTURED_GRID" << std::endl
          << "POINTS 9 float" << std::endl
          << 0.0 << ' ' << 0.0 << ' ' << z << std::endl
          << bx  << ' ' << 0.0 << ' ' << z << std::endl
          << p.w << ' ' << 0.0 << ' ' << z << std::endl
          << 0.0 << ' ' << by  << ' ' << z << std::endl
          << p.x << ' ' << p.y << ' ' << z << std::endl
          << p.w << ' ' << by  << ' ' << z << std::endl
          << 0.0 << ' ' << p.h << ' ' << z << std::endl
          << bx  << ' ' << p.h << ' ' << z << std::endl
          << p.w << ' ' << p.h << ' ' << z << std::endl
          << "CELLS 4 20" << std::endl
          << "4 0 1 4 3" << std::endl
          << "4 1 2 5 4" << std::endl
          << "4 4 5 8 7" << std::endl
          << "4 3 4 7 6" << std::endl
          << "CELL_TYPES 4" << std::endl
          << "9 9 9 9" << std::endl
          << "POINT_DATA 9" << std::endl
          << "SCALARS fixed int" << std::endl
          << "LOOKUP_TABLE default" << std::endl
          << "1 " << F << " 1" << std::endl
          <<  F << " 0 " << F  << std::endl
          << "1 " << F << " 1" << std::endl
          ;
  vtkfile.close();
  mesh.read_vtk( temp_file, err );
  std::remove( temp_file );
  MSQ_CHKERR(err);
}
예제 #14
0
  void VtkTest::test_read_unstructured( const char* filename )
  {
    MeshImpl mesh;
    MsqPrintError err(cout);
    
    mesh.read_vtk( filename, err );
    ASSERT_NO_ERROR(err);
    
      // Get mesh data
    std::vector<Mesh::VertexHandle> conn;
    std::vector<Mesh::ElementHandle> elems(38);
    std::vector<size_t> offsets(39);
    mesh.get_all_elements( elems, err );
    ASSERT_NO_ERROR(err);
    CPPUNIT_ASSERT_EQUAL( elems.size(), (size_t)38 );
    mesh.elements_get_attached_vertices( arrptr(elems), elems.size(),
                                         conn, offsets, err );
    ASSERT_NO_ERROR(err);

    unsigned i;
    struct meshdata { EntityTopology type; size_t nodes; size_t count; };
    meshdata list[] = {
      { Mesquite::HEXAHEDRON,    8,  8 },
      { Mesquite::QUADRILATERAL, 4,  4 },
      { Mesquite::PYRAMID,       5,  4 },
      { Mesquite::TETRAHEDRON,   4,  6 },
      { Mesquite::TRIANGLE,      3, 14 },
      { Mesquite::PRISM,         6,  2 }, 
      { Mesquite::MIXED,         0,  0 } };
      
      // Count expected lenght of connectivity list
    size_t conn_len = 0;
    for (i = 0; list[i].nodes; ++i)
      conn_len += list[i].nodes * list[i].count;
    CPPUNIT_ASSERT_EQUAL( conn_len, conn.size() );
    
    check_8hex_block( mesh, conn.begin() );
    check_4quad_block( mesh, conn.begin() + 64 );
  }
예제 #15
0
void create_input_mesh( double mid_x , MeshImpl& mesh, MsqError& err )
{
  std::ofstream vtkfile( temp_file );
  vtkfile << "# vtk DataFile Version 3.0" << std::endl
          << "Mesquite Syncronous Boundary test" << std::endl
          << "ASCII" << std::endl
          << "DATASET UNSTRUCTURED_GRID" << std::endl
          << "POINTS 9 float" << std::endl
          << min_x << ' ' << max_y << ' ' << z << std::endl
          << mid_x << ' ' << max_y << ' ' << z << std::endl
          << max_x << ' ' << max_y << ' ' << z << std::endl
          << min_x << ' ' << mid_y << ' ' << z << std::endl
          << mid_x << ' ' << mid_y << ' ' << z << std::endl
          << max_x << ' ' << mid_y << ' ' << z << std::endl
          << min_x << ' ' << min_y << ' ' << z << std::endl
          << mid_x << ' ' << min_y << ' ' << z << std::endl
          << max_x << ' ' << min_y << ' ' << z << std::endl
          << "CELLS 4 20" << std::endl
          << "4 1 0 3 4" << std::endl
          << "4 2 1 4 5" << std::endl
          << "4 4 3 6 7" << std::endl
          << "4 5 4 7 8" << std::endl
          << "CELL_TYPES 4" << std::endl
          << "9 9 9 9" << std::endl
          << "POINT_DATA 9" << std::endl
          << "SCALARS fixed int" << std::endl
          << "LOOKUP_TABLE default" << std::endl
          << "1 0 1" << std::endl
          << "1 0 1" << std::endl
          << "1 0 1" << std::endl
          ;
  vtkfile.close();
           
  mesh.read_vtk( temp_file, err );
  remove( temp_file );
}
예제 #16
0
   // Test writing quadtratic elements
 void VtkTest::test_write_field_attrib()
 {
   MeshImpl mesh;
   MsqPrintError err(cout);
   
     // Create file containing unstructured mesh test case
   FILE* file = fopen( temp_file_name, "w+" );
   fputs( structured_3d_points_data, file );
   fputs( simple_field_attrib, file );
   fclose( file );
   
     // Read unstructured mesh file
   mesh.read_vtk( temp_file_name, err );
   remove(temp_file_name);
   ASSERT_NO_ERROR(err);
   
     // Write unstructured mesh file back out
   mesh.write_vtk( temp_file_name, err );
   if (err)  remove( temp_file_name );
   ASSERT_NO_ERROR(err);
   
     // Check if file contained expected mesh
   check_field_attrib( temp_file_name );
 }
예제 #17
0
int uwt( bool skip,
         UntangleWrapper::UntangleMetric metric,
         const char* input_file_base,
         int expected,
         bool flip_domain )
{
  if (skip)
    return 0;

  if (!brief_output)
    std::cout << std::endl << "**********************************************" << std::endl;
  std::cout << "Running \"" << input_file_base << "\" for " << tostr(metric) << std::endl;
  if (!brief_output)
    std::cout << "**********************************************" << std::endl << std::endl;

    // get mesh
  MsqError err;
  MeshImpl mesh;
  std::string input_file( VTK_2D_DIR );
  input_file += input_file_base;
  mesh.read_vtk( input_file.c_str(), err );
  if (err) {
    std::cerr << err << std::endl;
    std::cerr << "ERROR: " << input_file << " : failed to read file" << std::endl;
    return 1;
  }
    // get domain
  std::vector<Mesh::VertexHandle> verts;
  mesh.get_all_vertices( verts, err );
  if (err || verts.empty()) abort();
  MsqVertex coords;
  mesh.vertices_get_coordinates( arrptr(verts), &coords, 1, err );
  if (err) abort();
  Vector3D norm(0,0,flip_domain ? -1 : 1);
  PlanarDomain domain( norm, coords );
    // run wrapper
  UntangleWrapper wrapper( metric );
  wrapper.set_vertex_movement_limit_factor( 0.005 );
  double constant = (metric == UntangleWrapper::BETA) ? beta : mu_sigma;
  if (constant > 0)
    wrapper.set_metric_constant( constant );
  if (brief_output)
    wrapper.quality_assessor().disable_printing_results();
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &domain);
  wrapper.run_instructions( &mesh_and_domain, err );
  if (err) {
    std::cerr << err << std::endl;
    std::cerr << "ERROR: optimization failed" << std::endl;
    return 1;
  }
    // write output file
  if (write_output) {
    std::string result_file(tostr(metric));
    result_file += "-";
    result_file += input_file_base;
    mesh.write_vtk( result_file.c_str(), err );
    if (err) {
      std::cerr << err << std::endl;
      std::cerr << "ERROR: " << result_file << " : failed to write file" << std::endl;
      err.clear();
    }
    else {
      std::cerr << "Wrote file: " << result_file << std::endl;
    }
  }
  
    // test number of inverted elements
  int count, junk;
  wrapper.quality_assessor().get_inverted_element_count( count, junk, err );
  if (err) abort();
  if (count < expected) {
    std::cout << "WARNING: expected " << expected 
              << " inverted elements but finished with only " 
              << count << std::endl
              << "Test needs to be updated?" << std::endl << std::endl;
    return 0;
  }
  else if (count == expected) {
    std::cout << "Completed with " << count << " inverted elements remaining" 
              << std::endl << std::endl;
    return 0;
  }
  else {
    std::cerr << "ERROR: expected " << expected 
              << " inverted elements but finished with " 
              << count << std::endl << std::endl;
    return 1;
  }
}
예제 #18
0
static int test(std::string filename_prefix, std::string mesh_topology_name, MeshDomain *domain=0)
{
  int rank, nprocs;
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

  if (nprocs > 2) { cerr << "parallel_untangle_shape::test(" << mesh_topology_name << " can only be run with 1 or 2 processors" << std::endl; return 0; }

  /* create processor-specific file names */
  ostringstream in_name, out_name, gold_name;
  in_name << filename_prefix << "par_untangle_original_" << mesh_topology_name << "_mesh." << nprocs << "." << rank << ".vtk";
  gold_name << filename_prefix << "par_untangle_smoothed_" << mesh_topology_name << "_mesh." << nprocs << "." << rank << ".vtk";
  out_name << "par_untangle_smoothed_" << mesh_topology_name << "_mesh." << nprocs << "." << rank << ".vtk";

  cout << "in_name= " << in_name.str() << " gold_name= " << gold_name.str() << " out_name= " << out_name.str() << std::endl;

  /* load different mesh files on each processor */
  MsqError err;
  MeshImpl mesh;
  mesh.read_vtk(in_name.str().c_str(), err);
  if (err) {cerr << err << endl; return 1;}

  /* create parallel mesh instance, specifying tags 
   * containing parallel data */
  ParallelMeshImpl parallel_mesh(&mesh, "GLOBAL_ID", "PROCESSOR_ID");
  ParallelHelperImpl helper;
  helper.set_communicator(MPI_COMM_WORLD);
  helper.set_parallel_mesh(&parallel_mesh);
  parallel_mesh.set_parallel_helper(&helper);

  /* do Laplacian smooth */
  //LaplaceWrapper optimizer;
  //optimizer.run_instructions(&parallel_mesh, err);

  int  msq_debug             = 0; // 1,2,3 for more debug info
  bool always_smooth         = true;
  int innerIter = 100;
  double gradNorm = 1.e-9;

  ParShapeImprover si(innerIter, gradNorm);
  //Mesh *pmesh = &parallel_mesh;
  si.run(parallel_mesh, domain, err, always_smooth, msq_debug);
  if (err) {cerr << err << endl; return 1; }

  /* write mesh */
  mesh.write_vtk(out_name.str().c_str(),err);
  if (err) {cerr << err << endl; return 1;}

  //std::cout << "P[ " << rank <<"] reading gold..." << std::endl;

  /* compare mesh with gold copy */
  MeshImpl gold;
  gold.read_vtk(gold_name.str().c_str(),err);
  if (err) {cerr << err << endl; return 1;}

  //std::cout << "P[ " << rank <<"] read gold, checking mesh diff..." << std::endl;
  bool do_print=true;
  double tol = 1.e-4;
  bool diff = MeshUtil::meshes_are_different(mesh, gold, err, tol, do_print);
  if (err) {cerr << err << endl; return 1;}
  //std::cout << "P[ " << rank <<"] read gold, checking mesh diff...done" << std::endl;

  if (diff) {cerr << "Error, computed mesh different from gold copy" << std::endl; return 1;}
  
  print_timing_diagnostics(cout);

  return 0;
}
예제 #19
0
std::string get_hex_3d_part_example( DomainClassifier& geom, MeshImpl& mesh, MsqError& err )
{
  const char filename[] = SRCDIR "hex3Dpart.vtk";

  //2D domains

  const Vector3D vec_i(1,0,0), vec_j(0,1,0), vec_k(0,0,1);
  const Vector3D vec_ni(-1,0,0), vec_nj(0,-1,0), vec_nk(0,0,-1);

  const Vector3D vec_left(-11.5,0,0), vec_right(11.5,0,0);
  const Vector3D vec_top(0,5,0), vec_bottom(0,-5,0);
  const Vector3D vec_front(0,0,5), vec_back(0,0,-5);

  //1D domains

  const Vector3D pt_top_front(0,5,5),pt_top_back(0,5,-5);
  const Vector3D pt_bottom_front(0,-5,5),pt_bottom_back(0,-5,-5);

  const Vector3D pt_top_left(-11.5,5,0),pt_top_right(11.5,5,0);
  const Vector3D pt_bottom_left(-11.5,-5,0),pt_bottom_right(11.5,-5,0);

  const Vector3D pt_left_front(-11.5,0,5),pt_left_back(-11.5,0,-5);
  const Vector3D pt_right_front(11.5,0,5),pt_right_back(11.5,0,-5);


  const Vector3D cpt_top_left(-1.5,5,0),cpt_top_right(1.5,5,0);
  const Vector3D cpt_bottom_left(-1.5,-5,0),cpt_bottom_right(1.5,-5,0);

  //0D domains

  const Vector3D pt_tlf(-11.5,5,5), pt_tlb(-11.5,5,-5);
  const Vector3D pt_trf(11.5,5,5), pt_trb(11.5,5,-5);
  const Vector3D pt_blf(-11.5,-5,5), pt_blb(-11.5,-5,-5);
  const Vector3D pt_brf(11.5,-5,5), pt_brb(11.5,-5,-5);

  const Vector3D pt_c_tlf(-1.5,5,5), pt_c_tlb(-1.5,5,-5);
  const Vector3D pt_c_trf(1.5,5,5), pt_c_trb(1.5,5,-5);
  const Vector3D pt_c_blf(-1.5,-5,5), pt_c_blb(-1.5,-5,-5);
  const Vector3D pt_c_brf(1.5,-5,5), pt_c_brb(1.5,-5,-5);

  static PointDomain p00(pt_tlf);
  static PointDomain p01(pt_tlb);
  static PointDomain p02(pt_trf);
  static PointDomain p03(pt_trb);
  static PointDomain p04(pt_blf);
  static PointDomain p05(pt_blb);
  static PointDomain p06(pt_brf);
  static PointDomain p07(pt_brb);

  static PointDomain p08(pt_c_tlf);
  static PointDomain p09(pt_c_tlb);
  static PointDomain p10(pt_c_trf);
  static PointDomain p11(pt_c_trb);
  static PointDomain p12(pt_c_blf);
  static PointDomain p13(pt_c_blb);
  static PointDomain p14(pt_c_brf);
  static PointDomain p15(pt_c_brb);

  static CircleDomain c00(pt_top_front,vec_k,1.5);
  static CircleDomain c01(pt_top_back,vec_k,1.5);
  static CircleDomain c02(pt_bottom_front,vec_k,1.5);
  static CircleDomain c03(pt_bottom_back,vec_k,1.5);

  static LineDomain l00(cpt_top_left,vec_k);
  static LineDomain l01(cpt_top_right,vec_k);
  static LineDomain l02(cpt_bottom_left,vec_k);
  static LineDomain l03(cpt_bottom_right,vec_k);

  static LineDomain l04(pt_top_front,vec_i);
  static LineDomain l05(pt_top_back,vec_i);
  static LineDomain l06(pt_bottom_front,vec_i);
  static LineDomain l07(pt_bottom_back,vec_i);
  static LineDomain l08(pt_top_left,vec_k);
  static LineDomain l09(pt_top_right,vec_k);
  static LineDomain l10(pt_bottom_left,vec_k);
  static LineDomain l11(pt_bottom_right,vec_k);
  static LineDomain l12(pt_left_front,vec_j);
  static LineDomain l13(pt_left_back,vec_j);
  static LineDomain l14(pt_right_front,vec_j);
  static LineDomain l15(pt_right_back,vec_j);

  static CylinderDomain C00(1.5,vec_k,vec_top,false);
  static CylinderDomain C01(1.5,vec_k,vec_bottom,false);
  static PlanarDomain P00(vec_ni,vec_left);
  static PlanarDomain P01(vec_i,vec_right);
  static PlanarDomain P02(vec_j,vec_top);
  static PlanarDomain P03(vec_nj,vec_bottom);
  static PlanarDomain P04(vec_k,vec_front);
  static PlanarDomain P05(vec_nk,vec_back);

  const int NDOM = 44;
  MeshDomain* base_domains[NDOM] = {
    &p00,
    &p01,
    &p02,
    &p03,
    &p04,
    &p05,
    &p06,
    &p07,

    &p08,
    &p09,
    &p10,
    &p11,
    &p12,
    &p13,
    &p14,
    &p15,

    &c00,
    &c01,
    &c02,
    &c03,

    &l00,
    &l01,
    &l02,
    &l03,

    &l04,
    &l05,
    &l06,
    &l07,
    &l08,
    &l09,
    &l10,
    &l11,
    &l12,
    &l13,
    &l14,
    &l15,

    &C00,
    &C01,
    &P00,
    &P01,
    &P02,
    &P03,
    &P04,
    &P05
  };

  int dim_array[NDOM] = { 
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    1, 1, 1, 1, 
    1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    2, 2, 2, 2, 2, 2, 2, 2
  };


  //++ MESH & DOMAIN ++

  mesh.read_vtk(filename, err); MSQ_ERRZERO(err);
  DomainClassifier::classify_skin_geometrically (geom, &mesh, 0.1, base_domains, dim_array, NDOM, err);
  MSQ_ERRZERO(err);
  mesh.set_skin_flags( false, false, true, err ); MSQ_ERRZERO(err);
  
  return filename;
}
예제 #20
0
std::string get_cut_cube_example( DomainClassifier& geom, MeshImpl& mesh, MsqError& err )
{
  const char filename[] = SRCDIR "cutCube.vtk";

  const Vector3D vec_i(5,0,0), vec_ni(-5,0,0);
  const Vector3D vec_j(0,5,0), vec_nj(0,-5,0);
  const Vector3D vec_k(0,0,5), vec_nk(0,0,-5);

  const Vector3D vec_tfl(5,-5,5), vec_tfr(5,5,5);
  const Vector3D vec_tbl(-5,-5,5), vec_tbr(-5,5,5);
  const Vector3D vec_bfl(5,-5,-5), vec_bfr(5,5,-5);
  const Vector3D vec_bbl(-5,-5,-5), vec_bbr(-5,5,-5);

  const Vector3D vec_ts(5,0,2), vec_bs(5,0,-2);


  //++ 0D domains ++

  static PointDomain pt_tfl(vec_tfl), pt_tfr(vec_tfr);
  static PointDomain pt_tbl(vec_tbl), pt_tbr(vec_tbr);
  static PointDomain pt_bfl(vec_bfl), pt_bfr(vec_bfr);
  static PointDomain pt_bbl(vec_bbl), pt_bbr(vec_bbr);


  //++ 1D domains ++

  //top square
  static LineDomain ln_tf(vec_tfl,vec_j), lin_tb(vec_tbr,vec_nj);
  static LineDomain ln_tl(vec_tfl,vec_ni), lin_tr(vec_tbr,vec_i);
  //bottom square
  static LineDomain ln_bf(vec_bfl,vec_j), lin_bb(vec_bbr,vec_nj);
  static LineDomain ln_bl(vec_bfl,vec_ni), lin_br(vec_bbr,vec_i);
  //sides
  static LineDomain ln_lf(vec_bfl,vec_k), lin_rf(vec_bfr,vec_k);
  static LineDomain ln_lb(vec_bbl,vec_k), lin_rb(vec_bbr,vec_k);

  //top sphere
  static CircleDomain cr_tf(vec_ts,vec_i,1.0), cr_tn(vec_ts,vec_k,1.0);
  //bottom sphere
  static CircleDomain cr_bf(vec_bs,vec_i,1.0), cr_bn(vec_bs,vec_k,1.0);


  //++ 2D domains ++

  //cube
  static PlanarDomain sf_i(vec_i,vec_i), sf_ni(vec_ni,vec_ni);
  static PlanarDomain sf_j(vec_j,vec_j), sf_nj(vec_nj,vec_nj);
  static PlanarDomain sf_k(vec_k,vec_k), sf_nk(vec_nk,vec_nk);
  //cut
  static CylinderDomain cy(1.0,vec_k,vec_bs);
  static SphericalDomain sp_t(vec_ts,1.0), sp_b(vec_bs,1.0);


  MeshDomain* base_domains[] = {
    &pt_tfl, &pt_tfr,
    &pt_tbl, &pt_tbr,
    &pt_bfl, &pt_bfr,
    &pt_bbl, &pt_bbr,

    &ln_tf, &lin_tb,
    &ln_tl, &lin_tr,
    &ln_bf, &lin_bb,
    &ln_bl, &lin_br,
    &ln_lf, &lin_rf,
    &ln_lb, &lin_rb,
    &cr_tf, &cr_tn,
    &cr_bf, &cr_bn,

    &sf_i, &sf_ni,
    &sf_j, &sf_nj,
    &sf_k, &sf_nk,
    &cy,
    &sp_t, &sp_b
  };
  const int NDOM = sizeof(base_domains)/sizeof(base_domains[0]);

  int dim_array[NDOM] = {
    0,0,0,0,0,0,0,0,
    1,1,1,1,1,1,1,1,
    1,1,1,1,1,1,1,1,
    2,2,2,2,2,2,2,2,2
  };

  //++ MESH & DOMAIN ++

  mesh.read_vtk(filename, err); MSQ_ERRZERO(err);
  DomainClassifier::classify_skin_geometrically (geom, &mesh, 0.1, base_domains, dim_array, NDOM, err);
  MSQ_ERRZERO(err);
  mesh.set_skin_flags( false, false, true, err ); MSQ_ERRZERO(err);
  
  return filename;
}
예제 #21
0
double run( QualityMetric* metric, 
            Solver solver_type,
            const char* input_file,
            double& seconds_out,
            int& iterations_out )
{
  MsqPrintError err(cerr);
  IdealWeightInverseMeanRatio qa_metric;
  TerminationCriterion inner, outer;
  outer.add_iteration_limit( 1 );
  inner.add_absolute_vertex_movement( 1e-4 );
  inner.add_iteration_limit( 100 );
  PMeanPTemplate of( 1.0, metric );
  QualityAssessor qa( &qa_metric );
  qa.add_quality_assessment( metric );
  InstructionQueue q;
  SteepestDescent steep(&of);
  QuasiNewton quasi(&of);
  ConjugateGradient conj(&of);
  VertexMover* solver = 0;
  switch (solver_type) {
    case STEEP_DESCENT: solver = &steep; break;
    case QUASI_NEWT:solver = &quasi;break;
    case CONJ_GRAD: solver = &conj; break;
  }
  q.set_master_quality_improver( solver, err );
  q.add_quality_assessor( &qa, err );
  solver->set_inner_termination_criterion(&inner);
  solver->set_outer_termination_criterion(&outer);
  
  
  if (plot_file)
    inner.write_iterations( plot_file, err );
  
  MeshImpl mesh;
  mesh.read_vtk( input_file, err );
  if (err) {
    cerr << "Failed to read input file: \"" << input_file << '"' << endl;
    exit(1);
  }
  
  std::vector<Mesh::VertexHandle> handles;
  mesh.get_all_vertices( handles, err );
  if (handles.empty()) {
    cerr << "no veritces in mesh" << endl;
    exit(1);
  }
  std::vector<MsqVertex> coords(handles.size());
  mesh.vertices_get_coordinates( arrptr(handles), arrptr(coords), handles.size(), err );
  Vector3D min(HUGE_VAL), max(-HUGE_VAL);
  for (size_t i = 0; i < coords.size(); ++i) {
    for (int j = 0; j < 3; ++j) {
      if (coords[i][j] < min[j])
        min[j] = coords[i][j];
      if (coords[i][j] > max[j])
        max[j] = coords[i][j];
    }
  }
  
  Vector3D size = max - min;
  PlanarDomain* domain = 0;
  if (size[0] < 1e-4) 
    domain = new PlanarDomain( PlanarDomain::YZ, min[0] );
  else if (size[1] < 1e-4)
    domain = new PlanarDomain( PlanarDomain::XZ, min[1] );
  else if (size[2] < 1e-4)
    domain = new PlanarDomain( PlanarDomain::XY, min[2] );
  
  Timer timer;
  q.run_instructions( &mesh, domain, err );
  seconds_out = timer.since_birth();
  if (err) {
    cerr << "Optimization failed." << endl << err << endl;
    abort();
  }

  if (vtk_file) {
    MeshWriter::write_vtk( &mesh, vtk_file, err );
    if (err) 
      cerr << vtk_file << ": failed to write file." << endl;
  }
  if (gpt_file) {
    MeshWriter::write_gnuplot( &mesh, gpt_file, err );
    if (err) 
      cerr << gpt_file << ": failed to write file." << endl;
  }
  if (eps_file) {
    PlanarDomain xy(PlanarDomain::XY);
    MeshWriter::Projection proj( domain ? domain : &xy );
    MeshWriter::write_eps( &mesh, eps_file, proj, err );
    if (err) 
      cerr << eps_file << ": failed to write file." << endl;
  }
  delete domain;
  
  iterations_out = inner.get_iteration_count();
  
  const QualityAssessor::Assessor* a = qa.get_results( &qa_metric );
  return a->get_average();
}
예제 #22
0
int main( int argc, char* argv[] )
{
  const char* input_file = 0;
  const char* output_file = 0;
  for (int i = 1; i < argc; ++i) {
    if (!strcmp("-h", argv[i]))
      usage(argv[0],true);
    else if (!input_file)
      input_file = argv[i];
    else if (!output_file)
      output_file = argv[i];
    else
      usage(argv[0]);
  }
  if (!input_file)
    input_file = DEFAULT_INPUT;
  
  MsqError err;
  MeshImpl mesh;
  mesh.read_vtk( input_file, err );
  if (err) {
    std::cerr << err << std::endl
              << input_file << ": failed to read file" << std::endl;
    return 3;
  }
  
  PlanarDomain plane(PlanarDomain::XY);
#ifdef TEST_OLD_WRAPPER
  ShapeImprovementWrapper smoother;
#else
  ShapeImprover smoother;
#endif
  IdealWeightInverseMeanRatio extra_metric;
  smoother.quality_assessor().add_quality_assessment(&extra_metric);
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &plane);
  smoother.run_instructions( &mesh_and_domain, err );
  if (err) {
    std::cerr << err << std::endl
              << input_file << ": smoother failed" << std::endl;
    return 2;
  }
  
  if (output_file) {
    mesh.write_vtk( output_file, err );
    if (err) {
      std::cerr << err << std::endl
                << output_file << ": failed to write file" << std::endl;
      return 3;
    }
  }

  if (smoother.quality_assessor().invalid_elements()) {
    std::cerr << "Resulting mesh contains invalid elements: untangler did not succeed" << std::endl;
    return 4;
  }
  
  const QualityAssessor::Assessor* quality = 
    smoother.quality_assessor().get_results(&extra_metric);
  if (!quality) {
    std::cerr << "Failed to get quality stats for IMR metric" << std::endl;
    return 2;
  }
  
  if (fabs(1 - quality->get_average()) > 1e-3) {
    std::cerr << "Average quality is not optimal." << std::endl;
    return 4;
  }
  
  if (quality->get_stddev() > 1e-3) {
    std::cerr << "Not all elements have optimal quality." << std::endl;
    return 4;
  }
  
  return 0;
}
예제 #23
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;
      }
    }
  }
예제 #24
0
int main( int argc, char* argv[] )
{
  MeshTransform xform;
  RotateArg rotate_arg( &xform );
  ScaleArg scale_arg( &xform );
  TranslateArg translate_arg( &xform );
  CLArgs::ToggleArg freeonly, skin;

  CLArgs args( "vtkxform", "Transform a mesh",
               "Apply one or more transformations to vertex coordinates "
               "in a mesh read from a VTK file." );
  
  const char* ROTATE_VALS[] = { "a", "i", "j", "k" };
  args.double_list_flag( ROTATE_FLAG, "Specify a rotation as an angle in degrees counter-clockwise about a vector", &rotate_arg );
  args.limit_list_flag( ROTATE_FLAG, 4, ROTATE_VALS );
  
  const char* SCALE_VALS[] = { "s", "sx", "sy", "sz" };
  args.double_list_flag( SCALE_FLAG, "Specify factor(s) by which to scale mesh about origin", &scale_arg );
  args.limit_list_flag( SCALE_FLAG, 1, SCALE_VALS );
  args.limit_list_flag( SCALE_FLAG, 3, SCALE_VALS + 1 );
  
  const char* TRANSLATE_VALS[] = { "dx", "dy", "dz" };
  args.double_list_flag( TRANSLATE_FLAG, "Specify translation of vertex coordinates.", &translate_arg );
  args.limit_list_flag( TRANSLATE_FLAG, 3, TRANSLATE_VALS );

  args.toggle_flag( 'f', "Do not move fixed vertices.", &freeonly );
  args.toggle_flag( 'k', "Mark boundary vertices as fixed", &skin );

  args.add_required_arg( "input_file" );
  args.add_required_arg( "output_file" );
  
  
  std::vector<std::string> files;
  if (!args.parse_options( argc, argv, files, std::cerr )) {
    args.print_usage( std::cerr );
    exit(1);
  }
  std::string input_file = files[0];
  std::string output_file = files[1];

  MeshImpl mesh;
  MsqError err;
  mesh.read_vtk( input_file.c_str(), err );
  if (err) {
    std::cerr << err << std::endl 
              << "Failed to read file: " << input_file << std::endl;
    return 1;
  }
  
  if (skin.value()) {
    mesh.mark_skin_fixed( err, false );
    if (err) {
      std::cerr << err << std::endl
                << "Failed to skin mesh from file: " << input_file << std::endl;
      return 1;
    }
  }
  
  xform.skip_fixed_vertices( freeonly.value() );
  MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, 0);
  xform.loop_over_mesh( &mesh_and_domain, 0, err );
  if (err) {
    std::cerr << err << std::endl ;
    return 2;
  }
  
  mesh.write_vtk( output_file.c_str(), err );
  if (err) {
    std::cerr << err << std::endl 
                    << "Failed to write file: " << output_file << std::endl;
    return 1;
  }
  
  return 0;
}
예제 #25
0
파일: setup.cpp 프로젝트: 00liujj/trilinos
// 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;
}
예제 #26
0
void DomainClassifierTest::setUp()
{
  myMesh.clear();
  myDomains.clear();
  domainDims.clear();
    // vertex coodinates
  const char vertex_data[] =
  "POINTS 64 float\n"
  "0 0 0  1 0 0  2 0 0  3 0 0\n"
  "0 1 0  1 1 0  2 1 0  3 1 0\n"
  "0 2 0  1 2 0  2 2 0  3 2 0\n"
  "0 3 0  1 3 0  2 3 0  3 3 0\n"
  "\n"
  "0 0 1  1 0 1  2 0 1  3 0 1\n"
  "0 1 1  1 1 1  2 1 1  3 1 1\n"
  "0 2 1  1 2 1  2 2 1  3 2 1\n"
  "0 3 1  1 3 1  2 3 1  3 3 1\n"
  "\n"
  "0 0 2  1 0 2  2 0 2  3 0 2\n"
  "0 1 2  1 1 2  2 1 2  3 1 2\n"
  "0 2 2  1 2 2  2 2 2  3 2 2\n"
  "0 3 2  1 3 2  2 3 2  3 3 2\n"
  "\n"
  "0 0 3  1 0 3  2 0 3  3 0 3\n"
  "0 1 3  1 1 3  2 1 3  3 1 3\n"
  "0 2 3  1 2 3  2 2 3  3 2 3\n"
  "0 3 3  1 3 3  2 3 3  3 3 3\n"
  "\n";
    // quad connectivity for quads on mesh skin
  const int num_quads = 9*6; // nine per side
  const char quad_data[] = 
  "4  1  0  4  5\n" // -z face (z == 0)
  "4  2  1  5  6\n"
  "4  3  2  6  7\n"
  "4  5  4  8  9\n"
  "4  6  5  9 10\n"
  "4  7  6 10 11\n"
  "4  9  8 12 13\n"
  "4 10  9 13 14\n"
  "4 11 10 14 15\n" 
  "\n"
  "4 48 49 53 52\n" // +z face (z == 3)
  "4 49 50 54 53\n"
  "4 50 51 55 54\n"
  "4 52 53 57 56\n"
  "4 53 54 58 57\n"
  "4 54 55 59 58\n"
  "4 56 57 61 60\n"
  "4 57 58 62 61\n"
  "4 58 59 63 62\n" 
  "\n"
  "4  0  1 17 16\n" // -y face (y == 0)
  "4  1  2 18 17\n"
  "4  2  3 19 18\n"
  "4 16 17 33 32\n"
  "4 17 18 34 33\n"
  "4 18 19 35 34\n"
  "4 32 33 49 48\n"
  "4 33 34 50 49\n"
  "4 34 35 51 50\n"
  "\n"
  "4 13 12 28 29\n" // +y face (y == 3)
  "4 14 13 29 30\n"
  "4 15 14 30 31\n"
  "4 29 28 44 45\n"
  "4 30 29 45 46\n"
  "4 31 30 46 47\n"
  "4 45 44 60 61\n"
  "4 46 45 61 62\n"
  "4 47 46 62 63\n"
  "\n"
  "4  4  0 16 20\n" // -x face (x == 0)
  "4  8  4 20 24\n"
  "4 12  8 24 28\n"
  "4 20 16 32 36\n"
  "4 24 20 36 40\n"
  "4 28 24 40 44\n"
  "4 36 32 48 52\n"
  "4 40 36 52 56\n"
  "4 44 40 56 60\n"
  "\n"
  "4  3  7 23 19\n" // +x face (x == 3)
  "4  7 11 27 23\n"
  "4 11 15 31 27\n"
  "4 19 23 39 35\n"
  "4 23 27 43 39\n"
  "4 27 31 47 43\n"
  "4 35 39 55 51\n"
  "4 39 43 59 55\n"
  "4 43 47 63 59\n"
  "\n";
    // hexahedron connectivity
  const int num_hexes = 3*3*3;
  const char hex_data[] =
  "8  0  1  5  4 16 17 21 20\n"
  "8  1  2  6  5 17 18 22 21\n"
  "8  2  3  7  6 18 19 23 22\n"
  "8  4  5  9  8 20 21 25 24\n"
  "8  5  6 10  9 21 22 26 25\n"
  "8  6  7 11 10 22 23 27 26\n"
  "8  8  9 13 12 24 25 29 28\n"
  "8  9 10 14 13 25 26 30 29\n"
  "8 10 11 15 14 26 27 31 30\n"
  "\n"
  "8 16 17 21 20 32 33 37 36\n"
  "8 17 18 22 21 33 34 38 37\n"
  "8 18 19 23 22 34 35 39 38\n"
  "8 20 21 25 24 36 37 41 40\n"
  "8 21 22 26 25 37 38 42 41\n"
  "8 22 23 27 26 38 39 43 42\n"
  "8 24 25 29 28 40 41 45 44\n"
  "8 25 26 30 29 41 42 46 45\n"
  "8 26 27 31 30 42 43 47 46\n"
  "\n"
  "8 32 33 37 36 48 49 53 52\n"
  "8 33 34 38 37 49 50 54 53\n"
  "8 34 35 39 38 50 51 55 54\n"
  "8 36 37 41 40 52 53 57 56\n"
  "8 37 38 42 41 53 54 58 57\n"
  "8 38 39 43 42 54 55 59 58\n"
  "8 40 41 45 44 56 57 61 60\n"
  "8 41 42 46 45 57 58 62 61\n"
  "8 42 43 47 46 58 59 63 62\n"
  "\n";
    // a few interior quads
  const int num_interior_quads = 3;
  const char interior_quad_data[] = 
  "4  1  5 25 17\n"
  "4  4  5 25 24\n"
  "4 16 17 25 24\n"
  "\n";
  
  
  const char filename[] = "dctest.vtk";
  FILE* file = fopen( filename, "w" );
  fputs( "# vtk DataFile Version 2.0\n", file );
  fputs( "Mesquite Mesh\n", file );
  fputs( "ASCII\n", file );
  fputs( "DATASET UNSTRUCTURED_GRID\n", file );
  fputs( vertex_data, file );
  
  int num_elem = num_quads + num_hexes + num_interior_quads;
  int num_elem_data = 5*num_quads + 9*num_hexes * 5*num_interior_quads;
  fprintf( file, "CELLS %d %d\n", num_elem, num_elem_data );
  fputs( quad_data, file );
  fputs( hex_data, file );
  fputs( interior_quad_data, file );
  fprintf( file, "CELL_TYPES %d\n", num_elem );
  for (int i = 0; i < num_quads; ++i)
    fputs( "9\n", file );
  for (int i = 0; i < num_hexes; ++i)
    fputs( "12\n", file );
  for (int i = 0; i < num_interior_quads; ++i)
    fputs( "9\n", file );
  
  fclose( file );
  MsqPrintError err(std::cerr);
  myMesh.read_vtk( filename, err );
  remove( filename );
  CPPUNIT_ASSERT(!err);

  std::vector<Mesh::VertexHandle> verts;
  std::vector<Mesh::ElementHandle> elems;
  myMesh.get_all_vertices(verts, err);
  CPPUNIT_ASSERT(!err);
  CPPUNIT_ASSERT_EQUAL( (size_t)64, verts.size() );
  myMesh.get_all_elements(elems, err);
  CPPUNIT_ASSERT(!err);
  CPPUNIT_ASSERT_EQUAL( (size_t)num_elem, elems.size() );
  
    // define point domains
  PointDomain* pdom[8];
  pdom[0] = new PointDomain( Vector3D(0,0,0) );
  pdom[1] = new PointDomain( Vector3D(3,0,0) );
  pdom[2] = new PointDomain( Vector3D(0,3,0) );
  pdom[3] = new PointDomain( Vector3D(3,3,0) );
  pdom[4] = new PointDomain( Vector3D(0,0,3) );
  pdom[5] = new PointDomain( Vector3D(3,0,3) );
  pdom[6] = new PointDomain( Vector3D(0,3,3) );
  pdom[7] = new PointDomain( Vector3D(3,3,3) );
  size_t pdidx[8] = { 0, 3, 12, 15, 48, 51, 60, 63 };
  for (unsigned i = 0; i < 8; ++i) {
    MsqVertex coords;
    Mesh::VertexHandle h = verts[pdidx[i]];
    myMesh.vertices_get_coordinates( &h, &coords, 1, err );
    CPPUNIT_ASSERT(!err);
    CPPUNIT_ASSERT_VECTORS_EQUAL( pdom[i]->geom(), coords, 1e-6 );
    DomSet set;
    set.domain = pdom[i];
    set.vertices.push_back( h );
    myDomains.push_back( set );
    domainDims.push_back( 0 );
  }
  
    // define line domains
  LineDomain* ldom[12];
  ldom[0] = new LineDomain( Vector3D(0,0,0), Vector3D(1,0,0) ); // y=0,z=0
  ldom[1] = new LineDomain( Vector3D(0,3,0), Vector3D(1,0,0) ); // y=3,z=0
  ldom[2] = new LineDomain( Vector3D(0,0,3), Vector3D(1,0,0) ); // y=0,z=3
  ldom[3] = new LineDomain( Vector3D(0,3,3), Vector3D(1,0,0) ); // y=3,z=3
  ldom[4] = new LineDomain( Vector3D(0,0,0), Vector3D(0,1,0) ); // x=0,z=0
  ldom[5] = new LineDomain( Vector3D(3,0,0), Vector3D(0,1,0) ); // x=3,z=0
  ldom[6] = new LineDomain( Vector3D(0,0,3), Vector3D(0,1,0) ); // x=0,z=3
  ldom[7] = new LineDomain( Vector3D(3,0,3), Vector3D(0,1,0) ); // x=3,z=3
  ldom[8] = new LineDomain( Vector3D(0,0,0), Vector3D(0,0,1) ); // x=0,y=0
  ldom[9] = new LineDomain( Vector3D(3,0,0), Vector3D(0,0,1) ); // x=3,y=0
  ldom[10]= new LineDomain( Vector3D(0,3,0), Vector3D(0,0,1) ); // x=0,y=3
  ldom[11]= new LineDomain( Vector3D(3,3,0), Vector3D(0,0,1) ); // x=3,y=3
  size_t ldidx[12][2] = { {  1,  2 }, { 13, 14 }, { 49, 50 }, { 61, 62 },
                          {  4,  8 }, {  7, 11 }, { 52, 56 }, { 55, 59 },
                          { 16, 32 }, { 19, 35 }, { 28, 44 }, { 31, 47 } };
  for (unsigned i = 0; i < 12; ++i) {
    Mesh::VertexHandle v[2];
    v[0] = verts[ldidx[i][0]];
    v[1] = verts[ldidx[i][1]];
    MsqVertex coords[2];
    myMesh.vertices_get_coordinates( v, coords, 2, err );
    CPPUNIT_ASSERT(!err);
    CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, ldom[i]->geom().distance( coords[0] ), 1e-6 );
    CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, ldom[i]->geom().distance( coords[1] ), 1e-6 );
    DomSet set;
    set.domain = ldom[i];
    set.vertices.push_back(v[0]);
    set.vertices.push_back(v[1]);
    myDomains.push_back( set );
    domainDims.push_back( 1 );
  }
  
    // define planar domains
  PlanarDomain* sdom[6];
  sdom[0] = new PlanarDomain( Vector3D( 0, 0,-1), Vector3D(0,0,0) );
  sdom[1] = new PlanarDomain( Vector3D( 0, 0, 1), Vector3D(0,0,3) );
  sdom[2] = new PlanarDomain( Vector3D( 0,-1, 0), Vector3D(0,0,0) );
  sdom[3] = new PlanarDomain( Vector3D( 0, 1, 0), Vector3D(0,3,0) );
  sdom[4] = new PlanarDomain( Vector3D(-1, 0, 0), Vector3D(0,0,0) );
  sdom[5] = new PlanarDomain( Vector3D( 1, 0, 0), Vector3D(3,0,0) );
  size_t sdidx[6][4] = { {  5,  6,  9, 10 }, { 53, 54, 57, 58 },
                         { 17, 18, 33, 34 }, { 29, 30, 45, 46 },
                         { 20, 24, 36, 40 }, { 23, 27, 39, 43 } };
  for (unsigned i = 0; i < 6; ++i) {
    DomSet set;
    set.domain = sdom[i];
    for (unsigned j = 0; j < 4; ++j)
      set.vertices.push_back( verts[sdidx[i][j]] );
    for (unsigned j = 0; j < 9; ++j)
      set.elements.push_back( elems[9*i+j] );
    myDomains.push_back( set );
    domainDims.push_back( 2 );
  }
  
  
//  for (unsigned i = 0; i < myDomains.size(); ++i) 
//    print_domain( i, myDomains[i] );
}
예제 #27
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();
}
예제 #28
0
int main( int argc, char* argv[] )
{
  /* init MPI */
  int rank, nprocs;
  if (MPI_SUCCESS != MPI_Init(&argc, &argv)) {
    cerr << "MPI_Init failed." << endl;
    return 2;
  }
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

  if (nprocs > 2) { cerr << "parallel_laplace_smooth test can only be run with 1 or 2 processors" << std::endl; return 0; }

  const int debug=0;  // 1,2,3 for more debug info
  if (debug)
    {
      MsqDebug::enable(1);
      if (debug > 1) MsqDebug::enable(2);
      if (debug > 2) MsqDebug::enable(3);
    }

  /* create processor-specific file names */
  ostringstream in_name, out_name, gold_name;
  in_name << VTK_3D_DIR << "par_original_hex_mesh." << nprocs << "." << rank << ".vtk";
  gold_name << VTK_3D_DIR << "par_smoothed_hex_mesh." << nprocs << "." << rank << ".vtk";
  out_name << "par_smoothed_hex_mesh." << nprocs << "." << rank << ".vtk";

  /* load different mesh files on each processor */
  Mesquite::MsqError err;
  Mesquite::MeshImpl mesh;
  mesh.read_vtk(in_name.str().c_str(), err);
  if (err) {cerr << err << endl; return 1;}

  /* create parallel mesh instance, specifying tags 
   * containing parallel data */
  Mesquite::ParallelMeshImpl parallel_mesh(&mesh, "GLOBAL_ID", "PROCESSOR_ID");
  Mesquite::ParallelHelperImpl helper;
  helper.set_communicator(MPI_COMM_WORLD);
  helper.set_parallel_mesh(&parallel_mesh);
  parallel_mesh.set_parallel_helper(&helper);

  /* do Laplacian smooth */
  LaplaceWrapper optimizer;
  optimizer.set_vertex_movement_limit_factor(1.e-10);
  optimizer.set_iteration_limit(2000);
  optimizer.enable_culling(false);
  optimizer.run_instructions(&parallel_mesh, err);
  if (err) {cerr << err << endl; return 1; }

  /* write mesh */
  mesh.write_vtk(out_name.str().c_str(),err);
  if (err) {cerr << err << endl; return 1;}

  /* compare mesh with gold copy */
  MeshImpl gold;
  gold.read_vtk(gold_name.str().c_str(),err);
  if (err) {cerr << err << endl; return 1;}

  bool do_print=true;
  double tol = 1.e-4;
  bool diff = MeshUtil::meshes_are_different(mesh, gold, err, tol, do_print);
  if (err) {cerr << err << endl; return 1;}

  if (diff) {cerr << "Error, computed mesh different from gold copy" << std::endl; return 1;}
  
  print_timing_diagnostics(cout);

  MPI_Finalize();
  return 0;
}
예제 #29
0
static int do_smoother( const char* input_file, 
                        const char* output_file, 
                        const char* ref_mesh_file,
                        double of_power, 
                        unsigned metric_idx,
                        AveragingScheme avg_scheme )
{
  MsqPrintError err(cerr);
  
  TMetric *const target_metric = metrics[metric_idx].u;
  cout << "Input file:  " << input_file << endl;
  cout << "Metric:      ";
  if (avg_scheme != NONE)
    cout << averaging_names[avg_scheme] << " average of ";
  cout << metrics[metric_idx].n << endl;
  cout << "Of Power:    " << of_power << endl;
  
  
  auto_ptr<TargetCalculator> tc;
  auto_ptr<MeshImpl> ref_mesh_impl;
  auto_ptr<ReferenceMesh> ref_mesh;
  if (ref_mesh_file) {
    ref_mesh_impl.reset(new MeshImpl);
    ref_mesh_impl->read_vtk( ref_mesh_file, err );
    if (MSQ_CHKERR(err)) return 2;
    ref_mesh.reset( new ReferenceMesh( ref_mesh_impl.get() ));
    tc.reset( new RefMeshTargetCalculator( ref_mesh.get() ) );
  }
  else {
    tc.reset( new IdealShapeTarget( ) );
  }
    
  TQualityMetric jacobian_metric( tc.get(), target_metric );
  ElementPMeanP elem_avg( of_power, &jacobian_metric );
  VertexPMeanP vtx_avg( of_power, &jacobian_metric );
  QualityMetric* mmetrics[] = { &jacobian_metric, &elem_avg, &vtx_avg, &jacobian_metric };
  QualityMetric* metric = mmetrics[avg_scheme];

  TerminationCriterion outer, inner;
  outer.add_iteration_limit( 1 );
  inner.add_absolute_vertex_movement( 1e-4 );
  inner.add_iteration_limit( 100 );
  
  PMeanPTemplate obj1( of_power, metric );
  PatchPowerMeanP obj2( of_power, metric );
  ObjectiveFunction& objective = *((avg_scheme == PATCH) ? (ObjectiveFunction*)&obj2 : (ObjectiveFunction*)&obj1);
  
  ConjugateGradient solver( &objective, err );
  if (MSQ_CHKERR(err)) return 1;
  solver.set_inner_termination_criterion( &inner );
  solver.set_outer_termination_criterion( &outer );
  solver.use_global_patch();
  
  ConditionNumberQualityMetric qm_metric;
  QualityAssessor before_assessor;
  QualityAssessor after_assessor;
  before_assessor.add_quality_assessment( metric, 10);
  before_assessor.add_quality_assessment( &qm_metric );
  after_assessor.add_quality_assessment( metric, 10 );

  InstructionQueue q;
  q.add_quality_assessor( &before_assessor, err );
  q.set_master_quality_improver( &solver, err );
  q.add_quality_assessor( &after_assessor, err );
  
  MeshImpl mesh;
  mesh.read_vtk( input_file, err );
  if (MSQ_CHKERR(err)) return 2;
  PlanarDomain geom = make_domain( &mesh, err );
  if (MSQ_CHKERR(err)) return 1;
  q.run_instructions( &mesh, &geom, err );
  if (MSQ_CHKERR(err)) return 3;
  mesh.write_vtk( output_file, err );
  if (MSQ_CHKERR(err)) return 2;
  cout << "Wrote: " << output_file << endl;

  before_assessor.scale_histograms(&after_assessor);
  
  return 0;
}
예제 #30
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 );
}