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 )
87 else if( partition_tagged_sets )
91 else if( partition_tagged_ents )
97 MB_SET_ERR( MB_FAILURE,
"Either partition tags or sets for Metis partitoner" );
102 std::cout <<
" time to assemble graph: " << ( clock() - t ) / (
double)CLOCKS_PER_SEC <<
"s. \n";
106 std::cout <<
"Computing partition using " << method <<
" method for " <<
nparts <<
" processors..." << std::endl;
108 idx_t nelems =
length.size() - 1;
110 assign_parts = (idx_t*)malloc(
sizeof( idx_t ) * nelems );
111 idx_t nconstraidx_ts = 1;
113 idx_t nOfPartitions =
static_cast< idx_t
>(
nparts );
116 if( strcmp( method,
"ML_KWAY" ) == 0 )
118 idx_t options[METIS_NOPTIONS];
119 METIS_SetDefaultOptions( options );
120 options[METIS_OPTION_CONTIG] = 1;
121 metis_RESULT = METIS_PartGraphKway( &nelems, &nconstraidx_ts, &
length[0], &adjs[0], NULL, NULL, NULL,
122 &nOfPartitions, NULL, NULL, options, &edgeCut, assign_parts );
124 else if( strcmp( method,
"ML_RB" ) == 0 )
126 idx_t options[METIS_NOPTIONS];
127 METIS_SetDefaultOptions( options );
128 options[METIS_OPTION_OBJTYPE] = METIS_OBJTYPE_CUT;
129 options[METIS_OPTION_IPTYPE] = METIS_IPTYPE_GROW;
130 options[METIS_OPTION_CTYPE] = METIS_CTYPE_RM;
131 options[METIS_OPTION_RTYPE] = METIS_RTYPE_FM;
132 options[METIS_OPTION_NCUTS] = 10;
134 options[METIS_OPTION_NITER] = 10;
135 options[METIS_OPTION_UFACTOR] = 30;
136 options[METIS_OPTION_DBGLVL] = METIS_DBG_INFO;
137 metis_RESULT = METIS_PartGraphRecursive( &nelems, &nconstraidx_ts, &
length[0], &adjs[0], NULL, NULL, NULL,
138 &nOfPartitions, NULL, NULL, options, &edgeCut, assign_parts );
141 MB_SET_ERR( MB_FAILURE,
"Either ML_KWAY or ML_RB needs to be specified for Metis partitioner" );
145 std::cout <<
" time to partition: " << ( clock() - t ) / (
double)CLOCKS_PER_SEC <<
"s. \n";
154 result = mbpc->assign_global_ids( rootset, part_dim, 1,
true,
false );
MB_CHK_ERR( result );
158 if( metis_RESULT != METIS_OK )
return MB_FAILURE;
161 std::cout <<
"Saving partition information to MOAB..." << std::endl;
163 if( partition_tagged_sets || partition_tagged_ents )
175 std::cout <<
" time to write partition in memory " << ( clock() - t ) / (
double)CLOCKS_PER_SEC <<
"s. \n";
178 free( assign_parts );
184 std::vector< double >& coords,
185 std::vector< idx_t >& moab_ids,
186 std::vector< idx_t >& adjacencies,
187 std::vector< idx_t >&
length,
189 const char* aggregating_tag )
199 std::map< idx_t, Range > aggloElems;
205 if( partSet >= 0 ) aggloElems[partSet].insert( entity );
232 for( std::map< idx_t, Range >::iterator mit = aggloElems.begin(); mit != aggloElems.end(); mit++ )
249 std::vector< double >& coords,
250 std::vector< idx_t >& moab_ids,
251 std::vector< idx_t >& adjacencies,
252 std::vector< idx_t >&
length,
254 const char* aggregating_tag )
294 std::vector< Range > skin_subFaces( elems.
size() );
304 upper = part_ents.
upper_bound( CN::TypeDimensionMap[dimension - 1].second );
305 part_ents.
erase( lower, upper );
308 result = skinner.
find_skin( 0, part_ents,
false, skin_subFaces[i], NULL,
false,
true,
false );
MB_CHK_ERR( result );
311 std::vector< EntityHandle > adjs;
312 std::vector< idx_t > neighbors;
313 double avg_position[3];
316 for(
unsigned int k = 0; k < i; k++ )
320 for(
unsigned int t = 0; t < i; t++ )
325 if( subFaces.
size() > 0 ) adjs.push_back( elems[t] );
330 neighbors.resize( adjs.size() );
335 std::copy( neighbors.begin(), neighbors.end(), std::back_inserter( adjacencies ) );
339 moab_ids.push_back( moab_id );
344 std::copy( avg_position, avg_position + 3, std::back_inserter( coords ) );
346 for(
unsigned int k = 0; k < i; k++ )
348 for(
unsigned int t = 0; t < k; t++ )
357 std::cout <<
"Length vector: " << std::endl;
358 std::copy(
length.begin(),
length.end(), std::ostream_iterator< idx_t >( std::cout,
", " ) );
359 std::cout << std::endl;
360 std::cout <<
"Adjacencies vector: " << std::endl;
361 std::copy( adjacencies.begin(), adjacencies.end(), std::ostream_iterator< idx_t >( std::cout,
", " ) );
362 std::cout << std::endl;
363 std::cout <<
"Moab_ids vector: " << std::endl;
364 std::copy( moab_ids.begin(), moab_ids.end(), std::ostream_iterator< idx_t >( std::cout,
", " ) );
365 std::cout << std::endl;
366 std::cout <<
"Coords vector: " << std::endl;
367 std::copy( coords.begin(), coords.end(), std::ostream_iterator< double >( std::cout,
", " ) );
368 std::cout << std::endl;
374 std::vector< double >& coords,
375 std::vector< idx_t >& moab_ids,
376 std::vector< idx_t >& adjacencies,
377 std::vector< idx_t >&
length,
392 result = mbpc->assign_global_ids( 0, dimension, 0 );
MB_CHK_ERR( result );
404 double avg_position[3];
405 int index_in_elems = 0;
422 neighbors[i] = elems.
index( adjEnt );
429 std::copy( neighbors, neighbors + adjs.
size(), std::back_inserter( adjacencies ) );
435 moab_ids.push_back( index_in_elems );
438 std::copy( avg_position, avg_position + 3, std::back_inserter( coords ) );
443 std::cout <<
"Length vector: " << std::endl;
444 std::copy(
length.begin(),
length.end(), std::ostream_iterator< idx_t >( std::cout,
", " ) );
445 std::cout << std::endl;
446 std::cout <<
"Adjacencies vector: " << std::endl;
447 std::copy( adjacencies.begin(), adjacencies.end(), std::ostream_iterator< idx_t >( std::cout,
", " ) );
448 std::cout << std::endl;
449 std::cout <<
"Moab_ids vector: " << std::endl;
450 std::copy( moab_ids.begin(), moab_ids.end(), std::ostream_iterator< idx_t >( std::cout,
", " ) );
451 std::cout << std::endl;
452 std::cout <<
"Coords vector: " << std::endl;
453 std::copy( coords.begin(), coords.end(), std::ostream_iterator< double >( std::cout,
", " ) );
454 std::cout << std::endl;
462 const idx_t* assignment,
463 const bool write_as_sets,
464 const bool write_as_tags )
477 if( !tagged_sets.
empty() )
495 for( idx_t i = 0; i < num_new; i++ )
499 tagged_sets.
insert( new_set );
506 for( idx_t i = 0; i < num_del; i++ )
518 idx_t* dum_ids =
new idx_t[
nparts];
519 for( idx_t i = 0; i <
nparts; i++ )
525 std::vector< EntityHandle > tmp_part_sets;
529 for( rit = elems.
begin(); rit != elems.
end(); rit++, j++ )
542 if( !empty_sets.
empty() )
544 std::cout <<
"WARNING: " << empty_sets.
size() <<
" empty sets in partition: ";
545 for( rit = empty_sets.
begin(); rit != empty_sets.
end(); rit++ )
546 std::cout << *rit <<
" ";
547 std::cout << std::endl;
580 const idx_t* assignment,
581 const bool write_as_sets,
582 const bool write_as_tags )
588 idx_t dum_id = -1, i;
596 if( !tagged_sets.
empty() )
614 for( i = 0; i < num_new; i++ )
618 tagged_sets.
insert( new_set );
625 for( i = 0; i < num_del; i++ )
637 int* dum_ids =
new int[
nparts];
638 for( i = 0; i <
nparts; i++ )
645 std::vector< EntityHandle > tmp_part_sets;
648 for( i = 0, rit = elems.
begin(); rit != elems.
end(); rit++, i++ )
661 if( !empty_sets.
empty() )
663 std::cout <<
"WARNING: " << empty_sets.
size() <<
" empty sets in partition: ";
664 for( rit = empty_sets.
begin(); rit != empty_sets.
end(); rit++ )
665 std::cout << *rit <<
" ";
666 std::cout << std::endl;
672 if(
sizeof(
int ) !=
sizeof( idx_t ) )
676 int* assg_int =
new int[elems.
size()];
677 for(
int k = 0; k < (int)elems.
size(); k++ )
678 assg_int[k] = assignment[k];