50 const bool write_as_sets,
51 const bool write_as_tags,
52 const bool partition_tagged_sets,
53 const bool partition_tagged_ents,
54 const char* aggregating_tag,
59 if( mbpc->proc_config().proc_size() != 1 )
61 std::cout <<
"MetisPartitioner::partition_mesh_and_geometry must be called in serial." << std::endl;
66 if( NULL != method && strcmp( method,
"ML_RB" ) != 0 && strcmp( method,
"ML_KWAY" ) != 0 )
68 std::cout <<
"ERROR: Method must be "
69 <<
"ML_RB or ML_KWAY" << std::endl;
73 std::vector< double > pts;
74 std::vector< idx_t > ids;
75 std::vector< idx_t > adjs, parts;
76 std::vector< idx_t >
length;
83 if( !partition_tagged_sets && !partition_tagged_ents )
88 else if( partition_tagged_sets )
93 else if( partition_tagged_ents )
100 MB_SET_ERR( MB_FAILURE,
"Either partition tags or sets for Metis partitoner" );
105 std::cout <<
" time to assemble graph: " << ( clock() - t ) / (
double)CLOCKS_PER_SEC <<
"s. \n";
109 std::cout <<
"Computing partition using " << method <<
" method for " <<
nparts <<
" processors..." << std::endl;
111 idx_t nelems =
length.size() - 1;
113 assign_parts = (idx_t*)malloc(
sizeof( idx_t ) * nelems );
114 idx_t nconstraidx_ts = 1;
116 idx_t nOfPartitions =
static_cast< idx_t
>(
nparts );
119 if( strcmp( method,
"ML_KWAY" ) == 0 )
121 idx_t options[METIS_NOPTIONS];
122 METIS_SetDefaultOptions( options );
123 options[METIS_OPTION_CONTIG] = 1;
124 metis_RESULT = METIS_PartGraphKway( &nelems, &nconstraidx_ts, &
length[0], &adjs[0], NULL, NULL, NULL,
125 &nOfPartitions, NULL, NULL, options, &edgeCut, assign_parts );
127 else if( strcmp( method,
"ML_RB" ) == 0 )
129 idx_t options[METIS_NOPTIONS];
130 METIS_SetDefaultOptions( options );
131 options[METIS_OPTION_OBJTYPE] = METIS_OBJTYPE_CUT;
132 options[METIS_OPTION_IPTYPE] = METIS_IPTYPE_GROW;
133 options[METIS_OPTION_CTYPE] = METIS_CTYPE_RM;
134 options[METIS_OPTION_RTYPE] = METIS_RTYPE_FM;
135 options[METIS_OPTION_NCUTS] = 10;
137 options[METIS_OPTION_NITER] = 10;
138 options[METIS_OPTION_UFACTOR] = 30;
139 options[METIS_OPTION_DBGLVL] = METIS_DBG_INFO;
140 metis_RESULT = METIS_PartGraphRecursive( &nelems, &nconstraidx_ts, &
length[0], &adjs[0], NULL, NULL, NULL,
141 &nOfPartitions, NULL, NULL, options, &edgeCut, assign_parts );
144 MB_SET_ERR( MB_FAILURE,
"Either ML_KWAY or ML_RB needs to be specified for Metis partitioner" );
148 std::cout <<
" time to partition: " << ( clock() - t ) / (
double)CLOCKS_PER_SEC <<
"s. \n";
157 result = mbpc->assign_global_ids( rootset, part_dim, 1,
true,
false );
162 if( metis_RESULT != METIS_OK )
return MB_FAILURE;
165 std::cout <<
"Saving partition information to MOAB..." << std::endl;
167 if( partition_tagged_sets || partition_tagged_ents )
181 std::cout <<
" time to write partition in memory " << ( clock() - t ) / (
double)CLOCKS_PER_SEC <<
"s. \n";
184 free( assign_parts );
190 std::vector< double >& coords,
191 std::vector< idx_t >& moab_ids,
192 std::vector< idx_t >& adjacencies,
193 std::vector< idx_t >&
length,
195 const char* aggregating_tag )
205 std::map< idx_t, Range > aggloElems;
211 if( partSet >= 0 ) aggloElems[partSet].insert( entity );
238 for( std::map< idx_t, Range >::iterator mit = aggloElems.begin(); mit != aggloElems.end(); mit++ )
255 std::vector< double >& coords,
256 std::vector< idx_t >& moab_ids,
257 std::vector< idx_t >& adjacencies,
258 std::vector< idx_t >&
length,
260 const char* aggregating_tag )
307 std::vector< Range > skin_subFaces( elems.
size() );
317 upper = part_ents.
upper_bound( CN::TypeDimensionMap[dimension - 1].second );
318 part_ents.
erase( lower, upper );
321 result = skinner.
find_skin( 0, part_ents,
false, skin_subFaces[i], NULL,
false,
true,
false );
325 std::vector< EntityHandle > adjs;
326 std::vector< idx_t > neighbors;
327 double avg_position[3];
330 for(
unsigned int k = 0; k < i; k++ )
334 for(
unsigned int t = 0; t < i; t++ )
339 if( subFaces.
size() > 0 ) adjs.push_back( elems[t] );
344 neighbors.resize( adjs.size() );
350 std::copy( neighbors.begin(), neighbors.end(), std::back_inserter( adjacencies ) );
354 moab_ids.push_back( moab_id );
361 std::copy( avg_position, avg_position + 3, std::back_inserter( coords ) );
363 for(
unsigned int k = 0; k < i; k++ )
365 for(
unsigned int t = 0; t < k; t++ )
374 std::cout <<
"Length vector: " << std::endl;
375 std::copy(
length.begin(),
length.end(), std::ostream_iterator< idx_t >( std::cout,
", " ) );
376 std::cout << std::endl;
377 std::cout <<
"Adjacencies vector: " << std::endl;
378 std::copy( adjacencies.begin(), adjacencies.end(), std::ostream_iterator< idx_t >( std::cout,
", " ) );
379 std::cout << std::endl;
380 std::cout <<
"Moab_ids vector: " << std::endl;
381 std::copy( moab_ids.begin(), moab_ids.end(), std::ostream_iterator< idx_t >( std::cout,
", " ) );
382 std::cout << std::endl;
383 std::cout <<
"Coords vector: " << std::endl;
384 std::copy( coords.begin(), coords.end(), std::ostream_iterator< double >( std::cout,
", " ) );
385 std::cout << std::endl;
391 std::vector< double >& coords,
392 std::vector< idx_t >& moab_ids,
393 std::vector< idx_t >& adjacencies,
394 std::vector< idx_t >&
length,
409 result = mbpc->assign_global_ids( 0, dimension, 0 );
422 double avg_position[3];
423 int index_in_elems = 0;
441 neighbors[i] = elems.
index( adjEnt );
448 std::copy( neighbors, neighbors + adjs.
size(), std::back_inserter( adjacencies ) );
455 moab_ids.push_back( index_in_elems );
458 std::copy( avg_position, avg_position + 3, std::back_inserter( coords ) );
463 std::cout <<
"Length vector: " << std::endl;
464 std::copy(
length.begin(),
length.end(), std::ostream_iterator< idx_t >( std::cout,
", " ) );
465 std::cout << std::endl;
466 std::cout <<
"Adjacencies vector: " << std::endl;
467 std::copy( adjacencies.begin(), adjacencies.end(), std::ostream_iterator< idx_t >( std::cout,
", " ) );
468 std::cout << std::endl;
469 std::cout <<
"Moab_ids vector: " << std::endl;
470 std::copy( moab_ids.begin(), moab_ids.end(), std::ostream_iterator< idx_t >( std::cout,
", " ) );
471 std::cout << std::endl;
472 std::cout <<
"Coords vector: " << std::endl;
473 std::copy( coords.begin(), coords.end(), std::ostream_iterator< double >( std::cout,
", " ) );
474 std::cout << std::endl;
482 const idx_t* assignment,
483 const bool write_as_sets,
484 const bool write_as_tags )
499 if( !tagged_sets.
empty() )
518 for( idx_t i = 0; i < num_new; i++ )
523 tagged_sets.
insert( new_set );
530 for( idx_t i = 0; i < num_del; i++ )
543 idx_t* dum_ids =
new idx_t[
nparts];
544 for( idx_t i = 0; i <
nparts; i++ )
551 std::vector< EntityHandle > tmp_part_sets;
555 for( rit = elems.
begin(); rit != elems.
end(); rit++, j++ )
569 if( !empty_sets.
empty() )
571 std::cout <<
"WARNING: " << empty_sets.
size() <<
" empty sets in partition: ";
572 for( rit = empty_sets.
begin(); rit != empty_sets.
end(); rit++ )
573 std::cout << *rit <<
" ";
574 std::cout << std::endl;
611 const idx_t* assignment,
612 const bool write_as_sets,
613 const bool write_as_tags )
619 idx_t dum_id = -1, i;
629 if( !tagged_sets.
empty() )
648 for( i = 0; i < num_new; i++ )
653 tagged_sets.
insert( new_set );
660 for( i = 0; i < num_del; i++ )
673 int* dum_ids =
new int[
nparts];
674 for( i = 0; i <
nparts; i++ )
681 std::vector< EntityHandle > tmp_part_sets;
684 for( i = 0, rit = elems.
begin(); rit != elems.
end(); rit++, i++ )
698 if( !empty_sets.
empty() )
700 std::cout <<
"WARNING: " << empty_sets.
size() <<
" empty sets in partition: ";
701 for( rit = empty_sets.
begin(); rit != empty_sets.
end(); rit++ )
702 std::cout << *rit <<
" ";
703 std::cout << std::endl;
709 if(
sizeof(
int ) !=
sizeof( idx_t ) )
713 int* assg_int =
new int[elems.
size()];
714 for(
int k = 0; k < (int)elems.
size(); k++ )
715 assg_int[k] = assignment[k];