81 int main(
int argc,
char** argv )
85 if( MPI_Init( &argc, &argv ) != MPI_SUCCESS )
87 std::cerr <<
"MPI_Init failed" << std::endl;
94 void operator()(
int* )
const
99 std::unique_ptr< int, MPIFinalizer > mpi_guard(
nullptr );
109 opts.
addOpt<
int >(
"dim,d",
"Dimension of mesh (default=3)", &dimension );
110 opts.
addOpt<
int >(
",n",
"Number of elements on a side (default=10)", &elements_per_side );
114 if( dimension < 1 || dimension > 3 )
116 throw std::invalid_argument(
"Dimension must be 1, 2, or 3" );
118 if( elements_per_side < 1 )
120 throw std::invalid_argument(
"Number of elements must be positive" );
123 catch(
const std::exception& e )
125 std::cerr <<
"Error parsing command line: " << e.what() << std::endl;
130 std::unique_ptr< Core > moab_instance = std::make_unique< Core >();
133 std::cerr <<
"Failed to create MOAB instance" << std::endl;
139 MB_CHK_SET_ERR( moab_instance->query_interface( scd_interface ),
"Failed to get ScdInterface" );
142 std::cerr <<
"Failed to get ScdInterface: null pointer returned" << std::endl;
149 int ihigh = elements_per_side;
153 MPI_Comm_rank( MPI_COMM_WORLD, &rank );
154 MPI_Comm_size( MPI_COMM_WORLD, &nprocs );
157 const int elements_per_proc = elements_per_side / nprocs;
158 const int remainder = elements_per_side % nprocs;
161 ilow = rank * elements_per_proc + std::min( rank, remainder );
162 ihigh = ilow + elements_per_proc + ( rank < remainder ? 1 : 0 );
165 std::string write_options =
"";
166 if( nprocs > 1 ) write_options =
"PARALLEL=WRITE_PART";
172 const moab::HomCoord low( ilow, ( dimension > 1 ) ? 0 : -1, ( dimension > 2 ) ? 0 : -1 );
174 const moab::HomCoord high( ihigh, ( dimension > 1 ) ? elements_per_side : -1,
175 ( dimension > 2 ) ? elements_per_side : -1 );
187 "Failed to construct structured box" );
191 std::cerr <<
"Failed to construct structured box: null box returned" << std::endl;
196 Range vertices, elements;
199 MB_CHK_SET_ERR( moab_instance->get_entities_by_dimension( 0, 0, vertices ),
"Failed to get vertices" );
200 MB_CHK_SET_ERR( moab_instance->get_entities_by_dimension( 0, dimension, elements ),
"Failed to get elements" );
203 std::size_t local_entities_size[2] = { vertices.
size(), elements.
size() }, global_entities_size[2] = { 0, 0 };
204 MPI_Allreduce( local_entities_size, global_entities_size, 2, MPI_UNSIGNED_LONG_LONG, MPI_SUM, MPI_COMM_WORLD );
208 const std::size_t expected_vertices =
static_cast< std::size_t
>( std::pow( elements_per_side + 1, dimension ) );
209 const std::size_t expected_elements =
static_cast< std::size_t
>( std::pow( elements_per_side, dimension ) );
212 auto print_message = [rank](
const auto& message ) {
215 std::cout << message << std::endl;
220 if( expected_elements == global_entities_size[1] )
222 const auto element_type = moab_instance->type_from_handle( *elements.
begin() );
223 std::ostringstream msg;
225 <<
" elements and " << global_entities_size[0] <<
" vertices.";
226 print_message( msg.str() );
230 std::ostringstream err_msg;
231 err_msg <<
"Error: Expected " << expected_elements <<
" elements and " << expected_vertices
232 <<
" vertices, but got " << global_entities_size[1] <<
" elements and " << global_entities_size[0]
234 print_message( err_msg.str() );
240 const int j_max = ( dimension > 1 ) ? elements_per_side - 1 : 0;
241 const int k_max = ( dimension > 2 ) ? elements_per_side - 1 : 0;
245 std::vector< double > coordinates;
246 for(
int k = 0; k <= k_max; ++k )
248 for(
int j = 0; j <= j_max; ++j )
250 for(
int i = ilow; i < ihigh; ++i )
256 std::cerr <<
"Failed to get element at (" << i <<
", " << j <<
", " << k <<
")" << std::endl;
262 std::vector< EntityHandle > connectivity;
263 MB_CHK_SET_ERR( moab_instance->get_connectivity( &element, 1, connectivity ),
264 "Failed to get connectivity for element at (" << i <<
", " << j <<
", " << k
265 <<
") with handle " << element );
268 coordinates.resize( 3 * connectivity.size() );
269 MB_CHK_SET_ERR( moab_instance->get_coords( connectivity.data(), connectivity.size(),
270 coordinates.data() ),
271 "Failed to get coordinates for element at (" << i <<
", " << j <<
", " << k
272 <<
") with handle " << element );
278 MB_CHK_SET_ERR( moab_instance->write_file(
"structured_mesh.h5m",
"h5m", write_options.c_str() ),
279 "Failed to write mesh file" );
282 MB_CHK_SET_ERR( moab_instance->release_interface( scd_interface ),
"Failed to release interface" );