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   // this UNION B == ! ( ! this & ! B )
00096 
00097   this->complement();                   //   ( ! (this) )
00098 
00099   const unsigned finalSize = 1 + m_op.size() + notB.m_op.size();
00100 
00101   m_op.insert( 
00102       m_op.end(), 
00103       notB.m_op.begin(), 
00104       notB.m_op.end() );                // ! ( ! (this) & !B )
00105   m_op.insert( 
00106       m_op.begin(), 
00107       OpType( 0 , 1 , finalSize ) );    // ! ( ! (this) & ? )
00108   return *this;
00109 }
00110 
00111 
00112 void Selector::verify_compatible( const Selector & B ) const
00113 {
00114   if (B.m_mesh_meta_data != m_mesh_meta_data) {
00115     std::ostringstream msg;
00116     msg << "Selector = " << *this << " has mesh meta data pointer = " << m_mesh_meta_data << std::endl;
00117     msg << "Selector = " << B << " has mesh meta data pointer = " << B.m_mesh_meta_data << std::endl;
00118     msg << "These selectors contain incompatible mesh meta data pointers!";
00119     throw std::runtime_error( msg.str() );
00120   }
00121 }
00122 
00123 
00124 void Selector::verify_compatible( const Bucket & B ) const
00125 {
00126   const MetaData * B_mesh_meta_data = &B.mesh().mesh_meta_data();
00127   if (B_mesh_meta_data != m_mesh_meta_data) {
00128     std::ostringstream msg;
00129     msg << "Selector = " << *this << " has mesh meta data pointer = " << m_mesh_meta_data << std::endl;
00130     msg << "Bucket has mesh meta data pointer = " << B_mesh_meta_data << std::endl;
00131     msg << "This selector is incompatible with this bucket!";
00132     throw std::runtime_error( msg.str() );
00133   }
00134 }
00135 
00136 
00137 bool Selector::apply( 
00138     unsigned part_id, 
00139     const Bucket & candidate 
00140     ) const
00141 {
00142   // Search for 'part_id' in the bucket's list of sorted integer part ids
00143   return has_superset(candidate,part_id);
00144 }
00145 
00146 bool Selector::apply( 
00147     std::vector<OpType>::const_iterator i,
00148     std::vector<OpType>::const_iterator j,
00149     const Bucket & candidate 
00150     ) const
00151 {
00152   bool result = i != j ;
00153   while ( result && i != j ) {
00154     if ( i->m_count ) { // Compound statement
00155       result = i->m_unary ^ apply( i + 1 , i + i->m_count , candidate );
00156       i += i->m_count ;
00157     }
00158     else { // Test for containment of bucket in this part, or not in
00159       result = i->m_unary ^ apply( i->m_part_id , candidate );
00160       ++i ;
00161     }
00162   }
00163   return result ;
00164 }
00165 
00166 
00167 bool Selector::operator()( const Bucket & candidate ) const
00168 {
00169   if (m_mesh_meta_data != NULL) {
00170     verify_compatible(candidate);
00171   }
00172   return apply( m_op.begin() , m_op.end() , candidate );
00173 }
00174 
00175 Selector operator & ( const Part & A , const Part & B )
00176 { 
00177   Selector S( A ); 
00178   S &= Selector( B ); 
00179   return S; 
00180 }
00181 
00182 
00183 Selector operator & ( const Part & A , const Selector & B )
00184 { 
00185   Selector S( A ); 
00186   S &= B; 
00187   return S; 
00188 }
00189 
00190 Selector operator & ( const Selector & A, const Part & B )
00191 { 
00192   Selector S( A ); 
00193   S &= Selector(B); 
00194   return S; 
00195 }
00196 
00197 Selector operator & ( const Selector & A, const Selector & B )
00198 { 
00199   Selector S( A ); 
00200   S &= Selector(B); 
00201   return S; 
00202 }
00203 
00204 Selector operator | ( const Part & A , const Part & B )
00205 { 
00206   Selector S( A ); 
00207   S |= Selector( B ); 
00208   return S; 
00209 }
00210 
00211 
00212 Selector operator | ( const Part & A , const Selector & B )
00213 { 
00214   Selector S( A ); 
00215   S |= B; 
00216   return S; 
00217 }
00218 
00219 Selector operator | ( const Selector & A, const Part & B  )
00220 { 
00221   Selector S( A ); 
00222   S |= Selector(B); 
00223   return S; 
00224 }
00225 
00226 Selector operator | ( const Selector & A, const Selector & B  )
00227 { 
00228   Selector S( A ); 
00229   S |= Selector(B); 
00230   return S; 
00231 }
00232 
00233 
00234 
00235 
00236 Selector operator ! ( const Part & A )
00237 {
00238   Selector S(A);
00239   return S.complement();
00240 }
00241 
00242 
00243 std::ostream & operator<<( std::ostream & out, const Selector & selector)
00244 {
00245   out << selector.printExpression(selector.m_op.begin(),selector.m_op.end());
00246   return out;
00247 }
00248 
00249 std::string Selector::printExpression(
00250     const std::vector<OpType>::const_iterator start,
00251     const std::vector<OpType>::const_iterator finish
00252     ) const
00253 {
00254   std::ostringstream outS;
00255 
00256   std::vector<OpType>::const_iterator start_it = start;
00257   std::vector<OpType>::const_iterator finish_it = finish;
00258 
00259   const OpType & op = *start_it;
00260   if (op.m_count > 0) { // Compound
00261     if (op.m_unary != 0) { // Complement
00262       outS << "!";
00263     } 
00264     outS << "(";
00265     if (op.m_count == 1) {
00266       outS << ")";
00267     }
00268     else {
00269       finish_it = start_it;
00270       for (int i=0 ; i < op.m_count ; ++i) {
00271         ++finish_it;
00272       }
00273       ++start_it;
00274       outS << printExpression(start_it,finish_it) << ")";
00275       start_it = finish_it;
00276       --start_it; // back up one
00277     }
00278   }
00279   else { // Part
00280     if (m_mesh_meta_data != NULL) {
00281       Part & part = m_mesh_meta_data->get_part(op.m_part_id);
00282       if (op.m_unary != 0) { // Complement
00283         outS << "!";
00284       }
00285       outS << part.name();
00286     }
00287   }
00288   ++start_it;
00289   if (start_it != finish) {
00290     outS << " AND " << printExpression(start_it,finish);
00291   }
00292   return outS.str();
00293 }
00294 
00295 
00296 Selector::OpType::OpType( const OpType & opType ) 
00297   : m_part_id(opType.m_part_id), 
00298     m_unary(opType.m_unary),
00299     m_count(opType.m_count)
00300 {
00301 }
00302 
00303 
00304 Selector::OpType & Selector::OpType::operator=( const OpType & opType )
00305 {
00306   this->m_part_id = opType.m_part_id;
00307   this->m_unary = opType.m_unary;
00308   this->m_count = opType.m_count;
00309   return *this;
00310 }
00311 
00312 
00313 Selector selectUnion( const PartVector& union_part_vector )
00314 {
00315   Selector selector;
00316   if (union_part_vector.size() > 0) {
00317     selector = *union_part_vector[0];
00318     for (unsigned i = 1 ; i < union_part_vector.size() ; ++i) {
00319       selector |= *union_part_vector[i];
00320     }
00321   }
00322   return selector;
00323 }
00324 
00325 
00326 Selector selectIntersection( const PartVector& intersection_part_vector )
00327 {
00328   Selector selector;
00329   if (intersection_part_vector.size() > 0) {
00330     selector = *intersection_part_vector[0];
00331     for (unsigned i = 1 ; i < intersection_part_vector.size() ; ++i) {
00332       selector &= *intersection_part_vector[i];
00333     }
00334   }
00335   return selector;
00336 }
00337 
00338 
00339 
00340 } // namespace mesh 
00341 } // namespace stk 
00342 
00343 

Generated on Tue Jul 13 09:27:32 2010 for Sierra Toolkit by  doxygen 1.4.7