xref: /libCEED/rust/libceed/src/vector.rs (revision 9ba83ac0e4b1fca39d6fa6737a318a9f0cbc172d)
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