Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
UniformRefinement.cpp
Go to the documentation of this file.
1 /** @example UniformRefinement.cpp
2  * @brief Example demonstrating uniform mesh refinement using MOAB's AHF data structures.
3  *
4  * This example shows how to:
5  * - Load a mesh file
6  * - Use the NestedRefine class for uniform mesh refinement
7  * - Control refinement levels and degrees
8  * - Write the refined mesh hierarchy to a file
9  *
10  * @note If no refinement degrees are specified, two levels are used by default.
11  *
12  * @code
13  * Usage: ./UniformRefinement [filename] [level1_degree] [level2_degree] ...
14  * Example: ./UniformRefinement input.h5m 2 3 2 # Three levels with degrees 2, 3, 2
15  * @endcode
16  */
17 
18 #include "moab/Core.hpp"
19 #include "moab/NestedRefine.hpp"
20 #include <iostream>
21 #include <vector>
22 #include <string>
23 #include <cstdlib>
24 #include <stdexcept>
25 
26 // Using declarations for cleaner code
27 using moab::Core;
28 using moab::EntityHandle;
29 using moab::ErrorCode;
30 using moab::NestedRefine;
31 
32 namespace
33 {
34 constexpr const char* DEFAULT_OUTPUT_FILE = "mesh_hierarchy.h5m";
35 constexpr int DEFAULT_REFINEMENT_LEVELS = 2;
36 
37 void print_usage( const char* program_name )
38 {
39  std::cout << "Usage: " << program_name << " filename [level1_degree level2_degree ...]\n"
40  << " filename - Path to the input mesh file\n"
41  << " levelN_degree - (Optional) Degree of refinement for each level\n"
42  << " If not specified, uses " << DEFAULT_REFINEMENT_LEVELS
43  << " levels with default degrees\n";
44 }
45 
46 std::vector< int > parse_refinement_levels( int argc, char* argv[] )
47 {
48  std::vector< int > level_degrees;
49 
50  if( argc > 2 )
51  {
52  level_degrees.reserve( argc - 2 );
53  for( int i = 2; i < argc; ++i )
54  {
55  try
56  {
57  int degree = std::stoi( argv[i] );
58  if( degree < 1 )
59  {
60  throw std::invalid_argument( "Refinement degree must be at least 1" );
61  }
62  level_degrees.push_back( degree );
63  }
64  catch( const std::exception& e )
65  {
66  throw std::runtime_error( "Invalid refinement degree: " + std::string( e.what() ) );
67  }
68  }
69  }
70  else
71  {
72  // Default: two levels with default degrees
73  level_degrees.resize( DEFAULT_REFINEMENT_LEVELS );
74  }
75 
76  return level_degrees;
77 }
78 } // namespace
79 
80 int main( int argc, char* argv[] )
81 {
82  try
83  {
84  // Parse command line arguments
85  if( argc < 2 || std::string( argv[1] ) == "--help" || std::string( argv[1] ) == "-h" )
86  {
87  print_usage( argv[0] );
88  return argc < 2 ? 1 : 0;
89  }
90 
91  const std::string input_file = argv[1];
92  auto level_degrees = parse_refinement_levels( argc, argv );
93  const int num_levels = static_cast< int >( level_degrees.size() );
94 
95  std::cout << "Input file: " << input_file << "\n"
96  << "Refinement levels: " << num_levels << "\n"
97  << "Level degrees: ";
98 
99  for( const auto& degree : level_degrees )
100  {
101  std::cout << degree << " ";
102  }
103  std::cout << "\n";
104 
105  // Initialize MOAB and load the mesh
106  auto moab = std::make_unique< Core >();
107  if( !moab )
108  {
109  throw std::runtime_error( "Failed to create MOAB instance" );
110  }
111 
112  // Load the input mesh file
113  MB_CHK_SET_ERR_CONT( moab->load_file( input_file.c_str() ), "Failed to load mesh file: " << input_file );
114 
115  // Set up the refinement
116  NestedRefine refiner( moab.get() );
117 
118  std::vector< EntityHandle > mesh_sets;
119  std::cout << "Starting mesh hierarchy generation for " << num_levels << " levels...\n";
120  // Perform the refinement
121  MB_CHK_SET_ERR( refiner.generate_mesh_hierarchy( num_levels, level_degrees.data(), mesh_sets ),
122  "Failed to generate mesh hierarchy" );
123  std::cout << "Successfully generated mesh hierarchy\n";
124 
125  // Write the refined mesh to file
126  MB_CHK_SET_ERR( moab->write_file( DEFAULT_OUTPUT_FILE ),
127  "Failed to write output file: " << DEFAULT_OUTPUT_FILE );
128 
129  std::cout << "Output written to: " << DEFAULT_OUTPUT_FILE << "\n";
130  return 0;
131  }
132  catch( const std::exception& e )
133  {
134  std::cerr << "\nError: " << e.what() << "\n";
135  return 1;
136  }
137  catch( ... )
138  {
139  std::cerr << "\nError: Unknown exception occurred\n";
140  return 1;
141  }
142 }