1*9ba83ac0SJeremy L Thompson // Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors. 23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 39df49d7eSJed Brown // 43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 59df49d7eSJed Brown // 63d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 79df49d7eSJed Brown 89df49d7eSJed Brown //! A Ceed Vector constitutes the main data structure and serves as input/output 99df49d7eSJed Brown //! for Ceed Operators. 109df49d7eSJed Brown 119df49d7eSJed Brown use std::{ 129df49d7eSJed Brown ops::{Deref, DerefMut}, 139df49d7eSJed Brown os::raw::c_char, 149df49d7eSJed Brown }; 159df49d7eSJed Brown 169df49d7eSJed Brown use crate::prelude::*; 179df49d7eSJed Brown 189df49d7eSJed Brown // ----------------------------------------------------------------------------- 197ed177dbSJed Brown // Vector option 209df49d7eSJed Brown // ----------------------------------------------------------------------------- 21c68be7a2SJeremy L Thompson #[derive(Debug)] 229df49d7eSJed Brown pub enum VectorOpt<'a> { 239df49d7eSJed Brown Some(&'a Vector<'a>), 249df49d7eSJed Brown Active, 259df49d7eSJed Brown None, 269df49d7eSJed Brown } 279df49d7eSJed Brown /// Construct a VectorOpt reference from a Vector reference 289df49d7eSJed Brown impl<'a> From<&'a Vector<'_>> for VectorOpt<'a> { 299df49d7eSJed Brown fn from(vec: &'a Vector) -> Self { 309df49d7eSJed Brown debug_assert!(vec.ptr != unsafe { bind_ceed::CEED_VECTOR_ACTIVE }); 31c68be7a2SJeremy L Thompson debug_assert!(vec.ptr != unsafe { bind_ceed::CEED_VECTOR_NONE }); 329df49d7eSJed Brown Self::Some(vec) 339df49d7eSJed Brown } 349df49d7eSJed Brown } 359df49d7eSJed Brown impl<'a> VectorOpt<'a> { 369df49d7eSJed Brown /// Transform a Rust libCEED VectorOpt into C libCEED CeedVector 3778c2cefaSJeremy L Thompson pub(crate) fn to_raw(&self) -> bind_ceed::CeedVector { 389df49d7eSJed Brown match self { 399df49d7eSJed Brown Self::Some(vec) => vec.ptr, 409df49d7eSJed Brown Self::Active => unsafe { bind_ceed::CEED_VECTOR_ACTIVE }, 41c68be7a2SJeremy L Thompson Self::None => unsafe { bind_ceed::CEED_VECTOR_NONE }, 429df49d7eSJed Brown } 439df49d7eSJed Brown } 44e03682afSJeremy L Thompson 45e03682afSJeremy L Thompson /// Check if a VectorOpt is Some 46e03682afSJeremy L Thompson /// 47e03682afSJeremy L Thompson /// ``` 48eb07d68fSJeremy L Thompson /// # use libceed::{prelude::*, VectorOpt}; 494d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 50e03682afSJeremy L Thompson /// # let ceed = libceed::Ceed::default_init(); 51e03682afSJeremy L Thompson /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?; 52e03682afSJeremy L Thompson /// let vec_opt = VectorOpt::from(&vec); 53e03682afSJeremy L Thompson /// assert!(vec_opt.is_some(), "Incorrect VectorOpt"); 54e03682afSJeremy L Thompson /// 55e03682afSJeremy L Thompson /// let vec_opt = VectorOpt::Active; 56e03682afSJeremy L Thompson /// assert!(!vec_opt.is_some(), "Incorrect VectorOpt"); 57e03682afSJeremy L Thompson /// 58e03682afSJeremy L Thompson /// let vec_opt = VectorOpt::None; 59e03682afSJeremy L Thompson /// assert!(!vec_opt.is_some(), "Incorrect VectorOpt"); 60e03682afSJeremy L Thompson /// # Ok(()) 61e03682afSJeremy L Thompson /// # } 62e03682afSJeremy L Thompson /// ``` 63e03682afSJeremy L Thompson pub fn is_some(&self) -> bool { 64e03682afSJeremy L Thompson match self { 65e03682afSJeremy L Thompson Self::Some(_) => true, 66e03682afSJeremy L Thompson Self::Active => false, 67e03682afSJeremy L Thompson Self::None => false, 68e03682afSJeremy L Thompson } 69e03682afSJeremy L Thompson } 70e03682afSJeremy L Thompson 71e03682afSJeremy L Thompson /// Check if a VectorOpt is Active 72e03682afSJeremy L Thompson /// 73e03682afSJeremy L Thompson /// ``` 74eb07d68fSJeremy L Thompson /// # use libceed::{prelude::*, VectorOpt}; 754d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 76e03682afSJeremy L Thompson /// # let ceed = libceed::Ceed::default_init(); 77e03682afSJeremy L Thompson /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?; 78e03682afSJeremy L Thompson /// let vec_opt = VectorOpt::from(&vec); 79e03682afSJeremy L Thompson /// assert!(!vec_opt.is_active(), "Incorrect VectorOpt"); 80e03682afSJeremy L Thompson /// 81e03682afSJeremy L Thompson /// let vec_opt = VectorOpt::Active; 82e03682afSJeremy L Thompson /// assert!(vec_opt.is_active(), "Incorrect VectorOpt"); 83e03682afSJeremy L Thompson /// 84e03682afSJeremy L Thompson /// let vec_opt = VectorOpt::None; 85e03682afSJeremy L Thompson /// assert!(!vec_opt.is_active(), "Incorrect VectorOpt"); 86e03682afSJeremy L Thompson /// # Ok(()) 87e03682afSJeremy L Thompson /// # } 88e03682afSJeremy L Thompson /// ``` 89e03682afSJeremy L Thompson pub fn is_active(&self) -> bool { 90e03682afSJeremy L Thompson match self { 91e03682afSJeremy L Thompson Self::Some(_) => false, 92e03682afSJeremy L Thompson Self::Active => true, 93e03682afSJeremy L Thompson Self::None => false, 94e03682afSJeremy L Thompson } 95e03682afSJeremy L Thompson } 96e03682afSJeremy L Thompson 97e03682afSJeremy L Thompson /// Check if a VectorOpt is Some 98e03682afSJeremy L Thompson /// 99e03682afSJeremy L Thompson /// ``` 100eb07d68fSJeremy L Thompson /// # use libceed::{prelude::*, VectorOpt}; 1014d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 102e03682afSJeremy L Thompson /// # let ceed = libceed::Ceed::default_init(); 103e03682afSJeremy L Thompson /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?; 104e03682afSJeremy L Thompson /// let vec_opt = VectorOpt::from(&vec); 105e03682afSJeremy L Thompson /// assert!(!vec_opt.is_none(), "Incorrect VectorOpt"); 106e03682afSJeremy L Thompson /// 107e03682afSJeremy L Thompson /// let vec_opt = VectorOpt::Active; 108e03682afSJeremy L Thompson /// assert!(!vec_opt.is_none(), "Incorrect VectorOpt"); 109e03682afSJeremy L Thompson /// 110e03682afSJeremy L Thompson /// let vec_opt = VectorOpt::None; 111e03682afSJeremy L Thompson /// assert!(vec_opt.is_none(), "Incorrect VectorOpt"); 112e03682afSJeremy L Thompson /// # Ok(()) 113e03682afSJeremy L Thompson /// # } 114e03682afSJeremy L Thompson /// ``` 115e03682afSJeremy L Thompson pub fn is_none(&self) -> bool { 116e03682afSJeremy L Thompson match self { 117e03682afSJeremy L Thompson Self::Some(_) => false, 118e03682afSJeremy L Thompson Self::Active => false, 119e03682afSJeremy L Thompson Self::None => true, 120e03682afSJeremy L Thompson } 121e03682afSJeremy L Thompson } 1229df49d7eSJed Brown } 1239df49d7eSJed Brown 1249df49d7eSJed Brown // ----------------------------------------------------------------------------- 1257ed177dbSJed Brown // Vector borrowed slice wrapper 12656e67e05SJeremy L Thompson // ----------------------------------------------------------------------------- 127486868d3SJeremy L Thompson pub struct VectorSliceWrapper<'a> { 128eb07d68fSJeremy L Thompson pub(crate) vector: Vector<'a>, 12956e67e05SJeremy L Thompson pub(crate) _slice: &'a mut [crate::Scalar], 13056e67e05SJeremy L Thompson } 13156e67e05SJeremy L Thompson 13256e67e05SJeremy L Thompson // ----------------------------------------------------------------------------- 13356e67e05SJeremy L Thompson // Destructor 13456e67e05SJeremy L Thompson // ----------------------------------------------------------------------------- 135486868d3SJeremy L Thompson impl<'a> Drop for VectorSliceWrapper<'a> { 13656e67e05SJeremy L Thompson fn drop(&mut self) { 13756e67e05SJeremy L Thompson unsafe { 13856e67e05SJeremy L Thompson bind_ceed::CeedVectorTakeArray( 13956e67e05SJeremy L Thompson self.vector.ptr, 14056e67e05SJeremy L Thompson crate::MemType::Host as bind_ceed::CeedMemType, 14156e67e05SJeremy L Thompson std::ptr::null_mut(), 14256e67e05SJeremy L Thompson ) 14356e67e05SJeremy L Thompson }; 14456e67e05SJeremy L Thompson } 14556e67e05SJeremy L Thompson } 14656e67e05SJeremy L Thompson 14756e67e05SJeremy L Thompson // ----------------------------------------------------------------------------- 14835afbe75SJeremy L Thompson // Convenience constructor 14935afbe75SJeremy L Thompson // ----------------------------------------------------------------------------- 15035afbe75SJeremy L Thompson impl<'a> VectorSliceWrapper<'a> { 15135afbe75SJeremy L Thompson fn from_vector_and_slice_mut<'b>( 152eb07d68fSJeremy L Thompson vec: &'b mut Vector, 15335afbe75SJeremy L Thompson slice: &'a mut [crate::Scalar], 15435afbe75SJeremy L Thompson ) -> crate::Result<Self> { 15535afbe75SJeremy L Thompson assert_eq!(vec.length(), slice.len()); 15635afbe75SJeremy L Thompson let (host, copy_mode) = ( 15735afbe75SJeremy L Thompson crate::MemType::Host as bind_ceed::CeedMemType, 15835afbe75SJeremy L Thompson crate::CopyMode::UsePointer as bind_ceed::CeedCopyMode, 15935afbe75SJeremy L Thompson ); 160656ef1e5SJeremy L Thompson vec.check_error(unsafe { 16135afbe75SJeremy L Thompson bind_ceed::CeedVectorSetArray( 16235afbe75SJeremy L Thompson vec.ptr, 16335afbe75SJeremy L Thompson host, 16435afbe75SJeremy L Thompson copy_mode, 16535afbe75SJeremy L Thompson slice.as_ptr() as *mut crate::Scalar, 16635afbe75SJeremy L Thompson ) 167656ef1e5SJeremy L Thompson })?; 16835afbe75SJeremy L Thompson Ok(Self { 169eb07d68fSJeremy L Thompson vector: unsafe { Vector::from_raw(vec.ptr_copy_mut()?)? }, 17035afbe75SJeremy L Thompson _slice: slice, 17135afbe75SJeremy L Thompson }) 17235afbe75SJeremy L Thompson } 17335afbe75SJeremy L Thompson } 17435afbe75SJeremy L Thompson 17535afbe75SJeremy L Thompson // ----------------------------------------------------------------------------- 1767ed177dbSJed Brown // Vector context wrapper 1779df49d7eSJed Brown // ----------------------------------------------------------------------------- 1789df49d7eSJed Brown #[derive(Debug)] 1799df49d7eSJed Brown pub struct Vector<'a> { 1809df49d7eSJed Brown pub(crate) ptr: bind_ceed::CeedVector, 1811142270cSJeremy L Thompson _lifeline: PhantomData<&'a ()>, 1829df49d7eSJed Brown } 1839df49d7eSJed Brown impl From<&'_ Vector<'_>> for bind_ceed::CeedVector { 1849df49d7eSJed Brown fn from(vec: &Vector) -> Self { 1859df49d7eSJed Brown vec.ptr 1869df49d7eSJed Brown } 1879df49d7eSJed Brown } 1889df49d7eSJed Brown 1899df49d7eSJed Brown // ----------------------------------------------------------------------------- 1909df49d7eSJed Brown // Destructor 1919df49d7eSJed Brown // ----------------------------------------------------------------------------- 1929df49d7eSJed Brown impl<'a> Drop for Vector<'a> { 1939df49d7eSJed Brown fn drop(&mut self) { 1949df49d7eSJed Brown let not_none_and_active = self.ptr != unsafe { bind_ceed::CEED_VECTOR_NONE } 1959df49d7eSJed Brown && self.ptr != unsafe { bind_ceed::CEED_VECTOR_ACTIVE }; 1969df49d7eSJed Brown 1979df49d7eSJed Brown if not_none_and_active { 1989df49d7eSJed Brown unsafe { bind_ceed::CeedVectorDestroy(&mut self.ptr) }; 1999df49d7eSJed Brown } 2009df49d7eSJed Brown } 2019df49d7eSJed Brown } 2029df49d7eSJed Brown 2039df49d7eSJed Brown // ----------------------------------------------------------------------------- 2049df49d7eSJed Brown // Display 2059df49d7eSJed Brown // ----------------------------------------------------------------------------- 2069df49d7eSJed Brown impl<'a> fmt::Display for Vector<'a> { 2079df49d7eSJed Brown /// View a Vector 2089df49d7eSJed Brown /// 2099df49d7eSJed Brown /// ``` 2109df49d7eSJed Brown /// # use libceed::prelude::*; 2114d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 2129df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 213c68be7a2SJeremy L Thompson /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?; 2149df49d7eSJed Brown /// assert_eq!( 2159df49d7eSJed Brown /// vec.to_string(), 2169df49d7eSJed Brown /// "CeedVector length 3 2179df49d7eSJed Brown /// 1.00000000 2189df49d7eSJed Brown /// 2.00000000 2199df49d7eSJed Brown /// 3.00000000 2209df49d7eSJed Brown /// " 221c68be7a2SJeremy L Thompson /// ); 222c68be7a2SJeremy L Thompson /// # Ok(()) 223c68be7a2SJeremy L Thompson /// # } 2249df49d7eSJed Brown /// ``` 2259df49d7eSJed Brown fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 2269df49d7eSJed Brown let mut ptr = std::ptr::null_mut(); 2279df49d7eSJed Brown let mut sizeloc = crate::MAX_BUFFER_LENGTH; 2289df49d7eSJed Brown let format = CString::new("%12.8f").expect("CString::new failed"); 2299df49d7eSJed Brown let format_c: *const c_char = format.into_raw(); 2309df49d7eSJed Brown let cstring = unsafe { 2319df49d7eSJed Brown let file = bind_ceed::open_memstream(&mut ptr, &mut sizeloc); 2329df49d7eSJed Brown bind_ceed::CeedVectorView(self.ptr, format_c, file); 2339df49d7eSJed Brown bind_ceed::fclose(file); 2349df49d7eSJed Brown CString::from_raw(ptr) 2359df49d7eSJed Brown }; 2369df49d7eSJed Brown cstring.to_string_lossy().fmt(f) 2379df49d7eSJed Brown } 2389df49d7eSJed Brown } 2399df49d7eSJed Brown 2409df49d7eSJed Brown // ----------------------------------------------------------------------------- 2419df49d7eSJed Brown // Implementations 2429df49d7eSJed Brown // ----------------------------------------------------------------------------- 2439df49d7eSJed Brown impl<'a> Vector<'a> { 2449df49d7eSJed Brown // Constructors 245594ef120SJeremy L Thompson pub fn create(ceed: &crate::Ceed, n: usize) -> crate::Result<Self> { 2461f9221feSJeremy L Thompson let n = isize::try_from(n).unwrap(); 2479df49d7eSJed Brown let mut ptr = std::ptr::null_mut(); 248656ef1e5SJeremy L Thompson ceed.check_error(unsafe { bind_ceed::CeedVectorCreate(ceed.ptr, n, &mut ptr) })?; 2491142270cSJeremy L Thompson Ok(Self { 2501142270cSJeremy L Thompson ptr, 2511142270cSJeremy L Thompson _lifeline: PhantomData, 2521142270cSJeremy L Thompson }) 2539df49d7eSJed Brown } 2549df49d7eSJed Brown 2552b671a0aSJeremy L Thompson pub(crate) unsafe fn from_raw(ptr: bind_ceed::CeedVector) -> crate::Result<Self> { 2561142270cSJeremy L Thompson Ok(Self { 2571142270cSJeremy L Thompson ptr, 2581142270cSJeremy L Thompson _lifeline: PhantomData, 2591142270cSJeremy L Thompson }) 2609df49d7eSJed Brown } 2619df49d7eSJed Brown 262e46a712dSJeremy L Thompson fn ptr_copy_mut(&mut self) -> crate::Result<bind_ceed::CeedVector> { 263e46a712dSJeremy L Thompson let mut ptr_copy = std::ptr::null_mut(); 264656ef1e5SJeremy L Thompson self.check_error(unsafe { bind_ceed::CeedVectorReferenceCopy(self.ptr, &mut ptr_copy) })?; 265e46a712dSJeremy L Thompson Ok(ptr_copy) 266e46a712dSJeremy L Thompson } 267e46a712dSJeremy L Thompson 2685fb68f37SKaren (Ren) Stengel /// Copy the array of self into vec_copy 2695fb68f37SKaren (Ren) Stengel /// 2705fb68f37SKaren (Ren) Stengel /// # arguments 2715fb68f37SKaren (Ren) Stengel /// 2725fb68f37SKaren (Ren) Stengel /// * `vec_source` - vector to copy array values from 27346de3253SJeremy L Thompson /// 27446de3253SJeremy L Thompson /// ``` 275eb07d68fSJeremy L Thompson /// # use libceed::{prelude::*, Scalar}; 27646de3253SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 27746de3253SJeremy L Thompson /// # let ceed = libceed::Ceed::default_init(); 27846de3253SJeremy L Thompson /// let a = ceed.vector_from_slice(&[1., 2., 3.])?; 27946de3253SJeremy L Thompson /// let mut b = ceed.vector(3)?; 28046de3253SJeremy L Thompson /// 28146de3253SJeremy L Thompson /// b.copy_from(&a)?; 28246de3253SJeremy L Thompson /// for (i, v) in b.view()?.iter().enumerate() { 28346de3253SJeremy L Thompson /// assert_eq!(*v, (i + 1) as Scalar, "Copy contents not set correctly"); 28446de3253SJeremy L Thompson /// } 28546de3253SJeremy L Thompson /// # Ok(()) 28646de3253SJeremy L Thompson /// # } 28746de3253SJeremy L Thompson /// ``` 28846de3253SJeremy L Thompson /// ``` 289eb07d68fSJeremy L Thompson pub fn copy_from(&mut self, vec_source: &Vector) -> crate::Result<i32> { 290656ef1e5SJeremy L Thompson self.check_error(unsafe { bind_ceed::CeedVectorCopy(vec_source.ptr, self.ptr) }) 2915fb68f37SKaren (Ren) Stengel } 2925fb68f37SKaren (Ren) Stengel 2939df49d7eSJed Brown /// Create a Vector from a slice 2949df49d7eSJed Brown /// 2959df49d7eSJed Brown /// # arguments 2969df49d7eSJed Brown /// 2979df49d7eSJed Brown /// * `slice` - values to initialize vector with 2989df49d7eSJed Brown /// 2999df49d7eSJed Brown /// ``` 3009df49d7eSJed Brown /// # use libceed::prelude::*; 3014d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 3029df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 303eb07d68fSJeremy L Thompson /// let vec = libceed::Vector::from_slice(&ceed, &[1., 2., 3.])?; 3049df49d7eSJed Brown /// assert_eq!(vec.length(), 3, "Incorrect length from slice"); 305c68be7a2SJeremy L Thompson /// # Ok(()) 306c68be7a2SJeremy L Thompson /// # } 3079df49d7eSJed Brown /// ``` 308594ef120SJeremy L Thompson pub fn from_slice(ceed: &crate::Ceed, v: &[crate::Scalar]) -> crate::Result<Self> { 3099df49d7eSJed Brown let mut x = Self::create(ceed, v.len())?; 3109df49d7eSJed Brown x.set_slice(v)?; 3119df49d7eSJed Brown Ok(x) 3129df49d7eSJed Brown } 3139df49d7eSJed Brown 3149df49d7eSJed Brown /// Create a Vector from a mutable array reference 3159df49d7eSJed Brown /// 3169df49d7eSJed Brown /// # arguments 3179df49d7eSJed Brown /// 3189df49d7eSJed Brown /// * `slice` - values to initialize vector with 3199df49d7eSJed Brown /// 3209df49d7eSJed Brown /// ``` 3219df49d7eSJed Brown /// # use libceed::prelude::*; 3224d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 3239df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 3249df49d7eSJed Brown /// let mut rust_vec = vec![1., 2., 3.]; 325c68be7a2SJeremy L Thompson /// let vec = libceed::vector::Vector::from_array(&ceed, &mut rust_vec)?; 3269df49d7eSJed Brown /// 3279df49d7eSJed Brown /// assert_eq!(vec.length(), 3, "Incorrect length from slice"); 328c68be7a2SJeremy L Thompson /// # Ok(()) 329c68be7a2SJeremy L Thompson /// # } 3309df49d7eSJed Brown /// ``` 331594ef120SJeremy L Thompson pub fn from_array(ceed: &crate::Ceed, v: &mut [crate::Scalar]) -> crate::Result<Self> { 3329df49d7eSJed Brown let x = Self::create(ceed, v.len())?; 3339df49d7eSJed Brown let (host, user_pointer) = ( 3349df49d7eSJed Brown crate::MemType::Host as bind_ceed::CeedMemType, 3359df49d7eSJed Brown crate::CopyMode::UsePointer as bind_ceed::CeedCopyMode, 3369df49d7eSJed Brown ); 33780a9ef05SNatalie Beams let v = v.as_ptr() as *mut crate::Scalar; 338656ef1e5SJeremy L Thompson ceed.check_error(unsafe { bind_ceed::CeedVectorSetArray(x.ptr, host, user_pointer, v) })?; 3399df49d7eSJed Brown Ok(x) 3409df49d7eSJed Brown } 3419df49d7eSJed Brown 34211544396SJeremy L Thompson // Raw Ceed for error handling 34311544396SJeremy L Thompson #[doc(hidden)] 34411544396SJeremy L Thompson fn ceed(&self) -> bind_ceed::Ceed { 34511544396SJeremy L Thompson unsafe { bind_ceed::CeedVectorReturnCeed(self.ptr) } 34611544396SJeremy L Thompson } 34711544396SJeremy L Thompson 3481142270cSJeremy L Thompson // Error handling 3491142270cSJeremy L Thompson #[doc(hidden)] 3501142270cSJeremy L Thompson fn check_error(&self, ierr: i32) -> crate::Result<i32> { 35111544396SJeremy L Thompson crate::check_error(|| self.ceed(), ierr) 3521142270cSJeremy L Thompson } 3531142270cSJeremy L Thompson 3547ed177dbSJed Brown /// Returns the length of a Vector 3559df49d7eSJed Brown /// 3569df49d7eSJed Brown /// ``` 3579df49d7eSJed Brown /// # use libceed::prelude::*; 3584d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 3599df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 360c68be7a2SJeremy L Thompson /// let vec = ceed.vector(10)?; 3619df49d7eSJed Brown /// 3629df49d7eSJed Brown /// let n = vec.length(); 3639df49d7eSJed Brown /// assert_eq!(n, 10, "Incorrect length"); 364c68be7a2SJeremy L Thompson /// # Ok(()) 365c68be7a2SJeremy L Thompson /// # } 3669df49d7eSJed Brown /// ``` 3679df49d7eSJed Brown pub fn length(&self) -> usize { 3689df49d7eSJed Brown let mut n = 0; 3699df49d7eSJed Brown unsafe { bind_ceed::CeedVectorGetLength(self.ptr, &mut n) }; 3709df49d7eSJed Brown usize::try_from(n).unwrap() 3719df49d7eSJed Brown } 3729df49d7eSJed Brown 3737ed177dbSJed Brown /// Returns the length of a Vector 3749df49d7eSJed Brown /// 3759df49d7eSJed Brown /// ``` 3769df49d7eSJed Brown /// # use libceed::prelude::*; 3774d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 3789df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 379c68be7a2SJeremy L Thompson /// let vec = ceed.vector(10)?; 3809df49d7eSJed Brown /// assert_eq!(vec.len(), 10, "Incorrect length"); 381c68be7a2SJeremy L Thompson /// # Ok(()) 382c68be7a2SJeremy L Thompson /// # } 3839df49d7eSJed Brown /// ``` 3849df49d7eSJed Brown pub fn len(&self) -> usize { 3859df49d7eSJed Brown self.length() 3869df49d7eSJed Brown } 3879df49d7eSJed Brown 38878c2cefaSJeremy L Thompson /// Returns true if the Vector contains no elements 38978c2cefaSJeremy L Thompson /// 39078c2cefaSJeremy L Thompson /// ``` 39178c2cefaSJeremy L Thompson /// # use libceed::prelude::*; 39278c2cefaSJeremy L Thompson /// # fn main() -> libceed::Result<()> { 39378c2cefaSJeremy L Thompson /// # let ceed = libceed::Ceed::default_init(); 39478c2cefaSJeremy L Thompson /// let vec = ceed.vector(10)?; 39578c2cefaSJeremy L Thompson /// assert!(!vec.is_empty(), "Incorrect emptiness"); 39678c2cefaSJeremy L Thompson /// let empty_vec = ceed.vector(0)?; 39778c2cefaSJeremy L Thompson /// assert!(empty_vec.is_empty(), "Incorrect emptiness"); 39878c2cefaSJeremy L Thompson /// # Ok(()) 39978c2cefaSJeremy L Thompson /// # } 40078c2cefaSJeremy L Thompson /// ``` 40178c2cefaSJeremy L Thompson pub fn is_empty(&self) -> bool { 40278c2cefaSJeremy L Thompson self.length() == 0 40378c2cefaSJeremy L Thompson } 40478c2cefaSJeremy L Thompson 4057ed177dbSJed Brown /// Set the Vector to a constant value 4069df49d7eSJed Brown /// 4079df49d7eSJed Brown /// # arguments 4089df49d7eSJed Brown /// 4099df49d7eSJed Brown /// * `val` - Value to be used 4109df49d7eSJed Brown /// 4119df49d7eSJed Brown /// ``` 4129df49d7eSJed Brown /// # use libceed::prelude::*; 4134d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 4149df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 4159df49d7eSJed Brown /// let len = 10; 416c68be7a2SJeremy L Thompson /// let mut vec = ceed.vector(len)?; 4179df49d7eSJed Brown /// 4189df49d7eSJed Brown /// let val = 42.0; 419c68be7a2SJeremy L Thompson /// vec.set_value(val)?; 4209df49d7eSJed Brown /// 421d3677ae8SJeremy L Thompson /// for v in vec.view()?.iter() { 4229df49d7eSJed Brown /// assert_eq!(*v, val, "Value not set correctly"); 423d3677ae8SJeremy L Thompson /// } 424c68be7a2SJeremy L Thompson /// # Ok(()) 425c68be7a2SJeremy L Thompson /// # } 4269df49d7eSJed Brown /// ``` 42780a9ef05SNatalie Beams pub fn set_value(&mut self, value: crate::Scalar) -> crate::Result<i32> { 428656ef1e5SJeremy L Thompson self.check_error(unsafe { bind_ceed::CeedVectorSetValue(self.ptr, value) }) 4299df49d7eSJed Brown } 4309df49d7eSJed Brown 4319df49d7eSJed Brown /// Set values from a slice of the same length 4329df49d7eSJed Brown /// 4339df49d7eSJed Brown /// # arguments 4349df49d7eSJed Brown /// 4359df49d7eSJed Brown /// * `slice` - values to into self; length must match 4369df49d7eSJed Brown /// 4379df49d7eSJed Brown /// ``` 438eb07d68fSJeremy L Thompson /// # use libceed::{prelude::*, Scalar}; 4394d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 4409df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 441c68be7a2SJeremy L Thompson /// let mut vec = ceed.vector(4)?; 442c68be7a2SJeremy L Thompson /// vec.set_slice(&[10., 11., 12., 13.])?; 4439df49d7eSJed Brown /// 444d3677ae8SJeremy L Thompson /// for (i, v) in vec.view()?.iter().enumerate() { 44580a9ef05SNatalie Beams /// assert_eq!(*v, 10. + i as Scalar, "Slice not set correctly"); 446d3677ae8SJeremy L Thompson /// } 447c68be7a2SJeremy L Thompson /// # Ok(()) 448c68be7a2SJeremy L Thompson /// # } 4499df49d7eSJed Brown /// ``` 45080a9ef05SNatalie Beams pub fn set_slice(&mut self, slice: &[crate::Scalar]) -> crate::Result<i32> { 4519df49d7eSJed Brown assert_eq!(self.length(), slice.len()); 4529df49d7eSJed Brown let (host, copy_mode) = ( 4539df49d7eSJed Brown crate::MemType::Host as bind_ceed::CeedMemType, 4549df49d7eSJed Brown crate::CopyMode::CopyValues as bind_ceed::CeedCopyMode, 4559df49d7eSJed Brown ); 456656ef1e5SJeremy L Thompson self.check_error(unsafe { 45780a9ef05SNatalie Beams bind_ceed::CeedVectorSetArray( 45880a9ef05SNatalie Beams self.ptr, 45980a9ef05SNatalie Beams host, 46080a9ef05SNatalie Beams copy_mode, 46180a9ef05SNatalie Beams slice.as_ptr() as *mut crate::Scalar, 46280a9ef05SNatalie Beams ) 463656ef1e5SJeremy L Thompson }) 4649df49d7eSJed Brown } 4659df49d7eSJed Brown 466486868d3SJeremy L Thompson /// Wrap a mutable slice in a Vector of the same length 46756e67e05SJeremy L Thompson /// 46856e67e05SJeremy L Thompson /// # arguments 46956e67e05SJeremy L Thompson /// 470486868d3SJeremy L Thompson /// * `slice` - values to wrap in self; length must match 47156e67e05SJeremy L Thompson /// 47256e67e05SJeremy L Thompson /// ``` 473eb07d68fSJeremy L Thompson /// # use libceed::{prelude::*, Scalar}; 47456e67e05SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 47556e67e05SJeremy L Thompson /// # let ceed = libceed::Ceed::default_init(); 47656e67e05SJeremy L Thompson /// let mut vec = ceed.vector(4)?; 477486868d3SJeremy L Thompson /// let mut array = [10., 11., 12., 13.]; 47856e67e05SJeremy L Thompson /// 47956e67e05SJeremy L Thompson /// { 480486868d3SJeremy L Thompson /// // `wrapper` holds a mutable reference to the wrapped slice 481486868d3SJeremy L Thompson /// // that is dropped when `wrapper` goes out of scope 482486868d3SJeremy L Thompson /// let wrapper = vec.wrap_slice_mut(&mut array)?; 483d3677ae8SJeremy L Thompson /// for (i, v) in vec.view()?.iter().enumerate() { 48456e67e05SJeremy L Thompson /// assert_eq!(*v, 10. + i as Scalar, "Slice not set correctly"); 485d3677ae8SJeremy L Thompson /// } 48656e67e05SJeremy L Thompson /// 487486868d3SJeremy L Thompson /// // This line will not compile, as the `wrapper` holds mutable 488486868d3SJeremy L Thompson /// // access to the `array` 489486868d3SJeremy L Thompson /// // array[0] = 5.0; 49056e67e05SJeremy L Thompson /// 491486868d3SJeremy L Thompson /// // Changes here are reflected in the `array` 49256e67e05SJeremy L Thompson /// vec.set_value(5.0)?; 493d3677ae8SJeremy L Thompson /// for v in vec.view()?.iter() { 494486868d3SJeremy L Thompson /// assert_eq!(*v, 5.0 as Scalar, "Value not set correctly"); 495d3677ae8SJeremy L Thompson /// } 49656e67e05SJeremy L Thompson /// } 49756e67e05SJeremy L Thompson /// 498486868d3SJeremy L Thompson /// // 'array' remains changed 499d3677ae8SJeremy L Thompson /// for v in array.iter() { 500486868d3SJeremy L Thompson /// assert_eq!(*v, 5.0 as Scalar, "Array not mutated correctly"); 501d3677ae8SJeremy L Thompson /// } 50256e67e05SJeremy L Thompson /// 503486868d3SJeremy L Thompson /// // While changes to `vec` no longer affect `array` 504486868d3SJeremy L Thompson /// vec.set_value(6.0)?; 505d3677ae8SJeremy L Thompson /// for v in array.iter() { 506486868d3SJeremy L Thompson /// assert_eq!(*v, 5.0 as Scalar, "Array mutated without permission"); 507d3677ae8SJeremy L Thompson /// } 50856e67e05SJeremy L Thompson /// # Ok(()) 50956e67e05SJeremy L Thompson /// # } 51056e67e05SJeremy L Thompson /// ``` 511486868d3SJeremy L Thompson pub fn wrap_slice_mut<'b>( 51256e67e05SJeremy L Thompson &mut self, 51356e67e05SJeremy L Thompson slice: &'b mut [crate::Scalar], 514486868d3SJeremy L Thompson ) -> crate::Result<VectorSliceWrapper<'b>> { 515eb07d68fSJeremy L Thompson VectorSliceWrapper::from_vector_and_slice_mut(self, slice) 51656e67e05SJeremy L Thompson } 51756e67e05SJeremy L Thompson 5187ed177dbSJed Brown /// Sync the Vector to a specified memtype 5199df49d7eSJed Brown /// 5209df49d7eSJed Brown /// # arguments 5219df49d7eSJed Brown /// 5229df49d7eSJed Brown /// * `mtype` - Memtype to be synced 5239df49d7eSJed Brown /// 5249df49d7eSJed Brown /// ``` 525eb07d68fSJeremy L Thompson /// # use libceed::{prelude::*, MemType}; 5264d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 5279df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 5289df49d7eSJed Brown /// let len = 10; 529c68be7a2SJeremy L Thompson /// let mut vec = ceed.vector(len)?; 5309df49d7eSJed Brown /// 5319df49d7eSJed Brown /// let val = 42.0; 5329df49d7eSJed Brown /// vec.set_value(val); 533c68be7a2SJeremy L Thompson /// vec.sync(MemType::Host)?; 5349df49d7eSJed Brown /// 535d3677ae8SJeremy L Thompson /// for v in vec.view()?.iter() { 5369df49d7eSJed Brown /// assert_eq!(*v, val, "Value not set correctly"); 537d3677ae8SJeremy L Thompson /// } 538c68be7a2SJeremy L Thompson /// # Ok(()) 539c68be7a2SJeremy L Thompson /// # } 5409df49d7eSJed Brown /// ``` 5419df49d7eSJed Brown pub fn sync(&self, mtype: crate::MemType) -> crate::Result<i32> { 542656ef1e5SJeremy L Thompson self.check_error(unsafe { 543656ef1e5SJeremy L Thompson bind_ceed::CeedVectorSyncArray(self.ptr, mtype as bind_ceed::CeedMemType) 544656ef1e5SJeremy L Thompson }) 5459df49d7eSJed Brown } 5469df49d7eSJed Brown 5479df49d7eSJed Brown /// Create an immutable view 5489df49d7eSJed Brown /// 5499df49d7eSJed Brown /// ``` 5509df49d7eSJed Brown /// # use libceed::prelude::*; 5514d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 5529df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 553c68be7a2SJeremy L Thompson /// let vec = ceed.vector_from_slice(&[10., 11., 12., 13.])?; 5549df49d7eSJed Brown /// 555e78171edSJeremy L Thompson /// let v = vec.view()?; 5569df49d7eSJed Brown /// assert_eq!(v[0..2], [10., 11.]); 5579df49d7eSJed Brown /// 5589df49d7eSJed Brown /// // It is valid to have multiple immutable views 559e78171edSJeremy L Thompson /// let w = vec.view()?; 5609df49d7eSJed Brown /// assert_eq!(v[1..], w[1..]); 561c68be7a2SJeremy L Thompson /// # Ok(()) 562c68be7a2SJeremy L Thompson /// # } 5639df49d7eSJed Brown /// ``` 564e78171edSJeremy L Thompson pub fn view(&self) -> crate::Result<VectorView> { 5659df49d7eSJed Brown VectorView::new(self) 5669df49d7eSJed Brown } 5679df49d7eSJed Brown 5689df49d7eSJed Brown /// Create an mutable view 5699df49d7eSJed Brown /// 5709df49d7eSJed Brown /// ``` 5719df49d7eSJed Brown /// # use libceed::prelude::*; 5724d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 5739df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 574c68be7a2SJeremy L Thompson /// let mut vec = ceed.vector_from_slice(&[10., 11., 12., 13.])?; 5759df49d7eSJed Brown /// 5769df49d7eSJed Brown /// { 577e78171edSJeremy L Thompson /// let mut v = vec.view_mut()?; 5789df49d7eSJed Brown /// v[2] = 9.; 5799df49d7eSJed Brown /// } 5809df49d7eSJed Brown /// 581e78171edSJeremy L Thompson /// let w = vec.view()?; 5829df49d7eSJed Brown /// assert_eq!(w[2], 9., "View did not mutate data"); 583c68be7a2SJeremy L Thompson /// # Ok(()) 584c68be7a2SJeremy L Thompson /// # } 5859df49d7eSJed Brown /// ``` 586e78171edSJeremy L Thompson pub fn view_mut(&mut self) -> crate::Result<VectorViewMut> { 5879df49d7eSJed Brown VectorViewMut::new(self) 5889df49d7eSJed Brown } 5899df49d7eSJed Brown 5907ed177dbSJed Brown /// Return the norm of a Vector 5919df49d7eSJed Brown /// 5929df49d7eSJed Brown /// # arguments 5939df49d7eSJed Brown /// 5949df49d7eSJed Brown /// * `ntype` - Norm type One, Two, or Max 5959df49d7eSJed Brown /// 5969df49d7eSJed Brown /// ``` 597eb07d68fSJeremy L Thompson /// # use libceed::{prelude::*, NormType}; 5984d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 5999df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 600c68be7a2SJeremy L Thompson /// let vec = ceed.vector_from_slice(&[1., 2., 3., 4.])?; 6019df49d7eSJed Brown /// 602c68be7a2SJeremy L Thompson /// let max_norm = vec.norm(NormType::Max)?; 6039df49d7eSJed Brown /// assert_eq!(max_norm, 4.0, "Incorrect Max norm"); 6049df49d7eSJed Brown /// 605c68be7a2SJeremy L Thompson /// let l1_norm = vec.norm(NormType::One)?; 6069df49d7eSJed Brown /// assert_eq!(l1_norm, 10., "Incorrect L1 norm"); 6079df49d7eSJed Brown /// 608c68be7a2SJeremy L Thompson /// let l2_norm = vec.norm(NormType::Two)?; 6099df49d7eSJed Brown /// assert!((l2_norm - 5.477) < 1e-3, "Incorrect L2 norm"); 610c68be7a2SJeremy L Thompson /// # Ok(()) 611c68be7a2SJeremy L Thompson /// # } 6129df49d7eSJed Brown /// ``` 61380a9ef05SNatalie Beams pub fn norm(&self, ntype: crate::NormType) -> crate::Result<crate::Scalar> { 61480a9ef05SNatalie Beams let mut res: crate::Scalar = 0.0; 615656ef1e5SJeremy L Thompson self.check_error(unsafe { 6169df49d7eSJed Brown bind_ceed::CeedVectorNorm(self.ptr, ntype as bind_ceed::CeedNormType, &mut res) 617656ef1e5SJeremy L Thompson })?; 6189df49d7eSJed Brown Ok(res) 6199df49d7eSJed Brown } 6209df49d7eSJed Brown 6217ed177dbSJed Brown /// Compute x = alpha x for a Vector 6229df49d7eSJed Brown /// 6239df49d7eSJed Brown /// # arguments 6249df49d7eSJed Brown /// 6259df49d7eSJed Brown /// * `alpha` - scaling factor 6269df49d7eSJed Brown /// 6279df49d7eSJed Brown /// ``` 628eb07d68fSJeremy L Thompson /// # use libceed::{prelude::*, Scalar}; 6294d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 6309df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 631c68be7a2SJeremy L Thompson /// let mut vec = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 6329df49d7eSJed Brown /// 633c68be7a2SJeremy L Thompson /// vec = vec.scale(-1.0)?; 634d3677ae8SJeremy L Thompson /// for (i, v) in vec.view()?.iter().enumerate() { 635d3677ae8SJeremy L Thompson /// assert_eq!(*v, -(i as Scalar), "Value not set correctly"); 636d3677ae8SJeremy L Thompson /// } 637c68be7a2SJeremy L Thompson /// # Ok(()) 638c68be7a2SJeremy L Thompson /// # } 6399df49d7eSJed Brown /// ``` 6409df49d7eSJed Brown #[allow(unused_mut)] 64180a9ef05SNatalie Beams pub fn scale(mut self, alpha: crate::Scalar) -> crate::Result<Self> { 642656ef1e5SJeremy L Thompson self.check_error(unsafe { bind_ceed::CeedVectorScale(self.ptr, alpha) })?; 6439df49d7eSJed Brown Ok(self) 6449df49d7eSJed Brown } 6459df49d7eSJed Brown 6467ed177dbSJed Brown /// Compute y = alpha x + y for a pair of Vectors 6479df49d7eSJed Brown /// 6489df49d7eSJed Brown /// # arguments 6499df49d7eSJed Brown /// 6509df49d7eSJed Brown /// * `alpha` - scaling factor 6519df49d7eSJed Brown /// * `x` - second vector, must be different than self 6529df49d7eSJed Brown /// 6539df49d7eSJed Brown /// ``` 654eb07d68fSJeremy L Thompson /// # use libceed::{prelude::*, Scalar}; 6554d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 6569df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 657c68be7a2SJeremy L Thompson /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 658c68be7a2SJeremy L Thompson /// let mut y = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 6599df49d7eSJed Brown /// 660c68be7a2SJeremy L Thompson /// y = y.axpy(-0.5, &x)?; 661d3677ae8SJeremy L Thompson /// for (i, y) in y.view()?.iter().enumerate() { 662d3677ae8SJeremy L Thompson /// assert_eq!(*y, (i as Scalar) / 2.0, "Value not set correctly"); 663d3677ae8SJeremy L Thompson /// } 664c68be7a2SJeremy L Thompson /// # Ok(()) 665c68be7a2SJeremy L Thompson /// # } 6669df49d7eSJed Brown /// ``` 6679df49d7eSJed Brown #[allow(unused_mut)] 668eb07d68fSJeremy L Thompson pub fn axpy(mut self, alpha: crate::Scalar, x: &Vector) -> crate::Result<Self> { 669656ef1e5SJeremy L Thompson self.check_error(unsafe { bind_ceed::CeedVectorAXPY(self.ptr, alpha, x.ptr) })?; 6709df49d7eSJed Brown Ok(self) 6719df49d7eSJed Brown } 6729df49d7eSJed Brown 6735fb68f37SKaren (Ren) Stengel /// Compute y = alpha x + beta y for a pair of Vectors 6745fb68f37SKaren (Ren) Stengel /// 6755fb68f37SKaren (Ren) Stengel /// # arguments 6765fb68f37SKaren (Ren) Stengel /// 6775fb68f37SKaren (Ren) Stengel /// * `alpha` - first scaling factor 6785fb68f37SKaren (Ren) Stengel /// * `beta` - second scaling factor 6795fb68f37SKaren (Ren) Stengel /// * `x` - second vector, must be different than self 6805fb68f37SKaren (Ren) Stengel /// 6815fb68f37SKaren (Ren) Stengel /// ``` 682eb07d68fSJeremy L Thompson /// # use libceed::{prelude::*, Scalar}; 6835fb68f37SKaren (Ren) Stengel /// # fn main() -> libceed::Result<()> { 6845fb68f37SKaren (Ren) Stengel /// # let ceed = libceed::Ceed::default_init(); 6855fb68f37SKaren (Ren) Stengel /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 6865fb68f37SKaren (Ren) Stengel /// let mut y = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 6875fb68f37SKaren (Ren) Stengel /// 6885fb68f37SKaren (Ren) Stengel /// y = y.axpby(-0.5, 1.0, &x)?; 6895fb68f37SKaren (Ren) Stengel /// for (i, y) in y.view()?.iter().enumerate() { 690aa67b842SZach Atkins /// assert_eq!(*y, (i as Scalar) * 0.5, "Value not set correctly"); 6915fb68f37SKaren (Ren) Stengel /// } 6925fb68f37SKaren (Ren) Stengel /// # Ok(()) 6935fb68f37SKaren (Ren) Stengel /// # } 6945fb68f37SKaren (Ren) Stengel /// ``` 6955fb68f37SKaren (Ren) Stengel #[allow(unused_mut)] 6965fb68f37SKaren (Ren) Stengel pub fn axpby( 6975fb68f37SKaren (Ren) Stengel mut self, 6985fb68f37SKaren (Ren) Stengel alpha: crate::Scalar, 6995fb68f37SKaren (Ren) Stengel beta: crate::Scalar, 700eb07d68fSJeremy L Thompson x: &Vector, 7015fb68f37SKaren (Ren) Stengel ) -> crate::Result<Self> { 702656ef1e5SJeremy L Thompson self.check_error(unsafe { bind_ceed::CeedVectorAXPBY(self.ptr, alpha, beta, x.ptr) })?; 7035fb68f37SKaren (Ren) Stengel Ok(self) 7045fb68f37SKaren (Ren) Stengel } 7055fb68f37SKaren (Ren) Stengel 7067ed177dbSJed Brown /// Compute the pointwise multiplication w = x .* y for Vectors 7079df49d7eSJed Brown /// 7089df49d7eSJed Brown /// # arguments 7099df49d7eSJed Brown /// 7109df49d7eSJed Brown /// * `x` - first vector for product 7119df49d7eSJed Brown /// * `y` - second vector for product 7129df49d7eSJed Brown /// 7139df49d7eSJed Brown /// ``` 714eb07d68fSJeremy L Thompson /// # use libceed::{prelude::*, Scalar}; 7154d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 7169df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 717c68be7a2SJeremy L Thompson /// let mut w = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 718c68be7a2SJeremy L Thompson /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 719c68be7a2SJeremy L Thompson /// let y = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 7209df49d7eSJed Brown /// 721c68be7a2SJeremy L Thompson /// w = w.pointwise_mult(&x, &y)?; 722d3677ae8SJeremy L Thompson /// for (i, w) in w.view()?.iter().enumerate() { 723d3677ae8SJeremy L Thompson /// assert_eq!(*w, (i as Scalar).powf(2.0), "Value not set correctly"); 724d3677ae8SJeremy L Thompson /// } 725c68be7a2SJeremy L Thompson /// # Ok(()) 726c68be7a2SJeremy L Thompson /// # } 7279df49d7eSJed Brown /// ``` 7289df49d7eSJed Brown #[allow(unused_mut)] 729eb07d68fSJeremy L Thompson pub fn pointwise_mult(mut self, x: &Vector, y: &Vector) -> crate::Result<Self> { 730656ef1e5SJeremy L Thompson self.check_error(unsafe { bind_ceed::CeedVectorPointwiseMult(self.ptr, x.ptr, y.ptr) })?; 7319df49d7eSJed Brown Ok(self) 7329df49d7eSJed Brown } 7339df49d7eSJed Brown 7347ed177dbSJed Brown /// Compute the pointwise multiplication w = w .* x for Vectors 7359df49d7eSJed Brown /// 7369df49d7eSJed Brown /// # arguments 7379df49d7eSJed Brown /// 7389df49d7eSJed Brown /// * `x` - second vector for product 7399df49d7eSJed Brown /// 7409df49d7eSJed Brown /// ``` 741eb07d68fSJeremy L Thompson /// # use libceed::{prelude::*, Scalar}; 7424d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 7439df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 744c68be7a2SJeremy L Thompson /// let mut w = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 745c68be7a2SJeremy L Thompson /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 7469df49d7eSJed Brown /// 747c68be7a2SJeremy L Thompson /// w = w.pointwise_scale(&x)?; 748d3677ae8SJeremy L Thompson /// for (i, w) in w.view()?.iter().enumerate() { 749d3677ae8SJeremy L Thompson /// assert_eq!(*w, (i as Scalar).powf(2.0), "Value not set correctly"); 750d3677ae8SJeremy L Thompson /// } 751c68be7a2SJeremy L Thompson /// # Ok(()) 752c68be7a2SJeremy L Thompson /// # } 7539df49d7eSJed Brown /// ``` 7549df49d7eSJed Brown #[allow(unused_mut)] 755eb07d68fSJeremy L Thompson pub fn pointwise_scale(mut self, x: &Vector) -> crate::Result<Self> { 756656ef1e5SJeremy L Thompson self.check_error(unsafe { bind_ceed::CeedVectorPointwiseMult(self.ptr, self.ptr, x.ptr) })?; 7579df49d7eSJed Brown Ok(self) 7589df49d7eSJed Brown } 7599df49d7eSJed Brown 7607ed177dbSJed Brown /// Compute the pointwise multiplication w = w .* w for a Vector 7619df49d7eSJed Brown /// 7629df49d7eSJed Brown /// ``` 763eb07d68fSJeremy L Thompson /// # use libceed::{prelude::*, Scalar}; 7644d27c890SJeremy L Thompson /// # fn main() -> libceed::Result<()> { 7659df49d7eSJed Brown /// # let ceed = libceed::Ceed::default_init(); 766c68be7a2SJeremy L Thompson /// let mut w = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 7679df49d7eSJed Brown /// 768c68be7a2SJeremy L Thompson /// w = w.pointwise_square()?; 769d3677ae8SJeremy L Thompson /// for (i, w) in w.view()?.iter().enumerate() { 770d3677ae8SJeremy L Thompson /// assert_eq!(*w, (i as Scalar).powf(2.0), "Value not set correctly"); 771d3677ae8SJeremy L Thompson /// } 772c68be7a2SJeremy L Thompson /// # Ok(()) 773c68be7a2SJeremy L Thompson /// # } 7749df49d7eSJed Brown /// ``` 7759df49d7eSJed Brown #[allow(unused_mut)] 7769df49d7eSJed Brown pub fn pointwise_square(mut self) -> crate::Result<Self> { 777656ef1e5SJeremy L Thompson self.check_error(unsafe { 778656ef1e5SJeremy L Thompson bind_ceed::CeedVectorPointwiseMult(self.ptr, self.ptr, self.ptr) 779656ef1e5SJeremy L Thompson })?; 7809df49d7eSJed Brown Ok(self) 7819df49d7eSJed Brown } 7829df49d7eSJed Brown } 7839df49d7eSJed Brown 7849df49d7eSJed Brown // ----------------------------------------------------------------------------- 7859df49d7eSJed Brown // Vector Viewer 7869df49d7eSJed Brown // ----------------------------------------------------------------------------- 7879df49d7eSJed Brown /// A (host) view of a Vector with Deref to slice. We can't make 7889df49d7eSJed Brown /// Vector itself Deref to slice because we can't handle the drop to 7899df49d7eSJed Brown /// call bind_ceed::CeedVectorRestoreArrayRead(). 7909df49d7eSJed Brown #[derive(Debug)] 7919df49d7eSJed Brown pub struct VectorView<'a> { 7929df49d7eSJed Brown vec: &'a Vector<'a>, 79380a9ef05SNatalie Beams array: *const crate::Scalar, 7949df49d7eSJed Brown } 7959df49d7eSJed Brown 7969df49d7eSJed Brown impl<'a> VectorView<'a> { 7979df49d7eSJed Brown /// Construct a VectorView from a Vector reference 7984d27c890SJeremy L Thompson fn new(vec: &'a Vector) -> crate::Result<Self> { 7999df49d7eSJed Brown let mut array = std::ptr::null(); 800656ef1e5SJeremy L Thompson vec.check_error(unsafe { 8019df49d7eSJed Brown bind_ceed::CeedVectorGetArrayRead( 8029df49d7eSJed Brown vec.ptr, 8039df49d7eSJed Brown crate::MemType::Host as bind_ceed::CeedMemType, 8049df49d7eSJed Brown &mut array, 805e78171edSJeremy L Thompson ) 806656ef1e5SJeremy L Thompson })?; 807bf55b007SJeremy L Thompson Ok(Self { vec, array }) 8089df49d7eSJed Brown } 8099df49d7eSJed Brown } 8109df49d7eSJed Brown 8119df49d7eSJed Brown // Destructor 8129df49d7eSJed Brown impl<'a> Drop for VectorView<'a> { 8139df49d7eSJed Brown fn drop(&mut self) { 8149df49d7eSJed Brown unsafe { 8159df49d7eSJed Brown bind_ceed::CeedVectorRestoreArrayRead(self.vec.ptr, &mut self.array); 8169df49d7eSJed Brown } 8179df49d7eSJed Brown } 8189df49d7eSJed Brown } 8199df49d7eSJed Brown 8209df49d7eSJed Brown // Data access 8219df49d7eSJed Brown impl<'a> Deref for VectorView<'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 // Viewing 8299df49d7eSJed Brown impl<'a> fmt::Display for VectorView<'a> { 8309df49d7eSJed Brown fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 8319df49d7eSJed Brown write!(f, "VectorView({:?})", self.deref()) 8329df49d7eSJed Brown } 8339df49d7eSJed Brown } 8349df49d7eSJed Brown 8359df49d7eSJed Brown // ----------------------------------------------------------------------------- 8369df49d7eSJed Brown // Vector Viewer Mutable 8379df49d7eSJed Brown // ----------------------------------------------------------------------------- 8389df49d7eSJed Brown /// A mutable (host) view of a Vector with Deref to slice. 8399df49d7eSJed Brown #[derive(Debug)] 8409df49d7eSJed Brown pub struct VectorViewMut<'a> { 8419df49d7eSJed Brown vec: &'a Vector<'a>, 84280a9ef05SNatalie Beams array: *mut crate::Scalar, 8439df49d7eSJed Brown } 8449df49d7eSJed Brown 8459df49d7eSJed Brown impl<'a> VectorViewMut<'a> { 8469df49d7eSJed Brown /// Construct a VectorViewMut from a Vector reference 8474d27c890SJeremy L Thompson fn new(vec: &'a mut Vector) -> crate::Result<Self> { 848e60d507dSJeremy L Thompson let mut array = std::ptr::null_mut(); 849656ef1e5SJeremy L Thompson vec.check_error(unsafe { 8509df49d7eSJed Brown bind_ceed::CeedVectorGetArray( 8519df49d7eSJed Brown vec.ptr, 8529df49d7eSJed Brown crate::MemType::Host as bind_ceed::CeedMemType, 853e60d507dSJeremy L Thompson &mut array, 854e78171edSJeremy L Thompson ) 855656ef1e5SJeremy L Thompson })?; 856e60d507dSJeremy L Thompson Ok(Self { vec, array }) 8579df49d7eSJed Brown } 8589df49d7eSJed Brown } 8599df49d7eSJed Brown 8609df49d7eSJed Brown // Destructor 8619df49d7eSJed Brown impl<'a> Drop for VectorViewMut<'a> { 8629df49d7eSJed Brown fn drop(&mut self) { 8639df49d7eSJed Brown unsafe { 8649df49d7eSJed Brown bind_ceed::CeedVectorRestoreArray(self.vec.ptr, &mut self.array); 8659df49d7eSJed Brown } 8669df49d7eSJed Brown } 8679df49d7eSJed Brown } 8689df49d7eSJed Brown 8699df49d7eSJed Brown // Data access 8709df49d7eSJed Brown impl<'a> Deref for VectorViewMut<'a> { 87180a9ef05SNatalie Beams type Target = [crate::Scalar]; 87280a9ef05SNatalie Beams fn deref(&self) -> &[crate::Scalar] { 8739df49d7eSJed Brown unsafe { std::slice::from_raw_parts(self.array, self.vec.len()) } 8749df49d7eSJed Brown } 8759df49d7eSJed Brown } 8769df49d7eSJed Brown 8779df49d7eSJed Brown // Mutable data access 8789df49d7eSJed Brown impl<'a> DerefMut for VectorViewMut<'a> { 87980a9ef05SNatalie Beams fn deref_mut(&mut self) -> &mut [crate::Scalar] { 8809df49d7eSJed Brown unsafe { std::slice::from_raw_parts_mut(self.array, self.vec.len()) } 8819df49d7eSJed Brown } 8829df49d7eSJed Brown } 8839df49d7eSJed Brown 8849df49d7eSJed Brown // Viewing 8859df49d7eSJed Brown impl<'a> fmt::Display for VectorViewMut<'a> { 8869df49d7eSJed Brown fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 8879df49d7eSJed Brown write!(f, "VectorViewMut({:?})", self.deref()) 8889df49d7eSJed Brown } 8899df49d7eSJed Brown } 8909df49d7eSJed Brown 8919df49d7eSJed Brown // ----------------------------------------------------------------------------- 892