Beispiel #1
0
    virtual void upscale_pressure (const double* coarseSaturation,
                                   const double* finePressure,
                                   double* coarsePressure) {
        // pressure locations we'll have to relate to
        static const int    FIRST_BLOCK = 0;    // relative index in the column
        static const double HALFWAY     = 0.5;  // center of the block

        // incompressible means that the density is the same everywhere
        // we can thus cache the phase properties outside of the loop
        const double gas_dens = density ()[GAS];
        const double wat_dens = density ()[WAT];

        // helper object to get the index (into the pressure array) and
        // the height of elements in a column
        const rlw_double ts_dz (ts.number_of_cells, ts.col_cellpos, ts.dz);
        const rlw_int col_cells (ts.number_of_cells, ts.col_cellpos, ts.col_cells);

        // upscale each column separately. assume that something like the
        // EQUIL keyword has been used in the Eclipse file and that the
        // pressures are already in equilibrium. thus, we only need to
        // extract the pressure at the reference point (top surface)
        for (int col = 0; col < col_cells.cols (); ++col) {
            // location of the brine-co2 phase contact
            const double gas_sat = coarseSaturation[col * NUM_PHASES + GAS];
            const Elevation& intf_lvl = intf_elev (col, gas_sat);

            // what fraction of the first block from the pressure point (halfway)
            // up to the top surface is of each of the phases? if the interface
            // is below the first block, or if it is further down than halfway,
            // then everything, otherwise the fraction (less than 0.5)
            double gas_frac = (intf_lvl.block () == FIRST_BLOCK) ?
                              min (HALFWAY, intf_lvl.fraction ()) : HALFWAY;

            // id of the upper-most block of this column. if there is no
            // blocks, then the TopSurf object wouldn't generate a column.
            const int block_id = col_cells[col][FIRST_BLOCK];

            // height of the uppermost block (twice the distance from the top
            // to the center
            const double hgt = ts_dz[col][FIRST_BLOCK];

            // get the pressure in the middle of this block
            const double mid_pres = finePressure[block_id];

            // pressure at the reference point; adjust hydrostatically for
            // those phases that are on the way up from the center of the first
            // block in the column.
            const double ref_pres = mid_pres - gravity * hgt *
                                    (gas_frac * gas_dens + (HALFWAY - gas_frac) * wat_dens);

            // Eclipse uses non-aquous pressure (see Variable Sets in Formulation
            // of the Equations in the Technical Description) as the main unknown
            // in the pressure equation; there is assumed continuity at the
            // contact, so the pressure at the top should always be a CO2 pressure
            coarsePressure[col] = ref_pres;
        }
    }
Beispiel #2
0
    virtual void downscale_pressure (const double* coarseSaturation,
                                     const double* coarsePressure,
                                     double* finePressure) {
        // pressure locations we'll have to relate to
        static const double HALFWAY     = 0.5;  // center of the block

        // helper object to get the index (into the pressure array) and
        // the height of elements in a column
        const rlw_double ts_h (ts.number_of_cells, ts.col_cellpos, ts.h);
        const rlw_double ts_dz (ts.number_of_cells, ts.col_cellpos, ts.dz);
        const rlw_int col_cells (ts.number_of_cells, ts.col_cellpos, ts.col_cells);

        // incompressible means that the density is the same everywhere
        // we can thus cache the phase properties outside of the loop
        const double gas_dens = density ()[GAS];
        const double wat_dens = density ()[WAT];

        for (int col = 0; col < col_cells.cols (); ++col) {
            // location of the brine-co2 phase contact
            const double gas_sat = coarseSaturation[col * NUM_PHASES + GAS];
            const Elevation& intf_lvl = intf_elev (col, gas_sat);

            // get the pressure difference between the phases at top of this column
            const double sat[NUM_PHASES] = { gas_sat, 1-gas_sat };
            double pres_diff;
            capPress (1, sat, &col, &pres_diff, 0);

            // get the reference phase pressure at the top; notice that the CO2
            // pressure is the largest so we subtract the difference
            const double gas_ref = coarsePressure[col];
            const double wat_ref = gas_ref - pres_diff;

            // are we going to include the block with the interface
            const int incl_intf = intf_lvl.fraction () >= HALFWAY ? 1 : 0;
            const int num_gas_rows = intf_lvl.block () + incl_intf;

            // write all CO2 pressure blocks
            for (int row = 0; row < num_gas_rows; ++row) {
                // height of block center
                const double hgt = ts_h[col][row] + HALFWAY * ts_dz[col][row];

                // hydrostatically get the pressure for this block
                const double gas_pres = gas_ref + gravity * hgt * gas_dens;
                const int block = col_cells[col][row];

                // (scatter) write to output array
                finePressure[block] = gas_pres;
            }

            // then write the brine blocks, starting where we left off
            for (int row = num_gas_rows; row < col_cells.size (col); ++row) {
                // height of block center
                const double hgt = ts_h[col][row] + HALFWAY * ts_dz[col][row];

                // hydrostatically get the pressure for this block
                const double wat_pres = wat_ref + gravity * hgt * wat_dens;
                const int block = col_cells[col][row];

                // (scatter) write to output array
                finePressure[block] = wat_pres;
            }
        }
    }