|
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 00010 #ifndef stk_mesh_base_FindRestriction_hpp 00011 #define stk_mesh_base_FindRestriction_hpp 00012 00013 #include <stk_mesh/base/Types.hpp> 00014 #include <stk_mesh/base/FieldBase.hpp> 00015 #include <stk_mesh/base/FieldRestriction.hpp> 00016 #include <stk_mesh/base/Selector.hpp> 00017 00018 namespace stk_classic { 00019 namespace mesh { 00020 00021 namespace { 00022 inline 00023 const FieldBase::Restriction & empty_field_restriction() 00024 { 00025 //NOT THREAD SAFE 00026 static const FieldBase::Restriction empty ; 00027 return empty ; 00028 } 00029 }//namespace anonymous 00030 00031 //Given a field and a range of parts, determine whether the field has a restriction 00032 //for the part range. (Common usage is to provide the part-range from a bucket; i.e., 00033 //determine whether the field should be allocated in the bucket.) 00034 template<typename PartIterator, class Compare> 00035 const FieldBase::Restriction& find_restriction(const FieldBase& field, 00036 EntityRank erank, 00037 PartIterator pbegin, 00038 PartIterator pend, 00039 Compare comp) 00040 { 00041 GetPartIterOrdinal<PartIterator> get_part_ordinal; 00042 00043 const FieldBase::Restriction & empty = empty_field_restriction(); 00044 const FieldBase::Restriction * restriction = & empty ; 00045 00046 const std::vector<FieldBase::Restriction> & restr_vec = field.restrictions(); 00047 const std::vector<FieldBase::Restriction>::const_iterator iend = restr_vec.end(); 00048 std::vector<FieldBase::Restriction>::const_iterator ibeg = restr_vec.begin(); 00049 00050 //NOT THREAD SAFE 00051 static FieldRestriction restr; 00052 00053 for ( PartIterator it = pbegin; it != pend && iend != ibeg ; ++it ) { 00054 00055 restr.set_entity_rank(erank); 00056 restr.set_part_ordinal(get_part_ordinal(it)); 00057 00058 //lower_bound returns an iterator to either the insertion point for the 00059 //'restr' argument, or to a matching restriction. 00060 //It only returns the 'end' iterator if 'restr' is past the end of the 00061 //vector of restrictions being searched. 00062 //This depends on the input part ordinals being sorted, and on the restriction 00063 //vector being sorted by part ordinal. 00064 00065 ibeg = std::lower_bound( ibeg , iend , restr ); 00066 00067 if ( (iend != ibeg) && (*ibeg == restr) ) { 00068 if ( restriction == & empty ) { restriction = & *ibeg ; } 00069 00070 if ( ibeg->not_equal_stride(*restriction) ) { 00071 00072 Part & p_old = MetaData::get(field).get_part( ibeg->part_ordinal() ); 00073 Part & p_new = MetaData::get(field).get_part( restriction->part_ordinal() ); 00074 00075 std::ostringstream msg ; 00076 msg << " FAILED WITH INCOMPATIBLE DIMENSIONS FOR " ; 00077 msg << field ; 00078 msg << " Part[" << p_old.name() ; 00079 msg << "] and Part[" << p_new.name() ; 00080 msg << "]" ; 00081 00082 ThrowErrorMsg( msg.str() ); 00083 } 00084 } 00085 } 00086 00087 const std::vector<FieldBase::Restriction> & sel_res = field.selector_restrictions(); 00088 std::pair<PartIterator,PartIterator> part_range = std::make_pair(pbegin, pend); 00089 for(std::vector<FieldBase::Restriction>::const_iterator it=sel_res.begin(), it_end=sel_res.end(); it != it_end; ++it) { 00090 const Selector& selector = it->selector(); 00091 if (it->entity_rank() == erank && selector.apply(part_range, comp)) { 00092 if (restriction == &empty) { 00093 restriction = &*it; 00094 } 00095 if (it->not_equal_stride(*restriction)) { 00096 ThrowErrorMsg("find_restriction calculation failed with different field-restriction selectors giving incompatible sizes."); 00097 } 00098 } 00099 } 00100 00101 return *restriction ; 00102 } 00103 00104 } // namespace mesh 00105 } // namespace stk_classic 00106 00107 #endif // stk_mesh_base_FindRestriction_hpp