/// Oil viscosity. /// \param[in] po Array of n oil pressure values. /// \param[in] rs Array of n gas solution factor values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n viscosity values. ADB BlackoilPropsAdFromDeck::muOil(const ADB& po, const ADB& rs, const Cells& cells) const { if (!phase_usage_.phase_used[Oil]) { OPM_THROW(std::runtime_error, "Cannot call muOil(): oil phase not present."); } const int n = cells.size(); assert(po.size() == n); V mu(n); V dmudp(n); V dmudr(n); props_[phase_usage_.phase_pos[Oil]]->mu(n, po.value().data(), rs.value().data(), mu.data(), dmudp.data(), dmudr.data()); ADB::M dmudp_diag = spdiag(dmudp); ADB::M dmudr_diag = spdiag(dmudr); const int num_blocks = po.numBlocks(); std::vector<ADB::M> jacs(num_blocks); for (int block = 0; block < num_blocks; ++block) { jacs[block] = dmudp_diag * po.derivative()[block] + dmudr_diag * rs.derivative()[block]; } return ADB::function(mu, jacs); }
// The strategy here is, though this is n^2, it's a very small n, just // finely-spaced adjacent cells. bool SpatialHash::isWithinDistanceOfAnything(PointType const& physPt, double distance) const { // (save taking a lot of square roots) double d2 = distance * distance; Index idx = index_of(physPt); Cells nbrs; get_neighbors(idx, nbrs); // 27 <= we include the center cell itself, too. assert(nbrs.size() <= 27); for (Cells::const_iterator itCells = nbrs.begin(), endCells = nbrs.end(); itCells != endCells; ++itCells) { Pts const* pts = *itCells; if (pts) { for (Pts::const_iterator itPts = pts->begin(), endPts = pts->end(); itPts != endPts; ++itPts) { if (itPts->SquaredEuclideanDistanceTo<double>(physPt) < d2) { return true; } } } } return false; }
void WriteNumberOfNeighboursToConsole(const Cells& cells) { for (int rowIndex = 0; rowIndex < cells.size(); ++rowIndex) { for (int columnIndex = 0; columnIndex < cells[rowIndex].size(); columnIndex++) { cout << GetNumberOfNeighbours(cells, rowIndex, columnIndex) << " "; } cout << "\n"; } }
std::vector<ADB> BlackoilPropsAd::capPress(const ADB& sw, const ADB& so, const ADB& sg, const Cells& cells) const { const int numCells = cells.size(); const int numActivePhases = numPhases(); const int numBlocks = so.numBlocks(); Block activeSat(numCells, numActivePhases); if (pu_.phase_used[Water]) { assert(sw.value().size() == numCells); activeSat.col(pu_.phase_pos[Water]) = sw.value(); } if (pu_.phase_used[Oil]) { assert(so.value().size() == numCells); activeSat.col(pu_.phase_pos[Oil]) = so.value(); } else { OPM_THROW(std::runtime_error, "BlackoilPropsAdFromDeck::relperm() assumes oil phase is active."); } if (pu_.phase_used[Gas]) { assert(sg.value().size() == numCells); activeSat.col(pu_.phase_pos[Gas]) = sg.value(); } Block pc(numCells, numActivePhases); Block dpc(numCells, numActivePhases*numActivePhases); props_.capPress(numCells, activeSat.data(), cells.data(), pc.data(), dpc.data()); std::vector<ADB> adbCapPressures; adbCapPressures.reserve(3); const ADB* s[3] = { &sw, &so, &sg }; for (int phase1 = 0; phase1 < 3; ++phase1) { if (pu_.phase_used[phase1]) { const int phase1_pos = pu_.phase_pos[phase1]; std::vector<ADB::M> jacs(numBlocks); for (int block = 0; block < numBlocks; ++block) { jacs[block] = ADB::M(numCells, s[phase1]->derivative()[block].cols()); } for (int phase2 = 0; phase2 < 3; ++phase2) { if (!pu_.phase_used[phase2]) continue; const int phase2_pos = pu_.phase_pos[phase2]; // Assemble dpc1/ds2. const int column = phase1_pos + numActivePhases*phase2_pos; // Recall: Fortran ordering from props_.relperm() ADB::M dpc1_ds2_diag = spdiag(dpc.col(column)); for (int block = 0; block < numBlocks; ++block) { jacs[block] += dpc1_ds2_diag * s[phase2]->derivative()[block]; } } adbCapPressures.emplace_back(ADB::function(pc.col(phase1_pos), jacs)); } else { adbCapPressures.emplace_back(ADB::null()); } } return adbCapPressures; }
V SolventPropsAdFromDeck::solventSurfaceDensity(const Cells& cells) const { const int n = cells.size(); V density(n); for (int i = 0; i < n; ++i) { int regionIdx = cellPvtRegionIdx_[cells[i]]; density[i] = solvent_surface_densities_[regionIdx]; } return density; }
/// Relative permeabilities for all phases. /// \param[in] sw Array of n water saturation values. /// \param[in] so Array of n oil saturation values. /// \param[in] sg Array of n gas saturation values. /// \param[in] cells Array of n cell indices to be associated with the saturation values. /// \return An std::vector with 3 elements, each an array of n relperm values, /// containing krw, kro, krg. Use PhaseIndex for indexing into the result. std::vector<ADB> BlackoilPropsAd::relperm(const ADB& sw, const ADB& so, const ADB& sg, const Cells& cells) const { const int n = cells.size(); const int np = props_.numPhases(); Block s_all(n, np); if (pu_.phase_used[Water]) { assert(sw.value().size() == n); s_all.col(pu_.phase_pos[Water]) = sw.value(); } if (pu_.phase_used[Oil]) { assert(so.value().size() == n); s_all.col(pu_.phase_pos[Oil]) = so.value(); } else { OPM_THROW(std::runtime_error, "BlackoilPropsAd::relperm() assumes oil phase is active."); } if (pu_.phase_used[Gas]) { assert(sg.value().size() == n); s_all.col(pu_.phase_pos[Gas]) = sg.value(); } Block kr(n, np); Block dkr(n, np*np); props_.relperm(n, s_all.data(), cells.data(), kr.data(), dkr.data()); const int num_blocks = so.numBlocks(); std::vector<ADB> relperms; relperms.reserve(3); typedef const ADB* ADBPtr; ADBPtr s[3] = { &sw, &so, &sg }; for (int phase1 = 0; phase1 < 3; ++phase1) { if (pu_.phase_used[phase1]) { const int phase1_pos = pu_.phase_pos[phase1]; std::vector<ADB::M> jacs(num_blocks); for (int block = 0; block < num_blocks; ++block) { jacs[block] = ADB::M(n, s[phase1]->derivative()[block].cols()); } for (int phase2 = 0; phase2 < 3; ++phase2) { if (!pu_.phase_used[phase2]) { continue; } const int phase2_pos = pu_.phase_pos[phase2]; // Assemble dkr1/ds2. const int column = phase1_pos + np*phase2_pos; // Recall: Fortran ordering from props_.relperm() ADB::M dkr1_ds2_diag = spdiag(dkr.col(column)); for (int block = 0; block < num_blocks; ++block) { jacs[block] += dkr1_ds2_diag * s[phase2]->derivative()[block]; } } relperms.emplace_back(ADB::function(kr.col(phase1_pos), jacs)); } else { relperms.emplace_back(ADB::null()); } } return relperms; }
void WriteToConsole(const Cells& cells) { for (int rowIndex = 0; rowIndex < cells.size(); ++rowIndex) { for (int columnIndex = 0; columnIndex < cells[rowIndex].size(); columnIndex++) { if (cells[rowIndex][columnIndex]) { cout << "# "; } else { cout << "~ "; } } cout << "\n"; } }
int GetNumberOfNeighbours(const Cells& cells, int rowIndex, int columnIndex) { int numberOfNeighbours = 0; int numberOfRows = cells.size(); int numberOfColumns = cells[0].size(); int i; int j; /* --- -0- ### */ i = modulus(rowIndex - 1, numberOfRows); j = modulus(columnIndex - 1, numberOfColumns); numberOfNeighbours += cells[i][j] ? 1 : 0; i = modulus(rowIndex - 1, numberOfRows); j = modulus(columnIndex, numberOfColumns); numberOfNeighbours += cells[i][j] ? 1 : 0; i = modulus(rowIndex - 1, numberOfRows); j = modulus(columnIndex + 1, numberOfColumns); numberOfNeighbours += cells[i][j] ? 1 : 0; /* --- #0# --- */ i = modulus(rowIndex, numberOfRows); j = modulus(columnIndex - 1, numberOfColumns); numberOfNeighbours += cells[i][j] ? 1 : 0; i = modulus(rowIndex, numberOfRows); j = modulus(columnIndex + 1, numberOfColumns); numberOfNeighbours += cells[i][j] ? 1 : 0; /* ### -0- --- */ i = modulus(rowIndex + 1, numberOfRows); j = modulus(columnIndex - 1, numberOfColumns); numberOfNeighbours += cells[i][j] ? 1 : 0; i = modulus(rowIndex + 1, numberOfRows); j = modulus(columnIndex, numberOfColumns); numberOfNeighbours += cells[i][j] ? 1 : 0; i = modulus(rowIndex + 1, numberOfRows); j = modulus(columnIndex + 1, numberOfColumns); numberOfNeighbours += cells[i][j] ? 1 : 0; return numberOfNeighbours; }
/// Bubble point curve for Rs as function of oil pressure. /// \param[in] po Array of n oil pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n bubble point values for Rs. V BlackoilPropsAdFromDeck::rsMax(const V& po, const Cells& cells) const { if (!phase_usage_.phase_used[Oil]) { OPM_THROW(std::runtime_error, "Cannot call rsMax(): oil phase not present."); } const int n = cells.size(); assert(po.size() == n); V rbub(n); V drbubdp(n); props_[Oil]->rbub(n, po.data(), rbub.data(), drbubdp.data()); return rbub; }
V SolventPropsAdFromDeck::mixingParameterDensity(const Cells& cells) const { const int n = cells.size(); if (mix_param_viscosity_.size() > 0) { V mix_param(n); for (int i = 0; i < n; ++i) { int regionIdx = cellMiscRegionIdx_[cells[i]]; mix_param[i] = mix_param_density_[regionIdx]; } return mix_param; } // return zeros if not specified return V::Zero(n); }
/// Gas viscosity. /// \param[in] pg Array of n gas pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n viscosity values. V BlackoilPropsAd::muGas(const V& pg, const Cells& cells) const { if (!pu_.phase_used[Gas]) { OPM_THROW(std::runtime_error, "Cannot call muGas(): gas phase not present."); } const int n = cells.size(); assert(pg.size() == n); const int np = props_.numPhases(); Block z = Block::Zero(n, np); Block mu(n, np); props_.viscosity(n, pg.data(), z.data(), cells.data(), mu.data(), 0); return mu.col(pu_.phase_pos[Gas]); }
/// Water viscosity. /// \param[in] pw Array of n water pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n viscosity values. V BlackoilPropsAd::muWat(const V& pw, const Cells& cells) const { if (!pu_.phase_used[Water]) { THROW("Cannot call muWat(): water phase not present."); } const int n = cells.size(); ASSERT(pw.size() == n); const int np = props_.numPhases(); Block z = Block::Zero(n, np); Block mu(n, np); props_.viscosity(n, pw.data(), z.data(), cells.data(), mu.data(), 0); return mu.col(pu_.phase_pos[Water]); }
void WriteToFile(const Cells& cells, string path) { ofstream file(path.c_str(), std::ios::trunc); for (int rowIndex = 0; rowIndex < cells.size(); ++rowIndex) { for (int columnIndex = 0; columnIndex < cells[rowIndex].size(); columnIndex++) { if (cells[rowIndex][columnIndex]) { file << "# "; } else { file << "~ "; } } file << "\n"; } file.close(); }
/// Gas formation volume factor. /// \param[in] pg Array of n gas pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n formation volume factor values. V BlackoilPropsAd::bGas(const V& pg, const Cells& cells) const { if (!pu_.phase_used[Gas]) { OPM_THROW(std::runtime_error, "Cannot call bGas(): gas phase not present."); } const int n = cells.size(); assert(pg.size() == n); const int np = props_.numPhases(); Block z = Block::Zero(n, np); Block matrix(n, np*np); props_.matrix(n, pg.data(), z.data(), cells.data(), matrix.data(), 0); const int gi = pu_.phase_pos[Gas]; return matrix.col(gi*np + gi); }
/// Water formation volume factor. /// \param[in] pw Array of n water pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n formation volume factor values. V BlackoilPropsAd::bWat(const V& pw, const Cells& cells) const { if (!pu_.phase_used[Water]) { OPM_THROW(std::runtime_error, "Cannot call bWat(): water phase not present."); } const int n = cells.size(); assert(pw.size() == n); const int np = props_.numPhases(); Block z = Block::Zero(n, np); Block matrix(n, np*np); props_.matrix(n, pw.data(), z.data(), cells.data(), matrix.data(), 0); const int wi = pu_.phase_pos[Water]; return matrix.col(wi*np + wi); }
/// Oil viscosity. /// \param[in] po Array of n oil pressure values. /// \param[in] rs Array of n gas solution factor values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n viscosity values. V BlackoilPropsAdFromDeck::muOil(const V& po, const V& rs, const Cells& cells) const { if (!phase_usage_.phase_used[Oil]) { OPM_THROW(std::runtime_error, "Cannot call muOil(): oil phase not present."); } const int n = cells.size(); assert(po.size() == n); V mu(n); V dmudp(n); V dmudr(n); props_[phase_usage_.phase_pos[Oil]]->mu(n, po.data(), rs.data(), mu.data(), dmudp.data(), dmudr.data()); return mu; }
/// Gas viscosity. /// \param[in] pg Array of n gas pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n viscosity values. V BlackoilPropsAdFromDeck::muGas(const V& pg, const Cells& cells) const { if (!phase_usage_.phase_used[Gas]) { OPM_THROW(std::runtime_error, "Cannot call muGas(): gas phase not present."); } const int n = cells.size(); assert(pg.size() == n); V mu(n); V dmudp(n); V dmudr(n); const double* rs = 0; props_[phase_usage_.phase_pos[Gas]]->mu(n, pg.data(), rs, mu.data(), dmudp.data(), dmudr.data()); return mu; }
/// Bubble point curve for Rs as function of oil pressure. /// \param[in] po Array of n oil pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n bubble point values for Rs. ADB BlackoilPropsAdFromDeck::rsMax(const ADB& po, const Cells& cells) const { if (!phase_usage_.phase_used[Oil]) { OPM_THROW(std::runtime_error, "Cannot call rsMax(): oil phase not present."); } const int n = cells.size(); assert(po.size() == n); V rbub(n); V drbubdp(n); props_[Oil]->rbub(n, po.value().data(), rbub.data(), drbubdp.data()); ADB::M drbubdp_diag = spdiag(drbubdp); const int num_blocks = po.numBlocks(); std::vector<ADB::M> jacs(num_blocks); for (int block = 0; block < num_blocks; ++block) { jacs[block] = drbubdp_diag * po.derivative()[block]; } return ADB::function(rbub, jacs); }
/// Water formation volume factor. /// \param[in] pw Array of n water pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n formation volume factor values. V BlackoilPropsAdFromDeck::bWat(const V& pw, const Cells& cells) const { if (!phase_usage_.phase_used[Water]) { OPM_THROW(std::runtime_error, "Cannot call bWat(): water phase not present."); } const int n = cells.size(); assert(pw.size() == n); V b(n); V dbdp(n); V dbdr(n); const double* rs = 0; props_[phase_usage_.phase_pos[Water]]->b(n, pw.data(), rs, b.data(), dbdp.data(), dbdr.data()); return b; }
/// Oil viscosity. /// \param[in] po Array of n oil pressure values. /// \param[in] rs Array of n gas solution factor values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n viscosity values. V BlackoilPropsAd::muOil(const V& po, const V& rs, const Cells& cells) const { if (!pu_.phase_used[Oil]) { THROW("Cannot call muOil(): oil phase not present."); } const int n = cells.size(); ASSERT(po.size() == n); const int np = props_.numPhases(); Block z = Block::Zero(n, np); if (pu_.phase_used[Gas]) { // Faking a z with the right ratio: // rs = zg/zo z.col(pu_.phase_pos[Oil]) = V::Ones(n, 1); z.col(pu_.phase_pos[Gas]) = rs; } Block mu(n, np); props_.viscosity(n, po.data(), z.data(), cells.data(), mu.data(), 0); return mu.col(pu_.phase_pos[Oil]); }
/// Gas viscosity. /// \param[in] pg Array of n gas pressure values. /// \param[in] rv Array of n vapor oil/gas ratio /// \param[in] cond Array of n objects, each specifying which phases are present with non-zero saturation in a cell. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n formation volume factor values. V BlackoilPropsAd::muGas(const V& pg, const V& rv, const std::vector<PhasePresence>& /*cond*/, const Cells& cells) const { if (!pu_.phase_used[Gas]) { OPM_THROW(std::runtime_error, "Cannot call muGas(): gas phase not present."); } const int n = cells.size(); assert(pg.size() == n); const int np = props_.numPhases(); Block z = Block::Zero(n, np); if (pu_.phase_used[Oil]) { // Faking a z with the right ratio: // rv = zo/zg z.col(pu_.phase_pos[Oil]) = rv; z.col(pu_.phase_pos[Gas]) = V::Ones(n, 1); } Block mu(n, np); props_.viscosity(n, pg.data(), z.data(), cells.data(), mu.data(), 0); return mu.col(pu_.phase_pos[Gas]); }
ADB SolventPropsAdFromDeck::makeADBfromTables(const ADB& X_AD, const Cells& cells, const std::vector<int>& regionIdx, const std::vector<NonuniformTableLinear<double>>& tables) const { const int n = cells.size(); assert(X_AD.value().size() == n); V x(n); V dx(n); for (int i = 0; i < n; ++i) { const double& X_i = X_AD.value()[i]; x[i] = tables[regionIdx[cells[i]]](X_i); dx[i] = tables[regionIdx[cells[i]]].derivative(X_i); } ADB::M dx_diag(dx.matrix().asDiagonal()); const int num_blocks = X_AD.numBlocks(); std::vector<ADB::M> jacs(num_blocks); for (int block = 0; block < num_blocks; ++block) { fastSparseProduct(dx_diag, X_AD.derivative()[block], jacs[block]); } return ADB::function(std::move(x), std::move(jacs)); }
/// Water formation volume factor. /// \param[in] pw Array of n water pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n formation volume factor values. ADB BlackoilPropsAd::bWat(const ADB& pw, const Cells& cells) const { if (!pu_.phase_used[Water]) { THROW("Cannot call muWat(): water phase not present."); } const int n = cells.size(); ASSERT(pw.value().size() == n); const int np = props_.numPhases(); Block z = Block::Zero(n, np); Block matrix(n, np*np); Block dmatrix(n, np*np); props_.matrix(n, pw.value().data(), z.data(), cells.data(), matrix.data(), dmatrix.data()); const int phase_ind = pu_.phase_pos[Water]; const int column = phase_ind*np + phase_ind; // Index of our sought diagonal column. ADB::M db_diag = spdiag(dmatrix.col(column)); const int num_blocks = pw.numBlocks(); std::vector<ADB::M> jacs(num_blocks); for (int block = 0; block < num_blocks; ++block) { jacs[block] = db_diag * pw.derivative()[block]; } return ADB::function(matrix.col(column), jacs); }
/// Gas formation volume factor. /// \param[in] pg Array of n gas pressure values. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n formation volume factor values. ADB BlackoilPropsAd::bGas(const ADB& pg, const Cells& cells) const { if (!pu_.phase_used[Gas]) { OPM_THROW(std::runtime_error, "Cannot call muGas(): gas phase not present."); } const int n = cells.size(); assert(pg.value().size() == n); const int np = props_.numPhases(); Block z = Block::Zero(n, np); Block matrix(n, np*np); Block dmatrix(n, np*np); props_.matrix(n, pg.value().data(), z.data(), cells.data(), matrix.data(), dmatrix.data()); const int phase_ind = pu_.phase_pos[Gas]; const int column = phase_ind*np + phase_ind; // Index of our sought diagonal column. ADB::M db_diag = spdiag(dmatrix.col(column)); const int num_blocks = pg.numBlocks(); std::vector<ADB::M> jacs(num_blocks); for (int block = 0; block < num_blocks; ++block) { jacs[block] = db_diag * pg.derivative()[block]; } return ADB::function(matrix.col(column), jacs); }
/// Oil formation volume factor. /// \param[in] po Array of n oil pressure values. /// \param[in] rs Array of n gas solution factor values. /// \param[in] cond Array of n taxonomies classifying fluid condition. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n formation volume factor values. V BlackoilPropsAd::bOil(const V& po, const V& rs, const std::vector<PhasePresence>& /*cond*/, const Cells& cells) const { if (!pu_.phase_used[Oil]) { OPM_THROW(std::runtime_error, "Cannot call bOil(): oil phase not present."); } const int n = cells.size(); assert(po.size() == n); const int np = props_.numPhases(); Block z = Block::Zero(n, np); if (pu_.phase_used[Gas]) { // Faking a z with the right ratio: // rs = zg/zo z.col(pu_.phase_pos[Oil]) = V::Ones(n, 1); z.col(pu_.phase_pos[Gas]) = rs; } Block matrix(n, np*np); props_.matrix(n, po.data(), z.data(), cells.data(), matrix.data(), 0); const int oi = pu_.phase_pos[Oil]; return matrix.col(oi*np + oi); }
/// Oil viscosity. /// \param[in] po Array of n oil pressure values. /// \param[in] rs Array of n gas solution factor values. /// \param[in] cond Array of n taxonomies classifying fluid condition. /// \param[in] cells Array of n cell indices to be associated with the pressure values. /// \return Array of n viscosity values. ADB BlackoilPropsAd::muOil(const ADB& po, const ADB& rs, const std::vector<PhasePresence>& cond, const Cells& cells) const { #if 1 return ADB::constant(muOil(po.value(), rs.value(), cond, cells), po.blockPattern()); #else if (!pu_.phase_used[Oil]) { OPM_THROW(std::runtime_error, "Cannot call muOil(): oil phase not present."); } const int n = cells.size(); assert(po.value().size() == n); const int np = props_.numPhases(); Block z = Block::Zero(n, np); if (pu_.phase_used[Gas]) { // Faking a z with the right ratio: // rs = zg/zo z.col(pu_.phase_pos[Oil]) = V::Ones(n, 1); z.col(pu_.phase_pos[Gas]) = rs.value(); } Block mu(n, np); Block dmu(n, np); props_.viscosity(n, po.value().data(), z.data(), cells.data(), mu.data(), dmu.data()); ADB::M dmu_diag = spdiag(dmu.col(pu_.phase_pos[Oil])); const int num_blocks = po.numBlocks(); std::vector<ADB::M> jacs(num_blocks); for (int block = 0; block < num_blocks; ++block) { // For now, we deliberately ignore the derivative with respect to rs, // since the BlackoilPropertiesInterface class does not evaluate it. // We would add to the next line: + dmu_drs_diag * rs.derivative()[block] jacs[block] = dmu_diag * po.derivative()[block]; } return ADB::function(mu.col(pu_.phase_pos[Oil]), jacs); #endif }
void test(const int d, const string & type, const int N) { // we must write 'typename' below, because we are in a template-function, // so the parser has no way to know that DC contains sub-types, before // instanciating the function. typedef typename DC::Full_cell_handle Full_cell_handle; typedef typename DC::Face Face; typedef typename DC::Point Point; typedef typename DC::Finite_full_cell_const_iterator Finite_full_cell_const_iterator; typedef typename DC::Finite_vertex_iterator Finite_vertex_iterator; typedef CGAL::Random_points_in_cube_d<Point> Random_points_iterator; DC pc(d); cerr << "\nBuilding Delaunay triangulation of (" << type << d << ") dimension with " << N << " points"; assert(pc.empty()); vector<Point> points; CGAL::Random rng; Random_points_iterator rand_it(d, 2.0, rng); //CGAL::cpp11::copy_n(rand_it, N, back_inserter(points)); vector<int> coords(d); for( int i = 0; i < N; ++i ) { for( int j = 0; j < d; ++j ) coords[j] = rand() % 100000; points.push_back(Point(d, coords.begin(), coords.end())); } pc.insert(points.begin(), points.end()); cerr << "\nChecking topology and geometry..."; assert( pc.is_valid() ); cerr << "\nTraversing finite full_cells... "; size_t nbfs(0), nbis(0); Finite_full_cell_const_iterator fsit = pc.finite_full_cells_begin(); while( fsit != pc.finite_full_cells_end() ) ++fsit, ++nbfs; cerr << nbfs << " + "; vector<Full_cell_handle> infinite_full_cells; pc.tds().incident_full_cells(pc.infinite_vertex(), back_inserter(infinite_full_cells)); nbis = infinite_full_cells.size(); cerr << nbis << " = " << (nbis+nbfs) << " = " << pc.number_of_full_cells(); cerr << "\nThe triangulation has current dimension " << pc.current_dimension(); CGAL_assertion( pc.number_of_full_cells() == nbis+nbfs); cerr << "\nTraversing finite vertices... "; size_t nbfv(0); Finite_vertex_iterator fvit = pc.finite_vertices_begin(); while( fvit != pc.finite_vertices_end() ) ++fvit, ++nbfv; cerr << nbfv <<endl; // Count convex hull vertices: if( pc.maximal_dimension() > 1 ) { typedef vector<Face> Faces; Faces edges; back_insert_iterator<Faces> out(edges); pc.tds().incident_faces(pc.infinite_vertex(), 1, out); cout << "\nThere are " << edges.size() << " vertices on the convex hull."; edges.clear(); } else // pc.maximal_dimension() == 1 { typedef vector<Full_cell_handle> Cells; Cells cells; back_insert_iterator<Cells> out(cells); pc.tds().incident_full_cells(pc.infinite_vertex(), out); cout << "\nThere are " << cells.size() << " vertices on the convex hull."; cells.clear(); } // Remove all ! cerr << "\nBefore removal: " << pc.number_of_vertices() << " vertices. After: "; random_shuffle(points.begin(), points.end()); pc.remove(points.begin(), points.end()); assert( pc.is_valid() ); cerr << pc.number_of_vertices() << " vertices."; // assert( pc.empty() ); NOT YET ! // CLEAR pc.clear(); assert( -1 == pc.current_dimension() ); assert( pc.empty() ); assert( pc.is_valid() ); }
vector<vector<int> > CreateTempArray(const Cells& cells) { vector<vector<int> > array(cells.size(), vector<int>(cells[0].size(), 0)); return array; }
bool testCellularGridSpaceND() { typedef typename KSpace::Cell Cell; typedef typename KSpace::SCell SCell; typedef typename KSpace::Point Point; typedef typename KSpace::DirIterator DirIterator; typedef typename KSpace::Cells Cells; typedef typename KSpace::SCells SCells; unsigned int nbok = 0; unsigned int nb = 0; trace.beginBlock ( "Testing block KSpace instantiation and scan ..." ); KSpace K; int xlow[ 4 ] = { -3, -2, -2, -1 }; int xhigh[ 4 ] = { 5, 3, 2, 3 }; Point low( xlow ); Point high( xhigh ); bool space_ok = K.init( low, high, true ); nbok += space_ok ? 1 : 0; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << "K.init( low, high )" << std::endl; trace.info() << "K.dim()=" << K.dimension << endl; int spel[ 4 ] = { 1, 1, 1, 1 }; // pixel Point kp( spel ); Cell center = K.uCell( kp ); Cell c1 = K.uCell( kp ); Cell clow = K.uCell( low, kp ); Cell chigh = K.uCell( high, kp ); trace.info() << c1 << clow << chigh << " topo(c1)=" << K.uTopology( c1 ) << " dirs="; for ( DirIterator q = K.uDirs( clow ); q != 0; ++q ) trace.info() << " " << *q; trace.info() << endl; Cell f = K.uFirst( c1 ); Cell l = K.uLast( c1 ); trace.info() << "Loop in " << clow << chigh << endl; c1 = f; unsigned int nbelems = 0; do { ++nbelems; // trace.info() << c1; } while ( K.uNext( c1, f, l ) ); trace.info() << " -> " << nbelems << " elements." << endl; unsigned int exp_nbelems = 1; for ( Dimension i = 0; i < K.dimension; ++i ) exp_nbelems *= K.size( i ); nbok += nbelems == exp_nbelems ? 1 : 0; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << nbelems << " scanned elements == " << exp_nbelems << " space size." << std::endl; trace.endBlock(); trace.beginBlock ( "Testing neighborhoods in KSpace..." ); Cells N = K.uNeighborhood( center ); nbok += N.size() == ( K.dimension*2 + 1 ) ? 1 : 0; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << N.size() << "(neighborhood size) == " << ( K.dimension*2 + 1 ) << "(2*dim()+1)" << endl; Cells Np = K.uProperNeighborhood( center ); nbok += Np.size() == ( K.dimension*2 ) ? 1 : 0; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << Np.size() << "(proper neighborhood size) == " << ( K.dimension*2 ) << "(2*dim())" << endl; trace.endBlock(); trace.beginBlock ( "Testing faces in KSpace..." ); Cells Nf = K.uFaces( center ); nbok += Nf.size() == ceil( std::pow( 3.0 ,(int) K.dimension ) - 1 ) ? 1 : 0; nb++; trace.info() << "(" << nbok << "/" << nb << ") " << Nf.size() << "(faces size) == " << floor( std::pow( 3.0, (int)K.dimension ) - 1 ) << "(3^dim()-1)" << endl; trace.endBlock(); trace.beginBlock ( "Testing block Incidence in KSpace..." ); SCell sspel = K.sCell( kp, K.POS ); for ( DirIterator q1 = K.sDirs( sspel ); q1 != 0; ++q1 ) for ( DirIterator q2 = K.sDirs( sspel ); q2 != 0; ++q2 ) { if ( *q1 != *q2 ) { SCell s0 = K.sIncident( sspel, *q1, true ); SCell s1 = K.sIncident( sspel, *q2, true ); SCell l10 = K.sIncident( s0, *q2, true ); SCell l01 = K.sIncident( s1, *q1, true ); trace.info() << "D+_" << *q2 << "(D+_" << *q1 << "(V))=" << l10 << " D+_" << *q1 << "(D+_" << *q2 << "(V))=" << l01 << endl; nbok += l10 == K.sOpp( l01 ) ? 1 : 0; nb++; } } trace.info() << "(" << nbok << "/" << nb << ") " << "anti-commutativity of incidence operators." << std::endl; trace.endBlock(); trace.beginBlock ( "Testing direct Incidence in KSpace..." ); for ( DirIterator q1 = K.sDirs( sspel ); q1 != 0; ++q1 ) for ( DirIterator q2 = K.sDirs( sspel ); q2 != 0; ++q2 ) { if ( *q1 != *q2 ) { SCell s0 = K.sDirectIncident( sspel, *q1 ); SCell l10 = K.sDirectIncident( s0, *q2 ); SCell s1 = K.sDirectIncident( sspel, *q2 ); SCell l01 = K.sDirectIncident( s1, *q1 ); trace.info() << "Dd_" << *q2 << "(Dd_" << *q1 << "(V))=" << l10 << " Dd_" << *q1 << "(Dd_" << *q2 << "(V))=" << l01 << endl; nbok += l10 != l01 ? 1 : 0; nbok += K.sSign( s0 ) == K.POS ? 1 : 0; nbok += K.sSign( s1 ) == K.POS ? 1 : 0; nbok += K.sSign( l10 ) == K.POS ? 1 : 0; nbok += K.sSign( l01 ) == K.POS ? 1 : 0; nbok += s0 == K.sIncident( sspel, *q1, K.sDirect( sspel, *q1 ) ) ? 1 : 0; nbok += s1 == K.sIncident( sspel, *q2, K.sDirect( sspel, *q2 ) ) ? 1 : 0; nbok += l10 == K.sIncident( s0, *q2, K.sDirect( s0, *q2 ) ) ? 1 : 0; nbok += l01 == K.sIncident( s1, *q1, K.sDirect( s1, *q1 ) ) ? 1 : 0; nb += 9; } } trace.info() << "(" << nbok << "/" << nb << ") " << "correctness of direct and indirect orientations." << std::endl; trace.endBlock(); return nbok == nb; }