SundanceDOFMapBuilder.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 "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     // if the mesh allows hanging nodes then create different DOF Map
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   /* eliminate overlap between cell filters */
00410   
00411   Sundance::Map<Set<int>, Set<CellFilter> > rtn=tmp;
00412   /*
00413     for (Sundance::Map<Set<int>, Set<CellFilter> >::const_iterator 
00414     i=tmp.begin(); i!=tmp.end(); i++)
00415     {
00416     rtn.put(i->first, reduceCellFilters(mesh, i->second));
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 //  TEST_FOR_EXCEPT(true);
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       //         Set<CellFilter> reducedS = reduceCellFilters(mesh(), s);
00568 //          rtn[b].append(reducedS);
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 //          Set<CellFilter> reducedS = reduceCellFilters(mesh(), s);
00597 //          rtn[b].append(reducedS);
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   /* If the input set explicitly contains all maximal cells, we're done */
00638   CellFilter m = new MaximalCellFilter();
00639   if (inputSet.contains(m))
00640   {
00641     rtn.put(m);
00642     return rtn;
00643   }
00644 
00645   /* Next, see if combining the maximal-dimension filters in the
00646    * input set gives us all maximal cells. */
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 //  if (myMax.size() == mesh.numCells(mesh.spatialDim()))
00658 //  {
00659 //    rtn.put(m);
00660 //    return rtn;
00661 //  }
00662 
00663   CellSet allMax = m.getCells(mesh);
00664   CellSet diff = allMax.setDifference(myMax);
00665   /* if the difference between the collected max cell set and the known
00666    * set of all max cells is empty, then we're done */
00667   if (diff.begin() == diff.end())
00668   {
00669     rtn.put(m);
00670     return rtn;
00671   }
00672   
00673   /* Otherwise, we return the remaining max cell filters, and possibly
00674    * some lower-dimensional filters to be identified below. */
00675   if (myMax.begin() != myMax.end()) rtn.put(myMaxFilters);
00676 
00677   /* At this point, we can eliminate as redundant any lower-dimensional
00678    * cell filters all of whose cells are facets of our subset of
00679    * maximal cell filters. Any other lower-dim cell filters must be 
00680    * appended to our list. */
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     /* if we're here, then we have a lower-dimensional cell filter
00689      * whose cells are not facets of cells in our maximal cell filters.
00690      * These will need to be processed separately in assigning DOFs.
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     /* find the cells in this region */
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     /* find the functions that appear in BCs on this region */
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     /* find the cells in this region */
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     /* find the functions that appear in BCs on this region */
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 }        

Site Contact