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