19df49d7eSJed Brown // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 29df49d7eSJed Brown // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 39df49d7eSJed Brown // reserved. See files LICENSE and NOTICE for details. 49df49d7eSJed Brown // 59df49d7eSJed Brown // This file is part of CEED, a collection of benchmarks, miniapps, software 69df49d7eSJed Brown // libraries and APIs for efficient high-order finite element and spectral 79df49d7eSJed Brown // element discretizations for exascale applications. For more information and 89df49d7eSJed Brown // source code availability see http://github.com/ceed. 99df49d7eSJed Brown // 109df49d7eSJed Brown // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 119df49d7eSJed Brown // a collaborative effort of two U.S. Department of Energy organizations (Office 129df49d7eSJed Brown // of Science and the National Nuclear Security Administration) responsible for 139df49d7eSJed Brown // the planning and preparation of a capable exascale ecosystem, including 149df49d7eSJed Brown // software, applications, hardware, advanced system engineering and early 159df49d7eSJed Brown // testbed platforms, in support of the nation's exascale computing imperative 169df49d7eSJed Brown 179df49d7eSJed Brown //! A Ceed Vector constitutes the main data structure and serves as input/output 189df49d7eSJed Brown //! for Ceed Operators. 199df49d7eSJed Brown 209df49d7eSJed Brown use std::{ 219df49d7eSJed Brown ops::{Deref, DerefMut}, 229df49d7eSJed Brown os::raw::c_char, 239df49d7eSJed Brown }; 249df49d7eSJed Brown 259df49d7eSJed Brown use crate::prelude::*; 269df49d7eSJed Brown 279df49d7eSJed Brown // ----------------------------------------------------------------------------- 289df49d7eSJed Brown // CeedVector option 299df49d7eSJed Brown // ----------------------------------------------------------------------------- 30c68be7a2SJeremy L Thompson #[derive(Debug)] 319df49d7eSJed Brown pub enum VectorOpt<'a> { 329df49d7eSJed Brown Some(&'a Vector<'a>), 339df49d7eSJed Brown Active, 349df49d7eSJed Brown None, 359df49d7eSJed Brown } 369df49d7eSJed Brown /// Construct a VectorOpt reference from a Vector reference 379df49d7eSJed Brown impl<'a> From<&'a Vector<'_>> for VectorOpt<'a> { 389df49d7eSJed Brown fn from(vec: &'a Vector) -> Self { 399df49d7eSJed Brown debug_assert!(vec.ptr != unsafe { bind_ceed::CEED_VECTOR_ACTIVE }); 40c68be7a2SJeremy L Thompson debug_assert!(vec.ptr != unsafe { bind_ceed::CEED_VECTOR_NONE }); 419df49d7eSJed Brown Self::Some(vec) 429df49d7eSJed Brown } 439df49d7eSJed Brown } 449df49d7eSJed Brown impl<'a> VectorOpt<'a> { 459df49d7eSJed Brown /// Transform a Rust libCEED VectorOpt into C libCEED CeedVector 469df49d7eSJed Brown pub(crate) fn to_raw(self) -> bind_ceed::CeedVector { 479df49d7eSJed Brown match self { 489df49d7eSJed Brown Self::Some(vec) => vec.ptr, 499df49d7eSJed Brown Self::Active => unsafe { bind_ceed::CEED_VECTOR_ACTIVE }, 50c68be7a2SJeremy L Thompson Self::None => unsafe { bind_ceed::CEED_VECTOR_NONE }, 519df49d7eSJed Brown } 529df49d7eSJed Brown } 53e03682afSJeremy L Thompson 54e03682afSJeremy L Thompson /// Check if a VectorOpt is Some 55e03682afSJeremy L Thompson /// 56e03682afSJeremy L Thompson /// ``` 57e03682afSJeremy L Thompson /// # use libceed::prelude::*; 584d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 59e03682afSJeremy L Thompson /// # let ceed = libceed::Ceed::default_init(); 60e03682afSJeremy L Thompson /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?; 61e03682afSJeremy L Thompson /// let vec_opt = VectorOpt::from(&vec); 62e03682afSJeremy L Thompson /// assert!(vec_opt.is_some(), "Incorrect VectorOpt"); 63e03682afSJeremy L Thompson /// 64e03682afSJeremy L Thompson /// let vec_opt = VectorOpt::Active; 65e03682afSJeremy L Thompson /// assert!(!vec_opt.is_some(), "Incorrect VectorOpt"); 66e03682afSJeremy L Thompson /// 67e03682afSJeremy L Thompson /// let vec_opt = VectorOpt::None; 68e03682afSJeremy L Thompson /// assert!(!vec_opt.is_some(), "Incorrect VectorOpt"); 69e03682afSJeremy L Thompson /// # Ok(()) 70e03682afSJeremy L Thompson /// # } 71e03682afSJeremy L Thompson /// ``` 72e03682afSJeremy L Thompson pub fn is_some(&self) -> bool { 73e03682afSJeremy L Thompson match self { 74e03682afSJeremy L Thompson Self::Some(_) => true, 75e03682afSJeremy L Thompson Self::Active => false, 76e03682afSJeremy L Thompson Self::None => false, 77e03682afSJeremy L Thompson } 78e03682afSJeremy L Thompson } 79e03682afSJeremy L Thompson 80e03682afSJeremy L Thompson /// Check if a VectorOpt is Active 81e03682afSJeremy L Thompson /// 82e03682afSJeremy L Thompson /// ``` 83e03682afSJeremy L Thompson /// # use libceed::prelude::*; 844d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 85e03682afSJeremy L Thompson /// # let ceed = libceed::Ceed::default_init(); 86e03682afSJeremy L Thompson /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?; 87e03682afSJeremy L Thompson /// let vec_opt = VectorOpt::from(&vec); 88e03682afSJeremy L Thompson /// assert!(!vec_opt.is_active(), "Incorrect VectorOpt"); 89e03682afSJeremy L Thompson /// 90e03682afSJeremy L Thompson /// let vec_opt = VectorOpt::Active; 91e03682afSJeremy L Thompson /// assert!(vec_opt.is_active(), "Incorrect VectorOpt"); 92e03682afSJeremy L Thompson /// 93e03682afSJeremy L Thompson /// let vec_opt = VectorOpt::None; 94e03682afSJeremy L Thompson /// assert!(!vec_opt.is_active(), "Incorrect VectorOpt"); 95e03682afSJeremy L Thompson /// # Ok(()) 96e03682afSJeremy L Thompson /// # } 97e03682afSJeremy L Thompson /// ``` 98e03682afSJeremy L Thompson pub fn is_active(&self) -> bool { 99e03682afSJeremy L Thompson match self { 100e03682afSJeremy L Thompson Self::Some(_) => false, 101e03682afSJeremy L Thompson Self::Active => true, 102e03682afSJeremy L Thompson Self::None => false, 103e03682afSJeremy L Thompson } 104e03682afSJeremy L Thompson } 105e03682afSJeremy L Thompson 106e03682afSJeremy L Thompson /// Check if a VectorOpt is Some 107e03682afSJeremy L Thompson /// 108e03682afSJeremy L Thompson /// ``` 109e03682afSJeremy L Thompson /// # use libceed::prelude::*; 1104d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 111e03682afSJeremy L Thompson /// # let ceed = libceed::Ceed::default_init(); 112e03682afSJeremy L Thompson /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?; 113e03682afSJeremy L Thompson /// let vec_opt = VectorOpt::from(&vec); 114e03682afSJeremy L Thompson /// assert!(!vec_opt.is_none(), "Incorrect VectorOpt"); 115e03682afSJeremy L Thompson /// 116e03682afSJeremy L Thompson /// let vec_opt = VectorOpt::Active; 117e03682afSJeremy L Thompson /// assert!(!vec_opt.is_none(), "Incorrect VectorOpt"); 118e03682afSJeremy L Thompson /// 119e03682afSJeremy L Thompson /// let vec_opt = VectorOpt::None; 120e03682afSJeremy L Thompson /// assert!(vec_opt.is_none(), "Incorrect VectorOpt"); 121e03682afSJeremy L Thompson /// # Ok(()) 122e03682afSJeremy L Thompson /// # } 123e03682afSJeremy L Thompson /// ``` 124e03682afSJeremy L Thompson pub fn is_none(&self) -> bool { 125e03682afSJeremy L Thompson match self { 126e03682afSJeremy L Thompson Self::Some(_) => false, 127e03682afSJeremy L Thompson Self::Active => false, 128e03682afSJeremy L Thompson Self::None => true, 129e03682afSJeremy L Thompson } 130e03682afSJeremy L Thompson } 1319df49d7eSJed Brown } 1329df49d7eSJed Brown 1339df49d7eSJed Brown // ----------------------------------------------------------------------------- 13456e67e05SJeremy L Thompson // CeedVector borrowed slice wrapper 13556e67e05SJeremy L Thompson // ----------------------------------------------------------------------------- 136486868d3SJeremy L Thompson pub struct VectorSliceWrapper<'a> { 13756e67e05SJeremy L Thompson pub(crate) vector: crate::Vector<'a>, 13856e67e05SJeremy L Thompson pub(crate) _slice: &'a mut [crate::Scalar], 13956e67e05SJeremy L Thompson } 14056e67e05SJeremy L Thompson 14156e67e05SJeremy L Thompson // ----------------------------------------------------------------------------- 14256e67e05SJeremy L Thompson // Destructor 14356e67e05SJeremy L Thompson // ----------------------------------------------------------------------------- 144486868d3SJeremy L Thompson impl<'a> Drop for VectorSliceWrapper<'a> { 14556e67e05SJeremy L Thompson fn drop(&mut self) { 14656e67e05SJeremy L Thompson unsafe { 14756e67e05SJeremy L Thompson bind_ceed::CeedVectorTakeArray( 14856e67e05SJeremy L Thompson self.vector.ptr, 14956e67e05SJeremy L Thompson crate::MemType::Host as bind_ceed::CeedMemType, 15056e67e05SJeremy L Thompson std::ptr::null_mut(), 15156e67e05SJeremy L Thompson ) 15256e67e05SJeremy L Thompson }; 15356e67e05SJeremy L Thompson } 15456e67e05SJeremy L Thompson } 15556e67e05SJeremy L Thompson 15656e67e05SJeremy L Thompson // ----------------------------------------------------------------------------- 15735afbe75SJeremy L Thompson // Convenience constructor 15835afbe75SJeremy L Thompson // ----------------------------------------------------------------------------- 15935afbe75SJeremy L Thompson impl<'a> VectorSliceWrapper<'a> { 16035afbe75SJeremy L Thompson fn from_vector_and_slice_mut<'b>( 16135afbe75SJeremy L Thompson vec: &'b mut crate::Vector, 16235afbe75SJeremy L Thompson slice: &'a mut [crate::Scalar], 16335afbe75SJeremy L Thompson ) -> crate::Result<Self> { 16435afbe75SJeremy L Thompson assert_eq!(vec.length(), slice.len()); 16535afbe75SJeremy L Thompson let (host, copy_mode) = ( 16635afbe75SJeremy L Thompson crate::MemType::Host as bind_ceed::CeedMemType, 16735afbe75SJeremy L Thompson crate::CopyMode::UsePointer as bind_ceed::CeedCopyMode, 16835afbe75SJeremy L Thompson ); 16935afbe75SJeremy L Thompson let ierr = unsafe { 17035afbe75SJeremy L Thompson bind_ceed::CeedVectorSetArray( 17135afbe75SJeremy L Thompson vec.ptr, 17235afbe75SJeremy L Thompson host, 17335afbe75SJeremy L Thompson copy_mode, 17435afbe75SJeremy L Thompson slice.as_ptr() as *mut crate::Scalar, 17535afbe75SJeremy L Thompson ) 17635afbe75SJeremy L Thompson }; 17735afbe75SJeremy L Thompson vec.check_error(ierr)?; 17835afbe75SJeremy L Thompson 17935afbe75SJeremy L Thompson Ok(Self { 180*e46a712dSJeremy L Thompson vector: crate::Vector::from_raw(vec.ptr_copy_mut()?)?, 18135afbe75SJeremy L Thompson _slice: slice, 18235afbe75SJeremy L Thompson }) 18335afbe75SJeremy L Thompson } 18435afbe75SJeremy L Thompson } 18535afbe75SJeremy L Thompson 18635afbe75SJeremy L Thompson // ----------------------------------------------------------------------------- 1879df49d7eSJed Brown // CeedVector context wrapper 1889df49d7eSJed Brown // ----------------------------------------------------------------------------- 1899df49d7eSJed Brown #[derive(Debug)] 1909df49d7eSJed Brown pub struct Vector<'a> { 1919df49d7eSJed Brown pub(crate) ptr: bind_ceed::CeedVector, 1921142270cSJeremy L Thompson _lifeline: PhantomData<&'a ()>, 1939df49d7eSJed Brown } 1949df49d7eSJed Brown impl From<&'_ Vector<'_>> for bind_ceed::CeedVector { 1959df49d7eSJed Brown fn from(vec: &Vector) -> Self { 1969df49d7eSJed Brown vec.ptr 1979df49d7eSJed Brown } 1989df49d7eSJed Brown } 1999df49d7eSJed Brown 2009df49d7eSJed Brown // ----------------------------------------------------------------------------- 2019df49d7eSJed Brown // Destructor 2029df49d7eSJed Brown // ----------------------------------------------------------------------------- 2039df49d7eSJed Brown impl<'a> Drop for Vector<'a> { 2049df49d7eSJed Brown fn drop(&mut self) { 2059df49d7eSJed Brown let not_none_and_active = self.ptr != unsafe { bind_ceed::CEED_VECTOR_NONE } 2069df49d7eSJed Brown && self.ptr != unsafe { bind_ceed::CEED_VECTOR_ACTIVE }; 2079df49d7eSJed Brown 2089df49d7eSJed Brown if not_none_and_active { 2099df49d7eSJed Brown unsafe { bind_ceed::CeedVectorDestroy(&mut self.ptr) }; 2109df49d7eSJed Brown } 2119df49d7eSJed Brown } 2129df49d7eSJed Brown } 2139df49d7eSJed Brown 2149df49d7eSJed Brown // ----------------------------------------------------------------------------- 2159df49d7eSJed Brown // Display 2169df49d7eSJed Brown // ----------------------------------------------------------------------------- 2179df49d7eSJed Brown impl<'a> fmt::Display for Vector<'a> { 2189df49d7eSJed Brown /// View a Vector 2199df49d7eSJed Brown /// 2209df49d7eSJed Brown /// ``` 2219df49d7eSJed Brown /// # use libceed::prelude::*; 2224d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 2239df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 224c68be7a2SJeremy L Thompson /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?; 2259df49d7eSJed Brown /// assert_eq!( 2269df49d7eSJed Brown /// vec.to_string(), 2279df49d7eSJed Brown /// "CeedVector length 3 2289df49d7eSJed Brown /// 1.00000000 2299df49d7eSJed Brown /// 2.00000000 2309df49d7eSJed Brown /// 3.00000000 2319df49d7eSJed Brown /// " 232c68be7a2SJeremy L Thompson /// ); 233c68be7a2SJeremy L Thompson /// # Ok(()) 234c68be7a2SJeremy L Thompson /// # } 2359df49d7eSJed Brown /// ``` 2369df49d7eSJed Brown fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 2379df49d7eSJed Brown let mut ptr = std::ptr::null_mut(); 2389df49d7eSJed Brown let mut sizeloc = crate::MAX_BUFFER_LENGTH; 2399df49d7eSJed Brown let format = CString::new("%12.8f").expect("CString::new failed"); 2409df49d7eSJed Brown let format_c: *const c_char = format.into_raw(); 2419df49d7eSJed Brown let cstring = unsafe { 2429df49d7eSJed Brown let file = bind_ceed::open_memstream(&mut ptr, &mut sizeloc); 2439df49d7eSJed Brown bind_ceed::CeedVectorView(self.ptr, format_c, file); 2449df49d7eSJed Brown bind_ceed::fclose(file); 2459df49d7eSJed Brown CString::from_raw(ptr) 2469df49d7eSJed Brown }; 2479df49d7eSJed Brown cstring.to_string_lossy().fmt(f) 2489df49d7eSJed Brown } 2499df49d7eSJed Brown } 2509df49d7eSJed Brown 2519df49d7eSJed Brown // ----------------------------------------------------------------------------- 2529df49d7eSJed Brown // Implementations 2539df49d7eSJed Brown // ----------------------------------------------------------------------------- 2549df49d7eSJed Brown impl<'a> Vector<'a> { 2559df49d7eSJed Brown // Constructors 2569df49d7eSJed Brown pub fn create(ceed: &'a crate::Ceed, n: usize) -> crate::Result<Self> { 2579df49d7eSJed Brown let n = i32::try_from(n).unwrap(); 2589df49d7eSJed Brown let mut ptr = std::ptr::null_mut(); 2599df49d7eSJed Brown let ierr = unsafe { bind_ceed::CeedVectorCreate(ceed.ptr, n, &mut ptr) }; 2609df49d7eSJed Brown ceed.check_error(ierr)?; 2611142270cSJeremy L Thompson Ok(Self { 2621142270cSJeremy L Thompson ptr, 2631142270cSJeremy L Thompson _lifeline: PhantomData, 2641142270cSJeremy L Thompson }) 2659df49d7eSJed Brown } 2669df49d7eSJed Brown 2671142270cSJeremy L Thompson pub(crate) fn from_raw(ptr: bind_ceed::CeedVector) -> crate::Result<Self> { 2681142270cSJeremy L Thompson Ok(Self { 2691142270cSJeremy L Thompson ptr, 2701142270cSJeremy L Thompson _lifeline: PhantomData, 2711142270cSJeremy L Thompson }) 2729df49d7eSJed Brown } 2739df49d7eSJed Brown 274*e46a712dSJeremy L Thompson fn ptr_copy_mut(&mut self) -> crate::Result<bind_ceed::CeedVector> { 275*e46a712dSJeremy L Thompson let mut ptr_copy = std::ptr::null_mut(); 276*e46a712dSJeremy L Thompson let ierr = unsafe { bind_ceed::CeedVectorReferenceCopy(self.ptr, &mut ptr_copy) }; 277*e46a712dSJeremy L Thompson self.check_error(ierr)?; 278*e46a712dSJeremy L Thompson Ok(ptr_copy) 279*e46a712dSJeremy L Thompson } 280*e46a712dSJeremy L Thompson 2819df49d7eSJed Brown /// Create a Vector from a slice 2829df49d7eSJed Brown /// 2839df49d7eSJed Brown /// # arguments 2849df49d7eSJed Brown /// 2859df49d7eSJed Brown /// * `slice` - values to initialize vector with 2869df49d7eSJed Brown /// 2879df49d7eSJed Brown /// ``` 2889df49d7eSJed Brown /// # use libceed::prelude::*; 2894d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 2909df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 291c68be7a2SJeremy L Thompson /// let vec = vector::Vector::from_slice(&ceed, &[1., 2., 3.])?; 2929df49d7eSJed Brown /// assert_eq!(vec.length(), 3, "Incorrect length from slice"); 293c68be7a2SJeremy L Thompson /// # Ok(()) 294c68be7a2SJeremy L Thompson /// # } 2959df49d7eSJed Brown /// ``` 29680a9ef05SNatalie Beams pub fn from_slice(ceed: &'a crate::Ceed, v: &[crate::Scalar]) -> crate::Result<Self> { 2979df49d7eSJed Brown let mut x = Self::create(ceed, v.len())?; 2989df49d7eSJed Brown x.set_slice(v)?; 2999df49d7eSJed Brown Ok(x) 3009df49d7eSJed Brown } 3019df49d7eSJed Brown 3029df49d7eSJed Brown /// Create a Vector from a mutable array reference 3039df49d7eSJed Brown /// 3049df49d7eSJed Brown /// # arguments 3059df49d7eSJed Brown /// 3069df49d7eSJed Brown /// * `slice` - values to initialize vector with 3079df49d7eSJed Brown /// 3089df49d7eSJed Brown /// ``` 3099df49d7eSJed Brown /// # use libceed::prelude::*; 3104d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 3119df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 3129df49d7eSJed Brown /// let mut rust_vec = vec![1., 2., 3.]; 313c68be7a2SJeremy L Thompson /// let vec = libceed::vector::Vector::from_array(&ceed, &mut rust_vec)?; 3149df49d7eSJed Brown /// 3159df49d7eSJed Brown /// assert_eq!(vec.length(), 3, "Incorrect length from slice"); 316c68be7a2SJeremy L Thompson /// # Ok(()) 317c68be7a2SJeremy L Thompson /// # } 3189df49d7eSJed Brown /// ``` 31980a9ef05SNatalie Beams pub fn from_array(ceed: &'a crate::Ceed, v: &mut [crate::Scalar]) -> crate::Result<Self> { 3209df49d7eSJed Brown let x = Self::create(ceed, v.len())?; 3219df49d7eSJed Brown let (host, user_pointer) = ( 3229df49d7eSJed Brown crate::MemType::Host as bind_ceed::CeedMemType, 3239df49d7eSJed Brown crate::CopyMode::UsePointer as bind_ceed::CeedCopyMode, 3249df49d7eSJed Brown ); 32580a9ef05SNatalie Beams let v = v.as_ptr() as *mut crate::Scalar; 3269df49d7eSJed Brown let ierr = unsafe { bind_ceed::CeedVectorSetArray(x.ptr, host, user_pointer, v) }; 3279df49d7eSJed Brown ceed.check_error(ierr)?; 3289df49d7eSJed Brown Ok(x) 3299df49d7eSJed Brown } 3309df49d7eSJed Brown 3311142270cSJeremy L Thompson // Error handling 3321142270cSJeremy L Thompson #[doc(hidden)] 3331142270cSJeremy L Thompson fn check_error(&self, ierr: i32) -> crate::Result<i32> { 3341142270cSJeremy L Thompson let mut ptr = std::ptr::null_mut(); 3351142270cSJeremy L Thompson unsafe { 3361142270cSJeremy L Thompson bind_ceed::CeedVectorGetCeed(self.ptr, &mut ptr); 3371142270cSJeremy L Thompson } 3381142270cSJeremy L Thompson crate::check_error(ptr, ierr) 3391142270cSJeremy L Thompson } 3401142270cSJeremy L Thompson 3419df49d7eSJed Brown /// Returns the length of a CeedVector 3429df49d7eSJed Brown /// 3439df49d7eSJed Brown /// ``` 3449df49d7eSJed Brown /// # use libceed::prelude::*; 3454d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 3469df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 347c68be7a2SJeremy L Thompson /// let vec = ceed.vector(10)?; 3489df49d7eSJed Brown /// 3499df49d7eSJed Brown /// let n = vec.length(); 3509df49d7eSJed Brown /// assert_eq!(n, 10, "Incorrect length"); 351c68be7a2SJeremy L Thompson /// # Ok(()) 352c68be7a2SJeremy L Thompson /// # } 3539df49d7eSJed Brown /// ``` 3549df49d7eSJed Brown pub fn length(&self) -> usize { 3559df49d7eSJed Brown let mut n = 0; 3569df49d7eSJed Brown unsafe { bind_ceed::CeedVectorGetLength(self.ptr, &mut n) }; 3579df49d7eSJed Brown usize::try_from(n).unwrap() 3589df49d7eSJed Brown } 3599df49d7eSJed Brown 3609df49d7eSJed Brown /// Returns the length of a CeedVector 3619df49d7eSJed Brown /// 3629df49d7eSJed Brown /// ``` 3639df49d7eSJed Brown /// # use libceed::prelude::*; 3644d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 3659df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 366c68be7a2SJeremy L Thompson /// let vec = ceed.vector(10)?; 3679df49d7eSJed Brown /// assert_eq!(vec.len(), 10, "Incorrect length"); 368c68be7a2SJeremy L Thompson /// # Ok(()) 369c68be7a2SJeremy L Thompson /// # } 3709df49d7eSJed Brown /// ``` 3719df49d7eSJed Brown pub fn len(&self) -> usize { 3729df49d7eSJed Brown self.length() 3739df49d7eSJed Brown } 3749df49d7eSJed Brown 3759df49d7eSJed Brown /// Set the CeedVector to a constant value 3769df49d7eSJed Brown /// 3779df49d7eSJed Brown /// # arguments 3789df49d7eSJed Brown /// 3799df49d7eSJed Brown /// * `val` - Value to be used 3809df49d7eSJed Brown /// 3819df49d7eSJed Brown /// ``` 3829df49d7eSJed Brown /// # use libceed::prelude::*; 3834d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 3849df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 3859df49d7eSJed Brown /// let len = 10; 386c68be7a2SJeremy L Thompson /// let mut vec = ceed.vector(len)?; 3879df49d7eSJed Brown /// 3889df49d7eSJed Brown /// let val = 42.0; 389c68be7a2SJeremy L Thompson /// vec.set_value(val)?; 3909df49d7eSJed Brown /// 391d3677ae8SJeremy L Thompson /// for v in vec.view()?.iter() { 3929df49d7eSJed Brown /// assert_eq!(*v, val, "Value not set correctly"); 393d3677ae8SJeremy L Thompson /// } 394c68be7a2SJeremy L Thompson /// # Ok(()) 395c68be7a2SJeremy L Thompson /// # } 3969df49d7eSJed Brown /// ``` 39780a9ef05SNatalie Beams pub fn set_value(&mut self, value: crate::Scalar) -> crate::Result<i32> { 3989df49d7eSJed Brown let ierr = unsafe { bind_ceed::CeedVectorSetValue(self.ptr, value) }; 3991142270cSJeremy L Thompson self.check_error(ierr) 4009df49d7eSJed Brown } 4019df49d7eSJed Brown 4029df49d7eSJed Brown /// Set values from a slice of the same length 4039df49d7eSJed Brown /// 4049df49d7eSJed Brown /// # arguments 4059df49d7eSJed Brown /// 4069df49d7eSJed Brown /// * `slice` - values to into self; length must match 4079df49d7eSJed Brown /// 4089df49d7eSJed Brown /// ``` 4099df49d7eSJed Brown /// # use libceed::prelude::*; 4104d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 4119df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 412c68be7a2SJeremy L Thompson /// let mut vec = ceed.vector(4)?; 413c68be7a2SJeremy L Thompson /// vec.set_slice(&[10., 11., 12., 13.])?; 4149df49d7eSJed Brown /// 415d3677ae8SJeremy L Thompson /// for (i, v) in vec.view()?.iter().enumerate() { 41680a9ef05SNatalie Beams /// assert_eq!(*v, 10. + i as Scalar, "Slice not set correctly"); 417d3677ae8SJeremy L Thompson /// } 418c68be7a2SJeremy L Thompson /// # Ok(()) 419c68be7a2SJeremy L Thompson /// # } 4209df49d7eSJed Brown /// ``` 42180a9ef05SNatalie Beams pub fn set_slice(&mut self, slice: &[crate::Scalar]) -> crate::Result<i32> { 4229df49d7eSJed Brown assert_eq!(self.length(), slice.len()); 4239df49d7eSJed Brown let (host, copy_mode) = ( 4249df49d7eSJed Brown crate::MemType::Host as bind_ceed::CeedMemType, 4259df49d7eSJed Brown crate::CopyMode::CopyValues as bind_ceed::CeedCopyMode, 4269df49d7eSJed Brown ); 4279df49d7eSJed Brown let ierr = unsafe { 42880a9ef05SNatalie Beams bind_ceed::CeedVectorSetArray( 42980a9ef05SNatalie Beams self.ptr, 43080a9ef05SNatalie Beams host, 43180a9ef05SNatalie Beams copy_mode, 43280a9ef05SNatalie Beams slice.as_ptr() as *mut crate::Scalar, 43380a9ef05SNatalie Beams ) 4349df49d7eSJed Brown }; 4351142270cSJeremy L Thompson self.check_error(ierr) 4369df49d7eSJed Brown } 4379df49d7eSJed Brown 438486868d3SJeremy L Thompson /// Wrap a mutable slice in a Vector of the same length 43956e67e05SJeremy L Thompson /// 44056e67e05SJeremy L Thompson /// # arguments 44156e67e05SJeremy L Thompson /// 442486868d3SJeremy L Thompson /// * `slice` - values to wrap in self; length must match 44356e67e05SJeremy L Thompson /// 44456e67e05SJeremy L Thompson /// ``` 44556e67e05SJeremy L Thompson /// # use libceed::prelude::*; 44656e67e05SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 44756e67e05SJeremy L Thompson /// # let ceed = libceed::Ceed::default_init(); 44856e67e05SJeremy L Thompson /// let mut vec = ceed.vector(4)?; 449486868d3SJeremy L Thompson /// let mut array = [10., 11., 12., 13.]; 45056e67e05SJeremy L Thompson /// 45156e67e05SJeremy L Thompson /// { 452486868d3SJeremy L Thompson /// // `wrapper` holds a mutable reference to the wrapped slice 453486868d3SJeremy L Thompson /// // that is dropped when `wrapper` goes out of scope 454486868d3SJeremy L Thompson /// let wrapper = vec.wrap_slice_mut(&mut array)?; 455d3677ae8SJeremy L Thompson /// for (i, v) in vec.view()?.iter().enumerate() { 45656e67e05SJeremy L Thompson /// assert_eq!(*v, 10. + i as Scalar, "Slice not set correctly"); 457d3677ae8SJeremy L Thompson /// } 45856e67e05SJeremy L Thompson /// 459486868d3SJeremy L Thompson /// // This line will not compile, as the `wrapper` holds mutable 460486868d3SJeremy L Thompson /// // access to the `array` 461486868d3SJeremy L Thompson /// // array[0] = 5.0; 46256e67e05SJeremy L Thompson /// 463486868d3SJeremy L Thompson /// // Changes here are reflected in the `array` 46456e67e05SJeremy L Thompson /// vec.set_value(5.0)?; 465d3677ae8SJeremy L Thompson /// for v in vec.view()?.iter() { 466486868d3SJeremy L Thompson /// assert_eq!(*v, 5.0 as Scalar, "Value not set correctly"); 467d3677ae8SJeremy L Thompson /// } 46856e67e05SJeremy L Thompson /// } 46956e67e05SJeremy L Thompson /// 470486868d3SJeremy L Thompson /// // 'array' remains changed 471d3677ae8SJeremy L Thompson /// for v in array.iter() { 472486868d3SJeremy L Thompson /// assert_eq!(*v, 5.0 as Scalar, "Array not mutated correctly"); 473d3677ae8SJeremy L Thompson /// } 47456e67e05SJeremy L Thompson /// 475486868d3SJeremy L Thompson /// // While changes to `vec` no longer affect `array` 476486868d3SJeremy L Thompson /// vec.set_value(6.0)?; 477d3677ae8SJeremy L Thompson /// for v in array.iter() { 478486868d3SJeremy L Thompson /// assert_eq!(*v, 5.0 as Scalar, "Array mutated without permission"); 479d3677ae8SJeremy L Thompson /// } 48056e67e05SJeremy L Thompson /// # Ok(()) 48156e67e05SJeremy L Thompson /// # } 48256e67e05SJeremy L Thompson /// ``` 483486868d3SJeremy L Thompson pub fn wrap_slice_mut<'b>( 48456e67e05SJeremy L Thompson &mut self, 48556e67e05SJeremy L Thompson slice: &'b mut [crate::Scalar], 486486868d3SJeremy L Thompson ) -> crate::Result<VectorSliceWrapper<'b>> { 48735afbe75SJeremy L Thompson crate::VectorSliceWrapper::from_vector_and_slice_mut(self, slice) 48856e67e05SJeremy L Thompson } 48956e67e05SJeremy L Thompson 4909df49d7eSJed Brown /// Sync the CeedVector to a specified memtype 4919df49d7eSJed Brown /// 4929df49d7eSJed Brown /// # arguments 4939df49d7eSJed Brown /// 4949df49d7eSJed Brown /// * `mtype` - Memtype to be synced 4959df49d7eSJed Brown /// 4969df49d7eSJed Brown /// ``` 4979df49d7eSJed Brown /// # use libceed::prelude::*; 4984d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 4999df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 5009df49d7eSJed Brown /// let len = 10; 501c68be7a2SJeremy L Thompson /// let mut vec = ceed.vector(len)?; 5029df49d7eSJed Brown /// 5039df49d7eSJed Brown /// let val = 42.0; 5049df49d7eSJed Brown /// vec.set_value(val); 505c68be7a2SJeremy L Thompson /// vec.sync(MemType::Host)?; 5069df49d7eSJed Brown /// 507d3677ae8SJeremy L Thompson /// for v in vec.view()?.iter() { 5089df49d7eSJed Brown /// assert_eq!(*v, val, "Value not set correctly"); 509d3677ae8SJeremy L Thompson /// } 510c68be7a2SJeremy L Thompson /// # Ok(()) 511c68be7a2SJeremy L Thompson /// # } 5129df49d7eSJed Brown /// ``` 5139df49d7eSJed Brown pub fn sync(&self, mtype: crate::MemType) -> crate::Result<i32> { 5149df49d7eSJed Brown let ierr = 5159df49d7eSJed Brown unsafe { bind_ceed::CeedVectorSyncArray(self.ptr, mtype as bind_ceed::CeedMemType) }; 5161142270cSJeremy L Thompson self.check_error(ierr) 5179df49d7eSJed Brown } 5189df49d7eSJed Brown 5199df49d7eSJed Brown /// Create an immutable view 5209df49d7eSJed Brown /// 5219df49d7eSJed Brown /// ``` 5229df49d7eSJed Brown /// # use libceed::prelude::*; 5234d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 5249df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 525c68be7a2SJeremy L Thompson /// let vec = ceed.vector_from_slice(&[10., 11., 12., 13.])?; 5269df49d7eSJed Brown /// 527e78171edSJeremy L Thompson /// let v = vec.view()?; 5289df49d7eSJed Brown /// assert_eq!(v[0..2], [10., 11.]); 5299df49d7eSJed Brown /// 5309df49d7eSJed Brown /// // It is valid to have multiple immutable views 531e78171edSJeremy L Thompson /// let w = vec.view()?; 5329df49d7eSJed Brown /// assert_eq!(v[1..], w[1..]); 533c68be7a2SJeremy L Thompson /// # Ok(()) 534c68be7a2SJeremy L Thompson /// # } 5359df49d7eSJed Brown /// ``` 536e78171edSJeremy L Thompson pub fn view(&self) -> crate::Result<VectorView> { 5379df49d7eSJed Brown VectorView::new(self) 5389df49d7eSJed Brown } 5399df49d7eSJed Brown 5409df49d7eSJed Brown /// Create an mutable view 5419df49d7eSJed Brown /// 5429df49d7eSJed Brown /// ``` 5439df49d7eSJed Brown /// # use libceed::prelude::*; 5444d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 5459df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 546c68be7a2SJeremy L Thompson /// let mut vec = ceed.vector_from_slice(&[10., 11., 12., 13.])?; 5479df49d7eSJed Brown /// 5489df49d7eSJed Brown /// { 549e78171edSJeremy L Thompson /// let mut v = vec.view_mut()?; 5509df49d7eSJed Brown /// v[2] = 9.; 5519df49d7eSJed Brown /// } 5529df49d7eSJed Brown /// 553e78171edSJeremy L Thompson /// let w = vec.view()?; 5549df49d7eSJed Brown /// assert_eq!(w[2], 9., "View did not mutate data"); 555c68be7a2SJeremy L Thompson /// # Ok(()) 556c68be7a2SJeremy L Thompson /// # } 5579df49d7eSJed Brown /// ``` 558e78171edSJeremy L Thompson pub fn view_mut(&mut self) -> crate::Result<VectorViewMut> { 5599df49d7eSJed Brown VectorViewMut::new(self) 5609df49d7eSJed Brown } 5619df49d7eSJed Brown 5629df49d7eSJed Brown /// Return the norm of a CeedVector 5639df49d7eSJed Brown /// 5649df49d7eSJed Brown /// # arguments 5659df49d7eSJed Brown /// 5669df49d7eSJed Brown /// * `ntype` - Norm type One, Two, or Max 5679df49d7eSJed Brown /// 5689df49d7eSJed Brown /// ``` 5699df49d7eSJed Brown /// # use libceed::prelude::*; 5704d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 5719df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 572c68be7a2SJeremy L Thompson /// let vec = ceed.vector_from_slice(&[1., 2., 3., 4.])?; 5739df49d7eSJed Brown /// 574c68be7a2SJeremy L Thompson /// let max_norm = vec.norm(NormType::Max)?; 5759df49d7eSJed Brown /// assert_eq!(max_norm, 4.0, "Incorrect Max norm"); 5769df49d7eSJed Brown /// 577c68be7a2SJeremy L Thompson /// let l1_norm = vec.norm(NormType::One)?; 5789df49d7eSJed Brown /// assert_eq!(l1_norm, 10., "Incorrect L1 norm"); 5799df49d7eSJed Brown /// 580c68be7a2SJeremy L Thompson /// let l2_norm = vec.norm(NormType::Two)?; 5819df49d7eSJed Brown /// assert!((l2_norm - 5.477) < 1e-3, "Incorrect L2 norm"); 582c68be7a2SJeremy L Thompson /// # Ok(()) 583c68be7a2SJeremy L Thompson /// # } 5849df49d7eSJed Brown /// ``` 58580a9ef05SNatalie Beams pub fn norm(&self, ntype: crate::NormType) -> crate::Result<crate::Scalar> { 58680a9ef05SNatalie Beams let mut res: crate::Scalar = 0.0; 5879df49d7eSJed Brown let ierr = unsafe { 5889df49d7eSJed Brown bind_ceed::CeedVectorNorm(self.ptr, ntype as bind_ceed::CeedNormType, &mut res) 5899df49d7eSJed Brown }; 5901142270cSJeremy L Thompson self.check_error(ierr)?; 5919df49d7eSJed Brown Ok(res) 5929df49d7eSJed Brown } 5939df49d7eSJed Brown 5949df49d7eSJed Brown /// Compute x = alpha x for a CeedVector 5959df49d7eSJed Brown /// 5969df49d7eSJed Brown /// # arguments 5979df49d7eSJed Brown /// 5989df49d7eSJed Brown /// * `alpha` - scaling factor 5999df49d7eSJed Brown /// 6009df49d7eSJed Brown /// ``` 6019df49d7eSJed Brown /// # use libceed::prelude::*; 6024d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 6039df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 604c68be7a2SJeremy L Thompson /// let mut vec = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 6059df49d7eSJed Brown /// 606c68be7a2SJeremy L Thompson /// vec = vec.scale(-1.0)?; 607d3677ae8SJeremy L Thompson /// for (i, v) in vec.view()?.iter().enumerate() { 608d3677ae8SJeremy L Thompson /// assert_eq!(*v, -(i as Scalar), "Value not set correctly"); 609d3677ae8SJeremy L Thompson /// } 610c68be7a2SJeremy L Thompson /// # Ok(()) 611c68be7a2SJeremy L Thompson /// # } 6129df49d7eSJed Brown /// ``` 6139df49d7eSJed Brown #[allow(unused_mut)] 61480a9ef05SNatalie Beams pub fn scale(mut self, alpha: crate::Scalar) -> crate::Result<Self> { 6159df49d7eSJed Brown let ierr = unsafe { bind_ceed::CeedVectorScale(self.ptr, alpha) }; 6161142270cSJeremy L Thompson self.check_error(ierr)?; 6179df49d7eSJed Brown Ok(self) 6189df49d7eSJed Brown } 6199df49d7eSJed Brown 6209df49d7eSJed Brown /// Compute y = alpha x + y for a pair of CeedVectors 6219df49d7eSJed Brown /// 6229df49d7eSJed Brown /// # arguments 6239df49d7eSJed Brown /// 6249df49d7eSJed Brown /// * `alpha` - scaling factor 6259df49d7eSJed Brown /// * `x` - second vector, must be different than self 6269df49d7eSJed Brown /// 6279df49d7eSJed Brown /// ``` 6289df49d7eSJed Brown /// # use libceed::prelude::*; 6294d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 6309df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 631c68be7a2SJeremy L Thompson /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 632c68be7a2SJeremy L Thompson /// let mut y = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 6339df49d7eSJed Brown /// 634c68be7a2SJeremy L Thompson /// y = y.axpy(-0.5, &x)?; 635d3677ae8SJeremy L Thompson /// for (i, y) in y.view()?.iter().enumerate() { 636d3677ae8SJeremy L Thompson /// assert_eq!(*y, (i as Scalar) / 2.0, "Value not set correctly"); 637d3677ae8SJeremy L Thompson /// } 638c68be7a2SJeremy L Thompson /// # Ok(()) 639c68be7a2SJeremy L Thompson /// # } 6409df49d7eSJed Brown /// ``` 6419df49d7eSJed Brown #[allow(unused_mut)] 64280a9ef05SNatalie Beams pub fn axpy(mut self, alpha: crate::Scalar, x: &crate::Vector) -> crate::Result<Self> { 6439df49d7eSJed Brown let ierr = unsafe { bind_ceed::CeedVectorAXPY(self.ptr, alpha, x.ptr) }; 6441142270cSJeremy L Thompson self.check_error(ierr)?; 6459df49d7eSJed Brown Ok(self) 6469df49d7eSJed Brown } 6479df49d7eSJed Brown 6489df49d7eSJed Brown /// Compute the pointwise multiplication w = x .* y for CeedVectors 6499df49d7eSJed Brown /// 6509df49d7eSJed Brown /// # arguments 6519df49d7eSJed Brown /// 6529df49d7eSJed Brown /// * `x` - first vector for product 6539df49d7eSJed Brown /// * `y` - second vector for product 6549df49d7eSJed Brown /// 6559df49d7eSJed Brown /// ``` 6569df49d7eSJed Brown /// # use libceed::prelude::*; 6574d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 6589df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 659c68be7a2SJeremy L Thompson /// let mut w = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 660c68be7a2SJeremy L Thompson /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 661c68be7a2SJeremy L Thompson /// let y = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 6629df49d7eSJed Brown /// 663c68be7a2SJeremy L Thompson /// w = w.pointwise_mult(&x, &y)?; 664d3677ae8SJeremy L Thompson /// for (i, w) in w.view()?.iter().enumerate() { 665d3677ae8SJeremy L Thompson /// assert_eq!(*w, (i as Scalar).powf(2.0), "Value not set correctly"); 666d3677ae8SJeremy L Thompson /// } 667c68be7a2SJeremy L Thompson /// # Ok(()) 668c68be7a2SJeremy L Thompson /// # } 6699df49d7eSJed Brown /// ``` 6709df49d7eSJed Brown #[allow(unused_mut)] 6719df49d7eSJed Brown pub fn pointwise_mult(mut self, x: &crate::Vector, y: &crate::Vector) -> crate::Result<Self> { 6729df49d7eSJed Brown let ierr = unsafe { bind_ceed::CeedVectorPointwiseMult(self.ptr, x.ptr, y.ptr) }; 6731142270cSJeremy L Thompson self.check_error(ierr)?; 6749df49d7eSJed Brown Ok(self) 6759df49d7eSJed Brown } 6769df49d7eSJed Brown 6779df49d7eSJed Brown /// Compute the pointwise multiplication w = w .* x for CeedVectors 6789df49d7eSJed Brown /// 6799df49d7eSJed Brown /// # arguments 6809df49d7eSJed Brown /// 6819df49d7eSJed Brown /// * `x` - second vector for product 6829df49d7eSJed Brown /// 6839df49d7eSJed Brown /// ``` 6849df49d7eSJed Brown /// # use libceed::prelude::*; 6854d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 6869df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 687c68be7a2SJeremy L Thompson /// let mut w = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 688c68be7a2SJeremy L Thompson /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 6899df49d7eSJed Brown /// 690c68be7a2SJeremy L Thompson /// w = w.pointwise_scale(&x)?; 691d3677ae8SJeremy L Thompson /// for (i, w) in w.view()?.iter().enumerate() { 692d3677ae8SJeremy L Thompson /// assert_eq!(*w, (i as Scalar).powf(2.0), "Value not set correctly"); 693d3677ae8SJeremy L Thompson /// } 694c68be7a2SJeremy L Thompson /// # Ok(()) 695c68be7a2SJeremy L Thompson /// # } 6969df49d7eSJed Brown /// ``` 6979df49d7eSJed Brown #[allow(unused_mut)] 6989df49d7eSJed Brown pub fn pointwise_scale(mut self, x: &crate::Vector) -> crate::Result<Self> { 6999df49d7eSJed Brown let ierr = unsafe { bind_ceed::CeedVectorPointwiseMult(self.ptr, self.ptr, x.ptr) }; 7001142270cSJeremy L Thompson self.check_error(ierr)?; 7019df49d7eSJed Brown Ok(self) 7029df49d7eSJed Brown } 7039df49d7eSJed Brown 7049df49d7eSJed Brown /// Compute the pointwise multiplication w = w .* w for a CeedVector 7059df49d7eSJed Brown /// 7069df49d7eSJed Brown /// ``` 7079df49d7eSJed Brown /// # use libceed::prelude::*; 7084d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 7099df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 710c68be7a2SJeremy L Thompson /// let mut w = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 7119df49d7eSJed Brown /// 712c68be7a2SJeremy L Thompson /// w = w.pointwise_square()?; 713d3677ae8SJeremy L Thompson /// for (i, w) in w.view()?.iter().enumerate() { 714d3677ae8SJeremy L Thompson /// assert_eq!(*w, (i as Scalar).powf(2.0), "Value not set correctly"); 715d3677ae8SJeremy L Thompson /// } 716c68be7a2SJeremy L Thompson /// # Ok(()) 717c68be7a2SJeremy L Thompson /// # } 7189df49d7eSJed Brown /// ``` 7199df49d7eSJed Brown #[allow(unused_mut)] 7209df49d7eSJed Brown pub fn pointwise_square(mut self) -> crate::Result<Self> { 7219df49d7eSJed Brown let ierr = unsafe { bind_ceed::CeedVectorPointwiseMult(self.ptr, self.ptr, self.ptr) }; 7221142270cSJeremy L Thompson self.check_error(ierr)?; 7239df49d7eSJed Brown Ok(self) 7249df49d7eSJed Brown } 7259df49d7eSJed Brown } 7269df49d7eSJed Brown 7279df49d7eSJed Brown // ----------------------------------------------------------------------------- 7289df49d7eSJed Brown // Vector Viewer 7299df49d7eSJed Brown // ----------------------------------------------------------------------------- 7309df49d7eSJed Brown /// A (host) view of a Vector with Deref to slice. We can't make 7319df49d7eSJed Brown /// Vector itself Deref to slice because we can't handle the drop to 7329df49d7eSJed Brown /// call bind_ceed::CeedVectorRestoreArrayRead(). 7339df49d7eSJed Brown #[derive(Debug)] 7349df49d7eSJed Brown pub struct VectorView<'a> { 7359df49d7eSJed Brown vec: &'a Vector<'a>, 73680a9ef05SNatalie Beams array: *const crate::Scalar, 7379df49d7eSJed Brown } 7389df49d7eSJed Brown 7399df49d7eSJed Brown impl<'a> VectorView<'a> { 7409df49d7eSJed Brown /// Construct a VectorView from a Vector reference 7414d27c890SJeremy L Thompson fn new(vec: &'a Vector) -> crate::Result<Self> { 7429df49d7eSJed Brown let mut array = std::ptr::null(); 743e78171edSJeremy L Thompson let ierr = unsafe { 7449df49d7eSJed Brown bind_ceed::CeedVectorGetArrayRead( 7459df49d7eSJed Brown vec.ptr, 7469df49d7eSJed Brown crate::MemType::Host as bind_ceed::CeedMemType, 7479df49d7eSJed Brown &mut array, 748e78171edSJeremy L Thompson ) 749e78171edSJeremy L Thompson }; 750e78171edSJeremy L Thompson vec.check_error(ierr)?; 751e78171edSJeremy L Thompson Ok(Self { 7529df49d7eSJed Brown vec: vec, 7539df49d7eSJed Brown array: array, 754e78171edSJeremy L Thompson }) 7559df49d7eSJed Brown } 7569df49d7eSJed Brown } 7579df49d7eSJed Brown 7589df49d7eSJed Brown // Destructor 7599df49d7eSJed Brown impl<'a> Drop for VectorView<'a> { 7609df49d7eSJed Brown fn drop(&mut self) { 7619df49d7eSJed Brown unsafe { 7629df49d7eSJed Brown bind_ceed::CeedVectorRestoreArrayRead(self.vec.ptr, &mut self.array); 7639df49d7eSJed Brown } 7649df49d7eSJed Brown } 7659df49d7eSJed Brown } 7669df49d7eSJed Brown 7679df49d7eSJed Brown // Data access 7689df49d7eSJed Brown impl<'a> Deref for VectorView<'a> { 76980a9ef05SNatalie Beams type Target = [crate::Scalar]; 77080a9ef05SNatalie Beams fn deref(&self) -> &[crate::Scalar] { 7719df49d7eSJed Brown unsafe { std::slice::from_raw_parts(self.array, self.vec.len()) } 7729df49d7eSJed Brown } 7739df49d7eSJed Brown } 7749df49d7eSJed Brown 7759df49d7eSJed Brown // Viewing 7769df49d7eSJed Brown impl<'a> fmt::Display for VectorView<'a> { 7779df49d7eSJed Brown fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 7789df49d7eSJed Brown write!(f, "VectorView({:?})", self.deref()) 7799df49d7eSJed Brown } 7809df49d7eSJed Brown } 7819df49d7eSJed Brown 7829df49d7eSJed Brown // ----------------------------------------------------------------------------- 7839df49d7eSJed Brown // Vector Viewer Mutable 7849df49d7eSJed Brown // ----------------------------------------------------------------------------- 7859df49d7eSJed Brown /// A mutable (host) view of a Vector with Deref to slice. 7869df49d7eSJed Brown #[derive(Debug)] 7879df49d7eSJed Brown pub struct VectorViewMut<'a> { 7889df49d7eSJed Brown vec: &'a Vector<'a>, 78980a9ef05SNatalie Beams array: *mut crate::Scalar, 7909df49d7eSJed Brown } 7919df49d7eSJed Brown 7929df49d7eSJed Brown impl<'a> VectorViewMut<'a> { 7939df49d7eSJed Brown /// Construct a VectorViewMut from a Vector reference 7944d27c890SJeremy L Thompson fn new(vec: &'a mut Vector) -> crate::Result<Self> { 7959df49d7eSJed Brown let mut ptr = std::ptr::null_mut(); 796e78171edSJeremy L Thompson let ierr = unsafe { 7979df49d7eSJed Brown bind_ceed::CeedVectorGetArray( 7989df49d7eSJed Brown vec.ptr, 7999df49d7eSJed Brown crate::MemType::Host as bind_ceed::CeedMemType, 8009df49d7eSJed Brown &mut ptr, 801e78171edSJeremy L Thompson ) 802e78171edSJeremy L Thompson }; 803e78171edSJeremy L Thompson vec.check_error(ierr)?; 804e78171edSJeremy L Thompson Ok(Self { 8059df49d7eSJed Brown vec: vec, 8069df49d7eSJed Brown array: ptr, 807e78171edSJeremy L Thompson }) 8089df49d7eSJed Brown } 8099df49d7eSJed Brown } 8109df49d7eSJed Brown 8119df49d7eSJed Brown // Destructor 8129df49d7eSJed Brown impl<'a> Drop for VectorViewMut<'a> { 8139df49d7eSJed Brown fn drop(&mut self) { 8149df49d7eSJed Brown unsafe { 8159df49d7eSJed Brown bind_ceed::CeedVectorRestoreArray(self.vec.ptr, &mut self.array); 8169df49d7eSJed Brown } 8179df49d7eSJed Brown } 8189df49d7eSJed Brown } 8199df49d7eSJed Brown 8209df49d7eSJed Brown // Data access 8219df49d7eSJed Brown impl<'a> Deref for VectorViewMut<'a> { 82280a9ef05SNatalie Beams type Target = [crate::Scalar]; 82380a9ef05SNatalie Beams fn deref(&self) -> &[crate::Scalar] { 8249df49d7eSJed Brown unsafe { std::slice::from_raw_parts(self.array, self.vec.len()) } 8259df49d7eSJed Brown } 8269df49d7eSJed Brown } 8279df49d7eSJed Brown 8289df49d7eSJed Brown // Mutable data access 8299df49d7eSJed Brown impl<'a> DerefMut for VectorViewMut<'a> { 83080a9ef05SNatalie Beams fn deref_mut(&mut self) -> &mut [crate::Scalar] { 8319df49d7eSJed Brown unsafe { std::slice::from_raw_parts_mut(self.array, self.vec.len()) } 8329df49d7eSJed Brown } 8339df49d7eSJed Brown } 8349df49d7eSJed Brown 8359df49d7eSJed Brown // Viewing 8369df49d7eSJed Brown impl<'a> fmt::Display for VectorViewMut<'a> { 8379df49d7eSJed Brown fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 8389df49d7eSJed Brown write!(f, "VectorViewMut({:?})", self.deref()) 8399df49d7eSJed Brown } 8409df49d7eSJed Brown } 8419df49d7eSJed Brown 8429df49d7eSJed Brown // ----------------------------------------------------------------------------- 843