예제 #1
0
void peanoclaw::interSubgridCommunication::GridLevelTransfer::stepUp(
  Patch*                               coarseSubgrid,
  Patch&                               finePatch,
  ParallelSubgrid&                     fineParallelSubgrid,
  bool                                 isPeanoCellLeaf,
  peanoclaw::Vertex * const            fineGridVertices,
  const peano::grid::VertexEnumerator& fineGridVerticesEnumerator
) {

  //Correct time intervals for virtual subgrid or going-to-be virtual subgrid
  if(!finePatch.isLeaf() || !isPeanoCellLeaf) {
    finePatch.switchValuesAndTimeIntervalToMinimalFineGridTimeInterval();
    assertion1(tarch::la::greaterEquals(finePatch.getTimeIntervals().getTimestepSize(), 0) || !isPeanoCellLeaf, finePatch);
  }

  //Update fine grid time interval on next coarser patch if possible
  if(coarseSubgrid != 0) {
    //Patch coarsePatch(coarseCellDescriptionIndex);
    coarseSubgrid->getTimeIntervals().updateMinimalFineGridTimeInterval(
      finePatch.getTimeIntervals().getCurrentTime(),
      finePatch.getTimeIntervals().getTimestepSize()
    );
  }

  if(finePatch.isLeaf()) {
    restrictToOverlappingVirtualSubgrids(finePatch, fineParallelSubgrid);

    //TODO unterweg dissertation:
    //If the patch is leaf, but the Peano cell is not, it got refined.
    //Thus, the patch was not turned to a virtual patch to avoid
    //restriction to this patch, which would lead to invalid data, since
    //the patch is not initialized with zeros. So, the patch needs to
    //be switched to refined (i.e. non-virtual) here...
    if(!isPeanoCellLeaf) {
      finePatch.switchToVirtual();

      //Fill ghostlayer
      for(int i = 0; i < TWO_POWER_D; i++) {

        fineGridVertices[fineGridVerticesEnumerator(i)].fillAdjacentGhostLayers(
          finePatch.getLevel(),
          _useDimensionalSplitting,
          _numerics,
          #ifdef PEANOCLAW_USE_ASCEND_FOR_RESTRICTION
          tarch::la::multiplyComponents(peano::utils::dDelinearised(i, 2).convertScalar<double>(), finePatch.getSize()) + finePatch.getPosition(),
          #else
          fineGridVerticesEnumerator.getVertexPosition(i),
          #endif
          _subgridStatistics
        );
      }

      finePatch.switchToNonVirtual();

      ParallelSubgrid parallelSubgrid(finePatch);
      parallelSubgrid.markCurrentStateAsSent(false);
    }
  } else if (finePatch.isVirtual()) {
    finalizeVirtualSubgrid(
      finePatch,
      fineGridVertices,
      fineGridVerticesEnumerator,
      isPeanoCellLeaf
    );
  }

  //If patch wasn't refined -> look if veto for coarsening is necessary
  if(!finePatch.isLeaf()) {
    vetoCoarseningIfNecessary(
      finePatch,
      fineGridVertices,
      fineGridVerticesEnumerator
    );
  }

  //Reset time constraint for optimization of ghostlayer filling
//  finePatch.resetMinimalNeighborTimeConstraint();
}
예제 #2
0
void peanoclaw::interSubgridCommunication::GridLevelTransfer::restrictToOverlappingVirtualSubgrids(
  Patch&           subgrid,
  ParallelSubgrid& parallelSubgrid
) {
  tarch::multicore::Lock lock(_virtualPatchListSemaphore);

  //Restrict to all
  //for(int i = 0;  i < (int)_virtualPatchDescriptionIndices.size(); i++) {
  for(VirtualSubgridMap::iterator i = _virtualPatchDescriptionIndices.begin();
      i != _virtualPatchDescriptionIndices.end();
      i++) {
    int virtualSubgridDescriptionIndex = i->second;
    CellDescription& virtualSubgridDescription = CellDescriptionHeap::getInstance().getData(virtualSubgridDescriptionIndex).at(0);
    Patch virtualSubgrid(virtualSubgridDescription);
    ParallelSubgrid virtualParallelSubgrid(virtualSubgridDescription);

    // Restrict only if coarse patches can advance in time
    bool areAllCoarseSubgridsBlocked
    = tarch::la::smaller(
        subgrid.getTimeIntervals().getCurrentTime() + subgrid.getTimeIntervals().getTimestepSize(),
        virtualSubgrid.getTimeIntervals().getMinimalLeafNeighborTimeConstraint()
      );
    // Restrict only if this patch is overlapped by neighboring ghostlayers
    bool isOverlappedByCoarseGhostlayers
      = tarch::la::oneGreater(virtualSubgrid.getUpperNeighboringGhostlayerBounds(), subgrid.getPosition())
        || tarch::la::oneGreater(subgrid.getPosition() + subgrid.getSize(), virtualSubgrid.getLowerNeighboringGhostlayerBounds());

    bool subgridOverlapsVirtualSubgrid = !tarch::la::oneGreater(virtualSubgrid.getPosition(), subgrid.getPosition())
                                      && !tarch::la::oneGreater(subgrid.getPosition() + subgrid.getSize(), virtualSubgrid.getPosition() + virtualSubgrid.getSize());

    //TODO unterweg debug
//    if(tarch::la::equals(subgrid.getPosition()(0), 10.0*2.0/3.0)
//      &&tarch::la::equals(subgrid.getPosition()(1), 10.0*2.0/3.0)) {
//      std::cout << "Restricting from " << subgrid
//          << ", isOverlapped=" << isOverlappedByCoarseGhostlayers
//          << ", areAllCoarseSubgridsBlocked=" << areAllCoarseSubgridsBlocked
//          << ", willCoarsen=" << virtualSubgrid.willCoarsen()
//          << std::endl << subgrid.toStringUNew() << std::endl
//          << " to " << virtualSubgrid << std::endl << virtualSubgrid.toStringUNew() << std::endl;
//    }

    if(
      subgridOverlapsVirtualSubgrid &&
      (
        // Restrict if virtual subgrid is coarsening or if the data on the virtual subgrid is required for timestepping
        virtualSubgrid.willCoarsen()
        || (!areAllCoarseSubgridsBlocked && isOverlappedByCoarseGhostlayers)
        //TODO unterweg dissertation: Es kann sein, dass ein Nachbarsubgitter vom groben Subgitter noch nicht angekommen ist, wenn
        //das Gitter gerade verteilt wurde.
        || subgrid.getAge() < 2
        //|| true
      )
    ) {
      assertion2(virtualSubgrid.isVirtual(), subgrid.toString(), virtualSubgrid.toString());
      assertion2(!tarch::la::oneGreater(virtualSubgrid.getPosition(), subgrid.getPosition())
          && !tarch::la::oneGreater(subgrid.getPosition() + subgrid.getSize(), virtualSubgrid.getPosition() + virtualSubgrid.getSize()),
          subgrid.toString(), virtualSubgrid.toString());

      int numberOfRestrictedCells
       = _numerics.restrictSolution(subgrid, virtualSubgrid, !virtualSubgrid.willCoarsen());
      _subgridStatistics.addRestrictedCells(numberOfRestrictedCells, subgrid.getLevel());

      virtualSubgrid.getTimeIntervals().setEstimatedNextTimestepSize(
        subgrid.getTimeIntervals().getEstimatedNextTimestepSize()
      );
    }

    if(!parallelSubgrid.wasCurrentStateSent()) {
      //virtualParallelSubgrid.markCurrentStateAsSent(virtualParallelSubgrid.wasCurrentStateSent() || parallelSubgrid.wasCurrentStateSent());
      virtualParallelSubgrid.markCurrentStateAsSent(false);
    }
  }
}
예제 #3
0
void peanoclaw::interSubgridCommunication::GridLevelTransfer::finalizeVirtualSubgrid(
  Patch&                               subgrid,
  peanoclaw::Vertex * const            fineGridVertices,
  const peano::grid::VertexEnumerator& fineGridVerticesEnumerator,
  bool                                 isPeanoCellLeaf
) {
  tarch::multicore::Lock lock(_virtualPatchListSemaphore);
  assertion1(_virtualPatchDescriptionIndices.size() >= 0, subgrid.toString());

  tarch::la::Vector<DIMENSIONS_PLUS_ONE, double> virtualSubgridKey = createVirtualSubgridKey(subgrid.getPosition(), subgrid.getLevel());
  int virtualPatchDescriptionIndex = _virtualPatchDescriptionIndices[virtualSubgridKey];
  _virtualPatchDescriptionIndices.erase(virtualSubgridKey);
//  _virtualPatchTimeConstraints.erase(virtualSubgridKey);
  CellDescription& virtualPatchDescription = CellDescriptionHeap::getInstance().getData(virtualPatchDescriptionIndex).at(0);
  Patch virtualPatch(virtualPatchDescription);

  //Assert that we're working on the correct virtual patch
  assertionEquals3(subgrid.getCellDescriptionIndex(), virtualPatchDescriptionIndex, subgrid, virtualPatch, _virtualPatchDescriptionIndices.size());
  assertionNumericalEquals(subgrid.getPosition(), virtualPatch.getPosition());
  assertionNumericalEquals(subgrid.getSize(), virtualPatch.getSize());
  assertionEquals(subgrid.getLevel(), virtualPatch.getLevel());
  assertionEquals(subgrid.getUIndex(), virtualPatch.getUIndex());
//    assertionEquals(finePatch.getUOldIndex(), virtualPatch.getUOldIndex());

  #ifndef PEANOCLAW_USE_ASCEND_FOR_RESTRICTION
  _numerics.postProcessRestriction(subgrid, !subgrid.willCoarsen());
  #endif

  //Fill ghostlayer
  for(int i = 0; i < TWO_POWER_D; i++) {
    fineGridVertices[fineGridVerticesEnumerator(i)].fillAdjacentGhostLayers(
      subgrid.getLevel(),
      _useDimensionalSplitting,
      _numerics,
      #ifdef PEANOCLAW_USE_ASCEND_FOR_RESTRICTION
      tarch::la::multiplyComponents(peano::utils::dDelinearised(i, 2).convertScalar<double>(), subgrid.getSize()) + subgrid.getPosition(),
      #else
      fineGridVerticesEnumerator.getVertexPosition(i),
      #endif
      _subgridStatistics
    );
  }

  //Switch to leaf or non-virtual
  if(isPeanoCellLeaf) {
    assertion1(tarch::la::greaterEquals(subgrid.getTimeIntervals().getTimestepSize(), 0.0), subgrid);
    subgrid.switchToLeaf();
    _numerics.update(subgrid);
    ParallelSubgrid parallelSubgrid(subgrid);
    parallelSubgrid.markCurrentStateAsSent(false);
  } else {
    if(!isPatchAdjacentToRemoteRank(
      fineGridVertices,
      fineGridVerticesEnumerator
    )) {
      subgrid.switchToNonVirtual();
    }
  }

  assertion1(!subgrid.isVirtual()
    || isPatchAdjacentToRemoteRank(
        fineGridVertices,
        fineGridVerticesEnumerator),
    subgrid);
}
예제 #4
0
void peanoclaw::interSubgridCommunication::GridLevelTransfer::switchToAndAddVirtualSubgrid(
  Patch& subgrid
) {
  tarch::multicore::Lock lock(_virtualPatchListSemaphore);

  //Push virtual stack
  tarch::la::Vector<DIMENSIONS_PLUS_ONE, double> virtualSubgridKey = createVirtualSubgridKey(subgrid.getPosition(), subgrid.getLevel());
  _virtualPatchDescriptionIndices[virtualSubgridKey] = subgrid.getCellDescriptionIndex();
//  _virtualPatchTimeConstraints[virtualSubgridKey] = subgrid.getMinimalNeighborTimeConstraint();

  if(static_cast<int>(_virtualPatchDescriptionIndices.size()) > _maximumNumberOfSimultaneousVirtualPatches) {
    _maximumNumberOfSimultaneousVirtualPatches = _virtualPatchDescriptionIndices.size();
  }

  //Create virtual patch
  if(subgrid.isVirtual()) {
    subgrid.getAccessor().clearRegion(
      peanoclaw::geometry::Region(tarch::la::Vector<DIMENSIONS, int>(0),
             subgrid.getSubdivisionFactor()),
      false
    );
    subgrid.getAccessor().clearRegion(
      peanoclaw::geometry::Region(tarch::la::Vector<DIMENSIONS, int>(0),
             subgrid.getSubdivisionFactor()),
      true
    );
  } else {
    subgrid.switchToVirtual();
  }
  _numerics.update(subgrid);
}