// Update attributes of a geogram mesh according to the current grid void OctreeGrid::updateMeshAttributes(GEO::Mesh &mesh) const { // Map octree cell to hex in the final mesh (keeping only the leaves) std::vector<int> cellToHex(numCells(), -1); for (int q = 0, c = 0; q < numCells(); ++q) { if (cellIsLeaf(q)) { cellToHex[q] = c++; } } for (auto name : cellAttributes.keys()) { setGeogramAttribute(name, *this, mesh, cellToHex); } }
// Return true iff the octree is paired bool OctreeGrid::isPaired() const { for (int i = 0; i < numCells(); ++i) { if (!cellIsPaired(i)) { return false; } } return true; }
// Returns true iff the octree is 2:1 graded bool OctreeGrid::is2to1Graded() const { for (int i = 0; i < numCells(); ++i) { if (cellIsLeaf(i) && !cellIs2to1Graded(i)) { return false; } } return true; }
// Initialize a new geogram mesh corresponding to the current grid void OctreeGrid::createMesh( GEO::Mesh &mesh, const Eigen::Vector3d &origin, const Eigen::Vector3d &spacing) const { mesh.clear(false, false); // logger_debug("OctreeGrid", "createMesh(): Allocate vertices and cells"); // Create the mesh of regular grid mesh.vertices.create_vertices(numNodes()); for (int idx = 0; idx < numNodes(); ++idx) { Eigen::Vector3d pos = origin + nodePos(idx).cast<double>().cwiseProduct(spacing); mesh.vertices.point(idx) = GEO::vec3(pos[0], pos[1], pos[2]); } // Count num of leaf cells int numLeaves = 0; for (int c = 0; c < numCells(); ++c) { if (cellIsLeaf(c)) { ++numLeaves; } } GEO::index_t firstCube = mesh.cells.create_hexes(numLeaves); for (int q = 0, c = 0; q < numCells(); ++q) { if (!cellIsLeaf(q)) { continue; } Eigen::Vector3i diff[8] = { {0,0,0}, {1,0,0}, {0,1,0}, {1,1,0}, {0,0,1}, {1,0,1}, {0,1,1}, {1,1,1} }; for (GEO::index_t lv = 0; lv < 8; ++lv) { int cornerId = Cube::invDelta(diff[lv]); int v = cellCornerId(q, cornerId); mesh.cells.set_vertex(firstCube + c, lv, v); } ++c; } // logger_debug("OctreeGrid", "createMesh(): Connecting cells"); //GEO::Logger::out("OctreeGrid") << "Computing borders..." << std::endl; //mesh.cells.compute_borders(); //GEO::Logger::out("OctreeGrid") << "Connecting cells..." << std::endl; //mesh.cells.connect(); // logger_debug("OctreeGrid", "createMesh(): Creating attributes..."); updateMeshAttributes(mesh); }
// Traverse the leaf cells recursively and split them according to the predicate function void OctreeGrid::subdivide(std::function<bool(int, int, int, int)> predicate, bool graded, bool paired, int maxCells) { std::queue<int> pending; for (int i = 0; i < (int) m_Cells.size(); ++i) { if (cellIsLeaf(i)) { pending.push(i); } } int numNodesBefore = numNodes(); int numCellsBefore = numCells(); int numSubdivided = 0; if (maxCells < 0) { maxCells = std::numeric_limits<int>::max(); } while (!pending.empty() && numCells() + 8 <= maxCells) { int id = pending.front(); pending.pop(); int extent = cellExtent(id); auto pos = cellCornerPos(id, 0); if (predicate(pos[0], pos[1], pos[2], extent)) { if (extent == 1) { std::cerr << "[OctreeGrid] Cannot subdivide cell of length 1." << std::endl; } else { if (cellIsLeaf(id)) { splitCell(id, graded, paired); } for (int k = 0; k < 8; ++k) { pending.push(m_Cells[id].firstChild + k); } } } } // Resize attribute vectors nodeAttributes.resize(numNodes()); cellAttributes.resize(numCells()); GEO::Logger::out("OctreeGrid") << "Subdivide has split " << numSubdivided << " cells\n"; GEO::Logger::out("OctreeGrid") << "Num nodes: " << numNodesBefore << " -> " << numNodes() << "\n"; GEO::Logger::out("OctreeGrid") << "Num cells: " << numCellsBefore << " -> " << numCells() << std::endl; }
Eigen::Array<double, Eigen::Dynamic, 1> cellCentroidsZ(const Dune::CpGrid& grid) { // Create an Eigen array of appropriate size int rows=numCells(grid); Eigen::Array<double, Eigen::Dynamic, 1> array(rows); // Fill it with the z coordinate of the cell centroids. for (int i=0; i<rows; ++i) array[i]=cellCentroid(grid, i)[2]; return array; }
void UniformGrid::create(KdTree * tree, int maxLevel) { m_maxLevel = maxLevel; std::cout<<"\n UniformGrid create max level "<<maxLevel; // start at 8 cells per axis int level = 3; const int dim = 1<<level; int i, j, k; const float h = cellSizeAtLevel(level); const float hh = h * .5f; const Vector3F ori = origin() + Vector3F(hh, hh, hh); Vector3F sample; BoundingBox box; for(k=0; k < dim; k++) { for(j=0; j < dim; j++) { for(i=0; i < dim; i++) { sample = ori + Vector3F(h* (float)i, h* (float)j, h* (float)k); box.setMin(sample.x - hh, sample.y - hh, sample.z - hh); box.setMax(sample.x + hh, sample.y + hh, sample.z + hh); if(tree->intersectBox(&box)) addCell(sample, level); } } } bool needRefine = tagCellsToRefine(tree); while(needRefine && level < maxLevel) { std::cout<<"\n level"<<level<<" n cell "<<numCells(); refine(tree); level++; if(level < maxLevel) needRefine = tagCellsToRefine(tree); } m_cellsToRefine->clear(); std::cout<<"\n level"<<level<<" n cell "<<numCells(); }
const double* endCellVolumes(const UnstructuredGrid& grid) { return grid.cell_volumes+numCells(grid); }
SparseTableView cell2Faces(const UnstructuredGrid& grid) { return SparseTableView(grid.cell_faces, grid.cell_facepos, numCells(grid)); }
Bool_t KernelDensity::readTuple(TTree* tree, std::vector<TString> &vars, UInt_t maxEvents) { if (vars.size() != m_phaseSpace->dimensionality() ) { printf("%20.20s ERROR: Number of TTree variables (%d) in tree \"%s\" does not correspond to phase space dimensionality (%d)\n", m_name, (UInt_t)vars.size(), tree->GetName(), m_phaseSpace->dimensionality() ); abort(); } UInt_t nvars = vars.size(); tree->ResetBranchAddresses(); Long64_t nentries = tree->GetEntries(); if (maxEvents > 0 && maxEvents < nentries) nentries = maxEvents; Long64_t i; std::vector<Float_t> varArray(nvars); UInt_t n; for (n=0; n < nvars; n++) { printf("%20.20s INFO: Will read branch \"%s\" from tree \"%s\"\n", m_name, vars[n].Data(), tree->GetName()); Int_t status = tree->SetBranchAddress(vars[n], &( varArray[n] )); if (status < 0) { printf("%20.20s WARNING: Error setting branch, status=%d\n", m_name, status); abort(); } } std::vector<Double_t> point(nvars); UInt_t cells = numCells(); m_dataVector.resize(cells); Int_t cell; for (cell = 0; cell < (Int_t)cells; cell++) { m_dataVector[cell].reserve(nentries/cells); } UInt_t nout = 0; for(i=0; i<nentries; i++) { // printf("DEBUG: before: %f\n", varArray[0]); tree->GetEntry(i); // printf("DEBUG: after: %f\n", varArray[0]); for (n=0; n<nvars; n++) { point[n] = varArray[n]; } if (!m_phaseSpace->withinLimits( point )) { nout ++; printf("%20.20s WARNING: Ntuple point (", m_name); for (n=0; n<nvars; n++) { printf("%f ", point[n]); } printf(", %f%%) outside phase space\n", 100.*float(nout)/float(i)); } else { cell = cellIndex( point ); if (cell>=0) m_dataVector[cell].push_back(point); } if (i % 10000 == 0) { printf("%20.20s INFO: Read %lld/%lld events (%f%%)\n", m_name, i, nentries, 100.*float(i)/float(nentries)); } } printf("%20.20s INFO: %lld events read in from \"%s\"\n", m_name, nentries-nout, tree->GetName() ); return 1; }
/// Create normalisation vector Bool_t KernelDensity::generateApproximation(UInt_t apprSize) { UInt_t dimensionality = m_phaseSpace->dimensionality(); UInt_t cells = numCells(); m_apprVector.resize(cells); Int_t cell; for (cell = 0; cell < (Int_t)cells; cell++) m_apprVector[cell].reserve(apprSize/cells); std::vector<Double_t> point(dimensionality); printf("%20.20s INFO: Generating approximation sample for %d-dim distribution, %d points, %d cells\n", m_name, dimensionality, apprSize, cells); UInt_t i; for (i=0; i<apprSize; i++) { if (!m_approxDensity) { UInt_t t; Bool_t success = 0; for (t = 0; t < m_maxTries; t++) { // Generate random point UInt_t var; for (var = 0; var < dimensionality; var++) { Double_t lowerLimit = m_phaseSpace->lowerLimit(var); Double_t upperLimit = m_phaseSpace->upperLimit(var); point[var] = lowerLimit + m_rnd.Rndm()*(upperLimit-lowerLimit); } Bool_t inPhsp = m_phaseSpace->withinLimits(point); if (inPhsp) { success = 1; break; } } if (!success) { printf("%20.20s WARNING: failed to generate a point within phase space after %d tries\n", m_name, m_maxTries); return 0; } } else { m_approxDensity->generate(point); } cell = cellIndex(point); if (cell < (Int_t)cells && cell >= 0) m_apprVector[cell].push_back(point); else if (cell > 0) { printf("%20.20s WARNING: cell number %d exceeds vector size %d\n", m_name, cell, cells); abort(); } if (i % 1000 == 0) printf("%20.20s INFO: %d%% done (%d/%d)\n", m_name, (100*i/apprSize), i, apprSize); } return 1; }
CellVolumeIterator endCellVolumes(const Dune::CpGrid& grid) { return CellVolumeIterator(grid, numCells(grid)); }