00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 #include "SundanceCellFilter.hpp"
00032 #include "SundanceCellFilterBase.hpp"
00033 #include "SundanceExplicitCellSet.hpp"
00034 #include "SundanceBinaryCellFilter.hpp"
00035 #include "SundanceSubsetCellFilter.hpp"
00036 #include "SundanceLabelCellPredicate.hpp"
00037 #include "SundancePositionalCellPredicate.hpp"
00038 #include "SundanceNullCellFilterStub.hpp"
00039 #include "SundanceNullCellFilter.hpp"
00040 #include "PlayaTabs.hpp"
00041 #include "SundanceSubsetManager.hpp"
00042 
00043 using namespace Sundance;
00044 using namespace Sundance;
00045 using namespace Sundance;
00046 using namespace Teuchos;
00047 
00048 bool CellFilter::isNullCellFilter() const 
00049 {
00050   return dynamic_cast<const NullCellFilterStub*>(ptr().get()) != 0;
00051 }
00052 
00053 bool CellFilter::isNull() const
00054 {
00055   return ptr().get() == 0 || isNullCellFilter();
00056 }
00057 
00058 void CellFilter::setName(const std::string& name)
00059 {
00060   nonConstCfbPtr()->setName(name);
00061 }
00062 
00063 CellSet CellFilter::getCells(const Mesh& mesh) const
00064 {
00065   if (isNull() || isNullCellFilter())
00066   {
00067     return new ExplicitCellSet(mesh, -1, 
00068       NullCell);
00069   }
00070   return cfbPtr()->getCells(mesh);
00071 }
00072 
00073 
00074 
00075 int CellFilter::dimension(const Mesh& mesh) const
00076 {
00077   if (isNullCellFilter())
00078   {
00079     return -1;
00080   }
00081   return cfbPtr()->dimension(mesh);
00082 }
00083 
00084 
00085 
00086 CellFilter CellFilter::operator+(const CellFilter& other) const 
00087 {
00088   if (isNull())
00089   {
00090     return other;
00091   }
00092   else if (other.isNull())
00093   {
00094     return *this;
00095   }
00096   else
00097   {
00098     CellFilter rtn 
00099       = new BinaryCellFilter(*this, other, BinaryCellFilter::Union);
00100     rtn.registerSubset(*this);
00101     rtn.registerSubset(other);
00102     return rtn;
00103   }
00104 }
00105 
00106 
00107 
00108 CellFilter CellFilter::operator-(const CellFilter& other) const 
00109 {
00110   if (other.isNull())
00111   {
00112     return *this;
00113   }
00114   else if (isKnownDisjointWith(other) || other.isKnownDisjointWith(*this))
00115   {
00116     return *this;
00117   }
00118   else if (isKnownSubsetOf(other))
00119   {
00120     CellFilter rtn;
00121     return rtn;
00122   }
00123   else if (*this == other)
00124   {
00125     CellFilter rtn;
00126     return rtn;
00127   }
00128   else
00129   {
00130     CellFilter rtn 
00131       = new BinaryCellFilter(*this, other, BinaryCellFilter::Difference);
00132     rtn.registerDisjoint(other);
00133     this->registerSubset(rtn);
00134     return rtn;
00135   }
00136 }
00137 
00138 
00139 
00140 CellFilter CellFilter::intersection(const CellFilter& other) const 
00141 {
00142   if (isNull() || other.isNull())
00143   {
00144     CellFilter rtn;
00145     return rtn;
00146   }
00147   else if (isKnownDisjointWith(other) || other.isKnownDisjointWith(*this))
00148   {
00149     CellFilter rtn;
00150     return rtn;
00151   }
00152   else if (isKnownSubsetOf(other))
00153   {
00154     return *this;
00155   }
00156   else if (other.isKnownSubsetOf(*this))
00157   {
00158     return other;
00159   }
00160   else if (*this==other)
00161   {
00162     return *this;
00163   }
00164   else
00165   {
00166     CellFilter rtn 
00167       = new BinaryCellFilter(*this, other, BinaryCellFilter::Intersection);
00168     other.registerSubset(rtn);
00169     this->registerSubset(rtn);
00170     
00171     return rtn;
00172   }
00173 }
00174 
00175 
00176 
00177 CellFilter CellFilter::labeledSubset(int label) const
00178 {
00179   return labeledSubset(tuple(label));
00180 }
00181 
00182 CellFilter CellFilter::labeledSubset(const Array<int>& labels) const
00183 {
00184   Set<int> labelSet = makeSet(labels);
00185   CellPredicate pred = new LabelCellPredicate(labelSet);
00186   CellFilter rtn = new SubsetCellFilter(*this, pred);
00187   this->registerLabeledSubset(labelSet, rtn);
00188   this->registerSubset(rtn);
00189 
00190   return rtn;
00191 }
00192 
00193 CellFilter CellFilter::coordSubset(int dir, const double& coordVal) const
00194 {
00195   CellPredicate pred = new CoordinateValueCellPredicate(dir, coordVal);
00196   CellFilter rtn = new SubsetCellFilter(*this, pred);
00197   this->registerSubset(rtn);
00198 
00199   return rtn;
00200 }
00201 
00202 CellFilter CellFilter::subset(const CellPredicate& pred) const
00203 {
00204   CellFilter rtn = new SubsetCellFilter(*this, pred);
00205   this->registerSubset(rtn);
00206   return rtn;
00207 }
00208 
00209 
00210 CellFilter CellFilter::subset(const RCP<CellPredicateFunctorBase>& test) const
00211 {
00212   CellFilter rtn = new SubsetCellFilter(*this, CellPredicate(test));
00213   this->registerSubset(rtn);
00214   return rtn;
00215 }
00216 
00217 bool CellFilter::isKnownSubsetOf(const CellFilter& other) const
00218 {
00219   if (other.knownSubsets().contains(*this)) return true;
00220   return false;
00221 }
00222 
00223 bool CellFilter::isKnownDisjointWith(const CellFilter& other) const
00224 {
00225   if (other.knownDisjoints().contains(*this)) return true;
00226   if (this->knownDisjoints().contains(other)) return true;
00227 
00228   return false;
00229 }
00230 
00231 bool CellFilter::isSubsetOf(const CellFilter& other,
00232   const Mesh& mesh) const
00233 {
00234   if (isKnownSubsetOf(other)) 
00235   {
00236     return true;
00237   }
00238   else
00239   {
00240     CellSet myCells = getCells(mesh);
00241     CellSet yourCells = other.getCells(mesh);
00242     CellSet inter = myCells.setIntersection(yourCells);
00243     if (inter.begin() == inter.end()) return false;
00244     CellSet diff = myCells.setDifference(inter);
00245     return (diff.begin() == diff.end());
00246   }
00247 }
00248 
00249 
00250 
00251 bool CellFilter::operator==(const CellFilter& other) const
00252 {
00253   if (*this < other) return false;
00254   if (other < *this) return false;
00255   return true;
00256 }
00257 
00258 bool CellFilter::operator!=(const CellFilter& other) const
00259 {
00260   return !( *this == other );
00261 }
00262 
00263 
00264 const Set<CellFilter>& CellFilter::knownSubsets() const
00265 {
00266   return SubsetManager::getSubsets(*this);
00267 }
00268 const Set<CellFilter>& CellFilter::knownDisjoints() const
00269 {
00270   return SubsetManager::getDisjoints(*this);
00271 }
00272 
00273 void CellFilter::registerSubset(const CellFilter& sub) const
00274 {
00275   SubsetManager::registerSubset(*this, sub);
00276   
00277   for (Set<CellFilter>::const_iterator 
00278          i=sub.knownSubsets().begin(); i!=sub.knownSubsets().end(); i++)
00279   {
00280     SubsetManager::registerSubset(*this, *i);
00281   }
00282 }
00283 
00284 
00285 void CellFilter::registerDisjoint(const CellFilter& sub) const
00286 {
00287   SubsetManager::registerDisjoint(*this, sub);
00288   
00289   for (Set<CellFilter>::const_iterator 
00290          i=sub.knownDisjoints().begin(); i!=sub.knownDisjoints().end(); i++)
00291   {
00292     SubsetManager::registerDisjoint(*this, *i);
00293   }
00294 }
00295 
00296 void CellFilter::registerLabeledSubset(const Set<int>& label, 
00297   const CellFilter& sub) const
00298 {
00299   SubsetManager::registerLabeledSubset(*this, label, sub);
00300   
00301   const Map<Set<int>, CellFilter>& subsub = SubsetManager::getLabeledSubsets(sub);
00302 
00303   for (Map<Set<int>, CellFilter>::const_iterator 
00304          iter=subsub.begin(); iter!=subsub.end(); iter++)
00305   {
00306     if (iter->first == label) continue;
00307     SubsetManager::registerDisjoint(sub, iter->second);
00308     SubsetManager::registerDisjoint(iter->second, sub);
00309   }
00310 }
00311 
00312 
00313 XMLObject CellFilter::toXML() const 
00314 {
00315   return ptr()->toXML();
00316 }
00317 
00318 string CellFilter::toString() const 
00319 {
00320   return cfbPtr()->toString();
00321 }
00322 
00323 const CellFilterBase* CellFilter::cfbPtr() const
00324 {
00325   const CellFilterBase* rtn = dynamic_cast<const CellFilterBase*>(ptr().get());
00326   TEUCHOS_TEST_FOR_EXCEPTION(rtn==0, std::logic_error, "CellFilter::cfbPtr() cast failed");
00327   return rtn;
00328 }
00329 
00330 CellFilterBase* CellFilter::nonConstCfbPtr()
00331 {
00332   CellFilterBase* rtn = dynamic_cast<CellFilterBase*>(ptr().get());
00333   TEUCHOS_TEST_FOR_EXCEPTION(rtn==0, std::logic_error, "CellFilter::nonConstCfbPtr() cast failed");
00334   return rtn;
00335 }