Пример #1
0
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;
}
Пример #2
0
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;
		}
	}
}