Newer
Older

Christian Godenschwager
committed
//======================================================================================================================
//

Christoph Schwarzmeier
committed
// This file is part of waLBerla. waLBerla is free software: you can

Christian Godenschwager
committed
// redistribute it and/or modify it under the terms of the GNU General Public

Christoph Schwarzmeier
committed
// License as published by the Free Software Foundation, either version 3 of

Christian Godenschwager
committed
// the License, or (at your option) any later version.

Christoph Schwarzmeier
committed
//
// waLBerla is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License

Christian Godenschwager
committed
// for more details.

Christoph Schwarzmeier
committed
//

Christian Godenschwager
committed
// You should have received a copy of the GNU General Public License along
// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
//
//! \file SweepTimeloop.cpp
//! \ingroup timeloop
//! \author Martin Bauer <martin.bauer@fau.de>
//! \author Christoph Schwarzmeier <christoph.schwarzmeier@fau.de>

Christian Godenschwager
committed
//
//======================================================================================================================
#include "SweepTimeloop.h"
#include "core/Abort.h"
namespace walberla {
namespace timeloop {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////// Execution of Timeloop ////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void SweepTimeloop::doTimeStep(const Set<SUID> &selectors)
{
removeForDeletionMarkedSweeps();
//iterate over all registered sweeps
for( auto sweepIt = sweeps_.begin(); sweepIt != sweeps_.end(); ++sweepIt )
{
SweepAdder & s = * ( sweepIt->second );
//select and execute before functions
for( size_t j=0; j < s.beforeFuncs.size(); ++j )
executeSelectable(s.beforeFuncs[j].selectableFunc_,selectors,"Pre-Sweep Function");
// Loop over all blocks
for( BlockStorage::iterator bi = blockStorage_.begin(); bi != blockStorage_.end(); ++bi )
{
// ensure that at least one sweep has been registered (regardless of its selector)

Christian Godenschwager
committed
if( s.sweep.empty() )
{
WALBERLA_ABORT("Selecting Sweep " << sweepIt->first << ": " <<
"No sweep has been registered! Did you only register a BeforeFunction or AfterFunction?" );
}
// ensure that exactly one sweep has been registered that matches the specified selectors
size_t numSweeps = s.sweep.getNumberOfMatching(selectors + bi->getState());

Christoph Schwarzmeier
committed
if (numSweeps == size_t(0)) {

Christoph Schwarzmeier
committed
} else {
if (numSweeps > size_t(1)) {
WALBERLA_ABORT("Only one sweep must be added to a single SweepAdder object. This error might be caused "
"by e.g. \"timeloop.add() << Sweep(A) << Sweep(B);\".")
}
}

Christian Godenschwager
committed
Sweep * selectedSweep = s.sweep.getUnique( selectors + bi->getState() );

Christian Godenschwager
committed
WALBERLA_LOG_PROGRESS_SECTION()
{
std::string sweepName;
s.sweep.getUnique( selectors + bi->getState(), sweepName );
WALBERLA_LOG_PROGRESS("Running sweep \"" << sweepName << "\" on block " << bi->getId() );
}
(selectedSweep->function_)( bi.get() );

Christian Godenschwager
committed
}
// select and execute after functions
for( size_t j=0; j < s.afterFuncs.size(); ++j )
executeSelectable(s.afterFuncs[j].selectableFunc_,selectors,"Post-Sweep Function");
}
}
void SweepTimeloop::doTimeStep(const Set<SUID> &selectors, WcTimingPool &timing)
{
removeForDeletionMarkedSweeps();
// On first run we extract all possible names of sweeps, independent of selectors
// to register timer for them. Since all timingPools have to have the same entries on
// all processes otherwise a timingPool.reduce() does not work
// see test SweepTimeloopTimerReduction.cpp
if ( firstRun_ || timing.empty() )
{
for( auto sweepIt = sweeps_.begin(); sweepIt != sweeps_.end(); ++sweepIt )
{
SweepAdder & s = * ( sweepIt->second );
// loop over all possibilities in selectable object

Christian Godenschwager
committed
for( auto it = s.sweep.begin(); it != s.sweep.end(); ++it )
timing.registerTimer( it.identifier() );
}
firstRun_ = false;
}
//iterate over all registered sweeps
for( auto sweepIt = sweeps_.begin(); sweepIt != sweeps_.end(); ++sweepIt )
{
SweepAdder & s = * ( sweepIt->second );
//select and execute before functions
for( size_t j=0; j < s.beforeFuncs.size(); ++j )
executeSelectable( s.beforeFuncs[j].selectableFunc_, selectors, "Pre-Sweep Function", timing );
for( BlockStorage::iterator bi = blockStorage_.begin(); bi != blockStorage_.end(); ++bi )
{
// ensure that at least one sweep has been registered (regardless of its selector)
if( s.sweep.empty() )
{
WALBERLA_ABORT("Selecting Sweep " << sweepIt->first << ": " <<
"No sweep has been registered! Did you only register a BeforeFunction or AfterFunction?" );
}
// ensure that exactly one sweep has been registered that matches the specified selectors
size_t numSweeps = s.sweep.getNumberOfMatching(selectors + bi->getState());

Christian Godenschwager
committed

Christoph Schwarzmeier
committed
if (numSweeps == size_t(0)) {

Christoph Schwarzmeier
committed
} else {
if (numSweeps > size_t(1)) {
WALBERLA_ABORT("Only one sweep must be added to a single SweepAdder object. This error might be caused "
"by e.g. \"timeloop.add() << Sweep(A) << Sweep(B);\".")
}
}

Christian Godenschwager
committed
std::string sweepName;
Sweep * selectedSweep = s.sweep.getUnique( selectors + bi->getState(), sweepName );

Christian Godenschwager
committed
WALBERLA_LOG_PROGRESS("Running sweep \"" << sweepName << "\" on block " << bi->getId() );
// loop over all blocks
timing[sweepName].start();
(selectedSweep->function_)( bi.get() );

Christian Godenschwager
committed
timing[sweepName].end();
}
// select and execute after functions
for( size_t j=0; j < s.afterFuncs.size(); ++j )
executeSelectable(s.afterFuncs[j].selectableFunc_,selectors,"Post-Sweep Function", timing );
}
}
} // namespace timeloop
} // namespace walberla