/* Loci on dyadic grids */ /* Last edited on 2009-08-21 15:29:34 by stolfilocal */ #ifndef dg_locus_H #define dg_locus_H #include "mdg_grid.h" #include "dg_tree.h" #include "vec.h" #include "box.h" #include /* LOCUS IN A MULTIGRID Note that, in any {d}-dimensional multigrid {G*}, an item {B} with dimension {m < d} may occur in two or more consecutive levels. This situation happens whenever the splitting axis {r \bmod d} is in the set {Nrm{B}}. In particular, any vertex of layer {r} is also a vertex of layer {r+t}, for all {t > 0}. A /locus/ in a {d}-dimensional multigrid is an occurrence of a specific item at a specific level. We can designate a grid locus uniquely by giving its normal axes {Nrm(B)}, and its /owner cell/ {Cll(B,r)}, the {d}-dimensional cell of level {r} of which {B} is an inferior face along all those axes. (In particular, if {B} itself is a cell, then {Cll(B,r) = B}.) Note that the toroidal (periodic) topology of each level means that {Cll(B,r)} always exists, even for items contained in the superior faces of the domain {D}. In these comments, will use the notation {} for the locus consisting of the inferior face of the cell with index {k} with normal axes encoded by the integer {A}, at the level that contains cell {k}. Thus, for example, the root cell is locus {<0:1>}, and the vertex at the origin of layer {r} is locus {<2^d-1:2^r>}. */ typedef struct dg_locus_t { mdg_axis_set_t norm; mdg_cell_index_t cell; } dg_locus_t; /* Identifies a locus in a multigrid, namely locus {}. */ #define dg_locus(A,k) ((dg_locus_t){(A),(k)}) /* The locus with normal axis set {A}, which is the inferior face of cell {k} along those axes. */ #define dg_locus_rank(E) (mdg_cell_rank(E.cell)) /* The rank of locus {E}. */ mdg_dim_t dg_locus_dimension(mdg_dim_t d, dg_locus_t E); /* The dimension of locus {E} in a {d}-dimensional dyadic multigrid. */ mdg_axis_t dg_locus_normal_axis(mdg_dim_t d, dg_locus_t E, mdg_axis_index_t j); /* Returns the {j}th normal axis of locus {E}. */ mdg_axis_t dg_locus_spanning_axis(mdg_dim_t d, dg_locus_t E, mdg_axis_index_t j); /* Returns the {j}th spanning axis of locus {E}. */ dg_locus_t dg_locus_minimize_rank(mdg_dim_t d, dg_locus_t E); /* Returns the locus of minimum rank which consists of the same face of the grid as {E}. */ /* FACES AND SUB-FACES OF A LOCUS The inferior facet of locus {} along its spanning axis {i} is {}. The superior facet is {} where {k'} is the cell adjacent to cell {k} in the {+oo} direction along axis {i}. */ dg_locus_t dg_locus_facet(mdg_dim_t d, dg_locus_t E, mdg_axis_t ax, box_signed_dir_t dir); /* Returns the facet of locus {E} that lies in the direction {dir} along axis {ax}. If {E} is orthogonal to axis {ax}, returns {E} itself. */ dg_locus_t dg_locus_face(mdg_dim_t d, dg_locus_t E, box_face_index_t fi); /* The face of locus {E} that is identified by the relative face index {fi}. */ dg_locus_t dg_locus_neighbor(mdg_dim_t d, dg_locus_t E, box_face_index_t fi); /* The locus {E'} of same dimension, rank and orientation as {E}, such that the largest common face of {E} and {E'} has index {fi} relative to {E}. In particular, if {fi == 0}, returns {E} itself. */ dg_locus_t dg_locus_extend(mdg_dim_t d, dg_locus_t E, mdg_axis_t ax, box_signed_dir_t dir); /* Returns the result of sweeping locus {E} by one grid step along the axis {ax}, in the direction {dir}. If {dir == SMD}, or if {E} is parallel to axis {ax}, returns {E} itself. */ dg_locus_t dg_locus_face_from_signature(mdg_dim_t d, dg_locus_t E, box_signed_dir_t dir[]); /* The face {F} of locus {E} that lies in the direction {dir[j]} along axis {ax[j]}, where {ax[0..m-1] = Spn(E)}. */ void dg_locus_box_root_relative(mdg_dim_t d, dg_locus_t E, interval_t B[]); /* Stores in {B[0..d-1]} the lower and upper root-relative coordinates of the box described by locus {E} in a {d}-dimensional grid. All coordinates will be in the range {[0_1)}. */ /* STAR OF A LOCUS For each {m}-dimensional locus {E} at level {r} of the infinite dyadic grid, we define the /star of {E}/, {K(E)}, as being the cell pack consisting of the {2^{d-m}} cells of level {r} whose boundary contains {E}. These cells are the /wings/ of {E}. In particular, the star of a cell {C} has only one cell, {C} itself; and the star of a vertex has {2^d} cells. DUPLICATED WINGS Thanks to the toroidal topology, every locus has a complete star. Note however that the star of a locus {E} of rank {r < d-1} will include the same cell more than once. More precisely, suppose that {dim(E) = m} and {Nrm(E)} includes {k} coordinate axes in the range {0 .. r}. Then the star {K(E)} actually has only {2^k} distinct cells, whose wing indices are {0..2^k-1}; these cells are then repeated {2^{m-k}} times in the list {K(E)}. */ void dg_locus_star_size(mdg_dim_t d, dg_locus_t E, mdg_grid_size_t psz[]); /* Returns in {psz[i]} the number of cells in {K(E)} along axis {i}, for {i} in {0..d-1}; namely {psz[i]=2} if axis {i} stabs {E}, {psz[i]=1} if {i} spans {E}. */ void dg_locus_star(mdg_dim_t d, dg_locus_t E, mdg_cell_index_t k[]); /* Returns in {k[0..2^m-1]} the indices of the cells of {K(E)}, where {m} is the co-dimension of {E}. */ /* PRINTOUT */ void dg_locus_print(FILE *wr, mdg_dim_t d, dg_locus_t E); /* Prints the locus {E} in the format "{CELL}:{n[0]..n[d-1]}" where {n[i]} is 1 if {i} is in {E.norm}, 0 otherwise. */ vec_typedef(dg_locus_vec_t,dg_locus_vec,dg_locus_t); /* A vector of {dg_locus_t}. */ #endif