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