Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
Implements the abstract EntityRefinerOutputFunctor class. More...
#include <MeshOutputFunctor.hpp>
Public Member Functions | |
MeshOutputFunctor (RefinerTagManager *tag_mgr) | |
~MeshOutputFunctor () | |
void | print_vert_crud (EntityHandle vout, int nvhash, EntityHandle *vhash, const double *vcoords, const void *vtags) |
void | assign_global_ids (ParallelComm *comm) |
void | exchange_handles (ParallelComm *comm) |
void | assign_tags (EntityHandle vhandle, const void *vtags) |
virtual EntityHandle | map_vertex (EntityHandle vhash, const double *vcoords, const void *vtags) |
Map an input vertex to the output mesh. This should return the same value when given the same input across multiple calls. | |
virtual EntityHandle | operator() (int nvhash, EntityHandle *vhash, const double *vcoords, const void *vtags) |
Create a new vertex along a \(k\)-facet. | |
virtual void | operator() (EntityHandle h) |
Append an output vertex to the list of vertices defining a new entity. | |
virtual void | operator() (EntityType etyp) |
Create a new entity from all previously appended output vertices. | |
Public Attributes | |
Interface * | mesh_in |
Interface * | mesh_out |
bool | input_is_output |
SplitVerticesBase * | vertex_map |
std::vector< SplitVerticesBase * > | split_vertices |
std::vector< EntitySource * > | new_entities |
std::vector< EntityHandle > | elem_vert |
RefinerTagManager * | tag_manager |
EntityHandle | destination_set |
std::map< ProcessSet, int > | proc_partition_counts |
Implements the abstract EntityRefinerOutputFunctor class.
This class is a concrete implementation of the EntityRefinerOutputFunctor. It creates new vertices and regions in a new or existing mesh as the input entities are streamed through the refiner.
Definition at line 47 of file MeshOutputFunctor.hpp.
Definition at line 17 of file MeshOutputFunctor.cpp.
References destination_set, moab::RefinerTagManager::get_input_mesh(), moab::RefinerTagManager::get_output_mesh(), input_is_output, mesh_in, mesh_out, new_entities, split_vertices, tag_manager, and vertex_map.
{ this->mesh_in = tag_mgr->get_input_mesh(); this->mesh_out = tag_mgr->get_output_mesh(); this->input_is_output = ( this->mesh_in == this->mesh_out ); this->tag_manager = tag_mgr; this->destination_set = 0; // don't place output entities in a set by default. // When the input mesh and the output mesh are different, this map serves // as a dictionary from input vertices to output vertices. this->vertex_map = new SplitVertices< 1 >( this->tag_manager ); // Hold information about newly-created vertices on subdivided edges and faces. this->split_vertices.resize( 4 ); this->split_vertices[0] = 0; // Vertices (0-faces) cannot be split this->split_vertices[1] = new SplitVertices< 1 >( this->tag_manager ); this->split_vertices[2] = new SplitVertices< 2 >( this->tag_manager ); this->split_vertices[3] = new SplitVertices< 3 >( this->tag_manager ); // Hold information about newly-created mesh entities (other than split vertices) // This is necessary in order for global IDs to be assigned consistently across processes. this->new_entities.resize( 5 ); this->new_entities[0] = new EntitySource( 1, this->tag_manager ); this->new_entities[1] = new EntitySource( 2, this->tag_manager ); this->new_entities[2] = new EntitySource( 3, this->tag_manager ); this->new_entities[3] = new EntitySource( 4, this->tag_manager ); this->new_entities[4] = new EntitySource( 5, this->tag_manager ); }
Definition at line 46 of file MeshOutputFunctor.cpp.
References new_entities, split_vertices, and vertex_map.
{ delete this->vertex_map; for( int i = 1; i < 4; ++i ) delete this->split_vertices[i]; for( int i = 0; i < 5; ++i ) delete this->new_entities[i]; }
void moab::MeshOutputFunctor::assign_global_ids | ( | ParallelComm * | comm | ) |
Definition at line 86 of file MeshOutputFunctor.cpp.
References new_entities, nparts, moab::ProcConfig::proc_comm(), moab::ParallelComm::proc_config(), proc_partition_counts, moab::ProcConfig::proc_size(), moab::ProcessSet::SHARED_PROC_BYTES, and split_vertices.
Referenced by moab::MeshRefiner::refine().
{ // First, we must gather the number of entities in each // partition (for all partitions, not just those resident locally). int lnparts = this->proc_partition_counts.size(); std::vector< unsigned char > lpdefns; std::vector< int > lpsizes; lpdefns.resize( ProcessSet::SHARED_PROC_BYTES * lnparts ); lpsizes.resize( lnparts ); #ifdef MB_DEBUG std::cout << "**** Partition Counts ****\n"; #endif // MB_DEBUG int i = 0; std::map< ProcessSet, int >::iterator it; for( it = this->proc_partition_counts.begin(); it != this->proc_partition_counts.end(); ++it, ++i ) { for( int j = 0; j < ProcessSet::SHARED_PROC_BYTES; ++j ) lpdefns[ProcessSet::SHARED_PROC_BYTES * i + j] = it->first.data()[j]; lpsizes[i] = it->second; #ifdef MB_DEBUG std::cout << "Partition " << it->first << ": " << it->second << "\n"; #endif // MB_DEBUG } if( !comm ) return; std::vector< int > nparts; std::vector< int > dparts; // unsigned long prank = comm->proc_config().proc_rank(); unsigned long psize = comm->proc_config().proc_size(); nparts.resize( psize ); dparts.resize( psize + 1 ); MPI_Allgather( &lnparts, 1, MPI_INT, &nparts[0], 1, MPI_INT, comm->proc_config().proc_comm() ); // unsigned long ndefs = 0; for( unsigned long rank = 1; rank <= psize; ++rank ) { dparts[rank] = nparts[rank - 1] + dparts[rank - 1]; #ifdef MB_DEBUG std::cout << "Proc " << rank << ": " << nparts[rank - 1] << " partitions, offset: " << dparts[rank] << "\n"; #endif // MB_DEBUG } std::vector< unsigned char > part_defns; std::vector< int > part_sizes; part_defns.resize( ProcessSet::SHARED_PROC_BYTES * dparts[psize] ); part_sizes.resize( dparts[psize] ); MPI_Allgatherv( &lpsizes[0], lnparts, MPI_INT, &part_sizes[0], &nparts[0], &dparts[0], MPI_INT, comm->proc_config().proc_comm() ); for( unsigned long rank = 0; rank < psize; ++rank ) { nparts[rank] *= ProcessSet::SHARED_PROC_BYTES; dparts[rank] *= ProcessSet::SHARED_PROC_BYTES; } MPI_Allgatherv( &lpdefns[0], ProcessSet::SHARED_PROC_BYTES * lnparts, MPI_UNSIGNED_CHAR, &part_defns[0], &nparts[0], &dparts[0], MPI_UNSIGNED_CHAR, comm->proc_config().proc_comm() ); // Now that we have the number of new entities in every partition, we // can deterministically assign the same GID to the same entity even // when shared across processors because we have an ordering that is // identical on all processes -- the vertex splits. for( int j = 0; j < dparts[psize]; ++j ) { ProcessSet pset( &part_defns[ProcessSet::SHARED_PROC_BYTES * j] ); std::map< ProcessSet, int >::iterator mit = this->proc_partition_counts.find( pset ); if( mit != this->proc_partition_counts.end() ) { #ifdef MB_DEBUG std::cout << "Partition " << pset << ( mit->second == part_sizes[j] ? " matches" : " broken" ) << ".\n"; #endif // MB_DEBUG } else { this->proc_partition_counts[pset] = part_sizes[j]; } } std::map< ProcessSet, int > gids; std::map< ProcessSet, int >::iterator pcit; EntityHandle start_gid = 100; // FIXME: Get actual maximum GID across all processes and add 1 for( pcit = this->proc_partition_counts.begin(); pcit != this->proc_partition_counts.end(); ++pcit ) { gids[pcit->first] = start_gid; start_gid += pcit->second; #ifdef MB_DEBUG std::cout << "Partition " << pcit->first << ": " << pcit->second << " # [" << gids[pcit->first] << "]\n"; #endif // MB_DEBUG } std::vector< SplitVerticesBase* >::iterator vit; vit = this->split_vertices.begin(); ++vit; // Skip split_vertices[0] since it's empty. ++vit; // Skip split_vertices[1] since those entries already have global IDs... they exist in // the input mesh. for( /* skip */; vit != this->split_vertices.end(); ++vit ) { ( *vit )->assign_global_ids( gids ); } std::vector< EntitySource* >::iterator sit; for( sit = this->new_entities.begin(); sit != this->new_entities.end(); ++sit ) { if( *sit ) ( *sit )->assign_global_ids( gids ); } }
void moab::MeshOutputFunctor::assign_tags | ( | EntityHandle | vhandle, |
const void * | vtags | ||
) |
Definition at line 190 of file MeshOutputFunctor.cpp.
References moab::RefinerTagManager::get_number_of_vertex_tags(), moab::RefinerTagManager::get_output_vertex_tag(), mesh_out, tag_manager, and moab::Interface::tag_set_data().
Referenced by map_vertex(), and operator()().
{ if( !vhandle ) return; // Ignore bad vertices int num_tags = this->tag_manager->get_number_of_vertex_tags(); Tag tag_handle; int tag_offset; for( int i = 0; i < num_tags; ++i ) { this->tag_manager->get_output_vertex_tag( i, tag_handle, tag_offset ); this->mesh_out->tag_set_data( tag_handle, &vhandle, 1, vtags ); } }
void moab::MeshOutputFunctor::exchange_handles | ( | ParallelComm * | comm | ) |
Definition at line 188 of file MeshOutputFunctor.cpp.
{}
EntityHandle moab::MeshOutputFunctor::map_vertex | ( | EntityHandle | vhash, |
const double * | vcoords, | ||
const void * | vtags | ||
) | [virtual] |
Map an input vertex to the output mesh. This should return the same value when given the same input across multiple calls.
Implements moab::EntityRefinerOutputFunctor.
Definition at line 204 of file MeshOutputFunctor.cpp.
References assign_tags(), moab::SplitVerticesBase::find_or_create(), moab::RefinerTagManager::get_input_gids(), input_is_output, MB_SUCCESS, print_vert_crud(), proc_partition_counts, moab::RefinerTagManager::set_gid(), tag_manager, and vertex_map.
{ if( this->input_is_output ) { // Don't copy the original vertex! #ifdef MB_DEBUG this->print_vert_crud( vhash, 1, &vhash, vcoords, vtags ); #endif // MB_DEBUG return vhash; } EntityHandle vertex_handle; bool newly_created = this->vertex_map->find_or_create( &vhash, vcoords, vertex_handle, this->proc_partition_counts, false ); if( newly_created ) { std::vector< int > gid; this->assign_tags( vertex_handle, vtags ); if( this->tag_manager->get_input_gids( 1, &vhash, gid ) == MB_SUCCESS ) { this->tag_manager->set_gid( vertex_handle, gid[0] ); } } if( !vertex_handle ) { std::cerr << "Could not insert vertex into new mesh!\n"; } #ifdef MB_DEBUG this->print_vert_crud( vertex_handle, 1, &vhash, vcoords, vtags ); std::cout << "\nMap vert: " << vhash << " to: " << vertex_handle << "\n"; #endif // MB_DEBUG return vertex_handle; }
EntityHandle moab::MeshOutputFunctor::operator() | ( | int | nhash, |
EntityHandle * | hash, | ||
const double * | vcoords, | ||
const void * | vtags | ||
) | [virtual] |
Create a new vertex along a \(k\)-facet.
[in] | nhash | The number of corner vertices (i.e, \(k\) ). |
[in] | hash | An array of corner handles on the output mesh. |
[in] | vcoords | The location of the new point in world coordinates. |
[in] | vtags | Field values at the new point. |
A | handle for the new point on the output mesh. |
Implements moab::EntityRefinerOutputFunctor.
Definition at line 236 of file MeshOutputFunctor.cpp.
References assign_tags(), print_vert_crud(), proc_partition_counts, and split_vertices.
{ EntityHandle vertex_handle; if( nvhash < 4 ) { bool newly_created = this->split_vertices[nvhash]->find_or_create( vhash, vcoords, vertex_handle, this->proc_partition_counts, true ); if( newly_created ) { this->assign_tags( vertex_handle, vtags ); } if( !vertex_handle ) { std::cerr << "Could not insert mid-edge vertex!\n"; } #ifdef MB_DEBUG std::cout << "(-" << nvhash << "-) "; this->print_vert_crud( vertex_handle, nvhash, vhash, vcoords, vtags ); #endif // MB_DEBUG } else { vertex_handle = 0; std::cerr << "Not handling splits on faces with " << nvhash << " corners yet.\n"; } return vertex_handle; }
void moab::MeshOutputFunctor::operator() | ( | EntityHandle | vhash | ) | [virtual] |
Append an output vertex to the list of vertices defining a new entity.
[in] | vhash | A vertex of the output mesh. |
Implements moab::EntityRefinerOutputFunctor.
Definition at line 264 of file MeshOutputFunctor.cpp.
References elem_vert, and input_is_output.
{ #ifdef MB_DEBUG std::cout << h << " "; #endif // MB_DEBUG if( !this->input_is_output ) { // FIXME: Copy to output mesh } this->elem_vert.push_back( h ); }
void moab::MeshOutputFunctor::operator() | ( | EntityType | etyp | ) | [virtual] |
Create a new entity from all previously appended output vertices.
This resets the list of appended vertices.
[in] | etyp | The type of entity to create. |
Implements moab::EntityRefinerOutputFunctor.
Definition at line 276 of file MeshOutputFunctor.cpp.
References moab::RefinerTagManager::assign_element_tags(), elem_vert, new_entities, proc_partition_counts, and tag_manager.
{ EntityHandle elem_handle; int nconn = this->elem_vert.size(); bool newly_created = this->new_entities[nconn]->create_element( etyp, nconn, &this->elem_vert[0], elem_handle, this->proc_partition_counts ); if( newly_created ) { #ifdef MB_DEBUG std::cout << " *** "; #endif // MB_DEBUG // FIXME: Handle tag assignment for elements as well as vertices this->tag_manager->assign_element_tags( elem_handle ); } #ifdef MB_DEBUG std::cout << "---------> " << elem_handle << " ( " << etyp << " )\n\n"; #endif // MB_DEBUG this->elem_vert.clear(); }
void moab::MeshOutputFunctor::print_vert_crud | ( | EntityHandle | vout, |
int | nvhash, | ||
EntityHandle * | vhash, | ||
const double * | vcoords, | ||
const void * | vtags | ||
) |
Definition at line 55 of file MeshOutputFunctor.cpp.
Referenced by map_vertex(), and operator()().
{ std::cout << "+ {"; for( int i = 0; i < nvhash; ++i ) std::cout << " " << vhash[i]; std::cout << " } -> " << vout << " "; std::cout << "[ " << vcoords[0]; for( int i = 1; i < 6; ++i ) std::cout << ", " << vcoords[i]; std::cout << " ] "; #if 0 double* x = (double*)vtags; int* m = (int*)( (char*)vtags + 2 * sizeof( double ) ); std::cout << "< " << x[0] << ", " << x[1]; for ( int i = 0; i < 4; ++i ) std::cout << ", " << m[i]; #endif // 0 std::cout << " >\n"; // std::cout << "##############################\n"; // this->mesh_out->list_entities( 0, 1 ); // std::cout << "##############################\n"; }
Definition at line 77 of file MeshOutputFunctor.hpp.
Referenced by MeshOutputFunctor(), and moab::MeshRefiner::refine().
std::vector< EntityHandle > moab::MeshOutputFunctor::elem_vert |
Definition at line 75 of file MeshOutputFunctor.hpp.
Referenced by operator()().
Definition at line 71 of file MeshOutputFunctor.hpp.
Referenced by map_vertex(), MeshOutputFunctor(), and operator()().
Definition at line 69 of file MeshOutputFunctor.hpp.
Referenced by MeshOutputFunctor().
Definition at line 70 of file MeshOutputFunctor.hpp.
Referenced by assign_tags(), and MeshOutputFunctor().
std::vector< EntitySource* > moab::MeshOutputFunctor::new_entities |
Definition at line 74 of file MeshOutputFunctor.hpp.
Referenced by assign_global_ids(), MeshOutputFunctor(), operator()(), and ~MeshOutputFunctor().
std::map< ProcessSet, int > moab::MeshOutputFunctor::proc_partition_counts |
Definition at line 78 of file MeshOutputFunctor.hpp.
Referenced by assign_global_ids(), map_vertex(), and operator()().
std::vector< SplitVerticesBase* > moab::MeshOutputFunctor::split_vertices |
Definition at line 73 of file MeshOutputFunctor.hpp.
Referenced by assign_global_ids(), MeshOutputFunctor(), operator()(), and ~MeshOutputFunctor().
Definition at line 76 of file MeshOutputFunctor.hpp.
Referenced by assign_tags(), map_vertex(), MeshOutputFunctor(), and operator()().
Definition at line 72 of file MeshOutputFunctor.hpp.
Referenced by map_vertex(), MeshOutputFunctor(), and ~MeshOutputFunctor().