You can create the C++ vector vals and resize it to a proper size, get its
data pointer, then pass it to PETSc,

int n;
Vec x;
std::vector<PetscScalar> vals;
vals.resize(n); /* You need to calculate n by other means */
ierr =
VecCreateMPIWithArray(PETSC_COMM_WORLD,bs,n,PETSC_DECIDE,vals.data(),&v);CHKERRQ(ierr);
// Code using v
ierr = VecDestroy(&v);CHKERRQ(ierr);
// Code using vals;

--Junchao Zhang



On Fri, Feb 28, 2020 at 1:12 PM Zane Charles Jakobs <
[email protected]> wrote:

> Hi PETSc devs,
>
> I'm writing some C++ code that calls PETSc, and I'd like to be able to
> place the result of VecGetArray into an std::vector and then later call
> VecRestoreArray on that data, or get the same effects. It seems like the
> correct way to do this would be something like:
>
> Vec x;
> std::vector<PetscScalar> vals, idx;
> int   num_vals, global_offset;
> PetscErrorCode ierr;
> ...
> /* do some stuff to x and compute num_vals  and global_offset*/
> ...
> vals.resize(num_vals);
> idx.resize(num_vals);
> std::iota(idx.begin(), idx.end(), global_offset);
> ierr = VecGetValues(x, num_vals, idx.data(), vals.data());CHKERRQ(ierr);
> /* do stuff to vals */
> ...
> ierr = VecSetValues(x, num_vals, idx.data(), vals.data(), [whatever insert
> mode]);CHKERRQ(ierr);
> idx.clear();
> vals.clear();
>
> Is that correct (in the sense that it does what you'd expect if you
> replaced the vectors with pointers to indices/data and used
> VecGet/RestoreArray() instead of VecGet/SetValues, and it doesn't violate
> any of std::vector's invariants, e.g. by reallocating its memory)? If not,
> is there a "normal" way to do this?
>
> Thanks!
>
> -Zane Jakobs
>
>
>

Reply via email to