template<typename TP = timing::WcPolicy>
class walberla::timeloop::SweepTimeloop< TP >
Timeloop that runs a collection of sweeps.
A Sweep is defined as an operation that processes a single block, i.e. a function "void sweepFunc ( IBlock * )" A sweep is usually some numeric kernel, for example a LBM Stream-Collide step. For all sweeps Before- and AfterFunctions can be registered. This are void(void) functions that are run before or after the sweep. Here one can register functions that have a close relation to the sweep, for example communication steps that are necessary before the sweep can run.
The SweepTimeloop supports the Selectable concept, so that the execution of sweeps can depend on the current uid::globalState(), together with the current block state. This mechanism makes the registration of Sweeps somewhat complex.
Simple Registration
When registering sweeps (even without Selectable concept) the syntax may seem a little strange. Lets do an example where we register simple C functions as sweeps:
void mySweep ( IBlock * ) { ... }
void myBeforeFunction () { ... }
void myAfterFunction () { ... }
timeloop.add() << BeforeFunction( & myBeforeFunction, "MyBeforeFunction")
<<
Sweep ( & mySweep,
"MySweep" )
<< AfterFunction ( & myAfterFunction, "MyAfterFunction );
So we do not pass the parameters directly to add(), but add() returns an object, where the different functions can be piped in. The BeforeFunction, Sweep and AfterFunction take additional selector arguments, so multiple of them can be piped into one sweep, as long a unique sweep can be determined using the selectors.
Instead of registering plain C functions, it is usually a good idea to use functors as sweeps, since they can have additional data. Be aware that the state of such functor sweeps is the same for all blocks. To store data per block register it as BlockData or use SweepOnBlock:
Sweeps on Block
Sometimes a sweep functor class needs to store data per block, not per process ( which is the default ). The solution in this case would be, to put this data into a separate data structure and register that as BlockData. The alternative is to register the sweep class itself as BlockData, whereas the actual sweep function (which is the same for all blocks ) then only consists of fetching the sweep class and executing it. This second solution is used by SweepOnBlock:
The starting point is a class, that has members which should be placed block local:
class MyLBMClass {
public:
MyLBMClass(
real_t omega, PdfField * pdfField );
private:
Type someBlockLocalData;
};
The second step is to write a so called creator class, which acts as the interface between the waLBerla block data mechanism and your data. It basically is the initialization function for the blockdata:
struct MyLBMClassCreator {
MyLBMClassCreator( BlockDataID pdfFieldID ): pdfFieldID_(pdfFieldID) {}
MyLBMClass * operator() ( IBlock * const block ) {
return new MyLBMClass( block->getData<PdfField>( pdfFieldID_ ) );
}
private:
BlockDataID pdfFieldID_
}
This is then registered like this:
timeloop.add() << SweepOnBlock<MyLBMClass>( MyLBMClassCreator(pdfFieldID) );
|
|
| SweepTimeloop (BlockStorage &blockStorage, uint_t nrOfTimeSteps) |
|
| SweepTimeloop (const shared_ptr< StructuredBlockStorage > &structuredBlockStorage, uint_t nrOfTimeSteps) |
|
| ~SweepTimeloop () override |
|
| Timeloop (uint_t nrOfTimeSteps) |
|
| ~Timeloop () override=default |
|
void | run () override |
|
void | run (const bool logTimeStep) |
|
void | run (timing::TimingPool< timing::WcPolicy > &timing, const bool logTimeStep=true) |
|
void | singleStep () override |
|
void | singleStep (const bool logTimeStep) |
|
void | singleStep (timing::TimingPool< timing::WcPolicy > &timing, const bool logTimeStep=true) |
|
void | stop () override |
| Stops the timeloop, has to be called on every process. More...
|
|
void | synchronizedStop (bool stop) override |
| Similar to stop - useful if the stop signal is only known on a single process. More...
|
|
void | setCurrentTimeStepToZero () |
|
void | setCurrentTimeStep (uint_t ts) override |
|
FctHandle | addFuncBeforeTimeStep (const VoidFctNoArguments &f, const std::string &identifier=std::string(), const Set< SUID > &require=Set< SUID >::emptySet(), const Set< SUID > &incompatible=Set< SUID >::emptySet()) |
|
void | addFuncBeforeTimeStep (const FctHandle &fctToBindTo, const VoidFctNoArguments &f, const std::string &identifier=std::string(), const Set< SUID > &require=Set< SUID >::emptySet(), const Set< SUID > &incompatible=Set< SUID >::emptySet()) |
|
FctHandle | addFuncAfterTimeStep (const VoidFctNoArguments &f, const std::string &identifier=std::string(), const Set< SUID > &require=Set< SUID >::emptySet(), const Set< SUID > &exludingSelector=Set< SUID >::emptySet()) |
|
void | addFuncAfterTimeStep (const FctHandle &fctToBindTo, const VoidFctNoArguments &f, const std::string &identifier=std::string(), const Set< SUID > &require=Set< SUID >::emptySet(), const Set< SUID > &incompatible=Set< SUID >::emptySet()) |
|
uint_t | getCurrentTimeStep () const override |
|
uint_t | getNrOfTimeSteps () const override |
|
virtual | ~ITimeloop ()=default |
|
virtual uint_t | getCurrentTimeStep () const =0 |
|
virtual uint_t | getNrOfTimeSteps () const =0 |
|