WellProductionProperties WellProductionProperties::history(double BHPLimit, const DeckRecord& record, const Phases &phases) { // Modes supported in WCONHIST just from {O,W,G}RAT values // // Note: The default value of observed {O,W,G}RAT is zero // (numerically) whence the following control modes are // unconditionally supported. WellProductionProperties p(record); p.predictionMode = false; namespace wp = WellProducer; if(phases.active(Phase::OIL)) p.addProductionControl( wp::ORAT ); if(phases.active(Phase::WATER)) p.addProductionControl( wp::WRAT ); if(phases.active(Phase::GAS)) p.addProductionControl( wp::GRAT ); for( auto cmode : { wp::LRAT, wp::RESV, wp::GRUP } ) { p.addProductionControl( cmode ); } /* We do not update the BHPLIMIT based on the BHP value given in WCONHIST, that is purely a historical value; instead we copy the old value of the BHP limit from the previous timestep. To actually set the BHPLIMIT in historical mode you must use the WELTARG keyword. */ p.BHPLimit = BHPLimit; const auto& cmodeItem = record.getItem("CMODE"); if (!cmodeItem.defaultApplied(0)) { const auto cmode = WellProducer::ControlModeFromString( cmodeItem.getTrimmedString( 0 ) ); if (p.hasProductionControl( cmode )) p.controlMode = cmode; else throw std::invalid_argument("Setting CMODE to unspecified control"); } if ( record.getItem( "BHP" ).hasValue(0) ) p.BHPH = record.getItem("BHP").getSIDouble(0); if ( record.getItem( "THP" ).hasValue(0) ) p.THPH = record.getItem("THP").getSIDouble(0); return p; }
void MSSimpleTrafficLightLogic::setPhases(const Phases& phases, int step) { assert(step < (int)phases.size()); deletePhases(); myPhases = phases; myStep = step; }
/// Determine the active phases inline PhaseUsage phaseUsage(const Phases& phases) { PhaseUsage pu; std::fill(pu.phase_used, pu.phase_used + BlackoilPhases::MaxNumPhases + BlackoilPhases::NumCryptoPhases, 0); // Discover phase usage. pu.phase_used[BlackoilPhases::Aqua] = phases.active(Phase::WATER); pu.phase_used[BlackoilPhases::Liquid] = phases.active(Phase::OIL); pu.phase_used[BlackoilPhases::Vapour] = phases.active(Phase::GAS); pu.num_phases = 0; int numActivePhases = 0; for (int phaseIdx = 0; phaseIdx < BlackoilPhases::MaxNumPhases; ++phaseIdx) { if (!pu.phase_used[phaseIdx]) { pu.phase_pos[phaseIdx] = -1; } else { pu.phase_pos[phaseIdx] = numActivePhases; ++ numActivePhases; pu.num_phases = numActivePhases; } } // Only 2 or 3 phase systems handled. if (pu.num_phases < 2 || pu.num_phases > 3) { OPM_THROW(std::runtime_error, "Cannot handle cases with " << pu.num_phases << " phases."); } // We need oil systems, since we do not support the keywords needed for // water-gas systems. if (!pu.phase_used[BlackoilPhases::Liquid]) { OPM_THROW(std::runtime_error, "Cannot handle cases with no OIL, i.e. water-gas systems."); } // Add solvent info pu.has_solvent = phases.active(Phase::SOLVENT); if (pu.has_solvent) { // this is quite a hack: even though solvent is not considered as in // MaxNumPhases and pu.num_phases because this would break a lot of // assumptions in old code, it is nevertheless an index to be translated // to. solvent and solvent are even larger hacks because not even this can be // done for them. pu.phase_pos[BlackoilPhases::Solvent] = numActivePhases; ++ numActivePhases; } else pu.phase_pos[BlackoilPhases::Solvent] = -1; // Add polymer info pu.has_polymer = phases.active(Phase::POLYMER); if (pu.has_polymer) { // this is quite a hack: even though polymer is not considered as in // MaxNumPhases and pu.num_phases because this would break a lot of // assumptions in old code, it is nevertheless an index to be translated // to. polymer and solvent are even larger hacks because not even this can be // done for them. pu.phase_pos[BlackoilPhases::Polymer] = numActivePhases; ++ numActivePhases; } else pu.phase_pos[BlackoilPhases::Polymer] = -1; // Add energy info pu.has_energy = phases.active(Phase::ENERGY); if (pu.has_energy) { // this is quite a hack: even though energy is not considered as in // MaxNumPhases and pu.num_phases because this would break a lot of // assumptions in old code, it is nevertheless an index to be translated // to. polymer and solvent are even larger hacks because not even this can be // done for them. pu.phase_pos[BlackoilPhases::Energy] = numActivePhases; ++ numActivePhases; } else pu.phase_pos[BlackoilPhases::Energy] = -1; // Add polymer molecular weight related pu.has_polymermw = phases.active(Phase::POLYMW); if (pu.has_polymermw) { if (!pu.has_polymer) { OPM_THROW(std::runtime_error, "pu.has_polymermw is true while pu.has_polymer is false"); } pu.phase_pos[BlackoilPhases::PolymerMW] = numActivePhases; ++ numActivePhases; } else pu.phase_pos[BlackoilPhases::PolymerMW] = -1; return pu; }