diff --git a/interface/ceed-fortran.c b/interface/ceed-fortran.c index f1062ffe89..beb3e73c95 100644 --- a/interface/ceed-fortran.c +++ b/interface/ceed-fortran.c @@ -239,6 +239,49 @@ CEED_EXTERN void fCeedElemRestrictionCreate(int *ceed, int *nelements, int *esiz } } +#define fCeedElemRestrictionCreateOriented FORTRAN_NAME(ceedelemrestrictioncreateoriented, CEEDELEMRESTRICTIONCREATEORIENTED) +CEED_EXTERN void fCeedElemRestrictionCreateOriented(int *ceed, int *nelements, int *esize, int *num_comp, int *comp_stride, int *lsize, int *memtype, + int *copymode, const int *offsets, const bool *orients, int *elemrestriction, int *err) { + if (CeedElemRestriction_count == CeedElemRestriction_count_max) { + CeedElemRestriction_count_max += CeedElemRestriction_count_max / 2 + 1; + CeedRealloc(CeedElemRestriction_count_max, &CeedElemRestriction_dict); + } + + const int *offsets_ = offsets; + const bool *orients_ = orients; + + CeedElemRestriction *elemrestriction_ = &CeedElemRestriction_dict[CeedElemRestriction_count]; + *err = CeedElemRestrictionCreateOriented(Ceed_dict[*ceed], *nelements, *esize, *num_comp, *comp_stride, *lsize, (CeedMemType)*memtype, + (CeedCopyMode)*copymode, offsets_, orients_, elemrestriction_); + + if (*err == 0) { + *elemrestriction = CeedElemRestriction_count++; + CeedElemRestriction_n++; + } +} + +#define fCeedElemRestrictionCreateCurlOriented FORTRAN_NAME(ceedelemrestrictioncreatecurloriented, CEEDELEMRESTRICTIONCREATECURLORIENTED) +CEED_EXTERN void fCeedElemRestrictionCreateCurlOriented(int *ceed, int *nelements, int *esize, int *num_comp, int *comp_stride, int *lsize, + int *memtype, int *copymode, const int *offsets, const int *curlorients, int *elemrestriction, + int *err) { + if (CeedElemRestriction_count == CeedElemRestriction_count_max) { + CeedElemRestriction_count_max += CeedElemRestriction_count_max / 2 + 1; + CeedRealloc(CeedElemRestriction_count_max, &CeedElemRestriction_dict); + } + + const int *offsets_ = offsets; + const int *curlorients_ = curlorients; + + CeedElemRestriction *elemrestriction_ = &CeedElemRestriction_dict[CeedElemRestriction_count]; + *err = CeedElemRestrictionCreateCurlOriented(Ceed_dict[*ceed], *nelements, *esize, *num_comp, *comp_stride, *lsize, (CeedMemType)*memtype, + (CeedCopyMode)*copymode, offsets_, curlorients_, elemrestriction_); + + if (*err == 0) { + *elemrestriction = CeedElemRestriction_count++; + CeedElemRestriction_n++; + } +} + #define fCeedElemRestrictionCreateStrided FORTRAN_NAME(ceedelemrestrictioncreatestrided, CEEDELEMRESTRICTIONCREATESTRIDED) CEED_EXTERN void fCeedElemRestrictionCreateStrided(int *ceed, int *nelements, int *esize, int *num_comp, int *lsize, int *strides, int *elemrestriction, int *err) { @@ -258,15 +301,62 @@ CEED_EXTERN void fCeedElemRestrictionCreateStrided(int *ceed, int *nelements, in #define fCeedElemRestrictionCreateBlocked FORTRAN_NAME(ceedelemrestrictioncreateblocked, CEEDELEMRESTRICTIONCREATEBLOCKED) CEED_EXTERN void fCeedElemRestrictionCreateBlocked(int *ceed, int *nelements, int *esize, int *blocksize, int *num_comp, int *comp_stride, int *lsize, - int *mtype, int *cmode, int *blkindices, int *elemrestriction, int *err) { + int *memtype, int *copymode, const int *offsets, int *elemrestriction, int *err) { + if (CeedElemRestriction_count == CeedElemRestriction_count_max) { + CeedElemRestriction_count_max += CeedElemRestriction_count_max / 2 + 1; + CeedRealloc(CeedElemRestriction_count_max, &CeedElemRestriction_dict); + } + + const int *offsets_ = offsets; + + CeedElemRestriction *elemrestriction_ = &CeedElemRestriction_dict[CeedElemRestriction_count]; + *err = CeedElemRestrictionCreateBlocked(Ceed_dict[*ceed], *nelements, *esize, *blocksize, *num_comp, *comp_stride, *lsize, (CeedMemType)*memtype, + (CeedCopyMode)*copymode, offsets_, elemrestriction_); + + if (*err == 0) { + *elemrestriction = CeedElemRestriction_count++; + CeedElemRestriction_n++; + } +} + +#define fCeedElemRestrictionCreateBlockedOriented FORTRAN_NAME(ceedelemrestrictioncreateblockedoriented, CEEDELEMRESTRICTIONCREATEBLOCKEDORIENTED) +CEED_EXTERN void fCeedElemRestrictionCreateBlockedOriented(int *ceed, int *nelements, int *esize, int *blocksize, int *num_comp, int *comp_stride, + int *lsize, int *memtype, int *copymode, const int *offsets, const bool *orients, + int *elemrestriction, int *err) { if (CeedElemRestriction_count == CeedElemRestriction_count_max) { CeedElemRestriction_count_max += CeedElemRestriction_count_max / 2 + 1; CeedRealloc(CeedElemRestriction_count_max, &CeedElemRestriction_dict); } + const int *offsets_ = offsets; + const bool *orients_ = orients; + + CeedElemRestriction *elemrestriction_ = &CeedElemRestriction_dict[CeedElemRestriction_count]; + *err = CeedElemRestrictionCreateBlockedOriented(Ceed_dict[*ceed], *nelements, *esize, *blocksize, *num_comp, *comp_stride, *lsize, + (CeedMemType)*memtype, (CeedCopyMode)*copymode, offsets_, orients_, elemrestriction_); + + if (*err == 0) { + *elemrestriction = CeedElemRestriction_count++; + CeedElemRestriction_n++; + } +} + +#define fCeedElemRestrictionCreateBlockedCurlOriented \ + FORTRAN_NAME(ceedelemrestrictioncreateblockedcurloriented, CEEDELEMRESTRICTIONCREATEBLOCKEDCURLORIENTED) +CEED_EXTERN void fCeedElemRestrictionCreateBlockedCurlOriented(int *ceed, int *nelements, int *esize, int *blocksize, int *num_comp, int *comp_stride, + int *lsize, int *memtype, int *copymode, const int *offsets, const int *curlorients, + int *elemrestriction, int *err) { + if (CeedElemRestriction_count == CeedElemRestriction_count_max) { + CeedElemRestriction_count_max += CeedElemRestriction_count_max / 2 + 1; + CeedRealloc(CeedElemRestriction_count_max, &CeedElemRestriction_dict); + } + + const int *offsets_ = offsets; + const int *curlorients_ = curlorients; + CeedElemRestriction *elemrestriction_ = &CeedElemRestriction_dict[CeedElemRestriction_count]; - *err = CeedElemRestrictionCreateBlocked(Ceed_dict[*ceed], *nelements, *esize, *blocksize, *num_comp, *comp_stride, *lsize, (CeedMemType)*mtype, - (CeedCopyMode)*cmode, blkindices, elemrestriction_); + *err = CeedElemRestrictionCreateBlockedCurlOriented(Ceed_dict[*ceed], *nelements, *esize, *blocksize, *num_comp, *comp_stride, *lsize, + (CeedMemType)*memtype, (CeedCopyMode)*copymode, offsets_, curlorients_, elemrestriction_); if (*err == 0) { *elemrestriction = CeedElemRestriction_count++; diff --git a/julia/LibCEED.jl/src/ElemRestriction.jl b/julia/LibCEED.jl/src/ElemRestriction.jl index c0ea88aba3..7c3b586125 100644 --- a/julia/LibCEED.jl/src/ElemRestriction.jl +++ b/julia/LibCEED.jl/src/ElemRestriction.jl @@ -94,6 +94,144 @@ function create_elem_restriction( ElemRestriction(ref) end +@doc raw""" + create_elem_restriction_oriented( + ceed::Ceed, + nelem, + elemsize, + ncomp, + compstride, + lsize, + offsets::AbstractArray{CeedInt}, + orients::AbstractArray{Bool}, + mtype::MemType=MEM_HOST, + cmode::CopyMode=COPY_VALUES, + ) + +Create an oriented `CeedElemRestriction`. + +!!! warning "Zero-based indexing" + In the below notation, we are using **0-based indexing**. libCEED expects the offset + indices to be 0-based. + +# Arguments: +- `ceed`: The [`Ceed`](@ref) object +- `nelem`: Number of elements described in the `offsets` array +- `elemsize`: Size (number of "nodes") per element +- `ncomp`: Number of field components per interpolation node (1 for scalar fields) +- `compstride`: Stride between components for the same L-vector "node". Data for node $i$, + component $j$, element $k$ can be found in the L-vector at index `offsets[i + + k*elemsize] + j*compstride`. +- `lsize`: The size of the L-vector. This vector may be larger than the elements and + fields given by this restriction. +- `offsets`: Array of shape `(elemsize, nelem)`. Column $i$ holds the ordered list of the + offsets (into the input [`CeedVector`](@ref)) for the unknowns corresponding + to element $i$, where $0 \leq i < \textit{nelem}$. All offsets must be in + the range $[0, \textit{lsize} - 1]$. +- `orients`: Array of shape `(elemsize, nelem)` with bool false for positively oriented + and true to flip the orientation. +- `mtype`: Memory type of the `offsets` array, see [`MemType`](@ref) +- `cmode`: Copy mode for the `offsets` array, see [`CopyMode`](@ref) +""" +function create_elem_restriction( + c::Ceed, + nelem, + elemsize, + ncomp, + compstride, + lsize, + offsets::AbstractArray{CeedInt}, + orients::AbstractArray{Bool}; + mtype::MemType=MEM_HOST, + cmode::CopyMode=COPY_VALUES, +) + ref = Ref{C.CeedElemRestriction}() + C.CeedElemRestrictionCreateOriented( + c[], + nelem, + elemsize, + ncomp, + compstride, + lsize, + mtype, + cmode, + offsets, + orients, + ref, + ) + ElemRestriction(ref) +end + +@doc raw""" + create_elem_restriction_curl_oriented( + ceed::Ceed, + nelem, + elemsize, + ncomp, + compstride, + lsize, + offsets::AbstractArray{CeedInt}, + curl_orients::AbstractArray{CeedInt}, + mtype::MemType=MEM_HOST, + cmode::CopyMode=COPY_VALUES, + ) + +Create an curl-oriented `CeedElemRestriction`. + +!!! warning "Zero-based indexing" + In the below notation, we are using **0-based indexing**. libCEED expects the offset + indices to be 0-based. + +# Arguments: +- `ceed`: The [`Ceed`](@ref) object +- `nelem`: Number of elements described in the `offsets` array +- `elemsize`: Size (number of "nodes") per element +- `ncomp`: Number of field components per interpolation node (1 for scalar fields) +- `compstride`: Stride between components for the same L-vector "node". Data for node $i$, + component $j$, element $k$ can be found in the L-vector at index `offsets[i + + k*elemsize] + j*compstride`. +- `lsize`: The size of the L-vector. This vector may be larger than the elements and + fields given by this restriction. +- `offsets`: Array of shape `(elemsize, nelem)`. Column $i$ holds the ordered list of + the offsets (into the input [`CeedVector`](@ref)) for the unknowns + corresponding to element $i$, where $0 \leq i < \textit{nelem}$. All + offsets must be in the range $[0, \textit{lsize} - 1]$. +- `curlorients`: Array of shape `(3 * elemsize, nelem)` representing a row-major tridiagonal + matrix (`curlorients[0] = curlorients[(i + 1) * 3 * elemsize - 1] = 0`, + where `0 <= i < nelem`) which is applied to the element unknowns upon + restriction. +- `mtype`: Memory type of the `offsets` array, see [`MemType`](@ref) +- `cmode`: Copy mode for the `offsets` array, see [`CopyMode`](@ref) +""" +function create_elem_restriction( + c::Ceed, + nelem, + elemsize, + ncomp, + compstride, + lsize, + offsets::AbstractArray{CeedInt}, + curlorients::AbstractArray{CeedInt}; + mtype::MemType=MEM_HOST, + cmode::CopyMode=COPY_VALUES, +) + ref = Ref{C.CeedElemRestriction}() + C.CeedElemRestrictionCreateCurlOriented( + c[], + nelem, + elemsize, + ncomp, + compstride, + lsize, + mtype, + cmode, + offsets, + curlorients, + ref, + ) + ElemRestriction(ref) +end + @doc raw""" create_elem_restriction_strided(ceed::Ceed, nelem, elemsize, ncomp, lsize, strides) diff --git a/julia/LibCEED.jl/src/generated/libceed_bindings.jl b/julia/LibCEED.jl/src/generated/libceed_bindings.jl index 7e954c2d40..7ad12719f3 100644 --- a/julia/LibCEED.jl/src/generated/libceed_bindings.jl +++ b/julia/LibCEED.jl/src/generated/libceed_bindings.jl @@ -152,6 +152,10 @@ function CeedVectorReferenceCopy(vec, vec_copy) ccall((:CeedVectorReferenceCopy, libceed), Cint, (CeedVector, Ptr{CeedVector}), vec, vec_copy) end +function CeedVectorCopy(vec, vec_copy) + ccall((:CeedVectorCopy, libceed), Cint, (CeedVector, CeedVector), vec, vec_copy) +end + function CeedVectorSetArray(vec, mem_type, copy_mode, array) ccall((:CeedVectorSetArray, libceed), Cint, (CeedVector, CeedMemType, CeedCopyMode, Ptr{CeedScalar}), vec, mem_type, copy_mode, array) end @@ -200,6 +204,10 @@ function CeedVectorAXPY(y, alpha, x) ccall((:CeedVectorAXPY, libceed), Cint, (CeedVector, CeedScalar, CeedVector), y, alpha, x) end +function CeedVectorAXPBY(y, alpha, beta, x) + ccall((:CeedVectorAXPBY, libceed), Cint, (CeedVector, CeedScalar, CeedScalar, CeedVector), y, alpha, beta, x) +end + function CeedVectorPointwiseMult(w, x, y) ccall((:CeedVectorPointwiseMult, libceed), Cint, (CeedVector, CeedVector, CeedVector), w, x, y) end @@ -208,6 +216,10 @@ function CeedVectorReciprocal(vec) ccall((:CeedVectorReciprocal, libceed), Cint, (CeedVector,), vec) end +function CeedVectorViewRange(vec, start, stop, step, fp_fmt, stream) + ccall((:CeedVectorViewRange, libceed), Cint, (CeedVector, CeedSize, CeedSize, CeedInt, Ptr{Cchar}, Ptr{Libc.FILE}), vec, start, stop, step, fp_fmt, stream) +end + function CeedVectorView(vec, fp_fmt, stream) ccall((:CeedVectorView, libceed), Cint, (CeedVector, Ptr{Cchar}, Ptr{Libc.FILE}), vec, fp_fmt, stream) end @@ -237,8 +249,12 @@ function CeedElemRestrictionCreate(ceed, num_elem, elem_size, num_comp, comp_str ccall((:CeedElemRestrictionCreate, libceed), Cint, (Ceed, CeedInt, CeedInt, CeedInt, CeedInt, CeedSize, CeedMemType, CeedCopyMode, Ptr{CeedInt}, Ptr{CeedElemRestriction}), ceed, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr) end -function CeedElemRestrictionCreateOriented(ceed, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orient, rstr) - ccall((:CeedElemRestrictionCreateOriented, libceed), Cint, (Ceed, CeedInt, CeedInt, CeedInt, CeedInt, CeedSize, CeedMemType, CeedCopyMode, Ptr{CeedInt}, Ptr{Bool}, Ptr{CeedElemRestriction}), ceed, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orient, rstr) +function CeedElemRestrictionCreateOriented(ceed, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients, rstr) + ccall((:CeedElemRestrictionCreateOriented, libceed), Cint, (Ceed, CeedInt, CeedInt, CeedInt, CeedInt, CeedSize, CeedMemType, CeedCopyMode, Ptr{CeedInt}, Ptr{Bool}, Ptr{CeedElemRestriction}), ceed, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients, rstr) +end + +function CeedElemRestrictionCreateCurlOriented(ceed, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, curl_orients, rstr) + ccall((:CeedElemRestrictionCreateCurlOriented, libceed), Cint, (Ceed, CeedInt, CeedInt, CeedInt, CeedInt, CeedSize, CeedMemType, CeedCopyMode, Ptr{CeedInt}, Ptr{CeedInt}, Ptr{CeedElemRestriction}), ceed, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, curl_orients, rstr) end function CeedElemRestrictionCreateStrided(ceed, num_elem, elem_size, num_comp, l_size, strides, rstr) @@ -249,6 +265,14 @@ function CeedElemRestrictionCreateBlocked(ceed, num_elem, elem_size, blk_size, n ccall((:CeedElemRestrictionCreateBlocked, libceed), Cint, (Ceed, CeedInt, CeedInt, CeedInt, CeedInt, CeedInt, CeedSize, CeedMemType, CeedCopyMode, Ptr{CeedInt}, Ptr{CeedElemRestriction}), ceed, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr) end +function CeedElemRestrictionCreateBlockedOriented(ceed, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients, rstr) + ccall((:CeedElemRestrictionCreateBlockedOriented, libceed), Cint, (Ceed, CeedInt, CeedInt, CeedInt, CeedInt, CeedInt, CeedSize, CeedMemType, CeedCopyMode, Ptr{CeedInt}, Ptr{Bool}, Ptr{CeedElemRestriction}), ceed, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients, rstr) +end + +function CeedElemRestrictionCreateBlockedCurlOriented(ceed, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, curl_orients, rstr) + ccall((:CeedElemRestrictionCreateBlockedCurlOriented, libceed), Cint, (Ceed, CeedInt, CeedInt, CeedInt, CeedInt, CeedInt, CeedSize, CeedMemType, CeedCopyMode, Ptr{CeedInt}, Ptr{CeedInt}, Ptr{CeedElemRestriction}), ceed, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, curl_orients, rstr) +end + function CeedElemRestrictionCreateBlockedStrided(ceed, num_elem, elem_size, blk_size, num_comp, l_size, strides, rstr) ccall((:CeedElemRestrictionCreateBlockedStrided, libceed), Cint, (Ceed, CeedInt, CeedInt, CeedInt, CeedInt, CeedSize, Ptr{CeedInt}, Ptr{CeedElemRestriction}), ceed, num_elem, elem_size, blk_size, num_comp, l_size, strides, rstr) end @@ -716,32 +740,36 @@ function CeedOperatorGetFlopsEstimate(op, flops) ccall((:CeedOperatorGetFlopsEstimate, libceed), Cint, (CeedOperator, Ptr{CeedSize}), op, flops) end -function CeedOperatorContextGetFieldLabel(op, field_name, field_label) - ccall((:CeedOperatorContextGetFieldLabel, libceed), Cint, (CeedOperator, Ptr{Cchar}, Ptr{CeedContextFieldLabel}), op, field_name, field_label) +function CeedOperatorGetContext(op, ctx) + ccall((:CeedOperatorGetContext, libceed), Cint, (CeedOperator, Ptr{CeedQFunctionContext}), op, ctx) +end + +function CeedOperatorGetContextFieldLabel(op, field_name, field_label) + ccall((:CeedOperatorGetContextFieldLabel, libceed), Cint, (CeedOperator, Ptr{Cchar}, Ptr{CeedContextFieldLabel}), op, field_name, field_label) end -function CeedOperatorContextSetDouble(op, field_label, values) - ccall((:CeedOperatorContextSetDouble, libceed), Cint, (CeedOperator, CeedContextFieldLabel, Ptr{Cdouble}), op, field_label, values) +function CeedOperatorSetContextDouble(op, field_label, values) + ccall((:CeedOperatorSetContextDouble, libceed), Cint, (CeedOperator, CeedContextFieldLabel, Ptr{Cdouble}), op, field_label, values) end -function CeedOperatorContextGetDoubleRead(op, field_label, num_values, values) - ccall((:CeedOperatorContextGetDoubleRead, libceed), Cint, (CeedOperator, CeedContextFieldLabel, Ptr{Csize_t}, Ptr{Ptr{Cdouble}}), op, field_label, num_values, values) +function CeedOperatorGetContextDoubleRead(op, field_label, num_values, values) + ccall((:CeedOperatorGetContextDoubleRead, libceed), Cint, (CeedOperator, CeedContextFieldLabel, Ptr{Csize_t}, Ptr{Ptr{Cdouble}}), op, field_label, num_values, values) end -function CeedOperatorContextRestoreDoubleRead(op, field_label, values) - ccall((:CeedOperatorContextRestoreDoubleRead, libceed), Cint, (CeedOperator, CeedContextFieldLabel, Ptr{Ptr{Cdouble}}), op, field_label, values) +function CeedOperatorRestoreContextDoubleRead(op, field_label, values) + ccall((:CeedOperatorRestoreContextDoubleRead, libceed), Cint, (CeedOperator, CeedContextFieldLabel, Ptr{Ptr{Cdouble}}), op, field_label, values) end -function CeedOperatorContextSetInt32(op, field_label, values) - ccall((:CeedOperatorContextSetInt32, libceed), Cint, (CeedOperator, CeedContextFieldLabel, Ptr{Cint}), op, field_label, values) +function CeedOperatorSetContextInt32(op, field_label, values) + ccall((:CeedOperatorSetContextInt32, libceed), Cint, (CeedOperator, CeedContextFieldLabel, Ptr{Cint}), op, field_label, values) end -function CeedOperatorContextGetInt32Read(op, field_label, num_values, values) - ccall((:CeedOperatorContextGetInt32Read, libceed), Cint, (CeedOperator, CeedContextFieldLabel, Ptr{Csize_t}, Ptr{Ptr{Cint}}), op, field_label, num_values, values) +function CeedOperatorGetContextInt32Read(op, field_label, num_values, values) + ccall((:CeedOperatorGetContextInt32Read, libceed), Cint, (CeedOperator, CeedContextFieldLabel, Ptr{Csize_t}, Ptr{Ptr{Cint}}), op, field_label, num_values, values) end -function CeedOperatorContextRestoreInt32Read(op, field_label, values) - ccall((:CeedOperatorContextRestoreInt32Read, libceed), Cint, (CeedOperator, CeedContextFieldLabel, Ptr{Ptr{Cint}}), op, field_label, values) +function CeedOperatorRestoreContextInt32Read(op, field_label, values) + ccall((:CeedOperatorRestoreContextInt32Read, libceed), Cint, (CeedOperator, CeedContextFieldLabel, Ptr{Ptr{Cint}}), op, field_label, values) end function CeedOperatorApply(op, in, out, request) @@ -936,10 +964,18 @@ function CeedVectorReference(vec) ccall((:CeedVectorReference, libceed), Cint, (CeedVector,), vec) end +function CeedElemRestrictionIsStrided(rstr, is_strided) + ccall((:CeedElemRestrictionIsStrided, libceed), Cint, (CeedElemRestriction, Ptr{Bool}), rstr, is_strided) +end + function CeedElemRestrictionGetStrides(rstr, strides) ccall((:CeedElemRestrictionGetStrides, libceed), Cint, (CeedElemRestriction, Ptr{NTuple{3, CeedInt}}), rstr, strides) end +function CeedElemRestrictionHasBackendStrides(rstr, has_backend_strides) + ccall((:CeedElemRestrictionHasBackendStrides, libceed), Cint, (CeedElemRestriction, Ptr{Bool}), rstr, has_backend_strides) +end + function CeedElemRestrictionGetOffsets(rstr, mem_type, offsets) ccall((:CeedElemRestrictionGetOffsets, libceed), Cint, (CeedElemRestriction, CeedMemType, Ptr{Ptr{CeedInt}}), rstr, mem_type, offsets) end @@ -948,16 +984,20 @@ function CeedElemRestrictionRestoreOffsets(rstr, offsets) ccall((:CeedElemRestrictionRestoreOffsets, libceed), Cint, (CeedElemRestriction, Ptr{Ptr{CeedInt}}), rstr, offsets) end -function CeedElemRestrictionIsStrided(rstr, is_strided) - ccall((:CeedElemRestrictionIsStrided, libceed), Cint, (CeedElemRestriction, Ptr{Bool}), rstr, is_strided) +function CeedElemRestrictionGetOrientations(rstr, mem_type, orients) + ccall((:CeedElemRestrictionGetOrientations, libceed), Cint, (CeedElemRestriction, CeedMemType, Ptr{Ptr{Bool}}), rstr, mem_type, orients) end -function CeedElemRestrictionIsOriented(rstr, is_oriented) - ccall((:CeedElemRestrictionIsOriented, libceed), Cint, (CeedElemRestriction, Ptr{Bool}), rstr, is_oriented) +function CeedElemRestrictionRestoreOrientations(rstr, orients) + ccall((:CeedElemRestrictionRestoreOrientations, libceed), Cint, (CeedElemRestriction, Ptr{Ptr{Bool}}), rstr, orients) end -function CeedElemRestrictionHasBackendStrides(rstr, has_backend_strides) - ccall((:CeedElemRestrictionHasBackendStrides, libceed), Cint, (CeedElemRestriction, Ptr{Bool}), rstr, has_backend_strides) +function CeedElemRestrictionGetCurlOrientations(rstr, mem_type, curl_orients) + ccall((:CeedElemRestrictionGetCurlOrientations, libceed), Cint, (CeedElemRestriction, CeedMemType, Ptr{Ptr{CeedInt}}), rstr, mem_type, curl_orients) +end + +function CeedElemRestrictionRestoreCurlOrientations(rstr, curl_orients) + ccall((:CeedElemRestrictionRestoreCurlOrientations, libceed), Cint, (CeedElemRestriction, Ptr{Ptr{CeedInt}}), rstr, curl_orients) end function CeedElemRestrictionGetELayout(rstr, layout) diff --git a/python/ceed_basis.py b/python/ceed_basis.py index 6be8765b2d..a706108df0 100644 --- a/python/ceed_basis.py +++ b/python/ceed_basis.py @@ -362,7 +362,7 @@ def apply(self, nelem, emode, u, v): Args: nelem: the number of elements to apply the basis evaluation to; the backend will specify the ordering in a - Blocked ElemRestriction + BlockedElemRestriction **emode: basis evaluation mode u: input vector v: output vector""" diff --git a/python/ceed_elemrestriction.py b/python/ceed_elemrestriction.py index 6c6421e50d..a660ed7523 100644 --- a/python/ceed_elemrestriction.py +++ b/python/ceed_elemrestriction.py @@ -181,6 +181,85 @@ def __init__(self, ceed, nelem, elemsize, ncomp, compstride, lsize, offsets, # ------------------------------------------------------------------------------ +class OrientedElemRestriction(_ElemRestrictionBase): + """Ceed Oriented ElemRestriction: oriented restriction from local vectors to elements.""" + + # Constructor + def __init__(self, ceed, nelem, elemsize, ncomp, compstride, lsize, offsets, + orients, memtype=MEM_HOST, cmode=COPY_VALUES): + # CeedVector object + self._pointer = ffi.new("CeedElemRestriction *") + + # Reference to Ceed + self._ceed = ceed + + # Store array reference if needed + if cmode == USE_POINTER: + self._array_reference = offsets + self._array_reference_aux = orients + else: + self._array_reference = None + self._array_reference_aux = None + + # Setup the numpy arrays for the libCEED call + offsets_pointer = ffi.new("const CeedInt *") + offsets_pointer = ffi.cast("const CeedInt *", + offsets.__array_interface__['data'][0]) + orients_pointer = ffi.new("const bool *") + orients_pointer = ffi.cast("const bool *", + orients.__array_interface__['data'][0]) + + # libCEED call + err_code = lib.CeedElemRestrictionCreateOriented(self._ceed._pointer[0], nelem, + elemsize, ncomp, compstride, + lsize, memtype, cmode, + offsets_pointer, orients_pointer, + self._pointer) + self._ceed._check_error(err_code) + +# ------------------------------------------------------------------------------ + + +class CurlOrientedElemRestriction(_ElemRestrictionBase): + """Ceed Curl Oriented ElemRestriction: curl-oriented restriction from local vectors to elements.""" + + # Constructor + def __init__(self, ceed, nelem, elemsize, ncomp, compstride, lsize, offsets, + curl_orients, memtype=MEM_HOST, cmode=COPY_VALUES): + # CeedVector object + self._pointer = ffi.new("CeedElemRestriction *") + + # Reference to Ceed + self._ceed = ceed + + # Store array reference if needed + if cmode == USE_POINTER: + self._array_reference = offsets + self._array_reference_aux = curl_orients + else: + self._array_reference = None + self._array_reference_aux = None + + # Setup the numpy arrays for the libCEED call + offsets_pointer = ffi.new("const CeedInt *") + offsets_pointer = ffi.cast("const CeedInt *", + offsets.__array_interface__['data'][0]) + curl_orients_pointer = ffi.new("const CeedInt *") + curl_orients_pointer = ffi.cast("const CeedInt *", + curl_orients.__array_interface__['data'][0]) + + # libCEED call + err_code = lib.CeedElemRestrictionCreateCurlOriented(self._ceed._pointer[0], nelem, + elemsize, ncomp, compstride, + lsize, memtype, cmode, + offsets_pointer, + curl_orients_pointer, + self._pointer) + self._ceed._check_error(err_code) + +# ------------------------------------------------------------------------------ + + class StridedElemRestriction(_ElemRestrictionBase): """Ceed Strided ElemRestriction: strided restriction from local vectors to elements.""" @@ -268,8 +347,70 @@ def apply_block(self, block, u, v, tmode=NOTRANSPOSE, # ------------------------------------------------------------------------------ +class BlockedOrientedElemRestriction(BlockedElemRestriction): + """Ceed Blocked Oriented ElemRestriction: blocked oriented restriction from local vectors to elements.""" + + # Constructor + def __init__(self, ceed, nelem, elemsize, blksize, ncomp, compstride, lsize, + offsets, orients, memtype=MEM_HOST, cmode=COPY_VALUES): + # CeedVector object + self._pointer = ffi.new("CeedElemRestriction *") + + # Reference to Ceed + self._ceed = ceed + + # Setup the numpy array for the libCEED call + offsets_pointer = ffi.new("const CeedInt *") + offsets_pointer = ffi.cast("const CeedInt *", + offsets.__array_interface__['data'][0]) + orients_pointer = ffi.new("const bool *") + orients_pointer = ffi.cast("const bool *", + orients.__array_interface__['data'][0]) + + # libCEED call + err_code = lib.CeedElemRestrictionCreateBlockedOriented(self._ceed._pointer[0], nelem, + elemsize, blksize, ncomp, + compstride, lsize, memtype, cmode, + offsets_pointer, orients_pointer, + self._pointer) + self._ceed._check_error(err_code) + +# ------------------------------------------------------------------------------ + + +class BlockedCurlOrientedElemRestriction(BlockedElemRestriction): + """Ceed Blocked Curl Oriented ElemRestriction: blocked curl-oriented restriction from local vectors to elements.""" + + # Constructor + def __init__(self, ceed, nelem, elemsize, blksize, ncomp, compstride, lsize, + offsets, curl_orients, memtype=MEM_HOST, cmode=COPY_VALUES): + # CeedVector object + self._pointer = ffi.new("CeedElemRestriction *") + + # Reference to Ceed + self._ceed = ceed + + # Setup the numpy array for the libCEED call + offsets_pointer = ffi.new("const CeedInt *") + offsets_pointer = ffi.cast("const CeedInt *", + offsets.__array_interface__['data'][0]) + curl_orients_pointer = ffi.new("const CeedInt *") + curl_orients_pointer = ffi.cast("const CeedInt *", + curl_orients.__array_interface__['data'][0]) + + # libCEED call + err_code = lib.CeedElemRestrictionCreateBlockedCurlOriented(self._ceed._pointer[0], nelem, + elemsize, blksize, ncomp, + compstride, lsize, memtype, cmode, + offsets_pointer, curl_orients_pointer, + self._pointer) + self._ceed._check_error(err_code) + +# ------------------------------------------------------------------------------ + + class BlockedStridedElemRestriction(BlockedElemRestriction): - """Ceed Blocked Strided ElemRestriction: strided restriction from local vectors to elements.""" + """Ceed Blocked Strided ElemRestriction: blocked strided restriction from local vectors to elements.""" # Constructor def __init__(self, ceed, nelem, elemsize, blksize, ncomp, lsize, strides): diff --git a/rust/libceed/src/elem_restriction.rs b/rust/libceed/src/elem_restriction.rs index dd9c489331..a831ae94af 100644 --- a/rust/libceed/src/elem_restriction.rs +++ b/rust/libceed/src/elem_restriction.rs @@ -193,6 +193,90 @@ impl<'a> ElemRestriction<'a> { }) } + pub fn create_oriented( + ceed: &crate::Ceed, + nelem: usize, + elemsize: usize, + ncomp: usize, + compstride: usize, + lsize: usize, + mtype: crate::MemType, + offsets: &[i32], + orients: &[bool], + ) -> crate::Result { + let mut ptr = std::ptr::null_mut(); + let (nelem, elemsize, ncomp, compstride, lsize, mtype) = ( + i32::try_from(nelem).unwrap(), + i32::try_from(elemsize).unwrap(), + i32::try_from(ncomp).unwrap(), + i32::try_from(compstride).unwrap(), + isize::try_from(lsize).unwrap(), + mtype as bind_ceed::CeedMemType, + ); + let ierr = unsafe { + bind_ceed::CeedElemRestrictionCreateOriented( + ceed.ptr, + nelem, + elemsize, + ncomp, + compstride, + lsize, + mtype, + crate::CopyMode::CopyValues as bind_ceed::CeedCopyMode, + offsets.as_ptr(), + orients.as_ptr(), + &mut ptr, + ) + }; + ceed.check_error(ierr)?; + Ok(Self { + ptr, + _lifeline: PhantomData, + }) + } + + pub fn create_curl_oriented( + ceed: &crate::Ceed, + nelem: usize, + elemsize: usize, + ncomp: usize, + compstride: usize, + lsize: usize, + mtype: crate::MemType, + offsets: &[i32], + curlorients: &[i32], + ) -> crate::Result { + let mut ptr = std::ptr::null_mut(); + let (nelem, elemsize, ncomp, compstride, lsize, mtype) = ( + i32::try_from(nelem).unwrap(), + i32::try_from(elemsize).unwrap(), + i32::try_from(ncomp).unwrap(), + i32::try_from(compstride).unwrap(), + isize::try_from(lsize).unwrap(), + mtype as bind_ceed::CeedMemType, + ); + let ierr = unsafe { + bind_ceed::CeedElemRestrictionCreateOriented( + ceed.ptr, + nelem, + elemsize, + ncomp, + compstride, + lsize, + mtype, + crate::CopyMode::CopyValues as bind_ceed::CeedCopyMode, + offsets.as_ptr(), + curlorients.as_ptr(), + &mut ptr, + ) + }; + ceed.check_error(ierr)?; + Ok(Self { + ptr, + _lifeline: PhantomData, + }) + } + pub fn create_strided( ceed: &crate::Ceed, nelem: usize,