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