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(); }
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); } } }
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); }
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); }