Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
dumux-repositories
dumux-lecture
Commits
cc78c503
Commit
cc78c503
authored
Aug 02, 2021
by
Timo Koch
Browse files
[sequential] Add sequential header from upstream to prepare for removal in dumux
parent
76b48e27
Pipeline
#6880
failed with stage
Changes
36
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
dumux/common/boundaryconditions.hh
0 → 100644
View file @
cc78c503
// -*- 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
dumux/common/start.hh
0 → 100644
View file @
cc78c503
// -*- 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
dumux/common/timemanager.hh
0 → 100644
View file @
cc78c503
// -*- 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.
*/
int
episodeIndex
()
const
{
return
episodeIndex_
;
}
/*!
* \brief Returns the absolute time when the current episode
* started \f$\mathrm{[s]}\f$.
*/
Scalar
episodeStartTime
()
const
{
return
episodeStartTime_
;
}
/*!
* \brief Returns the length of the current episode in
* simulated time \f$\mathrm{[s]}\f$.
*/
Scalar
episodeLength
()
const
{
return
episodeLength_
;
}
/*!
* \brief Returns true if the current episode is finished at the
* current time.
*/
bool
episodeIsFinished
()
const
{
return
time
()
>=
episodeStartTime_
+
episodeLength
();
}
/*!
* \brief Returns true if the current episode will be finished
* after the current time step.
*/
bool
episodeWillBeFinished
()
const
{
return
time
()
+
timeStepSize
()
>=
episodeStartTime_
+
episodeLength
();
}
/*!
* \brief Aligns the time step size to the episode boundary if the
* current time step crosses the boundary of the current episode.
*/
Scalar
episodeMaxTimeStepSize
()
const
{
// if the current episode is over and the simulation
// wants to give it some extra time, we will return
// the time step size it suggested instead of trying
// to align it to the end of the episode.
if
(
episodeIsFinished
())
return
0.0
;
// make sure that we don't exceed the end of the
// current episode.
using
std
::
max
;
return
max
<
Scalar
>
(
0.0
,
episodeLength
()
-
(
time
()
-
episodeStartTime
()));
}
/*
* @}
*/
/*!
* \brief Runs the simulation using a given problem class.
*
* This method makes sure that time step sizes are aligned to
* episode boundaries, amongst other stuff.
*/
void
run
()
{
timer_
.
reset
();
// do the time steps
while
(
!
finished
())
{
// pre-process the current solution
problem_
->
preTimeStep
();
// execute the time integration scheme
problem_
->
timeIntegration
();
Scalar
dt
=
timeStepSize
();
// post-process the current solution
problem_
->
postTimeStep
();
// write the result to disk
if
(
problem_
->
shouldWriteOutput
())
problem_
->
writeOutput
();
// prepare the model for the next time integration
problem_
->
advanceTimeLevel
();
// write restart file if mandated by the problem
if
(
problem_
->
shouldWriteRestartFile
())
problem_
->
serialize
();
// advance the simulated time by the current time step size
time_
+=
dt
;
++
timeStepIdx_
;
if
(
verbose_
)
{
std
::
cout
<<
"Time step "
<<
timeStepIndex
()
<<
" done. "
<<
"Wall time:"
<<
timer_
.
elapsed
()
<<
", time:"
<<
time
()
<<
", time step size:"
<<
dt
<<
"
\n
"
;
}
// notify the problem if an episode is finished
if
(
episodeIsFinished
())
{
//define what to do at the end of an episode in the problem
problem_
->
episodeEnd
();
//check if a time step size was explicitly defined in problem->episodeEnd()
if
(
Dune
::
FloatCmp
::
eq
<
Scalar
>
(
dt
,
timeStepSize
()))
{
// set the initial time step size of a an episode to the last real time step size before the episode
using
std
::
max
;