Merge pull request #228 from totto82/partial_copy2

Use well to name mapping when copying the old well state to the new
This commit is contained in:
Atgeirr Flø Rasmussen 2014-11-11 20:06:09 +01:00
commit 2a032dec71
2 changed files with 59 additions and 41 deletions

View File

@ -323,11 +323,7 @@ namespace Opm
props_.permeability());
const Wells* wells = wells_manager.c_wells();
WellStateFullyImplicitBlackoil well_state;
well_state.init(wells, state);
if (timer.currentStepNum() != 0) {
// Transfer previous well state to current.
well_state.partialCopy(prev_well_state, *wells, prev_well_state.numWells());
}
well_state.init(wells, state, prev_well_state);
// Output state at start of time step.
if (output_ && (timer.currentStepNum() % output_interval_ == 0)) {

View File

@ -27,6 +27,11 @@
#include <opm/core/utility/ErrorMacros.hpp>
#include <vector>
#include <cassert>
#include <string>
#include <utility>
#include <map>
#include <algorithm>
#include <array>
namespace Opm
{
@ -36,12 +41,19 @@ namespace Opm
class WellStateFullyImplicitBlackoil
{
public:
typedef std::array< int, 2 > mapentry_t;
typedef std::map< std::string, mapentry_t > WellMapType;
/// Allocate and initialize if wells is non-null. Also tries
/// to give useful initial values to the bhp(), wellRates()
/// and perfPhaseRates() fields, depending on controls
template <class State>
void init(const Wells* wells, const State& state)
template <class State, class PrevState>
void init(const Wells* wells, const State& state, const PrevState& prevState)
{
// clear old name mapping
wellMap_.clear();
if (wells == 0) {
return;
}
@ -58,6 +70,11 @@ namespace Opm
for (int w = 0; w < nw; ++w) {
assert((wells->type[w] == INJECTOR) || (wells->type[w] == PRODUCER));
const WellControls* ctrl = wells->ctrls[w];
std::string name( wells->name[ w ] );
assert( name.size() > 0 );
mapentry_t& wellMapEntry = wellMap_[ name ];
wellMapEntry[ 0 ] = w ;
wellMapEntry[ 1 ] = wells->well_connpos[w ] ;
if (well_controls_well_is_shut(ctrl)) {
// Shut well: perfphaserates_ are all zero.
} else {
@ -79,6 +96,43 @@ namespace Opm
for (int w = 0; w < nw; ++w) {
current_controls_[w] = well_controls_get_current(wells->ctrls[w]);
}
// intialize wells that have been there before
// order may change so the mapping is based on the well name
if( ! prevState.wellMap().empty() )
{
typedef typename WellMapType :: const_iterator const_iterator;
const_iterator end = prevState.wellMap().end();
for (int w = 0; w < nw; ++w) {
std::string name( wells->name[ w ] );
const_iterator it = prevState.wellMap().find( name );
if( it != end )
{
const int oldIndex = (*it).second[ 0 ];
const int newIndex = w;
// bhp
bhp()[ newIndex ] = prevState.bhp()[ oldIndex ];
// wellrates
for( int i=0, idx=newIndex*np, oldidx=oldIndex*np; i<np; ++i, ++idx, ++oldidx )
{
wellRates()[ idx ] = prevState.wellRates()[ oldidx ];
}
// perfPhaseRates
int oldPerf = (*it).second[ 1 ] * np;
for (int perf = wells->well_connpos[ newIndex ]*np;
perf < wells->well_connpos[ newIndex + 1]*np; ++perf, ++oldPerf )
{
perfPhaseRates()[ perf ] = prevState.perfPhaseRates()[ oldPerf ];
}
// currentControls
currentControls()[ newIndex ] = prevState.currentControls()[ oldIndex ];
}
}
}
}
/// One bhp pressure per well.
@ -115,45 +169,13 @@ namespace Opm
return wellRates().size() / numWells();
}
/// Copy data for the first num_wells_to_copy from source,
/// overwriting any data in this object associated with those
/// wells. Assumes that the number of phases are the same,
/// that the number of perforations associated with the wells
/// is unchanging, and that both objects contain at least
/// num_wells_to_copy wells.
void partialCopy(const WellStateFullyImplicitBlackoil& source,
const Wells& wells,
const int num_wells_to_copy)
{
if (numPhases() != source.numPhases()) {
OPM_THROW(std::logic_error, "partialCopy(): source and destination have different number of phases.");
}
if (num_wells_to_copy > numWells() || num_wells_to_copy > source.numWells()) {
OPM_THROW(std::logic_error, "partialCopy(): trying to copy too many wells.");
}
// bhp
std::copy(source.bhp().begin(),
source.bhp().begin() + num_wells_to_copy,
bhp().begin());
// wellRates
std::copy(source.wellRates().begin(),
source.wellRates().begin() + numPhases()*num_wells_to_copy,
wellRates().begin());
// perfPhaseRates
const int num_perfs_to_copy = wells.well_connpos[num_wells_to_copy];
std::copy(source.perfPhaseRates().begin(),
source.perfPhaseRates().begin() + numPhases()*num_perfs_to_copy,
perfPhaseRates().begin());
// currentControls
std::copy(source.currentControls().begin(),
source.currentControls().begin() + num_wells_to_copy,
currentControls().begin());
}
const WellMapType& wellMap() const { return wellMap_; }
private:
WellState basic_well_state_;
std::vector<double> perfphaserates_;
std::vector<int> current_controls_;
WellMapType wellMap_;
};
} // namespace Opm