0

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?

2
  • Your Vec *y is not initialized when you try to pass it to another function. What do you expect that function to receive? You probably want to pass the address of it instead. Commented Jul 22, 2020 at 5:40
  • @Chase: Does your comment imply I should call it as: foo(&y, 3);, and then later the call of the routine should be PetscErrorCode foo(Vec **y, int n)? Then inside the routine I would have to modify it as ierr = VecDuplicateVecs(x, n, y); CHKERRQ(ierr);. I tried this in my application, and although works for the first entry of the array of Vec's, it gives me a segfault for other entries. Commented Jul 22, 2020 at 7:20

1 Answer 1

0

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;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.