int oct_leaf(OctTree *tree, float3 *pos, int depth) { float4 volume = {0.0f, 0.0f, 0.0f, 1.0f}; int this = 0; int child=0; for(int i=0; i<depth; i++) { child = oct_child(pos, &volume); if(tree->block[this].n[child].child ) { this = tree->block[this].n[child].child; } else { int tmp = oct_new_block(tree); tree->block[this].n[child].child = tmp; this = tmp; } } child = oct_child(pos, &volume); if(!tree->block[this].n[child].brick) { tree->block[this].n[child].brick = oct_new_brick(tree, &volume); } return tree->block[this].n[child].brick; }
void oct_move( int oct_old, int oct_new ) { int i; cart_assert( oct_level[oct_old] != FREE_OCT_LEVEL ); cart_assert( oct_level[oct_new] == FREE_OCT_LEVEL ); cart_assert( oct_parent_cell[oct_old] >= 0 && oct_parent_cell[oct_old] < num_cells ); cart_assert( cell_child_oct[ oct_parent_cell[oct_old] ] == oct_old ); cell_child_oct[ oct_parent_cell[oct_old] ] = oct_new; oct_parent_cell[oct_new] = oct_parent_cell[oct_old]; oct_level[oct_new] = oct_level[oct_old]; oct_parent_root_sfc[oct_new] = oct_parent_root_sfc[oct_old]; for ( i = 0; i < num_children; i++ ) { cell_move( oct_child( oct_old, i ), oct_child( oct_new, i ) ); } for ( i = 0; i < num_neighbors; i++ ) { oct_neighbors[oct_new][i] = oct_neighbors[oct_old][i]; } for ( i = 0; i < nDim; i++ ) { oct_pos[oct_new][i] = oct_pos[oct_old][i]; } if ( root_cell_type(oct_parent_root_sfc[oct_new]) == CELL_TYPE_LOCAL ) { linked_list_insert( &local_oct_list[oct_level[oct_new]], oct_new ); } else { linked_list_insert( &buffer_oct_list[oct_level[oct_new]], oct_new ); } }
void kfb_pressurize(double dPressure, int level, int icell) { int ioct, ichild; switch ( kfb_internal_spread ) { case KFB_SPREAD_CELL: cell_extra_pressure_source(icell) += dPressure; break; case KFB_SPREAD_OCT: if ( level == min_level ) { cell_extra_pressure_source(icell) += dPressure; } else { ioct = cell_parent_oct(icell); for ( ichild = 0; ichild < num_children; ichild++ ) { /* 4.0=24faces/6faces */ cell_extra_pressure_source(oct_child(ioct,ichild)) += dPressure/4.0; } } break; case KFB_SPREAD_CUBE: if( kfb_internal_method == KFB_METHOD_HYBRID || kfb_internal_method == KFB_METHOD_HYBRIDGATHER ){ cell_extra_pressure_source(icell) += dPressure; }else{ cart_error(" Pressurizing across cube is not implemented"); } break; default: cart_error("bad kfb spread option %s",kfb_internal_spread); } }
int oct_read(OctTree *tree, float3 *pos) { float4 volume = {0.0f, 0.0f, 0.0f, 1.0f}; if(!inside(pos, &volume)) return 0; int this = 0; int child=0; while(1) { child = oct_child(pos, &volume); if(tree->block[this].n[child].child ) { this = tree->block[this].n[child].child; } else { if(!tree->block[this].n[child].brick) { tree->block[this].n[child].brick = oct_new_brick(tree, &volume); } return tree->block[this].n[child].brick; } } }
void kfb_kick_oct(double dp, int level, int icell){ int ioct, ichild; int dum[]={0,0,0}; if ( level == min_level ) { kfb_kick_cell(icell, UNIT_VECTOR, dum, dp, level); } else { ioct = cell_parent_oct(icell); for(ichild=0; ichild<num_children; ichild++){ kfb_kick_cell(oct_child(ioct,ichild), ichild, dum, dp/num_children, level ); } } }
/******************************************************* * split_cell *******************************************************/ int split_cell( int icell ) /* purpose: splits the given cell into num_children and * handles tree variables (does NOT handle interpolation * of actual cell variables. * * returns: 0 if operation is successful * -1 if cell is already split * -2 if there are no free octs remaining * NO LONGER USED: we need to use this function on buffer * cells which may violate +/- 1 refinement criteria * since they are pruned, so the refinement check * is moved to split * -4 if the split would violate the * +/- 1 refinement criteria */ { int i; int oct_ptr; int type; cart_assert ( icell >= 0 && icell < num_cells ); cart_assert ( cell_level( icell ) < max_level ); /* make sure cell isn't already split */ if ( cell_is_refined(icell) ) { cart_debug("split_cell(%u) error: cell already refined!", icell ); return -1; } /* allocate a new oct */ oct_ptr = oct_alloc(); /* make sure we haven't run out of octs */ if ( oct_ptr == NULL_OCT ) { return -2; } oct_level[oct_ptr] = cell_level(icell)+1; cart_assert( oct_level[oct_ptr] > min_level && oct_level[oct_ptr] <= max_level ); /* add oct to appropriate linked list */ type = root_cell_type( cell_parent_root_sfc(icell) ); if ( type == CELL_TYPE_LOCAL ) { linked_list_insert( &local_oct_list[oct_level[oct_ptr]], oct_ptr ); num_cells_per_level[oct_level[oct_ptr]] += num_children; } else if ( type == CELL_TYPE_BUFFER ) { linked_list_insert( &buffer_oct_list[oct_level[oct_ptr]], oct_ptr ); num_buffer_cells[oct_level[oct_ptr]] += num_children; } else { cart_error("Bad cell type in split_cell!"); } /* set up oct neighbors */ cell_all_neighbors( icell, oct_neighbors[oct_ptr] ); /* set up oct position */ cell_center_position( icell, oct_pos[oct_ptr] ); /* set up new oct */ oct_parent_cell[oct_ptr] = icell; oct_parent_root_sfc[oct_ptr] = cell_parent_root_sfc(icell); /* set all newly allocated children to leaves */ for ( i = 0; i < num_children; i++ ) { cell_child_oct[ oct_child( oct_ptr, i ) ] = UNREFINED_CELL; } /* set cell child pointer */ cell_child_oct[icell] = oct_ptr; #ifdef PARTICLES for ( i = 0; i < num_children; i++ ) { cell_particle_list[ oct_child( oct_ptr, i ) ] = NULL_PARTICLE; } split_particle_list( icell ); #endif /* PARTICLES */ #ifdef HYDRO_TRACERS for ( i = 0; i < num_children; i++ ) { cell_tracer_list[ oct_child( oct_ptr, i ) ] = NULL_TRACER; } split_tracer_list( icell ); #endif /* HYDRO_TRACERS */ return 0; }