From 88d6a626e35e2c697c23a7c87c326a2050c41d2a Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Tue, 27 Mar 2012 10:56:32 +0200 Subject: [PATCH 001/163] Added exmaple file --- examples/wells_example.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 examples/wells_example.cpp diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp new file mode 100644 index 000000000..68b54ce57 --- /dev/null +++ b/examples/wells_example.cpp @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include + +#include "opm/core/newwells.h" + +int main(int argc, char** argv) { + + using namespace Opm::parameter; + using namespace Opm; + ParameterGroup parameters( argc, argv, false ); + std::string file_name = parameters.getDefault("inputdeck", "data.data"); + + // Read input file + EclipseGridParser parser(file_name); + std::cout << "Done!" << std::endl; + // Setup grid + GridManager grid(parser); + + // Finally handle the wells + WellsManager wells(parser, *grid.c_grid(), NULL); + + return 0; +} + From 7db1027935777ddd23f1a51ec3f0ab839a14b6ad Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Tue, 10 Apr 2012 14:47:29 +0200 Subject: [PATCH 002/163] Fixed namespacing issue --- examples/wells_example.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 68b54ce57..2cc9bd8e6 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -3,8 +3,11 @@ #include #include #include - +#include +#include +#include #include "opm/core/newwells.h" +#include "opm/core/grid.h" int main(int argc, char** argv) { @@ -12,7 +15,7 @@ int main(int argc, char** argv) { using namespace Opm; ParameterGroup parameters( argc, argv, false ); std::string file_name = parameters.getDefault("inputdeck", "data.data"); - + // Read input file EclipseGridParser parser(file_name); std::cout << "Done!" << std::endl; @@ -22,6 +25,18 @@ int main(int argc, char** argv) { // Finally handle the wells WellsManager wells(parser, *grid.c_grid(), NULL); + std::vector global_cells(grid.c_grid()->global_cell, grid.c_grid()->global_cell + grid.c_grid()->number_of_cells); + + std::cout << "ahoi" << std::endl; + double gravity[3] = {0.0, 0.0, parameters.getDefault("gravity", 0.0)}; + IncompPropertiesFromDeck incomp_properties(parser, global_cells); + std::cout << "there" << std::endl; + + LinearSolverUmfpack umfpack_solver; + std::cout << "here" << std::endl; + IncompTpfa pressure_solver(*grid.c_grid(), incomp_properties.permeability(), + gravity, umfpack_solver, wells.c_wells()); + return 0; } From b37f1edc882501a7339c85a4e95cd52bf4f8dd6b Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Wed, 11 Apr 2012 15:29:58 +0200 Subject: [PATCH 003/163] Made linear solving of first timestep --- examples/wells_example.cpp | 45 ++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 2cc9bd8e6..ca09bc42f 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -1,14 +1,23 @@ #include #include #include + + +#include "opm/core/utility/initState.hpp" #include #include #include #include #include -#include "opm/core/newwells.h" -#include "opm/core/grid.h" +#include +#include +#include +#include +#include +#ifdef EXPERIMENT_ISTL +#include +#endif int main(int argc, char** argv) { using namespace Opm::parameter; @@ -27,16 +36,38 @@ int main(int argc, char** argv) { std::vector global_cells(grid.c_grid()->global_cell, grid.c_grid()->global_cell + grid.c_grid()->number_of_cells); - std::cout << "ahoi" << std::endl; double gravity[3] = {0.0, 0.0, parameters.getDefault("gravity", 0.0)}; IncompPropertiesFromDeck incomp_properties(parser, global_cells); - std::cout << "there" << std::endl; - LinearSolverUmfpack umfpack_solver; - std::cout << "here" << std::endl; +#ifdef EXPERIMENT_ISTL + Opm::LinearSolverIstl linsolver(parameters); +#else + Opm::LinearSolverUmfpack linsolver; +#endif // EXPERIMENT_ISTL IncompTpfa pressure_solver(*grid.c_grid(), incomp_properties.permeability(), - gravity, umfpack_solver, wells.c_wells()); + gravity, linsolver, wells.c_wells()); + + std::vector all_cells; + for(int i = 0; i < grid.c_grid()->number_of_cells; i++) { + all_cells.push_back(i); + } + + Opm::TwophaseState state; + + initStateTwophaseFromDeck(*grid.c_grid(), incomp_properties, parser, gravity[2], state); + + // Compute total mobility and omega + std::vector totmob; + std::vector omega; + computeTotalMobilityOmega(incomp_properties, all_cells, state.saturation(), totmob, omega); + + std::vector src; + Opm::FlowBCManager bcs; + + std::vector pressure; + std::vector face_flux; + pressure_solver.solve(totmob, omega, src, bcs.c_bcs(), pressure, face_flux); return 0; } From aaf887cf61b33b3af3cde4315d990320431403ff Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Thu, 12 Apr 2012 14:25:39 +0200 Subject: [PATCH 004/163] Made the WellNode be aware of their own index --- examples/wells_example.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index ca09bc42f..cebe46bd4 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -68,6 +68,14 @@ int main(int argc, char** argv) { std::vector pressure; std::vector face_flux; pressure_solver.solve(totmob, omega, src, bcs.c_bcs(), pressure, face_flux); + + if(wells.wellCollection().conditionsMet(pressure, *grid.c_grid())) { + std::cout << "Conditions met for wells!" << std::endl; + } + else + { + std::cout << "Conditions not met for wells!"< Date: Thu, 12 Apr 2012 15:48:24 +0200 Subject: [PATCH 005/163] Made queries upwards from wells to group to group --- examples/wells_example.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index cebe46bd4..4fb7c18c4 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -67,8 +67,8 @@ int main(int argc, char** argv) { std::vector pressure; std::vector face_flux; - pressure_solver.solve(totmob, omega, src, bcs.c_bcs(), pressure, face_flux); - + + //pressure_solver.solve(totmob, omega, src, bcs.c_bcs(), pressure, face_flux); if(wells.wellCollection().conditionsMet(pressure, *grid.c_grid())) { std::cout << "Conditions met for wells!" << std::endl; } From bbb5f56d2b14f551841487ed7245ff161eecf539 Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Thu, 12 Apr 2012 16:56:58 +0200 Subject: [PATCH 006/163] Changed input arguments for group checking --- examples/wells_example.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 4fb7c18c4..e11ee6050 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -68,8 +68,10 @@ int main(int argc, char** argv) { std::vector pressure; std::vector face_flux; - //pressure_solver.solve(totmob, omega, src, bcs.c_bcs(), pressure, face_flux); - if(wells.wellCollection().conditionsMet(pressure, *grid.c_grid())) { + std::vector well_bhp; + std::vector well_rate; + //pressure_solver.solve(totmob, omega, src, bcs.c_bcs(), pressure, face_flux, well_bhp, well_rate); + if(wells.wellCollection().conditionsMet(well_bhp, well_rate)) { std::cout << "Conditions met for wells!" << std::endl; } else From 23019eb23d1599b26e771029106174e0dd8e057f Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Thu, 12 Apr 2012 17:50:51 +0200 Subject: [PATCH 007/163] Made a computeWDP-function --- examples/wells_example.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index e11ee6050..d09a3fdb5 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -70,7 +70,8 @@ int main(int argc, char** argv) { std::vector well_bhp; std::vector well_rate; - //pressure_solver.solve(totmob, omega, src, bcs.c_bcs(), pressure, face_flux, well_bhp, well_rate); + pressure_solver.solve(totmob, omega, src, bcs.c_bcs(), pressure, face_flux, well_bhp, well_rate); + std::cout << "Solved" << std::endl; if(wells.wellCollection().conditionsMet(well_bhp, well_rate)) { std::cout << "Conditions met for wells!" << std::endl; } From 40ac7414ac00913327b1b5e37ec616f4ec2bf029 Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Thu, 12 Apr 2012 18:47:06 +0200 Subject: [PATCH 008/163] Made a (possibly wrong) adjustment to well_controls_append. Each control now has its current index set to 0, as there's only supposed to be one control per well. --- examples/wells_example.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index d09a3fdb5..11132ae0a 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -62,6 +62,10 @@ int main(int argc, char** argv) { std::vector omega; computeTotalMobilityOmega(incomp_properties, all_cells, state.saturation(), totmob, omega); + std::vector wdp; + std::vector densities(incomp_properties.density(), incomp_properties.density() + incomp_properties.numPhases()); + computeWDP(*wells.c_wells(), *grid.c_grid(), state.saturation(), densities, wdp); + std::vector src; Opm::FlowBCManager bcs; @@ -70,7 +74,7 @@ int main(int argc, char** argv) { std::vector well_bhp; std::vector well_rate; - pressure_solver.solve(totmob, omega, src, bcs.c_bcs(), pressure, face_flux, well_bhp, well_rate); + pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), pressure, face_flux, well_bhp, well_rate); std::cout << "Solved" << std::endl; if(wells.wellCollection().conditionsMet(well_bhp, well_rate)) { std::cout << "Conditions met for wells!" << std::endl; From fcca65748ee1b8c396f75d1fb5887dd64623b881 Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Fri, 13 Apr 2012 12:57:47 +0200 Subject: [PATCH 009/163] Added checks for BHP and fluid_volume_rate for group control. Also added error tolerance for group control --- examples/wells_example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 11132ae0a..09329be4e 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -76,7 +76,7 @@ int main(int argc, char** argv) { std::vector well_rate; pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), pressure, face_flux, well_bhp, well_rate); std::cout << "Solved" << std::endl; - if(wells.wellCollection().conditionsMet(well_bhp, well_rate)) { + if(wells.wellCollection().conditionsMet(well_bhp, well_rate, *grid.c_grid(), state.saturation() )) { std::cout << "Conditions met for wells!" << std::endl; } else From fb95c6da191c7a9ec09c28b557e91da8ba0a4a53 Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Fri, 13 Apr 2012 14:22:44 +0200 Subject: [PATCH 010/163] Added computations for total flow for each well --- examples/wells_example.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 09329be4e..44201ff54 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -73,9 +73,12 @@ int main(int argc, char** argv) { std::vector face_flux; std::vector well_bhp; - std::vector well_rate; - pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), pressure, face_flux, well_bhp, well_rate); + std::vector well_rate_per_cell; + pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), pressure, face_flux, well_bhp, well_rate_per_cell); std::cout << "Solved" << std::endl; + + std::vector well_rate; + computeFlowRatePerWell(*wells.c_wells(), well_rate_per_cell, well_rate); if(wells.wellCollection().conditionsMet(well_bhp, well_rate, *grid.c_grid(), state.saturation() )) { std::cout << "Conditions met for wells!" << std::endl; } From fe739986be35b3f0aef50cd0d11ff4831c3600b2 Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Fri, 13 Apr 2012 20:41:09 +0200 Subject: [PATCH 011/163] modified the group control interface slightly --- examples/wells_example.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 44201ff54..6c8d95509 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -77,7 +77,11 @@ int main(int argc, char** argv) { pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), pressure, face_flux, well_bhp, well_rate_per_cell); std::cout << "Solved" << std::endl; + for(size_t i = 0; i < well_rate_per_cell.size(); i++) { + std::cout << well_rate_per_cell[i] << std::endl; + } std::vector well_rate; + computeFlowRatePerWell(*wells.c_wells(), well_rate_per_cell, well_rate); if(wells.wellCollection().conditionsMet(well_bhp, well_rate, *grid.c_grid(), state.saturation() )) { std::cout << "Conditions met for wells!" << std::endl; From d557b91db059f93df5938dfa007b139b1ca6f54e Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Mon, 16 Apr 2012 12:18:37 +0200 Subject: [PATCH 012/163] Made use of the new LinearSolverFactory in wells_example --- examples/wells_example.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 6c8d95509..8059cb8e6 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -8,16 +8,12 @@ #include #include #include -#include #include #include #include #include #include - -#ifdef EXPERIMENT_ISTL -#include -#endif +#include int main(int argc, char** argv) { using namespace Opm::parameter; @@ -39,11 +35,9 @@ int main(int argc, char** argv) { double gravity[3] = {0.0, 0.0, parameters.getDefault("gravity", 0.0)}; IncompPropertiesFromDeck incomp_properties(parser, global_cells); -#ifdef EXPERIMENT_ISTL - Opm::LinearSolverIstl linsolver(parameters); -#else - Opm::LinearSolverUmfpack linsolver; -#endif // EXPERIMENT_ISTL + Opm::LinearSolverFactory linsolver(parameters); + + // EXPERIMENT_ISTL IncompTpfa pressure_solver(*grid.c_grid(), incomp_properties.permeability(), gravity, linsolver, wells.c_wells()); From 4197f16a147cf7eae89ed39ce6f5c13761c47e6f Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Tue, 17 Apr 2012 16:36:49 +0200 Subject: [PATCH 013/163] Passed around a WellControlResult argument to the different wellcontrol functions --- examples/wells_example.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 8059cb8e6..b60a4fb95 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -77,7 +77,8 @@ int main(int argc, char** argv) { std::vector well_rate; computeFlowRatePerWell(*wells.c_wells(), well_rate_per_cell, well_rate); - if(wells.wellCollection().conditionsMet(well_bhp, well_rate, *grid.c_grid(), state.saturation() )) { + WellControlResult well_control_results; + if(wells.wellCollection().conditionsMet(well_bhp, well_rate, *grid.c_grid(), state.saturation(), well_control_results )) { std::cout << "Conditions met for wells!" << std::endl; } else From 1d544455462032e0feb79cef37981a2bd72bbe22 Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Mon, 23 Apr 2012 13:24:47 +0200 Subject: [PATCH 014/163] Added a (small) hack to wellmanager (defaulting injected_phase to water) --- examples/wells_example.cpp | 41 +++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index b60a4fb95..f57b4d46a 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -78,13 +78,44 @@ int main(int argc, char** argv) { computeFlowRatePerWell(*wells.c_wells(), well_rate_per_cell, well_rate); WellControlResult well_control_results; - if(wells.wellCollection().conditionsMet(well_bhp, well_rate, *grid.c_grid(), state.saturation(), well_control_results )) { - std::cout << "Conditions met for wells!" << std::endl; - } - else + wells.wellCollection().conditionsMet(well_bhp, well_rate, *grid.c_grid(), state.saturation(), well_control_results ); + wells.applyControl(well_control_results); + +#if 0 + std::vector porevol; + computePorevolume(*grid->c_grid(), incomp_properties, porevol); + + + + TwophaseFluid fluid(incomp_properties); + TransportModel model (fluid, *grid->c_grid(), porevol, gravity[2], true); + + TransportSolver tsolver(model); + + TransportSource* tsrc = create_transport_source(2, 2); + double ssrc[] = { 1.0, 0.0 }; + double ssink[] = { 0.0, 1.0 }; + double zdummy[] = { 0.0, 0.0 }; + { - std::cout << "Conditions not met for wells!"<number_of_wells; ++well) { + for( int cell = wells.c_wells()->well_connpos[well]; cell < wells.c_wells()->well_connpos[well + 1]; ++cell) { + if (well_rate_per_cell[well_cell_index] > 0.0) { + append_transport_source(well_cell_index, 2, 0, + well_rate_per_cell[well_cell_index], ssrc, zdummy, tsrc); + } else if (well_rate_per_cell[well_cell_index] < 0.0) { + append_transport_source(well_cell_index, 2, 0, + well_rate_per_cell[well_cell_index], ssink, zdummy, tsrc); + } + } + } } + + tsolver.solve(*grid->c_grid(), tsrc, stepsize, ctrl, state, linsolve, rpt); + + Opm::computeInjectedProduced(*props, state.saturation(), src, stepsize, injected, produced); +#endif return 0; } From 4e55e8c91284141323ff6015fa487cc83813a286 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 24 Apr 2012 13:48:00 +0200 Subject: [PATCH 015/163] Minor change to computeWDP() interface. --- examples/wells_example.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index f57b4d46a..ea126dbaa 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -57,8 +57,7 @@ int main(int argc, char** argv) { computeTotalMobilityOmega(incomp_properties, all_cells, state.saturation(), totmob, omega); std::vector wdp; - std::vector densities(incomp_properties.density(), incomp_properties.density() + incomp_properties.numPhases()); - computeWDP(*wells.c_wells(), *grid.c_grid(), state.saturation(), densities, wdp); + computeWDP(*wells.c_wells(), *grid.c_grid(), state.saturation(), incomp_properties.density(), wdp, true); std::vector src; Opm::FlowBCManager bcs; From 8acd9d9f63807032f7829f5a6f30374e89578b65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 25 Apr 2012 12:37:30 +0200 Subject: [PATCH 016/163] Fixed bug in computeWDP(), add gravity argument. Make WellReport output in friendly units. --- examples/wells_example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index ea126dbaa..bb40cc8a2 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -57,7 +57,7 @@ int main(int argc, char** argv) { computeTotalMobilityOmega(incomp_properties, all_cells, state.saturation(), totmob, omega); std::vector wdp; - computeWDP(*wells.c_wells(), *grid.c_grid(), state.saturation(), incomp_properties.density(), wdp, true); + computeWDP(*wells.c_wells(), *grid.c_grid(), state.saturation(), incomp_properties.density(), gravity[2], true, wdp); std::vector src; Opm::FlowBCManager bcs; From 6b00381393488e02a124e2b322e26a002e6d10e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 25 Apr 2012 14:03:57 +0200 Subject: [PATCH 017/163] Removed unused saturation argument from conditionsMet() methods. --- examples/wells_example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index bb40cc8a2..ef2fb6ed3 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -77,7 +77,7 @@ int main(int argc, char** argv) { computeFlowRatePerWell(*wells.c_wells(), well_rate_per_cell, well_rate); WellControlResult well_control_results; - wells.wellCollection().conditionsMet(well_bhp, well_rate, *grid.c_grid(), state.saturation(), well_control_results ); + wells.wellCollection().conditionsMet(well_bhp, well_rate, *grid.c_grid(), well_control_results ); wells.applyControl(well_control_results); #if 0 From 7c6ac0bf09ff4eceb38e01290a8058777284374a Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Wed, 25 Apr 2012 16:14:40 +0200 Subject: [PATCH 018/163] Completly revamped the way group control is checked --- examples/wells_example.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index ef2fb6ed3..6c253129b 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -76,9 +76,17 @@ int main(int argc, char** argv) { std::vector well_rate; computeFlowRatePerWell(*wells.c_wells(), well_rate_per_cell, well_rate); - WellControlResult well_control_results; - wells.wellCollection().conditionsMet(well_bhp, well_rate, *grid.c_grid(), well_control_results ); - wells.applyControl(well_control_results); + + while (!wells.conditionsMet(well_bhp, well_rate)) { + std::cout << "Conditions not met for well, trying again" << std::endl; + pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), pressure, face_flux, well_bhp, well_rate_per_cell); + std::cout << "Solved" << std::endl; + + for (size_t i = 0; i < well_rate_per_cell.size(); i++) { + std::cout << well_rate_per_cell[i] << std::endl; + } + computeFlowRatePerWell(*wells.c_wells(), well_rate_per_cell, well_rate); + } #if 0 std::vector porevol; From bebe50afb0d94888191710ca652b81cab5f0eced Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Wed, 2 May 2012 13:02:59 +0200 Subject: [PATCH 019/163] Final fixes for new well structure (to make it compile) --- examples/wells_example.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 6c253129b..cc20e91ec 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -77,6 +77,7 @@ int main(int argc, char** argv) { computeFlowRatePerWell(*wells.c_wells(), well_rate_per_cell, well_rate); + #if 0 while (!wells.conditionsMet(well_bhp, well_rate)) { std::cout << "Conditions not met for well, trying again" << std::endl; pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), pressure, face_flux, well_bhp, well_rate_per_cell); @@ -88,7 +89,7 @@ int main(int argc, char** argv) { computeFlowRatePerWell(*wells.c_wells(), well_rate_per_cell, well_rate); } -#if 0 + std::vector porevol; computePorevolume(*grid->c_grid(), incomp_properties, porevol); From 81a9d2a5c14f21431a87a8294f62e0af72a05856 Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Thu, 3 May 2012 12:29:18 +0200 Subject: [PATCH 020/163] Added calculation of fractional flows and per phase flows in wells_example --- examples/wells_example.cpp | 49 +++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index cc20e91ec..ccb2a0285 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -51,6 +51,9 @@ int main(int argc, char** argv) { initStateTwophaseFromDeck(*grid.c_grid(), incomp_properties, parser, gravity[2], state); + // Compute phase mobilities + std::vector phase_mob; + computePhaseMobilities(incomp_properties, all_cells, state.saturation(), phase_mob); // Compute total mobility and omega std::vector totmob; std::vector omega; @@ -75,21 +78,55 @@ int main(int argc, char** argv) { } std::vector well_rate; + // This will be refactored into a separate function once done. + const int np = incomp_properties.numPhases(); + std::vector fractional_flows(grid.c_grid()->number_of_cells*np, 0.0); + for (int cell = 0; cell < grid.c_grid()->number_of_cells; ++cell) { + double phase_sum = 0.0; + for (int phase = 0; phase < np; ++phase) { + phase_sum += phase_mob[cell*np + phase]; + } + for (int phase = 0; phase < np; ++phase) { + fractional_flows[cell*np + phase] = phase_mob[cell*np + phase] / phase_sum; + } + } + // End stuff that needs to be refactored into a seperated function + computeFlowRatePerWell(*wells.c_wells(), well_rate_per_cell, well_rate); + + // This will be refactored into a separate function once done + std::vector well_resflows(wells.c_wells()->number_of_wells*np, 0.0); + for ( int wix = 0; wix < wells.c_wells()->number_of_wells; ++wix) { + for (int i = wells.c_wells()->well_connpos[wix]; i < wells.c_wells()->well_connpos[wix+1]; ++i) { + const int cell = wells.c_wells()->well_cells[i]; + for (int phase = 0; phase < np; ++phase) { + well_resflows[wix*np + phase] += well_rate_per_cell[i]*fractional_flows[cell*np + phase]; + } + } + } - #if 0 - while (!wells.conditionsMet(well_bhp, well_rate)) { + // We approximate (for _testing_ that resflows = surfaceflows) + while (!wells.conditionsMet(well_bhp, well_resflows, well_resflows)) { std::cout << "Conditions not met for well, trying again" << std::endl; pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), pressure, face_flux, well_bhp, well_rate_per_cell); std::cout << "Solved" << std::endl; - for (size_t i = 0; i < well_rate_per_cell.size(); i++) { - std::cout << well_rate_per_cell[i] << std::endl; + + for (int wix = 0; wix < wells.c_wells()->number_of_wells; ++wix) { + for (int phase = 0; phase < np; ++phase) { + // Reset + well_resflows[wix * np + phase] = 0.0; + } + for (int i = wells.c_wells()->well_connpos[wix]; i < wells.c_wells()->well_connpos[wix + 1]; ++i) { + const int cell = wells.c_wells()->well_cells[i]; + for (int phase = 0; phase < np; ++phase) { + well_resflows[wix * np + phase] += well_rate_per_cell[i] * fractional_flows[cell * np + phase]; + } + } } - computeFlowRatePerWell(*wells.c_wells(), well_rate_per_cell, well_rate); } - +#if 0 std::vector porevol; computePorevolume(*grid->c_grid(), incomp_properties, porevol); From 6782067d8d841253bb04611e46c83c9f09f3e436 Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Thu, 3 May 2012 15:35:44 +0200 Subject: [PATCH 021/163] Made a maximum number of iterations in wells_test --- examples/wells_example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index ccb2a0285..32451a7e9 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -106,7 +106,7 @@ int main(int argc, char** argv) { } // We approximate (for _testing_ that resflows = surfaceflows) - while (!wells.conditionsMet(well_bhp, well_resflows, well_resflows)) { + for (int iter = 0; iter < 10 && !wells.conditionsMet(well_bhp, well_resflows, well_resflows); ++iter) { std::cout << "Conditions not met for well, trying again" << std::endl; pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), pressure, face_flux, well_bhp, well_rate_per_cell); std::cout << "Solved" << std::endl; From 562573a07862b49e60628138afbcd222efe92efa Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Mon, 7 May 2012 13:29:52 +0200 Subject: [PATCH 022/163] Inserted rock_comp into wells_example. --- examples/wells_example.cpp | 76 ++++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 8 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 32451a7e9..82673cdc8 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -4,6 +4,7 @@ #include "opm/core/utility/initState.hpp" +#include "opm/core/utility/SimulatorTimer.hpp" #include #include #include @@ -14,6 +15,7 @@ #include #include #include +#include int main(int argc, char** argv) { using namespace Opm::parameter; @@ -21,6 +23,9 @@ int main(int argc, char** argv) { ParameterGroup parameters( argc, argv, false ); std::string file_name = parameters.getDefault("inputdeck", "data.data"); + SimulatorTimer simtimer; + simtimer.init(parameters); + // Read input file EclipseGridParser parser(file_name); std::cout << "Done!" << std::endl; @@ -35,6 +40,8 @@ int main(int argc, char** argv) { double gravity[3] = {0.0, 0.0, parameters.getDefault("gravity", 0.0)}; IncompPropertiesFromDeck incomp_properties(parser, global_cells); + RockCompressibility rock_comp(parser); + Opm::LinearSolverFactory linsolver(parameters); // EXPERIMENT_ISTL @@ -70,13 +77,43 @@ int main(int argc, char** argv) { std::vector well_bhp; std::vector well_rate_per_cell; - pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), pressure, face_flux, well_bhp, well_rate_per_cell); - std::cout << "Solved" << std::endl; + std::vector rc; + rc.resize(grid.c_grid()->number_of_cells); - for(size_t i = 0; i < well_rate_per_cell.size(); i++) { - std::cout << well_rate_per_cell[i] << std::endl; + const int nl_pressure_maxiter = 100; + const double nl_pressure_tolerance = 1e-8; + const int num_cells = grid.c_grid()->number_of_cells; + std::vector porevol; + if (rock_comp.isActive()) { + computePorevolume(*grid.c_grid(), incomp_properties, rock_comp, state.pressure(), porevol); + } else { + computePorevolume(*grid.c_grid(), incomp_properties, porevol); } - std::vector well_rate; + if (rock_comp.isActive()) { + std::vector initial_pressure = state.pressure(); + std::vector prev_pressure; + for (int iter = 0; iter < nl_pressure_maxiter; ++iter) { + prev_pressure = state.pressure(); + for (int cell = 0; cell < num_cells; ++cell) { + rc[cell] = rock_comp.rockComp(state.pressure()[cell]); + } + state.pressure() = initial_pressure; + pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), porevol, rc, simtimer.currentStepLength(), + state.pressure(), state.faceflux(), well_bhp, well_rate_per_cell); + double max_change = 0.0; + for (int cell = 0; cell < num_cells; ++cell) { + max_change = std::max(max_change, std::fabs(state.pressure()[cell] - prev_pressure[cell])); + } + std::cout << "Pressure iter " << iter << " max change = " << max_change << std::endl; + if (max_change < nl_pressure_tolerance) { + break; + } + } + computePorevolume(*grid.c_grid(), incomp_properties, rock_comp, state.pressure(), porevol); + } else { + pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), state.pressure(), state.faceflux(), + well_bhp, well_rate_per_cell); + } // This will be refactored into a separate function once done. const int np = incomp_properties.numPhases(); @@ -92,7 +129,6 @@ int main(int argc, char** argv) { } // End stuff that needs to be refactored into a seperated function - computeFlowRatePerWell(*wells.c_wells(), well_rate_per_cell, well_rate); // This will be refactored into a separate function once done std::vector well_resflows(wells.c_wells()->number_of_wells*np, 0.0); @@ -106,9 +142,33 @@ int main(int argc, char** argv) { } // We approximate (for _testing_ that resflows = surfaceflows) - for (int iter = 0; iter < 10 && !wells.conditionsMet(well_bhp, well_resflows, well_resflows); ++iter) { + for (int wc_iter = 0; wc_iter < 10 && !wells.conditionsMet(well_bhp, well_resflows, well_resflows); ++wc_iter) { std::cout << "Conditions not met for well, trying again" << std::endl; - pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), pressure, face_flux, well_bhp, well_rate_per_cell); + if (rock_comp.isActive()) { + std::vector initial_pressure = state.pressure(); + std::vector prev_pressure; + for (int iter = 0; iter < nl_pressure_maxiter; ++iter) { + prev_pressure = state.pressure(); + for (int cell = 0; cell < num_cells; ++cell) { + rc[cell] = rock_comp.rockComp(state.pressure()[cell]); + } + state.pressure() = initial_pressure; + pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), porevol, rc, simtimer.currentStepLength(), + state.pressure(), state.faceflux(), well_bhp, well_rate_per_cell); + double max_change = 0.0; + for (int cell = 0; cell < num_cells; ++cell) { + max_change = std::max(max_change, std::fabs(state.pressure()[cell] - prev_pressure[cell])); + } + std::cout << "Pressure iter " << iter << " max change = " << max_change << std::endl; + if (max_change < nl_pressure_tolerance) { + break; + } + } + computePorevolume(*grid.c_grid(), incomp_properties, rock_comp, state.pressure(), porevol); + } else { + pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), state.pressure(), state.faceflux(), + well_bhp, well_rate_per_cell); + } std::cout << "Solved" << std::endl; From 72a0db5f73c40af80fcff7e375caf94b42145f90 Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Mon, 7 May 2012 15:51:54 +0200 Subject: [PATCH 023/163] removed an extra uneeded call to the pressure solver --- examples/wells_example.cpp | 120 +++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 59 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 82673cdc8..3d9380ebd 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -16,12 +16,14 @@ #include #include #include -int main(int argc, char** argv) { + +int main(int argc, char** argv) +{ using namespace Opm::parameter; using namespace Opm; - ParameterGroup parameters( argc, argv, false ); - std::string file_name = parameters.getDefault("inputdeck", "data.data"); + ParameterGroup parameters(argc, argv, false); + std::string file_name = parameters.getDefault ("inputdeck", "data.data"); SimulatorTimer simtimer; simtimer.init(parameters); @@ -31,10 +33,10 @@ int main(int argc, char** argv) { std::cout << "Done!" << std::endl; // Setup grid GridManager grid(parser); - + // Finally handle the wells WellsManager wells(parser, *grid.c_grid(), NULL); - + std::vector global_cells(grid.c_grid()->global_cell, grid.c_grid()->global_cell + grid.c_grid()->number_of_cells); double gravity[3] = {0.0, 0.0, parameters.getDefault("gravity", 0.0)}; @@ -45,19 +47,19 @@ int main(int argc, char** argv) { Opm::LinearSolverFactory linsolver(parameters); // EXPERIMENT_ISTL - IncompTpfa pressure_solver(*grid.c_grid(), incomp_properties.permeability(), - gravity, linsolver, wells.c_wells()); - - + IncompTpfa pressure_solver(*grid.c_grid(), incomp_properties.permeability(), + gravity, linsolver, wells.c_wells()); + + std::vector all_cells; - for(int i = 0; i < grid.c_grid()->number_of_cells; i++) { + for (int i = 0; i < grid.c_grid()->number_of_cells; i++) { all_cells.push_back(i); } - + Opm::TwophaseState state; - + initStateTwophaseFromDeck(*grid.c_grid(), incomp_properties, parser, gravity[2], state); - + // Compute phase mobilities std::vector phase_mob; computePhaseMobilities(incomp_properties, all_cells, state.saturation(), phase_mob); @@ -65,10 +67,10 @@ int main(int argc, char** argv) { std::vector totmob; std::vector omega; computeTotalMobilityOmega(incomp_properties, all_cells, state.saturation(), totmob, omega); - + std::vector wdp; computeWDP(*wells.c_wells(), *grid.c_grid(), state.saturation(), incomp_properties.density(), gravity[2], true, wdp); - + std::vector src; Opm::FlowBCManager bcs; @@ -79,7 +81,7 @@ int main(int argc, char** argv) { std::vector well_rate_per_cell; std::vector rc; rc.resize(grid.c_grid()->number_of_cells); - + const int nl_pressure_maxiter = 100; const double nl_pressure_tolerance = 1e-8; const int num_cells = grid.c_grid()->number_of_cells; @@ -90,53 +92,53 @@ int main(int argc, char** argv) { computePorevolume(*grid.c_grid(), incomp_properties, porevol); } if (rock_comp.isActive()) { - std::vector initial_pressure = state.pressure(); - std::vector prev_pressure; - for (int iter = 0; iter < nl_pressure_maxiter; ++iter) { - prev_pressure = state.pressure(); - for (int cell = 0; cell < num_cells; ++cell) { - rc[cell] = rock_comp.rockComp(state.pressure()[cell]); - } - state.pressure() = initial_pressure; - pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), porevol, rc, simtimer.currentStepLength(), - state.pressure(), state.faceflux(), well_bhp, well_rate_per_cell); - double max_change = 0.0; - for (int cell = 0; cell < num_cells; ++cell) { - max_change = std::max(max_change, std::fabs(state.pressure()[cell] - prev_pressure[cell])); - } - std::cout << "Pressure iter " << iter << " max change = " << max_change << std::endl; - if (max_change < nl_pressure_tolerance) { - break; - } + std::vector initial_pressure = state.pressure(); + std::vector prev_pressure; + for (int iter = 0; iter < nl_pressure_maxiter; ++iter) { + prev_pressure = state.pressure(); + for (int cell = 0; cell < num_cells; ++cell) { + rc[cell] = rock_comp.rockComp(state.pressure()[cell]); + } + state.pressure() = initial_pressure; + pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), porevol, rc, simtimer.currentStepLength(), + state.pressure(), state.faceflux(), well_bhp, well_rate_per_cell); + double max_change = 0.0; + for (int cell = 0; cell < num_cells; ++cell) { + max_change = std::max(max_change, std::fabs(state.pressure()[cell] - prev_pressure[cell])); + } + std::cout << "Pressure iter " << iter << " max change = " << max_change << std::endl; + if (max_change < nl_pressure_tolerance) { + break; } - computePorevolume(*grid.c_grid(), incomp_properties, rock_comp, state.pressure(), porevol); - } else { - pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), state.pressure(), state.faceflux(), - well_bhp, well_rate_per_cell); } - + computePorevolume(*grid.c_grid(), incomp_properties, rock_comp, state.pressure(), porevol); + } else { + pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), state.pressure(), state.faceflux(), + well_bhp, well_rate_per_cell); + } + // This will be refactored into a separate function once done. const int np = incomp_properties.numPhases(); std::vector fractional_flows(grid.c_grid()->number_of_cells*np, 0.0); for (int cell = 0; cell < grid.c_grid()->number_of_cells; ++cell) { double phase_sum = 0.0; for (int phase = 0; phase < np; ++phase) { - phase_sum += phase_mob[cell*np + phase]; + phase_sum += phase_mob[cell * np + phase]; } for (int phase = 0; phase < np; ++phase) { - fractional_flows[cell*np + phase] = phase_mob[cell*np + phase] / phase_sum; + fractional_flows[cell * np + phase] = phase_mob[cell * np + phase] / phase_sum; } } // End stuff that needs to be refactored into a seperated function - - + + // This will be refactored into a separate function once done std::vector well_resflows(wells.c_wells()->number_of_wells*np, 0.0); - for ( int wix = 0; wix < wells.c_wells()->number_of_wells; ++wix) { - for (int i = wells.c_wells()->well_connpos[wix]; i < wells.c_wells()->well_connpos[wix+1]; ++i) { + for (int wix = 0; wix < wells.c_wells()->number_of_wells; ++wix) { + for (int i = wells.c_wells()->well_connpos[wix]; i < wells.c_wells()->well_connpos[wix + 1]; ++i) { const int cell = wells.c_wells()->well_cells[i]; for (int phase = 0; phase < np; ++phase) { - well_resflows[wix*np + phase] += well_rate_per_cell[i]*fractional_flows[cell*np + phase]; + well_resflows[wix * np + phase] += well_rate_per_cell[i] * fractional_flows[cell * np + phase]; } } } @@ -154,7 +156,7 @@ int main(int argc, char** argv) { } state.pressure() = initial_pressure; pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), porevol, rc, simtimer.currentStepLength(), - state.pressure(), state.faceflux(), well_bhp, well_rate_per_cell); + state.pressure(), state.faceflux(), well_bhp, well_rate_per_cell); double max_change = 0.0; for (int cell = 0; cell < num_cells; ++cell) { max_change = std::max(max_change, std::fabs(state.pressure()[cell] - prev_pressure[cell])); @@ -167,7 +169,7 @@ int main(int argc, char** argv) { computePorevolume(*grid.c_grid(), incomp_properties, rock_comp, state.pressure(), porevol); } else { pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), state.pressure(), state.faceflux(), - well_bhp, well_rate_per_cell); + well_bhp, well_rate_per_cell); } std::cout << "Solved" << std::endl; @@ -189,28 +191,28 @@ int main(int argc, char** argv) { #if 0 std::vector porevol; computePorevolume(*grid->c_grid(), incomp_properties, porevol); - - + + TwophaseFluid fluid(incomp_properties); - TransportModel model (fluid, *grid->c_grid(), porevol, gravity[2], true); + TransportModel model(fluid, *grid->c_grid(), porevol, gravity[2], true); TransportSolver tsolver(model); TransportSource* tsrc = create_transport_source(2, 2); - double ssrc[] = { 1.0, 0.0 }; - double ssink[] = { 0.0, 1.0 }; - double zdummy[] = { 0.0, 0.0 }; - + double ssrc[] = {1.0, 0.0}; + double ssink[] = {0.0, 1.0}; + double zdummy[] = {0.0, 0.0}; + { int well_cell_index = 0; for (int well = 0; well < wells.c_wells()->number_of_wells; ++well) { - for( int cell = wells.c_wells()->well_connpos[well]; cell < wells.c_wells()->well_connpos[well + 1]; ++cell) { + for (int cell = wells.c_wells()->well_connpos[well]; cell < wells.c_wells()->well_connpos[well + 1]; ++cell) { if (well_rate_per_cell[well_cell_index] > 0.0) { - append_transport_source(well_cell_index, 2, 0, + append_transport_source(well_cell_index, 2, 0, well_rate_per_cell[well_cell_index], ssrc, zdummy, tsrc); } else if (well_rate_per_cell[well_cell_index] < 0.0) { - append_transport_source(well_cell_index, 2, 0, + append_transport_source(well_cell_index, 2, 0, well_rate_per_cell[well_cell_index], ssink, zdummy, tsrc); } } @@ -218,7 +220,7 @@ int main(int argc, char** argv) { } tsolver.solve(*grid->c_grid(), tsrc, stepsize, ctrl, state, linsolve, rpt); - + Opm::computeInjectedProduced(*props, state.saturation(), src, stepsize, injected, produced); #endif return 0; From 0bd88866f2325aa9f51ea4a9f61c78dfbf927c62 Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Tue, 8 May 2012 11:04:15 +0200 Subject: [PATCH 024/163] Refactored some computations into seperate methods in wells_example.cpp --- examples/wells_example.cpp | 36 +++--------------------------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 3d9380ebd..168a5168c 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -120,29 +120,11 @@ int main(int argc, char** argv) // This will be refactored into a separate function once done. const int np = incomp_properties.numPhases(); std::vector fractional_flows(grid.c_grid()->number_of_cells*np, 0.0); - for (int cell = 0; cell < grid.c_grid()->number_of_cells; ++cell) { - double phase_sum = 0.0; - for (int phase = 0; phase < np; ++phase) { - phase_sum += phase_mob[cell * np + phase]; - } - for (int phase = 0; phase < np; ++phase) { - fractional_flows[cell * np + phase] = phase_mob[cell * np + phase] / phase_sum; - } - } - // End stuff that needs to be refactored into a seperated function - + //computeFractionalFlow(incomp_properties, all_cells, state.saturation(), fractional_flows); // This will be refactored into a separate function once done std::vector well_resflows(wells.c_wells()->number_of_wells*np, 0.0); - for (int wix = 0; wix < wells.c_wells()->number_of_wells; ++wix) { - for (int i = wells.c_wells()->well_connpos[wix]; i < wells.c_wells()->well_connpos[wix + 1]; ++i) { - const int cell = wells.c_wells()->well_cells[i]; - for (int phase = 0; phase < np; ++phase) { - well_resflows[wix * np + phase] += well_rate_per_cell[i] * fractional_flows[cell * np + phase]; - } - } - } - + computePhaseFlowRatesPerWell(*wells.c_wells(), well_rate_per_cell, fractional_flows, well_resflows); // We approximate (for _testing_ that resflows = surfaceflows) for (int wc_iter = 0; wc_iter < 10 && !wells.conditionsMet(well_bhp, well_resflows, well_resflows); ++wc_iter) { std::cout << "Conditions not met for well, trying again" << std::endl; @@ -173,19 +155,7 @@ int main(int argc, char** argv) } std::cout << "Solved" << std::endl; - - for (int wix = 0; wix < wells.c_wells()->number_of_wells; ++wix) { - for (int phase = 0; phase < np; ++phase) { - // Reset - well_resflows[wix * np + phase] = 0.0; - } - for (int i = wells.c_wells()->well_connpos[wix]; i < wells.c_wells()->well_connpos[wix + 1]; ++i) { - const int cell = wells.c_wells()->well_cells[i]; - for (int phase = 0; phase < np; ++phase) { - well_resflows[wix * np + phase] += well_rate_per_cell[i] * fractional_flows[cell * np + phase]; - } - } - } + computePhaseFlowRatesPerWell(*wells.c_wells(), well_rate_per_cell, fractional_flows, well_resflows); } #if 0 From 886457002e2fa78f28218aca432df08e55dde779 Mon Sep 17 00:00:00 2001 From: Kjetil Olsen Lye Date: Tue, 8 May 2012 12:23:58 +0200 Subject: [PATCH 025/163] Changed some minor bugs in the refactored code in wells_example --- examples/wells_example.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 168a5168c..159e43ac3 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -81,9 +81,14 @@ int main(int argc, char** argv) std::vector well_rate_per_cell; std::vector rc; rc.resize(grid.c_grid()->number_of_cells); + + int nl_pressure_maxiter = 100; + double nl_pressure_tolerance = 0.0; + if (rock_comp.isActive()) { + nl_pressure_maxiter = parameters.getDefault("nl_pressure_maxiter", 10); + nl_pressure_tolerance = parameters.getDefault("nl_pressure_tolerance", 1.0); // in Pascal + } - const int nl_pressure_maxiter = 100; - const double nl_pressure_tolerance = 1e-8; const int num_cells = grid.c_grid()->number_of_cells; std::vector porevol; if (rock_comp.isActive()) { @@ -117,10 +122,9 @@ int main(int argc, char** argv) well_bhp, well_rate_per_cell); } - // This will be refactored into a separate function once done. const int np = incomp_properties.numPhases(); std::vector fractional_flows(grid.c_grid()->number_of_cells*np, 0.0); - //computeFractionalFlow(incomp_properties, all_cells, state.saturation(), fractional_flows); + computeFractionalFlow(incomp_properties, all_cells, state.saturation(), fractional_flows); // This will be refactored into a separate function once done std::vector well_resflows(wells.c_wells()->number_of_wells*np, 0.0); From efce958c3b17e9771461eee78298cee7c0cd9ea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 14 May 2012 21:47:10 +0200 Subject: [PATCH 026/163] Now computePorevolume() takes a porosity array instead of a property object. This is to make it compatible with blackoil properties. An alternative would be to give [Incomp|Blackoil]PropertiesInterface a common base class (RockInterface?) with the common rock-related methods. --- examples/wells_example.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 159e43ac3..2c0709918 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -92,9 +92,9 @@ int main(int argc, char** argv) const int num_cells = grid.c_grid()->number_of_cells; std::vector porevol; if (rock_comp.isActive()) { - computePorevolume(*grid.c_grid(), incomp_properties, rock_comp, state.pressure(), porevol); + computePorevolume(*grid.c_grid(), incomp_properties.porosity(), rock_comp, state.pressure(), porevol); } else { - computePorevolume(*grid.c_grid(), incomp_properties, porevol); + computePorevolume(*grid.c_grid(), incomp_properties.porosity(), porevol); } if (rock_comp.isActive()) { std::vector initial_pressure = state.pressure(); @@ -116,7 +116,7 @@ int main(int argc, char** argv) break; } } - computePorevolume(*grid.c_grid(), incomp_properties, rock_comp, state.pressure(), porevol); + computePorevolume(*grid.c_grid(), incomp_properties.porosity(), rock_comp, state.pressure(), porevol); } else { pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), state.pressure(), state.faceflux(), well_bhp, well_rate_per_cell); @@ -152,7 +152,7 @@ int main(int argc, char** argv) break; } } - computePorevolume(*grid.c_grid(), incomp_properties, rock_comp, state.pressure(), porevol); + computePorevolume(*grid.c_grid(), incomp_properties.porosity(), rock_comp, state.pressure(), porevol); } else { pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), state.pressure(), state.faceflux(), well_bhp, well_rate_per_cell); From 13334f97d7ab910e0ccc29a70da97fe443e7c860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 16 May 2012 11:37:31 +0200 Subject: [PATCH 027/163] Renamed initStateTwophaseFromDeck() -> initStateFromDeck(). - Made initStateFromDeck() into a template taking arbitrary properties. Implementation detail: - initWaterOilContact() was also templatized on props. - initHydrostaticPressure() is now overloaded on prop interface types. --- examples/wells_example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 2c0709918..18c051aab 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -58,7 +58,7 @@ int main(int argc, char** argv) Opm::TwophaseState state; - initStateTwophaseFromDeck(*grid.c_grid(), incomp_properties, parser, gravity[2], state); + initStateFromDeck(*grid.c_grid(), incomp_properties, parser, gravity[2], state); // Compute phase mobilities std::vector phase_mob; From 3487ee840d815b145b53404d5505bce6089c3651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 5 Jun 2012 15:42:49 +0200 Subject: [PATCH 028/163] Reorganized, added opm/core/wells/ and opm/core/simulator/. --- examples/wells_example.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 18c051aab..a8bdaae93 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -5,14 +5,14 @@ #include "opm/core/utility/initState.hpp" #include "opm/core/utility/SimulatorTimer.hpp" -#include +#include #include #include #include #include #include #include -#include +#include #include #include #include From bad5614ced0d6bfe6d586d4fcdf4ea19db2fc9b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 12 Jun 2012 15:28:53 +0200 Subject: [PATCH 029/163] Examples and tutorials follow change to IncompTpfa interface. --- examples/wells_example.cpp | 112 ++++++++----------------------------- 1 file changed, 22 insertions(+), 90 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index a8bdaae93..ca63a5beb 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -45,10 +46,22 @@ int main(int argc, char** argv) RockCompressibility rock_comp(parser); Opm::LinearSolverFactory linsolver(parameters); + double nl_pressure_residual_tolerance = 1e-8; + double nl_pressure_change_tolerance = 0.0; + int nl_pressure_maxiter = 100; + if (rock_comp.isActive()) { + nl_pressure_residual_tolerance = parameters.getDefault("nl_pressure_residual_tolerance", 1e-8); + nl_pressure_change_tolerance = parameters.getDefault("nl_pressure_change_tolerance", 1.0); // in Pascal + nl_pressure_maxiter = parameters.getDefault("nl_pressure_maxiter", 10); + } + + std::vector src; + Opm::FlowBCManager bcs; // EXPERIMENT_ISTL - IncompTpfa pressure_solver(*grid.c_grid(), incomp_properties.permeability(), - gravity, linsolver, wells.c_wells()); + IncompTpfa pressure_solver(*grid.c_grid(), incomp_properties, &rock_comp, linsolver, + nl_pressure_residual_tolerance, nl_pressure_change_tolerance, nl_pressure_maxiter, + gravity, wells.c_wells(), src, bcs.c_bcs()); std::vector all_cells; @@ -60,67 +73,10 @@ int main(int argc, char** argv) initStateFromDeck(*grid.c_grid(), incomp_properties, parser, gravity[2], state); - // Compute phase mobilities - std::vector phase_mob; - computePhaseMobilities(incomp_properties, all_cells, state.saturation(), phase_mob); - // Compute total mobility and omega - std::vector totmob; - std::vector omega; - computeTotalMobilityOmega(incomp_properties, all_cells, state.saturation(), totmob, omega); + Opm::WellState well_state; + well_state.init(wells.c_wells(), state); - std::vector wdp; - computeWDP(*wells.c_wells(), *grid.c_grid(), state.saturation(), incomp_properties.density(), gravity[2], true, wdp); - - std::vector src; - Opm::FlowBCManager bcs; - - std::vector pressure; - std::vector face_flux; - - std::vector well_bhp; - std::vector well_rate_per_cell; - std::vector rc; - rc.resize(grid.c_grid()->number_of_cells); - - int nl_pressure_maxiter = 100; - double nl_pressure_tolerance = 0.0; - if (rock_comp.isActive()) { - nl_pressure_maxiter = parameters.getDefault("nl_pressure_maxiter", 10); - nl_pressure_tolerance = parameters.getDefault("nl_pressure_tolerance", 1.0); // in Pascal - } - - const int num_cells = grid.c_grid()->number_of_cells; - std::vector porevol; - if (rock_comp.isActive()) { - computePorevolume(*grid.c_grid(), incomp_properties.porosity(), rock_comp, state.pressure(), porevol); - } else { - computePorevolume(*grid.c_grid(), incomp_properties.porosity(), porevol); - } - if (rock_comp.isActive()) { - std::vector initial_pressure = state.pressure(); - std::vector prev_pressure; - for (int iter = 0; iter < nl_pressure_maxiter; ++iter) { - prev_pressure = state.pressure(); - for (int cell = 0; cell < num_cells; ++cell) { - rc[cell] = rock_comp.rockComp(state.pressure()[cell]); - } - state.pressure() = initial_pressure; - pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), porevol, rc, simtimer.currentStepLength(), - state.pressure(), state.faceflux(), well_bhp, well_rate_per_cell); - double max_change = 0.0; - for (int cell = 0; cell < num_cells; ++cell) { - max_change = std::max(max_change, std::fabs(state.pressure()[cell] - prev_pressure[cell])); - } - std::cout << "Pressure iter " << iter << " max change = " << max_change << std::endl; - if (max_change < nl_pressure_tolerance) { - break; - } - } - computePorevolume(*grid.c_grid(), incomp_properties.porosity(), rock_comp, state.pressure(), porevol); - } else { - pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), state.pressure(), state.faceflux(), - well_bhp, well_rate_per_cell); - } + pressure_solver.solve(simtimer.currentStepLength(), state, well_state); const int np = incomp_properties.numPhases(); std::vector fractional_flows(grid.c_grid()->number_of_cells*np, 0.0); @@ -128,38 +84,14 @@ int main(int argc, char** argv) // This will be refactored into a separate function once done std::vector well_resflows(wells.c_wells()->number_of_wells*np, 0.0); - computePhaseFlowRatesPerWell(*wells.c_wells(), well_rate_per_cell, fractional_flows, well_resflows); + computePhaseFlowRatesPerWell(*wells.c_wells(), well_state.perfRates(), fractional_flows, well_resflows); // We approximate (for _testing_ that resflows = surfaceflows) - for (int wc_iter = 0; wc_iter < 10 && !wells.conditionsMet(well_bhp, well_resflows, well_resflows); ++wc_iter) { + for (int wc_iter = 0; wc_iter < 10 && !wells.conditionsMet(well_state.bhp(), well_resflows, well_resflows); ++wc_iter) { std::cout << "Conditions not met for well, trying again" << std::endl; - if (rock_comp.isActive()) { - std::vector initial_pressure = state.pressure(); - std::vector prev_pressure; - for (int iter = 0; iter < nl_pressure_maxiter; ++iter) { - prev_pressure = state.pressure(); - for (int cell = 0; cell < num_cells; ++cell) { - rc[cell] = rock_comp.rockComp(state.pressure()[cell]); - } - state.pressure() = initial_pressure; - pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), porevol, rc, simtimer.currentStepLength(), - state.pressure(), state.faceflux(), well_bhp, well_rate_per_cell); - double max_change = 0.0; - for (int cell = 0; cell < num_cells; ++cell) { - max_change = std::max(max_change, std::fabs(state.pressure()[cell] - prev_pressure[cell])); - } - std::cout << "Pressure iter " << iter << " max change = " << max_change << std::endl; - if (max_change < nl_pressure_tolerance) { - break; - } - } - computePorevolume(*grid.c_grid(), incomp_properties.porosity(), rock_comp, state.pressure(), porevol); - } else { - pressure_solver.solve(totmob, omega, src, wdp, bcs.c_bcs(), state.pressure(), state.faceflux(), - well_bhp, well_rate_per_cell); - } + pressure_solver.solve(simtimer.currentStepLength(), state, well_state); std::cout << "Solved" << std::endl; - computePhaseFlowRatesPerWell(*wells.c_wells(), well_rate_per_cell, fractional_flows, well_resflows); + computePhaseFlowRatesPerWell(*wells.c_wells(), well_state.perfRates(), fractional_flows, well_resflows); } #if 0 From 67c13e794a94f6a8e61f777a7148084e3ca3b2af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 14 Jun 2012 14:02:22 +0200 Subject: [PATCH 030/163] Moved SimulatorTimer class to opm/core/simulator directory. --- examples/wells_example.cpp | 4 +- .../timestepping/SimulatorTimer.cpp | 136 ++++++++++++++++++ .../timestepping/SimulatorTimer.hpp | 92 ++++++++++++ 3 files changed, 230 insertions(+), 2 deletions(-) create mode 100644 opm/simulators/timestepping/SimulatorTimer.cpp create mode 100644 opm/simulators/timestepping/SimulatorTimer.hpp diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index ca63a5beb..9f7be7ec3 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -3,8 +3,8 @@ #include -#include "opm/core/utility/initState.hpp" -#include "opm/core/utility/SimulatorTimer.hpp" +#include +#include #include #include #include diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp new file mode 100644 index 000000000..db4b5aac0 --- /dev/null +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -0,0 +1,136 @@ +/* + Copyright 2012 SINTEF ICT, Applied Mathematics. + + This file is part of the Open Porous Media project (OPM). + + OPM 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. + + OPM 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 OPM. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +namespace Opm +{ + + /// Default constructor. + SimulatorTimer::SimulatorTimer() + : current_step_(0), + current_time_(0.0) + { + } + + /// Initialize from parameters. Accepts the following: + /// num_psteps (default 1) + /// stepsize_days (default 1) + void SimulatorTimer::init(const parameter::ParameterGroup& param) + { + const int num_psteps = param.getDefault("num_psteps", 1); + const double stepsize_days = param.getDefault("stepsize_days", 1.0); + const double stepsize = Opm::unit::convert::from(stepsize_days, Opm::unit::day); + timesteps_.clear(); + timesteps_.resize(num_psteps, stepsize); + total_time_ = num_psteps*stepsize; + } + + /// Initialize from TSTEP field. + void SimulatorTimer::init(const EclipseGridParser& deck) + { + timesteps_ = deck.getTSTEP().tstep_; + total_time_ = std::accumulate(timesteps_.begin(), timesteps_.end(), 0.0); + } + + /// Total number of steps. + int SimulatorTimer::numSteps() const + { + return timesteps_.size(); + } + + /// Current step number. + int SimulatorTimer::currentStepNum() const + { + return current_step_; + } + + /// Set current step number. + void SimulatorTimer::setCurrentStepNum(int step) + { + if (current_step_ < 0 || current_step_ > int(timesteps_.size())) { + // Note that we do allow current_step_ == timesteps_.size(), + // that is the done() state. + THROW("Trying to set invalid step number: " << step); + } + current_step_ = step; + current_time_ = std::accumulate(timesteps_.begin(), timesteps_.begin() + step, 0.0); + } + + + /// Current step length. + double SimulatorTimer::currentStepLength() const + { + ASSERT(!done()); + return timesteps_[current_step_]; + } + + /// Current time. + double SimulatorTimer::currentTime() const + { + return current_time_; + } + + /// Total time. + double SimulatorTimer::totalTime() const + { + return total_time_; + } + + /// Set total time. + /// This is primarily intended for multi-epoch schedules, + /// where a timer for a given epoch does not have + /// access to later timesteps. + void SimulatorTimer::setTotalTime(double time) + { + total_time_ = time; + } + + /// Print a report with current and total time etc. + void SimulatorTimer::report(std::ostream& os) const + { + os << "\n\n--------------- Simulation step number " << currentStepNum() << " ---------------" + << "\n Current time (days) " << Opm::unit::convert::to(currentTime(), Opm::unit::day) + << "\n Current stepsize (days) " << Opm::unit::convert::to(currentStepLength(), Opm::unit::day) + << "\n Total time (days) " << Opm::unit::convert::to(totalTime(), Opm::unit::day) + << "\n" << std::endl; + } + + /// Next step. + SimulatorTimer& SimulatorTimer::operator++() + { + ASSERT(!done()); + current_time_ += timesteps_[current_step_]; + ++current_step_; + return *this; + } + + /// Return true if op++() has been called numSteps() times. + bool SimulatorTimer::done() const + { + return int(timesteps_.size()) == current_step_; + } + + +} // namespace Opm diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp new file mode 100644 index 000000000..d9a35a168 --- /dev/null +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -0,0 +1,92 @@ +/* + Copyright 2012 SINTEF ICT, Applied Mathematics. + + This file is part of the Open Porous Media project (OPM). + + OPM 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. + + OPM 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 OPM. If not, see . +*/ + +#ifndef OPM_SIMULATORTIMER_HEADER_INCLUDED +#define OPM_SIMULATORTIMER_HEADER_INCLUDED + +#include +#include + +namespace Opm +{ + + namespace parameter { class ParameterGroup; } + class EclipseGridParser; + + + class SimulatorTimer + { + public: + /// Default constructor. + SimulatorTimer(); + + /// Initialize from parameters. Accepts the following: + /// num_psteps (default 1) + /// stepsize_days (default 1) + void init(const parameter::ParameterGroup& param); + + /// Initialize from TSTEP field. + void init(const EclipseGridParser& deck); + + /// Total number of steps. + int numSteps() const; + + /// Current step number. + int currentStepNum() const; + + /// Set current step number. + void setCurrentStepNum(int step); + + /// Current step length. + /// Note: if done(), it is an error to call currentStepLength(). + double currentStepLength() const; + + /// Current time. + double currentTime() const; + + /// Total time. + double totalTime() const; + + /// Set total time. + /// This is primarily intended for multi-epoch schedules, + /// where a timer for a given epoch does not have + /// access to later timesteps. + void setTotalTime(double time); + + /// Print a report with current and total time etc. + /// Note: if done(), it is an error to call report(). + void report(std::ostream& os) const; + + /// Next step. + SimulatorTimer& operator++(); + + /// Return true if op++() has been called numSteps() times. + bool done() const; + + private: + std::vector timesteps_; + int current_step_; + double current_time_; + double total_time_; + }; + + +} // namespace Opm + +#endif // OPM_SIMULATORTIMER_HEADER_INCLUDED From ffdf7ed4f72bda1a82fac6ff2f51e337a59b487d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 9 Aug 2012 14:35:00 +0200 Subject: [PATCH 031/163] Adapt to possibility for Cartesian grids from deck input. Now we may have a grid generated from deck input using the keywords DXV, DYV, DZV, which will have a null pointer for the global_cell mapping. We check if this pointer is null, and create an identity mapping in this case. The mapping is needed by the *PropertiesFromDeck classes (and helpers). --- examples/wells_example.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 9f7be7ec3..2da110f3e 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -38,7 +38,16 @@ int main(int argc, char** argv) // Finally handle the wells WellsManager wells(parser, *grid.c_grid(), NULL); - std::vector global_cells(grid.c_grid()->global_cell, grid.c_grid()->global_cell + grid.c_grid()->number_of_cells); + int nc = grid.c_grid()->number_of_cells; + std::vector global_cells(nc); + const int* gc = grid.c_grid()->global_cell; + if (gc != 0) { + std::copy(gc, gc + nc, global_cells.begin()); + } else { + for (int cell = 0; cell < nc; ++cell) { + global_cells[cell] = cell; + } + } double gravity[3] = {0.0, 0.0, parameters.getDefault("gravity", 0.0)}; IncompPropertiesFromDeck incomp_properties(parser, global_cells); From 158c33eb53821e744f8353a2cf9eb608e5f2ba8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 10 Aug 2012 10:12:45 +0200 Subject: [PATCH 032/163] Constructors of *FromDeck classes now take an UnstructuredGrid. This is a change from taking a vector containing the mapping to deck-consistent logical cartesian indices. The mapping is contained in the UnstructuredGrid::global_cell member, and may be null. The change therefore saves the overhead of constructing a vector as a copy of the data in the grid or (if null) as an identity mapping. --- examples/wells_example.cpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 2da110f3e..1c523420f 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -38,19 +38,8 @@ int main(int argc, char** argv) // Finally handle the wells WellsManager wells(parser, *grid.c_grid(), NULL); - int nc = grid.c_grid()->number_of_cells; - std::vector global_cells(nc); - const int* gc = grid.c_grid()->global_cell; - if (gc != 0) { - std::copy(gc, gc + nc, global_cells.begin()); - } else { - for (int cell = 0; cell < nc; ++cell) { - global_cells[cell] = cell; - } - } - double gravity[3] = {0.0, 0.0, parameters.getDefault("gravity", 0.0)}; - IncompPropertiesFromDeck incomp_properties(parser, global_cells); + IncompPropertiesFromDeck incomp_properties(parser, *grid.c_grid()); RockCompressibility rock_comp(parser); From 09b3ef785c9ce59a20adcb0212f334513bc16b00 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Wed, 7 Nov 2012 14:53:26 +0100 Subject: [PATCH 033/163] Added start_date_ property to the SimulatorTimer class --- .../timestepping/SimulatorTimer.cpp | 62 ++++++++++------- .../timestepping/SimulatorTimer.hpp | 67 ++++++++++--------- 2 files changed, 72 insertions(+), 57 deletions(-) diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index db4b5aac0..337723dbe 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -29,8 +29,9 @@ namespace Opm /// Default constructor. SimulatorTimer::SimulatorTimer() - : current_step_(0), - current_time_(0.0) + : current_step_(0), + current_time_(0.0), + start_date_(2012,1,1) // A really arbitrary default starting value?! { } @@ -39,31 +40,32 @@ namespace Opm /// stepsize_days (default 1) void SimulatorTimer::init(const parameter::ParameterGroup& param) { - const int num_psteps = param.getDefault("num_psteps", 1); - const double stepsize_days = param.getDefault("stepsize_days", 1.0); - const double stepsize = Opm::unit::convert::from(stepsize_days, Opm::unit::day); - timesteps_.clear(); - timesteps_.resize(num_psteps, stepsize); - total_time_ = num_psteps*stepsize; + const int num_psteps = param.getDefault("num_psteps", 1); + const double stepsize_days = param.getDefault("stepsize_days", 1.0); + const double stepsize = Opm::unit::convert::from(stepsize_days, Opm::unit::day); + timesteps_.clear(); + timesteps_.resize(num_psteps, stepsize); + total_time_ = num_psteps*stepsize; } /// Initialize from TSTEP field. void SimulatorTimer::init(const EclipseGridParser& deck) { - timesteps_ = deck.getTSTEP().tstep_; - total_time_ = std::accumulate(timesteps_.begin(), timesteps_.end(), 0.0); + timesteps_ = deck.getTSTEP().tstep_; + total_time_ = std::accumulate(timesteps_.begin(), timesteps_.end(), 0.0); + start_date_ = deck.getStartDate(); } /// Total number of steps. int SimulatorTimer::numSteps() const { - return timesteps_.size(); + return timesteps_.size(); } /// Current step number. int SimulatorTimer::currentStepNum() const { - return current_step_; + return current_step_; } /// Set current step number. @@ -82,20 +84,28 @@ namespace Opm /// Current step length. double SimulatorTimer::currentStepLength() const { - ASSERT(!done()); - return timesteps_[current_step_]; + ASSERT(!done()); + return timesteps_[current_step_]; } /// Current time. double SimulatorTimer::currentTime() const { - return current_time_; + return current_time_; } + + boost::posix_time::ptime SimulatorTimer::currentDateTime() const + { + return boost::posix_time::ptime(start_date_) + boost::posix_time::seconds( (int) current_time_ ); + } + + + /// Total time. double SimulatorTimer::totalTime() const { - return total_time_; + return total_time_; } /// Set total time. @@ -104,32 +114,32 @@ namespace Opm /// access to later timesteps. void SimulatorTimer::setTotalTime(double time) { - total_time_ = time; + total_time_ = time; } /// Print a report with current and total time etc. void SimulatorTimer::report(std::ostream& os) const { os << "\n\n--------------- Simulation step number " << currentStepNum() << " ---------------" - << "\n Current time (days) " << Opm::unit::convert::to(currentTime(), Opm::unit::day) - << "\n Current stepsize (days) " << Opm::unit::convert::to(currentStepLength(), Opm::unit::day) - << "\n Total time (days) " << Opm::unit::convert::to(totalTime(), Opm::unit::day) - << "\n" << std::endl; + << "\n Current time (days) " << Opm::unit::convert::to(currentTime(), Opm::unit::day) + << "\n Current stepsize (days) " << Opm::unit::convert::to(currentStepLength(), Opm::unit::day) + << "\n Total time (days) " << Opm::unit::convert::to(totalTime(), Opm::unit::day) + << "\n" << std::endl; } /// Next step. SimulatorTimer& SimulatorTimer::operator++() { - ASSERT(!done()); - current_time_ += timesteps_[current_step_]; - ++current_step_; - return *this; + ASSERT(!done()); + current_time_ += timesteps_[current_step_]; + ++current_step_; + return *this; } /// Return true if op++() has been called numSteps() times. bool SimulatorTimer::done() const { - return int(timesteps_.size()) == current_step_; + return int(timesteps_.size()) == current_step_; } diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index d9a35a168..832cdef95 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -22,6 +22,8 @@ #include #include +#include +#include namespace Opm { @@ -33,57 +35,60 @@ namespace Opm class SimulatorTimer { public: - /// Default constructor. - SimulatorTimer(); + /// Default constructor. + SimulatorTimer(); - /// Initialize from parameters. Accepts the following: - /// num_psteps (default 1) - /// stepsize_days (default 1) - void init(const parameter::ParameterGroup& param); + /// Initialize from parameters. Accepts the following: + /// num_psteps (default 1) + /// stepsize_days (default 1) + void init(const parameter::ParameterGroup& param); - /// Initialize from TSTEP field. - void init(const EclipseGridParser& deck); + /// Initialize from TSTEP field. + void init(const EclipseGridParser& deck); - /// Total number of steps. - int numSteps() const; + /// Total number of steps. + int numSteps() const; - /// Current step number. - int currentStepNum() const; + /// Current step number. + int currentStepNum() const; /// Set current step number. void setCurrentStepNum(int step); - /// Current step length. - /// Note: if done(), it is an error to call currentStepLength(). - double currentStepLength() const; + /// Current step length. + /// Note: if done(), it is an error to call currentStepLength(). + double currentStepLength() const; - /// Current time. - double currentTime() const; + /// Current time. + double currentTime() const; - /// Total time. - double totalTime() const; + boost::posix_time::ptime currentDateTime() const; + + /// Total time. + double totalTime() const; /// Set total time. /// This is primarily intended for multi-epoch schedules, /// where a timer for a given epoch does not have /// access to later timesteps. - void setTotalTime(double time); + void setTotalTime(double time); - /// Print a report with current and total time etc. - /// Note: if done(), it is an error to call report(). - void report(std::ostream& os) const; + /// Print a report with current and total time etc. + /// Note: if done(), it is an error to call report(). + void report(std::ostream& os) const; - /// Next step. - SimulatorTimer& operator++(); + /// Next step. + SimulatorTimer& operator++(); - /// Return true if op++() has been called numSteps() times. - bool done() const; + /// Return true if op++() has been called numSteps() times. + bool done() const; private: - std::vector timesteps_; - int current_step_; - double current_time_; - double total_time_; + std::vector timesteps_; + int current_step_; + double current_time_; + double total_time_; + boost::gregorian::date start_date_; }; From f893adbda620fa683f61896d8bbe9fefdfdd3aa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 26 Nov 2012 10:49:15 +0100 Subject: [PATCH 034/163] Document function currentDateTime(). --- opm/simulators/timestepping/SimulatorTimer.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index 832cdef95..d409128e1 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -44,6 +44,7 @@ namespace Opm void init(const parameter::ParameterGroup& param); /// Initialize from TSTEP field. + /// Note that DATES are folded into TSTEP by the parser. void init(const EclipseGridParser& deck); /// Total number of steps. @@ -62,6 +63,7 @@ namespace Opm /// Current time. double currentTime() const; + /// Return the current time as a posix time object. boost::posix_time::ptime currentDateTime() const; /// Total time. From ddd41bfcd7875b478f1a3a1984ea2f8abe36e373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 7 Mar 2013 22:59:06 +0100 Subject: [PATCH 035/163] Moved opm/core/eclipse/* to opm/core/io/eclipse/*. --- examples/wells_example.cpp | 2 +- opm/simulators/timestepping/SimulatorTimer.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 1c523420f..b4aa00244 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index 337723dbe..8a5471d38 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include From e83057e0ea2fabec1eb25ac07268d4c91bc2b8fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 14 Mar 2013 10:29:42 +0100 Subject: [PATCH 036/163] Adapt include statements to moved headers. --- examples/wells_example.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index b4aa00244..4c37681a4 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include @@ -16,7 +16,7 @@ #include #include #include -#include +#include int main(int argc, char** argv) { From 5fc63031edf9c9b6b4cc4326fc441ba001ba7daa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 18 Mar 2013 10:16:46 +0100 Subject: [PATCH 037/163] Move GridManager to grid subdir. Also remove GridAdapter (moved to dune-cornerpoint), and moved grid.c implementation file to grid subdir. --- examples/wells_example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 4c37681a4..45eb9e21a 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include From bfa9997dd24e47f0c42355a2a1c955852da5a57d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 18 Mar 2013 10:33:34 +0100 Subject: [PATCH 038/163] Renamed newwells.h -> wells.h. Also moved implementation file to subdir. --- examples/wells_example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 45eb9e21a..82498fbb4 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include From f3ec8e16348f47acad7a4efff4a89ac9a630393b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 18 Mar 2013 12:47:23 +0100 Subject: [PATCH 039/163] Moved ColumnExtract and initState. ColumnExtract -> opm/core/grid/ and initState -> opm/core/simulator/. --- examples/wells_example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 82498fbb4..fb202868a 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -3,7 +3,7 @@ #include -#include +#include #include #include #include From a2065b410122947310f690bb66cfe806623df16f Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Wed, 10 Apr 2013 12:56:14 +0200 Subject: [PATCH 040/163] make config.h the first header to be included in any compile unit this is required for consistency amongst the compile units which are linked into the same library and seems to be forgotten quite frequently. --- examples/wells_example.cpp | 1 + opm/simulators/timestepping/SimulatorTimer.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index fb202868a..f074fc69c 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -1,3 +1,4 @@ +#include "config.h" #include #include #include diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index 8a5471d38..4aa52ecf7 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -17,6 +17,7 @@ along with OPM. If not, see . */ +#include "config.h" #include #include #include From 43438b2bf8acbab3a3fab85ef5077be5856259e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BAlio=20Hoffimann?= Date: Sun, 28 Jul 2013 08:34:13 -0300 Subject: [PATCH 041/163] Remove trailing whitespaces --- opm/simulators/timestepping/SimulatorTimer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index 4aa52ecf7..c2d1342d5 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -100,7 +100,7 @@ namespace Opm { return boost::posix_time::ptime(start_date_) + boost::posix_time::seconds( (int) current_time_ ); } - + /// Total time. From f4a22486efdb0a75354c58b09e2ac9ff7543b559 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Wed, 28 Aug 2013 13:59:03 +0200 Subject: [PATCH 042/163] convert THROW to OPM_THROW --- opm/simulators/timestepping/SimulatorTimer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index c2d1342d5..5f2ecbdb7 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -75,7 +75,7 @@ namespace Opm if (current_step_ < 0 || current_step_ > int(timesteps_.size())) { // Note that we do allow current_step_ == timesteps_.size(), // that is the done() state. - THROW("Trying to set invalid step number: " << step); + OPM_THROW(std::runtime_error, "Trying to set invalid step number: " << step); } current_step_ = step; current_time_ = std::accumulate(timesteps_.begin(), timesteps_.begin() + step, 0.0); From 2cfe79f66403fe8962559cae5f4e6f64d3247a78 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Wed, 28 Aug 2013 14:00:35 +0200 Subject: [PATCH 043/163] convert users of the ASSERT and the ASSERT2 macros to standard assert() --- opm/simulators/timestepping/SimulatorTimer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index 5f2ecbdb7..c7bc64afc 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -85,7 +85,7 @@ namespace Opm /// Current step length. double SimulatorTimer::currentStepLength() const { - ASSERT(!done()); + assert(!done()); return timesteps_[current_step_]; } @@ -131,7 +131,7 @@ namespace Opm /// Next step. SimulatorTimer& SimulatorTimer::operator++() { - ASSERT(!done()); + assert(!done()); current_time_ += timesteps_[current_step_]; ++current_step_; return *this; From aa62980fbfbebb89198cd9f72ec1f67818618eff Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Mon, 2 Sep 2013 17:35:33 +0200 Subject: [PATCH 044/163] catch all exceptions in all tutorials and examples --- examples/wells_example.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index f074fc69c..2a2523387 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -20,8 +20,8 @@ #include int main(int argc, char** argv) +try { - using namespace Opm::parameter; using namespace Opm; ParameterGroup parameters(argc, argv, false); @@ -130,4 +130,7 @@ int main(int argc, char** argv) #endif return 0; } - +catch (const std::exception &e) { + std::cerr << "Program threw an exception: " << e.what() << "\n"; + throw; +} From 8159104218be89979aa6f7d9f1c54b60289b9f36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Wed, 25 Sep 2013 15:11:14 +0200 Subject: [PATCH 045/163] Fix null-pointer dereference during well construction The three-argument WellsManager constructor needs access to the real permeability field lest a null-pointer dereference result when the problem actually contains any wells. --- examples/wells_example.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 2a2523387..6af03a783 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -36,14 +36,14 @@ try // Setup grid GridManager grid(parser); - // Finally handle the wells - WellsManager wells(parser, *grid.c_grid(), NULL); - - double gravity[3] = {0.0, 0.0, parameters.getDefault("gravity", 0.0)}; + // Define rock and fluid properties IncompPropertiesFromDeck incomp_properties(parser, *grid.c_grid()); - RockCompressibility rock_comp(parser); + // Finally handle the wells + WellsManager wells(parser, *grid.c_grid(), incomp_properties.permeability()); + + double gravity[3] = {0.0, 0.0, parameters.getDefault("gravity", 0.0)}; Opm::LinearSolverFactory linsolver(parameters); double nl_pressure_residual_tolerance = 1e-8; double nl_pressure_change_tolerance = 0.0; From 2ba7b3329d804abdb2fef282d72f91082ef8e9c0 Mon Sep 17 00:00:00 2001 From: Roland Kaufmann Date: Tue, 26 Nov 2013 12:41:02 +0100 Subject: [PATCH 046/163] Make starting timestep more explicitly known One-based or zero-based? Better be documented (in a way that doesn't promote hard-coding in the clients!) --- opm/simulators/timestepping/SimulatorTimer.cpp | 2 +- opm/simulators/timestepping/SimulatorTimer.hpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index c7bc64afc..b0a205b81 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -30,7 +30,7 @@ namespace Opm /// Default constructor. SimulatorTimer::SimulatorTimer() - : current_step_(0), + : current_step_(FIRST_STEP), current_time_(0.0), start_date_(2012,1,1) // A really arbitrary default starting value?! { diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index d409128e1..5a02d93d6 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -50,6 +50,9 @@ namespace Opm /// Total number of steps. int numSteps() const; + /// First timestep returned from currentStepNum + static const int FIRST_STEP = 0; + /// Current step number. int currentStepNum() const; From 73dfe849d6f7ed29a38757eb83be6b4339b2c722 Mon Sep 17 00:00:00 2001 From: Roland Kaufmann Date: Wed, 27 Nov 2013 00:23:00 +0100 Subject: [PATCH 047/163] Replace unclear constant with better documentation The step number is zero before the first timestep has been taken, and one after. The step number is one before the second timestep has been taken, and two after. This was not clear from the text. --- opm/simulators/timestepping/SimulatorTimer.cpp | 2 +- opm/simulators/timestepping/SimulatorTimer.hpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index b0a205b81..c7bc64afc 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -30,7 +30,7 @@ namespace Opm /// Default constructor. SimulatorTimer::SimulatorTimer() - : current_step_(FIRST_STEP), + : current_step_(0), current_time_(0.0), start_date_(2012,1,1) // A really arbitrary default starting value?! { diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index 5a02d93d6..c9d3d61b2 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -50,10 +50,10 @@ namespace Opm /// Total number of steps. int numSteps() const; - /// First timestep returned from currentStepNum - static const int FIRST_STEP = 0; - - /// Current step number. + /// Current step number. This is the number of timesteps that + /// has been completed from the start of the run. The time + /// after initialization but before the simulation has started + /// is timestep number zero. int currentStepNum() const; /// Set current step number. From f30ab559742de79745f12d448b6e14b504028b3c Mon Sep 17 00:00:00 2001 From: Roland Kaufmann Date: Wed, 27 Nov 2013 00:36:17 +0100 Subject: [PATCH 048/163] Provide routine to return the step length taken The output routine needs to know which step that has been taken in the past (to arrive at this result), not which step to take next going forward. --- opm/simulators/timestepping/SimulatorTimer.cpp | 6 ++++++ opm/simulators/timestepping/SimulatorTimer.hpp | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index c7bc64afc..f3bef455d 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -89,6 +89,12 @@ namespace Opm return timesteps_[current_step_]; } + double SimulatorTimer::stepLengthTaken() const + { + assert(current_step_ > 0); + return timesteps_[current_step_ - 1]; + } + /// Current time. double SimulatorTimer::currentTime() const { diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index c9d3d61b2..a1d8a2706 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -59,10 +59,20 @@ namespace Opm /// Set current step number. void setCurrentStepNum(int step); - /// Current step length. - /// Note: if done(), it is an error to call currentStepLength(). + /// Current step length. This is the length of the step + /// the simulator will take in the next iteration. + /// + /// @note if done(), it is an error to call currentStepLength(). double currentStepLength() const; + /// Previous step length. This is the length of the step that + /// was taken to arrive at this time. + /// + /// @note if no increments have been done (i.e. the timer is + /// still in its constructed state and currentStepNum() == 0), + /// it is an error to call stepLengthTaken(). + double stepLengthTaken () const; + /// Current time. double currentTime() const; From 85a00322472420218e12a964ad51754a45861c90 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Thu, 20 Feb 2014 17:59:41 +0100 Subject: [PATCH 049/163] SimulatorTimer: make it possible to base it on opm-parser's TimeMap Since SimulatorTimer is a fairly shallow shim if using the TimeMap, it can also be removed relatively easily. Having said this, that would trigger _many_ changes in _a lot_ of places and I'm not motivated at all to fight that battle as long as the old parser needs to be supported. I thus decided that the best way is to add a "wrapper mode" to SimulationTimer... --- .../timestepping/SimulatorTimer.cpp | 59 +++++++++++++++---- .../timestepping/SimulatorTimer.hpp | 7 +++ 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index f3bef455d..fddc3aa80 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -57,10 +57,21 @@ namespace Opm start_date_ = deck.getStartDate(); } + /// Use the SimulatorTimer as a shim around opm-parser's Opm::TimeMap + void SimulatorTimer::init(Opm::TimeMapConstPtr timeMap, + int timeStepIdx) + { + timeMap_ = timeMap; + current_step_ = timeStepIdx; + } + /// Total number of steps. int SimulatorTimer::numSteps() const { - return timesteps_.size(); + if (timeMap_) + return timeMap_->numTimesteps(); + else + return timesteps_.size(); } /// Current step number. @@ -72,13 +83,14 @@ namespace Opm /// Set current step number. void SimulatorTimer::setCurrentStepNum(int step) { - if (current_step_ < 0 || current_step_ > int(timesteps_.size())) { + if (current_step_ < 0 || current_step_ > int(numSteps())) { // Note that we do allow current_step_ == timesteps_.size(), // that is the done() state. OPM_THROW(std::runtime_error, "Trying to set invalid step number: " << step); } current_step_ = step; - current_time_ = std::accumulate(timesteps_.begin(), timesteps_.begin() + step, 0.0); + if (timeMap_) + current_time_ = std::accumulate(timesteps_.begin(), timesteps_.begin() + step, 0.0); } @@ -86,25 +98,37 @@ namespace Opm double SimulatorTimer::currentStepLength() const { assert(!done()); - return timesteps_[current_step_]; + if (timeMap_) + return timeMap_->getTimeStepLength(current_step_); + else + return timesteps_[current_step_]; } double SimulatorTimer::stepLengthTaken() const { assert(current_step_ > 0); - return timesteps_[current_step_ - 1]; + if (timeMap_) + return timeMap_->getTimeStepLength(current_step_ - 1); + else + return timesteps_[current_step_ - 1]; } /// Current time. double SimulatorTimer::currentTime() const { - return current_time_; + if (timeMap_) + return timeMap_->getTimePassedUntil(current_step_); + else + return current_time_; } boost::posix_time::ptime SimulatorTimer::currentDateTime() const { - return boost::posix_time::ptime(start_date_) + boost::posix_time::seconds( (int) current_time_ ); + if (timeMap_) + return timeMap_->getStartTime(current_step_); + else + return boost::posix_time::ptime(start_date_) + boost::posix_time::seconds( (int) current_time_ ); } @@ -112,7 +136,10 @@ namespace Opm /// Total time. double SimulatorTimer::totalTime() const { - return total_time_; + if (timeMap_) + return timeMap_->getTotalTime(); + else + return total_time_; } /// Set total time. @@ -121,7 +148,13 @@ namespace Opm /// access to later timesteps. void SimulatorTimer::setTotalTime(double time) { - total_time_ = time; + if (timeMap_) { + // well, what can we do if we use opm-parser's TimeMap? + OPM_THROW(std::logic_error, + "Not implemented: SimulatorTimer::setTotalTime() if using a TimeMap."); + } + else + total_time_ = time; } /// Print a report with current and total time etc. @@ -138,7 +171,8 @@ namespace Opm SimulatorTimer& SimulatorTimer::operator++() { assert(!done()); - current_time_ += timesteps_[current_step_]; + if (!timeMap_) + current_time_ += timesteps_[current_step_]; ++current_step_; return *this; } @@ -146,7 +180,10 @@ namespace Opm /// Return true if op++() has been called numSteps() times. bool SimulatorTimer::done() const { - return int(timesteps_.size()) == current_step_; + if (timeMap_) + return int(timeMap_->numTimesteps()) <= current_step_; + else + return int(timesteps_.size()) == current_step_; } diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index a1d8a2706..949859e5f 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -20,6 +20,8 @@ #ifndef OPM_SIMULATORTIMER_HEADER_INCLUDED #define OPM_SIMULATORTIMER_HEADER_INCLUDED +#include + #include #include #include @@ -47,6 +49,10 @@ namespace Opm /// Note that DATES are folded into TSTEP by the parser. void init(const EclipseGridParser& deck); + /// Use the SimulatorTimer as a shim around opm-parser's Opm::TimeMap + void init(TimeMapConstPtr timeMap, + int timeStepIdx = 0); + /// Total number of steps. int numSteps() const; @@ -99,6 +105,7 @@ namespace Opm bool done() const; private: + Opm::TimeMapConstPtr timeMap_; std::vector timesteps_; int current_step_; double current_time_; From caf10e0e7f016a55e41489339ec4e3f4cbad5965 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Tue, 11 Mar 2014 15:06:07 +0100 Subject: [PATCH 050/163] SimulatorTimer: rename currentTime() to simulationTimeElapsed() because the name "currentTime()" can be mistaken for the point in real-life time at which the simulation is run (e.g. March 11, 2014, 15:07:45.123), the _point_ in time which the simulator timer currently represents (e.g. Jun 5, 1985, 02:33:12.345) instead of the simulator time in seconds which elapsed since the START date (e.g. 52633.345 s). this rename may lead to some fallout in other modules. I'll fix them after this PR has been merged... --- opm/simulators/timestepping/SimulatorTimer.cpp | 12 +++++++++--- opm/simulators/timestepping/SimulatorTimer.hpp | 9 +++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index fddc3aa80..b672b6135 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -113,8 +113,8 @@ namespace Opm return timesteps_[current_step_ - 1]; } - /// Current time. - double SimulatorTimer::currentTime() const + /// time elapsed since the start of the simulation [s]. + double SimulatorTimer::simulationTimeElapsed() const { if (timeMap_) return timeMap_->getTimePassedUntil(current_step_); @@ -122,6 +122,12 @@ namespace Opm return current_time_; } + /// time elapsed since the start of the POSIX epoch (Jan 1st, 1970) [s]. + time_t SimulatorTimer::currentPosixTime() const + { + tm t = boost::posix_time::to_tm(currentDateTime()); + return std::mktime(&t); + } boost::posix_time::ptime SimulatorTimer::currentDateTime() const { @@ -161,7 +167,7 @@ namespace Opm void SimulatorTimer::report(std::ostream& os) const { os << "\n\n--------------- Simulation step number " << currentStepNum() << " ---------------" - << "\n Current time (days) " << Opm::unit::convert::to(currentTime(), Opm::unit::day) + << "\n Current time (days) " << Opm::unit::convert::to(simulationTimeElapsed(), Opm::unit::day) << "\n Current stepsize (days) " << Opm::unit::convert::to(currentStepLength(), Opm::unit::day) << "\n Total time (days) " << Opm::unit::convert::to(totalTime(), Opm::unit::day) << "\n" << std::endl; diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index 949859e5f..ad49282fc 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -79,8 +79,13 @@ namespace Opm /// it is an error to call stepLengthTaken(). double stepLengthTaken () const; - /// Current time. - double currentTime() const; + /// Time elapsed since the start of the POSIX epoch (Jan 1st, + /// 1970) until the current time step begins [s]. + time_t currentPosixTime() const; + + /// Time elapsed since the start of the simulation until the + /// beginning of the current time step [s]. + double simulationTimeElapsed() const; /// Return the current time as a posix time object. boost::posix_time::ptime currentDateTime() const; From f2e9016bd0a2f48c8fd02ffc2082eb061a7eaf89 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Mon, 17 Mar 2014 16:30:03 +0100 Subject: [PATCH 051/163] SimulatorTimer: allow it to be limited to a sub-range of all report steps --- .../timestepping/SimulatorTimer.cpp | 47 +++++++++++++++---- .../timestepping/SimulatorTimer.hpp | 11 ++++- 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index b672b6135..4c36c0d78 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -59,21 +59,46 @@ namespace Opm /// Use the SimulatorTimer as a shim around opm-parser's Opm::TimeMap void SimulatorTimer::init(Opm::TimeMapConstPtr timeMap, - int timeStepIdx) + size_t beginReportStepIdx, + size_t endReportStepIdx) { timeMap_ = timeMap; - current_step_ = timeStepIdx; + current_step_ = 0; + beginReportStepIdx_ = beginReportStepIdx; + endReportStepIdx_ = std::min(timeMap_->numTimesteps() + 1, endReportStepIdx); } /// Total number of steps. int SimulatorTimer::numSteps() const { if (timeMap_) - return timeMap_->numTimesteps(); + return endReportStepIdx_ - beginReportStepIdx_; else return timesteps_.size(); } + /// Index of the first considered simulation episode + size_t SimulatorTimer::beginReportStepIndex() const + { + if (!timeMap_) { + OPM_THROW(std::runtime_error, "indexFirstEpisode() is only implemented " + "for simulation timers which are based on Opm::TimeMap"); + } + + return beginReportStepIdx_; + } + + /// Index of the last considered simulation episode + size_t SimulatorTimer::endReportStepIndex() const + { + if (!timeMap_) { + OPM_THROW(std::runtime_error, "indexLastEpisode() is only implemented " + "for simulation timers which are based on Opm::TimeMap"); + } + + return endReportStepIdx_; + } + /// Current step number. int SimulatorTimer::currentStepNum() const { @@ -99,7 +124,7 @@ namespace Opm { assert(!done()); if (timeMap_) - return timeMap_->getTimeStepLength(current_step_); + return timeMap_->getTimeStepLength(beginReportStepIdx_ + current_step_); else return timesteps_[current_step_]; } @@ -108,7 +133,7 @@ namespace Opm { assert(current_step_ > 0); if (timeMap_) - return timeMap_->getTimeStepLength(current_step_ - 1); + return timeMap_->getTimeStepLength(beginReportStepIdx_ + current_step_ - 1); else return timesteps_[current_step_ - 1]; } @@ -117,7 +142,9 @@ namespace Opm double SimulatorTimer::simulationTimeElapsed() const { if (timeMap_) - return timeMap_->getTimePassedUntil(current_step_); + return + timeMap_->getTimePassedUntil(beginReportStepIdx_ + current_step_) + - timeMap_->getTimePassedUntil(beginReportStepIdx_); else return current_time_; } @@ -132,7 +159,7 @@ namespace Opm boost::posix_time::ptime SimulatorTimer::currentDateTime() const { if (timeMap_) - return timeMap_->getStartTime(current_step_); + return timeMap_->getStartTime(beginReportStepIdx_ + current_step_); else return boost::posix_time::ptime(start_date_) + boost::posix_time::seconds( (int) current_time_ ); } @@ -143,7 +170,9 @@ namespace Opm double SimulatorTimer::totalTime() const { if (timeMap_) - return timeMap_->getTotalTime(); + return + timeMap_->getTimePassedUntil(endReportStepIdx_) - + timeMap_->getTimePassedUntil(beginReportStepIdx_); else return total_time_; } @@ -187,7 +216,7 @@ namespace Opm bool SimulatorTimer::done() const { if (timeMap_) - return int(timeMap_->numTimesteps()) <= current_step_; + return current_step_ > int(endReportStepIdx_ - beginReportStepIdx_ - 1); else return int(timesteps_.size()) == current_step_; } diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index ad49282fc..b743478d0 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -51,11 +51,18 @@ namespace Opm /// Use the SimulatorTimer as a shim around opm-parser's Opm::TimeMap void init(TimeMapConstPtr timeMap, - int timeStepIdx = 0); + size_t beginReportStepIdx = 0, + size_t endReportStepIdx = std::numeric_limits::max()); /// Total number of steps. int numSteps() const; + /// Index of the first report step considered + size_t beginReportStepIndex() const; + + /// Index of the next-after-last report step to be considered + size_t endReportStepIndex() const; + /// Current step number. This is the number of timesteps that /// has been completed from the start of the run. The time /// after initialization but before the simulation has started @@ -112,6 +119,8 @@ namespace Opm private: Opm::TimeMapConstPtr timeMap_; std::vector timesteps_; + size_t beginReportStepIdx_; + size_t endReportStepIdx_; int current_step_; double current_time_; double total_time_; From 54316c19c8584952fc90d0d6e2faf1782411667e Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Mon, 24 Mar 2014 16:41:02 +0100 Subject: [PATCH 052/163] Output correct information for temporary use. Change the SimulatorTimer class a little bit to output the totaltime and current time correctly. --- opm/simulators/timestepping/SimulatorTimer.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index 4c36c0d78..5295afe47 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -102,7 +102,7 @@ namespace Opm /// Current step number. int SimulatorTimer::currentStepNum() const { - return current_step_; + return current_step_ + beginReportStepIdx_; } /// Set current step number. @@ -143,8 +143,7 @@ namespace Opm { if (timeMap_) return - timeMap_->getTimePassedUntil(beginReportStepIdx_ + current_step_) - - timeMap_->getTimePassedUntil(beginReportStepIdx_); + timeMap_->getTimePassedUntil(beginReportStepIdx_ + current_step_); else return current_time_; } @@ -171,8 +170,7 @@ namespace Opm { if (timeMap_) return - timeMap_->getTimePassedUntil(endReportStepIdx_) - - timeMap_->getTimePassedUntil(beginReportStepIdx_); + timeMap_->getTotalTime(); else return total_time_; } From a845cfdfd7994214da28f7cece3e80e7dea34ee7 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Tue, 25 Mar 2014 18:57:58 +0100 Subject: [PATCH 053/163] Removed WellsManager constructor which takes an ole Eclipsegridparser instance. --- examples/wells_example.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 6af03a783..d0b915314 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -19,6 +19,9 @@ #include #include +#include +#include + int main(int argc, char** argv) try { @@ -39,9 +42,11 @@ try // Define rock and fluid properties IncompPropertiesFromDeck incomp_properties(parser, *grid.c_grid()); RockCompressibility rock_comp(parser); + ParserPtr newParser(new Opm::Parser()); + EclipseStateConstPtr eclipseState(new Opm::EclipseState(newParser->parseFile(file_name))); // Finally handle the wells - WellsManager wells(parser, *grid.c_grid(), incomp_properties.permeability()); + WellsManager wells(eclipseState , 0 , *grid.c_grid(), incomp_properties.permeability()); double gravity[3] = {0.0, 0.0, parameters.getDefault("gravity", 0.0)}; Opm::LinearSolverFactory linsolver(parameters); From 500053d6aad87137714a1a50a5c98480128d58a7 Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Wed, 26 Mar 2014 15:53:54 +0100 Subject: [PATCH 054/163] A new SimulatorTimer Class --- .../timestepping/SimulatorTimer.cpp | 94 ++++--------------- .../timestepping/SimulatorTimer.hpp | 13 +-- 2 files changed, 20 insertions(+), 87 deletions(-) diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index 5295afe47..ade613b08 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -58,64 +58,35 @@ namespace Opm } /// Use the SimulatorTimer as a shim around opm-parser's Opm::TimeMap - void SimulatorTimer::init(Opm::TimeMapConstPtr timeMap, - size_t beginReportStepIdx, - size_t endReportStepIdx) + void SimulatorTimer::init(Opm::TimeMapConstPtr timeMap) { - timeMap_ = timeMap; current_step_ = 0; - beginReportStepIdx_ = beginReportStepIdx; - endReportStepIdx_ = std::min(timeMap_->numTimesteps() + 1, endReportStepIdx); + total_time_ = timeMap->getTotalTime(); + timesteps_.resize(timeMap->numTimesteps()); + for ( size_t i = 0; i < timeMap->numTimesteps(); ++i ) { + timesteps_[i] = timeMap->getTimeStepLength(i); + } + boost::posix_time::ptime start_time = timeMap->getStartTime(0); + start_date_ = start_time.date(); } /// Total number of steps. int SimulatorTimer::numSteps() const { - if (timeMap_) - return endReportStepIdx_ - beginReportStepIdx_; - else - return timesteps_.size(); - } - - /// Index of the first considered simulation episode - size_t SimulatorTimer::beginReportStepIndex() const - { - if (!timeMap_) { - OPM_THROW(std::runtime_error, "indexFirstEpisode() is only implemented " - "for simulation timers which are based on Opm::TimeMap"); - } - - return beginReportStepIdx_; - } - - /// Index of the last considered simulation episode - size_t SimulatorTimer::endReportStepIndex() const - { - if (!timeMap_) { - OPM_THROW(std::runtime_error, "indexLastEpisode() is only implemented " - "for simulation timers which are based on Opm::TimeMap"); - } - - return endReportStepIdx_; + return timesteps_.size(); } /// Current step number. int SimulatorTimer::currentStepNum() const { - return current_step_ + beginReportStepIdx_; + return current_step_; } /// Set current step number. void SimulatorTimer::setCurrentStepNum(int step) { - if (current_step_ < 0 || current_step_ > int(numSteps())) { - // Note that we do allow current_step_ == timesteps_.size(), - // that is the done() state. - OPM_THROW(std::runtime_error, "Trying to set invalid step number: " << step); - } current_step_ = step; - if (timeMap_) - current_time_ = std::accumulate(timesteps_.begin(), timesteps_.begin() + step, 0.0); + current_time_ = std::accumulate(timesteps_.begin(), timesteps_.begin() + step, 0.0); } @@ -123,29 +94,19 @@ namespace Opm double SimulatorTimer::currentStepLength() const { assert(!done()); - if (timeMap_) - return timeMap_->getTimeStepLength(beginReportStepIdx_ + current_step_); - else - return timesteps_[current_step_]; + return timesteps_[current_step_]; } double SimulatorTimer::stepLengthTaken() const { assert(current_step_ > 0); - if (timeMap_) - return timeMap_->getTimeStepLength(beginReportStepIdx_ + current_step_ - 1); - else - return timesteps_[current_step_ - 1]; + return timesteps_[current_step_ - 1]; } /// time elapsed since the start of the simulation [s]. double SimulatorTimer::simulationTimeElapsed() const { - if (timeMap_) - return - timeMap_->getTimePassedUntil(beginReportStepIdx_ + current_step_); - else - return current_time_; + return current_time_; } /// time elapsed since the start of the POSIX epoch (Jan 1st, 1970) [s]. @@ -157,10 +118,7 @@ namespace Opm boost::posix_time::ptime SimulatorTimer::currentDateTime() const { - if (timeMap_) - return timeMap_->getStartTime(beginReportStepIdx_ + current_step_); - else - return boost::posix_time::ptime(start_date_) + boost::posix_time::seconds( (int) current_time_ ); + return boost::posix_time::ptime(start_date_) + boost::posix_time::seconds( (int) current_time_ ); } @@ -168,11 +126,7 @@ namespace Opm /// Total time. double SimulatorTimer::totalTime() const { - if (timeMap_) - return - timeMap_->getTotalTime(); - else - return total_time_; + return total_time_; } /// Set total time. @@ -181,13 +135,7 @@ namespace Opm /// access to later timesteps. void SimulatorTimer::setTotalTime(double time) { - if (timeMap_) { - // well, what can we do if we use opm-parser's TimeMap? - OPM_THROW(std::logic_error, - "Not implemented: SimulatorTimer::setTotalTime() if using a TimeMap."); - } - else - total_time_ = time; + total_time_ = time; } /// Print a report with current and total time etc. @@ -204,8 +152,7 @@ namespace Opm SimulatorTimer& SimulatorTimer::operator++() { assert(!done()); - if (!timeMap_) - current_time_ += timesteps_[current_step_]; + current_time_ += timesteps_[current_step_]; ++current_step_; return *this; } @@ -213,10 +160,7 @@ namespace Opm /// Return true if op++() has been called numSteps() times. bool SimulatorTimer::done() const { - if (timeMap_) - return current_step_ > int(endReportStepIdx_ - beginReportStepIdx_ - 1); - else - return int(timesteps_.size()) == current_step_; + return int(timesteps_.size()) == current_step_; } diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index b743478d0..e2b5db071 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -50,19 +50,11 @@ namespace Opm void init(const EclipseGridParser& deck); /// Use the SimulatorTimer as a shim around opm-parser's Opm::TimeMap - void init(TimeMapConstPtr timeMap, - size_t beginReportStepIdx = 0, - size_t endReportStepIdx = std::numeric_limits::max()); + void init(TimeMapConstPtr timeMap); /// Total number of steps. int numSteps() const; - /// Index of the first report step considered - size_t beginReportStepIndex() const; - - /// Index of the next-after-last report step to be considered - size_t endReportStepIndex() const; - /// Current step number. This is the number of timesteps that /// has been completed from the start of the run. The time /// after initialization but before the simulation has started @@ -117,10 +109,7 @@ namespace Opm bool done() const; private: - Opm::TimeMapConstPtr timeMap_; std::vector timesteps_; - size_t beginReportStepIdx_; - size_t endReportStepIdx_; int current_step_; double current_time_; double total_time_; From 5dd0434707a434ce9c740e204808fc8529b9083d Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Wed, 26 Mar 2014 17:53:06 +0100 Subject: [PATCH 055/163] Added the test code and test data. Added TESTTIMER.DATA and test_timer.cpp --- tests/TESTTIMER.DATA | 49 +++++++++++++++++++ tests/test_timer.cpp | 111 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100644 tests/TESTTIMER.DATA create mode 100644 tests/test_timer.cpp diff --git a/tests/TESTTIMER.DATA b/tests/TESTTIMER.DATA new file mode 100644 index 000000000..efe90c9e6 --- /dev/null +++ b/tests/TESTTIMER.DATA @@ -0,0 +1,49 @@ +RUNSPEC + +START + 26 'MAR' 2014 / + +TSTEP +1.0 2*5.0 + / + +TSTEP + 7*10.0 14*25.0 + / + +TSTEP + 19.0 + / + +TSTEP + 18*13.0 + / + +TSTEP + 17*10.0 + / + +TSTEP + 13.0 + / + +TSTEP + 18.0 + / + +TSTEP + 11.0 + / + +TSTEP + 17*5.0 + / + +TSTEP + 19*6.0 + / + +TSTEP + 21*5.0 / + +END == diff --git a/tests/test_timer.cpp b/tests/test_timer.cpp new file mode 100644 index 000000000..e02d150c3 --- /dev/null +++ b/tests/test_timer.cpp @@ -0,0 +1,111 @@ +/* + Copyright 2012 SINTEF ICT, Applied Mathematics. + + This file is part of the Open Porous Media project (OPM). + + OPM 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. + + OPM 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 OPM. If not, see . +*/ + +#include + +#if HAVE_DYNAMIC_BOOST_TEST +#define BOOST_TEST_DYN_LINK +#endif + +#define NVERBOSE // Suppress own messages when throw()ing + +#define BOOST_TEST_MODULE OPM-TimerTest +#include + +#include +#include +#include + +#include +#include +#include +#include + +BOOST_AUTO_TEST_CASE(CreateTimer) +{ + const std::string filename1 = "TESTTIMER.DATA"; + Opm::ParserPtr parser(new Opm::Parser() ); + Opm::DeckConstPtr parserDeck = parser->parseFile( filename1 ); + + Opm::TimeMapPtr timeMap(new Opm::TimeMap(parserDeck)); + Opm::SimulatorTimer simtimer; + + boost::gregorian::date defaultStartDate( 2012, 1, 1); + BOOST_CHECK_EQUAL( boost::posix_time::ptime(defaultStartDate), simtimer.currentDateTime() ); + + simtimer.init(timeMap); + boost::gregorian::date startDate( 2014, 3, 26); + BOOST_CHECK_EQUAL( boost::posix_time::ptime(startDate), simtimer.currentDateTime() ); + + BOOST_CHECK_EQUAL( 0, simtimer.currentStepNum() ); + BOOST_CHECK_EQUAL( 0., simtimer.simulationTimeElapsed() ); + BOOST_CHECK_EQUAL( 120, simtimer.numSteps() ); + BOOST_CHECK_EQUAL( 1200., Opm::unit::convert::to(simtimer.totalTime(), Opm::unit::day) ); + BOOST_CHECK_EQUAL( 0., Opm::unit::convert::to(simtimer.simulationTimeElapsed(), Opm::unit::day) ); + + double testCurrentTime = 0.; + BOOST_CHECK_EQUAL( Opm::unit::convert::to(testCurrentTime, Opm::unit::day), + Opm::unit::convert::to(simtimer.simulationTimeElapsed(), Opm::unit::day) ); + + for ( int i = 0; i < simtimer.numSteps(); ++i ) { + BOOST_CHECK_EQUAL( i, simtimer.currentStepNum() ); + BOOST_CHECK_EQUAL( Opm::unit::convert::to(testCurrentTime, Opm::unit::minute), + Opm::unit::convert::to(simtimer.simulationTimeElapsed(), Opm::unit::minute) ); + testCurrentTime += simtimer.currentStepLength(); + ++simtimer; + } + + for ( int i = 0; i <= simtimer.numSteps(); ++i ) { + simtimer.setCurrentStepNum(i); + BOOST_CHECK_EQUAL( i, simtimer.currentStepNum() ); + } + + BOOST_CHECK_EQUAL( true, simtimer.done() ); + simtimer.setCurrentStepNum(0); + BOOST_CHECK_EQUAL( false, simtimer.done() ); + BOOST_CHECK_EQUAL( 0., Opm::unit::convert::to(simtimer.simulationTimeElapsed(), Opm::unit::day) ); + + simtimer.setCurrentStepNum(120); + BOOST_CHECK_EQUAL( Opm::unit::convert::to(simtimer.simulationTimeElapsed(), Opm::unit::day), + Opm::unit::convert::to(simtimer.totalTime(), Opm::unit::day) ); + + int i = 0; + double testCurrentTime1 = 0.; + double testCurrentTime2 = 0.; + simtimer.setCurrentStepNum(0); + + while (!simtimer.done()) { + testCurrentTime1 += simtimer.currentStepLength(); + BOOST_CHECK_EQUAL( i, simtimer.currentStepNum() ); + ++i; + ++simtimer; + testCurrentTime2 += simtimer.stepLengthTaken(); + BOOST_CHECK_EQUAL( Opm::unit::convert::to(testCurrentTime1, Opm::unit::minute), + Opm::unit::convert::to(simtimer.simulationTimeElapsed(), Opm::unit::minute) ); + BOOST_CHECK_EQUAL( Opm::unit::convert::to(testCurrentTime2, Opm::unit::minute), + Opm::unit::convert::to(simtimer.simulationTimeElapsed(), Opm::unit::minute) ); + } + + BOOST_CHECK_EQUAL( true, simtimer.done() ); + BOOST_CHECK_EQUAL( Opm::unit::convert::to(testCurrentTime1, Opm::unit::minute), + Opm::unit::convert::to(simtimer.totalTime(), Opm::unit::minute) ); + BOOST_CHECK_EQUAL( Opm::unit::convert::to(testCurrentTime2, Opm::unit::minute), + Opm::unit::convert::to(simtimer.totalTime(), Opm::unit::minute) ); + +} From 2dacfc8c15d2fc8027599e42f11b00e8714f23df Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Thu, 17 Apr 2014 11:47:50 +0200 Subject: [PATCH 056/163] convert the examples and the tests to opm-parser --- examples/wells_example.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index d0b915314..ea8db46fb 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -1,8 +1,7 @@ #include "config.h" -#include -#include -#include +#include +#include #include #include @@ -20,6 +19,7 @@ #include #include +#include #include int main(int argc, char** argv) @@ -34,16 +34,17 @@ try simtimer.init(parameters); // Read input file - EclipseGridParser parser(file_name); + Opm::ParserPtr parser(new Opm::Parser()); + Opm::DeckConstPtr newParserDeck = parser->parseFile(file_name); std::cout << "Done!" << std::endl; + // Setup grid - GridManager grid(parser); + GridManager grid(newParserDeck); // Define rock and fluid properties - IncompPropertiesFromDeck incomp_properties(parser, *grid.c_grid()); - RockCompressibility rock_comp(parser); - ParserPtr newParser(new Opm::Parser()); - EclipseStateConstPtr eclipseState(new Opm::EclipseState(newParser->parseFile(file_name))); + IncompPropertiesFromDeck incomp_properties(newParserDeck, *grid.c_grid()); + RockCompressibility rock_comp(newParserDeck); + EclipseStateConstPtr eclipseState(new Opm::EclipseState(newParserDeck)); // Finally handle the wells WellsManager wells(eclipseState , 0 , *grid.c_grid(), incomp_properties.permeability()); @@ -75,7 +76,7 @@ try Opm::TwophaseState state; - initStateFromDeck(*grid.c_grid(), incomp_properties, parser, gravity[2], state); + initStateFromDeck(*grid.c_grid(), incomp_properties, newParserDeck, gravity[2], state); Opm::WellState well_state; well_state.init(wells.c_wells(), state); From 0fe2d04708b53ca8b901457bc2bcc9b90cab84f9 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Thu, 17 Apr 2014 12:04:31 +0200 Subject: [PATCH 057/163] remove EclipseGridParser compatibility methods from all classes --- opm/simulators/timestepping/SimulatorTimer.cpp | 9 --------- opm/simulators/timestepping/SimulatorTimer.hpp | 6 ------ 2 files changed, 15 deletions(-) diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index ade613b08..add8b7389 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include @@ -49,14 +48,6 @@ namespace Opm total_time_ = num_psteps*stepsize; } - /// Initialize from TSTEP field. - void SimulatorTimer::init(const EclipseGridParser& deck) - { - timesteps_ = deck.getTSTEP().tstep_; - total_time_ = std::accumulate(timesteps_.begin(), timesteps_.end(), 0.0); - start_date_ = deck.getStartDate(); - } - /// Use the SimulatorTimer as a shim around opm-parser's Opm::TimeMap void SimulatorTimer::init(Opm::TimeMapConstPtr timeMap) { diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index e2b5db071..61faef095 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -31,8 +31,6 @@ namespace Opm { namespace parameter { class ParameterGroup; } - class EclipseGridParser; - class SimulatorTimer { @@ -45,10 +43,6 @@ namespace Opm /// stepsize_days (default 1) void init(const parameter::ParameterGroup& param); - /// Initialize from TSTEP field. - /// Note that DATES are folded into TSTEP by the parser. - void init(const EclipseGridParser& deck); - /// Use the SimulatorTimer as a shim around opm-parser's Opm::TimeMap void init(TimeMapConstPtr timeMap); From bd81627dd34ddce02ccc99198f732d135487694c Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Sat, 26 Apr 2014 12:03:07 +0200 Subject: [PATCH 058/163] rename all "newParserDeck" objects to "deck" The "new" parser is now "the" parser... --- examples/wells_example.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index ea8db46fb..f2874800a 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -35,16 +35,16 @@ try // Read input file Opm::ParserPtr parser(new Opm::Parser()); - Opm::DeckConstPtr newParserDeck = parser->parseFile(file_name); + Opm::DeckConstPtr deck = parser->parseFile(file_name); std::cout << "Done!" << std::endl; // Setup grid - GridManager grid(newParserDeck); + GridManager grid(deck); // Define rock and fluid properties - IncompPropertiesFromDeck incomp_properties(newParserDeck, *grid.c_grid()); - RockCompressibility rock_comp(newParserDeck); - EclipseStateConstPtr eclipseState(new Opm::EclipseState(newParserDeck)); + IncompPropertiesFromDeck incomp_properties(deck, *grid.c_grid()); + RockCompressibility rock_comp(deck); + EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck)); // Finally handle the wells WellsManager wells(eclipseState , 0 , *grid.c_grid(), incomp_properties.permeability()); @@ -76,7 +76,7 @@ try Opm::TwophaseState state; - initStateFromDeck(*grid.c_grid(), incomp_properties, newParserDeck, gravity[2], state); + initStateFromDeck(*grid.c_grid(), incomp_properties, deck, gravity[2], state); Opm::WellState well_state; well_state.init(wells.c_wells(), state); From db8b68b1d159d38285878e6cf179cac4397b6d67 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Fri, 6 Jun 2014 14:07:14 +0200 Subject: [PATCH 059/163] Glue in support for the grid property modifier keywords this basically means using Opm::EclipseState instead of the raw deck for these keywords. with this, property modifiers like ADD, MULT, COPY and friends are supported for at least the PERM* keywords. If additional keywords are required these can be added relatively easily as well. no ctest regressions have been observed with this patch on my machine. --- examples/wells_example.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index f2874800a..daf869543 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -36,15 +36,15 @@ try // Read input file Opm::ParserPtr parser(new Opm::Parser()); Opm::DeckConstPtr deck = parser->parseFile(file_name); + Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck)); std::cout << "Done!" << std::endl; // Setup grid GridManager grid(deck); // Define rock and fluid properties - IncompPropertiesFromDeck incomp_properties(deck, *grid.c_grid()); + IncompPropertiesFromDeck incomp_properties(deck, eclipseState, *grid.c_grid()); RockCompressibility rock_comp(deck); - EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck)); // Finally handle the wells WellsManager wells(eclipseState , 0 , *grid.c_grid(), incomp_properties.permeability()); From b4fe4e36670eb3dca47636d1a1498fa78f40e0fb Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Wed, 17 Sep 2014 12:44:40 +0200 Subject: [PATCH 060/163] adapt the the table related API changes of opm-parser --- examples/wells_example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index daf869543..88a910413 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -44,7 +44,7 @@ try // Define rock and fluid properties IncompPropertiesFromDeck incomp_properties(deck, eclipseState, *grid.c_grid()); - RockCompressibility rock_comp(deck); + RockCompressibility rock_comp(deck, eclipseState); // Finally handle the wells WellsManager wells(eclipseState , 0 , *grid.c_grid(), incomp_properties.permeability()); From ade58e64b9db5525137ef94611c37ad26c3a2cbb Mon Sep 17 00:00:00 2001 From: Robert K Date: Tue, 30 Sep 2014 15:55:26 +0200 Subject: [PATCH 061/163] SubStepSimulationTimer for time step control. Needs documentation and cleanup. --- .../timestepping/SimulatorTimer.hpp | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index 61faef095..01b9b7498 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -110,6 +110,65 @@ namespace Opm boost::gregorian::date start_date_; }; + class SubStepSimulatorTimer + { + protected: + const SimulatorTimer& simulator_timer_; + double dt_; + double current_time_; + const double total_time_; + int sub_step_; + + std::vector< double > steps_; + public: + SubStepSimulatorTimer( const SimulatorTimer& st, const double lastDt ) + : simulator_timer_( st ) + , dt_( lastDt ) + , current_time_( simulator_timer_.simulationTimeElapsed() ) + , total_time_( current_time_ + simulator_timer_.currentStepLength() ) + , sub_step_( 0 ) + , steps_() + { + steps_.reserve( 10 ); + } + + void next( const double new_dt ) + { + ++sub_step_; + current_time_ += dt_; + // store used time step sizes + steps_.push_back( dt_ ); + + double remaining = total_time_ - current_time_; + // set new time step (depending on remaining time) + dt_ = ( new_dt > remaining && remaining > 0 ) ? remaining : new_dt ; + } + + int currentStepNum () const { return sub_step_; } + + double currentStepLength () const + { + assert( ! done () ); + return dt_; + } + + double totalTime() const { return total_time_; } + + double simulationTimeElapsed() const { return current_time_; } + + bool done () const { return (current_time_ >= total_time_) ; } + + void report(std::ostream& os) const + { + os << "Sub steps started at time = " << simulator_timer_.simulationTimeElapsed() << std::endl; + for( size_t i=0; i Date: Fri, 3 Oct 2014 13:33:13 +0200 Subject: [PATCH 065/163] class for handling adaptive time steps. --- .../timestepping/AdaptiveSimulatorTimer.hpp | 190 ++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp new file mode 100644 index 000000000..d86db01bf --- /dev/null +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp @@ -0,0 +1,190 @@ +/* + Copyright 2014 IRIS AS + + This file is part of the Open Porous Media project (OPM). + + OPM 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. + + OPM 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 OPM. If not, see . +*/ + +#ifndef OPM_ADAPTIVESIMULATORTIMER_HEADER_INCLUDED +#define OPM_ADAPTIVESIMULATORTIMER_HEADER_INCLUDED + +#include +#include +#include + +#include +#include + +namespace Opm +{ + + ///////////////////////////////////////////////////////// + /// + /// \brief Simulation timer for adaptive time stepping + /// + ///////////////////////////////////////////////////////// + class AdaptiveSimulatorTimer + { + protected: + const double start_time_; + const double total_time_; + double current_time_; + double dt_; + int current_step_; + + std::vector< double > steps_; + double suggestedMax_; + double suggestedAverage_; + + double computeInitialTimeStep( const double lastDt ) const + { + const double maxTimeStep = total_time_ - start_time_; + const double fraction = (lastDt / maxTimeStep); + // when lastDt and maxTimeStep are close together, choose the max time step + if( fraction > 0.95 ) return maxTimeStep; + // if lastDt is still pretty large, choose half step size since we have to + // do two steps anyway + // if( fraction > 0.85 ) return 0.5 * maxTimeStep; + + // otherwise choose lastDt + return std::min( lastDt, maxTimeStep ); + } + public: + /// \brief constructor taking a simulator timer to determine start and end time + /// \param start_time start time of timer + /// \param total_time total time of timer + /// \param lastDt last suggested length of time step interval + AdaptiveSimulatorTimer( const double start_time, const double total_time, const double lastDt ) + : start_time_( start_time ) + , total_time_( total_time ) + , current_time_( start_time_ ) + , dt_( computeInitialTimeStep( lastDt ) ) + , current_step_( 0 ) + , steps_() + , suggestedMax_( 0.0 ) + , suggestedAverage_( 0.0 ) + { + // reserve memory for sub steps + steps_.reserve( 10 ); + } + + /// \brief decrease current time step for factor of two + void halfTimeStep() { dt_ *= 0.5; } + + /// \brief advance time by currentStepLength and set new step lenght + void advance( const double new_dt ) + { + ++current_step_; + current_time_ += dt_; + // store used time step sizes + steps_.push_back( dt_ ); + + // store some information about the time steps suggested + suggestedMax_ = std::max( new_dt, suggestedMax_ ); + suggestedAverage_ += new_dt; + + double remaining = (total_time_ - current_time_); + + if( remaining > 0 ) { + + // set new time step (depending on remaining time) + if( 1.5 * new_dt > remaining ) { + dt_ = remaining; + return ; + } + + // check for half interval step to avoid very small step at the end + // remaining *= 0.5; + + if( 2.25 * new_dt > remaining ) { + dt_ = 0.5 * remaining ; + return ; + } + } + + // otherwise set new_dt as is + dt_ = new_dt; + } + + /// \brief \copydoc SimulationTimer::currentStepNum + int currentStepNum () const { return current_step_; } + + /// \brief \copydoc SimulationTimer::currentStepLength + double currentStepLength () const + { + assert( ! done () ); + return dt_; + } + + /// \brief \copydoc SimulationTimer::totalTime + double totalTime() const { return total_time_; } + + /// \brief \copydoc SimulationTimer::simulationTimeElapsed + double simulationTimeElapsed() const { return current_time_; } + + /// \brief \copydoc SimulationTimer::done + bool done () const { return (current_time_ >= total_time_) ; } + + /// \brief return average step length used so far + double averageStepLength() const + { + const int size = steps_.size(); + if( size == 0 ) return 0.0; + + const double sum = std::accumulate(steps_.begin(), steps_.end(), 0.0); + return sum / double(size); + } + + /// \brief return max step length used so far + double maxStepLength () const + { + if( steps_.size() == 0 ) return 0.0; + return *(std::max_element( steps_.begin(), steps_.end() )); + } + + /// \brief return min step length used so far + double minStepLength () const + { + if( steps_.size() == 0 ) return 0.0; + return *(std::min_element( steps_.begin(), steps_.end() )); + } + + /// \brief return max suggested step length + double suggestedMax () const { return suggestedMax_; } + + /// \brief return average suggested step length + double suggestedAverage () const + { + const int size = steps_.size(); + return (size > 0 ) ? (suggestedAverage_ / double(size)) : suggestedAverage_; + } + + /// \brief report start and end time as well as used steps so far + void report(std::ostream& os) const + { + const double factor = 24.0 * 3600.0; + os << "Sub steps started at time = " << start_time_/factor << " (days)" << std::endl; + for( size_t i=0; i Date: Fri, 3 Oct 2014 13:44:05 +0200 Subject: [PATCH 066/163] renamed and split advance method. --- .../timestepping/AdaptiveSimulatorTimer.hpp | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp index d86db01bf..05cbffead 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp @@ -83,24 +83,28 @@ namespace Opm /// \brief decrease current time step for factor of two void halfTimeStep() { dt_ *= 0.5; } - /// \brief advance time by currentStepLength and set new step lenght - void advance( const double new_dt ) + /// \brief advance time by currentStepLength + void advance() { ++current_step_; current_time_ += dt_; // store used time step sizes steps_.push_back( dt_ ); + } + /// \brief provide and estimate for new time step size + void provideTimeStepEstimate( const double dt_estimate ) + { // store some information about the time steps suggested - suggestedMax_ = std::max( new_dt, suggestedMax_ ); - suggestedAverage_ += new_dt; + suggestedMax_ = std::max( dt_estimate, suggestedMax_ ); + suggestedAverage_ += dt_estimate; double remaining = (total_time_ - current_time_); if( remaining > 0 ) { // set new time step (depending on remaining time) - if( 1.5 * new_dt > remaining ) { + if( 1.5 * dt_estimate > remaining ) { dt_ = remaining; return ; } @@ -108,14 +112,14 @@ namespace Opm // check for half interval step to avoid very small step at the end // remaining *= 0.5; - if( 2.25 * new_dt > remaining ) { + if( 2.25 * dt_estimate > remaining ) { dt_ = 0.5 * remaining ; return ; } } - // otherwise set new_dt as is - dt_ = new_dt; + // otherwise set dt_estimate as is + dt_ = dt_estimate; } /// \brief \copydoc SimulationTimer::currentStepNum From e99158faa9e1acd6fcbb1b9c88a3613d9c3f971c Mon Sep 17 00:00:00 2001 From: Robert K Date: Fri, 3 Oct 2014 14:10:56 +0200 Subject: [PATCH 067/163] reset to old state. --- .../timestepping/SimulatorTimer.hpp | 132 ------------------ 1 file changed, 132 deletions(-) diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index 3ff656a48..61faef095 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -1,6 +1,5 @@ /* Copyright 2012 SINTEF ICT, Applied Mathematics. - Copyright 2014 IRIS AS This file is part of the Open Porous Media project (OPM). @@ -25,9 +24,6 @@ #include #include -#include -#include - #include #include @@ -114,134 +110,6 @@ namespace Opm boost::gregorian::date start_date_; }; - class SubStepSimulatorTimer - { - protected: - const SimulatorTimer& simulator_timer_; - double dt_; - double current_time_; - const double total_time_; - int sub_step_; - - std::vector< double > steps_; - double suggestedMax_; - double suggestedAverage_; - - double computeInitialTimeStep( const double lastDt ) const - { - const double maxTimeStep = simulator_timer_.currentStepLength(); - const double fraction = (lastDt / maxTimeStep); - // when lastDt and maxTimeStep are close together, choose the max time step - if( fraction > 0.95 ) return maxTimeStep; - // if lastDt is still pretty large, choose half step size since we have to - // do two steps anyway - // if( fraction > 0.85 ) return 0.5 * maxTimeStep; - - // otherwise choose lastDt - return std::min( lastDt, maxTimeStep ); - } - public: - SubStepSimulatorTimer( const SimulatorTimer& st, const double lastDt ) - : simulator_timer_( st ) - , dt_( computeInitialTimeStep( lastDt ) ) - , current_time_( simulator_timer_.simulationTimeElapsed() ) - , total_time_( current_time_ + simulator_timer_.currentStepLength() ) - , sub_step_( 0 ) - , steps_() - , suggestedMax_( 0.0 ) - , suggestedAverage_( 0.0 ) - { - steps_.reserve( 10 ); - } - - void next( const double new_dt ) - { - ++sub_step_; - current_time_ += dt_; - // store used time step sizes - steps_.push_back( dt_ ); - - // store some information about the time steps suggested - suggestedMax_ = std::max( new_dt, suggestedMax_ ); - suggestedAverage_ += new_dt; - - double remaining = (total_time_ - current_time_); - - if( remaining > 0 ) { - - // set new time step (depending on remaining time) - if( 1.5 * new_dt > remaining ) { - dt_ = remaining; - return ; - } - - // check for half interval step to avoid very small step at the end - // remaining *= 0.5; - - if( 2.25 * new_dt > remaining ) { - dt_ = 0.5 * remaining ; - return ; - } - } - - // otherwise set new_dt as is - dt_ = new_dt; - } - - int currentStepNum () const { return sub_step_; } - - double currentStepLength () const - { - assert( ! done () ); - return dt_; - } - - double totalTime() const { return total_time_; } - - double simulationTimeElapsed() const { return current_time_; } - - bool done () const { return (current_time_ >= total_time_) ; } - - double averageStepLength() const - { - const int size = steps_.size(); - if( size == 0 ) return 0.0; - - const double sum = std::accumulate(steps_.begin(), steps_.end(), 0.0); - return sum / double(size); - } - - double maxStepLength () const - { - if( steps_.size() == 0 ) return 0.0; - return *(std::max_element( steps_.begin(), steps_.end() )); - } - - double minStepLength () const - { - if( steps_.size() == 0 ) return 0.0; - return *(std::min_element( steps_.begin(), steps_.end() )); - } - - double suggestedMax () const { return suggestedMax_; } - double suggestedAverage () const - { - const int size = steps_.size(); - return (size > 0 ) ? (suggestedAverage_ / double(size)) : suggestedAverage_; - } - - void report(std::ostream& os) const - { - const double factor = 24.0 * 3600.0; - os << "Sub steps started at time = " << simulator_timer_.simulationTimeElapsed()/factor << " (days)" << std::endl; - for( size_t i=0; i Date: Fri, 3 Oct 2014 14:14:01 +0200 Subject: [PATCH 068/163] remove white spaces. --- .../timestepping/AdaptiveSimulatorTimer.hpp | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp index 05cbffead..484551b49 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp @@ -32,8 +32,8 @@ namespace Opm ///////////////////////////////////////////////////////// /// - /// \brief Simulation timer for adaptive time stepping - /// + /// \brief Simulation timer for adaptive time stepping + /// ///////////////////////////////////////////////////////// class AdaptiveSimulatorTimer { @@ -48,7 +48,7 @@ namespace Opm double suggestedMax_; double suggestedAverage_; - double computeInitialTimeStep( const double lastDt ) const + double computeInitialTimeStep( const double lastDt ) const { const double maxTimeStep = total_time_ - start_time_; const double fraction = (lastDt / maxTimeStep); @@ -62,7 +62,7 @@ namespace Opm return std::min( lastDt, maxTimeStep ); } public: - /// \brief constructor taking a simulator timer to determine start and end time + /// \brief constructor taking a simulator timer to determine start and end time /// \param start_time start time of timer /// \param total_time total time of timer /// \param lastDt last suggested length of time step interval @@ -81,21 +81,21 @@ namespace Opm } /// \brief decrease current time step for factor of two - void halfTimeStep() { dt_ *= 0.5; } + void halfTimeStep() { dt_ *= 0.5; } /// \brief advance time by currentStepLength - void advance() + void advance() { ++current_step_; current_time_ += dt_; // store used time step sizes steps_.push_back( dt_ ); - } + } /// \brief provide and estimate for new time step size - void provideTimeStepEstimate( const double dt_estimate ) + void provideTimeStepEstimate( const double dt_estimate ) { - // store some information about the time steps suggested + // store some information about the time steps suggested suggestedMax_ = std::max( dt_estimate, suggestedMax_ ); suggestedAverage_ += dt_estimate; @@ -105,7 +105,7 @@ namespace Opm // set new time step (depending on remaining time) if( 1.5 * dt_estimate > remaining ) { - dt_ = remaining; + dt_ = remaining; return ; } @@ -113,7 +113,7 @@ namespace Opm // remaining *= 0.5; if( 2.25 * dt_estimate > remaining ) { - dt_ = 0.5 * remaining ; + dt_ = 0.5 * remaining; return ; } } @@ -122,10 +122,10 @@ namespace Opm dt_ = dt_estimate; } - /// \brief \copydoc SimulationTimer::currentStepNum + /// \brief \copydoc SimulationTimer::currentStepNum int currentStepNum () const { return current_step_; } - /// \brief \copydoc SimulationTimer::currentStepLength + /// \brief \copydoc SimulationTimer::currentStepLength double currentStepLength () const { assert( ! done () ); @@ -169,10 +169,10 @@ namespace Opm double suggestedMax () const { return suggestedMax_; } /// \brief return average suggested step length - double suggestedAverage () const - { + double suggestedAverage () const + { const int size = steps_.size(); - return (size > 0 ) ? (suggestedAverage_ / double(size)) : suggestedAverage_; + return (size > 0 ) ? (suggestedAverage_ / double(size)) : suggestedAverage_; } /// \brief report start and end time as well as used steps so far @@ -188,7 +188,6 @@ namespace Opm } }; - } // namespace Opm #endif // OPM_SIMULATORTIMER_HEADER_INCLUDED From 8a17e5e5d687b7e0bd31da3b8adc016559e65056 Mon Sep 17 00:00:00 2001 From: Robert K Date: Fri, 3 Oct 2014 15:53:18 +0200 Subject: [PATCH 069/163] move protected area to the bottom and remove unused lines as well as halfTimeStep method. --- .../timestepping/AdaptiveSimulatorTimer.hpp | 51 +++++++++---------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp index 484551b49..4c8cbea1b 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp @@ -37,30 +37,6 @@ namespace Opm ///////////////////////////////////////////////////////// class AdaptiveSimulatorTimer { - protected: - const double start_time_; - const double total_time_; - double current_time_; - double dt_; - int current_step_; - - std::vector< double > steps_; - double suggestedMax_; - double suggestedAverage_; - - double computeInitialTimeStep( const double lastDt ) const - { - const double maxTimeStep = total_time_ - start_time_; - const double fraction = (lastDt / maxTimeStep); - // when lastDt and maxTimeStep are close together, choose the max time step - if( fraction > 0.95 ) return maxTimeStep; - // if lastDt is still pretty large, choose half step size since we have to - // do two steps anyway - // if( fraction > 0.85 ) return 0.5 * maxTimeStep; - - // otherwise choose lastDt - return std::min( lastDt, maxTimeStep ); - } public: /// \brief constructor taking a simulator timer to determine start and end time /// \param start_time start time of timer @@ -80,9 +56,6 @@ namespace Opm steps_.reserve( 10 ); } - /// \brief decrease current time step for factor of two - void halfTimeStep() { dt_ *= 0.5; } - /// \brief advance time by currentStepLength void advance() { @@ -178,7 +151,7 @@ namespace Opm /// \brief report start and end time as well as used steps so far void report(std::ostream& os) const { - const double factor = 24.0 * 3600.0; + const double factor = 86400.0; os << "Sub steps started at time = " << start_time_/factor << " (days)" << std::endl; for( size_t i=0; i steps_; + double suggestedMax_; + double suggestedAverage_; + + double computeInitialTimeStep( const double lastDt ) const + { + const double maxTimeStep = total_time_ - start_time_; + const double fraction = (lastDt / maxTimeStep); + // when lastDt and maxTimeStep are close together, choose the max time step + if( fraction > 0.95 ) return maxTimeStep; + + // otherwise choose lastDt + return std::min( lastDt, maxTimeStep ); + } }; } // namespace Opm From 294b899ee82f468ee5d4edfc99788c35b6c371b6 Mon Sep 17 00:00:00 2001 From: Robert K Date: Mon, 6 Oct 2014 14:06:07 +0200 Subject: [PATCH 070/163] the adaptive time stepping utility classes. --- .../timestepping/AdaptiveSimulatorTimer.hpp | 3 +- .../timestepping/AdaptiveTimeStepping.hpp | 48 +++++++ .../AdaptiveTimeStepping_impl.hpp | 130 ++++++++++++++++++ .../timestepping/TimeStepControlInterface.hpp | 51 +++++++ 4 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 opm/simulators/timestepping/AdaptiveTimeStepping.hpp create mode 100644 opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp create mode 100644 opm/simulators/timestepping/TimeStepControlInterface.hpp diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp index 4c8cbea1b..4161fd40a 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp @@ -57,12 +57,13 @@ namespace Opm } /// \brief advance time by currentStepLength - void advance() + AdaptiveSimulatorTimer& operator++ () { ++current_step_; current_time_ += dt_; // store used time step sizes steps_.push_back( dt_ ); + return *this; } /// \brief provide and estimate for new time step size diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp new file mode 100644 index 000000000..db3b61b0b --- /dev/null +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -0,0 +1,48 @@ +#ifndef OPM_SUBSTEPPING_HEADER_INCLUDED +#define OPM_SUBSTEPPING_HEADER_INCLUDED + +#include +#include + +#include +#include +#include + +namespace Opm { + + // AdaptiveTimeStepping + //--------------------- + + class AdaptiveTimeStepping + { + public: + //! \brief contructor taking parameter object + AdaptiveTimeStepping( const parameter::ParameterGroup& param ); + + /** \brief step method that acts like the solver::step method + in a sub cycle of time steps + + \param solver solver object that must implement a method step( dt, state, well_state ) + \param state current state of the solution variables + \param well_state additional well state object + \param time current simulation time + \param timestep current time step length that is to be sub cycled + */ + template + void step( Solver& solver, State& state, WellState& well_state, + const double time, const double timestep ); + + protected: + typedef std::unique_ptr< TimeStepControlInterface > TimeStepControlType; + + TimeStepControlType timeStepControl_; //!< time step control object + const double restart_factor_; //!< factor to multiply time step with when solver fails to converge + const int solver_restart_max_; //!< how many restart of solver are allowed + const bool solver_verbose_; //!< solver verbosity + const bool timestep_verbose_; //!< timestep verbosity + double last_timestep_; //!< size of last timestep + }; +} + +#include +#endif diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp new file mode 100644 index 000000000..fa45bbc33 --- /dev/null +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -0,0 +1,130 @@ +#ifndef OPM_ADAPTIVETIMESTEPPING_IMPL_HEADER_INCLUDED +#define OPM_ADAPTIVETIMESTEPPING_IMPL_HEADER_INCLUDED + +#include +#include +#include + +#include +#include + +namespace Opm { + + // AdaptiveTimeStepping + //--------------------- + + AdaptiveTimeStepping::AdaptiveTimeStepping( const parameter::ParameterGroup& param ) + : timeStepControl_() + , restart_factor_( param.getDefault("solver.restartfactor", double(0.1) ) ) + , solver_restart_max_( param.getDefault("solver.restart", int(3) ) ) + , solver_verbose_( param.getDefault("solver.verbose", bool(false) ) ) + , timestep_verbose_( param.getDefault("timestep.verbose", bool(false) ) ) + , last_timestep_( std::numeric_limits< double >::max() ) + { + // valid are "pid" and "pid+iteration" + std::string control = param.getDefault("timestep.control", std::string("pid") ); + + const double tol = param.getDefault("timestep.control.tol", double(1e-3) ); + if( control == "pid" ) + timeStepControl_ = TimeStepControlType( new PIDTimeStepControl( tol ) ); + else if ( control == "pid+iteration" ) + { + const int iterations = param.getDefault("timestep.control.targetiteration", int(25) ); + timeStepControl_ = TimeStepControlType( new PIDAndIterationCountTimeStepControl( iterations, tol ) ); + } + else + OPM_THROW(std::runtime_error,"Unsupported time step control selected "<< control ); + } + + + template + void AdaptiveTimeStepping:: + step( Solver& solver, State& state, WellState& well_state, + const double time, const double timestep ) + { + // create adaptive step timer with previously used sub step size + AdaptiveSimulatorTimer timer( time, time+timestep, last_timestep_ ); + + // copy states in case solver has to be restarted (to be revised) + State last_state( state ); + WellState last_well_state( well_state ); + + // counter for solver restarts + int restarts = 0; + + // sub step time loop + while( ! timer.done() ) + { + // initialize time step control in case current state is needed later + timeStepControl_->initialize( state ); + + int linearIterations = -1; + try { + // (linearIterations < 0 means on convergence in solver) + linearIterations = solver.step(timer.currentStepLength(), state, well_state); + + if( solver_verbose_ ) { + // report number of linear iterations + std::cout << "Overall linear iterations used: " << linearIterations << std::endl; + } + } + catch (Opm::NumericalProblem) + { + // since linearIterations is < 0 this will restart the solver + } + + // (linearIterations < 0 means on convergence in solver) + if( linearIterations >= 0 ) + { + // advance by current dt + ++timer; + + // compute new time step estimate + const double dtEstimate = + timeStepControl_->computeTimeStepSize( timer.currentStepLength(), linearIterations, state ); + if( timestep_verbose_ ) + std::cout << "Suggested time step size = " << dtEstimate/86400.0 << " (days)" << std::endl; + + // set new time step length + timer.provideTimeStepEstimate( dtEstimate ); + + // update states + last_state = state ; + last_well_state = well_state; + } + else // in case of no convergence + { + // increase restart counter + if( restarts >= solver_restart_max_ ) { + OPM_THROW(Opm::NumericalProblem,"Solver failed to converge after " << restarts << " restarts."); + } + + const double newTimeStep = restart_factor_ * timer.currentStepLength(); + // we need to revise this + timer.provideTimeStepEstimate( newTimeStep ); + if( solver_verbose_ ) + std::cerr << "Solver convergence failed, restarting solver with new time step ("<< newTimeStep <<" days)." << std::endl; + + // reset states + state = last_state; + well_state = last_well_state; + + ++restarts; + } + } + + + // store last small time step for next reportStep + last_timestep_ = timer.suggestedAverage(); + if( timestep_verbose_ ) + { + timer.report( std::cout ); + std::cout << "Last suggested step size = " << last_timestep_/86400.0 << " (days)" << std::endl; + } + + if( ! std::isfinite( last_timestep_ ) ) // check for NaN + last_timestep_ = timestep; + } +} + +#endif diff --git a/opm/simulators/timestepping/TimeStepControlInterface.hpp b/opm/simulators/timestepping/TimeStepControlInterface.hpp new file mode 100644 index 000000000..69e3857d8 --- /dev/null +++ b/opm/simulators/timestepping/TimeStepControlInterface.hpp @@ -0,0 +1,51 @@ +/* + Copyright 2014 IRIS AS + + This file is part of the Open Porous Media project (OPM). + + OPM 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. + + OPM 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 OPM. If not, see . +*/ +#ifndef OPM_TIMESTEPCONTROLINTERFACE_HEADER_INCLUDED +#define OPM_TIMESTEPCONTROLINTERFACE_HEADER_INCLUDED + +namespace Opm +{ + + /////////////////////////////////////////////////////////////////// + /// + /// TimeStepControlInterface + /// + /////////////////////////////////////////////////////////////////// + class TimeStepControlInterface + { + protected: + TimeStepControlInterface() {} + public: + /// \param state simulation state before computing update in the solver (default is empty) + virtual void initialize( const SimulatorState& state ) {} + + /// compute new time step size suggestions based on the PID controller + /// \param dt time step size used in the current step + /// \param iterations number of iterations used (linear/nonlinear) + /// \param state new solution state + /// + /// \return suggested time step size for the next step + virtual double computeTimeStepSize( const double dt, const int iterations, const SimulatorState& ) const = 0; + + /// virtual destructor (empty) + virtual ~TimeStepControlInterface () {} + }; + +} +#endif From 0e133f2cca9ba2d299594c307dae3de19ddf4e8f Mon Sep 17 00:00:00 2001 From: Robert K Date: Mon, 6 Oct 2014 14:26:23 +0200 Subject: [PATCH 071/163] move implementation to .cpp files. --- .../timestepping/AdaptiveSimulatorTimer.cpp | 145 ++++++++++++++++++ .../timestepping/AdaptiveSimulatorTimer.hpp | 106 ++----------- .../timestepping/TimeStepControlInterface.hpp | 2 + 3 files changed, 161 insertions(+), 92 deletions(-) create mode 100644 opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp new file mode 100644 index 000000000..93a64a916 --- /dev/null +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp @@ -0,0 +1,145 @@ +/* + Copyright 2014 IRIS AS + + This file is part of the Open Porous Media project (OPM). + + OPM 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. + + OPM 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 OPM. If not, see . +*/ + +#include +#include +#include + +#include +#include + +#include + +namespace Opm +{ + AdaptiveSimulatorTimer:: + AdaptiveSimulatorTimer( const double start_time, const double total_time, const double lastDt ) + : start_time_( start_time ) + , total_time_( total_time ) + , current_time_( start_time_ ) + , dt_( computeInitialTimeStep( lastDt ) ) + , current_step_( 0 ) + , steps_() + , suggestedMax_( 0.0 ) + , suggestedAverage_( 0.0 ) + { + // reserve memory for sub steps + steps_.reserve( 10 ); + } + + AdaptiveSimulatorTimer& AdaptiveSimulatorTimer::operator++ () + { + ++current_step_; + current_time_ += dt_; + // store used time step sizes + steps_.push_back( dt_ ); + return *this; + } + + void AdaptiveSimulatorTimer:: + provideTimeStepEstimate( const double dt_estimate ) + { + // store some information about the time steps suggested + suggestedMax_ = std::max( dt_estimate, suggestedMax_ ); + suggestedAverage_ += dt_estimate; + + double remaining = (total_time_ - current_time_); + + if( remaining > 0 ) { + + // set new time step (depending on remaining time) + if( 1.5 * dt_estimate > remaining ) { + dt_ = remaining; + return ; + } + + // check for half interval step to avoid very small step at the end + // remaining *= 0.5; + + if( 2.25 * dt_estimate > remaining ) { + dt_ = 0.5 * remaining; + return ; + } + } + + // otherwise set dt_estimate as is + dt_ = dt_estimate; + } + + int AdaptiveSimulatorTimer:: + currentStepNum () const { return current_step_; } + + double AdaptiveSimulatorTimer::currentStepLength () const + { + assert( ! done () ); + return dt_; + } + + double AdaptiveSimulatorTimer::totalTime() const { return total_time_; } + + double AdaptiveSimulatorTimer::simulationTimeElapsed() const { return current_time_; } + + bool AdaptiveSimulatorTimer::done () const { return (current_time_ >= total_time_) ; } + + double AdaptiveSimulatorTimer::averageStepLength() const + { + const int size = steps_.size(); + if( size == 0 ) return 0.0; + + const double sum = std::accumulate(steps_.begin(), steps_.end(), 0.0); + return sum / double(size); + } + + /// \brief return max step length used so far + double AdaptiveSimulatorTimer::maxStepLength () const + { + if( steps_.size() == 0 ) return 0.0; + return *(std::max_element( steps_.begin(), steps_.end() )); + } + + /// \brief return min step length used so far + double AdaptiveSimulatorTimer::minStepLength () const + { + if( steps_.size() == 0 ) return 0.0; + return *(std::min_element( steps_.begin(), steps_.end() )); + } + + /// \brief return max suggested step length + double AdaptiveSimulatorTimer::suggestedMax () const { return suggestedMax_; } + + /// \brief return average suggested step length + double AdaptiveSimulatorTimer::suggestedAverage () const + { + const int size = steps_.size(); + return (size > 0 ) ? (suggestedAverage_ / double(size)) : suggestedAverage_; + } + + /// \brief report start and end time as well as used steps so far + void AdaptiveSimulatorTimer::report(std::ostream& os) const + { + const double factor = 86400.0; + os << "Sub steps started at time = " << start_time_/factor << " (days)" << std::endl; + for( size_t i=0; i 0 ) { - - // set new time step (depending on remaining time) - if( 1.5 * dt_estimate > remaining ) { - dt_ = remaining; - return ; - } - - // check for half interval step to avoid very small step at the end - // remaining *= 0.5; - - if( 2.25 * dt_estimate > remaining ) { - dt_ = 0.5 * remaining; - return ; - } - } - - // otherwise set dt_estimate as is - dt_ = dt_estimate; - } + void provideTimeStepEstimate( const double dt_estimate ); /// \brief \copydoc SimulationTimer::currentStepNum - int currentStepNum () const { return current_step_; } + int currentStepNum () const; /// \brief \copydoc SimulationTimer::currentStepLength - double currentStepLength () const - { - assert( ! done () ); - return dt_; - } + double currentStepLength () const; /// \brief \copydoc SimulationTimer::totalTime - double totalTime() const { return total_time_; } + double totalTime() const; /// \brief \copydoc SimulationTimer::simulationTimeElapsed - double simulationTimeElapsed() const { return current_time_; } + double simulationTimeElapsed() const; /// \brief \copydoc SimulationTimer::done - bool done () const { return (current_time_ >= total_time_) ; } + bool done () const; /// \brief return average step length used so far - double averageStepLength() const - { - const int size = steps_.size(); - if( size == 0 ) return 0.0; - - const double sum = std::accumulate(steps_.begin(), steps_.end(), 0.0); - return sum / double(size); - } + double averageStepLength() const; /// \brief return max step length used so far - double maxStepLength () const - { - if( steps_.size() == 0 ) return 0.0; - return *(std::max_element( steps_.begin(), steps_.end() )); - } + double maxStepLength () const; /// \brief return min step length used so far - double minStepLength () const - { - if( steps_.size() == 0 ) return 0.0; - return *(std::min_element( steps_.begin(), steps_.end() )); - } + double minStepLength () const; /// \brief return max suggested step length - double suggestedMax () const { return suggestedMax_; } + double suggestedMax () const; /// \brief return average suggested step length - double suggestedAverage () const - { - const int size = steps_.size(); - return (size > 0 ) ? (suggestedAverage_ / double(size)) : suggestedAverage_; - } + double suggestedAverage () const; /// \brief report start and end time as well as used steps so far - void report(std::ostream& os) const - { - const double factor = 86400.0; - os << "Sub steps started at time = " << start_time_/factor << " (days)" << std::endl; - for( size_t i=0; i + namespace Opm { From 246acea76556ec2e22d086f3f8debedf5c7224d6 Mon Sep 17 00:00:00 2001 From: Robert Kloefkorn Date: Tue, 7 Oct 2014 09:48:57 +0200 Subject: [PATCH 072/163] use unit::convert::to instead of hard coded 86400 factor. --- .../timestepping/AdaptiveSimulatorTimer.cpp | 23 +++++++++++++++---- .../timestepping/AdaptiveSimulatorTimer.hpp | 11 +-------- .../AdaptiveTimeStepping_impl.hpp | 4 ++-- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp index 93a64a916..576e4faeb 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp @@ -24,6 +24,7 @@ #include #include +#include #include namespace Opm @@ -131,15 +132,27 @@ namespace Opm } /// \brief report start and end time as well as used steps so far - void AdaptiveSimulatorTimer::report(std::ostream& os) const + void AdaptiveSimulatorTimer:: + report(std::ostream& os) const { - const double factor = 86400.0; - os << "Sub steps started at time = " << start_time_/factor << " (days)" << std::endl; + os << "Sub steps started at time = " << unit::convert::to( start_time_, unit::day ) << " (days)" << std::endl; for( size_t i=0; i 0.95 ) return maxTimeStep; + + // otherwise choose lastDt + return std::min( lastDt, maxTimeStep ); } } // namespace Opm diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp index 09b3f5704..3336a69cf 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp @@ -94,16 +94,7 @@ namespace Opm double suggestedMax_; double suggestedAverage_; - double computeInitialTimeStep( const double lastDt ) const - { - const double maxTimeStep = total_time_ - start_time_; - const double fraction = (lastDt / maxTimeStep); - // when lastDt and maxTimeStep are close together, choose the max time step - if( fraction > 0.95 ) return maxTimeStep; - - // otherwise choose lastDt - return std::min( lastDt, maxTimeStep ); - } + double computeInitialTimeStep( const double lastDt ) const; }; } // namespace Opm diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index fa45bbc33..96a83d088 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -83,7 +83,7 @@ namespace Opm { const double dtEstimate = timeStepControl_->computeTimeStepSize( timer.currentStepLength(), linearIterations, state ); if( timestep_verbose_ ) - std::cout << "Suggested time step size = " << dtEstimate/86400.0 << " (days)" << std::endl; + std::cout << "Suggested time step size = " << unit::convert::to(dtEstimate, unit::day) << " (days)" << std::endl; // set new time step length timer.provideTimeStepEstimate( dtEstimate ); @@ -119,7 +119,7 @@ namespace Opm { if( timestep_verbose_ ) { timer.report( std::cout ); - std::cout << "Last suggested step size = " << last_timestep_/86400.0 << " (days)" << std::endl; + std::cout << "Last suggested step size = " << unit::convert::to( last_timestep_, unit::day ) << " (days)" << std::endl; } if( ! std::isfinite( last_timestep_ ) ) // check for NaN From 3b58ad9aa4ba949e013de71db715473b16a8a909 Mon Sep 17 00:00:00 2001 From: Robert Kloefkorn Date: Fri, 10 Oct 2014 13:55:28 +0200 Subject: [PATCH 073/163] Two small adjustments that came up when running in debug mode. --- .../timestepping/AdaptiveTimeStepping_impl.hpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 96a83d088..37f1cdc90 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -55,13 +55,16 @@ namespace Opm { // sub step time loop while( ! timer.done() ) { + // get current delta t + const double dt = timer.currentStepLength() ; + // initialize time step control in case current state is needed later timeStepControl_->initialize( state ); int linearIterations = -1; try { // (linearIterations < 0 means on convergence in solver) - linearIterations = solver.step(timer.currentStepLength(), state, well_state); + linearIterations = solver.step( dt, state, well_state); if( solver_verbose_ ) { // report number of linear iterations @@ -81,7 +84,7 @@ namespace Opm { // compute new time step estimate const double dtEstimate = - timeStepControl_->computeTimeStepSize( timer.currentStepLength(), linearIterations, state ); + timeStepControl_->computeTimeStepSize( dt, linearIterations, state ); if( timestep_verbose_ ) std::cout << "Suggested time step size = " << unit::convert::to(dtEstimate, unit::day) << " (days)" << std::endl; @@ -99,7 +102,7 @@ namespace Opm { OPM_THROW(Opm::NumericalProblem,"Solver failed to converge after " << restarts << " restarts."); } - const double newTimeStep = restart_factor_ * timer.currentStepLength(); + const double newTimeStep = restart_factor_ * dt; // we need to revise this timer.provideTimeStepEstimate( newTimeStep ); if( solver_verbose_ ) From 1bda36b2512e7d1e2d8522f57a370419fe1a1764 Mon Sep 17 00:00:00 2001 From: Robert Kloefkorn Date: Mon, 13 Oct 2014 11:17:37 +0200 Subject: [PATCH 074/163] added initial fraction to initialize last_timestep. --- opm/simulators/timestepping/AdaptiveTimeStepping.hpp | 1 + .../timestepping/AdaptiveTimeStepping_impl.hpp | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index db3b61b0b..104285501 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -36,6 +36,7 @@ namespace Opm { typedef std::unique_ptr< TimeStepControlInterface > TimeStepControlType; TimeStepControlType timeStepControl_; //!< time step control object + const double initial_fraction_; //!< fraction to take as a guess for initial time interval const double restart_factor_; //!< factor to multiply time step with when solver fails to converge const int solver_restart_max_; //!< how many restart of solver are allowed const bool solver_verbose_; //!< solver verbosity diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 37f1cdc90..3b6bac86e 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -15,11 +15,12 @@ namespace Opm { AdaptiveTimeStepping::AdaptiveTimeStepping( const parameter::ParameterGroup& param ) : timeStepControl_() + , initial_fraction_( param.getDefault("solver.initialfraction", double(0.25) ) ) , restart_factor_( param.getDefault("solver.restartfactor", double(0.1) ) ) , solver_restart_max_( param.getDefault("solver.restart", int(3) ) ) , solver_verbose_( param.getDefault("solver.verbose", bool(false) ) ) , timestep_verbose_( param.getDefault("timestep.verbose", bool(false) ) ) - , last_timestep_( std::numeric_limits< double >::max() ) + , last_timestep_( -1.0 ) { // valid are "pid" and "pid+iteration" std::string control = param.getDefault("timestep.control", std::string("pid") ); @@ -42,6 +43,10 @@ namespace Opm { step( Solver& solver, State& state, WellState& well_state, const double time, const double timestep ) { + // init last time step as a fraction of the given time step + if( last_timestep_ < 0 ) + last_timestep_ = initial_fraction_ * timestep ; + // create adaptive step timer with previously used sub step size AdaptiveSimulatorTimer timer( time, time+timestep, last_timestep_ ); @@ -106,7 +111,8 @@ namespace Opm { // we need to revise this timer.provideTimeStepEstimate( newTimeStep ); if( solver_verbose_ ) - std::cerr << "Solver convergence failed, restarting solver with new time step ("<< newTimeStep <<" days)." << std::endl; + std::cerr << "Solver convergence failed, restarting solver with new time step (" + << unit::convert::to( newTimeStep, unit::day ) <<" days)." << std::endl; // reset states state = last_state; From 40d851e89f9b3011a8014a9146e9a63fc5d66b30 Mon Sep 17 00:00:00 2001 From: Robert Kloefkorn Date: Tue, 14 Oct 2014 15:18:36 +0200 Subject: [PATCH 075/163] also catch std::runtime_error, i.e. convergence of linear solver failed. --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 3b6bac86e..0d330dc7c 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -76,10 +76,14 @@ namespace Opm { std::cout << "Overall linear iterations used: " << linearIterations << std::endl; } } - catch (Opm::NumericalProblem) - { + catch (Opm::NumericalProblem e) { + std::cerr << e.what() << std::endl; // since linearIterations is < 0 this will restart the solver } + catch (std::runtime_error e) { + std::cerr << e.what() << std::endl; + // also catch linear solver not converged + } // (linearIterations < 0 means on convergence in solver) if( linearIterations >= 0 ) From 16624f6f4e19fabfbf6f5d80c78ad52edfc79520 Mon Sep 17 00:00:00 2001 From: Robert Kloefkorn Date: Mon, 20 Oct 2014 12:32:11 +0200 Subject: [PATCH 076/163] address Atgeirs comments. --- .../timestepping/AdaptiveTimeStepping_impl.hpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 0d330dc7c..43900f6d4 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -26,8 +26,9 @@ namespace Opm { std::string control = param.getDefault("timestep.control", std::string("pid") ); const double tol = param.getDefault("timestep.control.tol", double(1e-3) ); - if( control == "pid" ) + if( control == "pid" ) { timeStepControl_ = TimeStepControlType( new PIDTimeStepControl( tol ) ); + } else if ( control == "pid+iteration" ) { const int iterations = param.getDefault("timestep.control.targetiteration", int(25) ); @@ -44,8 +45,9 @@ namespace Opm { const double time, const double timestep ) { // init last time step as a fraction of the given time step - if( last_timestep_ < 0 ) + if( last_timestep_ < 0 ) { last_timestep_ = initial_fraction_ * timestep ; + } // create adaptive step timer with previously used sub step size AdaptiveSimulatorTimer timer( time, time+timestep, last_timestep_ ); @@ -85,7 +87,7 @@ namespace Opm { // also catch linear solver not converged } - // (linearIterations < 0 means on convergence in solver) + // (linearIterations < 0 means no convergence in solver) if( linearIterations >= 0 ) { // advance by current dt @@ -104,7 +106,7 @@ namespace Opm { last_state = state ; last_well_state = well_state; } - else // in case of no convergence + else // in case of no convergence (linearIterations < 0) { // increase restart counter if( restarts >= solver_restart_max_ ) { @@ -135,8 +137,9 @@ namespace Opm { std::cout << "Last suggested step size = " << unit::convert::to( last_timestep_, unit::day ) << " (days)" << std::endl; } - if( ! std::isfinite( last_timestep_ ) ) // check for NaN + if( ! std::isfinite( last_timestep_ ) ) { // check for NaN last_timestep_ = timestep; + } } } From f16f4a2e98f1a8d2bd21373da323a3ceefc0a8a3 Mon Sep 17 00:00:00 2001 From: Robert K Date: Fri, 24 Oct 2014 12:32:00 +0200 Subject: [PATCH 077/163] fix problem with solver reastart, variable was not reset. Also, the time step does only grow moderately after a solver restart. --- .../timestepping/AdaptiveTimeStepping.hpp | 1 + .../timestepping/AdaptiveTimeStepping_impl.hpp | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index 104285501..e73790dbb 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -38,6 +38,7 @@ namespace Opm { TimeStepControlType timeStepControl_; //!< time step control object const double initial_fraction_; //!< fraction to take as a guess for initial time interval const double restart_factor_; //!< factor to multiply time step with when solver fails to converge + const double growth_factor_; //!< factor to multiply time step when solver recovered from failed convergence const int solver_restart_max_; //!< how many restart of solver are allowed const bool solver_verbose_; //!< solver verbosity const bool timestep_verbose_; //!< timestep verbosity diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 43900f6d4..8e1bdda41 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -17,6 +17,7 @@ namespace Opm { : timeStepControl_() , initial_fraction_( param.getDefault("solver.initialfraction", double(0.25) ) ) , restart_factor_( param.getDefault("solver.restartfactor", double(0.1) ) ) + , growth_factor_( param.getDefault("solver.growthfactor", double(1.25) ) ) , solver_restart_max_( param.getDefault("solver.restart", int(3) ) ) , solver_verbose_( param.getDefault("solver.verbose", bool(false) ) ) , timestep_verbose_( param.getDefault("timestep.verbose", bool(false) ) ) @@ -36,6 +37,9 @@ namespace Opm { } else OPM_THROW(std::runtime_error,"Unsupported time step control selected "<< control ); + + // make sure growth factor is something reasonable + assert( growth_factor_ >= 1.0 ); } @@ -78,11 +82,11 @@ namespace Opm { std::cout << "Overall linear iterations used: " << linearIterations << std::endl; } } - catch (Opm::NumericalProblem e) { + catch (const Opm::NumericalProblem& e) { std::cerr << e.what() << std::endl; // since linearIterations is < 0 this will restart the solver } - catch (std::runtime_error e) { + catch (const std::runtime_error& e) { std::cerr << e.what() << std::endl; // also catch linear solver not converged } @@ -94,8 +98,16 @@ namespace Opm { ++timer; // compute new time step estimate - const double dtEstimate = + double dtEstimate = timeStepControl_->computeTimeStepSize( dt, linearIterations, state ); + + // avoid time step size growth + if( restarts > 0 ) { + dtEstimate = std::min( growth_factor_ * dt, dtEstimate ); + // solver converged, reset restarts counter + restarts = 0; + } + if( timestep_verbose_ ) std::cout << "Suggested time step size = " << unit::convert::to(dtEstimate, unit::day) << " (days)" << std::endl; From 1c5e4e9ef3c0da8201c4bf426b4985c4bc7087d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 5 Nov 2014 07:51:21 +0100 Subject: [PATCH 078/163] Suppress unused argument warning. --- opm/simulators/timestepping/TimeStepControlInterface.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/TimeStepControlInterface.hpp b/opm/simulators/timestepping/TimeStepControlInterface.hpp index 67c3d810b..a32e1285d 100644 --- a/opm/simulators/timestepping/TimeStepControlInterface.hpp +++ b/opm/simulators/timestepping/TimeStepControlInterface.hpp @@ -35,7 +35,7 @@ namespace Opm TimeStepControlInterface() {} public: /// \param state simulation state before computing update in the solver (default is empty) - virtual void initialize( const SimulatorState& state ) {} + virtual void initialize( const SimulatorState& /*state*/ ) {} /// compute new time step size suggestions based on the PID controller /// \param dt time step size used in the current step From aa9fe2a63175e5b3f6e24b750552653c6e731bbb Mon Sep 17 00:00:00 2001 From: Robert K Date: Wed, 10 Dec 2014 11:20:29 +0100 Subject: [PATCH 079/163] EclipseWriter: allow for writing of substeps in addition to report steps. --- .../timestepping/AdaptiveTimeStepping.hpp | 53 +++++++++--- .../AdaptiveTimeStepping_impl.hpp | 84 ++++++++++++++----- 2 files changed, 107 insertions(+), 30 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index e73790dbb..0b1af84b9 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -6,33 +6,66 @@ #include #include +#include #include namespace Opm { - // AdaptiveTimeStepping + + // AdaptiveTimeStepping //--------------------- - + class AdaptiveTimeStepping { - public: + public: //! \brief contructor taking parameter object AdaptiveTimeStepping( const parameter::ParameterGroup& param ); /** \brief step method that acts like the solver::step method - in a sub cycle of time steps - + in a sub cycle of time steps + \param solver solver object that must implement a method step( dt, state, well_state ) - \param state current state of the solution variables + \param state current state of the solution variables \param well_state additional well state object \param time current simulation time - \param timestep current time step length that is to be sub cycled - */ + \param timestep current time step length that is to be sub cycled + */ template void step( Solver& solver, State& state, WellState& well_state, const double time, const double timestep ); + /** \brief step method that acts like the solver::step method + in a sub cycle of time steps + + \param timer simulator timer providing time and timestep + \param solver solver object that must implement a method step( dt, state, well_state ) + \param state current state of the solution variables + \param well_state additional well state object + */ + template + void step( const SimulatorTimer& timer, + Solver& solver, State& state, WellState& well_state ); + + /** \brief step method that acts like the solver::step method + in a sub cycle of time steps + + \param timer simulator timer providing time and timestep + \param solver solver object that must implement a method step( dt, state, well_state ) + \param state current state of the solution variables + \param well_state additional well state object + \param outputWriter writer object to write sub steps + */ + template + void step( const SimulatorTimer& timer, + Solver& solver, State& state, WellState& well_state, + OutputWriter& outputWriter ); + protected: + template + void stepImpl( Solver& solver, State& state, WellState& well_state, + const double time, const double timestep, + const SimulatorTimer* timer, OutputWriter* outputWriter); + typedef std::unique_ptr< TimeStepControlInterface > TimeStepControlType; TimeStepControlType timeStepControl_; //!< time step control object @@ -40,8 +73,8 @@ namespace Opm { const double restart_factor_; //!< factor to multiply time step with when solver fails to converge const double growth_factor_; //!< factor to multiply time step when solver recovered from failed convergence const int solver_restart_max_; //!< how many restart of solver are allowed - const bool solver_verbose_; //!< solver verbosity - const bool timestep_verbose_; //!< timestep verbosity + const bool solver_verbose_; //!< solver verbosity + const bool timestep_verbose_; //!< timestep verbosity double last_timestep_; //!< size of last timestep }; } diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 8e1bdda41..4ec083dfa 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -5,15 +5,16 @@ #include #include +#include #include #include namespace Opm { - // AdaptiveTimeStepping + // AdaptiveTimeStepping //--------------------- - - AdaptiveTimeStepping::AdaptiveTimeStepping( const parameter::ParameterGroup& param ) + + AdaptiveTimeStepping::AdaptiveTimeStepping( const parameter::ParameterGroup& param ) : timeStepControl_() , initial_fraction_( param.getDefault("solver.initialfraction", double(0.25) ) ) , restart_factor_( param.getDefault("solver.restartfactor", double(0.1) ) ) @@ -25,17 +26,17 @@ namespace Opm { { // valid are "pid" and "pid+iteration" std::string control = param.getDefault("timestep.control", std::string("pid") ); - + const double tol = param.getDefault("timestep.control.tol", double(1e-3) ); if( control == "pid" ) { timeStepControl_ = TimeStepControlType( new PIDTimeStepControl( tol ) ); } - else if ( control == "pid+iteration" ) + else if ( control == "pid+iteration" ) { const int iterations = param.getDefault("timestep.control.targetiteration", int(25) ); timeStepControl_ = TimeStepControlType( new PIDAndIterationCountTimeStepControl( iterations, tol ) ); } - else + else OPM_THROW(std::runtime_error,"Unsupported time step control selected "<< control ); // make sure growth factor is something reasonable @@ -43,10 +44,44 @@ namespace Opm { } + template + void AdaptiveTimeStepping:: + step( const SimulatorTimer& simulatorTimer, Solver& solver, State& state, WellState& well_state ) + { + const double time = simulatorTimer.simulationTimeElapsed(); + const double timestep = simulatorTimer.currentStepLength(); + + step( solver, state, well_state, time, timestep ); + } + + template + void AdaptiveTimeStepping:: + step( const SimulatorTimer& simulatorTimer, Solver& solver, State& state, WellState& well_state, + OutputWriter& outputWriter ) + { + const double time = simulatorTimer.simulationTimeElapsed(); + const double timestep = simulatorTimer.currentStepLength(); + + stepImpl( solver, state, well_state, time, timestep, &simulatorTimer, &outputWriter ); + } + + // implementation of the step method template void AdaptiveTimeStepping:: step( Solver& solver, State& state, WellState& well_state, const double time, const double timestep ) + { + stepImpl( solver, state, well_state, time, timestep, + (SimulatorTimer *) 0, (OutputWriter *) 0 ); + } + + // implementation of the step method + template + void AdaptiveTimeStepping:: + stepImpl( Solver& solver, State& state, WState& well_state, + const double time, const double timestep, + const SimulatorTimer* simulatorTimer, + OutputWriter* outputWriter ) { // init last time step as a fraction of the given time step if( last_timestep_ < 0 ) { @@ -54,26 +89,26 @@ namespace Opm { } // create adaptive step timer with previously used sub step size - AdaptiveSimulatorTimer timer( time, time+timestep, last_timestep_ ); + AdaptiveSimulatorTimer substepTimer( time, time+timestep, last_timestep_ ); // copy states in case solver has to be restarted (to be revised) - State last_state( state ); - WellState last_well_state( well_state ); + State last_state( state ); + WState last_well_state( well_state ); // counter for solver restarts int restarts = 0; // sub step time loop - while( ! timer.done() ) + while( ! substepTimer.done() ) { // get current delta t - const double dt = timer.currentStepLength() ; + const double dt = substepTimer.currentStepLength() ; // initialize time step control in case current state is needed later timeStepControl_->initialize( state ); int linearIterations = -1; - try { + try { // (linearIterations < 0 means on convergence in solver) linearIterations = solver.step( dt, state, well_state); @@ -95,7 +130,7 @@ namespace Opm { if( linearIterations >= 0 ) { // advance by current dt - ++timer; + ++substepTimer; // compute new time step estimate double dtEstimate = @@ -109,14 +144,23 @@ namespace Opm { } if( timestep_verbose_ ) + { + std::cout << "Substep[ " << substepTimer.currentStepNum() << " ] " << unit::convert::to(substepTimer.simulationTimeElapsed(),unit::day) << std::endl; std::cout << "Suggested time step size = " << unit::convert::to(dtEstimate, unit::day) << " (days)" << std::endl; + } // set new time step length - timer.provideTimeStepEstimate( dtEstimate ); + substepTimer.provideTimeStepEstimate( dtEstimate ); - // update states + // update states last_state = state ; last_well_state = well_state; + + // write data if outputWriter was provided + if( outputWriter ) { + assert( simulatorTimer ); + outputWriter->writeTimeStep( *simulatorTimer, substepTimer, state, well_state ); + } } else // in case of no convergence (linearIterations < 0) { @@ -127,12 +171,12 @@ namespace Opm { const double newTimeStep = restart_factor_ * dt; // we need to revise this - timer.provideTimeStepEstimate( newTimeStep ); - if( solver_verbose_ ) + substepTimer.provideTimeStepEstimate( newTimeStep ); + if( solver_verbose_ ) std::cerr << "Solver convergence failed, restarting solver with new time step (" << unit::convert::to( newTimeStep, unit::day ) <<" days)." << std::endl; - // reset states + // reset states state = last_state; well_state = last_well_state; @@ -142,10 +186,10 @@ namespace Opm { // store last small time step for next reportStep - last_timestep_ = timer.suggestedAverage(); + last_timestep_ = substepTimer.suggestedAverage(); if( timestep_verbose_ ) { - timer.report( std::cout ); + substepTimer.report( std::cout ); std::cout << "Last suggested step size = " << unit::convert::to( last_timestep_, unit::day ) << " (days)" << std::endl; } From be69c4c10e296d028b517dcb2184397c8cccda18 Mon Sep 17 00:00:00 2001 From: Robert K Date: Thu, 8 Jan 2015 12:06:37 +0100 Subject: [PATCH 080/163] Introduce an interface for SimulatorTimer and AdaptiveSimulatorTimer. currentDateTime and currentPosixTime are default implementations. --- .../timestepping/AdaptiveSimulatorTimer.cpp | 28 +++++- .../timestepping/AdaptiveSimulatorTimer.hpp | 23 ++++- .../timestepping/SimulatorTimer.cpp | 12 +-- .../timestepping/SimulatorTimer.hpp | 19 ++-- .../timestepping/SimulatorTimerInterface.hpp | 95 +++++++++++++++++++ 5 files changed, 147 insertions(+), 30 deletions(-) create mode 100644 opm/simulators/timestepping/SimulatorTimerInterface.hpp diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp index 576e4faeb..72add45a0 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp @@ -1,5 +1,5 @@ /* - Copyright 2014 IRIS AS + Copyright (c) 2014 IRIS AS This file is part of the Open Porous Media project (OPM). @@ -30,11 +30,13 @@ namespace Opm { AdaptiveSimulatorTimer:: - AdaptiveSimulatorTimer( const double start_time, const double total_time, const double lastDt ) - : start_time_( start_time ) - , total_time_( total_time ) + AdaptiveSimulatorTimer( const SimulatorTimerInterface& timer, const double lastStepTaken ) + : start_date_( timer.startDate() ) + , start_time_( timer.simulationTimeElapsed() ) + , total_time_( start_time_ + timer.currentStepLength() ) + , report_step_( timer.reportStepNum() ) , current_time_( start_time_ ) - , dt_( computeInitialTimeStep( lastDt ) ) + , dt_( computeInitialTimeStep( lastStepTaken ) ) , current_step_( 0 ) , steps_() , suggestedMax_( 0.0 ) @@ -86,12 +88,23 @@ namespace Opm int AdaptiveSimulatorTimer:: currentStepNum () const { return current_step_; } + int AdaptiveSimulatorTimer:: + reportStepNum () const { return report_step_; } + double AdaptiveSimulatorTimer::currentStepLength () const { assert( ! done () ); return dt_; } + double AdaptiveSimulatorTimer::stepLengthTaken() const + { + assert( ! steps_.empty() ); + return *(steps_.rbegin()); + } + + + double AdaptiveSimulatorTimer::totalTime() const { return total_time_; } double AdaptiveSimulatorTimer::simulationTimeElapsed() const { return current_time_; } @@ -143,6 +156,11 @@ namespace Opm std::cout << "sub steps end time = " << unit::convert::to( simulationTimeElapsed(), unit::day ) << " (days)" << std::endl; } + boost::gregorian::date AdaptiveSimulatorTimer::startDate() const + { + return start_date_; + } + double AdaptiveSimulatorTimer:: computeInitialTimeStep( const double lastDt ) const { diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp index 3336a69cf..9958f4c9e 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp @@ -27,6 +27,8 @@ #include #include +#include + namespace Opm { @@ -35,14 +37,12 @@ namespace Opm /// \brief Simulation timer for adaptive time stepping /// ///////////////////////////////////////////////////////// - class AdaptiveSimulatorTimer + class AdaptiveSimulatorTimer : public SimulatorTimerInterface { public: /// \brief constructor taking a simulator timer to determine start and end time - /// \param start_time start time of timer - /// \param total_time total time of timer - /// \param lastDt last suggested length of time step interval - AdaptiveSimulatorTimer( const double start_time, const double total_time, const double lastDt ); + /// \param timer in case of sub stepping this is the outer timer + explicit AdaptiveSimulatorTimer( const SimulatorTimerInterface& timer, const double lastStepTaken ); /// \brief advance time by currentStepLength AdaptiveSimulatorTimer& operator++ (); @@ -53,6 +53,9 @@ namespace Opm /// \brief \copydoc SimulationTimer::currentStepNum int currentStepNum () const; + /// \brief return current report step + int reportStepNum() const; + /// \brief \copydoc SimulationTimer::currentStepLength double currentStepLength () const; @@ -80,12 +83,22 @@ namespace Opm /// \brief return average suggested step length double suggestedAverage () const; + /// \brief Previous step length. This is the length of the step that + /// was taken to arrive at this time. + double stepLengthTaken () const; + /// \brief report start and end time as well as used steps so far void report(std::ostream& os) const; + /// \brief start date of simulation + boost::gregorian::date startDate() const; + protected: + const boost::gregorian::date start_date_; const double start_time_; const double total_time_; + const int report_step_; + double current_time_; double dt_; int current_step_; diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index add8b7389..a7e368d1e 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -100,19 +100,11 @@ namespace Opm return current_time_; } - /// time elapsed since the start of the POSIX epoch (Jan 1st, 1970) [s]. - time_t SimulatorTimer::currentPosixTime() const + boost::gregorian::date SimulatorTimer::startDate() const { - tm t = boost::posix_time::to_tm(currentDateTime()); - return std::mktime(&t); + return start_date_; } - boost::posix_time::ptime SimulatorTimer::currentDateTime() const - { - return boost::posix_time::ptime(start_date_) + boost::posix_time::seconds( (int) current_time_ ); - } - - /// Total time. double SimulatorTimer::totalTime() const diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index 61faef095..5c9339359 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -21,20 +21,23 @@ #define OPM_SIMULATORTIMER_HEADER_INCLUDED #include +#include #include #include -#include -#include namespace Opm { namespace parameter { class ParameterGroup; } - class SimulatorTimer + class SimulatorTimer : public SimulatorTimerInterface { public: + // use default implementation of these methods + using SimulatorTimerInterface::currentDateTime; + using SimulatorTimerInterface::currentPosixTime; + /// Default constructor. SimulatorTimer(); @@ -72,20 +75,16 @@ namespace Opm /// it is an error to call stepLengthTaken(). double stepLengthTaken () const; - /// Time elapsed since the start of the POSIX epoch (Jan 1st, - /// 1970) until the current time step begins [s]. - time_t currentPosixTime() const; - /// Time elapsed since the start of the simulation until the /// beginning of the current time step [s]. double simulationTimeElapsed() const; - /// Return the current time as a posix time object. - boost::posix_time::ptime currentDateTime() const; - /// Total time. double totalTime() const; + /// Return start date of simulation + boost::gregorian::date startDate() const; + /// Set total time. /// This is primarily intended for multi-epoch schedules, /// where a timer for a given epoch does not have diff --git a/opm/simulators/timestepping/SimulatorTimerInterface.hpp b/opm/simulators/timestepping/SimulatorTimerInterface.hpp new file mode 100644 index 000000000..8028a7f0a --- /dev/null +++ b/opm/simulators/timestepping/SimulatorTimerInterface.hpp @@ -0,0 +1,95 @@ +/* + Copyright (c) 2014 IRIS AS + + This file is part of the Open Porous Media project (OPM). + + OPM 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. + + OPM 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 OPM. If not, see . +*/ + +#ifndef OPM_SIMULATORTIMERINTERFACE_HEADER_INCLUDED +#define OPM_SIMULATORTIMERINTERFACE_HEADER_INCLUDED + +#include +#include +#include + +namespace Opm +{ + + namespace parameter { class ParameterGroup; } + + /// Interface class for SimulatorTimer objects, to be improved. + class SimulatorTimerInterface + { + protected: + /// Default constructor, protected to not allow explicit instances of this class. + SimulatorTimerInterface() {} + + public: + /// Current step number. This is the number of timesteps that + /// has been completed from the start of the run. The time + /// after initialization but before the simulation has started + /// is timestep number zero. + virtual int currentStepNum() const = 0; + + /// Current report step number. This might differ from currentStepNum in case of sub stepping + virtual int reportStepNum() const { return currentStepNum(); } + + /// Current step length. This is the length of the step + /// the simulator will take in the next iteration. + /// + /// @note if done(), it is an error to call currentStepLength(). + virtual double currentStepLength() const = 0; + + /// Previous step length. This is the length of the step that + /// was taken to arrive at this time. + /// + /// @note if no increments have been done (i.e. the timer is + /// still in its constructed state and currentStepNum() == 0), + /// it is an error to call stepLengthTaken(). + virtual double stepLengthTaken () const = 0; + + /// Time elapsed since the start of the simulation until the + /// beginning of the current time step [s]. + virtual double simulationTimeElapsed() const = 0; + + /// Return true if timer indicates that simulation of timer interval is finished + virtual bool done() const = 0; + + /// Return start date of simulation + virtual boost::gregorian::date startDate() const = 0; + + /// Return the current time as a posix time object. + virtual boost::posix_time::ptime currentDateTime() const + { + return boost::posix_time::ptime(startDate()) + boost::posix_time::seconds( (int) simulationTimeElapsed()); + } + + /// Time elapsed since the start of the POSIX epoch (Jan 1st, + /// 1970) until the current time step begins [s]. + virtual time_t currentPosixTime() const + { + tm t = boost::posix_time::to_tm(currentDateTime()); + return std::mktime(&t); + } + + /// Print a report with current and total time etc. + /// Note: if done(), it is an error to call report(). + //virtual void report(std::ostream& os) const = 0; + }; + + +} // namespace Opm + +#endif // OPM_SIMULATORTIMER_HEADER_INCLUDED From 25af9e0033787b368bfcc99029c30eddf9fe8b2a Mon Sep 17 00:00:00 2001 From: Robert K Date: Thu, 8 Jan 2015 12:42:05 +0100 Subject: [PATCH 081/163] - adjust OutputWriter to SimulatorTimerInterface - remove WriterTimer from EclipseWriter and use SimulatorTimerInterface - adjust to the above in AdaptiveTimeStepping. --- .../timestepping/AdaptiveSimulatorTimer.hpp | 1 - .../timestepping/AdaptiveTimeStepping.hpp | 37 +++++++----- .../AdaptiveTimeStepping_impl.hpp | 58 ++++++++++--------- 3 files changed, 52 insertions(+), 44 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp index 9958f4c9e..d82dda413 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp @@ -16,7 +16,6 @@ You should have received a copy of the GNU General Public License along with OPM. If not, see . */ - #ifndef OPM_ADAPTIVESIMULATORTIMER_HEADER_INCLUDED #define OPM_ADAPTIVESIMULATORTIMER_HEADER_INCLUDED diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index 0b1af84b9..fe5f860a5 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -1,3 +1,21 @@ +/* + Copyright 2014 IRIS AS + + This file is part of the Open Porous Media project (OPM). + + OPM 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. + + OPM 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 OPM. If not, see . +*/ #ifndef OPM_SUBSTEPPING_HEADER_INCLUDED #define OPM_SUBSTEPPING_HEADER_INCLUDED @@ -21,19 +39,6 @@ namespace Opm { //! \brief contructor taking parameter object AdaptiveTimeStepping( const parameter::ParameterGroup& param ); - /** \brief step method that acts like the solver::step method - in a sub cycle of time steps - - \param solver solver object that must implement a method step( dt, state, well_state ) - \param state current state of the solution variables - \param well_state additional well state object - \param time current simulation time - \param timestep current time step length that is to be sub cycled - */ - template - void step( Solver& solver, State& state, WellState& well_state, - const double time, const double timestep ); - /** \brief step method that acts like the solver::step method in a sub cycle of time steps @@ -62,9 +67,9 @@ namespace Opm { protected: template - void stepImpl( Solver& solver, State& state, WellState& well_state, - const double time, const double timestep, - const SimulatorTimer* timer, OutputWriter* outputWriter); + void stepImpl( const SimulatorTimer& timer, + Solver& solver, State& state, WellState& well_state, + OutputWriter* outputWriter); typedef std::unique_ptr< TimeStepControlInterface > TimeStepControlType; diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 4ec083dfa..ace9eafa1 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -1,3 +1,21 @@ +/* + Copyright 2014 IRIS AS + + This file is part of the Open Porous Media project (OPM). + + OPM 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. + + OPM 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 OPM. If not, see . +*/ #ifndef OPM_ADAPTIVETIMESTEPPING_IMPL_HEADER_INCLUDED #define OPM_ADAPTIVETIMESTEPPING_IMPL_HEADER_INCLUDED @@ -48,10 +66,7 @@ namespace Opm { void AdaptiveTimeStepping:: step( const SimulatorTimer& simulatorTimer, Solver& solver, State& state, WellState& well_state ) { - const double time = simulatorTimer.simulationTimeElapsed(); - const double timestep = simulatorTimer.currentStepLength(); - - step( solver, state, well_state, time, timestep ); + stepImpl( simulatorTimer, solver, state, well_state ); } template @@ -59,37 +74,25 @@ namespace Opm { step( const SimulatorTimer& simulatorTimer, Solver& solver, State& state, WellState& well_state, OutputWriter& outputWriter ) { - const double time = simulatorTimer.simulationTimeElapsed(); - const double timestep = simulatorTimer.currentStepLength(); - - stepImpl( solver, state, well_state, time, timestep, &simulatorTimer, &outputWriter ); - } - - // implementation of the step method - template - void AdaptiveTimeStepping:: - step( Solver& solver, State& state, WellState& well_state, - const double time, const double timestep ) - { - stepImpl( solver, state, well_state, time, timestep, - (SimulatorTimer *) 0, (OutputWriter *) 0 ); + stepImpl( simulatorTimer, solver, state, well_state, &outputWriter ); } // implementation of the step method template void AdaptiveTimeStepping:: - stepImpl( Solver& solver, State& state, WState& well_state, - const double time, const double timestep, - const SimulatorTimer* simulatorTimer, + stepImpl( const SimulatorTimer& simulatorTimer, + Solver& solver, State& state, WState& well_state, OutputWriter* outputWriter ) { + const double timestep = simulatorTimer.currentStepLength(); + // init last time step as a fraction of the given time step if( last_timestep_ < 0 ) { - last_timestep_ = initial_fraction_ * timestep ; + last_timestep_ = initial_fraction_ * timestep; } // create adaptive step timer with previously used sub step size - AdaptiveSimulatorTimer substepTimer( time, time+timestep, last_timestep_ ); + AdaptiveSimulatorTimer substepTimer( simulatorTimer, last_timestep_ ); // copy states in case solver has to be restarted (to be revised) State last_state( state ); @@ -145,8 +148,10 @@ namespace Opm { if( timestep_verbose_ ) { - std::cout << "Substep[ " << substepTimer.currentStepNum() << " ] " << unit::convert::to(substepTimer.simulationTimeElapsed(),unit::day) << std::endl; - std::cout << "Suggested time step size = " << unit::convert::to(dtEstimate, unit::day) << " (days)" << std::endl; + std::cout << std::endl + <<"Substep( " << substepTimer.currentStepNum() + << " ): Current time (days) " << unit::convert::to(substepTimer.simulationTimeElapsed(),unit::day) << std::endl + << " Current stepsize est (days) " << unit::convert::to(dtEstimate, unit::day) << std::endl; } // set new time step length @@ -158,8 +163,7 @@ namespace Opm { // write data if outputWriter was provided if( outputWriter ) { - assert( simulatorTimer ); - outputWriter->writeTimeStep( *simulatorTimer, substepTimer, state, well_state ); + outputWriter->writeTimeStep( substepTimer, state, well_state ); } } else // in case of no convergence (linearIterations < 0) From 757bc67b80989224ac0bbaed5419f0a204c4dc67 Mon Sep 17 00:00:00 2001 From: Robert K Date: Fri, 9 Jan 2015 15:10:56 +0100 Subject: [PATCH 082/163] cleanup: reportStepIdx --> writeStepIdx. startDate --> startDateTime removal of debug output. --- .../timestepping/AdaptiveSimulatorTimer.cpp | 6 +++--- .../timestepping/AdaptiveSimulatorTimer.hpp | 6 +++--- .../AdaptiveTimeStepping_impl.hpp | 11 +++++----- .../timestepping/SimulatorTimer.cpp | 4 ++-- .../timestepping/SimulatorTimer.hpp | 2 +- .../timestepping/SimulatorTimerInterface.hpp | 20 +++++++++++++------ 6 files changed, 29 insertions(+), 20 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp index 72add45a0..46a077786 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp @@ -31,7 +31,7 @@ namespace Opm { AdaptiveSimulatorTimer:: AdaptiveSimulatorTimer( const SimulatorTimerInterface& timer, const double lastStepTaken ) - : start_date_( timer.startDate() ) + : start_date_time_( timer.startDateTime() ) , start_time_( timer.simulationTimeElapsed() ) , total_time_( start_time_ + timer.currentStepLength() ) , report_step_( timer.reportStepNum() ) @@ -156,9 +156,9 @@ namespace Opm std::cout << "sub steps end time = " << unit::convert::to( simulationTimeElapsed(), unit::day ) << " (days)" << std::endl; } - boost::gregorian::date AdaptiveSimulatorTimer::startDate() const + boost::posix_time::ptime AdaptiveSimulatorTimer::startDateTime() const { - return start_date_; + return start_date_time_; } double AdaptiveSimulatorTimer:: diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp index d82dda413..c2082619e 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp @@ -89,11 +89,11 @@ namespace Opm /// \brief report start and end time as well as used steps so far void report(std::ostream& os) const; - /// \brief start date of simulation - boost::gregorian::date startDate() const; + /// \brief start date time of simulation + boost::posix_time::ptime startDateTime() const; protected: - const boost::gregorian::date start_date_; + const boost::posix_time::ptime start_date_time_; const double start_time_; const double total_time_; const int report_step_; diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index ace9eafa1..b1d5ed719 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -151,7 +151,12 @@ namespace Opm { std::cout << std::endl <<"Substep( " << substepTimer.currentStepNum() << " ): Current time (days) " << unit::convert::to(substepTimer.simulationTimeElapsed(),unit::day) << std::endl - << " Current stepsize est (days) " << unit::convert::to(dtEstimate, unit::day) << std::endl; + << " Current stepsize est (days) " << unit::convert::to(dtEstimate, unit::day) << std::endl; + } + + // write data if outputWriter was provided + if( outputWriter ) { + outputWriter->writeTimeStep( substepTimer, state, well_state ); } // set new time step length @@ -161,10 +166,6 @@ namespace Opm { last_state = state ; last_well_state = well_state; - // write data if outputWriter was provided - if( outputWriter ) { - outputWriter->writeTimeStep( substepTimer, state, well_state ); - } } else // in case of no convergence (linearIterations < 0) { diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index a7e368d1e..757857519 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -100,9 +100,9 @@ namespace Opm return current_time_; } - boost::gregorian::date SimulatorTimer::startDate() const + boost::posix_time::ptime SimulatorTimer::startDateTime() const { - return start_date_; + return boost::posix_time::ptime(start_date_); } diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index 5c9339359..8f9e7b0b0 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -83,7 +83,7 @@ namespace Opm double totalTime() const; /// Return start date of simulation - boost::gregorian::date startDate() const; + boost::posix_time::ptime startDateTime() const; /// Set total time. /// This is primarily intended for multi-epoch schedules, diff --git a/opm/simulators/timestepping/SimulatorTimerInterface.hpp b/opm/simulators/timestepping/SimulatorTimerInterface.hpp index 8028a7f0a..25118fd21 100644 --- a/opm/simulators/timestepping/SimulatorTimerInterface.hpp +++ b/opm/simulators/timestepping/SimulatorTimerInterface.hpp @@ -37,6 +37,9 @@ namespace Opm SimulatorTimerInterface() {} public: + /// destructor + virtual ~SimulatorTimerInterface() {} + /// Current step number. This is the number of timesteps that /// has been completed from the start of the run. The time /// after initialization but before the simulation has started @@ -60,6 +63,14 @@ namespace Opm /// it is an error to call stepLengthTaken(). virtual double stepLengthTaken () const = 0; + /// Previous report step length. This is the length of the step that + /// was taken to arrive at this report step time. + /// + /// @note if no increments have been done (i.e. the timer is + /// still in its constructed state and reportStepNum() == 0), + /// it is an error to call stepLengthTaken(). + virtual double reportStepLengthTaken () const { return stepLengthTaken(); } + /// Time elapsed since the start of the simulation until the /// beginning of the current time step [s]. virtual double simulationTimeElapsed() const = 0; @@ -68,12 +79,13 @@ namespace Opm virtual bool done() const = 0; /// Return start date of simulation - virtual boost::gregorian::date startDate() const = 0; + virtual boost::posix_time::ptime startDateTime() const = 0; /// Return the current time as a posix time object. virtual boost::posix_time::ptime currentDateTime() const { - return boost::posix_time::ptime(startDate()) + boost::posix_time::seconds( (int) simulationTimeElapsed()); + return startDateTime() + boost::posix_time::seconds( (int) simulationTimeElapsed()); + //boost::posix_time::ptime(startDate()) + boost::posix_time::seconds( (int) simulationTimeElapsed()); } /// Time elapsed since the start of the POSIX epoch (Jan 1st, @@ -83,10 +95,6 @@ namespace Opm tm t = boost::posix_time::to_tm(currentDateTime()); return std::mktime(&t); } - - /// Print a report with current and total time etc. - /// Note: if done(), it is an error to call report(). - //virtual void report(std::ostream& os) const = 0; }; From aa66a4304f6e95af9879f61ae34c47162ed3a483 Mon Sep 17 00:00:00 2001 From: Robert K Date: Thu, 15 Jan 2015 11:34:59 +0100 Subject: [PATCH 083/163] EclipseWriter: remove leftovers of WriterTimer. AdaptiveSimulatorTimer: use back instead of rbegin. --- opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp index 46a077786..83716dfef 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp @@ -100,7 +100,7 @@ namespace Opm double AdaptiveSimulatorTimer::stepLengthTaken() const { assert( ! steps_.empty() ); - return *(steps_.rbegin()); + return steps_.back(); } From 04e8533ceef4d515ef889e8aecc130e14e14c0b0 Mon Sep 17 00:00:00 2001 From: Robert K Date: Fri, 16 Jan 2015 14:56:37 +0100 Subject: [PATCH 084/163] AdaptiveSimulatorTimer: initialization of first time step size follows the same rule as for later steps. PIDTimeStepControl: added maxgrowth factor which indicates the maximum allow groth of the time step from one to the next value. --- .../timestepping/AdaptiveSimulatorTimer.cpp | 17 ++++------------- .../timestepping/AdaptiveSimulatorTimer.hpp | 2 -- .../timestepping/AdaptiveTimeStepping_impl.hpp | 7 ++++--- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp index 83716dfef..7e5c200e3 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp @@ -36,7 +36,7 @@ namespace Opm , total_time_( start_time_ + timer.currentStepLength() ) , report_step_( timer.reportStepNum() ) , current_time_( start_time_ ) - , dt_( computeInitialTimeStep( lastStepTaken ) ) + , dt_( 0.0 ) , current_step_( 0 ) , steps_() , suggestedMax_( 0.0 ) @@ -44,6 +44,9 @@ namespace Opm { // reserve memory for sub steps steps_.reserve( 10 ); + + // set appropriate value for dt_ + provideTimeStepEstimate( lastStepTaken ); } AdaptiveSimulatorTimer& AdaptiveSimulatorTimer::operator++ () @@ -161,16 +164,4 @@ namespace Opm return start_date_time_; } - double AdaptiveSimulatorTimer:: - computeInitialTimeStep( const double lastDt ) const - { - const double maxTimeStep = total_time_ - start_time_; - const double fraction = (lastDt / maxTimeStep); - // when lastDt and maxTimeStep are close together, choose the max time step - if( fraction > 0.95 ) return maxTimeStep; - - // otherwise choose lastDt - return std::min( lastDt, maxTimeStep ); - } - } // namespace Opm diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp index c2082619e..cd6c56b64 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp @@ -105,8 +105,6 @@ namespace Opm std::vector< double > steps_; double suggestedMax_; double suggestedAverage_; - - double computeInitialTimeStep( const double lastDt ) const; }; } // namespace Opm diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index b1d5ed719..52148783f 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -51,8 +51,9 @@ namespace Opm { } else if ( control == "pid+iteration" ) { - const int iterations = param.getDefault("timestep.control.targetiteration", int(25) ); - timeStepControl_ = TimeStepControlType( new PIDAndIterationCountTimeStepControl( iterations, tol ) ); + const int iterations = param.getDefault("timestep.control.targetiteration", int(25) ); + const double maxgrowth = param.getDefault("timestep.control.maxgrowth", double(3.0) ); + timeStepControl_ = TimeStepControlType( new PIDAndIterationCountTimeStepControl( iterations, tol, maxgrowth ) ); } else OPM_THROW(std::runtime_error,"Unsupported time step control selected "<< control ); @@ -150,7 +151,7 @@ namespace Opm { { std::cout << std::endl <<"Substep( " << substepTimer.currentStepNum() - << " ): Current time (days) " << unit::convert::to(substepTimer.simulationTimeElapsed(),unit::day) << std::endl + << " ): Current time (days) " << unit::convert::to(substepTimer.simulationTimeElapsed(),unit::day) << std::endl << " Current stepsize est (days) " << unit::convert::to(dtEstimate, unit::day) << std::endl; } From 15c2e91730b42c3393d0615c49d88cb3d4be0559 Mon Sep 17 00:00:00 2001 From: Robert K Date: Fri, 16 Jan 2015 15:36:11 +0100 Subject: [PATCH 085/163] AdaptiveTimeStepping: Switch suggested time step to max of the previous taken substeps. --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 52148783f..04123304f 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -191,12 +191,12 @@ namespace Opm { } - // store last small time step for next reportStep - last_timestep_ = substepTimer.suggestedAverage(); + // store max of the small time step for next reportStep + last_timestep_ = substepTimer.maxStepLength(); if( timestep_verbose_ ) { substepTimer.report( std::cout ); - std::cout << "Last suggested step size = " << unit::convert::to( last_timestep_, unit::day ) << " (days)" << std::endl; + std::cout << "Suggested next step size = " << unit::convert::to( last_timestep_, unit::day ) << " (days)" << std::endl; } if( ! std::isfinite( last_timestep_ ) ) { // check for NaN From ae683efcfc4ba8e10369704ae25044bca264ac69 Mon Sep 17 00:00:00 2001 From: Robert K Date: Fri, 16 Jan 2015 16:02:18 +0100 Subject: [PATCH 086/163] AdaptiveTimeStepping: make output more easy to read. --- .../timestepping/AdaptiveTimeStepping_impl.hpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 04123304f..c77ec1d87 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -111,6 +111,12 @@ namespace Opm { // initialize time step control in case current state is needed later timeStepControl_->initialize( state ); + if( timestep_verbose_ ) + { + std::cout <<"Substep( " << substepTimer.currentStepNum() << " ), try with stepsize " + << unit::convert::to(substepTimer.currentStepLength(), unit::day) << " (days)." << std::endl; + } + int linearIterations = -1; try { // (linearIterations < 0 means on convergence in solver) @@ -149,10 +155,8 @@ namespace Opm { if( timestep_verbose_ ) { - std::cout << std::endl - <<"Substep( " << substepTimer.currentStepNum() - << " ): Current time (days) " << unit::convert::to(substepTimer.simulationTimeElapsed(),unit::day) << std::endl - << " Current stepsize est (days) " << unit::convert::to(dtEstimate, unit::day) << std::endl; + std::cout << "Substep( " << substepTimer.currentStepNum()-1 // it was already advanced by ++ + << " ) finished at time " << unit::convert::to(substepTimer.simulationTimeElapsed(),unit::day) << " (days)." << std::endl << std::endl; } // write data if outputWriter was provided From f771becf25e8b695388de2261b95ad40084f6097 Mon Sep 17 00:00:00 2001 From: Robert K Date: Wed, 28 Jan 2015 15:25:11 +0100 Subject: [PATCH 087/163] SimulatorTimer...: added method advance which is the new interface for previously used operator++. --- opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp | 3 +++ opm/simulators/timestepping/SimulatorTimer.hpp | 3 +++ opm/simulators/timestepping/SimulatorTimerInterface.hpp | 3 +++ 3 files changed, 9 insertions(+) diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp index cd6c56b64..870fffd8f 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp @@ -46,6 +46,9 @@ namespace Opm /// \brief advance time by currentStepLength AdaptiveSimulatorTimer& operator++ (); + /// \brief advance time by currentStepLength + void advance() { this->operator++ (); } + /// \brief provide and estimate for new time step size void provideTimeStepEstimate( const double dt_estimate ); diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index 8f9e7b0b0..19208ffd7 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -98,6 +98,9 @@ namespace Opm /// Next step. SimulatorTimer& operator++(); + /// Next step. + void advance() { this->operator++(); } + /// Return true if op++() has been called numSteps() times. bool done() const; diff --git a/opm/simulators/timestepping/SimulatorTimerInterface.hpp b/opm/simulators/timestepping/SimulatorTimerInterface.hpp index 25118fd21..6852fc571 100644 --- a/opm/simulators/timestepping/SimulatorTimerInterface.hpp +++ b/opm/simulators/timestepping/SimulatorTimerInterface.hpp @@ -75,6 +75,9 @@ namespace Opm /// beginning of the current time step [s]. virtual double simulationTimeElapsed() const = 0; + /// advance timer to the next time step + virtual void advance() = 0 ; + /// Return true if timer indicates that simulation of timer interval is finished virtual bool done() const = 0; From e84325a0a7c1eba6a792373aa451bc75cfb2022f Mon Sep 17 00:00:00 2001 From: Robert K Date: Wed, 28 Jan 2015 15:46:11 +0100 Subject: [PATCH 088/163] make documentation equal for all three classes. --- opm/simulators/timestepping/SimulatorTimer.hpp | 4 ++-- opm/simulators/timestepping/SimulatorTimerInterface.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index 19208ffd7..1f2e66b26 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -95,10 +95,10 @@ namespace Opm /// Note: if done(), it is an error to call report(). void report(std::ostream& os) const; - /// Next step. + /// advance time by currentStepLength SimulatorTimer& operator++(); - /// Next step. + /// advance time by currentStepLength void advance() { this->operator++(); } /// Return true if op++() has been called numSteps() times. diff --git a/opm/simulators/timestepping/SimulatorTimerInterface.hpp b/opm/simulators/timestepping/SimulatorTimerInterface.hpp index 6852fc571..c3cb9eee4 100644 --- a/opm/simulators/timestepping/SimulatorTimerInterface.hpp +++ b/opm/simulators/timestepping/SimulatorTimerInterface.hpp @@ -75,7 +75,7 @@ namespace Opm /// beginning of the current time step [s]. virtual double simulationTimeElapsed() const = 0; - /// advance timer to the next time step + /// advance time by currentStepLength virtual void advance() = 0 ; /// Return true if timer indicates that simulation of timer interval is finished From 26f113b64968703ea92a34e3610326e33bf17625 Mon Sep 17 00:00:00 2001 From: Robert K Date: Thu, 5 Feb 2015 14:43:43 +0100 Subject: [PATCH 089/163] AdaptiveSimulatorTimer: -improvement in time step adjustment near end of time interval -max time step parameter PIDTimeStepControl --> TimeStepControl: - added simple iteration count time step control - bug fix in PIDAndIterationCountTimeStepControl AdaptiveTimeStepping: apply the above changes. --- .../timestepping/AdaptiveSimulatorTimer.cpp | 38 ++-- .../timestepping/AdaptiveSimulatorTimer.hpp | 17 +- .../timestepping/AdaptiveTimeStepping.hpp | 1 + .../AdaptiveTimeStepping_impl.hpp | 19 +- .../timestepping/TimeStepControl.cpp | 191 ++++++++++++++++++ .../timestepping/TimeStepControl.hpp | 139 +++++++++++++ 6 files changed, 367 insertions(+), 38 deletions(-) create mode 100644 opm/simulators/timestepping/TimeStepControl.cpp create mode 100644 opm/simulators/timestepping/TimeStepControl.hpp diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp index 7e5c200e3..fd906eece 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp @@ -30,17 +30,18 @@ namespace Opm { AdaptiveSimulatorTimer:: - AdaptiveSimulatorTimer( const SimulatorTimerInterface& timer, const double lastStepTaken ) + AdaptiveSimulatorTimer( const SimulatorTimerInterface& timer, + const double lastStepTaken, + const double maxTimeStep ) : start_date_time_( timer.startDateTime() ) , start_time_( timer.simulationTimeElapsed() ) , total_time_( start_time_ + timer.currentStepLength() ) , report_step_( timer.reportStepNum() ) + , max_time_step_( maxTimeStep ) , current_time_( start_time_ ) , dt_( 0.0 ) , current_step_( 0 ) , steps_() - , suggestedMax_( 0.0 ) - , suggestedAverage_( 0.0 ) { // reserve memory for sub steps steps_.reserve( 10 ); @@ -61,31 +62,30 @@ namespace Opm void AdaptiveSimulatorTimer:: provideTimeStepEstimate( const double dt_estimate ) { - // store some information about the time steps suggested - suggestedMax_ = std::max( dt_estimate, suggestedMax_ ); - suggestedAverage_ += dt_estimate; - double remaining = (total_time_ - current_time_); + // apply max time step if it was set + dt_ = std::min( dt_estimate, max_time_step_ ); if( remaining > 0 ) { // set new time step (depending on remaining time) - if( 1.5 * dt_estimate > remaining ) { + if( 1.05 * dt_ > remaining ) { dt_ = remaining; - return ; + // check max time step again and use half remaining if to large + if( dt_ > max_time_step_ ) { + dt_ = 0.5 * remaining; + } + return; } // check for half interval step to avoid very small step at the end // remaining *= 0.5; - if( 2.25 * dt_estimate > remaining ) { + if( 1.5 * dt_ > remaining ) { dt_ = 0.5 * remaining; - return ; + return; } } - - // otherwise set dt_estimate as is - dt_ = dt_estimate; } int AdaptiveSimulatorTimer:: @@ -137,16 +137,6 @@ namespace Opm return *(std::min_element( steps_.begin(), steps_.end() )); } - /// \brief return max suggested step length - double AdaptiveSimulatorTimer::suggestedMax () const { return suggestedMax_; } - - /// \brief return average suggested step length - double AdaptiveSimulatorTimer::suggestedAverage () const - { - const int size = steps_.size(); - return (size > 0 ) ? (suggestedAverage_ / double(size)) : suggestedAverage_; - } - /// \brief report start and end time as well as used steps so far void AdaptiveSimulatorTimer:: report(std::ostream& os) const diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp index 870fffd8f..ac4bb6ed1 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp @@ -40,8 +40,12 @@ namespace Opm { public: /// \brief constructor taking a simulator timer to determine start and end time - /// \param timer in case of sub stepping this is the outer timer - explicit AdaptiveSimulatorTimer( const SimulatorTimerInterface& timer, const double lastStepTaken ); + /// \param timer in case of sub stepping this is the outer timer + /// \param lastStepTaken last suggested time step + /// \param maxTimeStep maximum time step allowed + AdaptiveSimulatorTimer( const SimulatorTimerInterface& timer, + const double lastStepTaken, + const double maxTimeStep = std::numeric_limits::max() ); /// \brief advance time by currentStepLength AdaptiveSimulatorTimer& operator++ (); @@ -79,12 +83,6 @@ namespace Opm /// \brief return min step length used so far double minStepLength () const; - /// \brief return max suggested step length - double suggestedMax () const; - - /// \brief return average suggested step length - double suggestedAverage () const; - /// \brief Previous step length. This is the length of the step that /// was taken to arrive at this time. double stepLengthTaken () const; @@ -100,14 +98,13 @@ namespace Opm const double start_time_; const double total_time_; const int report_step_; + const double max_time_step_; double current_time_; double dt_; int current_step_; std::vector< double > steps_; - double suggestedMax_; - double suggestedAverage_; }; } // namespace Opm diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index fe5f860a5..1cd38c53c 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -77,6 +77,7 @@ namespace Opm { const double initial_fraction_; //!< fraction to take as a guess for initial time interval const double restart_factor_; //!< factor to multiply time step with when solver fails to converge const double growth_factor_; //!< factor to multiply time step when solver recovered from failed convergence + const double max_time_step_; //!< maximal allowed time step size const int solver_restart_max_; //!< how many restart of solver are allowed const bool solver_verbose_; //!< solver verbosity const bool timestep_verbose_; //!< timestep verbosity diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index c77ec1d87..7f467c980 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -25,7 +25,7 @@ #include #include -#include +#include namespace Opm { @@ -37,13 +37,17 @@ namespace Opm { , initial_fraction_( param.getDefault("solver.initialfraction", double(0.25) ) ) , restart_factor_( param.getDefault("solver.restartfactor", double(0.1) ) ) , growth_factor_( param.getDefault("solver.growthfactor", double(1.25) ) ) + // default is 1 year, convert to seconds + , max_time_step_( unit::convert::from(param.getDefault("timestep.max_timestep_in_days", 365.0 ), unit::day) ) , solver_restart_max_( param.getDefault("solver.restart", int(3) ) ) , solver_verbose_( param.getDefault("solver.verbose", bool(false) ) ) , timestep_verbose_( param.getDefault("timestep.verbose", bool(false) ) ) , last_timestep_( -1.0 ) { // valid are "pid" and "pid+iteration" - std::string control = param.getDefault("timestep.control", std::string("pid") ); + std::string control = param.getDefault("timestep.control", std::string("pid+iteration") ); + // iterations is the accumulation of all linear iterations over all newton steops per time step + const int defaultTargetIterations = 30; const double tol = param.getDefault("timestep.control.tol", double(1e-3) ); if( control == "pid" ) { @@ -51,10 +55,17 @@ namespace Opm { } else if ( control == "pid+iteration" ) { - const int iterations = param.getDefault("timestep.control.targetiteration", int(25) ); + const int iterations = param.getDefault("timestep.control.targetiteration", defaultTargetIterations ); const double maxgrowth = param.getDefault("timestep.control.maxgrowth", double(3.0) ); timeStepControl_ = TimeStepControlType( new PIDAndIterationCountTimeStepControl( iterations, tol, maxgrowth ) ); } + else if ( control == "iterationcount" ) + { + const int iterations = param.getDefault("timestep.control.targetiteration", defaultTargetIterations ); + const double decayrate = param.getDefault("timestep.control.decayrate", double(0.75) ); + const double growthrate = param.getDefault("timestep.control.growthrate", double(1.25) ); + timeStepControl_ = TimeStepControlType( new SimpleIterationCountTimeStepControl( iterations, decayrate, growthrate ) ); + } else OPM_THROW(std::runtime_error,"Unsupported time step control selected "<< control ); @@ -93,7 +104,7 @@ namespace Opm { } // create adaptive step timer with previously used sub step size - AdaptiveSimulatorTimer substepTimer( simulatorTimer, last_timestep_ ); + AdaptiveSimulatorTimer substepTimer( simulatorTimer, last_timestep_, max_time_step_ ); // copy states in case solver has to be restarted (to be revised) State last_state( state ); diff --git a/opm/simulators/timestepping/TimeStepControl.cpp b/opm/simulators/timestepping/TimeStepControl.cpp new file mode 100644 index 000000000..98114eb2f --- /dev/null +++ b/opm/simulators/timestepping/TimeStepControl.cpp @@ -0,0 +1,191 @@ +/* + Copyright 2014 IRIS AS + + This file is part of the Open Porous Media project (OPM). + + OPM 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. + + OPM 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 OPM. If not, see . +*/ + +#include +#include +#include +#include + +#include +#include +#include + +namespace Opm +{ + //////////////////////////////////////////////////////// + // + // InterationCountTimeStepControl Implementation + // + //////////////////////////////////////////////////////// + + SimpleIterationCountTimeStepControl:: + SimpleIterationCountTimeStepControl( const int target_iterations, + const double decayrate, + const double growthrate, + const bool verbose) + : target_iterations_( target_iterations ) + , decayrate_( decayrate ) + , growthrate_( growthrate ) + , verbose_( verbose ) + { + if( decayrate_ > 1.0 ) { + OPM_THROW(std::runtime_error,"SimpleIterationCountTimeStepControl: decay should be <= 1 " << decayrate_ ); + } + if( growthrate_ < 1.0 ) { + OPM_THROW(std::runtime_error,"SimpleIterationCountTimeStepControl: growth should be >= 1 " << growthrate_ ); + } + } + + double SimpleIterationCountTimeStepControl:: + computeTimeStepSize( const double dt, const int iterations, const SimulatorState& state ) const + { + double dtEstimate = dt ; + + // reduce the time step size if we exceed the number of target iterations + if( iterations > target_iterations_ ) + { + // scale dtEstimate down with a given rate + dtEstimate *= decayrate_; + } + // increase the time step size if we are below the number of target iterations + else if ( iterations < target_iterations_-1 ) + { + dtEstimate *= growthrate_; + } + + return dtEstimate; + } + + + + //////////////////////////////////////////////////////// + // + // PIDTimeStepControl Implementation + // + //////////////////////////////////////////////////////// + + PIDTimeStepControl::PIDTimeStepControl( const double tol, const bool verbose ) + : p0_() + , sat0_() + , tol_( tol ) + , errors_( 3, tol_ ) + , verbose_( verbose ) + {} + + void PIDTimeStepControl::initialize( const SimulatorState& state ) + { + // store current state for later time step computation + p0_ = state.pressure(); + sat0_ = state.saturation(); + } + + double PIDTimeStepControl:: + computeTimeStepSize( const double dt, const int /* iterations */, const SimulatorState& state ) const + { + const std::size_t pSize = p0_.size(); + assert( state.pressure().size() == pSize ); + const std::size_t satSize = sat0_.size(); + assert( state.saturation().size() == satSize ); + + // compute u^n - u^n+1 + for( std::size_t i=0; i tol_ ) + { + // adjust dt by given tolerance + const double newDt = dt * tol_ / error; + if( verbose_ ) + std::cout << "Computed step size (tol): " << unit::convert::to( newDt, unit::day ) << " (days)" << std::endl; + return newDt; + } + else + { + // values taking from turek time stepping paper + const double kP = 0.075 ; + const double kI = 0.175 ; + const double kD = 0.01 ; + const double newDt = (dt * std::pow( errors_[ 1 ] / errors_[ 2 ], kP ) * + std::pow( tol_ / errors_[ 2 ], kI ) * + std::pow( errors_[0]*errors_[0]/errors_[ 1 ]/errors_[ 2 ], kD )); + if( verbose_ ) + std::cout << "Computed step size (pow): " << unit::convert::to( newDt, unit::day ) << " (days)" << std::endl; + return newDt; + } + } + + + + //////////////////////////////////////////////////////////// + // + // PIDAndIterationCountTimeStepControl Implementation + // + //////////////////////////////////////////////////////////// + + PIDAndIterationCountTimeStepControl:: + PIDAndIterationCountTimeStepControl( const int target_iterations, + const double tol, + const double maxgrowth, + const bool verbose) + : BaseType( tol, verbose ) + , target_iterations_( target_iterations ) + , maxgrowth_( maxgrowth ) + {} + + double PIDAndIterationCountTimeStepControl:: + computeTimeStepSize( const double dt, const int iterations, const SimulatorState& state ) const + { + double dtEstimate = BaseType :: computeTimeStepSize( dt, iterations, state ); + + // further reduce step size if to many iterations were used + if( iterations > target_iterations_ ) + { + // if iterations was the same or dts were the same, do some magic + dtEstimate *= double( target_iterations_ ) / double(iterations); + } + + // limit the growth of the timestep size by the growth factor + dtEstimate = std::min( dtEstimate, double(maxgrowth_ * dt) ); + + return dtEstimate; + } + +} // end namespace Opm diff --git a/opm/simulators/timestepping/TimeStepControl.hpp b/opm/simulators/timestepping/TimeStepControl.hpp new file mode 100644 index 000000000..ed8f13690 --- /dev/null +++ b/opm/simulators/timestepping/TimeStepControl.hpp @@ -0,0 +1,139 @@ +/* + Copyright 2014 IRIS AS + + This file is part of the Open Porous Media project (OPM). + + OPM 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. + + OPM 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 OPM. If not, see . +*/ +#ifndef OPM_TIMESTEPCONTROL_HEADER_INCLUDED +#define OPM_TIMESTEPCONTROL_HEADER_INCLUDED + +#include + +#include + +namespace Opm +{ + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// + /// A simple iteration count based adaptive time step control. + // + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + class SimpleIterationCountTimeStepControl : public TimeStepControlInterface + { + public: + /// \brief constructor + /// \param target_iterations number of desired iterations (e.g. Newton iterations) per time step in one time step + // \param decayrate decayrate of time step when target iterations are not met (should be <= 1) + // \param growthrate growthrate of time step when target iterations are not met (should be >= 1) + /// \param verbose if true get some output (default = false) + SimpleIterationCountTimeStepControl( const int target_iterations, + const double decayrate, + const double growthrate, + const bool verbose = false); + + /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize + double computeTimeStepSize( const double dt, const int iterations, const SimulatorState& state ) const; + + protected: + const int target_iterations_; + const double decayrate_; + const double growthrate_; + const bool verbose_; + }; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// + /// PID controller based adaptive time step control as suggested in: + /// Turek and Kuzmin. Algebraic Flux Correction III. Incompressible Flow Problems. Uni Dortmund. + /// + /// See also: + /// D. Kuzmin and S.Turek. Numerical simulation of turbulent bubbly flows. Techreport Uni Dortmund. 2004 + /// + /// and the original article: + /// Valli, Coutinho, and Carey. Adaptive Control for Time Step Selection in Finite Element + /// Simulation of Coupled Viscous Flow and Heat Transfer. Proc of the 10th + /// International Conference on Numerical Methods in Fluids. 1998. + /// + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + class PIDTimeStepControl : public TimeStepControlInterface + { + public: + /// \brief constructor + /// \param tol tolerance for the relative changes of the numerical solution to be accepted + /// in one time step (default is 1e-3) + /// \param verbose if true get some output (default = false) + PIDTimeStepControl( const double tol = 1e-3, const bool verbose = false ); + + /// \brief \copydoc TimeStepControlInterface::initialize + void initialize( const SimulatorState& state ); + + /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize + double computeTimeStepSize( const double dt, const int /* iterations */, const SimulatorState& state ) const; + + protected: + // return inner product for given container, here std::vector + template + double euclidianNormSquared( Iterator it, const Iterator end ) const + { + double product = 0.0 ; + for( ; it != end; ++it ) { + product += ( *it * *it ); + } + return product; + } + + protected: + mutable std::vector p0_; + mutable std::vector sat0_; + + const double tol_; + mutable std::vector< double > errors_; + + const bool verbose_; + }; + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// + /// PID controller based adaptive time step control as above that also takes + /// an target iteration into account. + // + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + class PIDAndIterationCountTimeStepControl : public PIDTimeStepControl + { + typedef PIDTimeStepControl BaseType; + public: + /// \brief constructor + /// \param target_iterations number of desired iterations per time step + /// \param tol tolerance for the relative changes of the numerical solution to be accepted + /// in one time step (default is 1e-3) + // \param maxgrowth max growth factor for new time step in relation of old time step (default = 3.0) + /// \param verbose if true get some output (default = false) + PIDAndIterationCountTimeStepControl( const int target_iterations = 20, + const double tol = 1e-3, + const double maxgrowth = 3.0, + const bool verbose = false); + + /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize + double computeTimeStepSize( const double dt, const int iterations, const SimulatorState& state ) const; + + protected: + const int target_iterations_; + const double maxgrowth_; + }; + + +} // end namespace Opm +#endif + From 4a885989dd0fe456a0f0468941b8a4f81acc191e Mon Sep 17 00:00:00 2001 From: Robert K Date: Tue, 10 Feb 2015 13:10:39 +0100 Subject: [PATCH 090/163] AdaptiveTimeStepping: remove initial_fraction (use restart factor instead) and use average of previously used time steps to suggest next time step. --- opm/simulators/timestepping/AdaptiveTimeStepping.hpp | 1 - opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 8 +++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index 1cd38c53c..8fc1d1d66 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -74,7 +74,6 @@ namespace Opm { typedef std::unique_ptr< TimeStepControlInterface > TimeStepControlType; TimeStepControlType timeStepControl_; //!< time step control object - const double initial_fraction_; //!< fraction to take as a guess for initial time interval const double restart_factor_; //!< factor to multiply time step with when solver fails to converge const double growth_factor_; //!< factor to multiply time step when solver recovered from failed convergence const double max_time_step_; //!< maximal allowed time step size diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 7f467c980..fcf595c81 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -34,7 +34,6 @@ namespace Opm { AdaptiveTimeStepping::AdaptiveTimeStepping( const parameter::ParameterGroup& param ) : timeStepControl_() - , initial_fraction_( param.getDefault("solver.initialfraction", double(0.25) ) ) , restart_factor_( param.getDefault("solver.restartfactor", double(0.1) ) ) , growth_factor_( param.getDefault("solver.growthfactor", double(1.25) ) ) // default is 1 year, convert to seconds @@ -100,9 +99,12 @@ namespace Opm { // init last time step as a fraction of the given time step if( last_timestep_ < 0 ) { - last_timestep_ = initial_fraction_ * timestep; + last_timestep_ = restart_factor_ * timestep; } + // TODO + // take change in well state into account + // create adaptive step timer with previously used sub step size AdaptiveSimulatorTimer substepTimer( simulatorTimer, last_timestep_, max_time_step_ ); @@ -207,7 +209,7 @@ namespace Opm { // store max of the small time step for next reportStep - last_timestep_ = substepTimer.maxStepLength(); + last_timestep_ = substepTimer.averageStepLength(); if( timestep_verbose_ ) { substepTimer.report( std::cout ); From 4cc0f7ef6de8a47c80950f16109865a7d2aaa0f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 17 Feb 2015 10:27:44 +0100 Subject: [PATCH 091/163] Suppress unused argument warning. --- opm/simulators/timestepping/TimeStepControl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/TimeStepControl.cpp b/opm/simulators/timestepping/TimeStepControl.cpp index 98114eb2f..b233002a7 100644 --- a/opm/simulators/timestepping/TimeStepControl.cpp +++ b/opm/simulators/timestepping/TimeStepControl.cpp @@ -53,7 +53,7 @@ namespace Opm } double SimpleIterationCountTimeStepControl:: - computeTimeStepSize( const double dt, const int iterations, const SimulatorState& state ) const + computeTimeStepSize( const double dt, const int iterations, const SimulatorState& /* state */ ) const { double dtEstimate = dt ; From 7f6008a80ebcc0d2e4e78163a23352a6ba4a57cb Mon Sep 17 00:00:00 2001 From: Robert Kloefkorn Date: Tue, 10 Mar 2015 12:47:38 +0100 Subject: [PATCH 092/163] AdaptiveTimeStepping: also catch ISTLError casued in AMG when time step is to large. --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index fcf595c81..12f9b8472 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -148,6 +148,10 @@ namespace Opm { std::cerr << e.what() << std::endl; // also catch linear solver not converged } + catch (const Dune::ISTLError& e) { + std::cerr << e.what() << std::endl; + // also catch errors in ISTL AMG that occur when time step is too large + } // (linearIterations < 0 means no convergence in solver) if( linearIterations >= 0 ) From 9272f2d8bf80cf2dc19cde44fd8a01a4e26520ca Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Fri, 10 Apr 2015 14:03:27 +0200 Subject: [PATCH 093/163] Add dune/istl/istlexception.hh to header Fix to make it compile with dune-istl 2.2 --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 12f9b8472..545bf0ddf 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -26,6 +26,7 @@ #include #include #include +#include namespace Opm { From 2dc02043e2a3582ba62f63c04ea81af0810b1018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Tue, 21 Apr 2015 11:41:45 +0200 Subject: [PATCH 094/163] Modify default parameters to be suitable for the Norne case. --- .../timestepping/AdaptiveTimeStepping_impl.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 545bf0ddf..63ee7ffc3 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -35,28 +35,28 @@ namespace Opm { AdaptiveTimeStepping::AdaptiveTimeStepping( const parameter::ParameterGroup& param ) : timeStepControl_() - , restart_factor_( param.getDefault("solver.restartfactor", double(0.1) ) ) + , restart_factor_( param.getDefault("solver.restartfactor", double(0.3) ) ) , growth_factor_( param.getDefault("solver.growthfactor", double(1.25) ) ) // default is 1 year, convert to seconds , max_time_step_( unit::convert::from(param.getDefault("timestep.max_timestep_in_days", 365.0 ), unit::day) ) - , solver_restart_max_( param.getDefault("solver.restart", int(3) ) ) - , solver_verbose_( param.getDefault("solver.verbose", bool(false) ) ) - , timestep_verbose_( param.getDefault("timestep.verbose", bool(false) ) ) + , solver_restart_max_( param.getDefault("solver.restart", int(10) ) ) + , solver_verbose_( param.getDefault("solver.verbose", bool(true) ) ) + , timestep_verbose_( param.getDefault("timestep.verbose", bool(true) ) ) , last_timestep_( -1.0 ) { // valid are "pid" and "pid+iteration" std::string control = param.getDefault("timestep.control", std::string("pid+iteration") ); // iterations is the accumulation of all linear iterations over all newton steops per time step - const int defaultTargetIterations = 30; + const int defaultTargetIterations = 8; - const double tol = param.getDefault("timestep.control.tol", double(1e-3) ); + const double tol = param.getDefault("timestep.control.tol", double(4e-5) ); if( control == "pid" ) { timeStepControl_ = TimeStepControlType( new PIDTimeStepControl( tol ) ); } else if ( control == "pid+iteration" ) { const int iterations = param.getDefault("timestep.control.targetiteration", defaultTargetIterations ); - const double maxgrowth = param.getDefault("timestep.control.maxgrowth", double(3.0) ); + const double maxgrowth = param.getDefault("timestep.control.maxgrowth", double(1.6) ); timeStepControl_ = TimeStepControlType( new PIDAndIterationCountTimeStepControl( iterations, tol, maxgrowth ) ); } else if ( control == "iterationcount" ) From b6d5a3cad50a382426244a8cc86a525a2127479d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 22 Apr 2015 13:03:19 +0200 Subject: [PATCH 095/163] Adjust parameters after testing. --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 63ee7ffc3..560193e60 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -35,7 +35,7 @@ namespace Opm { AdaptiveTimeStepping::AdaptiveTimeStepping( const parameter::ParameterGroup& param ) : timeStepControl_() - , restart_factor_( param.getDefault("solver.restartfactor", double(0.3) ) ) + , restart_factor_( param.getDefault("solver.restartfactor", double(0.1) ) ) , growth_factor_( param.getDefault("solver.growthfactor", double(1.25) ) ) // default is 1 year, convert to seconds , max_time_step_( unit::convert::from(param.getDefault("timestep.max_timestep_in_days", 365.0 ), unit::day) ) @@ -47,16 +47,16 @@ namespace Opm { // valid are "pid" and "pid+iteration" std::string control = param.getDefault("timestep.control", std::string("pid+iteration") ); // iterations is the accumulation of all linear iterations over all newton steops per time step - const int defaultTargetIterations = 8; + const int defaultTargetIterations = 30; - const double tol = param.getDefault("timestep.control.tol", double(4e-5) ); + const double tol = param.getDefault("timestep.control.tol", double(1e-3) ); if( control == "pid" ) { timeStepControl_ = TimeStepControlType( new PIDTimeStepControl( tol ) ); } else if ( control == "pid+iteration" ) { const int iterations = param.getDefault("timestep.control.targetiteration", defaultTargetIterations ); - const double maxgrowth = param.getDefault("timestep.control.maxgrowth", double(1.6) ); + const double maxgrowth = param.getDefault("timestep.control.maxgrowth", double(3.0) ); timeStepControl_ = TimeStepControlType( new PIDAndIterationCountTimeStepControl( iterations, tol, maxgrowth ) ); } else if ( control == "iterationcount" ) From 384ef845568937f942abf946fc82e3173c63266c Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Fri, 22 May 2015 20:51:59 +0200 Subject: [PATCH 096/163] Makes the time step control parallel. The only stage where parallelism changes the adaptive time stepping is when some inner products on the saturation and pressure are computed. This commit makes this part parallel by added an additonal boost::any parameter to the time stepping and the controller. Per default this is empty. In a parallel run it contains a ParallelIstlInformation object encapsulating the information about the parallelisation. This then used to compute the parallel inner product. --- .../timestepping/AdaptiveTimeStepping.hpp | 6 ++- .../AdaptiveTimeStepping_impl.hpp | 7 +-- .../timestepping/TimeStepControl.cpp | 15 ++++-- .../timestepping/TimeStepControl.hpp | 49 ++++++++++++++++--- 4 files changed, 61 insertions(+), 16 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index 8fc1d1d66..e1f6f80d4 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -37,7 +37,11 @@ namespace Opm { { public: //! \brief contructor taking parameter object - AdaptiveTimeStepping( const parameter::ParameterGroup& param ); + //! \param param The parameter object + //! \param pinfo The information about the data distribution + //! and communication for a parallel run. + AdaptiveTimeStepping( const parameter::ParameterGroup& param, + const boost::any& pinfo=boost::any() ); /** \brief step method that acts like the solver::step method in a sub cycle of time steps diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 560193e60..4e252e80e 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -33,7 +33,8 @@ namespace Opm { // AdaptiveTimeStepping //--------------------- - AdaptiveTimeStepping::AdaptiveTimeStepping( const parameter::ParameterGroup& param ) + AdaptiveTimeStepping::AdaptiveTimeStepping( const parameter::ParameterGroup& param, + const boost::any& parallel_information ) : timeStepControl_() , restart_factor_( param.getDefault("solver.restartfactor", double(0.1) ) ) , growth_factor_( param.getDefault("solver.growthfactor", double(1.25) ) ) @@ -51,13 +52,13 @@ namespace Opm { const double tol = param.getDefault("timestep.control.tol", double(1e-3) ); if( control == "pid" ) { - timeStepControl_ = TimeStepControlType( new PIDTimeStepControl( tol ) ); + timeStepControl_ = TimeStepControlType( new PIDTimeStepControl( tol, parallel_information ) ); } else if ( control == "pid+iteration" ) { const int iterations = param.getDefault("timestep.control.targetiteration", defaultTargetIterations ); const double maxgrowth = param.getDefault("timestep.control.maxgrowth", double(3.0) ); - timeStepControl_ = TimeStepControlType( new PIDAndIterationCountTimeStepControl( iterations, tol, maxgrowth ) ); + timeStepControl_ = TimeStepControlType( new PIDAndIterationCountTimeStepControl( iterations, tol, maxgrowth, parallel_information ) ); } else if ( control == "iterationcount" ) { diff --git a/opm/simulators/timestepping/TimeStepControl.cpp b/opm/simulators/timestepping/TimeStepControl.cpp index b233002a7..9186e4741 100644 --- a/opm/simulators/timestepping/TimeStepControl.cpp +++ b/opm/simulators/timestepping/TimeStepControl.cpp @@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with OPM. If not, see . */ - +#include #include #include #include @@ -80,12 +80,14 @@ namespace Opm // //////////////////////////////////////////////////////// - PIDTimeStepControl::PIDTimeStepControl( const double tol, const bool verbose ) + PIDTimeStepControl::PIDTimeStepControl( const double tol, const boost::any& pinfo, + const bool verbose ) : p0_() , sat0_() , tol_( tol ) , errors_( 3, tol_ ) , verbose_( verbose ) + , parallel_information_(pinfo) {} void PIDTimeStepControl::initialize( const SimulatorState& state ) @@ -114,11 +116,13 @@ namespace Opm // compute || u^n - u^n+1 || const double stateOld = euclidianNormSquared( p0_.begin(), p0_.end() ) + - euclidianNormSquared( sat0_.begin(), sat0_.end() ); + euclidianNormSquared( sat0_.begin(), sat0_.end(), + state.numPhases() ); // compute || u^n+1 || const double stateNew = euclidianNormSquared( state.pressure().begin(), state.pressure().end() ) + - euclidianNormSquared( state.saturation().begin(), state.saturation().end() ); + euclidianNormSquared( state.saturation().begin(), state.saturation().end(), + state.numPhases() ); // shift errors for( int i=0; i<2; ++i ) { @@ -164,8 +168,9 @@ namespace Opm PIDAndIterationCountTimeStepControl( const int target_iterations, const double tol, const double maxgrowth, + const boost::any& pinfo, const bool verbose) - : BaseType( tol, verbose ) + : BaseType( tol, pinfo, verbose ) , target_iterations_( target_iterations ) , maxgrowth_( maxgrowth ) {} diff --git a/opm/simulators/timestepping/TimeStepControl.hpp b/opm/simulators/timestepping/TimeStepControl.hpp index ed8f13690..4a25ca16c 100644 --- a/opm/simulators/timestepping/TimeStepControl.hpp +++ b/opm/simulators/timestepping/TimeStepControl.hpp @@ -21,7 +21,10 @@ #include +#include +#include #include +#include namespace Opm { @@ -73,8 +76,12 @@ namespace Opm /// \brief constructor /// \param tol tolerance for the relative changes of the numerical solution to be accepted /// in one time step (default is 1e-3) + /// \paramm pinfo The information about the parallel information. Needed to + /// compute parallel scalarproducts. /// \param verbose if true get some output (default = false) - PIDTimeStepControl( const double tol = 1e-3, const bool verbose = false ); + PIDTimeStepControl( const double tol = 1e-3, + const boost::any& pinfo = boost::any(), + const bool verbose = false ); /// \brief \copydoc TimeStepControlInterface::initialize void initialize( const SimulatorState& state ); @@ -83,15 +90,38 @@ namespace Opm double computeTimeStepSize( const double dt, const int /* iterations */, const SimulatorState& state ) const; protected: - // return inner product for given container, here std::vector template - double euclidianNormSquared( Iterator it, const Iterator end ) const + double euclidianNormSquared( Iterator it, const Iterator end, + int num_components=1 ) const { - double product = 0.0 ; - for( ; it != end; ++it ) { - product += ( *it * *it ); +#if HAVE_MPI + if ( parallel_information_.type() == typeid(ParallelISTLInformation) ) + { + const ParallelISTLInformation& info = + boost::any_cast(parallel_information_); + std::size_t size_per_component = (end - it) / num_components; + assert((end - it) == num_components * size_per_component); + double component_product = 0.0; + for( std::size_t i = 0; i < num_components; ++i ) + { + auto component_container = + boost::make_iterator_range(it + i * size_per_component, + it + (i + 1) * size_per_component); + info.computeReduction(component_container, + Opm::Reduction::makeInnerProductFunctor(), + component_product); + } + return component_product; + } + else +#endif + { + double product = 0.0 ; + for( ; it != end; ++it ) { + product += ( *it * *it ); + } + return product; } - return product; } protected: @@ -102,6 +132,8 @@ namespace Opm mutable std::vector< double > errors_; const bool verbose_; + private: + const boost::any parallel_information_; }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -119,10 +151,13 @@ namespace Opm /// \param tol tolerance for the relative changes of the numerical solution to be accepted /// in one time step (default is 1e-3) // \param maxgrowth max growth factor for new time step in relation of old time step (default = 3.0) + /// \paramm pinfo The information about the parallel information. Needed to + /// compute parallel scalarproducts. /// \param verbose if true get some output (default = false) PIDAndIterationCountTimeStepControl( const int target_iterations = 20, const double tol = 1e-3, const double maxgrowth = 3.0, + const boost::any& = boost::any(), const bool verbose = false); /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize From 845de266ee3258c54eed69b91a8d6c206b67def5 Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Fri, 22 May 2015 20:59:41 +0200 Subject: [PATCH 097/163] Update copyright --- opm/simulators/timestepping/AdaptiveTimeStepping.hpp | 2 ++ opm/simulators/timestepping/TimeStepControl.cpp | 2 ++ opm/simulators/timestepping/TimeStepControl.hpp | 2 ++ 3 files changed, 6 insertions(+) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index e1f6f80d4..c11277121 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -1,5 +1,7 @@ /* Copyright 2014 IRIS AS + Copyright 2015 Dr. Blatt - HPC-Simulation-Software & Services + Copyright 2015 Statoil AS This file is part of the Open Porous Media project (OPM). diff --git a/opm/simulators/timestepping/TimeStepControl.cpp b/opm/simulators/timestepping/TimeStepControl.cpp index 9186e4741..6e223e0a7 100644 --- a/opm/simulators/timestepping/TimeStepControl.cpp +++ b/opm/simulators/timestepping/TimeStepControl.cpp @@ -1,5 +1,7 @@ /* Copyright 2014 IRIS AS + Copyright 2015 Dr. Blatt - HPC-Simulation-Software & Services + Copyright 2015 Statoil AS This file is part of the Open Porous Media project (OPM). diff --git a/opm/simulators/timestepping/TimeStepControl.hpp b/opm/simulators/timestepping/TimeStepControl.hpp index 4a25ca16c..6d92d5f80 100644 --- a/opm/simulators/timestepping/TimeStepControl.hpp +++ b/opm/simulators/timestepping/TimeStepControl.hpp @@ -1,5 +1,7 @@ /* Copyright 2014 IRIS AS + Copyright 2015 Dr. Blatt - HPC-Simulation-Software & Services + Copyright 2015 Statoil AS This file is part of the Open Porous Media project (OPM). From fcd637896c44f8cf9bcff1346ee1c1601005643d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 27 May 2015 11:41:52 +0200 Subject: [PATCH 098/163] Suppress a warning in serial mode. --- opm/simulators/timestepping/TimeStepControl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opm/simulators/timestepping/TimeStepControl.hpp b/opm/simulators/timestepping/TimeStepControl.hpp index 6d92d5f80..b663df6b1 100644 --- a/opm/simulators/timestepping/TimeStepControl.hpp +++ b/opm/simulators/timestepping/TimeStepControl.hpp @@ -93,9 +93,9 @@ namespace Opm protected: template - double euclidianNormSquared( Iterator it, const Iterator end, - int num_components=1 ) const + double euclidianNormSquared( Iterator it, const Iterator end, int num_components = 1 ) const { + static_cast(num_components); // Suppress warning in the serial case. #if HAVE_MPI if ( parallel_information_.type() == typeid(ParallelISTLInformation) ) { From 9f721bbe9a1dd8a9c43711a2fabf63ce03800369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Thu, 28 May 2015 14:05:09 +0200 Subject: [PATCH 099/163] Silence multiple warnings. Also add more warnings to the disabling list of disable_warnings.h. --- opm/simulators/timestepping/TimeStepControl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opm/simulators/timestepping/TimeStepControl.hpp b/opm/simulators/timestepping/TimeStepControl.hpp index b663df6b1..939f27b35 100644 --- a/opm/simulators/timestepping/TimeStepControl.hpp +++ b/opm/simulators/timestepping/TimeStepControl.hpp @@ -101,10 +101,10 @@ namespace Opm { const ParallelISTLInformation& info = boost::any_cast(parallel_information_); - std::size_t size_per_component = (end - it) / num_components; + int size_per_component = (end - it) / num_components; assert((end - it) == num_components * size_per_component); double component_product = 0.0; - for( std::size_t i = 0; i < num_components; ++i ) + for( int i = 0; i < num_components; ++i ) { auto component_container = boost::make_iterator_range(it + i * size_per_component, From d0af851f8ebdb2e84cd9e1d3ef6866e9616d2ef7 Mon Sep 17 00:00:00 2001 From: chflo Date: Mon, 27 Jul 2015 13:25:33 +0200 Subject: [PATCH 100/163] OPM-218: Fix Flow vs Eclipse restart interval write differences: Added new method to SimulatorTimerInterface --- .../timestepping/SimulatorTimerInterface.hpp | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/opm/simulators/timestepping/SimulatorTimerInterface.hpp b/opm/simulators/timestepping/SimulatorTimerInterface.hpp index c3cb9eee4..7386555f5 100644 --- a/opm/simulators/timestepping/SimulatorTimerInterface.hpp +++ b/opm/simulators/timestepping/SimulatorTimerInterface.hpp @@ -75,6 +75,11 @@ namespace Opm /// beginning of the current time step [s]. virtual double simulationTimeElapsed() const = 0; + + /// Time elapsed since the start of the simulation until the + /// beginning of the current time step [s]. + virtual double simulationStartTimeForCurrentReportStep() const { return simulationTimeElapsed(); } + /// advance time by currentStepLength virtual void advance() = 0 ; @@ -91,6 +96,12 @@ namespace Opm //boost::posix_time::ptime(startDate()) + boost::posix_time::seconds( (int) simulationTimeElapsed()); } + /// Return start time for current report step as a posix time object. + virtual boost::posix_time::ptime currentStepStartTime() const + { + return startDateTime() + boost::posix_time::seconds( (int) simulationStartTimeForCurrentReportStep()); + } + /// Time elapsed since the start of the POSIX epoch (Jan 1st, /// 1970) until the current time step begins [s]. virtual time_t currentPosixTime() const @@ -98,6 +109,20 @@ namespace Opm tm t = boost::posix_time::to_tm(currentDateTime()); return std::mktime(&t); } + + /// Time elapsed since the start of the POSIX epoch (Jan 1st, + /// 1970) until the current time step begins [s]. + /// This method might give different results from currentPosixTime() + /// if timer contains supstepping. + /// Override method simulationStartTimeForCurrentReportStep() if timer + /// contains substeps and currentPosixTime() and startOfCurrentStepPosixTime() + /// can differ due to substepping + virtual time_t startOfCurrentStepPosixTime() const + { + tm t = boost::posix_time::to_tm(currentStepStartTime()); + return std::mktime(&t); + } + }; From 84934d0c1f357cc60bd125d145a1bf5ce911a692 Mon Sep 17 00:00:00 2001 From: chflo Date: Mon, 27 Jul 2015 13:26:28 +0200 Subject: [PATCH 101/163] OPM-218: Fix Flow vs Eclipse restart interval write differences: Override method from SimulatorTimerInterface --- opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp | 2 ++ opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp index fd906eece..383880e1f 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp @@ -112,6 +112,8 @@ namespace Opm double AdaptiveSimulatorTimer::simulationTimeElapsed() const { return current_time_; } + double AdaptiveSimulatorTimer::simulationStartTimeForCurrentReportStep() const { return start_time_; } + bool AdaptiveSimulatorTimer::done () const { return (current_time_ >= total_time_) ; } double AdaptiveSimulatorTimer::averageStepLength() const diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp index ac4bb6ed1..e1afebe52 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp @@ -71,6 +71,10 @@ namespace Opm /// \brief \copydoc SimulationTimer::simulationTimeElapsed double simulationTimeElapsed() const; + /// \brief \copydoc SimulationTimer::simulationStartTimeForCurrentReportStep + double simulationStartTimeForCurrentReportStep() const; + + /// \brief \copydoc SimulationTimer::done bool done () const; From bfa1d476e36395a02753fb5662d9fb2ae414a9b0 Mon Sep 17 00:00:00 2001 From: chflo Date: Sun, 2 Aug 2015 22:26:45 +0200 Subject: [PATCH 102/163] OPM-218: Write restart files at same interval as eclipse --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 4e252e80e..950a975b1 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -180,7 +180,8 @@ namespace Opm { // write data if outputWriter was provided if( outputWriter ) { - outputWriter->writeTimeStep( substepTimer, state, well_state ); + bool substep = true; + outputWriter->writeTimeStep( substepTimer, state, well_state, substep); } // set new time step length From b94d5a135d30db71918ef331b8299c0408dc992b Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Mon, 27 Jul 2015 13:07:02 +0200 Subject: [PATCH 103/163] Updated to use ParseMode. --- examples/wells_example.cpp | 6 ++++-- tests/test_timer.cpp | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 88a910413..02fe261ba 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -34,9 +35,10 @@ try simtimer.init(parameters); // Read input file + ParseMode parseMode; Opm::ParserPtr parser(new Opm::Parser()); - Opm::DeckConstPtr deck = parser->parseFile(file_name); - Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck)); + Opm::DeckConstPtr deck = parser->parseFile(file_name , parseMode); + Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck , parseMode)); std::cout << "Done!" << std::endl; // Setup grid diff --git a/tests/test_timer.cpp b/tests/test_timer.cpp index e02d150c3..065cf8f6b 100644 --- a/tests/test_timer.cpp +++ b/tests/test_timer.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -41,7 +42,8 @@ BOOST_AUTO_TEST_CASE(CreateTimer) { const std::string filename1 = "TESTTIMER.DATA"; Opm::ParserPtr parser(new Opm::Parser() ); - Opm::DeckConstPtr parserDeck = parser->parseFile( filename1 ); + Opm::ParseMode parseMode; + Opm::DeckConstPtr parserDeck = parser->parseFile( filename1 , parseMode); Opm::TimeMapPtr timeMap(new Opm::TimeMap(parserDeck)); Opm::SimulatorTimer simtimer; From b3b0b427ab4188896b9769969718f683963f3048 Mon Sep 17 00:00:00 2001 From: chflo Date: Mon, 10 Aug 2015 14:17:59 +0200 Subject: [PATCH 104/163] Reverse changes that should not have been merged into master --- .../timestepping/AdaptiveSimulatorTimer.cpp | 2 -- .../timestepping/AdaptiveSimulatorTimer.hpp | 4 --- .../timestepping/SimulatorTimerInterface.hpp | 25 ------------------- 3 files changed, 31 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp index 383880e1f..fd906eece 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp @@ -112,8 +112,6 @@ namespace Opm double AdaptiveSimulatorTimer::simulationTimeElapsed() const { return current_time_; } - double AdaptiveSimulatorTimer::simulationStartTimeForCurrentReportStep() const { return start_time_; } - bool AdaptiveSimulatorTimer::done () const { return (current_time_ >= total_time_) ; } double AdaptiveSimulatorTimer::averageStepLength() const diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp index e1afebe52..ac4bb6ed1 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp @@ -71,10 +71,6 @@ namespace Opm /// \brief \copydoc SimulationTimer::simulationTimeElapsed double simulationTimeElapsed() const; - /// \brief \copydoc SimulationTimer::simulationStartTimeForCurrentReportStep - double simulationStartTimeForCurrentReportStep() const; - - /// \brief \copydoc SimulationTimer::done bool done () const; diff --git a/opm/simulators/timestepping/SimulatorTimerInterface.hpp b/opm/simulators/timestepping/SimulatorTimerInterface.hpp index 7386555f5..c3cb9eee4 100644 --- a/opm/simulators/timestepping/SimulatorTimerInterface.hpp +++ b/opm/simulators/timestepping/SimulatorTimerInterface.hpp @@ -75,11 +75,6 @@ namespace Opm /// beginning of the current time step [s]. virtual double simulationTimeElapsed() const = 0; - - /// Time elapsed since the start of the simulation until the - /// beginning of the current time step [s]. - virtual double simulationStartTimeForCurrentReportStep() const { return simulationTimeElapsed(); } - /// advance time by currentStepLength virtual void advance() = 0 ; @@ -96,12 +91,6 @@ namespace Opm //boost::posix_time::ptime(startDate()) + boost::posix_time::seconds( (int) simulationTimeElapsed()); } - /// Return start time for current report step as a posix time object. - virtual boost::posix_time::ptime currentStepStartTime() const - { - return startDateTime() + boost::posix_time::seconds( (int) simulationStartTimeForCurrentReportStep()); - } - /// Time elapsed since the start of the POSIX epoch (Jan 1st, /// 1970) until the current time step begins [s]. virtual time_t currentPosixTime() const @@ -109,20 +98,6 @@ namespace Opm tm t = boost::posix_time::to_tm(currentDateTime()); return std::mktime(&t); } - - /// Time elapsed since the start of the POSIX epoch (Jan 1st, - /// 1970) until the current time step begins [s]. - /// This method might give different results from currentPosixTime() - /// if timer contains supstepping. - /// Override method simulationStartTimeForCurrentReportStep() if timer - /// contains substeps and currentPosixTime() and startOfCurrentStepPosixTime() - /// can differ due to substepping - virtual time_t startOfCurrentStepPosixTime() const - { - tm t = boost::posix_time::to_tm(currentStepStartTime()); - return std::mktime(&t); - } - }; From e41b766780f8fca483452fcd44f1fe468371efbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 17 Aug 2015 12:59:31 +0200 Subject: [PATCH 105/163] Catch MatrixBlockError in the adaptive time stepper. This can be thrown by the ILU0 preconditioner when using the interleaved solver approach. --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 950a975b1..f89893140 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -27,6 +27,7 @@ #include #include #include +#include // For MatrixBlockException namespace Opm { @@ -154,6 +155,10 @@ namespace Opm { std::cerr << e.what() << std::endl; // also catch errors in ISTL AMG that occur when time step is too large } + catch (const Dune::MatrixBlockError& e) { + std::cerr << e.what() << std::endl; + // also catch errors in ISTL AMG that occur when time step is too large + } // (linearIterations < 0 means no convergence in solver) if( linearIterations >= 0 ) From 2dfbb4ed8203ebebdd3f523589450acfb3311f54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 17 Aug 2015 13:02:37 +0200 Subject: [PATCH 106/163] Correct comment. --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index f89893140..120bc2859 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -157,7 +157,7 @@ namespace Opm { } catch (const Dune::MatrixBlockError& e) { std::cerr << e.what() << std::endl; - // also catch errors in ISTL AMG that occur when time step is too large + // this can be thrown by ISTL's ILU0 in block mode, yet is not an ISTLError } // (linearIterations < 0 means no convergence in solver) From a7f177e35e92d52a45178491aefe6002b78bae3a Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Mon, 17 Aug 2015 14:58:47 +0200 Subject: [PATCH 107/163] adding command line option full_timestep_initially_ when the option is true, for each report step, the size of the adaptive time step always beginning with the size of the report step. --- opm/simulators/timestepping/AdaptiveTimeStepping.hpp | 1 + opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index c11277121..ce4edfdf1 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -87,6 +87,7 @@ namespace Opm { const bool solver_verbose_; //!< solver verbosity const bool timestep_verbose_; //!< timestep verbosity double last_timestep_; //!< size of last timestep + bool full_timestep_initially_; //!< beginning with the size of the time step from data file }; } diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 120bc2859..3ca9a3c67 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -44,6 +44,7 @@ namespace Opm { , solver_restart_max_( param.getDefault("solver.restart", int(10) ) ) , solver_verbose_( param.getDefault("solver.verbose", bool(true) ) ) , timestep_verbose_( param.getDefault("timestep.verbose", bool(true) ) ) + , full_timestep_initially_( param.getDefault("full_timestep_initially", bool(false) ) ) , last_timestep_( -1.0 ) { // valid are "pid" and "pid+iteration" @@ -105,6 +106,10 @@ namespace Opm { last_timestep_ = restart_factor_ * timestep; } + if (full_timestep_initially_) { + last_timestep_ = timestep; + } + // TODO // take change in well state into account From 42464cbcb7f3f4245493a6232540be61beaabf44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Wed, 19 Aug 2015 11:33:29 +0200 Subject: [PATCH 108/163] Match init order to member order. In a constructor initialisation list, the order should be the same as the order in which the variables actually are initialised, which is given by the order they are declared in the class and not by the order in the initialisation list. --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 3ca9a3c67..2fa6bd995 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -44,8 +44,8 @@ namespace Opm { , solver_restart_max_( param.getDefault("solver.restart", int(10) ) ) , solver_verbose_( param.getDefault("solver.verbose", bool(true) ) ) , timestep_verbose_( param.getDefault("timestep.verbose", bool(true) ) ) - , full_timestep_initially_( param.getDefault("full_timestep_initially", bool(false) ) ) , last_timestep_( -1.0 ) + , full_timestep_initially_( param.getDefault("full_timestep_initially", bool(false) ) ) { // valid are "pid" and "pid+iteration" std::string control = param.getDefault("timestep.control", std::string("pid+iteration") ); From 81b8b631a6c74a0e418b47a91947e1d24b74324d Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Tue, 25 Aug 2015 06:31:55 +0200 Subject: [PATCH 109/163] Use estimated time-step instead of average in next report step --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 2fa6bd995..7dc8a2ceb 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -225,8 +225,8 @@ namespace Opm { } - // store max of the small time step for next reportStep - last_timestep_ = substepTimer.averageStepLength(); + // store estimated time step for next reportStep + last_timestep_ = substepTimer.currentStepLength(); if( timestep_verbose_ ) { substepTimer.report( std::cout ); From 0227165bd535f93205a853a16f4f5bd8f2dfbff4 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Tue, 25 Aug 2015 11:16:36 +0200 Subject: [PATCH 110/163] Rename last_timestep_ to suggested_next_timestep_ --- .../timestepping/AdaptiveTimeStepping.hpp | 2 +- .../timestepping/AdaptiveTimeStepping_impl.hpp | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index ce4edfdf1..cbc587782 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -86,7 +86,7 @@ namespace Opm { const int solver_restart_max_; //!< how many restart of solver are allowed const bool solver_verbose_; //!< solver verbosity const bool timestep_verbose_; //!< timestep verbosity - double last_timestep_; //!< size of last timestep + double suggested_next_timestep_; //!< suggested size of next timestep bool full_timestep_initially_; //!< beginning with the size of the time step from data file }; } diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 7dc8a2ceb..1cd99aca9 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -44,7 +44,7 @@ namespace Opm { , solver_restart_max_( param.getDefault("solver.restart", int(10) ) ) , solver_verbose_( param.getDefault("solver.verbose", bool(true) ) ) , timestep_verbose_( param.getDefault("timestep.verbose", bool(true) ) ) - , last_timestep_( -1.0 ) + , suggested_next_timestep_( -1.0 ) , full_timestep_initially_( param.getDefault("full_timestep_initially", bool(false) ) ) { // valid are "pid" and "pid+iteration" @@ -102,19 +102,19 @@ namespace Opm { const double timestep = simulatorTimer.currentStepLength(); // init last time step as a fraction of the given time step - if( last_timestep_ < 0 ) { - last_timestep_ = restart_factor_ * timestep; + if( suggested_next_timestep_ < 0 ) { + suggested_next_timestep_ = restart_factor_ * timestep; } if (full_timestep_initially_) { - last_timestep_ = timestep; + suggested_next_timestep_ = timestep; } // TODO // take change in well state into account // create adaptive step timer with previously used sub step size - AdaptiveSimulatorTimer substepTimer( simulatorTimer, last_timestep_, max_time_step_ ); + AdaptiveSimulatorTimer substepTimer( simulatorTimer, suggested_next_timestep_, max_time_step_ ); // copy states in case solver has to be restarted (to be revised) State last_state( state ); @@ -226,15 +226,15 @@ namespace Opm { // store estimated time step for next reportStep - last_timestep_ = substepTimer.currentStepLength(); + suggested_next_timestep_ = substepTimer.currentStepLength(); if( timestep_verbose_ ) { substepTimer.report( std::cout ); - std::cout << "Suggested next step size = " << unit::convert::to( last_timestep_, unit::day ) << " (days)" << std::endl; + std::cout << "Suggested next step size = " << unit::convert::to( suggested_next_timestep_, unit::day ) << " (days)" << std::endl; } - if( ! std::isfinite( last_timestep_ ) ) { // check for NaN - last_timestep_ = timestep; + if( ! std::isfinite( suggested_next_timestep_ ) ) { // check for NaN + suggested_next_timestep_ = timestep; } } } From 4c0189f917869a1111471b62e546993303d1ee24 Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Tue, 1 Sep 2015 19:28:56 +0200 Subject: [PATCH 111/163] [bugfix] Allow querying the current time step even if we are done. Previously there was an assertion whether the time stepping is still running when querying the time step. After commit 5af794cfd588b this triggered an assertion for Norne. As there is no reason to limit querying the current time step in this way. This commit simply removes the assertion in AdaptiveSimulatorTimer::currentStepLength. This closes OPM/opm-autodiff#446 --- opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp index fd906eece..9b2737d74 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp @@ -96,7 +96,6 @@ namespace Opm double AdaptiveSimulatorTimer::currentStepLength () const { - assert( ! done () ); return dt_; } From dbce88aa2c5e41b6639a31dbc7a3922d00546b73 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Thu, 3 Sep 2015 12:02:36 +0200 Subject: [PATCH 112/163] Limit the timestep growth for all timestepping algorithm The time step restriction is moved to AdaptiveTimeStepping_impl.hpp to make it apply to all time-stepping algorithms. --- opm/simulators/timestepping/AdaptiveTimeStepping.hpp | 1 + .../timestepping/AdaptiveTimeStepping_impl.hpp | 9 ++++++--- opm/simulators/timestepping/TimeStepControl.cpp | 5 ----- opm/simulators/timestepping/TimeStepControl.hpp | 2 -- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index cbc587782..2ace10f25 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -82,6 +82,7 @@ namespace Opm { TimeStepControlType timeStepControl_; //!< time step control object const double restart_factor_; //!< factor to multiply time step with when solver fails to converge const double growth_factor_; //!< factor to multiply time step when solver recovered from failed convergence + const double max_growth_; //!< factor that limits the maximum growth of a time step const double max_time_step_; //!< maximal allowed time step size const int solver_restart_max_; //!< how many restart of solver are allowed const bool solver_verbose_; //!< solver verbosity diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 1cd99aca9..202cda580 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -39,6 +39,7 @@ namespace Opm { : timeStepControl_() , restart_factor_( param.getDefault("solver.restartfactor", double(0.1) ) ) , growth_factor_( param.getDefault("solver.growthfactor", double(1.25) ) ) + , max_growth_( param.getDefault("timestep.control.maxgrowth", double(3.0) ) ) // default is 1 year, convert to seconds , max_time_step_( unit::convert::from(param.getDefault("timestep.max_timestep_in_days", 365.0 ), unit::day) ) , solver_restart_max_( param.getDefault("solver.restart", int(10) ) ) @@ -59,8 +60,7 @@ namespace Opm { else if ( control == "pid+iteration" ) { const int iterations = param.getDefault("timestep.control.targetiteration", defaultTargetIterations ); - const double maxgrowth = param.getDefault("timestep.control.maxgrowth", double(3.0) ); - timeStepControl_ = TimeStepControlType( new PIDAndIterationCountTimeStepControl( iterations, tol, maxgrowth, parallel_information ) ); + timeStepControl_ = TimeStepControlType( new PIDAndIterationCountTimeStepControl( iterations, tol, parallel_information ) ); } else if ( control == "iterationcount" ) { @@ -175,7 +175,10 @@ namespace Opm { double dtEstimate = timeStepControl_->computeTimeStepSize( dt, linearIterations, state ); - // avoid time step size growth + // limit the growth of the timestep size by the growth factor + dtEstimate = std::min( dtEstimate, double(max_growth_ * dt) ); + + // further restrict time step size growth after convergence problems if( restarts > 0 ) { dtEstimate = std::min( growth_factor_ * dt, dtEstimate ); // solver converged, reset restarts counter diff --git a/opm/simulators/timestepping/TimeStepControl.cpp b/opm/simulators/timestepping/TimeStepControl.cpp index 6e223e0a7..260a12871 100644 --- a/opm/simulators/timestepping/TimeStepControl.cpp +++ b/opm/simulators/timestepping/TimeStepControl.cpp @@ -169,12 +169,10 @@ namespace Opm PIDAndIterationCountTimeStepControl:: PIDAndIterationCountTimeStepControl( const int target_iterations, const double tol, - const double maxgrowth, const boost::any& pinfo, const bool verbose) : BaseType( tol, pinfo, verbose ) , target_iterations_( target_iterations ) - , maxgrowth_( maxgrowth ) {} double PIDAndIterationCountTimeStepControl:: @@ -189,9 +187,6 @@ namespace Opm dtEstimate *= double( target_iterations_ ) / double(iterations); } - // limit the growth of the timestep size by the growth factor - dtEstimate = std::min( dtEstimate, double(maxgrowth_ * dt) ); - return dtEstimate; } diff --git a/opm/simulators/timestepping/TimeStepControl.hpp b/opm/simulators/timestepping/TimeStepControl.hpp index 939f27b35..eee92d5f2 100644 --- a/opm/simulators/timestepping/TimeStepControl.hpp +++ b/opm/simulators/timestepping/TimeStepControl.hpp @@ -158,7 +158,6 @@ namespace Opm /// \param verbose if true get some output (default = false) PIDAndIterationCountTimeStepControl( const int target_iterations = 20, const double tol = 1e-3, - const double maxgrowth = 3.0, const boost::any& = boost::any(), const bool verbose = false); @@ -167,7 +166,6 @@ namespace Opm protected: const int target_iterations_; - const double maxgrowth_; }; From 6d28f190094906937acde4ba1dcd8599d1546f14 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Tue, 8 Sep 2015 10:56:58 +0200 Subject: [PATCH 113/163] Change default values - use time stepping algorithm pid instead of pid + iter Adjusting the time-steps on the number of linear iterations does currently not give any improvents on the time-stepping. - Change the pid tolerance. The time-stepper will take longer time-steps and thus reduce the simulation time significantly. The Norne and the SPE results does not degrade - Less aggressive reduction of time-steps after convergence problems --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 202cda580..eb92fc1ab 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -37,8 +37,8 @@ namespace Opm { AdaptiveTimeStepping::AdaptiveTimeStepping( const parameter::ParameterGroup& param, const boost::any& parallel_information ) : timeStepControl_() - , restart_factor_( param.getDefault("solver.restartfactor", double(0.1) ) ) - , growth_factor_( param.getDefault("solver.growthfactor", double(1.25) ) ) + , restart_factor_( param.getDefault("solver.restartfactor", double(0.33) ) ) + , growth_factor_( param.getDefault("solver.growthfactor", double(2) ) ) , max_growth_( param.getDefault("timestep.control.maxgrowth", double(3.0) ) ) // default is 1 year, convert to seconds , max_time_step_( unit::convert::from(param.getDefault("timestep.max_timestep_in_days", 365.0 ), unit::day) ) @@ -49,11 +49,11 @@ namespace Opm { , full_timestep_initially_( param.getDefault("full_timestep_initially", bool(false) ) ) { // valid are "pid" and "pid+iteration" - std::string control = param.getDefault("timestep.control", std::string("pid+iteration") ); + std::string control = param.getDefault("timestep.control", std::string("pid") ); // iterations is the accumulation of all linear iterations over all newton steops per time step const int defaultTargetIterations = 30; - const double tol = param.getDefault("timestep.control.tol", double(1e-3) ); + const double tol = param.getDefault("timestep.control.tol", double(1e-1) ); if( control == "pid" ) { timeStepControl_ = TimeStepControlType( new PIDTimeStepControl( tol, parallel_information ) ); } From 8c93936fd563bbe697dca461b11d5c35e128c9dd Mon Sep 17 00:00:00 2001 From: Robert Kloefkorn Date: Wed, 16 Sep 2015 14:33:35 +0200 Subject: [PATCH 114/163] AdaptiveTimeStepping: pass variable terminal output to avoid multiple outputs in parallel. --- opm/simulators/timestepping/AdaptiveTimeStepping.hpp | 3 ++- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index 2ace10f25..81c6b4742 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -43,7 +43,8 @@ namespace Opm { //! \param pinfo The information about the data distribution //! and communication for a parallel run. AdaptiveTimeStepping( const parameter::ParameterGroup& param, - const boost::any& pinfo=boost::any() ); + const boost::any& pinfo=boost::any(), + const bool terminal_output = true ); /** \brief step method that acts like the solver::step method in a sub cycle of time steps diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index eb92fc1ab..ae648b21a 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -35,7 +35,8 @@ namespace Opm { //--------------------- AdaptiveTimeStepping::AdaptiveTimeStepping( const parameter::ParameterGroup& param, - const boost::any& parallel_information ) + const boost::any& parallel_information, + const bool terminal_output ) : timeStepControl_() , restart_factor_( param.getDefault("solver.restartfactor", double(0.33) ) ) , growth_factor_( param.getDefault("solver.growthfactor", double(2) ) ) @@ -44,7 +45,7 @@ namespace Opm { , max_time_step_( unit::convert::from(param.getDefault("timestep.max_timestep_in_days", 365.0 ), unit::day) ) , solver_restart_max_( param.getDefault("solver.restart", int(10) ) ) , solver_verbose_( param.getDefault("solver.verbose", bool(true) ) ) - , timestep_verbose_( param.getDefault("timestep.verbose", bool(true) ) ) + , timestep_verbose_( param.getDefault("timestep.verbose", bool(true) ) && terminal_output ) , suggested_next_timestep_( -1.0 ) , full_timestep_initially_( param.getDefault("full_timestep_initially", bool(false) ) ) { From 4f8906c5fc44f36529b00191c18562794008ea28 Mon Sep 17 00:00:00 2001 From: Robert Kloefkorn Date: Wed, 16 Sep 2015 15:19:19 +0200 Subject: [PATCH 115/163] AdaptiveTimeStepping: also apply terminal output to solver_verbose. --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index ae648b21a..0cfe655b3 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -44,7 +44,7 @@ namespace Opm { // default is 1 year, convert to seconds , max_time_step_( unit::convert::from(param.getDefault("timestep.max_timestep_in_days", 365.0 ), unit::day) ) , solver_restart_max_( param.getDefault("solver.restart", int(10) ) ) - , solver_verbose_( param.getDefault("solver.verbose", bool(true) ) ) + , solver_verbose_( param.getDefault("solver.verbose", bool(true) ) && terminal_output ) , timestep_verbose_( param.getDefault("timestep.verbose", bool(true) ) && terminal_output ) , suggested_next_timestep_( -1.0 ) , full_timestep_initially_( param.getDefault("full_timestep_initially", bool(false) ) ) From 2399629ebc33a928177eb0578815108982c4b6fb Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Thu, 8 Oct 2015 11:42:15 +0200 Subject: [PATCH 116/163] use the error macros from opm-common --- opm/simulators/timestepping/AdaptiveTimeStepping.hpp | 2 +- opm/simulators/timestepping/TimeStepControl.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index 81c6b4742..732e4006e 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include diff --git a/opm/simulators/timestepping/TimeStepControl.cpp b/opm/simulators/timestepping/TimeStepControl.cpp index 260a12871..cd0fb73f2 100644 --- a/opm/simulators/timestepping/TimeStepControl.cpp +++ b/opm/simulators/timestepping/TimeStepControl.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include From 005a0c293006d4d6a5afb66dcd8a8f9fc730f1be Mon Sep 17 00:00:00 2001 From: Robert Kloefkorn Date: Sat, 31 Oct 2015 12:42:23 +0100 Subject: [PATCH 117/163] AdaptiveTimeStepping: pass object to compute time error to time step control. This allows us to shift the computation of the error to the physical model. --- .../timestepping/AdaptiveTimeStepping.hpp | 1 - .../AdaptiveTimeStepping_impl.hpp | 39 +++++++++++--- .../timestepping/TimeStepControl.cpp | 53 ++++--------------- .../timestepping/TimeStepControl.hpp | 51 ++---------------- .../timestepping/TimeStepControlInterface.hpp | 38 ++++++++----- 5 files changed, 71 insertions(+), 111 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index 732e4006e..3725ea7c5 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -43,7 +43,6 @@ namespace Opm { //! \param pinfo The information about the data distribution //! and communication for a parallel run. AdaptiveTimeStepping( const parameter::ParameterGroup& param, - const boost::any& pinfo=boost::any(), const bool terminal_output = true ); /** \brief step method that acts like the solver::step method diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 0cfe655b3..354fe9108 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -31,11 +31,35 @@ namespace Opm { + namespace detail + { + template + class SolutionTimeErrorSolverWrapper : public SolutionTimeErrorInterface + { + const Solver& solver_; + const State& previous_; + const State& current_; + public: + SolutionTimeErrorSolverWrapper( const Solver& solver, + const State& previous, + const State& current ) + : solver_( solver ), + previous_( previous ), + current_( current ) + {} + + /// return || u^n+1 - u^n || / || u^n+1 || + double timeError() const + { + return solver_.model().computeTimeError( previous_, current_ ); + } + }; + } + // AdaptiveTimeStepping //--------------------- AdaptiveTimeStepping::AdaptiveTimeStepping( const parameter::ParameterGroup& param, - const boost::any& parallel_information, const bool terminal_output ) : timeStepControl_() , restart_factor_( param.getDefault("solver.restartfactor", double(0.33) ) ) @@ -56,12 +80,12 @@ namespace Opm { const double tol = param.getDefault("timestep.control.tol", double(1e-1) ); if( control == "pid" ) { - timeStepControl_ = TimeStepControlType( new PIDTimeStepControl( tol, parallel_information ) ); + timeStepControl_ = TimeStepControlType( new PIDTimeStepControl( tol ) ); } else if ( control == "pid+iteration" ) { const int iterations = param.getDefault("timestep.control.targetiteration", defaultTargetIterations ); - timeStepControl_ = TimeStepControlType( new PIDAndIterationCountTimeStepControl( iterations, tol, parallel_information ) ); + timeStepControl_ = TimeStepControlType( new PIDAndIterationCountTimeStepControl( iterations, tol ) ); } else if ( control == "iterationcount" ) { @@ -130,9 +154,6 @@ namespace Opm { // get current delta t const double dt = substepTimer.currentStepLength() ; - // initialize time step control in case current state is needed later - timeStepControl_->initialize( state ); - if( timestep_verbose_ ) { std::cout <<"Substep( " << substepTimer.currentStepNum() << " ), try with stepsize " @@ -172,9 +193,13 @@ namespace Opm { // advance by current dt ++substepTimer; + // create object to compute the time error, simply forwards the call to the model + detail::SolutionTimeErrorSolverWrapper< Solver, State > + timeError( solver, last_state, state ); + // compute new time step estimate double dtEstimate = - timeStepControl_->computeTimeStepSize( dt, linearIterations, state ); + timeStepControl_->computeTimeStepSize( dt, linearIterations, timeError ); // limit the growth of the timestep size by the growth factor dtEstimate = std::min( dtEstimate, double(max_growth_ * dt) ); diff --git a/opm/simulators/timestepping/TimeStepControl.cpp b/opm/simulators/timestepping/TimeStepControl.cpp index cd0fb73f2..7ac85d2cd 100644 --- a/opm/simulators/timestepping/TimeStepControl.cpp +++ b/opm/simulators/timestepping/TimeStepControl.cpp @@ -55,7 +55,7 @@ namespace Opm } double SimpleIterationCountTimeStepControl:: - computeTimeStepSize( const double dt, const int iterations, const SimulatorState& /* state */ ) const + computeTimeStepSize( const double dt, const int iterations, const SolutionTimeErrorInterface& /* timeError */ ) const { double dtEstimate = dt ; @@ -82,58 +82,24 @@ namespace Opm // //////////////////////////////////////////////////////// - PIDTimeStepControl::PIDTimeStepControl( const double tol, const boost::any& pinfo, + PIDTimeStepControl::PIDTimeStepControl( const double tol, const bool verbose ) - : p0_() - , sat0_() - , tol_( tol ) + : tol_( tol ) , errors_( 3, tol_ ) , verbose_( verbose ) - , parallel_information_(pinfo) {} - void PIDTimeStepControl::initialize( const SimulatorState& state ) - { - // store current state for later time step computation - p0_ = state.pressure(); - sat0_ = state.saturation(); - } - double PIDTimeStepControl:: - computeTimeStepSize( const double dt, const int /* iterations */, const SimulatorState& state ) const + computeTimeStepSize( const double dt, const int /* iterations */, const SolutionTimeErrorInterface& errorObj ) const { - const std::size_t pSize = p0_.size(); - assert( state.pressure().size() == pSize ); - const std::size_t satSize = sat0_.size(); - assert( state.saturation().size() == satSize ); - - // compute u^n - u^n+1 - for( std::size_t i=0; i tol_ ) { @@ -169,16 +135,15 @@ namespace Opm PIDAndIterationCountTimeStepControl:: PIDAndIterationCountTimeStepControl( const int target_iterations, const double tol, - const boost::any& pinfo, const bool verbose) - : BaseType( tol, pinfo, verbose ) + : BaseType( tol, verbose ) , target_iterations_( target_iterations ) {} double PIDAndIterationCountTimeStepControl:: - computeTimeStepSize( const double dt, const int iterations, const SimulatorState& state ) const + computeTimeStepSize( const double dt, const int iterations, const SolutionTimeErrorInterface& errorObj ) const { - double dtEstimate = BaseType :: computeTimeStepSize( dt, iterations, state ); + double dtEstimate = BaseType :: computeTimeStepSize( dt, iterations, errorObj ); // further reduce step size if to many iterations were used if( iterations > target_iterations_ ) diff --git a/opm/simulators/timestepping/TimeStepControl.hpp b/opm/simulators/timestepping/TimeStepControl.hpp index eee92d5f2..b3ebc3b5c 100644 --- a/opm/simulators/timestepping/TimeStepControl.hpp +++ b/opm/simulators/timestepping/TimeStepControl.hpp @@ -49,7 +49,7 @@ namespace Opm const bool verbose = false); /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize - double computeTimeStepSize( const double dt, const int iterations, const SimulatorState& state ) const; + double computeTimeStepSize( const double dt, const int iterations, const SolutionTimeErrorInterface& /* timeError */ ) const; protected: const int target_iterations_; @@ -82,60 +82,18 @@ namespace Opm /// compute parallel scalarproducts. /// \param verbose if true get some output (default = false) PIDTimeStepControl( const double tol = 1e-3, - const boost::any& pinfo = boost::any(), const bool verbose = false ); - /// \brief \copydoc TimeStepControlInterface::initialize - void initialize( const SimulatorState& state ); - /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize - double computeTimeStepSize( const double dt, const int /* iterations */, const SimulatorState& state ) const; + double computeTimeStepSize( const double dt, const int /* iterations */, const SolutionTimeErrorInterface& timeError ) const; protected: - template - double euclidianNormSquared( Iterator it, const Iterator end, int num_components = 1 ) const - { - static_cast(num_components); // Suppress warning in the serial case. -#if HAVE_MPI - if ( parallel_information_.type() == typeid(ParallelISTLInformation) ) - { - const ParallelISTLInformation& info = - boost::any_cast(parallel_information_); - int size_per_component = (end - it) / num_components; - assert((end - it) == num_components * size_per_component); - double component_product = 0.0; - for( int i = 0; i < num_components; ++i ) - { - auto component_container = - boost::make_iterator_range(it + i * size_per_component, - it + (i + 1) * size_per_component); - info.computeReduction(component_container, - Opm::Reduction::makeInnerProductFunctor(), - component_product); - } - return component_product; - } - else -#endif - { - double product = 0.0 ; - for( ; it != end; ++it ) { - product += ( *it * *it ); - } - return product; - } - } - - protected: - mutable std::vector p0_; - mutable std::vector sat0_; - const double tol_; mutable std::vector< double > errors_; const bool verbose_; private: - const boost::any parallel_information_; + // const boost::any parallel_information_; }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -158,11 +116,10 @@ namespace Opm /// \param verbose if true get some output (default = false) PIDAndIterationCountTimeStepControl( const int target_iterations = 20, const double tol = 1e-3, - const boost::any& = boost::any(), const bool verbose = false); /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize - double computeTimeStepSize( const double dt, const int iterations, const SimulatorState& state ) const; + double computeTimeStepSize( const double dt, const int iterations, const SolutionTimeErrorInterface& timeError ) const; protected: const int target_iterations_; diff --git a/opm/simulators/timestepping/TimeStepControlInterface.hpp b/opm/simulators/timestepping/TimeStepControlInterface.hpp index a32e1285d..0da1637a0 100644 --- a/opm/simulators/timestepping/TimeStepControlInterface.hpp +++ b/opm/simulators/timestepping/TimeStepControlInterface.hpp @@ -1,5 +1,5 @@ /* - Copyright 2014 IRIS AS + Copyright 2014 IRIS AS This file is part of the Open Porous Media project (OPM). @@ -19,31 +19,45 @@ #ifndef OPM_TIMESTEPCONTROLINTERFACE_HEADER_INCLUDED #define OPM_TIMESTEPCONTROLINTERFACE_HEADER_INCLUDED -#include +#include namespace Opm { /////////////////////////////////////////////////////////////////// /// - /// TimeStepControlInterface - /// + /// TimeStepControlInterface + /// /////////////////////////////////////////////////////////////////// - class TimeStepControlInterface + class SolutionTimeErrorInterface { - protected: + protected: + SolutionTimeErrorInterface() {} + public: + /// \return || u^n+1 - u^n || / || u^n+1 || + virtual double timeError() const = 0; + + /// virtual destructor (empty) + virtual ~SolutionTimeErrorInterface () {} + }; + + /////////////////////////////////////////////////////////////////// + /// + /// TimeStepControlInterface + /// + /////////////////////////////////////////////////////////////////// + class TimeStepControlInterface + { + protected: TimeStepControlInterface() {} public: - /// \param state simulation state before computing update in the solver (default is empty) - virtual void initialize( const SimulatorState& /*state*/ ) {} - /// compute new time step size suggestions based on the PID controller /// \param dt time step size used in the current step - /// \param iterations number of iterations used (linear/nonlinear) - /// \param state new solution state + /// \param iterations number of iterations used (linear/nonlinear) + /// \param timeError object to compute || u^n+1 - u^n || / || u^n+1 || /// /// \return suggested time step size for the next step - virtual double computeTimeStepSize( const double dt, const int iterations, const SimulatorState& ) const = 0; + virtual double computeTimeStepSize( const double dt, const int iterations, const SolutionTimeErrorInterface& timeError ) const = 0; /// virtual destructor (empty) virtual ~TimeStepControlInterface () {} From d3af817ff2cf13f91ba8d0bdfa6938b85f4c699d Mon Sep 17 00:00:00 2001 From: Robert Kloefkorn Date: Tue, 10 Nov 2015 09:53:40 -0700 Subject: [PATCH 118/163] timeError --> relativeChange. --- .../timestepping/AdaptiveTimeStepping_impl.hpp | 8 ++++---- opm/simulators/timestepping/TimeStepControl.cpp | 10 +++++----- opm/simulators/timestepping/TimeStepControl.hpp | 14 +++----------- .../timestepping/TimeStepControlInterface.hpp | 12 ++++++------ 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 354fe9108..9a5859005 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -49,9 +49,9 @@ namespace Opm { {} /// return || u^n+1 - u^n || / || u^n+1 || - double timeError() const + double relativeChange() const { - return solver_.model().computeTimeError( previous_, current_ ); + return solver_.model().relativeChange( previous_, current_ ); } }; } @@ -195,11 +195,11 @@ namespace Opm { // create object to compute the time error, simply forwards the call to the model detail::SolutionTimeErrorSolverWrapper< Solver, State > - timeError( solver, last_state, state ); + relativeChange( solver, last_state, state ); // compute new time step estimate double dtEstimate = - timeStepControl_->computeTimeStepSize( dt, linearIterations, timeError ); + timeStepControl_->computeTimeStepSize( dt, linearIterations, relativeChange ); // limit the growth of the timestep size by the growth factor dtEstimate = std::min( dtEstimate, double(max_growth_ * dt) ); diff --git a/opm/simulators/timestepping/TimeStepControl.cpp b/opm/simulators/timestepping/TimeStepControl.cpp index 7ac85d2cd..e7d110434 100644 --- a/opm/simulators/timestepping/TimeStepControl.cpp +++ b/opm/simulators/timestepping/TimeStepControl.cpp @@ -55,7 +55,7 @@ namespace Opm } double SimpleIterationCountTimeStepControl:: - computeTimeStepSize( const double dt, const int iterations, const SolutionTimeErrorInterface& /* timeError */ ) const + computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& /* relativeChange */ ) const { double dtEstimate = dt ; @@ -90,7 +90,7 @@ namespace Opm {} double PIDTimeStepControl:: - computeTimeStepSize( const double dt, const int /* iterations */, const SolutionTimeErrorInterface& errorObj ) const + computeTimeStepSize( const double dt, const int /* iterations */, const RelativeChangeInterface& relChange ) const { // shift errors for( int i=0; i<2; ++i ) { @@ -98,7 +98,7 @@ namespace Opm } // store new error - const double error = errorObj.timeError(); + const double error = relChange.relativeChange(); errors_[ 2 ] = error; if( error > tol_ ) @@ -141,9 +141,9 @@ namespace Opm {} double PIDAndIterationCountTimeStepControl:: - computeTimeStepSize( const double dt, const int iterations, const SolutionTimeErrorInterface& errorObj ) const + computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& relChange ) const { - double dtEstimate = BaseType :: computeTimeStepSize( dt, iterations, errorObj ); + double dtEstimate = BaseType :: computeTimeStepSize( dt, iterations, relChange ); // further reduce step size if to many iterations were used if( iterations > target_iterations_ ) diff --git a/opm/simulators/timestepping/TimeStepControl.hpp b/opm/simulators/timestepping/TimeStepControl.hpp index b3ebc3b5c..ec14ddbef 100644 --- a/opm/simulators/timestepping/TimeStepControl.hpp +++ b/opm/simulators/timestepping/TimeStepControl.hpp @@ -26,7 +26,6 @@ #include #include #include -#include namespace Opm { @@ -49,7 +48,7 @@ namespace Opm const bool verbose = false); /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize - double computeTimeStepSize( const double dt, const int iterations, const SolutionTimeErrorInterface& /* timeError */ ) const; + double computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& /* relativeChange */ ) const; protected: const int target_iterations_; @@ -78,22 +77,18 @@ namespace Opm /// \brief constructor /// \param tol tolerance for the relative changes of the numerical solution to be accepted /// in one time step (default is 1e-3) - /// \paramm pinfo The information about the parallel information. Needed to - /// compute parallel scalarproducts. /// \param verbose if true get some output (default = false) PIDTimeStepControl( const double tol = 1e-3, const bool verbose = false ); /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize - double computeTimeStepSize( const double dt, const int /* iterations */, const SolutionTimeErrorInterface& timeError ) const; + double computeTimeStepSize( const double dt, const int /* iterations */, const RelativeChangeInterface& relativeChange ) const; protected: const double tol_; mutable std::vector< double > errors_; const bool verbose_; - private: - // const boost::any parallel_information_; }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -110,16 +105,13 @@ namespace Opm /// \param target_iterations number of desired iterations per time step /// \param tol tolerance for the relative changes of the numerical solution to be accepted /// in one time step (default is 1e-3) - // \param maxgrowth max growth factor for new time step in relation of old time step (default = 3.0) - /// \paramm pinfo The information about the parallel information. Needed to - /// compute parallel scalarproducts. /// \param verbose if true get some output (default = false) PIDAndIterationCountTimeStepControl( const int target_iterations = 20, const double tol = 1e-3, const bool verbose = false); /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize - double computeTimeStepSize( const double dt, const int iterations, const SolutionTimeErrorInterface& timeError ) const; + double computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& relativeChange ) const; protected: const int target_iterations_; diff --git a/opm/simulators/timestepping/TimeStepControlInterface.hpp b/opm/simulators/timestepping/TimeStepControlInterface.hpp index 0da1637a0..0302def4b 100644 --- a/opm/simulators/timestepping/TimeStepControlInterface.hpp +++ b/opm/simulators/timestepping/TimeStepControlInterface.hpp @@ -26,19 +26,19 @@ namespace Opm /////////////////////////////////////////////////////////////////// /// - /// TimeStepControlInterface + /// RelativeChangeInterface /// /////////////////////////////////////////////////////////////////// - class SolutionTimeErrorInterface + class RelativeChangeInterface { protected: - SolutionTimeErrorInterface() {} + RelativeChangeInterface() {} public: /// \return || u^n+1 - u^n || / || u^n+1 || - virtual double timeError() const = 0; + virtual double relativeChange() const = 0; /// virtual destructor (empty) - virtual ~SolutionTimeErrorInterface () {} + virtual ~RelativeChangeInterface() {} }; /////////////////////////////////////////////////////////////////// @@ -57,7 +57,7 @@ namespace Opm /// \param timeError object to compute || u^n+1 - u^n || / || u^n+1 || /// /// \return suggested time step size for the next step - virtual double computeTimeStepSize( const double dt, const int iterations, const SolutionTimeErrorInterface& timeError ) const = 0; + virtual double computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& relativeChange ) const = 0; /// virtual destructor (empty) virtual ~TimeStepControlInterface () {} From 0de2cff986db6bc93caf0b50a67a57e89632b871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 13 Nov 2015 11:37:53 +0100 Subject: [PATCH 119/163] Follow class renaming. --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 9a5859005..58fe5d007 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -34,7 +34,7 @@ namespace Opm { namespace detail { template - class SolutionTimeErrorSolverWrapper : public SolutionTimeErrorInterface + class SolutionTimeErrorSolverWrapper : public RelativeChangeInterface { const Solver& solver_; const State& previous_; From d43f1097704ef8b107288b741d2fa1e66637e77c Mon Sep 17 00:00:00 2001 From: chflo Date: Thu, 10 Dec 2015 14:47:33 +0100 Subject: [PATCH 120/163] OPM-251: Support for restart --- opm/simulators/timestepping/SimulatorTimer.cpp | 6 ++++-- opm/simulators/timestepping/SimulatorTimer.hpp | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index 757857519..34d58fb03 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -49,14 +49,16 @@ namespace Opm } /// Use the SimulatorTimer as a shim around opm-parser's Opm::TimeMap - void SimulatorTimer::init(Opm::TimeMapConstPtr timeMap) + void SimulatorTimer::init(Opm::TimeMapConstPtr timeMap, bool restart, size_t report_step) { - current_step_ = 0; total_time_ = timeMap->getTotalTime(); timesteps_.resize(timeMap->numTimesteps()); for ( size_t i = 0; i < timeMap->numTimesteps(); ++i ) { timesteps_[i] = timeMap->getTimeStepLength(i); } + + setCurrentStepNum(report_step); + boost::posix_time::ptime start_time = timeMap->getStartTime(0); start_date_ = start_time.date(); } diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index 1f2e66b26..25ca48840 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -47,7 +47,7 @@ namespace Opm void init(const parameter::ParameterGroup& param); /// Use the SimulatorTimer as a shim around opm-parser's Opm::TimeMap - void init(TimeMapConstPtr timeMap); + void init(TimeMapConstPtr timeMap, bool restart = false, size_t report_step = 0); /// Total number of steps. int numSteps() const; From 98190eceb10cee730f720624d840af59cf19fa30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Kvalsvik?= Date: Wed, 20 Jan 2016 14:12:04 +0100 Subject: [PATCH 121/163] Fixes includes wrt opm-parser PR-656 Several files stopped compiling due to relying on opm-parser headers doing includes. From opm-parser PR-656 https://github.com/OPM/opm-parser/pull/656 this assumption is no longer valid. --- tests/test_timer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_timer.cpp b/tests/test_timer.cpp index 065cf8f6b..de78e8fc8 100644 --- a/tests/test_timer.cpp +++ b/tests/test_timer.cpp @@ -27,6 +27,7 @@ #define BOOST_TEST_MODULE OPM-TimerTest #include +#include #include #include From e8c6c3102f5349a3a598ccda782850ac0274e372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Kvalsvik?= Date: Sun, 24 Jan 2016 23:09:47 +0100 Subject: [PATCH 122/163] Improve includes from opm-parser Adopting to opm-parser PR#661, add previously missing includes. https://github.com/OPM/opm-parser/pull/661 --- tests/test_timer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_timer.cpp b/tests/test_timer.cpp index de78e8fc8..4b7552a21 100644 --- a/tests/test_timer.cpp +++ b/tests/test_timer.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include #include From cb41a456873c64865ae7f096b2c3e25a3b5668f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 29 Feb 2016 11:03:08 +0100 Subject: [PATCH 123/163] Remove unused 'restart' parameter from SimulatorTimer::init(). --- opm/simulators/timestepping/SimulatorTimer.cpp | 2 +- opm/simulators/timestepping/SimulatorTimer.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index 34d58fb03..2dc2f295f 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -49,7 +49,7 @@ namespace Opm } /// Use the SimulatorTimer as a shim around opm-parser's Opm::TimeMap - void SimulatorTimer::init(Opm::TimeMapConstPtr timeMap, bool restart, size_t report_step) + void SimulatorTimer::init(Opm::TimeMapConstPtr timeMap, size_t report_step) { total_time_ = timeMap->getTotalTime(); timesteps_.resize(timeMap->numTimesteps()); diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index 25ca48840..12794ebf8 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -47,7 +47,7 @@ namespace Opm void init(const parameter::ParameterGroup& param); /// Use the SimulatorTimer as a shim around opm-parser's Opm::TimeMap - void init(TimeMapConstPtr timeMap, bool restart = false, size_t report_step = 0); + void init(TimeMapConstPtr timeMap, size_t report_step = 0); /// Total number of steps. int numSteps() const; From 8cd08728f751614c94b8c88cf11f8e246b657563 Mon Sep 17 00:00:00 2001 From: Liu Ming Date: Thu, 17 Mar 2016 09:57:59 +0800 Subject: [PATCH 124/163] rename ParseMode as ParseContext. --- examples/wells_example.cpp | 10 +++++----- tests/test_timer.cpp | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 02fe261ba..fbb3db616 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include #include @@ -35,10 +35,10 @@ try simtimer.init(parameters); // Read input file - ParseMode parseMode; + ParseContext parseContext; Opm::ParserPtr parser(new Opm::Parser()); - Opm::DeckConstPtr deck = parser->parseFile(file_name , parseMode); - Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck , parseMode)); + Opm::DeckConstPtr deck = parser->parseFile(file_name , parseContext); + Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck , parseContext)); std::cout << "Done!" << std::endl; // Setup grid @@ -108,7 +108,7 @@ try TwophaseFluid fluid(incomp_properties); - TransportModel model(fluid, *grid->c_grid(), porevol, gravity[2], true); + TransportContextl model(fluid, *grid->c_grid(), porevol, gravity[2], true); TransportSolver tsolver(model); diff --git a/tests/test_timer.cpp b/tests/test_timer.cpp index 4b7552a21..3512ddd69 100644 --- a/tests/test_timer.cpp +++ b/tests/test_timer.cpp @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include @@ -44,8 +44,8 @@ BOOST_AUTO_TEST_CASE(CreateTimer) { const std::string filename1 = "TESTTIMER.DATA"; Opm::ParserPtr parser(new Opm::Parser() ); - Opm::ParseMode parseMode; - Opm::DeckConstPtr parserDeck = parser->parseFile( filename1 , parseMode); + Opm::ParseContext parseContext; + Opm::DeckConstPtr parserDeck = parser->parseFile( filename1 , parseContext); Opm::TimeMapPtr timeMap(new Opm::TimeMap(parserDeck)); Opm::SimulatorTimer simtimer; From f9f13143a2a5d474b624658845416b3f96e4955a Mon Sep 17 00:00:00 2001 From: Robert Kloefkorn Date: Mon, 21 Mar 2016 10:53:54 +0100 Subject: [PATCH 125/163] SimulatorTimers: added method clone to allow for copying of the objects. --- opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp | 9 +++++++++ opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp | 3 +++ opm/simulators/timestepping/SimulatorTimer.cpp | 8 ++++++++ opm/simulators/timestepping/SimulatorTimer.hpp | 3 +++ opm/simulators/timestepping/SimulatorTimerInterface.hpp | 3 +++ 5 files changed, 26 insertions(+) diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp index 9b2737d74..d64d47cea 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp @@ -153,4 +153,13 @@ namespace Opm return start_date_time_; } + /// return copy of object + std::unique_ptr< SimulatorTimerInterface > + AdaptiveSimulatorTimer::clone() const + { + return std::unique_ptr< SimulatorTimerInterface > (new AdaptiveSimulatorTimer( *this )); + } + + + } // namespace Opm diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp index ac4bb6ed1..be93f3047 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp @@ -93,6 +93,9 @@ namespace Opm /// \brief start date time of simulation boost::posix_time::ptime startDateTime() const; + /// return copy of object + virtual std::unique_ptr< SimulatorTimerInterface > clone() const; + protected: const boost::posix_time::ptime start_date_time_; const double start_time_; diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index 2dc2f295f..c5a58749a 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -148,5 +148,13 @@ namespace Opm return int(timesteps_.size()) == current_step_; } + /// return copy of object + std::unique_ptr< SimulatorTimerInterface > + SimulatorTimer::clone() const + { + return std::unique_ptr< SimulatorTimerInterface > (new SimulatorTimer( *this )); + } + + } // namespace Opm diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index 12794ebf8..882f13a19 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -104,6 +104,9 @@ namespace Opm /// Return true if op++() has been called numSteps() times. bool done() const; + /// return copy of object + virtual std::unique_ptr< SimulatorTimerInterface > clone() const; + private: std::vector timesteps_; int current_step_; diff --git a/opm/simulators/timestepping/SimulatorTimerInterface.hpp b/opm/simulators/timestepping/SimulatorTimerInterface.hpp index c3cb9eee4..4a1edbdf4 100644 --- a/opm/simulators/timestepping/SimulatorTimerInterface.hpp +++ b/opm/simulators/timestepping/SimulatorTimerInterface.hpp @@ -98,6 +98,9 @@ namespace Opm tm t = boost::posix_time::to_tm(currentDateTime()); return std::mktime(&t); } + + /// return copy of current timer instance + virtual std::unique_ptr< SimulatorTimerInterface > clone () const = 0; }; From 65d4127f4ecf79678ae7f5263c27c92d71254675 Mon Sep 17 00:00:00 2001 From: Robert Kloefkorn Date: Tue, 29 Mar 2016 10:42:03 +0200 Subject: [PATCH 126/163] SimulatorTimerInterface: include missing header for unique_ptr. --- opm/simulators/timestepping/SimulatorTimerInterface.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/opm/simulators/timestepping/SimulatorTimerInterface.hpp b/opm/simulators/timestepping/SimulatorTimerInterface.hpp index 4a1edbdf4..c9e28471e 100644 --- a/opm/simulators/timestepping/SimulatorTimerInterface.hpp +++ b/opm/simulators/timestepping/SimulatorTimerInterface.hpp @@ -20,6 +20,8 @@ #ifndef OPM_SIMULATORTIMERINTERFACE_HEADER_INCLUDED #define OPM_SIMULATORTIMERINTERFACE_HEADER_INCLUDED +#include + #include #include #include From b42700c6a8c8ab01f1cfce94d8e4408f3326f914 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Thu, 25 Feb 2016 21:47:47 +0100 Subject: [PATCH 127/163] Replaced SimulatorState -> SimulationDatacontainer Have removed the SimulatorState base class, and instead replaced with the SimulationDatacontainer class from opm-common. The SimulatorState objects were typcially created with a default constructor, and then explicitly initialized with a SimulatorState::init() method. For the SimulationDataContainer RAII is employed; the init( ) has been removed - and there is no default constructor. --- examples/wells_example.cpp | 2 +- opm/simulators/timestepping/TimeStepControlInterface.hpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index fbb3db616..6a56893f6 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -76,7 +76,7 @@ try all_cells.push_back(i); } - Opm::TwophaseState state; + Opm::TwophaseState state( grid.c_grid()->number_of_cells , grid.c_grid()->number_of_faces ); initStateFromDeck(*grid.c_grid(), incomp_properties, deck, gravity[2], state); diff --git a/opm/simulators/timestepping/TimeStepControlInterface.hpp b/opm/simulators/timestepping/TimeStepControlInterface.hpp index 0302def4b..2aee5aebe 100644 --- a/opm/simulators/timestepping/TimeStepControlInterface.hpp +++ b/opm/simulators/timestepping/TimeStepControlInterface.hpp @@ -19,7 +19,6 @@ #ifndef OPM_TIMESTEPCONTROLINTERFACE_HEADER_INCLUDED #define OPM_TIMESTEPCONTROLINTERFACE_HEADER_INCLUDED -#include namespace Opm { From 938e6119f4182db717c01b46c6a071fa3137b5de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A5l=20Gr=C3=B8n=C3=A5s=20Drange?= Date: Tue, 19 Apr 2016 17:00:01 +0200 Subject: [PATCH 128/163] Using getInputGrid API from Parser, changed GridManager to no longer accept Deck in constructor --- examples/wells_example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 6a56893f6..5d04b3168 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -42,7 +42,7 @@ try std::cout << "Done!" << std::endl; // Setup grid - GridManager grid(deck); + GridManager grid(eclipseState->getInputGrid()); // Define rock and fluid properties IncompPropertiesFromDeck incomp_properties(deck, eclipseState, *grid.c_grid()); From cabfffe25d56c75469b09ba361c8c7a3070f51c7 Mon Sep 17 00:00:00 2001 From: Liu Ming Date: Mon, 9 May 2016 13:30:28 +0800 Subject: [PATCH 129/163] use ostream not std::cout directly. --- opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp index d64d47cea..c730c80ac 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp @@ -145,7 +145,7 @@ namespace Opm { os << " step[ " << i << " ] = " << unit::convert::to( steps_[ i ], unit::day ) << " (days)" << std::endl; } - std::cout << "sub steps end time = " << unit::convert::to( simulationTimeElapsed(), unit::day ) << " (days)" << std::endl; + os << "sub steps end time = " << unit::convert::to( simulationTimeElapsed(), unit::day ) << " (days)" << std::endl; } boost::posix_time::ptime AdaptiveSimulatorTimer::startDateTime() const From 40dbcc496a508576d034e82e7a5c72679cd8e6c8 Mon Sep 17 00:00:00 2001 From: Liu Ming Date: Mon, 9 May 2016 13:31:04 +0800 Subject: [PATCH 130/163] output timer messages for terminal and log file. --- .../timestepping/AdaptiveTimeStepping_impl.hpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 58fe5d007..a255bec0c 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include // For MatrixBlockException @@ -149,15 +150,15 @@ namespace Opm { int restarts = 0; // sub step time loop + std::ostringstream ss; while( ! substepTimer.done() ) { // get current delta t const double dt = substepTimer.currentStepLength() ; - if( timestep_verbose_ ) { - std::cout <<"Substep( " << substepTimer.currentStepNum() << " ), try with stepsize " - << unit::convert::to(substepTimer.currentStepLength(), unit::day) << " (days)." << std::endl; + ss <<"Substep( " << substepTimer.currentStepNum() << " ), try with stepsize " + << unit::convert::to(substepTimer.currentStepLength(), unit::day) << " (days)." << std::endl; } int linearIterations = -1; @@ -167,7 +168,7 @@ namespace Opm { if( solver_verbose_ ) { // report number of linear iterations - std::cout << "Overall linear iterations used: " << linearIterations << std::endl; + ss << "Overall linear iterations used: " << linearIterations << std::endl; } } catch (const Opm::NumericalProblem& e) { @@ -213,7 +214,7 @@ namespace Opm { if( timestep_verbose_ ) { - std::cout << "Substep( " << substepTimer.currentStepNum()-1 // it was already advanced by ++ + ss << "Substep( " << substepTimer.currentStepNum()-1 // it was already advanced by ++ << " ) finished at time " << unit::convert::to(substepTimer.simulationTimeElapsed(),unit::day) << " (days)." << std::endl << std::endl; } @@ -258,13 +259,15 @@ namespace Opm { suggested_next_timestep_ = substepTimer.currentStepLength(); if( timestep_verbose_ ) { - substepTimer.report( std::cout ); - std::cout << "Suggested next step size = " << unit::convert::to( suggested_next_timestep_, unit::day ) << " (days)" << std::endl; + substepTimer.report(ss); + ss << "Suggested next step size = " << unit::convert::to( suggested_next_timestep_, unit::day ) << " (days)" << std::endl; } if( ! std::isfinite( suggested_next_timestep_ ) ) { // check for NaN suggested_next_timestep_ = timestep; } + std::cout << ss.str(); + OpmLog::info(ss.str()); } } From a4dc1350455011727aff4682ec71eb417411dc2d Mon Sep 17 00:00:00 2001 From: Liu Ming Date: Tue, 10 May 2016 14:13:33 +0800 Subject: [PATCH 131/163] use OpmLog only for error messages. --- .../timestepping/AdaptiveTimeStepping_impl.hpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index a255bec0c..7018bbcc5 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -150,15 +150,16 @@ namespace Opm { int restarts = 0; // sub step time loop - std::ostringstream ss; while( ! substepTimer.done() ) { // get current delta t const double dt = substepTimer.currentStepLength() ; if( timestep_verbose_ ) { + std::ostringstream ss; ss <<"Substep( " << substepTimer.currentStepNum() << " ), try with stepsize " << unit::convert::to(substepTimer.currentStepLength(), unit::day) << " (days)." << std::endl; + OpmLog::info(ss.str()); } int linearIterations = -1; @@ -168,7 +169,7 @@ namespace Opm { if( solver_verbose_ ) { // report number of linear iterations - ss << "Overall linear iterations used: " << linearIterations << std::endl; + OpmLog::info("Overall linear iterations used: " + std::to_string(linearIterations)); } } catch (const Opm::NumericalProblem& e) { @@ -214,8 +215,10 @@ namespace Opm { if( timestep_verbose_ ) { + std::ostringstream ss; ss << "Substep( " << substepTimer.currentStepNum()-1 // it was already advanced by ++ << " ) finished at time " << unit::convert::to(substepTimer.simulationTimeElapsed(),unit::day) << " (days)." << std::endl << std::endl; + OpmLog::info(ss.str()); } // write data if outputWriter was provided @@ -243,8 +246,10 @@ namespace Opm { // we need to revise this substepTimer.provideTimeStepEstimate( newTimeStep ); if( solver_verbose_ ) - std::cerr << "Solver convergence failed, restarting solver with new time step (" - << unit::convert::to( newTimeStep, unit::day ) <<" days)." << std::endl; + std::string msg; + msg = "Solver convergence failed, restarting solver with new time step (" + + std::to_string(unit::convert::to( newTimeStep, unit::day )) + " days).\n"; + OpmLog::error(msg); // reset states state = last_state; @@ -259,15 +264,15 @@ namespace Opm { suggested_next_timestep_ = substepTimer.currentStepLength(); if( timestep_verbose_ ) { + std::ostringstream ss; substepTimer.report(ss); ss << "Suggested next step size = " << unit::convert::to( suggested_next_timestep_, unit::day ) << " (days)" << std::endl; + OpmLog::info(ss.str()); } if( ! std::isfinite( suggested_next_timestep_ ) ) { // check for NaN suggested_next_timestep_ = timestep; } - std::cout << ss.str(); - OpmLog::info(ss.str()); } } From 248ea780b3c61a7a3d0cc476dfa17fdc0be3dedd Mon Sep 17 00:00:00 2001 From: Liu Ming Date: Mon, 16 May 2016 09:04:54 +0800 Subject: [PATCH 132/163] add missing braces. --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 7018bbcc5..679296045 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -245,12 +245,12 @@ namespace Opm { const double newTimeStep = restart_factor_ * dt; // we need to revise this substepTimer.provideTimeStepEstimate( newTimeStep ); - if( solver_verbose_ ) + if( solver_verbose_ ) { std::string msg; msg = "Solver convergence failed, restarting solver with new time step (" + std::to_string(unit::convert::to( newTimeStep, unit::day )) + " days).\n"; OpmLog::error(msg); - + } // reset states state = last_state; well_state = last_well_state; From 18fda2d7f0190934ea5e1ebb8fcebca3c9f6b785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Kvalsvik?= Date: Fri, 20 May 2016 16:21:14 +0200 Subject: [PATCH 133/163] WellState::report() to make opm-output Well data --- opm/simulators/timestepping/AdaptiveTimeStepping.hpp | 8 ++++---- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index 3725ea7c5..d722f9cfd 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -66,16 +66,16 @@ namespace Opm { \param well_state additional well state object \param outputWriter writer object to write sub steps */ - template + template void step( const SimulatorTimer& timer, Solver& solver, State& state, WellState& well_state, - OutputWriter& outputWriter ); + Output& outputWriter ); protected: - template + template void stepImpl( const SimulatorTimer& timer, Solver& solver, State& state, WellState& well_state, - OutputWriter* outputWriter); + Output* outputWriter); typedef std::unique_ptr< TimeStepControlInterface > TimeStepControlType; diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 679296045..c4d074579 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -110,20 +110,20 @@ namespace Opm { stepImpl( simulatorTimer, solver, state, well_state ); } - template + template void AdaptiveTimeStepping:: step( const SimulatorTimer& simulatorTimer, Solver& solver, State& state, WellState& well_state, - OutputWriter& outputWriter ) + Output& outputWriter ) { stepImpl( simulatorTimer, solver, state, well_state, &outputWriter ); } // implementation of the step method - template + template void AdaptiveTimeStepping:: stepImpl( const SimulatorTimer& simulatorTimer, Solver& solver, State& state, WState& well_state, - OutputWriter* outputWriter ) + Output* outputWriter ) { const double timestep = simulatorTimer.currentStepLength(); From 63f244a36d8427bb295e0529a226b2f924da2ec4 Mon Sep 17 00:00:00 2001 From: Liu Ming Date: Tue, 21 Jun 2016 08:44:32 +0800 Subject: [PATCH 134/163] mark time stepping messages type as OpmLog::note --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index c4d074579..8ddc28a22 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -159,7 +159,7 @@ namespace Opm { std::ostringstream ss; ss <<"Substep( " << substepTimer.currentStepNum() << " ), try with stepsize " << unit::convert::to(substepTimer.currentStepLength(), unit::day) << " (days)." << std::endl; - OpmLog::info(ss.str()); + OpmLog::note(ss.str()); } int linearIterations = -1; @@ -169,7 +169,7 @@ namespace Opm { if( solver_verbose_ ) { // report number of linear iterations - OpmLog::info("Overall linear iterations used: " + std::to_string(linearIterations)); + OpmLog::note("Overall linear iterations used: " + std::to_string(linearIterations)); } } catch (const Opm::NumericalProblem& e) { @@ -218,7 +218,7 @@ namespace Opm { std::ostringstream ss; ss << "Substep( " << substepTimer.currentStepNum()-1 // it was already advanced by ++ << " ) finished at time " << unit::convert::to(substepTimer.simulationTimeElapsed(),unit::day) << " (days)." << std::endl << std::endl; - OpmLog::info(ss.str()); + OpmLog::note(ss.str()); } // write data if outputWriter was provided @@ -267,7 +267,7 @@ namespace Opm { std::ostringstream ss; substepTimer.report(ss); ss << "Suggested next step size = " << unit::convert::to( suggested_next_timestep_, unit::day ) << " (days)" << std::endl; - OpmLog::info(ss.str()); + OpmLog::note(ss.str()); } if( ! std::isfinite( suggested_next_timestep_ ) ) { // check for NaN From 6097a14b0e9f0a73cb95d3c8e71364a7622af709 Mon Sep 17 00:00:00 2001 From: Liu Ming Date: Tue, 21 Jun 2016 11:25:05 +0800 Subject: [PATCH 135/163] get current date time. --- opm/simulators/timestepping/SimulatorTimer.cpp | 5 +++++ opm/simulators/timestepping/SimulatorTimer.hpp | 3 +++ 2 files changed, 8 insertions(+) diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index c5a58749a..66e8e2ffe 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -108,6 +108,11 @@ namespace Opm } + boost::posix_time::ptime SimulatorTimer::currentDateTime() const + { + return startDateTime() + boost::posix_time::seconds( (int) simulationTimeElapsed()); + } + /// Total time. double SimulatorTimer::totalTime() const { diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index 882f13a19..4db760930 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -85,6 +85,9 @@ namespace Opm /// Return start date of simulation boost::posix_time::ptime startDateTime() const; + /// Return current date. + boost::posix_time::ptime currentDateTime() const; + /// Set total time. /// This is primarily intended for multi-epoch schedules, /// where a timer for a given epoch does not have From b1b464535ad93cde3c814119292feb6cb0dd0f0d Mon Sep 17 00:00:00 2001 From: Liu Ming Date: Tue, 28 Jun 2016 13:40:32 +0800 Subject: [PATCH 136/163] output well iterations and non-linear iterations. --- .../timestepping/AdaptiveTimeStepping_impl.hpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 8ddc28a22..ba8fcfa3b 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -157,9 +157,9 @@ namespace Opm { if( timestep_verbose_ ) { std::ostringstream ss; - ss <<"Substep( " << substepTimer.currentStepNum() << " ), try with stepsize " - << unit::convert::to(substepTimer.currentStepLength(), unit::day) << " (days)." << std::endl; - OpmLog::note(ss.str()); + ss <<"Adaptive time step(" << substepTimer.currentStepNum() << "), stepsize " + << unit::convert::to(substepTimer.currentStepLength(), unit::day) << " days."; + OpmLog::info(ss.str()); } int linearIterations = -1; @@ -215,10 +215,12 @@ namespace Opm { if( timestep_verbose_ ) { - std::ostringstream ss; - ss << "Substep( " << substepTimer.currentStepNum()-1 // it was already advanced by ++ - << " ) finished at time " << unit::convert::to(substepTimer.simulationTimeElapsed(),unit::day) << " (days)." << std::endl << std::endl; - OpmLog::note(ss.str()); + std::ostringstream ss; + ss << "well iterations = " << solver.wellIterations() + << ", non-linear iterations = " << solver.nonlinearIterations() + << ", total linear iterations = " << solver.linearIterations() + << "\n"; + OpmLog::info(ss.str()); } // write data if outputWriter was provided From 30d9c34481e436a9df19b40631be8079adcbe2e1 Mon Sep 17 00:00:00 2001 From: Liu Ming Date: Tue, 28 Jun 2016 15:26:06 +0800 Subject: [PATCH 137/163] Add space. --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index ba8fcfa3b..73a515764 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -157,7 +157,7 @@ namespace Opm { if( timestep_verbose_ ) { std::ostringstream ss; - ss <<"Adaptive time step(" << substepTimer.currentStepNum() << "), stepsize " + ss <<"Adaptive time step (" << substepTimer.currentStepNum() << "), stepsize " << unit::convert::to(substepTimer.currentStepLength(), unit::day) << " days."; OpmLog::info(ss.str()); } From b8ef9cb630aa87cf6b85de370f1c396ceb8639b5 Mon Sep 17 00:00:00 2001 From: Liu Ming Date: Thu, 30 Jun 2016 09:03:30 +0800 Subject: [PATCH 138/163] output well iterations if it is a valid number. --- .../timestepping/AdaptiveTimeStepping_impl.hpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 73a515764..c5b30f947 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -216,10 +216,11 @@ namespace Opm { if( timestep_verbose_ ) { std::ostringstream ss; - ss << "well iterations = " << solver.wellIterations() - << ", non-linear iterations = " << solver.nonlinearIterations() - << ", total linear iterations = " << solver.linearIterations() - << "\n"; + if (solver.wellIterations() != std::numeric_limits::min()) { + ss << "well iterations = " << solver.wellIterations() << ", "; + } + ss << "non-linear iterations = " << solver.nonlinearIterations() + << ", total linear iterations = " << solver.linearIterations(); OpmLog::info(ss.str()); } From 02a3ba39b59dd0aeec7204f5f75d276e67490ce5 Mon Sep 17 00:00:00 2001 From: Kai Bao Date: Mon, 4 Jul 2016 11:12:53 +0200 Subject: [PATCH 139/163] adding a initialStep() function to SimulatorTimer to indicate if the current step is the inital step. --- opm/simulators/timestepping/SimulatorTimer.cpp | 6 ++++++ opm/simulators/timestepping/SimulatorTimer.hpp | 3 +++ 2 files changed, 9 insertions(+) diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index 66e8e2ffe..df3140428 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -63,6 +63,12 @@ namespace Opm start_date_ = start_time.date(); } + /// Whether the current step is the first step. + bool SimulatorTimer::initialStep() const + { + return (current_step_ == 0); + } + /// Total number of steps. int SimulatorTimer::numSteps() const { diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index 4db760930..52494a391 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -49,6 +49,9 @@ namespace Opm /// Use the SimulatorTimer as a shim around opm-parser's Opm::TimeMap void init(TimeMapConstPtr timeMap, size_t report_step = 0); + /// Whether the current step is the first step. + bool initialStep() const; + /// Total number of steps. int numSteps() const; From 0dda8d49c5e38c993fe5ec824f604e777e4f9c64 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Tue, 5 Jul 2016 12:23:55 +0200 Subject: [PATCH 140/163] pass the timer object instead of the time step size to the simulators --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index c5b30f947..829eed9dc 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include // For MatrixBlockException @@ -165,7 +166,7 @@ namespace Opm { int linearIterations = -1; try { // (linearIterations < 0 means on convergence in solver) - linearIterations = solver.step( dt, state, well_state); + linearIterations = solver.step( substepTimer, state, well_state); if( solver_verbose_ ) { // report number of linear iterations From 62134b4a0f8edb05d3cf06ad2ad487563e5ab901 Mon Sep 17 00:00:00 2001 From: Liu Ming Date: Thu, 14 Jul 2016 10:27:13 +0800 Subject: [PATCH 141/163] drop useage of std::numeric_limits --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index c5b30f947..c30380fa4 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -216,7 +216,7 @@ namespace Opm { if( timestep_verbose_ ) { std::ostringstream ss; - if (solver.wellIterations() != std::numeric_limits::min()) { + if (solver.wellIterations() != 0) { ss << "well iterations = " << solver.wellIterations() << ", "; } ss << "non-linear iterations = " << solver.nonlinearIterations() From 61889dafbd6757dfdb59070e61e5dbd7df32cda6 Mon Sep 17 00:00:00 2001 From: Liu Ming Date: Thu, 14 Jul 2016 10:30:20 +0800 Subject: [PATCH 142/163] fix indentation. --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index c30380fa4..d67a298a0 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -219,7 +219,7 @@ namespace Opm { if (solver.wellIterations() != 0) { ss << "well iterations = " << solver.wellIterations() << ", "; } - ss << "non-linear iterations = " << solver.nonlinearIterations() + ss << "non-linear iterations = " << solver.nonlinearIterations() << ", total linear iterations = " << solver.linearIterations(); OpmLog::info(ss.str()); } From 9579e4acd8b2a9e109accd757c0aa07f1c4d9729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A5l=20Gr=C3=B8n=C3=A5s=20Drange?= Date: Mon, 8 Aug 2016 10:02:53 +0200 Subject: [PATCH 143/163] transmult and initconfig are ref's, use ref for EclipseState constructor --- examples/wells_example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 5d04b3168..3a79e66c9 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -38,7 +38,7 @@ try ParseContext parseContext; Opm::ParserPtr parser(new Opm::Parser()); Opm::DeckConstPtr deck = parser->parseFile(file_name , parseContext); - Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(deck , parseContext)); + Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(*deck , parseContext)); std::cout << "Done!" << std::endl; // Setup grid From 63da817852b71ac2529b0101b1c01bac346f8213 Mon Sep 17 00:00:00 2001 From: babrodtk Date: Thu, 1 Sep 2016 11:36:25 +0200 Subject: [PATCH 144/163] Initial version for outputting cell data --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index b2ba05d51..56a11dec1 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -228,7 +228,8 @@ namespace Opm { // write data if outputWriter was provided if( outputWriter ) { bool substep = true; - outputWriter->writeTimeStep( substepTimer, state, well_state, substep); + const auto& physicalModel = solver.model(); + outputWriter->writeTimeStep( substepTimer, state, well_state, physicalModel, substep); } // set new time step length From 5aa2b97c31cc5280b5457df370023e98857b0060 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Wed, 31 Aug 2016 10:02:24 +0200 Subject: [PATCH 145/163] shared_ptr -> const EclipseGrid& --- examples/wells_example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 3a79e66c9..8f5da7044 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -42,7 +42,7 @@ try std::cout << "Done!" << std::endl; // Setup grid - GridManager grid(eclipseState->getInputGrid()); + GridManager grid(*eclipseState->getInputGrid()); // Define rock and fluid properties IncompPropertiesFromDeck incomp_properties(deck, eclipseState, *grid.c_grid()); From 380fe6e2fd2f6b075e3c54b5f379d27ac5719cb3 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Thu, 15 Sep 2016 12:21:59 +0200 Subject: [PATCH 146/163] Timestepper based on userInput A new timestepper that reads timesteps from a file generated using ecl_summary "DECK" TIME and applies it to the simulator Also a parameter timestep.initial_step_length (default 1 day) is added to controll the frist timestep. --- .../AdaptiveTimeStepping_impl.hpp | 8 +++- .../timestepping/TimeStepControl.cpp | 43 +++++++++++++++++-- .../timestepping/TimeStepControl.hpp | 27 ++++++++++-- .../timestepping/TimeStepControlInterface.hpp | 2 +- 4 files changed, 70 insertions(+), 10 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 56a11dec1..0ac481ac2 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -72,7 +72,7 @@ namespace Opm { , solver_restart_max_( param.getDefault("solver.restart", int(10) ) ) , solver_verbose_( param.getDefault("solver.verbose", bool(true) ) && terminal_output ) , timestep_verbose_( param.getDefault("timestep.verbose", bool(true) ) && terminal_output ) - , suggested_next_timestep_( -1.0 ) + , suggested_next_timestep_( unit::convert::from(param.getDefault("timestep.initial_step_length", double(1.0) ), unit::day) ) , full_timestep_initially_( param.getDefault("full_timestep_initially", bool(false) ) ) { // valid are "pid" and "pid+iteration" @@ -95,6 +95,10 @@ namespace Opm { const double decayrate = param.getDefault("timestep.control.decayrate", double(0.75) ); const double growthrate = param.getDefault("timestep.control.growthrate", double(1.25) ); timeStepControl_ = TimeStepControlType( new SimpleIterationCountTimeStepControl( iterations, decayrate, growthrate ) ); + } else if ( control == "hardcoded") { + const std::string filename = param.getDefault("timestep.control.filename", std::string("timesteps")); + timeStepControl_ = TimeStepControlType( new HardcodedTimeStepControl( filename ) ); + } else OPM_THROW(std::runtime_error,"Unsupported time step control selected "<< control ); @@ -202,7 +206,7 @@ namespace Opm { // compute new time step estimate double dtEstimate = - timeStepControl_->computeTimeStepSize( dt, linearIterations, relativeChange ); + timeStepControl_->computeTimeStepSize( dt, linearIterations, relativeChange, substepTimer.simulationTimeElapsed()); // limit the growth of the timestep size by the growth factor dtEstimate = std::min( dtEstimate, double(max_growth_ * dt) ); diff --git a/opm/simulators/timestepping/TimeStepControl.cpp b/opm/simulators/timestepping/TimeStepControl.cpp index e7d110434..0c01b24e3 100644 --- a/opm/simulators/timestepping/TimeStepControl.cpp +++ b/opm/simulators/timestepping/TimeStepControl.cpp @@ -23,6 +23,9 @@ #include #include #include +#include +#include +#include #include #include @@ -55,7 +58,7 @@ namespace Opm } double SimpleIterationCountTimeStepControl:: - computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& /* relativeChange */ ) const + computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& /* relativeChange */, const double /*simulationTimeElapsed */) const { double dtEstimate = dt ; @@ -74,6 +77,38 @@ namespace Opm return dtEstimate; } + //////////////////////////////////////////////////////// + // + // HardcodedTimeStepControl Implementation + // + //////////////////////////////////////////////////////// + + HardcodedTimeStepControl:: + HardcodedTimeStepControl( const std::string filename) + { + std::ifstream infile (filename); + double time; + std::string line; + std::getline(infile, line); //assumes two lines before the timing starts. + std::getline(infile, line); + + while (!infile.eof() ) { + infile >> time; // read the time in days + std::string line; + std::getline(infile, line); // skip the rest of the line + timesteps_.push_back( time * unit::day ); + } + + } + + double HardcodedTimeStepControl:: + computeTimeStepSize( const double /*dt */, const int /*iterations */, const RelativeChangeInterface& /* relativeChange */ , const double simulationTimeElapsed) const + { + auto nextTime = std::upper_bound(timesteps_.begin(), timesteps_.end(), simulationTimeElapsed); + double dtEstimate = (*nextTime - simulationTimeElapsed); + return dtEstimate; + } + //////////////////////////////////////////////////////// @@ -90,7 +125,7 @@ namespace Opm {} double PIDTimeStepControl:: - computeTimeStepSize( const double dt, const int /* iterations */, const RelativeChangeInterface& relChange ) const + computeTimeStepSize( const double dt, const int /* iterations */, const RelativeChangeInterface& relChange, const double /*simulationTimeElapsed */) const { // shift errors for( int i=0; i<2; ++i ) { @@ -141,9 +176,9 @@ namespace Opm {} double PIDAndIterationCountTimeStepControl:: - computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& relChange ) const + computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& relChange, const double simulationTimeElapsed ) const { - double dtEstimate = BaseType :: computeTimeStepSize( dt, iterations, relChange ); + double dtEstimate = BaseType :: computeTimeStepSize( dt, iterations, relChange, simulationTimeElapsed); // further reduce step size if to many iterations were used if( iterations > target_iterations_ ) diff --git a/opm/simulators/timestepping/TimeStepControl.hpp b/opm/simulators/timestepping/TimeStepControl.hpp index ec14ddbef..40f5db6e0 100644 --- a/opm/simulators/timestepping/TimeStepControl.hpp +++ b/opm/simulators/timestepping/TimeStepControl.hpp @@ -48,7 +48,7 @@ namespace Opm const bool verbose = false); /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize - double computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& /* relativeChange */ ) const; + double computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& /* relativeChange */, const double /*simulationTimeElapsed */ ) const; protected: const int target_iterations_; @@ -82,7 +82,7 @@ namespace Opm const bool verbose = false ); /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize - double computeTimeStepSize( const double dt, const int /* iterations */, const RelativeChangeInterface& relativeChange ) const; + double computeTimeStepSize( const double dt, const int /* iterations */, const RelativeChangeInterface& relativeChange, const double /*simulationTimeElapsed */ ) const; protected: const double tol_; @@ -111,12 +111,33 @@ namespace Opm const bool verbose = false); /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize - double computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& relativeChange ) const; + double computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& relativeChange, const double /*simulationTimeElapsed */ ) const; protected: const int target_iterations_; }; + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// + /// HardcodedTimeStepControl + /// Input generated from summary file using the ert application: + /// ecl_summary DECK TIME > filename + // + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + class HardcodedTimeStepControl : public TimeStepControlInterface + { + public: + /// \brief constructor + /// \param filename filename contaning the timesteps + HardcodedTimeStepControl( const std::string filename); + + /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize + double computeTimeStepSize( const double dt, const int /* iterations */, const RelativeChangeInterface& /*relativeChange */, const double simulationTimeElapsed) const; + + protected: + std::vector timesteps_; + }; + } // end namespace Opm #endif diff --git a/opm/simulators/timestepping/TimeStepControlInterface.hpp b/opm/simulators/timestepping/TimeStepControlInterface.hpp index 2aee5aebe..bdab5e3a4 100644 --- a/opm/simulators/timestepping/TimeStepControlInterface.hpp +++ b/opm/simulators/timestepping/TimeStepControlInterface.hpp @@ -56,7 +56,7 @@ namespace Opm /// \param timeError object to compute || u^n+1 - u^n || / || u^n+1 || /// /// \return suggested time step size for the next step - virtual double computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& relativeChange ) const = 0; + virtual double computeTimeStepSize( const double dt, const int iterations, const RelativeChangeInterface& relativeChange , const double simulationTimeElapsed) const = 0; /// virtual destructor (empty) virtual ~TimeStepControlInterface () {} From 1bde4f4a22ce27cd1146cedd20b773b97246b8da Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Fri, 16 Sep 2016 10:01:19 +0200 Subject: [PATCH 147/163] Small fixes hardcodedTimestepControl -- avoid using eof() -- add comments -- no longer assumes two lines of comments. -- revert change to default value for timestep.initial_step_length -- make contructer explicit -- pass reference --- .../AdaptiveTimeStepping_impl.hpp | 2 +- .../timestepping/TimeStepControl.cpp | 22 ++++++++----------- .../timestepping/TimeStepControl.hpp | 9 +++++--- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 0ac481ac2..33d92d904 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -72,7 +72,7 @@ namespace Opm { , solver_restart_max_( param.getDefault("solver.restart", int(10) ) ) , solver_verbose_( param.getDefault("solver.verbose", bool(true) ) && terminal_output ) , timestep_verbose_( param.getDefault("timestep.verbose", bool(true) ) && terminal_output ) - , suggested_next_timestep_( unit::convert::from(param.getDefault("timestep.initial_step_length", double(1.0) ), unit::day) ) + , suggested_next_timestep_( -1.0 ) , full_timestep_initially_( param.getDefault("full_timestep_initially", bool(false) ) ) { // valid are "pid" and "pid+iteration" diff --git a/opm/simulators/timestepping/TimeStepControl.cpp b/opm/simulators/timestepping/TimeStepControl.cpp index 0c01b24e3..91cb478c0 100644 --- a/opm/simulators/timestepping/TimeStepControl.cpp +++ b/opm/simulators/timestepping/TimeStepControl.cpp @@ -84,29 +84,25 @@ namespace Opm //////////////////////////////////////////////////////// HardcodedTimeStepControl:: - HardcodedTimeStepControl( const std::string filename) + HardcodedTimeStepControl( const std::string& filename) { std::ifstream infile (filename); - double time; + std::string::size_type sz; std::string line; - std::getline(infile, line); //assumes two lines before the timing starts. - std::getline(infile, line); + while ( std::getline(infile, line)) { + if( line[0] != '-') { // ignore lines starting with '-' + const double time = std::stod(line,&sz); // read the first number i.e. the actual substep time + subStepTime_.push_back( time * unit::day ); + } - while (!infile.eof() ) { - infile >> time; // read the time in days - std::string line; - std::getline(infile, line); // skip the rest of the line - timesteps_.push_back( time * unit::day ); } - } double HardcodedTimeStepControl:: computeTimeStepSize( const double /*dt */, const int /*iterations */, const RelativeChangeInterface& /* relativeChange */ , const double simulationTimeElapsed) const { - auto nextTime = std::upper_bound(timesteps_.begin(), timesteps_.end(), simulationTimeElapsed); - double dtEstimate = (*nextTime - simulationTimeElapsed); - return dtEstimate; + auto nextTime = std::upper_bound(subStepTime_.begin(), subStepTime_.end(), simulationTimeElapsed); + return (*nextTime - simulationTimeElapsed); } diff --git a/opm/simulators/timestepping/TimeStepControl.hpp b/opm/simulators/timestepping/TimeStepControl.hpp index 40f5db6e0..00a82d743 100644 --- a/opm/simulators/timestepping/TimeStepControl.hpp +++ b/opm/simulators/timestepping/TimeStepControl.hpp @@ -121,21 +121,24 @@ namespace Opm /// /// HardcodedTimeStepControl /// Input generated from summary file using the ert application: + /// /// ecl_summary DECK TIME > filename - // + /// + /// Assumes time is given in days /////////////////////////////////////////////////////////////////////////////////////////////////////////////// class HardcodedTimeStepControl : public TimeStepControlInterface { public: /// \brief constructor /// \param filename filename contaning the timesteps - HardcodedTimeStepControl( const std::string filename); + explicit HardcodedTimeStepControl( const std::string& filename); /// \brief \copydoc TimeStepControlInterface::computeTimeStepSize double computeTimeStepSize( const double dt, const int /* iterations */, const RelativeChangeInterface& /*relativeChange */, const double simulationTimeElapsed) const; protected: - std::vector timesteps_; + // store the time (in days) of the substeps the simulator should use + std::vector subStepTime_; }; From 4c4b5233c022a2f09a4488d6793a33f3ad6c12a7 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Wed, 21 Sep 2016 09:38:51 +0200 Subject: [PATCH 148/163] Guard against non-existing file --- opm/simulators/timestepping/TimeStepControl.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/opm/simulators/timestepping/TimeStepControl.cpp b/opm/simulators/timestepping/TimeStepControl.cpp index 91cb478c0..a67871911 100644 --- a/opm/simulators/timestepping/TimeStepControl.cpp +++ b/opm/simulators/timestepping/TimeStepControl.cpp @@ -87,6 +87,9 @@ namespace Opm HardcodedTimeStepControl( const std::string& filename) { std::ifstream infile (filename); + if (!infile.is_open()) { + OPM_THROW(std::runtime_error,"Incorrect or no filename is provided to the hardcodedTimeStep. Use timestep.control.filename=your_file_name"); + } std::string::size_type sz; std::string line; while ( std::getline(infile, line)) { From 815480d052d4a53e04b637251ace7020b678d51a Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Mon, 26 Sep 2016 11:02:10 +0200 Subject: [PATCH 149/163] Only call writeTimeStep for real sub steps. Previously, we also called it when the full time step was done. As the simulator writes that information anyway and we cannot call it a sub step, we omit the final write in the adaptive time stepper. --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 33d92d904..6cb242f0e 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -230,7 +230,10 @@ namespace Opm { } // write data if outputWriter was provided - if( outputWriter ) { + // if the time step is done we do not need + // to write it as this will be done by the simulator + // anyway. + if( outputWriter && !substepTimer.done() ) { bool substep = true; const auto& physicalModel = solver.model(); outputWriter->writeTimeStep( substepTimer, state, well_state, physicalModel, substep); From e034bbc7ad9bce362173ffb061ed8678f300763a Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Wed, 28 Sep 2016 09:59:50 +0200 Subject: [PATCH 150/163] Add initalizer for adaptiveTimeStepper that uses values from TUNING Some of the tuning values from the TUNING keywords is used to tune the timestepping. --- .../timestepping/AdaptiveTimeStepping.hpp | 13 +++++++++ .../AdaptiveTimeStepping_impl.hpp | 29 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index d722f9cfd..2c84e8500 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -45,6 +45,17 @@ namespace Opm { AdaptiveTimeStepping( const parameter::ParameterGroup& param, const bool terminal_output = true ); + //! \brief contructor taking parameter object + //! \param tuning Pointer to ecl TUNING keyword + //! \param time_step current report step + //! \param param The parameter object + //! \param pinfo The information about the data distribution + //! and communication for a parallel run. + AdaptiveTimeStepping( const Tuning& tuning, + size_t time_step, + const parameter::ParameterGroup& param, + const bool terminal_output = true ); + /** \brief step method that acts like the solver::step method in a sub cycle of time steps @@ -77,6 +88,8 @@ namespace Opm { Solver& solver, State& state, WellState& well_state, Output* outputWriter); + void init(const parameter::ParameterGroup& param); + typedef std::unique_ptr< TimeStepControlInterface > TimeStepControlType; TimeStepControlType timeStepControl_; //!< time step control object diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 6cb242f0e..a79cd2937 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -30,6 +30,7 @@ #include #include #include // For MatrixBlockException +#include namespace Opm { @@ -61,6 +62,26 @@ namespace Opm { // AdaptiveTimeStepping //--------------------- + AdaptiveTimeStepping::AdaptiveTimeStepping( const Tuning& tuning, + size_t time_step, + const parameter::ParameterGroup& param, + const bool terminal_output ) + : timeStepControl_() + , restart_factor_( tuning.getTSFCNV(time_step) ) + , growth_factor_(tuning.getTFDIFF(time_step) ) + , max_growth_( tuning.getTSFMAX(time_step) ) + // default is 1 year, convert to seconds + , max_time_step_( tuning.getTSMAXZ(time_step) ) + , solver_restart_max_( param.getDefault("solver.restart", int(10) ) ) + , solver_verbose_( param.getDefault("solver.verbose", bool(true) ) && terminal_output ) + , timestep_verbose_( param.getDefault("timestep.verbose", bool(true) ) && terminal_output ) + , suggested_next_timestep_( tuning.getTSINIT(time_step) ) + , full_timestep_initially_( param.getDefault("full_timestep_initially", bool(false) ) ) + { + init(param); + + } + AdaptiveTimeStepping::AdaptiveTimeStepping( const parameter::ParameterGroup& param, const bool terminal_output ) : timeStepControl_() @@ -74,6 +95,12 @@ namespace Opm { , timestep_verbose_( param.getDefault("timestep.verbose", bool(true) ) && terminal_output ) , suggested_next_timestep_( -1.0 ) , full_timestep_initially_( param.getDefault("full_timestep_initially", bool(false) ) ) + { + init(param); + } + + void AdaptiveTimeStepping:: + init(const parameter::ParameterGroup& param) { // valid are "pid" and "pid+iteration" std::string control = param.getDefault("timestep.control", std::string("pid") ); @@ -108,6 +135,7 @@ namespace Opm { } + template void AdaptiveTimeStepping:: step( const SimulatorTimer& simulatorTimer, Solver& solver, State& state, WellState& well_state ) @@ -123,6 +151,7 @@ namespace Opm { stepImpl( simulatorTimer, solver, state, well_state, &outputWriter ); } + // implementation of the step method template void AdaptiveTimeStepping:: From 66f0b71fc1f3db90f1cae04f0050940007be193e Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Mon, 19 Sep 2016 19:44:41 +0200 Subject: [PATCH 151/163] Log the message of exceptions in the catch clause of adaptive time stepper. --- .../AdaptiveTimeStepping_impl.hpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index a79cd2937..23ef1dd50 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -57,6 +57,17 @@ namespace Opm { return solver_.model().relativeChange( previous_, current_ ); } }; + + template + void logException(const E& exception, bool verbose) + { + if( verbose ) + { + std::ostringstream message; + message << "Caught Exception: " << exception.what(); + OpmLog::debug(message.str()); + } + } } // AdaptiveTimeStepping @@ -207,19 +218,19 @@ namespace Opm { } } catch (const Opm::NumericalProblem& e) { - std::cerr << e.what() << std::endl; + detail::logException(e, solver_verbose_); // since linearIterations is < 0 this will restart the solver } catch (const std::runtime_error& e) { - std::cerr << e.what() << std::endl; + detail::logException(e, solver_verbose_); // also catch linear solver not converged } catch (const Dune::ISTLError& e) { - std::cerr << e.what() << std::endl; + detail::logException(e, solver_verbose_); // also catch errors in ISTL AMG that occur when time step is too large } catch (const Dune::MatrixBlockError& e) { - std::cerr << e.what() << std::endl; + detail::logException(e, solver_verbose_); // this can be thrown by ISTL's ILU0 in block mode, yet is not an ISTLError } From 144318b5674b9da7038b3696b6253bfeb255da1b Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Mon, 10 Oct 2016 17:23:03 +0200 Subject: [PATCH 152/163] consolidate the unit system to opm-parser since the unit code within opm-parser is now a drop-in replacement, this simplifies things and make them less error-prone. unfortunately, this requires quite a few PRs. (most are pretty trivial, though.) --- opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp | 2 +- opm/simulators/timestepping/SimulatorTimer.cpp | 2 +- opm/simulators/timestepping/TimeStepControl.cpp | 2 +- tests/test_timer.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp index c730c80ac..927b06419 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include namespace Opm diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index df3140428..f94baf874 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -20,7 +20,7 @@ #include "config.h" #include #include -#include +#include #include #include diff --git a/opm/simulators/timestepping/TimeStepControl.cpp b/opm/simulators/timestepping/TimeStepControl.cpp index a67871911..df25e4c44 100644 --- a/opm/simulators/timestepping/TimeStepControl.cpp +++ b/opm/simulators/timestepping/TimeStepControl.cpp @@ -28,7 +28,7 @@ #include #include -#include +#include #include namespace Opm diff --git a/tests/test_timer.cpp b/tests/test_timer.cpp index 3512ddd69..05b10f595 100644 --- a/tests/test_timer.cpp +++ b/tests/test_timer.cpp @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include From ad6b77cc15557fc78fd51ccb144caef4f55f5ef3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Kvalsvik?= Date: Thu, 13 Oct 2016 16:03:35 +0200 Subject: [PATCH 153/163] Update to shared_ptr-less parser interface. --- examples/wells_example.cpp | 8 ++++---- opm/simulators/timestepping/SimulatorTimer.cpp | 12 ++++++------ opm/simulators/timestepping/SimulatorTimer.hpp | 2 +- tests/test_timer.cpp | 6 +++--- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 8f5da7044..8be7c7aa2 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -36,13 +36,13 @@ try // Read input file ParseContext parseContext; - Opm::ParserPtr parser(new Opm::Parser()); - Opm::DeckConstPtr deck = parser->parseFile(file_name , parseContext); - Opm::EclipseStateConstPtr eclipseState(new Opm::EclipseState(*deck , parseContext)); + Opm::Parser parser; + Opm::Deck deck = parser.parseFile(file_name , parseContext); + Opm::EclipseState eclipseState(deck , parseContext); std::cout << "Done!" << std::endl; // Setup grid - GridManager grid(*eclipseState->getInputGrid()); + GridManager grid(eclipseState.getInputGrid()); // Define rock and fluid properties IncompPropertiesFromDeck incomp_properties(deck, eclipseState, *grid.c_grid()); diff --git a/opm/simulators/timestepping/SimulatorTimer.cpp b/opm/simulators/timestepping/SimulatorTimer.cpp index f94baf874..cedcaeefe 100644 --- a/opm/simulators/timestepping/SimulatorTimer.cpp +++ b/opm/simulators/timestepping/SimulatorTimer.cpp @@ -49,17 +49,17 @@ namespace Opm } /// Use the SimulatorTimer as a shim around opm-parser's Opm::TimeMap - void SimulatorTimer::init(Opm::TimeMapConstPtr timeMap, size_t report_step) + void SimulatorTimer::init(const TimeMap& timeMap, size_t report_step) { - total_time_ = timeMap->getTotalTime(); - timesteps_.resize(timeMap->numTimesteps()); - for ( size_t i = 0; i < timeMap->numTimesteps(); ++i ) { - timesteps_[i] = timeMap->getTimeStepLength(i); + total_time_ = timeMap.getTotalTime(); + timesteps_.resize(timeMap.numTimesteps()); + for ( size_t i = 0; i < timeMap.numTimesteps(); ++i ) { + timesteps_[i] = timeMap.getTimeStepLength(i); } setCurrentStepNum(report_step); - boost::posix_time::ptime start_time = timeMap->getStartTime(0); + boost::posix_time::ptime start_time = timeMap.getStartTime(0); start_date_ = start_time.date(); } diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index 52494a391..ada0cc049 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -47,7 +47,7 @@ namespace Opm void init(const parameter::ParameterGroup& param); /// Use the SimulatorTimer as a shim around opm-parser's Opm::TimeMap - void init(TimeMapConstPtr timeMap, size_t report_step = 0); + void init(const TimeMap& timeMap, size_t report_step = 0); /// Whether the current step is the first step. bool initialStep() const; diff --git a/tests/test_timer.cpp b/tests/test_timer.cpp index 05b10f595..59d1bcf74 100644 --- a/tests/test_timer.cpp +++ b/tests/test_timer.cpp @@ -43,11 +43,11 @@ BOOST_AUTO_TEST_CASE(CreateTimer) { const std::string filename1 = "TESTTIMER.DATA"; - Opm::ParserPtr parser(new Opm::Parser() ); Opm::ParseContext parseContext; - Opm::DeckConstPtr parserDeck = parser->parseFile( filename1 , parseContext); + Opm::Parser parser; + Opm::Deck parserDeck = parser.parseFile( filename1 , parseContext); - Opm::TimeMapPtr timeMap(new Opm::TimeMap(parserDeck)); + Opm::TimeMap timeMap( parserDeck ); Opm::SimulatorTimer simtimer; boost::gregorian::date defaultStartDate( 2012, 1, 1); From 83b3d8a149136f3058a0e90892a0cf4567034d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 17 Oct 2016 13:28:43 +0200 Subject: [PATCH 154/163] Ensure logging only on first rank. --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 23ef1dd50..3176ce26b 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -291,7 +291,12 @@ namespace Opm { { // increase restart counter if( restarts >= solver_restart_max_ ) { - OPM_THROW(Opm::NumericalProblem,"Solver failed to converge after " << restarts << " restarts."); + const auto msg = std::string("Solver failed to converge after ") + + std::to_string(restarts) + " restarts."; + if (solver_verbose_) { + OpmLog::error(msg); + } + OPM_THROW_NOLOG(Opm::NumericalProblem, msg); } const double newTimeStep = restart_factor_ * dt; From 08b7db6c7ffccb1856d697b4c68f58f14df34543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 17 Oct 2016 13:29:11 +0200 Subject: [PATCH 155/163] Classify convergence failure as a "problem" not "error". --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 3176ce26b..f5f4a2dc7 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -306,7 +306,7 @@ namespace Opm { std::string msg; msg = "Solver convergence failed, restarting solver with new time step (" + std::to_string(unit::convert::to( newTimeStep, unit::day )) + " days).\n"; - OpmLog::error(msg); + OpmLog::problem(msg); } // reset states state = last_state; From a083f46d4480416c9c4b21d371d698537e5472c6 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Fri, 28 Oct 2016 09:03:29 +0200 Subject: [PATCH 156/163] Make it possible to set initial timestep Default is kept at -1.0. I.e. this PR does not change the current behaviour. --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index f5f4a2dc7..d6005dca4 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -104,7 +104,7 @@ namespace Opm { , solver_restart_max_( param.getDefault("solver.restart", int(10) ) ) , solver_verbose_( param.getDefault("solver.verbose", bool(true) ) && terminal_output ) , timestep_verbose_( param.getDefault("timestep.verbose", bool(true) ) && terminal_output ) - , suggested_next_timestep_( -1.0 ) + , suggested_next_timestep_( unit::convert::from(param.getDefault("timestep.initial_timestep_in_days", -1.0 ), unit::day) ) , full_timestep_initially_( param.getDefault("full_timestep_initially", bool(false) ) ) { init(param); From 6720eb7a755efda2c02e44e211f02c71d6dc57b4 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Wed, 23 Nov 2016 21:30:01 +0100 Subject: [PATCH 157/163] clean up and extend the SimulationReport class it now also accounts for assembly, linear solve, update and output write time and indicates if an operation has converged. --- .../timestepping/AdaptiveTimeStepping.hpp | 16 +++--- .../AdaptiveTimeStepping_impl.hpp | 49 ++++++++++++------- 2 files changed, 39 insertions(+), 26 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index 2c84e8500..8e1adc6c9 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -65,8 +65,8 @@ namespace Opm { \param well_state additional well state object */ template - void step( const SimulatorTimer& timer, - Solver& solver, State& state, WellState& well_state ); + SimulatorReport step( const SimulatorTimer& timer, + Solver& solver, State& state, WellState& well_state ); /** \brief step method that acts like the solver::step method in a sub cycle of time steps @@ -78,15 +78,15 @@ namespace Opm { \param outputWriter writer object to write sub steps */ template - void step( const SimulatorTimer& timer, - Solver& solver, State& state, WellState& well_state, - Output& outputWriter ); + SimulatorReport step( const SimulatorTimer& timer, + Solver& solver, State& state, WellState& well_state, + Output& outputWriter ); protected: template - void stepImpl( const SimulatorTimer& timer, - Solver& solver, State& state, WellState& well_state, - Output* outputWriter); + SimulatorReport stepImpl( const SimulatorTimer& timer, + Solver& solver, State& state, WellState& well_state, + Output* outputWriter); void init(const parameter::ParameterGroup& param); diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index d6005dca4..a0e4324e0 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -148,28 +149,29 @@ namespace Opm { template - void AdaptiveTimeStepping:: + SimulatorReport AdaptiveTimeStepping:: step( const SimulatorTimer& simulatorTimer, Solver& solver, State& state, WellState& well_state ) { - stepImpl( simulatorTimer, solver, state, well_state ); + return stepImpl( simulatorTimer, solver, state, well_state ); } template - void AdaptiveTimeStepping:: + SimulatorReport AdaptiveTimeStepping:: step( const SimulatorTimer& simulatorTimer, Solver& solver, State& state, WellState& well_state, Output& outputWriter ) { - stepImpl( simulatorTimer, solver, state, well_state, &outputWriter ); + return stepImpl( simulatorTimer, solver, state, well_state, &outputWriter ); } // implementation of the step method template - void AdaptiveTimeStepping:: + SimulatorReport AdaptiveTimeStepping:: stepImpl( const SimulatorTimer& simulatorTimer, Solver& solver, State& state, WState& well_state, Output* outputWriter ) { + SimulatorReport report; const double timestep = simulatorTimer.currentStepLength(); // init last time step as a fraction of the given time step @@ -202,19 +204,19 @@ namespace Opm { if( timestep_verbose_ ) { std::ostringstream ss; - ss <<"Adaptive time step (" << substepTimer.currentStepNum() << "), stepsize " + ss <<" Substep " << substepTimer.currentStepNum() << ", stepsize " << unit::convert::to(substepTimer.currentStepLength(), unit::day) << " days."; OpmLog::info(ss.str()); } - int linearIterations = -1; + SimulatorReport substepReport; try { - // (linearIterations < 0 means on convergence in solver) - linearIterations = solver.step( substepTimer, state, well_state); + substepReport = solver.step( substepTimer, state, well_state); + report += substepReport; if( solver_verbose_ ) { // report number of linear iterations - OpmLog::note("Overall linear iterations used: " + std::to_string(linearIterations)); + OpmLog::note("Overall linear iterations used: " + std::to_string(substepReport.total_linear_iterations)); } } catch (const Opm::NumericalProblem& e) { @@ -234,8 +236,7 @@ namespace Opm { // this can be thrown by ISTL's ILU0 in block mode, yet is not an ISTLError } - // (linearIterations < 0 means no convergence in solver) - if( linearIterations >= 0 ) + if( substepReport.converged ) { // advance by current dt ++substepTimer; @@ -246,7 +247,7 @@ namespace Opm { // compute new time step estimate double dtEstimate = - timeStepControl_->computeTimeStepSize( dt, linearIterations, relativeChange, substepTimer.simulationTimeElapsed()); + timeStepControl_->computeTimeStepSize( dt, substepReport.total_linear_iterations, relativeChange, substepTimer.simulationTimeElapsed()); // limit the growth of the timestep size by the growth factor dtEstimate = std::min( dtEstimate, double(max_growth_ * dt) ); @@ -261,11 +262,15 @@ namespace Opm { if( timestep_verbose_ ) { std::ostringstream ss; - if (solver.wellIterations() != 0) { - ss << "well iterations = " << solver.wellIterations() << ", "; + ss << " Substep summary: "; + if (report.total_well_iterations != 0) { + ss << "well iterations = " << report.total_well_iterations << ", "; } - ss << "non-linear iterations = " << solver.nonlinearIterations() - << ", total linear iterations = " << solver.linearIterations(); + ss << "newton iterations = " << report.total_newton_iterations << ", " + << "linearizations = " << report.total_newton_iterations + << " (" << report.assemble_time << " sec), " + << "linear iterations = " << report.total_linear_iterations + << " (" << report.linear_solve_time << " sec)"; OpmLog::info(ss.str()); } @@ -274,9 +279,12 @@ namespace Opm { // to write it as this will be done by the simulator // anyway. if( outputWriter && !substepTimer.done() ) { + Opm::time::StopWatch perfTimer; + perfTimer.start(); bool substep = true; const auto& physicalModel = solver.model(); outputWriter->writeTimeStep( substepTimer, state, well_state, physicalModel, substep); + report.output_write_time += perfTimer.secsSinceStart(); } // set new time step length @@ -286,9 +294,13 @@ namespace Opm { last_state = state ; last_well_state = well_state; + report.converged = substepTimer.done(); + } else // in case of no convergence (linearIterations < 0) { + report.converged = false; + // increase restart counter if( restarts >= solver_restart_max_ ) { const auto msg = std::string("Solver failed to converge after ") @@ -307,7 +319,7 @@ namespace Opm { msg = "Solver convergence failed, restarting solver with new time step (" + std::to_string(unit::convert::to( newTimeStep, unit::day )) + " days).\n"; OpmLog::problem(msg); - } + } // reset states state = last_state; well_state = last_well_state; @@ -330,6 +342,7 @@ namespace Opm { if( ! std::isfinite( suggested_next_timestep_ ) ) { // check for NaN suggested_next_timestep_ = timestep; } + return report; } } From 676af2b00be3c0e854f5fe45d81e564c0d133fc2 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Sat, 3 Dec 2016 15:04:32 +0100 Subject: [PATCH 158/163] AdaptiveTimeStepping: fix stupid (but harmless) mistake in the sub-step info message that was a copy-and-pasto: newton iterations = linearizations - 1 --- opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index a0e4324e0..03c16e0e0 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -267,7 +267,7 @@ namespace Opm { ss << "well iterations = " << report.total_well_iterations << ", "; } ss << "newton iterations = " << report.total_newton_iterations << ", " - << "linearizations = " << report.total_newton_iterations + << "linearizations = " << report.total_linearizations << " (" << report.assemble_time << " sec), " << "linear iterations = " << report.total_linear_iterations << " (" << report.linear_solve_time << " sec)"; From f65f5d2c3b2083f3a7d3864384036ded82326794 Mon Sep 17 00:00:00 2001 From: Tor Harald Sandve Date: Mon, 5 Dec 2016 09:37:30 +0100 Subject: [PATCH 159/163] Store whether timestep failed or not Used in flow ebos to tell the simulator to recalculate the cached quantities for failed timesteps. --- opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp | 1 + opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp | 8 ++++++++ opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp | 3 ++- opm/simulators/timestepping/SimulatorTimer.hpp | 4 ++++ opm/simulators/timestepping/SimulatorTimerInterface.hpp | 3 +++ 5 files changed, 18 insertions(+), 1 deletion(-) diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp index 927b06419..6fd59d3f1 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp @@ -42,6 +42,7 @@ namespace Opm , dt_( 0.0 ) , current_step_( 0 ) , steps_() + , lastStepFailed_( false ) { // reserve memory for sub steps steps_.reserve( 10 ); diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp index be93f3047..31af15b83 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp @@ -93,6 +93,12 @@ namespace Opm /// \brief start date time of simulation boost::posix_time::ptime startDateTime() const; + /// \brief Return true if last time step failed + bool lastStepFailed() const {return lastStepFailed_;} + + /// \brief tell the timestepper whether timestep failed or not + void setLastStepFailed(bool lastStepFailed) {lastStepFailed_ = lastStepFailed;} + /// return copy of object virtual std::unique_ptr< SimulatorTimerInterface > clone() const; @@ -108,6 +114,8 @@ namespace Opm int current_step_; std::vector< double > steps_; + bool lastStepFailed_; + }; } // namespace Opm diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 03c16e0e0..12d31dec9 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -295,12 +295,13 @@ namespace Opm { last_well_state = well_state; report.converged = substepTimer.done(); + substepTimer.setLastStepFailed(false); } else // in case of no convergence (linearIterations < 0) { report.converged = false; - + substepTimer.setLastStepFailed(true); // increase restart counter if( restarts >= solver_restart_max_ ) { const auto msg = std::string("Solver failed to converge after ") diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index ada0cc049..8b920192c 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -110,6 +110,10 @@ namespace Opm /// Return true if op++() has been called numSteps() times. bool done() const; + /// Always return false. Timestep failures is handled in the + /// substepTimer + bool lastStepFailed() const {return false;} + /// return copy of object virtual std::unique_ptr< SimulatorTimerInterface > clone() const; diff --git a/opm/simulators/timestepping/SimulatorTimerInterface.hpp b/opm/simulators/timestepping/SimulatorTimerInterface.hpp index c9e28471e..ae30d381c 100644 --- a/opm/simulators/timestepping/SimulatorTimerInterface.hpp +++ b/opm/simulators/timestepping/SimulatorTimerInterface.hpp @@ -101,6 +101,9 @@ namespace Opm return std::mktime(&t); } + /// Return true if last time step failed + virtual bool lastStepFailed() const = 0; + /// return copy of current timer instance virtual std::unique_ptr< SimulatorTimerInterface > clone () const = 0; }; From 6e92374d34c4a8f8d99facab7258b5adda7ea765 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Kvalsvik?= Date: Tue, 20 Dec 2016 12:24:27 +0100 Subject: [PATCH 160/163] Read ROCK from EclipseState, not Deck --- examples/wells_example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 8be7c7aa2..af0c20312 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -46,7 +46,7 @@ try // Define rock and fluid properties IncompPropertiesFromDeck incomp_properties(deck, eclipseState, *grid.c_grid()); - RockCompressibility rock_comp(deck, eclipseState); + RockCompressibility rock_comp(eclipseState); // Finally handle the wells WellsManager wells(eclipseState , 0 , *grid.c_grid(), incomp_properties.permeability()); From 04a1c25ebfd92654c8cbddddfa49d39fc428fa09 Mon Sep 17 00:00:00 2001 From: Andreas Lauser Date: Thu, 26 Jan 2017 17:36:00 +0100 Subject: [PATCH 161/163] do not explicitly pass the permeability to the well model anymore this information is already part of the EclipseState. The reason why this should IMO be avoided is that this enforces an implementation (ordering of the permeability matrices) the simulator on the well model. If this needs to be done for performance reasons, IMO it would be smarter to pass an array of matrices, instead of passing a raw array of doubles. I doubt that this is necessary, though: completing the full Norne deck takes about 0.25 seconds longer on my machine, that's substantially less than 0.1% of the total runtime. in order to avoid code duplication, the permeability extraction function of the RockFromDeck class is now made a public static function and used as an implementation detail of the WellsManager. finally, the permfield_valid_ attribute is removed from the RockFromDeck class because this data was unused and not accessible via the class' public API. --- examples/wells_example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index af0c20312..48f68c8b1 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -49,7 +49,7 @@ try RockCompressibility rock_comp(eclipseState); // Finally handle the wells - WellsManager wells(eclipseState , 0 , *grid.c_grid(), incomp_properties.permeability()); + WellsManager wells(eclipseState , 0 , *grid.c_grid()); double gravity[3] = {0.0, 0.0, parameters.getDefault("gravity", 0.0)}; Opm::LinearSolverFactory linsolver(parameters); From 1cb81c12e8d6657ae3abab5f513ffd956a7504d7 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Thu, 9 Feb 2017 09:33:32 +0100 Subject: [PATCH 162/163] changed: pass fipnum array into adaptive time stepping loop needed as substep summary reports requires FIP data to be available. add calculation of this data if output is requested and summary config holds relevant keywords. --- .../timestepping/AdaptiveTimeStepping.hpp | 7 +++++-- .../timestepping/AdaptiveTimeStepping_impl.hpp | 16 +++++++++++----- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index 8e1adc6c9..a4734fe98 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -72,6 +72,7 @@ namespace Opm { in a sub cycle of time steps \param timer simulator timer providing time and timestep + \param fipnum Fluid-in-place numbering array \param solver solver object that must implement a method step( dt, state, well_state ) \param state current state of the solution variables \param well_state additional well state object @@ -80,13 +81,15 @@ namespace Opm { template SimulatorReport step( const SimulatorTimer& timer, Solver& solver, State& state, WellState& well_state, - Output& outputWriter ); + Output& outputWriter, + const std::vector* fipnum = nullptr); protected: template SimulatorReport stepImpl( const SimulatorTimer& timer, Solver& solver, State& state, WellState& well_state, - Output* outputWriter); + Output* outputWriter, + const std::vector* fipnum); void init(const parameter::ParameterGroup& param); diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index 12d31dec9..aab2413e2 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -152,15 +152,17 @@ namespace Opm { SimulatorReport AdaptiveTimeStepping:: step( const SimulatorTimer& simulatorTimer, Solver& solver, State& state, WellState& well_state ) { - return stepImpl( simulatorTimer, solver, state, well_state ); + return stepImpl( simulatorTimer, solver, state, well_state, nullptr, nullptr ); } template SimulatorReport AdaptiveTimeStepping:: - step( const SimulatorTimer& simulatorTimer, Solver& solver, State& state, WellState& well_state, - Output& outputWriter ) + step( const SimulatorTimer& simulatorTimer, + Solver& solver, State& state, WellState& well_state, + Output& outputWriter, + const std::vector* fipnum) { - return stepImpl( simulatorTimer, solver, state, well_state, &outputWriter ); + return stepImpl( simulatorTimer, solver, state, well_state, &outputWriter, fipnum ); } @@ -169,7 +171,8 @@ namespace Opm { SimulatorReport AdaptiveTimeStepping:: stepImpl( const SimulatorTimer& simulatorTimer, Solver& solver, State& state, WState& well_state, - Output* outputWriter ) + Output* outputWriter, + const std::vector* fipnum) { SimulatorReport report; const double timestep = simulatorTimer.currentStepLength(); @@ -279,6 +282,9 @@ namespace Opm { // to write it as this will be done by the simulator // anyway. if( outputWriter && !substepTimer.done() ) { + if (fipnum) { + solver.computeFluidInPlace(state, *fipnum); + } Opm::time::StopWatch perfTimer; perfTimer.start(); bool substep = true; From 86fbb36fd2fc43672030a1d857a9f9e3b8424dfa Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Fri, 10 Feb 2017 13:01:50 +0100 Subject: [PATCH 163/163] adjustments for imported files - adjust include paths - add new test to build system - add new example to build system --- CMakeLists_files.cmake | 13 +++++++++++++ examples/wells_example.cpp | 2 +- opm/autodiff/FlowMain.hpp | 2 +- opm/autodiff/SimulatorBase.hpp | 6 +++--- opm/autodiff/SimulatorFullyImplicitBlackoilEbos.hpp | 2 +- .../SimulatorFullyImplicitBlackoilSolvent.hpp | 4 ++-- .../timestepping/AdaptiveSimulatorTimer.cpp | 2 +- .../timestepping/AdaptiveSimulatorTimer.hpp | 2 +- .../timestepping/AdaptiveTimeStepping.hpp | 4 ++-- .../timestepping/AdaptiveTimeStepping_impl.hpp | 4 ++-- opm/simulators/timestepping/SimulatorTimer.hpp | 2 +- opm/simulators/timestepping/TimeStepControl.cpp | 2 +- opm/simulators/timestepping/TimeStepControl.hpp | 2 +- tests/test_timer.cpp | 2 +- 14 files changed, 31 insertions(+), 18 deletions(-) diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index c65af9dc4..3abd6613e 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -67,6 +67,9 @@ list (APPEND MAIN_SOURCE_FILES opm/simulators/SimulatorIncompTwophase.cpp opm/simulators/WellSwitchingLogger.cpp opm/simulators/vtk/writeVtkData.cpp + opm/simulators/timestepping/TimeStepControl.cpp + opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp + opm/simulators/timestepping/SimulatorTimer.cpp ) @@ -89,6 +92,7 @@ list (APPEND TEST_SOURCE_FILES tests/test_multisegmentwells.cpp # tests/test_thresholdpressure.cpp tests/test_wellswitchlogger.cpp + tests/test_timer.cpp ) list (APPEND TEST_DATA_FILES @@ -96,6 +100,7 @@ list (APPEND TEST_DATA_FILES tests/VFPPROD1 tests/VFPPROD2 tests/msw.data + tests/TESTTIMER.DATA ) @@ -117,6 +122,7 @@ list (APPEND EXAMPLE_SOURCE_FILES examples/sim_poly2p_incomp_reorder.cpp examples/sim_poly_fi2p_comp_ad.cpp examples/flow_polymer.cpp + examples/wells_example.cpp ) # programs listed here will not only be compiled, but also marked for @@ -259,5 +265,12 @@ list (APPEND PUBLIC_HEADER_FILES opm/simulators/thresholdPressures.hpp opm/simulators/WellSwitchingLogger.hpp opm/simulators/vtk/writeVtkData.hpp + opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp + opm/simulators/timestepping/AdaptiveTimeStepping.hpp + opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp + opm/simulators/timestepping/TimeStepControl.hpp + opm/simulators/timestepping/TimeStepControlInterface.hpp + opm/simulators/timestepping/SimulatorTimer.hpp + opm/simulators/timestepping/SimulatorTimerInterface.hpp ) diff --git a/examples/wells_example.cpp b/examples/wells_example.cpp index 48f68c8b1..53c6f548e 100644 --- a/examples/wells_example.cpp +++ b/examples/wells_example.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include diff --git a/opm/autodiff/FlowMain.hpp b/opm/autodiff/FlowMain.hpp index d9b5dc8ff..62877d03f 100644 --- a/opm/autodiff/FlowMain.hpp +++ b/opm/autodiff/FlowMain.hpp @@ -48,7 +48,7 @@ #include #include #include -#include +#include #include #include #include // Note: the GridHelpers must be included before this (to make overloads available). \TODO: Fix. diff --git a/opm/autodiff/SimulatorBase.hpp b/opm/autodiff/SimulatorBase.hpp index dc5591b22..2a09f3506 100644 --- a/opm/autodiff/SimulatorBase.hpp +++ b/opm/autodiff/SimulatorBase.hpp @@ -40,8 +40,8 @@ #include #include -#include -#include +#include +#include #include #include #include @@ -49,7 +49,7 @@ #include #include -#include +#include #include #include diff --git a/opm/autodiff/SimulatorFullyImplicitBlackoilEbos.hpp b/opm/autodiff/SimulatorFullyImplicitBlackoilEbos.hpp index 871062fa0..cb83aad67 100644 --- a/opm/autodiff/SimulatorFullyImplicitBlackoilEbos.hpp +++ b/opm/autodiff/SimulatorFullyImplicitBlackoilEbos.hpp @@ -32,7 +32,7 @@ #include #include -#include +#include #include #include diff --git a/opm/autodiff/SimulatorFullyImplicitBlackoilSolvent.hpp b/opm/autodiff/SimulatorFullyImplicitBlackoilSolvent.hpp index 1cba6695a..81d095c1e 100644 --- a/opm/autodiff/SimulatorFullyImplicitBlackoilSolvent.hpp +++ b/opm/autodiff/SimulatorFullyImplicitBlackoilSolvent.hpp @@ -42,14 +42,14 @@ #include #include -//#include +//#include #include #include #include #include -//#include +//#include //#include #include diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp index 6fd59d3f1..577cbbe42 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp @@ -25,7 +25,7 @@ #include #include -#include +#include namespace Opm { diff --git a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp index 31af15b83..fd34af8c1 100644 --- a/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp +++ b/opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp @@ -26,7 +26,7 @@ #include #include -#include +#include namespace Opm { diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp index a4734fe98..74cfb99f4 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping.hpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include namespace Opm { @@ -108,5 +108,5 @@ namespace Opm { }; } -#include +#include #endif diff --git a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp index aab2413e2..440555c5f 100644 --- a/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp +++ b/opm/simulators/timestepping/AdaptiveTimeStepping_impl.hpp @@ -24,8 +24,8 @@ #include #include -#include -#include +#include +#include #include #include #include diff --git a/opm/simulators/timestepping/SimulatorTimer.hpp b/opm/simulators/timestepping/SimulatorTimer.hpp index 8b920192c..0caf225a5 100644 --- a/opm/simulators/timestepping/SimulatorTimer.hpp +++ b/opm/simulators/timestepping/SimulatorTimer.hpp @@ -21,7 +21,7 @@ #define OPM_SIMULATORTIMER_HEADER_INCLUDED #include -#include +#include #include #include diff --git a/opm/simulators/timestepping/TimeStepControl.cpp b/opm/simulators/timestepping/TimeStepControl.cpp index df25e4c44..ebbfaa428 100644 --- a/opm/simulators/timestepping/TimeStepControl.cpp +++ b/opm/simulators/timestepping/TimeStepControl.cpp @@ -29,7 +29,7 @@ #include #include -#include +#include namespace Opm { diff --git a/opm/simulators/timestepping/TimeStepControl.hpp b/opm/simulators/timestepping/TimeStepControl.hpp index 00a82d743..e0e202dbd 100644 --- a/opm/simulators/timestepping/TimeStepControl.hpp +++ b/opm/simulators/timestepping/TimeStepControl.hpp @@ -25,7 +25,7 @@ #include #include -#include +#include namespace Opm { diff --git a/tests/test_timer.cpp b/tests/test_timer.cpp index 59d1bcf74..68511f444 100644 --- a/tests/test_timer.cpp +++ b/tests/test_timer.cpp @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include