Generation and product of multidimensional complexes
We introduce the use of multidimensional grid generation of cuboidal and simplicial cell complexes, and the more general Cartesian product of cellular complexes. Both kind of operators, depending on the dimension of their input, may generate either full-dimensional (i.e. solid) output complexes, or lower-dimensional complexes of dimension $d$ embedded in Euclidean space of dimension $n$, with $d\leq n$.
E.g., just think to a mesh of 3D cubes in three-dimensional space for the first case, and to the (non-manifold) framework of boundary polygons of such cubic cells for the second case. In particular, both $n$-dimensional solid grids of (hyper)-cuboidal cells and their $d$-dimensional skeletons ($0\leq d\leq n$), embedded in $E^n$, are generated by assembling the cells produced by a number $n$ of either $0$- or $1$-dimensional cell complexes, that in such lowest dimensions coincide with simplicial complexes.
Introduction
First the simple implementation of lower-dimensional (say, either 0- or 1-dimensional) regular cellular complexes with integer coordinates is built. Then, the generation of either full-dimensional cuboidal complexes in $E^n$ and their $d$-skeletons ($0\leq d\leq n$) is provided, since every skeleton can be efficiently generated as a partition of cell subsets produced by the Cartesian product of a proper ordered combination of 0-1 complexes, according to the binary representation of a subset of the integer interval $[0,2^n]$. For this purpose a simple and general implementation of topological product of two cellular complexes of any topology is given by the package. When applied to cellular complexes (i.e. when the coordinates of 0-cells of arguments are fixed and given) the algorithm produces a Cartesian product of its arguments.
The base case
We use 0- and 1-dimensional cell complexes as the basic material for several operations, including generation of simplicial and cellular grids and topological and Cartesian product of cell complexes. The grid_0
second-order function generates a 0-dimensional uniform complex embedding $n+1$ equally-spaced (at unit intervals) 0-cells within the $[0,n]$ interval. It returns the cells of this 0-complex, as an array of indices to vertices. The grid_1
second-order function generates a 1-dimensional uniform complex embedding $n$ 1-cells of unit size within the $[0,n]$ interval. A larGrid
function is given to generate the LAR representation of the cells of either a 0- or a 1-dimensional complex, depending on the value of a d
parameter, to take values in the set $\{0,1\}$, and providing the order of the output complex.
julia> Lar = LinearAlgebraicRepresentation
julia> Lar.larGrid(10)(0)
1×11 Array{Int64,2}:
0 1 2 3 4 5 6 7 8 9 10
julia> Lar.larGrid(10)(1)
2×10 Array{Int64,2}:
0 1 2 3 4 5 6 7 8 9
1 2 3 4 5 6 7 8 9 10
Dimension-independent cuboidal grids
More interesting is the generation of hyper-cubical grids of intrinsic dimension $d$ embedded in $n$-dimensional space, via the Cartesian product of $d$ 1-complexes and $(n-d)$ 0-complexes. When $d=n$ the resulting grid is said solid; when $d=0$ the output grid is 0-dimensional, and corresponds to a grid-arrangement of a discrete set of points in $E^n$.
Generation of grid cells by Cartesian product of 0/1-complexes. The output complex is generated by the product of any number of either 0- or 1-dimensional cell complexes. The product of $d$ 1-complexes generates solid $d$-cells, while the product of $n$ 0-complexes and $n-d$ 1-complexes ($d < n$) generates non-solid $(n-d)$-cells, properly embedded in $n$-space, i.e. with vertices having $n$ coordinates.
The second-order utility index2addr
function transforms a multidimensional shape
array into a function that, when applied to a multindex array, i.e. to a list of integers within the shape
's bounds, returns the integer address of the array component, within the linear storage of the multidimensional array.
The transformation formula for a $d$-dimensional array with shape
$(n_0,n_1,...,n_{d-1})$ is a linear combination of the 0-based multi-index $(i_0,i_1,...,i_{d-1})$ with weights
equal to $(w_0,w_1,...,w_{d-2},1)$:
$addr = i_0\times w_0 +i_1\times w_1 +\cdots +i_{d-1}\times w_{d-1}$
where
$w_k = n_{k+1} \times n_{k+2} \times\cdots\times n_{d-1}, \qquad 0\leq k\leq d-2.$
Therefore, we get index2addr([4,3,6])([2,2,0])=48
=$2\times(3\times 6)+2\times(6\times 1)+0$, where [2,2,0]
represent the numbers of (pages, rows, columns) indexing an element in the three-dimensional array of shape [4,3,6]
.
Examples
To understand the generation of cuboidal grids from products of 0- or 1-dimensional complexes, below we show a simple example of 2D grids embedded in $R^3$. In particular, v1 = [0 1 2 3]
and v0 = [0 1 2]
are two 2-arrays of 1D Points
(i.e. with just one coordinate per vertex), c1 = [[0,1],[1,2],[2,3]]
and c0 = [[0],[1],[2]]
are the LAR representation of one $1$-complex and one $0$-complex, respectively. The solid 2-complex named grid2D
is generated in 2D as follows, with reference to LinearAlgebraicRepresentation types:
julia> v1 = [0 1 2 3]::Lar.Points
1×4 Array{Int64,2}:
0 1 2 3
julia> c1 = [[0,1],[1,2],[2,3]]::Lar.Cells
3-element Array{Array{Int64,1},1}:
[0, 1]
[1, 2]
[2, 3]
julia> grid2D = ( Lar.larVertProd([v1,v1]), Lar.larCellProd([c1,c1]) )::Lar.LAR
([0 0 … 3 3; 0 1 … 2 3], Array{Int64,1}[[1, 2, 5, 6], [2, 3, 6, 7], [3, 4, 7, 8], [5, 6,
9, 10], [6, 7, 10, 11], [7, 8, 11, 12], [9, 10, 13, 14], [10, 11, 14, 15], [11, 12, 15,
16]])
julia> grid2D[1]
2×16 Array{Int64,2}:
0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3
0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3
julia> grid2D[2]
9-element Array{Array{Int64,1},1}:
[1, 2, 5, 6]
[2, 3, 6, 7]
[3, 4, 7, 8]
[5, 6, 9, 10]
[6, 7, 10, 11]
[7, 8, 11, 12]
[9, 10, 13, 14]
[10, 11, 14, 15]
[11, 12, 15, 16]
Main Interface
LinearAlgebraicRepresentation.larCellProd
— FunctionlarCellProd(cellLists::Array{Cells,1})::Cells
Generation of grid cells by Cartesian product of 0/1-complexes. The output complex is generated by the product of any number of either 0- or 1-dimensional cell complexes. The product of $d$ 1-complexes generates solid $d$-cells, while the product of $n$ 0-complexes and $d-n$ 1-complexes ($n < d$) generates non-solid $(d-n)$-cells, properly embedded in $d$-space, i.e. with vertices having $d$ coordinates.
Examples
To understand the generation of cuboidal grids from products of 0- or 1-dimensional complexes, below we show a simple example of 2D grids embedded in $R^3$. In particular, v1 = [0. 1. 2. 3.]
and v0 = [0. 1. 2.]
are two 2-arrays of 1D vertices, c1 = [[0,1],[1,2],[2,3]]
and c0 = [[0],[1],[2]]
are the LAR representation of one $1$-complex and one $0$-complex, respectively. The solid 2-complex named grid2D
is generated in 2D as follows:
julia> v1 = [0. 1. 2. 3.]
1×4 Array{Float64,2}:
0.0 1.0 2.0 3.0
julia> c1 = [[0,1],[1,2],[2,3]]
3-element Array{Array{Int64,1},1}:
[0, 1]
[1, 2]
[2, 3]
julia> grid2D = larVertProd([v1,v1]),larCellProd([c1,c1])
([0.0 0.0 … 3.0 3.0; 0.0 1.0 … 2.0 3.0], Array{Int64,1}[[1, 2, 5, 6], [2, 3, 6, 7], [3, 4, 7, 8], [5, 6, 9, 10], [6, 7, 10, 11], [7, 8, 11, 12], [9, 10, 13, 14], [10, 11, 14, 15], [11, 12, 15, 16]])
whereas a non-solid $2$-complex in $3D$ is generated as:
julia> v1, c1 = [0. 1. 2. 3.],[[0,1],[1,2],[2,3]]
([0.0 1.0 2.0 3.0], Array{Int64,1}[[0, 1], [1, 2], [2, 3]])
julia> v0, c0 = [0. 1. 2.], [[0],[1],[2]]
([0.0 1.0 2.0], Array{Int64,1}[[0], [1], [2]])
julia> vertGrid = larVertProd([v1, v1, v0])
3×48 Array{Float64,2}:
0.0 0.0 0.0 0.0 0.0 0.0 … 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0
0.0 0.0 0.0 1.0 1.0 1.0 … 1.0 1.0 1.0 2.0 2.0 2.0 3.0 3.0 3.0
0.0 1.0 2.0 0.0 1.0 2.0 … 0.0 1.0 2.0 0.0 1.0 2.0 0.0 1.0 2.0
julia> cellGrid = larCellProd([c1, c1, c0])
27-element Array{Array{Int64,1},1}:
[1, 4, 13, 16]
[2, 5, 14, 17]
... ... ...
[32, 35, 44, 47]
[33, 36, 45, 48]
julia> grid3D = vertGrid,cellGrid
([0.0 0.0 … 3.0 3.0; 0.0 0.0 … 3.0 3.0; 0.0 1.0 … 1.0 2.0], Array{Int64,1}[[1, 4, 13, 16], [2, 5, 14, 17], … [32, 35, 44, 47], [33, 36, 45, 48]])
julia> using Plasm
julia> Plasm.view(grid3D)
LinearAlgebraicRepresentation.larGridSkeleton
— FunctionlarGridSkeleton( shape::Array{Int,1} )( d::Int )::Cells
Produce the d
-dimensional skeleton (set of d
-cells) of a cuboidal grid of given shape
.
Example
A shape=[1,1,1]
parameter refers to a grid with a single step on the three axes, i.e. to a single 3D unit cube. Below all skeletons of such simplest grid are generated.
julia> Lar.larGridSkeleton([1,1,1])(0)
# output
8-element Array{Array{Int64,1},1}:
[[1], [2], [3], [4], [5], [6], [7], [8]]
julia> Lar.larGridSkeleton([1,1,1])(1)
# output
12-element Array{Array{Int64,1},1}:
[[1,2],[3,4],[5,6],[7,8],[1,3],[2,4],[5,7],[6,8],[1,5],[2,6],[3,7],[4,8]]
julia> Lar.larGridSkeleton([1,1,1])(2)
# output
6-element Array{Array{Int64,1},1}:
[[1,2,3,4], [5,6,7,8], [1,2,5,6], [3,4,7,8], [1,3,5,7], [2,4,6,8]]
julia> Lar.larGridSkeleton([1,1,1])(3)
# output
1-element Array{Array{Int64,1},1}:
[1, 2, 3, 4, 5, 6, 7, 8]
LinearAlgebraicRepresentation.cuboidGrid
— FunctioncuboidGrid( shape, filled=false )::Union( Cells, Array{Cells,1} )
Multi-dimensional generator function. Generate either a solid $d$-grid of unit $d$-cuboids in $d$-dimensional space, or the array of $p$-skeletons ($0 <=p<= d$), depending on the Boolean variable filled
. $0$-cuboids are points, $1$-cuboids are segments, , $2$-cuboids are squares, $3$-cuboids are cubes, etc. The shape=[a,b,c]
value determines the number $a x b x c$ of $d$-cells. Notice that d = length(shape)
LinearAlgebraicRepresentation.larModelProduct
— FunctionlarModelProduct
The larModelProduct
function takes as input a pair of LAR models and returns the model of their Cartesian product. Since LAR type is a pair $(geometry,topology)$, the second element of output is the topological product of the input topologies.
Example
Data preparation follows.
julia> geom_0,topol_0 = [0. 1. 2. 3. 4.],[[1],[2],[3],[4],[5]]
([0.0 1.0 … 3.0 4.0], Array{Int64,1}[[1, 2], [2, 3], [3, 4], [4, 5]])
julia> geom_1,topol_1 = [0. 1. 2.], [[1,2],[2,3]]
([0.0 1.0 2.0], Array{Int64,1}[[1, 2], [2, 3]])
julia> mod_0 = (geom_0,topol_0)
([0.0 1.0 … 3.0 4.0], Array{Int64,1}[[1, 2], [2, 3], [3, 4], [4, 5]])
julia> mod_1 = (geom_1,topol_1)
([0.0 1.0 2.0], Array{Int64,1}[[1, 2], [2, 3]])
Generation of a 2D squares
model, with 8 two-dimensional cells.
julia> squares = larModelProduct(mod_1,mod_1)
([0.0 0.0 … 4.0 4.0; 0.0 1.0 … 1.0 2.0], Array{Int64,1}[[1, 2, 4, 5], [2, 3, 5, 6], [4, 5, 7, 8], [5, 6, 8, 9], [7, 8, 10, 11], [8, 9, 11, 12], [10, 11, 13, 14], [11, 12, 14, 15]])
julia> squares[1]
2×15 Array{Float64,2}:
0.0 0.0 0.0 1.0 1.0 1.0 2.0 2.0 2.0 3.0 3.0 3.0 4.0 4.0 4.0
0.0 1.0 2.0 0.0 1.0 2.0 0.0 1.0 2.0 0.0 1.0 2.0 0.0 1.0 2.0
julia> squares[2]
8-element Array{Array{Int64,1},1}:
[[1,2,4,5], [2,3,5,6], [4,5,7,8], [5,6,8,9], [7,8,10,11], [8,9,11,12], [10,11,13,14], [11,12,14,15]]
Generation of a 3D cubes
model, with 32 three-dimensional cells.
julia> cubes = larModelProduct(squares,mod_0)
([0.0 0.0 … 4.0 4.0; 0.0 0.0 … 2.0 2.0; 0.0 1.0 … 3.0 4.0], Array{Int64,1}[[1, 2, 6, 7, 16, 17, 21, 22], [2, 3, 7, 8, 17, 18, 22, 23], [3, 4, 8, 9, 18, 19, 23, 24], [4, 5, 9, 10, 19, 20, 24, 25], … [53, 54, 58, 59, 68, 69, 73, 74], [54, 55, 59, 60, 69, 70, 74, 75]])
larModelProduct(twoModels)
Further method associated to larModelProduct
function.