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