SundanceDiscreteSpace.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 "SundanceDiscreteSpace.hpp"
00032 #include "SundanceDOFMapBuilder.hpp"
00033 #include "SundanceFunctionSupportResolver.hpp"
00034 #include "SundanceOut.hpp"
00035 #include "SundanceMaximalCellFilter.hpp"
00036 #include "TSFProductVectorSpaceImpl.hpp"
00037 #include "Teuchos_MPIContainerComm.hpp"
00038 
00039 using namespace Sundance;
00040 using namespace Teuchos;
00041 
00042 const int* vecPtr(const Array<int>& x)
00043 {
00044   static const int* dum = 0;
00045   if (x.size()==0) return dum;
00046   else return &(x[0]);
00047 }
00048 
00049 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisFamily& basis,
00050   const VectorType<double>& vecType,
00051   int setupVerb)
00052   : setupVerb_(setupVerb), 
00053     map_(),
00054     mesh_(mesh), 
00055     subdomains_(),
00056     basis_(),
00057     vecSpace_(), 
00058     vecType_(vecType),
00059     ghostImporter_()
00060   ,transformationBuilder_(0)
00061 {
00062   init(maximalRegions(1), BasisArray(tuple(basis)));
00063 }
00064 
00065 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisArray& basis,
00066   const VectorType<double>& vecType,
00067   int setupVerb)
00068   : setupVerb_(setupVerb),
00069     map_(), 
00070     mesh_(mesh), 
00071     subdomains_(),
00072     basis_(),
00073     vecSpace_(), 
00074     vecType_(vecType),
00075     ghostImporter_()
00076   ,transformationBuilder_(0)
00077 {
00078   init(maximalRegions(basis.size()), basis);
00079 }
00080 
00081 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisArray& basis,
00082   const Array<CellFilter>& funcDomains,
00083   const VectorType<double>& vecType,
00084   int setupVerb)
00085   : setupVerb_(setupVerb),
00086     map_(), 
00087     mesh_(mesh), 
00088     subdomains_(),
00089     basis_(),
00090     vecSpace_(), 
00091     vecType_(vecType),
00092     ghostImporter_()
00093   ,transformationBuilder_(0)
00094 {
00095   init(funcDomains, basis);
00096 }
00097 
00098 
00099 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisFamily& basis,
00100   const CellFilter& funcDomains,
00101   const VectorType<double>& vecType,
00102   int setupVerb)
00103   : map_(), 
00104     mesh_(mesh), 
00105     subdomains_(),
00106     basis_(),
00107     vecSpace_(), 
00108     vecType_(vecType),
00109     ghostImporter_()
00110   ,transformationBuilder_(0)
00111 {
00112   init(tuple(funcDomains), BasisArray(tuple(basis)));
00113 }
00114 
00115 
00116 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisArray& basis,
00117   const CellFilter& funcDomains,
00118   const VectorType<double>& vecType,
00119   int setupVerb)
00120   : setupVerb_(setupVerb),
00121     map_(), 
00122     mesh_(mesh), 
00123     subdomains_(),
00124     basis_(),
00125     vecSpace_(), 
00126     vecType_(vecType),
00127     ghostImporter_()
00128   ,transformationBuilder_(0)
00129 {
00130   init(Array<CellFilter>(basis.size(), funcDomains), basis);
00131 }
00132 
00133 
00134 
00135 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisArray& basis,
00136   const RCP<DOFMapBase>& map,
00137   const RCP<Array<int> >& bcIndices,
00138   const VectorType<double>& vecType,
00139   int setupVerb)
00140   : setupVerb_(setupVerb),
00141     map_(map), 
00142     mesh_(mesh),
00143     subdomains_(),
00144     basis_(),
00145     vecSpace_(), 
00146     vecType_(vecType),
00147     ghostImporter_()
00148   ,transformationBuilder_(0)
00149 {
00150   init(map->funcDomains(), basis, bcIndices, true);
00151 }
00152 
00153 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisArray& basis,
00154   const RCP<DOFMapBase>& map,
00155   const VectorType<double>& vecType,
00156   int setupVerb)
00157   : map_(map), 
00158     mesh_(mesh),
00159     subdomains_(),
00160     basis_(),
00161     vecSpace_(), 
00162     vecType_(vecType),
00163     ghostImporter_()
00164   ,transformationBuilder_(0)
00165 {
00166   init(map->funcDomains(), basis);
00167 }
00168 
00169 
00170 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisFamily& basis,
00171   const SpectralBasis& spBasis,
00172   const VectorType<double>& vecType,
00173   int setupVerb)
00174   : setupVerb_(setupVerb),
00175     map_(),
00176     mesh_(mesh), 
00177     subdomains_(),
00178     basis_(),
00179     vecSpace_(), 
00180     vecType_(vecType),
00181     ghostImporter_()
00182   ,transformationBuilder_(0)
00183 {
00184   init(maximalRegions(spBasis.nterms()), 
00185     replicate(basis, spBasis.nterms()));
00186 }
00187 
00188 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisArray& basis,
00189   const SpectralBasis& spBasis,
00190   const VectorType<double>& vecType,
00191   int setupVerb)
00192   : setupVerb_(setupVerb),
00193     map_(), 
00194     mesh_(mesh), 
00195     subdomains_(),
00196     basis_(),
00197     vecSpace_(), 
00198     vecType_(vecType),
00199     ghostImporter_()
00200   ,transformationBuilder_(0)
00201 {
00202   init(maximalRegions(basis.size() * spBasis.nterms()), 
00203     replicate(basis, spBasis.nterms()));
00204 }
00205 
00206 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisArray& basis,
00207   const RCP<FunctionSupportResolver>& fsr,
00208   const VectorType<double>& vecType,
00209   int setupVerb)
00210   : setupVerb_(setupVerb),
00211     map_(), 
00212     mesh_(mesh), 
00213     subdomains_(),
00214     basis_(basis),
00215     vecSpace_(), 
00216     vecType_(vecType),
00217     ghostImporter_()
00218   ,transformationBuilder_(new DiscreteSpaceTransfBuilder())
00219 {
00220   bool partitionBCs = false;
00221   DOFMapBuilder builder(mesh, fsr, partitionBCs, setupVerb);
00222 
00223   map_ = builder.colMap()[0];
00224   Array<Set<CellFilter> > cf = builder.unkCellFilters()[0];
00225 
00226   for (int i=0; i<cf.size(); i++)
00227   {
00228     Array<Array<CellFilter> > dimCF(mesh.spatialDim()+1);
00229     for (Set<CellFilter>::const_iterator 
00230            iter=cf[i].begin(); iter != cf[i].end(); iter++)
00231     {
00232       CellFilter f = *iter;
00233       int dim = f.dimension(mesh);
00234       dimCF[dim].append(f);
00235     }
00236     for (int d=mesh.spatialDim(); d>=0; d--)
00237     {
00238       if (dimCF[d].size() == 0) continue;
00239       CellFilter f = dimCF[d][0];
00240       for (int j=1; j<dimCF[d].size(); j++)
00241       {
00242         f = f + dimCF[d][j];
00243       }
00244       subdomains_.append(f);
00245       break;
00246     }
00247   }
00248   RCP<Array<int> > dummyBCIndices;
00249   
00250   // set up the transformation
00251   transformationBuilder_ = rcp(new DiscreteSpaceTransfBuilder( mesh , basis , map_ ));
00252 
00253   initVectorSpace(dummyBCIndices, partitionBCs);
00254   initImporter();
00255 }
00256 
00257 void DiscreteSpace::init(
00258   const Array<CellFilter>& regions,
00259   const BasisArray& basis)
00260 {
00261   RCP<Array<int> > dummyBCIndices;
00262   init(regions, basis, dummyBCIndices, false);
00263 }
00264 
00265 void DiscreteSpace::init(
00266   const Array<CellFilter>& regions,
00267   const BasisArray& basis,
00268   const RCP<Array<int> >& isBCIndex, 
00269   bool partitionBCs)
00270 {
00271   basis_ = basis;
00272   subdomains_ = regions;
00273   Array<RCP<BasisDOFTopologyBase> > basisTop(basis.size());
00274   for (int b=0; b<basis.size(); b++)
00275   {
00276     basisTop[b] = rcp_dynamic_cast<BasisDOFTopologyBase>(basis[b].ptr());
00277   }
00278 
00279   if (map_.get()==0) 
00280   {
00281     Array<Set<CellFilter> > cf(regions.size());
00282     for (int i=0; i<regions.size(); i++) cf[i] = makeSet(regions[i]);
00283     DOFMapBuilder b(setupVerb_);
00284     map_ = b.makeMap(mesh_, basisTop, cf);
00285   }
00286 
00287   // set up the transformation
00288   transformationBuilder_ = rcp(new DiscreteSpaceTransfBuilder( mesh_ , basis , map_ ));
00289 
00290   initVectorSpace(isBCIndex, partitionBCs);
00291 
00292   if (!partitionBCs)
00293   {
00294     initImporter();
00295   }
00296 }
00297 
00298 void DiscreteSpace::initVectorSpace(
00299   const RCP<Array<int> >& isBCIndex, 
00300   bool partitionBCs)
00301 {
00302   TEST_FOR_EXCEPTION(map_.get()==0, InternalError,
00303     "uninitialized map");
00304 
00305   int nDof = map_->numLocalDOFs();
00306   int lowDof = map_->lowestLocalDOF();
00307 
00308   if (partitionBCs)
00309   {
00310     TEST_FOR_EXCEPT(isBCIndex.get() == 0);
00311 
00312     int nBCDofs = 0;
00313     for (int i=0; i<nDof; i++)
00314     {
00315       if ((*isBCIndex)[i]) nBCDofs++;
00316     }
00317     
00318     int nTotalBCDofs = nBCDofs;
00319     mesh().comm().allReduce(&nBCDofs, &nTotalBCDofs, 1, MPIComm::INT, MPIComm::SUM);
00320     int nTotalInteriorDofs = map_->numDOFs() - nTotalBCDofs;
00321 
00322     Array<int> interiorDofs(nDof - nBCDofs);
00323     Array<int> bcDofs(nBCDofs);
00324     int iBC = 0;
00325     int iIn = 0;
00326     for (int i=0; i<nDof; i++)
00327     {
00328       if ((*isBCIndex)[i]) bcDofs[iBC++] = lowDof+i;
00329       else interiorDofs[iIn++] = lowDof+i;
00330     }
00331     const int* bcDofPtr = vecPtr(bcDofs);
00332     const int* intDofPtr = vecPtr(interiorDofs);
00333     VectorSpace<double> bcSpace = vecType_.createSpace(nTotalBCDofs, nBCDofs,
00334       bcDofPtr, mesh().comm());
00335     VectorSpace<double> interiorSpace = vecType_.createSpace(nTotalInteriorDofs, nDof-nBCDofs,
00336       intDofPtr, mesh().comm());
00337 
00338     vecSpace_ = productSpace<double>(interiorSpace, bcSpace);
00339   }
00340   else
00341   {
00342     Array<int> dofs(nDof);
00343     for (int i=0; i<nDof; i++) dofs[i] = lowDof + i;
00344     
00345     vecSpace_ = vecType_.createSpace(map_->numDOFs(),
00346       map_->numLocalDOFs(),
00347       &(dofs[0]), mesh().comm());
00348   }
00349 }
00350 
00351 void DiscreteSpace::initImporter()
00352 {
00353   TEST_FOR_EXCEPTION(map_.get()==0, InternalError,
00354     "uninitialized map");
00355   TEST_FOR_EXCEPTION(vecSpace_.ptr().get()==0, InternalError,
00356     "uninitialized vector space");
00357   TEST_FOR_EXCEPTION(vecType_.ptr().get()==0, InternalError,
00358     "uninitialized vector type");
00359   
00360   RCP<Array<int> > ghostIndices = map_->ghostIndices();
00361   int nGhost = ghostIndices->size();
00362   int* ghosts = 0;
00363   if (nGhost!=0) ghosts = &((*ghostIndices)[0]);
00364   ghostImporter_ = vecType_.createGhostImporter(vecSpace_, nGhost, ghosts);
00365 }
00366 
00367 
00368 Array<CellFilter> DiscreteSpace::maximalRegions(int n) const
00369 {
00370   CellFilter cf = new MaximalCellFilter();
00371   Array<CellFilter> rtn(n, cf);
00372   return rtn;
00373 }
00374 
00375 
00376 
00377 void DiscreteSpace::importGhosts(const Vector<double>& x,
00378   RCP<GhostView<double> >& ghostView) const
00379 {
00380   ghostImporter_->importView(x, ghostView);
00381 }

Site Contact