|
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 { 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