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 "SundanceDOFMapBuilder.hpp"
00032 #include "SundanceOut.hpp"
00033 #include "SundanceTabs.hpp"
00034 #include "SundanceBasisFamily.hpp"
00035 #include "SundanceLagrange.hpp"
00036 #include "SundanceMixedDOFMap.hpp"
00037 #include "SundanceMixedDOFMapHN.hpp"
00038 #include "SundanceNodalDOFMap.hpp"
00039 #include "SundanceNodalDOFMapHN.hpp"
00040 #include "SundancePartialElementDOFMap.hpp"
00041 #include "SundanceMaximalCellFilter.hpp"
00042 #include "SundanceInhomogeneousNodalDOFMap.hpp"
00043 #include "SundanceCellFilter.hpp"
00044 #include "SundanceDimensionalCellFilter.hpp"
00045 #include "SundanceCellSet.hpp"
00046 #include "SundanceCFMeshPair.hpp"
00047 #include "Teuchos_Time.hpp"
00048 #include "Teuchos_TimeMonitor.hpp"
00049
00050
00051 using namespace Sundance;
00052 using namespace Teuchos;
00053
00054 static Time& DOFBuilderCtorTimer()
00055 {
00056 static RCP<Time> rtn
00057 = TimeMonitor::getNewTimer("DOF map building");
00058 return *rtn;
00059 }
00060
00061 static Time& cellFilterReductionTimer()
00062 {
00063 static RCP<Time> rtn
00064 = TimeMonitor::getNewTimer("cell filter reduction");
00065 return *rtn;
00066 }
00067
00068 static Time& findFuncDomainTimer()
00069 {
00070 static RCP<Time> rtn
00071 = TimeMonitor::getNewTimer("finding func domains");
00072 return *rtn;
00073 }
00074
00075 DOFMapBuilder::DOFMapBuilder(const Mesh& mesh,
00076 const RCP<FunctionSupportResolver>& fsr, bool findBCCols,
00077 int setupVerb)
00078 : verb_(setupVerb),
00079 mesh_(mesh),
00080 fsr_(fsr),
00081 rowMap_(),
00082 colMap_(),
00083 isBCRow_(),
00084 isBCCol_(),
00085 remoteBCCols_()
00086 {
00087 init(findBCCols);
00088 }
00089
00090 DOFMapBuilder::DOFMapBuilder(int setupVerb)
00091 : verb_(setupVerb),
00092 mesh_(),
00093 fsr_(),
00094 rowMap_(),
00095 colMap_(),
00096 isBCRow_(),
00097 isBCCol_(),
00098 remoteBCCols_()
00099 {}
00100
00101 RCP<DOFMapBase> DOFMapBuilder::makeMap(const Mesh& mesh,
00102 const Array<RCP<BasisDOFTopologyBase> >& basis,
00103 const Array<Set<CellFilter> >& filters)
00104 {
00105 TimeMonitor timer(DOFBuilderCtorTimer());
00106 SUNDANCE_MSG1(verb_, "in DOFMapBuilder::makeMap()");
00107 for (int i=0; i<basis.size(); i++)
00108 {
00109 SUNDANCE_MSG2(verb_, "i=" << i
00110 << " basis=" << basis[i]->description()
00111 << " filters=" << filters[i]);
00112 }
00113
00114 RCP<DOFMapBase> rtn;
00115
00116 if (allowNodalMap() && hasOmnipresentNodalMap(basis, mesh, filters))
00117 {
00118 SUNDANCE_MSG2(verb_, "creating omnipresent nodal map");
00119 CellFilter maxCells = getMaxCellFilter(filters);
00120
00121 if (mesh.allowsHangingHodes()){
00122 rtn = rcp(new NodalDOFMapHN(mesh, basis.size(), maxCells, verb_));
00123 }
00124 else {
00125 rtn = rcp(new NodalDOFMap(mesh, basis.size(), maxCells, verb_));
00126 }
00127 }
00128 else if (hasCellBasis(basis) && hasCommonDomain(filters))
00129 {
00130 TEST_FOR_EXCEPTION(filters[0].size() != 1, RuntimeError,
00131 "only a single domain expected in construction of an element "
00132 "DOF map");
00133 rtn = rcp(new PartialElementDOFMap(mesh, *filters[0].begin(), basis.size(), verb_));
00134 }
00135 else if (allFuncsAreOmnipresent(mesh, filters))
00136 {
00137 SUNDANCE_MSG2(verb_, "creating omnipresent mixed map");
00138 CellFilter maxCells = getMaxCellFilter(filters);
00139 if (mesh.allowsHangingHodes()){
00140 rtn = rcp(new MixedDOFMapHN(mesh, basis, maxCells, verb_));
00141 }else
00142 {
00143 rtn = rcp(new MixedDOFMap(mesh, basis, maxCells, verb_));
00144 }
00145 }
00146 else if (hasNodalBasis(basis))
00147 {
00148 SUNDANCE_MSG2(verb_, "creating inhomogeneous nodal map");
00149 Sundance::Map<CellFilter, Set<int> > fmap = domainToFuncSetMap(filters);
00150 Sundance::Map<CellFilter, Sundance::Map<Set<int>, CellSet> > inputChildren;
00151
00152 Array<Sundance::Map<Set<int>, CellFilter> > disjoint
00153 = DOFMapBuilder::funcDomains(mesh, fmap, inputChildren);
00154
00155 rtn = rcp(new InhomogeneousNodalDOFMap(mesh, disjoint, verb_));
00156 }
00157 else
00158 {
00159 TEST_FOR_EXCEPT(true);
00160 }
00161 return rtn;
00162 }
00163
00164
00165 Sundance::Map<CellFilter, Set<int> > DOFMapBuilder::domainToFuncSetMap(const Array<Set<CellFilter> >& filters) const
00166 {
00167 SUNDANCE_MSG2(verb_, "in DOFMapBuilder::domainToFuncSetMap()");
00168 Map<CellFilter, Set<int> > rtn;
00169 for (int i=0; i<filters.size(); i++)
00170 {
00171 const Set<CellFilter>& s = filters[i];
00172 for (Set<CellFilter>::const_iterator j=s.begin(); j!=s.end(); j++)
00173 {
00174 const CellFilter& cf = *j;
00175 if (rtn.containsKey(cf))
00176 {
00177 rtn[cf].put(i);
00178 }
00179 else
00180 {
00181
00182 rtn.put(cf, makeSet((int) i));
00183 }
00184 }
00185 }
00186 for (Map<CellFilter, Set<int> >::const_iterator
00187 i=rtn.begin(); i!=rtn.end(); i++)
00188 {
00189 SUNDANCE_MSG2(verb_, "subdomain=" << i->first << ", functions="
00190 << i->second);
00191 }
00192 return rtn;
00193 }
00194
00195
00196 void DOFMapBuilder
00197 ::getSubdomainUnkFuncMatches(const FunctionSupportResolver& fsr,
00198 Array<Sundance::Map<CellFilter, Set<int> > >& fmap) const
00199 {
00200 fmap.resize(fsr.numUnkBlocks());
00201
00202 for (int r=0; r<fsr.numRegions(); r++)
00203 {
00204 CellFilter subreg = fsr.region(r);
00205 Set<int> funcs = fsr.unksOnRegion(r).setUnion(fsr.bcUnksOnRegion(r));
00206 for (Set<int>::const_iterator i=funcs.begin(); i!=funcs.end(); i++)
00207 {
00208 int block = fsr.blockForUnkID(*i);
00209 if (fmap[block].containsKey(subreg))
00210 {
00211 fmap[block][subreg].put(*i);
00212 }
00213 else
00214 {
00215 fmap[block].put(subreg, makeSet(*i));
00216 }
00217 }
00218 }
00219 }
00220
00221 void DOFMapBuilder
00222 ::getSubdomainVarFuncMatches(const FunctionSupportResolver& fsr,
00223 Array<Sundance::Map<CellFilter, Set<int> > >& fmap) const
00224 {
00225 fmap.resize(fsr.numVarBlocks());
00226
00227 for (int r=0; r<fsr.numRegions(); r++)
00228 {
00229 CellFilter subreg = fsr.region(r);
00230 Set<int> funcs = fsr.varsOnRegion(r).setUnion(fsr.bcVarsOnRegion(r));
00231 for (Set<int>::const_iterator i=funcs.begin(); i!=funcs.end(); i++)
00232 {
00233 int block = fsr.blockForVarID(*i);
00234 if (fmap[block].containsKey(subreg))
00235 {
00236 fmap[block][subreg].put(*i);
00237 }
00238 else
00239 {
00240 fmap[block].put(subreg, makeSet(*i));
00241 }
00242 }
00243 }
00244 }
00245
00246 Array<Sundance::Map<Set<int>, CellFilter> > DOFMapBuilder
00247 ::funcDomains(const Mesh& mesh,
00248 const Sundance::Map<CellFilter, Set<int> >& fmap,
00249 Sundance::Map<CellFilter, Sundance::Map<Set<int>, CellSet> >& inputToChildrenMap) const
00250 {
00251 TimeMonitor timer(findFuncDomainTimer());
00252 Array<Array<CellFilter> > filters(mesh.spatialDim()+1);
00253 Array<Array<Set<int> > > funcs(mesh.spatialDim()+1);
00254
00255 for (Sundance::Map<CellFilter, Set<int> >::const_iterator
00256 i=fmap.begin(); i!=fmap.end(); i++)
00257 {
00258 int d = i->first.dimension(mesh);
00259 filters[d].append(i->first);
00260 funcs[d].append(i->second);
00261 }
00262 Array<Array<CFMeshPair> > tmp(mesh.spatialDim()+1);
00263 for (int d=0; d<tmp.size(); d++)
00264 {
00265 if (filters[d].size() != 0)
00266 tmp[d] = findDisjointFilters(filters[d], funcs[d], mesh);
00267 }
00268
00269 for (int d=0; d<tmp.size(); d++)
00270 {
00271 for (int r=0; r<tmp[d].size(); r++)
00272 {
00273 for (int p=0; p<filters[d].size(); p++)
00274 {
00275 if (tmp[d][r].filter().isSubsetOf(filters[d][p], mesh))
00276 {
00277 if (inputToChildrenMap.containsKey(filters[d][p]))
00278 {
00279 Sundance::Map<Set<int>, CellSet>& m
00280 = inputToChildrenMap[filters[d][p]];
00281 if (m.containsKey(tmp[d][r].funcs()))
00282 {
00283 m.put(tmp[d][r].funcs(), m[tmp[d][r].funcs()].setUnion(tmp[d][r].cellSet()));
00284 }
00285 else
00286 {
00287 m.put(tmp[d][r].funcs(), tmp[d][r].cellSet());
00288 }
00289 }
00290 else
00291 {
00292 Sundance::Map<Set<int>, CellSet> m;
00293 m.put(tmp[d][r].funcs(), tmp[d][r].cellSet());
00294 inputToChildrenMap.put(filters[d][p], m);
00295 }
00296 }
00297 }
00298 }
00299 }
00300
00301 Array<Sundance::Map<Set<int>, CellFilter> > rtn(mesh.spatialDim()+1);
00302 for (int d=0; d<tmp.size(); d++)
00303 {
00304 if (tmp[d].size() == 0) continue;
00305 for (int i=0; i<tmp[d].size(); i++)
00306 {
00307 const Set<int>& f = tmp[d][i].funcs();
00308 const CellFilter& cf = tmp[d][i].filter();
00309 if (rtn[d].containsKey(f))
00310 {
00311 rtn[d].put(f, rtn[d][f] + cf);
00312 }
00313 else
00314 {
00315 rtn[d].put(f, cf);
00316 }
00317 }
00318 }
00319
00320 return rtn;
00321 }
00322
00323
00324 void DOFMapBuilder::init(bool findBCCols)
00325 {
00326 SUNDANCE_MSG1(verb_, "in DOFMapBuilder::init()");
00327 SUNDANCE_MSG2(verb_, "num var blocks=" << fsr_->numVarBlocks());
00328 SUNDANCE_MSG2(verb_, "num unk blocks=" << fsr_->numUnkBlocks());
00329
00330 rowMap_.resize(fsr_->numVarBlocks());
00331 colMap_.resize(fsr_->numUnkBlocks());
00332 isBCRow_.resize(fsr_->numVarBlocks());
00333 isBCCol_.resize(fsr_->numUnkBlocks());
00334
00335 Array<Array<RCP<BasisDOFTopologyBase> > > testBasis = testBasisTopologyArray();
00336 Array<Array<Set<CellFilter> > > testRegions = testCellFilters();
00337
00338 for (int br=0; br<fsr_->numVarBlocks(); br++)
00339 {
00340 SUNDANCE_MSG2(verb_, "making map for block row=" << br);
00341 rowMap_[br] = makeMap(mesh_, testBasis[br], testRegions[br]);
00342 SUNDANCE_MSG2(verb_, "marking BC rows for block row=" << br);
00343 markBCRows(br);
00344 }
00345
00346
00347 Array<Array<RCP<BasisDOFTopologyBase> > > unkBasis = unkBasisTopologyArray();
00348 Array<Array<Set<CellFilter> > > unkRegions = unkCellFilters();
00349
00350 for (int bc=0; bc<fsr_->numUnkBlocks(); bc++)
00351 {
00352 if (isSymmetric(bc))
00353 {
00354 colMap_[bc] = rowMap_[bc];
00355 }
00356 else
00357 {
00358 SUNDANCE_MSG2(verb_, "making map for block col=" << bc);
00359 colMap_[bc] = makeMap(mesh_, unkBasis[bc], unkRegions[bc]);
00360 }
00361 SUNDANCE_MSG2(verb_, "marking BC cols for block col=" << bc);
00362 if (findBCCols) markBCCols(bc);
00363 }
00364 }
00365
00366 void DOFMapBuilder::extractUnkSetsFromFSR(const FunctionSupportResolver& fsr,
00367 Array<Set<int> >& funcSets,
00368 Array<CellFilter>& regions) const
00369 {
00370 funcSets.resize(fsr.numRegions());
00371 regions.resize(fsr.numRegions());
00372 for (int r=0; r<fsr.numRegions(); r++)
00373 {
00374 regions[r] = fsr.region(r);
00375 funcSets[r] = fsr.unksOnRegion(r).setUnion(fsr.bcUnksOnRegion(r));
00376 }
00377 }
00378
00379 void DOFMapBuilder::extractVarSetsFromFSR(const FunctionSupportResolver& fsr,
00380 Array<Set<int> >& funcSets,
00381 Array<CellFilter>& regions) const
00382 {
00383 funcSets.resize(fsr.numRegions());
00384 regions.resize(fsr.numRegions());
00385 for (int r=0; r<fsr.numRegions(); r++)
00386 {
00387 regions[r] = fsr.region(r);
00388 funcSets[r] = fsr.varsOnRegion(r).setUnion(fsr.bcVarsOnRegion(r));
00389 }
00390 }
00391
00392 Sundance::Map<Set<int>, Set<CellFilter> >
00393 DOFMapBuilder::buildFuncSetToCFSetMap(const Array<Set<int> >& funcSets,
00394 const Array<CellFilter>& regions,
00395 const Mesh& mesh) const
00396 {
00397 Sundance::Map<Set<int>, Set<CellFilter> > tmp;
00398
00399 for (int r=0; r<regions.size(); r++)
00400 {
00401 const CellFilter& reg = regions[r];
00402 if (!tmp.containsKey(funcSets[r]))
00403 {
00404 tmp.put(funcSets[r], Set<CellFilter>());
00405 }
00406 tmp[funcSets[r]].put(reg);
00407 }
00408
00409
00410
00411 Sundance::Map<Set<int>, Set<CellFilter> > rtn=tmp;
00412
00413
00414
00415
00416
00417
00418
00419 return rtn;
00420 }
00421
00422 bool DOFMapBuilder::hasOmnipresentNodalMap(const Array<RCP<BasisDOFTopologyBase> >& basis,
00423 const Mesh& mesh,
00424 const Array<Set<CellFilter> >& filters) const
00425 {
00426 return hasNodalBasis(basis) && allFuncsAreOmnipresent(mesh, filters);
00427 }
00428
00429
00430
00431 bool DOFMapBuilder::hasCommonDomain(const Array<Set<CellFilter> >& filters) const
00432 {
00433 Set<CellFilter> first = filters[0];
00434 for (int i=1; i<filters.size(); i++)
00435 {
00436 if (! (filters[i] == first) ) return false;
00437 }
00438 return true;
00439 }
00440
00441 bool DOFMapBuilder::hasNodalBasis(const Array<RCP<BasisDOFTopologyBase> >& basis) const
00442 {
00443 for (int i=0; i<basis.size(); i++)
00444 {
00445 const Lagrange* lagr
00446 = dynamic_cast<const Lagrange*>(basis[i].get());
00447 if (lagr==0 || lagr->order()!=1) return false;
00448 }
00449 return true;
00450 }
00451
00452
00453 bool DOFMapBuilder::hasCellBasis(const Array<RCP<BasisDOFTopologyBase> >& basis) const
00454 {
00455 for (int i=0; i<basis.size(); i++)
00456 {
00457 const Lagrange* lagr
00458 = dynamic_cast<const Lagrange*>(basis[i].get());
00459 if (lagr==0 || lagr->order()!=0) return false;
00460 }
00461 return true;
00462 }
00463
00464 bool DOFMapBuilder::allFuncsAreOmnipresent(const Mesh& mesh,
00465 const Array<Set<CellFilter> >& filters) const
00466 {
00467 int maxFilterDim = 0;
00468 Set<Set<CellFilter> > distinctSets;
00469 for (int i=0; i<filters.size(); i++)
00470 {
00471 for (Set<CellFilter>::const_iterator iter=filters[i].begin();
00472 iter != filters[i].end(); iter++)
00473 {
00474 int dim = iter->dimension(mesh);
00475 if (dim > maxFilterDim) maxFilterDim = dim;
00476 }
00477 distinctSets.put(filters[i]);
00478 }
00479
00480 for (Set<Set<CellFilter> >::const_iterator
00481 iter=distinctSets.begin(); iter != distinctSets.end(); iter++)
00482 {
00483 if (!isWholeDomain(mesh, maxFilterDim, *iter)) return false;
00484 }
00485
00486 return true;
00487 }
00488
00489 bool DOFMapBuilder::isWholeDomain(const Mesh& mesh,
00490 int maxFilterDim,
00491 const Set<CellFilter>& filters) const
00492 {
00493 CellFilter allMax;
00494 if (maxFilterDim==mesh.spatialDim()) allMax = new MaximalCellFilter();
00495 else allMax = new DimensionalCellFilter(maxFilterDim);
00496
00497 CellSet remainder = allMax.getCells(mesh);
00498
00499 for (Set<CellFilter>::const_iterator
00500 i=filters.begin(); i!=filters.end(); i++)
00501 {
00502 const CellFilter& cf = *i;
00503 if (maxFilterDim==mesh.spatialDim())
00504 {
00505 if (0 != dynamic_cast<const MaximalCellFilter*>(cf.ptr().get()))
00506 {
00507 return true;
00508 }
00509 }
00510 else
00511 {
00512 const DimensionalCellFilter* dcf
00513 = dynamic_cast<const DimensionalCellFilter*>(cf.ptr().get());
00514 if (0 != dcf && dcf->dimension(mesh) == maxFilterDim)
00515 {
00516 return true;
00517 }
00518 }
00519 if (cf.dimension(mesh) != maxFilterDim) continue;
00520 CellSet cells = cf.getCells(mesh);
00521 remainder = remainder.setDifference(cells);
00522 if (remainder.begin() == remainder.end()) return true;
00523 }
00524
00525 return false;
00526 }
00527
00528
00529
00530 CellFilter DOFMapBuilder::getMaxCellFilter(const Array<Set<CellFilter> >& filters) const
00531 {
00532 for (int i=0; i<filters.size(); i++)
00533 {
00534 const Set<CellFilter>& cfs = filters[i];
00535 if (cfs.size() != 1) continue;
00536 const CellFilter& cf = *cfs.begin();
00537 if (0 != dynamic_cast<const MaximalCellFilter*>(cf.ptr().get()))
00538 return cf;
00539 }
00540
00541 return new MaximalCellFilter();
00542 }
00543
00544
00545
00546 Array<Array<Set<CellFilter> > > DOFMapBuilder::testCellFilters() const
00547 {
00548 Array<Array<Set<CellFilter> > > rtn(fsr_->numVarBlocks());
00549
00550 for (int b=0; b<fsr_->numVarBlocks(); b++)
00551 {
00552 for (int i=0; i<fsr_->numVarIDs(b); i++)
00553 {
00554 int testID = fsr_->unreducedVarID(b, i);
00555 Set<CellFilter> s;
00556 const Set<OrderedHandle<CellFilterStub> >& cfs
00557 = fsr_->regionsForTestFunc(testID);
00558 for (Set<OrderedHandle<CellFilterStub> >::const_iterator
00559 j=cfs.begin(); j!=cfs.end(); j++)
00560 {
00561 RCP<CellFilterBase> cfb
00562 = rcp_dynamic_cast<CellFilterBase>(j->ptr());
00563 TEST_FOR_EXCEPT(cfb.get()==0);
00564 CellFilter cf = j->ptr();
00565 s.put(cf);
00566 }
00567
00568
00569 rtn[b].append(s);
00570 }
00571 }
00572 return rtn;
00573 }
00574
00575 Array<Array<Set<CellFilter> > > DOFMapBuilder::unkCellFilters() const
00576 {
00577 Array<Array<Set<CellFilter> > > rtn(fsr_->numUnkBlocks());
00578
00579 for (int b=0; b<fsr_->numUnkBlocks(); b++)
00580 {
00581 for (int i=0; i<fsr_->numUnkIDs(b); i++)
00582 {
00583 int unkID = fsr_->unreducedUnkID(b, i);
00584 Set<CellFilter> s;
00585 const Set<OrderedHandle<CellFilterStub> >& cfs
00586 = fsr_->regionsForUnkFunc(unkID);
00587 for (Set<OrderedHandle<CellFilterStub> >::const_iterator
00588 j=cfs.begin(); j!=cfs.end(); j++)
00589 {
00590 RCP<CellFilterBase> cfb
00591 = rcp_dynamic_cast<CellFilterBase>(j->ptr());
00592 TEST_FOR_EXCEPT(cfb.get()==0);
00593 CellFilter cf = j->ptr();
00594 s.put(cf);
00595 }
00596
00597
00598 rtn[b].append(s);
00599 }
00600 }
00601 return rtn;
00602 }
00603
00604 Array<Array<RCP<BasisDOFTopologyBase> > > DOFMapBuilder::testBasisTopologyArray() const
00605 {
00606 Array<Array<RCP<BasisDOFTopologyBase> > > rtn(fsr_->numVarBlocks());
00607 for (int b=0; b<fsr_->numVarBlocks(); b++)
00608 {
00609 for (int i=0; i<fsr_->numVarIDs(b); i++)
00610 {
00611 rtn[b].append(BasisFamily::getBasisTopology(fsr_->varFuncData(b, i)));
00612 }
00613 }
00614 return rtn;
00615 }
00616
00617 Array<Array<RCP<BasisDOFTopologyBase> > > DOFMapBuilder::unkBasisTopologyArray() const
00618 {
00619 Array<Array<RCP<BasisDOFTopologyBase> > > rtn(fsr_->numUnkBlocks());
00620 for (int b=0; b<fsr_->numUnkBlocks(); b++)
00621 {
00622 for (int i=0; i<fsr_->numUnkIDs(b); i++)
00623 {
00624 rtn[b].append(BasisFamily::getBasisTopology(fsr_->unkFuncData(b, i)));
00625 }
00626 }
00627 return rtn;
00628 }
00629
00630
00631 Set<CellFilter> DOFMapBuilder
00632 ::reduceCellFilters(const Mesh& mesh,
00633 const Set<CellFilter>& inputSet) const
00634 {
00635 TimeMonitor timer(cellFilterReductionTimer());
00636 Set<CellFilter> rtn;
00637
00638 CellFilter m = new MaximalCellFilter();
00639 if (inputSet.contains(m))
00640 {
00641 rtn.put(m);
00642 return rtn;
00643 }
00644
00645
00646
00647 CellFilter myMaxFilters;
00648 for (Set<CellFilter>::const_iterator
00649 i=inputSet.begin(); i!=inputSet.end(); i++)
00650 {
00651 CellFilter f = *i;
00652 if (f.dimension(mesh) != mesh.spatialDim()) continue;
00653 myMaxFilters = myMaxFilters + f;
00654 }
00655
00656 CellSet myMax = myMaxFilters.getCells(mesh);
00657
00658
00659
00660
00661
00662
00663 CellSet allMax = m.getCells(mesh);
00664 CellSet diff = allMax.setDifference(myMax);
00665
00666
00667 if (diff.begin() == diff.end())
00668 {
00669 rtn.put(m);
00670 return rtn;
00671 }
00672
00673
00674
00675 if (myMax.begin() != myMax.end()) rtn.put(myMaxFilters);
00676
00677
00678
00679
00680
00681 for (Set<CellFilter>::const_iterator
00682 i=inputSet.begin(); i!=inputSet.end(); i++)
00683 {
00684 CellFilter f = *i;
00685 if (f.dimension(mesh) == mesh.spatialDim()) continue;
00686 CellSet s = f.getCells(mesh);
00687 if (s.areFacetsOf(myMax)) continue;
00688
00689
00690
00691
00692 rtn.put(f);
00693 }
00694 return rtn;
00695 }
00696
00697
00698 bool DOFMapBuilder::isSymmetric(int b) const
00699 {
00700 if ((int)fsr_->numVarBlocks() < b || (int)fsr_->numUnkBlocks() < b) return false;
00701
00702 if (fsr_->numVarIDs(b) != fsr_->numUnkIDs(b)) return false;
00703
00704 for (int i=0; i<fsr_->numVarIDs(b); i++)
00705 {
00706 BasisFamily basis1 = BasisFamily::getBasis(fsr_->varFuncData(b,i));
00707 BasisFamily basis2 = BasisFamily::getBasis(fsr_->unkFuncData(b,i));
00708 if (!(basis1 == basis2)) return false;
00709 }
00710 return true;
00711 }
00712
00713 bool DOFMapBuilder::regionIsMaximal(int r) const
00714 {
00715 const CellFilterStub* reg = fsr_->region(r).get();
00716 return (dynamic_cast<const MaximalCellFilter*>(reg) != 0);
00717 }
00718
00719 void DOFMapBuilder::markBCRows(int block)
00720 {
00721 isBCRow_[block] = rcp(new Array<int>(rowMap_[block]->numLocalDOFs()));
00722 int ndof = rowMap_[block]->numLocalDOFs();
00723 Array<int>& isBC = *isBCRow_[block];
00724 for (int i=0; i<ndof; i++) isBC[i] = false;
00725
00726 RCP<Array<int> > cellLID = rcp(new Array<int>());
00727 Array<RCP<Array<int> > > cellBatches;
00728 const RCP<DOFMapBase>& rowMap = rowMap_[block];
00729
00730 for (int r=0; r<fsr_->numRegions(); r++)
00731 {
00732
00733 CellFilter region = fsr_->region(r);
00734
00735 if (!fsr_->isBCRegion(r)) continue;
00736
00737 int dim = region.dimension(mesh_);
00738 CellSet cells = region.getCells(mesh_);
00739 cellLID->resize(0);
00740 for (CellIterator c=cells.begin(); c != cells.end(); c++)
00741 {
00742 cellLID->append(*c);
00743 }
00744 if (cellLID->size() == 0) continue;
00745
00746
00747 const Set<int>& allBcFuncs = fsr_->bcVarsOnRegion(r);
00748
00749 Set<int> bcFuncs;
00750 for (Set<int>::const_iterator
00751 i=allBcFuncs.begin(); i != allBcFuncs.end(); i++)
00752 {
00753 if (block == fsr_->blockForVarID(*i))
00754 {
00755 bcFuncs.put(fsr_->reducedVarID(*i));
00756 }
00757 }
00758 if (bcFuncs.size()==0) continue;
00759 Array<int> bcFuncID = bcFuncs.elements();
00760
00761 Array<Array<int> > dofs;
00762 Array<int> nNodes;
00763
00764 RCP<const MapStructure> s
00765 = rowMap->getDOFsForCellBatch(dim, *cellLID, bcFuncs, dofs, nNodes,0);
00766 int offset = rowMap->lowestLocalDOF();
00767 int high = offset + rowMap->numLocalDOFs();
00768
00769 for (int c=0; c<cellLID->size(); c++)
00770 {
00771 for (int b=0; b< s->numBasisChunks(); b++)
00772 {
00773 int nFuncs = s->numFuncs(b);
00774 for (int n=0; n<nNodes[b]; n++)
00775 {
00776 for (int f=0; f<bcFuncID.size(); f++)
00777 {
00778 int chunk = s->chunkForFuncID(bcFuncID[f]);
00779 if (chunk != b) continue;
00780 int funcOffset = s->indexForFuncID(bcFuncID[f]);
00781 int dof = dofs[b][(c*nFuncs + funcOffset)*nNodes[b]+n];
00782 if (dof < offset || dof >= high) continue;
00783 (*isBCRow_[block])[dof-offset]=true;
00784 }
00785 }
00786 }
00787 }
00788 }
00789 }
00790
00791
00792
00793 void DOFMapBuilder::markBCCols(int block)
00794 {
00795 isBCCol_[block] = rcp(new Array<int>(colMap_[block]->numLocalDOFs()));
00796 int ndof = colMap_[block]->numLocalDOFs();
00797 Array<int>& isBC = *isBCCol_[block];
00798 for (int i=0; i<ndof; i++) isBC[i] = false;
00799
00800 RCP<Array<int> > cellLID = rcp(new Array<int>());
00801 Array<RCP<Array<int> > > cellBatches;
00802 const RCP<DOFMapBase>& colMap = colMap_[block];
00803
00804 for (int r=0; r<fsr_->numRegions(); r++)
00805 {
00806
00807 CellFilter region = fsr_->region(r);
00808
00809 if (!fsr_->isBCRegion(r)) continue;
00810
00811 int dim = region.dimension(mesh_);
00812 CellSet cells = region.getCells(mesh_);
00813 cellLID->resize(0);
00814 for (CellIterator c=cells.begin(); c != cells.end(); c++)
00815 {
00816 cellLID->append(*c);
00817 }
00818 if (cellLID->size() == 0) continue;
00819
00820
00821 const Set<int>& allBcFuncs = fsr_->bcUnksOnRegion(r);
00822
00823 Set<int> bcFuncs;
00824 for (Set<int>::const_iterator
00825 i=allBcFuncs.begin(); i != allBcFuncs.end(); i++)
00826 {
00827 if (block == fsr_->blockForUnkID(*i))
00828 {
00829 bcFuncs.put(fsr_->reducedUnkID(*i));
00830 }
00831 }
00832 if (bcFuncs.size()==0) continue;
00833 Array<int> bcFuncID = bcFuncs.elements();
00834
00835 Array<Array<int> > dofs;
00836 Array<int> nNodes;
00837
00838 RCP<const MapStructure> s
00839 = colMap->getDOFsForCellBatch(dim, *cellLID, bcFuncs, dofs, nNodes,0);
00840 int offset = colMap->lowestLocalDOF();
00841 int high = offset + colMap->numLocalDOFs();
00842
00843 for (int c=0; c<cellLID->size(); c++)
00844 {
00845 for (int b=0; b< s->numBasisChunks(); b++)
00846 {
00847 int nFuncs = s->numFuncs(b);
00848 for (int n=0; n<nNodes[b]; n++)
00849 {
00850 for (int f=0; f<bcFuncID.size(); f++)
00851 {
00852 int chunk = s->chunkForFuncID(bcFuncID[f]);
00853 if (chunk != b) continue;
00854 int funcOffset = s->indexForFuncID(bcFuncID[f]);
00855 int dof = dofs[b][(c*nFuncs + funcOffset)*nNodes[b]+n];
00856 if (dof < offset || dof >= high)
00857 {
00858 remoteBCCols_[block]->insert(dof);
00859 }
00860 else
00861 {
00862 (*isBCCol_[block])[dof-offset]=true;
00863 }
00864 }
00865 }
00866 }
00867 }
00868 }
00869 }
00870
00871
00872
00873 namespace Sundance
00874 {
00875
00876 Array<Array<BasisFamily> > testBasisArray(const RCP<FunctionSupportResolver>& fsr)
00877 {
00878 Array<Array<BasisFamily> > rtn(fsr->numVarBlocks());
00879 for (int b=0; b<fsr->numVarBlocks(); b++)
00880 {
00881 for (int i=0; i<fsr->numVarIDs(b); i++)
00882 {
00883 rtn[b].append(BasisFamily::getBasis(fsr->varFuncData(b, i)));
00884 }
00885 }
00886 return rtn;
00887 }
00888
00889
00890 Array<Array<BasisFamily> > unkBasisArray(const RCP<FunctionSupportResolver>& fsr)
00891 {
00892 Array<Array<BasisFamily> > rtn(fsr->numUnkBlocks());
00893 for (int b=0; b<fsr->numUnkBlocks(); b++)
00894 {
00895 for (int i=0; i<fsr->numUnkIDs(b); i++)
00896 {
00897 rtn[b].append(BasisFamily::getBasis(fsr->unkFuncData(b, i)));
00898 }
00899 }
00900 return rtn;
00901 }
00902
00903
00904 }