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); } } }
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; } }
/// 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]; }
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; }
void PIDTimeStepControl::initialize( const SimulatorState& state ) { // store current state for later time step computation p0_ = state.pressure(); sat0_ = state.saturation(); }