Skip to content

TensorProducts ​

Mantis.TensorProducts Module
julia
module TensorProducts

Utilities for constructing and working with tensor-products of sets.

A TensorProduct represents the tensor-product of multiple, lower-dimensional factor sets, providing efficient conversion between linear indices and Cartesian indices of the product space. This module provides the shared infrastructure for this pattern: a generic interface for creating and indexing tensor-products of arbitrary sets.

source

The module is intentionally minimal. Its only task is to take any tuple of factor sets, pre-compute the bijection between a global linear index and the tuple of per-set indices, and provide utilities to traverse and map over the factors. Modules such as Geometry and FunctionSpaces implement a small interface and delegate all index bookkeeping to TensorProducts, keeping the tensor-product logic in one place rather than scattered across the codebase.

The TensorProduct Type ​

The central type in this module is TensorProduct.

Mantis.TensorProducts.TensorProduct Type
julia
TensorProduct{I,CI,LI}

Represents the tensor (Cartesian) product of a tuple of factor sets.

A TensorProduct stores the factor sets together with the corresponding CartesianIndices and LinearIndices, allowing efficient conversion between linear and multi-dimensional indexing.

Fields

  • factors::I: Tuple of factor sets.

  • cart_ids::CI: Cartesian indices of the tensor product.

  • lin_ids::LI: Linear index mapping for the Cartesian indices.

source

For convenience, the module exports the symbolic operator ⊗:

Mantis.TensorProducts.:⊗ Type

Alias for TensorProduct.

source

Two or more sets can also be freely composed. These compositions are automatically flattened: (A ⊗ B) ⊗ C and A ⊗ (B ⊗ C) are both equivalent to A ⊗ B ⊗ C, producing a single TensorProduct with three factors rather than a nested pair.

The get_num_objects requirement ​

For a set to be used in a TensorProduct, it must implement one function:

Mantis.TensorProducts.get_num_objects Function
julia
get_num_objects(set::Any)

Return the number of objects contained in set.

This function must be implemented for any type that is used as an factor to a TensorProduct.

Defaults are defined in later modules for Geometry.AbstractGeometry and FunctionSpaces.AbstractFESpace, namely Geometry.get_num_elements and FunctionSpaces.get_num_basis.

Examples

julia
julia> using Mantis

julia> TensorProducts.get_num_objects(["a", "b", "c"]) == 3
true

julia> TensorProducts.get_num_objects(Geometry.create_cartesian_box((0.0, 0.0), (1.0, 1.0), (2, 2))) == 4
true

julia> TensorProducts.get_num_objects(word::String) = length(word); nothing

julia> TensorProducts.get_num_objects("Pequod") == 6
true
source

This is the only requirement imposed by the module. Standard Julia containers (Tuple and AbstractArray) satisfy it out of the box using length. Custom types — such as Mantis.Geometry.AbstractGeometry or Mantis.FunctionSpaces.AbstractFESpace — implement this function to expose their element or basis count, respectively. This keeps the TensorProducts module free of any dependency on the rest of Mantis.

Index Bookkeeping ​

The central service provided by a TensorProduct is the efficient bidirectional mapping between a single linear index and a tuple of per-factor indices. This mapping is pre-computed once at construction time and stored internally. Mantis has a few helpers for this purpose:

Mantis.TensorProducts.get_cart_ids Function
julia
get_cart_ids(tp::TensorProduct)

Return the CartesianIndices associated with the tensor product.

source
Mantis.TensorProducts.get_lin_ids Function
julia
get_lin_ids(tp::TensorProduct)

Return the LinearIndices associated with the tensor product.

source
Mantis.TensorProducts.get_factor_ids Function
julia
get_factor_ids(tp::TensorProduct, id)

Return the tuple of indices corresponding to the linear index id. The tuple can be used to index each factor of tp.

source
Mantis.TensorProducts.get_factor_num_objects Function
julia
get_factor_num_objects(tp::TensorProduct)

Return a tuple containing the number of objects in each factor set.

source
Mantis.TensorProducts.get_num_factors Function
julia
get_num_factors(tp::TensorProduct)

Return the number of factor sets in the tensor product.

source
Mantis.TensorProducts.get_num_objects Method
julia
get_num_objects(set::Any)

Return the number of objects contained in set.

This function must be implemented for any type that is used as an factor to a TensorProduct.

Defaults are defined in later modules for Geometry.AbstractGeometry and FunctionSpaces.AbstractFESpace, namely Geometry.get_num_elements and FunctionSpaces.get_num_basis.

Examples

julia
julia> using Mantis

julia> TensorProducts.get_num_objects(["a", "b", "c"]) == 3
true

julia> TensorProducts.get_num_objects(Geometry.create_cartesian_box((0.0, 0.0), (1.0, 1.0), (2, 2))) == 4
true

julia> TensorProducts.get_num_objects(word::String) = length(word); nothing

julia> TensorProducts.get_num_objects("Pequod") == 6
true
source

An example should make it clear.

julia
julia> using Mantis

julia> tp = TensorProducts.TensorProduct(("a", "b"), ("x", "y", "z"))  # 2 × 3 product
Mantis.TensorProducts.TensorProduct{Tuple{Tuple{String, String}, Tuple{String, String, String}}, CartesianIndices{2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}, LinearIndices{2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}}((("a", "b"), ("x", "y", "z")), CartesianIndices((2, 3)), LinearIndices((Base.OneTo(2), Base.OneTo(3))))

julia> TensorProducts.get_num_objects(tp)
6

julia> TensorProducts.get_factor_ids(tp, 4)  # (2, 2): second of "a","b", second of "x","y","z"
(2, 2)

julia> TensorProducts.get_factor_num_objects(tp)
(2, 3)

Accessing and Mapping factors ​

The following functions provide access to the factor sets and allow applying operations to them in a dimension-independent way.

Mantis.TensorProducts.get_factors Function
julia
get_factors(tp::TensorProduct)

Return the tuple of factor sets defining the tensor product.

source
Mantis.TensorProducts.mapfactors Method
julia
mapfactors(f, tp::TensorProduct)

Apply f to each factor set and return the resulting tuple.

source
Mantis.TensorProducts.mapfactors Method
julia
mapfactors(f, tp::TensorProduct, id)

Apply f to each factor set and factor id, converted from the global id, and return the resulting tuple.

source
Base.map Method
julia
map(f, tp::TensorProduct, args...)

Apply f to each factor set and construct a new TensorProduct from the resulting sets.

source

Usage in Other Modules ​

TensorProducts is used by several modules in Mantis. The two most prominent use-cases are Mantis.Geometry.TensorProductGeometry and Mantis.FunctionSpaces.TensorProductSpace.

Tensor-Product Geometry ​

In Geometry, a Mantis.Geometry.TensorProductGeometry is formed by assembling lower-dimensional geometries along independent coordinate directions. The interface with TensorProducts is valid since Mantis.Geometry.AbstractGeometry implements get_num_objects as an alias of Mantis.Geometry.get_num_elements. As a result, a global element ID in the product geometry can be decomposed into per-factor element IDs, and geometry evaluation, Jacobian computation, and Hessian computation all reduce to per-factor operations with no special-casing.

julia
julia> using Mantis

julia> line_x = Geometry.create_cartesian_box((0.0,), (2.0,), (4,))
Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 2.0, 5),),), (CartesianIndices((4,)),), (LinearIndices((Base.OneTo(4),)),))

julia> line_y = Geometry.create_cartesian_box((0.0,), (1.0,), (3,))
Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 4),),), (CartesianIndices((3,)),), (LinearIndices((Base.OneTo(3),)),))

julia> geo = Geometry.TensorProductGeometry(line_x, line_y)
Mantis.Geometry.TensorProductGeometry{2, 2, 1, 2, Mantis.TensorProducts.TensorProduct{Tuple{Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}}, CartesianIndices{2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}, LinearIndices{2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}}}(Mantis.TensorProducts.TensorProduct{Tuple{Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}}, CartesianIndices{2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}, LinearIndices{2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}}((Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 2.0, 5),),), (CartesianIndices((4,)),), (LinearIndices((Base.OneTo(4),)),)), Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 4),),), (CartesianIndices((3,)),), (LinearIndices((Base.OneTo(3),)),))), CartesianIndices((4, 3)), LinearIndices((Base.OneTo(4), Base.OneTo(3)))), (12,))

julia> Geometry.get_num_elements(geo)
12

julia> Geometry.get_factor_num_elements(geo)
(4, 3)

Tensor-Product Function Spaces ​

In FunctionSpaces, a Mantis.FunctionSpaces.TensorProductSpace assembles a multi-dimensional finite element space from lower-dimensional ones. Here the TensorProducts interface uses the number of basis functions, aliasing get_num_objects with Mantis.FunctionSpaces.get_num_basis. As such, a global basis ID decomposes into per-factor basis IDs.

The local basis functions on a product element are assembled via Kronecker products of the per-factor local bases, and supports and extraction operators follow the same structure.

julia
julia> using Mantis

julia> Bx = FunctionSpaces.create_bspline_space((0.0,), (1.0,), (4,), (3,), (2,))
Mantis.FunctionSpaces.BSplineSpace{Mantis.FunctionSpaces.Bernstein, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Vector{Int64}, Matrix{Float64}, UnitRange{Int64}, UnitRange{Int64}, Vector{Vector{Vector{Int64}}}}(Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 5),),), (CartesianIndices((4,)),), (LinearIndices((Base.OneTo(4),)),)), Mantis.FunctionSpaces.KnotVector{Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Vector{Int64}}(Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 5),),), (CartesianIndices((4,)),), (LinearIndices((Base.OneTo(4),)),)), 3, [4, 1, 1, 1, 4]), Mantis.FunctionSpaces.Bernstein(3), Mantis.FunctionSpaces.ExtractionOperator{1, Matrix{Float64}, UnitRange{Int64}, UnitRange{Int64}}([([1.0 0.0 0.0 0.0; 0.0 1.0 0.0 0.0; 0.0 0.5 0.5 0.0; 0.0 0.25 0.5833333333333334 0.16666666666666666],), ([0.25 0.5833333333333334 0.16666666666666666 0.0; 0.0 0.6666666666666667 0.3333333333333333 0.0; 0.0 0.33333333333333337 0.6666666666666666 0.0; 0.0 0.16666666666666669 0.6666666666666667 0.16666666666666666],), ([0.16666666666666669 0.6666666666666667 0.16666666666666666 0.0; 0.0 0.6666666666666667 0.3333333333333333 0.0; 0.0 0.33333333333333337 0.6666666666666666 0.0; 0.0 0.16666666666666669 0.5833333333333333 0.25],), ([0.16666666666666669 0.5833333333333333 0.25 0.0; 0.0 0.5 0.5 0.0; 0.0 0.0 1.0 0.0; 0.0 0.0 0.0 1.0],)], Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}[Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}(1:4, (1:4,)), Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}(2:5, (1:4,)), Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}(3:6, (1:4,)), Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}(4:7, (1:4,))], 4, 7), [[[1], [2, 3, 4, 5, 6], [7]]])

julia> By = FunctionSpaces.create_bspline_space((0.0,), (1.0,), (2,), (3,), (2,))
Mantis.FunctionSpaces.BSplineSpace{Mantis.FunctionSpaces.Bernstein, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Vector{Int64}, Matrix{Float64}, UnitRange{Int64}, UnitRange{Int64}, Vector{Vector{Vector{Int64}}}}(Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 3),),), (CartesianIndices((2,)),), (LinearIndices((Base.OneTo(2),)),)), Mantis.FunctionSpaces.KnotVector{Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Vector{Int64}}(Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 3),),), (CartesianIndices((2,)),), (LinearIndices((Base.OneTo(2),)),)), 3, [4, 1, 4]), Mantis.FunctionSpaces.Bernstein(3), Mantis.FunctionSpaces.ExtractionOperator{1, Matrix{Float64}, UnitRange{Int64}, UnitRange{Int64}}([([1.0 0.0 0.0 0.0; 0.0 1.0 0.0 0.0; 0.0 0.5 0.5 0.0; 0.0 0.25 0.5 0.25],), ([0.25 0.5 0.25 0.0; 0.0 0.5 0.5 0.0; 0.0 0.0 1.0 0.0; 0.0 0.0 0.0 1.0],)], Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}[Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}(1:4, (1:4,)), Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}(2:5, (1:4,))], 2, 5), [[[1], [2, 3, 4], [5]]])

julia> Bz = FunctionSpaces.create_bspline_space((0.0,), (1.0,), (3,), (3,), (2,))
Mantis.FunctionSpaces.BSplineSpace{Mantis.FunctionSpaces.Bernstein, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Vector{Int64}, Matrix{Float64}, UnitRange{Int64}, UnitRange{Int64}, Vector{Vector{Vector{Int64}}}}(Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 4),),), (CartesianIndices((3,)),), (LinearIndices((Base.OneTo(3),)),)), Mantis.FunctionSpaces.KnotVector{Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Vector{Int64}}(Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 4),),), (CartesianIndices((3,)),), (LinearIndices((Base.OneTo(3),)),)), 3, [4, 1, 1, 4]), Mantis.FunctionSpaces.Bernstein(3), Mantis.FunctionSpaces.ExtractionOperator{1, Matrix{Float64}, UnitRange{Int64}, UnitRange{Int64}}([([1.0 0.0 0.0 0.0; 0.0 1.0 0.0 0.0; 0.0 0.5 0.5 0.0; 0.0 0.25 0.5833333333333334 0.16666666666666666],), ([0.25 0.5833333333333334 0.16666666666666666 0.0; 0.0 0.6666666666666667 0.3333333333333333 0.0; 0.0 0.33333333333333337 0.6666666666666666 0.0; 0.0 0.16666666666666669 0.5833333333333333 0.24999999999999994],), ([0.16666666666666669 0.5833333333333333 0.24999999999999994 0.0; 0.0 0.5 0.49999999999999994 0.0; 0.0 0.0 1.0 0.0; 0.0 0.0 0.0 1.0],)], Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}[Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}(1:4, (1:4,)), Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}(2:5, (1:4,)), Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}(3:6, (1:4,))], 3, 6), [[[1], [2, 3, 4, 5], [6]]])

julia> B3D = FunctionSpaces.TensorProductSpace(Bx, By, Bz)
Mantis.FunctionSpaces.TensorProductSpace{3, 1, 3, Mantis.TensorProducts.TensorProduct{Tuple{Mantis.FunctionSpaces.BSplineSpace{Mantis.FunctionSpaces.Bernstein, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Vector{Int64}, Matrix{Float64}, UnitRange{Int64}, UnitRange{Int64}, Vector{Vector{Vector{Int64}}}}, Mantis.FunctionSpaces.BSplineSpace{Mantis.FunctionSpaces.Bernstein, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Vector{Int64}, Matrix{Float64}, UnitRange{Int64}, UnitRange{Int64}, Vector{Vector{Vector{Int64}}}}, Mantis.FunctionSpaces.BSplineSpace{Mantis.FunctionSpaces.Bernstein, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Vector{Int64}, Matrix{Float64}, UnitRange{Int64}, UnitRange{Int64}, Vector{Vector{Vector{Int64}}}}}, CartesianIndices{3, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}, LinearIndices{3, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}}, Mantis.Geometry.TensorProductGeometry{3, 3, 1, 3, Mantis.TensorProducts.TensorProduct{Tuple{Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}}, CartesianIndices{3, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}, LinearIndices{3, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}}}, Mantis.Geometry.TensorProductGeometry{3, 3, 1, 3, Mantis.TensorProducts.TensorProduct{Tuple{Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}}, CartesianIndices{3, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}, LinearIndices{3, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}}}, Vector{Vector{Vector{Int64}}}}(Mantis.TensorProducts.TensorProduct{Tuple{Mantis.FunctionSpaces.BSplineSpace{Mantis.FunctionSpaces.Bernstein, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Vector{Int64}, Matrix{Float64}, UnitRange{Int64}, UnitRange{Int64}, Vector{Vector{Vector{Int64}}}}, Mantis.FunctionSpaces.BSplineSpace{Mantis.FunctionSpaces.Bernstein, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Vector{Int64}, Matrix{Float64}, UnitRange{Int64}, UnitRange{Int64}, Vector{Vector{Vector{Int64}}}}, Mantis.FunctionSpaces.BSplineSpace{Mantis.FunctionSpaces.Bernstein, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Vector{Int64}, Matrix{Float64}, UnitRange{Int64}, UnitRange{Int64}, Vector{Vector{Vector{Int64}}}}}, CartesianIndices{3, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}, LinearIndices{3, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}}((Mantis.FunctionSpaces.BSplineSpace{Mantis.FunctionSpaces.Bernstein, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Vector{Int64}, Matrix{Float64}, UnitRange{Int64}, UnitRange{Int64}, Vector{Vector{Vector{Int64}}}}(Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 5),),), (CartesianIndices((4,)),), (LinearIndices((Base.OneTo(4),)),)), Mantis.FunctionSpaces.KnotVector{Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Vector{Int64}}(Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 5),),), (CartesianIndices((4,)),), (LinearIndices((Base.OneTo(4),)),)), 3, [4, 1, 1, 1, 4]), Mantis.FunctionSpaces.Bernstein(3), Mantis.FunctionSpaces.ExtractionOperator{1, Matrix{Float64}, UnitRange{Int64}, UnitRange{Int64}}([([1.0 0.0 0.0 0.0; 0.0 1.0 0.0 0.0; 0.0 0.5 0.5 0.0; 0.0 0.25 0.5833333333333334 0.16666666666666666],), ([0.25 0.5833333333333334 0.16666666666666666 0.0; 0.0 0.6666666666666667 0.3333333333333333 0.0; 0.0 0.33333333333333337 0.6666666666666666 0.0; 0.0 0.16666666666666669 0.6666666666666667 0.16666666666666666],), ([0.16666666666666669 0.6666666666666667 0.16666666666666666 0.0; 0.0 0.6666666666666667 0.3333333333333333 0.0; 0.0 0.33333333333333337 0.6666666666666666 0.0; 0.0 0.16666666666666669 0.5833333333333333 0.25],), ([0.16666666666666669 0.5833333333333333 0.25 0.0; 0.0 0.5 0.5 0.0; 0.0 0.0 1.0 0.0; 0.0 0.0 0.0 1.0],)], Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}[Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}(1:4, (1:4,)), Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}(2:5, (1:4,)), Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}(3:6, (1:4,)), Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}(4:7, (1:4,))], 4, 7), [[[1], [2, 3, 4, 5, 6], [7]]]), Mantis.FunctionSpaces.BSplineSpace{Mantis.FunctionSpaces.Bernstein, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Vector{Int64}, Matrix{Float64}, UnitRange{Int64}, UnitRange{Int64}, Vector{Vector{Vector{Int64}}}}(Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 3),),), (CartesianIndices((2,)),), (LinearIndices((Base.OneTo(2),)),)), Mantis.FunctionSpaces.KnotVector{Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Vector{Int64}}(Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 3),),), (CartesianIndices((2,)),), (LinearIndices((Base.OneTo(2),)),)), 3, [4, 1, 4]), Mantis.FunctionSpaces.Bernstein(3), Mantis.FunctionSpaces.ExtractionOperator{1, Matrix{Float64}, UnitRange{Int64}, UnitRange{Int64}}([([1.0 0.0 0.0 0.0; 0.0 1.0 0.0 0.0; 0.0 0.5 0.5 0.0; 0.0 0.25 0.5 0.25],), ([0.25 0.5 0.25 0.0; 0.0 0.5 0.5 0.0; 0.0 0.0 1.0 0.0; 0.0 0.0 0.0 1.0],)], Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}[Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}(1:4, (1:4,)), Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}(2:5, (1:4,))], 2, 5), [[[1], [2, 3, 4], [5]]]), Mantis.FunctionSpaces.BSplineSpace{Mantis.FunctionSpaces.Bernstein, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Vector{Int64}, Matrix{Float64}, UnitRange{Int64}, UnitRange{Int64}, Vector{Vector{Vector{Int64}}}}(Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 4),),), (CartesianIndices((3,)),), (LinearIndices((Base.OneTo(3),)),)), Mantis.FunctionSpaces.KnotVector{Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Vector{Int64}}(Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 4),),), (CartesianIndices((3,)),), (LinearIndices((Base.OneTo(3),)),)), 3, [4, 1, 1, 4]), Mantis.FunctionSpaces.Bernstein(3), Mantis.FunctionSpaces.ExtractionOperator{1, Matrix{Float64}, UnitRange{Int64}, UnitRange{Int64}}([([1.0 0.0 0.0 0.0; 0.0 1.0 0.0 0.0; 0.0 0.5 0.5 0.0; 0.0 0.25 0.5833333333333334 0.16666666666666666],), ([0.25 0.5833333333333334 0.16666666666666666 0.0; 0.0 0.6666666666666667 0.3333333333333333 0.0; 0.0 0.33333333333333337 0.6666666666666666 0.0; 0.0 0.16666666666666669 0.5833333333333333 0.24999999999999994],), ([0.16666666666666669 0.5833333333333333 0.24999999999999994 0.0; 0.0 0.5 0.49999999999999994 0.0; 0.0 0.0 1.0 0.0; 0.0 0.0 0.0 1.0],)], Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}[Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}(1:4, (1:4,)), Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}(2:5, (1:4,)), Mantis.FunctionSpaces.Indices{1, UnitRange{Int64}, UnitRange{Int64}}(3:6, (1:4,))], 3, 6), [[[1], [2, 3, 4, 5], [6]]])), CartesianIndices((7, 5, 6)), LinearIndices((Base.OneTo(7), Base.OneTo(5), Base.OneTo(6)))), Mantis.Geometry.TensorProductGeometry{3, 3, 1, 3, Mantis.TensorProducts.TensorProduct{Tuple{Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}}, CartesianIndices{3, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}, LinearIndices{3, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}}}(Mantis.TensorProducts.TensorProduct{Tuple{Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}}, CartesianIndices{3, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}, LinearIndices{3, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}}((Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 5),),), (CartesianIndices((4,)),), (LinearIndices((Base.OneTo(4),)),)), Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 3),),), (CartesianIndices((2,)),), (LinearIndices((Base.OneTo(2),)),)), Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 4),),), (CartesianIndices((3,)),), (LinearIndices((Base.OneTo(3),)),))), CartesianIndices((4, 2, 3)), LinearIndices((Base.OneTo(4), Base.OneTo(2), Base.OneTo(3)))), (24,)), Mantis.Geometry.TensorProductGeometry{3, 3, 1, 3, Mantis.TensorProducts.TensorProduct{Tuple{Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}}, CartesianIndices{3, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}, LinearIndices{3, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}}}(Mantis.TensorProducts.TensorProduct{Tuple{Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}, Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}}, CartesianIndices{3, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}, LinearIndices{3, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}}}((Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 5),),), (CartesianIndices((4,)),), (LinearIndices((Base.OneTo(4),)),)), Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 3),),), (CartesianIndices((2,)),), (LinearIndices((Base.OneTo(2),)),)), Mantis.Geometry.CartesianGeometry{1, 1, 1, Tuple{Tuple{LinRange{Float64, Int64}}}, Tuple{CartesianIndices{1, Tuple{Base.OneTo{Int64}}}}, Tuple{LinearIndices{1, Tuple{Base.OneTo{Int64}}}}}(((LinRange{Float64}(0.0, 1.0, 4),),), (CartesianIndices((3,)),), (LinearIndices((Base.OneTo(3),)),))), CartesianIndices((4, 2, 3)), LinearIndices((Base.OneTo(4), Base.OneTo(2), Base.OneTo(3)))), (24,)), [[[1], [2, 3, 4, 5, 6], [7], [8, 15, 22], [9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 23, 24, 25, 26, 27], [14, 21, 28], [29], [30, 31, 32, 33, 34], [35], [36, 71, 106, 141]  …  [70, 105, 140, 175], [176], [177, 178, 179, 180, 181], [182], [183, 190, 197], [184, 185, 186, 187, 188, 191, 192, 193, 194, 195, 198, 199, 200, 201, 202], [189, 196, 203], [204], [205, 206, 207, 208, 209], [210]]])

julia> FunctionSpaces.get_num_basis(B3D)
210

julia> FunctionSpaces.get_factor_num_basis(B3D)
(7, 5, 6)