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); }
peanoclaw::ParallelSubgrid::ParallelSubgrid( Patch& subgrid ) { _cellDescription = &CellDescriptionHeap::getInstance().getData(subgrid.getCellDescriptionIndex()).at(0); }
void peanoclaw::interSubgridCommunication::GridLevelTransfer::restrictDestroyedSubgrid( const Patch& destroyedSubgrid, Patch& coarseSubgrid, peanoclaw::Vertex * const fineGridVertices, const peano::grid::VertexEnumerator& fineGridVerticesEnumerator ) { assertion2(tarch::la::greaterEquals(coarseSubgrid.getTimeIntervals().getTimestepSize(), 0.0), destroyedSubgrid, coarseSubgrid); //Fix timestep size assertion1(tarch::la::greaterEquals(coarseSubgrid.getTimeIntervals().getTimestepSize(), 0), coarseSubgrid); coarseSubgrid.getTimeIntervals().setTimestepSize(std::max(0.0, coarseSubgrid.getTimeIntervals().getTimestepSize())); //Set indices on coarse adjacent vertices for(int i = 0; i < TWO_POWER_D; i++) { fineGridVertices[fineGridVerticesEnumerator(i)].setAdjacentCellDescriptionIndex(i, coarseSubgrid.getCellDescriptionIndex()); } //Skip update for coarse patch in next grid iteration coarseSubgrid.setSkipNextGridIteration(2); //Set demanded mesh width for coarse cell to coarse cell size. Otherwise //the coarse patch might get refined immediately. coarseSubgrid.setDemandedMeshWidth(coarseSubgrid.getSubcellSize()); }
void peanoclaw::interSubgridCommunication::GridLevelTransfer::stepDown( Patch* coarseSubgrid, Patch& fineSubgrid, peanoclaw::Vertex * const fineGridVertices, const peano::grid::VertexEnumerator& fineGridVerticesEnumerator, bool isInitializing, bool isPeanoCellLeaf ) { //Switch to virtual subgrid if necessary if(shouldBecomeVirtualSubgrid( fineSubgrid, fineGridVertices, fineGridVerticesEnumerator, isInitializing, isPeanoCellLeaf )) { switchToAndAddVirtualSubgrid(fineSubgrid); } else if(fineSubgrid.isVirtual()) { //Switch to non-virtual if still virtual fineSubgrid.switchToNonVirtual(); } //Prepare flags for subgrid if(!fineSubgrid.isLeaf()) { fineSubgrid.setWillCoarsen(peano::grid::aspects::VertexStateAnalysis::doesOneVertexCarryRefinementFlag ( fineGridVertices, fineGridVerticesEnumerator, peanoclaw::records::Vertex::Erasing ) ); } fineSubgrid.getTimeIntervals().resetMinimalNeighborTimeConstraint(); fineSubgrid.getTimeIntervals().resetMaximalNeighborTimeInterval(); fineSubgrid.resetNeighboringGhostlayerBounds(); fineSubgrid.getTimeIntervals().resetMinimalFineGridTimeInterval(); //Get data from neighbors: // - Ghostlayers data // - Ghostlayer bounds // - Neighbor times for(int i = 0; i < TWO_POWER_D; i++) { assertion1(fineSubgrid.getCellDescriptionIndex() != -1, fineSubgrid); fineGridVertices[fineGridVerticesEnumerator(i)].setAdjacentCellDescriptionIndex(i, fineSubgrid.getCellDescriptionIndex()); fineGridVertices[fineGridVerticesEnumerator(i)].fillAdjacentGhostLayers( fineGridVerticesEnumerator.getLevel(), _useDimensionalSplitting, _numerics, fineGridVerticesEnumerator.getVertexPosition(peano::utils::dDelinearised(i, 2)), _subgridStatistics, // fineGridVerticesEnumerator.getVertexPosition(i), i ); } //Data from coarse patch: // -> Update minimal time constraint of coarse neighbors if(coarseSubgrid != 0) { //Patch coarsePatch(coarseCellDescriptionIndex); if(coarseSubgrid->getTimeIntervals().shouldFineGridsSynchronize()) { //Set time constraint of fine grid to time of coarse grid to synch //on that time. fineSubgrid.getTimeIntervals().updateMinimalNeighborTimeConstraint( coarseSubgrid->getTimeIntervals().getCurrentTime() + coarseSubgrid->getTimeIntervals().getTimestepSize(), coarseSubgrid->getCellDescriptionIndex() ); } } }
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); }