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