From 66dea391a800b705ace453c111b1098f35430472 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halvor=20M=C3=B8ll=20Nilsen?= Date: Tue, 21 Aug 2012 15:23:46 +0200 Subject: [PATCH 01/12] added writing of reorder iterations for each cell --- opm/core/simulator/SimulatorTwophase.cpp | 137 ++++++++++++------ .../reorder/TransportModelTwophase.cpp | 11 +- .../reorder/TransportModelTwophase.hpp | 10 +- 3 files changed, 108 insertions(+), 50 deletions(-) diff --git a/opm/core/simulator/SimulatorTwophase.cpp b/opm/core/simulator/SimulatorTwophase.cpp index 9b5ac0e2..a2a0ad70 100644 --- a/opm/core/simulator/SimulatorTwophase.cpp +++ b/opm/core/simulator/SimulatorTwophase.cpp @@ -75,7 +75,6 @@ namespace Opm private: // Data. - // Parameters for output. bool output_; bool output_vtk_; @@ -129,8 +128,38 @@ namespace Opm return pimpl_->run(timer, state, well_state); } - - + static void reportVolumes(std::ostream &os,double satvol[2],double tot_porevol_init, + double tot_injected[2],double tot_produced[2], + double injected[2], double produced[2], + double init_satvol[2]){ + std::cout.precision(5); + const int width = 18; + os << "\nVolume balance report (all numbers relative to total pore volume).\n"; + os << " Saturated volumes: " + << std::setw(width) << satvol[0]/tot_porevol_init + << std::setw(width) << satvol[1]/tot_porevol_init << std::endl; + os << " Injected volumes: " + << std::setw(width) << injected[0]/tot_porevol_init + << std::setw(width) << injected[1]/tot_porevol_init << std::endl; + os << " Produced volumes: " + << std::setw(width) << produced[0]/tot_porevol_init + << std::setw(width) << produced[1]/tot_porevol_init << std::endl; + os << " Total inj volumes: " + << std::setw(width) << tot_injected[0]/tot_porevol_init + << std::setw(width) << tot_injected[1]/tot_porevol_init << std::endl; + os << " Total prod volumes: " + << std::setw(width) << tot_produced[0]/tot_porevol_init + << std::setw(width) << tot_produced[1]/tot_porevol_init << std::endl; + os << " In-place + prod - inj: " + << std::setw(width) << (satvol[0] + tot_produced[0] - tot_injected[0])/tot_porevol_init + << std::setw(width) << (satvol[1] + tot_produced[1] - tot_injected[1])/tot_porevol_init << std::endl; + os << " Init - now - pr + inj: " + << std::setw(width) << (init_satvol[0] - satvol[0] - tot_produced[0] + tot_injected[0])/tot_porevol_init + << std::setw(width) << (init_satvol[1] - satvol[1] - tot_produced[1] + tot_injected[1])/tot_porevol_init + << std::endl; + os.precision(8); + } + static void outputStateVtk(const UnstructuredGrid& grid, const Opm::TwophaseState& state, const int step, @@ -159,6 +188,49 @@ namespace Opm dm["velocity"] = &cell_velocity; Opm::writeVtkData(grid, dm, vtkfile); } + static void outputVectorMatlab(const std::string name, + const std::vector vec, + const int step, + const std::string& output_dir) + { + std::ostringstream fname; + fname << output_dir << "/" << name; + boost::filesystem::path fpath = fname.str(); + try { + create_directories(fpath); + } + catch (...) { + THROW("Creating directories failed: " << fpath); + } + fname << "/" << std::setw(3) << std::setfill('0') << step << ".txt"; + std::ofstream file(fname.str().c_str()); + if (!file) { + THROW("Failed to open " << fname.str()); + } + std::copy(vec.begin(), vec.end(), std::ostream_iterator(file, "\n")); + } + + static void outputVectorMatlab(const std::string name, + const std::vector vec, + const int step, + const std::string& output_dir) + { + std::ostringstream fname; + fname << output_dir << "/" << name; + boost::filesystem::path fpath = fname.str(); + try { + create_directories(fpath); + } + catch (...) { + THROW("Creating directories failed: " << fpath); + } + fname << "/" << std::setw(3) << std::setfill('0') << step << ".txt"; + std::ofstream file(fname.str().c_str()); + if (!file) { + THROW("Failed to open " << fname.str()); + } + std::copy(vec.begin(), vec.end(), std::ostream_iterator(file, "\n")); + } static void outputStateMatlab(const UnstructuredGrid& grid, @@ -221,9 +293,6 @@ namespace Opm } - - - SimulatorTwophase::Impl::Impl(const parameter::ParameterGroup& param, const UnstructuredGrid& grid, const IncompPropertiesInterface& props, @@ -341,6 +410,9 @@ namespace Opm outputStateVtk(grid_, state, timer.currentStepNum(), output_dir_); } outputStateMatlab(grid_, state, timer.currentStepNum(), output_dir_); + outputVectorMatlab(std::string("reorder_it"), + tsolver_.getReorderIterations(), + timer.currentStepNum(), output_dir_); } SimulatorReport sreport; @@ -376,8 +448,16 @@ namespace Opm stepsize, state.saturation()); Opm::computeInjectedProduced(props_, state.saturation(), transport_src, stepsize, injected, produced); if (use_segregation_split_) { - tsolver_.solveGravity(columns_, &porevol[0], stepsize, state.saturation()); + tsolver_.solveGravity(columns_, &porevol[0], stepsize, state.saturation()); } + watercut.push(timer.currentTime() + timer.currentStepLength(), + produced[0]/(produced[0] + produced[1]), + tot_produced[0]/tot_porevol_init); + if (wells_) { + wellreport.push(props_, *wells_, state.saturation(), + timer.currentTime() + timer.currentStepLength(), + well_state.bhp(), well_state.perfRates()); + } } transport_timer.stop(); double tt = transport_timer.secsSinceStart(); @@ -390,41 +470,11 @@ namespace Opm tot_injected[1] += injected[1]; tot_produced[0] += produced[0]; tot_produced[1] += produced[1]; - std::cout.precision(5); - const int width = 18; - std::cout << "\nVolume balance report (all numbers relative to total pore volume).\n"; - std::cout << " Saturated volumes: " - << std::setw(width) << satvol[0]/tot_porevol_init - << std::setw(width) << satvol[1]/tot_porevol_init << std::endl; - std::cout << " Injected volumes: " - << std::setw(width) << injected[0]/tot_porevol_init - << std::setw(width) << injected[1]/tot_porevol_init << std::endl; - std::cout << " Produced volumes: " - << std::setw(width) << produced[0]/tot_porevol_init - << std::setw(width) << produced[1]/tot_porevol_init << std::endl; - std::cout << " Total inj volumes: " - << std::setw(width) << tot_injected[0]/tot_porevol_init - << std::setw(width) << tot_injected[1]/tot_porevol_init << std::endl; - std::cout << " Total prod volumes: " - << std::setw(width) << tot_produced[0]/tot_porevol_init - << std::setw(width) << tot_produced[1]/tot_porevol_init << std::endl; - std::cout << " In-place + prod - inj: " - << std::setw(width) << (satvol[0] + tot_produced[0] - tot_injected[0])/tot_porevol_init - << std::setw(width) << (satvol[1] + tot_produced[1] - tot_injected[1])/tot_porevol_init << std::endl; - std::cout << " Init - now - pr + inj: " - << std::setw(width) << (init_satvol[0] - satvol[0] - tot_produced[0] + tot_injected[0])/tot_porevol_init - << std::setw(width) << (init_satvol[1] - satvol[1] - tot_produced[1] + tot_injected[1])/tot_porevol_init - << std::endl; - std::cout.precision(8); - - watercut.push(timer.currentTime() + timer.currentStepLength(), - produced[0]/(produced[0] + produced[1]), - tot_produced[0]/tot_porevol_init); - if (wells_) { - wellreport.push(props_, *wells_, state.saturation(), - timer.currentTime() + timer.currentStepLength(), - well_state.bhp(), well_state.perfRates()); - } + //reportVolumes(std::cout,satvol[0],&tot_porevol_init[0],&tot_injected[0]); + Opm::reportVolumes(std::cout,satvol, tot_porevol_init, + tot_injected, tot_produced, + injected, produced, + init_satvol); sreport.total_time = step_timer.secsSinceStart(); if(output_){ sreport.reportParam(tstep_os); @@ -438,6 +488,9 @@ namespace Opm outputStateVtk(grid_, state, timer.currentStepNum(), output_dir_); } outputStateMatlab(grid_, state, timer.currentStepNum(), output_dir_); + outputVectorMatlab(std::string("reorder_it"), + tsolver_.getReorderIterations(), + timer.currentStepNum(), output_dir_); outputWaterCut(watercut, output_dir_); if (wells_) { outputWellReport(wellreport, output_dir_); diff --git a/opm/core/transport/reorder/TransportModelTwophase.cpp b/opm/core/transport/reorder/TransportModelTwophase.cpp index b3630ea7..49cafa49 100644 --- a/opm/core/transport/reorder/TransportModelTwophase.cpp +++ b/opm/core/transport/reorder/TransportModelTwophase.cpp @@ -52,6 +52,7 @@ namespace Opm source_(0), dt_(0.0), saturation_(grid.number_of_cells, -1.0), + reorder_iterations_(grid.number_of_cells, 0), fractionalflow_(grid.number_of_cells, -1.0), mob_(2*grid.number_of_cells, -1.0) #ifdef EXPERIMENT_GAUSS_SEIDEL @@ -101,7 +102,7 @@ namespace Opm &seq[0], &comp[0], &ncomp, &ia_downw_[0], &ja_downw_[0]); #endif - + std::fill(reorder_iterations_.begin(),reorder_iterations_.end(),0); reorderAndTransport(grid_, darcyflux); toBothSat(saturation_, saturation); } @@ -170,9 +171,11 @@ namespace Opm // if (std::fabs(r0) < tol_) { // return; // } - int iters_used; + int iters_used=0; // saturation_[cell] = modifiedRegulaFalsi(res, smin_[2*cell], smax_[2*cell], maxit_, tol_, iters_used); saturation_[cell] = RootFinder::solve(res, saturation_[cell], 0.0, 1.0, maxit_, tol_, iters_used); + // add if it is iteration on an out loop + reorder_iterations_[cell] = reorder_iterations_[cell] + iters_used; fractionalflow_[cell] = fracFlow(saturation_[cell], cell); } @@ -544,8 +547,9 @@ namespace Opm const int cell = cells[pos]; GravityResidual res(*this, cells, pos, gravflux); if (std::fabs(res(saturation_[cell])) > tol_) { - int iters_used; + int iters_used=0; saturation_[cell] = RootFinder::solve(res, smin_[2*cell], smax_[2*cell], maxit_, tol_, iters_used); + reorder_iterations_[cell] = reorder_iterations_[cell] + iters_used; } saturation_[cell] = std::min(std::max(saturation_[cell], smin_[2*cell]), smax_[2*cell]); mobility(saturation_[cell], cell, &mob_[2*cell]); @@ -641,7 +645,6 @@ namespace Opm toBothSat(saturation_, saturation); } - } // namespace Opm diff --git a/opm/core/transport/reorder/TransportModelTwophase.hpp b/opm/core/transport/reorder/TransportModelTwophase.hpp index 74ed2bfe..69297607 100644 --- a/opm/core/transport/reorder/TransportModelTwophase.hpp +++ b/opm/core/transport/reorder/TransportModelTwophase.hpp @@ -23,7 +23,7 @@ #include #include #include - +#include struct UnstructuredGrid; namespace Opm @@ -74,7 +74,8 @@ namespace Opm const double* porevolume, const double dt, std::vector& saturation); - + void reportIterations(std::ostream &os); + const std::vector& getReorderIterations(){return reorder_iterations_;}; private: virtual void solveSingleCell(const int cell); virtual void solveMultiCell(const int num_cells, const int* cells); @@ -83,8 +84,7 @@ namespace Opm const int pos, const double* gravflux); int solveGravityColumn(const std::vector& cells); - - private: + private: const UnstructuredGrid& grid_; const IncompPropertiesInterface& props_; const double* visc_; @@ -99,6 +99,8 @@ namespace Opm double dt_; std::vector saturation_; // one per cell, only water saturation! std::vector fractionalflow_; // = m[0]/(m[0] + m[1]) per cell + std::vector reorder_iterations_; + //std::vector reorder_fval_; // For gravity segregation. std::vector gravflux_; std::vector mob_; From b448adff16d9c9921b905a56a72e6cc16afe129f Mon Sep 17 00:00:00 2001 From: Ivar Ursin Nikolaisen Date: Thu, 23 Aug 2012 14:20:41 +0200 Subject: [PATCH 02/12] Make configure.ac compatible with automake 1.12 Since automake 1.12 warnings in the category 'extra-portability' are enabled with -Wall [1]. In automake 1.11.2 the AM_PROG_AR macro was added and is required when compiling with extra-compatibility [2]. [1] http://lists.gnu.org/archive/html/automake/2012-04/msg00060.html [2] http://lists.gnu.org/archive/html/automake/2011-12/msg00055.html --- configure.ac | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/configure.ac b/configure.ac index 59d642f0..cc4b92e1 100644 --- a/configure.ac +++ b/configure.ac @@ -8,6 +8,10 @@ AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +# Needed for automake since version 1.12 because extra-portability +# warnings were then added to -Wall. Ifdef makes it backwards compatible. +m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) + AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([opm/core/grid.h]) AC_CONFIG_HEADERS([config.h]) From 24a9b8b539540c8b183d8fa81e48fe6ddd7f944b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 24 Aug 2012 08:18:59 +0200 Subject: [PATCH 03/12] Removed unneeded function numGlobalCells(). --- opm/core/fluid/RockFromDeck.cpp | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/opm/core/fluid/RockFromDeck.cpp b/opm/core/fluid/RockFromDeck.cpp index 02f67556..7ba8903f 100644 --- a/opm/core/fluid/RockFromDeck.cpp +++ b/opm/core/fluid/RockFromDeck.cpp @@ -36,8 +36,6 @@ namespace Opm PermeabilityKind fillTensor(const EclipseGridParser& parser, std::vector*>& tensor, std::tr1::array& kmap); - - int numGlobalCells(const EclipseGridParser& parser); } // anonymous namespace @@ -334,26 +332,6 @@ namespace Opm return kind; } - int numGlobalCells(const EclipseGridParser& parser) - { - int ngc = -1; - - if (parser.hasField("DIMENS")) { - const std::vector& - dims = parser.getIntegerValue("DIMENS"); - - ngc = dims[0] * dims[1] * dims[2]; - } - else if (parser.hasField("SPECGRID")) { - const SPECGRID& sgr = parser.getSPECGRID(); - - ngc = sgr.dimensions[ 0 ]; - ngc *= sgr.dimensions[ 1 ]; - ngc *= sgr.dimensions[ 2 ]; - } - - return ngc; - } } // anonymous namespace } // namespace Opm From 3f2d1773f5644c37521243d825992f0f6802edcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 24 Aug 2012 08:19:24 +0200 Subject: [PATCH 04/12] Require DIMENS or SPECGRID also for DXV, DYZ etc. grid specs. Also check that dimensions are consistent. --- opm/core/GridManager.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/opm/core/GridManager.cpp b/opm/core/GridManager.cpp index f84d1c55..04d8cd04 100644 --- a/opm/core/GridManager.cpp +++ b/opm/core/GridManager.cpp @@ -166,6 +166,16 @@ namespace Opm // Construct tensor grid from deck. void GridManager::initFromDeckTensorgrid(const Opm::EclipseGridParser& deck) { + // Extract logical cartesian size. + std::vector dims; + if (deck.hasField("DIMENS")) { + dims = deck.getIntegerValue("DIMENS"); + } else if (deck.hasField("SPECGRID")) { + dims = deck.getSPECGRID().dimensions; + } else { + THROW("Deck must have either DIMENS or SPECGRID."); + } + // Extract coordinates (or offsets from top, in case of z). const std::vector& dxv = deck.getFloatingPointValue("DXV"); const std::vector& dyv = deck.getFloatingPointValue("DYV"); @@ -174,6 +184,17 @@ namespace Opm std::vector y = coordsFromDeltas(dyv); std::vector z = coordsFromDeltas(dzv); + // Check that number of cells given are consistent with DIMENS/SPECGRID. + if (dims[0] != int(dxv.size())) { + THROW("Number of DXV data points do not match DIMENS or SPECGRID."); + } + if (dims[1] != int(dyv.size())) { + THROW("Number of DYV data points do not match DIMENS or SPECGRID."); + } + if (dims[2] != int(dzv.size())) { + THROW("Number of DZV data points do not match DIMENS or SPECGRID."); + } + // Extract top corner depths, if available. const double* top_depths = 0; std::vector top_depths_vec; From 5df2980f6d8d90c46c8fb0eac63ae7d828972d3c Mon Sep 17 00:00:00 2001 From: kristinf Date: Thu, 23 Aug 2012 13:58:41 +0200 Subject: [PATCH 05/12] First attempt at README file --- README | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 README diff --git a/README b/README new file mode 100644 index 00000000..21eb98a2 --- /dev/null +++ b/README @@ -0,0 +1,41 @@ +These are the release notes for opm-core + +Open Porous Media Core Library + +CONTENT +opm-core is the core library within OPM and contains the following + +* Eclipse preprosessing +* Fluid properties (basic PVT models and rock properties) +* Grid (generates different grids) +* Linear Algerbra (interface to different linear solvers) +* Pressure solvers (different discretization schemes, different flow models) +* Simulator (some basic examples of simulators based on sequential schemes) +* Transport solvers (different discretization schemes, different flow models) +* Utility (input and output processing, unit conversion) +* Wells (basic well handling) + +ON WHAT PLATFORMS DOES IT RUN? +The opm-core module is designed to run on linux platforms. No efforts have +been made to ensure that the code will compile and run on windows platforms. + +DOCUMENTATION +Efforts have been made to document the code with Doxygen. + +DOWNLOAD opm-core +git clone git://github.com/OPM/opm-core.git + +BUILDING opm-core +cd ../opm-core + autoreconf -i + ./configure + make + sudo make install + + +DEPENDENCIES FOR DEBIAN BASED DISTRIBUTIONS + + +DEPENDENCIES FOR SUSE BASED DISTRIBUTIONS +blas libblas3 lapack liblapack3 libboost libxml2 gcc automake autoconf git +doxygen umfpack From fd0d060ed8a585b71b3a0e36de377cd6b762d992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halvor=20M=C3=B8ll=20Nilsen?= Date: Fri, 24 Aug 2012 12:52:41 +0200 Subject: [PATCH 06/12] Corrected typing pointed out by atgeirr in respose to pullrequest --- .../simulator/SimulatorIncompTwophase.cpp | 101 +++++++++--------- .../reorder/TransportModelTwophase.cpp | 8 +- .../reorder/TransportModelTwophase.hpp | 4 +- 3 files changed, 60 insertions(+), 53 deletions(-) diff --git a/opm/core/simulator/SimulatorIncompTwophase.cpp b/opm/core/simulator/SimulatorIncompTwophase.cpp index 35b3e84b..d4e7459f 100644 --- a/opm/core/simulator/SimulatorIncompTwophase.cpp +++ b/opm/core/simulator/SimulatorIncompTwophase.cpp @@ -132,10 +132,11 @@ namespace Opm return pimpl_->run(timer, state, well_state); } - static void reportVolumes(std::ostream &os,double satvol[2],double tot_porevol_init, - double tot_injected[2],double tot_produced[2], - double injected[2], double produced[2], - double init_satvol[2]){ + static void reportVolumes(std::ostream &os,double satvol[2],double tot_porevol_init, + double tot_injected[2], double tot_produced[2], + double injected[2], double produced[2], + double init_satvol[2]) + { std::cout.precision(5); const int width = 18; os << "\nVolume balance report (all numbers relative to total pore volume).\n"; @@ -163,7 +164,7 @@ namespace Opm << std::endl; os.precision(8); } - + static void outputStateVtk(const UnstructuredGrid& grid, const Opm::TwophaseState& state, const int step, @@ -174,10 +175,10 @@ namespace Opm vtkfilename << output_dir << "/vtk_files"; boost::filesystem::path fpath(vtkfilename.str()); try { - create_directories(fpath); + create_directories(fpath); } catch (...) { - THROW("Creating directories failed: " << fpath); + THROW("Creating directories failed: " << fpath); } vtkfilename << "/" << std::setw(3) << std::setfill('0') << step << ".vtu"; std::ofstream vtkfile(vtkfilename.str().c_str()); @@ -193,47 +194,47 @@ namespace Opm Opm::writeVtkData(grid, dm, vtkfile); } static void outputVectorMatlab(const std::string name, - const std::vector vec, - const int step, - const std::string& output_dir) + const std::vector& vec, + const int step, + const std::string& output_dir) { - std::ostringstream fname; - fname << output_dir << "/" << name; - boost::filesystem::path fpath = fname.str(); - try { - create_directories(fpath); - } - catch (...) { - THROW("Creating directories failed: " << fpath); - } - fname << "/" << std::setw(3) << std::setfill('0') << step << ".txt"; - std::ofstream file(fname.str().c_str()); - if (!file) { - THROW("Failed to open " << fname.str()); - } - std::copy(vec.begin(), vec.end(), std::ostream_iterator(file, "\n")); + std::ostringstream fname; + fname << output_dir << "/" << name; + boost::filesystem::path fpath = fname.str(); + try { + create_directories(fpath); + } + catch (...) { + THROW("Creating directories failed: " << fpath); + } + fname << "/" << std::setw(3) << std::setfill('0') << step << ".txt"; + std::ofstream file(fname.str().c_str()); + if (!file) { + THROW("Failed to open " << fname.str()); + } + std::copy(vec.begin(), vec.end(), std::ostream_iterator(file, "\n")); } static void outputVectorMatlab(const std::string name, - const std::vector vec, - const int step, - const std::string& output_dir) + const std::vector vec, + const int step, + const std::string& output_dir) { - std::ostringstream fname; - fname << output_dir << "/" << name; - boost::filesystem::path fpath = fname.str(); - try { - create_directories(fpath); - } - catch (...) { - THROW("Creating directories failed: " << fpath); - } - fname << "/" << std::setw(3) << std::setfill('0') << step << ".txt"; - std::ofstream file(fname.str().c_str()); - if (!file) { - THROW("Failed to open " << fname.str()); - } - std::copy(vec.begin(), vec.end(), std::ostream_iterator(file, "\n")); + std::ostringstream fname; + fname << output_dir << "/" << name; + boost::filesystem::path fpath = fname.str(); + try { + create_directories(fpath); + } + catch (...) { + THROW("Creating directories failed: " << fpath); + } + fname << "/" << std::setw(3) << std::setfill('0') << step << ".txt"; + std::ofstream file(fname.str().c_str()); + if (!file) { + THROW("Failed to open " << fname.str()); + } + std::copy(vec.begin(), vec.end(), std::ostream_iterator(file, "\n")); } @@ -255,10 +256,10 @@ namespace Opm fname << output_dir << "/" << it->first; boost::filesystem::path fpath = fname.str(); try { - create_directories(fpath); + create_directories(fpath); } catch (...) { - THROW("Creating directories failed: " << fpath); + THROW("Creating directories failed: " << fpath); } fname << "/" << std::setw(3) << std::setfill('0') << step << ".txt"; std::ofstream file(fname.str().c_str()); @@ -543,18 +544,18 @@ namespace Opm } for (int tr_substep = 0; tr_substep < num_transport_substeps_; ++tr_substep) { tsolver_.solve(&state.faceflux()[0], &porevol[0], &transport_src[0], - stepsize, state.saturation()); + stepsize, state.saturation()); Opm::computeInjectedProduced(props_, state.saturation(), transport_src, stepsize, injected, produced); if (use_segregation_split_) { - tsolver_.solveGravity(columns_, &porevol[0], stepsize, state.saturation()); + tsolver_.solveGravity(columns_, &porevol[0], stepsize, state.saturation()); } watercut.push(timer.currentTime() + timer.currentStepLength(), produced[0]/(produced[0] + produced[1]), tot_produced[0]/tot_porevol_init); if (wells_) { - wellreport.push(props_, *wells_, state.saturation(), - timer.currentTime() + timer.currentStepLength(), - well_state.bhp(), well_state.perfRates()); + wellreport.push(props_, *wells_, state.saturation(), + timer.currentTime() + timer.currentStepLength(), + well_state.bhp(), well_state.perfRates()); } } transport_timer.stop(); diff --git a/opm/core/transport/reorder/TransportModelTwophase.cpp b/opm/core/transport/reorder/TransportModelTwophase.cpp index 49cafa49..b6451809 100644 --- a/opm/core/transport/reorder/TransportModelTwophase.cpp +++ b/opm/core/transport/reorder/TransportModelTwophase.cpp @@ -171,7 +171,7 @@ namespace Opm // if (std::fabs(r0) < tol_) { // return; // } - int iters_used=0; + int iters_used = 0; // saturation_[cell] = modifiedRegulaFalsi(res, smin_[2*cell], smax_[2*cell], maxit_, tol_, iters_used); saturation_[cell] = RootFinder::solve(res, saturation_[cell], 0.0, 1.0, maxit_, tol_, iters_used); // add if it is iteration on an out loop @@ -547,7 +547,7 @@ namespace Opm const int cell = cells[pos]; GravityResidual res(*this, cells, pos, gravflux); if (std::fabs(res(saturation_[cell])) > tol_) { - int iters_used=0; + int iters_used = 0; saturation_[cell] = RootFinder::solve(res, smin_[2*cell], smax_[2*cell], maxit_, tol_, iters_used); reorder_iterations_[cell] = reorder_iterations_[cell] + iters_used; } @@ -645,6 +645,10 @@ namespace Opm toBothSat(saturation_, saturation); } + void TransportModelTwophase::getReorderIterations() + { + return reorder_iterations_; + }; } // namespace Opm diff --git a/opm/core/transport/reorder/TransportModelTwophase.hpp b/opm/core/transport/reorder/TransportModelTwophase.hpp index 69297607..358baaa3 100644 --- a/opm/core/transport/reorder/TransportModelTwophase.hpp +++ b/opm/core/transport/reorder/TransportModelTwophase.hpp @@ -74,7 +74,9 @@ namespace Opm const double* porevolume, const double dt, std::vector& saturation); - void reportIterations(std::ostream &os); + //// Return reorder iterations + //// + //// \param[out] vector of iteration per cell const std::vector& getReorderIterations(){return reorder_iterations_;}; private: virtual void solveSingleCell(const int cell); From 7d0b9fc3b039e905ab38046bac0e5485ed0b2cdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 24 Aug 2012 13:31:23 +0200 Subject: [PATCH 07/12] Minor code cleanup in TransportModelTwophase. --- .../transport/reorder/TransportModelTwophase.cpp | 14 +++++++++----- .../transport/reorder/TransportModelTwophase.hpp | 9 +++++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/opm/core/transport/reorder/TransportModelTwophase.cpp b/opm/core/transport/reorder/TransportModelTwophase.cpp index b6451809..2740d065 100644 --- a/opm/core/transport/reorder/TransportModelTwophase.cpp +++ b/opm/core/transport/reorder/TransportModelTwophase.cpp @@ -52,8 +52,8 @@ namespace Opm source_(0), dt_(0.0), saturation_(grid.number_of_cells, -1.0), - reorder_iterations_(grid.number_of_cells, 0), fractionalflow_(grid.number_of_cells, -1.0), + reorder_iterations_(grid.number_of_cells, 0), mob_(2*grid.number_of_cells, -1.0) #ifdef EXPERIMENT_GAUSS_SEIDEL , ia_upw_(grid.number_of_cells + 1, -1), @@ -107,6 +107,13 @@ namespace Opm toBothSat(saturation_, saturation); } + + const std::vector& TransportModelTwophase::getReorderIterations() const + { + return reorder_iterations_; + } + + // Residual function r(s) for a single-cell implicit Euler transport // // r(s) = s - s0 + dt/pv*( influx + outflux*f(s) ) @@ -645,10 +652,7 @@ namespace Opm toBothSat(saturation_, saturation); } - void TransportModelTwophase::getReorderIterations() - { - return reorder_iterations_; - }; + } // namespace Opm diff --git a/opm/core/transport/reorder/TransportModelTwophase.hpp b/opm/core/transport/reorder/TransportModelTwophase.hpp index 358baaa3..3630ada8 100644 --- a/opm/core/transport/reorder/TransportModelTwophase.hpp +++ b/opm/core/transport/reorder/TransportModelTwophase.hpp @@ -74,10 +74,11 @@ namespace Opm const double* porevolume, const double dt, std::vector& saturation); - //// Return reorder iterations - //// + + //// Return the number of iterations used by the reordering solver. //// \param[out] vector of iteration per cell - const std::vector& getReorderIterations(){return reorder_iterations_;}; + const std::vector& getReorderIterations() const; + private: virtual void solveSingleCell(const int cell); virtual void solveMultiCell(const int num_cells, const int* cells); @@ -86,7 +87,7 @@ namespace Opm const int pos, const double* gravflux); int solveGravityColumn(const std::vector& cells); - private: + private: const UnstructuredGrid& grid_; const IncompPropertiesInterface& props_; const double* visc_; From b7e9fbe9a50191bd3e5d8c03c90ead8870f2d036 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halvor=20M=C3=B8ll=20Nilsen?= Date: Fri, 24 Aug 2012 13:39:42 +0200 Subject: [PATCH 08/12] Corrected mistake from moving function calls. --- opm/core/transport/reorder/TransportModelTwophase.cpp | 2 +- opm/core/transport/reorder/TransportModelTwophase.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/opm/core/transport/reorder/TransportModelTwophase.cpp b/opm/core/transport/reorder/TransportModelTwophase.cpp index b6451809..3346d28e 100644 --- a/opm/core/transport/reorder/TransportModelTwophase.cpp +++ b/opm/core/transport/reorder/TransportModelTwophase.cpp @@ -645,7 +645,7 @@ namespace Opm toBothSat(saturation_, saturation); } - void TransportModelTwophase::getReorderIterations() + const std::vector& TransportModelTwophase::getReorderIterations() { return reorder_iterations_; }; diff --git a/opm/core/transport/reorder/TransportModelTwophase.hpp b/opm/core/transport/reorder/TransportModelTwophase.hpp index 358baaa3..64449f9f 100644 --- a/opm/core/transport/reorder/TransportModelTwophase.hpp +++ b/opm/core/transport/reorder/TransportModelTwophase.hpp @@ -77,7 +77,7 @@ namespace Opm //// Return reorder iterations //// //// \param[out] vector of iteration per cell - const std::vector& getReorderIterations(){return reorder_iterations_;}; + const std::vector& getReorderIterations(); private: virtual void solveSingleCell(const int cell); virtual void solveMultiCell(const int num_cells, const int* cells); From c4608327cf9202b1755ecb4d2030b5087dc2b3f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 24 Aug 2012 13:46:16 +0200 Subject: [PATCH 09/12] Improved README in some small ways. --- README | 72 ++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 20 deletions(-) diff --git a/README b/README index 21eb98a2..54dbb531 100644 --- a/README +++ b/README @@ -1,41 +1,73 @@ -These are the release notes for opm-core - Open Porous Media Core Library +============================== + +These are release notes for opm-core. + CONTENT +------- + opm-core is the core library within OPM and contains the following -* Eclipse preprosessing +* Eclipse deck input and preprosessing * Fluid properties (basic PVT models and rock properties) -* Grid (generates different grids) -* Linear Algerbra (interface to different linear solvers) -* Pressure solvers (different discretization schemes, different flow models) -* Simulator (some basic examples of simulators based on sequential schemes) -* Transport solvers (different discretization schemes, different flow models) -* Utility (input and output processing, unit conversion) +* Grid handling (cornerpoint grids, unstructured grid interface) +* Linear Algebra (interface to different linear solvers) +* Pressure solvers (various discretization schemes, flow models) +* Simulators (some basic examples of simulators based on sequential splitting schemes) +* Transport solvers (various discretization schemes, flow models) +* Utilities (input and output processing, unit conversion) * Wells (basic well handling) -ON WHAT PLATFORMS DOES IT RUN? -The opm-core module is designed to run on linux platforms. No efforts have -been made to ensure that the code will compile and run on windows platforms. -DOCUMENTATION -Efforts have been made to document the code with Doxygen. +LICENSE +------- + +The library is distributed under the GNU General Public License, +version 3 or later (GPLv3+). + + +PLATFORMS +--------- + +The opm-core module is designed to run on Linux platforms. It is also +regularly run on Mac OS X. No efforts have been made to ensure that +the code will compile and run on windows platforms. + + +DOWNLOADING +----------- -DOWNLOAD opm-core git clone git://github.com/OPM/opm-core.git -BUILDING opm-core -cd ../opm-core - autoreconf -i + +BUILDING +-------- + + cd ../opm-core + autoreconf -i ./configure make sudo make install DEPENDENCIES FOR DEBIAN BASED DISTRIBUTIONS +------------------------------------------- + +(to be updated) DEPENDENCIES FOR SUSE BASED DISTRIBUTIONS -blas libblas3 lapack liblapack3 libboost libxml2 gcc automake autoconf git -doxygen umfpack +----------------------------------------- + +blas libblas3 lapack liblapack3 libboost libxml2 gcc automake autoconf +git doxygen umfpack + + +DOCUMENTATION +------------- + +Efforts have been made to document the code with Doxygen. +In order to build the documentation, enter the command +$ doxygen +in the topmost directory. From cd1edde45d3119a6825773831b37ad9243a79173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 27 Aug 2012 09:48:06 +0200 Subject: [PATCH 10/12] Minor revision, mostly whitespace cleanup and comments. --- examples/sim_2p_comp_reorder.cpp | 6 +++--- opm/core/pressure/CompressibleTpfa.cpp | 6 +++--- opm/core/pressure/CompressibleTpfa.hpp | 16 ++++++++-------- .../TransportModelCompressibleTwophase.cpp | 2 +- .../transport/reorder/TransportModelTwophase.hpp | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/examples/sim_2p_comp_reorder.cpp b/examples/sim_2p_comp_reorder.cpp index 22e32c37..9f2b516b 100644 --- a/examples/sim_2p_comp_reorder.cpp +++ b/examples/sim_2p_comp_reorder.cpp @@ -277,9 +277,9 @@ main(int argc, char** argv) rep.report(std::cout); if (output) { - std::string filename = output_dir + "/walltime.param"; - std::fstream tot_os(filename.c_str(),std::fstream::trunc | std::fstream::out); - rep.reportParam(tot_os); + std::string filename = output_dir + "/walltime.param"; + std::fstream tot_os(filename.c_str(),std::fstream::trunc | std::fstream::out); + rep.reportParam(tot_os); } } diff --git a/opm/core/pressure/CompressibleTpfa.cpp b/opm/core/pressure/CompressibleTpfa.cpp index 67d3a651..954e07fa 100644 --- a/opm/core/pressure/CompressibleTpfa.cpp +++ b/opm/core/pressure/CompressibleTpfa.cpp @@ -504,13 +504,13 @@ namespace Opm cq.phasemobf = &face_phasemob_[0]; cq.voldiscr = &cell_voldisc_[0]; int was_adjusted = 0; - if (rock_comp_props_ == NULL || !rock_comp_props_->isActive()) { - was_adjusted = + if (! (rock_comp_props_ && rock_comp_props_->isActive())) { + was_adjusted = cfs_tpfa_res_assemble(gg, dt, &forces, z, &cq, &trans_[0], &face_gravcap_[0], cell_press, well_bhp, &porevol_[0], h_); } else { - was_adjusted = + was_adjusted = cfs_tpfa_res_comprock_assemble(gg, dt, &forces, z, &cq, &trans_[0], &face_gravcap_[0], cell_press, well_bhp, &porevol_[0], &initial_porevol_[0], diff --git a/opm/core/pressure/CompressibleTpfa.hpp b/opm/core/pressure/CompressibleTpfa.hpp index 9fc5c43f..054ac2e4 100644 --- a/opm/core/pressure/CompressibleTpfa.hpp +++ b/opm/core/pressure/CompressibleTpfa.hpp @@ -61,7 +61,7 @@ namespace Opm /// and completions does not change during the /// run. However, controls (only) are allowed /// to change. - CompressibleTpfa(const UnstructuredGrid& grid, + CompressibleTpfa(const UnstructuredGrid& grid, const BlackoilPropertiesInterface& props, const RockCompressibility* rock_comp_props, const LinearSolverInterface& linsolver, @@ -71,8 +71,8 @@ namespace Opm const double* gravity, const Wells* wells); - /// Destructor. - ~CompressibleTpfa(); + /// Destructor. + ~CompressibleTpfa(); /// Solve the pressure equation by Newton-Raphson scheme. /// May throw an exception if the number of iterations @@ -112,11 +112,11 @@ namespace Opm void solveIncrement(); double residualNorm() const; double incrementNorm() const; - void computeResults(BlackoilState& state, + void computeResults(BlackoilState& state, WellState& well_state) const; // ------ Data that will remain unmodified after construction. ------ - const UnstructuredGrid& grid_; + const UnstructuredGrid& grid_; const BlackoilPropertiesInterface& props_; const RockCompressibility* rock_comp_props_; const LinearSolverInterface& linsolver_; @@ -125,12 +125,12 @@ namespace Opm const int maxiter_; const double* gravity_; // May be NULL const Wells* wells_; // May be NULL, outside may modify controls (only) between calls to solve(). - std::vector htrans_; - std::vector trans_ ; + std::vector htrans_; + std::vector trans_ ; std::vector allcells_; // ------ Internal data for the cfs_tpfa_res solver. ------ - struct cfs_tpfa_res_data* h_; + struct cfs_tpfa_res_data* h_; // ------ Data that will be modified for every solve. ------ std::vector wellperf_gpot_; diff --git a/opm/core/transport/reorder/TransportModelCompressibleTwophase.cpp b/opm/core/transport/reorder/TransportModelCompressibleTwophase.cpp index c2d50327..697f94a5 100644 --- a/opm/core/transport/reorder/TransportModelCompressibleTwophase.cpp +++ b/opm/core/transport/reorder/TransportModelCompressibleTwophase.cpp @@ -96,7 +96,7 @@ namespace Opm props_.viscosity(props_.numCells(), pressure, NULL, &allcells_[0], &visc_[0], NULL); props_.matrix(props_.numCells(), pressure, NULL, &allcells_[0], &A_[0], NULL); - // Check non-miscibility requirement (only done for first cell). + // Check immiscibility requirement (only done for first cell). if (A_[1] != 0.0 || A_[2] != 0.0) { THROW("TransportModelCompressibleTwophase requires a property object without miscibility."); } diff --git a/opm/core/transport/reorder/TransportModelTwophase.hpp b/opm/core/transport/reorder/TransportModelTwophase.hpp index 3630ada8..97386c8a 100644 --- a/opm/core/transport/reorder/TransportModelTwophase.hpp +++ b/opm/core/transport/reorder/TransportModelTwophase.hpp @@ -76,7 +76,7 @@ namespace Opm std::vector& saturation); //// Return the number of iterations used by the reordering solver. - //// \param[out] vector of iteration per cell + //// \return vector of iteration per cell const std::vector& getReorderIterations() const; private: From 8e5ef9ac0da5ebadccdc8c0396f3f43294efb928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 27 Aug 2012 11:19:22 +0200 Subject: [PATCH 11/12] Fixed bug in matrix multiplication (matrix has Fortran element order). --- opm/core/utility/miscUtilitiesBlackoil.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/core/utility/miscUtilitiesBlackoil.cpp b/opm/core/utility/miscUtilitiesBlackoil.cpp index 548aaa23..74eb1c9c 100644 --- a/opm/core/utility/miscUtilitiesBlackoil.cpp +++ b/opm/core/utility/miscUtilitiesBlackoil.cpp @@ -245,7 +245,7 @@ namespace Opm for (int i = 0; i < n; ++i) { for (int row = 0; row < np; ++row) { for (int col = 0; col < np; ++col) { - surfacevol[i*np + row] += A[i*np*np + row*np + col] * saturation[i*np + col]; + surfacevol[i*np + row] += A[i*np*np + row + col*np] * saturation[i*np + col]; } } } From 80e54a93d07d11f62974276bc114649da3be4c52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 27 Aug 2012 13:17:27 +0200 Subject: [PATCH 12/12] Switch loop ordering for better cache performance. --- opm/core/utility/miscUtilitiesBlackoil.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opm/core/utility/miscUtilitiesBlackoil.cpp b/opm/core/utility/miscUtilitiesBlackoil.cpp index 74eb1c9c..6f4f7556 100644 --- a/opm/core/utility/miscUtilitiesBlackoil.cpp +++ b/opm/core/utility/miscUtilitiesBlackoil.cpp @@ -243,8 +243,8 @@ namespace Opm // matrix data. std::fill(surfacevol, surfacevol + n*np, 0.0); for (int i = 0; i < n; ++i) { - for (int row = 0; row < np; ++row) { - for (int col = 0; col < np; ++col) { + for (int col = 0; col < np; ++col) { + for (int row = 0; row < np; ++row) { surfacevol[i*np + row] += A[i*np*np + row + col*np] * saturation[i*np + col]; } }