xref: /libCEED/rust/libceed/src/vector.rs (revision d3677ae8c8463ed424a8c5269c03811212785cd9)
19df49d7eSJed Brown // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
29df49d7eSJed Brown // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
39df49d7eSJed Brown // reserved. See files LICENSE and NOTICE for details.
49df49d7eSJed Brown //
59df49d7eSJed Brown // This file is part of CEED, a collection of benchmarks, miniapps, software
69df49d7eSJed Brown // libraries and APIs for efficient high-order finite element and spectral
79df49d7eSJed Brown // element discretizations for exascale applications. For more information and
89df49d7eSJed Brown // source code availability see http://github.com/ceed.
99df49d7eSJed Brown //
109df49d7eSJed Brown // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
119df49d7eSJed Brown // a collaborative effort of two U.S. Department of Energy organizations (Office
129df49d7eSJed Brown // of Science and the National Nuclear Security Administration) responsible for
139df49d7eSJed Brown // the planning and preparation of a capable exascale ecosystem, including
149df49d7eSJed Brown // software, applications, hardware, advanced system engineering and early
159df49d7eSJed Brown // testbed platforms, in support of the nation's exascale computing imperative
169df49d7eSJed Brown 
179df49d7eSJed Brown //! A Ceed Vector constitutes the main data structure and serves as input/output
189df49d7eSJed Brown //! for Ceed Operators.
199df49d7eSJed Brown 
209df49d7eSJed Brown use std::{
219df49d7eSJed Brown     ops::{Deref, DerefMut},
229df49d7eSJed Brown     os::raw::c_char,
239df49d7eSJed Brown };
249df49d7eSJed Brown 
259df49d7eSJed Brown use crate::prelude::*;
269df49d7eSJed Brown 
279df49d7eSJed Brown // -----------------------------------------------------------------------------
289df49d7eSJed Brown // CeedVector option
299df49d7eSJed Brown // -----------------------------------------------------------------------------
30c68be7a2SJeremy L Thompson #[derive(Debug)]
319df49d7eSJed Brown pub enum VectorOpt<'a> {
329df49d7eSJed Brown     Some(&'a Vector<'a>),
339df49d7eSJed Brown     Active,
349df49d7eSJed Brown     None,
359df49d7eSJed Brown }
369df49d7eSJed Brown /// Construct a VectorOpt reference from a Vector reference
379df49d7eSJed Brown impl<'a> From<&'a Vector<'_>> for VectorOpt<'a> {
389df49d7eSJed Brown     fn from(vec: &'a Vector) -> Self {
399df49d7eSJed Brown         debug_assert!(vec.ptr != unsafe { bind_ceed::CEED_VECTOR_ACTIVE });
40c68be7a2SJeremy L Thompson         debug_assert!(vec.ptr != unsafe { bind_ceed::CEED_VECTOR_NONE });
419df49d7eSJed Brown         Self::Some(vec)
429df49d7eSJed Brown     }
439df49d7eSJed Brown }
449df49d7eSJed Brown impl<'a> VectorOpt<'a> {
459df49d7eSJed Brown     /// Transform a Rust libCEED VectorOpt into C libCEED CeedVector
469df49d7eSJed Brown     pub(crate) fn to_raw(self) -> bind_ceed::CeedVector {
479df49d7eSJed Brown         match self {
489df49d7eSJed Brown             Self::Some(vec) => vec.ptr,
499df49d7eSJed Brown             Self::Active => unsafe { bind_ceed::CEED_VECTOR_ACTIVE },
50c68be7a2SJeremy L Thompson             Self::None => unsafe { bind_ceed::CEED_VECTOR_NONE },
519df49d7eSJed Brown         }
529df49d7eSJed Brown     }
53e03682afSJeremy L Thompson 
54e03682afSJeremy L Thompson     /// Check if a VectorOpt is Some
55e03682afSJeremy L Thompson     ///
56e03682afSJeremy L Thompson     /// ```
57e03682afSJeremy L Thompson     /// # use libceed::prelude::*;
584d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
59e03682afSJeremy L Thompson     /// # let ceed = libceed::Ceed::default_init();
60e03682afSJeremy L Thompson     /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?;
61e03682afSJeremy L Thompson     /// let vec_opt = VectorOpt::from(&vec);
62e03682afSJeremy L Thompson     /// assert!(vec_opt.is_some(), "Incorrect VectorOpt");
63e03682afSJeremy L Thompson     ///
64e03682afSJeremy L Thompson     /// let vec_opt = VectorOpt::Active;
65e03682afSJeremy L Thompson     /// assert!(!vec_opt.is_some(), "Incorrect VectorOpt");
66e03682afSJeremy L Thompson     ///
67e03682afSJeremy L Thompson     /// let vec_opt = VectorOpt::None;
68e03682afSJeremy L Thompson     /// assert!(!vec_opt.is_some(), "Incorrect VectorOpt");
69e03682afSJeremy L Thompson     /// # Ok(())
70e03682afSJeremy L Thompson     /// # }
71e03682afSJeremy L Thompson     /// ```
72e03682afSJeremy L Thompson     pub fn is_some(&self) -> bool {
73e03682afSJeremy L Thompson         match self {
74e03682afSJeremy L Thompson             Self::Some(_) => true,
75e03682afSJeremy L Thompson             Self::Active => false,
76e03682afSJeremy L Thompson             Self::None => false,
77e03682afSJeremy L Thompson         }
78e03682afSJeremy L Thompson     }
79e03682afSJeremy L Thompson 
80e03682afSJeremy L Thompson     /// Check if a VectorOpt is Active
81e03682afSJeremy L Thompson     ///
82e03682afSJeremy L Thompson     /// ```
83e03682afSJeremy L Thompson     /// # use libceed::prelude::*;
844d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
85e03682afSJeremy L Thompson     /// # let ceed = libceed::Ceed::default_init();
86e03682afSJeremy L Thompson     /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?;
87e03682afSJeremy L Thompson     /// let vec_opt = VectorOpt::from(&vec);
88e03682afSJeremy L Thompson     /// assert!(!vec_opt.is_active(), "Incorrect VectorOpt");
89e03682afSJeremy L Thompson     ///
90e03682afSJeremy L Thompson     /// let vec_opt = VectorOpt::Active;
91e03682afSJeremy L Thompson     /// assert!(vec_opt.is_active(), "Incorrect VectorOpt");
92e03682afSJeremy L Thompson     ///
93e03682afSJeremy L Thompson     /// let vec_opt = VectorOpt::None;
94e03682afSJeremy L Thompson     /// assert!(!vec_opt.is_active(), "Incorrect VectorOpt");
95e03682afSJeremy L Thompson     /// # Ok(())
96e03682afSJeremy L Thompson     /// # }
97e03682afSJeremy L Thompson     /// ```
98e03682afSJeremy L Thompson     pub fn is_active(&self) -> bool {
99e03682afSJeremy L Thompson         match self {
100e03682afSJeremy L Thompson             Self::Some(_) => false,
101e03682afSJeremy L Thompson             Self::Active => true,
102e03682afSJeremy L Thompson             Self::None => false,
103e03682afSJeremy L Thompson         }
104e03682afSJeremy L Thompson     }
105e03682afSJeremy L Thompson 
106e03682afSJeremy L Thompson     /// Check if a VectorOpt is Some
107e03682afSJeremy L Thompson     ///
108e03682afSJeremy L Thompson     /// ```
109e03682afSJeremy L Thompson     /// # use libceed::prelude::*;
1104d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
111e03682afSJeremy L Thompson     /// # let ceed = libceed::Ceed::default_init();
112e03682afSJeremy L Thompson     /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?;
113e03682afSJeremy L Thompson     /// let vec_opt = VectorOpt::from(&vec);
114e03682afSJeremy L Thompson     /// assert!(!vec_opt.is_none(), "Incorrect VectorOpt");
115e03682afSJeremy L Thompson     ///
116e03682afSJeremy L Thompson     /// let vec_opt = VectorOpt::Active;
117e03682afSJeremy L Thompson     /// assert!(!vec_opt.is_none(), "Incorrect VectorOpt");
118e03682afSJeremy L Thompson     ///
119e03682afSJeremy L Thompson     /// let vec_opt = VectorOpt::None;
120e03682afSJeremy L Thompson     /// assert!(vec_opt.is_none(), "Incorrect VectorOpt");
121e03682afSJeremy L Thompson     /// # Ok(())
122e03682afSJeremy L Thompson     /// # }
123e03682afSJeremy L Thompson     /// ```
124e03682afSJeremy L Thompson     pub fn is_none(&self) -> bool {
125e03682afSJeremy L Thompson         match self {
126e03682afSJeremy L Thompson             Self::Some(_) => false,
127e03682afSJeremy L Thompson             Self::Active => false,
128e03682afSJeremy L Thompson             Self::None => true,
129e03682afSJeremy L Thompson         }
130e03682afSJeremy L Thompson     }
1319df49d7eSJed Brown }
1329df49d7eSJed Brown 
1339df49d7eSJed Brown // -----------------------------------------------------------------------------
13456e67e05SJeremy L Thompson // CeedVector borrowed slice wrapper
13556e67e05SJeremy L Thompson // -----------------------------------------------------------------------------
136486868d3SJeremy L Thompson pub struct VectorSliceWrapper<'a> {
13756e67e05SJeremy L Thompson     pub(crate) vector: crate::Vector<'a>,
13856e67e05SJeremy L Thompson     pub(crate) _slice: &'a mut [crate::Scalar],
13956e67e05SJeremy L Thompson }
14056e67e05SJeremy L Thompson 
14156e67e05SJeremy L Thompson // -----------------------------------------------------------------------------
14256e67e05SJeremy L Thompson // Destructor
14356e67e05SJeremy L Thompson // -----------------------------------------------------------------------------
144486868d3SJeremy L Thompson impl<'a> Drop for VectorSliceWrapper<'a> {
14556e67e05SJeremy L Thompson     fn drop(&mut self) {
14656e67e05SJeremy L Thompson         unsafe {
14756e67e05SJeremy L Thompson             bind_ceed::CeedVectorTakeArray(
14856e67e05SJeremy L Thompson                 self.vector.ptr,
14956e67e05SJeremy L Thompson                 crate::MemType::Host as bind_ceed::CeedMemType,
15056e67e05SJeremy L Thompson                 std::ptr::null_mut(),
15156e67e05SJeremy L Thompson             )
15256e67e05SJeremy L Thompson         };
15356e67e05SJeremy L Thompson     }
15456e67e05SJeremy L Thompson }
15556e67e05SJeremy L Thompson 
15656e67e05SJeremy L Thompson // -----------------------------------------------------------------------------
1579df49d7eSJed Brown // CeedVector context wrapper
1589df49d7eSJed Brown // -----------------------------------------------------------------------------
1599df49d7eSJed Brown #[derive(Debug)]
1609df49d7eSJed Brown pub struct Vector<'a> {
1619df49d7eSJed Brown     pub(crate) ptr: bind_ceed::CeedVector,
1621142270cSJeremy L Thompson     _lifeline: PhantomData<&'a ()>,
1639df49d7eSJed Brown }
1649df49d7eSJed Brown impl From<&'_ Vector<'_>> for bind_ceed::CeedVector {
1659df49d7eSJed Brown     fn from(vec: &Vector) -> Self {
1669df49d7eSJed Brown         vec.ptr
1679df49d7eSJed Brown     }
1689df49d7eSJed Brown }
1699df49d7eSJed Brown 
1709df49d7eSJed Brown // -----------------------------------------------------------------------------
1719df49d7eSJed Brown // Destructor
1729df49d7eSJed Brown // -----------------------------------------------------------------------------
1739df49d7eSJed Brown impl<'a> Drop for Vector<'a> {
1749df49d7eSJed Brown     fn drop(&mut self) {
1759df49d7eSJed Brown         let not_none_and_active = self.ptr != unsafe { bind_ceed::CEED_VECTOR_NONE }
1769df49d7eSJed Brown             && self.ptr != unsafe { bind_ceed::CEED_VECTOR_ACTIVE };
1779df49d7eSJed Brown 
1789df49d7eSJed Brown         if not_none_and_active {
1799df49d7eSJed Brown             unsafe { bind_ceed::CeedVectorDestroy(&mut self.ptr) };
1809df49d7eSJed Brown         }
1819df49d7eSJed Brown     }
1829df49d7eSJed Brown }
1839df49d7eSJed Brown 
1849df49d7eSJed Brown // -----------------------------------------------------------------------------
1859df49d7eSJed Brown // Display
1869df49d7eSJed Brown // -----------------------------------------------------------------------------
1879df49d7eSJed Brown impl<'a> fmt::Display for Vector<'a> {
1889df49d7eSJed Brown     /// View a Vector
1899df49d7eSJed Brown     ///
1909df49d7eSJed Brown     /// ```
1919df49d7eSJed Brown     /// # use libceed::prelude::*;
1924d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
1939df49d7eSJed Brown     /// # let ceed = libceed::Ceed::default_init();
194c68be7a2SJeremy L Thompson     /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?;
1959df49d7eSJed Brown     /// assert_eq!(
1969df49d7eSJed Brown     ///     vec.to_string(),
1979df49d7eSJed Brown     ///     "CeedVector length 3
1989df49d7eSJed Brown     ///     1.00000000
1999df49d7eSJed Brown     ///     2.00000000
2009df49d7eSJed Brown     ///     3.00000000
2019df49d7eSJed Brown     /// "
202c68be7a2SJeremy L Thompson     /// );
203c68be7a2SJeremy L Thompson     /// # Ok(())
204c68be7a2SJeremy L Thompson     /// # }
2059df49d7eSJed Brown     /// ```
2069df49d7eSJed Brown     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2079df49d7eSJed Brown         let mut ptr = std::ptr::null_mut();
2089df49d7eSJed Brown         let mut sizeloc = crate::MAX_BUFFER_LENGTH;
2099df49d7eSJed Brown         let format = CString::new("%12.8f").expect("CString::new failed");
2109df49d7eSJed Brown         let format_c: *const c_char = format.into_raw();
2119df49d7eSJed Brown         let cstring = unsafe {
2129df49d7eSJed Brown             let file = bind_ceed::open_memstream(&mut ptr, &mut sizeloc);
2139df49d7eSJed Brown             bind_ceed::CeedVectorView(self.ptr, format_c, file);
2149df49d7eSJed Brown             bind_ceed::fclose(file);
2159df49d7eSJed Brown             CString::from_raw(ptr)
2169df49d7eSJed Brown         };
2179df49d7eSJed Brown         cstring.to_string_lossy().fmt(f)
2189df49d7eSJed Brown     }
2199df49d7eSJed Brown }
2209df49d7eSJed Brown 
2219df49d7eSJed Brown // -----------------------------------------------------------------------------
2229df49d7eSJed Brown // Implementations
2239df49d7eSJed Brown // -----------------------------------------------------------------------------
2249df49d7eSJed Brown impl<'a> Vector<'a> {
2259df49d7eSJed Brown     // Constructors
2269df49d7eSJed Brown     pub fn create(ceed: &'a crate::Ceed, n: usize) -> crate::Result<Self> {
2279df49d7eSJed Brown         let n = i32::try_from(n).unwrap();
2289df49d7eSJed Brown         let mut ptr = std::ptr::null_mut();
2299df49d7eSJed Brown         let ierr = unsafe { bind_ceed::CeedVectorCreate(ceed.ptr, n, &mut ptr) };
2309df49d7eSJed Brown         ceed.check_error(ierr)?;
2311142270cSJeremy L Thompson         Ok(Self {
2321142270cSJeremy L Thompson             ptr,
2331142270cSJeremy L Thompson             _lifeline: PhantomData,
2341142270cSJeremy L Thompson         })
2359df49d7eSJed Brown     }
2369df49d7eSJed Brown 
2371142270cSJeremy L Thompson     pub(crate) fn from_raw(ptr: bind_ceed::CeedVector) -> crate::Result<Self> {
2381142270cSJeremy L Thompson         Ok(Self {
2391142270cSJeremy L Thompson             ptr,
2401142270cSJeremy L Thompson             _lifeline: PhantomData,
2411142270cSJeremy L Thompson         })
2429df49d7eSJed Brown     }
2439df49d7eSJed Brown 
2449df49d7eSJed Brown     /// Create a Vector from a slice
2459df49d7eSJed Brown     ///
2469df49d7eSJed Brown     /// # arguments
2479df49d7eSJed Brown     ///
2489df49d7eSJed Brown     /// * `slice` - values to initialize vector with
2499df49d7eSJed Brown     ///
2509df49d7eSJed Brown     /// ```
2519df49d7eSJed Brown     /// # use libceed::prelude::*;
2524d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
2539df49d7eSJed Brown     /// # let ceed = libceed::Ceed::default_init();
254c68be7a2SJeremy L Thompson     /// let vec = vector::Vector::from_slice(&ceed, &[1., 2., 3.])?;
2559df49d7eSJed Brown     /// assert_eq!(vec.length(), 3, "Incorrect length from slice");
256c68be7a2SJeremy L Thompson     /// # Ok(())
257c68be7a2SJeremy L Thompson     /// # }
2589df49d7eSJed Brown     /// ```
25980a9ef05SNatalie Beams     pub fn from_slice(ceed: &'a crate::Ceed, v: &[crate::Scalar]) -> crate::Result<Self> {
2609df49d7eSJed Brown         let mut x = Self::create(ceed, v.len())?;
2619df49d7eSJed Brown         x.set_slice(v)?;
2629df49d7eSJed Brown         Ok(x)
2639df49d7eSJed Brown     }
2649df49d7eSJed Brown 
2659df49d7eSJed Brown     /// Create a Vector from a mutable array reference
2669df49d7eSJed Brown     ///
2679df49d7eSJed Brown     /// # arguments
2689df49d7eSJed Brown     ///
2699df49d7eSJed Brown     /// * `slice` - values to initialize vector with
2709df49d7eSJed Brown     ///
2719df49d7eSJed Brown     /// ```
2729df49d7eSJed Brown     /// # use libceed::prelude::*;
2734d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
2749df49d7eSJed Brown     /// # let ceed = libceed::Ceed::default_init();
2759df49d7eSJed Brown     /// let mut rust_vec = vec![1., 2., 3.];
276c68be7a2SJeremy L Thompson     /// let vec = libceed::vector::Vector::from_array(&ceed, &mut rust_vec)?;
2779df49d7eSJed Brown     ///
2789df49d7eSJed Brown     /// assert_eq!(vec.length(), 3, "Incorrect length from slice");
279c68be7a2SJeremy L Thompson     /// # Ok(())
280c68be7a2SJeremy L Thompson     /// # }
2819df49d7eSJed Brown     /// ```
28280a9ef05SNatalie Beams     pub fn from_array(ceed: &'a crate::Ceed, v: &mut [crate::Scalar]) -> crate::Result<Self> {
2839df49d7eSJed Brown         let x = Self::create(ceed, v.len())?;
2849df49d7eSJed Brown         let (host, user_pointer) = (
2859df49d7eSJed Brown             crate::MemType::Host as bind_ceed::CeedMemType,
2869df49d7eSJed Brown             crate::CopyMode::UsePointer as bind_ceed::CeedCopyMode,
2879df49d7eSJed Brown         );
28880a9ef05SNatalie Beams         let v = v.as_ptr() as *mut crate::Scalar;
2899df49d7eSJed Brown         let ierr = unsafe { bind_ceed::CeedVectorSetArray(x.ptr, host, user_pointer, v) };
2909df49d7eSJed Brown         ceed.check_error(ierr)?;
2919df49d7eSJed Brown         Ok(x)
2929df49d7eSJed Brown     }
2939df49d7eSJed Brown 
2941142270cSJeremy L Thompson     // Error handling
2951142270cSJeremy L Thompson     #[doc(hidden)]
2961142270cSJeremy L Thompson     fn check_error(&self, ierr: i32) -> crate::Result<i32> {
2971142270cSJeremy L Thompson         let mut ptr = std::ptr::null_mut();
2981142270cSJeremy L Thompson         unsafe {
2991142270cSJeremy L Thompson             bind_ceed::CeedVectorGetCeed(self.ptr, &mut ptr);
3001142270cSJeremy L Thompson         }
3011142270cSJeremy L Thompson         crate::check_error(ptr, ierr)
3021142270cSJeremy L Thompson     }
3031142270cSJeremy L Thompson 
3049df49d7eSJed Brown     /// Returns the length of a CeedVector
3059df49d7eSJed Brown     ///
3069df49d7eSJed Brown     /// ```
3079df49d7eSJed Brown     /// # use libceed::prelude::*;
3084d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
3099df49d7eSJed Brown     /// # let ceed = libceed::Ceed::default_init();
310c68be7a2SJeremy L Thompson     /// let vec = ceed.vector(10)?;
3119df49d7eSJed Brown     ///
3129df49d7eSJed Brown     /// let n = vec.length();
3139df49d7eSJed Brown     /// assert_eq!(n, 10, "Incorrect length");
314c68be7a2SJeremy L Thompson     /// # Ok(())
315c68be7a2SJeremy L Thompson     /// # }
3169df49d7eSJed Brown     /// ```
3179df49d7eSJed Brown     pub fn length(&self) -> usize {
3189df49d7eSJed Brown         let mut n = 0;
3199df49d7eSJed Brown         unsafe { bind_ceed::CeedVectorGetLength(self.ptr, &mut n) };
3209df49d7eSJed Brown         usize::try_from(n).unwrap()
3219df49d7eSJed Brown     }
3229df49d7eSJed Brown 
3239df49d7eSJed Brown     /// Returns the length of a CeedVector
3249df49d7eSJed Brown     ///
3259df49d7eSJed Brown     /// ```
3269df49d7eSJed Brown     /// # use libceed::prelude::*;
3274d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
3289df49d7eSJed Brown     /// # let ceed = libceed::Ceed::default_init();
329c68be7a2SJeremy L Thompson     /// let vec = ceed.vector(10)?;
3309df49d7eSJed Brown     /// assert_eq!(vec.len(), 10, "Incorrect length");
331c68be7a2SJeremy L Thompson     /// # Ok(())
332c68be7a2SJeremy L Thompson     /// # }
3339df49d7eSJed Brown     /// ```
3349df49d7eSJed Brown     pub fn len(&self) -> usize {
3359df49d7eSJed Brown         self.length()
3369df49d7eSJed Brown     }
3379df49d7eSJed Brown 
3389df49d7eSJed Brown     /// Set the CeedVector to a constant value
3399df49d7eSJed Brown     ///
3409df49d7eSJed Brown     /// # arguments
3419df49d7eSJed Brown     ///
3429df49d7eSJed Brown     /// * `val` - Value to be used
3439df49d7eSJed Brown     ///
3449df49d7eSJed Brown     /// ```
3459df49d7eSJed Brown     /// # use libceed::prelude::*;
3464d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
3479df49d7eSJed Brown     /// # let ceed = libceed::Ceed::default_init();
3489df49d7eSJed Brown     /// let len = 10;
349c68be7a2SJeremy L Thompson     /// let mut vec = ceed.vector(len)?;
3509df49d7eSJed Brown     ///
3519df49d7eSJed Brown     /// let val = 42.0;
352c68be7a2SJeremy L Thompson     /// vec.set_value(val)?;
3539df49d7eSJed Brown     ///
354*d3677ae8SJeremy L Thompson     /// for v in vec.view()?.iter() {
3559df49d7eSJed Brown     ///     assert_eq!(*v, val, "Value not set correctly");
356*d3677ae8SJeremy L Thompson     /// }
357c68be7a2SJeremy L Thompson     /// # Ok(())
358c68be7a2SJeremy L Thompson     /// # }
3599df49d7eSJed Brown     /// ```
36080a9ef05SNatalie Beams     pub fn set_value(&mut self, value: crate::Scalar) -> crate::Result<i32> {
3619df49d7eSJed Brown         let ierr = unsafe { bind_ceed::CeedVectorSetValue(self.ptr, value) };
3621142270cSJeremy L Thompson         self.check_error(ierr)
3639df49d7eSJed Brown     }
3649df49d7eSJed Brown 
3659df49d7eSJed Brown     /// Set values from a slice of the same length
3669df49d7eSJed Brown     ///
3679df49d7eSJed Brown     /// # arguments
3689df49d7eSJed Brown     ///
3699df49d7eSJed Brown     /// * `slice` - values to into self; length must match
3709df49d7eSJed Brown     ///
3719df49d7eSJed Brown     /// ```
3729df49d7eSJed Brown     /// # use libceed::prelude::*;
3734d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
3749df49d7eSJed Brown     /// # let ceed = libceed::Ceed::default_init();
375c68be7a2SJeremy L Thompson     /// let mut vec = ceed.vector(4)?;
376c68be7a2SJeremy L Thompson     /// vec.set_slice(&[10., 11., 12., 13.])?;
3779df49d7eSJed Brown     ///
378*d3677ae8SJeremy L Thompson     /// for (i, v) in vec.view()?.iter().enumerate() {
37980a9ef05SNatalie Beams     ///     assert_eq!(*v, 10. + i as Scalar, "Slice not set correctly");
380*d3677ae8SJeremy L Thompson     /// }
381c68be7a2SJeremy L Thompson     /// # Ok(())
382c68be7a2SJeremy L Thompson     /// # }
3839df49d7eSJed Brown     /// ```
38480a9ef05SNatalie Beams     pub fn set_slice(&mut self, slice: &[crate::Scalar]) -> crate::Result<i32> {
3859df49d7eSJed Brown         assert_eq!(self.length(), slice.len());
3869df49d7eSJed Brown         let (host, copy_mode) = (
3879df49d7eSJed Brown             crate::MemType::Host as bind_ceed::CeedMemType,
3889df49d7eSJed Brown             crate::CopyMode::CopyValues as bind_ceed::CeedCopyMode,
3899df49d7eSJed Brown         );
3909df49d7eSJed Brown         let ierr = unsafe {
39180a9ef05SNatalie Beams             bind_ceed::CeedVectorSetArray(
39280a9ef05SNatalie Beams                 self.ptr,
39380a9ef05SNatalie Beams                 host,
39480a9ef05SNatalie Beams                 copy_mode,
39580a9ef05SNatalie Beams                 slice.as_ptr() as *mut crate::Scalar,
39680a9ef05SNatalie Beams             )
3979df49d7eSJed Brown         };
3981142270cSJeremy L Thompson         self.check_error(ierr)
3999df49d7eSJed Brown     }
4009df49d7eSJed Brown 
401486868d3SJeremy L Thompson     /// Wrap a mutable slice in a Vector of the same length
40256e67e05SJeremy L Thompson     ///
40356e67e05SJeremy L Thompson     /// # arguments
40456e67e05SJeremy L Thompson     ///
405486868d3SJeremy L Thompson     /// * `slice` - values to wrap in self; length must match
40656e67e05SJeremy L Thompson     ///
40756e67e05SJeremy L Thompson     /// ```
40856e67e05SJeremy L Thompson     /// # use libceed::prelude::*;
40956e67e05SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
41056e67e05SJeremy L Thompson     /// # let ceed = libceed::Ceed::default_init();
41156e67e05SJeremy L Thompson     /// let mut vec = ceed.vector(4)?;
412486868d3SJeremy L Thompson     /// let mut array = [10., 11., 12., 13.];
41356e67e05SJeremy L Thompson     ///
41456e67e05SJeremy L Thompson     /// {
415486868d3SJeremy L Thompson     ///     // `wrapper` holds a mutable reference to the wrapped slice
416486868d3SJeremy L Thompson     ///     //   that is dropped when `wrapper` goes out of scope
417486868d3SJeremy L Thompson     ///     let wrapper = vec.wrap_slice_mut(&mut array)?;
418*d3677ae8SJeremy L Thompson     ///     for (i, v) in vec.view()?.iter().enumerate() {
41956e67e05SJeremy L Thompson     ///         assert_eq!(*v, 10. + i as Scalar, "Slice not set correctly");
420*d3677ae8SJeremy L Thompson     ///     }
42156e67e05SJeremy L Thompson     ///
422486868d3SJeremy L Thompson     ///     // This line will not compile, as the `wrapper` holds mutable
423486868d3SJeremy L Thompson     ///     //   access to the `array`
424486868d3SJeremy L Thompson     ///     // array[0] = 5.0;
42556e67e05SJeremy L Thompson     ///
426486868d3SJeremy L Thompson     ///     // Changes here are reflected in the `array`
42756e67e05SJeremy L Thompson     ///     vec.set_value(5.0)?;
428*d3677ae8SJeremy L Thompson     ///     for v in vec.view()?.iter() {
429486868d3SJeremy L Thompson     ///         assert_eq!(*v, 5.0 as Scalar, "Value not set correctly");
430*d3677ae8SJeremy L Thompson     ///     }
43156e67e05SJeremy L Thompson     /// }
43256e67e05SJeremy L Thompson     ///
433486868d3SJeremy L Thompson     /// // 'array' remains changed
434*d3677ae8SJeremy L Thompson     /// for v in array.iter() {
435486868d3SJeremy L Thompson     ///     assert_eq!(*v, 5.0 as Scalar, "Array not mutated correctly");
436*d3677ae8SJeremy L Thompson     /// }
43756e67e05SJeremy L Thompson     ///
438486868d3SJeremy L Thompson     /// // While changes to `vec` no longer affect `array`
439486868d3SJeremy L Thompson     /// vec.set_value(6.0)?;
440*d3677ae8SJeremy L Thompson     /// for v in array.iter() {
441486868d3SJeremy L Thompson     ///     assert_eq!(*v, 5.0 as Scalar, "Array mutated without permission");
442*d3677ae8SJeremy L Thompson     /// }
44356e67e05SJeremy L Thompson     /// # Ok(())
44456e67e05SJeremy L Thompson     /// # }
44556e67e05SJeremy L Thompson     /// ```
446486868d3SJeremy L Thompson     pub fn wrap_slice_mut<'b>(
44756e67e05SJeremy L Thompson         &mut self,
44856e67e05SJeremy L Thompson         slice: &'b mut [crate::Scalar],
449486868d3SJeremy L Thompson     ) -> crate::Result<VectorSliceWrapper<'b>> {
45056e67e05SJeremy L Thompson         assert_eq!(self.length(), slice.len());
45156e67e05SJeremy L Thompson         let (host, copy_mode) = (
45256e67e05SJeremy L Thompson             crate::MemType::Host as bind_ceed::CeedMemType,
45356e67e05SJeremy L Thompson             crate::CopyMode::UsePointer as bind_ceed::CeedCopyMode,
45456e67e05SJeremy L Thompson         );
45556e67e05SJeremy L Thompson         let ierr = unsafe {
45656e67e05SJeremy L Thompson             bind_ceed::CeedVectorSetArray(
45756e67e05SJeremy L Thompson                 self.ptr,
45856e67e05SJeremy L Thompson                 host,
45956e67e05SJeremy L Thompson                 copy_mode,
46056e67e05SJeremy L Thompson                 slice.as_ptr() as *mut crate::Scalar,
46156e67e05SJeremy L Thompson             )
46256e67e05SJeremy L Thompson         };
46356e67e05SJeremy L Thompson         self.check_error(ierr)?;
46456e67e05SJeremy L Thompson 
46556e67e05SJeremy L Thompson         let mut ptr_copy = std::ptr::null_mut();
46656e67e05SJeremy L Thompson         let ierr = unsafe { bind_ceed::CeedVectorReferenceCopy(self.ptr, &mut ptr_copy) };
46756e67e05SJeremy L Thompson         self.check_error(ierr)?;
46856e67e05SJeremy L Thompson 
469486868d3SJeremy L Thompson         Ok(crate::VectorSliceWrapper {
47056e67e05SJeremy L Thompson             vector: crate::Vector::from_raw(ptr_copy)?,
47156e67e05SJeremy L Thompson             _slice: slice,
47256e67e05SJeremy L Thompson         })
47356e67e05SJeremy L Thompson     }
47456e67e05SJeremy L Thompson 
4759df49d7eSJed Brown     /// Sync the CeedVector to a specified memtype
4769df49d7eSJed Brown     ///
4779df49d7eSJed Brown     /// # arguments
4789df49d7eSJed Brown     ///
4799df49d7eSJed Brown     /// * `mtype` - Memtype to be synced
4809df49d7eSJed Brown     ///
4819df49d7eSJed Brown     /// ```
4829df49d7eSJed Brown     /// # use libceed::prelude::*;
4834d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
4849df49d7eSJed Brown     /// # let ceed = libceed::Ceed::default_init();
4859df49d7eSJed Brown     /// let len = 10;
486c68be7a2SJeremy L Thompson     /// let mut vec = ceed.vector(len)?;
4879df49d7eSJed Brown     ///
4889df49d7eSJed Brown     /// let val = 42.0;
4899df49d7eSJed Brown     /// vec.set_value(val);
490c68be7a2SJeremy L Thompson     /// vec.sync(MemType::Host)?;
4919df49d7eSJed Brown     ///
492*d3677ae8SJeremy L Thompson     /// for v in vec.view()?.iter() {
4939df49d7eSJed Brown     ///     assert_eq!(*v, val, "Value not set correctly");
494*d3677ae8SJeremy L Thompson     /// }
495c68be7a2SJeremy L Thompson     /// # Ok(())
496c68be7a2SJeremy L Thompson     /// # }
4979df49d7eSJed Brown     /// ```
4989df49d7eSJed Brown     pub fn sync(&self, mtype: crate::MemType) -> crate::Result<i32> {
4999df49d7eSJed Brown         let ierr =
5009df49d7eSJed Brown             unsafe { bind_ceed::CeedVectorSyncArray(self.ptr, mtype as bind_ceed::CeedMemType) };
5011142270cSJeremy L Thompson         self.check_error(ierr)
5029df49d7eSJed Brown     }
5039df49d7eSJed Brown 
5049df49d7eSJed Brown     /// Create an immutable view
5059df49d7eSJed Brown     ///
5069df49d7eSJed Brown     /// ```
5079df49d7eSJed Brown     /// # use libceed::prelude::*;
5084d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
5099df49d7eSJed Brown     /// # let ceed = libceed::Ceed::default_init();
510c68be7a2SJeremy L Thompson     /// let vec = ceed.vector_from_slice(&[10., 11., 12., 13.])?;
5119df49d7eSJed Brown     ///
512e78171edSJeremy L Thompson     /// let v = vec.view()?;
5139df49d7eSJed Brown     /// assert_eq!(v[0..2], [10., 11.]);
5149df49d7eSJed Brown     ///
5159df49d7eSJed Brown     /// // It is valid to have multiple immutable views
516e78171edSJeremy L Thompson     /// let w = vec.view()?;
5179df49d7eSJed Brown     /// assert_eq!(v[1..], w[1..]);
518c68be7a2SJeremy L Thompson     /// # Ok(())
519c68be7a2SJeremy L Thompson     /// # }
5209df49d7eSJed Brown     /// ```
521e78171edSJeremy L Thompson     pub fn view(&self) -> crate::Result<VectorView> {
5229df49d7eSJed Brown         VectorView::new(self)
5239df49d7eSJed Brown     }
5249df49d7eSJed Brown 
5259df49d7eSJed Brown     /// Create an mutable view
5269df49d7eSJed Brown     ///
5279df49d7eSJed Brown     /// ```
5289df49d7eSJed Brown     /// # use libceed::prelude::*;
5294d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
5309df49d7eSJed Brown     /// # let ceed = libceed::Ceed::default_init();
531c68be7a2SJeremy L Thompson     /// let mut vec = ceed.vector_from_slice(&[10., 11., 12., 13.])?;
5329df49d7eSJed Brown     ///
5339df49d7eSJed Brown     /// {
534e78171edSJeremy L Thompson     ///     let mut v = vec.view_mut()?;
5359df49d7eSJed Brown     ///     v[2] = 9.;
5369df49d7eSJed Brown     /// }
5379df49d7eSJed Brown     ///
538e78171edSJeremy L Thompson     /// let w = vec.view()?;
5399df49d7eSJed Brown     /// assert_eq!(w[2], 9., "View did not mutate data");
540c68be7a2SJeremy L Thompson     /// # Ok(())
541c68be7a2SJeremy L Thompson     /// # }
5429df49d7eSJed Brown     /// ```
543e78171edSJeremy L Thompson     pub fn view_mut(&mut self) -> crate::Result<VectorViewMut> {
5449df49d7eSJed Brown         VectorViewMut::new(self)
5459df49d7eSJed Brown     }
5469df49d7eSJed Brown 
5479df49d7eSJed Brown     /// Return the norm of a CeedVector
5489df49d7eSJed Brown     ///
5499df49d7eSJed Brown     /// # arguments
5509df49d7eSJed Brown     ///
5519df49d7eSJed Brown     /// * `ntype` - Norm type One, Two, or Max
5529df49d7eSJed Brown     ///
5539df49d7eSJed Brown     /// ```
5549df49d7eSJed Brown     /// # use libceed::prelude::*;
5554d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
5569df49d7eSJed Brown     /// # let ceed = libceed::Ceed::default_init();
557c68be7a2SJeremy L Thompson     /// let vec = ceed.vector_from_slice(&[1., 2., 3., 4.])?;
5589df49d7eSJed Brown     ///
559c68be7a2SJeremy L Thompson     /// let max_norm = vec.norm(NormType::Max)?;
5609df49d7eSJed Brown     /// assert_eq!(max_norm, 4.0, "Incorrect Max norm");
5619df49d7eSJed Brown     ///
562c68be7a2SJeremy L Thompson     /// let l1_norm = vec.norm(NormType::One)?;
5639df49d7eSJed Brown     /// assert_eq!(l1_norm, 10., "Incorrect L1 norm");
5649df49d7eSJed Brown     ///
565c68be7a2SJeremy L Thompson     /// let l2_norm = vec.norm(NormType::Two)?;
5669df49d7eSJed Brown     /// assert!((l2_norm - 5.477) < 1e-3, "Incorrect L2 norm");
567c68be7a2SJeremy L Thompson     /// # Ok(())
568c68be7a2SJeremy L Thompson     /// # }
5699df49d7eSJed Brown     /// ```
57080a9ef05SNatalie Beams     pub fn norm(&self, ntype: crate::NormType) -> crate::Result<crate::Scalar> {
57180a9ef05SNatalie Beams         let mut res: crate::Scalar = 0.0;
5729df49d7eSJed Brown         let ierr = unsafe {
5739df49d7eSJed Brown             bind_ceed::CeedVectorNorm(self.ptr, ntype as bind_ceed::CeedNormType, &mut res)
5749df49d7eSJed Brown         };
5751142270cSJeremy L Thompson         self.check_error(ierr)?;
5769df49d7eSJed Brown         Ok(res)
5779df49d7eSJed Brown     }
5789df49d7eSJed Brown 
5799df49d7eSJed Brown     /// Compute x = alpha x for a CeedVector
5809df49d7eSJed Brown     ///
5819df49d7eSJed Brown     /// # arguments
5829df49d7eSJed Brown     ///
5839df49d7eSJed Brown     /// * `alpha` - scaling factor
5849df49d7eSJed Brown     ///
5859df49d7eSJed Brown     /// ```
5869df49d7eSJed Brown     /// # use libceed::prelude::*;
5874d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
5889df49d7eSJed Brown     /// # let ceed = libceed::Ceed::default_init();
589c68be7a2SJeremy L Thompson     /// let mut vec = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
5909df49d7eSJed Brown     ///
591c68be7a2SJeremy L Thompson     /// vec = vec.scale(-1.0)?;
592*d3677ae8SJeremy L Thompson     /// for (i, v) in vec.view()?.iter().enumerate() {
593*d3677ae8SJeremy L Thompson     ///     assert_eq!(*v, -(i as Scalar), "Value not set correctly");
594*d3677ae8SJeremy L Thompson     /// }
595c68be7a2SJeremy L Thompson     /// # Ok(())
596c68be7a2SJeremy L Thompson     /// # }
5979df49d7eSJed Brown     /// ```
5989df49d7eSJed Brown     #[allow(unused_mut)]
59980a9ef05SNatalie Beams     pub fn scale(mut self, alpha: crate::Scalar) -> crate::Result<Self> {
6009df49d7eSJed Brown         let ierr = unsafe { bind_ceed::CeedVectorScale(self.ptr, alpha) };
6011142270cSJeremy L Thompson         self.check_error(ierr)?;
6029df49d7eSJed Brown         Ok(self)
6039df49d7eSJed Brown     }
6049df49d7eSJed Brown 
6059df49d7eSJed Brown     /// Compute y = alpha x + y for a pair of CeedVectors
6069df49d7eSJed Brown     ///
6079df49d7eSJed Brown     /// # arguments
6089df49d7eSJed Brown     ///
6099df49d7eSJed Brown     /// * `alpha` - scaling factor
6109df49d7eSJed Brown     /// * `x`     - second vector, must be different than self
6119df49d7eSJed Brown     ///
6129df49d7eSJed Brown     /// ```
6139df49d7eSJed Brown     /// # use libceed::prelude::*;
6144d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
6159df49d7eSJed Brown     /// # let ceed = libceed::Ceed::default_init();
616c68be7a2SJeremy L Thompson     /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
617c68be7a2SJeremy L Thompson     /// let mut y = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
6189df49d7eSJed Brown     ///
619c68be7a2SJeremy L Thompson     /// y = y.axpy(-0.5, &x)?;
620*d3677ae8SJeremy L Thompson     /// for (i, y) in y.view()?.iter().enumerate() {
621*d3677ae8SJeremy L Thompson     ///     assert_eq!(*y, (i as Scalar) / 2.0, "Value not set correctly");
622*d3677ae8SJeremy L Thompson     /// }
623c68be7a2SJeremy L Thompson     /// # Ok(())
624c68be7a2SJeremy L Thompson     /// # }
6259df49d7eSJed Brown     /// ```
6269df49d7eSJed Brown     #[allow(unused_mut)]
62780a9ef05SNatalie Beams     pub fn axpy(mut self, alpha: crate::Scalar, x: &crate::Vector) -> crate::Result<Self> {
6289df49d7eSJed Brown         let ierr = unsafe { bind_ceed::CeedVectorAXPY(self.ptr, alpha, x.ptr) };
6291142270cSJeremy L Thompson         self.check_error(ierr)?;
6309df49d7eSJed Brown         Ok(self)
6319df49d7eSJed Brown     }
6329df49d7eSJed Brown 
6339df49d7eSJed Brown     /// Compute the pointwise multiplication w = x .* y for CeedVectors
6349df49d7eSJed Brown     ///
6359df49d7eSJed Brown     /// # arguments
6369df49d7eSJed Brown     ///
6379df49d7eSJed Brown     /// * `x` - first vector for product
6389df49d7eSJed Brown     /// * `y` - second vector for product
6399df49d7eSJed Brown     ///
6409df49d7eSJed Brown     /// ```
6419df49d7eSJed Brown     /// # use libceed::prelude::*;
6424d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
6439df49d7eSJed Brown     /// # let ceed = libceed::Ceed::default_init();
644c68be7a2SJeremy L Thompson     /// let mut w = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
645c68be7a2SJeremy L Thompson     /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
646c68be7a2SJeremy L Thompson     /// let y = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
6479df49d7eSJed Brown     ///
648c68be7a2SJeremy L Thompson     /// w = w.pointwise_mult(&x, &y)?;
649*d3677ae8SJeremy L Thompson     /// for (i, w) in w.view()?.iter().enumerate() {
650*d3677ae8SJeremy L Thompson     ///     assert_eq!(*w, (i as Scalar).powf(2.0), "Value not set correctly");
651*d3677ae8SJeremy L Thompson     /// }
652c68be7a2SJeremy L Thompson     /// # Ok(())
653c68be7a2SJeremy L Thompson     /// # }
6549df49d7eSJed Brown     /// ```
6559df49d7eSJed Brown     #[allow(unused_mut)]
6569df49d7eSJed Brown     pub fn pointwise_mult(mut self, x: &crate::Vector, y: &crate::Vector) -> crate::Result<Self> {
6579df49d7eSJed Brown         let ierr = unsafe { bind_ceed::CeedVectorPointwiseMult(self.ptr, x.ptr, y.ptr) };
6581142270cSJeremy L Thompson         self.check_error(ierr)?;
6599df49d7eSJed Brown         Ok(self)
6609df49d7eSJed Brown     }
6619df49d7eSJed Brown 
6629df49d7eSJed Brown     /// Compute the pointwise multiplication w = w .* x for CeedVectors
6639df49d7eSJed Brown     ///
6649df49d7eSJed Brown     /// # arguments
6659df49d7eSJed Brown     ///
6669df49d7eSJed Brown     /// * `x` - second vector for product
6679df49d7eSJed Brown     ///
6689df49d7eSJed Brown     /// ```
6699df49d7eSJed Brown     /// # use libceed::prelude::*;
6704d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
6719df49d7eSJed Brown     /// # let ceed = libceed::Ceed::default_init();
672c68be7a2SJeremy L Thompson     /// let mut w = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
673c68be7a2SJeremy L Thompson     /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
6749df49d7eSJed Brown     ///
675c68be7a2SJeremy L Thompson     /// w = w.pointwise_scale(&x)?;
676*d3677ae8SJeremy L Thompson     /// for (i, w) in w.view()?.iter().enumerate() {
677*d3677ae8SJeremy L Thompson     ///     assert_eq!(*w, (i as Scalar).powf(2.0), "Value not set correctly");
678*d3677ae8SJeremy L Thompson     /// }
679c68be7a2SJeremy L Thompson     /// # Ok(())
680c68be7a2SJeremy L Thompson     /// # }
6819df49d7eSJed Brown     /// ```
6829df49d7eSJed Brown     #[allow(unused_mut)]
6839df49d7eSJed Brown     pub fn pointwise_scale(mut self, x: &crate::Vector) -> crate::Result<Self> {
6849df49d7eSJed Brown         let ierr = unsafe { bind_ceed::CeedVectorPointwiseMult(self.ptr, self.ptr, x.ptr) };
6851142270cSJeremy L Thompson         self.check_error(ierr)?;
6869df49d7eSJed Brown         Ok(self)
6879df49d7eSJed Brown     }
6889df49d7eSJed Brown 
6899df49d7eSJed Brown     /// Compute the pointwise multiplication w = w .* w for a CeedVector
6909df49d7eSJed Brown     ///
6919df49d7eSJed Brown     /// ```
6929df49d7eSJed Brown     /// # use libceed::prelude::*;
6934d27c890SJeremy L Thompson     /// # fn main() -> libceed::Result<()> {
6949df49d7eSJed Brown     /// # let ceed = libceed::Ceed::default_init();
695c68be7a2SJeremy L Thompson     /// let mut w = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
6969df49d7eSJed Brown     ///
697c68be7a2SJeremy L Thompson     /// w = w.pointwise_square()?;
698*d3677ae8SJeremy L Thompson     /// for (i, w) in w.view()?.iter().enumerate() {
699*d3677ae8SJeremy L Thompson     ///     assert_eq!(*w, (i as Scalar).powf(2.0), "Value not set correctly");
700*d3677ae8SJeremy L Thompson     /// }
701c68be7a2SJeremy L Thompson     /// # Ok(())
702c68be7a2SJeremy L Thompson     /// # }
7039df49d7eSJed Brown     /// ```
7049df49d7eSJed Brown     #[allow(unused_mut)]
7059df49d7eSJed Brown     pub fn pointwise_square(mut self) -> crate::Result<Self> {
7069df49d7eSJed Brown         let ierr = unsafe { bind_ceed::CeedVectorPointwiseMult(self.ptr, self.ptr, self.ptr) };
7071142270cSJeremy L Thompson         self.check_error(ierr)?;
7089df49d7eSJed Brown         Ok(self)
7099df49d7eSJed Brown     }
7109df49d7eSJed Brown }
7119df49d7eSJed Brown 
7129df49d7eSJed Brown // -----------------------------------------------------------------------------
7139df49d7eSJed Brown // Vector Viewer
7149df49d7eSJed Brown // -----------------------------------------------------------------------------
7159df49d7eSJed Brown /// A (host) view of a Vector with Deref to slice.  We can't make
7169df49d7eSJed Brown /// Vector itself Deref to slice because we can't handle the drop to
7179df49d7eSJed Brown /// call bind_ceed::CeedVectorRestoreArrayRead().
7189df49d7eSJed Brown #[derive(Debug)]
7199df49d7eSJed Brown pub struct VectorView<'a> {
7209df49d7eSJed Brown     vec: &'a Vector<'a>,
72180a9ef05SNatalie Beams     array: *const crate::Scalar,
7229df49d7eSJed Brown }
7239df49d7eSJed Brown 
7249df49d7eSJed Brown impl<'a> VectorView<'a> {
7259df49d7eSJed Brown     /// Construct a VectorView from a Vector reference
7264d27c890SJeremy L Thompson     fn new(vec: &'a Vector) -> crate::Result<Self> {
7279df49d7eSJed Brown         let mut array = std::ptr::null();
728e78171edSJeremy L Thompson         let ierr = unsafe {
7299df49d7eSJed Brown             bind_ceed::CeedVectorGetArrayRead(
7309df49d7eSJed Brown                 vec.ptr,
7319df49d7eSJed Brown                 crate::MemType::Host as bind_ceed::CeedMemType,
7329df49d7eSJed Brown                 &mut array,
733e78171edSJeremy L Thompson             )
734e78171edSJeremy L Thompson         };
735e78171edSJeremy L Thompson         vec.check_error(ierr)?;
736e78171edSJeremy L Thompson         Ok(Self {
7379df49d7eSJed Brown             vec: vec,
7389df49d7eSJed Brown             array: array,
739e78171edSJeremy L Thompson         })
7409df49d7eSJed Brown     }
7419df49d7eSJed Brown }
7429df49d7eSJed Brown 
7439df49d7eSJed Brown // Destructor
7449df49d7eSJed Brown impl<'a> Drop for VectorView<'a> {
7459df49d7eSJed Brown     fn drop(&mut self) {
7469df49d7eSJed Brown         unsafe {
7479df49d7eSJed Brown             bind_ceed::CeedVectorRestoreArrayRead(self.vec.ptr, &mut self.array);
7489df49d7eSJed Brown         }
7499df49d7eSJed Brown     }
7509df49d7eSJed Brown }
7519df49d7eSJed Brown 
7529df49d7eSJed Brown // Data access
7539df49d7eSJed Brown impl<'a> Deref for VectorView<'a> {
75480a9ef05SNatalie Beams     type Target = [crate::Scalar];
75580a9ef05SNatalie Beams     fn deref(&self) -> &[crate::Scalar] {
7569df49d7eSJed Brown         unsafe { std::slice::from_raw_parts(self.array, self.vec.len()) }
7579df49d7eSJed Brown     }
7589df49d7eSJed Brown }
7599df49d7eSJed Brown 
7609df49d7eSJed Brown // Viewing
7619df49d7eSJed Brown impl<'a> fmt::Display for VectorView<'a> {
7629df49d7eSJed Brown     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7639df49d7eSJed Brown         write!(f, "VectorView({:?})", self.deref())
7649df49d7eSJed Brown     }
7659df49d7eSJed Brown }
7669df49d7eSJed Brown 
7679df49d7eSJed Brown // -----------------------------------------------------------------------------
7689df49d7eSJed Brown // Vector Viewer Mutable
7699df49d7eSJed Brown // -----------------------------------------------------------------------------
7709df49d7eSJed Brown /// A mutable (host) view of a Vector with Deref to slice.
7719df49d7eSJed Brown #[derive(Debug)]
7729df49d7eSJed Brown pub struct VectorViewMut<'a> {
7739df49d7eSJed Brown     vec: &'a Vector<'a>,
77480a9ef05SNatalie Beams     array: *mut crate::Scalar,
7759df49d7eSJed Brown }
7769df49d7eSJed Brown 
7779df49d7eSJed Brown impl<'a> VectorViewMut<'a> {
7789df49d7eSJed Brown     /// Construct a VectorViewMut from a Vector reference
7794d27c890SJeremy L Thompson     fn new(vec: &'a mut Vector) -> crate::Result<Self> {
7809df49d7eSJed Brown         let mut ptr = std::ptr::null_mut();
781e78171edSJeremy L Thompson         let ierr = unsafe {
7829df49d7eSJed Brown             bind_ceed::CeedVectorGetArray(
7839df49d7eSJed Brown                 vec.ptr,
7849df49d7eSJed Brown                 crate::MemType::Host as bind_ceed::CeedMemType,
7859df49d7eSJed Brown                 &mut ptr,
786e78171edSJeremy L Thompson             )
787e78171edSJeremy L Thompson         };
788e78171edSJeremy L Thompson         vec.check_error(ierr)?;
789e78171edSJeremy L Thompson         Ok(Self {
7909df49d7eSJed Brown             vec: vec,
7919df49d7eSJed Brown             array: ptr,
792e78171edSJeremy L Thompson         })
7939df49d7eSJed Brown     }
7949df49d7eSJed Brown }
7959df49d7eSJed Brown 
7969df49d7eSJed Brown // Destructor
7979df49d7eSJed Brown impl<'a> Drop for VectorViewMut<'a> {
7989df49d7eSJed Brown     fn drop(&mut self) {
7999df49d7eSJed Brown         unsafe {
8009df49d7eSJed Brown             bind_ceed::CeedVectorRestoreArray(self.vec.ptr, &mut self.array);
8019df49d7eSJed Brown         }
8029df49d7eSJed Brown     }
8039df49d7eSJed Brown }
8049df49d7eSJed Brown 
8059df49d7eSJed Brown // Data access
8069df49d7eSJed Brown impl<'a> Deref for VectorViewMut<'a> {
80780a9ef05SNatalie Beams     type Target = [crate::Scalar];
80880a9ef05SNatalie Beams     fn deref(&self) -> &[crate::Scalar] {
8099df49d7eSJed Brown         unsafe { std::slice::from_raw_parts(self.array, self.vec.len()) }
8109df49d7eSJed Brown     }
8119df49d7eSJed Brown }
8129df49d7eSJed Brown 
8139df49d7eSJed Brown // Mutable data access
8149df49d7eSJed Brown impl<'a> DerefMut for VectorViewMut<'a> {
81580a9ef05SNatalie Beams     fn deref_mut(&mut self) -> &mut [crate::Scalar] {
8169df49d7eSJed Brown         unsafe { std::slice::from_raw_parts_mut(self.array, self.vec.len()) }
8179df49d7eSJed Brown     }
8189df49d7eSJed Brown }
8199df49d7eSJed Brown 
8209df49d7eSJed Brown // Viewing
8219df49d7eSJed Brown impl<'a> fmt::Display for VectorViewMut<'a> {
8229df49d7eSJed Brown     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8239df49d7eSJed Brown         write!(f, "VectorViewMut({:?})", self.deref())
8249df49d7eSJed Brown     }
8259df49d7eSJed Brown }
8269df49d7eSJed Brown 
8279df49d7eSJed Brown // -----------------------------------------------------------------------------
828