Sierra Toolkit Version of the Day
Selector.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 
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 {
00021 namespace mesh {
00022 
00023 Selector::Selector( )
00024   : m_mesh_meta_data(0), m_op()
00025 {
00026   compoundAll();
00027 }
00028 
00029 
00030 Selector::~Selector( )
00031 { }
00032 
00033 
00034 // Deep copy
00035 Selector::Selector( const Selector & selector )
00036   : m_mesh_meta_data(selector.m_mesh_meta_data), m_op(selector.m_op)
00037 {
00038 }
00039 
00040 
00041 Selector::Selector( const Part & p )
00042   : m_mesh_meta_data( & MetaData::get(p) ) , m_op()
00043 {
00044   m_op.push_back( OpType( p.mesh_meta_data_ordinal() , 0 , 0 ) );
00045 }
00046 
00047 void Selector::compoundAll()
00048 {
00049   m_op.insert( m_op.begin(), OpType( 0, 0, m_op.size()+1 ) );
00050 }
00051 
00052 
00053 Selector & Selector::complement()
00054 {
00055   bool singlePart = (m_op.size() == 1);
00056   bool fullCompoundPart = (m_op[0].m_count == m_op.size());
00057 
00058   if ( !(singlePart || fullCompoundPart) ) {
00059     // Turn into a compound
00060     compoundAll();
00061   }
00062   // Flip the bit
00063   m_op[0].m_unary ^= 1;
00064   return *this;
00065 }
00066 
00067 
00068 Selector & Selector::operator = ( const Selector & B )
00069 {
00070   this->m_mesh_meta_data = B.m_mesh_meta_data;
00071   this->m_op = B.m_op;
00072   return *this;
00073 }
00074 
00075 Selector & Selector::operator &= ( const Selector & B )
00076 {
00077   if (m_mesh_meta_data == 0) {
00078     m_mesh_meta_data = B.m_mesh_meta_data;
00079   }
00080   verify_compatible( B );
00081   m_op.insert( m_op.end() , B.m_op.begin() , B.m_op.end() );
00082   return *this;
00083 }
00084 
00085 
00086 Selector & Selector::operator |= ( const Selector & B )
00087 {
00088   if (m_mesh_meta_data == 0) {
00089     m_mesh_meta_data = B.m_mesh_meta_data;
00090   }
00091   verify_compatible( B );
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 
00140 void Selector::verify_compatible( const Selector & B ) const
00141 {
00142   ThrowErrorMsgIf( B.m_mesh_meta_data != m_mesh_meta_data,
00143       "Selector = " << *this << " has mesh meta data pointer = " << m_mesh_meta_data <<
00144       "\nSelector = " << B << " has mesh meta data pointer = " << B.m_mesh_meta_data <<
00145       "\nThese selectors contain incompatible mesh meta data pointers!" );
00146 }
00147 
00148 
00149 void Selector::verify_compatible( const Bucket & B ) const
00150 {
00151   const MetaData * B_mesh_meta_data = & MetaData::get(B);
00152   ThrowErrorMsgIf( B_mesh_meta_data != m_mesh_meta_data,
00153       "Selector = " << *this << " has mesh meta data pointer = " << m_mesh_meta_data <<
00154       "\nBucket has mesh meta data pointer = " << B_mesh_meta_data <<
00155       "\nThis selector is incompatible with this bucket!" );
00156 }
00157 
00158 
00159 bool Selector::apply(
00160     unsigned part_id,
00161     const Bucket & candidate
00162     ) const
00163 {
00164   // Search for 'part_id' in the bucket's list of sorted integer part ids
00165   return has_superset(candidate,part_id);
00166 }
00167 
00168 bool Selector::apply(
00169     std::vector<OpType>::const_iterator i,
00170     std::vector<OpType>::const_iterator j,
00171     const Bucket & candidate
00172     ) const
00173 {
00174   bool result = i != j ;
00175   while ( result && i != j ) {
00176     if ( i->m_count ) { // Compound statement
00177       result = i->m_unary ^ apply( i + 1 , i + i->m_count , candidate );
00178       i += i->m_count ;
00179     }
00180     else { // Test for containment of bucket in this part, or not in
00181       result = i->m_unary ^ apply( i->m_part_id , candidate );
00182       ++i ;
00183     }
00184   }
00185   return result ;
00186 }
00187 
00188 
00189 bool Selector::operator()( const Bucket & candidate ) const
00190 {
00191   if (m_mesh_meta_data != NULL) {
00192     verify_compatible(candidate);
00193   }
00194   return apply( m_op.begin() , m_op.end() , candidate );
00195 }
00196 
00197 bool Selector::operator()( const Entity & candidate ) const
00198 {
00199   const Bucket & b = candidate.bucket();
00200   return this->operator()(b);
00201 }
00202 
00203 Selector operator & ( const Part & A , const Part & B )
00204 {
00205   Selector S( A );
00206   S &= Selector( B );
00207   return S;
00208 }
00209 
00210 
00211 Selector operator & ( const Part & A , const Selector & B )
00212 {
00213   Selector S( A );
00214   S &= B;
00215   return S;
00216 }
00217 
00218 Selector operator & ( const Selector & A, const Part & B )
00219 {
00220   Selector S( A );
00221   S &= Selector(B);
00222   return S;
00223 }
00224 
00225 Selector operator & ( const Selector & A, const Selector & B )
00226 {
00227   Selector S( A );
00228   S &= Selector(B);
00229   return S;
00230 }
00231 
00232 Selector operator | ( const Part & A , const Part & B )
00233 {
00234   Selector S( A );
00235   S |= Selector( B );
00236   return S;
00237 }
00238 
00239 
00240 Selector operator | ( const Part & A , const Selector & B )
00241 {
00242   Selector S( A );
00243   S |= B;
00244   return S;
00245 }
00246 
00247 Selector operator | ( const Selector & A, const Part & B  )
00248 {
00249   Selector S( A );
00250   S |= Selector(B);
00251   return S;
00252 }
00253 
00254 Selector operator | ( const Selector & A, const Selector & B  )
00255 {
00256   Selector S( A );
00257   S |= Selector(B);
00258   return S;
00259 }
00260 
00261 
00262 
00263 
00264 Selector operator ! ( const Part & A )
00265 {
00266   Selector S(A);
00267   return S.complement();
00268 }
00269 
00270 
00271 std::ostream & operator<<( std::ostream & out, const Selector & selector)
00272 {
00273   out << selector.printExpression(selector.m_op.begin(),selector.m_op.end());
00274   return out;
00275 }
00276 
00277 std::string Selector::printExpression(
00278     const std::vector<OpType>::const_iterator start,
00279     const std::vector<OpType>::const_iterator finish
00280     ) const
00281 {
00282   std::ostringstream outS;
00283 
00284   std::vector<OpType>::const_iterator start_it = start;
00285   std::vector<OpType>::const_iterator finish_it = finish;
00286 
00287   const OpType & op = *start_it;
00288   if (op.m_count > 0) { // Compound
00289     if (op.m_unary != 0) { // Complement
00290       outS << "!";
00291     }
00292     outS << "(";
00293     if (op.m_count == 1) {
00294       outS << ")";
00295     }
00296     else {
00297       finish_it = start_it;
00298       for (int i=0 ; i < op.m_count ; ++i) {
00299         ++finish_it;
00300       }
00301       ++start_it;
00302       outS << printExpression(start_it,finish_it) << ")";
00303       start_it = finish_it;
00304       --start_it; // back up one
00305     }
00306   }
00307   else { // Part
00308     if (m_mesh_meta_data != NULL) {
00309       Part & part = m_mesh_meta_data->get_part(op.m_part_id);
00310       if (op.m_unary != 0) { // Complement
00311         outS << "!";
00312       }
00313       outS << part.name();
00314     }
00315   }
00316   ++start_it;
00317   if (start_it != finish) {
00318     outS << " AND " << printExpression(start_it,finish);
00319   }
00320   return outS.str();
00321 }
00322 
00323 
00324 Selector selectUnion( const PartVector& union_part_vector )
00325 {
00326   Selector selector;
00327   if (union_part_vector.size() > 0) {
00328     selector = *union_part_vector[0];
00329     for (unsigned i = 1 ; i < union_part_vector.size() ; ++i) {
00330       selector |= *union_part_vector[i];
00331     }
00332   }
00333   return selector;
00334 }
00335 
00336 
00337 Selector selectIntersection( const PartVector& intersection_part_vector )
00338 {
00339   Selector selector;
00340   if (intersection_part_vector.size() > 0) {
00341     selector = *intersection_part_vector[0];
00342     for (unsigned i = 1 ; i < intersection_part_vector.size() ; ++i) {
00343       selector &= *intersection_part_vector[i];
00344     }
00345   }
00346   return selector;
00347 }
00348 
00349 Selector selectField( const FieldBase& field )
00350 {
00351   Selector selector;
00352   const MetaData& meta = MetaData::get(field);
00353   const FieldRestrictionVector& rvec = field.restrictions();
00354 
00355   for(size_t i=0; i<rvec.size(); ++i) {
00356     selector |= meta.get_part(rvec[i].part_ordinal());
00357   }
00358   return selector;
00359 }
00360 
00361 
00362 
00363 } // namespace mesh
00364 } // namespace stk
00365 
00366 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends