Entity & declare_element_edge( BulkData & mesh , const stk_classic::mesh::EntityId global_edge_id , Entity & elem , const unsigned local_edge_id , Part * part ) { verify_declare_element_edge(mesh, elem, local_edge_id); const CellTopologyData * const elem_top = get_cell_topology( elem ).getCellTopologyData(); ThrowErrorMsgIf( elem_top == NULL, "Element[" << elem.identifier() << "] has no defined topology"); const CellTopologyData * const edge_top = elem_top->edge[ local_edge_id ].topology; ThrowErrorMsgIf( edge_top == NULL, "Element[" << elem.identifier() << "], local_edge_id = " << local_edge_id << ", edge has no defined topology" ); PartVector empty_parts ; Entity & edge = mesh.declare_entity( edge_top->dimension , global_edge_id, empty_parts ); return declare_element_edge( elem, edge, local_edge_id, part); }
const CellTopologyData * get_subcell_nodes(const Entity & entity , EntityRank subcell_rank , unsigned subcell_identifier , EntityVector & subcell_nodes) { subcell_nodes.clear(); // get cell topology const CellTopologyData* celltopology = get_cell_topology(entity).getCellTopologyData(); //error checking { //no celltopology defined if (celltopology == NULL) { return NULL; } // valid ranks fall within the dimension of the cell topology const bool bad_rank = subcell_rank >= celltopology->dimension; ThrowInvalidArgMsgIf( bad_rank, "subcell_rank is >= celltopology dimension\n"); // subcell_identifier must be less than the subcell count const bool bad_id = subcell_identifier >= celltopology->subcell_count[subcell_rank]; ThrowInvalidArgMsgIf( bad_id, "subcell_id is >= subcell_count\n"); } // Get the cell topology of the subcell const CellTopologyData * subcell_topology = celltopology->subcell[subcell_rank][subcell_identifier].topology; const int num_nodes_in_subcell = subcell_topology->node_count; // For the subcell, get it's local nodes ids const unsigned* subcell_node_local_ids = celltopology->subcell[subcell_rank][subcell_identifier].node; FEMMetaData & fem_meta = FEMMetaData::get(entity); const EntityRank node_rank = fem_meta.node_rank(); PairIterRelation node_relations = entity.relations(node_rank); subcell_nodes.reserve(num_nodes_in_subcell); for (int i = 0; i < num_nodes_in_subcell; ++i ) { subcell_nodes.push_back( node_relations[subcell_node_local_ids[i]].entity() ); } return subcell_topology; }
bool element_side_polarity( const Entity & elem , const Entity & side , int local_side_id ) { // 09/14/10: TODO: tscoffe: Will this work in 1D? FEMMetaData &fem_meta = FEMMetaData::get(elem); const bool is_side = side.entity_rank() != fem_meta.edge_rank(); const CellTopologyData * const elem_top = get_cell_topology( elem ).getCellTopologyData(); const unsigned side_count = ! elem_top ? 0 : ( is_side ? elem_top->side_count : elem_top->edge_count ); ThrowErrorMsgIf( elem_top == NULL, "For Element[" << elem.identifier() << "], element has no defined topology"); ThrowErrorMsgIf( local_side_id < 0 || static_cast<int>(side_count) <= local_side_id, "For Element[" << elem.identifier() << "], " << "side: " << print_entity_key(side) << ", " << "local_side_id = " << local_side_id << " ; unsupported local_side_id"); const CellTopologyData * const side_top = is_side ? elem_top->side[ local_side_id ].topology : elem_top->edge[ local_side_id ].topology ; const unsigned * const side_map = is_side ? elem_top->side[ local_side_id ].node : elem_top->edge[ local_side_id ].node ; const PairIterRelation elem_nodes = elem.relations( FEMMetaData::NODE_RANK ); const PairIterRelation side_nodes = side.relations( FEMMetaData::NODE_RANK ); const unsigned n = side_top->node_count; bool good = false ; for ( unsigned i = 0 ; !good && i < n ; ++i ) { good = true; for ( unsigned j = 0; good && j < n ; ++j ) { good = side_nodes[(j+i)%n].entity() == elem_nodes[ side_map[j] ].entity(); } } return good ; }
Entity & declare_element_edge( Entity & elem , Entity & edge, const unsigned local_edge_id , Part * part ) { BulkData & mesh = BulkData::get(edge); // verify_declare_element_edge(mesh, elem, local_edge_id); const CellTopologyData * const elem_top = get_cell_topology( elem ).getCellTopologyData(); ThrowErrorMsgIf( elem_top == NULL, "Element[" << elem.identifier() << "] has no defined topology" ); const CellTopologyData * const edge_top = elem_top->edge[ local_edge_id ].topology; ThrowErrorMsgIf( edge_top == NULL, "Element[" << elem.identifier() << "], local_edge_id = " << local_edge_id << ", edge has no defined topology" ); const unsigned * const edge_node_map = elem_top->edge[ local_edge_id ].node ; PartVector add_parts ; if ( part ) { add_parts.push_back( part ); } mesh.change_entity_parts(edge, add_parts); mesh.declare_relation( elem , edge , local_edge_id ); PairIterRelation rel = elem.relations( FEMMetaData::NODE_RANK ); for ( unsigned i = 0 ; i < edge_top->node_count ; ++i ) { Entity & node = * rel[ edge_node_map[i] ].entity(); mesh.declare_relation( edge , node , i ); } return edge ; }
int get_entity_subcell_id( const Entity & entity , const EntityRank subcell_rank, const CellTopologyData * subcell_topology, const std::vector<Entity*>& subcell_nodes ) { const int INVALID_SIDE = -1; unsigned num_nodes = subcell_topology->node_count; if (num_nodes != subcell_nodes.size()) { return INVALID_SIDE; } // get topology of elem const CellTopologyData* entity_topology = get_cell_topology(entity).getCellTopologyData(); if (entity_topology == NULL) { return INVALID_SIDE; } // get nodal relations for entity FEMMetaData & fem_meta = FEMMetaData::get(entity); const EntityRank node_rank = fem_meta.node_rank(); PairIterRelation relations = entity.relations(node_rank); const int num_permutations = subcell_topology->permutation_count; // Iterate over the subcells of entity... for (unsigned local_subcell_ordinal = 0; local_subcell_ordinal < entity_topology->subcell_count[subcell_rank]; ++local_subcell_ordinal) { // get topological data for this subcell const CellTopologyData* curr_subcell_topology = entity_topology->subcell[subcell_rank][local_subcell_ordinal].topology; // If topologies are not the same, there is no way the subcells are the same if (subcell_topology == curr_subcell_topology) { const unsigned* const subcell_node_map = entity_topology->subcell[subcell_rank][local_subcell_ordinal].node; // Taking all positive permutations into account, check if this subcell // has the same nodes as the subcell_nodes argument. Note that this // implementation preserves the node-order so that we can take // entity-orientation into account. for (int p = 0; p < num_permutations; ++p) { if (curr_subcell_topology->permutation[p].polarity == CELL_PERMUTATION_POLARITY_POSITIVE) { const unsigned * const perm_node = curr_subcell_topology->permutation[p].node ; bool all_match = true; for (unsigned j = 0 ; j < num_nodes; ++j ) { if (subcell_nodes[j] != relations[subcell_node_map[perm_node[j]]].entity()) { all_match = false; break; } } // all nodes were the same, we have a match if ( all_match ) { return local_subcell_ordinal ; } } } } } return INVALID_SIDE; }
const CellTopologyData * TopologicalMetaData::get_cell_topology( const Entity & entity , const char * required_by ) { return get_cell_topology( entity.bucket(), required_by ); }