/// Execute a data processor over several MultiGrid3D void executeDataProcessor( DataProcessorGenerator3D const& generator, std::vector<MultiGrid3D*> multiGrids, plint referenceLevel ) { if(multiGrids.empty()) return; for (plint iLevel=0; iLevel<(plint)multiGrids[0]->getNumLevels(); ++iLevel) { std::auto_ptr<DataProcessorGenerator3D> localGenerator(generator.clone()); int dxScale = (int)referenceLevel - (int)iLevel; int dtScale = dxScale; // TODO: here, we assume convective scaling; general case should be considered. plint boxRescaleFactor = util::roundToInt(util::twoToThePowerPlint(std::abs(referenceLevel-iLevel))); if (dxScale < 0) // if we go to a coarser grid localGenerator->divide(boxRescaleFactor); else // otherwise we go to a finer grid localGenerator->multiply(boxRescaleFactor); localGenerator->setscale(dxScale,dtScale); std::vector<MultiBlock3D*> localBlocks(multiGrids.size()); for (plint iBlock=0; iBlock<(plint)localBlocks.size(); ++iBlock) { localBlocks[iBlock] = &multiGrids[iBlock]->getComponent(iLevel); } executeDataProcessor(*localGenerator, localBlocks); } }
void addInternalProcessor( DataProcessorGenerator3D const& generator, MultiBlock3D& actor, std::vector<MultiBlock3D*> multiBlockArgs, plint level ) { MultiProcessing3D<DataProcessorGenerator3D const, DataProcessorGenerator3D > multiProcessing(generator, multiBlockArgs); std::vector<DataProcessorGenerator3D*> const& retainedGenerators = multiProcessing.getRetainedGenerators(); std::vector<std::vector<plint> > const& atomicBlockNumbers = multiProcessing.getAtomicBlockNumbers(); for (pluint iGenerator=0; iGenerator<retainedGenerators.size(); ++iGenerator) { std::vector<AtomicBlock3D*> extractedAtomicBlocks(multiBlockArgs.size()); for (pluint iBlock=0; iBlock<extractedAtomicBlocks.size(); ++iBlock) { extractedAtomicBlocks[iBlock] = &multiBlockArgs[iBlock]->getComponent(atomicBlockNumbers[iGenerator][iBlock]); } // It is assumed that the actor has the same distribution as block 0. PLB_ASSERT(!atomicBlockNumbers[iGenerator].empty()); AtomicBlock3D& atomicActor = actor.getComponent(atomicBlockNumbers[iGenerator][0]); // Delegate to the "AtomicBlock version" of addInternal. plb::addInternalProcessor(*retainedGenerators[iGenerator], atomicActor, extractedAtomicBlocks, level); } // Subscribe the processor in the multi-block. This guarantees that the multi-block is aware // of the maximal current processor level, and it instantiates the communication pattern // for an update of envelopes after processor execution. std::vector<MultiBlock3D*> updatedMultiBlocks; std::vector<modif::ModifT> typeOfModification; multiProcessing.multiBlocksWhichRequireUpdate(updatedMultiBlocks, typeOfModification); actor.subscribeProcessor ( level, updatedMultiBlocks, typeOfModification, BlockDomain::usesEnvelope(generator.appliesTo()) ); actor.storeProcessor(generator, multiBlockArgs, level); }
MultiBlock3D::ProcessorStorage3D::ProcessorStorage3D ( DataProcessorGenerator3D const& generator_, std::vector<MultiBlock3D*> const& multiBlocks_, plint level_ ) : generator(generator_.clone()), multiBlockIds(multiBlocks_.size()), level(level_) { for(pluint iBlock=0; iBlock<multiBlockIds.size(); ++iBlock) { multiBlockIds[iBlock] = multiBlocks_[iBlock]->getId(); } }