Commit 2886e967 authored by Lukas Riedel's avatar Lukas Riedel

Fix time stepping behavior of KnoFuInterface

When a simulation end time coincided with a boundary condition change,
the solver would take one more step because the current time was less
than the final time.

Add a unit test case which covers the desired behavior.
parent a782cbee
......@@ -132,8 +132,15 @@ public:
// time has advanced after calculation
time += dt;
if(time >= tEnd-eps) // Simulation has ended. Do nothing
// Simulation has ended. Do nothing
if (time > tEnd) {
return true;
}
// NOTE: Simulation needs to know that we are actually at the end
else if (time <= tEnd && time >= tEnd-eps) {
time = tEnd;
return true;
}
dt = std::max(dt,dtmin);
dt = std::min(dt*dtinc,dtmax);
......@@ -145,18 +152,19 @@ public:
changeTime = tsc.getNextTimeStamp(time);
}
if(changeTime < 0.0 && time+dt > tEnd){
// time step adjustment to tEnd
dt = tEnd-time;
_log->trace("Adjusting time step to simulation end at: {:.2e}",
tEnd);
}
else if(changeTime > 0.0 && time+dt >= changeTime){
if(changeTime > 0.0 && time+dt >= changeTime){
// time step adjustment to BC Change
dt = changeTime-time-eps;
_log->trace("Adapting time step to change in boundary condition at "
"{:.2e}", changeTime);
}
if(time+dt > tEnd){
// time step adjustment to tEnd
dt = tEnd-time;
_log->trace("Adjusting time step to simulation end at: {:.2e}",
tEnd);
}
}
else // Newton solver threw error. Time is not advanced
......
spatial_resolution_north 0
spatial_resolution_south 0
spatial_resolution_west -1
spatial_resolution_east -1
number_BC_change_times 2
0 neumann 0 dirichlet 0
1000 neumann 0 dirichlet 0
......@@ -115,6 +115,34 @@ void verify_position_vector (const Sim& sim,
}
}
/// Run the simulation in the specified time frame and assert the final time
template<typename Sim>
bool check_time_stepping (Sim& sim,
const double time_begin,
const double time_end)
{
sim.set_propagation_times(time_begin, time_end);
sim.run();
return Dune::FloatCmp::eq(sim.current_time(), time_end);
}
/// Check if the simulation beforms the expected time stepping
template<typename Sim>
void test_sim_time (Sim& sim)
{
const double time_begin = 0.0;
// perform the first step to t=500
assert(check_time_stepping(sim, time_begin, 500.0));
// perform another step from t=0 to t=1000, where the BC changes
const auto time_bc_change = 1000.0;
assert(check_time_stepping(sim, time_begin, time_bc_change));
// perform final step to t=1500
assert(check_time_stepping(sim, time_bc_change, 1500.0));
}
int main(int argc, char** argv)
{
try{
......@@ -166,6 +194,11 @@ int main(int argc, char** argv)
log->info("Testing the state position vector");
verify_position_vector(sim_1, grid);
log->info("Performing the time step test");
Dune::Dorie::KnoFuInterface<Traits> sim_3(inifile, gc, helper,
Dune::Dorie::FilterSolutionType::matric_head);
test_sim_time(sim_3);
return 0;
}
catch (Dune::Exception &e){
......
include ${CMAKE_BINARY_DIR}/doc/default_files/config.ini
__name = sand, silt | expand medium
_asset_path = "${PROJECT_SOURCE_DIR}/test"
[grid]
dimensions = 2
......@@ -16,7 +15,10 @@ volume = 0, 1 | expand medium
[richards]
boundary.file = "{_asset_path}/bcs/infiltration_2d.dat"
output.logLevel = trace
time.startTimestep = 500
boundary.file = "${CMAKE_CURRENT_LIST_DIR}/test-knofu-interface-richards.bcdat"
parameters.file = test-param-richards-unscaled.yml
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment