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