cpetsc

How to pass array of PETSc Vec to a function


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?


Solution

  • 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;
    }