/*! * \brief Initialize the oil parameters via the data specified by the PVDO ECL keyword. */ void initFromDeck(const Deck& deck, const EclipseState& eclState) { const auto& pvdoTables = eclState.getTableManager().getPvdoTables(); const auto& densityKeyword = deck.getKeyword("DENSITY"); assert(pvdoTables.size() == densityKeyword.size()); size_t numRegions = pvdoTables.size(); setNumRegions(numRegions); for (unsigned regionIdx = 0; regionIdx < numRegions; ++ regionIdx) { Scalar rhoRefO = densityKeyword.getRecord(regionIdx).getItem("OIL").getSIDouble(0); Scalar rhoRefG = densityKeyword.getRecord(regionIdx).getItem("GAS").getSIDouble(0); Scalar rhoRefW = densityKeyword.getRecord(regionIdx).getItem("WATER").getSIDouble(0); setReferenceDensities(regionIdx, rhoRefO, rhoRefG, rhoRefW); const auto& pvdoTable = pvdoTables.getTable<PvdoTable>(regionIdx); const auto& BColumn(pvdoTable.getFormationFactorColumn()); std::vector<Scalar> invBColumn(BColumn.size()); for (unsigned i = 0; i < invBColumn.size(); ++i) invBColumn[i] = 1/BColumn[i]; inverseOilB_[regionIdx].setXYArrays(pvdoTable.numRows(), pvdoTable.getPressureColumn(), invBColumn); oilMu_[regionIdx].setXYArrays(pvdoTable.numRows(), pvdoTable.getPressureColumn(), pvdoTable.getViscosityColumn()); } initEnd(); }
/*! * \brief Initialize the parameters for dry gas using an ECL deck. * * This method assumes that the deck features valid DENSITY and PVDG keywords. */ void initFromDeck(DeckConstPtr deck, EclipseStateConstPtr eclState) { const auto& pvdgTables = eclState->getTableManager()->getPvdgTables(); const auto& densityKeyword = deck->getKeyword("DENSITY"); assert(pvdgTables.size() == densityKeyword.size()); size_t numRegions = pvdgTables.size(); setNumRegions(numRegions); for (unsigned regionIdx = 0; regionIdx < numRegions; ++ regionIdx) { Scalar rhoRefO = densityKeyword.getRecord(regionIdx).getItem("OIL").getSIDouble(0); Scalar rhoRefG = densityKeyword.getRecord(regionIdx).getItem("GAS").getSIDouble(0); Scalar rhoRefW = densityKeyword.getRecord(regionIdx).getItem("WATER").getSIDouble(0); setReferenceDensities(regionIdx, rhoRefO, rhoRefG, rhoRefW); // determine the molar masses of the components Scalar p = 1.01325e5; // surface pressure, [Pa] Scalar T = 273.15 + 15.56; // surface temperature, [K] Scalar MO = 175e-3; // [kg/mol] Scalar MG = Opm::Constants<Scalar>::R*T*rhoRefG / p; // [kg/mol], consequence of the ideal gas law Scalar MW = 18.0e-3; // [kg/mol] // TODO (?): the molar mass of the components can possibly specified // explicitly in the deck. setMolarMasses(regionIdx, MO, MG, MW); const auto& pvdgTable = pvdgTables.getTable<PvdgTable>(regionIdx); // say 99.97% of all time: "premature optimization is the root of all // evil". Eclipse does this "optimization" for apparently no good reason! std::vector<Scalar> invB(pvdgTable.numRows()); const auto& Bg = pvdgTable.getFormationFactorColumn(); for (unsigned i = 0; i < Bg.size(); ++ i) { invB[i] = 1.0/Bg[i]; } size_t numSamples = invB.size(); inverseGasB_[regionIdx].setXYArrays(numSamples, pvdgTable.getPressureColumn(), invB); gasMu_[regionIdx].setXYArrays(numSamples, pvdgTable.getPressureColumn(), pvdgTable.getViscosityColumn()); } initEnd(); }
/*! * \brief Initialize the oil parameters via the data specified by the PVTO ECL keyword. */ void initFromDeck(const Deck& deck, const EclipseState& eclState) { const auto& pvtoTables = eclState.getTableManager().getPvtoTables(); const auto& densityKeyword = deck.getKeyword("DENSITY"); assert(pvtoTables.size() == densityKeyword.size()); size_t numRegions = pvtoTables.size(); setNumRegions(numRegions); for (unsigned regionIdx = 0; regionIdx < numRegions; ++ regionIdx) { Scalar rhoRefO = densityKeyword.getRecord(regionIdx).getItem("OIL").getSIDouble(0); Scalar rhoRefG = densityKeyword.getRecord(regionIdx).getItem("GAS").getSIDouble(0); Scalar rhoRefW = densityKeyword.getRecord(regionIdx).getItem("WATER").getSIDouble(0); setReferenceDensities(regionIdx, rhoRefO, rhoRefG, rhoRefW); } // initialize the internal table objects for (unsigned regionIdx = 0; regionIdx < numRegions; ++ regionIdx) { const auto& pvtoTable = pvtoTables[regionIdx]; const auto& saturatedTable = pvtoTable.getSaturatedTable(); assert(saturatedTable.numRows() > 1); auto& oilMu = oilMuTable_[regionIdx]; auto& satOilMu = saturatedOilMuTable_[regionIdx]; auto& invOilB = inverseOilBTable_[regionIdx]; auto& invSatOilB = inverseSaturatedOilBTable_[regionIdx]; auto& gasDissolutionFac = saturatedGasDissolutionFactorTable_[regionIdx]; std::vector<Scalar> invSatOilBArray; std::vector<Scalar> satOilMuArray; // extract the table for the gas dissolution and the oil formation volume factors for (unsigned outerIdx = 0; outerIdx < saturatedTable.numRows(); ++ outerIdx) { Scalar Rs = saturatedTable.get("RS", outerIdx); Scalar BoSat = saturatedTable.get("BO", outerIdx); Scalar muoSat = saturatedTable.get("MU", outerIdx); satOilMuArray.push_back(muoSat); invSatOilBArray.push_back(1.0/BoSat); invOilB.appendXPos(Rs); oilMu.appendXPos(Rs); assert(invOilB.numX() == outerIdx + 1); assert(oilMu.numX() == outerIdx + 1); const auto& underSaturatedTable = pvtoTable.getUnderSaturatedTable(outerIdx); size_t numRows = underSaturatedTable.numRows(); for (unsigned innerIdx = 0; innerIdx < numRows; ++ innerIdx) { Scalar po = underSaturatedTable.get("P", innerIdx); Scalar Bo = underSaturatedTable.get("BO", innerIdx); Scalar muo = underSaturatedTable.get("MU", innerIdx); invOilB.appendSamplePoint(outerIdx, po, 1.0/Bo); oilMu.appendSamplePoint(outerIdx, po, muo); } } // update the tables for the formation volume factor and for the gas // dissolution factor of saturated oil { const auto& tmpPressureColumn = saturatedTable.getColumn("P"); const auto& tmpGasSolubilityColumn = saturatedTable.getColumn("RS"); invSatOilB.setXYContainers(tmpPressureColumn, invSatOilBArray); satOilMu.setXYContainers(tmpPressureColumn, satOilMuArray); gasDissolutionFac.setXYContainers(tmpPressureColumn, tmpGasSolubilityColumn); } updateSaturationPressure_(regionIdx); // make sure to have at least two sample points per Rs value for (unsigned xIdx = 0; xIdx < invOilB.numX(); ++xIdx) { // a single sample point is definitely needed assert(invOilB.numY(xIdx) > 0); // everything is fine if the current table has two or more sampling points // for a given mole fraction if (invOilB.numY(xIdx) > 1) continue; // find the master table which will be used as a template to extend the // current line. We define master table as the first table which has values // for undersaturated oil... size_t masterTableIdx = xIdx + 1; for (; masterTableIdx < saturatedTable.numRows(); ++masterTableIdx) { if (pvtoTable.getUnderSaturatedTable(masterTableIdx).numRows() > 1) break; } if (masterTableIdx >= saturatedTable.numRows()) throw std::runtime_error("PVTO tables are invalid: The last table must exhibit at least one " "entry for undersaturated oil!"); // extend the current table using the master table. extendPvtoTable_(regionIdx, xIdx, pvtoTable.getUnderSaturatedTable(xIdx), pvtoTable.getUnderSaturatedTable(masterTableIdx)); } } vapPar2_ = 0.0; if (deck.hasKeyword("VAPPARS")) { const auto& vapParsKeyword = deck.getKeyword("VAPPARS"); vapPar2_ = vapParsKeyword.getRecord(0).getItem("OIL_DENSITY_PROPENSITY").template get<double>(0); } initEnd(); }
int main(void) { // seed pseudorandom number generator srand48(time(NULL)); double vy = drand48(); double vx = drand48(); // instantiate window GWindow window = newGWindow(WIDTH, HEIGHT); // instantiate bricks initBricks(window); // instantiate ball, centered in middle of window GOval ball = initBall(window); // instantiate paddle, centered at bottom of window GRect paddle = initPaddle(window); // instantiate scoreboard, centered in middle of window, just above ball GLabel label = initScoreboard(window); GLabel llabel = initlives(window); setLocation(llabel, 10, 590); // number of bricks initially int bricks = COLS * ROWS; // number of lives initially int lives = LIVES; // number of points initially int points = 0; pause(1000); // keep playing until game over updatellabel(window, llabel, 3); while (lives > 0 && bricks > 0) { while(bricks > 0) { GEvent mouse = getNextEvent(MOUSE_EVENT); if (mouse != NULL) { if (getEventType(mouse) == MOUSE_MOVED) { double x = getX(mouse) - getWidth(paddle) / 2; double y = getY(paddle); setLocation(paddle, x,y); } } move(ball,vx,vy); if (getX(ball) + CD >= WIDTH) { vx = -vx; } else if (getX(ball) <= 0) { vx = -vx; } else if (getY(ball) <= 0) { vy = -vy; } pause(1); GObject object = detectCollision(window, ball); if (object != NULL) { if (object == paddle) { vy = -vy; } else if (strcmp(getType(object), "GRect") == 0) { bricks--; points++; updateScoreboard(window, label, points); vy = -vy; removeGWindow(window, object); } } if (getY(ball) + CD >= HEIGHT) { lives = lives - 1; updatellabel(window, llabel, lives); setLocation(ball,(WIDTH/2) - (CD/2), (HEIGHT/2) - (CD/2)); pause (1000); if (bricks == 0) { GLabel win = initWin(window); pause(5000); break; } else { break; } } } } // wait for click before exiting removeGWindow(window, label); GLabel messege = initEnd(window); sleep(5000); waitForClick(); // game over closeGWindow(window); return 0; }