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_oriented( 99 ceed::Ceed, 100 nelem, 101 elemsize, 102 ncomp, 103 compstride, 104 lsize, 105 offsets::AbstractArray{CeedInt}, 106 orients::AbstractArray{Bool}, 107 mtype::MemType=MEM_HOST, 108 cmode::CopyMode=COPY_VALUES, 109 ) 110 111Create an oriented `CeedElemRestriction`. 112 113!!! warning "Zero-based indexing" 114 In the below notation, we are using **0-based indexing**. libCEED expects the offset 115 indices to be 0-based. 116 117# Arguments: 118- `ceed`: The [`Ceed`](@ref) object 119- `nelem`: Number of elements described in the `offsets` array 120- `elemsize`: Size (number of "nodes") per element 121- `ncomp`: Number of field components per interpolation node (1 for scalar fields) 122- `compstride`: Stride between components for the same L-vector "node". Data for node $i$, 123 component $j$, element $k$ can be found in the L-vector at index `offsets[i 124 + k*elemsize] + j*compstride`. 125- `lsize`: The size of the L-vector. This vector may be larger than the elements and 126 fields given by this restriction. 127- `offsets`: Array of shape `(elemsize, nelem)`. Column $i$ holds the ordered list of the 128 offsets (into the input [`CeedVector`](@ref)) for the unknowns corresponding 129 to element $i$, where $0 \leq i < \textit{nelem}$. All offsets must be in 130 the range $[0, \textit{lsize} - 1]$. 131- `orients`: Array of shape `(elemsize, nelem)` with bool false for positively oriented 132 and true to flip the orientation. 133- `mtype`: Memory type of the `offsets` array, see [`MemType`](@ref) 134- `cmode`: Copy mode for the `offsets` array, see [`CopyMode`](@ref) 135""" 136function create_elem_restriction_oriented( 137 c::Ceed, 138 nelem, 139 elemsize, 140 ncomp, 141 compstride, 142 lsize, 143 offsets::AbstractArray{CeedInt}, 144 orients::AbstractArray{Bool}; 145 mtype::MemType=MEM_HOST, 146 cmode::CopyMode=COPY_VALUES, 147) 148 ref = Ref{C.CeedElemRestriction}() 149 C.CeedElemRestrictionCreateOriented( 150 c[], 151 nelem, 152 elemsize, 153 ncomp, 154 compstride, 155 lsize, 156 mtype, 157 cmode, 158 offsets, 159 orients, 160 ref, 161 ) 162 ElemRestriction(ref) 163end 164 165@doc raw""" 166 create_elem_restriction_curl_oriented( 167 ceed::Ceed, 168 nelem, 169 elemsize, 170 ncomp, 171 compstride, 172 lsize, 173 offsets::AbstractArray{CeedInt}, 174 curlorients::AbstractArray{CeedInt}, 175 mtype::MemType=MEM_HOST, 176 cmode::CopyMode=COPY_VALUES, 177 ) 178 179Create an curl-oriented `CeedElemRestriction`. 180 181!!! warning "Zero-based indexing" 182 In the below notation, we are using **0-based indexing**. libCEED expects the offset 183 indices to be 0-based. 184 185# Arguments: 186- `ceed`: The [`Ceed`](@ref) object 187- `nelem`: Number of elements described in the `offsets` array 188- `elemsize`: Size (number of "nodes") per element 189- `ncomp`: Number of field components per interpolation node (1 for scalar fields) 190- `compstride`: Stride between components for the same L-vector "node". Data for node $i$, 191 component $j$, element $k$ can be found in the L-vector at index `offsets[i 192 + k*elemsize] + j*compstride`. 193- `lsize`: The size of the L-vector. This vector may be larger than the elements and 194 fields given by this restriction. 195- `offsets`: Array of shape `(elemsize, nelem)`. Column $i$ holds the ordered list of 196 the offsets (into the input [`CeedVector`](@ref)) for the unknowns 197 corresponding to element $i$, where $0 \leq i < \textit{nelem}$. All 198 offsets must be in the range $[0, \textit{lsize} - 1]$. 199- `curlorients`: Array of shape `(3 * elemsize, nelem)` representing a row-major tridiagonal 200 matrix (`curlorients[0, i] = curlorients[3 * elemsize - 1, i] = 0`, where 201 $0 \leq i < \textit{nelem}$) which is applied to the element unknowns upon 202 restriction. 203- `mtype`: Memory type of the `offsets` array, see [`MemType`](@ref) 204- `cmode`: Copy mode for the `offsets` array, see [`CopyMode`](@ref) 205""" 206function create_elem_restriction_curl_oriented( 207 c::Ceed, 208 nelem, 209 elemsize, 210 ncomp, 211 compstride, 212 lsize, 213 offsets::AbstractArray{CeedInt}, 214 curlorients::AbstractArray{CeedInt8}; 215 mtype::MemType=MEM_HOST, 216 cmode::CopyMode=COPY_VALUES, 217) 218 ref = Ref{C.CeedElemRestriction}() 219 C.CeedElemRestrictionCreateCurlOriented( 220 c[], 221 nelem, 222 elemsize, 223 ncomp, 224 compstride, 225 lsize, 226 mtype, 227 cmode, 228 offsets, 229 curlorients, 230 ref, 231 ) 232 ElemRestriction(ref) 233end 234 235@doc raw""" 236 create_elem_restriction_strided(ceed::Ceed, nelem, elemsize, ncomp, lsize, strides) 237 238Create a strided `CeedElemRestriction`. 239 240!!! warning "Zero-based indexing" 241 In the below notation, we are using **0-based indexing**. libCEED expects the offset 242 indices to be 0-based. 243 244# Arguments: 245- `ceed`: The [`Ceed`](@ref) object 246- `nelem`: Number of elements described by the restriction 247- `elemsize`: Size (number of "nodes") per element 248- `ncomp`: Number of field components per interpolation node (1 for scalar fields) 249- `lsize`: The size of the L-vector. This vector may be larger than the elements and 250 fields given by this restriction. 251- `strides`: Array for strides between [nodes, components, elements]. Data for node $i$, 252 component $j$, element $k$ can be found in the L-vector at index `i*strides[0] 253 + j*strides[1] + k*strides[2]`. [`STRIDES_BACKEND`](@ref) may be used with 254 vectors created by a Ceed backend. 255""" 256function create_elem_restriction_strided(c::Ceed, nelem, elemsize, ncomp, lsize, strides) 257 ref = Ref{C.CeedElemRestriction}() 258 C.CeedElemRestrictionCreateStrided(c[], nelem, elemsize, ncomp, lsize, strides, ref) 259 ElemRestriction(ref) 260end 261 262""" 263 apply!( 264 r::ElemRestriction, 265 u::CeedVector, 266 ru::CeedVector; 267 tmode=NOTRANSPOSE, 268 request=RequestImmediate(), 269 ) 270 271Use the [`ElemRestriction`](@ref) to convert from L-vector to an E-vector (or apply the 272tranpose operation). The input [`CeedVector`](@ref) is `u` and the result stored in `ru`. 273 274If `tmode` is `TRANSPOSE`, then the result is added to `ru`. If `tmode` is `NOTRANSPOSE`, 275then `ru` is overwritten with the result. 276""" 277function apply!( 278 r::ElemRestriction, 279 u::CeedVector, 280 ru::CeedVector; 281 tmode=NOTRANSPOSE, 282 request=RequestImmediate(), 283) 284 C.CeedElemRestrictionApply(r[], tmode, u[], ru[], request[]) 285end 286 287""" 288 apply(r::ElemRestriction, u::AbstractVector; tmode=NOTRANSPOSE) 289 290Use the [`ElemRestriction`](@ref) to convert from L-vector to an E-vector (or apply the 291tranpose operation). The input is given by `u`, and the result is returned as an array of 292type `Vector{CeedScalar}`. 293""" 294function apply(r::ElemRestriction, u::AbstractVector; tmode=NOTRANSPOSE) 295 ceed_ref = Ref{C.Ceed}() 296 ccall( 297 (:CeedElemRestrictionGetCeed, C.libceed), 298 Cint, 299 (C.CeedElemRestriction, Ptr{C.Ceed}), 300 r[], 301 ceed_ref, 302 ) 303 c = Ceed(ceed_ref) 304 uv = CeedVector(c, u) 305 if tmode == NOTRANSPOSE 306 ruv = create_evector(r) 307 else 308 ruv = create_lvector(r) 309 end 310 ruv[] = 0.0 311 apply!(r, uv, ruv; tmode=tmode) 312 Vector(ruv) 313end 314 315""" 316 create_evector(r::ElemRestriction) 317 318Return a new [`CeedVector`](@ref) E-vector. 319""" 320function create_evector(r::ElemRestriction) 321 ref = Ref{C.CeedVector}() 322 C.CeedElemRestrictionCreateVector(r[], C_NULL, ref) 323 CeedVector(ref) 324end 325 326""" 327 create_lvector(r::ElemRestriction) 328 329Return a new [`CeedVector`](@ref) L-vector. 330""" 331function create_lvector(r::ElemRestriction) 332 ref = Ref{C.CeedVector}() 333 C.CeedElemRestrictionCreateVector(r[], ref, C_NULL) 334 CeedVector(ref) 335end 336 337""" 338 create_vectors(r::ElemRestriction) 339 340Return an (L-vector, E-vector) pair. 341""" 342function create_vectors(r::ElemRestriction) 343 l_ref = Ref{C.CeedVector}() 344 e_ref = Ref{C.CeedVector}() 345 C.CeedElemRestrictionCreateVector(r[], l_ref, e_ref) 346 CeedVector(l_ref), CeedVector(e_ref) 347end 348 349""" 350 getcompstride(r::ElemRestriction) 351 352Get the L-vector component stride. 353""" 354function getcompstride(r::ElemRestriction) 355 lsize = Ref{CeedInt}() 356 C.CeedElemRestrictionGetCompStride(r[], lsize) 357 lsize[] 358end 359 360""" 361 getnumelements(r::ElemRestriction) 362 363Get the total number of elements in the range of an [`ElemRestriction`](@ref). 364""" 365function getnumelements(r::ElemRestriction) 366 result = Ref{CeedInt}() 367 C.CeedElemRestrictionGetNumElements(r[], result) 368 result[] 369end 370 371""" 372 getelementsize(r::ElemRestriction) 373 374Get the size of elements in the given [`ElemRestriction`](@ref). 375""" 376function getelementsize(r::ElemRestriction) 377 result = Ref{CeedInt}() 378 C.CeedElemRestrictionGetElementSize(r[], result) 379 result[] 380end 381 382""" 383 getlvectorsize(r::ElemRestriction) 384 385Get the size of an L-vector for the given [`ElemRestriction`](@ref). 386""" 387function getlvectorsize(r::ElemRestriction) 388 result = Ref{CeedSize}() 389 C.CeedElemRestrictionGetLVectorSize(r[], result) 390 result[] 391end 392 393""" 394 getnumcomponents(r::ElemRestriction) 395 396Get the number of components in the elements of an [`ElemRestriction`](@ref). 397""" 398function getnumcomponents(r::ElemRestriction) 399 result = Ref{CeedInt}() 400 C.CeedElemRestrictionGetNumComponents(r[], result) 401 result[] 402end 403 404""" 405 getmultiplicity!(r::ElemRestriction, v::AbstractCeedVector) 406 407Get the multiplicity of nodes in an [`ElemRestriction`](@ref). The [`CeedVector`](@ref) `v` 408should be an L-vector (i.e. `length(v) == getlvectorsize(r)`, see [`create_lvector`](@ref)). 409""" 410function getmultiplicity!(r::ElemRestriction, v::AbstractCeedVector) 411 @assert length(v) == getlvectorsize(r) 412 C.CeedElemRestrictionGetMultiplicity(r[], v[]) 413end 414 415""" 416 getmultiplicity(r::ElemRestriction) 417 418Convenience function to get the multiplicity of nodes in the [`ElemRestriction`](@ref), 419where the result is returned in a newly allocated Julia `Vector{CeedScalar}` (see also 420[`getmultiplicity!`](@ref)). 421""" 422function getmultiplicity(r::ElemRestriction) 423 v = create_lvector(r) 424 getmultiplicity!(r, v) 425 Vector(v) 426end 427