xref: /libCEED/julia/LibCEED.jl/src/ElemRestriction.jl (revision 44554ea01e90fce366fc2a203c44be15754a38d6)
1*44554ea0SWill Paznerabstract type AbstractElemRestriction end
2*44554ea0SWill Pazner
3*44554ea0SWill Pazner"""
4*44554ea0SWill Pazner    ElemRestrictionNone()
5*44554ea0SWill Pazner
6*44554ea0SWill PaznerReturns the singleton object corresponding to libCEED's `CEED_ELEMRESTRICTION_NONE`
7*44554ea0SWill Pazner"""
8*44554ea0SWill Paznerstruct ElemRestrictionNone <: AbstractElemRestriction end
9*44554ea0SWill PaznerBase.getindex(::ElemRestrictionNone) = C.CEED_ELEMRESTRICTION_NONE[]
10*44554ea0SWill Pazner
11*44554ea0SWill Pazner"""
12*44554ea0SWill Pazner    ElemRestriction
13*44554ea0SWill Pazner
14*44554ea0SWill PaznerWraps a `CeedElemRestriction` object, representing the restriction from local vectors to
15*44554ea0SWill Paznerelements. An `ElemRestriction` object can be created using [`create_elem_restriction`](@ref)
16*44554ea0SWill Pazneror [`create_elem_restriction_strided`](@ref).
17*44554ea0SWill Pazner"""
18*44554ea0SWill Paznermutable struct ElemRestriction <: AbstractElemRestriction
19*44554ea0SWill Pazner    ref::RefValue{C.CeedElemRestriction}
20*44554ea0SWill Pazner    function ElemRestriction(ref)
21*44554ea0SWill Pazner        obj = new(ref)
22*44554ea0SWill Pazner        finalizer(obj) do x
23*44554ea0SWill Pazner            # ccall(:jl_safe_printf, Cvoid, (Cstring, Cstring), "Finalizing %s.\n", repr(x))
24*44554ea0SWill Pazner            destroy(x)
25*44554ea0SWill Pazner        end
26*44554ea0SWill Pazner        return obj
27*44554ea0SWill Pazner    end
28*44554ea0SWill Paznerend
29*44554ea0SWill Paznerdestroy(r::ElemRestriction) = C.CeedElemRestrictionDestroy(r.ref) # COV_EXCL_LINE
30*44554ea0SWill PaznerBase.getindex(r::ElemRestriction) = r.ref[]
31*44554ea0SWill PaznerBase.show(io::IO, ::MIME"text/plain", e::ElemRestriction) =
32*44554ea0SWill Pazner    ceed_show(io, e, C.CeedElemRestrictionView)
33*44554ea0SWill Pazner
34*44554ea0SWill Pazner@doc raw"""
35*44554ea0SWill Pazner    create_elem_restriction(
36*44554ea0SWill Pazner        ceed::Ceed,
37*44554ea0SWill Pazner        nelem,
38*44554ea0SWill Pazner        elemsize,
39*44554ea0SWill Pazner        ncomp,
40*44554ea0SWill Pazner        compstride,
41*44554ea0SWill Pazner        lsize,
42*44554ea0SWill Pazner        offsets::AbstractArray{CeedInt},
43*44554ea0SWill Pazner        mtype::MemType=MEM_HOST,
44*44554ea0SWill Pazner        cmode::CopyMode=COPY_VALUES,
45*44554ea0SWill Pazner    )
46*44554ea0SWill Pazner
47*44554ea0SWill PaznerCreate a `CeedElemRestriction`.
48*44554ea0SWill Pazner
49*44554ea0SWill Pazner!!! warning "Zero-based indexing"
50*44554ea0SWill Pazner    In the below notation, we are using **0-based indexing**. libCEED expects the offset
51*44554ea0SWill Pazner    indices to be 0-based.
52*44554ea0SWill Pazner
53*44554ea0SWill Pazner# Arguments:
54*44554ea0SWill Pazner- `ceed`:       The [`Ceed`](@ref) object
55*44554ea0SWill Pazner- `nelem`:      Number of elements described in the `offsets` array
56*44554ea0SWill Pazner- `elemsize`:   Size (number of "nodes") per element
57*44554ea0SWill Pazner- `ncomp`:      Number of field components per interpolation node (1 for scalar fields)
58*44554ea0SWill Pazner- `compstride`: Stride between components for the same L-vector "node". Data for node $i$,
59*44554ea0SWill Pazner                component $j$, element $k$ can be found in the L-vector at index `offsets[i
60*44554ea0SWill Pazner                + k*elemsize] + j*compstride`.
61*44554ea0SWill Pazner- `lsize`:      The size of the L-vector. This vector may be larger than the elements and
62*44554ea0SWill Pazner                fields given by this restriction.
63*44554ea0SWill Pazner- `offsets`:    Array of shape `(elemsize, nelem)`. Column $i$ holds the ordered list of the
64*44554ea0SWill Pazner                offsets (into the input [`CeedVector`](@ref)) for the unknowns corresponding
65*44554ea0SWill Pazner                to element $i$, where $0 \leq i < \textit{nelem}$. All offsets must be in
66*44554ea0SWill Pazner                the range $[0, \textit{lsize} - 1]$.
67*44554ea0SWill Pazner- `mtype`:      Memory type of the `offsets` array, see [`MemType`](@ref)
68*44554ea0SWill Pazner- `cmode`:      Copy mode for the `offsets` array, see [`CopyMode`](@ref)
69*44554ea0SWill Pazner"""
70*44554ea0SWill Paznerfunction create_elem_restriction(
71*44554ea0SWill Pazner    c::Ceed,
72*44554ea0SWill Pazner    nelem,
73*44554ea0SWill Pazner    elemsize,
74*44554ea0SWill Pazner    ncomp,
75*44554ea0SWill Pazner    compstride,
76*44554ea0SWill Pazner    lsize,
77*44554ea0SWill Pazner    offsets::AbstractArray{CeedInt};
78*44554ea0SWill Pazner    mtype::MemType=MEM_HOST,
79*44554ea0SWill Pazner    cmode::CopyMode=COPY_VALUES,
80*44554ea0SWill Pazner)
81*44554ea0SWill Pazner    ref = Ref{C.CeedElemRestriction}()
82*44554ea0SWill Pazner    C.CeedElemRestrictionCreate(
83*44554ea0SWill Pazner        c[],
84*44554ea0SWill Pazner        nelem,
85*44554ea0SWill Pazner        elemsize,
86*44554ea0SWill Pazner        ncomp,
87*44554ea0SWill Pazner        compstride,
88*44554ea0SWill Pazner        lsize,
89*44554ea0SWill Pazner        mtype,
90*44554ea0SWill Pazner        cmode,
91*44554ea0SWill Pazner        offsets,
92*44554ea0SWill Pazner        ref,
93*44554ea0SWill Pazner    )
94*44554ea0SWill Pazner    ElemRestriction(ref)
95*44554ea0SWill Paznerend
96*44554ea0SWill Pazner
97*44554ea0SWill Pazner@doc raw"""
98*44554ea0SWill Pazner    create_elem_restriction_strided(ceed::Ceed, nelem, elemsize, ncomp, lsize, strides)
99*44554ea0SWill Pazner
100*44554ea0SWill PaznerCreate a strided `CeedElemRestriction`.
101*44554ea0SWill Pazner
102*44554ea0SWill Pazner!!! warning "Zero-based indexing"
103*44554ea0SWill Pazner    In the below notation, we are using **0-based indexing**. libCEED expects the offset
104*44554ea0SWill Pazner    indices to be 0-based.
105*44554ea0SWill Pazner
106*44554ea0SWill Pazner# Arguments:
107*44554ea0SWill Pazner- `ceed`:     The [`Ceed`](@ref) object
108*44554ea0SWill Pazner- `nelem`:    Number of elements described by the restriction
109*44554ea0SWill Pazner- `elemsize`: Size (number of "nodes") per element
110*44554ea0SWill Pazner- `ncomp`:    Number of field components per interpolation node (1 for scalar fields)
111*44554ea0SWill Pazner- `lsize`:    The size of the L-vector. This vector may be larger than the elements and
112*44554ea0SWill Pazner              fields given by this restriction.
113*44554ea0SWill Pazner- `strides`:  Array for strides between [nodes, components, elements]. Data for node $i$,
114*44554ea0SWill Pazner              component $j$, element $k$ can be found in the L-vector at index `i*strides[0]
115*44554ea0SWill Pazner              + j*strides[1] + k*strides[2]`. [`STRIDES_BACKEND`](@ref) may be used with
116*44554ea0SWill Pazner              vectors created by a Ceed backend.
117*44554ea0SWill Pazner"""
118*44554ea0SWill Paznerfunction create_elem_restriction_strided(c::Ceed, nelem, elemsize, ncomp, lsize, strides)
119*44554ea0SWill Pazner    ref = Ref{C.CeedElemRestriction}()
120*44554ea0SWill Pazner    C.CeedElemRestrictionCreateStrided(c[], nelem, elemsize, ncomp, lsize, strides, ref)
121*44554ea0SWill Pazner    ElemRestriction(ref)
122*44554ea0SWill Paznerend
123*44554ea0SWill Pazner
124*44554ea0SWill Pazner"""
125*44554ea0SWill Pazner    apply!(
126*44554ea0SWill Pazner        r::ElemRestriction,
127*44554ea0SWill Pazner        u::CeedVector,
128*44554ea0SWill Pazner        ru::CeedVector;
129*44554ea0SWill Pazner        tmode=NOTRANSPOSE,
130*44554ea0SWill Pazner        request=RequestImmediate(),
131*44554ea0SWill Pazner    )
132*44554ea0SWill Pazner
133*44554ea0SWill PaznerUse the [`ElemRestriction`](@ref) to convert from L-vector to an E-vector (or apply the
134*44554ea0SWill Paznertranpose operation). The input [`CeedVector`](@ref) is `u` and the result stored in `ru`.
135*44554ea0SWill Pazner
136*44554ea0SWill PaznerIf `tmode` is `TRANSPOSE`, then the result is added to `ru`. If `tmode` is `NOTRANSPOSE`,
137*44554ea0SWill Paznerthen `ru` is overwritten with the result.
138*44554ea0SWill Pazner"""
139*44554ea0SWill Paznerfunction apply!(
140*44554ea0SWill Pazner    r::ElemRestriction,
141*44554ea0SWill Pazner    u::CeedVector,
142*44554ea0SWill Pazner    ru::CeedVector;
143*44554ea0SWill Pazner    tmode=NOTRANSPOSE,
144*44554ea0SWill Pazner    request=RequestImmediate(),
145*44554ea0SWill Pazner)
146*44554ea0SWill Pazner    C.CeedElemRestrictionApply(r[], tmode, u[], ru[], request[])
147*44554ea0SWill Paznerend
148*44554ea0SWill Pazner
149*44554ea0SWill Pazner"""
150*44554ea0SWill Pazner    apply(r::ElemRestriction, u::AbstractVector; tmode=NOTRANSPOSE)
151*44554ea0SWill Pazner
152*44554ea0SWill PaznerUse the [`ElemRestriction`](@ref) to convert from L-vector to an E-vector (or apply the
153*44554ea0SWill Paznertranpose operation). The input is given by `u`, and the result is returned as an array of
154*44554ea0SWill Paznertype `Vector{CeedScalar}`.
155*44554ea0SWill Pazner"""
156*44554ea0SWill Paznerfunction apply(r::ElemRestriction, u::AbstractVector; tmode=NOTRANSPOSE)
157*44554ea0SWill Pazner    ceed_ref = Ref{C.Ceed}()
158*44554ea0SWill Pazner    ccall(
159*44554ea0SWill Pazner        (:CeedElemRestrictionGetCeed, C.libceed),
160*44554ea0SWill Pazner        Cint,
161*44554ea0SWill Pazner        (C.CeedElemRestriction, Ptr{C.Ceed}),
162*44554ea0SWill Pazner        r[],
163*44554ea0SWill Pazner        ceed_ref,
164*44554ea0SWill Pazner    )
165*44554ea0SWill Pazner    c = Ceed(ceed_ref)
166*44554ea0SWill Pazner    uv = CeedVector(c, u)
167*44554ea0SWill Pazner    if tmode == NOTRANSPOSE
168*44554ea0SWill Pazner        ruv = create_evector(r)
169*44554ea0SWill Pazner    else
170*44554ea0SWill Pazner        ruv = create_lvector(r)
171*44554ea0SWill Pazner        ruv[] = 0.0
172*44554ea0SWill Pazner    end
173*44554ea0SWill Pazner    apply!(r, uv, ruv; tmode=tmode)
174*44554ea0SWill Pazner    Vector(ruv)
175*44554ea0SWill Paznerend
176*44554ea0SWill Pazner
177*44554ea0SWill Pazner"""
178*44554ea0SWill Pazner    create_evector(r::ElemRestriction)
179*44554ea0SWill Pazner
180*44554ea0SWill PaznerReturn a new [`CeedVector`](@ref) E-vector.
181*44554ea0SWill Pazner"""
182*44554ea0SWill Paznerfunction create_evector(r::ElemRestriction)
183*44554ea0SWill Pazner    ref = Ref{C.CeedVector}()
184*44554ea0SWill Pazner    C.CeedElemRestrictionCreateVector(r[], C_NULL, ref)
185*44554ea0SWill Pazner    CeedVector(ref)
186*44554ea0SWill Paznerend
187*44554ea0SWill Pazner
188*44554ea0SWill Pazner"""
189*44554ea0SWill Pazner    create_lvector(r::ElemRestriction)
190*44554ea0SWill Pazner
191*44554ea0SWill PaznerReturn a new [`CeedVector`](@ref) L-vector.
192*44554ea0SWill Pazner"""
193*44554ea0SWill Paznerfunction create_lvector(r::ElemRestriction)
194*44554ea0SWill Pazner    ref = Ref{C.CeedVector}()
195*44554ea0SWill Pazner    C.CeedElemRestrictionCreateVector(r[], ref, C_NULL)
196*44554ea0SWill Pazner    CeedVector(ref)
197*44554ea0SWill Paznerend
198*44554ea0SWill Pazner
199*44554ea0SWill Pazner"""
200*44554ea0SWill Pazner    create_vectors(r::ElemRestriction)
201*44554ea0SWill Pazner
202*44554ea0SWill PaznerReturn an (L-vector, E-vector) pair.
203*44554ea0SWill Pazner"""
204*44554ea0SWill Paznerfunction create_vectors(r::ElemRestriction)
205*44554ea0SWill Pazner    l_ref = Ref{C.CeedVector}()
206*44554ea0SWill Pazner    e_ref = Ref{C.CeedVector}()
207*44554ea0SWill Pazner    C.CeedElemRestrictionCreateVector(r[], l_ref, e_ref)
208*44554ea0SWill Pazner    CeedVector(l_ref), CeedVector(e_ref)
209*44554ea0SWill Paznerend
210*44554ea0SWill Pazner
211*44554ea0SWill Pazner"""
212*44554ea0SWill Pazner    getcompstride(r::ElemRestriction)
213*44554ea0SWill Pazner
214*44554ea0SWill PaznerGet the L-vector component stride.
215*44554ea0SWill Pazner"""
216*44554ea0SWill Paznerfunction getcompstride(r::ElemRestriction)
217*44554ea0SWill Pazner    lsize = Ref{CeedInt}()
218*44554ea0SWill Pazner    C.CeedElemRestrictionGetCompStride(r[], lsize)
219*44554ea0SWill Pazner    lsize[]
220*44554ea0SWill Paznerend
221*44554ea0SWill Pazner
222*44554ea0SWill Pazner"""
223*44554ea0SWill Pazner    getnumelements(r::ElemRestriction)
224*44554ea0SWill Pazner
225*44554ea0SWill PaznerGet the total number of elements in the range of an [`ElemRestriction`](@ref).
226*44554ea0SWill Pazner"""
227*44554ea0SWill Paznerfunction getnumelements(r::ElemRestriction)
228*44554ea0SWill Pazner    result = Ref{CeedInt}()
229*44554ea0SWill Pazner    C.CeedElemRestrictionGetNumElements(r[], result)
230*44554ea0SWill Pazner    result[]
231*44554ea0SWill Paznerend
232*44554ea0SWill Pazner
233*44554ea0SWill Pazner"""
234*44554ea0SWill Pazner    getelementsize(r::ElemRestriction)
235*44554ea0SWill Pazner
236*44554ea0SWill PaznerGet the size of elements in the given [`ElemRestriction`](@ref).
237*44554ea0SWill Pazner"""
238*44554ea0SWill Paznerfunction getelementsize(r::ElemRestriction)
239*44554ea0SWill Pazner    result = Ref{CeedInt}()
240*44554ea0SWill Pazner    C.CeedElemRestrictionGetElementSize(r[], result)
241*44554ea0SWill Pazner    result[]
242*44554ea0SWill Paznerend
243*44554ea0SWill Pazner
244*44554ea0SWill Pazner"""
245*44554ea0SWill Pazner    getlvectorsize(r::ElemRestriction)
246*44554ea0SWill Pazner
247*44554ea0SWill PaznerGet the size of an L-vector for the given [`ElemRestriction`](@ref).
248*44554ea0SWill Pazner"""
249*44554ea0SWill Paznerfunction getlvectorsize(r::ElemRestriction)
250*44554ea0SWill Pazner    result = Ref{CeedInt}()
251*44554ea0SWill Pazner    C.CeedElemRestrictionGetLVectorSize(r[], result)
252*44554ea0SWill Pazner    result[]
253*44554ea0SWill Paznerend
254*44554ea0SWill Pazner
255*44554ea0SWill Pazner"""
256*44554ea0SWill Pazner    getnumcomponents(r::ElemRestriction)
257*44554ea0SWill Pazner
258*44554ea0SWill PaznerGet the number of components in the elements of an [`ElemRestriction`](@ref).
259*44554ea0SWill Pazner"""
260*44554ea0SWill Paznerfunction getnumcomponents(r::ElemRestriction)
261*44554ea0SWill Pazner    result = Ref{CeedInt}()
262*44554ea0SWill Pazner    C.CeedElemRestrictionGetNumComponents(r[], result)
263*44554ea0SWill Pazner    result[]
264*44554ea0SWill Paznerend
265*44554ea0SWill Pazner
266*44554ea0SWill Pazner"""
267*44554ea0SWill Pazner    getmultiplicity!(r::ElemRestriction, v::AbstractCeedVector)
268*44554ea0SWill Pazner
269*44554ea0SWill PaznerGet the multiplicity of nodes in an [`ElemRestriction`](@ref). The [`CeedVector`](@ref) `v`
270*44554ea0SWill Paznershould be an L-vector (i.e. `length(v) == getlvectorsize(r)`, see [`create_lvector`](@ref)).
271*44554ea0SWill Pazner"""
272*44554ea0SWill Paznerfunction getmultiplicity!(r::ElemRestriction, v::AbstractCeedVector)
273*44554ea0SWill Pazner    @assert length(v) == getlvectorsize(r)
274*44554ea0SWill Pazner    C.CeedElemRestrictionGetMultiplicity(r[], v[])
275*44554ea0SWill Paznerend
276*44554ea0SWill Pazner
277*44554ea0SWill Pazner"""
278*44554ea0SWill Pazner    getmultiplicity(r::ElemRestriction)
279*44554ea0SWill Pazner
280*44554ea0SWill PaznerConvenience function to get the multiplicity of nodes in the [`ElemRestriction`](@ref),
281*44554ea0SWill Paznerwhere the result is returned in a newly allocated Julia `Vector{CeedScalar}` (see also
282*44554ea0SWill Pazner[`getmultiplicity!`](@ref)).
283*44554ea0SWill Pazner"""
284*44554ea0SWill Paznerfunction getmultiplicity(r::ElemRestriction)
285*44554ea0SWill Pazner    v = create_lvector(r)
286*44554ea0SWill Pazner    getmultiplicity!(r, v)
287*44554ea0SWill Pazner    Vector(v)
288*44554ea0SWill Paznerend
289