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