Go to the documentation of this file.
28#ifndef OPM_GENERIC_TRACER_MODEL_IMPL_HPP
29#define OPM_GENERIC_TRACER_MODEL_IMPL_HPP
31#include <dune/istl/operators.hh>
32#include <dune/istl/solvers.hh>
33#include <dune/istl/schwarz.hh>
34#include <dune/istl/preconditioners.hh>
35#include <dune/istl/schwarz.hh>
37#include <opm/common/OpmLog/OpmLog.hpp>
38#include <opm/common/TimingMacros.hpp>
40#include <opm/grid/CpGrid.hpp>
42#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
43#include <opm/input/eclipse/EclipseState/Tables/TracerVdTable.hpp>
44#include <opm/input/eclipse/Schedule/Well/Well.hpp>
45#include <opm/input/eclipse/Schedule/Well/WellTracerProperties.hpp>
54#include <fmt/format.h>
66template< class M, class V>
69 using Comm = Dune::OwnerOverlapCopyCommunication<int, int>;
74template< class Vector, class Gr id, class Matrix>
75std::tuple<std::unique_ptr<Dune::OverlappingSchwarzOperator<Matrix,Vector,Vector,
76 Dune::OwnerOverlapCopyCommunication<int,int>>>,
77 std::unique_ptr<typename TracerSolverSelector<Matrix,Vector>::type>>
80 OPM_THROW(std::logic_error, "Grid not supported for parallel Tracers.");
81 return { nullptr, nullptr};
84template< class Vector, class Matrix>
85std::tuple<std::unique_ptr<Dune::OverlappingSchwarzOperator<Matrix,Vector,Vector,
86 Dune::OwnerOverlapCopyCommunication<int,int>>>,
87 std::unique_ptr<typename TracerSolverSelector<Matrix,Vector>::type>>
90 using TracerOperator = Dune::OverlappingSchwarzOperator<Matrix,Vector,Vector,
91 Dune::OwnerOverlapCopyCommunication<int,int>>;
93 const auto& cellComm = grid.cellCommunication();
94 auto op = std::make_unique<TracerOperator>(M, cellComm);
95 auto dummyWeights = [](){ return Vector();};
96 return {std::move(op), std::make_unique<TracerSolver>(*op, cellComm, prm, dummyWeights, 0)};
100template< class Gr id, class Gr idView, class DofMapper, class Stencil, class Flu idSystem, class Scalar>
103 const EclipseState& eclState,
105 const DofMapper& dofMapper,
106 const std::function<std::array<double,dimWorld>( int)> centroids)
107 : gridView_(gridView)
108 , eclState_(eclState)
109 , cartMapper_(cartMapper)
110 , dofMapper_(dofMapper)
111 , centroids_(centroids)
115template< class Gr id, class Gr idView, class DofMapper, class Stencil, class Flu idSystem, class Scalar>
119 if (freeTracerConcentration_.empty()) {
123 return freeTracerConcentration_[tracerIdx][globalDofIdx];
126template< class Gr id, class Gr idView, class DofMapper, class Stencil, class Flu idSystem, class Scalar>
130 if (solTracerConcentration_.empty()) {
134 return solTracerConcentration_[tracerIdx][globalDofIdx];
137template< class Gr id, class Gr idView, class DofMapper, class Stencil, class Flu idSystem, class Scalar>
141 this->freeTracerConcentration_[tracerIdx][globalDofIdx] = value;
142 this->tracerConcentration_[tracerIdx][globalDofIdx][0] = value;
145template< class Gr id, class Gr idView, class DofMapper, class Stencil, class Flu idSystem, class Scalar>
149 this->solTracerConcentration_[tracerIdx][globalDofIdx] = value;
150 this->tracerConcentration_[tracerIdx][globalDofIdx][1] = value;
153template< class Gr id, class Gr idView, class DofMapper, class Stencil, class Flu idSystem, class Scalar>
157 this->enableSolTracers_[tracerIdx] = enableSolTracer;
160template< class Gr id, class Gr idView, class DofMapper, class Stencil, class Flu idSystem, class Scalar>
164 return this->eclState_.tracer().size();
167template< class Gr id, class Gr idView, class DofMapper, class Stencil, class Flu idSystem, class Scalar>
169fname( int tracerIdx) const
171 return this->eclState_.tracer()[tracerIdx].fname();
174template< class Gr id, class Gr idView, class DofMapper, class Stencil, class Flu idSystem, class Scalar>
176sname( int tracerIdx) const
178 return this->eclState_.tracer()[tracerIdx].sname();
181template< class Gr id, class Gr idView, class DofMapper, class Stencil, class Flu idSystem, class Scalar>
185 return this->eclState_.tracer()[tracerIdx].wellfname();
188template< class Gr id, class Gr idView, class DofMapper, class Stencil, class Flu idSystem, class Scalar>
192 return this->eclState_.tracer()[tracerIdx].wellsname();
195template< class Gr id, class Gr idView, class DofMapper, class Stencil, class Flu idSystem, class Scalar>
197phase( int tracerIdx) const
199 return this->eclState_.tracer()[tracerIdx].phase;
202template< class Gr id, class Gr idView, class DofMapper, class Stencil, class Flu idSystem, class Scalar>
206 return this->enableSolTracers_;
209template< class Gr id, class Gr idView, class DofMapper, class Stencil, class Flu idSystem, class Scalar>
213 return eclWell.getTracerProperties().getConcentration(name);
216template< class Gr id, class Gr idView, class DofMapper, class Stencil, class Flu idSystem, class Scalar>
218name( int tracerIdx) const
220 return this->eclState_.tracer()[tracerIdx].name;
223template< class Gr id, class Gr idView, class DofMapper, class Stencil, class Flu idSystem, class Scalar>
225doInit( bool rst, std::size_t numGridDof,
226 std::size_t gasPhaseIdx, std::size_t oilPhaseIdx, std::size_t waterPhaseIdx)
228 const auto& tracers = eclState_.tracer();
230 if (tracers.size() == 0) {
235 const std::size_t numTracers = tracers.size();
236 enableSolTracers_.resize(numTracers);
237 tracerConcentration_.resize(numTracers);
238 freeTracerConcentration_.resize(numTracers);
239 solTracerConcentration_.resize(numTracers);
242 tracerPhaseIdx_.resize(numTracers);
243 for (std::size_t tracerIdx = 0; tracerIdx < numTracers; tracerIdx++) {
244 const auto& tracer = tracers[tracerIdx];
246 if (tracer.phase == Phase::WATER)
247 tracerPhaseIdx_[tracerIdx] = waterPhaseIdx;
248 else if (tracer.phase == Phase::OIL)
249 tracerPhaseIdx_[tracerIdx] = oilPhaseIdx;
250 else if (tracer.phase == Phase::GAS)
251 tracerPhaseIdx_[tracerIdx] = gasPhaseIdx;
253 tracerConcentration_[tracerIdx].resize(numGridDof);
254 freeTracerConcentration_[tracerIdx].resize(numGridDof);
255 solTracerConcentration_[tracerIdx].resize(numGridDof);
262 if (tracer.free_concentration.has_value()){
263 const auto& free_concentration = tracer.free_concentration.value();
264 int tblkDatasize = free_concentration.size();
265 if (tblkDatasize < cartMapper_.cartesianSize()){
266 throw std::runtime_error( "Wrong size of TBLKF for" + tracer.name);
268 for (std::size_t globalDofIdx = 0; globalDofIdx < numGridDof; ++globalDofIdx) {
269 int cartDofIdx = cartMapper_.cartesianIndex(globalDofIdx);
270 tracerConcentration_[tracerIdx][globalDofIdx][0] = free_concentration[cartDofIdx];
271 freeTracerConcentration_[tracerIdx][globalDofIdx] = free_concentration[cartDofIdx];
275 else if (tracer.free_tvdp.has_value()) {
276 const auto& free_tvdp = tracer.free_tvdp.value();
277 for (std::size_t globalDofIdx = 0; globalDofIdx < numGridDof; ++globalDofIdx) {
278 tracerConcentration_[tracerIdx][globalDofIdx][0] =
279 free_tvdp.evaluate( "TRACER_CONCENTRATION",
280 centroids_(globalDofIdx)[2]);
281 freeTracerConcentration_[tracerIdx][globalDofIdx] =
282 free_tvdp.evaluate( "TRACER_CONCENTRATION",
283 centroids_(globalDofIdx)[2]);
287 OpmLog::warning(fmt::format( "No TBLKF or TVDPF given for free tracer {}. "
288 "Initial values set to zero. ", tracer.name));
289 for (std::size_t globalDofIdx = 0; globalDofIdx < numGridDof; ++globalDofIdx) {
290 tracerConcentration_[tracerIdx][globalDofIdx][0] = 0.0;
291 freeTracerConcentration_[tracerIdx][globalDofIdx] = 0.0;
296 if (tracer.phase != Phase::WATER &&
297 ((tracer.phase == Phase::GAS && FluidSystem::enableDissolvedGas()) ||
298 (tracer.phase == Phase::OIL && FluidSystem::enableVaporizedOil()))) {
300 if (tracer.solution_concentration.has_value()){
301 enableSolTracers_[tracerIdx] = true;
302 const auto& solution_concentration = tracer.solution_concentration.value();
303 int tblkDatasize = solution_concentration.size();
304 if (tblkDatasize < cartMapper_.cartesianSize()){
305 throw std::runtime_error( "Wrong size of TBLKS for" + tracer.name);
307 for (std::size_t globalDofIdx = 0; globalDofIdx < numGridDof; ++globalDofIdx) {
308 int cartDofIdx = cartMapper_.cartesianIndex(globalDofIdx);
309 tracerConcentration_[tracerIdx][globalDofIdx][1] = solution_concentration[cartDofIdx];
310 solTracerConcentration_[tracerIdx][globalDofIdx] = solution_concentration[cartDofIdx];
314 else if (tracer.solution_tvdp.has_value()) {
315 enableSolTracers_[tracerIdx] = true;
316 const auto& solution_tvdp = tracer.solution_tvdp.value();
317 for (std::size_t globalDofIdx = 0; globalDofIdx < numGridDof; ++globalDofIdx) {
318 tracerConcentration_[tracerIdx][globalDofIdx][1] =
319 solution_tvdp.evaluate( "TRACER_CONCENTRATION",
320 centroids_(globalDofIdx)[2]);
321 solTracerConcentration_[tracerIdx][globalDofIdx] =
322 solution_tvdp.evaluate( "TRACER_CONCENTRATION",
323 centroids_(globalDofIdx)[2]);
328 enableSolTracers_[tracerIdx] = false;
329 OpmLog::warning(fmt::format( "No TBLKS or TVDPS given for solution tracer {}. "
330 "Initial values set to zero. ", tracer.name));
331 for (std::size_t globalDofIdx = 0; globalDofIdx < numGridDof; ++globalDofIdx) {
332 tracerConcentration_[tracerIdx][globalDofIdx][1] = 0.0;
333 solTracerConcentration_[tracerIdx][globalDofIdx] = 0.0;
339 enableSolTracers_[tracerIdx] = false;
340 for (std::size_t globalDofIdx = 0; globalDofIdx < numGridDof; ++globalDofIdx) {
341 tracerConcentration_[tracerIdx][globalDofIdx][1] = 0.0;
342 solTracerConcentration_[tracerIdx][globalDofIdx] = 0.0;
348 tracerMatrix_ = std::make_unique<TracerMatrix>(numGridDof, numGridDof, TracerMatrix::random);
351 using NeighborSet = std::set<unsigned>;
352 std::vector<NeighborSet> neighbors(numGridDof);
354 Stencil stencil(gridView_, dofMapper_);
355 for ( const auto& elem : elements(gridView_)) {
356 stencil.update(elem);
358 for ( unsigned primaryDofIdx = 0; primaryDofIdx < stencil.numPrimaryDof(); ++primaryDofIdx) {
359 unsigned myIdx = stencil.globalSpaceIndex(primaryDofIdx);
361 for ( unsigned dofIdx = 0; dofIdx < stencil.numDof(); ++dofIdx) {
362 unsigned neighborIdx = stencil.globalSpaceIndex(dofIdx);
363 neighbors[myIdx].insert(neighborIdx);
369 for ( unsigned dofIdx = 0; dofIdx < numGridDof; ++ dofIdx) {
370 tracerMatrix_->setrowsize(dofIdx, neighbors[dofIdx].size());
372 tracerMatrix_->endrowsizes();
377 for ( unsigned dofIdx = 0; dofIdx < numGridDof; ++ dofIdx) {
378 for ( const auto& index : neighbors[dofIdx]) {
379 tracerMatrix_->addindex(dofIdx, index);
382 tracerMatrix_->endindices();
385template< class Gr id, class Gr idView, class DofMapper, class Stencil, class Flu idSystem, class Scalar>
390 Scalar tolerance = 1e-2;
395 prm. put( "maxiter", maxIter);
396 prm. put( "tol", tolerance);
397 prm. put( "verbosity", verbosity);
398 prm. put( "solver", std::string( "bicgstab"));
399 prm. put( "preconditioner.type", std::string( "ParOverILU0"));
402 if(gridView_.grid().comm().size() > 1)
404 auto [tracerOperator, solver] =
405 createParallelFlexibleSolver<TracerVector>(gridView_.grid(), M, prm);
406 (void) tracerOperator;
409 solver->apply(x, b, result);
412 return result.converged;
417 using TracerSolver = Dune::BiCGSTABSolver<TracerVector>;
418 using TracerOperator = Dune::MatrixAdapter<TracerMatrix,TracerVector,TracerVector>;
419 using TracerScalarProduct = Dune::SeqScalarProduct<TracerVector>;
420 using TracerPreconditioner = Dune::SeqILU< TracerMatrix,TracerVector,TracerVector>;
422 TracerOperator tracerOperator(M);
423 TracerScalarProduct tracerScalarProduct;
424 TracerPreconditioner tracerPreconditioner(M, 0, 1);
426 TracerSolver solver (tracerOperator, tracerScalarProduct,
427 tracerPreconditioner, tolerance, maxIter,
431 solver.apply(x, b, result);
434 return result.converged;
440template< class Gr id, class Gr idView, class DofMapper, class Stencil, class Flu idSystem, class Scalar>
444 OPM_TIMEBLOCK(tracerSolve);
445 const Scalar tolerance = 1e-2;
446 const int maxIter = 100;
447 const int verbosity = 0;
450 if (gridView_.grid().comm().size() > 1)
453 prm. put( "maxiter", maxIter);
454 prm. put( "tol", tolerance);
455 prm. put( "verbosity", verbosity);
456 prm. put( "solver", std::string( "bicgstab"));
457 prm. put( "preconditioner.type", std::string( "ParOverILU0"));
458 auto [tracerOperator, solver] =
459 createParallelFlexibleSolver<TracerVector>(gridView_.grid(), M, prm);
460 (void) tracerOperator;
461 bool converged = true;
462 for (std::size_t nrhs = 0; nrhs < b.size(); ++nrhs) {
465 solver->apply(x[nrhs], b[nrhs], result);
466 converged = (converged && result.converged);
473 using TracerSolver = Dune::BiCGSTABSolver<TracerVector>;
474 using TracerOperator = Dune::MatrixAdapter<TracerMatrix,TracerVector,TracerVector>;
475 using TracerScalarProduct = Dune::SeqScalarProduct<TracerVector>;
476 using TracerPreconditioner = Dune::SeqILU<TracerMatrix,TracerVector,TracerVector>;
478 if (std::all_of(b.begin(), b.end(),
479 []( const auto& v) { return v.infinity_norm() == 0.0; }))
484 TracerOperator tracerOperator(M);
485 TracerScalarProduct tracerScalarProduct;
486 TracerPreconditioner tracerPreconditioner(M, 0, 1);
488 TracerSolver solver (tracerOperator, tracerScalarProduct,
489 tracerPreconditioner, tolerance, maxIter,
492 bool converged = true;
493 for (std::size_t nrhs = 0; nrhs < b.size(); ++nrhs) {
496 solver.apply(x[nrhs], b[nrhs], result);
497 converged = (converged && result.converged);
Definition: CollectDataOnIORank.hpp:49
Definition: FlexibleSolver.hpp:45
void setEnableSolTracers(int tracerIdx, bool enableSolTracer) Definition: GenericTracerModel_impl.hpp:155
int numTracers() const Return the number of tracers considered by the tracerModel. Definition: GenericTracerModel_impl.hpp:162
Scalar currentConcentration_(const Well &eclWell, const std::string &name) const Definition: GenericTracerModel_impl.hpp:211
void doInit(bool rst, std::size_t numGridDof, std::size_t gasPhaseIdx, std::size_t oilPhaseIdx, std::size_t waterPhaseIdx) Initialize all internal data structures needed by the tracer module. Definition: GenericTracerModel_impl.hpp:225
std::string sname(int tracerIdx) const Definition: GenericTracerModel_impl.hpp:176
void setSolTracerConcentration(int tracerIdx, int globalDofIdx, Scalar value) Definition: GenericTracerModel_impl.hpp:147
std::string wellfname(int tracerIdx) const Definition: GenericTracerModel_impl.hpp:183
GenericTracerModel(const GridView &gridView, const EclipseState &eclState, const CartesianIndexMapper &cartMapper, const DofMapper &dofMapper, const std::function< std::array< double, dimWorld >(int)> centroids) Definition: GenericTracerModel_impl.hpp:102
const std::string & name(int tracerIdx) const Return the tracer name. Definition: GenericTracerModel_impl.hpp:218
const std::vector< bool > & enableSolTracers() const Definition: GenericTracerModel_impl.hpp:204
Phase phase(int tracerIdx) const Definition: GenericTracerModel_impl.hpp:197
std::string wellsname(int tracerIdx) const Definition: GenericTracerModel_impl.hpp:190
std::string fname(int tracerIdx) const Definition: GenericTracerModel_impl.hpp:169
bool linearSolve_(const TracerMatrix &M, TracerVector &x, TracerVector &b) Definition: GenericTracerModel_impl.hpp:387
Dune::BlockVector< Dune::FieldVector< Scalar, 2 > > TracerVector Definition: GenericTracerModel.hpp:60
void setFreeTracerConcentration(int tracerIdx, int globalDofIdx, Scalar value) Definition: GenericTracerModel_impl.hpp:139
Scalar solTracerConcentration(int tracerIdx, int globalDofIdx) const Definition: GenericTracerModel_impl.hpp:128
bool linearSolveBatchwise_(const TracerMatrix &M, std::vector< TracerVector > &x, std::vector< TracerVector > &b) Definition: GenericTracerModel_impl.hpp:442
Dune::BCRSMatrix< Opm::MatrixBlock< Scalar, 2, 2 > > TracerMatrix Definition: GenericTracerModel.hpp:59
Scalar freeTracerConcentration(int tracerIdx, int globalDofIdx) const Return the tracer concentration for tracer index and global DofIdx. Definition: GenericTracerModel_impl.hpp:117
Hierarchical collection of key/value pairs. Definition: PropertyTree.hpp:39
void put(const std::string &key, const T &data)
Definition: blackoilboundaryratevector.hh:39
Dune::InverseOperatorResult InverseOperatorResult Definition: GpuBridge.hpp:32
std::tuple< std::unique_ptr< Dune::OverlappingSchwarzOperator< Matrix, Vector, Vector, Dune::OwnerOverlapCopyCommunication< int, int > > >, std::unique_ptr< typename TracerSolverSelector< Matrix, Vector >::type > > createParallelFlexibleSolver(const Grid &, const Matrix &, const PropertyTree &) Definition: GenericTracerModel_impl.hpp:78
Definition: GenericTracerModel_impl.hpp:68
Dune::FlexibleSolver< TracerOperator > type Definition: GenericTracerModel_impl.hpp:71
Dune::OverlappingSchwarzOperator< M, V, V, Comm > TracerOperator Definition: GenericTracerModel_impl.hpp:70
Dune::OwnerOverlapCopyCommunication< int, int > Comm Definition: GenericTracerModel_impl.hpp:69
|