mirror of
				https://github.com/OPM/opm-simulators.git
				synced 2025-02-25 18:55:30 -06:00 
			
		
		
		
	Use wellcontainer2 (#3255)
Use WellContainer<> to manage members in WellState
This commit is contained in:
		@@ -1979,20 +1979,19 @@ namespace Opm {
 | 
			
		||||
            well_state.update_temperature( well_index,  rst_well.temperature);
 | 
			
		||||
 | 
			
		||||
            if (rst_well.current_control.isProducer) {
 | 
			
		||||
                well_state.currentProductionControls()[ well_index ] = rst_well.current_control.prod;
 | 
			
		||||
                well_state.currentProductionControl( well_index, rst_well.current_control.prod);
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                well_state.currentInjectionControls()[ well_index ] = rst_well.current_control.inj;
 | 
			
		||||
                well_state.currentInjectionControl( well_index, rst_well.current_control.inj);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const auto wellrate_index = well_index * np;
 | 
			
		||||
            for( size_t i = 0; i < phs.size(); ++i ) {
 | 
			
		||||
                assert( rst_well.rates.has( phs[ i ] ) );
 | 
			
		||||
                well_state.wellRates()[ wellrate_index + i ] = rst_well.rates.get( phs[ i ] );
 | 
			
		||||
                well_state.wellRates(well_index)[ i ] = rst_well.rates.get( phs[ i ] );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            auto * perf_pressure = well_state.perfPress().data() + wm.second[1];
 | 
			
		||||
            auto * perf_rates = well_state.perfRates().data() + wm.second[1];
 | 
			
		||||
            auto& perf_pressure = well_state.perfPress(well_index);
 | 
			
		||||
            auto& perf_rates = well_state.perfRates(well_index);
 | 
			
		||||
            auto * perf_phase_rates = well_state.mutable_perfPhaseRates().data() + wm.second[1]*np;
 | 
			
		||||
            const auto& perf_data = this->well_perf_data_[well_index];
 | 
			
		||||
 | 
			
		||||
@@ -3370,6 +3369,7 @@ namespace Opm {
 | 
			
		||||
 | 
			
		||||
            auto& well_info = *local_parallel_well_info_[wellID];
 | 
			
		||||
            const int num_perf_this_well = well_info.communication().sum(well_perf_data_[wellID].size());
 | 
			
		||||
            auto * perf_phase_rate = &this->wellState().perfPhaseRates()[connpos];
 | 
			
		||||
 | 
			
		||||
            for (int perf = 0; perf < num_perf_this_well; ++perf) {
 | 
			
		||||
                const int cell_idx = well_perf_data_[wellID][perf].cell_index;
 | 
			
		||||
@@ -3382,7 +3382,7 @@ namespace Opm {
 | 
			
		||||
                    cellInternalEnergy = fs.enthalpy(phaseIdx).value() - fs.pressure(phaseIdx).value() / fs.density(phaseIdx).value();
 | 
			
		||||
                    cellBinv = fs.invB(phaseIdx).value();
 | 
			
		||||
                    cellDensity = fs.density(phaseIdx).value();
 | 
			
		||||
                    perfPhaseRate = this->wellState().perfPhaseRates()[connpos + perf*np + phaseIdx ];
 | 
			
		||||
                    perfPhaseRate = perf_phase_rate[ perf*np + phaseIdx ];
 | 
			
		||||
                    weight_factor += cellDensity  * perfPhaseRate/cellBinv * cellInternalEnergy/cellTemperatures;
 | 
			
		||||
                }
 | 
			
		||||
                total_weight += weight_factor;
 | 
			
		||||
 
 | 
			
		||||
@@ -420,12 +420,11 @@ GasLiftStage2<TypeTag>::
 | 
			
		||||
getStdWellRates_(const WellInterface<TypeTag> &well)
 | 
			
		||||
{
 | 
			
		||||
    const int well_index = well.indexOfWell();
 | 
			
		||||
    const int np = this->well_state_.numPhases();
 | 
			
		||||
    const auto& pu = well.phaseUsage();
 | 
			
		||||
    auto oil_rate =
 | 
			
		||||
        -this->well_state_.wellRates()[np * well_index + pu.phase_pos[Oil]];
 | 
			
		||||
        -this->well_state_.wellRates(well_index)[pu.phase_pos[Oil]];
 | 
			
		||||
    auto gas_rate =
 | 
			
		||||
        -this->well_state_.wellRates()[np * well_index + pu.phase_pos[Gas]];
 | 
			
		||||
        -this->well_state_.wellRates(well_index)[pu.phase_pos[Gas]];
 | 
			
		||||
    return {oil_rate, gas_rate};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -281,8 +281,8 @@ namespace Opm
 | 
			
		||||
        const int top_segment_index = well_state.topSegmentIndex(index_of_well_);
 | 
			
		||||
        auto * segment_rates = &well_state.segRates()[top_segment_index*this->number_of_phases_];
 | 
			
		||||
        for (int phase = 0; phase < number_of_phases_; ++phase) {
 | 
			
		||||
            const double well_phase_rate = well_state.wellRates()[number_of_phases_*index_of_well_ + phase];
 | 
			
		||||
            const double unscaled_top_seg_rate = segment_rates[phase];
 | 
			
		||||
            const double well_phase_rate = well_state.wellRates(index_of_well_)[phase];
 | 
			
		||||
            if (std::abs(unscaled_top_seg_rate) > 1e-12)
 | 
			
		||||
            {
 | 
			
		||||
                for (int seg = 0; seg < numberOfSegments(); ++seg) {
 | 
			
		||||
@@ -297,7 +297,7 @@ namespace Opm
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                std::vector<double> perforation_rates(number_of_phases_ * number_of_perforations_,0.0);
 | 
			
		||||
                const double perf_phaserate_scaled = well_state.wellRates()[number_of_phases_ * index_of_well_ + phase] / sumTw;
 | 
			
		||||
                const double perf_phaserate_scaled = well_state.wellRates(index_of_well_)[phase] / sumTw;
 | 
			
		||||
                for (int perf = 0; perf < number_of_perforations_; ++perf) {
 | 
			
		||||
                    perforation_rates[number_of_phases_ * perf + phase] = well_index_[perf] * perf_phaserate_scaled;
 | 
			
		||||
                }
 | 
			
		||||
@@ -545,7 +545,7 @@ namespace Opm
 | 
			
		||||
/*         {
 | 
			
		||||
            bool pressure_controlled_well = false;
 | 
			
		||||
            if (this->isInjector()) {
 | 
			
		||||
                const Well::InjectorCMode& current = well_state.currentInjectionControls()[index_of_well_];
 | 
			
		||||
                const Well::InjectorCMode& current = well_state.currentInjectionControl()[index_of_well_];
 | 
			
		||||
                if (current == Well::InjectorCMode::BHP || current == Well::InjectorCMode::THP) {
 | 
			
		||||
                    pressure_controlled_well = true;
 | 
			
		||||
                }
 | 
			
		||||
@@ -566,7 +566,7 @@ namespace Opm
 | 
			
		||||
        debug_cost_counter_ = 0;
 | 
			
		||||
        // does the well have a THP related constraint?
 | 
			
		||||
        const auto& summaryState = ebosSimulator.vanguard().summaryState();
 | 
			
		||||
        const Well::ProducerCMode& current_control = well_state.currentProductionControls()[this->index_of_well_];
 | 
			
		||||
        auto current_control = well_state.currentProductionControl(this->index_of_well_);
 | 
			
		||||
        if ( !Base::wellHasTHPConstraints(summaryState) || current_control == Well::ProducerCMode::BHP) {
 | 
			
		||||
            computeWellRatesAtBhpLimit(ebosSimulator, well_potentials, deferred_logger);
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -626,10 +626,10 @@ namespace Opm
 | 
			
		||||
        //  Set current control to bhp, and bhp value in state, modify bhp limit in control object.
 | 
			
		||||
        if (well_copy.well_ecl_.isInjector()) {
 | 
			
		||||
            inj_controls.bhp_limit = bhp;
 | 
			
		||||
            well_state_copy.currentInjectionControls()[index_of_well_] = Well::InjectorCMode::BHP;
 | 
			
		||||
            well_state_copy.currentInjectionControl(index_of_well_, Well::InjectorCMode::BHP);
 | 
			
		||||
        } else {
 | 
			
		||||
            prod_controls.bhp_limit = bhp;
 | 
			
		||||
            well_state_copy.currentProductionControls()[index_of_well_] = Well::ProducerCMode::BHP;
 | 
			
		||||
            well_state_copy.currentProductionControl(index_of_well_, Well::ProducerCMode::BHP);
 | 
			
		||||
        }
 | 
			
		||||
        well_state_copy.update_bhp(well_copy.index_of_well_, bhp);
 | 
			
		||||
        well_copy.scaleSegmentPressuresWithBhp(well_state_copy);
 | 
			
		||||
@@ -638,7 +638,7 @@ namespace Opm
 | 
			
		||||
        const int np = number_of_phases_;
 | 
			
		||||
        const double sign = well_copy.well_ecl_.isInjector() ? 1.0 : -1.0;
 | 
			
		||||
        for (int phase = 0; phase < np; ++phase){
 | 
			
		||||
            well_state_copy.wellRates()[well_copy.index_of_well_*np + phase]
 | 
			
		||||
            well_state_copy.wellRates(well_copy.index_of_well_)[phase]
 | 
			
		||||
                    = sign * well_state_copy.wellPotentials()[well_copy.index_of_well_*np + phase];
 | 
			
		||||
        }
 | 
			
		||||
        well_copy.scaleSegmentRatesWithWellRates(well_state_copy);
 | 
			
		||||
@@ -1847,13 +1847,13 @@ namespace Opm
 | 
			
		||||
 | 
			
		||||
        const PhaseUsage& pu = phaseUsage();
 | 
			
		||||
        if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
 | 
			
		||||
            rates[ Water ] = well_state.wellRates()[index_of_well_ * number_of_phases_ + pu.phase_pos[ Water ] ];
 | 
			
		||||
            rates[ Water ] = well_state.wellRates(index_of_well_)[pu.phase_pos[ Water ] ];
 | 
			
		||||
        }
 | 
			
		||||
        if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)) {
 | 
			
		||||
            rates[ Oil ] = well_state.wellRates()[index_of_well_ * number_of_phases_ + pu.phase_pos[ Oil ] ];
 | 
			
		||||
            rates[ Oil ] = well_state.wellRates(index_of_well_)[pu.phase_pos[ Oil ] ];
 | 
			
		||||
        }
 | 
			
		||||
        if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
 | 
			
		||||
            rates[ Gas ] = well_state.wellRates()[index_of_well_ * number_of_phases_ + pu.phase_pos[ Gas ] ];
 | 
			
		||||
            rates[ Gas ] = well_state.wellRates(index_of_well_)[pu.phase_pos[ Gas ] ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const double bhp = well_state.bhp(index_of_well_);
 | 
			
		||||
@@ -2376,7 +2376,7 @@ namespace Opm
 | 
			
		||||
                const double phase_rate = g_total * fractions[p];
 | 
			
		||||
                segment_rates[seg*this->number_of_phases_ + p] = phase_rate;
 | 
			
		||||
                if (seg == 0) { // top segment
 | 
			
		||||
                    well_state.wellRates()[index_of_well_ * number_of_phases_ + p] = phase_rate;
 | 
			
		||||
                    well_state.wellRates(index_of_well_)[p] = phase_rate;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -2644,7 +2644,7 @@ namespace Opm
 | 
			
		||||
            const EvalWell seg_pressure = getSegmentPressure(seg);
 | 
			
		||||
            const int rate_start_offset = first_perf_ * number_of_phases_;
 | 
			
		||||
            auto * perf_rates = &well_state.mutable_perfPhaseRates()[rate_start_offset];
 | 
			
		||||
            auto * perf_press_state = &well_state.perfPress()[first_perf_];
 | 
			
		||||
            auto& perf_press_state = well_state.perfPress(this->index_of_well_);
 | 
			
		||||
            for (const int perf : segment_perforations_[seg]) {
 | 
			
		||||
                const int cell_idx = well_cells_[perf];
 | 
			
		||||
                const auto& int_quants = *(ebosSimulator.model().cachedIntensiveQuantities(cell_idx, /*timeIdx=*/ 0));
 | 
			
		||||
@@ -3063,7 +3063,7 @@ namespace Opm
 | 
			
		||||
        const int well_index = index_of_well_;
 | 
			
		||||
        if (this->isInjector() )
 | 
			
		||||
        {
 | 
			
		||||
            const Well::InjectorCMode& current = well_state.currentInjectionControls()[well_index];
 | 
			
		||||
            auto current = well_state.currentInjectionControl(well_index);
 | 
			
		||||
            switch(current) {
 | 
			
		||||
            case Well::InjectorCMode::THP:
 | 
			
		||||
                control_tolerance = param_.tolerance_pressure_ms_wells_;
 | 
			
		||||
@@ -3085,7 +3085,7 @@ namespace Opm
 | 
			
		||||
 | 
			
		||||
        if (this->isProducer() )
 | 
			
		||||
        {
 | 
			
		||||
            const Well::ProducerCMode& current = well_state.currentProductionControls()[well_index];
 | 
			
		||||
            auto current = well_state.currentProductionControl(well_index);
 | 
			
		||||
            switch(current) {
 | 
			
		||||
            case Well::ProducerCMode::THP:
 | 
			
		||||
                control_tolerance = param_.tolerance_pressure_ms_wells_; // 0.1 bar
 | 
			
		||||
@@ -3130,7 +3130,7 @@ namespace Opm
 | 
			
		||||
        const int well_index = index_of_well_;
 | 
			
		||||
        if (this->isInjector() )
 | 
			
		||||
        {
 | 
			
		||||
            const Well::InjectorCMode& current = well_state.currentInjectionControls()[well_index];
 | 
			
		||||
            auto current = well_state.currentInjectionControl(well_index);
 | 
			
		||||
            switch(current) {
 | 
			
		||||
            case Well::InjectorCMode::THP:
 | 
			
		||||
                ctrltype = CR::WellFailure::Type::ControlTHP;
 | 
			
		||||
@@ -3156,7 +3156,7 @@ namespace Opm
 | 
			
		||||
 | 
			
		||||
        if (this->isProducer() )
 | 
			
		||||
        {
 | 
			
		||||
            const Well::ProducerCMode& current = well_state.currentProductionControls()[well_index];
 | 
			
		||||
            auto current = well_state.currentProductionControl(well_index);
 | 
			
		||||
            switch(current) {
 | 
			
		||||
            case Well::ProducerCMode::THP:
 | 
			
		||||
                ctrltype = CR::WellFailure::Type::ControlTHP;
 | 
			
		||||
 
 | 
			
		||||
@@ -848,7 +848,7 @@ namespace Opm
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Store the perforation pressure for later usage.
 | 
			
		||||
        auto * perf_press = &well_state.perfPress()[first_perf_];
 | 
			
		||||
        auto& perf_press = well_state.perfPress(index_of_well_);
 | 
			
		||||
        perf_press[perf] = well_state.bhp(index_of_well_) + perf_pressure_diffs_[perf];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1271,21 +1271,21 @@ namespace Opm
 | 
			
		||||
        if (this->isProducer()) {
 | 
			
		||||
            const double g_total = primary_variables_[WQTotal];
 | 
			
		||||
            for (int p = 0; p < number_of_phases_; ++p) {
 | 
			
		||||
                well_state.wellRates()[index_of_well_ * number_of_phases_ + p] = g_total * F[p];
 | 
			
		||||
                well_state.wellRates(index_of_well_)[p] = g_total * F[p];
 | 
			
		||||
            }
 | 
			
		||||
        } else { // injectors
 | 
			
		||||
            for (int p = 0; p < number_of_phases_; ++p) {
 | 
			
		||||
                well_state.wellRates()[index_of_well_ * number_of_phases_ + p] = 0.0;
 | 
			
		||||
                well_state.wellRates(index_of_well_)[p] = 0.0;
 | 
			
		||||
            }
 | 
			
		||||
            switch (this->wellEcl().injectorType()) {
 | 
			
		||||
            case InjectorType::WATER:
 | 
			
		||||
                well_state.wellRates()[index_of_well_ * number_of_phases_ + pu.phase_pos[Water]] = primary_variables_[WQTotal];
 | 
			
		||||
                well_state.wellRates(index_of_well_)[pu.phase_pos[Water]] = primary_variables_[WQTotal];
 | 
			
		||||
                break;
 | 
			
		||||
            case InjectorType::GAS:
 | 
			
		||||
                well_state.wellRates()[index_of_well_ * number_of_phases_ + pu.phase_pos[Gas]] = primary_variables_[WQTotal];
 | 
			
		||||
                well_state.wellRates(index_of_well_)[pu.phase_pos[Gas]] = primary_variables_[WQTotal];
 | 
			
		||||
                break;
 | 
			
		||||
            case InjectorType::OIL:
 | 
			
		||||
                well_state.wellRates()[index_of_well_ * number_of_phases_ + pu.phase_pos[Oil]] = primary_variables_[WQTotal];
 | 
			
		||||
                well_state.wellRates(index_of_well_)[pu.phase_pos[Oil]] = primary_variables_[WQTotal];
 | 
			
		||||
                break;
 | 
			
		||||
            case InjectorType::MULTI:
 | 
			
		||||
                // Not supported.
 | 
			
		||||
@@ -1328,13 +1328,13 @@ namespace Opm
 | 
			
		||||
 | 
			
		||||
        const Opm::PhaseUsage& pu = phaseUsage();
 | 
			
		||||
        if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
 | 
			
		||||
            rates[ Water ] = well_state.wellRates()[index_of_well_ * number_of_phases_ + pu.phase_pos[ Water ] ];
 | 
			
		||||
            rates[ Water ] = well_state.wellRates(index_of_well_)[pu.phase_pos[ Water ] ];
 | 
			
		||||
        }
 | 
			
		||||
        if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)) {
 | 
			
		||||
            rates[ Oil ] = well_state.wellRates()[index_of_well_ * number_of_phases_ + pu.phase_pos[ Oil ] ];
 | 
			
		||||
            rates[ Oil ] = well_state.wellRates(index_of_well_)[pu.phase_pos[ Oil ] ];
 | 
			
		||||
        }
 | 
			
		||||
        if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
 | 
			
		||||
            rates[ Gas ] = well_state.wellRates()[index_of_well_ * number_of_phases_ + pu.phase_pos[ Gas ] ];
 | 
			
		||||
            rates[ Gas ] = well_state.wellRates(index_of_well_)[pu.phase_pos[ Gas ] ];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const double bhp = well_state.bhp(index_of_well_);
 | 
			
		||||
@@ -1665,9 +1665,9 @@ namespace Opm
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Compute the average pressure in each well block
 | 
			
		||||
        const auto * perf_press = &well_state.perfPress()[first_perf_];
 | 
			
		||||
        const auto& perf_press = well_state.perfPress(w);
 | 
			
		||||
        auto p_above =  this->parallel_well_info_.communicateAboveValues(well_state.bhp(w),
 | 
			
		||||
                                                                         perf_press,
 | 
			
		||||
                                                                         perf_press.data(),
 | 
			
		||||
                                                                         nperf);
 | 
			
		||||
 | 
			
		||||
        for (int perf = 0; perf < nperf; ++perf) {
 | 
			
		||||
@@ -1690,14 +1690,12 @@ namespace Opm
 | 
			
		||||
            if (gasPresent) {
 | 
			
		||||
                const unsigned gasCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx);
 | 
			
		||||
                const int gaspos = gasCompIdx + perf * num_components_;
 | 
			
		||||
                const int gaspos_well = pu.phase_pos[Gas] + w * pu.num_phases;
 | 
			
		||||
 | 
			
		||||
                if (oilPresent) {
 | 
			
		||||
                    const int oilpos_well = pu.phase_pos[Oil] + w * pu.num_phases;
 | 
			
		||||
                    const double oilrate = std::abs(well_state.wellRates()[oilpos_well]); //in order to handle negative rates in producers
 | 
			
		||||
                    const double oilrate = std::abs(well_state.wellRates(w)[pu.phase_pos[Oil]]); //in order to handle negative rates in producers
 | 
			
		||||
                    rvmax_perf[perf] = FluidSystem::gasPvt().saturatedOilVaporizationFactor(fs.pvtRegionIndex(), temperature, p_avg);
 | 
			
		||||
                    if (oilrate > 0) {
 | 
			
		||||
                        const double gasrate = std::abs(well_state.wellRates()[gaspos_well]) - (has_solvent ? well_state.solventWellRate(w) : 0.0);
 | 
			
		||||
                        const double gasrate = std::abs(well_state.wellRates(w)[pu.phase_pos[Gas]]) - (has_solvent ? well_state.solventWellRate(w) : 0.0);
 | 
			
		||||
                        double rv = 0.0;
 | 
			
		||||
                        if (gasrate > 0) {
 | 
			
		||||
                            rv = oilrate / gasrate;
 | 
			
		||||
@@ -1718,13 +1716,11 @@ namespace Opm
 | 
			
		||||
            if (oilPresent) {
 | 
			
		||||
                const unsigned oilCompIdx = Indices::canonicalToActiveComponentIndex(FluidSystem::oilCompIdx);
 | 
			
		||||
                const int oilpos = oilCompIdx + perf * num_components_;
 | 
			
		||||
                const int oilpos_well = pu.phase_pos[Oil] + w * pu.num_phases;
 | 
			
		||||
                if (gasPresent) {
 | 
			
		||||
                    rsmax_perf[perf] = FluidSystem::oilPvt().saturatedGasDissolutionFactor(fs.pvtRegionIndex(), temperature, p_avg);
 | 
			
		||||
                    const int gaspos_well = pu.phase_pos[Gas] + w * pu.num_phases;
 | 
			
		||||
                    const double gasrate = std::abs(well_state.wellRates()[gaspos_well]) - (has_solvent ? well_state.solventWellRate(w) : 0.0);
 | 
			
		||||
                    const double gasrate = std::abs(well_state.wellRates(w)[pu.phase_pos[Gas]]) - (has_solvent ? well_state.solventWellRate(w) : 0.0);
 | 
			
		||||
                    if (gasrate > 0) {
 | 
			
		||||
                        const double oilrate = std::abs(well_state.wellRates()[oilpos_well]);
 | 
			
		||||
                        const double oilrate = std::abs(well_state.wellRates(w)[pu.phase_pos[Oil]]);
 | 
			
		||||
                        double rs = 0.0;
 | 
			
		||||
                        if (oilrate > 0) {
 | 
			
		||||
                            rs = gasrate / oilrate;
 | 
			
		||||
@@ -2423,9 +2419,9 @@ namespace Opm
 | 
			
		||||
 | 
			
		||||
        //  Set current control to bhp, and bhp value in state, modify bhp limit in control object.
 | 
			
		||||
        if (well_ecl_.isInjector()) {
 | 
			
		||||
            well_state_copy.currentInjectionControls()[index_of_well_] = Well::InjectorCMode::BHP;
 | 
			
		||||
            well_state_copy.currentInjectionControl(index_of_well_, Well::InjectorCMode::BHP);
 | 
			
		||||
        } else {
 | 
			
		||||
            well_state_copy.currentProductionControls()[index_of_well_] = Well::ProducerCMode::BHP;
 | 
			
		||||
            well_state_copy.currentProductionControl(index_of_well_, Well::ProducerCMode::BHP);
 | 
			
		||||
        }
 | 
			
		||||
        well_state_copy.update_bhp(index_of_well_, bhp);
 | 
			
		||||
 | 
			
		||||
@@ -2507,8 +2503,7 @@ namespace Opm
 | 
			
		||||
        }
 | 
			
		||||
        if (this->glift_optimize_only_thp_wells) {
 | 
			
		||||
            const int well_index = index_of_well_;
 | 
			
		||||
            const Well::ProducerCMode& control_mode
 | 
			
		||||
                = well_state.currentProductionControls()[well_index];
 | 
			
		||||
            auto control_mode = well_state.currentProductionControl(well_index);
 | 
			
		||||
            if (control_mode != Well::ProducerCMode::THP ) {
 | 
			
		||||
                gliftDebug("Not THP control", deferred_logger);
 | 
			
		||||
                return false;
 | 
			
		||||
@@ -2691,7 +2686,7 @@ namespace Opm
 | 
			
		||||
 | 
			
		||||
        // does the well have a THP related constraint?
 | 
			
		||||
        const auto& summaryState = ebosSimulator.vanguard().summaryState();
 | 
			
		||||
        const Well::ProducerCMode& current_control = well_state.currentProductionControls()[this->index_of_well_];
 | 
			
		||||
        auto current_control = well_state.currentProductionControl(this->index_of_well_);
 | 
			
		||||
        if ( !well.Base::wellHasTHPConstraints(summaryState) || current_control == Well::ProducerCMode::BHP ) {
 | 
			
		||||
            // get the bhp value based on the bhp constraints
 | 
			
		||||
            const double bhp = well.mostStrictBhpFromBhpLimits(summaryState);
 | 
			
		||||
@@ -2721,7 +2716,7 @@ namespace Opm
 | 
			
		||||
        // the weighted total well rate
 | 
			
		||||
        double total_well_rate = 0.0;
 | 
			
		||||
        for (int p = 0; p < np; ++p) {
 | 
			
		||||
            total_well_rate += scalingFactor(p) * well_state.wellRates()[np * well_index + p];
 | 
			
		||||
            total_well_rate += scalingFactor(p) * well_state.wellRates(well_index)[p];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Not: for the moment, the first primary variable for the injectors is not G_total. The injection rate
 | 
			
		||||
@@ -2729,13 +2724,13 @@ namespace Opm
 | 
			
		||||
        if (this->isInjector()) {
 | 
			
		||||
            switch (this->wellEcl().injectorType()) {
 | 
			
		||||
            case InjectorType::WATER:
 | 
			
		||||
                primary_variables_[WQTotal] = well_state.wellRates()[np * well_index + pu.phase_pos[Water]];
 | 
			
		||||
                primary_variables_[WQTotal] = well_state.wellRates(well_index)[pu.phase_pos[Water]];
 | 
			
		||||
                break;
 | 
			
		||||
            case InjectorType::GAS:
 | 
			
		||||
                primary_variables_[WQTotal] = well_state.wellRates()[np * well_index + pu.phase_pos[Gas]];
 | 
			
		||||
                primary_variables_[WQTotal] = well_state.wellRates(well_index)[pu.phase_pos[Gas]];
 | 
			
		||||
                break;
 | 
			
		||||
            case InjectorType::OIL:
 | 
			
		||||
                primary_variables_[WQTotal] = well_state.wellRates()[np * well_index + pu.phase_pos[Oil]];
 | 
			
		||||
                primary_variables_[WQTotal] = well_state.wellRates(well_index)[pu.phase_pos[Oil]];
 | 
			
		||||
                break;
 | 
			
		||||
            case InjectorType::MULTI:
 | 
			
		||||
                // Not supported.
 | 
			
		||||
@@ -2749,10 +2744,10 @@ namespace Opm
 | 
			
		||||
 | 
			
		||||
        if (std::abs(total_well_rate) > 0.) {
 | 
			
		||||
            if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) {
 | 
			
		||||
                primary_variables_[WFrac] = scalingFactor(pu.phase_pos[Water]) * well_state.wellRates()[np*well_index + pu.phase_pos[Water]] / total_well_rate;
 | 
			
		||||
                primary_variables_[WFrac] = scalingFactor(pu.phase_pos[Water]) * well_state.wellRates(well_index)[pu.phase_pos[Water]] / total_well_rate;
 | 
			
		||||
            }
 | 
			
		||||
            if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
 | 
			
		||||
                primary_variables_[GFrac] = scalingFactor(pu.phase_pos[Gas]) * (well_state.wellRates()[np*well_index + pu.phase_pos[Gas]]
 | 
			
		||||
                primary_variables_[GFrac] = scalingFactor(pu.phase_pos[Gas]) * (well_state.wellRates(well_index)[pu.phase_pos[Gas]]
 | 
			
		||||
                                                 - (has_solvent ? well_state.solventWellRate(well_index) : 0.0) ) / total_well_rate ;
 | 
			
		||||
            }
 | 
			
		||||
            if constexpr (has_solvent) {
 | 
			
		||||
@@ -3276,7 +3271,7 @@ namespace Opm
 | 
			
		||||
        }
 | 
			
		||||
        else if (this->isInjector() )
 | 
			
		||||
        {
 | 
			
		||||
            const Opm::Well::InjectorCMode& current = well_state.currentInjectionControls()[well_index];
 | 
			
		||||
            auto current = well_state.currentInjectionControl(well_index);
 | 
			
		||||
            switch(current) {
 | 
			
		||||
            case Well::InjectorCMode::THP:
 | 
			
		||||
                ctrltype = CR::WellFailure::Type::ControlTHP;
 | 
			
		||||
@@ -3301,7 +3296,7 @@ namespace Opm
 | 
			
		||||
        }
 | 
			
		||||
        else if (this->isProducer() )
 | 
			
		||||
        {
 | 
			
		||||
            const Well::ProducerCMode& current = well_state.currentProductionControls()[well_index];
 | 
			
		||||
            auto current = well_state.currentProductionControl(well_index);
 | 
			
		||||
            switch(current) {
 | 
			
		||||
            case Well::ProducerCMode::THP:
 | 
			
		||||
                ctrltype = CR::WellFailure::Type::ControlTHP;
 | 
			
		||||
 
 | 
			
		||||
@@ -55,23 +55,23 @@ public:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    std::size_t size() const {
 | 
			
		||||
        return this->data.size();
 | 
			
		||||
        return this->m_data.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void add(const std::string& name, T&& value) {
 | 
			
		||||
        if (index_map.count(name) != 0)
 | 
			
		||||
            throw std::logic_error("An object with name: " + name + " already exists in container");
 | 
			
		||||
 | 
			
		||||
        this->index_map.emplace(name, this->data.size());
 | 
			
		||||
        this->data.push_back(std::forward<T>(value));
 | 
			
		||||
        this->index_map.emplace(name, this->m_data.size());
 | 
			
		||||
        this->m_data.push_back(std::forward<T>(value));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void add(const std::string& name, const T& value) {
 | 
			
		||||
        if (index_map.count(name) != 0)
 | 
			
		||||
            throw std::logic_error("An object with name: " + name + " already exists in container");
 | 
			
		||||
 | 
			
		||||
        this->index_map.emplace(name, this->data.size());
 | 
			
		||||
        this->data.push_back(value);
 | 
			
		||||
        this->index_map.emplace(name, this->m_data.size());
 | 
			
		||||
        this->m_data.push_back(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool has(const std::string& name) const {
 | 
			
		||||
@@ -81,20 +81,20 @@ public:
 | 
			
		||||
 | 
			
		||||
    void update(const std::string& name, T&& value) {
 | 
			
		||||
        auto index = this->index_map.at(name);
 | 
			
		||||
        this->data[index] = std::forward<T>(value);
 | 
			
		||||
        this->m_data[index] = std::forward<T>(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void update(const std::string& name, const T& value) {
 | 
			
		||||
        auto index = this->index_map.at(name);
 | 
			
		||||
        this->data[index] = value;
 | 
			
		||||
        this->m_data[index] = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void update(std::size_t index, T&& value) {
 | 
			
		||||
        this->data.at(index) = std::forward<T>(value);
 | 
			
		||||
        this->m_data.at(index) = std::forward<T>(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void update(std::size_t index, const T& value) {
 | 
			
		||||
        this->data.at(index) = value;
 | 
			
		||||
        this->m_data.at(index) = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
@@ -103,7 +103,7 @@ public:
 | 
			
		||||
    */
 | 
			
		||||
    void copy_welldata(const WellContainer<T>& other) {
 | 
			
		||||
        if (this->index_map == other.index_map)
 | 
			
		||||
            this->data = other.data;
 | 
			
		||||
            this->m_data = other.m_data;
 | 
			
		||||
        else {
 | 
			
		||||
            for (const auto& [name, index] : this->index_map)
 | 
			
		||||
                this->update_if(index, name, other);
 | 
			
		||||
@@ -117,40 +117,45 @@ public:
 | 
			
		||||
    void copy_welldata(const WellContainer<T>& other, const std::string& name) {
 | 
			
		||||
        auto this_index = this->index_map.at(name);
 | 
			
		||||
        auto other_index = other.index_map.at(name);
 | 
			
		||||
        this->data[this_index] = other.data[other_index];
 | 
			
		||||
        this->m_data[this_index] = other.m_data[other_index];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T& operator[](std::size_t index) {
 | 
			
		||||
        return this->data.at(index);
 | 
			
		||||
        return this->m_data.at(index);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const T& operator[](std::size_t index) const {
 | 
			
		||||
        return this->data.at(index);
 | 
			
		||||
        return this->m_data.at(index);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T& operator[](const std::string& name) {
 | 
			
		||||
        auto index = this->index_map.at(name);
 | 
			
		||||
        return this->data[index];
 | 
			
		||||
        return this->m_data[index];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const T& operator[](const std::string& name) const {
 | 
			
		||||
        auto index = this->index_map.at(name);
 | 
			
		||||
        return this->data[index];
 | 
			
		||||
        return this->m_data[index];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void clear() {
 | 
			
		||||
        this->data.clear();
 | 
			
		||||
        this->m_data.clear();
 | 
			
		||||
        this->index_map.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    typename std::vector<T>::const_iterator begin() const {
 | 
			
		||||
        return this->data.begin();
 | 
			
		||||
        return this->m_data.begin();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    typename std::vector<T>::const_iterator end() const {
 | 
			
		||||
        return this->data.end();
 | 
			
		||||
        return this->m_data.end();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const std::vector<T>& data() const {
 | 
			
		||||
        return this->m_data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void update_if(std::size_t index, const std::string& name, const WellContainer<T>& other) {
 | 
			
		||||
        auto other_iter = other.index_map.find(name);
 | 
			
		||||
@@ -158,11 +163,11 @@ private:
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        auto other_index = other_iter->second;
 | 
			
		||||
        this->data[index] = other.data[other_index];
 | 
			
		||||
        this->m_data[index] = other.m_data[other_index];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    std::vector<T> data;
 | 
			
		||||
    std::vector<T> m_data;
 | 
			
		||||
    std::unordered_map<std::string, std::size_t> index_map;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,7 @@
 | 
			
		||||
#include <opm/simulators/wells/TargetCalculator.hpp>
 | 
			
		||||
#include <opm/simulators/wells/VFPProdProperties.hpp>
 | 
			
		||||
#include <opm/simulators/wells/WellStateFullyImplicitBlackoil.hpp>
 | 
			
		||||
#include <opm/simulators/wells/WellContainer.hpp>
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
@@ -125,7 +126,7 @@ namespace WellGroupHelpers
 | 
			
		||||
                schedule.getGroup(group.parent(), reportStepIdx), schedule, reportStepIdx, factor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    double sumWellPhaseRates(const std::vector<double>& rates,
 | 
			
		||||
    double sumWellPhaseRates(const WellContainer<std::vector<double>>& rates,
 | 
			
		||||
                             const Group& group,
 | 
			
		||||
                             const Schedule& schedule,
 | 
			
		||||
                             const WellStateFullyImplicitBlackoil& wellState,
 | 
			
		||||
@@ -162,11 +163,11 @@ namespace WellGroupHelpers
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            double factor = wellEcl.getEfficiencyFactor();
 | 
			
		||||
            const auto wellrate_index = well_index * wellState.numPhases();
 | 
			
		||||
            const auto& well_rates = rates[well_index];
 | 
			
		||||
            if (injector)
 | 
			
		||||
                rate += factor * rates[wellrate_index + phasePos];
 | 
			
		||||
                rate += factor * well_rates[phasePos];
 | 
			
		||||
            else
 | 
			
		||||
                rate -= factor * rates[wellrate_index + phasePos];
 | 
			
		||||
                rate -= factor * well_rates[phasePos];
 | 
			
		||||
        }
 | 
			
		||||
        const auto& gefac = group.getGroupEfficiencyFactor();
 | 
			
		||||
        return gefac * rate;
 | 
			
		||||
@@ -391,18 +392,17 @@ namespace WellGroupHelpers
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const auto wellrate_index = well_index * wellState.numPhases();
 | 
			
		||||
            const double efficiency = wellTmp.getEfficiencyFactor();
 | 
			
		||||
            // add contributino from wells not under group control
 | 
			
		||||
            if (isInjector) {
 | 
			
		||||
                if (wellState.currentInjectionControls()[well_index] != Well::InjectorCMode::GRUP)
 | 
			
		||||
                if (wellState.currentInjectionControl(well_index) != Well::InjectorCMode::GRUP)
 | 
			
		||||
                    for (int phase = 0; phase < np; phase++) {
 | 
			
		||||
                        groupTargetReduction[phase] += wellStateNupcol.wellRates()[wellrate_index + phase] * efficiency;
 | 
			
		||||
                        groupTargetReduction[phase] += wellStateNupcol.wellRates(well_index)[phase] * efficiency;
 | 
			
		||||
                    }
 | 
			
		||||
            } else {
 | 
			
		||||
                if (wellState.currentProductionControls()[well_index] != Well::ProducerCMode::GRUP)
 | 
			
		||||
                if (wellState.currentProductionControl(well_index) != Well::ProducerCMode::GRUP)
 | 
			
		||||
                    for (int phase = 0; phase < np; phase++) {
 | 
			
		||||
                        groupTargetReduction[phase] -= wellStateNupcol.wellRates()[wellrate_index + phase] * efficiency;
 | 
			
		||||
                        groupTargetReduction[phase] -= wellStateNupcol.wellRates(well_index)[phase] * efficiency;
 | 
			
		||||
                    }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -491,7 +491,7 @@ namespace WellGroupHelpers
 | 
			
		||||
                if (!wellTmp.isInjector())
 | 
			
		||||
                    sign = -1;
 | 
			
		||||
                for (int phase = 0; phase < np; ++phase) {
 | 
			
		||||
                    rates[phase] = sign * wellStateNupcol.wellRates()[well_index * np + phase];
 | 
			
		||||
                    rates[phase] = sign * wellStateNupcol.wellRates(well_index)[phase];
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            wellState.setCurrentWellRates(wellName, rates);
 | 
			
		||||
 
 | 
			
		||||
@@ -39,6 +39,9 @@ class Schedule;
 | 
			
		||||
class VFPProdProperties;
 | 
			
		||||
class WellStateFullyImplicitBlackoil;
 | 
			
		||||
 | 
			
		||||
template <typename>
 | 
			
		||||
class WellContainer;
 | 
			
		||||
 | 
			
		||||
namespace Network { class ExtNetwork; }
 | 
			
		||||
 | 
			
		||||
namespace WellGroupHelpers
 | 
			
		||||
@@ -58,7 +61,7 @@ namespace WellGroupHelpers
 | 
			
		||||
                                         const int reportStepIdx,
 | 
			
		||||
                                         double& factor);
 | 
			
		||||
 | 
			
		||||
    double sumWellPhaseRates(const std::vector<double>& rates,
 | 
			
		||||
    double sumWellPhaseRates(const WellContainer<std::vector<double>>& rates,
 | 
			
		||||
                             const Group& group,
 | 
			
		||||
                             const Schedule& schedule,
 | 
			
		||||
                             const WellStateFullyImplicitBlackoil& wellState,
 | 
			
		||||
 
 | 
			
		||||
@@ -321,7 +321,7 @@ namespace Opm
 | 
			
		||||
        double wsalt() const;
 | 
			
		||||
 | 
			
		||||
        bool checkRateEconLimits(const WellEconProductionLimits& econ_production_limits,
 | 
			
		||||
                                 const std::vector<double>& well_rates,
 | 
			
		||||
                                 const double * rates_or_potentials,
 | 
			
		||||
                                 DeferredLogger& deferred_logger) const;
 | 
			
		||||
 | 
			
		||||
        template <class ValueType>
 | 
			
		||||
 
 | 
			
		||||
@@ -214,9 +214,9 @@ namespace Opm
 | 
			
		||||
        const auto& well = well_ecl_;
 | 
			
		||||
        std::string from;
 | 
			
		||||
        if (well.isInjector()) {
 | 
			
		||||
            from = Well::InjectorCMode2String(well_state.currentInjectionControls()[index_of_well_]);
 | 
			
		||||
            from = Well::InjectorCMode2String(well_state.currentInjectionControl(index_of_well_));
 | 
			
		||||
        } else {
 | 
			
		||||
            from = Well::ProducerCMode2String(well_state.currentProductionControls()[index_of_well_]);
 | 
			
		||||
            from = Well::ProducerCMode2String(well_state.currentProductionControl(index_of_well_));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool changed = false;
 | 
			
		||||
@@ -235,9 +235,9 @@ namespace Opm
 | 
			
		||||
        if (changed) {
 | 
			
		||||
            std::string to;
 | 
			
		||||
            if (well.isInjector()) {
 | 
			
		||||
                to = Well::InjectorCMode2String(well_state.currentInjectionControls()[index_of_well_]);
 | 
			
		||||
                to = Well::InjectorCMode2String(well_state.currentInjectionControl(index_of_well_));
 | 
			
		||||
            } else {
 | 
			
		||||
                to = Well::ProducerCMode2String(well_state.currentProductionControls()[index_of_well_]);
 | 
			
		||||
                to = Well::ProducerCMode2String(well_state.currentProductionControl(index_of_well_));
 | 
			
		||||
            }
 | 
			
		||||
            std::ostringstream ss;
 | 
			
		||||
            ss << "    Switching control mode for well " << name()
 | 
			
		||||
@@ -262,15 +262,14 @@ namespace Opm
 | 
			
		||||
    bool
 | 
			
		||||
    WellInterface<TypeTag>::
 | 
			
		||||
    checkRateEconLimits(const WellEconProductionLimits& econ_production_limits,
 | 
			
		||||
                        const std::vector<double>& well_rates,
 | 
			
		||||
                        const double * rates_or_potentials,
 | 
			
		||||
                        DeferredLogger& deferred_logger) const
 | 
			
		||||
    {
 | 
			
		||||
        const PhaseUsage& pu = phaseUsage();
 | 
			
		||||
        const int np = number_of_phases_;
 | 
			
		||||
 | 
			
		||||
        if (econ_production_limits.onMinOilRate()) {
 | 
			
		||||
            assert(FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx));
 | 
			
		||||
            const double oil_rate = well_rates[index_of_well_ * np + pu.phase_pos[ Oil ] ];
 | 
			
		||||
            const double oil_rate = rates_or_potentials[pu.phase_pos[ Oil ] ];
 | 
			
		||||
            const double min_oil_rate = econ_production_limits.minOilRate();
 | 
			
		||||
            if (std::abs(oil_rate) < min_oil_rate) {
 | 
			
		||||
                return true;
 | 
			
		||||
@@ -279,7 +278,7 @@ namespace Opm
 | 
			
		||||
 | 
			
		||||
        if (econ_production_limits.onMinGasRate() ) {
 | 
			
		||||
            assert(FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx));
 | 
			
		||||
            const double gas_rate = well_rates[index_of_well_ * np + pu.phase_pos[ Gas ] ];
 | 
			
		||||
            const double gas_rate = rates_or_potentials[pu.phase_pos[ Gas ] ];
 | 
			
		||||
            const double min_gas_rate = econ_production_limits.minGasRate();
 | 
			
		||||
            if (std::abs(gas_rate) < min_gas_rate) {
 | 
			
		||||
                return true;
 | 
			
		||||
@@ -289,8 +288,8 @@ namespace Opm
 | 
			
		||||
        if (econ_production_limits.onMinLiquidRate() ) {
 | 
			
		||||
            assert(FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx));
 | 
			
		||||
            assert(FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx));
 | 
			
		||||
            const double oil_rate = well_rates[index_of_well_ * np + pu.phase_pos[ Oil ] ];
 | 
			
		||||
            const double water_rate = well_rates[index_of_well_ * np + pu.phase_pos[ Water ] ];
 | 
			
		||||
            const double oil_rate = rates_or_potentials[pu.phase_pos[ Oil ] ];
 | 
			
		||||
            const double water_rate = rates_or_potentials[pu.phase_pos[ Water ] ];
 | 
			
		||||
            const double liquid_rate = oil_rate + water_rate;
 | 
			
		||||
            const double min_liquid_rate = econ_production_limits.minLiquidRate();
 | 
			
		||||
            if (std::abs(liquid_rate) < min_liquid_rate) {
 | 
			
		||||
@@ -558,7 +557,7 @@ namespace Opm
 | 
			
		||||
        std::vector<double> well_rates(np, 0.0);
 | 
			
		||||
 | 
			
		||||
        for (int p = 0; p < np; ++p) {
 | 
			
		||||
            well_rates[p] = well_state.wellRates()[index_of_well_ * np + p];
 | 
			
		||||
            well_rates[p] = well_state.wellRates(index_of_well_)[p];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const double well_ratio = ratioFunc(well_rates, phaseUsage());
 | 
			
		||||
@@ -682,11 +681,12 @@ namespace Opm
 | 
			
		||||
        bool rate_limit_violated = false;
 | 
			
		||||
 | 
			
		||||
        const auto& quantity_limit = econ_production_limits.quantityLimit();
 | 
			
		||||
        const int np = number_of_phases_;
 | 
			
		||||
        if (econ_production_limits.onAnyRateLimit()) {
 | 
			
		||||
            if (quantity_limit == WellEconProductionLimits::QuantityLimit::POTN)
 | 
			
		||||
                rate_limit_violated = checkRateEconLimits(econ_production_limits, well_state.wellPotentials(), deferred_logger);
 | 
			
		||||
                rate_limit_violated = checkRateEconLimits(econ_production_limits, &well_state.wellPotentials()[index_of_well_ * np], deferred_logger);
 | 
			
		||||
            else {
 | 
			
		||||
                rate_limit_violated = checkRateEconLimits(econ_production_limits, well_state.wellRates(), deferred_logger);
 | 
			
		||||
                rate_limit_violated = checkRateEconLimits(econ_production_limits, well_state.wellRates(index_of_well_).data(), deferred_logger);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -932,16 +932,15 @@ namespace Opm
 | 
			
		||||
        const int np = number_of_phases_;
 | 
			
		||||
 | 
			
		||||
        std::vector<double> surface_rates(np, 0.0);
 | 
			
		||||
        const int well_rate_index = np * index_of_well_;
 | 
			
		||||
        for (int p = 0; p < np; ++p) {
 | 
			
		||||
            surface_rates[p] = well_state.wellRates()[well_rate_index + p];
 | 
			
		||||
            surface_rates[p] = well_state.wellRates(index_of_well_)[p];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        std::vector<double> voidage_rates(np, 0.0);
 | 
			
		||||
        rateConverter_.calcReservoirVoidageRates(fipreg, pvtRegionIdx_, surface_rates, voidage_rates);
 | 
			
		||||
 | 
			
		||||
        for (int p = 0; p < np; ++p) {
 | 
			
		||||
            well_state.wellReservoirRates()[well_rate_index + p] = voidage_rates[p];
 | 
			
		||||
            well_state.wellReservoirRates(index_of_well_)[p] = voidage_rates[p];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1170,7 +1169,7 @@ namespace Opm
 | 
			
		||||
    {
 | 
			
		||||
        this->operability_status_.reset();
 | 
			
		||||
 | 
			
		||||
        const Well::ProducerCMode& current_control = well_state.currentProductionControls()[this->index_of_well_];
 | 
			
		||||
        auto current_control = well_state.currentProductionControl(this->index_of_well_);
 | 
			
		||||
        // Operability checking is not free
 | 
			
		||||
        // Only check wells under BHP and THP control
 | 
			
		||||
        if(current_control == Well::ProducerCMode::BHP || current_control == Well::ProducerCMode::THP) {
 | 
			
		||||
@@ -1201,7 +1200,7 @@ namespace Opm
 | 
			
		||||
 | 
			
		||||
        if (this->wellIsStopped()) {
 | 
			
		||||
            for (int p = 0; p<np; ++p) {
 | 
			
		||||
                well_state.wellRates()[well_index*np + p] = 0.0;
 | 
			
		||||
                well_state.wellRates(well_index)[p] = 0.0;
 | 
			
		||||
            }
 | 
			
		||||
            well_state.update_thp(well_index, 0.0);
 | 
			
		||||
            return;
 | 
			
		||||
@@ -1233,12 +1232,12 @@ namespace Opm
 | 
			
		||||
                OPM_DEFLOG_THROW(std::runtime_error, "Expected WATER, OIL or GAS as type for injectors "  + name(), deferred_logger );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const Well::InjectorCMode& current = well_state.currentInjectionControls()[well_index];
 | 
			
		||||
            auto current = well_state.currentInjectionControl(well_index);
 | 
			
		||||
 | 
			
		||||
            switch(current) {
 | 
			
		||||
            case Well::InjectorCMode::RATE:
 | 
			
		||||
            {
 | 
			
		||||
                well_state.wellRates()[well_index*np + phasePos] = controls.surface_rate;
 | 
			
		||||
                well_state.wellRates(well_index)[phasePos] = controls.surface_rate;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -1247,7 +1246,7 @@ namespace Opm
 | 
			
		||||
                std::vector<double> convert_coeff(number_of_phases_, 1.0);
 | 
			
		||||
                rateConverter_.calcCoeff(/*fipreg*/ 0, pvtRegionIdx_, convert_coeff);
 | 
			
		||||
                const double coeff = convert_coeff[phasePos];
 | 
			
		||||
                well_state.wellRates()[well_index*np + phasePos] = controls.reservoir_rate/coeff;
 | 
			
		||||
                well_state.wellRates(well_index)[phasePos] = controls.reservoir_rate/coeff;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -1255,7 +1254,7 @@ namespace Opm
 | 
			
		||||
            {
 | 
			
		||||
                std::vector<double> rates(3, 0.0);
 | 
			
		||||
                for (int p = 0; p<np; ++p) {
 | 
			
		||||
                    rates[p] = well_state.wellRates()[well_index*np + p];
 | 
			
		||||
                    rates[p] = well_state.wellRates(well_index)[p];
 | 
			
		||||
                }
 | 
			
		||||
                double bhp = calculateBhpFromThp(well_state, rates, well, summaryState, deferred_logger);
 | 
			
		||||
                well_state.update_bhp(well_index, bhp);
 | 
			
		||||
@@ -1266,7 +1265,7 @@ namespace Opm
 | 
			
		||||
                double total_rate = std::accumulate(rates.begin(), rates.end(), 0.0);
 | 
			
		||||
                if (total_rate <= 0.0){
 | 
			
		||||
                    for (int p = 0; p<np; ++p) {
 | 
			
		||||
                        well_state.wellRates()[well_index*np + p] = well_state.wellPotentials()[well_index*np + p];
 | 
			
		||||
                        well_state.wellRates(well_index)[p] = well_state.wellPotentials()[well_index*np + p];
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
@@ -1276,14 +1275,14 @@ namespace Opm
 | 
			
		||||
                well_state.update_bhp(well_index, controls.bhp_limit);
 | 
			
		||||
                double total_rate = 0.0;
 | 
			
		||||
                for (int p = 0; p<np; ++p) {
 | 
			
		||||
                    total_rate += well_state.wellRates()[well_index*np + p];
 | 
			
		||||
                    total_rate += well_state.wellRates(well_index)[p];
 | 
			
		||||
                }
 | 
			
		||||
                // if the total rates are negative or zero
 | 
			
		||||
                // we try to provide a better intial well rate
 | 
			
		||||
                // using the well potentials
 | 
			
		||||
                if (total_rate <= 0.0){
 | 
			
		||||
                    for (int p = 0; p<np; ++p) {
 | 
			
		||||
                        well_state.wellRates()[well_index*np + p] = well_state.wellPotentials()[well_index*np + p];
 | 
			
		||||
                        well_state.wellRates(well_index)[p] = well_state.wellPotentials()[well_index*np + p];
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
@@ -1303,24 +1302,24 @@ namespace Opm
 | 
			
		||||
        //Producer
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            const Well::ProducerCMode& current = well_state.currentProductionControls()[well_index];
 | 
			
		||||
            auto current = well_state.currentProductionControl(well_index);
 | 
			
		||||
            const auto& controls = well.productionControls(summaryState);
 | 
			
		||||
            switch (current) {
 | 
			
		||||
            case Well::ProducerCMode::ORAT:
 | 
			
		||||
            {
 | 
			
		||||
                double current_rate = -well_state.wellRates()[ well_index*np + pu.phase_pos[Oil] ];
 | 
			
		||||
                double current_rate = -well_state.wellRates(well_index)[ pu.phase_pos[Oil] ];
 | 
			
		||||
                // for trivial rates or opposite direction we don't just scale the rates
 | 
			
		||||
                // but use either the potentials or the mobility ratio to initial the well rates
 | 
			
		||||
                if (current_rate > 0.0) {
 | 
			
		||||
                    for (int p = 0; p<np; ++p) {
 | 
			
		||||
                        well_state.wellRates()[well_index*np + p] *= controls.oil_rate/current_rate;
 | 
			
		||||
                        well_state.wellRates(well_index)[p] *= controls.oil_rate/current_rate;
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    const std::vector<double> fractions = initialWellRateFractions(ebos_simulator, well_state.wellPotentials());
 | 
			
		||||
                    double control_fraction = fractions[pu.phase_pos[Oil]];
 | 
			
		||||
                    if (control_fraction != 0.0) {
 | 
			
		||||
                        for (int p = 0; p<np; ++p) {
 | 
			
		||||
                            well_state.wellRates()[well_index*np + p] = - fractions[p] * controls.oil_rate/control_fraction;
 | 
			
		||||
                            well_state.wellRates(well_index)[p] = - fractions[p] * controls.oil_rate/control_fraction;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@@ -1328,19 +1327,19 @@ namespace Opm
 | 
			
		||||
            }
 | 
			
		||||
            case Well::ProducerCMode::WRAT:
 | 
			
		||||
            {
 | 
			
		||||
                double current_rate = -well_state.wellRates()[ well_index*np + pu.phase_pos[Water] ];
 | 
			
		||||
                double current_rate = -well_state.wellRates(well_index)[ pu.phase_pos[Water] ];
 | 
			
		||||
                // for trivial rates or opposite direction we don't just scale the rates
 | 
			
		||||
                // but use either the potentials or the mobility ratio to initial the well rates
 | 
			
		||||
                if (current_rate > 0.0) {
 | 
			
		||||
                    for (int p = 0; p<np; ++p) {
 | 
			
		||||
                        well_state.wellRates()[well_index*np + p] *= controls.water_rate/current_rate;
 | 
			
		||||
                        well_state.wellRates(well_index)[p] *= controls.water_rate/current_rate;
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    const std::vector<double> fractions = initialWellRateFractions(ebos_simulator, well_state.wellPotentials());
 | 
			
		||||
                    double control_fraction = fractions[pu.phase_pos[Water]];
 | 
			
		||||
                    if (control_fraction != 0.0) {
 | 
			
		||||
                        for (int p = 0; p<np; ++p) {
 | 
			
		||||
                            well_state.wellRates()[well_index*np + p] = - fractions[p] * controls.water_rate/control_fraction;
 | 
			
		||||
                            well_state.wellRates(well_index)[p] = - fractions[p] * controls.water_rate/control_fraction;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@@ -1348,19 +1347,19 @@ namespace Opm
 | 
			
		||||
            }
 | 
			
		||||
            case Well::ProducerCMode::GRAT:
 | 
			
		||||
            {
 | 
			
		||||
                double current_rate = -well_state.wellRates()[ well_index*np + pu.phase_pos[Gas] ];
 | 
			
		||||
                double current_rate = -well_state.wellRates(well_index)[pu.phase_pos[Gas] ];
 | 
			
		||||
                // or trivial rates or opposite direction we don't just scale the rates
 | 
			
		||||
                // but use either the potentials or the mobility ratio to initial the well rates
 | 
			
		||||
                if (current_rate > 0.0) {
 | 
			
		||||
                    for (int p = 0; p<np; ++p) {
 | 
			
		||||
                        well_state.wellRates()[well_index*np + p] *= controls.gas_rate/current_rate;
 | 
			
		||||
                        well_state.wellRates(well_index)[p] *= controls.gas_rate/current_rate;
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    const std::vector<double> fractions = initialWellRateFractions(ebos_simulator, well_state.wellPotentials());
 | 
			
		||||
                    double control_fraction = fractions[pu.phase_pos[Gas]];
 | 
			
		||||
                    if (control_fraction != 0.0) {
 | 
			
		||||
                        for (int p = 0; p<np; ++p) {
 | 
			
		||||
                            well_state.wellRates()[well_index*np + p] = - fractions[p] * controls.gas_rate/control_fraction;
 | 
			
		||||
                            well_state.wellRates(well_index)[p] = - fractions[p] * controls.gas_rate/control_fraction;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@@ -1370,20 +1369,20 @@ namespace Opm
 | 
			
		||||
            }
 | 
			
		||||
            case Well::ProducerCMode::LRAT:
 | 
			
		||||
            {
 | 
			
		||||
                double current_rate = -well_state.wellRates()[ well_index*np + pu.phase_pos[Water] ]
 | 
			
		||||
                        - well_state.wellRates()[ well_index*np + pu.phase_pos[Oil] ];
 | 
			
		||||
                double current_rate = -well_state.wellRates(well_index)[ pu.phase_pos[Water] ]
 | 
			
		||||
                        - well_state.wellRates(well_index)[ pu.phase_pos[Oil] ];
 | 
			
		||||
                // or trivial rates or opposite direction we don't just scale the rates
 | 
			
		||||
                // but use either the potentials or the mobility ratio to initial the well rates
 | 
			
		||||
                if (current_rate > 0.0) {
 | 
			
		||||
                    for (int p = 0; p<np; ++p) {
 | 
			
		||||
                        well_state.wellRates()[well_index*np + p] *= controls.liquid_rate/current_rate;
 | 
			
		||||
                        well_state.wellRates(well_index)[p] *= controls.liquid_rate/current_rate;
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    const std::vector<double> fractions = initialWellRateFractions(ebos_simulator, well_state.wellPotentials());
 | 
			
		||||
                    double control_fraction = fractions[pu.phase_pos[Water]] + fractions[pu.phase_pos[Oil]];
 | 
			
		||||
                    if (control_fraction != 0.0) {
 | 
			
		||||
                        for (int p = 0; p<np; ++p) {
 | 
			
		||||
                            well_state.wellRates()[well_index*np + p] = - fractions[p] * controls.liquid_rate / control_fraction;
 | 
			
		||||
                            well_state.wellRates(well_index)[p] = - fractions[p] * controls.liquid_rate / control_fraction;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@@ -1399,19 +1398,19 @@ namespace Opm
 | 
			
		||||
                rateConverter_.calcCoeff(/*fipreg*/ 0, pvtRegionIdx_, convert_coeff);
 | 
			
		||||
                double total_res_rate = 0.0;
 | 
			
		||||
                for (int p = 0; p<np; ++p) {
 | 
			
		||||
                    total_res_rate -= well_state.wellRates()[well_index*np + p] * convert_coeff[p];
 | 
			
		||||
                    total_res_rate -= well_state.wellRates(well_index)[p] * convert_coeff[p];
 | 
			
		||||
                }
 | 
			
		||||
                if (controls.prediction_mode) {
 | 
			
		||||
                    // or trivial rates or opposite direction we don't just scale the rates
 | 
			
		||||
                    // but use either the potentials or the mobility ratio to initial the well rates
 | 
			
		||||
                    if (total_res_rate > 0.0) {
 | 
			
		||||
                        for (int p = 0; p<np; ++p) {
 | 
			
		||||
                            well_state.wellRates()[well_index*np + p] *= controls.resv_rate/total_res_rate;
 | 
			
		||||
                            well_state.wellRates(well_index)[p] *= controls.resv_rate/total_res_rate;
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        const std::vector<double> fractions = initialWellRateFractions(ebos_simulator, well_state.wellPotentials());
 | 
			
		||||
                        for (int p = 0; p<np; ++p) {
 | 
			
		||||
                            well_state.wellRates()[well_index*np + p] = - fractions[p] * controls.resv_rate / convert_coeff[p];
 | 
			
		||||
                            well_state.wellRates(well_index)[p] = - fractions[p] * controls.resv_rate / convert_coeff[p];
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
@@ -1432,12 +1431,12 @@ namespace Opm
 | 
			
		||||
                    // but use either the potentials or the mobility ratio to initial the well rates
 | 
			
		||||
                    if (total_res_rate > 0.0) {
 | 
			
		||||
                        for (int p = 0; p<np; ++p) {
 | 
			
		||||
                            well_state.wellRates()[well_index*np + p] *= target/total_res_rate;
 | 
			
		||||
                            well_state.wellRates(well_index)[p] *= target/total_res_rate;
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                        const std::vector<double> fractions = initialWellRateFractions(ebos_simulator, well_state.wellPotentials());
 | 
			
		||||
                        for (int p = 0; p<np; ++p) {
 | 
			
		||||
                            well_state.wellRates()[well_index*np + p] = - fractions[p] * target / convert_coeff[p];
 | 
			
		||||
                            well_state.wellRates(well_index)[p] = - fractions[p] * target / convert_coeff[p];
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
@@ -1449,14 +1448,14 @@ namespace Opm
 | 
			
		||||
                well_state.update_bhp(well_index, controls.bhp_limit);
 | 
			
		||||
                double total_rate = 0.0;
 | 
			
		||||
                for (int p = 0; p<np; ++p) {
 | 
			
		||||
                    total_rate -= well_state.wellRates()[well_index*np + p];
 | 
			
		||||
                    total_rate -= well_state.wellRates(well_index)[p];
 | 
			
		||||
                }
 | 
			
		||||
                // if the total rates are negative or zero
 | 
			
		||||
                // we try to provide a better intial well rate
 | 
			
		||||
                // using the well potentials
 | 
			
		||||
                if (total_rate <= 0.0){
 | 
			
		||||
                    for (int p = 0; p<np; ++p) {
 | 
			
		||||
                        well_state.wellRates()[well_index*np + p] = -well_state.wellPotentials()[well_index*np + p];
 | 
			
		||||
                        well_state.wellRates(well_index)[p] = -well_state.wellPotentials()[well_index*np + p];
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
@@ -1465,7 +1464,7 @@ namespace Opm
 | 
			
		||||
            {
 | 
			
		||||
                std::vector<double> rates(3, 0.0);
 | 
			
		||||
                for (int p = 0; p<np; ++p) {
 | 
			
		||||
                    rates[p] = well_state.wellRates()[well_index*np + p];
 | 
			
		||||
                    rates[p] = well_state.wellRates(well_index)[p];
 | 
			
		||||
                }
 | 
			
		||||
                double bhp = calculateBhpFromThp(well_state, rates, well, summaryState, deferred_logger);
 | 
			
		||||
                well_state.update_bhp(well_index, bhp);
 | 
			
		||||
@@ -1476,7 +1475,7 @@ namespace Opm
 | 
			
		||||
                double total_rate = -std::accumulate(rates.begin(), rates.end(), 0.0);
 | 
			
		||||
                if (total_rate <= 0.0){
 | 
			
		||||
                    for (int p = 0; p<np; ++p) {
 | 
			
		||||
                        well_state.wellRates()[well_index*np + p] = -well_state.wellPotentials()[well_index*np + p];
 | 
			
		||||
                        well_state.wellRates(well_index)[p] = -well_state.wellPotentials()[well_index*np + p];
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
@@ -1570,18 +1569,17 @@ namespace Opm
 | 
			
		||||
        const auto& well = well_ecl_;
 | 
			
		||||
        const PhaseUsage& pu = phaseUsage();
 | 
			
		||||
        const int well_index = index_of_well_;
 | 
			
		||||
        const auto wellrate_index = well_index * pu.num_phases;
 | 
			
		||||
 | 
			
		||||
        if (well.isInjector()) {
 | 
			
		||||
            const auto controls = well.injectionControls(summaryState);
 | 
			
		||||
            Well::InjectorCMode& currentControl = well_state.currentInjectionControls()[well_index];
 | 
			
		||||
            auto currentControl = well_state.currentInjectionControl(well_index);
 | 
			
		||||
 | 
			
		||||
            if (controls.hasControl(Well::InjectorCMode::BHP) && currentControl != Well::InjectorCMode::BHP)
 | 
			
		||||
            {
 | 
			
		||||
                const auto& bhp = controls.bhp_limit;
 | 
			
		||||
                double current_bhp = well_state.bhp(well_index);
 | 
			
		||||
                if (bhp < current_bhp) {
 | 
			
		||||
                    currentControl = Well::InjectorCMode::BHP;
 | 
			
		||||
                    well_state.currentInjectionControl(well_index, Well::InjectorCMode::BHP);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -1594,17 +1592,17 @@ namespace Opm
 | 
			
		||||
                switch (injectorType) {
 | 
			
		||||
                case InjectorType::WATER:
 | 
			
		||||
                {
 | 
			
		||||
                    current_rate = well_state.wellRates()[ wellrate_index + pu.phase_pos[BlackoilPhases::Aqua] ];
 | 
			
		||||
                    current_rate = well_state.wellRates(well_index)[ pu.phase_pos[BlackoilPhases::Aqua] ];
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case InjectorType::OIL:
 | 
			
		||||
                {
 | 
			
		||||
                    current_rate = well_state.wellRates()[ wellrate_index + pu.phase_pos[BlackoilPhases::Liquid] ];
 | 
			
		||||
                    current_rate = well_state.wellRates(well_index)[ pu.phase_pos[BlackoilPhases::Liquid] ];
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                case InjectorType::GAS:
 | 
			
		||||
                {
 | 
			
		||||
                    current_rate = well_state.wellRates()[ wellrate_index + pu.phase_pos[BlackoilPhases::Vapour] ];
 | 
			
		||||
                    current_rate = well_state.wellRates(well_index)[  pu.phase_pos[BlackoilPhases::Vapour] ];
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                default:
 | 
			
		||||
@@ -1612,7 +1610,7 @@ namespace Opm
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (controls.surface_rate < current_rate) {
 | 
			
		||||
                    currentControl = Well::InjectorCMode::RATE;
 | 
			
		||||
                    well_state.currentInjectionControl(well_index, Well::InjectorCMode::RATE);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@@ -1622,13 +1620,13 @@ namespace Opm
 | 
			
		||||
            {
 | 
			
		||||
                double current_rate = 0.0;
 | 
			
		||||
                if( pu.phase_used[BlackoilPhases::Aqua] )
 | 
			
		||||
                    current_rate += well_state.wellReservoirRates()[ wellrate_index + pu.phase_pos[BlackoilPhases::Aqua] ];
 | 
			
		||||
                    current_rate += well_state.wellReservoirRates(well_index)[ pu.phase_pos[BlackoilPhases::Aqua] ];
 | 
			
		||||
 | 
			
		||||
                if( pu.phase_used[BlackoilPhases::Liquid] )
 | 
			
		||||
                    current_rate += well_state.wellReservoirRates()[ wellrate_index + pu.phase_pos[BlackoilPhases::Liquid] ];
 | 
			
		||||
                    current_rate += well_state.wellReservoirRates(well_index)[ pu.phase_pos[BlackoilPhases::Liquid] ];
 | 
			
		||||
 | 
			
		||||
                if( pu.phase_used[BlackoilPhases::Vapour] )
 | 
			
		||||
                    current_rate += well_state.wellReservoirRates()[ wellrate_index + pu.phase_pos[BlackoilPhases::Vapour] ];
 | 
			
		||||
                    current_rate += well_state.wellReservoirRates(well_index)[ pu.phase_pos[BlackoilPhases::Vapour] ];
 | 
			
		||||
 | 
			
		||||
                if (controls.reservoir_rate < current_rate) {
 | 
			
		||||
                    currentControl = Well::InjectorCMode::RESV;
 | 
			
		||||
@@ -1650,47 +1648,47 @@ namespace Opm
 | 
			
		||||
 | 
			
		||||
        if (well.isProducer( )) {
 | 
			
		||||
            const auto controls = well.productionControls(summaryState);
 | 
			
		||||
            Well::ProducerCMode& currentControl = well_state.currentProductionControls()[well_index];
 | 
			
		||||
            auto currentControl = well_state.currentProductionControl(well_index);
 | 
			
		||||
 | 
			
		||||
            if (controls.hasControl(Well::ProducerCMode::BHP) && currentControl != Well::ProducerCMode::BHP )
 | 
			
		||||
            {
 | 
			
		||||
                const double bhp = controls.bhp_limit;
 | 
			
		||||
                double current_bhp = well_state.bhp(well_index);
 | 
			
		||||
                if (bhp > current_bhp) {
 | 
			
		||||
                    currentControl = Well::ProducerCMode::BHP;
 | 
			
		||||
                    well_state.currentProductionControl(well_index, Well::ProducerCMode::BHP);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (controls.hasControl(Well::ProducerCMode::ORAT) && currentControl != Well::ProducerCMode::ORAT) {
 | 
			
		||||
                double current_rate = -well_state.wellRates()[ wellrate_index + pu.phase_pos[BlackoilPhases::Liquid] ];
 | 
			
		||||
                double current_rate = -well_state.wellRates(well_index)[ pu.phase_pos[BlackoilPhases::Liquid] ];
 | 
			
		||||
                if (controls.oil_rate < current_rate  ) {
 | 
			
		||||
                    currentControl = Well::ProducerCMode::ORAT;
 | 
			
		||||
                    well_state.currentProductionControl(well_index, Well::ProducerCMode::ORAT);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (controls.hasControl(Well::ProducerCMode::WRAT) && currentControl != Well::ProducerCMode::WRAT ) {
 | 
			
		||||
                double current_rate = -well_state.wellRates()[ wellrate_index + pu.phase_pos[BlackoilPhases::Aqua] ];
 | 
			
		||||
                double current_rate = -well_state.wellRates(well_index)[ pu.phase_pos[BlackoilPhases::Aqua] ];
 | 
			
		||||
                if (controls.water_rate < current_rate  ) {
 | 
			
		||||
                    currentControl = Well::ProducerCMode::WRAT;
 | 
			
		||||
                    well_state.currentProductionControl(well_index, Well::ProducerCMode::WRAT);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (controls.hasControl(Well::ProducerCMode::GRAT) && currentControl != Well::ProducerCMode::GRAT ) {
 | 
			
		||||
                double current_rate = -well_state.wellRates()[ wellrate_index + pu.phase_pos[BlackoilPhases::Vapour] ];
 | 
			
		||||
                double current_rate = -well_state.wellRates(well_index)[ pu.phase_pos[BlackoilPhases::Vapour] ];
 | 
			
		||||
                if (controls.gas_rate < current_rate  ) {
 | 
			
		||||
                    currentControl = Well::ProducerCMode::GRAT;
 | 
			
		||||
                    well_state.currentProductionControl(well_index, Well::ProducerCMode::GRAT);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (controls.hasControl(Well::ProducerCMode::LRAT) && currentControl != Well::ProducerCMode::LRAT) {
 | 
			
		||||
                double current_rate = -well_state.wellRates()[ wellrate_index + pu.phase_pos[BlackoilPhases::Liquid] ];
 | 
			
		||||
                current_rate -= well_state.wellRates()[ wellrate_index + pu.phase_pos[BlackoilPhases::Aqua] ];
 | 
			
		||||
                double current_rate = -well_state.wellRates(well_index)[ pu.phase_pos[BlackoilPhases::Liquid] ];
 | 
			
		||||
                current_rate -= well_state.wellRates(well_index)[ pu.phase_pos[BlackoilPhases::Aqua] ];
 | 
			
		||||
                if (controls.liquid_rate < current_rate  ) {
 | 
			
		||||
                    currentControl = Well::ProducerCMode::LRAT;
 | 
			
		||||
                    well_state.currentProductionControl(well_index, Well::ProducerCMode::LRAT);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -1698,16 +1696,16 @@ namespace Opm
 | 
			
		||||
            if (controls.hasControl(Well::ProducerCMode::RESV) && currentControl != Well::ProducerCMode::RESV ) {
 | 
			
		||||
                double current_rate = 0.0;
 | 
			
		||||
                if( pu.phase_used[BlackoilPhases::Aqua] )
 | 
			
		||||
                    current_rate -= well_state.wellReservoirRates()[ wellrate_index + pu.phase_pos[BlackoilPhases::Aqua] ];
 | 
			
		||||
                    current_rate -= well_state.wellReservoirRates(well_index)[ pu.phase_pos[BlackoilPhases::Aqua] ];
 | 
			
		||||
 | 
			
		||||
                if( pu.phase_used[BlackoilPhases::Liquid] )
 | 
			
		||||
                    current_rate -= well_state.wellReservoirRates()[ wellrate_index + pu.phase_pos[BlackoilPhases::Liquid] ];
 | 
			
		||||
                    current_rate -= well_state.wellReservoirRates(well_index)[ pu.phase_pos[BlackoilPhases::Liquid] ];
 | 
			
		||||
 | 
			
		||||
                if( pu.phase_used[BlackoilPhases::Vapour] )
 | 
			
		||||
                    current_rate -= well_state.wellReservoirRates()[ wellrate_index + pu.phase_pos[BlackoilPhases::Vapour] ];
 | 
			
		||||
                    current_rate -= well_state.wellReservoirRates(well_index)[ pu.phase_pos[BlackoilPhases::Vapour] ];
 | 
			
		||||
 | 
			
		||||
                if (controls.prediction_mode && controls.resv_rate < current_rate) {
 | 
			
		||||
                    currentControl = Well::ProducerCMode::RESV;
 | 
			
		||||
                    well_state.currentProductionControl(well_index, Well::ProducerCMode::RESV);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@@ -1732,7 +1730,7 @@ namespace Opm
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (resv_rate < current_rate) {
 | 
			
		||||
                        currentControl = Well::ProducerCMode::RESV;
 | 
			
		||||
                        well_state.currentProductionControl(well_index, Well::ProducerCMode::RESV);
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@@ -1743,7 +1741,7 @@ namespace Opm
 | 
			
		||||
                const auto& thp = this->getTHPConstraint(summaryState);
 | 
			
		||||
                double current_thp =  well_state.thp(well_index);
 | 
			
		||||
                if (thp > current_thp) {
 | 
			
		||||
                    currentControl = Well::ProducerCMode::THP;
 | 
			
		||||
                    well_state.currentProductionControl(well_index, Well::ProducerCMode::THP);
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -1769,7 +1767,7 @@ namespace Opm
 | 
			
		||||
        const int well_index = index_of_well_;
 | 
			
		||||
 | 
			
		||||
        if (well.isInjector()) {
 | 
			
		||||
            Well::InjectorCMode& currentControl = well_state.currentInjectionControls()[well_index];
 | 
			
		||||
            auto currentControl = well_state.currentInjectionControl(well_index);
 | 
			
		||||
 | 
			
		||||
            if (currentControl != Well::InjectorCMode::GRUP) {
 | 
			
		||||
                // This checks only the first encountered group limit,
 | 
			
		||||
@@ -1785,10 +1783,10 @@ namespace Opm
 | 
			
		||||
                // If a group constraint was broken, we set the current well control to
 | 
			
		||||
                // be GRUP.
 | 
			
		||||
                if (group_constraint.first) {
 | 
			
		||||
                    well_state.currentInjectionControls()[index_of_well_] = Well::InjectorCMode::GRUP;
 | 
			
		||||
                    well_state.currentInjectionControl(index_of_well_, Well::InjectorCMode::GRUP);
 | 
			
		||||
                    const int np = well_state.numPhases();
 | 
			
		||||
                    for (int p = 0; p<np; ++p) {
 | 
			
		||||
                        well_state.wellRates()[index_of_well_*np + p] *= group_constraint.second;
 | 
			
		||||
                        well_state.wellRates(index_of_well_)[p] *= group_constraint.second;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                return group_constraint.first;
 | 
			
		||||
@@ -1796,7 +1794,7 @@ namespace Opm
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (well.isProducer( )) {
 | 
			
		||||
            Well::ProducerCMode& currentControl = well_state.currentProductionControls()[well_index];
 | 
			
		||||
            auto currentControl = well_state.currentProductionControl(well_index);
 | 
			
		||||
 | 
			
		||||
            if (currentControl != Well::ProducerCMode::GRUP) {
 | 
			
		||||
                // This checks only the first encountered group limit,
 | 
			
		||||
@@ -1812,10 +1810,10 @@ namespace Opm
 | 
			
		||||
                // If a group constraint was broken, we set the current well control to
 | 
			
		||||
                // be GRUP.
 | 
			
		||||
                if (group_constraint.first) {
 | 
			
		||||
                    well_state.currentProductionControls()[index_of_well_] = Well::ProducerCMode::GRUP;
 | 
			
		||||
                    well_state.currentProductionControl(index_of_well_, Well::ProducerCMode::GRUP);
 | 
			
		||||
                    const int np = well_state.numPhases();
 | 
			
		||||
                    for (int p = 0; p<np; ++p) {
 | 
			
		||||
                        well_state.wellRates()[index_of_well_*np + p] *= group_constraint.second;
 | 
			
		||||
                        well_state.wellRates(index_of_well_)[p] *= group_constraint.second;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                return group_constraint.first;
 | 
			
		||||
@@ -1875,7 +1873,7 @@ namespace Opm
 | 
			
		||||
                                                          group_state,
 | 
			
		||||
                                                          current_step_,
 | 
			
		||||
                                                          guide_rate_,
 | 
			
		||||
                                                          well_state.wellRates().data() + index_of_well_ * phaseUsage().num_phases,
 | 
			
		||||
                                                          well_state.wellRates(index_of_well_).data(),
 | 
			
		||||
                                                          injectionPhase,
 | 
			
		||||
                                                          phaseUsage(),
 | 
			
		||||
                                                          efficiencyFactor,
 | 
			
		||||
@@ -1910,7 +1908,7 @@ namespace Opm
 | 
			
		||||
                                                           group_state,
 | 
			
		||||
                                                           current_step_,
 | 
			
		||||
                                                           guide_rate_,
 | 
			
		||||
                                                           well_state.wellRates().data() + index_of_well_ * phaseUsage().num_phases,
 | 
			
		||||
                                                           well_state.wellRates(index_of_well_).data(),
 | 
			
		||||
                                                           phaseUsage(),
 | 
			
		||||
                                                           efficiencyFactor,
 | 
			
		||||
                                                           schedule,
 | 
			
		||||
@@ -1937,7 +1935,7 @@ namespace Opm
 | 
			
		||||
                                                 EvalWell& control_eq,
 | 
			
		||||
                                                 DeferredLogger& deferred_logger)
 | 
			
		||||
    {
 | 
			
		||||
        const Well::InjectorCMode& current = well_state.currentInjectionControls()[index_of_well_];
 | 
			
		||||
        auto current = well_state.currentInjectionControl(index_of_well_);
 | 
			
		||||
        const InjectorType injectorType = controls.injector_type;
 | 
			
		||||
        const auto& pu = phaseUsage();
 | 
			
		||||
        const double efficiencyFactor = well_ecl_.getEfficiencyFactor();
 | 
			
		||||
@@ -2020,7 +2018,7 @@ namespace Opm
 | 
			
		||||
                                                  EvalWell& control_eq,
 | 
			
		||||
                                                  DeferredLogger& deferred_logger)
 | 
			
		||||
    {
 | 
			
		||||
        const Well::ProducerCMode& current = well_state.currentProductionControls()[index_of_well_];
 | 
			
		||||
        auto current = well_state.currentProductionControl(index_of_well_);
 | 
			
		||||
        const auto& pu = phaseUsage();
 | 
			
		||||
        const double efficiencyFactor = well_ecl_.getEfficiencyFactor();
 | 
			
		||||
 | 
			
		||||
@@ -2348,7 +2346,7 @@ namespace Opm
 | 
			
		||||
        // if more than one nonzero rate.
 | 
			
		||||
        int nonzero_rate_index = -1;
 | 
			
		||||
        for (int p = 0; p < number_of_phases_; ++p) {
 | 
			
		||||
            if (well_state.wellRates()[index_of_well_ * number_of_phases_ + p] != 0.0) {
 | 
			
		||||
            if (well_state.wellRates(index_of_well_)[p] != 0.0) {
 | 
			
		||||
                if (nonzero_rate_index == -1) {
 | 
			
		||||
                    nonzero_rate_index = p;
 | 
			
		||||
                } else {
 | 
			
		||||
@@ -2366,12 +2364,12 @@ namespace Opm
 | 
			
		||||
        std::vector<double> well_q_s = computeCurrentWellRates(ebosSimulator, deferred_logger);
 | 
			
		||||
 | 
			
		||||
        // Set the currently-zero phase flows to be nonzero in proportion to well_q_s.
 | 
			
		||||
        const double initial_nonzero_rate = well_state.wellRates()[index_of_well_ * number_of_phases_ + nonzero_rate_index];
 | 
			
		||||
        const double initial_nonzero_rate = well_state.wellRates(index_of_well_)[nonzero_rate_index];
 | 
			
		||||
        const int comp_idx_nz = flowPhaseToEbosCompIdx(nonzero_rate_index);
 | 
			
		||||
        for (int p = 0; p < number_of_phases_; ++p) {
 | 
			
		||||
            if (p != nonzero_rate_index) {
 | 
			
		||||
                const int comp_idx = flowPhaseToEbosCompIdx(p);
 | 
			
		||||
                double& rate = well_state.wellRates()[index_of_well_ * number_of_phases_ + p];
 | 
			
		||||
                double& rate = well_state.wellRates(index_of_well_)[p];
 | 
			
		||||
                rate = (initial_nonzero_rate/well_q_s[comp_idx_nz]) * (well_q_s[comp_idx]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -35,27 +35,26 @@ void WellState::init(const std::vector<double>& cellPressures,
 | 
			
		||||
                     const SummaryState& summary_state)
 | 
			
		||||
{
 | 
			
		||||
    // clear old name mapping
 | 
			
		||||
    wellMap_.clear();
 | 
			
		||||
 | 
			
		||||
    well_perf_data_ = well_perf_data;
 | 
			
		||||
    parallel_well_info_ = parallel_well_info;
 | 
			
		||||
 | 
			
		||||
    this->wellMap_.clear();
 | 
			
		||||
    this->perfpress_.clear();
 | 
			
		||||
    this->perfrates_.clear();
 | 
			
		||||
    this->status_.clear();
 | 
			
		||||
    this->well_perf_data_.clear();
 | 
			
		||||
    this->parallel_well_info_.clear();
 | 
			
		||||
    this->wellrates_.clear();
 | 
			
		||||
    {
 | 
			
		||||
        // const int nw = wells->number_of_wells;
 | 
			
		||||
        const int nw = wells_ecl.size();
 | 
			
		||||
        const int np = this->phase_usage_.num_phases;
 | 
			
		||||
        // const int np = wells->number_of_phases;
 | 
			
		||||
        status_.assign(nw, Well::Status::OPEN);
 | 
			
		||||
        bhp_.resize(nw, 0.0);
 | 
			
		||||
        thp_.resize(nw, 0.0);
 | 
			
		||||
        temperature_.resize(nw, 273.15 + 15.56); // standard condition temperature
 | 
			
		||||
        wellrates_.resize(nw * np, 0.0);
 | 
			
		||||
        int connpos = 0;
 | 
			
		||||
        for (int w = 0; w < nw; ++w) {
 | 
			
		||||
            const Well& well = wells_ecl[w];
 | 
			
		||||
 | 
			
		||||
            // Initialize bhp(), thp(), wellRates(), temperature().
 | 
			
		||||
            initSingleWell(cellPressures, w, well, *parallel_well_info[w], summary_state);
 | 
			
		||||
            initSingleWell(cellPressures, w, well, well_perf_data[w], parallel_well_info[w], summary_state);
 | 
			
		||||
 | 
			
		||||
            // Setup wellname -> well index mapping.
 | 
			
		||||
            const int num_perf_this_well = well_perf_data[w].size();
 | 
			
		||||
@@ -67,12 +66,6 @@ void WellState::init(const std::vector<double>& cellPressures,
 | 
			
		||||
            wellMapEntry[ 2 ] = num_perf_this_well;
 | 
			
		||||
            connpos += num_perf_this_well;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // The perforation rates and perforation pressures are
 | 
			
		||||
        // not expected to be consistent with bhp_ and wellrates_
 | 
			
		||||
        // after init().
 | 
			
		||||
        perfrates_.resize(connpos, 0.0);
 | 
			
		||||
        perfpress_.resize(connpos, -1e100);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -146,8 +139,7 @@ void WellState::shutWell(int well_index)
 | 
			
		||||
    this->thp_[well_index] = 0;
 | 
			
		||||
    this->bhp_[well_index] = 0;
 | 
			
		||||
    const int np = numPhases();
 | 
			
		||||
    for (int p = 0; p < np; ++p)
 | 
			
		||||
        this->wellrates_[np * well_index + p] = 0;
 | 
			
		||||
    this->wellrates_[well_index].assign(np, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WellState::stopWell(int well_index)
 | 
			
		||||
@@ -196,18 +188,17 @@ data::Wells WellState::report(const int* globalCellIdxMap,
 | 
			
		||||
        well.thp = this->thp( well_index );
 | 
			
		||||
        well.temperature = this->temperature( well_index );
 | 
			
		||||
 | 
			
		||||
        const auto wellrate_index = well_index * pu.num_phases;
 | 
			
		||||
        const auto& wv = this->wellRates();
 | 
			
		||||
        const auto& wv = this->wellRates(well_index);
 | 
			
		||||
        if( pu.phase_used[BlackoilPhases::Aqua] ) {
 | 
			
		||||
            well.rates.set( rt::wat, wv[ wellrate_index + pu.phase_pos[BlackoilPhases::Aqua] ] );
 | 
			
		||||
            well.rates.set( rt::wat, wv[ pu.phase_pos[BlackoilPhases::Aqua] ] );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( pu.phase_used[BlackoilPhases::Liquid] ) {
 | 
			
		||||
            well.rates.set( rt::oil, wv[ wellrate_index + pu.phase_pos[BlackoilPhases::Liquid] ] );
 | 
			
		||||
            well.rates.set( rt::oil, wv[ pu.phase_pos[BlackoilPhases::Liquid] ] );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( pu.phase_used[BlackoilPhases::Vapour] ) {
 | 
			
		||||
            well.rates.set( rt::gas, wv[ wellrate_index + pu.phase_pos[BlackoilPhases::Vapour] ] );
 | 
			
		||||
            well.rates.set( rt::gas, wv[ pu.phase_pos[BlackoilPhases::Vapour] ] );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (pwinfo.communication().size()==1)
 | 
			
		||||
@@ -239,8 +230,8 @@ void WellState::reportConnections(data::Well& well,
 | 
			
		||||
    const int num_perf_well = pd.size();
 | 
			
		||||
    well.connections.resize(num_perf_well);
 | 
			
		||||
 | 
			
		||||
    const auto * perf_rates = &this->perfRates()[itr.second[1]];
 | 
			
		||||
    const auto * perf_pressure = &this->perfPress()[itr.second[1]];
 | 
			
		||||
    const auto& perf_rates = this->perfRates(well_index);
 | 
			
		||||
    const auto& perf_pressure = this->perfPress(well_index);
 | 
			
		||||
    for( int i = 0; i < num_perf_well; ++i ) {
 | 
			
		||||
        const auto active_index = this->well_perf_data_[well_index][i].cell_index;
 | 
			
		||||
        auto& connection = well.connections[ i ];
 | 
			
		||||
@@ -277,7 +268,8 @@ void WellState::gatherVectorsOnRoot(const std::vector<data::Connection>& from_co
 | 
			
		||||
void WellState::initSingleWell(const std::vector<double>& cellPressures,
 | 
			
		||||
                               const int w,
 | 
			
		||||
                               const Well& well,
 | 
			
		||||
                               const ParallelWellInfo& well_info,
 | 
			
		||||
                               const std::vector<PerforationData>& well_perf_data,
 | 
			
		||||
                               const ParallelWellInfo* well_info,
 | 
			
		||||
                               const SummaryState& summary_state)
 | 
			
		||||
{
 | 
			
		||||
    assert(well.isInjector() || well.isProducer());
 | 
			
		||||
@@ -286,15 +278,18 @@ void WellState::initSingleWell(const std::vector<double>& cellPressures,
 | 
			
		||||
    // May be overwritten below.
 | 
			
		||||
    const auto& pu = this->phase_usage_;
 | 
			
		||||
    const int np = pu.num_phases;
 | 
			
		||||
    for (int p = 0; p < np; ++p) {
 | 
			
		||||
        wellrates_[np*w + p] = 0.0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( well.isInjector() ) {
 | 
			
		||||
        temperature_[w] = well.injectionControls(summary_state).temperature;
 | 
			
		||||
    }
 | 
			
		||||
    this->status_.add(well.name(), Well::Status::OPEN);
 | 
			
		||||
    this->well_perf_data_.add(well.name(), well_perf_data);
 | 
			
		||||
    this->parallel_well_info_.add(well.name(), well_info);
 | 
			
		||||
    this->wellrates_.add(well.name(), std::vector<double>(np, 0));
 | 
			
		||||
 | 
			
		||||
    const int num_perf_this_well = well_info.communication().sum(well_perf_data_[w].size());
 | 
			
		||||
    const int num_perf_this_well = well_info->communication().sum(well_perf_data_[w].size());
 | 
			
		||||
    this->perfpress_.add(well.name(), std::vector<double>(num_perf_this_well, -1e100));
 | 
			
		||||
    this->perfrates_.add(well.name(), std::vector<double>(num_perf_this_well, 0));
 | 
			
		||||
    if ( num_perf_this_well == 0 ) {
 | 
			
		||||
        // No perforations of the well. Initialize to zero.
 | 
			
		||||
        bhp_[w] = 0.;
 | 
			
		||||
@@ -315,7 +310,7 @@ void WellState::initSingleWell(const std::vector<double>& cellPressures,
 | 
			
		||||
 | 
			
		||||
    const double local_pressure = well_perf_data_[w].empty() ?
 | 
			
		||||
                                      0 : cellPressures[well_perf_data_[w][0].cell_index];
 | 
			
		||||
    const double global_pressure = well_info.broadcastFirstPerforationValue(local_pressure);
 | 
			
		||||
    const double global_pressure = well_info->broadcastFirstPerforationValue(local_pressure);
 | 
			
		||||
 | 
			
		||||
    if (well.getStatus() == Well::Status::OPEN) {
 | 
			
		||||
        this->openWell(w);
 | 
			
		||||
@@ -348,20 +343,21 @@ void WellState::initSingleWell(const std::vector<double>& cellPressures,
 | 
			
		||||
        //    (producer) or RATE (injector).
 | 
			
		||||
        //    Otherwise, we cannot set the correct
 | 
			
		||||
        //    value here and initialize to zero rate.
 | 
			
		||||
        auto & well_rates = this->wellrates_[w];
 | 
			
		||||
        if (well.isInjector()) {
 | 
			
		||||
            if (inj_controls.cmode == Well::InjectorCMode::RATE) {
 | 
			
		||||
                switch (inj_controls.injector_type) {
 | 
			
		||||
                case InjectorType::WATER:
 | 
			
		||||
                    assert(pu.phase_used[BlackoilPhases::Aqua]);
 | 
			
		||||
                    wellrates_[np*w + pu.phase_pos[BlackoilPhases::Aqua]] = inj_surf_rate;
 | 
			
		||||
                    well_rates[pu.phase_pos[BlackoilPhases::Aqua]] = inj_surf_rate;
 | 
			
		||||
                    break;
 | 
			
		||||
                case InjectorType::GAS:
 | 
			
		||||
                    assert(pu.phase_used[BlackoilPhases::Vapour]);
 | 
			
		||||
                    wellrates_[np*w + pu.phase_pos[BlackoilPhases::Vapour]] = inj_surf_rate;
 | 
			
		||||
                    well_rates[pu.phase_pos[BlackoilPhases::Vapour]] = inj_surf_rate;
 | 
			
		||||
                    break;
 | 
			
		||||
                case InjectorType::OIL:
 | 
			
		||||
                    assert(pu.phase_used[BlackoilPhases::Liquid]);
 | 
			
		||||
                    wellrates_[np*w + pu.phase_pos[BlackoilPhases::Liquid]] = inj_surf_rate;
 | 
			
		||||
                    well_rates[pu.phase_pos[BlackoilPhases::Liquid]] = inj_surf_rate;
 | 
			
		||||
                    break;
 | 
			
		||||
                case InjectorType::MULTI:
 | 
			
		||||
                    // Not currently handled, keep zero init.
 | 
			
		||||
@@ -376,15 +372,15 @@ void WellState::initSingleWell(const std::vector<double>& cellPressures,
 | 
			
		||||
            switch (prod_controls.cmode) {
 | 
			
		||||
            case Well::ProducerCMode::ORAT:
 | 
			
		||||
                assert(pu.phase_used[BlackoilPhases::Liquid]);
 | 
			
		||||
                wellrates_[np*w + pu.phase_pos[BlackoilPhases::Liquid]] = -prod_controls.oil_rate;
 | 
			
		||||
                well_rates[pu.phase_pos[BlackoilPhases::Liquid]] = -prod_controls.oil_rate;
 | 
			
		||||
                break;
 | 
			
		||||
            case Well::ProducerCMode::WRAT:
 | 
			
		||||
                assert(pu.phase_used[BlackoilPhases::Aqua]);
 | 
			
		||||
                wellrates_[np*w + pu.phase_pos[BlackoilPhases::Aqua]] = -prod_controls.water_rate;
 | 
			
		||||
                well_rates[pu.phase_pos[BlackoilPhases::Aqua]] = -prod_controls.water_rate;
 | 
			
		||||
                break;
 | 
			
		||||
            case Well::ProducerCMode::GRAT:
 | 
			
		||||
                assert(pu.phase_used[BlackoilPhases::Vapour]);
 | 
			
		||||
                wellrates_[np*w + pu.phase_pos[BlackoilPhases::Vapour]] = -prod_controls.gas_rate;
 | 
			
		||||
                well_rates[pu.phase_pos[BlackoilPhases::Vapour]] = -prod_controls.gas_rate;
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                // Keep zero init.
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,7 @@
 | 
			
		||||
#include <opm/output/data/Wells.hpp>
 | 
			
		||||
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
 | 
			
		||||
#include <opm/simulators/wells/PerforationData.hpp>
 | 
			
		||||
#include <opm/simulators/wells/WellContainer.hpp>
 | 
			
		||||
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
@@ -92,16 +93,21 @@ public:
 | 
			
		||||
    double temperature(std::size_t well_index) const { return temperature_[well_index]; }
 | 
			
		||||
 | 
			
		||||
    /// One rate per well and phase.
 | 
			
		||||
    std::vector<double>& wellRates() { return wellrates_; }
 | 
			
		||||
    const std::vector<double>& wellRates() const { return wellrates_; }
 | 
			
		||||
    const WellContainer<std::vector<double>>& wellRates() const { return wellrates_; }
 | 
			
		||||
    std::vector<double>& wellRates(std::size_t well_index) { return wellrates_[well_index]; }
 | 
			
		||||
    const std::vector<double>& wellRates(std::size_t well_index) const { return wellrates_[well_index]; }
 | 
			
		||||
 | 
			
		||||
    /// One rate per well connection.
 | 
			
		||||
    std::vector<double>& perfRates() { return perfrates_; }
 | 
			
		||||
    const std::vector<double>& perfRates() const { return perfrates_; }
 | 
			
		||||
    std::vector<double>& perfRates(std::size_t well_index) { return this->perfrates_[well_index]; }
 | 
			
		||||
    const std::vector<double>& perfRates(std::size_t well_index) const { return this->perfrates_[well_index]; }
 | 
			
		||||
    std::vector<double>& perfRates(const std::string& wname) { return this->perfrates_[wname]; }
 | 
			
		||||
    const std::vector<double>& perfRates(const std::string& wname) const { return this->perfrates_[wname]; }
 | 
			
		||||
 | 
			
		||||
    /// One pressure per well connection.
 | 
			
		||||
    std::vector<double>& perfPress() { return perfpress_; }
 | 
			
		||||
    const std::vector<double>& perfPress() const { return perfpress_; }
 | 
			
		||||
    std::vector<double>& perfPress(std::size_t well_index) { return perfpress_[well_index]; }
 | 
			
		||||
    const std::vector<double>& perfPress(std::size_t well_index) const { return perfpress_[well_index]; }
 | 
			
		||||
    std::vector<double>& perfPress(const std::string& wname) { return perfpress_[wname]; }
 | 
			
		||||
    const std::vector<double>& perfPress(const std::string& wname) const { return perfpress_[wname]; }
 | 
			
		||||
 | 
			
		||||
    const WellMapType& wellMap() const { return wellMap_; }
 | 
			
		||||
    WellMapType& wellMap() { return wellMap_; }
 | 
			
		||||
@@ -148,18 +154,18 @@ public:
 | 
			
		||||
                                   const int* globalCellIdxMap) const;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    std::vector<Well::Status> status_;
 | 
			
		||||
    std::vector<std::vector<PerforationData>> well_perf_data_;
 | 
			
		||||
    std::vector<ParallelWellInfo*> parallel_well_info_;
 | 
			
		||||
    WellContainer<Well::Status> status_;
 | 
			
		||||
    WellContainer<std::vector<PerforationData>> well_perf_data_;
 | 
			
		||||
    WellContainer<const ParallelWellInfo*> parallel_well_info_;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    PhaseUsage phase_usage_;
 | 
			
		||||
    std::vector<double> bhp_;
 | 
			
		||||
    std::vector<double> thp_;
 | 
			
		||||
    std::vector<double> temperature_;
 | 
			
		||||
    std::vector<double> wellrates_;
 | 
			
		||||
    std::vector<double> perfrates_;
 | 
			
		||||
    std::vector<double> perfpress_;
 | 
			
		||||
    WellContainer<std::vector<double>> wellrates_;
 | 
			
		||||
    WellContainer<std::vector<double>> perfrates_;
 | 
			
		||||
    WellContainer<std::vector<double>> perfpress_;
 | 
			
		||||
 | 
			
		||||
    WellMapType wellMap_;
 | 
			
		||||
 | 
			
		||||
@@ -171,7 +177,8 @@ private:
 | 
			
		||||
    void initSingleWell(const std::vector<double>& cellPressures,
 | 
			
		||||
                        const int w,
 | 
			
		||||
                        const Well& well,
 | 
			
		||||
                        const ParallelWellInfo& well_info,
 | 
			
		||||
                        const std::vector<PerforationData>& well_perf_data,
 | 
			
		||||
                        const ParallelWellInfo* well_info,
 | 
			
		||||
                        const SummaryState& summary_state);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -62,7 +62,7 @@ void WellStateFullyImplicitBlackoil::init(const std::vector<double>& cellPressur
 | 
			
		||||
        nperf += wpd.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    well_reservoir_rates_.resize(nw * this->numPhases(), 0.0);
 | 
			
		||||
    well_reservoir_rates_.clear();
 | 
			
		||||
    well_dissolved_gas_rates_.resize(nw, 0.0);
 | 
			
		||||
    well_vaporized_oil_rates_.resize(nw, 0.0);
 | 
			
		||||
 | 
			
		||||
@@ -100,36 +100,42 @@ void WellStateFullyImplicitBlackoil::init(const std::vector<double>& cellPressur
 | 
			
		||||
        const int connpos = well_info[1];
 | 
			
		||||
        const int num_perf_this_well = well_info[2];
 | 
			
		||||
        const int global_num_perf_this_well = parallel_well_info[w]->communication().sum(num_perf_this_well);
 | 
			
		||||
        auto * perf_press = &this->perfPress()[connpos];
 | 
			
		||||
        auto& perf_press = this->perfPress(w);
 | 
			
		||||
        auto * phase_rates = &this->mutable_perfPhaseRates()[connpos * this->numPhases()];
 | 
			
		||||
 | 
			
		||||
        for (int perf = 0; perf < num_perf_this_well; ++perf) {
 | 
			
		||||
            if (wells_ecl[w].getStatus() == Well::Status::OPEN) {
 | 
			
		||||
                for (int p = 0; p < this->numPhases(); ++p) {
 | 
			
		||||
                    phase_rates[this->numPhases()*perf + p] = wellRates()[this->numPhases()*w + p] / double(global_num_perf_this_well);
 | 
			
		||||
                    phase_rates[this->numPhases()*perf + p] = wellRates(w)[p] / double(global_num_perf_this_well);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            perf_press[perf] = cellPressures[well_perf_data[w][perf].cell_index];
 | 
			
		||||
        }
 | 
			
		||||
        num_perf_[w] = num_perf_this_well;
 | 
			
		||||
        first_perf_index_[w] = connpos;
 | 
			
		||||
 | 
			
		||||
        this->well_reservoir_rates_.add(wname, std::vector<double>(np, 0));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    is_producer_.resize(nw, false);
 | 
			
		||||
    is_producer_.clear();
 | 
			
		||||
    for (int w = 0; w < nw; ++w) {
 | 
			
		||||
        is_producer_[w] = wells_ecl[w].isProducer();
 | 
			
		||||
        const auto& ecl_well = wells_ecl[w];
 | 
			
		||||
        this->is_producer_.add( ecl_well.name(), ecl_well.isProducer());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    current_injection_controls_.resize(nw, Well::InjectorCMode::CMODE_UNDEFINED);
 | 
			
		||||
    current_production_controls_.resize(nw, Well::ProducerCMode::CMODE_UNDEFINED);
 | 
			
		||||
    current_injection_controls_.clear();
 | 
			
		||||
    current_production_controls_.clear();
 | 
			
		||||
    for (int w = 0; w < nw; ++w) {
 | 
			
		||||
        const auto& wname = wells_ecl[w].name();
 | 
			
		||||
        current_production_controls_.add(wname, Well::ProducerCMode::CMODE_UNDEFINED);
 | 
			
		||||
        current_injection_controls_.add(wname, Well::InjectorCMode::CMODE_UNDEFINED);
 | 
			
		||||
        if (wells_ecl[w].isProducer()) {
 | 
			
		||||
            const auto controls = wells_ecl[w].productionControls(summary_state);
 | 
			
		||||
            currentProductionControls()[w] = controls.cmode;
 | 
			
		||||
            currentProductionControl(w, controls.cmode);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
            const auto controls = wells_ecl[w].injectionControls(summary_state);
 | 
			
		||||
            currentInjectionControls()[w] = controls.cmode;
 | 
			
		||||
            currentInjectionControl(w, controls.cmode);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -194,21 +200,12 @@ void WellStateFullyImplicitBlackoil::init(const std::vector<double>& cellPressur
 | 
			
		||||
 | 
			
		||||
                // If new target is set using WCONPROD, WCONINJE etc. we use the new control
 | 
			
		||||
                if (!this->events_[w].hasEvent(WellStateFullyImplicitBlackoil::event_mask)) {
 | 
			
		||||
                    current_injection_controls_[ newIndex ] = prevState->currentInjectionControls()[ oldIndex ];
 | 
			
		||||
                    current_production_controls_[ newIndex ] = prevState->currentProductionControls()[ oldIndex ];
 | 
			
		||||
                    current_injection_controls_[ newIndex ] = prevState->currentInjectionControl(oldIndex);
 | 
			
		||||
                    current_production_controls_[ newIndex ] = prevState->currentProductionControl(oldIndex);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // wellrates
 | 
			
		||||
                for( int i=0, idx=newIndex*np, oldidx=oldIndex*np; i<np; ++i, ++idx, ++oldidx )
 | 
			
		||||
                {
 | 
			
		||||
                    wellRates()[ idx ] = prevState->wellRates()[ oldidx ];
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // wellResrates
 | 
			
		||||
                for( int i=0, idx=newIndex*np, oldidx=oldIndex*np; i<np; ++i, ++idx, ++oldidx )
 | 
			
		||||
                {
 | 
			
		||||
                    wellReservoirRates()[ idx ] = prevState->wellReservoirRates()[ oldidx ];
 | 
			
		||||
                }
 | 
			
		||||
                wellRates(w) = prevState->wellRates(oldIndex);
 | 
			
		||||
                wellReservoirRates(w) = prevState->wellReservoirRates(oldIndex);
 | 
			
		||||
 | 
			
		||||
                // Well potentials
 | 
			
		||||
                for( int i=0, idx=newIndex*np, oldidx=oldIndex*np; i<np; ++i, ++idx, ++oldidx )
 | 
			
		||||
@@ -253,7 +250,7 @@ void WellStateFullyImplicitBlackoil::init(const std::vector<double>& cellPressur
 | 
			
		||||
                    auto * target_rates = &this->mutable_perfPhaseRates()[connpos*np];
 | 
			
		||||
                    for (int perf_index = 0; perf_index < num_perf_this_well; perf_index++) {
 | 
			
		||||
                        for (int p = 0; p < np; ++p) {
 | 
			
		||||
                            target_rates[perf_index*np + p] = wellRates()[np*newIndex + p] / double(global_num_perf_this_well);
 | 
			
		||||
                            target_rates[perf_index*np + p] = wellRates(w)[p] / double(global_num_perf_this_well);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@@ -261,8 +258,8 @@ void WellStateFullyImplicitBlackoil::init(const std::vector<double>& cellPressur
 | 
			
		||||
                // perfPressures
 | 
			
		||||
                if (global_num_perf_same)
 | 
			
		||||
                {
 | 
			
		||||
                    auto * target_press = &perfPress()[connpos];
 | 
			
		||||
                    const auto * src_press = &prevState->perfPress()[oldPerf_idx_beg];
 | 
			
		||||
                    auto& target_press = perfPress(w);
 | 
			
		||||
                    const auto& src_press = prevState->perfPress(well.name());
 | 
			
		||||
                    for (int perf = 0; perf < num_perf_this_well; ++perf)
 | 
			
		||||
                    {
 | 
			
		||||
                        target_press[perf] = src_press[perf];
 | 
			
		||||
@@ -335,8 +332,8 @@ void WellStateFullyImplicitBlackoil::init(const std::vector<double>& cellPressur
 | 
			
		||||
            seg_number_[w] = 1; // Top segment is segment #1
 | 
			
		||||
            this->seg_press_[w] = this->bhp(w);
 | 
			
		||||
        }
 | 
			
		||||
        seg_rates_ = wellRates();
 | 
			
		||||
 | 
			
		||||
        //seg_rates_ = wellRates();
 | 
			
		||||
        seg_rates_.assign(nw*np, 0);
 | 
			
		||||
        seg_pressdrop_.assign(nw, 0.);
 | 
			
		||||
        seg_pressdrop_hydorstatic_.assign(nw, 0.);
 | 
			
		||||
        seg_pressdrop_friction_.assign(nw, 0.);
 | 
			
		||||
@@ -420,24 +417,25 @@ WellStateFullyImplicitBlackoil::report(const int* globalCellIdxMap,
 | 
			
		||||
 | 
			
		||||
        auto& well = res.at(wt.first);
 | 
			
		||||
        const int well_rate_index = w * pu.num_phases;
 | 
			
		||||
        const auto& reservoir_rates = this->well_reservoir_rates_[w];
 | 
			
		||||
 | 
			
		||||
        if (pu.phase_used[Water]) {
 | 
			
		||||
            const auto i = well_rate_index + pu.phase_pos[Water];
 | 
			
		||||
            well.rates.set(rt::reservoir_water, this->well_reservoir_rates_[i]);
 | 
			
		||||
            well.rates.set(rt::reservoir_water, reservoir_rates[pu.phase_pos[Water]]);
 | 
			
		||||
            well.rates.set(rt::productivity_index_water, this->productivity_index_[i]);
 | 
			
		||||
            well.rates.set(rt::well_potential_water, this->well_potentials_[i]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (pu.phase_used[Oil]) {
 | 
			
		||||
            const auto i = well_rate_index + pu.phase_pos[Oil];
 | 
			
		||||
            well.rates.set(rt::reservoir_oil, this->well_reservoir_rates_[i]);
 | 
			
		||||
            well.rates.set(rt::reservoir_oil, reservoir_rates[pu.phase_pos[Oil]]);
 | 
			
		||||
            well.rates.set(rt::productivity_index_oil, this->productivity_index_[i]);
 | 
			
		||||
            well.rates.set(rt::well_potential_oil, this->well_potentials_[i]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (pu.phase_used[Gas]) {
 | 
			
		||||
            const auto i = well_rate_index + pu.phase_pos[Gas];
 | 
			
		||||
            well.rates.set(rt::reservoir_gas, this->well_reservoir_rates_[i]);
 | 
			
		||||
            well.rates.set(rt::reservoir_gas, reservoir_rates[pu.phase_pos[Gas]]);
 | 
			
		||||
            well.rates.set(rt::productivity_index_gas, this->productivity_index_[i]);
 | 
			
		||||
            well.rates.set(rt::well_potential_gas, this->well_potentials_[i]);
 | 
			
		||||
        }
 | 
			
		||||
@@ -468,8 +466,8 @@ WellStateFullyImplicitBlackoil::report(const int* globalCellIdxMap,
 | 
			
		||||
            auto& curr = well.current_control;
 | 
			
		||||
 | 
			
		||||
            curr.isProducer = this->is_producer_[w];
 | 
			
		||||
            curr.prod = this->currentProductionControls()[w];
 | 
			
		||||
            curr.inj  = this->currentInjectionControls() [w];
 | 
			
		||||
            curr.prod = this->currentProductionControl(w);
 | 
			
		||||
            curr.inj  = this->currentInjectionControl(w);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const auto nseg = this->numSegments(w);
 | 
			
		||||
@@ -559,13 +557,14 @@ void WellStateFullyImplicitBlackoil::initWellStateMSWell(const std::vector<Well>
 | 
			
		||||
        const int connpos = well_info[1];
 | 
			
		||||
        const int num_perf_this_well = well_info[2];
 | 
			
		||||
 | 
			
		||||
        const auto& rates = this->wellRates(w);
 | 
			
		||||
        top_segment_index_.push_back(nseg_);
 | 
			
		||||
        if ( !well_ecl.isMultiSegment() ) { // not multi-segment well
 | 
			
		||||
            nseg_ += 1;
 | 
			
		||||
            seg_number_.push_back(1); // Assign single segment (top) as number 1.
 | 
			
		||||
            seg_press_.push_back(bhp(w));
 | 
			
		||||
            for (int p = 0; p < np; ++p) {
 | 
			
		||||
                seg_rates_.push_back(wellRates()[np * w + p]);
 | 
			
		||||
                seg_rates_.push_back(rates[p]);
 | 
			
		||||
            }
 | 
			
		||||
        } else { // it is a multi-segment well
 | 
			
		||||
            const WellSegments& segment_set = well_ecl.getSegments();
 | 
			
		||||
@@ -641,8 +640,7 @@ void WellStateFullyImplicitBlackoil::initWellStateMSWell(const std::vector<Well>
 | 
			
		||||
                // top segment is always the first one, and its pressure is the well bhp
 | 
			
		||||
                seg_press_.push_back(bhp(w));
 | 
			
		||||
                const int top_segment = top_segment_index_[w];
 | 
			
		||||
                const int start_perf = connpos;
 | 
			
		||||
                const auto * perf_press = &this->perfPress()[start_perf];
 | 
			
		||||
                const auto& perf_press = this->perfPress(w);
 | 
			
		||||
                for (int seg = 1; seg < well_nseg; ++seg) {
 | 
			
		||||
                    if ( !segment_perforations[seg].empty() ) {
 | 
			
		||||
                        const int first_perf = segment_perforations[seg][0];
 | 
			
		||||
@@ -769,7 +767,7 @@ void WellStateFullyImplicitBlackoil::shutWell(int well_index)
 | 
			
		||||
    WellState::shutWell(well_index);
 | 
			
		||||
    const int np = numPhases();
 | 
			
		||||
 | 
			
		||||
    auto* resv = &this->well_reservoir_rates_[np*well_index + 0];
 | 
			
		||||
    auto& resv = this->well_reservoir_rates_[well_index];
 | 
			
		||||
    auto* wpi  = &this->productivity_index_[np*well_index + 0];
 | 
			
		||||
 | 
			
		||||
    for (int p = 0; p < np; ++p) {
 | 
			
		||||
@@ -849,7 +847,7 @@ void WellStateFullyImplicitBlackoil::communicateGroupRates(const Comm& comm)
 | 
			
		||||
template<class Comm>
 | 
			
		||||
void WellStateFullyImplicitBlackoil::updateGlobalIsGrup(const Comm& comm)
 | 
			
		||||
{
 | 
			
		||||
    this->global_well_info.value().update_group(this->status_, this->currentInjectionControls(), this->currentProductionControls());
 | 
			
		||||
    this->global_well_info.value().update_group(this->status_.data(), this->current_injection_controls_.data(), this->current_production_controls_.data());
 | 
			
		||||
    this->global_well_info.value().communicate(comm);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -99,12 +99,12 @@ public:
 | 
			
		||||
    const std::vector<double>& perfPhaseRates() const { return perfphaserates_; }
 | 
			
		||||
 | 
			
		||||
    /// One current control per injecting well.
 | 
			
		||||
    std::vector<Opm::Well::InjectorCMode>& currentInjectionControls() { return current_injection_controls_; }
 | 
			
		||||
    const std::vector<Opm::Well::InjectorCMode>& currentInjectionControls() const { return current_injection_controls_; }
 | 
			
		||||
    Well::InjectorCMode currentInjectionControl(std::size_t well_index) const { return current_injection_controls_[well_index]; }
 | 
			
		||||
    void currentInjectionControl(std::size_t well_index, Well::InjectorCMode cmode) { current_injection_controls_[well_index] = cmode; }
 | 
			
		||||
 | 
			
		||||
    /// One current control per producing well.
 | 
			
		||||
    std::vector<Well::ProducerCMode>& currentProductionControls() { return current_production_controls_; }
 | 
			
		||||
    const std::vector<Well::ProducerCMode>& currentProductionControls() const { return current_production_controls_; }
 | 
			
		||||
    Well::ProducerCMode currentProductionControl(std::size_t well_index) const { return current_production_controls_[well_index]; }
 | 
			
		||||
    void currentProductionControl(std::size_t well_index, Well::ProducerCMode cmode) { current_production_controls_[well_index] = cmode; }
 | 
			
		||||
 | 
			
		||||
    void setCurrentWellRates(const std::string& wellName, const std::vector<double>& rates ) {
 | 
			
		||||
        well_rates[wellName].second = rates;
 | 
			
		||||
@@ -161,14 +161,16 @@ public:
 | 
			
		||||
    /// One rate pr well
 | 
			
		||||
    double brineWellRate(const int w) const;
 | 
			
		||||
 | 
			
		||||
    std::vector<double>& wellReservoirRates()
 | 
			
		||||
    const WellContainer<std::vector<double>>& wellReservoirRates() const { return well_reservoir_rates_; }
 | 
			
		||||
 | 
			
		||||
    std::vector<double>& wellReservoirRates(std::size_t well_index)
 | 
			
		||||
    {
 | 
			
		||||
        return well_reservoir_rates_;
 | 
			
		||||
        return well_reservoir_rates_[well_index];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const std::vector<double>& wellReservoirRates() const
 | 
			
		||||
    const std::vector<double>& wellReservoirRates(std::size_t well_index) const
 | 
			
		||||
    {
 | 
			
		||||
        return well_reservoir_rates_;
 | 
			
		||||
        return well_reservoir_rates_[well_index];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::vector<double>& wellDissolvedGasRates()
 | 
			
		||||
@@ -365,15 +367,15 @@ public:
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    std::vector<double> perfphaserates_;
 | 
			
		||||
    std::vector<bool> is_producer_; // Size equal to number of local wells.
 | 
			
		||||
    WellContainer<int> is_producer_; // Size equal to number of local wells.
 | 
			
		||||
 | 
			
		||||
    // vector with size number of wells +1.
 | 
			
		||||
    // iterate over all perforations of a given well
 | 
			
		||||
    // for (int perf = first_perf_index_[well_index]; perf < first_perf_index_[well_index] + num_perf_[well_index]; ++perf)
 | 
			
		||||
    std::vector<int> first_perf_index_;
 | 
			
		||||
    std::vector<int> num_perf_;
 | 
			
		||||
    std::vector<Opm::Well::InjectorCMode> current_injection_controls_;
 | 
			
		||||
    std::vector<Well::ProducerCMode> current_production_controls_;
 | 
			
		||||
    WellContainer<Opm::Well::InjectorCMode> current_injection_controls_;
 | 
			
		||||
    WellContainer<Well::ProducerCMode> current_production_controls_;
 | 
			
		||||
 | 
			
		||||
    // Use of std::optional<> here is a technical crutch, the
 | 
			
		||||
    // WellStateFullyImplicitBlackoil class should be default constructible,
 | 
			
		||||
@@ -405,7 +407,7 @@ private:
 | 
			
		||||
 | 
			
		||||
    // phase rates under reservoir condition for wells
 | 
			
		||||
    // or voidage phase rates
 | 
			
		||||
    std::vector<double> well_reservoir_rates_;
 | 
			
		||||
    WellContainer<std::vector<double>> well_reservoir_rates_;
 | 
			
		||||
 | 
			
		||||
    // dissolved gas rates or solution gas production rates
 | 
			
		||||
    // should be zero for injection wells
 | 
			
		||||
 
 | 
			
		||||
@@ -393,37 +393,61 @@ BOOST_AUTO_TEST_CASE(STOP_well)
 | 
			
		||||
 | 
			
		||||
    std::vector<Opm::ParallelWellInfo> pinfos;
 | 
			
		||||
    auto wstate = buildWellState(setup, 0, pinfos);
 | 
			
		||||
    for (const auto& p : wstate.perfPress())
 | 
			
		||||
        BOOST_CHECK(p > 0);
 | 
			
		||||
    for (std::size_t well_index = 0; well_index < setup.sched.numWells(0); well_index++) {
 | 
			
		||||
        for (const auto& p : wstate.perfPress(well_index))
 | 
			
		||||
            BOOST_CHECK(p > 0);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
BOOST_AUTO_TEST_CASE(GlobalWellInfo_TEST) {
 | 
			
		||||
    const Setup setup{ "msw.data" };
 | 
			
		||||
    std::vector<Opm::Well> local_wells = { setup.sched.getWell("PROD01", 1) };
 | 
			
		||||
    Opm::GlobalWellInfo gwi(setup.sched, 1, local_wells);
 | 
			
		||||
 | 
			
		||||
    BOOST_CHECK(!gwi.in_injecting_group("INJE01"));
 | 
			
		||||
    BOOST_CHECK(!gwi.in_injecting_group("PROD01"));
 | 
			
		||||
    BOOST_CHECK(!gwi.in_producing_group("INJE01"));
 | 
			
		||||
    BOOST_CHECK(!gwi.in_producing_group("PROD01"));
 | 
			
		||||
 | 
			
		||||
    BOOST_CHECK_EQUAL( gwi.well_name(0), "INJE01");
 | 
			
		||||
    BOOST_CHECK_EQUAL( gwi.well_name(1), "PROD01");
 | 
			
		||||
    BOOST_CHECK_EQUAL( gwi.well_index("PROD01"), 1);
 | 
			
		||||
 | 
			
		||||
    BOOST_CHECK_THROW( gwi.update_group( {}, {}, {} ), std::exception);
 | 
			
		||||
 | 
			
		||||
    gwi.update_group( {Opm::Well::Status::OPEN}, {Opm::Well::InjectorCMode::CMODE_UNDEFINED}, {Opm::Well::ProducerCMode::GRUP} );
 | 
			
		||||
    BOOST_CHECK(!gwi.in_producing_group("INJE01"));
 | 
			
		||||
    BOOST_CHECK(gwi.in_producing_group("PROD01"));
 | 
			
		||||
 | 
			
		||||
    gwi.update_group( {Opm::Well::Status::OPEN}, {Opm::Well::InjectorCMode::CMODE_UNDEFINED}, {Opm::Well::ProducerCMode::NONE} );
 | 
			
		||||
    BOOST_CHECK(!gwi.in_producing_group("INJE01"));
 | 
			
		||||
    BOOST_CHECK(!gwi.in_producing_group("PROD01"));
 | 
			
		||||
}
 | 
			
		||||
//BOOST_AUTO_TEST_CASE(GlobalWellInfo_TEST) {
 | 
			
		||||
//    const Setup setup{ "msw.data" };
 | 
			
		||||
//    std::vector<Opm::Well> local_wells = { setup.sched.getWell("PROD01", 1) };
 | 
			
		||||
//    Opm::GlobalWellInfo gwi(setup.sched, 1, local_wells);
 | 
			
		||||
//    Opm::WellContainer<Opm::Well::Status> status({{"PROD01", Opm::Well::Status::OPEN}});
 | 
			
		||||
//
 | 
			
		||||
//    BOOST_CHECK(!gwi.in_injecting_group("INJE01"));
 | 
			
		||||
//    BOOST_CHECK(!gwi.in_injecting_group("PROD01"));
 | 
			
		||||
//    BOOST_CHECK(!gwi.in_producing_group("INJE01"));
 | 
			
		||||
//    BOOST_CHECK(!gwi.in_producing_group("PROD01"));
 | 
			
		||||
//
 | 
			
		||||
//    BOOST_CHECK_EQUAL( gwi.well_name(0), "INJE01");
 | 
			
		||||
//    BOOST_CHECK_EQUAL( gwi.well_name(1), "PROD01");
 | 
			
		||||
//    BOOST_CHECK_EQUAL( gwi.well_index("PROD01"), 1);
 | 
			
		||||
//
 | 
			
		||||
//    BOOST_CHECK_THROW( gwi.update_group( {}, {}, {} ), std::exception);
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
//    Opm::WellContainer<Opm::Well::InjectorCMode> inj_cmode({{"PROD01", Opm::Well::InjectorCMode::CMODE_UNDEFINED}});
 | 
			
		||||
//    {
 | 
			
		||||
//        Opm::WellContainer<Opm::Well::ProducerCMode> prod_cmode({{"PROD01", Opm::Well::ProducerCMode::GRUP}});
 | 
			
		||||
//        gwi.update_group(status, inj_cmode, prod_cmode);
 | 
			
		||||
//    }
 | 
			
		||||
//    BOOST_CHECK(!gwi.in_producing_group("INJE01"));
 | 
			
		||||
//    BOOST_CHECK(gwi.in_producing_group("PROD01"));
 | 
			
		||||
//
 | 
			
		||||
//    {
 | 
			
		||||
//        Opm::WellContainer<Opm::Well::ProducerCMode> prod_cmode(
 | 
			
		||||
//            {{"PROD01", Opm::Well::ProducerCMode::CMODE_UNDEFINED}});
 | 
			
		||||
//        gwi.update_group(status, inj_cmode, prod_cmode);
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    {
 | 
			
		||||
//        Opm::WellContainer<Opm::Well::ProducerCMode> prod_cmode({{"PROD01", Opm::Well::ProducerCMode::GRUP}});
 | 
			
		||||
//        gwi.update_group(status, inj_cmode, prod_cmode);
 | 
			
		||||
//    }
 | 
			
		||||
//    BOOST_CHECK(!gwi.in_producing_group("INJE01"));
 | 
			
		||||
//    BOOST_CHECK(gwi.in_producing_group("PROD01"));
 | 
			
		||||
//
 | 
			
		||||
//    {
 | 
			
		||||
//        Opm::WellContainer<Opm::Well::ProducerCMode> prod_cmode({{"PROD01", Opm::Well::ProducerCMode::NONE}});
 | 
			
		||||
//        gwi.update_group(status, inj_cmode, prod_cmode);
 | 
			
		||||
//    }
 | 
			
		||||
//    BOOST_CHECK(!gwi.in_producing_group("INJE01"));
 | 
			
		||||
//    BOOST_CHECK(!gwi.in_producing_group("PROD01"));
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
BOOST_AUTO_TEST_CASE(TESTWellContainer) {
 | 
			
		||||
    Opm::WellContainer<int> wc;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user