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);
}
Exemple #2
0
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);

}