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( 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
00307 
00308 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines