Esempio n. 1
0
    void restoreSaturation(const ecl_file_type* file_type,
                           const PhaseUsage& phaseUsage,
                           int numcells,
                           SimulatorState& simulator_state) {

        float* sgas_data = NULL;
        float* swat_data = NULL;

        if (phaseUsage.phase_used[BlackoilPhases::Aqua]) {
            const char* swat = "SWAT";
            if (ecl_file_has_kw(file_type, swat)) {
                ecl_kw_type* swat_kw = ecl_file_iget_named_kw(file_type , swat, 0);
                swat_data = ecl_kw_get_float_ptr(swat_kw);
                std::vector<double> swat_datavec(&swat_data[0], &swat_data[numcells]);
                EclipseIOUtil::addToStripedData(swat_datavec, simulator_state.saturation(), phaseUsage.phase_pos[BlackoilPhases::Aqua], phaseUsage.num_phases);
            } else {
                std::string error_str = "Restart file is missing SWAT data!\n";
                throw std::runtime_error(error_str);
            }
        }

        if (phaseUsage.phase_used[BlackoilPhases::Vapour]) {
            const char* sgas = "SGAS";
            if (ecl_file_has_kw(file_type, sgas)) {
                ecl_kw_type* sgas_kw = ecl_file_iget_named_kw(file_type , sgas, 0);
                sgas_data = ecl_kw_get_float_ptr(sgas_kw);
                std::vector<double> sgas_datavec(&sgas_data[0], &sgas_data[numcells]);
                EclipseIOUtil::addToStripedData(sgas_datavec, simulator_state.saturation(), phaseUsage.phase_pos[BlackoilPhases::Vapour], phaseUsage.num_phases);
            } else {
                std::string error_str = "Restart file is missing SGAS data!\n";
                throw std::runtime_error(error_str);
            }
        }
    }
Esempio n. 2
0
    // Solve with no rock compressibility (linear eqn).
    void IncompTpfa::solveIncomp(const double dt,
                                 SimulatorState& state,
                                 WellState& well_state)
    {
        // Set up properties.
        computePerSolveDynamicData(dt, state, well_state);

        // Assemble.
        UnstructuredGrid* gg = const_cast<UnstructuredGrid*>(&grid_);
        int ok = ifs_tpfa_assemble(gg, &forces_, &trans_[0], &gpress_omegaweighted_[0], h_);
        if (!ok) {
            OPM_THROW(std::runtime_error, "Failed assembling pressure system.");
        }

        // Solve.
        linsolver_.solve(h_->A, h_->b, h_->x);

        // Obtain solution.
        assert(int(state.pressure().size()) == grid_.number_of_cells);
        assert(int(state.faceflux().size()) == grid_.number_of_faces);
        ifs_tpfa_solution soln = { NULL, NULL, NULL, NULL };
        soln.cell_press = &state.pressure()[0];
        soln.face_flux  = &state.faceflux()[0];
        if (wells_ != NULL) {
            assert(int(well_state.bhp().size()) == wells_->number_of_wells);
            assert(int(well_state.perfRates().size()) == wells_->well_connpos[ wells_->number_of_wells ]);
            soln.well_flux = &well_state.perfRates()[0];
            soln.well_press = &well_state.bhp()[0];
        }
        ifs_tpfa_press_flux(gg, &forces_, &trans_[0], h_, &soln);
    }
Esempio n. 3
0
    void restoreTemperatureData(const ecl_file_type* file,
                              EclipseStateConstPtr eclipse_state,
                              int numcells,
                              SimulatorState& simulator_state) {
        const char* temperature = "TEMP";

        if (ecl_file_has_kw(file , temperature)) {
            ecl_kw_type* temperature_kw = ecl_file_iget_named_kw(file, temperature, 0);

            if (ecl_kw_get_size(temperature_kw) != numcells) {
                throw std::runtime_error("Read of restart file: Could not restore temperature data, length of data from file not equal number of cells");
            }

            float* temperature_data = ecl_kw_get_float_ptr(temperature_kw);

            // factor and offset from the temperature values given in the deck to Kelvin
            double scaling = eclipse_state->getDeckUnitSystem().parse("Temperature")->getSIScaling();
            double offset  = eclipse_state->getDeckUnitSystem().parse("Temperature")->getSIOffset();

            for (size_t index = 0; index < simulator_state.temperature().size(); ++index) {
                simulator_state.temperature()[index] = unit::convert::from((double)temperature_data[index] - offset, scaling);
            }
          } else {
              throw std::runtime_error("Read of restart file: File does not contain TEMP data\n");
          }
    }
Esempio n. 4
0
bool
SimulatorState::equals (const SimulatorState& other,
                        double epsilon) const {
    bool equal = (num_phases_ == other.num_phases_);

    // if we use &=, then all the tests will be run regardless
    equal = equal && vectorApproxEqual( pressure() , other.pressure() , epsilon);
    equal = equal && vectorApproxEqual( temperature() , other.temperature() , epsilon);
    equal = equal && vectorApproxEqual( facepressure() , other.facepressure() , epsilon);
    equal = equal && vectorApproxEqual( faceflux() , other.faceflux() , epsilon);
    equal = equal && vectorApproxEqual( saturation() , other.saturation() , epsilon);

    return equal;
}
Esempio n. 5
0
    double PIDTimeStepControl::
    computeTimeStepSize( const double dt, const int /* iterations */, const SimulatorState& state ) const
    {
        const std::size_t pSize = p0_.size();
        assert( state.pressure().size() == pSize );
        const std::size_t satSize = sat0_.size();
        assert( state.saturation().size() == satSize );

        // compute u^n - u^n+1 
        for( std::size_t i=0; i<pSize; ++i ) {
            p0_[ i ]   -= state.pressure()[ i ];
        }

        for( std::size_t i=0; i<satSize; ++i ) {
            sat0_[ i ] -= state.saturation()[ i ];
        }

        // compute || u^n - u^n+1 || 
        const double stateOld  = euclidianNormSquared( p0_.begin(),   p0_.end() ) +
                                 euclidianNormSquared( sat0_.begin(), sat0_.end() );

        // compute || u^n+1 || 
        const double stateNew  = euclidianNormSquared( state.pressure().begin(),   state.pressure().end()   ) +
                                 euclidianNormSquared( state.saturation().begin(), state.saturation().end() );

        // shift errors
        for( int i=0; i<2; ++i ) {
          errors_[ i ] = errors_[i+1];
        }

        // store new error
        const double error = stateOld / stateNew;
        errors_[ 2 ] =  error ;

        if( error > tol_ )
        {
            // adjust dt by given tolerance 
            const double newDt = dt * tol_ / error;
            if( verbose_ )
                std::cout << "Computed step size (tol): " << unit::convert::to( newDt, unit::day ) << " (days)" << std::endl;
            return newDt;
        }
        else
        {
            // values taking from turek time stepping paper
            const double kP = 0.075 ;
            const double kI = 0.175 ;
            const double kD = 0.01 ;
            const double newDt = (dt * std::pow( errors_[ 1 ] / errors_[ 2 ], kP ) *
                                 std::pow( tol_         / errors_[ 2 ], kI ) *
                                 std::pow( errors_[0]*errors_[0]/errors_[ 1 ]/errors_[ 2 ], kD ));
            if( verbose_ )
                std::cout << "Computed step size (pow): " << unit::convert::to( newDt, unit::day ) << " (days)" << std::endl;
            return newDt;
        }
    }
Esempio n. 6
0
    /// Compute per-solve dynamic properties.
    void IncompTpfa::computePerSolveDynamicData(const double /*dt*/,
                                                const SimulatorState& state,
                                                const WellState& /*well_state*/)
    {
        // Computed here:
        //
        // std::vector<double> wdp_;
        // std::vector<double> totmob_;
        // std::vector<double> omega_;
        // std::vector<double> trans_;
        // std::vector<double> gpress_omegaweighted_;
        // std::vector<double> initial_porevol_;
        // ifs_tpfa_forces forces_;

        // wdp_
        if (wells_) {
            Opm::computeWDP(*wells_, grid_, state.saturation(), props_.density(),
                            gravity_ ? gravity_[2] : 0.0, true, wdp_);
        }
        // totmob_, omega_, gpress_omegaweighted_
        if (gravity_) {
            computeTotalMobilityOmega(props_, allcells_, state.saturation(), totmob_, omega_);
            mim_ip_density_update(grid_.number_of_cells, grid_.cell_facepos,
                                  &omega_[0],
                                  &gpress_[0], &gpress_omegaweighted_[0]);
        } else {
            computeTotalMobility(props_, allcells_, state.saturation(), totmob_);
        }
        // trans_
        tpfa_eff_trans_compute(const_cast<UnstructuredGrid*>(&grid_), &totmob_[0], &htrans_[0], &trans_[0]);
        // initial_porevol_
        if (rock_comp_props_ && rock_comp_props_->isActive()) {
            computePorevolume(grid_, props_.porosity(), *rock_comp_props_, state.pressure(), initial_porevol_);
        }
        // forces_
        forces_.src = src_.empty() ? NULL : &src_[0];
        forces_.bc = bcs_;
        forces_.W = wells_;
        forces_.totmob = &totmob_[0];
        forces_.wdp = wdp_.empty() ? NULL : &wdp_[0];
    }
Esempio n. 7
0
    /// Compute per-iteration dynamic properties.
    void IncompTpfa::computePerIterationDynamicData(const double /*dt*/,
                                                    const SimulatorState& state,
                                                    const WellState& well_state)
    {
        // These are the variables that get computed by this function:
        //
        // std::vector<double> porevol_
        // std::vector<double> rock_comp_
        // std::vector<double> pressures_

        computePorevolume(grid_, props_.porosity(), *rock_comp_props_, state.pressure(), porevol_);
        if (rock_comp_props_ && rock_comp_props_->isActive()) {
            for (int cell = 0; cell < grid_.number_of_cells; ++cell) {
                rock_comp_[cell] = rock_comp_props_->rockComp(state.pressure()[cell]);
            }
        }
        if (wells_) {
            std::copy(state.pressure().begin(), state.pressure().end(), pressures_.begin());
            std::copy(well_state.bhp().begin(), well_state.bhp().end(), pressures_.begin() + grid_.number_of_cells);
        }
    }
Esempio n. 8
0
    /// Compute the output.
    void IncompTpfa::computeResults(SimulatorState& state,
                                    WellState& well_state) const
    {
        // Make sure h_ contains the direct-solution matrix
        // and right hand side (not jacobian and residual).
        // TODO: optimize by only adjusting b and diagonal of A.
        UnstructuredGrid* gg = const_cast<UnstructuredGrid*>(&grid_);
        ifs_tpfa_assemble(gg, &forces_, &trans_[0], &gpress_omegaweighted_[0], h_);


        // Make sure h_->x contains the direct solution vector.
        assert(int(state.pressure().size()) == grid_.number_of_cells);
        assert(int(state.faceflux().size()) == grid_.number_of_faces);
        std::copy(state.pressure().begin(), state.pressure().end(), h_->x);
        std::copy(well_state.bhp().begin(), well_state.bhp().end(), h_->x + grid_.number_of_cells);

        // Obtain solution.
        ifs_tpfa_solution soln = { NULL, NULL, NULL, NULL };
        soln.cell_press = &state.pressure()[0];
        soln.face_flux  = &state.faceflux()[0];
        if (wells_ != NULL) {
            assert(int(well_state.bhp().size()) == wells_->number_of_wells);
            assert(int(well_state.perfRates().size()) == wells_->well_connpos[ wells_->number_of_wells ]);
            soln.well_flux = &well_state.perfRates()[0];
            soln.well_press = &well_state.bhp()[0];
        }
        ifs_tpfa_press_flux(gg, &forces_, &trans_[0], h_, &soln); // TODO: Check what parts of h_ are used here.
    }
Esempio n. 9
0
    /// Compute the residual in h_->b and Jacobian in h_->A.
    void IncompTpfa::assemble(const double dt,
                              const SimulatorState& state,
                              const WellState& /*well_state*/)
    {
        const double* pressures = wells_ ? &pressures_[0] : &state.pressure()[0];

        bool ok = ifs_tpfa_assemble_comprock_increment(const_cast<UnstructuredGrid*>(&grid_),
                                                       &forces_, &trans_[0], &gpress_omegaweighted_[0],
                                                       &porevol_[0], &rock_comp_[0], dt, pressures,
                                                       &initial_porevol_[0], h_);
        if (!ok) {
            OPM_THROW(std::runtime_error, "Failed assembling pressure system.");
        }
    }
Esempio n. 10
0
    void restorePressureData(const ecl_file_type* file,
                             EclipseStateConstPtr eclipse_state,
                             int numcells,
                             SimulatorState& simulator_state) {
        const char* pressure = "PRESSURE";

        if (ecl_file_has_kw(file , pressure)) {

            ecl_kw_type* pressure_kw = ecl_file_iget_named_kw(file, pressure, 0);

            if (ecl_kw_get_size(pressure_kw) != numcells) {
                throw std::runtime_error("Read of restart file: Could not restore pressure data, length of data from file not equal number of cells");
            }

            float* pressure_data = ecl_kw_get_float_ptr(pressure_kw);
            const double deck_pressure_unit = (eclipse_state->getDeckUnitSystem().getType() == UnitSystem::UNIT_TYPE_METRIC) ? Opm::unit::barsa : Opm::unit::psia;
            for (size_t index = 0; index < simulator_state.pressure().size(); ++index) {
                simulator_state.pressure()[index] = unit::convert::from((double)pressure_data[index], deck_pressure_unit);
            }
        } else {
            throw std::runtime_error("Read of restart file: File does not contain PRESSURE data\n");
        }
    }
Esempio n. 11
0
    // Solve with rock compressibility (nonlinear eqn).
    void IncompTpfa::solveRockComp(const double dt,
                                   SimulatorState& state,
                                   WellState& well_state)
    {
        // This function is identical to CompressibleTpfa::solve().
        // \TODO refactor?

        const int nc = grid_.number_of_cells;
        const int nw = (wells_) ? wells_->number_of_wells : 0;

        // Set up dynamic data.
        computePerSolveDynamicData(dt, state, well_state);
        computePerIterationDynamicData(dt, state, well_state);

        // Assemble J and F.
        assemble(dt, state, well_state);

        double inc_norm = 0.0;
        int iter = 0;
        double res_norm = residualNorm();
        std::cout << "\nIteration         Residual        Change in p\n"
                  << std::setw(9) << iter
                  << std::setw(18) << res_norm
                  << std::setw(18) << '*' << std::endl;
        while ((iter < maxiter_) && (res_norm > residual_tol_)) {
            // Solve for increment in Newton method:
            //   incr = x_{n+1} - x_{n} = -J^{-1}F
            // (J is Jacobian matrix, F is residual)
            solveIncrement();
            ++iter;

            // Update pressure vars with increment.
            for (int c = 0; c < nc; ++c) {
                state.pressure()[c] += h_->x[c];
            }
            for (int w = 0; w < nw; ++w) {
                well_state.bhp()[w] += h_->x[nc + w];
            }

            // Stop iterating if increment is small.
            inc_norm = incrementNorm();
            if (inc_norm <= change_tol_) {
                std::cout << std::setw(9) << iter
                          << std::setw(18) << '*'
                          << std::setw(18) << inc_norm << std::endl;
                break;
            }

            // Set up dynamic data.
            computePerIterationDynamicData(dt, state, well_state);

            // Assemble J and F.
            assemble(dt, state, well_state);

            // Update residual norm.
            res_norm = residualNorm();

            std::cout << std::setw(9) << iter
                      << std::setw(18) << res_norm
                      << std::setw(18) << inc_norm << std::endl;
        }

        if ((iter == maxiter_) && (res_norm > residual_tol_) && (inc_norm > change_tol_)) {
            OPM_THROW(std::runtime_error, "IncompTpfa::solve() failed to converge in " << maxiter_ << " iterations.");
        }

        std::cout << "Solved pressure in " << iter << " iterations." << std::endl;

        // Compute fluxes and face pressures.
        computeResults(state, well_state);
    }
Esempio n. 12
0
 const std::vector<double>& rv () const { return cellData()[ rvId_ ] ; }
Esempio n. 13
0
 const std::vector<double>& gasoilratio () const { return cellData()[ gorId_ ] ; }
Esempio n. 14
0
 const std::vector<double>& surfacevol  () const { return cellData()[ surfaceVolId_ ]; }
int main()
{
    SimulatorState state;

    zrtp_zid_t libzrtp_zid;
    memset(&libzrtp_zid, 1, sizeof(libzrtp_zid));

    ZID libzorg_zid;
    memset(&libzorg_zid, 2, sizeof(libzorg_zid));

    uint32_t libzrtp_ssrc;
    memset(&libzrtp_ssrc, 1, sizeof(libzrtp_ssrc));

    SSRC libzorg_ssrc;
    memset(&libzorg_ssrc, 2, sizeof(libzorg_ssrc));

    // initialize libraries
    zrtp_global_t * libzrtp;
    std::auto_ptr<Instance> libzorg;

    zrtp_status_t status;
    ZORG_DECL_ERROR(e);

    zrtp_config_t libzrtp_config;
    zrtp_config_defaults(&libzrtp_config);
    libzrtp_config.lic_mode = ZRTP_LICENSE_MODE_UNLIMITED; /////////////////////
    libzrtp_config.cb.sched_cb.on_init = &libzrtp_sched_on_init;
    libzrtp_config.cb.sched_cb.on_down = &libzrtp_sched_on_down;
    libzrtp_config.cb.sched_cb.on_call_later = &libzrtp_sched_on_call_later;
    libzrtp_config.cb.sched_cb.on_cancel_call_later = &libzrtp_sched_on_cancel_call_later;
    libzrtp_config.cb.sched_cb.on_wait_call_later = &libzrtp_sched_on_wait_call_later;
    libzrtp_config.cb.misc_cb.on_send_packet = &libzrtp_misc_on_send_packet;
    status = zrtp_init(&libzrtp_config, &libzrtp);

    libzorg_CryptoSuite libzorg_crypt(e);
    std::auto_ptr<Cache> libzorg_cache(ZRTP::Impl::CreateCache(e, "./zorg_cache", &libzorg_crypt));

    SRTP::Libsrtp::Init(e);
    libzorg.reset(Instance::Create(e, &libzorg_crypt, SRTP::Libsrtp::Create(e)));

    libzorg_Interface libzorg_iface((state));

    // create sessions
    zrtp_session_t * libzrtp_session;
    std::auto_ptr<Session> libzorg_session;

    zrtp_profile_t libzrtp_profile;
    zrtp_profile_defaults(&libzrtp_profile, libzrtp);
    libzrtp_profile.autosecure = 1; ///////////////////
    status = zrtp_session_init(libzrtp, &libzrtp_profile, libzrtp_zid, 1, &libzrtp_session);
    zrtp_session_set_userdata(libzrtp_session, &state);

    Profile libzorg_profile = Profile::Default();
    libzorg_session.reset(libzorg->createSession(e, &libzorg_iface, libzorg_cache.get(), libzorg_zid, libzorg_profile));

    // create streams
    zrtp_stream_t * libzrtp_stream;
    std::auto_ptr<Stream> libzorg_stream;

    status = zrtp_stream_attach(libzrtp_session, &libzrtp_stream);
    zrtp_stream_set_userdata(libzrtp_stream, &state);

    libzrtp_IoTarget libzrtp_io_target((libzrtp_stream));
    state.setIoTargetA(&libzrtp_io_target);

    libzorg_stream.reset(libzorg_session->createStream(e, &libzorg_iface));

    libzorg_IoTarget libzorg_io_target((libzorg_stream.get()));
    state.setIoTargetB(&libzorg_io_target);

    // start streams
    status = zrtp_stream_start(libzrtp_stream, libzrtp_ssrc);
    libzorg_stream->start(e, libzorg_ssrc);

    // message loop
    for(WorkItem * item = state.dequeueTask(); item; item = state.dequeueTask())
    {
	item->run();
	delete item;
    }
}
Esempio n. 16
0
 void PIDTimeStepControl::initialize( const SimulatorState& state ) 
 {
     // store current state for later time step computation
     p0_   = state.pressure();
     sat0_ = state.saturation();
 }