18 #include <stk_util/parallel/ParallelComm.hpp> 19 #include <stk_util/parallel/ParallelReduce.hpp> 21 #include <stk_mesh/base/BulkData.hpp> 22 #include <stk_mesh/base/MetaData.hpp> 23 #include <stk_mesh/base/Comm.hpp> 24 #include <stk_mesh/base/FieldData.hpp> 25 #include <stk_mesh/base/Trace.hpp> 30 void set_field_relations( Entity & e_from ,
32 const unsigned ident )
34 const std::vector<FieldRelation> & field_rels =
35 MetaData::get(e_from).get_field_relations();
37 for ( std::vector<FieldRelation>::const_iterator
38 j = field_rels.begin() ; j != field_rels.end() ; ++j ) {
40 const FieldRelation & fr = *j ;
42 void **
const ptr = (
void**)
field_data( * fr.m_root , e_from );
46 void *
const src =
field_data( * fr.m_target , e_to );
52 (*fr.m_function)( e_from.entity_rank() ,
53 e_to.entity_rank() , ident );
55 if ( offset < number ) {
64 void clear_field_relations( Entity & e_from ,
66 const unsigned ident )
68 const std::vector<FieldRelation> & field_rels =
69 MetaData::get(e_from).get_field_relations();
71 for ( std::vector<FieldRelation>::const_iterator
72 j = field_rels.begin() ; j != field_rels.end() ; ++j ) {
74 const FieldRelation & fr = *j ;
76 void **
const ptr = (
void**)
field_data( * fr.m_root , e_from );
84 (*fr.m_function)( e_from.entity_rank() , type , ident );
86 if ( offset < number ) {
87 ptr[ offset ] = NULL ;
97 void BulkData::require_valid_relation(
const char action[] ,
98 const BulkData & mesh ,
99 const Entity & e_from ,
100 const Entity & e_to )
102 const bool error_mesh_from = & mesh != & BulkData::get(e_from);
103 const bool error_mesh_to = & mesh != & BulkData::get(e_to);
104 const bool error_type = e_from.entity_rank() <= e_to.entity_rank();
105 const bool error_nil_from = EntityLogDeleted == e_from.log_query();
106 const bool error_nil_to = EntityLogDeleted == e_to.log_query();
108 if ( error_mesh_from || error_mesh_to || error_type ||
109 error_nil_from || error_nil_to ) {
110 std::ostringstream msg ;
112 msg <<
"Could not " << action <<
" relation from entity " 113 << print_entity_key(e_from) <<
" to entity " 114 << print_entity_key(e_to) <<
"\n";
116 ThrowErrorMsgIf( error_mesh_from || error_mesh_to,
117 msg.str() << (error_mesh_from ?
"e_from" :
"e_to" ) <<
118 " not member of this mesh");
119 ThrowErrorMsgIf( error_nil_from || error_nil_to,
120 msg.str() << (error_mesh_from ?
"e_from" :
"e_to" ) <<
122 ThrowErrorMsgIf( error_type, msg.str() <<
123 "A relation must be from higher to lower ranking entity");
131 const RelationIdentifier local_id )
133 TraceIfWatching(
"stk_classic::mesh::BulkData::declare_relation", LOG_ENTITY, e_from.
key());
134 TraceIfWatchingDec(
"stk_classic::mesh::BulkData::declare_relation", LOG_ENTITY, e_to.
key(), 1);
135 DiagIfWatching(LOG_ENTITY, e_from.
key(),
136 "from: " << e_from <<
"; " <<
137 "to: " << e_to <<
"; " <<
139 DiagIfWatching(LOG_ENTITY, e_to.
key(),
140 "from: " << e_from <<
"; " <<
141 "to: " << e_to <<
"; " <<
144 require_ok_to_modify();
146 require_valid_relation(
"declare" , *
this , e_from , e_to );
150 m_entity_repo.declare_relation( e_from, e_to, local_id, m_sync_count);
152 OrdinalVector add , empty ;
158 internal_change_entity_parts( e_to , add , empty );
160 set_field_relations( e_from , e_to , local_id );
166 const std::vector<Relation> & rel )
168 require_ok_to_modify();
170 const unsigned erank = entity.entity_rank();
172 std::vector<Relation>::const_iterator i ;
173 for ( i = rel.begin() ; i != rel.end() ; ++i ) {
174 Entity & e = * i->entity();
183 ThrowErrorMsg(
"Given entities of the same entity rank. entity is " <<
184 print_entity_key(entity));
193 const RelationIdentifier local_id )
195 TraceIfWatching(
"stk_classic::mesh::BulkData::destroy_relation", LOG_ENTITY, e_from.
key());
196 TraceIfWatchingDec(
"stk_classic::mesh::BulkData::destroy_relation", LOG_ENTITY, e_to.
key(), 1);
197 DiagIfWatching(LOG_ENTITY, e_from.
key(),
198 "from: " << e_from <<
"; " <<
199 "to: " << e_to <<
"; " <<
201 DiagIfWatching(LOG_ENTITY, e_to.
key(),
202 "from: " << e_from <<
"; " <<
203 "to: " << e_to <<
"; " <<
206 require_ok_to_modify();
208 require_valid_relation(
"destroy" , *
this , e_from , e_to );
214 if (
parallel_size() < 2 || m_entity_comm_map.sharing(e_to.
key()).empty() ) {
224 OrdinalVector del, keep, empty;
230 if ( !( i->entity() == & e_from && i->
identifier() == local_id ) ) {
232 i->identifier(), keep,
241 if ( i->entity() == & e_to && i->
identifier() == local_id ) {
243 i->identifier(), del,
245 clear_field_relations( e_from , e_to.
entity_rank() ,
251 if ( !del.empty() ) {
252 internal_change_entity_parts( e_to , empty , del );
258 if ( i->entity() == & e_to && i->
identifier() == local_id ) {
259 clear_field_relations( e_from , e_to.
entity_rank() ,
267 return m_entity_repo.destroy_relation( e_from, e_to, local_id);
275 void BulkData::internal_propagate_part_changes(
279 TraceIfWatching(
"stk_classic::mesh::BulkData::internal_propagate_part_changes",
282 DiagIfWatching(LOG_ENTITY, entity.key(),
"entity state: " << entity);
283 DiagIfWatching(LOG_ENTITY, entity.key(),
"Removed: " << removed);
285 const unsigned etype = entity.entity_rank();
289 OrdinalVector to_del , to_add , empty ;
291 for ( ; ! rel.empty() ; ++rel ) {
292 const unsigned rel_type = rel->entity_rank();
293 const unsigned rel_ident = rel->identifier();
295 if ( rel_type < etype ) {
297 Entity & e_to = * rel->entity();
306 rel_type, rel_ident, to_add );
308 if ( ! removed.empty() ) {
317 to_rel = e_to.
relations(); ! to_rel.empty() ; ++to_rel ) {
319 & entity != to_rel->entity() ) {
323 to_rel->identifier(),
328 OrdinalVector::const_iterator to_add_begin = to_add.begin(),
329 to_add_end = to_add.end();
331 for ( PartVector::const_iterator
332 j = removed.begin() ; j != removed.end() ; ++j ) {
333 if ( ! contains_ordinal( to_add_begin, to_add_end , (*j)->mesh_meta_data_ordinal() ) ) {
339 if (
parallel_size() < 2 || m_entity_comm_map.sharing(e_to.
key()).empty() ) {
341 internal_change_entity_parts( e_to , to_add , to_del );
346 internal_change_entity_parts( e_to , to_add , empty );
349 set_field_relations( entity, e_to, rel_ident );
351 else if ( etype < rel_type ) {
352 Entity & e_from = * rel->entity();
354 set_field_relations( e_from, entity, rel_ident );
359 void BulkData::internal_propagate_part_changes(
361 const OrdinalVector & removed )
363 TraceIfWatching(
"stk_classic::mesh::BulkData::internal_propagate_part_changes",
366 DiagIfWatching(LOG_ENTITY, entity.key(),
"entity state: " << entity);
367 DiagIfWatching(LOG_ENTITY, entity.key(),
"Removed: " << removed);
369 const unsigned etype = entity.entity_rank();
371 PairIterRelation rel = entity.relations();
373 OrdinalVector to_del , to_add , empty ;
375 const PartVector& all_parts = m_mesh_meta_data.get_parts();
377 for ( ; ! rel.empty() ; ++rel ) {
378 const unsigned rel_type = rel->entity_rank();
379 const unsigned rel_ident = rel->identifier();
381 if ( rel_type < etype ) {
383 Entity & e_to = * rel->entity();
392 rel_type, rel_ident, to_add );
394 if ( ! removed.empty() ) {
402 for ( PairIterRelation
403 to_rel = e_to.relations(); ! to_rel.empty() ; ++to_rel ) {
404 if ( e_to.entity_rank() < to_rel->entity_rank() &&
405 & entity != to_rel->entity() ) {
409 to_rel->identifier(),
414 OrdinalVector::const_iterator to_add_begin = to_add.begin(),
415 to_add_end = to_add.end();
417 for ( OrdinalVector::const_iterator
418 j = removed.begin() ; j != removed.end() ; ++j ) {
419 if ( ! contains_ordinal( to_add_begin, to_add_end , *j ) ) {
425 if (
parallel_size() < 2 || m_entity_comm_map.sharing(e_to.key()).empty() ) {
427 internal_change_entity_parts( e_to , to_add , to_del );
432 internal_change_entity_parts( e_to , to_add , empty );
435 set_field_relations( entity, e_to, rel_ident );
437 else if ( etype < rel_type ) {
438 Entity & e_from = * rel->entity();
440 set_field_relations( e_from, entity, rel_ident );
unsigned field_data_size(const FieldBase &f, const Bucket &k)
Size, in bytes, of the field data for each entity.
void declare_relation(Entity &e_from, Entity &e_to, const RelationIdentifier local_id)
Declare a relation and its converse between entities in the same mesh.
bool destroy_relation(Entity &e_from, Entity &e_to, const RelationIdentifier local_id)
Remove all relations between two entities.
FieldTraits< field_type >::data_type * field_data(const field_type &f, const Bucket::iterator i)
Pointer to the field data array.
void induced_part_membership(Part &part, unsigned entity_rank_from, unsigned entity_rank_to, RelationIdentifier relation_identifier, OrdinalVector &induced_parts, bool include_supersets)
Induce entities' part membership based upon relationships between entities. Insert the result into 'i...
const EntityKey & key() const
The globally unique key ( entity type + identifier ) of this entity.
unsigned parallel_size() const
Size of the parallel machine.
PairIterRelation relations() const
All Entity relations for which this entity is a member. The relations are ordered from lowest entity-...
A fundamental unit within the discretization of a problem domain, including but not limited to nodes...
EntityRank entity_rank() const
The rank of this entity.
EntityId identifier() const
Identifier for this entity which is globally unique for a given entity type.
std::vector< Part *> PartVector
Collections of parts are frequently maintained as a vector of Part pointers.