|
Sierra Toolkit Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* Copyright 2010 Sandia Corporation. */ 00003 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */ 00004 /* license for use of this work by or on behalf of the U.S. Government. */ 00005 /* Export of this program may require a license from the */ 00006 /* United States Government. */ 00007 /*------------------------------------------------------------------------*/ 00008 00009 #include <algorithm> 00010 #include <sstream> 00011 #include <stdexcept> 00012 #include <cassert> 00013 00014 #include <stk_mesh/base/Ghosting.hpp> 00015 00016 #include <stk_mesh/baseImpl/EntityImpl.hpp> 00017 #include <stk_mesh/base/Bucket.hpp> 00018 #include <stk_mesh/base/BulkData.hpp> 00019 #include <stk_mesh/base/MetaData.hpp> 00020 00021 namespace stk { 00022 namespace mesh { 00023 namespace impl { 00024 00025 EntityImpl::~EntityImpl() 00026 { 00027 } 00028 00029 00030 EntityImpl::EntityImpl( const EntityKey & arg_key ) 00031 : m_key(arg_key), 00032 m_relation(), 00033 m_comm(), 00034 m_bucket( NULL ), 00035 m_bucket_ord(0), 00036 m_owner_rank(0), 00037 m_sync_count(0), 00038 m_mod_log( EntityLogCreated ) 00039 { 00040 } 00041 00042 00043 PairIterRelation EntityImpl::relations( unsigned rank ) const 00044 { 00045 std::vector<Relation>::const_iterator i = m_relation.begin(); 00046 std::vector<Relation>::const_iterator e = m_relation.end(); 00047 00048 if ( rank ) { 00049 const Relation::raw_attr_type lo_attr = Relation::attribute( rank , 0 ); 00050 i = std::lower_bound( i , e , lo_attr , LessRelation() ); 00051 } 00052 00053 const Relation::raw_attr_type hi_attr = Relation::attribute( rank + 1 , 0 ); 00054 e = std::lower_bound( i , e , hi_attr , LessRelation() ); 00055 00056 return PairIterRelation( i , e ); 00057 } 00058 00059 00060 PairIterEntityComm EntityImpl::sharing() const 00061 { 00062 EntityCommInfoVector::const_iterator i = m_comm.begin(); 00063 EntityCommInfoVector::const_iterator e = m_comm.end(); 00064 00065 e = std::lower_bound( i , e , EntityCommInfo(1,0) ); 00066 00067 return PairIterEntityComm( i , e ); 00068 } 00069 00070 00071 PairIterEntityComm EntityImpl::comm( const Ghosting & sub ) const 00072 { 00073 typedef std::vector< EntityCommInfo > EntityComm ; 00074 00075 const EntityCommInfo s_begin( sub.ordinal() , 0 ); 00076 const EntityCommInfo s_end( sub.ordinal() + 1 , 0 ); 00077 00078 EntityComm::const_iterator i = m_comm.begin(); 00079 EntityComm::const_iterator e = m_comm.end(); 00080 00081 i = std::lower_bound( i , e , s_begin ); 00082 e = std::lower_bound( i , e , s_end ); 00083 00084 return PairIterEntityComm( i , e ); 00085 } 00086 00087 00088 bool EntityImpl::insert( const EntityCommInfo & val ) 00089 { 00090 std::vector< EntityCommInfo >::iterator i = 00091 std::lower_bound( m_comm.begin() , m_comm.end() , val ); 00092 00093 const bool result = i == m_comm.end() || val != *i ; 00094 00095 if ( result ) { 00096 m_comm.insert( i , val ); 00097 } 00098 00099 return result ; 00100 } 00101 00102 00103 bool EntityImpl::erase( const EntityCommInfo & val ) 00104 { 00105 std::vector< EntityCommInfo >::iterator i = 00106 std::lower_bound( m_comm.begin() , m_comm.end() , val ); 00107 00108 const bool result = i != m_comm.end() && val == *i ; 00109 00110 if ( result ) { 00111 m_comm.erase( i ); 00112 } 00113 00114 return result ; 00115 } 00116 00117 00118 bool EntityImpl::erase( const Ghosting & ghost ) 00119 { 00120 typedef std::vector< EntityCommInfo > EntityComm ; 00121 00122 const EntityCommInfo s_begin( ghost.ordinal() , 0 ); 00123 const EntityCommInfo s_end( ghost.ordinal() + 1 , 0 ); 00124 00125 EntityComm::iterator i = m_comm.begin(); 00126 EntityComm::iterator e = m_comm.end(); 00127 00128 i = std::lower_bound( i , e , s_begin ); 00129 e = std::lower_bound( i , e , s_end ); 00130 00131 const bool result = i != e ; 00132 00133 if ( result ) { 00134 m_comm.erase( i , e ); 00135 } 00136 00137 return result ; 00138 } 00139 00140 00141 void EntityImpl::comm_clear_ghosting() 00142 { 00143 std::vector< EntityCommInfo >::iterator j = m_comm.begin(); 00144 while ( j != m_comm.end() && j->ghost_id == 0 ) { ++j ; } 00145 m_comm.erase( j , m_comm.end() ); 00146 } 00147 00148 00149 void EntityImpl::comm_clear() { 00150 m_comm.clear(); 00151 } 00152 00153 bool EntityImpl::marked_for_destruction() const { 00154 // The original implementation of this method checked bucket capacity. In 00155 // order to ensure that the addition of EntityLogDeleted does not change 00156 // behavior, we put error check here. 00157 if ( (bucket().capacity() == 0) != (m_mod_log == EntityLogDeleted) ) { 00158 std::ostringstream msg; 00159 msg << "Inconsistent destruction state; " 00160 << "destroyed entities should be in the nil bucket and vice versa.\n" 00161 << "Problem is with entity: " 00162 << print_entity_key( msg, bucket().mesh().mesh_meta_data(), key() ) 00163 << "\n" 00164 << "Was in nil bucket: " << (bucket().capacity() == 0) << ", " 00165 << "was in destroyed state: " << (m_mod_log == EntityLogDeleted); 00166 throw std::runtime_error( msg.str() ); 00167 } 00168 return m_mod_log == EntityLogDeleted; 00169 } 00170 00171 namespace { 00172 00173 bool is_degenerate_relation ( const Relation &r1 , const Relation &r2 ) 00174 { 00175 return r1.attribute() == r2.attribute() && r1.entity() != r2.entity() ; 00176 } 00177 00178 } 00179 00180 void EntityImpl::log_resurrect() 00181 { 00182 if ( EntityLogDeleted != m_mod_log ) { 00183 std::ostringstream msg; 00184 msg << "Trying to resurrect non-deleted entity: " 00185 << print_entity_key( msg, bucket().mesh().mesh_meta_data(), key() ); 00186 throw std::runtime_error( msg.str() ); 00187 } 00188 m_mod_log = EntityLogModified; 00189 m_bucket = NULL; 00190 } 00191 00192 void EntityImpl::log_created_parallel_copy() 00193 { 00194 if ( EntityLogCreated == m_mod_log ) { 00195 m_mod_log = EntityLogModified ; 00196 } 00197 } 00198 00199 bool EntityImpl::destroy_relation( Entity& e_to ) 00200 { 00201 bool destroyed_relations = false; 00202 for ( std::vector<Relation>::iterator i = m_relation.end() ; 00203 i != m_relation.begin() ; ) { 00204 --i ; 00205 if ( i->entity() == & e_to ) { 00206 i = m_relation.erase( i ); 00207 destroyed_relations = true; 00208 } 00209 } 00210 return destroyed_relations; 00211 } 00212 00213 bool EntityImpl::declare_relation( Entity & e_to, 00214 const unsigned local_id, 00215 unsigned sync_count, 00216 bool is_converse ) 00217 { 00218 const MetaData & meta_data = bucket().mesh().mesh_meta_data(); 00219 00220 static const char method[] = "stk::mesh::impl::EntityImpl::declare_relation"; 00221 00222 const Relation new_relation( e_to , local_id ); 00223 00224 const std::vector<Relation>::iterator fe = m_relation.end(); 00225 std::vector<Relation>::iterator fi = m_relation.begin(); 00226 00227 fi = std::lower_bound( fi , fe , new_relation , LessRelation() ); 00228 00229 // The ordering of the Relations allows for two situations that do 00230 // not arise often in meshes. The first situation is 2 relations between 00231 // e_from and e_to with the same kind but different local_ids. This 00232 // can happen if, for example, a triangle should be used as a quad. In 00233 // this case, one node of the triangle must be two different local nodes of 00234 // the quad. This situation is a valid state of mesh entities. 00235 00236 // The second situation involves malformed stencils. Given e_from, e_to1, 00237 // and e_to2, e_to1 and eto2 can share a relation with e_from with the same 00238 // kind and local_id. This can arise, for instance, if an edge has three 00239 // nodes. The local_id 1 of the edge may point to two different nodes. 00240 // This situation is disallowed in the mesh. We now check for it. 00241 00242 bool found_degenerate_relation = false; 00243 EntityKey degenerate_key; 00244 if ( fi != fe ) 00245 { 00246 bool downstream = fi->entity_rank() < entity_rank(); 00247 if ( is_degenerate_relation ( new_relation , *fi ) && downstream ) 00248 { 00249 found_degenerate_relation = true; 00250 degenerate_key = fi->entity()->key(); 00251 } 00252 } 00253 if ( fi != m_relation.begin() ) 00254 { 00255 --fi; 00256 bool downstream = fi->entity_rank() < entity_rank(); 00257 if ( is_degenerate_relation ( new_relation , *fi ) && downstream ) 00258 { 00259 found_degenerate_relation = true; 00260 degenerate_key = fi->entity()->key(); 00261 } 00262 ++fi; 00263 } 00264 if ( found_degenerate_relation && !is_converse ) 00265 { 00266 std::ostringstream msg ; 00267 msg << method << "( from " ; 00268 print_entity_key( msg , meta_data, key() ); 00269 msg << " , to " ; 00270 print_entity_key( msg , meta_data, e_to.key() ); 00271 msg << " , id " << local_id ; 00272 msg << " ) FAILED "; 00273 msg << " Relation already exists to " ; 00274 print_entity_key( msg , meta_data, degenerate_key ); 00275 throw std::runtime_error( msg.str() ); 00276 } 00277 00278 // If the relation is not degenerate, we add it 00279 00280 if ( ( !is_converse && (fe == fi || 00281 new_relation.attribute() != fi->attribute() ) ) || 00282 (is_converse && (fe == fi || new_relation != *fi ) ) ) { 00283 00284 fi = m_relation.insert( fi , new_relation ); 00285 00286 set_sync_count( sync_count ); 00287 00288 return true; 00289 } 00290 else { 00291 return false; 00292 } 00293 } 00294 00295 } // namespace impl 00296 } // namespace mesh 00297 } // namespace stk 00298