1*9df49d7eSJed Brown // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 2*9df49d7eSJed Brown // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 3*9df49d7eSJed Brown // reserved. See files LICENSE and NOTICE for details. 4*9df49d7eSJed Brown // 5*9df49d7eSJed Brown // This file is part of CEED, a collection of benchmarks, miniapps, software 6*9df49d7eSJed Brown // libraries and APIs for efficient high-order finite element and spectral 7*9df49d7eSJed Brown // element discretizations for exascale applications. For more information and 8*9df49d7eSJed Brown // source code availability see http://github.com/ceed. 9*9df49d7eSJed Brown // 10*9df49d7eSJed Brown // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11*9df49d7eSJed Brown // a collaborative effort of two U.S. Department of Energy organizations (Office 12*9df49d7eSJed Brown // of Science and the National Nuclear Security Administration) responsible for 13*9df49d7eSJed Brown // the planning and preparation of a capable exascale ecosystem, including 14*9df49d7eSJed Brown // software, applications, hardware, advanced system engineering and early 15*9df49d7eSJed Brown // testbed platforms, in support of the nation's exascale computing imperative 16*9df49d7eSJed Brown 17*9df49d7eSJed Brown //! A Ceed ElemRestriction decomposes elements and groups the degrees of freedom 18*9df49d7eSJed Brown //! (dofs) according to the different elements they belong to. 19*9df49d7eSJed Brown 20*9df49d7eSJed Brown use crate::prelude::*; 21*9df49d7eSJed Brown 22*9df49d7eSJed Brown // ----------------------------------------------------------------------------- 23*9df49d7eSJed Brown // CeedElemRestriction option 24*9df49d7eSJed Brown // ----------------------------------------------------------------------------- 25*9df49d7eSJed Brown #[derive(Clone, Copy)] 26*9df49d7eSJed Brown pub enum ElemRestrictionOpt<'a> { 27*9df49d7eSJed Brown Some(&'a ElemRestriction<'a>), 28*9df49d7eSJed Brown None, 29*9df49d7eSJed Brown } 30*9df49d7eSJed Brown /// Construct a ElemRestrictionOpt reference from a ElemRestriction reference 31*9df49d7eSJed Brown impl<'a> From<&'a ElemRestriction<'_>> for ElemRestrictionOpt<'a> { 32*9df49d7eSJed Brown fn from(restr: &'a ElemRestriction) -> Self { 33*9df49d7eSJed Brown debug_assert!(restr.ptr != unsafe { bind_ceed::CEED_ELEMRESTRICTION_NONE }); 34*9df49d7eSJed Brown Self::Some(restr) 35*9df49d7eSJed Brown } 36*9df49d7eSJed Brown } 37*9df49d7eSJed Brown impl<'a> ElemRestrictionOpt<'a> { 38*9df49d7eSJed Brown /// Transform a Rust libCEED ElemRestrictionOpt into C libCEED 39*9df49d7eSJed Brown /// CeedElemRestriction 40*9df49d7eSJed Brown pub(crate) fn to_raw(self) -> bind_ceed::CeedElemRestriction { 41*9df49d7eSJed Brown match self { 42*9df49d7eSJed Brown Self::Some(restr) => restr.ptr, 43*9df49d7eSJed Brown Self::None => unsafe { bind_ceed::CEED_ELEMRESTRICTION_NONE }, 44*9df49d7eSJed Brown } 45*9df49d7eSJed Brown } 46*9df49d7eSJed Brown } 47*9df49d7eSJed Brown 48*9df49d7eSJed Brown // ----------------------------------------------------------------------------- 49*9df49d7eSJed Brown // CeedElemRestriction context wrapper 50*9df49d7eSJed Brown // ----------------------------------------------------------------------------- 51*9df49d7eSJed Brown pub struct ElemRestriction<'a> { 52*9df49d7eSJed Brown ceed: &'a crate::Ceed, 53*9df49d7eSJed Brown pub(crate) ptr: bind_ceed::CeedElemRestriction, 54*9df49d7eSJed Brown } 55*9df49d7eSJed Brown 56*9df49d7eSJed Brown // ----------------------------------------------------------------------------- 57*9df49d7eSJed Brown // Destructor 58*9df49d7eSJed Brown // ----------------------------------------------------------------------------- 59*9df49d7eSJed Brown impl<'a> Drop for ElemRestriction<'a> { 60*9df49d7eSJed Brown fn drop(&mut self) { 61*9df49d7eSJed Brown unsafe { 62*9df49d7eSJed Brown if self.ptr != bind_ceed::CEED_ELEMRESTRICTION_NONE { 63*9df49d7eSJed Brown bind_ceed::CeedElemRestrictionDestroy(&mut self.ptr); 64*9df49d7eSJed Brown } 65*9df49d7eSJed Brown } 66*9df49d7eSJed Brown } 67*9df49d7eSJed Brown } 68*9df49d7eSJed Brown 69*9df49d7eSJed Brown // ----------------------------------------------------------------------------- 70*9df49d7eSJed Brown // Display 71*9df49d7eSJed Brown // ----------------------------------------------------------------------------- 72*9df49d7eSJed Brown impl<'a> fmt::Display for ElemRestriction<'a> { 73*9df49d7eSJed Brown /// View an ElemRestriction 74*9df49d7eSJed Brown /// 75*9df49d7eSJed Brown /// ``` 76*9df49d7eSJed Brown /// # use libceed::prelude::*; 77*9df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 78*9df49d7eSJed Brown /// let nelem = 3; 79*9df49d7eSJed Brown /// let mut ind: Vec<i32> = vec![0; 2 * nelem]; 80*9df49d7eSJed Brown /// for i in 0..nelem { 81*9df49d7eSJed Brown /// ind[2 * i + 0] = i as i32; 82*9df49d7eSJed Brown /// ind[2 * i + 1] = (i + 1) as i32; 83*9df49d7eSJed Brown /// } 84*9df49d7eSJed Brown /// let r = ceed 85*9df49d7eSJed Brown /// .elem_restriction(nelem, 2, 1, 1, nelem + 1, MemType::Host, &ind) 86*9df49d7eSJed Brown /// .unwrap(); 87*9df49d7eSJed Brown /// println!("{}", r); 88*9df49d7eSJed Brown /// ``` 89*9df49d7eSJed Brown fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 90*9df49d7eSJed Brown let mut ptr = std::ptr::null_mut(); 91*9df49d7eSJed Brown let mut sizeloc = crate::MAX_BUFFER_LENGTH; 92*9df49d7eSJed Brown let cstring = unsafe { 93*9df49d7eSJed Brown let file = bind_ceed::open_memstream(&mut ptr, &mut sizeloc); 94*9df49d7eSJed Brown bind_ceed::CeedElemRestrictionView(self.ptr, file); 95*9df49d7eSJed Brown bind_ceed::fclose(file); 96*9df49d7eSJed Brown CString::from_raw(ptr) 97*9df49d7eSJed Brown }; 98*9df49d7eSJed Brown cstring.to_string_lossy().fmt(f) 99*9df49d7eSJed Brown } 100*9df49d7eSJed Brown } 101*9df49d7eSJed Brown 102*9df49d7eSJed Brown // ----------------------------------------------------------------------------- 103*9df49d7eSJed Brown // Implementations 104*9df49d7eSJed Brown // ----------------------------------------------------------------------------- 105*9df49d7eSJed Brown impl<'a> ElemRestriction<'a> { 106*9df49d7eSJed Brown // Constructors 107*9df49d7eSJed Brown pub fn create( 108*9df49d7eSJed Brown ceed: &'a crate::Ceed, 109*9df49d7eSJed Brown nelem: usize, 110*9df49d7eSJed Brown elemsize: usize, 111*9df49d7eSJed Brown ncomp: usize, 112*9df49d7eSJed Brown compstride: usize, 113*9df49d7eSJed Brown lsize: usize, 114*9df49d7eSJed Brown mtype: crate::MemType, 115*9df49d7eSJed Brown offsets: &[i32], 116*9df49d7eSJed Brown ) -> crate::Result<Self> { 117*9df49d7eSJed Brown let mut ptr = std::ptr::null_mut(); 118*9df49d7eSJed Brown let (nelem, elemsize, ncomp, compstride, lsize, mtype) = ( 119*9df49d7eSJed Brown i32::try_from(nelem).unwrap(), 120*9df49d7eSJed Brown i32::try_from(elemsize).unwrap(), 121*9df49d7eSJed Brown i32::try_from(ncomp).unwrap(), 122*9df49d7eSJed Brown i32::try_from(compstride).unwrap(), 123*9df49d7eSJed Brown i32::try_from(lsize).unwrap(), 124*9df49d7eSJed Brown mtype as bind_ceed::CeedMemType, 125*9df49d7eSJed Brown ); 126*9df49d7eSJed Brown let ierr = unsafe { 127*9df49d7eSJed Brown bind_ceed::CeedElemRestrictionCreate( 128*9df49d7eSJed Brown ceed.ptr, 129*9df49d7eSJed Brown nelem, 130*9df49d7eSJed Brown elemsize, 131*9df49d7eSJed Brown ncomp, 132*9df49d7eSJed Brown compstride, 133*9df49d7eSJed Brown lsize, 134*9df49d7eSJed Brown mtype, 135*9df49d7eSJed Brown crate::CopyMode::CopyValues as bind_ceed::CeedCopyMode, 136*9df49d7eSJed Brown offsets.as_ptr(), 137*9df49d7eSJed Brown &mut ptr, 138*9df49d7eSJed Brown ) 139*9df49d7eSJed Brown }; 140*9df49d7eSJed Brown ceed.check_error(ierr)?; 141*9df49d7eSJed Brown Ok(Self { ceed, ptr }) 142*9df49d7eSJed Brown } 143*9df49d7eSJed Brown 144*9df49d7eSJed Brown pub fn create_strided( 145*9df49d7eSJed Brown ceed: &'a crate::Ceed, 146*9df49d7eSJed Brown nelem: usize, 147*9df49d7eSJed Brown elemsize: usize, 148*9df49d7eSJed Brown ncomp: usize, 149*9df49d7eSJed Brown lsize: usize, 150*9df49d7eSJed Brown strides: [i32; 3], 151*9df49d7eSJed Brown ) -> crate::Result<Self> { 152*9df49d7eSJed Brown let mut ptr = std::ptr::null_mut(); 153*9df49d7eSJed Brown let (nelem, elemsize, ncomp, lsize) = ( 154*9df49d7eSJed Brown i32::try_from(nelem).unwrap(), 155*9df49d7eSJed Brown i32::try_from(elemsize).unwrap(), 156*9df49d7eSJed Brown i32::try_from(ncomp).unwrap(), 157*9df49d7eSJed Brown i32::try_from(lsize).unwrap(), 158*9df49d7eSJed Brown ); 159*9df49d7eSJed Brown let ierr = unsafe { 160*9df49d7eSJed Brown bind_ceed::CeedElemRestrictionCreateStrided( 161*9df49d7eSJed Brown ceed.ptr, 162*9df49d7eSJed Brown nelem, 163*9df49d7eSJed Brown elemsize, 164*9df49d7eSJed Brown ncomp, 165*9df49d7eSJed Brown lsize, 166*9df49d7eSJed Brown strides.as_ptr(), 167*9df49d7eSJed Brown &mut ptr, 168*9df49d7eSJed Brown ) 169*9df49d7eSJed Brown }; 170*9df49d7eSJed Brown ceed.check_error(ierr)?; 171*9df49d7eSJed Brown Ok(Self { ceed, ptr }) 172*9df49d7eSJed Brown } 173*9df49d7eSJed Brown 174*9df49d7eSJed Brown /// Create an Lvector for an ElemRestriction 175*9df49d7eSJed Brown /// 176*9df49d7eSJed Brown /// ``` 177*9df49d7eSJed Brown /// # use libceed::prelude::*; 178*9df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 179*9df49d7eSJed Brown /// let nelem = 3; 180*9df49d7eSJed Brown /// let mut ind: Vec<i32> = vec![0; 2 * nelem]; 181*9df49d7eSJed Brown /// for i in 0..nelem { 182*9df49d7eSJed Brown /// ind[2 * i + 0] = i as i32; 183*9df49d7eSJed Brown /// ind[2 * i + 1] = (i + 1) as i32; 184*9df49d7eSJed Brown /// } 185*9df49d7eSJed Brown /// let r = ceed 186*9df49d7eSJed Brown /// .elem_restriction(nelem, 2, 1, 1, nelem + 1, MemType::Host, &ind) 187*9df49d7eSJed Brown /// .unwrap(); 188*9df49d7eSJed Brown /// 189*9df49d7eSJed Brown /// let lvector = r.create_lvector().unwrap(); 190*9df49d7eSJed Brown /// 191*9df49d7eSJed Brown /// assert_eq!(lvector.length(), nelem + 1, "Incorrect Lvector size"); 192*9df49d7eSJed Brown /// ``` 193*9df49d7eSJed Brown pub fn create_lvector(&self) -> crate::Result<Vector> { 194*9df49d7eSJed Brown let mut ptr_lvector = std::ptr::null_mut(); 195*9df49d7eSJed Brown let null = std::ptr::null_mut() as *mut _; 196*9df49d7eSJed Brown let ierr = 197*9df49d7eSJed Brown unsafe { bind_ceed::CeedElemRestrictionCreateVector(self.ptr, &mut ptr_lvector, null) }; 198*9df49d7eSJed Brown self.ceed.check_error(ierr)?; 199*9df49d7eSJed Brown Vector::from_raw(self.ceed, ptr_lvector) 200*9df49d7eSJed Brown } 201*9df49d7eSJed Brown 202*9df49d7eSJed Brown /// Create an Evector for an ElemRestriction 203*9df49d7eSJed Brown /// 204*9df49d7eSJed Brown /// ``` 205*9df49d7eSJed Brown /// # use libceed::prelude::*; 206*9df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 207*9df49d7eSJed Brown /// let nelem = 3; 208*9df49d7eSJed Brown /// let mut ind: Vec<i32> = vec![0; 2 * nelem]; 209*9df49d7eSJed Brown /// for i in 0..nelem { 210*9df49d7eSJed Brown /// ind[2 * i + 0] = i as i32; 211*9df49d7eSJed Brown /// ind[2 * i + 1] = (i + 1) as i32; 212*9df49d7eSJed Brown /// } 213*9df49d7eSJed Brown /// let r = ceed 214*9df49d7eSJed Brown /// .elem_restriction(nelem, 2, 1, 1, nelem + 1, MemType::Host, &ind) 215*9df49d7eSJed Brown /// .unwrap(); 216*9df49d7eSJed Brown /// 217*9df49d7eSJed Brown /// let evector = r.create_evector().unwrap(); 218*9df49d7eSJed Brown /// 219*9df49d7eSJed Brown /// assert_eq!(evector.length(), nelem * 2, "Incorrect Evector size"); 220*9df49d7eSJed Brown /// ``` 221*9df49d7eSJed Brown pub fn create_evector(&self) -> crate::Result<Vector> { 222*9df49d7eSJed Brown let mut ptr_evector = std::ptr::null_mut(); 223*9df49d7eSJed Brown let null = std::ptr::null_mut() as *mut _; 224*9df49d7eSJed Brown let ierr = 225*9df49d7eSJed Brown unsafe { bind_ceed::CeedElemRestrictionCreateVector(self.ptr, null, &mut ptr_evector) }; 226*9df49d7eSJed Brown self.ceed.check_error(ierr)?; 227*9df49d7eSJed Brown Vector::from_raw(self.ceed, ptr_evector) 228*9df49d7eSJed Brown } 229*9df49d7eSJed Brown 230*9df49d7eSJed Brown /// Create Vectors for an ElemRestriction 231*9df49d7eSJed Brown /// 232*9df49d7eSJed Brown /// ``` 233*9df49d7eSJed Brown /// # use libceed::prelude::*; 234*9df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 235*9df49d7eSJed Brown /// let nelem = 3; 236*9df49d7eSJed Brown /// let mut ind: Vec<i32> = vec![0; 2 * nelem]; 237*9df49d7eSJed Brown /// for i in 0..nelem { 238*9df49d7eSJed Brown /// ind[2 * i + 0] = i as i32; 239*9df49d7eSJed Brown /// ind[2 * i + 1] = (i + 1) as i32; 240*9df49d7eSJed Brown /// } 241*9df49d7eSJed Brown /// let r = ceed 242*9df49d7eSJed Brown /// .elem_restriction(nelem, 2, 1, 1, nelem + 1, MemType::Host, &ind) 243*9df49d7eSJed Brown /// .unwrap(); 244*9df49d7eSJed Brown /// 245*9df49d7eSJed Brown /// let (lvector, evector) = r.create_vectors().unwrap(); 246*9df49d7eSJed Brown /// 247*9df49d7eSJed Brown /// assert_eq!(lvector.length(), nelem + 1, "Incorrect Lvector size"); 248*9df49d7eSJed Brown /// assert_eq!(evector.length(), nelem * 2, "Incorrect Evector size"); 249*9df49d7eSJed Brown /// ``` 250*9df49d7eSJed Brown pub fn create_vectors(&self) -> crate::Result<(Vector, Vector)> { 251*9df49d7eSJed Brown let mut ptr_lvector = std::ptr::null_mut(); 252*9df49d7eSJed Brown let mut ptr_evector = std::ptr::null_mut(); 253*9df49d7eSJed Brown let ierr = unsafe { 254*9df49d7eSJed Brown bind_ceed::CeedElemRestrictionCreateVector(self.ptr, &mut ptr_lvector, &mut ptr_evector) 255*9df49d7eSJed Brown }; 256*9df49d7eSJed Brown self.ceed.check_error(ierr)?; 257*9df49d7eSJed Brown let lvector = Vector::from_raw(self.ceed, ptr_lvector)?; 258*9df49d7eSJed Brown let evector = Vector::from_raw(self.ceed, ptr_evector)?; 259*9df49d7eSJed Brown Ok((lvector, evector)) 260*9df49d7eSJed Brown } 261*9df49d7eSJed Brown 262*9df49d7eSJed Brown /// Restrict an Lvector to an Evector or apply its transpose 263*9df49d7eSJed Brown /// 264*9df49d7eSJed Brown /// # arguments 265*9df49d7eSJed Brown /// 266*9df49d7eSJed Brown /// * `tmode` - Apply restriction or transpose 267*9df49d7eSJed Brown /// * `u` - Input vector (of size `lsize` when `TransposeMode::NoTranspose`) 268*9df49d7eSJed Brown /// * `ru` - Output vector (of shape `[nelem * elemsize]` when 269*9df49d7eSJed Brown /// `TransposeMode::NoTranspose`). Ordering of the Evector is 270*9df49d7eSJed Brown /// decided by the backend. 271*9df49d7eSJed Brown /// 272*9df49d7eSJed Brown /// ``` 273*9df49d7eSJed Brown /// # use libceed::prelude::*; 274*9df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 275*9df49d7eSJed Brown /// let nelem = 3; 276*9df49d7eSJed Brown /// let mut ind: Vec<i32> = vec![0; 2 * nelem]; 277*9df49d7eSJed Brown /// for i in 0..nelem { 278*9df49d7eSJed Brown /// ind[2 * i + 0] = i as i32; 279*9df49d7eSJed Brown /// ind[2 * i + 1] = (i + 1) as i32; 280*9df49d7eSJed Brown /// } 281*9df49d7eSJed Brown /// let r = ceed 282*9df49d7eSJed Brown /// .elem_restriction(nelem, 2, 1, 1, nelem + 1, MemType::Host, &ind) 283*9df49d7eSJed Brown /// .unwrap(); 284*9df49d7eSJed Brown /// 285*9df49d7eSJed Brown /// let x = ceed.vector_from_slice(&[0., 1., 2., 3.]).unwrap(); 286*9df49d7eSJed Brown /// let mut y = ceed.vector(nelem * 2).unwrap(); 287*9df49d7eSJed Brown /// y.set_value(0.0); 288*9df49d7eSJed Brown /// 289*9df49d7eSJed Brown /// r.apply(TransposeMode::NoTranspose, &x, &mut y).unwrap(); 290*9df49d7eSJed Brown /// 291*9df49d7eSJed Brown /// y.view().iter().enumerate().for_each(|(i, arr)| { 292*9df49d7eSJed Brown /// assert_eq!( 293*9df49d7eSJed Brown /// *arr, 294*9df49d7eSJed Brown /// ((i + 1) / 2) as f64, 295*9df49d7eSJed Brown /// "Incorrect value in restricted vector" 296*9df49d7eSJed Brown /// ); 297*9df49d7eSJed Brown /// }); 298*9df49d7eSJed Brown /// ``` 299*9df49d7eSJed Brown pub fn apply(&self, tmode: TransposeMode, u: &Vector, ru: &mut Vector) -> crate::Result<i32> { 300*9df49d7eSJed Brown let tmode = tmode as bind_ceed::CeedTransposeMode; 301*9df49d7eSJed Brown let ierr = unsafe { 302*9df49d7eSJed Brown bind_ceed::CeedElemRestrictionApply( 303*9df49d7eSJed Brown self.ptr, 304*9df49d7eSJed Brown tmode, 305*9df49d7eSJed Brown u.ptr, 306*9df49d7eSJed Brown ru.ptr, 307*9df49d7eSJed Brown bind_ceed::CEED_REQUEST_IMMEDIATE, 308*9df49d7eSJed Brown ) 309*9df49d7eSJed Brown }; 310*9df49d7eSJed Brown self.ceed.check_error(ierr) 311*9df49d7eSJed Brown } 312*9df49d7eSJed Brown 313*9df49d7eSJed Brown /// Returns the Lvector component stride 314*9df49d7eSJed Brown /// 315*9df49d7eSJed Brown /// ``` 316*9df49d7eSJed Brown /// # use libceed::prelude::*; 317*9df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 318*9df49d7eSJed Brown /// let nelem = 3; 319*9df49d7eSJed Brown /// let compstride = 1; 320*9df49d7eSJed Brown /// let mut ind: Vec<i32> = vec![0; 2 * nelem]; 321*9df49d7eSJed Brown /// for i in 0..nelem { 322*9df49d7eSJed Brown /// ind[2 * i + 0] = i as i32; 323*9df49d7eSJed Brown /// ind[2 * i + 1] = (i + 1) as i32; 324*9df49d7eSJed Brown /// } 325*9df49d7eSJed Brown /// let r = ceed 326*9df49d7eSJed Brown /// .elem_restriction(nelem, 2, 1, compstride, nelem + 1, MemType::Host, &ind) 327*9df49d7eSJed Brown /// .unwrap(); 328*9df49d7eSJed Brown /// 329*9df49d7eSJed Brown /// let c = r.comp_stride(); 330*9df49d7eSJed Brown /// assert_eq!(c, compstride, "Incorrect component stride"); 331*9df49d7eSJed Brown /// ``` 332*9df49d7eSJed Brown pub fn comp_stride(&self) -> usize { 333*9df49d7eSJed Brown let mut compstride = 0; 334*9df49d7eSJed Brown unsafe { bind_ceed::CeedElemRestrictionGetCompStride(self.ptr, &mut compstride) }; 335*9df49d7eSJed Brown usize::try_from(compstride).unwrap() 336*9df49d7eSJed Brown } 337*9df49d7eSJed Brown 338*9df49d7eSJed Brown /// Returns the total number of elements in the range of a ElemRestriction 339*9df49d7eSJed Brown /// 340*9df49d7eSJed Brown /// ``` 341*9df49d7eSJed Brown /// # use libceed::prelude::*; 342*9df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 343*9df49d7eSJed Brown /// let nelem = 3; 344*9df49d7eSJed Brown /// let mut ind: Vec<i32> = vec![0; 2 * nelem]; 345*9df49d7eSJed Brown /// for i in 0..nelem { 346*9df49d7eSJed Brown /// ind[2 * i + 0] = i as i32; 347*9df49d7eSJed Brown /// ind[2 * i + 1] = (i + 1) as i32; 348*9df49d7eSJed Brown /// } 349*9df49d7eSJed Brown /// let r = ceed 350*9df49d7eSJed Brown /// .elem_restriction(nelem, 2, 1, 1, nelem + 1, MemType::Host, &ind) 351*9df49d7eSJed Brown /// .unwrap(); 352*9df49d7eSJed Brown /// 353*9df49d7eSJed Brown /// let n = r.num_elements(); 354*9df49d7eSJed Brown /// assert_eq!(n, nelem, "Incorrect number of elements"); 355*9df49d7eSJed Brown /// ``` 356*9df49d7eSJed Brown pub fn num_elements(&self) -> usize { 357*9df49d7eSJed Brown let mut numelem = 0; 358*9df49d7eSJed Brown unsafe { bind_ceed::CeedElemRestrictionGetNumElements(self.ptr, &mut numelem) }; 359*9df49d7eSJed Brown usize::try_from(numelem).unwrap() 360*9df49d7eSJed Brown } 361*9df49d7eSJed Brown 362*9df49d7eSJed Brown /// Returns the size of elements in the ElemRestriction 363*9df49d7eSJed Brown /// 364*9df49d7eSJed Brown /// ``` 365*9df49d7eSJed Brown /// # use libceed::prelude::*; 366*9df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 367*9df49d7eSJed Brown /// let nelem = 3; 368*9df49d7eSJed Brown /// let elem_size = 2; 369*9df49d7eSJed Brown /// let mut ind: Vec<i32> = vec![0; 2 * nelem]; 370*9df49d7eSJed Brown /// for i in 0..nelem { 371*9df49d7eSJed Brown /// ind[2 * i + 0] = i as i32; 372*9df49d7eSJed Brown /// ind[2 * i + 1] = (i + 1) as i32; 373*9df49d7eSJed Brown /// } 374*9df49d7eSJed Brown /// let r = ceed 375*9df49d7eSJed Brown /// .elem_restriction(nelem, elem_size, 1, 1, nelem + 1, MemType::Host, &ind) 376*9df49d7eSJed Brown /// .unwrap(); 377*9df49d7eSJed Brown /// 378*9df49d7eSJed Brown /// let e = r.elem_size(); 379*9df49d7eSJed Brown /// assert_eq!(e, elem_size, "Incorrect element size"); 380*9df49d7eSJed Brown /// ``` 381*9df49d7eSJed Brown pub fn elem_size(&self) -> usize { 382*9df49d7eSJed Brown let mut elemsize = 0; 383*9df49d7eSJed Brown unsafe { bind_ceed::CeedElemRestrictionGetElementSize(self.ptr, &mut elemsize) }; 384*9df49d7eSJed Brown usize::try_from(elemsize).unwrap() 385*9df49d7eSJed Brown } 386*9df49d7eSJed Brown 387*9df49d7eSJed Brown /// Returns the size of the Lvector for an ElemRestriction 388*9df49d7eSJed Brown /// 389*9df49d7eSJed Brown /// ``` 390*9df49d7eSJed Brown /// # use libceed::prelude::*; 391*9df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 392*9df49d7eSJed Brown /// let nelem = 3; 393*9df49d7eSJed Brown /// let mut ind: Vec<i32> = vec![0; 2 * nelem]; 394*9df49d7eSJed Brown /// for i in 0..nelem { 395*9df49d7eSJed Brown /// ind[2 * i + 0] = i as i32; 396*9df49d7eSJed Brown /// ind[2 * i + 1] = (i + 1) as i32; 397*9df49d7eSJed Brown /// } 398*9df49d7eSJed Brown /// let r = ceed 399*9df49d7eSJed Brown /// .elem_restriction(nelem, 2, 1, 1, nelem + 1, MemType::Host, &ind) 400*9df49d7eSJed Brown /// .unwrap(); 401*9df49d7eSJed Brown /// 402*9df49d7eSJed Brown /// let lsize = r.lvector_size(); 403*9df49d7eSJed Brown /// assert_eq!(lsize, nelem + 1); 404*9df49d7eSJed Brown /// ``` 405*9df49d7eSJed Brown pub fn lvector_size(&self) -> usize { 406*9df49d7eSJed Brown let mut lsize = 0; 407*9df49d7eSJed Brown unsafe { bind_ceed::CeedElemRestrictionGetLVectorSize(self.ptr, &mut lsize) }; 408*9df49d7eSJed Brown usize::try_from(lsize).unwrap() 409*9df49d7eSJed Brown } 410*9df49d7eSJed Brown 411*9df49d7eSJed Brown /// Returns the number of components in the elements of an ElemRestriction 412*9df49d7eSJed Brown /// 413*9df49d7eSJed Brown /// ``` 414*9df49d7eSJed Brown /// # use libceed::prelude::*; 415*9df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 416*9df49d7eSJed Brown /// let nelem = 3; 417*9df49d7eSJed Brown /// let ncomp = 42; 418*9df49d7eSJed Brown /// let mut ind: Vec<i32> = vec![0; 2 * nelem]; 419*9df49d7eSJed Brown /// for i in 0..nelem { 420*9df49d7eSJed Brown /// ind[2 * i + 0] = i as i32; 421*9df49d7eSJed Brown /// ind[2 * i + 1] = (i + 1) as i32; 422*9df49d7eSJed Brown /// } 423*9df49d7eSJed Brown /// let r = ceed 424*9df49d7eSJed Brown /// .elem_restriction(nelem, 2, 42, 1, ncomp * (nelem + 1), MemType::Host, &ind) 425*9df49d7eSJed Brown /// .unwrap(); 426*9df49d7eSJed Brown /// 427*9df49d7eSJed Brown /// let n = r.num_components(); 428*9df49d7eSJed Brown /// assert_eq!(n, ncomp, "Incorrect number of components"); 429*9df49d7eSJed Brown /// ``` 430*9df49d7eSJed Brown pub fn num_components(&self) -> usize { 431*9df49d7eSJed Brown let mut ncomp = 0; 432*9df49d7eSJed Brown unsafe { bind_ceed::CeedElemRestrictionGetNumComponents(self.ptr, &mut ncomp) }; 433*9df49d7eSJed Brown usize::try_from(ncomp).unwrap() 434*9df49d7eSJed Brown } 435*9df49d7eSJed Brown 436*9df49d7eSJed Brown /// Returns the multiplicity of nodes in an ElemRestriction 437*9df49d7eSJed Brown /// 438*9df49d7eSJed Brown /// ``` 439*9df49d7eSJed Brown /// # use libceed::prelude::*; 440*9df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 441*9df49d7eSJed Brown /// let nelem = 3; 442*9df49d7eSJed Brown /// let mut ind: Vec<i32> = vec![0; 2 * nelem]; 443*9df49d7eSJed Brown /// for i in 0..nelem { 444*9df49d7eSJed Brown /// ind[2 * i + 0] = i as i32; 445*9df49d7eSJed Brown /// ind[2 * i + 1] = (i + 1) as i32; 446*9df49d7eSJed Brown /// } 447*9df49d7eSJed Brown /// let r = ceed 448*9df49d7eSJed Brown /// .elem_restriction(nelem, 2, 1, 1, nelem + 1, MemType::Host, &ind) 449*9df49d7eSJed Brown /// .unwrap(); 450*9df49d7eSJed Brown /// 451*9df49d7eSJed Brown /// let mut mult = ceed.vector(nelem + 1).unwrap(); 452*9df49d7eSJed Brown /// mult.set_value(0.0); 453*9df49d7eSJed Brown /// 454*9df49d7eSJed Brown /// r.multiplicity(&mut mult).unwrap(); 455*9df49d7eSJed Brown /// 456*9df49d7eSJed Brown /// mult.view().iter().enumerate().for_each(|(i, arr)| { 457*9df49d7eSJed Brown /// assert_eq!( 458*9df49d7eSJed Brown /// if (i == 0 || i == nelem) { 1. } else { 2. }, 459*9df49d7eSJed Brown /// *arr, 460*9df49d7eSJed Brown /// "Incorrect multiplicity array" 461*9df49d7eSJed Brown /// ); 462*9df49d7eSJed Brown /// }); 463*9df49d7eSJed Brown /// ``` 464*9df49d7eSJed Brown pub fn multiplicity(&self, mult: &mut Vector) -> crate::Result<i32> { 465*9df49d7eSJed Brown let ierr = unsafe { bind_ceed::CeedElemRestrictionGetMultiplicity(self.ptr, mult.ptr) }; 466*9df49d7eSJed Brown self.ceed.check_error(ierr) 467*9df49d7eSJed Brown } 468*9df49d7eSJed Brown } 469*9df49d7eSJed Brown 470*9df49d7eSJed Brown // ----------------------------------------------------------------------------- 471