libceed/
vector.rs

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