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 }