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
00032
00033
00034
00035
00036
00037
00038
00039
00040
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
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
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 }