Sierra Toolkit Version of the Day
Entity.cpp
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::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::mesh::RelationIterator INVALID_RELATION_ITR = dummy_vector.end(); // Some STL implementation use POD for iterators
00029 
00030 unsigned get_derived_type(const stk::mesh::Entity&);
00031 
00032 }
00033 }
00034 #endif
00035 
00036 namespace stk {
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
00281 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines