|
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 <stddef.h> 00010 #include <stdexcept> 00011 #include <iostream> 00012 #include <sstream> 00013 #include <algorithm> 00014 00015 #include <stk_mesh/base/Entity.hpp> 00016 #include <stk_mesh/base/BulkData.hpp> 00017 #include <stk_mesh/base/MetaData.hpp> 00018 00019 #ifdef SIERRA_MIGRATION 00020 namespace { 00021 static const std::vector<stk_classic::mesh::Relation> dummy_vector; 00022 } 00023 00024 namespace sierra { 00025 namespace Fmwk { 00026 00027 const unsigned int INVALID_LOCAL_ID = std::numeric_limits<unsigned int>::max(); 00028 const stk_classic::mesh::RelationIterator INVALID_RELATION_ITR = dummy_vector.end(); // Some STL implementation use POD for iterators 00029 00030 unsigned get_derived_type(const stk_classic::mesh::Entity&); 00031 00032 } 00033 } 00034 #endif 00035 00036 namespace stk_classic { 00037 namespace mesh { 00038 00039 //---------------------------------------------------------------------- 00040 00041 std::string print_entity_key(const Entity& entity) 00042 { 00043 return print_entity_key(MetaData::get(entity), 00044 entity.key()); 00045 } 00046 00047 std::string print_entity_key(const Entity* entity) 00048 { 00049 if (entity == NULL) { 00050 return "NULL ENTITY"; 00051 } 00052 else { 00053 return print_entity_key(*entity); 00054 } 00055 } 00056 00057 00058 00059 00060 // 00061 //---------------------------------------------------------------------- 00062 00063 #ifdef SIERRA_MIGRATION 00064 00065 00066 std::string Entity::TypeToString (Entity::ObjectTypeEnum type) { 00067 if(type == NODE ) return "NODE"; 00068 if(type == EDGE ) return "EDGE"; 00069 if(type == FACE ) return "FACE"; 00070 if(type == ELEMENT ) return "ELMENT"; 00071 if(type == CONSTRAINT) return "CONSTRANT"; 00072 if(type == BASE_CLASS) return "BASE_CLASS"; 00073 return "UNKNOWN"; 00074 00075 } 00076 00077 00078 // --------------------------------------------------------------------- 00079 00080 void Entity::compress_relation_capacity() 00081 { 00082 m_entityImpl.compress_relation_capacity(); 00083 #ifdef SIERRA_MIGRATION 00084 if (!m_fmwk_attrs->aux_relations.empty()) { 00085 RelationVector tmp(m_fmwk_attrs->aux_relations); 00086 tmp.swap(m_fmwk_attrs->aux_relations); 00087 } 00088 #endif 00089 } 00090 00091 void Entity::internal_swap_in_real_entity(const int globalId) 00092 { 00093 ThrowRequire(globalId > 0); 00094 m_fmwk_attrs->global_id = globalId; 00095 00096 BulkData::get(*this).change_entity_id(globalId, *this); 00097 00098 internal_verify_initialization_invariant(); 00099 00100 // Issue: Fmwk-managed relations (also called auxiliary relations, are not 00101 // being resorted here, so we have to use a different < operator 00102 // when looking for relations 00103 00104 #ifndef NDEBUG 00105 internal_verify_meshobj_invariant(); 00106 #endif 00107 } 00108 00109 // --------------------------------------------------------------------- 00110 00111 void Entity::reserve_relation(const unsigned num) 00112 { 00113 if (num == 0 && aux_relations().empty()) { 00114 RelationVector tmp; 00115 aux_relations().swap(tmp); // clear memory of m_relations. 00116 } 00117 else { 00118 aux_relations().reserve(num); 00119 } 00120 } 00121 00122 // --------------------------------------------------------------------- 00123 00124 namespace { 00125 00126 struct IgnoreIdOrder 00127 { 00128 bool operator()(const Relation& lhs, const Relation& rhs) 00129 { 00130 bool result = false; 00131 00132 if (lhs.entity_rank() != rhs.entity_rank()) { 00133 result = lhs.entity_rank() < rhs.entity_rank(); 00134 } 00135 else if (lhs.getRelationType() != rhs.getRelationType()) { 00136 result = lhs.getRelationType() < rhs.getRelationType(); 00137 } 00138 else { 00139 result = lhs.identifier() < rhs.identifier(); 00140 } 00141 return result; 00142 } 00143 }; 00144 00145 } 00146 00147 RelationIterator Entity::find_relation(const Relation& relation) const 00148 { 00149 // Extremely hacky: It would be better to set up the < operator for relations so that lower_bound 00150 // can return the desired iterator, but any sane definition would probably force a change in 00151 // relation ordering and that's more than I'm willing to take on now. 00152 // 00153 // The current semantics for relation-searching is as follows: 00154 // Ordered based on derived_type, relation_type, and ordinal in descending precedence 00155 // If multiple relations have the same derived_type, relation_type, and ordinal, a linear 00156 // scan takes place looking for a matching meshobj. If no such meshobj was found, then 00157 // we are left with an iterator pointing to the first relation with a different derived_type, 00158 // relation_type, or ordinal. To sum up, the result of the search can either be equivalent to 00159 // lower_bound OR upper_bound depending upon the state of the relations... YUCK! 00160 00161 const Relation::RelationType relation_type = relation.getRelationType(); 00162 00163 RelationIterator rel = std::lower_bound(internal_begin_relation(relation_type), 00164 internal_end_relation(relation_type), 00165 relation, 00166 IgnoreIdOrder()); 00167 00168 // Should only loop if we are looking at back-relations, otherwise, relations with 00169 // matching specifications are not legal. 00170 while (rel != internal_end_relation(relation_type) && 00171 same_specification(*rel, relation) && 00172 rel->getMeshObj() != relation.getMeshObj()) 00173 ++rel; 00174 00175 return rel; 00176 } 00177 00178 // --------------------------------------------------------------------- 00179 00180 bool Entity::update_relation( 00181 const RelationIterator ir , 00182 const bool back_rel_flag) const 00183 { 00184 const Relation::RelationType relType = ir->getRelationType(); 00185 ThrowAssert(verify_relation_ordering(internal_begin_relation(relType), internal_end_relation(relType))); 00186 ThrowAssertMsg(!internal_is_handled_generically(relType), 00187 "update_relation should not be called for STK-managed relations"); 00188 00189 Entity & meshObj = *ir->getMeshObj() ; 00190 00191 const Relation::RelationType backRelType = back_relation_type(relType); 00192 00193 ThrowAssert(verify_relation_ordering(meshObj.internal_begin_relation(backRelType), meshObj.internal_end_relation(backRelType))); 00194 00195 // Create the corresponding back relation to ir 00196 Relation backRel_obj(const_cast<Entity*>(this), backRelType, ir->getOrdinal(), ir->getOrientation()); 00197 RelationIterator backRel_itr = meshObj.find_relation(backRel_obj); 00198 00199 const bool exists = backRel_itr != meshObj.internal_end_relation(backRelType) && *backRel_itr == backRel_obj; 00200 00201 if (exists && !back_rel_flag) { 00202 // Remove back relation and increment the counter 00203 00204 meshObj.erase_and_clear_if_empty(backRel_itr); 00205 00206 //ThrowAssert(sierra::Fmwk::get_derived_type(meshObj) != Entity::ELEMENT); 00207 00208 meshObj.inc_connection(); 00209 } 00210 else if (!exists && back_rel_flag) { 00211 // Insert back relation 00212 00213 const unsigned k = backRel_itr - meshObj.internal_begin_relation(backRelType) ; 00214 00215 meshObj.reserve_relation(meshObj.aux_relations().size() + 1); 00216 00217 meshObj.aux_relations().insert(meshObj.aux_relations().begin() + k, backRel_obj); 00218 00219 //ThrowAssert(sierra::Fmwk::get_derived_type(meshObj) != Entity::ELEMENT); 00220 00221 meshObj.dec_connection(); 00222 } 00223 00224 ThrowAssert(verify_relation_ordering(meshObj.internal_begin_relation(relType), meshObj.internal_end_relation(relType))); 00225 00226 return true; 00227 } 00228 00229 // --------------------------------------------------------------------- 00230 00231 void Entity::erase_and_clear_if_empty(RelationIterator rel_itr) 00232 { 00233 ThrowRequire(!internal_is_handled_generically(rel_itr->getRelationType())); 00234 00235 RelationVector& aux_relations = m_fmwk_attrs->aux_relations; 00236 aux_relations.erase(aux_relations.begin() + (rel_itr - aux_relations.begin())); // Need to convert to non-const iterator 00237 00238 if (aux_relations.empty()) { 00239 reserve_relation(0); 00240 } 00241 } 00242 00243 // --------------------------------------------------------------------- 00244 00245 void Entity::internal_verify_meshobj_invariant() const 00246 { 00247 PairIterRelation stk_relations = relations(); 00248 for ( ; !stk_relations.empty(); ++stk_relations ) { 00249 ThrowRequireMsg(stk_relations->getMeshObj() != NULL, "Problem with: " << *stk_relations); 00250 } 00251 00252 RelationVector& aux_relations = m_fmwk_attrs->aux_relations; 00253 for (RelationVector::const_iterator itr = aux_relations.begin(), end = aux_relations.end(); itr != end; ++itr) { 00254 ThrowRequireMsg(itr->getMeshObj() != NULL, "Problem with: " << *itr); 00255 } 00256 } 00257 00258 // --------------------------------------------------------------------- 00259 00260 void Entity::set_relation_orientation(RelationIterator rel, unsigned orientation) 00261 { 00262 const Relation::RelationType backRelType = back_relation_type(rel->getRelationType()); 00263 00264 Entity & meshObj = *rel->getMeshObj(); 00265 Relation backRel_obj(const_cast<Entity*>(this), backRelType, rel->getOrdinal(), rel->getOrientation()); 00266 RelationIterator backRel_itr = meshObj.find_relation(backRel_obj); 00267 00268 const bool exists = backRel_itr != meshObj.internal_end_relation(backRelType) && *backRel_itr == backRel_obj; 00269 ThrowRequire(exists); 00270 00271 // Allow clients to make changes to orientation 00272 // Orientations do not affect Relation ordering, so this is safe. 00273 const_cast<Relation*>(&*rel)->setOrientation(orientation); 00274 const_cast<Relation*>(&*backRel_itr)->setOrientation(orientation); 00275 } 00276 00277 #endif 00278 00279 } // namespace mesh 00280 } // namespace stk_classic 00281