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