xref: /libCEED/rust/libceed/src/vector.rs (revision 11544396610b36de1cb2f0d18032eefe5c670568)
1 // Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and other CEED contributors.
2 // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3 //
4 // SPDX-License-Identifier: BSD-2-Clause
5 //
6 // This file is part of CEED:  http://github.com/ceed
7 
8 //! A Ceed Vector constitutes the main data structure and serves as input/output
9 //! for Ceed Operators.
10 
11 use std::{
12     ops::{Deref, DerefMut},
13     os::raw::c_char,
14 };
15 
16 use crate::prelude::*;
17 
18 // -----------------------------------------------------------------------------
19 // Vector option
20 // -----------------------------------------------------------------------------
21 #[derive(Debug)]
22 pub enum VectorOpt<'a> {
23     Some(&'a Vector<'a>),
24     Active,
25     None,
26 }
27 /// Construct a VectorOpt reference from a Vector reference
28 impl<'a> From<&'a Vector<'_>> for VectorOpt<'a> {
29     fn from(vec: &'a Vector) -> Self {
30         debug_assert!(vec.ptr != unsafe { bind_ceed::CEED_VECTOR_ACTIVE });
31         debug_assert!(vec.ptr != unsafe { bind_ceed::CEED_VECTOR_NONE });
32         Self::Some(vec)
33     }
34 }
35 impl<'a> VectorOpt<'a> {
36     /// Transform a Rust libCEED VectorOpt into C libCEED CeedVector
37     pub(crate) fn to_raw(self) -> bind_ceed::CeedVector {
38         match self {
39             Self::Some(vec) => vec.ptr,
40             Self::Active => unsafe { bind_ceed::CEED_VECTOR_ACTIVE },
41             Self::None => unsafe { bind_ceed::CEED_VECTOR_NONE },
42         }
43     }
44 
45     /// Check if a VectorOpt is Some
46     ///
47     /// ```
48     /// # use libceed::prelude::*;
49     /// # fn main() -> libceed::Result<()> {
50     /// # let ceed = libceed::Ceed::default_init();
51     /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?;
52     /// let vec_opt = VectorOpt::from(&vec);
53     /// assert!(vec_opt.is_some(), "Incorrect VectorOpt");
54     ///
55     /// let vec_opt = VectorOpt::Active;
56     /// assert!(!vec_opt.is_some(), "Incorrect VectorOpt");
57     ///
58     /// let vec_opt = VectorOpt::None;
59     /// assert!(!vec_opt.is_some(), "Incorrect VectorOpt");
60     /// # Ok(())
61     /// # }
62     /// ```
63     pub fn is_some(&self) -> bool {
64         match self {
65             Self::Some(_) => true,
66             Self::Active => false,
67             Self::None => false,
68         }
69     }
70 
71     /// Check if a VectorOpt is Active
72     ///
73     /// ```
74     /// # use libceed::prelude::*;
75     /// # fn main() -> libceed::Result<()> {
76     /// # let ceed = libceed::Ceed::default_init();
77     /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?;
78     /// let vec_opt = VectorOpt::from(&vec);
79     /// assert!(!vec_opt.is_active(), "Incorrect VectorOpt");
80     ///
81     /// let vec_opt = VectorOpt::Active;
82     /// assert!(vec_opt.is_active(), "Incorrect VectorOpt");
83     ///
84     /// let vec_opt = VectorOpt::None;
85     /// assert!(!vec_opt.is_active(), "Incorrect VectorOpt");
86     /// # Ok(())
87     /// # }
88     /// ```
89     pub fn is_active(&self) -> bool {
90         match self {
91             Self::Some(_) => false,
92             Self::Active => true,
93             Self::None => false,
94         }
95     }
96 
97     /// Check if a VectorOpt is Some
98     ///
99     /// ```
100     /// # use libceed::prelude::*;
101     /// # fn main() -> libceed::Result<()> {
102     /// # let ceed = libceed::Ceed::default_init();
103     /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?;
104     /// let vec_opt = VectorOpt::from(&vec);
105     /// assert!(!vec_opt.is_none(), "Incorrect VectorOpt");
106     ///
107     /// let vec_opt = VectorOpt::Active;
108     /// assert!(!vec_opt.is_none(), "Incorrect VectorOpt");
109     ///
110     /// let vec_opt = VectorOpt::None;
111     /// assert!(vec_opt.is_none(), "Incorrect VectorOpt");
112     /// # Ok(())
113     /// # }
114     /// ```
115     pub fn is_none(&self) -> bool {
116         match self {
117             Self::Some(_) => false,
118             Self::Active => false,
119             Self::None => true,
120         }
121     }
122 }
123 
124 // -----------------------------------------------------------------------------
125 // Vector borrowed slice wrapper
126 // -----------------------------------------------------------------------------
127 pub struct VectorSliceWrapper<'a> {
128     pub(crate) vector: crate::Vector<'a>,
129     pub(crate) _slice: &'a mut [crate::Scalar],
130 }
131 
132 // -----------------------------------------------------------------------------
133 // Destructor
134 // -----------------------------------------------------------------------------
135 impl<'a> Drop for VectorSliceWrapper<'a> {
136     fn drop(&mut self) {
137         unsafe {
138             bind_ceed::CeedVectorTakeArray(
139                 self.vector.ptr,
140                 crate::MemType::Host as bind_ceed::CeedMemType,
141                 std::ptr::null_mut(),
142             )
143         };
144     }
145 }
146 
147 // -----------------------------------------------------------------------------
148 // Convenience constructor
149 // -----------------------------------------------------------------------------
150 impl<'a> VectorSliceWrapper<'a> {
151     fn from_vector_and_slice_mut<'b>(
152         vec: &'b mut crate::Vector,
153         slice: &'a mut [crate::Scalar],
154     ) -> crate::Result<Self> {
155         assert_eq!(vec.length(), slice.len());
156         let (host, copy_mode) = (
157             crate::MemType::Host as bind_ceed::CeedMemType,
158             crate::CopyMode::UsePointer as bind_ceed::CeedCopyMode,
159         );
160         let ierr = unsafe {
161             bind_ceed::CeedVectorSetArray(
162                 vec.ptr,
163                 host,
164                 copy_mode,
165                 slice.as_ptr() as *mut crate::Scalar,
166             )
167         };
168         vec.check_error(ierr)?;
169 
170         Ok(Self {
171             vector: crate::Vector::from_raw(vec.ptr_copy_mut()?)?,
172             _slice: slice,
173         })
174     }
175 }
176 
177 // -----------------------------------------------------------------------------
178 // Vector context wrapper
179 // -----------------------------------------------------------------------------
180 #[derive(Debug)]
181 pub struct Vector<'a> {
182     pub(crate) ptr: bind_ceed::CeedVector,
183     _lifeline: PhantomData<&'a ()>,
184 }
185 impl From<&'_ Vector<'_>> for bind_ceed::CeedVector {
186     fn from(vec: &Vector) -> Self {
187         vec.ptr
188     }
189 }
190 
191 // -----------------------------------------------------------------------------
192 // Destructor
193 // -----------------------------------------------------------------------------
194 impl<'a> Drop for Vector<'a> {
195     fn drop(&mut self) {
196         let not_none_and_active = self.ptr != unsafe { bind_ceed::CEED_VECTOR_NONE }
197             && self.ptr != unsafe { bind_ceed::CEED_VECTOR_ACTIVE };
198 
199         if not_none_and_active {
200             unsafe { bind_ceed::CeedVectorDestroy(&mut self.ptr) };
201         }
202     }
203 }
204 
205 // -----------------------------------------------------------------------------
206 // Display
207 // -----------------------------------------------------------------------------
208 impl<'a> fmt::Display for Vector<'a> {
209     /// View a Vector
210     ///
211     /// ```
212     /// # use libceed::prelude::*;
213     /// # fn main() -> libceed::Result<()> {
214     /// # let ceed = libceed::Ceed::default_init();
215     /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?;
216     /// assert_eq!(
217     ///     vec.to_string(),
218     ///     "CeedVector length 3
219     ///     1.00000000
220     ///     2.00000000
221     ///     3.00000000
222     /// "
223     /// );
224     /// # Ok(())
225     /// # }
226     /// ```
227     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
228         let mut ptr = std::ptr::null_mut();
229         let mut sizeloc = crate::MAX_BUFFER_LENGTH;
230         let format = CString::new("%12.8f").expect("CString::new failed");
231         let format_c: *const c_char = format.into_raw();
232         let cstring = unsafe {
233             let file = bind_ceed::open_memstream(&mut ptr, &mut sizeloc);
234             bind_ceed::CeedVectorView(self.ptr, format_c, file);
235             bind_ceed::fclose(file);
236             CString::from_raw(ptr)
237         };
238         cstring.to_string_lossy().fmt(f)
239     }
240 }
241 
242 // -----------------------------------------------------------------------------
243 // Implementations
244 // -----------------------------------------------------------------------------
245 impl<'a> Vector<'a> {
246     // Constructors
247     pub fn create(ceed: &crate::Ceed, n: usize) -> crate::Result<Self> {
248         let n = isize::try_from(n).unwrap();
249         let mut ptr = std::ptr::null_mut();
250         let ierr = unsafe { bind_ceed::CeedVectorCreate(ceed.ptr, n, &mut ptr) };
251         ceed.check_error(ierr)?;
252         Ok(Self {
253             ptr,
254             _lifeline: PhantomData,
255         })
256     }
257 
258     pub(crate) fn from_raw(ptr: bind_ceed::CeedVector) -> crate::Result<Self> {
259         Ok(Self {
260             ptr,
261             _lifeline: PhantomData,
262         })
263     }
264 
265     fn ptr_copy_mut(&mut self) -> crate::Result<bind_ceed::CeedVector> {
266         let mut ptr_copy = std::ptr::null_mut();
267         let ierr = unsafe { bind_ceed::CeedVectorReferenceCopy(self.ptr, &mut ptr_copy) };
268         self.check_error(ierr)?;
269         Ok(ptr_copy)
270     }
271 
272     /// Copy the array of self into vec_copy
273     ///
274     /// # arguments
275     ///
276     /// * `vec_source` - vector to copy array values from
277     ///
278     /// ```
279     /// # use libceed::prelude::*;
280     /// # fn main() -> libceed::Result<()> {
281     /// # let ceed = libceed::Ceed::default_init();
282     /// let a = ceed.vector_from_slice(&[1., 2., 3.])?;
283     /// let mut b = ceed.vector(3)?;
284     ///
285     /// b.copy_from(&a)?;
286     /// for (i, v) in b.view()?.iter().enumerate() {
287     ///     assert_eq!(*v, (i + 1) as Scalar, "Copy contents not set correctly");
288     /// }
289     /// # Ok(())
290     /// # }
291     /// ```
292     /// ```
293     pub fn copy_from(&mut self, vec_source: &crate::Vector) -> crate::Result<i32> {
294         let ierr = unsafe { bind_ceed::CeedVectorCopy(vec_source.ptr, self.ptr) };
295         self.check_error(ierr)
296     }
297 
298     /// Create a Vector from a slice
299     ///
300     /// # arguments
301     ///
302     /// * `slice` - values to initialize vector with
303     ///
304     /// ```
305     /// # use libceed::prelude::*;
306     /// # fn main() -> libceed::Result<()> {
307     /// # let ceed = libceed::Ceed::default_init();
308     /// let vec = vector::Vector::from_slice(&ceed, &[1., 2., 3.])?;
309     /// assert_eq!(vec.length(), 3, "Incorrect length from slice");
310     /// # Ok(())
311     /// # }
312     /// ```
313     pub fn from_slice(ceed: &crate::Ceed, v: &[crate::Scalar]) -> crate::Result<Self> {
314         let mut x = Self::create(ceed, v.len())?;
315         x.set_slice(v)?;
316         Ok(x)
317     }
318 
319     /// Create a Vector from a mutable array reference
320     ///
321     /// # arguments
322     ///
323     /// * `slice` - values to initialize vector with
324     ///
325     /// ```
326     /// # use libceed::prelude::*;
327     /// # fn main() -> libceed::Result<()> {
328     /// # let ceed = libceed::Ceed::default_init();
329     /// let mut rust_vec = vec![1., 2., 3.];
330     /// let vec = libceed::vector::Vector::from_array(&ceed, &mut rust_vec)?;
331     ///
332     /// assert_eq!(vec.length(), 3, "Incorrect length from slice");
333     /// # Ok(())
334     /// # }
335     /// ```
336     pub fn from_array(ceed: &crate::Ceed, v: &mut [crate::Scalar]) -> crate::Result<Self> {
337         let x = Self::create(ceed, v.len())?;
338         let (host, user_pointer) = (
339             crate::MemType::Host as bind_ceed::CeedMemType,
340             crate::CopyMode::UsePointer as bind_ceed::CeedCopyMode,
341         );
342         let v = v.as_ptr() as *mut crate::Scalar;
343         let ierr = unsafe { bind_ceed::CeedVectorSetArray(x.ptr, host, user_pointer, v) };
344         ceed.check_error(ierr)?;
345         Ok(x)
346     }
347 
348     // Raw Ceed for error handling
349     #[doc(hidden)]
350     fn ceed(&self) -> bind_ceed::Ceed {
351         unsafe { bind_ceed::CeedVectorReturnCeed(self.ptr) }
352     }
353 
354     // Error handling
355     #[doc(hidden)]
356     fn check_error(&self, ierr: i32) -> crate::Result<i32> {
357         crate::check_error(|| self.ceed(), ierr)
358     }
359 
360     /// Returns the length of a Vector
361     ///
362     /// ```
363     /// # use libceed::prelude::*;
364     /// # fn main() -> libceed::Result<()> {
365     /// # let ceed = libceed::Ceed::default_init();
366     /// let vec = ceed.vector(10)?;
367     ///
368     /// let n = vec.length();
369     /// assert_eq!(n, 10, "Incorrect length");
370     /// # Ok(())
371     /// # }
372     /// ```
373     pub fn length(&self) -> usize {
374         let mut n = 0;
375         unsafe { bind_ceed::CeedVectorGetLength(self.ptr, &mut n) };
376         usize::try_from(n).unwrap()
377     }
378 
379     /// Returns the length of a Vector
380     ///
381     /// ```
382     /// # use libceed::prelude::*;
383     /// # fn main() -> libceed::Result<()> {
384     /// # let ceed = libceed::Ceed::default_init();
385     /// let vec = ceed.vector(10)?;
386     /// assert_eq!(vec.len(), 10, "Incorrect length");
387     /// # Ok(())
388     /// # }
389     /// ```
390     pub fn len(&self) -> usize {
391         self.length()
392     }
393 
394     /// Set the Vector to a constant value
395     ///
396     /// # arguments
397     ///
398     /// * `val` - Value to be used
399     ///
400     /// ```
401     /// # use libceed::prelude::*;
402     /// # fn main() -> libceed::Result<()> {
403     /// # let ceed = libceed::Ceed::default_init();
404     /// let len = 10;
405     /// let mut vec = ceed.vector(len)?;
406     ///
407     /// let val = 42.0;
408     /// vec.set_value(val)?;
409     ///
410     /// for v in vec.view()?.iter() {
411     ///     assert_eq!(*v, val, "Value not set correctly");
412     /// }
413     /// # Ok(())
414     /// # }
415     /// ```
416     pub fn set_value(&mut self, value: crate::Scalar) -> crate::Result<i32> {
417         let ierr = unsafe { bind_ceed::CeedVectorSetValue(self.ptr, value) };
418         self.check_error(ierr)
419     }
420 
421     /// Set values from a slice of the same length
422     ///
423     /// # arguments
424     ///
425     /// * `slice` - values to into self; length must match
426     ///
427     /// ```
428     /// # use libceed::prelude::*;
429     /// # fn main() -> libceed::Result<()> {
430     /// # let ceed = libceed::Ceed::default_init();
431     /// let mut vec = ceed.vector(4)?;
432     /// vec.set_slice(&[10., 11., 12., 13.])?;
433     ///
434     /// for (i, v) in vec.view()?.iter().enumerate() {
435     ///     assert_eq!(*v, 10. + i as Scalar, "Slice not set correctly");
436     /// }
437     /// # Ok(())
438     /// # }
439     /// ```
440     pub fn set_slice(&mut self, slice: &[crate::Scalar]) -> crate::Result<i32> {
441         assert_eq!(self.length(), slice.len());
442         let (host, copy_mode) = (
443             crate::MemType::Host as bind_ceed::CeedMemType,
444             crate::CopyMode::CopyValues as bind_ceed::CeedCopyMode,
445         );
446         let ierr = unsafe {
447             bind_ceed::CeedVectorSetArray(
448                 self.ptr,
449                 host,
450                 copy_mode,
451                 slice.as_ptr() as *mut crate::Scalar,
452             )
453         };
454         self.check_error(ierr)
455     }
456 
457     /// Wrap a mutable slice in a Vector of the same length
458     ///
459     /// # arguments
460     ///
461     /// * `slice` - values to wrap in self; length must match
462     ///
463     /// ```
464     /// # use libceed::prelude::*;
465     /// # fn main() -> libceed::Result<()> {
466     /// # let ceed = libceed::Ceed::default_init();
467     /// let mut vec = ceed.vector(4)?;
468     /// let mut array = [10., 11., 12., 13.];
469     ///
470     /// {
471     ///     // `wrapper` holds a mutable reference to the wrapped slice
472     ///     //   that is dropped when `wrapper` goes out of scope
473     ///     let wrapper = vec.wrap_slice_mut(&mut array)?;
474     ///     for (i, v) in vec.view()?.iter().enumerate() {
475     ///         assert_eq!(*v, 10. + i as Scalar, "Slice not set correctly");
476     ///     }
477     ///
478     ///     // This line will not compile, as the `wrapper` holds mutable
479     ///     //   access to the `array`
480     ///     // array[0] = 5.0;
481     ///
482     ///     // Changes here are reflected in the `array`
483     ///     vec.set_value(5.0)?;
484     ///     for v in vec.view()?.iter() {
485     ///         assert_eq!(*v, 5.0 as Scalar, "Value not set correctly");
486     ///     }
487     /// }
488     ///
489     /// // 'array' remains changed
490     /// for v in array.iter() {
491     ///     assert_eq!(*v, 5.0 as Scalar, "Array not mutated correctly");
492     /// }
493     ///
494     /// // While changes to `vec` no longer affect `array`
495     /// vec.set_value(6.0)?;
496     /// for v in array.iter() {
497     ///     assert_eq!(*v, 5.0 as Scalar, "Array mutated without permission");
498     /// }
499     /// # Ok(())
500     /// # }
501     /// ```
502     pub fn wrap_slice_mut<'b>(
503         &mut self,
504         slice: &'b mut [crate::Scalar],
505     ) -> crate::Result<VectorSliceWrapper<'b>> {
506         crate::VectorSliceWrapper::from_vector_and_slice_mut(self, slice)
507     }
508 
509     /// Sync the Vector to a specified memtype
510     ///
511     /// # arguments
512     ///
513     /// * `mtype` - Memtype to be synced
514     ///
515     /// ```
516     /// # use libceed::prelude::*;
517     /// # fn main() -> libceed::Result<()> {
518     /// # let ceed = libceed::Ceed::default_init();
519     /// let len = 10;
520     /// let mut vec = ceed.vector(len)?;
521     ///
522     /// let val = 42.0;
523     /// vec.set_value(val);
524     /// vec.sync(MemType::Host)?;
525     ///
526     /// for v in vec.view()?.iter() {
527     ///     assert_eq!(*v, val, "Value not set correctly");
528     /// }
529     /// # Ok(())
530     /// # }
531     /// ```
532     pub fn sync(&self, mtype: crate::MemType) -> crate::Result<i32> {
533         let ierr =
534             unsafe { bind_ceed::CeedVectorSyncArray(self.ptr, mtype as bind_ceed::CeedMemType) };
535         self.check_error(ierr)
536     }
537 
538     /// Create an immutable view
539     ///
540     /// ```
541     /// # use libceed::prelude::*;
542     /// # fn main() -> libceed::Result<()> {
543     /// # let ceed = libceed::Ceed::default_init();
544     /// let vec = ceed.vector_from_slice(&[10., 11., 12., 13.])?;
545     ///
546     /// let v = vec.view()?;
547     /// assert_eq!(v[0..2], [10., 11.]);
548     ///
549     /// // It is valid to have multiple immutable views
550     /// let w = vec.view()?;
551     /// assert_eq!(v[1..], w[1..]);
552     /// # Ok(())
553     /// # }
554     /// ```
555     pub fn view(&self) -> crate::Result<VectorView> {
556         VectorView::new(self)
557     }
558 
559     /// Create an mutable view
560     ///
561     /// ```
562     /// # use libceed::prelude::*;
563     /// # fn main() -> libceed::Result<()> {
564     /// # let ceed = libceed::Ceed::default_init();
565     /// let mut vec = ceed.vector_from_slice(&[10., 11., 12., 13.])?;
566     ///
567     /// {
568     ///     let mut v = vec.view_mut()?;
569     ///     v[2] = 9.;
570     /// }
571     ///
572     /// let w = vec.view()?;
573     /// assert_eq!(w[2], 9., "View did not mutate data");
574     /// # Ok(())
575     /// # }
576     /// ```
577     pub fn view_mut(&mut self) -> crate::Result<VectorViewMut> {
578         VectorViewMut::new(self)
579     }
580 
581     /// Return the norm of a Vector
582     ///
583     /// # arguments
584     ///
585     /// * `ntype` - Norm type One, Two, or Max
586     ///
587     /// ```
588     /// # use libceed::prelude::*;
589     /// # fn main() -> libceed::Result<()> {
590     /// # let ceed = libceed::Ceed::default_init();
591     /// let vec = ceed.vector_from_slice(&[1., 2., 3., 4.])?;
592     ///
593     /// let max_norm = vec.norm(NormType::Max)?;
594     /// assert_eq!(max_norm, 4.0, "Incorrect Max norm");
595     ///
596     /// let l1_norm = vec.norm(NormType::One)?;
597     /// assert_eq!(l1_norm, 10., "Incorrect L1 norm");
598     ///
599     /// let l2_norm = vec.norm(NormType::Two)?;
600     /// assert!((l2_norm - 5.477) < 1e-3, "Incorrect L2 norm");
601     /// # Ok(())
602     /// # }
603     /// ```
604     pub fn norm(&self, ntype: crate::NormType) -> crate::Result<crate::Scalar> {
605         let mut res: crate::Scalar = 0.0;
606         let ierr = unsafe {
607             bind_ceed::CeedVectorNorm(self.ptr, ntype as bind_ceed::CeedNormType, &mut res)
608         };
609         self.check_error(ierr)?;
610         Ok(res)
611     }
612 
613     /// Compute x = alpha x for a Vector
614     ///
615     /// # arguments
616     ///
617     /// * `alpha` - scaling factor
618     ///
619     /// ```
620     /// # use libceed::prelude::*;
621     /// # fn main() -> libceed::Result<()> {
622     /// # let ceed = libceed::Ceed::default_init();
623     /// let mut vec = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
624     ///
625     /// vec = vec.scale(-1.0)?;
626     /// for (i, v) in vec.view()?.iter().enumerate() {
627     ///     assert_eq!(*v, -(i as Scalar), "Value not set correctly");
628     /// }
629     /// # Ok(())
630     /// # }
631     /// ```
632     #[allow(unused_mut)]
633     pub fn scale(mut self, alpha: crate::Scalar) -> crate::Result<Self> {
634         let ierr = unsafe { bind_ceed::CeedVectorScale(self.ptr, alpha) };
635         self.check_error(ierr)?;
636         Ok(self)
637     }
638 
639     /// Compute y = alpha x + y for a pair of Vectors
640     ///
641     /// # arguments
642     ///
643     /// * `alpha` - scaling factor
644     /// * `x`     - second vector, must be different than self
645     ///
646     /// ```
647     /// # use libceed::prelude::*;
648     /// # fn main() -> libceed::Result<()> {
649     /// # let ceed = libceed::Ceed::default_init();
650     /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
651     /// let mut y = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
652     ///
653     /// y = y.axpy(-0.5, &x)?;
654     /// for (i, y) in y.view()?.iter().enumerate() {
655     ///     assert_eq!(*y, (i as Scalar) / 2.0, "Value not set correctly");
656     /// }
657     /// # Ok(())
658     /// # }
659     /// ```
660     #[allow(unused_mut)]
661     pub fn axpy(mut self, alpha: crate::Scalar, x: &crate::Vector) -> crate::Result<Self> {
662         let ierr = unsafe { bind_ceed::CeedVectorAXPY(self.ptr, alpha, x.ptr) };
663         self.check_error(ierr)?;
664         Ok(self)
665     }
666 
667     /// Compute y = alpha x + beta y for a pair of Vectors
668     ///
669     /// # arguments
670     ///
671     /// * `alpha` - first scaling factor
672     /// * `beta`  - second scaling factor
673     /// * `x`     - second vector, must be different than self
674     ///
675     /// ```
676     /// # use libceed::prelude::*;
677     /// # fn main() -> libceed::Result<()> {
678     /// # let ceed = libceed::Ceed::default_init();
679     /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
680     /// let mut y = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
681     ///
682     /// y = y.axpby(-0.5, 1.0, &x)?;
683     /// for (i, y) in y.view()?.iter().enumerate() {
684     ///     assert_eq!(*y, (i as Scalar) * 0.5, "Value not set correctly");
685     /// }
686     /// # Ok(())
687     /// # }
688     /// ```
689     #[allow(unused_mut)]
690     pub fn axpby(
691         mut self,
692         alpha: crate::Scalar,
693         beta: crate::Scalar,
694         x: &crate::Vector,
695     ) -> crate::Result<Self> {
696         let ierr = unsafe { bind_ceed::CeedVectorAXPBY(self.ptr, alpha, beta, x.ptr) };
697         self.check_error(ierr)?;
698         Ok(self)
699     }
700 
701     /// Compute the pointwise multiplication w = x .* y for Vectors
702     ///
703     /// # arguments
704     ///
705     /// * `x` - first vector for product
706     /// * `y` - second vector for product
707     ///
708     /// ```
709     /// # use libceed::prelude::*;
710     /// # fn main() -> libceed::Result<()> {
711     /// # let ceed = libceed::Ceed::default_init();
712     /// let mut w = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
713     /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
714     /// let y = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
715     ///
716     /// w = w.pointwise_mult(&x, &y)?;
717     /// for (i, w) in w.view()?.iter().enumerate() {
718     ///     assert_eq!(*w, (i as Scalar).powf(2.0), "Value not set correctly");
719     /// }
720     /// # Ok(())
721     /// # }
722     /// ```
723     #[allow(unused_mut)]
724     pub fn pointwise_mult(mut self, x: &crate::Vector, y: &crate::Vector) -> crate::Result<Self> {
725         let ierr = unsafe { bind_ceed::CeedVectorPointwiseMult(self.ptr, x.ptr, y.ptr) };
726         self.check_error(ierr)?;
727         Ok(self)
728     }
729 
730     /// Compute the pointwise multiplication w = w .* x for Vectors
731     ///
732     /// # arguments
733     ///
734     /// * `x` - second vector for product
735     ///
736     /// ```
737     /// # use libceed::prelude::*;
738     /// # fn main() -> libceed::Result<()> {
739     /// # let ceed = libceed::Ceed::default_init();
740     /// let mut w = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
741     /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
742     ///
743     /// w = w.pointwise_scale(&x)?;
744     /// for (i, w) in w.view()?.iter().enumerate() {
745     ///     assert_eq!(*w, (i as Scalar).powf(2.0), "Value not set correctly");
746     /// }
747     /// # Ok(())
748     /// # }
749     /// ```
750     #[allow(unused_mut)]
751     pub fn pointwise_scale(mut self, x: &crate::Vector) -> crate::Result<Self> {
752         let ierr = unsafe { bind_ceed::CeedVectorPointwiseMult(self.ptr, self.ptr, x.ptr) };
753         self.check_error(ierr)?;
754         Ok(self)
755     }
756 
757     /// Compute the pointwise multiplication w = w .* w for a Vector
758     ///
759     /// ```
760     /// # use libceed::prelude::*;
761     /// # fn main() -> libceed::Result<()> {
762     /// # let ceed = libceed::Ceed::default_init();
763     /// let mut w = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
764     ///
765     /// w = w.pointwise_square()?;
766     /// for (i, w) in w.view()?.iter().enumerate() {
767     ///     assert_eq!(*w, (i as Scalar).powf(2.0), "Value not set correctly");
768     /// }
769     /// # Ok(())
770     /// # }
771     /// ```
772     #[allow(unused_mut)]
773     pub fn pointwise_square(mut self) -> crate::Result<Self> {
774         let ierr = unsafe { bind_ceed::CeedVectorPointwiseMult(self.ptr, self.ptr, self.ptr) };
775         self.check_error(ierr)?;
776         Ok(self)
777     }
778 }
779 
780 // -----------------------------------------------------------------------------
781 // Vector Viewer
782 // -----------------------------------------------------------------------------
783 /// A (host) view of a Vector with Deref to slice.  We can't make
784 /// Vector itself Deref to slice because we can't handle the drop to
785 /// call bind_ceed::CeedVectorRestoreArrayRead().
786 #[derive(Debug)]
787 pub struct VectorView<'a> {
788     vec: &'a Vector<'a>,
789     array: *const crate::Scalar,
790 }
791 
792 impl<'a> VectorView<'a> {
793     /// Construct a VectorView from a Vector reference
794     fn new(vec: &'a Vector) -> crate::Result<Self> {
795         let mut array = std::ptr::null();
796         let ierr = unsafe {
797             bind_ceed::CeedVectorGetArrayRead(
798                 vec.ptr,
799                 crate::MemType::Host as bind_ceed::CeedMemType,
800                 &mut array,
801             )
802         };
803         vec.check_error(ierr)?;
804         Ok(Self {
805             vec: vec,
806             array: array,
807         })
808     }
809 }
810 
811 // Destructor
812 impl<'a> Drop for VectorView<'a> {
813     fn drop(&mut self) {
814         unsafe {
815             bind_ceed::CeedVectorRestoreArrayRead(self.vec.ptr, &mut self.array);
816         }
817     }
818 }
819 
820 // Data access
821 impl<'a> Deref for VectorView<'a> {
822     type Target = [crate::Scalar];
823     fn deref(&self) -> &[crate::Scalar] {
824         unsafe { std::slice::from_raw_parts(self.array, self.vec.len()) }
825     }
826 }
827 
828 // Viewing
829 impl<'a> fmt::Display for VectorView<'a> {
830     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
831         write!(f, "VectorView({:?})", self.deref())
832     }
833 }
834 
835 // -----------------------------------------------------------------------------
836 // Vector Viewer Mutable
837 // -----------------------------------------------------------------------------
838 /// A mutable (host) view of a Vector with Deref to slice.
839 #[derive(Debug)]
840 pub struct VectorViewMut<'a> {
841     vec: &'a Vector<'a>,
842     array: *mut crate::Scalar,
843 }
844 
845 impl<'a> VectorViewMut<'a> {
846     /// Construct a VectorViewMut from a Vector reference
847     fn new(vec: &'a mut Vector) -> crate::Result<Self> {
848         let mut ptr = std::ptr::null_mut();
849         let ierr = unsafe {
850             bind_ceed::CeedVectorGetArray(
851                 vec.ptr,
852                 crate::MemType::Host as bind_ceed::CeedMemType,
853                 &mut ptr,
854             )
855         };
856         vec.check_error(ierr)?;
857         Ok(Self {
858             vec: vec,
859             array: ptr,
860         })
861     }
862 }
863 
864 // Destructor
865 impl<'a> Drop for VectorViewMut<'a> {
866     fn drop(&mut self) {
867         unsafe {
868             bind_ceed::CeedVectorRestoreArray(self.vec.ptr, &mut self.array);
869         }
870     }
871 }
872 
873 // Data access
874 impl<'a> Deref for VectorViewMut<'a> {
875     type Target = [crate::Scalar];
876     fn deref(&self) -> &[crate::Scalar] {
877         unsafe { std::slice::from_raw_parts(self.array, self.vec.len()) }
878     }
879 }
880 
881 // Mutable data access
882 impl<'a> DerefMut for VectorViewMut<'a> {
883     fn deref_mut(&mut self) -> &mut [crate::Scalar] {
884         unsafe { std::slice::from_raw_parts_mut(self.array, self.vec.len()) }
885     }
886 }
887 
888 // Viewing
889 impl<'a> fmt::Display for VectorViewMut<'a> {
890     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
891         write!(f, "VectorViewMut({:?})", self.deref())
892     }
893 }
894 
895 // -----------------------------------------------------------------------------
896