xref: /libCEED/julia/LibCEED.jl/src/ElemRestriction.jl (revision 9c774eddf8c0b4f5416196d32c5355c9591a7190)
144554ea0SWill Paznerabstract type AbstractElemRestriction end
244554ea0SWill Pazner
344554ea0SWill Pazner"""
444554ea0SWill Pazner    ElemRestrictionNone()
544554ea0SWill Pazner
644554ea0SWill PaznerReturns the singleton object corresponding to libCEED's `CEED_ELEMRESTRICTION_NONE`
744554ea0SWill Pazner"""
844554ea0SWill Paznerstruct ElemRestrictionNone <: AbstractElemRestriction end
944554ea0SWill PaznerBase.getindex(::ElemRestrictionNone) = C.CEED_ELEMRESTRICTION_NONE[]
1044554ea0SWill Pazner
1144554ea0SWill Pazner"""
1244554ea0SWill Pazner    ElemRestriction
1344554ea0SWill Pazner
1444554ea0SWill PaznerWraps a `CeedElemRestriction` object, representing the restriction from local vectors to
1544554ea0SWill Paznerelements. An `ElemRestriction` object can be created using [`create_elem_restriction`](@ref)
1644554ea0SWill Pazneror [`create_elem_restriction_strided`](@ref).
1744554ea0SWill Pazner"""
1844554ea0SWill Paznermutable struct ElemRestriction <: AbstractElemRestriction
1944554ea0SWill Pazner    ref::RefValue{C.CeedElemRestriction}
2044554ea0SWill Pazner    function ElemRestriction(ref)
2144554ea0SWill Pazner        obj = new(ref)
2244554ea0SWill Pazner        finalizer(obj) do x
2344554ea0SWill Pazner            # ccall(:jl_safe_printf, Cvoid, (Cstring, Cstring), "Finalizing %s.\n", repr(x))
2444554ea0SWill Pazner            destroy(x)
2544554ea0SWill Pazner        end
2644554ea0SWill Pazner        return obj
2744554ea0SWill Pazner    end
2844554ea0SWill Paznerend
2944554ea0SWill Paznerdestroy(r::ElemRestriction) = C.CeedElemRestrictionDestroy(r.ref) # COV_EXCL_LINE
3044554ea0SWill PaznerBase.getindex(r::ElemRestriction) = r.ref[]
3144554ea0SWill PaznerBase.show(io::IO, ::MIME"text/plain", e::ElemRestriction) =
3244554ea0SWill Pazner    ceed_show(io, e, C.CeedElemRestrictionView)
3344554ea0SWill Pazner
3444554ea0SWill Pazner@doc raw"""
3544554ea0SWill Pazner    create_elem_restriction(
3644554ea0SWill Pazner        ceed::Ceed,
3744554ea0SWill Pazner        nelem,
3844554ea0SWill Pazner        elemsize,
3944554ea0SWill Pazner        ncomp,
4044554ea0SWill Pazner        compstride,
4144554ea0SWill Pazner        lsize,
4244554ea0SWill Pazner        offsets::AbstractArray{CeedInt},
4344554ea0SWill Pazner        mtype::MemType=MEM_HOST,
4444554ea0SWill Pazner        cmode::CopyMode=COPY_VALUES,
4544554ea0SWill Pazner    )
4644554ea0SWill Pazner
4744554ea0SWill PaznerCreate a `CeedElemRestriction`.
4844554ea0SWill Pazner
4944554ea0SWill Pazner!!! warning "Zero-based indexing"
5044554ea0SWill Pazner    In the below notation, we are using **0-based indexing**. libCEED expects the offset
5144554ea0SWill Pazner    indices to be 0-based.
5244554ea0SWill Pazner
5344554ea0SWill Pazner# Arguments:
5444554ea0SWill Pazner- `ceed`:       The [`Ceed`](@ref) object
5544554ea0SWill Pazner- `nelem`:      Number of elements described in the `offsets` array
5644554ea0SWill Pazner- `elemsize`:   Size (number of "nodes") per element
5744554ea0SWill Pazner- `ncomp`:      Number of field components per interpolation node (1 for scalar fields)
5844554ea0SWill Pazner- `compstride`: Stride between components for the same L-vector "node". Data for node $i$,
5944554ea0SWill Pazner                component $j$, element $k$ can be found in the L-vector at index `offsets[i
6044554ea0SWill Pazner                + k*elemsize] + j*compstride`.
6144554ea0SWill Pazner- `lsize`:      The size of the L-vector. This vector may be larger than the elements and
6244554ea0SWill Pazner                fields given by this restriction.
6344554ea0SWill Pazner- `offsets`:    Array of shape `(elemsize, nelem)`. Column $i$ holds the ordered list of the
6444554ea0SWill Pazner                offsets (into the input [`CeedVector`](@ref)) for the unknowns corresponding
6544554ea0SWill Pazner                to element $i$, where $0 \leq i < \textit{nelem}$. All offsets must be in
6644554ea0SWill Pazner                the range $[0, \textit{lsize} - 1]$.
6744554ea0SWill Pazner- `mtype`:      Memory type of the `offsets` array, see [`MemType`](@ref)
6844554ea0SWill Pazner- `cmode`:      Copy mode for the `offsets` array, see [`CopyMode`](@ref)
6944554ea0SWill Pazner"""
7044554ea0SWill Paznerfunction create_elem_restriction(
7144554ea0SWill Pazner    c::Ceed,
7244554ea0SWill Pazner    nelem,
7344554ea0SWill Pazner    elemsize,
7444554ea0SWill Pazner    ncomp,
7544554ea0SWill Pazner    compstride,
7644554ea0SWill Pazner    lsize,
7744554ea0SWill Pazner    offsets::AbstractArray{CeedInt};
7844554ea0SWill Pazner    mtype::MemType=MEM_HOST,
7944554ea0SWill Pazner    cmode::CopyMode=COPY_VALUES,
8044554ea0SWill Pazner)
8144554ea0SWill Pazner    ref = Ref{C.CeedElemRestriction}()
8244554ea0SWill Pazner    C.CeedElemRestrictionCreate(
8344554ea0SWill Pazner        c[],
8444554ea0SWill Pazner        nelem,
8544554ea0SWill Pazner        elemsize,
8644554ea0SWill Pazner        ncomp,
8744554ea0SWill Pazner        compstride,
8844554ea0SWill Pazner        lsize,
8944554ea0SWill Pazner        mtype,
9044554ea0SWill Pazner        cmode,
9144554ea0SWill Pazner        offsets,
9244554ea0SWill Pazner        ref,
9344554ea0SWill Pazner    )
9444554ea0SWill Pazner    ElemRestriction(ref)
9544554ea0SWill Paznerend
9644554ea0SWill Pazner
9744554ea0SWill Pazner@doc raw"""
9844554ea0SWill Pazner    create_elem_restriction_strided(ceed::Ceed, nelem, elemsize, ncomp, lsize, strides)
9944554ea0SWill Pazner
10044554ea0SWill PaznerCreate a strided `CeedElemRestriction`.
10144554ea0SWill Pazner
10244554ea0SWill Pazner!!! warning "Zero-based indexing"
10344554ea0SWill Pazner    In the below notation, we are using **0-based indexing**. libCEED expects the offset
10444554ea0SWill Pazner    indices to be 0-based.
10544554ea0SWill Pazner
10644554ea0SWill Pazner# Arguments:
10744554ea0SWill Pazner- `ceed`:     The [`Ceed`](@ref) object
10844554ea0SWill Pazner- `nelem`:    Number of elements described by the restriction
10944554ea0SWill Pazner- `elemsize`: Size (number of "nodes") per element
11044554ea0SWill Pazner- `ncomp`:    Number of field components per interpolation node (1 for scalar fields)
11144554ea0SWill Pazner- `lsize`:    The size of the L-vector. This vector may be larger than the elements and
11244554ea0SWill Pazner              fields given by this restriction.
11344554ea0SWill Pazner- `strides`:  Array for strides between [nodes, components, elements]. Data for node $i$,
11444554ea0SWill Pazner              component $j$, element $k$ can be found in the L-vector at index `i*strides[0]
11544554ea0SWill Pazner              + j*strides[1] + k*strides[2]`. [`STRIDES_BACKEND`](@ref) may be used with
11644554ea0SWill Pazner              vectors created by a Ceed backend.
11744554ea0SWill Pazner"""
11844554ea0SWill Paznerfunction create_elem_restriction_strided(c::Ceed, nelem, elemsize, ncomp, lsize, strides)
11944554ea0SWill Pazner    ref = Ref{C.CeedElemRestriction}()
12044554ea0SWill Pazner    C.CeedElemRestrictionCreateStrided(c[], nelem, elemsize, ncomp, lsize, strides, ref)
12144554ea0SWill Pazner    ElemRestriction(ref)
12244554ea0SWill Paznerend
12344554ea0SWill Pazner
12444554ea0SWill Pazner"""
12544554ea0SWill Pazner    apply!(
12644554ea0SWill Pazner        r::ElemRestriction,
12744554ea0SWill Pazner        u::CeedVector,
12844554ea0SWill Pazner        ru::CeedVector;
12944554ea0SWill Pazner        tmode=NOTRANSPOSE,
13044554ea0SWill Pazner        request=RequestImmediate(),
13144554ea0SWill Pazner    )
13244554ea0SWill Pazner
13344554ea0SWill PaznerUse the [`ElemRestriction`](@ref) to convert from L-vector to an E-vector (or apply the
13444554ea0SWill Paznertranpose operation). The input [`CeedVector`](@ref) is `u` and the result stored in `ru`.
13544554ea0SWill Pazner
13644554ea0SWill PaznerIf `tmode` is `TRANSPOSE`, then the result is added to `ru`. If `tmode` is `NOTRANSPOSE`,
13744554ea0SWill Paznerthen `ru` is overwritten with the result.
13844554ea0SWill Pazner"""
13944554ea0SWill Paznerfunction apply!(
14044554ea0SWill Pazner    r::ElemRestriction,
14144554ea0SWill Pazner    u::CeedVector,
14244554ea0SWill Pazner    ru::CeedVector;
14344554ea0SWill Pazner    tmode=NOTRANSPOSE,
14444554ea0SWill Pazner    request=RequestImmediate(),
14544554ea0SWill Pazner)
14644554ea0SWill Pazner    C.CeedElemRestrictionApply(r[], tmode, u[], ru[], request[])
14744554ea0SWill Paznerend
14844554ea0SWill Pazner
14944554ea0SWill Pazner"""
15044554ea0SWill Pazner    apply(r::ElemRestriction, u::AbstractVector; tmode=NOTRANSPOSE)
15144554ea0SWill Pazner
15244554ea0SWill PaznerUse the [`ElemRestriction`](@ref) to convert from L-vector to an E-vector (or apply the
15344554ea0SWill Paznertranpose operation). The input is given by `u`, and the result is returned as an array of
15444554ea0SWill Paznertype `Vector{CeedScalar}`.
15544554ea0SWill Pazner"""
15644554ea0SWill Paznerfunction apply(r::ElemRestriction, u::AbstractVector; tmode=NOTRANSPOSE)
15744554ea0SWill Pazner    ceed_ref = Ref{C.Ceed}()
15844554ea0SWill Pazner    ccall(
15944554ea0SWill Pazner        (:CeedElemRestrictionGetCeed, C.libceed),
16044554ea0SWill Pazner        Cint,
16144554ea0SWill Pazner        (C.CeedElemRestriction, Ptr{C.Ceed}),
16244554ea0SWill Pazner        r[],
16344554ea0SWill Pazner        ceed_ref,
16444554ea0SWill Pazner    )
16544554ea0SWill Pazner    c = Ceed(ceed_ref)
16644554ea0SWill Pazner    uv = CeedVector(c, u)
16744554ea0SWill Pazner    if tmode == NOTRANSPOSE
16844554ea0SWill Pazner        ruv = create_evector(r)
16944554ea0SWill Pazner    else
17044554ea0SWill Pazner        ruv = create_lvector(r)
17144554ea0SWill Pazner    end
172*9c774eddSJeremy L Thompson    ruv[] = 0.0
17344554ea0SWill Pazner    apply!(r, uv, ruv; tmode=tmode)
17444554ea0SWill Pazner    Vector(ruv)
17544554ea0SWill Paznerend
17644554ea0SWill Pazner
17744554ea0SWill Pazner"""
17844554ea0SWill Pazner    create_evector(r::ElemRestriction)
17944554ea0SWill Pazner
18044554ea0SWill PaznerReturn a new [`CeedVector`](@ref) E-vector.
18144554ea0SWill Pazner"""
18244554ea0SWill Paznerfunction create_evector(r::ElemRestriction)
18344554ea0SWill Pazner    ref = Ref{C.CeedVector}()
18444554ea0SWill Pazner    C.CeedElemRestrictionCreateVector(r[], C_NULL, ref)
18544554ea0SWill Pazner    CeedVector(ref)
18644554ea0SWill Paznerend
18744554ea0SWill Pazner
18844554ea0SWill Pazner"""
18944554ea0SWill Pazner    create_lvector(r::ElemRestriction)
19044554ea0SWill Pazner
19144554ea0SWill PaznerReturn a new [`CeedVector`](@ref) L-vector.
19244554ea0SWill Pazner"""
19344554ea0SWill Paznerfunction create_lvector(r::ElemRestriction)
19444554ea0SWill Pazner    ref = Ref{C.CeedVector}()
19544554ea0SWill Pazner    C.CeedElemRestrictionCreateVector(r[], ref, C_NULL)
19644554ea0SWill Pazner    CeedVector(ref)
19744554ea0SWill Paznerend
19844554ea0SWill Pazner
19944554ea0SWill Pazner"""
20044554ea0SWill Pazner    create_vectors(r::ElemRestriction)
20144554ea0SWill Pazner
20244554ea0SWill PaznerReturn an (L-vector, E-vector) pair.
20344554ea0SWill Pazner"""
20444554ea0SWill Paznerfunction create_vectors(r::ElemRestriction)
20544554ea0SWill Pazner    l_ref = Ref{C.CeedVector}()
20644554ea0SWill Pazner    e_ref = Ref{C.CeedVector}()
20744554ea0SWill Pazner    C.CeedElemRestrictionCreateVector(r[], l_ref, e_ref)
20844554ea0SWill Pazner    CeedVector(l_ref), CeedVector(e_ref)
20944554ea0SWill Paznerend
21044554ea0SWill Pazner
21144554ea0SWill Pazner"""
21244554ea0SWill Pazner    getcompstride(r::ElemRestriction)
21344554ea0SWill Pazner
21444554ea0SWill PaznerGet the L-vector component stride.
21544554ea0SWill Pazner"""
21644554ea0SWill Paznerfunction getcompstride(r::ElemRestriction)
21744554ea0SWill Pazner    lsize = Ref{CeedInt}()
21844554ea0SWill Pazner    C.CeedElemRestrictionGetCompStride(r[], lsize)
21944554ea0SWill Pazner    lsize[]
22044554ea0SWill Paznerend
22144554ea0SWill Pazner
22244554ea0SWill Pazner"""
22344554ea0SWill Pazner    getnumelements(r::ElemRestriction)
22444554ea0SWill Pazner
22544554ea0SWill PaznerGet the total number of elements in the range of an [`ElemRestriction`](@ref).
22644554ea0SWill Pazner"""
22744554ea0SWill Paznerfunction getnumelements(r::ElemRestriction)
22844554ea0SWill Pazner    result = Ref{CeedInt}()
22944554ea0SWill Pazner    C.CeedElemRestrictionGetNumElements(r[], result)
23044554ea0SWill Pazner    result[]
23144554ea0SWill Paznerend
23244554ea0SWill Pazner
23344554ea0SWill Pazner"""
23444554ea0SWill Pazner    getelementsize(r::ElemRestriction)
23544554ea0SWill Pazner
23644554ea0SWill PaznerGet the size of elements in the given [`ElemRestriction`](@ref).
23744554ea0SWill Pazner"""
23844554ea0SWill Paznerfunction getelementsize(r::ElemRestriction)
23944554ea0SWill Pazner    result = Ref{CeedInt}()
24044554ea0SWill Pazner    C.CeedElemRestrictionGetElementSize(r[], result)
24144554ea0SWill Pazner    result[]
24244554ea0SWill Paznerend
24344554ea0SWill Pazner
24444554ea0SWill Pazner"""
24544554ea0SWill Pazner    getlvectorsize(r::ElemRestriction)
24644554ea0SWill Pazner
24744554ea0SWill PaznerGet the size of an L-vector for the given [`ElemRestriction`](@ref).
24844554ea0SWill Pazner"""
24944554ea0SWill Paznerfunction getlvectorsize(r::ElemRestriction)
25044554ea0SWill Pazner    result = Ref{CeedInt}()
25144554ea0SWill Pazner    C.CeedElemRestrictionGetLVectorSize(r[], result)
25244554ea0SWill Pazner    result[]
25344554ea0SWill Paznerend
25444554ea0SWill Pazner
25544554ea0SWill Pazner"""
25644554ea0SWill Pazner    getnumcomponents(r::ElemRestriction)
25744554ea0SWill Pazner
25844554ea0SWill PaznerGet the number of components in the elements of an [`ElemRestriction`](@ref).
25944554ea0SWill Pazner"""
26044554ea0SWill Paznerfunction getnumcomponents(r::ElemRestriction)
26144554ea0SWill Pazner    result = Ref{CeedInt}()
26244554ea0SWill Pazner    C.CeedElemRestrictionGetNumComponents(r[], result)
26344554ea0SWill Pazner    result[]
26444554ea0SWill Paznerend
26544554ea0SWill Pazner
26644554ea0SWill Pazner"""
26744554ea0SWill Pazner    getmultiplicity!(r::ElemRestriction, v::AbstractCeedVector)
26844554ea0SWill Pazner
26944554ea0SWill PaznerGet the multiplicity of nodes in an [`ElemRestriction`](@ref). The [`CeedVector`](@ref) `v`
27044554ea0SWill Paznershould be an L-vector (i.e. `length(v) == getlvectorsize(r)`, see [`create_lvector`](@ref)).
27144554ea0SWill Pazner"""
27244554ea0SWill Paznerfunction getmultiplicity!(r::ElemRestriction, v::AbstractCeedVector)
27344554ea0SWill Pazner    @assert length(v) == getlvectorsize(r)
27444554ea0SWill Pazner    C.CeedElemRestrictionGetMultiplicity(r[], v[])
27544554ea0SWill Paznerend
27644554ea0SWill Pazner
27744554ea0SWill Pazner"""
27844554ea0SWill Pazner    getmultiplicity(r::ElemRestriction)
27944554ea0SWill Pazner
28044554ea0SWill PaznerConvenience function to get the multiplicity of nodes in the [`ElemRestriction`](@ref),
28144554ea0SWill Paznerwhere the result is returned in a newly allocated Julia `Vector{CeedScalar}` (see also
28244554ea0SWill Pazner[`getmultiplicity!`](@ref)).
28344554ea0SWill Pazner"""
28444554ea0SWill Paznerfunction getmultiplicity(r::ElemRestriction)
28544554ea0SWill Pazner    v = create_lvector(r)
28644554ea0SWill Pazner    getmultiplicity!(r, v)
28744554ea0SWill Pazner    Vector(v)
28844554ea0SWill Paznerend
289