void App::adapt_mesh() { getIndicator(); double convergence_order = 2.0; double adapt_tolerence = 1.0e-03; memoryReclaim(); ir_mesh_t * old_ir_mesh = ir_mesh; fe_space_t * old_fem_space = fem_space; fe_func_t * old_phi_h = phi_h; fe_func_t * old_alpha_h = alpha_h; fe_func_t * old_c_h = c_h; fe_func_t * old_u_h = u_h; fe_func_t * old_v_h = v_h; fe_func_t * old_p_h = p_h; fe_func_t * old_last_p_h = last_p_h; ir_mesh = new ir_mesh_t(*old_ir_mesh); //MeshAdaptor<DIM> mesh_adaptor(*old_ir_mesh,*ir_mesh); MeshAdaptor<DIM> mesh_adaptor(*ir_mesh); mesh_adaptor.convergenceOrder() = convergence_order; mesh_adaptor.refineStep() = 1; mesh_adaptor.setIndicator(*indicator); mesh_adaptor.tolerence() = adapt_tolerence; mesh_adaptor.adapt(); ir_mesh->semiregularize(); ir_mesh->regularize(false); build_femspace(); Operator::L2Interpolate(*old_phi_h, *phi_h); Operator::L2Interpolate(*old_alpha_h, *alpha_h); Operator::L2Interpolate(*old_c_h, *c_h); delete old_phi_h;old_phi_h=NULL; delete old_alpha_h;old_alpha_h=NULL; delete old_c_h;old_c_h=NULL; Operator::L2Interpolate(*old_u_h,*u_h); Operator::L2Interpolate(*old_v_h,*v_h); Operator::L2Interpolate(*old_p_h,*p_h); Operator::L2Interpolate(*old_last_p_h,*last_p_h); delete old_u_h; old_u_h = NULL; delete old_v_h; old_v_h = NULL; delete old_p_h; old_p_h = NULL; delete old_last_p_h; old_last_p_h = NULL; //Operator::L2Project(*old_phi_h, *phi_h, Operator::LOCAL_LEAST_SQUARE, 5); //Operator::L2Project(*old_c_h, *c_h, Operator::LOCAL_LEAST_SQUARE, 5); //memoryReclaim(old_ir_mesh); //memoryReclaim(ir_mesh); //memoryReclaim(); delete old_fem_space;old_fem_space=NULL; delete old_ir_mesh;old_ir_mesh=NULL; }
void SCL::adapt_mesh() { get_indicator(); /// 计算自适应指示子 double convergence_order = 1.0; double adapt_tolerence = 5.0e-04; double ADAPT_RATIO = 0.03; double rtol = (1.33333*pow(2.0, DIM + 1.0))*adapt_tolerence; double ctol = adapt_tolerence/(1.33333*pow(2.0, DIM + 1.0)); size_t n_ele, n_ele_to_refine, n_ele_to_coarse; n_ele = fem_space->n_element(); n_ele_to_refine = std::count_if(indicator.begin(), indicator.end(), std::bind2nd(std::greater<double>(), rtol)); n_ele_to_coarse = std::count_if(indicator.begin(), indicator.end(), std::bind2nd(std::less<double>(), ctol)); /// 如果需要加密的网格数太少,则不做自适应 int is_rank_adapt = (n_ele_to_refine + n_ele_to_coarse < ADAPT_RATIO*n_ele)?0:1; int is_adapt; /// 是否做自适应需要在所有进程间进行同步 MPI_Allreduce(&is_rank_adapt, &is_adapt, 1, MPI_INT, MPI_SUM, htree.communicator()); if (is_adapt == 0) return; ir_mesh_t * old_ir_mesh = ir_mesh; fe_space_t * old_fem_space = fem_space; fe_func_t * old_u_h = u_h; ir_mesh = new ir_mesh_t(*old_ir_mesh); MeshAdaptor<DIM> mesh_adaptor(*ir_mesh); mesh_adaptor.convergenceOrder() = convergence_order; mesh_adaptor.refineStep() = 1; mesh_adaptor.setIndicator(indicator); mesh_adaptor.tolerence() = adapt_tolerence; mesh_adaptor.adapt(); /**< 正则化自适应后的网格 */ ir_mesh->semiregularize(); ir_mesh->regularize(false); /**< 建立新的有限元空间和将解更新到新的空间 */ build_fe_space(); u_h = new fe_func_t(*fem_space); Operator::L2Project(*old_u_h, *u_h, Operator::LOCAL_LEAST_SQUARE, 3); /**< 释放旧的网格、有限元空间以及解的内存 */ delete old_u_h; delete old_fem_space; delete old_ir_mesh; update_edge_cache(*u_h); /// 更新边界缓冲 }
int main(int argc, char * argv[]) { std::cerr << "PARAMETERIZATION" << std::endl; std::cerr << " Floater parameterization" << std::endl; std::cerr << " Circle border" << std::endl; std::cerr << " Eigen solver" << std::endl; //*************************************** // decode parameters //*************************************** if (argc-1 != 1) { std::cerr << "Usage: " << argv[0] << " input_file.off" << std::endl; return(EXIT_FAILURE); } // File name is: const char* input_filename = argv[1]; //*************************************** // Read the mesh //*************************************** // Read the mesh std::ifstream stream(input_filename); Polyhedron mesh; stream >> mesh; if(!stream || !mesh.is_valid() || mesh.empty()) { std::cerr << "Error: cannot read OFF file " << input_filename << std::endl; return EXIT_FAILURE; } //*************************************** // Create Polyhedron adaptor // Note: no cutting => we support only // meshes that are topological disks //*************************************** typedef CGAL::Parameterization_polyhedron_adaptor_3<Polyhedron> Parameterization_polyhedron_adaptor; Timer t; t.start(); Parameterization_polyhedron_adaptor mesh_adaptor(mesh); //*************************************** // Floater Mean Value Coordinates parameterization // (circular border) with Eigen solver //*************************************** // Circular border parameterizer (the default) typedef CGAL::Circular_border_arc_length_parameterizer_3<Parameterization_polyhedron_adaptor> Border_parameterizer; // Eigen solver typedef CGAL::Eigen_solver_traits<Eigen::BiCGSTAB<CGAL::Eigen_sparse_matrix<double>::EigenType, Eigen::IncompleteLUT< double > > > Solver; // Floater Mean Value Coordinates parameterization // (circular border) with Eigen solver typedef CGAL::Mean_value_coordinates_parameterizer_3<Parameterization_polyhedron_adaptor, Border_parameterizer, Solver> Parameterizer; Parameterizer::Error_code err = CGAL::parameterize(mesh_adaptor, Parameterizer()); t.stop(); switch(err) { case Parameterizer::OK: // Success break; case Parameterizer::ERROR_EMPTY_MESH: // Input mesh not supported case Parameterizer::ERROR_NON_TRIANGULAR_MESH: case Parameterizer::ERROR_NO_TOPOLOGICAL_DISC: case Parameterizer::ERROR_BORDER_TOO_SHORT: std::cerr << "Input mesh not supported: " << Parameterizer::get_error_message(err) << std::endl; return EXIT_FAILURE; break; default: // Error std::cerr << "Error: " << Parameterizer::get_error_message(err) << std::endl; return EXIT_FAILURE; break; }; //*************************************** // Output //*************************************** // Raw output: dump (u,v) pairs Polyhedron::Vertex_const_iterator pVertex; for (pVertex = mesh.vertices_begin(); pVertex != mesh.vertices_end(); pVertex++) { // (u,v) pair is stored in any halfedge double u = mesh_adaptor.info(pVertex->halfedge())->uv().x(); double v = mesh_adaptor.info(pVertex->halfedge())->uv().y(); std::cout << "(u,v) = (" << u << "," << v << ")" << std::endl; } std::cerr << t.time() << "sec." << std::endl; return EXIT_SUCCESS; }
// ---------------------------------------------------------------------------- // main() // ---------------------------------------------------------------------------- int main(int argc, char * argv[]) { std::cerr << "PARAMETERIZATION" << std::endl; std::cerr << " Discrete Authalic Parameterization" << std::endl; std::cerr << " Circular arclength border" << std::endl; std::cerr << " Eigen solver" << std::endl; std::cerr << " Very simple cut if model is not a topological disk" << std::endl; std::cerr << " Output: EPS" << std::endl; //*************************************** // decode parameters //*************************************** if (argc-1 != 2) { std::cerr << "Usage: " << argv[0] << " input_file.off output_file.eps" << std::endl; return(EXIT_FAILURE); } // File names are: const char* input_filename = argv[1]; const char* output_filename = argv[2]; //*************************************** // Read the mesh //*************************************** // Read the mesh std::ifstream stream(input_filename); Polyhedron mesh; stream >> mesh; if(!stream || !mesh.is_valid() || mesh.empty()) { std::cerr << "Error: cannot read OFF file " << input_filename << std::endl; return EXIT_FAILURE; } //*************************************** // Create Polyhedron adaptor //*************************************** Parameterization_polyhedron_adaptor mesh_adaptor(mesh); //*************************************** // Virtually cut mesh //*************************************** // The parameterization methods support only meshes that // are topological disks => we need to compute a "cutting" of the mesh // that makes it homeomorphic to a disk Seam seam = cut_mesh(mesh_adaptor); if (seam.empty()) { std::cerr << "Input mesh not supported: the example cutting algorithm is too simple to cut this shape" << std::endl; return EXIT_FAILURE; } // Create a second adaptor that virtually "cuts" the mesh following the 'seam' path typedef CGAL::Parameterization_mesh_patch_3<Parameterization_polyhedron_adaptor> Mesh_patch_polyhedron; Mesh_patch_polyhedron mesh_patch(mesh_adaptor, seam.begin(), seam.end()); if (!mesh_patch.is_valid()) { std::cerr << "Input mesh not supported: non manifold shape or invalid cutting" << std::endl; return EXIT_FAILURE; } //*************************************** // Discrete Authalic Parameterization (square border) // with Eigen solver //*************************************** // Border parameterizer typedef CGAL::Circular_border_arc_length_parameterizer_3<Mesh_patch_polyhedron> Border_parameterizer; // Discrete Authalic Parameterization (square border) // with Eigen solver typedef CGAL::Discrete_authalic_parameterizer_3<Mesh_patch_polyhedron, Border_parameterizer> Parameterizer; Parameterizer::Error_code err = CGAL::parameterize(mesh_patch, Parameterizer()); switch(err) { case Parameterizer::OK: // Success break; case Parameterizer::ERROR_EMPTY_MESH: // Input mesh not supported case Parameterizer::ERROR_NON_TRIANGULAR_MESH: case Parameterizer::ERROR_NO_TOPOLOGICAL_DISC: case Parameterizer::ERROR_BORDER_TOO_SHORT: std::cerr << "Input mesh not supported: " << Parameterizer::get_error_message(err) << std::endl; return EXIT_FAILURE; break; default: // Error std::cerr << "Error: " << Parameterizer::get_error_message(err) << std::endl; return EXIT_FAILURE; break; }; //*************************************** // Output //*************************************** // Write Postscript file if ( ! write_file_eps(mesh_adaptor, output_filename) ) { std::cerr << "Error: cannot write file " << output_filename << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }
int main() #endif { CGAL::Timer total_timer; total_timer.start(); std::cerr << "PARAMETERIZATION" << std::endl; //*************************************** // Read options on the command line //*************************************** std::string type; // default: Floater param std::string border; // default: circular border param. std::string solver; // default: OpenNL solver std::string input; // required std::string output; // default: out.eps try { #ifdef CGAL_USE_BOOST_PROGRAM_OPTIONS po::options_description desc("Allowed options"); desc.add_options() ("help,h", "prints this help message") ("type,t", po::value<std::string>(&type)->default_value("floater"), "parameterization method: floater, conformal, barycentric, authalic or lscm") ("border,b", po::value<std::string>(&border)->default_value("circle"), "border shape: circle, square or 2pts (lscm only)") ("solver,s", po::value<std::string>(&solver)->default_value("opennl"), "solver: opennl") ("input,i", po::value<std::string>(&input)->default_value(""), "input mesh (OFF)") ("output,o", po::value<std::string>(&output)->default_value("out.eps"), "output file (EPS or OBJ)") ; po::positional_options_description p; p.add("input", 1); p.add("output", 1); po::variables_map vm; po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm); po::notify(vm); if (vm.count("help")) { std::cout << desc << "\n"; return 1; } #else std::cerr << "Command-line options require Boost.ProgramOptions" << std::endl; std::cerr << "Use hard-coded options" << std::endl; border = "square"; type = "floater"; solver = "opennl"; input = "data/rotor.off"; output = "rotor_floater_square_opennl_parameterized.obj"; #endif } catch(std::exception& e) { std::cerr << "error: " << e.what() << "\n"; return 1; } catch(...) { std::cerr << "Exception of unknown type!\n"; throw; } //*************************************** // Read the mesh //*************************************** CGAL::Timer task_timer; task_timer.start(); // Read the mesh std::ifstream stream(input.c_str()); Polyhedron mesh; stream >> mesh; if(!stream || !mesh.is_valid() || mesh.empty()) { std::cerr << "Error: cannot read OFF file " << input << std::endl; return EXIT_FAILURE; } std::cerr << "Read file " << input << ": " << task_timer.time() << " seconds " << "(" << mesh.size_of_facets() << " facets, " << mesh.size_of_vertices() << " vertices)" << std::endl; task_timer.reset(); //*************************************** // Create mesh adaptor //*************************************** // The Surface_mesh_parameterization package needs an adaptor to handle Polyhedron_ex meshes Parameterization_polyhedron_adaptor mesh_adaptor(mesh); // The parameterization methods support only meshes that // are topological disks => we need to compute a cutting path // that makes the mesh a "virtual" topological disk // // 1) Cut the mesh Seam seam = cut_mesh(mesh_adaptor); if (seam.empty()) { std::cerr << "Input mesh not supported: the example cutting algorithm is too simple to cut this shape" << std::endl; return EXIT_FAILURE; } // // 2) Create adaptor that virtually "cuts" a patch in a Polyhedron_ex mesh Mesh_patch_polyhedron mesh_patch(mesh_adaptor, seam.begin(), seam.end()); if (!mesh_patch.is_valid()) { std::cerr << "Input mesh not supported: non manifold shape or invalid cutting" << std::endl; return EXIT_FAILURE; } std::cerr << "Mesh cutting: " << task_timer.time() << " seconds." << std::endl; task_timer.reset(); //*************************************** // switch parameterization //*************************************** std::cerr << "Parameterization..." << std::endl; // Defines the error codes typedef CGAL::Parameterizer_traits_3<Mesh_patch_polyhedron> Parameterizer; Parameterizer::Error_code err; if (solver == std::string("opennl")) { err = parameterize<Mesh_patch_polyhedron, OpenNL::DefaultLinearSolverTraits<double>, OpenNL::SymmetricLinearSolverTraits<double> >(mesh_patch, type, border); } else { std::cerr << "Error: invalid solver parameter " << solver << std::endl; err = Parameterizer::ERROR_WRONG_PARAMETER; } // Report errors switch(err) { case Parameterizer::OK: // Success break; case Parameterizer::ERROR_EMPTY_MESH: // Input mesh not supported case Parameterizer::ERROR_NON_TRIANGULAR_MESH: case Parameterizer::ERROR_NO_TOPOLOGICAL_DISC: case Parameterizer::ERROR_BORDER_TOO_SHORT: std::cerr << "Input mesh not supported: " << Parameterizer::get_error_message(err) << std::endl; return EXIT_FAILURE; break; default: // Error std::cerr << "Error: " << Parameterizer::get_error_message(err) << std::endl; return EXIT_FAILURE; break; }; std::cerr << "Parameterization: " << task_timer.time() << " seconds." << std::endl; task_timer.reset(); //*************************************** // Output //*************************************** // get output file's extension std::string extension = output.substr(output.find_last_of('.')); // Save mesh if (extension == ".eps" || extension == ".EPS") { // write Postscript file if ( ! mesh.write_file_eps(output.c_str()) ) { std::cerr << "Error: cannot write file " << output << std::endl; return EXIT_FAILURE; } } else if (extension == ".obj" || extension == ".OBJ") { // write Wavefront obj file if ( ! mesh.write_file_obj(output.c_str()) ) { std::cerr << "Error: cannot write file " << output << std::endl; return EXIT_FAILURE; } } else { std::cerr << "Error: output format not supported" << output << std::endl; err = Parameterizer::ERROR_WRONG_PARAMETER; return EXIT_FAILURE; } std::cerr << "Write file " << output << ": " << task_timer.time() << " seconds " << std::endl; return EXIT_SUCCESS; }
int main(int argc, char * argv[]) { std::cerr << "PARAMETERIZATION" << std::endl; std::cerr << " Floater parameterization" << std::endl; std::cerr << " Circle border" << std::endl; std::cerr << " OpenNL solver" << std::endl; std::cerr << " Very simple cut if model is not a topological disk" << std::endl; //*************************************** // decode parameters //*************************************** if (argc-1 != 1) { std::cerr << "Usage: " << argv[0] << " input_file.off" << std::endl; return(EXIT_FAILURE); } // File name is: const char* input_filename = argv[1]; //*************************************** // Read the mesh //*************************************** // Read the mesh std::ifstream stream(input_filename); Polyhedron mesh; stream >> mesh; if(!stream || !mesh.is_valid() || mesh.empty()) { std::cerr << "Error: cannot read OFF file " << input_filename << std::endl; return EXIT_FAILURE; } //*************************************** // Create Polyhedron adaptor //*************************************** Parameterization_polyhedron_adaptor mesh_adaptor(mesh); //*************************************** // Virtually cut mesh //*************************************** // The parameterization methods support only meshes that // are topological disks => we need to compute a "cutting" of the mesh // that makes it homeomorphic to a disk Seam seam = cut_mesh(mesh_adaptor); if (seam.empty()) { std::cerr << "Input mesh not supported: the example cutting algorithm is too simple to cut this shape" << std::endl; return EXIT_FAILURE; } // Create a second adaptor that virtually "cuts" the mesh following the 'seam' path typedef CGAL::Parameterization_mesh_patch_3<Parameterization_polyhedron_adaptor> Mesh_patch_polyhedron; Mesh_patch_polyhedron mesh_patch(mesh_adaptor, seam.begin(), seam.end()); if (!mesh_patch.is_valid()) { std::cerr << "Input mesh not supported: non manifold shape or invalid cutting" << std::endl; return EXIT_FAILURE; } //*************************************** // Floater Mean Value Coordinates parameterization //*************************************** typedef CGAL::Parameterizer_traits_3<Mesh_patch_polyhedron> Parameterizer; // Type that defines the error codes Parameterizer::Error_code err = CGAL::parameterize(mesh_patch); switch(err) { case Parameterizer::OK: // Success break; case Parameterizer::ERROR_EMPTY_MESH: // Input mesh not supported case Parameterizer::ERROR_NON_TRIANGULAR_MESH: case Parameterizer::ERROR_NO_TOPOLOGICAL_DISC: case Parameterizer::ERROR_BORDER_TOO_SHORT: std::cerr << "Input mesh not supported: " << Parameterizer::get_error_message(err) << std::endl; return EXIT_FAILURE; break; default: // Error std::cerr << "Error: " << Parameterizer::get_error_message(err) << std::endl; return EXIT_FAILURE; break; }; //*************************************** // Output //*************************************** // Raw output: dump (u,v) pairs Polyhedron::Vertex_const_iterator pVertex; for (pVertex = mesh.vertices_begin(); pVertex != mesh.vertices_end(); pVertex++) { // (u,v) pair is stored in any halfedge double u = mesh_adaptor.info(pVertex->halfedge())->uv().x(); double v = mesh_adaptor.info(pVertex->halfedge())->uv().y(); std::cout << "(u,v) = (" << u << "," << v << ")" << std::endl; } return EXIT_SUCCESS; }