PetscErrorCode MatColoringCreateLargestFirstWeights(MatColoring mc,PetscReal *weights) { PetscErrorCode ierr; PetscInt i,s,e,n,ncols; PetscRandom rand; PetscReal r; PetscInt *degrees; Mat G = mc->mat; PetscFunctionBegin; /* each weight should be the degree plus a random perturbation */ ierr = PetscRandomCreate(PetscObjectComm((PetscObject)mc),&rand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rand);CHKERRQ(ierr); ierr = MatGetOwnershipRange(G,&s,&e);CHKERRQ(ierr); n=e-s; ierr = PetscMalloc1(n,°rees);CHKERRQ(ierr); ierr = MatColoringGetDegrees(G,mc->dist,degrees);CHKERRQ(ierr); for (i=s;i<e;i++) { ierr = MatGetRow(G,i,&ncols,NULL,NULL);CHKERRQ(ierr); ierr = PetscRandomGetValueReal(rand,&r);CHKERRQ(ierr); weights[i-s] = ncols + PetscAbsReal(r); ierr = MatRestoreRow(G,i,&ncols,NULL,NULL);CHKERRQ(ierr); } ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); ierr = PetscFree(degrees);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode TestSetup(DMLabel label, AppCtx *user) { PetscRandom r; PetscInt n = (PetscInt) (user->fill*(user->pEnd - user->pStart)), i; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscRandomCreate(PETSC_COMM_SELF, &r);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(r);CHKERRQ(ierr);/* -random_type <> */ ierr = PetscRandomSetInterval(r, user->pStart, user->pEnd);CHKERRQ(ierr); ierr = PetscRandomSetSeed(r, 123456789L);CHKERRQ(ierr); ierr = PetscRandomSeed(r);CHKERRQ(ierr); user->size = 0; for(i = 0; i < n; ++i) { PetscReal p; PetscInt val; ierr = PetscRandomGetValueReal(r, &p);CHKERRQ(ierr); ierr = DMLabelGetValue(label, (PetscInt) p, &val);CHKERRQ(ierr); if (val < 0) { ++user->size; ierr = DMLabelSetValue(label, (PetscInt) p, i % user->numStrata);CHKERRQ(ierr); } } ierr = PetscRandomDestroy(&r);CHKERRQ(ierr); ierr = DMLabelCreateIndex(label, user->pStart, user->pEnd);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF, "Created label with chart [%D, %D) and set %D values\n", user->pStart, user->pEnd, user->size);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscInt i,n = 1000,*values; int event; PetscRandom rand; PetscReal value; PetscErrorCode ierr; PetscBool values_view=PETSC_FALSE; PetscMPIInt rank; ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,0,"-values_view",&values_view,NULL);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_SELF,&rand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rand);CHKERRQ(ierr); ierr = PetscMalloc1(n,&values);CHKERRQ(ierr); for (i=0; i<n; i++) { ierr = PetscRandomGetValueReal(rand,&value);CHKERRQ(ierr); values[i] = (PetscInt)(n*value + 2.0); } ierr = PetscSortInt(n,values);CHKERRQ(ierr); ierr = PetscLogEventRegister("Sort",0,&event);CHKERRQ(ierr); ierr = PetscLogEventBegin(event,0,0,0,0);CHKERRQ(ierr); for (i=0; i<n; i++) { ierr = PetscRandomGetValueReal(rand,&value);CHKERRQ(ierr); values[i] = (PetscInt)(n*value + 2.0); } ierr = PetscSortInt(n,values);CHKERRQ(ierr); ierr = PetscLogEventEnd(event,0,0,0,0);CHKERRQ(ierr); for (i=1; i<n; i++) { if (values[i] < values[i-1]) SETERRQ(PETSC_COMM_SELF,1,"Values not sorted"); if (values_view && !rank) {ierr = PetscPrintf(PETSC_COMM_SELF,"%D %D\n",i,values[i]);CHKERRQ(ierr);} } ierr = PetscFree(values);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
PetscErrorCode MatColoringCreateRandomWeights(MatColoring mc,PetscReal *weights) { PetscErrorCode ierr; PetscInt i,s,e; PetscRandom rand; PetscReal r; Mat G = mc->mat; PetscFunctionBegin; /* each weight should be the degree plus a random perturbation */ ierr = PetscRandomCreate(PetscObjectComm((PetscObject)mc),&rand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rand);CHKERRQ(ierr); ierr = MatGetOwnershipRange(G,&s,&e);CHKERRQ(ierr); for (i=s;i<e;i++) { ierr = PetscRandomGetValueReal(rand,&r);CHKERRQ(ierr); weights[i-s] = PetscAbsReal(r); } ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int Argc,char **Args) { PetscBool flg; PetscInt n = -6; PetscScalar rho = 1.0; PetscReal h; PetscReal beta = 1.0; DM da; PetscRandom rctx; PetscMPIInt comm_size; Mat H,HtH; PetscInt x, y, xs, ys, xm, ym; PetscReal r1, r2; PetscScalar uxy1, uxy2; MatStencil sxy, sxy_m; PetscScalar val, valconj; Vec b, Htb,xvec; KSP kspmg; PC pcmg; PetscErrorCode ierr; PetscInt ix[1] = {0}; PetscScalar vals[1] = {1.0}; PetscInitialize(&Argc,&Args,(char*)0,help); ierr = PetscOptionsGetInt(NULL,"-size",&n,&flg);CHKERRQ(ierr); ierr = PetscOptionsGetReal(NULL,"-beta",&beta,&flg);CHKERRQ(ierr); ierr = PetscOptionsGetScalar(NULL,"-rho",&rho,&flg);CHKERRQ(ierr); /* Set the fudge parameters, we scale the whole thing by 1/(2*h) later */ h = 1.; rho *= 1./(2.*h); /* Geometry info */ ierr = DMDACreate2d(PETSC_COMM_WORLD, DMDA_BOUNDARY_PERIODIC,DMDA_BOUNDARY_PERIODIC, DMDA_STENCIL_STAR, n, n, PETSC_DECIDE, PETSC_DECIDE, 2 /* this is the # of dof's */, 1, NULL, NULL, &da);CHKERRQ(ierr); /* Random numbers */ ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rctx);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rctx);CHKERRQ(ierr); /* Single or multi processor ? */ ierr = MPI_Comm_size(PETSC_COMM_WORLD,&comm_size);CHKERRQ(ierr); /* construct matrix */ ierr = DMSetMatType(da,MATAIJ);CHKERRQ(ierr); ierr = DMCreateMatrix(da, &H);CHKERRQ(ierr); /* get local corners for this processor */ ierr = DMDAGetCorners(da,&xs,&ys,0,&xm,&ym,0);CHKERRQ(ierr); /* Assemble the matrix */ for (x=xs; x<xs+xm; x++) { for (y=ys; y<ys+ym; y++) { /* each lattice point sets only the *forward* pointing parameters (right, down), i.e. Nabla_1^+ and Nabla_2^+. In this way we can use only local random number creation. That means we also have to set the corresponding backward pointing entries. */ /* Compute some normally distributed random numbers via Box-Muller */ ierr = PetscRandomGetValueReal(rctx, &r1);CHKERRQ(ierr); r1 = 1.-r1; /* to change from [0,1) to (0,1], which we need for the log */ ierr = PetscRandomGetValueReal(rctx, &r2);CHKERRQ(ierr); PetscReal R = PetscSqrtReal(-2.*PetscLogReal(r1)); PetscReal c = PetscCosReal(2.*PETSC_PI*r2); PetscReal s = PetscSinReal(2.*PETSC_PI*r2); /* use those to set the field */ uxy1 = PetscExpScalar(((PetscScalar) (R*c/beta))*PETSC_i); uxy2 = PetscExpScalar(((PetscScalar) (R*s/beta))*PETSC_i); sxy.i = x; sxy.j = y; /* the point where we are */ /* center action */ sxy.c = 0; /* spin 0, 0 */ ierr = MatSetValuesStencil(H, 1, &sxy, 1, &sxy, &rho, ADD_VALUES);CHKERRQ(ierr); sxy.c = 1; /* spin 1, 1 */ val = -rho; ierr = MatSetValuesStencil(H, 1, &sxy, 1, &sxy, &val, ADD_VALUES);CHKERRQ(ierr); sxy_m.i = x+1; sxy_m.j = y; /* right action */ sxy.c = 0; sxy_m.c = 0; /* spin 0, 0 */ val = -uxy1; valconj = PetscConj(val); ierr = MatSetValuesStencil(H, 1, &sxy_m, 1, &sxy, &val, ADD_VALUES);CHKERRQ(ierr); ierr = MatSetValuesStencil(H, 1, &sxy, 1, &sxy_m, &valconj, ADD_VALUES);CHKERRQ(ierr); sxy.c = 0; sxy_m.c = 1; /* spin 0, 1 */ val = -uxy1; valconj = PetscConj(val); ierr = MatSetValuesStencil(H, 1, &sxy_m, 1, &sxy, &val, ADD_VALUES);CHKERRQ(ierr); ierr = MatSetValuesStencil(H, 1, &sxy, 1, &sxy_m, &valconj, ADD_VALUES);CHKERRQ(ierr); sxy.c = 1; sxy_m.c = 0; /* spin 1, 0 */ val = uxy1; valconj = PetscConj(val); ierr = MatSetValuesStencil(H, 1, &sxy_m, 1, &sxy, &val, ADD_VALUES);CHKERRQ(ierr); ierr = MatSetValuesStencil(H, 1, &sxy, 1, &sxy_m, &valconj, ADD_VALUES);CHKERRQ(ierr); sxy.c = 1; sxy_m.c = 1; /* spin 1, 1 */ val = uxy1; valconj = PetscConj(val); ierr = MatSetValuesStencil(H, 1, &sxy_m, 1, &sxy, &val, ADD_VALUES);CHKERRQ(ierr); ierr = MatSetValuesStencil(H, 1, &sxy, 1, &sxy_m, &valconj, ADD_VALUES);CHKERRQ(ierr); sxy_m.i = x; sxy_m.j = y+1; /* down action */ sxy.c = 0; sxy_m.c = 0; /* spin 0, 0 */ val = -uxy2; valconj = PetscConj(val); ierr = MatSetValuesStencil(H, 1, &sxy_m, 1, &sxy, &val, ADD_VALUES);CHKERRQ(ierr); ierr = MatSetValuesStencil(H, 1, &sxy, 1, &sxy_m, &valconj, ADD_VALUES);CHKERRQ(ierr); sxy.c = 0; sxy_m.c = 1; /* spin 0, 1 */ val = -PETSC_i*uxy2; valconj = PetscConj(val); ierr = MatSetValuesStencil(H, 1, &sxy_m, 1, &sxy, &val, ADD_VALUES);CHKERRQ(ierr); ierr = MatSetValuesStencil(H, 1, &sxy, 1, &sxy_m, &valconj, ADD_VALUES);CHKERRQ(ierr); sxy.c = 1; sxy_m.c = 0; /* spin 1, 0 */ val = -PETSC_i*uxy2; valconj = PetscConj(val); ierr = MatSetValuesStencil(H, 1, &sxy_m, 1, &sxy, &val, ADD_VALUES);CHKERRQ(ierr); ierr = MatSetValuesStencil(H, 1, &sxy, 1, &sxy_m, &valconj, ADD_VALUES);CHKERRQ(ierr); sxy.c = 1; sxy_m.c = 1; /* spin 1, 1 */ val = PetscConj(uxy2); valconj = PetscConj(val); ierr = MatSetValuesStencil(H, 1, &sxy_m, 1, &sxy, &val, ADD_VALUES);CHKERRQ(ierr); ierr = MatSetValuesStencil(H, 1, &sxy, 1, &sxy_m, &valconj, ADD_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(H, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(H, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* scale H */ ierr = MatScale(H, 1./(2.*h));CHKERRQ(ierr); /* it looks like H is Hermetian */ /* construct normal equations */ ierr = MatMatMult(H, H, MAT_INITIAL_MATRIX, 1., &HtH);CHKERRQ(ierr); /* permutation matrix to check whether H and HtH are identical to the ones in the paper */ /* Mat perm; */ /* ierr = DMCreateMatrix(da, &perm);CHKERRQ(ierr); */ /* PetscInt row, col; */ /* PetscScalar one = 1.0; */ /* for (PetscInt i=0; i<n; i++) { */ /* for (PetscInt j=0; j<n; j++) { */ /* row = (i*n+j)*2; col = i*n+j; */ /* ierr = MatSetValues(perm, 1, &row, 1, &col, &one, INSERT_VALUES);CHKERRQ(ierr); */ /* row = (i*n+j)*2+1; col = i*n+j + n*n; */ /* ierr = MatSetValues(perm, 1, &row, 1, &col, &one, INSERT_VALUES);CHKERRQ(ierr); */ /* } */ /* } */ /* ierr = MatAssemblyBegin(perm, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); */ /* ierr = MatAssemblyEnd(perm, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); */ /* Mat Hperm; */ /* ierr = MatPtAP(H, perm, MAT_INITIAL_MATRIX, 1.0, &Hperm);CHKERRQ(ierr); */ /* ierr = PetscPrintf(PETSC_COMM_WORLD, "Matrix H after construction\n");CHKERRQ(ierr); */ /* ierr = MatView(Hperm, PETSC_VIEWER_STDOUT_(PETSC_COMM_WORLD));CHKERRQ(ierr); */ /* Mat HtHperm; */ /* ierr = MatPtAP(HtH, perm, MAT_INITIAL_MATRIX, 1.0, &HtHperm);CHKERRQ(ierr); */ /* ierr = PetscPrintf(PETSC_COMM_WORLD, "Matrix HtH:\n");CHKERRQ(ierr); */ /* ierr = MatView(HtHperm, PETSC_VIEWER_STDOUT_(PETSC_COMM_WORLD));CHKERRQ(ierr); */ /* right hand side */ ierr = DMCreateGlobalVector(da, &b);CHKERRQ(ierr); ierr = VecSet(b,0.0);CHKERRQ(ierr); ierr = VecSetValues(b, 1, ix, vals, INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(b);CHKERRQ(ierr); ierr = VecAssemblyEnd(b);CHKERRQ(ierr); /* ierr = VecSetRandom(b, rctx);CHKERRQ(ierr); */ ierr = VecDuplicate(b, &Htb);CHKERRQ(ierr); ierr = MatMultTranspose(H, b, Htb);CHKERRQ(ierr); /* construct solver */ ierr = KSPCreate(PETSC_COMM_WORLD,&kspmg);CHKERRQ(ierr); ierr = KSPSetType(kspmg, KSPCG);CHKERRQ(ierr); ierr = KSPGetPC(kspmg,&pcmg);CHKERRQ(ierr); ierr = PCSetType(pcmg,PCASA);CHKERRQ(ierr); /* maybe user wants to override some of the choices */ ierr = KSPSetFromOptions(kspmg);CHKERRQ(ierr); ierr = KSPSetOperators(kspmg, HtH, HtH, DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = DMDASetRefinementFactor(da, 3, 3, 3);CHKERRQ(ierr); ierr = PCSetDM(pcmg,da);CHKERRQ(ierr); ierr = PCASASetTolerances(pcmg, 1.e-6, 1.e-10,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr); ierr = VecDuplicate(b, &xvec);CHKERRQ(ierr); ierr = VecSet(xvec, 0.0);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve the linear system - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = KSPSolve(kspmg, Htb, xvec);CHKERRQ(ierr); /* ierr = VecView(xvec, PETSC_VIEWER_STDOUT_(PETSC_COMM_WORLD));CHKERRQ(ierr); */ ierr = KSPDestroy(&kspmg);CHKERRQ(ierr); ierr = VecDestroy(&xvec);CHKERRQ(ierr); /* seems to be destroyed by KSPDestroy */ ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = VecDestroy(&Htb);CHKERRQ(ierr); ierr = MatDestroy(&HtH);CHKERRQ(ierr); ierr = MatDestroy(&H);CHKERRQ(ierr); ierr = DMDestroy(&da);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
PetscErrorCode TestTriangle(MPI_Comm comm, PetscBool interpolate, PetscBool transform) { DM dm; PetscRandom r, ang, ang2; PetscInt dim, t; PetscErrorCode ierr; PetscFunctionBegin; /* Create reference triangle */ dim = 2; ierr = DMCreate(comm, &dm);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) dm, "triangle");CHKERRQ(ierr); ierr = DMSetType(dm, DMPLEX);CHKERRQ(ierr); ierr = DMPlexSetDimension(dm, dim);CHKERRQ(ierr); { PetscInt numPoints[2] = {3, 1}; PetscInt coneSize[4] = {3, 0, 0, 0}; PetscInt cones[3] = {1, 2, 3}; PetscInt coneOrientations[3] = {0, 0, 0}; PetscScalar vertexCoords[6] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0}; ierr = DMPlexCreateFromDAG(dm, 1, numPoints, coneSize, cones, coneOrientations, vertexCoords);CHKERRQ(ierr); if (interpolate) { DM idm; ierr = DMPlexInterpolate(dm, &idm);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) idm, "triangle");CHKERRQ(ierr); ierr = DMPlexCopyCoordinates(dm, idm);CHKERRQ(ierr); ierr = DMDestroy(&dm);CHKERRQ(ierr); dm = idm; } ierr = DMSetFromOptions(dm);CHKERRQ(ierr); } /* Check reference geometry: determinant is scaled by reference volume (2.0) */ { PetscReal v0Ex[2] = {-1.0, -1.0}; PetscReal JEx[4] = {1.0, 0.0, 0.0, 1.0}; PetscReal invJEx[4] = {1.0, 0.0, 0.0, 1.0}; PetscReal detJEx = 1.0; PetscReal centroidEx[2] = {-0.333333333333, -0.333333333333}; PetscReal normalEx[2] = {0.0, 0.0}; PetscReal volEx = 2.0; ierr = CheckFEMGeometry(dm, 0, dim, v0Ex, JEx, invJEx, detJEx);CHKERRQ(ierr); if (interpolate) {ierr = CheckFVMGeometry(dm, 0, dim, centroidEx, normalEx, volEx);CHKERRQ(ierr);} } /* Check random triangles: rotate, scale, then translate */ if (transform) { ierr = PetscRandomCreate(PETSC_COMM_SELF, &r);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(r);CHKERRQ(ierr); ierr = PetscRandomSetInterval(r, 0.0, 10.0);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_SELF, &ang);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(ang);CHKERRQ(ierr); ierr = PetscRandomSetInterval(ang, 0.0, 2*PETSC_PI);CHKERRQ(ierr); for (t = 0; t < 100; ++t) { PetscScalar vertexCoords[6] = {-1.0, -1.0, 1.0, -1.0, -1.0, 1.0}, trans[2]; PetscReal v0Ex[2] = {-1.0, -1.0}; PetscReal JEx[4] = {1.0, 0.0, 0.0, 1.0}, R[4], rot[2], rotM[4]; PetscReal invJEx[4] = {1.0, 0.0, 0.0, 1.0}; PetscReal detJEx = 1.0, scale, phi; PetscReal centroidEx[2] = {-0.333333333333, -0.333333333333}; PetscReal normalEx[2] = {0.0, 0.0}; PetscReal volEx = 2.0; PetscInt d, e, f, p; ierr = PetscRandomGetValueReal(r, &scale);CHKERRQ(ierr); ierr = PetscRandomGetValueReal(ang, &phi);CHKERRQ(ierr); R[0] = cos(phi); R[1] = -sin(phi); R[2] = sin(phi); R[3] = cos(phi); for (p = 0; p < 3; ++p) { for (d = 0; d < dim; ++d) { for (e = 0, rot[d] = 0.0; e < dim; ++e) { rot[d] += R[d*dim+e] * vertexCoords[p*dim+e]; } } for (d = 0; d < dim; ++d) vertexCoords[p*dim+d] = rot[d]; } for (d = 0; d < dim; ++d) { for (e = 0, rot[d] = 0.0; e < dim; ++e) { rot[d] += R[d*dim+e] * centroidEx[e]; } } for (d = 0; d < dim; ++d) centroidEx[d] = rot[d]; for (d = 0; d < dim; ++d) { for (e = 0; e < dim; ++e) { for (f = 0, rotM[d*dim+e] = 0.0; f < dim; ++f) { rotM[d*dim+e] += R[d*dim+f] * JEx[f*dim+e]; } } } for (d = 0; d < dim; ++d) { for (e = 0; e < dim; ++e) { JEx[d*dim+e] = rotM[d*dim+e]; } } for (d = 0; d < dim; ++d) { for (e = 0; e < dim; ++e) { for (f = 0, rotM[d*dim+e] = 0.0; f < dim; ++f) { rotM[d*dim+e] += invJEx[d*dim+f] * R[e*dim+f]; } } } for (d = 0; d < dim; ++d) { for (e = 0; e < dim; ++e) { invJEx[d*dim+e] = rotM[d*dim+e]; } } for (d = 0; d < dim; ++d) { ierr = PetscRandomGetValueReal(r, &trans[d]);CHKERRQ(ierr); for (p = 0; p < 3; ++p) { vertexCoords[p*dim+d] *= scale; vertexCoords[p*dim+d] += trans[d]; } v0Ex[d] = vertexCoords[d]; for (e = 0; e < dim; ++e) { JEx[d*dim+e] *= scale; invJEx[d*dim+e] /= scale; } detJEx *= scale; centroidEx[d] *= scale; centroidEx[d] += trans[d]; volEx *= scale; } ierr = ChangeCoordinates(dm, dim, vertexCoords);CHKERRQ(ierr); ierr = CheckFEMGeometry(dm, 0, dim, v0Ex, JEx, invJEx, detJEx);CHKERRQ(ierr); if (interpolate) {ierr = CheckFVMGeometry(dm, 0, dim, centroidEx, normalEx, volEx);CHKERRQ(ierr);} } ierr = PetscRandomDestroy(&r);CHKERRQ(ierr); ierr = PetscRandomDestroy(&ang);CHKERRQ(ierr); } /* Move to 3D: Check reference geometry: determinant is scaled by reference volume (2.0) */ dim = 3; { PetscScalar vertexCoords[9] = {-1.0, -1.0, 0.0, 1.0, -1.0, 0.0, -1.0, 1.0, 0.0}; PetscReal v0Ex[3] = {-1.0, -1.0, 0.0}; PetscReal JEx[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; PetscReal invJEx[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; PetscReal detJEx = 1.0; PetscReal centroidEx[3] = {-0.333333333333, -0.333333333333, 0.0}; PetscReal normalEx[3] = {0.0, 0.0, 1.0}; PetscReal volEx = 2.0; ierr = ChangeCoordinates(dm, dim, vertexCoords);CHKERRQ(ierr); ierr = CheckFEMGeometry(dm, 0, dim, v0Ex, JEx, invJEx, detJEx);CHKERRQ(ierr); if (interpolate) {ierr = CheckFVMGeometry(dm, 0, dim, centroidEx, normalEx, volEx);CHKERRQ(ierr);} } /* Rotated reference element */ { PetscScalar vertexCoords[9] = {0.0, -1.0, -1.0, 0.0, 1.0, -1.0, 0.0, -1.0, 1.0}; PetscReal v0Ex[3] = {0.0, -1.0, -1.0}; PetscReal JEx[9] = {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0}; PetscReal invJEx[9] = {0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0}; PetscReal detJEx = 1.0; PetscReal centroidEx[3] = {0.0, -0.333333333333, -0.333333333333}; PetscReal normalEx[3] = {1.0, 0.0, 0.0}; PetscReal volEx = 2.0; ierr = ChangeCoordinates(dm, dim, vertexCoords);CHKERRQ(ierr); ierr = CheckFEMGeometry(dm, 0, dim, v0Ex, JEx, invJEx, detJEx);CHKERRQ(ierr); if (interpolate) {ierr = CheckFVMGeometry(dm, 0, dim, centroidEx, normalEx, volEx);CHKERRQ(ierr);} } /* Check random triangles: scale, translate, then rotate */ if (transform) { ierr = PetscRandomCreate(PETSC_COMM_SELF, &r);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(r);CHKERRQ(ierr); ierr = PetscRandomSetInterval(r, 0.0, 10.0);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_SELF, &ang);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(ang);CHKERRQ(ierr); ierr = PetscRandomSetInterval(ang, 0.0, 2*PETSC_PI);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_SELF, &ang2);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(ang2);CHKERRQ(ierr); ierr = PetscRandomSetInterval(ang2, 0.0, PETSC_PI);CHKERRQ(ierr); for (t = 0; t < 100; ++t) { PetscScalar vertexCoords[9] = {-1.0, -1.0, 0.0, 1.0, -1.0, 0.0, -1.0, 1.0, 0.0}, trans[3]; PetscReal v0Ex[3] = {-1.0, -1.0, 0.0}; PetscReal JEx[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}, R[9], rot[3], rotM[9]; PetscReal invJEx[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; PetscReal detJEx = 1.0, scale, phi, theta, psi = 0.0; PetscReal centroidEx[3] = {-0.333333333333, -0.333333333333, 0.0}; PetscReal normalEx[3] = {0.0, 0.0, 1.0}; PetscReal volEx = 2.0; PetscInt d, e, f, p; ierr = PetscRandomGetValueReal(r, &scale);CHKERRQ(ierr); ierr = PetscRandomGetValueReal(ang, &phi);CHKERRQ(ierr); ierr = PetscRandomGetValueReal(ang2, &theta);CHKERRQ(ierr); for (d = 0; d < dim; ++d) { ierr = PetscRandomGetValueReal(r, &trans[d]);CHKERRQ(ierr); for (p = 0; p < 3; ++p) { vertexCoords[p*dim+d] *= scale; vertexCoords[p*dim+d] += trans[d]; } centroidEx[d] *= scale; centroidEx[d] += trans[d]; for (e = 0; e < dim-1; ++e) { JEx[d*dim+e] *= scale; invJEx[d*dim+e] /= scale; } if (d < dim-1) { detJEx *= scale; volEx *= scale; } } R[0] = cos(theta)*cos(psi); R[1] = sin(phi)*sin(theta)*cos(psi) - cos(phi)*sin(psi); R[2] = sin(phi)*sin(psi) + cos(phi)*sin(theta)*cos(psi); R[3] = cos(theta)*sin(psi); R[4] = cos(phi)*cos(psi) + sin(phi)*sin(theta)*sin(psi); R[5] = cos(phi)*sin(theta)*sin(psi) - sin(phi)*cos(psi); R[6] = -sin(theta); R[7] = sin(phi)*cos(theta); R[8] = cos(phi)*cos(theta); for (p = 0; p < 3; ++p) { for (d = 0; d < dim; ++d) { for (e = 0, rot[d] = 0.0; e < dim; ++e) { rot[d] += R[d*dim+e] * vertexCoords[p*dim+e]; } } for (d = 0; d < dim; ++d) vertexCoords[p*dim+d] = rot[d]; } for (d = 0; d < dim; ++d) { for (e = 0, rot[d] = 0.0; e < dim; ++e) { rot[d] += R[d*dim+e] * centroidEx[e]; } } for (d = 0; d < dim; ++d) centroidEx[d] = rot[d]; for (d = 0; d < dim; ++d) { for (e = 0, rot[d] = 0.0; e < dim; ++e) { rot[d] += R[d*dim+e] * normalEx[e]; } } for (d = 0; d < dim; ++d) normalEx[d] = rot[d]; for (d = 0; d < dim; ++d) { v0Ex[d] = vertexCoords[d]; for (e = 0; e < dim; ++e) { for (f = 0, rotM[d*dim+e] = 0.0; f < dim; ++f) { rotM[d*dim+e] += R[d*dim+f] * JEx[f*dim+e]; } } } for (d = 0; d < dim; ++d) { for (e = 0; e < dim; ++e) { JEx[d*dim+e] = rotM[d*dim+e]; } } for (d = 0; d < dim; ++d) { for (e = 0; e < dim; ++e) { for (f = 0, rotM[d*dim+e] = 0.0; f < dim; ++f) { rotM[d*dim+e] += invJEx[d*dim+f] * R[e*dim+f]; } } } for (d = 0; d < dim; ++d) { for (e = 0; e < dim; ++e) { invJEx[d*dim+e] = rotM[d*dim+e]; } } ierr = ChangeCoordinates(dm, dim, vertexCoords);CHKERRQ(ierr); ierr = CheckFEMGeometry(dm, 0, dim, v0Ex, JEx, invJEx, detJEx);CHKERRQ(ierr); if (interpolate) {ierr = CheckFVMGeometry(dm, 0, dim, centroidEx, normalEx, volEx);CHKERRQ(ierr);} } ierr = PetscRandomDestroy(&r);CHKERRQ(ierr); ierr = PetscRandomDestroy(&ang);CHKERRQ(ierr); ierr = PetscRandomDestroy(&ang2);CHKERRQ(ierr); } /* Cleanup */ ierr = DMDestroy(&dm);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode random_network(PetscInt nvertex,PetscInt *pnbranch,Node **pnode,Branch **pbranch,PetscInt **pedgelist,PetscInt seed) { PetscErrorCode ierr; PetscInt i, j, nedges = 0; PetscInt *edgelist; PetscInt nbat, ncurr, fr, to; PetscReal *x, *y, value, xmax = 10.0; /* generate points in square */ PetscReal maxdist = 0.0, dist, alpha, beta, prob; PetscRandom rnd; Branch *branch; Node *node; Edge *head = NULL, *nnew= NULL, *aux= NULL; PetscFunctionBeginUser; ierr = PetscRandomCreate(PETSC_COMM_SELF,&rnd);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rnd);CHKERRQ(ierr); ierr = PetscRandomSetSeed(rnd, seed);CHKERRQ(ierr); ierr = PetscRandomSeed(rnd);CHKERRQ(ierr); /* These parameters might be modified for experimentation */ nbat = (PetscInt)(0.1*nvertex); ncurr = (PetscInt)(0.1*nvertex); alpha = 0.6; beta = 0.2; ierr = PetscMalloc2(nvertex,&x,nvertex,&y);CHKERRQ(ierr); ierr = PetscRandomSetInterval(rnd,0.0,xmax);CHKERRQ(ierr); for (i=0; i<nvertex; i++) { ierr = PetscRandomGetValueReal(rnd,&x[i]);CHKERRQ(ierr); ierr = PetscRandomGetValueReal(rnd,&y[i]);CHKERRQ(ierr); } /* find maximum distance */ for (i=0; i<nvertex; i++) { for (j=0; j<nvertex; j++) { dist = findDistance(x[i],x[j],y[i],y[j]); if (dist >= maxdist) maxdist = dist; } } ierr = PetscRandomSetInterval(rnd,0.0,1.0);CHKERRQ(ierr); for (i=0; i<nvertex; i++) { for (j=0; j<nvertex; j++) { if (j != i) { dist = findDistance(x[i],x[j],y[i],y[j]); prob = beta*PetscExpScalar(-dist/(maxdist*alpha)); ierr = PetscRandomGetValueReal(rnd,&value);CHKERRQ(ierr); if (value <= prob) { ierr = PetscMalloc1(1,&nnew);CHKERRQ(ierr); if (head == NULL) { head = nnew; head->next = NULL; head->n = nedges; head->i = i; head->j = j; } else { aux = head; head = nnew; head->n = nedges; head->next = aux; head->i = i; head->j = j; } nedges += 1; } } } } ierr = PetscMalloc1(2*nedges,&edgelist);CHKERRQ(ierr); for (aux = head; aux; aux = aux->next) { edgelist[(aux->n)*2] = aux->i; edgelist[(aux->n)*2 + 1] = aux->j; } aux = head; while (aux != NULL) { nnew = aux; aux = aux->next; ierr = PetscFree(nnew);CHKERRQ(ierr); } ierr = PetscCalloc2(nvertex,&node,nedges,&branch);CHKERRQ(ierr); for (i = 0; i < nvertex; i++) { node[i].id = i; node[i].inj = 0; node[i].gr = PETSC_FALSE; } for (i = 0; i < nedges; i++) { branch[i].id = i; branch[i].r = 1.0; branch[i].bat = 0; } /* Chose random node as ground voltage */ ierr = PetscRandomSetInterval(rnd,0.0,nvertex);CHKERRQ(ierr); ierr = PetscRandomGetValueReal(rnd,&value);CHKERRQ(ierr); node[(int)value].gr = PETSC_TRUE; /* Create random current and battery injectionsa */ for (i=0; i<ncurr; i++) { ierr = PetscRandomSetInterval(rnd,0.0,nvertex);CHKERRQ(ierr); ierr = PetscRandomGetValueReal(rnd,&value);CHKERRQ(ierr); fr = edgelist[(int)value*2]; to = edgelist[(int)value*2 + 1]; node[fr].inj += 1.0; node[to].inj -= 1.0; } for (i=0; i<nbat; i++) { ierr = PetscRandomSetInterval(rnd,0.0,nedges);CHKERRQ(ierr); ierr = PetscRandomGetValueReal(rnd,&value);CHKERRQ(ierr); branch[(int)value].bat += 1.0; } ierr = PetscFree2(x,y);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rnd);CHKERRQ(ierr); /* assign pointers */ *pnbranch = nedges; *pedgelist = edgelist; *pbranch = branch; *pnode = node; PetscFunctionReturn(ierr); }
int main(int argc,char **argv) { Mat A1,A2; /* problem matrices */ EPS eps; /* eigenproblem solver context */ PetscScalar value[3]; PetscReal tol=1000*PETSC_MACHINE_EPSILON,v; Vec d; PetscInt n=30,i,Istart,Iend,col[3]; PetscBool FirstBlock=PETSC_FALSE,LastBlock=PETSC_FALSE; PetscRandom myrand; PetscErrorCode ierr; SlepcInitialize(&argc,&argv,(char*)0,help); ierr = PetscOptionsGetInt(NULL,"-n",&n,NULL);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"\nTridiagonal with random diagonal, n=%D\n\n",n);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create matrix tridiag([-1 0 -1]) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatCreate(PETSC_COMM_WORLD,&A1);CHKERRQ(ierr); ierr = MatSetSizes(A1,PETSC_DECIDE,PETSC_DECIDE,n,n);CHKERRQ(ierr); ierr = MatSetFromOptions(A1);CHKERRQ(ierr); ierr = MatSetUp(A1);CHKERRQ(ierr); ierr = MatGetOwnershipRange(A1,&Istart,&Iend);CHKERRQ(ierr); if (Istart==0) FirstBlock=PETSC_TRUE; if (Iend==n) LastBlock=PETSC_TRUE; value[0]=-1.0; value[1]=0.0; value[2]=-1.0; for (i=(FirstBlock? Istart+1: Istart); i<(LastBlock? Iend-1: Iend); i++) { col[0]=i-1; col[1]=i; col[2]=i+1; ierr = MatSetValues(A1,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } if (LastBlock) { i=n-1; col[0]=n-2; col[1]=n-1; ierr = MatSetValues(A1,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); } if (FirstBlock) { i=0; col[0]=0; col[1]=1; value[0]=0.0; value[1]=-1.0; ierr = MatSetValues(A1,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A1,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create two matrices by filling the diagonal with rand values - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = MatDuplicate(A1,MAT_COPY_VALUES,&A2);CHKERRQ(ierr); ierr = MatGetVecs(A1,NULL,&d);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&myrand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(myrand);CHKERRQ(ierr); ierr = PetscRandomSetInterval(myrand,0.0,1.0);CHKERRQ(ierr); for (i=0; i<n; i++) { ierr = PetscRandomGetValueReal(myrand,&v);CHKERRQ(ierr); ierr = VecSetValue(d,i,v,INSERT_VALUES);CHKERRQ(ierr); } ierr = VecAssemblyBegin(d);CHKERRQ(ierr); ierr = VecAssemblyEnd(d);CHKERRQ(ierr); ierr = MatDiagonalSet(A1,d,INSERT_VALUES);CHKERRQ(ierr); for (i=0; i<n; i++) { ierr = PetscRandomGetValueReal(myrand,&v);CHKERRQ(ierr); ierr = VecSetValue(d,i,v,INSERT_VALUES);CHKERRQ(ierr); } ierr = VecAssemblyBegin(d);CHKERRQ(ierr); ierr = VecAssemblyEnd(d);CHKERRQ(ierr); ierr = MatDiagonalSet(A2,d,INSERT_VALUES);CHKERRQ(ierr); ierr = VecDestroy(&d);CHKERRQ(ierr); ierr = PetscRandomDestroy(&myrand);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create the eigensolver - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSCreate(PETSC_COMM_WORLD,&eps);CHKERRQ(ierr); ierr = EPSSetProblemType(eps,EPS_HEP);CHKERRQ(ierr); ierr = EPSSetTolerances(eps,tol,PETSC_DEFAULT);CHKERRQ(ierr); ierr = EPSSetOperators(eps,A1,NULL);CHKERRQ(ierr); ierr = EPSSetFromOptions(eps);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve first eigenproblem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSSolve(eps);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," - - - First matrix - - -\n");CHKERRQ(ierr); ierr = EPSPrintSolution(eps,NULL);CHKERRQ(ierr); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Solve second eigenproblem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ ierr = EPSSetOperators(eps,A2,NULL);CHKERRQ(ierr); ierr = EPSSolve(eps);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD," - - - Second matrix - - -\n");CHKERRQ(ierr); ierr = EPSPrintSolution(eps,NULL);CHKERRQ(ierr); ierr = EPSDestroy(&eps);CHKERRQ(ierr); ierr = MatDestroy(&A1);CHKERRQ(ierr); ierr = MatDestroy(&A2);CHKERRQ(ierr); ierr = SlepcFinalize(); return 0; }
PetscErrorCode MatColoringCreateSmallestLastWeights(MatColoring mc,PetscReal *weights) { PetscInt *degrees,*degb,*llprev,*llnext; PetscInt j,i,s,e,n,nin,ln,lm,degree,maxdegree=0,bidx,idx,dist,distance=mc->dist; Mat lG,*lGs; IS ris; PetscErrorCode ierr; PetscInt *seen; const PetscInt *gidx; PetscInt *idxbuf; PetscInt *distbuf; PetscInt ncols,nxt,prv,cur; const PetscInt *cols; PetscBool isSEQAIJ; Mat_SeqAIJ *aij; PetscInt *Gi,*Gj,*rperm; Mat G = mc->mat; PetscReal *lweights,r; PetscRandom rand; PetscFunctionBegin; ierr = MatGetOwnershipRange(G,&s,&e);CHKERRQ(ierr); n=e-s; ierr = ISCreateStride(PetscObjectComm((PetscObject)G),n,s,1,&ris);CHKERRQ(ierr); ierr = MatIncreaseOverlap(G,1,&ris,distance+1);CHKERRQ(ierr); ierr = ISSort(ris);CHKERRQ(ierr); ierr = MatGetSubMatrices(G,1,&ris,&ris,MAT_INITIAL_MATRIX,&lGs);CHKERRQ(ierr); lG = lGs[0]; ierr = PetscObjectTypeCompare((PetscObject)lG,MATSEQAIJ,&isSEQAIJ);CHKERRQ(ierr); if (!isSEQAIJ) SETERRQ(PetscObjectComm((PetscObject)G),PETSC_ERR_ARG_WRONGSTATE,"Requires an MPI/SEQAIJ Matrix"); ierr = MatGetSize(lG,&ln,&lm);CHKERRQ(ierr); aij = (Mat_SeqAIJ*)lG->data; Gi = aij->i; Gj = aij->j; ierr = PetscMalloc3(lm,&seen,lm,&idxbuf,lm,&distbuf);CHKERRQ(ierr); ierr = PetscMalloc1(lm,°rees);CHKERRQ(ierr); ierr = PetscMalloc1(lm,&lweights);CHKERRQ(ierr); for (i=0;i<ln;i++) { seen[i]=-1; lweights[i] = 1.; } ierr = ISGetIndices(ris,&gidx);CHKERRQ(ierr); for (i=0;i<ln;i++) { bidx=-1; ncols = Gi[i+1]-Gi[i]; cols = &(Gj[Gi[i]]); degree = 0; /* place the distance-one neighbors on the queue */ for (j=0;j<ncols;j++) { bidx++; seen[cols[j]] = i; distbuf[bidx] = 1; idxbuf[bidx] = cols[j]; } while (bidx >= 0) { /* pop */ idx = idxbuf[bidx]; dist = distbuf[bidx]; bidx--; degree++; if (dist < distance) { ncols = Gi[idx+1]-Gi[idx]; cols = &(Gj[Gi[idx]]); for (j=0;j<ncols;j++) { if (seen[cols[j]] != i) { bidx++; seen[cols[j]] = i; idxbuf[bidx] = cols[j]; distbuf[bidx] = dist+1; } } } } degrees[i] = degree; if (degree > maxdegree) maxdegree = degree; } /* bucket by degree by some random permutation */ ierr = PetscRandomCreate(PetscObjectComm((PetscObject)mc),&rand);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rand);CHKERRQ(ierr); ierr = PetscMalloc1(ln,&rperm);CHKERRQ(ierr); for (i=0;i<ln;i++) { ierr = PetscRandomGetValueReal(rand,&r);CHKERRQ(ierr); lweights[i] = r; rperm[i]=i; } ierr = PetscSortRealWithPermutation(lm,lweights,rperm);CHKERRQ(ierr); ierr = PetscMalloc1(maxdegree+1,°b);CHKERRQ(ierr); ierr = PetscMalloc2(ln,&llnext,ln,&llprev);CHKERRQ(ierr); for (i=0;i<maxdegree+1;i++) { degb[i] = -1; } for (i=0;i<ln;i++) { llnext[i] = -1; llprev[i] = -1; seen[i] = -1; } for (i=0;i<ln;i++) { idx = rperm[i]; llnext[idx] = degb[degrees[idx]]; if (degb[degrees[idx]] > 0) llprev[degb[degrees[idx]]] = idx; degb[degrees[idx]] = idx; } ierr = PetscFree(rperm);CHKERRQ(ierr); /* remove the lowest degree one */ i=0; nin=0; while (i != maxdegree+1) { for (i=1;i<maxdegree+1; i++) { if (degb[i] > 0) { cur = degb[i]; nin++; degrees[cur] = 0; degb[i] = llnext[cur]; bidx=-1; ncols = Gi[cur+1]-Gi[cur]; cols = &(Gj[Gi[cur]]); /* place the distance-one neighbors on the queue */ for (j=0;j<ncols;j++) { if (cols[j] != cur) { bidx++; seen[cols[j]] = i; distbuf[bidx] = 1; idxbuf[bidx] = cols[j]; } } while (bidx >= 0) { /* pop */ idx = idxbuf[bidx]; dist = distbuf[bidx]; bidx--; nxt=llnext[idx]; prv=llprev[idx]; if (degrees[idx] > 0) { /* change up the degree of the neighbors still in the graph */ if (lweights[idx] <= lweights[cur]) lweights[idx] = lweights[cur]+1; if (nxt > 0) { llprev[nxt] = prv; } if (prv > 0) { llnext[prv] = nxt; } else { degb[degrees[idx]] = nxt; } degrees[idx]--; llnext[idx] = degb[degrees[idx]]; llprev[idx] = -1; if (degb[degrees[idx]] >= 0) { llprev[degb[degrees[idx]]] = idx; } degb[degrees[idx]] = idx; if (dist < distance) { ncols = Gi[idx+1]-Gi[idx]; cols = &(Gj[Gi[idx]]); for (j=0;j<ncols;j++) { if (seen[cols[j]] != i) { bidx++; seen[cols[j]] = i; idxbuf[bidx] = cols[j]; distbuf[bidx] = dist+1; } } } } } break; } } } for (i=0;i<lm;i++) { if (gidx[i] >= s && gidx[i] < e) { weights[gidx[i]-s] = lweights[i]; } } ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); ierr = PetscFree(degb);CHKERRQ(ierr); ierr = PetscFree2(llnext,llprev);CHKERRQ(ierr); ierr = PetscFree(degrees);CHKERRQ(ierr); ierr = PetscFree(lweights);CHKERRQ(ierr); ierr = ISRestoreIndices(ris,&gidx);CHKERRQ(ierr); ierr = ISDestroy(&ris);CHKERRQ(ierr); ierr = PetscFree3(seen,idxbuf,distbuf);CHKERRQ(ierr); ierr = MatDestroyMatrices(1,&lGs);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode PCGAMGCoarsen_GEO(PC a_pc,Mat *a_Gmat,PetscCoarsenData **a_llist_parent) { PetscErrorCode ierr; PetscInt Istart,Iend,nloc,kk,Ii,ncols; IS perm; GAMGNode *gnodes; PetscInt *permute; Mat Gmat = *a_Gmat; MPI_Comm comm; MatCoarsen crs; PetscFunctionBegin; ierr = PetscObjectGetComm((PetscObject)a_pc,&comm);CHKERRQ(ierr); ierr = PetscLogEventBegin(PC_GAMGCoarsen_GEO,0,0,0,0);CHKERRQ(ierr); ierr = MatGetOwnershipRange(Gmat, &Istart, &Iend);CHKERRQ(ierr); nloc = (Iend-Istart); /* create random permutation with sort for geo-mg */ ierr = PetscMalloc1(nloc, &gnodes);CHKERRQ(ierr); ierr = PetscMalloc1(nloc, &permute);CHKERRQ(ierr); for (Ii=Istart; Ii<Iend; Ii++) { /* locals only? */ ierr = MatGetRow(Gmat,Ii,&ncols,0,0);CHKERRQ(ierr); { PetscInt lid = Ii - Istart; gnodes[lid].lid = lid; gnodes[lid].degree = ncols; } ierr = MatRestoreRow(Gmat,Ii,&ncols,0,0);CHKERRQ(ierr); } if (PETSC_TRUE) { PetscRandom rand; PetscBool *bIndexSet; PetscReal rr; PetscInt iSwapIndex; ierr = PetscRandomCreate(comm,&rand);CHKERRQ(ierr); ierr = PetscCalloc1(nloc, &bIndexSet);CHKERRQ(ierr); for (Ii = 0; Ii < nloc; Ii++) { ierr = PetscRandomGetValueReal(rand,&rr);CHKERRQ(ierr); iSwapIndex = (PetscInt) (rr*nloc); if (!bIndexSet[iSwapIndex] && iSwapIndex != Ii) { GAMGNode iTemp = gnodes[iSwapIndex]; gnodes[iSwapIndex] = gnodes[Ii]; gnodes[Ii] = iTemp; bIndexSet[Ii] = PETSC_TRUE; bIndexSet[iSwapIndex] = PETSC_TRUE; } } ierr = PetscRandomDestroy(&rand);CHKERRQ(ierr); ierr = PetscFree(bIndexSet);CHKERRQ(ierr); } /* only sort locals */ qsort(gnodes, nloc, sizeof(GAMGNode), petsc_geo_mg_compare); /* create IS of permutation */ for (kk=0; kk<nloc; kk++) permute[kk] = gnodes[kk].lid; /* locals only */ ierr = ISCreateGeneral(PETSC_COMM_SELF, nloc, permute, PETSC_OWN_POINTER, &perm);CHKERRQ(ierr); ierr = PetscFree(gnodes);CHKERRQ(ierr); /* get MIS aggs */ ierr = MatCoarsenCreate(comm, &crs);CHKERRQ(ierr); ierr = MatCoarsenSetType(crs, MATCOARSENMIS);CHKERRQ(ierr); ierr = MatCoarsenSetGreedyOrdering(crs, perm);CHKERRQ(ierr); ierr = MatCoarsenSetAdjacency(crs, Gmat);CHKERRQ(ierr); ierr = MatCoarsenSetStrictAggs(crs, PETSC_FALSE);CHKERRQ(ierr); ierr = MatCoarsenApply(crs);CHKERRQ(ierr); ierr = MatCoarsenGetData(crs, a_llist_parent);CHKERRQ(ierr); ierr = MatCoarsenDestroy(&crs);CHKERRQ(ierr); ierr = ISDestroy(&perm);CHKERRQ(ierr); ierr = PetscLogEventEnd(PC_GAMGCoarsen_GEO,0,0,0,0);CHKERRQ(ierr); PetscFunctionReturn(0); }