I am trying to pass an array of Vec's in PETSc to a function, modify it internally and retrieve the results. A pseudocode is as follows:
PetscErrorCode foo(Vec *y, int n) {
// ...
ierr = VecDuplicateVecs(x, n, &y); CHKERRQ(ierr);
// ...
ierr = VecNorm(y[0],NORM_2,&norm); CHKERRQ(ierr); // this prints out fine
printf("norm = %f\n", norm);
}
int main(int argc,char **argv)
{
PetscErrorCode ierr;
PetscScalar norm;
Vec *y;
foo(y, 3);
ierr = VecNorm(y[0],NORM_2,&norm); CHKERRQ(ierr); // this breaks: segfault
ierr = VecDestroyVecs(3, &y); CHKERRQ(ierr);
return 0;
}
I am indeed getting a message from the compiler stating that variable "y" is used before its value is set
, but I am failing to see how to pass these guys by reference. VecDuplicateVecs
has to necessarily be initialized in main?
There were two problems: 1) The address of the pointer *y
was not passed to foo [@Chase] . 2) a double pointer call would solve the issue in VecNorm
within foo()
PetscErrorCode foo(Vec **y, int n) {
// ...
ierr = VecDuplicateVecs(x, n, y); CHKERRQ(ierr);
// ...
ierr = VecNorm((*y)[0],NORM_2,&norm); CHKERRQ(ierr);
printf("norm = %f\n", norm);
}
int main(int argc,char **argv)
{
PetscErrorCode ierr;
PetscScalar norm;
Vec *y;
foo(&y, 3);
ierr = VecNorm(y[0],NORM_2,&norm); CHKERRQ(ierr);
ierr = VecDestroyVecs(3, &y); CHKERRQ(ierr);
return 0;
}