inline TreeNode down_heap(TreeNode x, const Compare& comp, ExternalData& edata) { while (x.children().size() > 0) { typename TreeNode::children_type::iterator child_iter = std::min_element(x.children().begin(), x.children().end(), comp); if (comp(*child_iter, x)) x.swap(*child_iter, edata); else break; } return x; }
std::list<std::string> getNodeChildren(const std::string& parentId) const { std::list<std::string> children; if (parentId.empty()) { if (this->dataSource_->modelRoot() != NULL) { QPersistentModelIndex pindex(this->model_->index(this->dataSource_->modelRoot(), 0)); this->nodeIndexes_.insert(pindex); // Convert uint64 internal id to string. QString qstr = QString::number(pindex.internalId()); children.push_back(qstr.toLocal8Bit().constData()); } } else { TreeNode* parentNode = getNode(parentId); if (parentNode != NULL) { QList<TreeNode*> childNodes = parentNode->children(); for (int i = 0; i < childNodes.count(); ++i) { QPersistentModelIndex pindex(this->model_->index(childNodes[i], 0)); this->nodeIndexes_.insert(pindex); // Convert uint64 internal id to string. QString qstr = QString::number(pindex.internalId()); children.push_back(qstr.toLocal8Bit().constData()); } } } return children; }
Tree<_DATA>& Tree<_DATA>:: save_this(const char* dir) { char path[SIZEOF_PATH], * filename; std::strcpy(path, dir); std::size_t dir_len = std::strlen(path); std::size_t file_len; if (dir_len > 0 && (path[dir_len - 1] != '/' && path[dir_len - 1] != '\\')) path[dir_len++] = '/'; filename = path + dir_len; file_len = SIZEOF_PATH - dir_len; std::strcpy(filename, "Tree"); std::ofstream file(path); if (!file.is_open()) { std::cerr << "\nFailed opening file: " << path << std::endl; return *this; } unsigned long node_num = 0; file << std::setw(16) << std::setfill('0') << node_num << ".node" << " # root" << std::endl; file.close(); std::queue<TreeNode*> node_pointer; std::queue<unsigned long> node_name; std::queue<unsigned long> node_parent_name; node_pointer.push(root_); node_name.push(node_num); node_parent_name.push(0); while (!node_pointer.empty()) { TreeNode* node = node_pointer.front(); unsigned long name = node_name.front(); unsigned long parent_name = node_parent_name.front(); std::snprintf(filename, file_len, "%016lu.node", name); file.open(path); if (!file.is_open()) { std::cerr << "\nFailed opening file: " << path << std::endl; return *this; } file << std::setw(16) << std::setfill('0') << parent_name << ".node # parent\n" << node->depth() << " # depth\n"; unsigned int n_child = node->num_of_children(); file << n_child << " # number of children\n"; if (n_child) { TreeNode** child = node->children(); for (unsigned int i = 0; i < n_child; ++i) { node_pointer.push(child[i]); node_name.push(++node_num); node_parent_name.push(name); file << std::setw(16) << std::setfill('0') << node_num << ".node # child " << i << "\n"; } } file << node->content(); file.close(); node_pointer.pop(); node_name.pop(); node_parent_name.pop(); } return *this; }
template<class _DATA> inline Tree<_DATA>::~Tree() { if (!root_) return; std::queue<TreeNode*> breadth_first_traverse; breadth_first_traverse.push(root_); while (!breadth_first_traverse.empty()) { TreeNode* cur = breadth_first_traverse.front(); unsigned int cur_n_ch = cur->num_of_children(); if (cur_n_ch) { TreeNode** cur_ch = cur->children(); for (unsigned int i = 0; i < cur_n_ch; i++) { breadth_first_traverse.push(cur_ch[i]); } } breadth_first_traverse.pop(); delete cur; } }
void ParticleTreeDustGridStructure::setupSelfBefore() { GenDustGridStructure::setupSelfBefore(); // Verify property values if (_xmax <= 0.0 || _ymax <= 0.0 || _zmax <= 0.0) throw FATALERROR("The maximum extent should be positive"); // Cache some often used values Log* log = find<Log>(); _eps = 1e-12 * extent().widths().norm(); DustDistribution* dd = find<DustDistribution>(); _dmib = dd->interface<DustMassInBoxInterface>(); DustParticleInterface* dpi = dd->interface<DustParticleInterface>(); if (!dpi) throw FATALERROR("Can't retrieve particle locations from this dust distribution"); int numParticles = dpi->numParticles(); log->info("Constructing tree for " + QString::number(numParticles) + " particles..."); // Create a list, used only during construction, that contains the index of the particle // contained in each leaf node so far created, or -1 if the node is empty // (the value is undefined for nonleaf nodes) vector<int> particlev; // Create the root node (which at this point is an empty leaf) using the requested type switch (_treeType) { default: case OctTree: _tree.push_back(new OctTreeNode(0,0,extent())); break; case BinTree: _tree.push_back(new BinTreeNode(0,0,extent())); break; } particlev.push_back(-1); int maxlevel = 0; // Add particles one by one, subdividing if the leaf node containing the new particle // already contains another particle for (int i=0; i<numParticles; i++) { if (i%50000 == 0) log->info("Adding particle number " + QString::number(i) + " (" + QString::number(i*100/numParticles) + "%)..."); int level = addParticleToNode(i, root(), dpi, particlev, _tree); maxlevel = max(maxlevel, level); } // Perform additional subdivisions as requested if (_extraLevels>0) { log->info("Performing additional subdivisions..."); maxlevel += _extraLevels; for (int e=0; e<_extraLevels; e++) { int Nnodes = _tree.size(); for (int l=0; l<Nnodes; l++) { TreeNode* node = _tree[l]; if (node->ynchildless()) { node->createchildren(_tree.size()); _tree.insert(_tree.end(), node->children().begin(), node->children().end()); } } } } // Construction of a vector _idv that contains the node IDs of all // leaves. This is the actual dust cell vector (only the leaves will // eventually become valid dust cells). We also create a vector // _cellnumberv with the cell numbers of all the nodes (i.e. the // rank m of the node in the vector _idv if the node is a leaf, and // -1 if the node is not a leaf). int Nnodes = _tree.size(); int m = 0; _cellnumberv.resize(Nnodes,-1); for (int l=0; l<Nnodes; l++) { if (_tree[l]->ynchildless()) { _idv.push_back(l); _cellnumberv[l] = m; m++; } } _Ncells = _idv.size(); // Log the number of cells log->info("Construction of the tree finished."); log->info(" Total number of nodes: " + QString::number(Nnodes)); log->info(" Total number of leaves: " + QString::number(_Ncells)); vector<int> countv(maxlevel+1); for (int m=0; m<_Ncells; m++) { TreeNode* node = _tree[_idv[m]]; int level = node->level(); countv[level]++; } log->info(" Number of leaf cells of each level:"); for (int level=0; level<=maxlevel; level++) log->info(" Level " + QString::number(level) + ": " + QString::number(countv[level]) + " cells"); // Determine the number of levels to be included in 3D grid output (if such output is requested) if (writeGrid()) { int cumulativeCells = 0; for (_highestWriteLevel=0; _highestWriteLevel<=maxlevel; _highestWriteLevel++) { cumulativeCells += countv[_highestWriteLevel]; if (cumulativeCells > 1500) break; // experimental number } if (_highestWriteLevel<maxlevel) log->info("Will be outputting 3D grid data up to level " + QString::number(_highestWriteLevel) + ", i.e. " + QString::number(cumulativeCells) + " cells."); } }