Exemple #1
0
void check_controls_epoch0( struct WellControls ** ctrls) {
    // The injector
    {
        const struct WellControls * ctrls0 = ctrls[0];
        BOOST_CHECK_EQUAL( 3 , well_controls_get_num(ctrls0));   // The number of controls for the injector == 3??

        BOOST_CHECK_EQUAL( SURFACE_RATE   , well_controls_iget_type(ctrls0 , 0) );
        BOOST_CHECK_EQUAL( RESERVOIR_RATE , well_controls_iget_type(ctrls0 , 1) );
        BOOST_CHECK_EQUAL( BHP            , well_controls_iget_type(ctrls0 , 2) );

        // The different targets
        BOOST_CHECK_EQUAL( 100.0 / 86400 , well_controls_iget_target(ctrls0,0));
        BOOST_CHECK_EQUAL( 200.0 / 86400 , well_controls_iget_target(ctrls0,1));
        BOOST_CHECK_EQUAL( 400 * 100000  , well_controls_iget_target(ctrls0,2));

        // Which control is active
        BOOST_CHECK_EQUAL( 0 , well_controls_get_current(ctrls0) );
        
        // The phase distribution in the active target
        {
             const double * distr = well_controls_iget_distr( ctrls0 , 0 );
             BOOST_CHECK_EQUAL( 0 , distr[0] );  // Water
             BOOST_CHECK_EQUAL( 0 , distr[1] );  // Oil
             BOOST_CHECK_EQUAL( 1 , distr[2] );  // Gas
        }
    }
    
    // The producer
    {
        const struct WellControls * ctrls1 = ctrls[1];
        BOOST_CHECK_EQUAL( 2 , well_controls_get_num( ctrls1 ));   // The number of controls for the producer == 2??
        BOOST_CHECK_EQUAL( SURFACE_RATE   , well_controls_iget_type(ctrls1 , 0) );
        BOOST_CHECK_EQUAL( BHP            , well_controls_iget_type(ctrls1 , 1) );

        // The different targets
        BOOST_CHECK_EQUAL( -20000.0 / 86400 , well_controls_iget_target(ctrls1,0));
        BOOST_CHECK_EQUAL(  1000 * 100000   , well_controls_iget_target(ctrls1,1));

        // Which control is active
        BOOST_CHECK_EQUAL( 0 , well_controls_get_current(ctrls1));

        // The phase distribution in the active target
       {
            const double * distr = well_controls_iget_distr( ctrls1 , 0 );
            BOOST_CHECK_EQUAL( 0 , distr[0] );  // Water
            BOOST_CHECK_EQUAL( 1 , distr[1] );  // Oil
            BOOST_CHECK_EQUAL( 0 , distr[2] );  // Gas
        }
    }
}
Exemple #2
0
 /// Create a src vector equivalent to a wells structure.
 /// For this to be valid, the wells must be all rate-controlled and
 /// single-perforation.
 void wellsToSrc(const Wells& wells, const int num_cells, std::vector<double>& src)
 {
     const int np = wells.number_of_phases;
     if (np != 2) {
         OPM_THROW(std::runtime_error, "wellsToSrc() requires a 2 phase case.");
     }
     src.resize(num_cells);
     for (int w = 0; w < wells.number_of_wells; ++w) {
         const int cur = well_controls_get_current(wells.ctrls[w]);
         if (well_controls_get_num(wells.ctrls[w]) != 1) {
             OPM_MESSAGE("In wellsToSrc(): well has more than one control, all but current control will be ignored.");
         }
         if (well_controls_iget_type(wells.ctrls[w] , cur) != RESERVOIR_RATE) {
             OPM_THROW(std::runtime_error, "In wellsToSrc(): well is something other than RESERVOIR_RATE.");
         }
         if (wells.well_connpos[w+1] - wells.well_connpos[w] != 1) {
             OPM_THROW(std::runtime_error, "In wellsToSrc(): well has multiple perforations.");
         }
         {
             const double * distr = well_controls_iget_distr( wells.ctrls[w] , cur);
             for (int p = 0; p < np; ++p) {
                 if (distr[p] != 1.0) {
                     OPM_THROW(std::runtime_error, "In wellsToSrc(): well not controlled on total rate.");
                 }
             }
         }
         double flow = well_controls_iget_target(wells.ctrls[w] , cur);
         if (wells.type[w] == INJECTOR) {
             flow *= wells.comp_frac[np*w + 0]; // Obtaining water rate for inflow source.
         }
         const int cell = wells.well_cells[wells.well_connpos[w]];
         src[cell] = flow;
     }
 }
    void SimulatorBase<Implementation>::computeWellPotentials(const Wells* wells,
                                                              const BlackoilState& x,
                                                              const WellState& xw,
                                                              std::vector<double>& well_potentials)
    {
        const int nw = wells->number_of_wells;
        const int np = wells->number_of_phases;

        well_potentials.clear();
        well_potentials.resize(nw*np,0.0);       
        for (int w = 0; w < nw; ++w) {
            for (int perf = wells->well_connpos[w]; perf < wells->well_connpos[w + 1]; ++perf) {
                const double well_cell_pressure = x.pressure()[wells->well_cells[perf]];
                const double drawdown_used = well_cell_pressure - xw.perfPress()[perf];
                const WellControls* ctrl = wells->ctrls[w];
                const int nwc = well_controls_get_num(ctrl);
                //Loop over all controls until we find a BHP control
                //that specifies what we need...
                double bhp = 0.0;
                for (int ctrl_index=0; ctrl_index < nwc; ++ctrl_index) {
                    if (well_controls_iget_type(ctrl, ctrl_index) == BHP) {
                        bhp = well_controls_iget_target(ctrl, ctrl_index);
                    }
                    // TODO: do something for thp;
                }
                // Calculate the pressure difference in the well perforation
                const double dp = xw.perfPress()[perf] - xw.bhp()[w];
                const double drawdown_maximum = well_cell_pressure - (bhp + dp);

                for (int phase = 0; phase < np; ++phase) {
                    well_potentials[w*np + phase] += (drawdown_maximum / drawdown_used * xw.perfPhaseRates()[perf*np + phase]);
                }
            }
        }
    }
Exemple #4
0
void check_controls_epoch1( struct WellControls ** ctrls) {
    // The injector
    {
        const struct WellControls * ctrls0 = ctrls[0];
        BOOST_CHECK_EQUAL( 3 , well_controls_get_num(ctrls0));   // The number of controls for the injector == 3??

        BOOST_CHECK_EQUAL( SURFACE_RATE   , well_controls_iget_type(ctrls0 , 0 ));
        BOOST_CHECK_EQUAL( RESERVOIR_RATE , well_controls_iget_type(ctrls0 , 1 ));
        BOOST_CHECK_EQUAL( BHP            , well_controls_iget_type(ctrls0 , 2 ));

        // The different targets
        BOOST_CHECK_CLOSE( 10.0 / 86400 , well_controls_iget_target(ctrls0 , 0) , 0.001);
        BOOST_CHECK_CLOSE( 20.0 / 86400 , well_controls_iget_target(ctrls0 , 1) , 0.001);
        BOOST_CHECK_CLOSE( 40 * 100000  , well_controls_iget_target(ctrls0 , 2) , 0.001);

        // Which control is active
        BOOST_CHECK_EQUAL( 1 , well_controls_get_current(ctrls0));

        {
            const double * distr = well_controls_iget_distr( ctrls0 , 1 );
            BOOST_CHECK_EQUAL( 1 , distr[0] );  // Water
            BOOST_CHECK_EQUAL( 0 , distr[1] );  // Oil
            BOOST_CHECK_EQUAL( 0 , distr[2] );  // Gas
        }
    }
    
    // The producer
    {
        const struct WellControls * ctrls1 = ctrls[1];
        BOOST_CHECK_EQUAL( 3 , well_controls_get_num(ctrls1));   // The number of controls for the producer - now 3.
        BOOST_CHECK_EQUAL( SURFACE_RATE   , well_controls_iget_type(ctrls1 , 0) );
        BOOST_CHECK_EQUAL( RESERVOIR_RATE , well_controls_iget_type(ctrls1 , 1) );
        BOOST_CHECK_EQUAL( BHP            , well_controls_iget_type(ctrls1 , 2) );

        // The different targets
        BOOST_CHECK_CLOSE( -999.0 / 86400 , well_controls_iget_target(ctrls1 , 0), 0.001);
        BOOST_CHECK_CLOSE( -123.0 / 86400 , well_controls_iget_target(ctrls1 , 1), 0.001);
        BOOST_CHECK_CLOSE(  100 * 100000  , well_controls_iget_target(ctrls1 , 2), 0.001);

        // Which control is active
        BOOST_CHECK_EQUAL( 1 , well_controls_get_current(ctrls1) );

        {
            const double * distr = well_controls_iget_distr( ctrls1 , 1 );
            BOOST_CHECK_EQUAL( 1 , distr[0] );  // Water
            BOOST_CHECK_EQUAL( 1 , distr[1] );  // Oil
            BOOST_CHECK_EQUAL( 1 , distr[2] );  // Gas
        }
    }
}
        inline
        bool constraintBroken(const std::vector<double>& bhp,
                              const std::vector<double>& thp,
                              const std::vector<double>& well_phase_flow_rate,
                              const int well,
                              const int num_phases,
                              const WellType& well_type,
                              const WellControls* wc,
                              const int ctrl_index)
        {
            const WellControlType ctrl_type = well_controls_iget_type(wc, ctrl_index);
            const double target = well_controls_iget_target(wc, ctrl_index);
            const double* distr = well_controls_iget_distr(wc, ctrl_index);

            bool broken = false;

            switch (well_type) {
            case INJECTOR:
            {
                switch (ctrl_type) {
                case BHP:
                    broken = bhp[well] > target;
                    break;

                case THP:
                    broken = thp[well] > target;
                    break;

                case RESERVOIR_RATE: // Intentional fall-through
                case SURFACE_RATE:
                    broken = rateToCompare(well_phase_flow_rate,
                                           well, num_phases, distr) > target;
                    break;
                }
            }
            break;

            case PRODUCER:
            {
                switch (ctrl_type) {
                case BHP:
                    broken = bhp[well] < target;
                    break;

                case THP:
                    broken = thp[well] < target;
                    break;

                case RESERVOIR_RATE: // Intentional fall-through
                case SURFACE_RATE:
                    // Note that the rates compared below are negative,
                    // so breaking the constraints means: too high flow rate
                    // (as for injection).
                    broken = rateToCompare(well_phase_flow_rate,
                                           well, num_phases, distr) < target;
                    break;
                }
            }
            break;

            default:
                OPM_THROW(std::logic_error, "Can only handle INJECTOR and PRODUCER wells.");
            }

            return broken;
        }