// 输出网格到 VTK 文件 void MeshOpt::writeToVTK(hier::Patch<NDIM>& patch, const double time, const double dt, const bool initial_time) { NULL_USE(dt); NULL_USE(time); NULL_USE(initial_time); const tbox::Pointer< hier::BlockPatchGeometry<NDIM> > pgeom = patch.getPatchGeometry(); int block_index = pgeom->getBlockNumber(); int patch_index = patch.getPatchNumber(); std::stringstream bi, pi, df; bi << block_index; pi << patch_index; df << d_flag; std::string file_name = df.str() + "_block_ " + bi.str()+ "_patch_" + pi.str() + ".vtk"; MsqError err; MeshImpl * mesh = createLocalMesh(patch); mesh->write_vtk(file_name.c_str(), err); return; }
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); }
void TagVertexMeshTest::test_cleanup() { MsqPrintError err( std::cerr ); Vector3D new_coords(5, 5, 5); MsqVertex get_coords; std::vector<Mesh::VertexHandle> vertices; realMesh->get_all_vertices( vertices, err ); ASSERT_NO_ERROR(err); Mesh::VertexHandle vertex = vertices[0]; realMesh->vertices_get_coordinates( &vertex, &get_coords, 1, err ); ASSERT_NO_ERROR(err); Vector3D orig_coords = get_coords; // modify a vertex in the tag interface { TagVertexMesh tag_mesh( err, realMesh, true ); ASSERT_NO_ERROR(err); tag_mesh.vertex_set_coordinates( vertex, new_coords, err ); ASSERT_NO_ERROR(err); } // check that values were cleaned up when previous instance was destroyed { TagVertexMesh tag_mesh( err, realMesh, false ); ASSERT_NO_ERROR(err); tag_mesh.vertices_get_coordinates( &vertex, &get_coords, 1, err ); ASSERT_NO_ERROR(err); CPPUNIT_ASSERT_VECTORS_EQUAL( orig_coords, get_coords, DBL_EPSILON ); } }
void TagVertexMeshTest::test_alternate_name() { MsqPrintError err( std::cerr ); Vector3D new_coords(5, 5, 5); MsqVertex get_coords; std::vector<Mesh::VertexHandle> vertices; realMesh->get_all_vertices( vertices, err ); ASSERT_NO_ERROR(err); Mesh::VertexHandle vertex = vertices[0]; realMesh->vertices_get_coordinates( &vertex, &get_coords, 1, err ); ASSERT_NO_ERROR(err); Vector3D orig_coords = get_coords; // modify a vertex in the tag interface and save it { TagVertexMesh tag_mesh( err, realMesh, false, "foobar" ); ASSERT_NO_ERROR(err); tag_mesh.vertex_set_coordinates( vertex, new_coords, err ); ASSERT_NO_ERROR(err); } // verify that it is modified in the new interface { TagVertexMesh tag_mesh( err, realMesh, false, "foobar" ); ASSERT_NO_ERROR(err); tag_mesh.vertices_get_coordinates( &vertex, &get_coords, 1, err ); ASSERT_NO_ERROR(err); CPPUNIT_ASSERT_VECTORS_EQUAL( new_coords, get_coords, DBL_EPSILON ); } }
// 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 ); }
int main( int argc, char* argv[] ) { parse_options( argv, argc ); MeshImpl mesh; XYRectangle domain( max_x - min_x, max_y - min_y, min_x, min_y ); MsqError err; create_input_mesh( input_x, mesh, err ); if (MSQ_CHKERR(err)) { std::cerr << err << std::endl; return 2; } domain.setup( &mesh, err ); if (MSQ_CHKERR(err)) { std::cerr << err << std::endl; return 2; } QualityMetric* metric = 0; if (mMetric == 'c') metric = new ConditionNumberQualityMetric; else metric = new IdealWeightInverseMeanRatio; LPtoPTemplate function( 1, metric ); VertexMover* solver = 0; if (mSolver == 'j') solver = new ConjugateGradient( &function ); else solver = new FeasibleNewton( &function ); if (PatchSetUser* psu = dynamic_cast<PatchSetUser*>(solver)) psu->use_global_patch(); TerminationCriterion inner; inner.add_absolute_vertex_movement( 1e-4 ); inner.write_mesh_steps( "synchronous", TerminationCriterion::GNUPLOT ); solver->set_inner_termination_criterion( &inner ); InstructionQueue q; QualityAssessor qa( metric, 10 ); q.add_quality_assessor( &qa, err ); q.set_master_quality_improver( solver, err ); q.add_quality_assessor( &qa, err ); MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &domain); q.run_instructions( &mesh_and_domain, err ); delete solver; delete metric; if (MSQ_CHKERR(err)) { std::cerr << err << std::endl; return 3; } mesh.write_vtk( outputFile, err ); if (MSQ_CHKERR(err)) { std::cerr << err << std::endl; return 2; } return 0; }
void DomainClassifierTest::check_domain( DomainClassifier& domain ) { std::vector<Mesh::VertexHandle> vertices, cverts; std::vector<Mesh::ElementHandle> elements, celems; // Check that, for each entity with a domain, the // DomainClassifier instance returns that domain. // Also, put all entities with domains into cverts and // celems for later. for (unsigned i = 0; i < myDomains.size(); ++i) { for (unsigned j = 0; j < myDomains[i].vertices.size(); ++j) { Mesh::VertexHandle v = myDomains[i].vertices[j]; const MeshDomain* ptr = domain.find_vertex_domain( v ); CPPUNIT_ASSERT( myDomains[i].domain == ptr ); cverts.push_back( v ); } for (unsigned k = 0; k < myDomains[i].elements.size(); ++k) { Mesh::ElementHandle e = myDomains[i].elements[k]; const MeshDomain* ptr = domain.find_element_domain( e ); CPPUNIT_ASSERT( myDomains[i].domain == ptr ); celems.push_back( e ); } } // sort cverts and celems so we can do binary_search later std::sort( cverts.begin(), cverts.end() ); std::sort( celems.begin(), celems.end() ); // get all vertices and elements in mesh MsqPrintError err(std::cerr); myMesh.get_all_vertices( vertices, err ); CPPUNIT_ASSERT(!err); myMesh.get_all_elements( elements, err ); CPPUNIT_ASSERT(!err); // For each vertex not in a domain (not in cverts), make sure // that the domain is NULL. for (size_t i = 0; i < vertices.size(); ++i) { if (std::binary_search( cverts.begin(), cverts.end(), vertices[i] )) continue; const MeshDomain* ptr = domain.find_vertex_domain( vertices[i] ); CPPUNIT_ASSERT( NULL == ptr ); } // For each element not in a domain (not in celems), make sure // that the domain is NULL. for (size_t i = 0; i < elements.size(); ++i) { if (std::binary_search( celems.begin(), celems.end(), elements[i] )) continue; const MeshDomain* ptr = domain.find_element_domain( elements[i] ); CPPUNIT_ASSERT( NULL == ptr ); } }
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); }
int run_example( const Example& e, bool write_output_file ) { MsqPrintError err(std::cerr); MeshImpl mesh; DomainClassifier domain; HexLagrangeShape hex27; std::cout << std::endl << "--------------------------------------------------------------------" << std::endl << e.desc << std::endl << "--------------------------------------------------------------------" << std::endl; std::string name = e.func( domain, mesh, err ); if (MSQ_CHKERR(err)) return 2; std::cout << "Loaded mesh from: " << name << std::endl; UntangleWrapper untangler; untangler.set_slaved_ho_node_mode( Settings::SLAVE_NONE ); untangler.set_mapping_function( &hex27 ); MeshDomainAssoc mesh_and_domain = MeshDomainAssoc(&mesh, &domain, false, true); untangler.run_instructions( &mesh_and_domain, err ); if (MSQ_CHKERR(err)) return 1; ShapeImprover smoother; smoother.set_slaved_ho_node_mode( Settings::SLAVE_NONE ); smoother.set_mapping_function( &hex27 ); smoother.set_vertex_movement_limit_factor( 0.05 ); smoother.run_instructions( &mesh_and_domain, err ); if (MSQ_CHKERR(err)) return 1; if (write_output_file) { size_t idx = name.find( ".vtk" ); if (idx != std::string::npos) { std::string newname( name.substr(0, idx) ); newname += ".out"; newname += name.substr(idx); name.swap(newname); } else { name += ".out"; } mesh.write_vtk( name.c_str(), err ); MSQ_CHKERR(err); std::cout << "Write mesh to file: " << name << std::endl; } return smoother.quality_assessor().invalid_elements(); }
// 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 ); }
// 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 ); }
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); }
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); }
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 ); }
void DomainClassifierTest::tearDown() { myMesh.clear(); while (!myDomains.empty()) { delete myDomains.back().domain; myDomains.pop_back(); } domainDims.clear(); }
// 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] ); } }
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; }
void DomainClassifierTest::test_classify_by_tag() { CPPUNIT_ASSERT( !myDomains.empty() ); MsqPrintError err(std::cerr); int def = myDomains.size(); TagHandle tag = myMesh.tag_create( "domain", Mesh::INT, 1, &def, err ); CPPUNIT_ASSERT(!err); std::vector<MeshDomain*> dom_list; std::vector<int> id_list; for (unsigned i = 0; i < myDomains.size(); ++i) { std::vector<int> vtx_data( myDomains[i].vertices.size(), i ); std::vector<int> elm_data( myDomains[i].elements.size(), i ); if (!vtx_data.empty()) { myMesh.tag_set_vertex_data( tag, vtx_data.size(), &(myDomains[i].vertices[0]), &vtx_data[0], err ); CPPUNIT_ASSERT(!err); } if (!elm_data.empty()) { myMesh.tag_set_element_data( tag, elm_data.size(), &(myDomains[i].elements[0]), &elm_data[0], err ); CPPUNIT_ASSERT(!err); } dom_list.push_back( myDomains[i].domain ); id_list.push_back( i ); } DomainClassifier domain; DomainClassifier::classify_by_tag( domain, &myMesh, "domain", &dom_list[0], &id_list[0], myDomains.size(), err ); CPPUNIT_ASSERT(!err); check_domain( domain ); }
void cond_write_file( MeshImpl& mesh, const char* filename ) { if (filename) { MsqPrintError err(std::cerr); mesh.write_vtk( filename, err ); if (MSQ_CHKERR(err)) { std::cerr << filename << ": failed to write file" << std::endl; exit(1); } std::cout << "Wrote file: " << filename << std::endl; } }
// 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) ); }
// 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 ) ); }
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 ); }
void TagVertexMeshTest::test_vertex_coordinates() { 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); // 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 tag mesh but not // real mesh. Vector3D new_coords(5,5,5); tag_mesh.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( new_coords, tag_coords, DBL_EPSILON ); realMesh->vertices_get_coordinates( &vertex, &get_coords, 1, err ); ASSERT_NO_ERROR(err); real_coords = get_coords; CPPUNIT_ASSERT_VECTORS_EQUAL( orig_coords, real_coords, DBL_EPSILON ); }
// 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 ); }
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); }
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 ); }
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; } }
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; }
// 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; }
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(); }