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