bool PolicyTree::ChainContainsBranch(vector<PABase *>& _chain, string branchId) { if (branchId == GetBranchId(_chain)) { return true; } // Get the chainId of the last entry (or descend into an OrBranch, if that is last). PABase *lastOne = _chain[_chain.size() - 1]; if (typeid(lastOne) == typeid(PolicyOr *)) { PolicyOr *orNode = dynamic_cast<PolicyOr *>(lastOne); for (size_t k = 0; k < orNode->Branches.size(); k++) { if (ChainContainsBranch(orNode->Branches[k], branchId)) { return true; } } } return false; }
void TreeConstruction(particle_t* SPH, node_t* node){ //node関連の変数セット int num_node = 0; //host.num_group = 0; struct{ double x, y, z; }max, min, half_length; //rootのデータをセット min.x = 1.0e+30; min.y = 1.0e+30; min.z = 1.0e+30; max.x = - min.x; max.y = - min.y; max.z = - min.z; for(int i = 0 ; i < N_SPHP ; ++ i){ if(SPH[i].r.x < min.x) min.x = SPH[i].r.x; if(SPH[i].r.y < min.y) min.y = SPH[i].r.y; if(SPH[i].r.z < min.z) min.z = SPH[i].r.z; if(SPH[i].r.x > max.x) max.x = SPH[i].r.x; if(SPH[i].r.y > max.y) max.y = SPH[i].r.y; if(SPH[i].r.z > max.z) max.z = SPH[i].r.z; } half_length.x = (max.x - min.x) / 2.0; half_length.y = (max.y - min.y) / 2.0; half_length.z = (max.z - min.z) / 2.0; if(N_DIM == 1){ node[0].half_length = half_length.x; }else if(N_DIM == 2){ if(half_length.x > half_length.y){ node[0].half_length = half_length.x; }else{ node[0].half_length = half_length.y; } }else if(N_DIM == 3){ if(half_length.x > half_length.y){ node[0].half_length = half_length.x; }else{ node[0].half_length = half_length.y; } if(node[0].half_length < half_length.z) node[0].half_length = half_length.z; } node[0].center.x = (max.x + min.x) / 2.0; node[0].center.y = (max.y + min.y) / 2.0; node[0].center.z = (max.z + min.z) / 2.0; node[0].num_particle = N_SPHP; node[0].head_particle = 0; //================ //Morton key生成からのソート //================ ulli grid_size = 1 << 20;//多分20分割くらい for(int i = 0 ; i < N_SPHP ; ++ i){ struct{ ulli x, y, z; } grid_address; grid_address.x = (ulli)((SPH[i].r.x - min.x) / (max.x - min.x) * grid_size - 1.0 / grid_size); grid_address.y = (ulli)((SPH[i].r.y - min.y) / (max.y - min.y) * grid_size - 1.0 / grid_size); grid_address.z = (ulli)((SPH[i].r.z - min.z) / (max.z - min.z) * grid_size - 1.0 / grid_size); SPH[i].zkey = zorder3d(grid_address.x, grid_address.y, grid_address.z); } qsort(SPH, N_SPHP, sizeof(particle_t), (int(*)(const void*, const void*))keycmp); //================ //tree作る //================ for(int node_id = 0 ; node_id <= num_node ; ++ node_id){ if(node[node_id].num_particle <= N_LEAF){//ノードの粒子数が<=N_LEAF個だったら… //まぁやるべきことは特に無い。。。と。 }else{//nodeに複数の粒子が入ってたら… //branchを作る node_t branch[8]; //nodeに入っているbranchの中の一番小さいidをセット node[node_id].head_branch = num_node + 1; //more ptrをセット? //node[node_id].more = &node[node[node_id].head_branch]; //branchのデータを初期化 for(int b = 0 ; b < 8 ; ++ b){ branch[b].num_particle = 0; branch[b].mass = 0; branch[b].mass_center.x = 0; branch[b].mass_center.y = 0; branch[b].mass_center.z = 0; } //tree level取得 short int level = log2(node[0].half_length / node[node_id].half_length + 0.01); //nodeの中の全粒子を各branchに振り分ける for (int i = node[node_id].head_particle ; i < node[node_id].head_particle + node[node_id].num_particle ; ++ i){ //Morton keyから出す。。。 int branch_id = GetBranchId(SPH[i].zkey, level + 1); ++ branch[branch_id].num_particle;//所属branchの粒子数をインクリメント } //branchの重心・質量に関する情報を計算。 branch[0].head_particle = node[node_id].head_particle; for (int b = 1 ; b < 8 ; ++ b) branch[b].head_particle = branch[b-1].head_particle + branch[b-1].num_particle; for (int b = 0 ; b < 8 ; ++ b){ branch[b].half_length = node[node_id].half_length / 2.0; for(int i = branch[b].head_particle ; i < branch[b].head_particle + branch[b].num_particle ; ++ i){ branch[b].mass += SPH[i].m; branch[b].mass_center.x += SPH[i].m * SPH[i].r.x; branch[b].mass_center.y += SPH[i].m * SPH[i].r.y; branch[b].mass_center.z += SPH[i].m * SPH[i].r.z; } branch[b].mass_center.x /= branch[b].mass; branch[b].mass_center.y /= branch[b].mass; branch[b].mass_center.z /= branch[b].mass; } //各branchのサイズに関する情報を計算。泥臭いけどまぁいいや。 #if N_DIM == 1 branch[0].center.x = node[node_id].center.x - branch[0].half_length; branch[0].center.y = 0; branch[0].center.z = 0; branch[1].center.x = node[node_id].center.x + branch[1].half_length; branch[1].center.y = 0; branch[1].center.z = 0; #elif N_DIM == 2 branch[0].center.x = node[node_id].center.x - branch[0].half_length; branch[0].center.y = node[node_id].center.y - branch[0].half_length; branch[0].center.z = 0; branch[1].center.x = node[node_id].center.x + branch[1].half_length; branch[1].center.y = node[node_id].center.y - branch[1].half_length; branch[1].center.z = 0; branch[2].center.x = node[node_id].center.x - branch[2].half_length; branch[2].center.y = node[node_id].center.y + branch[2].half_length; branch[2].center.z = 0; branch[3].center.x = node[node_id].center.x + branch[3].half_length; branch[3].center.y = node[node_id].center.y + branch[3].half_length; branch[3].center.z = 0; #else branch[0].center.x = node[node_id].center.x - branch[0].half_length; branch[0].center.y = node[node_id].center.y - branch[0].half_length; branch[0].center.z = node[node_id].center.z - branch[0].half_length; branch[1].center.x = node[node_id].center.x + branch[1].half_length; branch[1].center.y = node[node_id].center.y - branch[1].half_length; branch[1].center.z = node[node_id].center.z - branch[1].half_length; branch[2].center.x = node[node_id].center.x - branch[2].half_length; branch[2].center.y = node[node_id].center.y + branch[2].half_length; branch[2].center.z = node[node_id].center.z - branch[2].half_length; branch[3].center.x = node[node_id].center.x + branch[3].half_length; branch[3].center.y = node[node_id].center.y + branch[3].half_length; branch[3].center.z = node[node_id].center.z - branch[3].half_length; branch[4].center.x = node[node_id].center.x - branch[4].half_length; branch[4].center.y = node[node_id].center.y - branch[4].half_length; branch[4].center.z = node[node_id].center.z + branch[4].half_length; branch[5].center.x = node[node_id].center.x + branch[5].half_length; branch[5].center.y = node[node_id].center.y - branch[5].half_length; branch[5].center.z = node[node_id].center.z + branch[5].half_length; branch[6].center.x = node[node_id].center.x - branch[6].half_length; branch[6].center.y = node[node_id].center.y + branch[6].half_length; branch[6].center.z = node[node_id].center.z + branch[6].half_length; branch[7].center.x = node[node_id].center.x + branch[7].half_length; branch[7].center.y = node[node_id].center.y + branch[7].half_length; branch[7].center.z = node[node_id].center.z + branch[7].half_length; #endif //作成したbranchの情報をbranch classからnode classにコピー。 node[node_id].num_branch = 0; for(int b = 0 ; b < 8 ; ++ b){ if(branch[b].num_particle != 0){//empty cellだったらコピーしない ++ node[node_id].num_branch;//node内のbranch数上げる int branch_id = num_node + node[node_id].num_branch;//branchのarray id取得 node[branch_id] = branch[b]; } } //ノードの総数を上げる num_node += node[node_id].num_branch; } } }