5 #include <stk_mesh/base/Types.hpp> 6 #include <stk_mesh/base/BulkData.hpp> 7 #include <stk_mesh/base/BulkModification.hpp> 8 #include <stk_mesh/base/Entity.hpp> 9 #include <stk_mesh/base/GetBuckets.hpp> 10 #include <stk_mesh/base/MetaData.hpp> 11 #include <stk_mesh/base/Selector.hpp> 12 #include <stk_mesh/base/Relation.hpp> 14 #include <stk_mesh/fem/FEMMetaData.hpp> 15 #include <stk_mesh/fem/FEMHelpers.hpp> 16 #include <stk_mesh/fem/CellTopology.hpp> 17 #include <stk_mesh/fem/CreateAdjacentEntities.hpp> 18 #include <stk_mesh/fem/BoundaryAnalysis.hpp> 20 #include <stk_util/parallel/ParallelComm.hpp> 28 struct EntitySubcellComponent {
30 EntitySubcellComponent()
36 EntitySubcellComponent(
38 EntityRank arg_subcell_rank,
39 unsigned arg_subcell_id
42 , subcell_rank(arg_subcell_rank)
43 , subcell_id(arg_subcell_id)
47 EntityRank subcell_rank;
53 void get_entities_with_given_subcell(
54 const CellTopologyData * subcell_topology,
55 const EntityRank subcell_rank,
56 const EntityVector & subcell_nodes,
57 const EntityRank entities_rank,
58 std::vector< EntitySubcellComponent> & entities_with_subcell
62 EntityVector entities;
69 for (EntityVector::const_iterator eitr = entities.begin();
70 eitr != entities.end(); ++eitr) {
76 if ( local_subcell_num != -1) {
77 entities_with_subcell.push_back(EntitySubcellComponent(*eitr, subcell_rank, local_subcell_num));
85 bool is_degenerate(
const fem::CellTopology & topo)
87 return topo.getSideCount() < 3;
91 bool relation_exist(
const Entity & entity, EntityRank subcell_rank, RelationIdentifier subcell_id )
94 PairIterRelation relations = entity.
relations(subcell_rank);
96 for (; !relations.empty(); ++relations) {
97 if (relations->identifier() == subcell_id) {
108 void internal_count_entities_to_create( BulkData & mesh, std::vector<size_t> & entities_to_request) {
111 const EntityRank element_rank = fem_meta.element_rank();
112 const EntityRank side_rank = fem_meta.side_rank();
113 const EntityRank edge_rank = fem_meta.edge_rank();
118 BucketVector element_buckets;
120 get_buckets( select_owned, mesh.buckets(element_rank), element_buckets);
123 for ( EntityRank subcell_rank = side_rank; subcell_rank >= edge_rank; --subcell_rank) {
124 for (BucketVector::iterator bitr = element_buckets.begin();
125 bitr != element_buckets.end();
129 const fem::CellTopology topo = fem::get_cell_topology(b);
131 ThrowErrorMsgIf( is_degenerate(topo),
132 "stk_classic::mesh::create_adjacent_entities(...) does not yet support degenerate topologies (i.e. shells and beams)");
135 if ( !is_degenerate(topo) ) {
137 for (
size_t i = 0; i<b.size(); ++i) {
139 Entity & elem = b[i];
141 const unsigned subcell_count = topo.getSubcellCount(subcell_rank);
143 for (
size_t subcell_id = 0; subcell_id < subcell_count; ++subcell_id ) {
145 if ( ! relation_exist( elem, subcell_rank, subcell_id) ) {
148 EntityVector subcell_nodes;
150 const CellTopologyData * subcell_topology =
158 std::vector<EntitySubcellComponent> adjacent_elements;
160 get_entities_with_given_subcell(
168 std::reverse( subcell_nodes.begin(), subcell_nodes.end());
170 get_entities_with_given_subcell(
178 bool current_elem_has_lowest_id =
true;
181 for (std::vector<EntitySubcellComponent>::iterator adjacent_itr = adjacent_elements.begin();
182 adjacent_itr != adjacent_elements.end();
185 if (adjacent_itr->entity->identifier() < elem.identifier()) {
186 current_elem_has_lowest_id =
false;
194 if (current_elem_has_lowest_id) {
195 entities_to_request[subcell_rank]++;
205 void request_entities(
207 std::vector<size_t> & entities_to_request,
208 std::vector< EntityVector > & requested_entities)
211 const size_t num_ranks = fem_meta.entity_rank_count();
213 requested_entities.clear();
214 requested_entities.resize(num_ranks);
216 EntityVector requested_entities_flat_vector;
217 mesh.generate_new_entities(entities_to_request, requested_entities_flat_vector);
219 EntityVector::iterator b_itr = requested_entities_flat_vector.begin();
221 for (
size_t i=0; i<num_ranks; ++i) {
222 EntityVector & temp = requested_entities[i];
223 temp.insert(temp.begin(), b_itr, b_itr + entities_to_request[i]);
224 b_itr += entities_to_request[i];
227 ThrowRequire(b_itr == requested_entities_flat_vector.end());
231 void internal_create_adjacent_entities( BulkData & mesh,
const PartVector & arg_add_parts, std::vector<size_t> & entities_to_request) {
234 const EntityRank element_rank = fem_meta.element_rank();
235 const EntityRank side_rank = fem_meta.side_rank();
236 const EntityRank edge_rank = fem_meta.edge_rank();
238 const size_t num_ranks = fem_meta.entity_rank_count();
240 Selector select_owned = fem_meta.locally_owned_part();
242 BucketVector element_buckets;
244 get_buckets( select_owned, mesh.buckets(element_rank), element_buckets);
247 mesh.modification_begin();
250 std::vector< EntityVector > requested_entities;
258 std::vector<size_t> entities_used(num_ranks, 0);
260 for ( EntityRank subcell_rank = side_rank; subcell_rank >= edge_rank; --subcell_rank) {
261 for (BucketVector::iterator bitr = element_buckets.begin();
262 bitr != element_buckets.end();
266 const fem::CellTopology topo = fem::get_cell_topology(b);
268 if ( !is_degenerate(topo) ) {
270 for (
size_t i = 0; i<b.size(); ++i) {
272 Entity & elem = b[i];
274 const unsigned subcell_count = topo.getSubcellCount(subcell_rank);
276 for (
size_t subcell_id = 0; subcell_id < subcell_count; ++subcell_id ) {
278 if ( ! relation_exist( elem, subcell_rank, subcell_id) ) {
281 EntityVector subcell_nodes;
283 const CellTopologyData * subcell_topology =
291 std::vector<EntitySubcellComponent> adjacent_elements;
293 get_entities_with_given_subcell(
301 std::reverse( subcell_nodes.begin(), subcell_nodes.end());
303 get_entities_with_given_subcell(
311 bool current_elem_has_lowest_id =
true;
314 for (std::vector<EntitySubcellComponent>::iterator adjacent_itr = adjacent_elements.begin();
315 adjacent_itr != adjacent_elements.end();
318 if (adjacent_itr->entity->identifier() < elem.identifier()) {
319 current_elem_has_lowest_id =
false;
327 if (current_elem_has_lowest_id) {
328 Entity & subcell = * requested_entities[subcell_rank][entities_used[subcell_rank]++];
332 for (
size_t n = 0; n<subcell_nodes.size(); ++n) {
333 Entity & node = *subcell_nodes[n];
334 mesh.declare_relation( subcell, node, n);
337 mesh.declare_relation( elem, subcell, subcell_id);
343 add_parts.push_back( & fem_meta.get_cell_topology_root_part(topo.getCellTopologyData(subcell_rank,subcell_id)));
345 mesh.change_entity_parts(subcell, add_parts, empty_remove_parts);
355 mesh.modification_end();
358 void complete_connectivity( BulkData & mesh ) {
361 const EntityRank element_rank = fem_meta.element_rank();
362 const EntityRank side_rank = fem_meta.side_rank();
363 const EntityRank edge_rank = fem_meta.edge_rank();
365 Selector select_owned_or_shared = fem_meta.locally_owned_part() | fem_meta.globally_shared_part();
367 BucketVector element_buckets;
374 for ( EntityRank subcell_rank = side_rank; subcell_rank >= edge_rank; --subcell_rank) {
376 mesh.modification_begin();
380 BucketVector entity_buckets;
385 for (BucketVector::iterator bitr = entity_buckets.begin();
386 bitr != entity_buckets.end();
390 const fem::CellTopology topo = fem::get_cell_topology(b);
392 ThrowErrorMsgIf( is_degenerate(topo),
393 "stk_classic::mesh::create_adjacent_entities(...) does not yet support degenerate topologies (i.e. shells and beams)");
396 for (
size_t i = 0; i<b.size(); ++i) {
397 Entity & entity = b[i];
399 const unsigned subcell_count = topo.getSubcellCount(subcell_rank);
401 for (
size_t subcell_id = 0; subcell_id < subcell_count; ++subcell_id ) {
403 if ( !relation_exist(entity, subcell_rank, subcell_id) ) {
405 EntityVector subcell_nodes;
407 const CellTopologyData * subcell_topology =
415 std::vector<EntitySubcellComponent> adjacent_entities;
421 get_entities_with_given_subcell(
429 std::reverse( subcell_nodes.begin(), subcell_nodes.end());
431 get_entities_with_given_subcell(
440 if ( !adjacent_entities.empty()) {
442 mesh.declare_relation( entity, *adjacent_entities[0].entity, subcell_id);
450 mesh.modification_end();
457 void create_adjacent_entities( BulkData & mesh,
PartVector & arg_add_parts)
459 ThrowErrorMsgIf(mesh.synchronized_state() == BulkData::MODIFIABLE,
460 "stk_classic::mesh::skin_mesh is not SYNCHRONIZED");
476 complete_connectivity(mesh);
480 const size_t num_ranks = fem_meta.entity_rank_count();
481 std::vector<size_t> entities_to_request(num_ranks, 0);
483 internal_count_entities_to_create( mesh, entities_to_request);
485 internal_create_adjacent_entities( mesh, arg_add_parts, entities_to_request);
488 complete_connectivity(mesh);
int get_entity_subcell_id(const Entity &entity, const EntityRank subcell_rank, const CellTopologyData *side_topology, const EntityVector &side_nodes)
Given an entity and collection of nodes, return the local id of the subcell that contains those nodes...
const CellTopologyData * get_subcell_nodes(const Entity &entity, EntityRank subcell_rank, unsigned subcell_identifier, EntityVector &subcell_nodes)
PairIterRelation relations() const
All Entity relations for which this entity is a member. The relations are ordered from lowest entity-...
void get_entities_through_relations(const std::vector< Entity *> &entities, std::vector< Entity *> &entities_related)
Query which mesh entities have a relation to all of the input mesh entities.
AllSelectedBucketsRange get_buckets(const Selector &selector, const BulkData &mesh)
std::vector< Part *> PartVector
Collections of parts are frequently maintained as a vector of Part pointers.
EntityRank entity_rank(const EntityKey &key)
Given an entity key, return an entity type (rank).