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( & p.mesh_meta_data() ) , 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   if (B.m_mesh_meta_data != m_mesh_meta_data) {
00143     std::ostringstream msg;
00144     msg << "Selector = " << *this << " has mesh meta data pointer = " << m_mesh_meta_data << std::endl;
00145     msg << "Selector = " << B << " has mesh meta data pointer = " << B.m_mesh_meta_data << std::endl;
00146     msg << "These selectors contain incompatible mesh meta data pointers!";
00147     throw std::runtime_error( msg.str() );
00148   }
00149 }
00150 
00151 
00152 void Selector::verify_compatible( const Bucket & B ) const
00153 {
00154   const MetaData * B_mesh_meta_data = &B.mesh().mesh_meta_data();
00155   if (B_mesh_meta_data != m_mesh_meta_data) {
00156     std::ostringstream msg;
00157     msg << "Selector = " << *this << " has mesh meta data pointer = " << m_mesh_meta_data << std::endl;
00158     msg << "Bucket has mesh meta data pointer = " << B_mesh_meta_data << std::endl;
00159     msg << "This selector is incompatible with this bucket!";
00160     throw std::runtime_error( msg.str() );
00161   }
00162 }
00163 
00164 
00165 bool Selector::apply(
00166     unsigned part_id,
00167     const Bucket & candidate
00168     ) const
00169 {
00170   // Search for 'part_id' in the bucket's list of sorted integer part ids
00171   return has_superset(candidate,part_id);
00172 }
00173 
00174 bool Selector::apply(
00175     std::vector<OpType>::const_iterator i,
00176     std::vector<OpType>::const_iterator j,
00177     const Bucket & candidate
00178     ) const
00179 {
00180   bool result = i != j ;
00181   while ( result && i != j ) {
00182     if ( i->m_count ) { // Compound statement
00183       result = i->m_unary ^ apply( i + 1 , i + i->m_count , candidate );
00184       i += i->m_count ;
00185     }
00186     else { // Test for containment of bucket in this part, or not in
00187       result = i->m_unary ^ apply( i->m_part_id , candidate );
00188       ++i ;
00189     }
00190   }
00191   return result ;
00192 }
00193 
00194 
00195 bool Selector::operator()( const Bucket & candidate ) const
00196 {
00197   if (m_mesh_meta_data != NULL) {
00198     verify_compatible(candidate);
00199   }
00200   return apply( m_op.begin() , m_op.end() , candidate );
00201 }
00202 
00203 bool Selector::operator()( const Entity & candidate ) const
00204 {
00205   const Bucket & b = candidate.bucket();
00206   return this->operator()(b);
00207 }
00208 
00209 Selector operator & ( const Part & A , const Part & B )
00210 {
00211   Selector S( A );
00212   S &= Selector( B );
00213   return S;
00214 }
00215 
00216 
00217 Selector operator & ( const Part & A , const Selector & B )
00218 {
00219   Selector S( A );
00220   S &= B;
00221   return S;
00222 }
00223 
00224 Selector operator & ( const Selector & A, const Part & B )
00225 {
00226   Selector S( A );
00227   S &= Selector(B);
00228   return S;
00229 }
00230 
00231 Selector operator & ( const Selector & A, const Selector & B )
00232 {
00233   Selector S( A );
00234   S &= Selector(B);
00235   return S;
00236 }
00237 
00238 Selector operator | ( const Part & A , const Part & B )
00239 {
00240   Selector S( A );
00241   S |= Selector( B );
00242   return S;
00243 }
00244 
00245 
00246 Selector operator | ( const Part & A , const Selector & B )
00247 {
00248   Selector S( A );
00249   S |= B;
00250   return S;
00251 }
00252 
00253 Selector operator | ( const Selector & A, const Part & B  )
00254 {
00255   Selector S( A );
00256   S |= Selector(B);
00257   return S;
00258 }
00259 
00260 Selector operator | ( const Selector & A, const Selector & B  )
00261 {
00262   Selector S( A );
00263   S |= Selector(B);
00264   return S;
00265 }
00266 
00267 
00268 
00269 
00270 Selector operator ! ( const Part & A )
00271 {
00272   Selector S(A);
00273   return S.complement();
00274 }
00275 
00276 
00277 std::ostream & operator<<( std::ostream & out, const Selector & selector)
00278 {
00279   out << selector.printExpression(selector.m_op.begin(),selector.m_op.end());
00280   return out;
00281 }
00282 
00283 std::string Selector::printExpression(
00284     const std::vector<OpType>::const_iterator start,
00285     const std::vector<OpType>::const_iterator finish
00286     ) const
00287 {
00288   std::ostringstream outS;
00289 
00290   std::vector<OpType>::const_iterator start_it = start;
00291   std::vector<OpType>::const_iterator finish_it = finish;
00292 
00293   const OpType & op = *start_it;
00294   if (op.m_count > 0) { // Compound
00295     if (op.m_unary != 0) { // Complement
00296       outS << "!";
00297     }
00298     outS << "(";
00299     if (op.m_count == 1) {
00300       outS << ")";
00301     }
00302     else {
00303       finish_it = start_it;
00304       for (int i=0 ; i < op.m_count ; ++i) {
00305         ++finish_it;
00306       }
00307       ++start_it;
00308       outS << printExpression(start_it,finish_it) << ")";
00309       start_it = finish_it;
00310       --start_it; // back up one
00311     }
00312   }
00313   else { // Part
00314     if (m_mesh_meta_data != NULL) {
00315       Part & part = m_mesh_meta_data->get_part(op.m_part_id);
00316       if (op.m_unary != 0) { // Complement
00317         outS << "!";
00318       }
00319       outS << part.name();
00320     }
00321   }
00322   ++start_it;
00323   if (start_it != finish) {
00324     outS << " AND " << printExpression(start_it,finish);
00325   }
00326   return outS.str();
00327 }
00328 
00329 
00330 Selector::OpType::OpType( const OpType & opType )
00331   : m_part_id(opType.m_part_id),
00332     m_unary(opType.m_unary),
00333     m_count(opType.m_count)
00334 {
00335 }
00336 
00337 
00338 Selector::OpType & Selector::OpType::operator=( const OpType & opType )
00339 {
00340   this->m_part_id = opType.m_part_id;
00341   this->m_unary = opType.m_unary;
00342   this->m_count = opType.m_count;
00343   return *this;
00344 }
00345 
00346 
00347 Selector selectUnion( const PartVector& union_part_vector )
00348 {
00349   Selector selector;
00350   if (union_part_vector.size() > 0) {
00351     selector = *union_part_vector[0];
00352     for (unsigned i = 1 ; i < union_part_vector.size() ; ++i) {
00353       selector |= *union_part_vector[i];
00354     }
00355   }
00356   return selector;
00357 }
00358 
00359 
00360 Selector selectIntersection( const PartVector& intersection_part_vector )
00361 {
00362   Selector selector;
00363   if (intersection_part_vector.size() > 0) {
00364     selector = *intersection_part_vector[0];
00365     for (unsigned i = 1 ; i < intersection_part_vector.size() ; ++i) {
00366       selector &= *intersection_part_vector[i];
00367     }
00368   }
00369   return selector;
00370 }
00371 
00372 
00373 
00374 } // namespace mesh
00375 } // namespace stk
00376 
00377 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends