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 "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
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
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 }