Actual source code: ex18.c

petsc-3.7.5 2017-01-01
Report Typos and Errors
  2: static char help[] = "Computes the integral of 2*x/(1+x^2) from x=0..1 \nThis is equal to the ln(2).\n\n";

  4: /*T
  5:    Concepts: vectors^assembling vectors;
  6:    Processors: n

  8:    Contributed by Mike McCourt <mccomic@iit.edu> and Nathan Johnston <johnnat@iit.edu>
  9: T*/

 11: /*
 12:   Include "petscvec.h" so that we can use vectors.  Note that this file
 13:   automatically includes:
 14:      petscsys.h       - base PETSc routines   petscis.h     - index sets
 15:      petscviewer.h - viewers
 16: */
 17: #include <petscvec.h>

 19: PetscScalar func(PetscScalar a)
 20: {
 21:   return 2*a/(1+a*a);
 22: }

 26: int main(int argc,char **argv)
 27: {
 29:   PetscMPIInt    rank,size;
 30:   PetscInt       rstart,rend,i,k,N,numPoints=1000000;
 31:   PetscScalar    dummy,result=0,h=1.0/numPoints,*xarray;
 32:   Vec            x,xend;

 34:   PetscInitialize(&argc,&argv,(char*)0,help);
 35:   MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
 36:   MPI_Comm_size(PETSC_COMM_WORLD,&size);

 38:   /*
 39:      Create a parallel vector.
 40:        Here we set up our x vector which will be given values below.
 41:        The xend vector is a dummy vector to find the value of the
 42:          elements at the endpoints for use in the trapezoid rule.
 43:   */
 44:   VecCreate(PETSC_COMM_WORLD,&x);
 45:   VecSetSizes(x,PETSC_DECIDE,numPoints);
 46:   VecSetFromOptions(x);
 47:   VecGetSize(x,&N);
 48:   VecSet(x,result);
 49:   VecDuplicate(x,&xend);
 50:   result = 0.5;
 51:   if (!rank) {
 52:     i    = 0;
 53:     VecSetValues(xend,1,&i,&result,INSERT_VALUES);
 54:   }
 55:   if (rank == size-1) {
 56:     i    = N-1;
 57:     VecSetValues(xend,1,&i,&result,INSERT_VALUES);
 58:   }
 59:   /*
 60:      Assemble vector, using the 2-step process:
 61:        VecAssemblyBegin(), VecAssemblyEnd()
 62:      Computations can be done while messages are in transition
 63:      by placing code between these two statements.
 64:   */
 65:   VecAssemblyBegin(xend);
 66:   VecAssemblyEnd(xend);

 68:   /*
 69:      Set the x vector elements.
 70:       i*h will return 0 for i=0 and 1 for i=N-1.
 71:       The function evaluated (2x/(1+x^2)) is defined above.
 72:       Each evaluation is put into the local array of the vector without message passing.
 73:   */
 74:   VecGetOwnershipRange(x,&rstart,&rend);
 75:   VecGetArray(x,&xarray);
 76:   k    = 0;
 77:   for (i=rstart; i<rend; i++) {
 78:     xarray[k] = i*h;
 79:     xarray[k] = func(xarray[k]);
 80:     k++;
 81:   }
 82:   VecRestoreArray(x,&xarray);

 84:   /*
 85:      Evaluates the integral.  First the sum of all the points is taken.
 86:      That result is multiplied by the step size for the trapezoid rule.
 87:      Then half the value at each endpoint is subtracted,
 88:      this is part of the composite trapezoid rule.
 89:   */
 90:   VecSum(x,&result);
 91:   result = result*h;
 92:   VecDot(x,xend,&dummy);
 93:   result = result-h*dummy;

 95:   /*
 96:       Return the value of the integral.
 97:   */
 98:   PetscPrintf(PETSC_COMM_WORLD,"ln(2) is %g\n",(double)result);
 99:   VecDestroy(&x);
100:   VecDestroy(&xend);

102:   PetscFinalize();
103:   return 0;
104: }