void init(const Wells* wells, const State& state, const PrevState& prevState, const PhaseUsage& pu) { // call init on base class BaseType :: init(wells, state, prevState); // if there are no well, do nothing in init if (wells == 0) { return; } const int nw = wells->number_of_wells; if( nw == 0 ) return ; const int np = wells->number_of_phases; 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) { 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 = currentControls()[w]; well_controls_set_current( wc, current); const WellType& well_type = wells->type[w]; switch (well_controls_iget_type(wc, current)) { case THP: // Intentional fall-through 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; } double total_rates = 0.0; for (int p = 0; p < np; ++p) { total_rates += g[p] * wellRates()[np*w + p]; } const int waterpos = pu.phase_pos[Water]; const int gaspos = pu.phase_pos[Gas]; assert(np == 3 || (np == 2 && !pu.phase_used[Gas])); // assumes the gas fractions are stored after water fractions if(std::abs(total_rates) > 0) { if( pu.phase_used[Water] ) { wellSolutions()[nw + w] = g[Water] * wellRates()[np*w + waterpos] / total_rates; } if( pu.phase_used[Gas] ) { wellSolutions()[2*nw + w] = g[Gas] * wellRates()[np*w + gaspos] / total_rates ; } } else { if( pu.phase_used[Water] ) { wellSolutions()[nw + w] = wells->comp_frac[np*w + waterpos]; } if( pu.phase_used[Gas] ) { wellSolutions()[2*nw + w] = wells->comp_frac[np*w + gaspos]; } } } // 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(); int nw_old = prevState.bhp().size(); 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; // wellSolutions for( int i = 0; i < np; ++i) { wellSolutions()[ i*nw + newIndex ] = prevState.wellSolutions()[i * nw_old + oldIndex ]; } } } } }
/// Set wellSolutions() based on the base class members. void setWellSolutions(const PhaseUsage& pu) { // Set nw and np, or return if no wells. if (wells_.get() == nullptr) { return; } const int nw = wells_->number_of_wells; if (nw == 0) { return; } const int np = wells_->number_of_phases; 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) { 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 = currentControls()[w]; well_controls_set_current( wc, current); const WellType& well_type = wells_->type[w]; switch (well_controls_iget_type(wc, current)) { case THP: // Intentional fall-through 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; } double total_rates = 0.0; for (int p = 0; p < np; ++p) { total_rates += g[p] * wellRates()[np*w + p]; } const int waterpos = pu.phase_pos[Water]; const int gaspos = pu.phase_pos[Gas]; assert(np == 3 || (np == 2 && !pu.phase_used[Gas])); // assumes the gas fractions are stored after water fractions if(std::abs(total_rates) > 0) { if( pu.phase_used[Water] ) { wellSolutions()[nw + w] = g[Water] * wellRates()[np*w + waterpos] / total_rates; } if( pu.phase_used[Gas] ) { wellSolutions()[2*nw + w] = g[Gas] * wellRates()[np*w + gaspos] / total_rates ; } } else { if( pu.phase_used[Water] ) { wellSolutions()[nw + w] = wells_->comp_frac[np*w + waterpos]; } if( pu.phase_used[Gas] ) { wellSolutions()[2*nw + w] = wells_->comp_frac[np*w + gaspos]; } } } }