void PiecewiseLinearDiscontinuousScalarSpace<BasisFunctionType>::assignDofsImpl( const GridSegment &segment, bool strictlyOnSegment) { const int gridDim = this->domainDimension(); const Mapper &elementMapper = m_view->elementMapper(); const IndexSet &indexSet = m_view->indexSet(); // int globalDofCount_ = m_view->entityCount(this->grid()->dim()); int elementCount = m_view->entityCount(0); // (Re)initialise DOF maps m_local2globalDofs.clear(); m_local2globalDofs.resize(elementCount); m_global2localDofs.clear(); // estimated number of global DOFs m_global2localDofs.reserve(4 * elementCount); // TODO: consider calling reserve(x) for each element of m_global2localDofs // with x being the typical number of elements adjacent to a vertex in a // grid of dimension gridDim // Iterate over elements std::unique_ptr<EntityIterator<0>> it = m_view->entityIterator<0>(); size_t globalDofCount = 0; while (!it->finished()) { const Entity<0> &element = it->entity(); EntityIndex elementIndex = elementMapper.entityIndex(element); int vertexCount; if (gridDim == 1) vertexCount = element.template subEntityCount<1>(); else // gridDim == 2 vertexCount = element.template subEntityCount<2>(); // List of global DOF indices corresponding to the local DOFs of the // current element std::vector<GlobalDofIndex> &globalDofs = m_local2globalDofs[elementIndex]; globalDofs.reserve(vertexCount); for (int i = 0; i < vertexCount; ++i) { int vertexIndex = indexSet.subEntityIndex(element, i, gridDim); if ((strictlyOnSegment && segment.contains(0, elementIndex)) || (!strictlyOnSegment && segment.contains(gridDim, vertexIndex))) { globalDofs.push_back(globalDofCount); std::vector<LocalDof> localDofs(1, LocalDof(elementIndex, i)); m_global2localDofs.push_back(localDofs); ++globalDofCount; } else globalDofs.push_back(-1); } it->next(); } // Initialize the container mapping the flat local dof indices to // local dof indices SpaceHelper<BasisFunctionType>::initializeLocal2FlatLocalDofMap( globalDofCount, m_local2globalDofs, m_flatLocal2localDofs); }
void SpaceHelper<BasisFunctionType>::initializeLocal2FlatLocalDofMap( size_t flatLocalDofCount, const std::vector<std::vector<GlobalDofIndex>> &local2globalDofs, std::vector<LocalDof> &flatLocal2localDofs) { flatLocal2localDofs.clear(); flatLocal2localDofs.reserve(flatLocalDofCount); for (size_t e = 0; e < local2globalDofs.size(); ++e) for (size_t dof = 0; dof < acc(local2globalDofs, e).size(); ++dof) if (acc(acc(local2globalDofs, e), dof) >= 0) flatLocal2localDofs.push_back(LocalDof(e, dof)); }
void PiecewiseConstantDiscontinuousScalarSpaceBarycentric< BasisFunctionType>::assignDofsImpl(const GridSegment &segment) { const GridView &view = this->gridView(); std::unique_ptr<GridView> viewCoarseGridPtr = this->grid()->levelView(0); const GridView &viewCoarseGrid = *viewCoarseGridPtr; const Mapper &elementMapper = view.elementMapper(); const Mapper &elementMapperCoarseGrid = viewCoarseGrid.elementMapper(); int elementCount = view.entityCount(0); int elementCountCoarseGrid = viewCoarseGrid.entityCount(0); // Assign gdofs to grid vertices (choosing only those that belong to // the selected grid segment) std::vector<int> continuousDofIndices(elementCountCoarseGrid, 0); segment.markExcludedEntities(0, continuousDofIndices); int continuousDofCount_ = 0; for (int elementIndex = 0; elementIndex < elementCountCoarseGrid; ++elementIndex) if (acc(continuousDofIndices, elementIndex) == 0) // not excluded acc(continuousDofIndices, elementIndex) = continuousDofCount_++; // (Re)initialise DOF maps m_local2globalDofs.clear(); m_local2globalDofs.resize(elementCount); m_global2localDofs.clear(); m_global2localDofs.reserve(elementCount); // Iterate over elements std::unique_ptr<EntityIterator<0>> itCoarseGrid = viewCoarseGrid.entityIterator<0>(); int flatLocalDofCount_ = 0; while (!itCoarseGrid->finished()) { const Entity<0> &elementCoarseGrid = itCoarseGrid->entity(); EntityIndex elementIndexCoarseGrid = elementMapperCoarseGrid.entityIndex(elementCoarseGrid); // Iterate through refined elements std::unique_ptr<EntityIterator<0>> sonIt = elementCoarseGrid.sonIterator(this->grid()->maxLevel()); while (!sonIt->finished()) { const Entity<0> &element = sonIt->entity(); int elementIndex = elementMapper.entityIndex(element); std::vector<GlobalDofIndex> &globalDofs = acc(m_local2globalDofs, elementIndex); int continuousDofIndex = acc(continuousDofIndices, elementIndexCoarseGrid); if (continuousDofIndex != -1) { globalDofs.push_back(flatLocalDofCount_); m_global2localDofs.push_back(std::vector<LocalDof>()); acc(m_global2localDofs, flatLocalDofCount_) .push_back(LocalDof(elementIndex, 0)); ++flatLocalDofCount_; } else { globalDofs.push_back(-1); } sonIt->next(); } itCoarseGrid->next(); } // Initialize the container mapping the flat local dof indices to // local dof indices SpaceHelper<BasisFunctionType>::initializeLocal2FlatLocalDofMap( flatLocalDofCount_, m_local2globalDofs, m_flatLocal2localDofs); }
void PiecewiseLinearDiscontinuousScalarSpaceBarycentric<BasisFunctionType>::assignDofsImpl() { const int gridDim = this->domainDimension(); const int elementCodim = 0; const GridView& view = this->gridView(); std::auto_ptr<GridView> viewCoarseGridPtr = this->grid()->levelView(0); const GridView& viewCoarseGrid = *viewCoarseGridPtr; const Mapper& elementMapper = view.elementMapper(); const Mapper& elementMapperCoarseGrid = viewCoarseGrid.elementMapper(); int elementCount = view.entityCount(0); int vertexCount = view.entityCount(gridDim); int vertexCountCoarseGrid = viewCoarseGrid.entityCount(gridDim); int elementCountCoarseGrid = viewCoarseGrid.entityCount(0); const IndexSet& indexSetCoarseGrid = viewCoarseGrid.indexSet(); // Assign gdofs to grid vertices (choosing only those that belong to // the selected grid segment) std::vector<int> globalDofIndicesContinuous(vertexCountCoarseGrid, 0); m_segment.markExcludedEntities(gridDim, globalDofIndicesContinuous); std::vector<bool> segmentContainsElement; if (m_strictlyOnSegment) { std::vector<bool> noAdjacentElementsInsideSegment(vertexCountCoarseGrid, true); segmentContainsElement.resize(elementCountCoarseGrid); std::auto_ptr<EntityIterator<0> > itCoarseGrid = viewCoarseGrid.entityIterator<0>(); while (!itCoarseGrid->finished()) { const Entity<0>& elementCoarseGrid = itCoarseGrid->entity(); EntityIndex elementIndexCoarseGrid = elementMapperCoarseGrid.entityIndex(elementCoarseGrid); bool elementContained = m_segment.contains(elementCodim, elementIndexCoarseGrid); acc(segmentContainsElement, elementIndexCoarseGrid) = elementContained; int cornerCount; if (gridDim == 1) cornerCount = elementCoarseGrid.template subEntityCount<1>(); else // gridDim == 2 cornerCount = elementCoarseGrid.template subEntityCount<2>(); if (elementContained) for (int i = 0; i < cornerCount; ++i) { int vertexIndexCoarseGrid = indexSetCoarseGrid.subEntityIndex(elementCoarseGrid,i,gridDim); acc(noAdjacentElementsInsideSegment, vertexIndexCoarseGrid) = false; } itCoarseGrid->next(); } // Remove all DOFs associated with vertices lying next to no element // belonging to the grid segment for (size_t i = 0; i < vertexCount; ++i) if (acc(noAdjacentElementsInsideSegment, i)) acc(globalDofIndicesContinuous, i) = -1; } int globalDofCount_ = 0; for (int vertexIndex = 0; vertexIndex < vertexCountCoarseGrid; ++vertexIndex) if (acc(globalDofIndicesContinuous, vertexIndex) == 0) // not excluded acc(globalDofIndicesContinuous, vertexIndex) = globalDofCount_++; // (Re)initialise DOF maps m_local2globalDofs.clear(); m_local2globalDofs.resize(elementCount); m_global2localDofs.clear(); m_global2localDofs.reserve(3*elementCount); m_elementIndex2Type.resize(elementCount); m_flatLocal2localDofs.clear(); m_flatLocal2localDofs.reserve(3*elementCount); // TODO: consider calling reserve(x) for each element of m_global2localDofs // with x being the typical number of elements adjacent to a vertex in a // grid of dimension gridDim const int element2Basis[6][3] = {{0,1,2}, {0,1,2}, {2,0,1}, {2,0,1}, {1,2,0}, {1,2,0}}; // element2Basis[i][j] is the basis fct. associated with the jth vertex // on element i. // Iterate over elements std::auto_ptr<EntityIterator<0> > itCoarseGrid = viewCoarseGrid.entityIterator<0>(); int flatLocalDofCount_ = 0; while (!itCoarseGrid->finished()) { const Entity<0>& elementCoarseGrid = itCoarseGrid->entity(); EntityIndex elementIndexCoarseGrid = elementMapperCoarseGrid.entityIndex(elementCoarseGrid); bool elementContained = m_strictlyOnSegment ? acc(segmentContainsElement, elementIndexCoarseGrid) : true; // Iterate through refined elements std::auto_ptr<EntityIterator<0> > sonIt = elementCoarseGrid.sonIterator(this->grid()->maxLevel()); int sonCounter = 5; while (!sonIt->finished()){ const Entity<0>& element = sonIt->entity(); int elementIndex = elementMapper.entityIndex(element); int cornerCount = 3; if (sonCounter%2==0){ acc(m_elementIndex2Type,elementIndex) = Shapeset::TYPE1; } else { acc(m_elementIndex2Type,elementIndex) = Shapeset::TYPE2; } std::vector<GlobalDofIndex>& globalDofs = acc(m_local2globalDofs, elementIndex); globalDofs.resize(cornerCount); for (int i=0;i<cornerCount;++i){ int basisNumber = element2Basis[sonCounter][i]; EntityIndex vertexIndex = indexSetCoarseGrid.subEntityIndex(elementCoarseGrid,i,gridDim); int globalDofIndexContinuous = elementContained ? acc(globalDofIndicesContinuous,vertexIndex) : -1; //acc(globalDofs,basisNumber)=globalDofIndex; if (globalDofIndexContinuous >=0){ acc(globalDofs,basisNumber)=flatLocalDofCount_; m_global2localDofs.push_back(std::vector<LocalDof>()); m_flatLocal2localDofs.push_back(LocalDof(elementIndex,basisNumber)); acc(m_global2localDofs, flatLocalDofCount_).push_back( LocalDof(elementIndex, basisNumber)); ++flatLocalDofCount_; } else { acc(globalDofs,basisNumber) = -1; } } sonIt->next(); sonCounter--; // The Foamgrid iterator gives son elements in reverse order } itCoarseGrid->next(); } // Now we have the variables from the continuous space setup. We can now define the discontinuous space. // Initialize the container mapping the flat local dof indices to // local dof indices //SpaceHelper<BasisFunctionType>::initializeLocal2FlatLocalDofMap( // flatLocalDofCount_, local2globalDofsCont, m_flatLocal2localDofs); }