Commit f64408c3 authored by Dennis Gläser's avatar Dennis Gläser
Browse files

Merge branch 'feature/sequential' into 'master'

[sequential] Add sequential header from upstream to prepare for removal in dumux

See merge request !156
parents 76b48e27 9e5b0739
......@@ -13,6 +13,7 @@ workflow:
# variables that may be overwritten by the trigger
variables:
DUMUX_REPO: "https://git.iws.uni-stuttgart.de/dumux-repositories/dumux.git"
DUMUX_FOLDER: "dumux"
MR_TARGET_BRANCH_NAME: ""
DUMUX_MR_SOURCE_BRANCH: ""
DUMUX_MR_TARGET_BRANCH: ""
......@@ -23,20 +24,21 @@ select tests:
stage: configure
before_script:
- |
if [ ! -d $DUMUX_FOLDER ]; then
git clone -b master --depth 1 $DUMUX_REPO $DUMUX_FOLDER
fi
if [[ -n "$DUMUX_MR_SOURCE_BRANCH" ]]; then
echo "Fetching upstream branches related to merge request."
echo "Source branch: $DUMUX_MR_SOURCE_BRANCH"
echo "Target branch: $DUMUX_MR_TARGET_BRANCH"
git clone -b ${DUMUX_MR_SOURCE_BRANCH} --depth 1 $DUMUX_REPO
pushd dumux
pushd $DUMUX_FOLDER
git fetch --depth=1 origin ${DUMUX_MR_TARGET_BRANCH}:${DUMUX_MR_TARGET_BRANCH}
popd
else
git clone -b master --depth 1 $DUMUX_REPO
pushd dumux
pushd $DUMUX_FOLDER
if [[ -n "$DUMUX_TRIGGER_COMMIT_SHA" ]]; then
echo "Fetching upstream commit $DUMUX_TRIGGER_COMMIT_SHA"
git fetch --depth=1 origin ${DUMUX_TRIGGER_COMMIT_SHA}
......@@ -54,11 +56,11 @@ select tests:
- dunecontrol --opts=$DUNE_OPTS_FILE --current all
- |
if [[ -n "$DUMUX_MR_SOURCE_BRANCH" ]]; then
CHECK_FOLDER="dumux"
CHECK_FOLDER=$DUMUX_FOLDER
SOURCE_TREE=$DUMUX_MR_SOURCE_BRANCH
TARGET_TREE=$DUMUX_MR_TARGET_BRANCH
elif [[ -n "$DUMUX_TRIGGER_REF_SHA" ]]; then
CHECK_FOLDER="dumux"
CHECK_FOLDER=$DUMUX_FOLDER
SOURCE_TREE=$DUMUX_TRIGGER_COMMIT_SHA
TARGET_TREE=$DUMUX_TRIGGER_REF_SHA
elif [[ -n "$MR_TARGET_BRANCH_NAME" ]]; then
......@@ -70,20 +72,20 @@ select tests:
if [[ -n "$SOURCE_TREE" ]]; then
echo "Detecting tests affected by changes in folder $CHECK_FOLDER,"
echo "using source/target trees: $SOURCE_TREE / $TARGET_TREE"
python3 dumux/bin/testing/getchangedfiles.py --folder $CHECK_FOLDER \
--source-tree $SOURCE_TREE \
--target-tree $TARGET_TREE \
--outfile changedfiles.txt
python3 dumux/bin/testing/findtests.py --outfile affectedtests.json \
--file-list changedfiles.txt \
--build-dir build-cmake
python3 $DUMUX_FOLDER/bin/testing/getchangedfiles.py --folder $CHECK_FOLDER \
--source-tree $SOURCE_TREE \
--target-tree $TARGET_TREE \
--outfile changedfiles.txt
python3 $DUMUX_FOLDER/bin/testing/findtests.py --outfile affectedtests.json \
--file-list changedfiles.txt \
--build-dir build-cmake
else
echo "Skipping test selection, build/test stages will consider all tests!"
touch affectedtests.json
fi
artifacts:
paths:
- dumux
- $DUMUX_FOLDER
- build-cmake
- affectedtests.json
expire_in: 3 hours
......@@ -95,15 +97,15 @@ build lecture:
pushd build-cmake
make clean
if [ -s ../affectedtests.json ]; then
python3 ../dumux/bin/testing/runselectedtests.py -c ../affectedtests.json -b
python3 ../$DUMUX_FOLDER/bin/testing/runselectedtests.py -c ../affectedtests.json -b
else
python3 ../dumux/bin/testing/runselectedtests.py --all -b
python3 ../$DUMUX_FOLDER/bin/testing/runselectedtests.py --all -b
fi
popd
artifacts:
paths:
- build-cmake
- dumux
- $DUMUX_FOLDER
- affectedtests.json
expire_in: 3 hours
......@@ -116,9 +118,9 @@ test lecture:
- |
pushd build-cmake
if [ -s ../affectedtests.json ]; then
python3 ../dumux/bin/testing/runselectedtests.py -c ../affectedtests.json -t
python3 ../$DUMUX_FOLDER/bin/testing/runselectedtests.py -c ../affectedtests.json -t
else
python3 ../dumux/bin/testing/runselectedtests.py --all -t
python3 ../$DUMUX_FOLDER/bin/testing/runselectedtests.py --all -t
fi
popd
needs:
......
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
* See the file COPYING for full copying permissions. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program 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 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*****************************************************************************/
/*!
* \file
* \ingroup Common
* \brief Definition of boundary condition types, extend if necessary
* \todo can this be removed for the sake of boundarytypes.hh?
*/
#ifndef DUMUX_BOUNDARYCONDITIONS_HH
#define DUMUX_BOUNDARYCONDITIONS_HH
namespace Dumux {
/*!
* \ingroup Common
* \brief Define a class containing boundary condition flags
*/
struct BoundaryConditions
{
/** \brief These values are ordered according to precedence */
enum Flags {
outflow = 0, //!< An outflow boundary
neumann = 1, //!< Neumann boundary
process = 2, //!< Processor boundary
dirichlet = 3 //!< Dirichlet boundary
};
};
} // end namespace Dumux
#endif
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
* See the file COPYING for full copying permissions. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program 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 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*****************************************************************************/
/*!
* \file
* \ingroup Common
* \brief Provides a few default main functions for convenience.
*/
#ifndef DUMUX_COMMON_START_HH
#define DUMUX_COMMON_START_HH
#include <ctime>
#include <iostream>
#include <dune/common/parallel/mpihelper.hh>
#include <dune/grid/io/file/dgfparser/dgfexception.hh>
#include <dumux/common/properties.hh>
#include <dumux/common/parameters.hh>
#include <dumux/common/dumuxmessage.hh>
#include <dumux/io/grid/gridmanager.hh>
#warning "start.hh is deprecated. Use new style main files see e.g. /test/porousmediumflow/1p."
namespace Dumux {
/*!
* \ingroup Common
*
* \brief Provides a main function which reads in parameters from the
* command line and a parameter file.
*
* \tparam TypeTag The type tag of the problem which needs to be solved
*
* \param argc The 'argc' argument of the main function: count of arguments (1 if there are no arguments)
* \param argv The 'argv' argument of the main function: array of pointers to the argument strings
* \param usage Callback function for printing the usage message
*/
template <class TypeTag>
int start_(int argc,
char **argv,
void (*usage)(const char *, const std::string &))
{
// some aliases for better readability
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using Problem = GetPropType<TypeTag, Properties::Problem>;
using TimeManager = GetPropType<TypeTag, Properties::TimeManager>;
// initialize MPI, finalize is done automatically on exit
const auto& mpiHelper = Dune::MPIHelper::instance(argc, argv);
// print dumux start message
if (mpiHelper.rank() == 0)
DumuxMessage::print(/*firstCall=*/true);
////////////////////////////////////////////////////////////
// parse the command line arguments and input file
////////////////////////////////////////////////////////////
auto defaultParams = [] (Dune::ParameterTree& p) {GetProp<TypeTag, Properties::ModelDefaultParameters>::defaultParams(p);};
Parameters::init(argc, argv, defaultParams, usage);
//////////////////////////////////////////////////////////////////////
// try to create a grid (from the given grid file or the input file)
/////////////////////////////////////////////////////////////////////
GridManager<GetPropType<TypeTag, Properties::Grid>> gridManager;
gridManager.init();
//////////////////////////////////////////////////////////////////////
// run the simulation
/////////////////////////////////////////////////////////////////////
// read the initial time step and the end time (mandatory parameters)
auto tEnd = getParam<Scalar>("TimeManager.TEnd");
auto dt = getParam<Scalar>("TimeManager.DtInitial");
// check if we are about to restart a previously interrupted simulation
bool restart = false;
Scalar restartTime = 0;
if (hasParam("Restart") || hasParam("TimeManager.Restart"))
{
restart = true;
restartTime = getParam<Scalar>("TimeManager.Restart");
}
// instantiate and run the problem
TimeManager timeManager;
Problem problem(timeManager, gridManager.grid());
timeManager.init(problem, restartTime, dt, tEnd, restart);
timeManager.run();
// print dumux end message and maybe the parameters for debugging
if (mpiHelper.rank() == 0)
DumuxMessage::print(/*firstCall=*/false);
return 0;
}
/*!
* \ingroup Common
*
* \brief Provides a main function with error handling
*
* \tparam TypeTag The type tag of the problem which needs to be solved
*
* \param argc The number of command line arguments of the program
* \param argv The contents of the command line arguments of the program
* \param usage Callback function for printing the usage message
*/
template <class TypeTag>
int start(int argc,
char **argv,
void (*usage)(const char *, const std::string &))
{
try {
return start_<TypeTag>(argc, argv, usage);
}
catch (ParameterException &e) {
std::cerr << std::endl << e << ". Abort!" << std::endl;
return 1;
}
catch (Dune::DGFException & e) {
std::cerr << "DGF exception thrown (" << e <<
"). Most likely, the DGF file name is wrong "
"or the DGF file is corrupted, "
"e.g. missing hash at end of file or wrong number (dimensions) of entries."
<< std::endl;
return 2;
}
catch (Dune::Exception &e) {
std::cerr << "Dune reported error: " << e << std::endl;
return 3;
}
catch (...) {
std::cerr << "Unknown exception thrown!\n";
return 4;
}
}
} // end namespace Dumux
#endif
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
// vi: set et ts=4 sw=4 sts=4:
/*****************************************************************************
* See the file COPYING for full copying permissions. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program 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 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*****************************************************************************/
/*!
* \file
* \ingroup Common
* \brief Manages the handling of time dependent problems
*/
#ifndef DUMUX_TIME_MANAGER_HH
#define DUMUX_TIME_MANAGER_HH
#warning "This file is deprecated. Use the TimeLoop class in common/timeloop.hh"
#include <algorithm>
#include <dune/common/float_cmp.hh>
#include <dune/common/timer.hh>
#include <dune/common/parallel/mpihelper.hh>
#include <dumux/common/properties.hh>
#include <dumux/common/parameters.hh>
namespace Dumux {
/*!
* \ingroup Common
* \brief Manages the handling of time dependent problems.
*
* This class facilitates the time management of the simulation.
* It doesn't manage any user data, but keeps track of what the
* current time, time step size and "episode" of the
* simulation is. It triggers the initialization of the problem and
* is responsible for the time control of a simulation run.
*
* The time manager allows to specify a sequence of "episodes" which
* determine the boundary conditions of a problem. This approach
* is handy if the problem is not static, i.e. the boundary
* conditions change over time.
*
* An episode is a span of simulated time in which
* the problem behaves in a specific way. It is characterized by
* the (simulation) time it starts, its length and a consecutive
* index starting at 0.
*/
template <class TypeTag>
class TimeManager
{
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using Problem = GetPropType<TypeTag, Properties::Problem>;
TimeManager(const TimeManager&)
{}
public:
TimeManager(bool verbose = true)
{
verbose_ =
verbose &&
Dune::MPIHelper::getCollectiveCommunication().rank() == 0;
episodeIndex_ = 0;
episodeStartTime_ = 0;
time_ = 0.0;
endTime_ = -1e100;
timeStepSize_ = 1.0;
previousTimeStepSize_ = timeStepSize_;
timeStepIdx_ = 0;
finished_ = false;
episodeLength_ = 1e100;
}
/*!
* \brief Initialize the model and problem and write the initial
* condition to disk.
*
* \param problem The physical problem which needs to be solved
* \param tStart The start time \f$\mathrm{[s]}\f$ of the simulation (typically 0)
* \param dtInitial The initial time step size \f$\mathrm{[s]}\f$
* \param tEnd The time at which the simulation is finished \f$\mathrm{[s]}\f$
* \param restart Specifies whether the initial condition should be written to disk
*/
void init(Problem &problem,
Scalar tStart,
Scalar dtInitial,
Scalar tEnd,
bool restart = false)
{
timer_.reset();
problem_ = &problem;
time_ = tStart;
timeStepSize_ = dtInitial;
previousTimeStepSize_ = dtInitial;
endTime_ = tEnd;
if (verbose_)
std::cout << "Initializing problem '" << problem_->name() << "'\n";
// initialize the problem
problem_->init();
// restart problem if necessary
if(restart)
problem_->restart(tStart);
else
{
// write initial condition (if problem is not restarted)
time_ -= timeStepSize_;
if (problem_->shouldWriteOutput())
problem_->writeOutput();
time_ += timeStepSize_;
}
if (verbose_) {
int numProcesses = Dune::MPIHelper::getCollectiveCommunication().size();
std::cout << "Initialization took " << timer_.elapsed() <<" seconds on "
<< numProcesses << " processes.\n"
<< "The cumulative CPU time was " << timer_.elapsed()*numProcesses << " seconds.\n";
}
}
/*!
* \name Simulated time and time step management
* @{
*/
/*!
* \brief Set the current simulated time, don't change the current
* time step index.
*
* \param t The time \f$\mathrm{[s]}\f$ which should be jumped to
*/
void setTime(Scalar t)
{ time_ = t; }
/*!
* \brief Set the current simulated time and the time step index.
*
* \param t The time \f$\mathrm{[s]}\f$ which should be jumped to
* \param stepIdx The new time step index
*/
void setTime(Scalar t, int stepIdx)
{ time_ = t; timeStepIdx_ = stepIdx; }
/*!
* \brief Return the time \f$\mathrm{[s]}\f$ before the time integration.
* To get the time after the time integration you have to add timeStepSize() to
* time().
*/
Scalar time() const
{ return time_; }
/*!
* \brief Returns the number of (simulated) seconds which the simulation runs.
*/
Scalar endTime() const
{ return endTime_; }
/*!
* \brief Set the time of simulated seconds at which the simulation runs.
*
* \param t The time \f$\mathrm{[s]}\f$ at which the simulation is finished
*/
void setEndTime(Scalar t)
{ endTime_ = t; }
/*!
* \brief Returns the current wall time (cpu time).
*/
double wallTime() const
{ return timer_.elapsed(); }
/*!
* \brief Set the current time step size to a given value.
*
* If the step size would exceed the length of the current
* episode, the timeStep() method will take care that the step
* size won't exceed the episode or the end of the simulation,
* though.
*
* \param dt The new value for the time step size \f$\mathrm{[s]}\f$
*/
void setTimeStepSize(Scalar dt)
{
using std::min;
timeStepSize_ = min(dt, maxTimeStepSize());
}
/*!
* \brief Returns the suggested time step length \f$\mathrm{[s]}\f$ so that we
* don't miss the beginning of the next episode or cross
* the end of the simulation.
*/
Scalar timeStepSize() const
{ return timeStepSize_; }
/*!
* \brief Returns the size of the previous time step \f$\mathrm{[s]}\f$.
*/
Scalar previousTimeStepSize() const
{ return previousTimeStepSize_; }
/*!
* \brief Returns number of time steps which have been
* executed since the beginning of the simulation.
*/
int timeStepIndex() const
{ return timeStepIdx_; }
/*!
* \brief Specify whether the simulation is finished
*
* \param yesno If true the simulation is considered finished
* before the end time is reached, else it is only
* considered finished if the end time is reached.
*/
void setFinished(bool yesno = true)
{ finished_ = yesno; }
/*!
* \brief Returns true if the simulation is finished.
*
* This is the case if either setFinished(true) has been called or
* if the end time is reached.
*/
bool finished() const
{ return finished_ || time() >= endTime(); }
/*!
* \brief Returns true if the simulation is finished after the
* time level is incremented by the current time step size.
*/
bool willBeFinished() const
{ return finished_ || time() + timeStepSize() >= endTime(); }
/*!
* \brief Aligns dt to the episode boundary or the end time of the
* simulation.
*/
Scalar maxTimeStepSize() const
{
if (finished())
return 0.0;
using std::max;
using std::min;
return min(min(episodeMaxTimeStepSize(),
problem_->maxTimeStepSize()),
max<Scalar>(0.0, endTime() - time()));
}
/*
* @}
*/
/*!
* \name episode Episode management
* @{
*/
/*!
* \brief Change the current episode of the simulation.
*
* \param tStart Time when the episode began \f$\mathrm{[s]}\f$
* \param len Length of the episode \f$\mathrm{[s]}\f$
* \param description descriptive name of the episode
*/
void startNextEpisode(Scalar tStart,
Scalar len,
const std::string &description = "")
{
++ episodeIndex_;
episodeStartTime_ = tStart;
episodeLength_ = len;
episodeDescription_ = description;
}
/*!
* \brief Start the next episode, but don't change the episode
* identifier.
*
* \param len Length of the episode \f$\mathrm{[s]}\f$, infinite if not specified.
*/
void startNextEpisode(Scalar len = 1e100)
{
++ episodeIndex_;
episodeStartTime_ = time_;
episodeLength_ = len;
}
/*!
* \brief Returns the index of the current episode.
*
* The first episode has the index 0.