PetscErrorCode GetExactEigenvalues(PetscInt M,PetscInt N,PetscInt P,PetscInt nconv,PetscReal *exact) { PetscInt n,i,j,k,l; PetscReal *evals,ax,ay,az,sx,sy,sz; PetscErrorCode ierr; PetscFunctionBeginUser; ax = PETSC_PI/2/(M+1); ay = PETSC_PI/2/(N+1); az = PETSC_PI/2/(P+1); n = PetscCeilReal(PetscPowReal(nconv,0.33333)+1); ierr = PetscMalloc1(n*n*n,&evals);CHKERRQ(ierr); l = 0; for (i=1;i<=n;i++) { sx = PetscSinReal(ax*i); for (j=1;j<=n;j++) { sy = PetscSinReal(ay*j); for (k=1;k<=n;k++) { sz = PetscSinReal(az*k); evals[l++] = 4.0*(sx*sx+sy*sy+sz*sz); } } } ierr = PetscSortReal(n*n*n,evals);CHKERRQ(ierr); for (i=0;i<nconv;i++) exact[i] = evals[i]; ierr = PetscFree(evals);CHKERRQ(ierr); PetscFunctionReturn(0); }
// Find the squarest grid, with best[0] <= best[1] <= best[2]. PetscErrorCode ProcessGridFindSquarest(PetscMPIInt nranks,PetscInt best[3]) { PetscMPIInt target,s,a,b,c; PetscFunctionBegin; target = PetscCeilReal(PetscPowReal(nranks,1./3)); if (target*target*target > nranks) target--; // if ceil was overzealous for (a=target; a>=1; a--) { if (nranks%a) continue; // Not a candidate factor s = PetscCeilReal(PetscSqrtReal(nranks/a)); if (s*s > nranks/a) s--; // If our ceil was overzealous for (b=s; b>=a; b--) { if (nranks/a % b == 0) { // The first proper divisor is the one I want c = nranks/a/b; best[0] = a; best[1] = b; best[2] = c; PetscFunctionReturn(0); } } } SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_ARG_INCOMP,"Could not find squarest grid"); PetscFunctionReturn(0); }