MOAB: Mesh Oriented datABase
(version 5.4.1)
|
Functions for converting to/from higher-order elements. More...
#include <HigherOrderFactory.hpp>
Functions for converting to/from higher-order elements.
Definition at line 38 of file HigherOrderFactory.hpp.
moab::HigherOrderFactory::HigherOrderFactory | ( | Core * | MB, |
Interface::HONodeAddedRemoved * | function_object | ||
) |
Definition at line 39 of file HigherOrderFactory.cpp.
References initialize_map().
: mMB( MB ), mHONodeAddedRemoved( function_object ) { initialize_map(); }
Definition at line 44 of file HigherOrderFactory.cpp.
{}
bool moab::HigherOrderFactory::add_center_node | ( | EntityType | type, |
EntityHandle * | element_conn, | ||
int | conn_size, | ||
EntityHandle | corner_node1, | ||
EntityHandle | corner_node2, | ||
EntityHandle | center_node | ||
) | [private] |
adds a center node to element between corner nodes, returns success
Definition at line 597 of file HigherOrderFactory.cpp.
References element_conn(), and mNodeMap.
{ int first_node = std::find( element_conn, element_conn + conn_size, corner_node1 ) - element_conn; int second_node = std::find( element_conn, element_conn + conn_size, corner_node2 ) - element_conn; if( first_node == conn_size || second_node == conn_size ) assert( "We should always find our nodes no matter what" == NULL ); int high_node_index = mNodeMap[this_type][first_node][second_node]; element_conn[high_node_index] = center_node; return true; }
ErrorCode moab::HigherOrderFactory::add_mid_edge_nodes | ( | ElementSequence * | seq | ) | [private] |
Definition at line 387 of file HigherOrderFactory.cpp.
References center_node_exist(), moab::CN::ConnMap::conn, moab::Core::create_vertex(), moab::SequenceManager::find(), moab::ElementSequence::get_connectivity_array(), MB_SUCCESS, moab::CN::mConnectivityMap, mHONodeAddedRemoved, mMB, moab::Interface::HONodeAddedRemoved::node_added(), moab::ElementSequence::nodes_per_element(), moab::CN::ConnMap::num_sub_elements, moab::Core::sequence_manager(), moab::EntitySequence::size(), moab::EntitySequence::start_handle(), moab::EntitySequence::type(), and moab::CN::VerticesPerEntity().
Referenced by convert_sequence().
{ // for each node, need to see if it was already created. EntityType this_type = seq->type(); SequenceManager* seq_manager = mMB->sequence_manager(); // offset by number of corner nodes int num_vertices = CN::VerticesPerEntity( this_type ); int num_edges = CN::mConnectivityMap[this_type][0].num_sub_elements; const CN::ConnMap& entity_edges = CN::mConnectivityMap[this_type][0]; EntityHandle* element = seq->get_connectivity_array(); EntityHandle curr_handle = seq->start_handle(); int nodes_per_element = seq->nodes_per_element(); EntityHandle* end_element = element + nodes_per_element * ( seq->size() ); EntityHandle tmp_edge_conn[2]; std::vector< EntityHandle > adjacent_entities( 32 ); double tmp_coords[3]; // iterate over the elements for( ; element < end_element; element += nodes_per_element ) { // for each edge in this entity for( int i = 0; i < num_edges; i++ ) { // a node was already assigned if( element[i + num_vertices] != 0 ) continue; tmp_edge_conn[0] = element[entity_edges.conn[i][0]]; tmp_edge_conn[1] = element[entity_edges.conn[i][1]]; EntityHandle already_made_node = center_node_exist( tmp_edge_conn[0], tmp_edge_conn[1], adjacent_entities ); if( already_made_node ) { element[i + num_vertices] = already_made_node; } // create a node else { EntitySequence* tmp_sequence = NULL; double sum_coords[3] = { 0, 0, 0 }; seq_manager->find( tmp_edge_conn[0], tmp_sequence ); static_cast< VertexSequence* >( tmp_sequence ) ->get_coordinates( tmp_edge_conn[0], tmp_coords[0], tmp_coords[1], tmp_coords[2] ); sum_coords[0] += tmp_coords[0]; sum_coords[1] += tmp_coords[1]; sum_coords[2] += tmp_coords[2]; seq_manager->find( tmp_edge_conn[1], tmp_sequence ); static_cast< VertexSequence* >( tmp_sequence ) ->get_coordinates( tmp_edge_conn[1], tmp_coords[0], tmp_coords[1], tmp_coords[2] ); sum_coords[0] = ( sum_coords[0] + tmp_coords[0] ) / 2; sum_coords[1] = ( sum_coords[1] + tmp_coords[1] ) / 2; sum_coords[2] = ( sum_coords[2] + tmp_coords[2] ) / 2; mMB->create_vertex( sum_coords, element[i + num_vertices] ); } if( mHONodeAddedRemoved ) mHONodeAddedRemoved->node_added( element[i + num_vertices], curr_handle ); } curr_handle++; } return MB_SUCCESS; }
ErrorCode moab::HigherOrderFactory::add_mid_face_nodes | ( | ElementSequence * | seq | ) | [private] |
Definition at line 310 of file HigherOrderFactory.cpp.
References center_node_exist(), moab::CN::ConnMap::conn, moab::Core::create_vertex(), moab::SequenceManager::find(), moab::ElementSequence::get_connectivity_array(), moab::ElementSequence::has_mid_edge_nodes(), MB_SUCCESS, moab::CN::mConnectivityMap, mHONodeAddedRemoved, mMB, moab::Interface::HONodeAddedRemoved::node_added(), moab::ElementSequence::nodes_per_element(), moab::CN::ConnMap::num_corners_per_sub_element, moab::CN::ConnMap::num_sub_elements, moab::Core::sequence_manager(), moab::EntitySequence::size(), moab::EntitySequence::start_handle(), moab::EntitySequence::type(), and moab::CN::VerticesPerEntity().
Referenced by convert_sequence().
{ EntityType this_type = seq->type(); SequenceManager* seq_manager = mMB->sequence_manager(); int num_vertices = CN::VerticesPerEntity( this_type ); int num_edges = CN::mConnectivityMap[this_type][0].num_sub_elements; num_edges = seq->has_mid_edge_nodes() ? num_edges : 0; int num_faces = CN::mConnectivityMap[this_type][1].num_sub_elements; const CN::ConnMap& entity_faces = CN::mConnectivityMap[this_type][1]; EntityHandle* element = seq->get_connectivity_array(); EntityHandle curr_handle = seq->start_handle(); int nodes_per_element = seq->nodes_per_element(); EntityHandle* end_element = element + nodes_per_element * ( seq->size() ); EntityHandle tmp_face_conn[4]; // max face nodes = 4 std::vector< EntityHandle > adjacent_entities( 4 ); double tmp_coords[3]; // iterate over the elements for( ; element < end_element; element += nodes_per_element ) { // for each edge in this entity for( int i = 0; i < num_faces; i++ ) { // a node was already assigned if( element[i + num_edges + num_vertices] != 0 ) continue; tmp_face_conn[0] = element[entity_faces.conn[i][0]]; tmp_face_conn[1] = element[entity_faces.conn[i][1]]; tmp_face_conn[2] = element[entity_faces.conn[i][2]]; if( entity_faces.num_corners_per_sub_element[i] == 4 ) tmp_face_conn[3] = element[entity_faces.conn[i][3]]; else tmp_face_conn[3] = 0; EntityHandle already_made_node = center_node_exist( tmp_face_conn, adjacent_entities ); if( already_made_node ) { element[i + num_edges + num_vertices] = already_made_node; } // create a node else { EntitySequence* tmp_sequence = NULL; double sum_coords[3] = { 0, 0, 0 }; int max_nodes = entity_faces.num_corners_per_sub_element[i]; for( int k = 0; k < max_nodes; k++ ) { seq_manager->find( tmp_face_conn[k], tmp_sequence ); static_cast< VertexSequence* >( tmp_sequence ) ->get_coordinates( tmp_face_conn[k], tmp_coords[0], tmp_coords[1], tmp_coords[2] ); sum_coords[0] += tmp_coords[0]; sum_coords[1] += tmp_coords[1]; sum_coords[2] += tmp_coords[2]; } sum_coords[0] /= max_nodes; sum_coords[1] /= max_nodes; sum_coords[2] /= max_nodes; mMB->create_vertex( sum_coords, element[i + num_edges + num_vertices] ); } if( mHONodeAddedRemoved ) mHONodeAddedRemoved->node_added( element[i + num_edges + num_vertices], curr_handle ); } curr_handle++; } return MB_SUCCESS; }
ErrorCode moab::HigherOrderFactory::add_mid_volume_nodes | ( | ElementSequence * | seq | ) | [private] |
Definition at line 261 of file HigherOrderFactory.cpp.
References moab::Core::create_vertex(), moab::SequenceManager::find(), moab::ElementSequence::get_connectivity_array(), moab::ElementSequence::has_mid_edge_nodes(), moab::ElementSequence::has_mid_face_nodes(), MB_SUCCESS, moab::CN::mConnectivityMap, mHONodeAddedRemoved, mMB, moab::Interface::HONodeAddedRemoved::node_added(), moab::ElementSequence::nodes_per_element(), moab::CN::ConnMap::num_sub_elements, moab::Core::sequence_manager(), moab::EntitySequence::size(), moab::EntitySequence::start_handle(), moab::EntitySequence::type(), and moab::CN::VerticesPerEntity().
Referenced by convert_sequence().
{ EntityType this_type = seq->type(); SequenceManager* seq_manager = mMB->sequence_manager(); // find out where in the connectivity list to add these new mid volume nodes int edge_factor = seq->has_mid_edge_nodes() ? 1 : 0; int face_factor = seq->has_mid_face_nodes() ? 1 : 0; // offset by number of higher order nodes on edges if they exist int num_corner_nodes = CN::VerticesPerEntity( this_type ); int new_node_index = num_corner_nodes; new_node_index += edge_factor * CN::mConnectivityMap[this_type][0].num_sub_elements; new_node_index += face_factor * CN::mConnectivityMap[this_type][1].num_sub_elements; EntityHandle* element = seq->get_connectivity_array(); EntityHandle curr_handle = seq->start_handle(); int nodes_per_element = seq->nodes_per_element(); EntityHandle* end_element = element + nodes_per_element * ( seq->size() ); // iterate over the elements for( ; element < end_element; element += nodes_per_element ) { // find the centroid of this element double tmp_coords[3], sum_coords[3] = { 0, 0, 0 }; EntitySequence* eseq = NULL; for( int i = 0; i < num_corner_nodes; i++ ) { seq_manager->find( element[i], eseq ); static_cast< VertexSequence* >( eseq )->get_coordinates( element[i], tmp_coords[0], tmp_coords[1], tmp_coords[2] ); sum_coords[0] += tmp_coords[0]; sum_coords[1] += tmp_coords[1]; sum_coords[2] += tmp_coords[2]; } sum_coords[0] /= num_corner_nodes; sum_coords[1] /= num_corner_nodes; sum_coords[2] /= num_corner_nodes; // create a new vertex at the centroid mMB->create_vertex( sum_coords, element[new_node_index] ); if( mHONodeAddedRemoved ) mHONodeAddedRemoved->node_added( element[new_node_index], curr_handle ); curr_handle++; } return MB_SUCCESS; }
EntityHandle moab::HigherOrderFactory::center_node_exist | ( | EntityHandle | corner1, |
EntityHandle | corner2, | ||
std::vector< EntityHandle > & | adj_entities | ||
) | [private] |
returns the handle of the first center node found between the two corner nodes. returns zero if none found entities that share those two corner nodes and have space allocated for mid-edge nodes are returned in a vector
Definition at line 457 of file HigherOrderFactory.cpp.
References moab::Core::a_entity_factory(), moab::AEntityFactory::create_vert_elem_adjacencies(), moab::AEntityFactory::get_adjacencies(), moab::Core::get_connectivity(), moab::CN::HasMidEdgeNodes(), MBENTITYSET, mMB, mNodeMap, moab::TYPE_FROM_HANDLE(), and moab::AEntityFactory::vert_elem_adjacencies().
Referenced by add_mid_edge_nodes(), and add_mid_face_nodes().
{ AEntityFactory* a_fact = mMB->a_entity_factory(); std::vector< EntityHandle > adj_corner1( 32 ); std::vector< EntityHandle > adj_corner2( 32 ); // create needed vertex adjacencies if( !a_fact->vert_elem_adjacencies() ) a_fact->create_vert_elem_adjacencies(); // vectors are returned sorted a_fact->get_adjacencies( corner1, adj_corner1 ); a_fact->get_adjacencies( corner2, adj_corner2 ); // these are the entities adjacent to both nodes adj_entities.clear(); std::set_intersection( adj_corner1.begin(), adj_corner1.end(), adj_corner2.begin(), adj_corner2.end(), std::back_inserter< std::vector< EntityHandle > >( adj_entities ) ); // iterate of the entities to find a mid node const EntityHandle* conn; int conn_size = 0; for( std::vector< EntityHandle >::iterator iter = adj_entities.begin(); iter != adj_entities.end(); ) { EntityType this_type = TYPE_FROM_HANDLE( *iter ); if( this_type == MBENTITYSET ) { ++iter; continue; } mMB->get_connectivity( *iter, conn, conn_size ); // if this entity has mid edge nodes if( CN::HasMidEdgeNodes( this_type, conn_size ) ) { // find out at which index the mid node should be at int first_node = std::find( conn, conn + conn_size, corner1 ) - conn; int second_node = std::find( conn, conn + conn_size, corner2 ) - conn; if( first_node == conn_size || second_node == conn_size ) assert( "We should always find our nodes no matter what" == NULL ); int high_node_index = mNodeMap[this_type][first_node][second_node]; if( conn[high_node_index] != 0 ) return conn[high_node_index]; ++iter; } else { iter = adj_entities.erase( iter ); } } return 0; }
EntityHandle moab::HigherOrderFactory::center_node_exist | ( | EntityHandle | corners[4], |
std::vector< EntityHandle > & | adj_entities | ||
) | [private] |
returns the handle of the first center node found between the 3-4 corner nodes. set the last node to zero if you want only 3 nodes returns zero if none found entities that share those corner nodes and have space allocated for mid face nodes are returned in a vector
Definition at line 511 of file HigherOrderFactory.cpp.
References moab::Core::a_entity_factory(), moab::CN::ConnMap::conn, moab::AEntityFactory::create_vert_elem_adjacencies(), moab::AEntityFactory::get_adjacencies(), moab::Core::get_connectivity(), moab::CN::HasMidEdgeNodes(), moab::CN::HasMidFaceNodes(), MBENTITYSET, moab::CN::mConnectivityMap, mMB, moab::CN::ConnMap::num_sub_elements, moab::CN::ConnMap::target_type, moab::TYPE_FROM_HANDLE(), moab::AEntityFactory::vert_elem_adjacencies(), and moab::CN::VerticesPerEntity().
{ AEntityFactory* a_fact = mMB->a_entity_factory(); std::vector< EntityHandle > adj_corner[4]; int num_nodes = corners[3] == 0 ? 3 : 4; int i = 0; // create needed vertex adjacencies if( !a_fact->vert_elem_adjacencies() ) a_fact->create_vert_elem_adjacencies(); // vectors are returned sorted for( i = 0; i < num_nodes; i++ ) a_fact->get_adjacencies( corners[i], adj_corner[i] ); // these are the entities adjacent to both nodes for( i = 1; i < num_nodes; i++ ) { adj_entities.clear(); std::set_intersection( adj_corner[i - 1].begin(), adj_corner[i - 1].end(), adj_corner[i].begin(), adj_corner[i].end(), std::back_inserter< std::vector< EntityHandle > >( adj_entities ) ); adj_corner[i].swap( adj_entities ); } adj_entities.swap( adj_corner[i - 1] ); // iterate of the entities to find a mid node const EntityHandle* conn; int conn_size = 0; for( std::vector< EntityHandle >::iterator iter = adj_entities.begin(); iter != adj_entities.end(); ) { EntityType this_type = TYPE_FROM_HANDLE( *iter ); if( this_type == MBENTITYSET ) { ++iter; continue; } const CN::ConnMap& entity_faces = CN::mConnectivityMap[this_type][1]; mMB->get_connectivity( *iter, conn, conn_size ); int offset = CN::VerticesPerEntity( this_type ); if( CN::HasMidEdgeNodes( this_type, conn_size ) ) offset += CN::mConnectivityMap[this_type][0].num_sub_elements; // if this entity has mid face nodes if( CN::HasMidFaceNodes( this_type, conn_size ) ) { int k; int indexes[4]; for( k = 0; k < num_nodes; k++ ) indexes[k] = std::find( conn, conn + conn_size, corners[k] ) - conn; // find out at which index the mid node should be at for( k = 0; k < entity_faces.num_sub_elements; k++ ) { if( CN::VerticesPerEntity( entity_faces.target_type[k] ) != num_nodes ) continue; int* pivot = std::find( indexes, indexes + num_nodes, entity_faces.conn[k][0] ); if( pivot == indexes + num_nodes ) continue; if( pivot != indexes ) std::rotate( indexes, pivot, indexes + num_nodes ); if( std::equal( indexes, indexes + num_nodes, entity_faces.conn[k] ) ) { if( conn[k + offset] != 0 ) return conn[k + offset]; k = entity_faces.num_sub_elements; } else { int temp = indexes[1]; indexes[1] = indexes[num_nodes - 1]; indexes[num_nodes - 1] = temp; if( std::equal( indexes, indexes + num_nodes, entity_faces.conn[k] ) ) { if( conn[k + offset] != 0 ) return conn[k + offset]; k = entity_faces.num_sub_elements; } } } ++iter; } else { iter = adj_entities.erase( iter ); } } return 0; }
ErrorCode moab::HigherOrderFactory::convert | ( | const EntityHandle | meshset, |
const bool | mid_edge_nodes, | ||
const bool | mid_face_nodes, | ||
const bool | mid_volume_nodes | ||
) |
Definition at line 71 of file HigherOrderFactory.cpp.
References entities, moab::Core::get_entities_by_handle(), and mMB.
Referenced by moab::Core::convert_entities(), and moab::Tqdcfr::read_block().
{ Range entities; mMB->get_entities_by_handle( meshset, entities, true ); return convert( entities, mid_edge_nodes, mid_face_nodes, mid_volume_nodes ); }
ErrorCode moab::HigherOrderFactory::convert | ( | const Range & | entities, |
const bool | mid_edge_nodes, | ||
const bool | mid_face_nodes, | ||
const bool | mid_volume_nodes | ||
) |
Definition at line 81 of file HigherOrderFactory.cpp.
References moab::Range::const_pair_begin(), moab::Range::const_pair_end(), convert_sequence(), moab::EntitySequence::end_handle(), ErrorCode, moab::SequenceManager::find(), moab::ElementSequence::get_connectivity_array(), MB_NOT_IMPLEMENTED, MB_SUCCESS, MB_TYPE_OUT_OF_RANGE, MBENTITYSET, MBVERTEX, mMB, moab::Core::sequence_manager(), and moab::EntitySequence::type().
{ // TODO -- add some more code to prevent from splitting of entity sequences when we don't need // to. Say we have all hex8's in our mesh and 3 falses are passed in. In the end, no conversion // will happen, but the sequences could still be split up. // find out what entity sequences we need to convert // and where, if necessary, to split them SequenceManager* seq_manager = mMB->sequence_manager(); Range::const_pair_iterator p_iter; for( p_iter = entities.const_pair_begin(); p_iter != entities.const_pair_end(); ++p_iter ) { EntityHandle h = p_iter->first; while( h <= p_iter->second ) { EntitySequence* seq; ErrorCode rval = seq_manager->find( h, seq ); if( MB_SUCCESS != rval ) return rval; if( seq->type() == MBVERTEX || seq->type() >= MBENTITYSET ) return MB_TYPE_OUT_OF_RANGE; // make sequence is not structured mesh ElementSequence* elemseq = static_cast< ElementSequence* >( seq ); if( NULL == elemseq->get_connectivity_array() ) return MB_NOT_IMPLEMENTED; EntityHandle last = p_iter->second; if( last > seq->end_handle() ) last = seq->end_handle(); rval = convert_sequence( elemseq, h, last, mid_edge_nodes, mid_face_nodes, mid_volume_nodes ); if( MB_SUCCESS != rval ) return rval; h = last + 1; } } return MB_SUCCESS; }
ErrorCode moab::HigherOrderFactory::convert_sequence | ( | ElementSequence * | sequence, |
EntityHandle | sequence_subset_start, | ||
EntityHandle | sequence_subset_end, | ||
bool | mid_edge_nodes, | ||
bool | mid_face_nodes, | ||
bool | mid_volume_nodes | ||
) | [private] |
Definition at line 127 of file HigherOrderFactory.cpp.
References add_mid_edge_nodes(), add_mid_face_nodes(), add_mid_volume_nodes(), moab::Range::begin(), copy_corner_nodes(), copy_mid_edge_nodes(), copy_mid_face_nodes(), copy_mid_volume_nodes(), moab::EntitySequence::data(), moab::Core::delete_entities(), moab::CN::Dimension(), moab::Range::end(), ErrorCode, moab::Core::get_entities_by_type_and_tag(), moab::ElementSequence::has_mid_edge_nodes(), moab::ElementSequence::has_mid_face_nodes(), moab::ElementSequence::has_mid_volume_nodes(), MB_SUCCESS, MB_TAG_BIT, MB_TAG_CREAT, MB_TYPE_BIT, MB_TYPE_OUT_OF_RANGE, MBEDGE, MBHEX, MBKNIFE, MBPRISM, MBPYRAMID, MBQUAD, MBTET, MBTRI, MBVERTEX, mHONodeAddedRemoved, mMB, moab::Interface::HONodeAddedRemoved::node_removed(), moab::ElementSequence::nodes_per_element(), moab::CN::NumSubEntities(), remove_mid_edge_nodes(), remove_mid_face_nodes(), remove_mid_volume_nodes(), moab::SequenceManager::replace_subsequence(), moab::Core::sequence_manager(), moab::Core::tag_delete(), moab::Core::tag_get_data(), moab::Core::tag_get_handle(), moab::EntitySequence::type(), moab::CN::VerticesPerEntity(), zero_mid_edge_nodes(), zero_mid_face_nodes(), and zero_mid_volume_nodes().
Referenced by convert().
{ ErrorCode status = MB_SUCCESS; // lets make sure parameters are ok before we continue switch( seq->type() ) { default: return MB_TYPE_OUT_OF_RANGE; case MBEDGE: mid_face_nodes = false; mid_volume_nodes = false; break; case MBTRI: case MBQUAD: mid_volume_nodes = false; break; case MBTET: case MBHEX: case MBPRISM: case MBPYRAMID: case MBKNIFE: break; } // calculate number of nodes in target configuration unsigned nodes_per_elem = CN::VerticesPerEntity( seq->type() ); if( mid_edge_nodes ) nodes_per_elem += ( seq->type() == MBEDGE ) ? 1 : CN::NumSubEntities( seq->type(), 1 ); if( mid_face_nodes ) nodes_per_elem += ( CN::Dimension( seq->type() ) == 2 ) ? 1 : CN::NumSubEntities( seq->type(), 2 ); if( mid_volume_nodes ) nodes_per_elem += 1; if( nodes_per_elem == seq->nodes_per_element() ) return MB_SUCCESS; Tag deletable_nodes; status = mMB->tag_get_handle( 0, 1, MB_TYPE_BIT, deletable_nodes, MB_TAG_CREAT | MB_TAG_BIT ); if( MB_SUCCESS != status ) return status; UnstructuredElemSeq* new_seq = new UnstructuredElemSeq( start, end - start + 1, nodes_per_elem, end - start + 1 ); copy_corner_nodes( seq, new_seq ); if( seq->has_mid_edge_nodes() && mid_edge_nodes ) status = copy_mid_edge_nodes( seq, new_seq ); else if( seq->has_mid_edge_nodes() && !mid_edge_nodes ) status = remove_mid_edge_nodes( seq, start, end, deletable_nodes ); else if( !seq->has_mid_edge_nodes() && mid_edge_nodes ) status = zero_mid_edge_nodes( new_seq ); if( MB_SUCCESS != status ) return status; if( seq->has_mid_face_nodes() && mid_face_nodes ) status = copy_mid_face_nodes( seq, new_seq ); else if( seq->has_mid_face_nodes() && !mid_face_nodes ) status = remove_mid_face_nodes( seq, start, end, deletable_nodes ); else if( !seq->has_mid_face_nodes() && mid_face_nodes ) status = zero_mid_face_nodes( new_seq ); if( MB_SUCCESS != status ) { mMB->tag_delete( deletable_nodes ); return status; } if( seq->has_mid_volume_nodes() && mid_volume_nodes ) status = copy_mid_volume_nodes( seq, new_seq ); else if( seq->has_mid_volume_nodes() && !mid_volume_nodes ) status = remove_mid_volume_nodes( seq, start, end, deletable_nodes ); else if( !seq->has_mid_volume_nodes() && mid_volume_nodes ) status = zero_mid_volume_nodes( new_seq ); if( MB_SUCCESS != status ) { mMB->tag_delete( deletable_nodes ); return status; } // gather nodes that were marked Range nodes; mMB->get_entities_by_type_and_tag( 0, MBVERTEX, &deletable_nodes, NULL, 1, nodes ); // EntityHandle low_meshset; // int dum; // low_meshset = CREATE_HANDLE(MBENTITYSET, 0, dum); for( Range::iterator iter = nodes.begin(); iter != nodes.end(); ++iter ) { unsigned char marked = 0; mMB->tag_get_data( deletable_nodes, &( *iter ), 1, &marked ); if( marked ) { // we can delete it if( mHONodeAddedRemoved ) mHONodeAddedRemoved->node_removed( *iter ); mMB->delete_entities( &( *iter ), 1 ); } } const bool create_midedge = !seq->has_mid_edge_nodes() && mid_edge_nodes; const bool create_midface = !seq->has_mid_face_nodes() && mid_face_nodes; const bool create_midvolm = !seq->has_mid_volume_nodes() && mid_volume_nodes; mMB->tag_delete( deletable_nodes ); status = mMB->sequence_manager()->replace_subsequence( new_seq ); if( MB_SUCCESS != status ) { SequenceData* data = new_seq->data(); delete new_seq; delete data; return status; } if( create_midedge ) { status = add_mid_edge_nodes( new_seq ); if( MB_SUCCESS != status ) return status; } if( create_midface ) { status = add_mid_face_nodes( new_seq ); if( MB_SUCCESS != status ) return status; } if( create_midvolm ) { status = add_mid_volume_nodes( new_seq ); if( MB_SUCCESS != status ) return status; } return status; }
ErrorCode moab::HigherOrderFactory::copy_corner_nodes | ( | ElementSequence * | src, |
ElementSequence * | dst | ||
) | [private] |
Definition at line 613 of file HigherOrderFactory.cpp.
References copy_nodes(), moab::EntitySequence::type(), and moab::CN::VerticesPerEntity().
Referenced by convert_sequence().
{ unsigned num_corners = CN::VerticesPerEntity( src->type() ); return copy_nodes( src, dst, num_corners, 0, 0 ); }
ErrorCode moab::HigherOrderFactory::copy_mid_edge_nodes | ( | ElementSequence * | src, |
ElementSequence * | dst | ||
) | [private] |
Definition at line 619 of file HigherOrderFactory.cpp.
References copy_nodes(), moab::ElementSequence::has_mid_edge_nodes(), MBEDGE, moab::CN::NumSubEntities(), moab::EntitySequence::type(), and moab::CN::VerticesPerEntity().
Referenced by convert_sequence().
{ if( !src->has_mid_edge_nodes() || !dst->has_mid_edge_nodes() ) return MB_FAILURE; unsigned num_corners = CN::VerticesPerEntity( src->type() ); unsigned num_edges = ( src->type() == MBEDGE ) ? 1 : CN::NumSubEntities( src->type(), 1 ); return copy_nodes( src, dst, num_edges, num_corners, num_corners ); }
ErrorCode moab::HigherOrderFactory::copy_mid_face_nodes | ( | ElementSequence * | src, |
ElementSequence * | dst | ||
) | [private] |
Definition at line 637 of file HigherOrderFactory.cpp.
References copy_nodes(), moab::CN::Dimension(), moab::ElementSequence::has_mid_edge_nodes(), moab::ElementSequence::has_mid_face_nodes(), moab::CN::NumSubEntities(), moab::EntitySequence::type(), and moab::CN::VerticesPerEntity().
Referenced by convert_sequence().
{ if( !src->has_mid_face_nodes() || !dst->has_mid_face_nodes() ) return MB_FAILURE; unsigned src_offset = CN::VerticesPerEntity( src->type() ); unsigned dst_offset = src_offset; if( src->has_mid_edge_nodes() ) src_offset += CN::NumSubEntities( src->type(), 1 ); if( dst->has_mid_edge_nodes() ) dst_offset += CN::NumSubEntities( dst->type(), 1 ); unsigned num_faces = ( CN::Dimension( src->type() ) == 2 ) ? 1 : CN::NumSubEntities( src->type(), 2 ); return copy_nodes( src, dst, num_faces, src_offset, dst_offset ); }
ErrorCode moab::HigherOrderFactory::copy_mid_volume_nodes | ( | ElementSequence * | src, |
ElementSequence * | dst | ||
) | [private] |
Definition at line 659 of file HigherOrderFactory.cpp.
References copy_nodes(), moab::ElementSequence::has_mid_edge_nodes(), moab::ElementSequence::has_mid_face_nodes(), moab::ElementSequence::has_mid_volume_nodes(), moab::CN::NumSubEntities(), moab::EntitySequence::type(), and moab::CN::VerticesPerEntity().
Referenced by convert_sequence().
{ if( !src->has_mid_volume_nodes() || !dst->has_mid_volume_nodes() ) return MB_FAILURE; unsigned src_offset = CN::VerticesPerEntity( src->type() ); unsigned dst_offset = src_offset; if( src->has_mid_edge_nodes() ) src_offset += CN::NumSubEntities( src->type(), 1 ); if( dst->has_mid_edge_nodes() ) dst_offset += CN::NumSubEntities( dst->type(), 1 ); if( src->has_mid_face_nodes() ) src_offset += CN::NumSubEntities( src->type(), 2 ); if( dst->has_mid_face_nodes() ) dst_offset += CN::NumSubEntities( dst->type(), 2 ); return copy_nodes( src, dst, 1, src_offset, dst_offset ); }
ErrorCode moab::HigherOrderFactory::copy_nodes | ( | ElementSequence * | src, |
ElementSequence * | dst, | ||
unsigned | nodes_per_elem_to_copy, | ||
unsigned | src_conn_offset, | ||
unsigned | dst_conn_offset | ||
) | [private] |
Definition at line 682 of file HigherOrderFactory.cpp.
References moab::EntitySequence::end_handle(), moab::ElementSequence::get_connectivity_array(), MB_SUCCESS, moab::ElementSequence::nodes_per_element(), moab::EntitySequence::size(), moab::EntitySequence::start_handle(), and moab::EntitySequence::type().
Referenced by copy_corner_nodes(), copy_mid_edge_nodes(), copy_mid_face_nodes(), and copy_mid_volume_nodes().
{ if( src->type() != dst->type() ) return MB_FAILURE; unsigned src_stride = src->nodes_per_element(); unsigned dst_stride = dst->nodes_per_element(); EntityHandle* src_conn = src->get_connectivity_array(); EntityHandle* dst_conn = dst->get_connectivity_array(); if( !src_conn || !dst_conn ) return MB_FAILURE; if( dst->start_handle() < src->start_handle() || dst->end_handle() > src->end_handle() ) return MB_FAILURE; src_conn += ( dst->start_handle() - src->start_handle() ) * src_stride; EntityID count = dst->size(); for( EntityID i = 0; i < count; ++i ) { for( unsigned j = 0; j < nodes_per_elem; ++j ) dst_conn[j + dst_offset] = src_conn[j + src_offset]; src_conn += src_stride; dst_conn += dst_stride; } return MB_SUCCESS; }
void moab::HigherOrderFactory::initialize_map | ( | ) | [private] |
Definition at line 48 of file HigherOrderFactory.cpp.
References moab::CN::ConnMap::conn, MBMAXTYPE, MBVERTEX, moab::CN::mConnectivityMap, mNodeMap, moab::CN::ConnMap::num_sub_elements, and moab::CN::VerticesPerEntity().
Referenced by HigherOrderFactory().
{ // if(mMapInitialized) // return; for( EntityType i = MBVERTEX; i < MBMAXTYPE; i++ ) { const CN::ConnMap& canon_map = CN::mConnectivityMap[i][0]; unsigned char( &this_map )[8][8] = mNodeMap[i]; int num_node = CN::VerticesPerEntity( i ); for( int j = 0; j < canon_map.num_sub_elements; j++ ) { unsigned char x = canon_map.conn[j][0]; unsigned char y = canon_map.conn[j][1]; this_map[x][y] = num_node; this_map[y][x] = num_node; num_node++; } } // mMapInitialized = true; }
ErrorCode moab::HigherOrderFactory::remove_ho_nodes | ( | ElementSequence * | seq, |
EntityHandle | start, | ||
EntityHandle | end, | ||
int | nodes_per_elem, | ||
int | elem_conn_offset, | ||
Tag | deletable_nodes | ||
) | [private] |
MOAB, a Mesh-Oriented datABase, is a software component for creating, storing and accessing finite element mesh data.
Copyright 2004 Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software.
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
Definition at line 794 of file HigherOrderFactory.cpp.
References moab::EntitySequence::end_handle(), moab::ElementSequence::get_connectivity_array(), MB_ENTITY_NOT_FOUND, MB_NOT_IMPLEMENTED, MB_SUCCESS, mMB, moab::ElementSequence::nodes_per_element(), moab::EntitySequence::start_handle(), tag_for_deletion(), and moab::Core::tag_set_data().
Referenced by remove_mid_edge_nodes(), remove_mid_face_nodes(), and remove_mid_volume_nodes().
{ if( start < seq->start_handle() || end > seq->end_handle() ) return MB_ENTITY_NOT_FOUND; EntityHandle* array = seq->get_connectivity_array(); if( !array ) return MB_NOT_IMPLEMENTED; std::set< EntityHandle > nodes_processed; for( EntityHandle i = start; i <= end; ++i ) { // for each element for( int j = 0; j < nodes_per_elem; ++j ) { // for each HO node to remove const EntityID elem = ( i - seq->start_handle() ); // element index const int conn_idx = j + elem_conn_offset; const EntityID index = elem * seq->nodes_per_element() + conn_idx; if( array[index] && nodes_processed.insert( array[index] ).second ) { if( tag_for_deletion( i, conn_idx, seq ) ) { unsigned char bit = 0x1; mMB->tag_set_data( deletable_nodes, &( array[index] ), 1, &bit ); } } } } return MB_SUCCESS; }
ErrorCode moab::HigherOrderFactory::remove_mid_edge_nodes | ( | ElementSequence * | seq, |
EntityHandle | start, | ||
EntityHandle | stop, | ||
Tag | deletable_ndoes | ||
) | [private] |
Definition at line 727 of file HigherOrderFactory.cpp.
References MBEDGE, moab::CN::NumSubEntities(), remove_ho_nodes(), moab::EntitySequence::type(), and moab::CN::VerticesPerEntity().
Referenced by convert_sequence().
{ int count; int offset; if( seq->type() == MBEDGE ) { count = 1; offset = 2; } else { count = CN::NumSubEntities( seq->type(), 1 ); offset = CN::VerticesPerEntity( seq->type() ); } return remove_ho_nodes( seq, start, end, count, offset, deletable_nodes ); }
ErrorCode moab::HigherOrderFactory::remove_mid_face_nodes | ( | ElementSequence * | seq, |
EntityHandle | start, | ||
EntityHandle | stop, | ||
Tag | deletable_ndoes | ||
) | [private] |
Definition at line 748 of file HigherOrderFactory.cpp.
References moab::CN::Dimension(), moab::ElementSequence::has_mid_edge_nodes(), moab::CN::NumSubEntities(), remove_ho_nodes(), moab::EntitySequence::type(), and moab::CN::VerticesPerEntity().
Referenced by convert_sequence().
{ int count; if( CN::Dimension( seq->type() ) == 2 ) count = 1; else count = CN::NumSubEntities( seq->type(), 2 ); int offset = CN::VerticesPerEntity( seq->type() ); if( seq->has_mid_edge_nodes() ) offset += CN::NumSubEntities( seq->type(), 1 ); return remove_ho_nodes( seq, start, end, count, offset, deletable_nodes ); }
ErrorCode moab::HigherOrderFactory::remove_mid_volume_nodes | ( | ElementSequence * | seq, |
EntityHandle | start, | ||
EntityHandle | stop, | ||
Tag | deletable_ndoes | ||
) | [private] |
Definition at line 764 of file HigherOrderFactory.cpp.
References moab::ElementSequence::has_mid_edge_nodes(), moab::ElementSequence::has_mid_face_nodes(), moab::CN::NumSubEntities(), remove_ho_nodes(), moab::EntitySequence::type(), and moab::CN::VerticesPerEntity().
Referenced by convert_sequence().
{ int offset = CN::VerticesPerEntity( seq->type() ); if( seq->has_mid_edge_nodes() ) offset += CN::NumSubEntities( seq->type(), 1 ); if( seq->has_mid_face_nodes() ) offset += CN::NumSubEntities( seq->type(), 2 ); return remove_ho_nodes( seq, start, end, 1, offset, deletable_nodes ); }
bool moab::HigherOrderFactory::tag_for_deletion | ( | EntityHandle | element_with_node, |
int | node_index_in_elem_connectivity, | ||
ElementSequence * | sequence | ||
) | [private] |
Definition at line 827 of file HigherOrderFactory.cpp.
References moab::Core::a_entity_factory(), moab::CREATE_HANDLE(), moab::Core::dimension_from_handle(), moab::dum, moab::EntitySequence::end_handle(), ErrorCode, moab::AEntityFactory::get_adjacencies(), moab::Core::get_connectivity(), moab::CN::HONodeParent(), MB_CHK_ERR, MBENTITYSET, mMB, moab::ElementSequence::nodes_per_element(), moab::Core::side_element(), moab::side_number(), moab::EntitySequence::start_handle(), and moab::EntitySequence::type().
Referenced by remove_ho_nodes().
{ // get type of this sequence EntityType this_type = seq->type(); // get dimension of 'parent' element int this_dimension = mMB->dimension_from_handle( parent_handle ); // tells us if higher order node is on int dimension, side_number; CN::HONodeParent( this_type, seq->nodes_per_element(), conn_index, dimension, side_number ); // it MUST be a higher-order node bool delete_node = false; assert( dimension != -1 ); assert( side_number != -1 ); // could be a mid-volume/face/edge node on a hex/face/edge respectively // if so...delete it bc/ no one else owns it too std::vector< EntityHandle > connectivity; if( dimension == this_dimension && side_number == 0 ) delete_node = true; else // the node could also be on a lower order entity of 'tmp_entity' { // get 'side' of 'parent_handle' that node is on EntityHandle target_entity = 0; mMB->side_element( parent_handle, dimension, side_number, target_entity ); if( target_entity ) { AEntityFactory* a_fact = mMB->a_entity_factory(); EntityHandle low_meshset; int dum; low_meshset = CREATE_HANDLE( MBENTITYSET, 0, dum ); // just get corner nodes of target_entity connectivity.clear(); ErrorCode rval; rval = mMB->get_connectivity( &( target_entity ), 1, connectivity, true );MB_CHK_ERR( rval ); // for each node, get all common adjacencies of nodes in 'parent_handle' std::vector< EntityHandle > adj_list_1, adj_list_2, adj_entities; a_fact->get_adjacencies( connectivity[0], adj_list_1 ); // remove meshsets adj_list_1.erase( std::remove_if( adj_list_1.begin(), adj_list_1.end(), std::bind( std::greater< EntityHandle >(), std::placeholders::_1, low_meshset ) ), adj_list_1.end() ); // std::bind2nd(std::greater<EntityHandle>(),low_meshset)), adj_list_1.end()); // https://stackoverflow.com/questions/32739018/a-replacement-for-stdbind2nd size_t i; for( i = 1; i < connectivity.size(); i++ ) { adj_list_2.clear(); a_fact->get_adjacencies( connectivity[i], adj_list_2 ); // remove meshsets adj_list_2.erase( std::remove_if( adj_list_2.begin(), adj_list_2.end(), std::bind( std::greater< EntityHandle >(), std::placeholders::_1, low_meshset ) ), adj_list_2.end() ); // std::bind2nd(std::greater<EntityHandle>(),low_meshset)), adj_list_2.end()); // https://stackoverflow.com/questions/32739018/a-replacement-for-stdbind2nd // intersect the 2 lists adj_entities.clear(); std::set_intersection( adj_list_1.begin(), adj_list_1.end(), adj_list_2.begin(), adj_list_2.end(), std::back_inserter< std::vector< EntityHandle > >( adj_entities ) ); adj_list_1.clear(); adj_list_1 = adj_entities; } assert( adj_entities.size() ); // has to have at least one adjacency // see if node is in other elements, not in this sequence...if so, delete it for( i = 0; i < adj_entities.size(); i++ ) { if( adj_entities[i] >= seq->start_handle() && adj_entities[i] <= seq->end_handle() ) { delete_node = false; break; } else delete_node = true; } } else // there is no lower order entity that also contains node delete_node = true; } return delete_node; }
ErrorCode moab::HigherOrderFactory::zero_mid_edge_nodes | ( | ElementSequence * | dst | ) | [private] |
Definition at line 628 of file HigherOrderFactory.cpp.
References moab::ElementSequence::has_mid_edge_nodes(), MBEDGE, moab::CN::NumSubEntities(), moab::EntitySequence::type(), moab::CN::VerticesPerEntity(), and zero_nodes().
Referenced by convert_sequence().
{ if( !dst->has_mid_edge_nodes() ) return MB_FAILURE; unsigned num_corners = CN::VerticesPerEntity( dst->type() ); unsigned num_edges = ( dst->type() == MBEDGE ) ? 1 : CN::NumSubEntities( dst->type(), 1 ); return zero_nodes( dst, num_edges, num_corners ); }
ErrorCode moab::HigherOrderFactory::zero_mid_face_nodes | ( | ElementSequence * | dst | ) | [private] |
Definition at line 649 of file HigherOrderFactory.cpp.
References moab::CN::Dimension(), moab::ElementSequence::has_mid_edge_nodes(), moab::ElementSequence::has_mid_face_nodes(), moab::CN::NumSubEntities(), moab::EntitySequence::type(), moab::CN::VerticesPerEntity(), and zero_nodes().
Referenced by convert_sequence().
{ if( !dst->has_mid_face_nodes() ) return MB_FAILURE; unsigned dst_offset = CN::VerticesPerEntity( dst->type() ); if( dst->has_mid_edge_nodes() ) dst_offset += CN::NumSubEntities( dst->type(), 1 ); unsigned num_faces = ( CN::Dimension( dst->type() ) == 2 ) ? 1 : CN::NumSubEntities( dst->type(), 2 ); return zero_nodes( dst, num_faces, dst_offset ); }
ErrorCode moab::HigherOrderFactory::zero_mid_volume_nodes | ( | ElementSequence * | dst | ) | [private] |
Definition at line 672 of file HigherOrderFactory.cpp.
References moab::ElementSequence::has_mid_edge_nodes(), moab::ElementSequence::has_mid_face_nodes(), moab::ElementSequence::has_mid_volume_nodes(), moab::CN::NumSubEntities(), moab::EntitySequence::type(), moab::CN::VerticesPerEntity(), and zero_nodes().
Referenced by convert_sequence().
{ if( !dst->has_mid_volume_nodes() ) return MB_FAILURE; unsigned dst_offset = CN::VerticesPerEntity( dst->type() ); if( dst->has_mid_edge_nodes() ) dst_offset += CN::NumSubEntities( dst->type(), 1 ); if( dst->has_mid_face_nodes() ) dst_offset += CN::NumSubEntities( dst->type(), 2 ); return zero_nodes( dst, 1, dst_offset ); }
ErrorCode moab::HigherOrderFactory::zero_nodes | ( | ElementSequence * | dst, |
unsigned | nodes_per_elem_to_zero, | ||
unsigned | dst_conn_offset | ||
) | [private] |
Definition at line 711 of file HigherOrderFactory.cpp.
References moab::ElementSequence::get_connectivity_array(), MB_SUCCESS, moab::ElementSequence::nodes_per_element(), and moab::EntitySequence::size().
Referenced by zero_mid_edge_nodes(), zero_mid_face_nodes(), and zero_mid_volume_nodes().
{ unsigned dst_stride = dst->nodes_per_element(); EntityHandle* dst_conn = dst->get_connectivity_array(); if( !dst_conn ) return MB_FAILURE; EntityID count = dst->size(); for( EntityID i = 0; i < count; ++i ) { std::fill( dst_conn + offset, dst_conn + offset + nodes_per_elem, 0 ); dst_conn += dst_stride; } return MB_SUCCESS; }
Definition at line 61 of file HigherOrderFactory.hpp.
Referenced by add_mid_edge_nodes(), add_mid_face_nodes(), add_mid_volume_nodes(), and convert_sequence().
Core* moab::HigherOrderFactory::mMB [private] |
Definition at line 60 of file HigherOrderFactory.hpp.
Referenced by add_mid_edge_nodes(), add_mid_face_nodes(), add_mid_volume_nodes(), center_node_exist(), convert(), convert_sequence(), remove_ho_nodes(), and tag_for_deletion().
unsigned char moab::HigherOrderFactory::mNodeMap[MBMAXTYPE][8][8] |
Definition at line 54 of file HigherOrderFactory.hpp.
Referenced by add_center_node(), center_node_exist(), and initialize_map().