From b82a41df18f288884b39043e5d4d5fbf06225b33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 22 Apr 2013 14:02:45 +0200 Subject: [PATCH] Work in progress on tracers. - Changed interface. - Read tracerheads (tracer start locations) from file in compute_tof_from_files. - Initialize tracerheads from wells in compute_tof. --- examples/compute_tof_from_files.cpp | 21 +++++++++++++++++-- opm/core/tof/TofReorder.cpp | 31 +++++++++++++++++++---------- opm/core/tof/TofReorder.hpp | 5 +++++ 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/examples/compute_tof_from_files.cpp b/examples/compute_tof_from_files.cpp index deba61ea5..a186e0f4e 100644 --- a/examples/compute_tof_from_files.cpp +++ b/examples/compute_tof_from_files.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -120,6 +121,23 @@ main(int argc, char** argv) } } + const bool compute_tracer = param.getDefault("compute_tracer", false); + Opm::SparseTable tracerheads; + { + std::ifstream tr_stream(param.get("tracerheads_filename").c_str()); + int num_rows; + tr_stream >> num_rows; + for (int row = 0; row < num_rows; ++row) { + int row_size; + tr_stream >> row_size; + std::vector rowdata(row_size); + for (int elem = 0; elem < row_size; ++elem) { + tr_stream >> rowdata[elem]; + } + tracerheads.appendRow(rowdata.begin(), rowdata.end()); + } + } + // Choice of tof solver. bool use_dg = param.getDefault("use_dg", false); bool use_multidim_upwind = false; @@ -130,7 +148,6 @@ main(int argc, char** argv) } else { use_multidim_upwind = param.getDefault("use_multidim_upwind", false); } - bool compute_tracer = param.getDefault("compute_tracer", false); if (use_dg && compute_tracer) { THROW("DG for tracer not yet implemented."); } @@ -165,7 +182,7 @@ main(int argc, char** argv) } else { Opm::TofReorder tofsolver(grid, use_multidim_upwind); if (compute_tracer) { - tofsolver.solveTofTracer(&flux[0], &porevol[0], &src[0], tof, tracer); + tofsolver.solveTofTracer(&flux[0], &porevol[0], &src[0], tracerheads, tof, tracer); } else { tofsolver.solveTof(&flux[0], &porevol[0], &src[0], tof); } diff --git a/opm/core/tof/TofReorder.cpp b/opm/core/tof/TofReorder.cpp index 1091fbdd7..ccb35ed49 100644 --- a/opm/core/tof/TofReorder.cpp +++ b/opm/core/tof/TofReorder.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -57,9 +58,9 @@ namespace Opm /// (-) outflow flux. /// \param[out] tof Array of time-of-flight values. void TofReorder::solveTof(const double* darcyflux, - const double* porevolume, - const double* source, - std::vector& tof) + const double* porevolume, + const double* source, + std::vector& tof) { darcyflux_ = darcyflux; porevolume_ = porevolume; @@ -101,12 +102,15 @@ namespace Opm /// \param[in] source Source term. Sign convention is: /// (+) inflow flux, /// (-) outflow flux. + /// \param[in] tracerheads Table containing one row per tracer, and each + /// row contains the source cells for that tracer. /// \param[out] tof Array of time-of-flight values (1 per cell). /// \param[out] tracer Array of tracer values (N per cell, where N is /// the number of cells c for which source[c] > 0.0). void TofReorder::solveTofTracer(const double* darcyflux, const double* porevolume, const double* source, + const SparseTable& tracerheads, std::vector& tof, std::vector& tracer) { @@ -123,26 +127,33 @@ namespace Opm tof.resize(grid_.number_of_cells); std::fill(tof.begin(), tof.end(), 0.0); tof_ = &tof[0]; + // Find the tracer heads (injectors). - std::vector tracerheads; - for (int c = 0; c < grid_.number_of_cells; ++c) { - if (source[c] > 0.0) { - tracerheads.push_back(c); - } - } num_tracers_ = tracerheads.size(); tracer.resize(grid_.number_of_cells*num_tracers_); std::fill(tracer.begin(), tracer.end(), 0.0); for (int tr = 0; tr < num_tracers_; ++tr) { - tracer[tracerheads[tr]*num_tracers_ + tr] = 1.0; + for (int i = 0; i < tracerheads[tr].size(); ++i) { + const int cell = tracerheads[tr][i]; + tracer[cell*num_tracers_ + tr] = 1.0; + } } + tracer_ = &tracer[0]; if (use_multidim_upwind_) { face_tof_.resize(grid_.number_of_faces); std::fill(face_tof_.begin(), face_tof_.end(), 0.0); THROW("Multidimensional upwind not yet implemented for tracer."); } + num_multicell_ = 0; + max_size_multicell_ = 0; + max_iter_multicell_ = 0; reorderAndTransport(grid_, darcyflux); + if (num_multicell_ > 0) { + std::cout << num_multicell_ << " multicell blocks with max size " + << max_size_multicell_ << " cells in upto " + << max_iter_multicell_ << " iterations." << std::endl; + } } diff --git a/opm/core/tof/TofReorder.hpp b/opm/core/tof/TofReorder.hpp index 56ccd1129..7394ad59d 100644 --- a/opm/core/tof/TofReorder.hpp +++ b/opm/core/tof/TofReorder.hpp @@ -24,12 +24,14 @@ #include #include #include + struct UnstructuredGrid; namespace Opm { class IncompPropertiesInterface; + template class SparseTable; /// Implements a first-order finite volume solver for /// (single-phase) time-of-flight using reordering. @@ -67,12 +69,15 @@ namespace Opm /// \param[in] source Source term. Sign convention is: /// (+) inflow flux, /// (-) outflow flux. + /// \param[in] tracerheads Table containing one row per tracer, and each + /// row contains the source cells for that tracer. /// \param[out] tof Array of time-of-flight values (1 per cell). /// \param[out] tracer Array of tracer values (N per cell, where N is /// the number of cells c for which source[c] > 0.0). void solveTofTracer(const double* darcyflux, const double* porevolume, const double* source, + const SparseTable& tracerheads, std::vector& tof, std::vector& tracer);