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