SundanceDiscreteSpace.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 #include "SundanceDiscreteSpace.hpp"
00043 #include "SundanceDOFMapBuilder.hpp"
00044 #include "SundanceFunctionSupportResolver.hpp"
00045 #include "SundanceOut.hpp"
00046 #include "SundanceMaximalCellFilter.hpp"
00047 #include "PlayaDefaultBlockVectorSpaceDecl.hpp"
00048 #include "PlayaMPIContainerComm.hpp"
00049 
00050 
00051 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00052 #include "PlayaVectorImpl.hpp"
00053 #include "PlayaDefaultBlockVectorImpl.hpp"
00054 #endif
00055 
00056 
00057 using namespace Sundance;
00058 using namespace Teuchos;
00059 using Playa::blockSpace;
00060 using Playa::MPIComm;
00061 using Playa::MPIContainerComm;
00062 using Playa::MPIDataType;
00063 using Playa::MPIOp;
00064 
00065 const int* vecPtr(const Array<int>& x)
00066 {
00067   static const int* dum = 0;
00068   if (x.size()==0) return dum;
00069   else return &(x[0]);
00070 }
00071 
00072 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisFamily& basis,
00073   const VectorType<double>& vecType,
00074   int setupVerb)
00075   : setupVerb_(setupVerb), 
00076     map_(),
00077     mesh_(mesh), 
00078     subdomains_(),
00079     basis_(),
00080     vecSpace_(), 
00081     vecType_(vecType),
00082     ghostImporter_()
00083   ,transformationBuilder_(0)
00084 {
00085   init(maximalRegions(1), BasisArray(tuple(basis)));
00086 }
00087 
00088 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisArray& basis,
00089   const VectorType<double>& vecType,
00090   int setupVerb)
00091   : setupVerb_(setupVerb),
00092     map_(), 
00093     mesh_(mesh), 
00094     subdomains_(),
00095     basis_(),
00096     vecSpace_(), 
00097     vecType_(vecType),
00098     ghostImporter_()
00099   ,transformationBuilder_(0)
00100 {
00101   init(maximalRegions(basis.size()), basis);
00102 }
00103 
00104 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisArray& basis,
00105   const Array<CellFilter>& funcDomains,
00106   const VectorType<double>& vecType,
00107   int setupVerb)
00108   : setupVerb_(setupVerb),
00109     map_(), 
00110     mesh_(mesh), 
00111     subdomains_(),
00112     basis_(),
00113     vecSpace_(), 
00114     vecType_(vecType),
00115     ghostImporter_()
00116   ,transformationBuilder_(0)
00117 {
00118   init(funcDomains, basis);
00119 }
00120 
00121 
00122 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisFamily& basis,
00123   const CellFilter& funcDomains,
00124   const VectorType<double>& vecType,
00125   int setupVerb)
00126   : setupVerb_(setupVerb),
00127     map_(), 
00128     mesh_(mesh), 
00129     subdomains_(),
00130     basis_(),
00131     vecSpace_(), 
00132     vecType_(vecType),
00133     ghostImporter_()
00134   ,transformationBuilder_(0)
00135 {
00136   init(tuple(funcDomains), BasisArray(tuple(basis)));
00137 }
00138 
00139 
00140 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisArray& basis,
00141   const CellFilter& funcDomains,
00142   const VectorType<double>& vecType,
00143   int setupVerb)
00144   : setupVerb_(setupVerb),
00145     map_(), 
00146     mesh_(mesh), 
00147     subdomains_(),
00148     basis_(),
00149     vecSpace_(), 
00150     vecType_(vecType),
00151     ghostImporter_()
00152   ,transformationBuilder_(0)
00153 {
00154   init(Array<CellFilter>(basis.size(), funcDomains), basis);
00155 }
00156 
00157 
00158 
00159 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisArray& basis,
00160   const RCP<DOFMapBase>& map,
00161   const RCP<Array<int> >& bcIndices,
00162   const VectorType<double>& vecType,
00163   int setupVerb)
00164   : setupVerb_(setupVerb),
00165     map_(map), 
00166     mesh_(mesh),
00167     subdomains_(),
00168     basis_(),
00169     vecSpace_(), 
00170     vecType_(vecType),
00171     ghostImporter_()
00172   ,transformationBuilder_(0)
00173 {
00174   init(map->funcDomains(), basis, bcIndices, true);
00175 }
00176 
00177 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisArray& basis,
00178   const RCP<DOFMapBase>& map,
00179   const VectorType<double>& vecType,
00180   int setupVerb)
00181   : map_(map), 
00182     mesh_(mesh),
00183     subdomains_(),
00184     basis_(),
00185     vecSpace_(), 
00186     vecType_(vecType),
00187     ghostImporter_()
00188   ,transformationBuilder_(0)
00189 {
00190   init(map->funcDomains(), basis);
00191 }
00192 
00193 
00194 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisFamily& basis,
00195   const SpectralBasis& spBasis,
00196   const VectorType<double>& vecType,
00197   int setupVerb)
00198   : setupVerb_(setupVerb),
00199     map_(),
00200     mesh_(mesh), 
00201     subdomains_(),
00202     basis_(),
00203     vecSpace_(), 
00204     vecType_(vecType),
00205     ghostImporter_()
00206   ,transformationBuilder_(0)
00207 {
00208   init(maximalRegions(spBasis.nterms()), 
00209     replicate(basis, spBasis.nterms()));
00210 }
00211 
00212 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisArray& basis,
00213   const SpectralBasis& spBasis,
00214   const VectorType<double>& vecType,
00215   int setupVerb)
00216   : setupVerb_(setupVerb),
00217     map_(), 
00218     mesh_(mesh), 
00219     subdomains_(),
00220     basis_(),
00221     vecSpace_(), 
00222     vecType_(vecType),
00223     ghostImporter_()
00224   ,transformationBuilder_(0)
00225 {
00226   init(maximalRegions(basis.size() * spBasis.nterms()), 
00227     replicate(basis, spBasis.nterms()));
00228 }
00229 
00230 DiscreteSpace::DiscreteSpace(const Mesh& mesh, const BasisArray& basis,
00231   const RCP<FunctionSupportResolver>& fsr,
00232   const VectorType<double>& vecType,
00233   int setupVerb)
00234   : setupVerb_(setupVerb),
00235     map_(), 
00236     mesh_(mesh), 
00237     subdomains_(),
00238     basis_(basis),
00239     vecSpace_(), 
00240     vecType_(vecType),
00241     ghostImporter_()
00242   ,transformationBuilder_(new DiscreteSpaceTransfBuilder())
00243 {
00244   bool partitionBCs = false;
00245   DOFMapBuilder builder(mesh, fsr, partitionBCs, setupVerb);
00246 
00247   map_ = builder.colMap()[0];
00248   Array<Set<CellFilter> > cf = builder.unkCellFilters()[0];
00249 
00250   for (int i=0; i<cf.size(); i++)
00251   {
00252     Array<Array<CellFilter> > dimCF(mesh.spatialDim()+1);
00253     for (Set<CellFilter>::const_iterator 
00254            iter=cf[i].begin(); iter != cf[i].end(); iter++)
00255     {
00256       CellFilter f = *iter;
00257       int dim = f.dimension(mesh);
00258       dimCF[dim].append(f);
00259     }
00260     for (int d=mesh.spatialDim(); d>=0; d--)
00261     {
00262       if (dimCF[d].size() == 0) continue;
00263       CellFilter f = dimCF[d][0];
00264       for (int j=1; j<dimCF[d].size(); j++)
00265       {
00266         f = f + dimCF[d][j];
00267       }
00268       subdomains_.append(f);
00269       break;
00270     }
00271   }
00272   RCP<Array<int> > dummyBCIndices;
00273   
00274   // set up the transformation
00275   transformationBuilder_ = rcp(new DiscreteSpaceTransfBuilder( mesh , basis , map_ ));
00276 
00277   initVectorSpace(dummyBCIndices, partitionBCs);
00278   initImporter();
00279 }
00280 
00281 void DiscreteSpace::init(
00282   const Array<CellFilter>& regions,
00283   const BasisArray& basis)
00284 {
00285   RCP<Array<int> > dummyBCIndices;
00286   init(regions, basis, dummyBCIndices, false);
00287 }
00288 
00289 void DiscreteSpace::init(
00290   const Array<CellFilter>& regions,
00291   const BasisArray& basis,
00292   const RCP<Array<int> >& isBCIndex, 
00293   bool partitionBCs)
00294 {
00295   basis_ = basis;
00296   subdomains_ = regions;
00297   Array<RCP<BasisDOFTopologyBase> > basisTop(basis.size());
00298   for (int b=0; b<basis.size(); b++)
00299   {
00300     basisTop[b] = rcp_dynamic_cast<BasisDOFTopologyBase>(basis[b].ptr());
00301   }
00302 
00303   if (map_.get()==0) 
00304   {
00305     Array<Set<CellFilter> > cf(regions.size());
00306     for (int i=0; i<regions.size(); i++) cf[i] = makeSet(regions[i]);
00307     DOFMapBuilder b(setupVerb_);
00308     map_ = b.makeMap(mesh_, basisTop, cf);
00309   }
00310 
00311   // set up the transformation
00312   transformationBuilder_ = rcp(new DiscreteSpaceTransfBuilder( mesh_ , basis , map_ ));
00313 
00314   initVectorSpace(isBCIndex, partitionBCs);
00315 
00316   if (!partitionBCs)
00317   {
00318     initImporter();
00319   }
00320 }
00321 
00322 void DiscreteSpace::initVectorSpace(
00323   const RCP<Array<int> >& isBCIndex, 
00324   bool partitionBCs)
00325 {
00326   TEUCHOS_TEST_FOR_EXCEPTION(map_.get()==0, std::logic_error,
00327     "uninitialized map");
00328 
00329   int nDof = map_->numLocalDOFs();
00330   int lowDof = map_->lowestLocalDOF();
00331 
00332   if (partitionBCs)
00333   {
00334     TEUCHOS_TEST_FOR_EXCEPT(isBCIndex.get() == 0);
00335 
00336     int nBCDofs = 0;
00337     for (int i=0; i<nDof; i++)
00338     {
00339       if ((*isBCIndex)[i]) nBCDofs++;
00340     }
00341     
00342     int nTotalBCDofs = nBCDofs;
00343     mesh().comm().allReduce(&nBCDofs, &nTotalBCDofs, 1, MPIDataType::intType(), MPIOp::sumOp());
00344     int nTotalInteriorDofs = map_->numDOFs() - nTotalBCDofs;
00345 
00346     Array<int> interiorDofs(nDof - nBCDofs);
00347     Array<int> bcDofs(nBCDofs);
00348     int iBC = 0;
00349     int iIn = 0;
00350     for (int i=0; i<nDof; i++)
00351     {
00352       if ((*isBCIndex)[i]) bcDofs[iBC++] = lowDof+i;
00353       else interiorDofs[iIn++] = lowDof+i;
00354     }
00355     const int* bcDofPtr = vecPtr(bcDofs);
00356     const int* intDofPtr = vecPtr(interiorDofs);
00357     VectorSpace<double> bcSpace = vecType_.createSpace(nTotalBCDofs, nBCDofs,
00358       bcDofPtr, mesh().comm());
00359     VectorSpace<double> interiorSpace = vecType_.createSpace(nTotalInteriorDofs, nDof-nBCDofs,
00360       intDofPtr, mesh().comm());
00361 
00362     vecSpace_ = blockSpace<double>(interiorSpace, bcSpace);
00363   }
00364   else
00365   {
00366     Array<int> dofs(nDof);
00367     for (int i=0; i<nDof; i++) dofs[i] = lowDof + i;
00368     
00369     vecSpace_ = vecType_.createSpace(map_->numDOFs(),
00370       map_->numLocalDOFs(),
00371       &(dofs[0]), mesh().comm());
00372   }
00373 }
00374 
00375 void DiscreteSpace::initImporter()
00376 {
00377   TEUCHOS_TEST_FOR_EXCEPTION(map_.get()==0, std::logic_error,
00378     "uninitialized map");
00379   TEUCHOS_TEST_FOR_EXCEPTION(vecSpace_.ptr().get()==0, std::logic_error,
00380     "uninitialized vector space");
00381   TEUCHOS_TEST_FOR_EXCEPTION(vecType_.ptr().get()==0, std::logic_error,
00382     "uninitialized vector type");
00383   
00384   RCP<Array<int> > ghostIndices = map_->ghostIndices();
00385   int nGhost = ghostIndices->size();
00386   int* ghosts = 0;
00387   if (nGhost!=0) ghosts = &((*ghostIndices)[0]);
00388   ghostImporter_ = vecType_.createGhostImporter(vecSpace_, nGhost, ghosts);
00389 }
00390 
00391 
00392 Array<CellFilter> DiscreteSpace::maximalRegions(int n) const
00393 {
00394   CellFilter cf = new MaximalCellFilter();
00395   Array<CellFilter> rtn(n, cf);
00396   return rtn;
00397 }
00398 
00399 
00400 
00401 void DiscreteSpace::importGhosts(const Vector<double>& x,
00402   RCP<GhostView<double> >& ghostView) const
00403 {
00404   ghostImporter_->importView(x, ghostView);
00405 }

Site Contact