mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Moved PolymerInflow* classes to separate file.
Also, implemented PolymerInflowFromDeck (but not yet used).
This commit is contained in:
parent
6033e5ca69
commit
0428c4abb4
@ -13,6 +13,7 @@ opm/polymer/SimulatorPolymer.cpp \
|
|||||||
opm/polymer/SimulatorCompressiblePolymer.cpp \
|
opm/polymer/SimulatorCompressiblePolymer.cpp \
|
||||||
opm/polymer/TransportModelPolymer.cpp \
|
opm/polymer/TransportModelPolymer.cpp \
|
||||||
opm/polymer/TransportModelCompressiblePolymer.cpp \
|
opm/polymer/TransportModelCompressiblePolymer.cpp \
|
||||||
|
opm/polymer/PolymerInflow.cpp \
|
||||||
opm/polymer/PolymerProperties.cpp \
|
opm/polymer/PolymerProperties.cpp \
|
||||||
opm/polymer/polymerUtilities.cpp
|
opm/polymer/polymerUtilities.cpp
|
||||||
|
|
||||||
@ -22,6 +23,7 @@ opm/polymer/GravityColumnSolverPolymer_impl.hpp \
|
|||||||
opm/polymer/IncompPropertiesDefaultPolymer.hpp \
|
opm/polymer/IncompPropertiesDefaultPolymer.hpp \
|
||||||
opm/polymer/IncompTpfaPolymer.hpp \
|
opm/polymer/IncompTpfaPolymer.hpp \
|
||||||
opm/polymer/CompressibleTpfaPolymer.hpp \
|
opm/polymer/CompressibleTpfaPolymer.hpp \
|
||||||
|
opm/polymer/PolymerInflow.hpp \
|
||||||
opm/polymer/PolymerProperties.hpp \
|
opm/polymer/PolymerProperties.hpp \
|
||||||
opm/polymer/PolymerState.hpp \
|
opm/polymer/PolymerState.hpp \
|
||||||
opm/polymer/SinglePointUpwindTwoPhasePolymer.hpp \
|
opm/polymer/SinglePointUpwindTwoPhasePolymer.hpp \
|
||||||
|
118
opm/polymer/PolymerInflow.cpp
Normal file
118
opm/polymer/PolymerInflow.cpp
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <opm/polymer/PolymerInflow.hpp>
|
||||||
|
#include <opm/core/eclipse/EclipseGridParser.hpp>
|
||||||
|
#include <opm/core/newwells.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace Opm
|
||||||
|
{
|
||||||
|
|
||||||
|
// ---------- Methods of PolymerInflowBasic ----------
|
||||||
|
|
||||||
|
/// Constructor.
|
||||||
|
/// @param[in] starttime Start time of injection in seconds.
|
||||||
|
/// @param[in] endtime End time of injection in seconds.
|
||||||
|
/// @param[in] amount Amount to be injected per second.
|
||||||
|
PolymerInflowBasic::PolymerInflowBasic(const double starttime,
|
||||||
|
const double endtime,
|
||||||
|
const double amount)
|
||||||
|
: stime_(starttime), etime_(endtime), amount_(amount)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolymerInflowBasic::getInflowValues(const double step_start,
|
||||||
|
const double step_end,
|
||||||
|
std::vector<double>& poly_inflow_c)
|
||||||
|
{
|
||||||
|
const double eps = 1e-5*(step_end - step_start);
|
||||||
|
if (step_start + eps >= stime_ && step_end - eps <= etime_) {
|
||||||
|
std::fill(poly_inflow_c.begin(), poly_inflow_c.end(), amount_);
|
||||||
|
} else if (step_start + eps <= etime_ && step_end - eps >= stime_) {
|
||||||
|
MESSAGE("Warning: polymer injection set to change inside timestep. Using value at start of step.");
|
||||||
|
std::fill(poly_inflow_c.begin(), poly_inflow_c.end(), amount_);
|
||||||
|
} else {
|
||||||
|
std::fill(poly_inflow_c.begin(), poly_inflow_c.end(), 0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------- Methods of PolymerInflowFromDeck ----------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// Constructor.
|
||||||
|
/// @param[in] deck Input deck expected to contain WPOLYMER.
|
||||||
|
PolymerInflowFromDeck::PolymerInflowFromDeck(const EclipseGridParser& deck,
|
||||||
|
const Wells& wells,
|
||||||
|
const int num_cells)
|
||||||
|
: sparse_inflow_(num_cells)
|
||||||
|
{
|
||||||
|
if (!deck.hasField("WPOLYMER")) {
|
||||||
|
THROW("PolymerInflowFromDeck requires WPOLYMER in deck.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract concentrations and put into cell->concentration map.
|
||||||
|
const std::vector<WpolymerLine>& wpl = deck.getWPOLYMER().wpolymer_;
|
||||||
|
const int num_wpl = wpl.size();
|
||||||
|
std::map<int, double> perfcell_conc;
|
||||||
|
for (int i = 0; i < num_wpl; ++i) {
|
||||||
|
// Only use well name and polymer concentration.
|
||||||
|
// That is, we ignore salt concentration and group
|
||||||
|
// names.
|
||||||
|
int wix = 0;
|
||||||
|
for (; wix < wells.number_of_wells; ++wix) {
|
||||||
|
if (wpl[i].well_ == wells.name[wix]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (wix == wells.number_of_wells) {
|
||||||
|
THROW("Could not find a match for well " << wpl[i].well_ << " from WPOLYMER.");
|
||||||
|
}
|
||||||
|
for (int j = wells.well_connpos[wix]; j < wells.well_connpos[wix+1]; ++j) {
|
||||||
|
const int perf_cell = wells.well_cells[j];
|
||||||
|
perfcell_conc[perf_cell] = wpl[i].polymer_concentration_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build sparse vector from map.
|
||||||
|
std::map<int, double>::const_iterator it = perfcell_conc.begin();
|
||||||
|
for (; it != perfcell_conc.end(); ++it) {
|
||||||
|
sparse_inflow_.addElement(it->second, it->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PolymerInflowFromDeck::getInflowValues(const double /*step_start*/,
|
||||||
|
const double /*step_end*/,
|
||||||
|
std::vector<double>& poly_inflow_c)
|
||||||
|
{
|
||||||
|
// This method does not depend on the given time,
|
||||||
|
// instead one would have a new epoch (and create a new
|
||||||
|
// instance) for each change in WPOLYMER.
|
||||||
|
std::fill(poly_inflow_c.begin(), poly_inflow_c.end(), 0.0);
|
||||||
|
const int nnz = sparse_inflow_.nonzeroSize();
|
||||||
|
for (int i = 0; i < nnz; ++i) {
|
||||||
|
poly_inflow_c[sparse_inflow_.nonzeroIndex(i)] = sparse_inflow_.nonzeroElement(i) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Opm
|
113
opm/polymer/PolymerInflow.hpp
Normal file
113
opm/polymer/PolymerInflow.hpp
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OPM_POLYMERINFLOW_HEADER_INCLUDED
|
||||||
|
#define OPM_POLYMERINFLOW_HEADER_INCLUDED
|
||||||
|
|
||||||
|
#include <opm/core/utility/SparseVector.hpp>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct Wells;
|
||||||
|
|
||||||
|
namespace Opm
|
||||||
|
{
|
||||||
|
|
||||||
|
class EclipseGridParser;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// @brief Interface for classes encapsulating polymer inflow information.
|
||||||
|
class PolymerInflowInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Virtual destructor for subclassing.
|
||||||
|
virtual ~PolymerInflowInterface() {}
|
||||||
|
|
||||||
|
/// Get inflow concentrations for all cells.
|
||||||
|
/// \param[in] step_start Start of timestep.
|
||||||
|
/// \param[in] step_end End of timestep.
|
||||||
|
/// \param[out] poly_inflow_c Injection concentrations to use for timestep, per cell.
|
||||||
|
/// Must be properly sized before calling.
|
||||||
|
virtual void getInflowValues(const double step_start,
|
||||||
|
const double step_end,
|
||||||
|
std::vector<double>& poly_inflow_c) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// @brief Basic polymer injection behaviour class.
|
||||||
|
/// This class gives all injectors the same polymer concentration,
|
||||||
|
/// during a single time interval. Amount and interval can be specified.
|
||||||
|
class PolymerInflowBasic : public PolymerInflowInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Constructor.
|
||||||
|
/// \param[in] starttime Start time of injection in seconds.
|
||||||
|
/// \param[in] endtime End time of injection in seconds.
|
||||||
|
/// \param[in] amount Amount to be injected per second.
|
||||||
|
PolymerInflowBasic(const double starttime,
|
||||||
|
const double endtime,
|
||||||
|
const double amount);
|
||||||
|
|
||||||
|
/// Get inflow concentrations for all cells.
|
||||||
|
/// \param[in] step_start Start of timestep.
|
||||||
|
/// \param[in] step_end End of timestep.
|
||||||
|
/// \param[out] poly_inflow_c Injection concentrations to use for timestep, per cell.
|
||||||
|
/// Must be properly sized before calling.
|
||||||
|
virtual void getInflowValues(const double step_start,
|
||||||
|
const double step_end,
|
||||||
|
std::vector<double>& poly_inflow_c);
|
||||||
|
private:
|
||||||
|
double stime_;
|
||||||
|
double etime_;
|
||||||
|
double amount_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// @brief Polymer injection behaviour class using deck WPOLYMER.
|
||||||
|
/// This class reads the accumulated WPOLYMER lines from the deck,
|
||||||
|
/// and applies the last row given for each well.
|
||||||
|
class PolymerInflowFromDeck : public PolymerInflowInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Constructor.
|
||||||
|
/// \param[in] deck Input deck expected to contain WPOLYMER.
|
||||||
|
/// \param[in] wells Wells structure.
|
||||||
|
/// \param[in] num_cells Number of cells in grid.
|
||||||
|
PolymerInflowFromDeck(const EclipseGridParser& deck,
|
||||||
|
const Wells& wells,
|
||||||
|
const int num_cells);
|
||||||
|
|
||||||
|
/// Get inflow concentrations for all cells.
|
||||||
|
/// \param[in] step_start Start of timestep.
|
||||||
|
/// \param[in] step_end End of timestep.
|
||||||
|
/// \param[out] poly_inflow_c Injection concentrations to use for timestep, per cell.
|
||||||
|
/// Must be properly sized before calling.
|
||||||
|
virtual void getInflowValues(const double /*step_start*/,
|
||||||
|
const double /*step_end*/,
|
||||||
|
std::vector<double>& poly_inflow_c);
|
||||||
|
private:
|
||||||
|
SparseVector<double> sparse_inflow_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Opm
|
||||||
|
|
||||||
|
|
||||||
|
#endif // OPM_POLYMERINFLOW_HEADER_INCLUDED
|
@ -48,6 +48,7 @@
|
|||||||
#include <opm/polymer/PolymerBlackoilState.hpp>
|
#include <opm/polymer/PolymerBlackoilState.hpp>
|
||||||
#include <opm/core/simulator/WellState.hpp>
|
#include <opm/core/simulator/WellState.hpp>
|
||||||
#include <opm/polymer/TransportModelCompressiblePolymer.hpp>
|
#include <opm/polymer/TransportModelCompressiblePolymer.hpp>
|
||||||
|
#include <opm/polymer/PolymerInflow.hpp>
|
||||||
#include <opm/polymer/PolymerProperties.hpp>
|
#include <opm/polymer/PolymerProperties.hpp>
|
||||||
#include <opm/polymer/polymerUtilities.hpp>
|
#include <opm/polymer/polymerUtilities.hpp>
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include <opm/polymer/PolymerState.hpp>
|
#include <opm/polymer/PolymerState.hpp>
|
||||||
#include <opm/core/simulator/WellState.hpp>
|
#include <opm/core/simulator/WellState.hpp>
|
||||||
#include <opm/polymer/TransportModelPolymer.hpp>
|
#include <opm/polymer/TransportModelPolymer.hpp>
|
||||||
|
#include <opm/polymer/PolymerInflow.hpp>
|
||||||
#include <opm/polymer/PolymerProperties.hpp>
|
#include <opm/polymer/PolymerProperties.hpp>
|
||||||
#include <opm/polymer/polymerUtilities.hpp>
|
#include <opm/polymer/polymerUtilities.hpp>
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include <opm/polymer/PolymerProperties.hpp>
|
#include <opm/polymer/PolymerProperties.hpp>
|
||||||
#include <opm/polymer/PolymerBlackoilState.hpp>
|
#include <opm/polymer/PolymerBlackoilState.hpp>
|
||||||
#include <opm/core/fluid/RockCompressibility.hpp>
|
#include <opm/core/fluid/RockCompressibility.hpp>
|
||||||
|
#include <opm/core/utility/SparseVector.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
@ -172,51 +173,6 @@ namespace Opm
|
|||||||
const RockCompressibility* rock_comp);
|
const RockCompressibility* rock_comp);
|
||||||
|
|
||||||
|
|
||||||
class PolymerInflowInterface
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~PolymerInflowInterface() {}
|
|
||||||
virtual void getInflowValues(const double step_start,
|
|
||||||
const double step_end,
|
|
||||||
std::vector<double>& poly_inflow_c) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @brief Functor giving the injected amount of polymer per cell as a function of time.
|
|
||||||
class PolymerInflowBasic : public PolymerInflowInterface
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/// Constructor.
|
|
||||||
/// @param[in] starttime Start time of injection in seconds.
|
|
||||||
/// @param[in] endtime End time of injection in seconds.
|
|
||||||
/// @param[in] amount Amount to be injected per second.
|
|
||||||
PolymerInflowBasic(const double starttime,
|
|
||||||
const double endtime,
|
|
||||||
const double amount)
|
|
||||||
: stime_(starttime), etime_(endtime), amount_(amount)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void getInflowValues(const double step_start,
|
|
||||||
const double step_end,
|
|
||||||
std::vector<double>& poly_inflow_c)
|
|
||||||
{
|
|
||||||
const double eps = 1e-5*(step_end - step_start);
|
|
||||||
if (step_start + eps >= stime_ && step_end - eps <= etime_) {
|
|
||||||
std::fill(poly_inflow_c.begin(), poly_inflow_c.end(), amount_);
|
|
||||||
} else if (step_start + eps <= etime_ && step_end - eps >= stime_) {
|
|
||||||
MESSAGE("Warning: polymer injection set to change inside timestep. Using value at start of step.");
|
|
||||||
std::fill(poly_inflow_c.begin(), poly_inflow_c.end(), amount_);
|
|
||||||
} else {
|
|
||||||
std::fill(poly_inflow_c.begin(), poly_inflow_c.end(), 0.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
double stime_;
|
|
||||||
double etime_;
|
|
||||||
double amount_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
Loading…
Reference in New Issue
Block a user