SundanceCellFilter.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                              Sundance
00005 //                 Copyright (2005) Sandia Corporation
00006 // 
00007 // Copyright (year first published) Sandia Corporation.  Under the terms 
00008 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 
00009 // retains certain rights in this software.
00010 // 
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //  
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //                                                                                 
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA                                                                                
00025 // Questions? Contact Kevin Long (krlong@sandia.gov), 
00026 // Sandia National Laboratories, Livermore, California, USA
00027 // 
00028 // ************************************************************************
00029 /* @HEADER@ */
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 "SundanceNullCellFilterStub.hpp"
00038 #include "SundanceNullCellFilter.hpp"
00039 #include "SundanceTabs.hpp"
00040 #include "SundanceSubsetManager.hpp"
00041 
00042 using namespace Sundance;
00043 using namespace Sundance;
00044 using namespace Sundance;
00045 using namespace Teuchos;
00046 
00047 bool CellFilter::isNullCellFilter() const 
00048 {
00049   return dynamic_cast<const NullCellFilterStub*>(ptr().get()) != 0;
00050 }
00051 
00052 bool CellFilter::isNull() const
00053 {
00054   return ptr().get() == 0 || isNullCellFilter();
00055 }
00056 
00057 void CellFilter::setName(const std::string& name)
00058 {
00059   nonConstCfbPtr()->setName(name);
00060 }
00061 
00062 CellSet CellFilter::getCells(const Mesh& mesh) const
00063 {
00064   if (isNull() || isNullCellFilter())
00065   {
00066     return new ExplicitCellSet(mesh, -1, 
00067       NullCell);
00068   }
00069   return cfbPtr()->getCells(mesh);
00070 }
00071 
00072 
00073 
00074 int CellFilter::dimension(const Mesh& mesh) const
00075 {
00076   if (isNullCellFilter())
00077   {
00078     return -1;
00079   }
00080   return cfbPtr()->dimension(mesh);
00081 }
00082 
00083 
00084 
00085 CellFilter CellFilter::operator+(const CellFilter& other) const 
00086 {
00087   if (isNull())
00088   {
00089     return other;
00090   }
00091   else if (other.isNull())
00092   {
00093     return *this;
00094   }
00095   else
00096   {
00097     CellFilter rtn 
00098       = new BinaryCellFilter(*this, other, BinaryCellFilter::Union);
00099     rtn.registerSubset(*this);
00100     rtn.registerSubset(other);
00101     return rtn;
00102   }
00103 }
00104 
00105 
00106 
00107 CellFilter CellFilter::operator-(const CellFilter& other) const 
00108 {
00109   if (other.isNull())
00110   {
00111     return *this;
00112   }
00113   else if (isKnownDisjointWith(other) || other.isKnownDisjointWith(*this))
00114   {
00115     return *this;
00116   }
00117   else if (isKnownSubsetOf(other))
00118   {
00119     CellFilter rtn;
00120     return rtn;
00121   }
00122   else if (*this == other)
00123   {
00124     CellFilter rtn;
00125     return rtn;
00126   }
00127   else
00128   {
00129     CellFilter rtn 
00130       = new BinaryCellFilter(*this, other, BinaryCellFilter::Difference);
00131     rtn.registerDisjoint(other);
00132     this->registerSubset(rtn);
00133     return rtn;
00134   }
00135 }
00136 
00137 
00138 
00139 CellFilter CellFilter::intersection(const CellFilter& other) const 
00140 {
00141   if (isNull() || other.isNull())
00142   {
00143     CellFilter rtn;
00144     return rtn;
00145   }
00146   else if (isKnownDisjointWith(other) || other.isKnownDisjointWith(*this))
00147   {
00148     CellFilter rtn;
00149     return rtn;
00150   }
00151   else if (isKnownSubsetOf(other))
00152   {
00153     return *this;
00154   }
00155   else if (other.isKnownSubsetOf(*this))
00156   {
00157     return other;
00158   }
00159   else if (*this==other)
00160   {
00161     return *this;
00162   }
00163   else
00164   {
00165     CellFilter rtn 
00166       = new BinaryCellFilter(*this, other, BinaryCellFilter::Intersection);
00167     other.registerSubset(rtn);
00168     this->registerSubset(rtn);
00169     
00170     return rtn;
00171   }
00172 }
00173 
00174 
00175 
00176 CellFilter CellFilter::labeledSubset(int label) const
00177 {
00178   CellPredicate pred = new LabelCellPredicate(label);
00179   CellFilter rtn = new SubsetCellFilter(*this, pred);
00180   this->registerLabeledSubset(label, rtn);
00181   this->registerSubset(rtn);
00182 
00183   return rtn;
00184 }
00185 
00186 CellFilter CellFilter::subset(const CellPredicate& pred) const
00187 {
00188   CellFilter rtn = new SubsetCellFilter(*this, pred);
00189   this->registerSubset(rtn);
00190   return rtn;
00191 }
00192 
00193 
00194 CellFilter CellFilter::subset(const RCP<CellPredicateFunctorBase>& test) const
00195 {
00196   CellFilter rtn = new SubsetCellFilter(*this, CellPredicate(test));
00197   this->registerSubset(rtn);
00198   return rtn;
00199 }
00200 
00201 bool CellFilter::isKnownSubsetOf(const CellFilter& other) const
00202 {
00203   if (other.knownSubsets().contains(*this)) return true;
00204   return false;
00205 }
00206 
00207 bool CellFilter::isKnownDisjointWith(const CellFilter& other) const
00208 {
00209   if (other.knownDisjoints().contains(*this)) return true;
00210   if (this->knownDisjoints().contains(other)) return true;
00211 
00212   return false;
00213 }
00214 
00215 bool CellFilter::isSubsetOf(const CellFilter& other,
00216   const Mesh& mesh) const
00217 {
00218   if (isKnownSubsetOf(other)) 
00219   {
00220     return true;
00221   }
00222   else
00223   {
00224     CellSet myCells = getCells(mesh);
00225     CellSet yourCells = other.getCells(mesh);
00226     CellSet inter = myCells.setIntersection(yourCells);
00227     if (inter.begin() == inter.end()) return false;
00228     CellSet diff = myCells.setDifference(inter);
00229     return (diff.begin() == diff.end());
00230   }
00231 }
00232 
00233 
00234 
00235 bool CellFilter::operator==(const CellFilter& other) const
00236 {
00237   if (*this < other) return false;
00238   if (other < *this) return false;
00239   return true;
00240 }
00241 
00242 bool CellFilter::operator!=(const CellFilter& other) const
00243 {
00244   return !( *this == other );
00245 }
00246 
00247 
00248 const Set<CellFilter>& CellFilter::knownSubsets() const
00249 {
00250   return SubsetManager::getSubsets(*this);
00251 }
00252 const Set<CellFilter>& CellFilter::knownDisjoints() const
00253 {
00254   return SubsetManager::getDisjoints(*this);
00255 }
00256 
00257 void CellFilter::registerSubset(const CellFilter& sub) const
00258 {
00259   SubsetManager::registerSubset(*this, sub);
00260   
00261   for (Set<CellFilter>::const_iterator 
00262          i=sub.knownSubsets().begin(); i!=sub.knownSubsets().end(); i++)
00263   {
00264     SubsetManager::registerSubset(*this, *i);
00265   }
00266 }
00267 
00268 
00269 void CellFilter::registerDisjoint(const CellFilter& sub) const
00270 {
00271   SubsetManager::registerDisjoint(*this, sub);
00272   
00273   for (Set<CellFilter>::const_iterator 
00274          i=sub.knownDisjoints().begin(); i!=sub.knownDisjoints().end(); i++)
00275   {
00276     SubsetManager::registerDisjoint(*this, *i);
00277   }
00278 }
00279 
00280 void CellFilter::registerLabeledSubset(int label, const CellFilter& sub) const
00281 {
00282   SubsetManager::registerLabeledSubset(*this, label, sub);
00283   
00284   const Map<int, CellFilter>& subsub = SubsetManager::getLabeledSubsets(sub);
00285 
00286   for (Map<int, CellFilter>::const_iterator 
00287          iter=subsub.begin(); iter!=subsub.end(); iter++)
00288   {
00289     if (iter->first == label) continue;
00290     SubsetManager::registerDisjoint(sub, iter->second);
00291     SubsetManager::registerDisjoint(iter->second, sub);
00292   }
00293 }
00294 
00295 
00296 XMLObject CellFilter::toXML() const 
00297 {
00298   return ptr()->toXML();
00299 }
00300 
00301 string CellFilter::toString() const 
00302 {
00303   return cfbPtr()->toString();
00304 }
00305 
00306 const CellFilterBase* CellFilter::cfbPtr() const
00307 {
00308   const CellFilterBase* rtn = dynamic_cast<const CellFilterBase*>(ptr().get());
00309   TEST_FOR_EXCEPTION(rtn==0, InternalError, "CellFilter::cfbPtr() cast failed");
00310   return rtn;
00311 }
00312 
00313 CellFilterBase* CellFilter::nonConstCfbPtr()
00314 {
00315   CellFilterBase* rtn = dynamic_cast<CellFilterBase*>(ptr().get());
00316   TEST_FOR_EXCEPTION(rtn==0, InternalError, "CellFilter::nonConstCfbPtr() cast failed");
00317   return rtn;
00318 }

Site Contact