|
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 #include <stdexcept> 00011 #include <sstream> 00012 #include <iostream> 00013 00014 #include <stk_mesh/base/Selector.hpp> 00015 #include <stk_mesh/base/Bucket.hpp> 00016 #include <stk_mesh/base/MetaData.hpp> 00017 #include <stk_mesh/base/BulkData.hpp> 00018 #include <stk_mesh/base/Types.hpp> 00019 00020 namespace stk_classic { 00021 namespace mesh { 00022 00023 Selector::Selector( ) 00024 : m_mesh_meta_data(0), m_op() 00025 { 00026 compoundAll(); 00027 } 00028 00029 00030 Selector::Selector( const Part & p ) 00031 : m_mesh_meta_data( & MetaData::get(p) ) , m_op() 00032 { 00033 m_op.push_back( OpType( p.mesh_meta_data_ordinal() , 0 , 0 ) ); 00034 } 00035 00036 void Selector::compoundAll() 00037 { 00038 m_op.insert( m_op.begin(), OpType( 0, 0, m_op.size()+1 ) ); 00039 } 00040 00041 00042 Selector & Selector::complement() 00043 { 00044 bool singlePart = (m_op.size() == 1); 00045 bool fullCompoundPart = (m_op[0].m_count == m_op.size()); 00046 00047 if ( !(singlePart || fullCompoundPart) ) { 00048 // Turn into a compound 00049 compoundAll(); 00050 } 00051 // Flip the bit 00052 m_op[0].m_unary ^= 1; 00053 return *this; 00054 } 00055 00056 bool Selector::operator()( const Part & part ) const 00057 { 00058 unsigned part_ord = part.mesh_meta_data_ordinal(); 00059 std::pair<const unsigned *, const unsigned *> part_ords(&part_ord, &part_ord+1); 00060 return apply(part_ords, PartOrdLess()); 00061 } 00062 00063 bool Selector::operator()( const Bucket & candidate ) const 00064 { return apply( m_op.begin() , m_op.end() , candidate.superset_part_ordinals(), PartOrdLess() ); } 00065 00066 bool Selector::operator()( const Bucket * candidate ) const{ 00067 return operator()(*candidate); 00068 } 00069 00070 bool Selector::operator()( const Entity & candidate ) const 00071 { 00072 const Bucket & b = candidate.bucket(); 00073 return this->operator()(b); 00074 } 00075 00076 Selector & Selector::operator &= ( const Selector & B ) 00077 { 00078 if (m_mesh_meta_data == 0) { 00079 m_mesh_meta_data = B.m_mesh_meta_data; 00080 } 00081 00082 m_op.insert( m_op.end() , B.m_op.begin() , B.m_op.end() ); 00083 return *this; 00084 } 00085 00086 00087 Selector & Selector::operator |= ( const Selector & B ) 00088 { 00089 if (m_mesh_meta_data == 0) { 00090 m_mesh_meta_data = B.m_mesh_meta_data; 00091 } 00092 00093 Selector notB = B; notB.complement(); 00094 00095 const size_t original_size = m_op.size(); 00096 00097 if ( 1 == original_size && 00098 m_op.front().m_count == 1 && 00099 m_op.front().m_unary == 0 ) { 00100 // this == empty ; therefore, 00101 // this UNION B == B 00102 m_op = B.m_op ; 00103 } 00104 else if ( m_op.front().m_count == original_size && 00105 m_op.front().m_unary != 0 ) { 00106 // This is a full-compound complement. 00107 // Simply add notB to the end and increase the size of the compound 00108 00109 // this == ! A ; therefore, 00110 // this UNION B == ! ( ! ( ! A ) & ! B ) 00111 // this UNION B == ! ( A & ! B ) 00112 00113 m_op.insert( 00114 m_op.end(), 00115 notB.m_op.begin(), 00116 notB.m_op.end() ); 00117 00118 m_op.front().m_count = m_op.size(); 00119 } 00120 else { 00121 // this UNION B == ! ( ! this & ! B ) 00122 00123 this->complement(); // ( ! (this) ) 00124 00125 const unsigned finalSize = 1 + m_op.size() + notB.m_op.size(); 00126 00127 m_op.insert( 00128 m_op.end(), 00129 notB.m_op.begin(), 00130 notB.m_op.end() ); // ! ( ! (this) & !B ) 00131 m_op.insert( 00132 m_op.begin(), 00133 OpType( 0 , 1 , finalSize ) ); // ! ( ! (this) & ? ) 00134 } 00135 00136 return *this; 00137 } 00138 00139 Selector operator & ( const Part & A , const Part & B ) 00140 { 00141 Selector S( A ); 00142 S &= Selector( B ); 00143 return S; 00144 } 00145 00146 00147 Selector operator & ( const Part & A , const Selector & B ) 00148 { 00149 Selector S( A ); 00150 S &= B; 00151 return S; 00152 } 00153 00154 Selector operator & ( const Selector & A, const Part & B ) 00155 { 00156 Selector S( A ); 00157 S &= Selector(B); 00158 return S; 00159 } 00160 00161 Selector operator & ( const Selector & A, const Selector & B ) 00162 { 00163 Selector S( A ); 00164 S &= Selector(B); 00165 return S; 00166 } 00167 00168 Selector operator | ( const Part & A , const Part & B ) 00169 { 00170 Selector S( A ); 00171 S |= Selector( B ); 00172 return S; 00173 } 00174 00175 00176 Selector operator | ( const Part & A , const Selector & B ) 00177 { 00178 Selector S( A ); 00179 S |= B; 00180 return S; 00181 } 00182 00183 Selector operator | ( const Selector & A, const Part & B ) 00184 { 00185 Selector S( A ); 00186 S |= Selector(B); 00187 return S; 00188 } 00189 00190 Selector operator | ( const Selector & A, const Selector & B ) 00191 { 00192 Selector S( A ); 00193 S |= Selector(B); 00194 return S; 00195 } 00196 00197 00198 00199 00200 Selector operator ! ( const Part & A ) 00201 { 00202 Selector S(A); 00203 return S.complement(); 00204 } 00205 00206 00207 std::ostream & operator<<( std::ostream & out, const Selector & selector) 00208 { 00209 out << selector.printExpression(selector.m_op.begin(),selector.m_op.end()); 00210 return out; 00211 } 00212 00213 std::string Selector::printExpression( 00214 const std::vector<OpType>::const_iterator start, 00215 const std::vector<OpType>::const_iterator finish 00216 ) const 00217 { 00218 std::ostringstream outS; 00219 00220 std::vector<OpType>::const_iterator start_it = start; 00221 std::vector<OpType>::const_iterator finish_it = finish; 00222 00223 const OpType & op = *start_it; 00224 if (op.m_count > 0) { // Compound 00225 if (op.m_unary != 0) { // Complement 00226 outS << "!"; 00227 } 00228 outS << "("; 00229 if (op.m_count == 1) { 00230 outS << ")"; 00231 } 00232 else { 00233 finish_it = start_it; 00234 for (int i=0 ; i < op.m_count ; ++i) { 00235 ++finish_it; 00236 } 00237 ++start_it; 00238 outS << printExpression(start_it,finish_it) << ")"; 00239 start_it = finish_it; 00240 --start_it; // back up one 00241 } 00242 } 00243 else { // Part 00244 if (m_mesh_meta_data != NULL) { 00245 Part & part = m_mesh_meta_data->get_part(op.m_part_id); 00246 if (op.m_unary != 0) { // Complement 00247 outS << "!"; 00248 } 00249 outS << part.name(); 00250 } 00251 } 00252 ++start_it; 00253 if (start_it != finish) { 00254 outS << " AND " << printExpression(start_it,finish); 00255 } 00256 return outS.str(); 00257 } 00258 00259 00260 Selector selectUnion( const PartVector& union_part_vector ) 00261 { 00262 Selector selector; 00263 if (union_part_vector.size() > 0) { 00264 selector = *union_part_vector[0]; 00265 for (unsigned i = 1 ; i < union_part_vector.size() ; ++i) { 00266 selector |= *union_part_vector[i]; 00267 } 00268 } 00269 return selector; 00270 } 00271 00272 00273 Selector selectIntersection( const PartVector& intersection_part_vector ) 00274 { 00275 Selector selector; 00276 if (intersection_part_vector.size() > 0) { 00277 selector = *intersection_part_vector[0]; 00278 for (unsigned i = 1 ; i < intersection_part_vector.size() ; ++i) { 00279 selector &= *intersection_part_vector[i]; 00280 } 00281 } 00282 return selector; 00283 } 00284 00285 Selector selectField( const FieldBase& field ) 00286 { 00287 Selector selector; 00288 const MetaData& meta = MetaData::get(field); 00289 const FieldRestrictionVector& rvec = field.restrictions(); 00290 00291 for(size_t i=0; i<rvec.size(); ++i) { 00292 selector |= meta.get_part(rvec[i].part_ordinal()); 00293 } 00294 00295 const FieldRestrictionVector& sel_rvec = field.selector_restrictions(); 00296 for(size_t i=0; i<sel_rvec.size(); ++i) { 00297 selector |= sel_rvec[i].selector(); 00298 } 00299 00300 return selector; 00301 } 00302 00303 00304 00305 } // namespace mesh 00306 } // namespace stk_classic 00307 00308