mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
commit
1415168729
File diff suppressed because it is too large
Load Diff
@ -37,6 +37,7 @@ namespace Opm {
|
|||||||
, rv ( ADB::null())
|
, rv ( ADB::null())
|
||||||
, qs ( ADB::null())
|
, qs ( ADB::null())
|
||||||
, bhp ( ADB::null())
|
, bhp ( ADB::null())
|
||||||
|
, wellVariables ( ADB::null())
|
||||||
, canonical_phase_pressures(3, ADB::null())
|
, canonical_phase_pressures(3, ADB::null())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -47,6 +48,7 @@ namespace Opm {
|
|||||||
ADB rv;
|
ADB rv;
|
||||||
ADB qs;
|
ADB qs;
|
||||||
ADB bhp;
|
ADB bhp;
|
||||||
|
ADB wellVariables;
|
||||||
// Below are quantities stored in the state for optimization purposes.
|
// Below are quantities stored in the state for optimization purposes.
|
||||||
std::vector<ADB> canonical_phase_pressures; // Always has 3 elements, even if only 2 phases active.
|
std::vector<ADB> canonical_phase_pressures; // Always has 3 elements, even if only 2 phases active.
|
||||||
};
|
};
|
||||||
|
@ -66,8 +66,8 @@ namespace Opm
|
|||||||
// Possibly override IOConfig setting (from deck) for how often RESTART files should get written to disk (every N report step)
|
// Possibly override IOConfig setting (from deck) for how often RESTART files should get written to disk (every N report step)
|
||||||
if (Base::param_.has("output_interval")) {
|
if (Base::param_.has("output_interval")) {
|
||||||
const int output_interval = Base::param_.get<int>("output_interval");
|
const int output_interval = Base::param_.get<int>("output_interval");
|
||||||
IOConfigPtr ioConfig = Base::eclipse_state_->getIOConfig();
|
eclipse_state_->getRestartConfig().overrideRestartWriteInterval( size_t( output_interval ) );
|
||||||
ioConfig->overrideRestartWriteInterval(static_cast<size_t>(output_interval));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Possible to force initialization only behavior (NOSIM).
|
// Possible to force initialization only behavior (NOSIM).
|
||||||
|
@ -390,7 +390,7 @@ namespace Opm
|
|||||||
//const int np = residual.material_balance_eq.size();
|
//const int np = residual.material_balance_eq.size();
|
||||||
assert( np == int(residual.material_balance_eq.size()) );
|
assert( np == int(residual.material_balance_eq.size()) );
|
||||||
std::vector<ADB> eqs;
|
std::vector<ADB> eqs;
|
||||||
eqs.reserve(np + 2);
|
eqs.reserve(np + 1);
|
||||||
for (int phase = 0; phase < np; ++phase) {
|
for (int phase = 0; phase < np; ++phase) {
|
||||||
eqs.push_back(residual.material_balance_eq[phase]);
|
eqs.push_back(residual.material_balance_eq[phase]);
|
||||||
}
|
}
|
||||||
@ -401,14 +401,14 @@ namespace Opm
|
|||||||
if( hasWells )
|
if( hasWells )
|
||||||
{
|
{
|
||||||
eqs.push_back(residual.well_flux_eq);
|
eqs.push_back(residual.well_flux_eq);
|
||||||
eqs.push_back(residual.well_eq);
|
//eqs.push_back(residual.well_eq);
|
||||||
|
|
||||||
// Eliminate the well-related unknowns, and corresponding equations.
|
// Eliminate the well-related unknowns, and corresponding equations.
|
||||||
elim_eqs.reserve(2);
|
elim_eqs.reserve(1);
|
||||||
elim_eqs.push_back(eqs[np]);
|
elim_eqs.push_back(eqs[np]);
|
||||||
eqs = eliminateVariable(eqs, np); // Eliminate well flux unknowns.
|
eqs = eliminateVariable(eqs, np); // Eliminate well flux unknowns.
|
||||||
elim_eqs.push_back(eqs[np]);
|
//elim_eqs.push_back(eqs[np]);
|
||||||
eqs = eliminateVariable(eqs, np); // Eliminate well bhp unknowns.
|
//eqs = eliminateVariable(eqs, np); // Eliminate well bhp unknowns.
|
||||||
assert(int(eqs.size()) == np);
|
assert(int(eqs.size()) == np);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,7 +500,7 @@ namespace Opm
|
|||||||
if ( hasWells ) {
|
if ( hasWells ) {
|
||||||
// Compute full solution using the eliminated equations.
|
// Compute full solution using the eliminated equations.
|
||||||
// Recovery in inverse order of elimination.
|
// Recovery in inverse order of elimination.
|
||||||
dx = recoverVariable(elim_eqs[1], dx, np);
|
//dx = recoverVariable(elim_eqs[1], dx, np);
|
||||||
dx = recoverVariable(elim_eqs[0], dx, np);
|
dx = recoverVariable(elim_eqs[0], dx, np);
|
||||||
}
|
}
|
||||||
return dx;
|
return dx;
|
||||||
|
@ -25,11 +25,15 @@
|
|||||||
#include <opm/autodiff/NonlinearSolver.hpp>
|
#include <opm/autodiff/NonlinearSolver.hpp>
|
||||||
#include <opm/autodiff/BlackoilModelEbos.hpp>
|
#include <opm/autodiff/BlackoilModelEbos.hpp>
|
||||||
#include <opm/autodiff/BlackoilModelParameters.hpp>
|
#include <opm/autodiff/BlackoilModelParameters.hpp>
|
||||||
|
#include <opm/autodiff/WellStateFullyImplicitBlackoil.hpp>
|
||||||
|
#include <opm/autodiff/StandardWellsDense.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace Opm {
|
namespace Opm {
|
||||||
|
|
||||||
class SimulatorFullyImplicitBlackoilEbos;
|
class SimulatorFullyImplicitBlackoilEbos;
|
||||||
class StandardWells;
|
class StandardWellsDense;
|
||||||
|
|
||||||
/// a simulator for the blackoil model
|
/// a simulator for the blackoil model
|
||||||
class SimulatorFullyImplicitBlackoilEbos
|
class SimulatorFullyImplicitBlackoilEbos
|
||||||
@ -44,7 +48,7 @@ public:
|
|||||||
typedef BlackoilModelEbos Model;
|
typedef BlackoilModelEbos Model;
|
||||||
typedef BlackoilModelParameters ModelParameters;
|
typedef BlackoilModelParameters ModelParameters;
|
||||||
typedef NonlinearSolver<Model> Solver;
|
typedef NonlinearSolver<Model> Solver;
|
||||||
typedef StandardWells WellModel;
|
typedef StandardWellsDense WellModel;
|
||||||
|
|
||||||
|
|
||||||
/// Initialise from parameters and objects to observe.
|
/// Initialise from parameters and objects to observe.
|
||||||
@ -169,11 +173,11 @@ public:
|
|||||||
// -1 means that we'll take the last report step that was written
|
// -1 means that we'll take the last report step that was written
|
||||||
const int desiredRestoreStep = param_.getDefault("restorestep", int(-1) );
|
const int desiredRestoreStep = param_.getDefault("restorestep", int(-1) );
|
||||||
|
|
||||||
output_writer_.restore( timer,
|
// output_writer_.restore( timer,
|
||||||
state,
|
// state,
|
||||||
prev_well_state,
|
// prev_well_state,
|
||||||
restorefilename,
|
// restorefilename,
|
||||||
desiredRestoreStep );
|
// desiredRestoreStep );
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int totalLinearizations = 0;
|
unsigned int totalLinearizations = 0;
|
||||||
|
310
opm/autodiff/StandardWellsDense.hpp
Normal file
310
opm/autodiff/StandardWellsDense.hpp
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2016 SINTEF ICT, Applied Mathematics.
|
||||||
|
Copyright 2016 Statoil ASA.
|
||||||
|
|
||||||
|
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_STANDARDWELLSDENSE_HEADER_INCLUDED
|
||||||
|
#define OPM_STANDARDWELLSDENSE_HEADER_INCLUDED
|
||||||
|
|
||||||
|
#include <opm/common/OpmLog/OpmLog.hpp>
|
||||||
|
|
||||||
|
#include <opm/common/utility/platform_dependent/disable_warnings.h>
|
||||||
|
#include <Eigen/Eigen>
|
||||||
|
#include <Eigen/Sparse>
|
||||||
|
#include <opm/common/utility/platform_dependent/reenable_warnings.h>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
|
||||||
|
|
||||||
|
#include <opm/core/wells.h>
|
||||||
|
#include <opm/core/wells/DynamicListEconLimited.hpp>
|
||||||
|
#include <opm/autodiff/AutoDiffBlock.hpp>
|
||||||
|
#include <opm/autodiff/AutoDiffHelpers.hpp>
|
||||||
|
#include <opm/autodiff/VFPProperties.hpp>
|
||||||
|
#include <opm/autodiff/BlackoilPropsAdInterface.hpp>
|
||||||
|
|
||||||
|
#include <opm/material/densead/Math.hpp>
|
||||||
|
#include <opm/material/densead/Evaluation.hpp>
|
||||||
|
|
||||||
|
namespace Opm {
|
||||||
|
|
||||||
|
|
||||||
|
/// Class for handling the standard well model.
|
||||||
|
class StandardWellsDense {
|
||||||
|
public:
|
||||||
|
struct WellOps {
|
||||||
|
explicit WellOps(const Wells* wells);
|
||||||
|
Eigen::SparseMatrix<double> w2p; // well -> perf (scatter)
|
||||||
|
Eigen::SparseMatrix<double> p2w; // perf -> well (gather)
|
||||||
|
std::vector<int> well_cells; // the set of perforated cells
|
||||||
|
};
|
||||||
|
|
||||||
|
// --------- Types ---------
|
||||||
|
using ADB = AutoDiffBlock<double>;
|
||||||
|
|
||||||
|
typedef DenseAd::Evaluation<double, /*size=*/6> EvalWell;
|
||||||
|
//typedef AutoDiffBlock<double> ADB;
|
||||||
|
using Vector = ADB::V;
|
||||||
|
using V = ADB::V;
|
||||||
|
|
||||||
|
|
||||||
|
// copied from BlackoilModelBase
|
||||||
|
// should put to somewhere better
|
||||||
|
using DataBlock = Eigen::Array<double,
|
||||||
|
Eigen::Dynamic,
|
||||||
|
Eigen::Dynamic,
|
||||||
|
Eigen::RowMajor>;
|
||||||
|
// --------- Public methods ---------
|
||||||
|
explicit StandardWellsDense(const Wells* wells_arg);
|
||||||
|
|
||||||
|
void init(const BlackoilPropsAdInterface* fluid_arg,
|
||||||
|
const std::vector<bool>* active_arg,
|
||||||
|
const std::vector<PhasePresence>* pc_arg,
|
||||||
|
const VFPProperties* vfp_properties_arg,
|
||||||
|
const double gravity_arg,
|
||||||
|
const Vector& depth_arg);
|
||||||
|
|
||||||
|
const WellOps& wellOps() const;
|
||||||
|
|
||||||
|
int numPhases() const { return wells().number_of_phases; };
|
||||||
|
|
||||||
|
template<class WellState>
|
||||||
|
void resetWellControlFromState(WellState xw) {
|
||||||
|
const int nw = wells_->number_of_wells;
|
||||||
|
for (int w = 0; w < nw; ++w) {
|
||||||
|
WellControls* wc = wells_->ctrls[w];
|
||||||
|
well_controls_set_current( wc, xw.currentControls()[w]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Wells& wells() const;
|
||||||
|
|
||||||
|
const Wells* wellsPointer() const;
|
||||||
|
|
||||||
|
/// return true if wells are available in the reservoir
|
||||||
|
bool wellsActive() const;
|
||||||
|
void setWellsActive(const bool wells_active);
|
||||||
|
/// return true if wells are available on this process
|
||||||
|
bool localWellsActive() const;
|
||||||
|
|
||||||
|
int numWellVars() const;
|
||||||
|
|
||||||
|
/// Density of each well perforation
|
||||||
|
Vector& wellPerforationDensities(); // mutable version kept for BlackoilMultisegmentModel
|
||||||
|
const Vector& wellPerforationDensities() const;
|
||||||
|
|
||||||
|
/// Diff to bhp for each well perforation.
|
||||||
|
Vector& wellPerforationPressureDiffs(); // mutable version kept for BlackoilMultisegmentModel
|
||||||
|
const Vector& wellPerforationPressureDiffs() const;
|
||||||
|
|
||||||
|
template <class ReservoirResidualQuant, class SolutionState>
|
||||||
|
void extractWellPerfProperties(const SolutionState& state,
|
||||||
|
const std::vector<ReservoirResidualQuant>& rq,
|
||||||
|
std::vector<ADB>& mob_perfcells,
|
||||||
|
std::vector<ADB>& b_perfcells) const;
|
||||||
|
|
||||||
|
template <class SolutionState>
|
||||||
|
void computeWellFlux(const SolutionState& state,
|
||||||
|
const std::vector<ADB>& mob_perfcells,
|
||||||
|
const std::vector<ADB>& b_perfcells,
|
||||||
|
Vector& aliveWells,
|
||||||
|
std::vector<ADB>& cq_s) const;
|
||||||
|
|
||||||
|
template <class SolutionState>
|
||||||
|
void
|
||||||
|
computeWellFluxDense(const SolutionState& state,
|
||||||
|
const std::vector<ADB>& mob_perfcells,
|
||||||
|
const std::vector<ADB>& b_perfcells,
|
||||||
|
std::vector<ADB>& cq_s) const;
|
||||||
|
|
||||||
|
EvalWell extractDenseAD(const ADB& data, int i, int j) const;
|
||||||
|
EvalWell extractDenseADWell(const ADB& data, int i) const;
|
||||||
|
|
||||||
|
const ADB convertToADB(const std::vector<EvalWell>& local, const std::vector<int>& well_cells, const int nc, const std::vector<int>& well_id, const int nw, const int numVars) const;
|
||||||
|
|
||||||
|
|
||||||
|
template <class SolutionState, class WellState>
|
||||||
|
void updatePerfPhaseRatesAndPressures(const std::vector<ADB>& cq_s,
|
||||||
|
const SolutionState& state,
|
||||||
|
WellState& xw) const;
|
||||||
|
|
||||||
|
template <class WellState>
|
||||||
|
void updateWellState(const Vector& dwells,
|
||||||
|
const double dpmaxrel,
|
||||||
|
WellState& well_state);
|
||||||
|
|
||||||
|
template <class WellState>
|
||||||
|
void updateWellControls(WellState& xw);
|
||||||
|
|
||||||
|
// TODO: should LinearisedBlackoilResidual also be a template class?
|
||||||
|
template <class SolutionState>
|
||||||
|
void addWellFluxEq(const std::vector<ADB>& cq_s,
|
||||||
|
const SolutionState& state,
|
||||||
|
const double dt,
|
||||||
|
LinearisedBlackoilResidual& residual);
|
||||||
|
|
||||||
|
// TODO: some parameters, like gravity, maybe it is better to put in the member list
|
||||||
|
template <class SolutionState, class WellState>
|
||||||
|
void addWellControlEq(const SolutionState& state,
|
||||||
|
const WellState& xw,
|
||||||
|
const Vector& aliveWells,
|
||||||
|
LinearisedBlackoilResidual& residual);
|
||||||
|
|
||||||
|
template <class SolutionState, class WellState>
|
||||||
|
void computeWellConnectionPressures(const SolutionState& state,
|
||||||
|
const WellState& xw);
|
||||||
|
|
||||||
|
// state0 is non-constant, while it will not be used outside of the function
|
||||||
|
template <class SolutionState, class WellState>
|
||||||
|
void
|
||||||
|
computeWellPotentials(const std::vector<ADB>& mob_perfcells,
|
||||||
|
const std::vector<ADB>& b_perfcells,
|
||||||
|
SolutionState& state0,
|
||||||
|
WellState& well_state);
|
||||||
|
|
||||||
|
template <class SolutionState, class WellState>
|
||||||
|
void
|
||||||
|
variableStateExtractWellsVars(const std::vector<int>& indices,
|
||||||
|
std::vector<ADB>& vars,
|
||||||
|
SolutionState& state,
|
||||||
|
WellState& well_state) const;
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
variableStateWellIndices(std::vector<int>& indices,
|
||||||
|
int& next) const;
|
||||||
|
|
||||||
|
std::vector<int>
|
||||||
|
variableWellStateIndices() const;
|
||||||
|
|
||||||
|
template <class WellState>
|
||||||
|
void
|
||||||
|
variableWellStateInitials(const WellState& xw,
|
||||||
|
std::vector<Vector>& vars0) const;
|
||||||
|
|
||||||
|
/// If set, computeWellFlux() will additionally store the
|
||||||
|
/// total reservoir volume perforation fluxes.
|
||||||
|
void setStoreWellPerforationFluxesFlag(const bool store_fluxes);
|
||||||
|
|
||||||
|
/// Retrieves the stored fluxes. It is an error to call this
|
||||||
|
/// unless setStoreWellPerforationFluxesFlag(true) has been
|
||||||
|
/// called.
|
||||||
|
const Vector& getStoredWellPerforationFluxes() const;
|
||||||
|
|
||||||
|
/// upate the dynamic lists related to economic limits
|
||||||
|
template<class WellState>
|
||||||
|
void
|
||||||
|
updateListEconLimited(ScheduleConstPtr schedule,
|
||||||
|
const int current_step,
|
||||||
|
const Wells* wells,
|
||||||
|
const WellState& well_state,
|
||||||
|
DynamicListEconLimited& list_econ_limited) const;
|
||||||
|
|
||||||
|
template <class SolutionState>
|
||||||
|
std::vector<ADB> wellVolumeFractions(const SolutionState& state) const;
|
||||||
|
|
||||||
|
|
||||||
|
template <class SolutionState>
|
||||||
|
void computeAccumWells(const SolutionState& state);
|
||||||
|
|
||||||
|
template <class WellState>
|
||||||
|
void computeWellConnectionDensitesPressures(const WellState& xw,
|
||||||
|
const std::vector<double>& b_perf,
|
||||||
|
const std::vector<double>& rsmax_perf,
|
||||||
|
const std::vector<double>& rvmax_perf,
|
||||||
|
const std::vector<double>& surf_dens_perf,
|
||||||
|
const std::vector<double>& depth_perf,
|
||||||
|
const double grav);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool wells_active_;
|
||||||
|
const Wells* wells_;
|
||||||
|
const WellOps wops_;
|
||||||
|
|
||||||
|
const BlackoilPropsAdInterface* fluid_;
|
||||||
|
const std::vector<bool>* active_;
|
||||||
|
const std::vector<PhasePresence>* phase_condition_;
|
||||||
|
const VFPProperties* vfp_properties_;
|
||||||
|
double gravity_;
|
||||||
|
// the depth of the all the cell centers
|
||||||
|
// for standard Wells, it the same with the perforation depth
|
||||||
|
Vector perf_cell_depth_;
|
||||||
|
|
||||||
|
Vector well_perforation_densities_;
|
||||||
|
Vector well_perforation_pressure_diffs_;
|
||||||
|
|
||||||
|
bool store_well_perforation_fluxes_;
|
||||||
|
Vector well_perforation_fluxes_;
|
||||||
|
|
||||||
|
std::vector<ADB> F0_;
|
||||||
|
|
||||||
|
// protected methods
|
||||||
|
template <class SolutionState, class WellState>
|
||||||
|
void computePropertiesForWellConnectionPressures(const SolutionState& state,
|
||||||
|
const WellState& xw,
|
||||||
|
std::vector<double>& b_perf,
|
||||||
|
std::vector<double>& rsmax_perf,
|
||||||
|
std::vector<double>& rvmax_perf,
|
||||||
|
std::vector<double>& surf_dens_perf);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class WellState>
|
||||||
|
bool checkRateEconLimits(const WellEconProductionLimits& econ_production_limits,
|
||||||
|
const WellState& well_state,
|
||||||
|
const int well_number) const;
|
||||||
|
|
||||||
|
using WellMapType = typename WellState::WellMapType;
|
||||||
|
using WellMapEntryType = typename WellState::mapentry_t;
|
||||||
|
|
||||||
|
// a tuple type for ratio limit check.
|
||||||
|
// first value indicates whether ratio limit is violated, when the ratio limit is not violated, the following three
|
||||||
|
// values should not be used.
|
||||||
|
// second value indicates whehter there is only one connection left.
|
||||||
|
// third value indicates the indx of the worst-offending connection.
|
||||||
|
// the last value indicates the extent of the violation for the worst-offending connection, which is defined by
|
||||||
|
// the ratio of the actual value to the value of the violated limit.
|
||||||
|
using RatioCheckTuple = std::tuple<bool, bool, int, double>;
|
||||||
|
|
||||||
|
enum ConnectionIndex {
|
||||||
|
INVALIDCONNECTION = -10000
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class WellState>
|
||||||
|
RatioCheckTuple checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits,
|
||||||
|
const WellState& well_state,
|
||||||
|
const WellMapEntryType& map_entry) const;
|
||||||
|
|
||||||
|
template <class WellState>
|
||||||
|
RatioCheckTuple checkMaxWaterCutLimit(const WellEconProductionLimits& econ_production_limits,
|
||||||
|
const WellState& well_state,
|
||||||
|
const WellMapEntryType& map_entry) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Opm
|
||||||
|
|
||||||
|
#include "StandardWellsDense_impl.hpp"
|
||||||
|
|
||||||
|
#endif
|
2247
opm/autodiff/StandardWellsDense_impl.hpp
Normal file
2247
opm/autodiff/StandardWellsDense_impl.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -24,6 +24,7 @@
|
|||||||
#include <opm/core/wells.h>
|
#include <opm/core/wells.h>
|
||||||
#include <opm/core/well_controls.h>
|
#include <opm/core/well_controls.h>
|
||||||
#include <opm/core/simulator/WellState.hpp>
|
#include <opm/core/simulator/WellState.hpp>
|
||||||
|
#include <opm/autodiff/BlackoilModelEnums.hpp>
|
||||||
#include <opm/common/ErrorMacros.hpp>
|
#include <opm/common/ErrorMacros.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@ -105,12 +106,67 @@ namespace Opm
|
|||||||
well_potentials_.clear();
|
well_potentials_.clear();
|
||||||
well_potentials_.resize(nperf * np, 0.0);
|
well_potentials_.resize(nperf * np, 0.0);
|
||||||
|
|
||||||
|
well_solutions_.clear();
|
||||||
|
well_solutions_.resize(nw * np, 0.0);
|
||||||
|
std::vector<double> g = {1.0,1.0,0.01};
|
||||||
|
for (int w = 0; w < nw; ++w) {
|
||||||
|
const WellControls* wc = wells->ctrls[w];
|
||||||
|
|
||||||
|
// The current control in the well state overrides
|
||||||
|
// the current control set in the Wells struct, which
|
||||||
|
// is instead treated as a default.
|
||||||
|
const int current = current_controls_[w];
|
||||||
|
const WellType& well_type = wells->type[w];
|
||||||
|
|
||||||
|
switch (well_controls_iget_type(wc, current)) {
|
||||||
|
case BHP:
|
||||||
|
{
|
||||||
|
if (well_type == INJECTOR) {
|
||||||
|
for (int p = 0; p < np; ++p) {
|
||||||
|
well_solutions_[w] += wellRates()[np*w + p] * wells->comp_frac[np*w + p];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int p = 0; p < np; ++p) {
|
||||||
|
well_solutions_[w] += g[p] * wellRates()[np*w + p];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case RESERVOIR_RATE: // Intentional fall-through
|
||||||
|
case SURFACE_RATE:
|
||||||
|
{
|
||||||
|
wellSolutions()[w] = bhp()[w];
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
assert(np == 3);
|
||||||
|
double total_rates = 0.0;
|
||||||
|
for (int p = 0; p < np; ++p) {
|
||||||
|
total_rates += g[p] * wellRates()[np*w + p];
|
||||||
|
}
|
||||||
|
|
||||||
|
//if(std::abs(total_rates) > 0) {
|
||||||
|
// wellSolutions()[nw + w] = g[Water] * wellRates()[np*w + Water] / total_rates; //wells->comp_frac[np*w + Water]; // Water;
|
||||||
|
// wellSolutions()[2*nw + w] = g[Gas] * wellRates()[np*w + Gas] / total_rates ; //wells->comp_frac[np*w + Gas]; //Gas
|
||||||
|
//} else {
|
||||||
|
wellSolutions()[nw + w] = wells->comp_frac[np*w + Water];
|
||||||
|
wellSolutions()[2*nw + w] = wells->comp_frac[np*w + Gas];
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// intialize wells that have been there before
|
// intialize wells that have been there before
|
||||||
// order may change so the mapping is based on the well name
|
// order may change so the mapping is based on the well name
|
||||||
if( ! prevState.wellMap().empty() )
|
if( ! prevState.wellMap().empty() )
|
||||||
{
|
{
|
||||||
typedef typename WellMapType :: const_iterator const_iterator;
|
typedef typename WellMapType :: const_iterator const_iterator;
|
||||||
const_iterator end = prevState.wellMap().end();
|
const_iterator end = prevState.wellMap().end();
|
||||||
|
int nw_old = prevState.bhp().size();
|
||||||
for (int w = 0; w < nw; ++w) {
|
for (int w = 0; w < nw; ++w) {
|
||||||
std::string name( wells->name[ w ] );
|
std::string name( wells->name[ w ] );
|
||||||
const_iterator it = prevState.wellMap().find( name );
|
const_iterator it = prevState.wellMap().find( name );
|
||||||
@ -123,11 +179,31 @@ namespace Opm
|
|||||||
bhp()[ newIndex ] = prevState.bhp()[ oldIndex ];
|
bhp()[ newIndex ] = prevState.bhp()[ oldIndex ];
|
||||||
|
|
||||||
// wellrates
|
// wellrates
|
||||||
|
double total_well_rates = 0.0;
|
||||||
|
for( int i=0, idx=newIndex*np, oldidx=oldIndex*np; i<np; ++i, ++idx, ++oldidx )
|
||||||
|
{
|
||||||
|
total_well_rates += prevState.wellRates()[ oldidx ];
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (std::abs(total_well_rates) > 0) {
|
||||||
|
|
||||||
for( int i=0, idx=newIndex*np, oldidx=oldIndex*np; i<np; ++i, ++idx, ++oldidx )
|
for( int i=0, idx=newIndex*np, oldidx=oldIndex*np; i<np; ++i, ++idx, ++oldidx )
|
||||||
{
|
{
|
||||||
wellRates()[ idx ] = prevState.wellRates()[ oldidx ];
|
wellRates()[ idx ] = prevState.wellRates()[ oldidx ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wellSolutions
|
||||||
|
//if (std::abs(total_well_rates) > 0.0) {
|
||||||
|
//wellSolutions()[ 0*nw + newIndex ] = prevState.wellSolutions()[0 * nw_old + oldIndex ];
|
||||||
|
//if (wells->type[w] == PRODUCER) {
|
||||||
|
for( int i = 0; i < np; ++i)
|
||||||
|
{
|
||||||
|
wellSolutions()[ i*nw + newIndex ] = prevState.wellSolutions()[i * nw_old + oldIndex ];
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
// perfPhaseRates
|
// perfPhaseRates
|
||||||
int oldPerf_idx = (*it).second[ 1 ];
|
int oldPerf_idx = (*it).second[ 1 ];
|
||||||
const int num_perf_old_well = (*it).second[ 2 ];
|
const int num_perf_old_well = (*it).second[ 2 ];
|
||||||
@ -149,6 +225,7 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// perfPressures
|
// perfPressures
|
||||||
if( num_perf_old_well == num_perf_this_well )
|
if( num_perf_old_well == num_perf_this_well )
|
||||||
{
|
{
|
||||||
@ -165,6 +242,9 @@ namespace Opm
|
|||||||
// If the set of controls have changed, this may not be identical
|
// If the set of controls have changed, this may not be identical
|
||||||
// to the last control, but it must be a valid control.
|
// to the last control, but it must be a valid control.
|
||||||
currentControls()[ newIndex ] = old_control_index;
|
currentControls()[ newIndex ] = old_control_index;
|
||||||
|
WellControls* wc = wells->ctrls[newIndex];
|
||||||
|
well_controls_set_current( wc, old_control_index);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -191,6 +271,10 @@ namespace Opm
|
|||||||
std::vector<double>& wellPotentials() { return well_potentials_; }
|
std::vector<double>& wellPotentials() { return well_potentials_; }
|
||||||
const std::vector<double>& wellPotentials() const { return well_potentials_; }
|
const std::vector<double>& wellPotentials() const { return well_potentials_; }
|
||||||
|
|
||||||
|
/// One rate per phase and well connection.
|
||||||
|
std::vector<double>& wellSolutions() { return well_solutions_; }
|
||||||
|
const std::vector<double>& wellSolutions() const { return well_solutions_; }
|
||||||
|
|
||||||
data::Wells report() const override {
|
data::Wells report() const override {
|
||||||
data::Wells res = WellState::report();
|
data::Wells res = WellState::report();
|
||||||
|
|
||||||
@ -247,10 +331,31 @@ namespace Opm
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WellStateFullyImplicitBlackoil() = default;
|
||||||
|
WellStateFullyImplicitBlackoil( const WellStateFullyImplicitBlackoil& rhs ) :
|
||||||
|
BaseType(rhs),
|
||||||
|
perfphaserates_( rhs.perfphaserates_ ),
|
||||||
|
current_controls_( rhs.current_controls_ ),
|
||||||
|
well_potentials_( rhs.well_potentials_ ),
|
||||||
|
well_solutions_( rhs.well_solutions_ )
|
||||||
|
{}
|
||||||
|
|
||||||
|
WellStateFullyImplicitBlackoil& operator=( const WellStateFullyImplicitBlackoil& rhs ) {
|
||||||
|
|
||||||
|
BaseType::operator =(rhs);
|
||||||
|
this->perfPhaseRates() = rhs.perfPhaseRates();
|
||||||
|
this->currentControls() = rhs.currentControls();
|
||||||
|
this->wellPotentials() = rhs.wellPotentials();
|
||||||
|
this->wellSolutions() = rhs.wellSolutions();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<double> perfphaserates_;
|
std::vector<double> perfphaserates_;
|
||||||
std::vector<int> current_controls_;
|
std::vector<int> current_controls_;
|
||||||
std::vector<double> well_potentials_;
|
std::vector<double> well_potentials_;
|
||||||
|
std::vector<double> well_solutions_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
Loading…
Reference in New Issue
Block a user