diff --git a/docs/TBG_macros.cfg b/docs/TBG_macros.cfg index d4b5f90b2d..c2ade0346d 100644 --- a/docs/TBG_macros.cfg +++ b/docs/TBG_macros.cfg @@ -90,6 +90,10 @@ TBG_periodic="--periodic 1 0 1" # Enables moving window (sliding) in your simulation TBG_movingWindow="-m" + +# stop the moving window after given simulation step +TBG_stopWindow="--stopWindow 1337" + ################################################################################ ## Placeholder for multi data plugins: ## diff --git a/include/picongpu/fields/FieldManipulator.hpp b/include/picongpu/fields/FieldManipulator.hpp index 9e2a1a549e..0c2cd58393 100644 --- a/include/picongpu/fields/FieldManipulator.hpp +++ b/include/picongpu/fields/FieldManipulator.hpp @@ -83,7 +83,7 @@ class FieldManipulator } /* if sliding window is active we disable absorber on bottom side*/ - if (MovingWindow::getInstance().isSlidingWindowActive() && i == BOTTOM) continue; + if (MovingWindow::getInstance().isSlidingWindowActive(currentStep) && i == BOTTOM) continue; ExchangeMapping mapper(cellDescription, i); constexpr uint32_t numWorkers = pmacc::traits::GetNumWorkers< diff --git a/include/picongpu/plugins/IsaacPlugin.hpp b/include/picongpu/plugins/IsaacPlugin.hpp index 3df9665412..d87c1ac33d 100644 --- a/include/picongpu/plugins/IsaacPlugin.hpp +++ b/include/picongpu/plugins/IsaacPlugin.hpp @@ -374,7 +374,7 @@ class IsaacPlugin : public ILightweightPlugin { MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &numProc); - if ( MovingWindow::getInstance().isSlidingWindowActive() ) + if ( MovingWindow::getInstance().isEnabled() ) movingWindow = true; float_X minCellSize = math::min( cellSize[0], math::min( cellSize[1], cellSize[2] ) ); float3_X cellSizeFactor = cellSize / minCellSize; diff --git a/include/picongpu/plugins/PngPlugin.hpp b/include/picongpu/plugins/PngPlugin.hpp index 47734c9f27..1c9311ee2c 100644 --- a/include/picongpu/plugins/PngPlugin.hpp +++ b/include/picongpu/plugins/PngPlugin.hpp @@ -128,13 +128,14 @@ namespace picongpu charToAxisNumber(getValue(axis, i)[1]) ); /* if simulation run in 2D ignore all xz, yz slices (we had no z direction)*/ - const bool isAllowed2DSlice= (simDim==DIM3) || (transpose.x()!=2 && transpose.y()!=2); - const bool isSlidingWindowActive=MovingWindow::getInstance().isSlidingWindowActive(); + const bool isAllowed2DSlice = (simDim == DIM3) || (transpose.x() != 2 && transpose.y() != 2); + const bool isSlidingWindowEnabled = MovingWindow::getInstance().isEnabled(); /* if sliding window is active we are not allowed to create pngs from xz slice * This means one dimension in transpose must contain 1 (y direction) */ - const bool isAllowedMovingWindowSlice=!isSlidingWindowActive || - (transpose.x()==1 || transpose.y()==1); + const bool isAllowedMovingWindowSlice = + !isSlidingWindowEnabled || + (transpose.x() == 1 || transpose.y() == 1); if( isAllowed2DSlice && isAllowedMovingWindowSlice ) { VisType* tmp = new VisType(pluginName, pngCreator, period, transpose, getValue(slicePoints, i)); diff --git a/include/picongpu/plugins/adios/WriteSpecies.hpp b/include/picongpu/plugins/adios/WriteSpecies.hpp index 8075777716..e19e045f4f 100644 --- a/include/picongpu/plugins/adios/WriteSpecies.hpp +++ b/include/picongpu/plugins/adios/WriteSpecies.hpp @@ -126,7 +126,7 @@ struct WriteSpecies typedef typename FilterFactory::FilterType MyParticleFilter; MyParticleFilter filter; /* activate filter pipeline if moving window is activated */ - filter.setStatus(MovingWindow::getInstance().isSlidingWindowActive()); + filter.setStatus(MovingWindow::getInstance().isEnabled()); filter.setWindowPosition(params->localWindowToDomainOffset, params->window.localDimensions.size); diff --git a/include/picongpu/plugins/hdf5/WriteSpecies.hpp b/include/picongpu/plugins/hdf5/WriteSpecies.hpp index c12f26f78c..1c4cc97301 100644 --- a/include/picongpu/plugins/hdf5/WriteSpecies.hpp +++ b/include/picongpu/plugins/hdf5/WriteSpecies.hpp @@ -210,7 +210,7 @@ struct WriteSpecies typedef typename FilterFactory::FilterType MyParticleFilter; MyParticleFilter filter; /* activate filter pipeline if moving window is activated */ - filter.setStatus(MovingWindow::getInstance().isSlidingWindowActive()); + filter.setStatus(MovingWindow::getInstance().isEnabled()); filter.setWindowPosition(params->localWindowToDomainOffset, params->window.localDimensions.size); diff --git a/include/picongpu/simulationControl/MovingWindow.hpp b/include/picongpu/simulationControl/MovingWindow.hpp index 7831a2599b..9f3739965e 100644 --- a/include/picongpu/simulationControl/MovingWindow.hpp +++ b/include/picongpu/simulationControl/MovingWindow.hpp @@ -36,9 +36,7 @@ class MovingWindow { private: - MovingWindow() : slidingWindowActive(false), slideCounter(0), lastSlideStep(0) - { - } + MovingWindow() = default; MovingWindow(MovingWindow& cc); @@ -50,8 +48,15 @@ class MovingWindow if (offsetFirstGPU) *offsetFirstGPU = 0.0; - if (slidingWindowActive) + if (slidingWindowEnabled) { + /* Sliding stayed enabled but if we reach the end step where we should stop sliding + * the moving window is freezed. + * All offsets will stay constant until the end of the simulation. + */ + if (currentStep >= endSlidingOnStep) + currentStep = endSlidingOnStep; + const SubGrid& subGrid = Environment::get().SubGrid(); /* speed of the moving window */ @@ -181,34 +186,55 @@ class MovingWindow void incrementSlideCounter(const uint32_t currentStep) { // do not slide twice in one simulation step - if (slidingWindowActive==true && lastSlideStep < currentStep) + if (isSlidingWindowActive( currentStep ) && lastSlideStep < currentStep) { slideCounter++; lastSlideStep = currentStep; } } - /** true is sliding window is activated */ - bool slidingWindowActive; + /** true is sliding window is activated + * + * How long the window is sliding is defined with endSlidingOnStep. + */ + bool slidingWindowEnabled = false; /** current number of slides since start of simulation */ - uint32_t slideCounter; + uint32_t slideCounter = 0u; /** * last simulation step with slide * used to prevent multiple slides per simulation step */ - uint32_t lastSlideStep; + uint32_t lastSlideStep = 0u; + + //! time step where the sliding window is stopped + uint32_t endSlidingOnStep = 0u; + public: /** - * Enable or disable sliding window + * Set step where the simulation stops the moving window * - * @param value true to enable, false otherwise + * @param step 0 means no sliding window, else sliding is enabled until step is reached. */ - void setSlidingWindow(bool value) + void setEndSlideOnStep(int32_t step) { - slidingWindowActive = value; + // maybe we have a underflow in the cast, this is fine because it results in a very large number + const uint32_t maxSlideStep = static_cast(step); + if ( maxSlideStep < lastSlideStep) + throw std::runtime_error("It is not allowed to stop the moving window in the past."); + + endSlidingOnStep = maxSlideStep; + + static bool firstCall = true; + /* Disable or enable sliding window only in the first call. + * Later changes of step will not influence if the sliding window is activated. + */ + if (firstCall && endSlidingOnStep != 0u) + slidingWindowEnabled = true; + + firstCall = false; } /** @@ -240,13 +266,24 @@ class MovingWindow } /** - * Returns if sliding window is active + * Returns if sliding window is enabled + * + * @return true if enabled, false otherwise + */ + bool isEnabled() const + { + return slidingWindowEnabled; + } + + /** + * Returns if the window can move in the current step * - * @return true if active, false otherwise + * @return false, if Moving window is activated (isEnabled() == true) but already stopped. + * true if moving windows is enabled and simulation step is smaller than */ - bool isSlidingWindowActive() const + bool isSlidingWindowActive(const uint32_t currenStep) const { - return slidingWindowActive; + return isEnabled() && currenStep < endSlidingOnStep; } /** @@ -259,7 +296,7 @@ class MovingWindow { bool doSlide = false; - if (slidingWindowActive) + if (slidingWindowEnabled) { getCurrentSlideInfo(currentStep, &doSlide, nullptr); } @@ -311,7 +348,7 @@ class MovingWindow window.globalDimensions = Selection(subGrid.getGlobalDomain().size); /* moving window can only slide in y direction */ - if (slidingWindowActive) + if (slidingWindowEnabled) { /* the moving window is smaller than the global domain by exactly one * GPU (local domain size) in moving (y) direction diff --git a/include/picongpu/simulationControl/MySimulation.hpp b/include/picongpu/simulationControl/MySimulation.hpp index 863a9e6a2d..4e872178d0 100644 --- a/include/picongpu/simulationControl/MySimulation.hpp +++ b/include/picongpu/simulationControl/MySimulation.hpp @@ -117,6 +117,7 @@ class MySimulation : public SimulationHelper cellDescription(nullptr), initialiserController(nullptr), slidingWindow(false), + endSlidingOnStep(-1), showVersionOnce(false) { } @@ -143,7 +144,10 @@ class MySimulation : public SimulationHelper ("periodic", po::value > (&periodic)->multitoken(), "specifying whether the grid is periodic (1) or not (0) in each dimension, default: no periodic dimensions") - ("moving,m", po::value(&slidingWindow)->zero_tokens(), "enable sliding/moving window"); + ("moving,m", po::value(&slidingWindow)->zero_tokens(), "enable sliding/moving window") + ("stopWindow", po::value(&endSlidingOnStep)->default_value(-1), + "stops the window at stimulation step, " + "-1 means that window is never stopping"); } std::string pluginGetName() const @@ -224,7 +228,10 @@ class MySimulation : public SimulationHelper Environment::get().initGrids(global_grid_size, gridSizeLocal, gridOffset); - MovingWindow::getInstance().setSlidingWindow(slidingWindow); + if (slidingWindow) + MovingWindow::getInstance().setEndSlideOnStep(endSlidingOnStep); + else + MovingWindow::getInstance().setEndSlideOnStep(0); log ("rank %1%; localsize %2%; localoffset %3%;") % myGPUpos.toString() % gridSizeLocal.toString() % gridOffset.toString(); @@ -238,7 +245,7 @@ class MySimulation : public SimulationHelper if (gc.getGlobalRank() == 0) { - if (slidingWindow) + if (MovingWindow::getInstance().isEnabled()) log ("Sliding Window is ON"); else log ("Sliding Window is OFF"); @@ -807,6 +814,7 @@ class MySimulation : public SimulationHelper std::vector gridDistribution; bool slidingWindow; + int32_t endSlidingOnStep; bool showVersionOnce; }; } /* namespace picongpu */