use crate::prelude::*;
#[derive(Debug)]
pub enum ElemRestrictionOpt<'a> {
Some(&'a ElemRestriction<'a>),
None,
}
impl<'a> From<&'a ElemRestriction<'_>> for ElemRestrictionOpt<'a> {
fn from(rstr: &'a ElemRestriction) -> Self {
debug_assert!(rstr.ptr != unsafe { bind_ceed::CEED_ELEMRESTRICTION_NONE });
Self::Some(rstr)
}
}
impl<'a> ElemRestrictionOpt<'a> {
pub(crate) fn to_raw(self) -> bind_ceed::CeedElemRestriction {
match self {
Self::Some(rstr) => rstr.ptr,
Self::None => unsafe { bind_ceed::CEED_ELEMRESTRICTION_NONE },
}
}
pub fn is_some(&self) -> bool {
match self {
Self::Some(_) => true,
Self::None => false,
}
}
pub fn is_none(&self) -> bool {
match self {
Self::Some(_) => false,
Self::None => true,
}
}
}
#[derive(Debug)]
pub struct ElemRestriction<'a> {
pub(crate) ptr: bind_ceed::CeedElemRestriction,
_lifeline: PhantomData<&'a ()>,
}
impl<'a> Drop for ElemRestriction<'a> {
fn drop(&mut self) {
unsafe {
if self.ptr != bind_ceed::CEED_ELEMRESTRICTION_NONE {
bind_ceed::CeedElemRestrictionDestroy(&mut self.ptr);
}
}
}
}
impl<'a> fmt::Display for ElemRestriction<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut ptr = std::ptr::null_mut();
let mut sizeloc = crate::MAX_BUFFER_LENGTH;
let cstring = unsafe {
let file = bind_ceed::open_memstream(&mut ptr, &mut sizeloc);
bind_ceed::CeedElemRestrictionView(self.ptr, file);
bind_ceed::fclose(file);
CString::from_raw(ptr)
};
cstring.to_string_lossy().fmt(f)
}
}
impl<'a> ElemRestriction<'a> {
pub fn create(
ceed: &crate::Ceed,
nelem: usize,
elemsize: usize,
ncomp: usize,
compstride: usize,
lsize: usize,
mtype: crate::MemType,
offsets: &[i32],
) -> crate::Result<Self> {
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::CeedElemRestrictionCreate(
ceed.ptr,
nelem,
elemsize,
ncomp,
compstride,
lsize,
mtype,
crate::CopyMode::CopyValues as bind_ceed::CeedCopyMode,
offsets.as_ptr(),
&mut ptr,
)
};
ceed.check_error(ierr)?;
Ok(Self {
ptr,
_lifeline: PhantomData,
})
}
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<Self> {
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: &[i8],
) -> crate::Result<Self> {
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::CeedElemRestrictionCreateCurlOriented(
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,
elemsize: usize,
ncomp: usize,
lsize: usize,
strides: [i32; 3],
) -> crate::Result<Self> {
let mut ptr = std::ptr::null_mut();
let (nelem, elemsize, ncomp, lsize) = (
i32::try_from(nelem).unwrap(),
i32::try_from(elemsize).unwrap(),
i32::try_from(ncomp).unwrap(),
isize::try_from(lsize).unwrap(),
);
let ierr = unsafe {
bind_ceed::CeedElemRestrictionCreateStrided(
ceed.ptr,
nelem,
elemsize,
ncomp,
lsize,
strides.as_ptr(),
&mut ptr,
)
};
ceed.check_error(ierr)?;
Ok(Self {
ptr,
_lifeline: PhantomData,
})
}
#[doc(hidden)]
fn check_error(&self, ierr: i32) -> crate::Result<i32> {
let mut ptr = std::ptr::null_mut();
unsafe {
bind_ceed::CeedElemRestrictionGetCeed(self.ptr, &mut ptr);
}
crate::check_error(ptr, ierr)
}
pub fn create_lvector<'b>(&self) -> crate::Result<Vector<'b>> {
let mut ptr_lvector = std::ptr::null_mut();
let null = std::ptr::null_mut() as *mut _;
let ierr =
unsafe { bind_ceed::CeedElemRestrictionCreateVector(self.ptr, &mut ptr_lvector, null) };
self.check_error(ierr)?;
Vector::from_raw(ptr_lvector)
}
pub fn create_evector<'b>(&self) -> crate::Result<Vector<'b>> {
let mut ptr_evector = std::ptr::null_mut();
let null = std::ptr::null_mut() as *mut _;
let ierr =
unsafe { bind_ceed::CeedElemRestrictionCreateVector(self.ptr, null, &mut ptr_evector) };
self.check_error(ierr)?;
Vector::from_raw(ptr_evector)
}
pub fn create_vectors<'b, 'c>(&self) -> crate::Result<(Vector<'b>, Vector<'c>)> {
let mut ptr_lvector = std::ptr::null_mut();
let mut ptr_evector = std::ptr::null_mut();
let ierr = unsafe {
bind_ceed::CeedElemRestrictionCreateVector(self.ptr, &mut ptr_lvector, &mut ptr_evector)
};
self.check_error(ierr)?;
let lvector = Vector::from_raw(ptr_lvector)?;
let evector = Vector::from_raw(ptr_evector)?;
Ok((lvector, evector))
}
pub fn apply(&self, tmode: TransposeMode, u: &Vector, ru: &mut Vector) -> crate::Result<i32> {
let tmode = tmode as bind_ceed::CeedTransposeMode;
let ierr = unsafe {
bind_ceed::CeedElemRestrictionApply(
self.ptr,
tmode,
u.ptr,
ru.ptr,
bind_ceed::CEED_REQUEST_IMMEDIATE,
)
};
self.check_error(ierr)
}
pub fn comp_stride(&self) -> usize {
let mut compstride = 0;
unsafe { bind_ceed::CeedElemRestrictionGetCompStride(self.ptr, &mut compstride) };
usize::try_from(compstride).unwrap()
}
pub fn num_elements(&self) -> usize {
let mut numelem = 0;
unsafe { bind_ceed::CeedElemRestrictionGetNumElements(self.ptr, &mut numelem) };
usize::try_from(numelem).unwrap()
}
pub fn elem_size(&self) -> usize {
let mut elemsize = 0;
unsafe { bind_ceed::CeedElemRestrictionGetElementSize(self.ptr, &mut elemsize) };
usize::try_from(elemsize).unwrap()
}
pub fn lvector_size(&self) -> usize {
let mut lsize = 0;
unsafe { bind_ceed::CeedElemRestrictionGetLVectorSize(self.ptr, &mut lsize) };
usize::try_from(lsize).unwrap()
}
pub fn num_components(&self) -> usize {
let mut ncomp = 0;
unsafe { bind_ceed::CeedElemRestrictionGetNumComponents(self.ptr, &mut ncomp) };
usize::try_from(ncomp).unwrap()
}
pub fn multiplicity(&self, mult: &mut Vector) -> crate::Result<i32> {
let ierr = unsafe { bind_ceed::CeedElemRestrictionGetMultiplicity(self.ptr, mult.ptr) };
self.check_error(ierr)
}
}