PetscErrorCode SetupSection(DM dm, AppCtx *user) { DM cdm = dm; const PetscInt id = 1; PetscErrorCode ierr; PetscFunctionBeginUser; ierr = PetscObjectSetName((PetscObject) user->fe[0], "potential");CHKERRQ(ierr); while (cdm) { ierr = DMSetNumFields(cdm, 1);CHKERRQ(ierr); ierr = DMSetField(cdm, 0, (PetscObject) user->fe[0]);CHKERRQ(ierr); ierr = DMPlexAddBoundary(cdm, user->bcType == DIRICHLET, user->bcType == NEUMANN ? "boundary" : "marker", 0, user->exactFuncs[0], 1, &id, user);CHKERRQ(ierr); ierr = DMPlexGetCoarseDM(cdm, &cdm);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode TestCellShape(DM dm) { PetscMPIInt rank; PetscInt dim, c, cStart, cEnd, count = 0; ex1_stats_t stats, globalStats; PetscReal *J, *invJ, min = 0, max = 0, mean = 0, stdev = 0; MPI_Comm comm = PetscObjectComm((PetscObject)dm); DM dmCoarse; PetscErrorCode ierr; PetscFunctionBegin; stats.min = PETSC_MAX_REAL; stats.max = PETSC_MIN_REAL; stats.sum = stats.squaresum = 0.; stats.count = 0; ierr = DMGetDimension(dm,&dim);CHKERRQ(ierr); ierr = PetscMalloc2(dim * dim, &J, dim * dim, &invJ);CHKERRQ(ierr); ierr = DMPlexGetHeightStratum(dm,0,&cStart,&cEnd);CHKERRQ(ierr); for (c = cStart; c < cEnd; c++) { PetscInt i; PetscReal frobJ = 0., frobInvJ = 0., cond2, cond, detJ; ierr = DMPlexComputeCellGeometryAffineFEM(dm,c,NULL,J,invJ,&detJ);CHKERRQ(ierr); for (i = 0; i < dim * dim; i++) { frobJ += J[i] * J[i]; frobInvJ += invJ[i] * invJ[i]; } cond2 = frobJ * frobInvJ; cond = PetscSqrtReal(cond2); stats.min = PetscMin(stats.min,cond); stats.max = PetscMax(stats.max,cond); stats.sum += cond; stats.squaresum += cond2; stats.count++; } { PetscMPIInt blockLengths[2] = {4,1}; MPI_Aint blockOffsets[2] = {offsetof(ex1_stats_t,min),offsetof(ex1_stats_t,count)}; MPI_Datatype blockTypes[2] = {MPIU_REAL,MPIU_INT}, statType; MPI_Op statReduce; ierr = MPI_Type_create_struct(2,blockLengths,blockOffsets,blockTypes,&statType);CHKERRQ(ierr); ierr = MPI_Type_commit(&statType);CHKERRQ(ierr); ierr = MPI_Op_create(ex1_stats_reduce, PETSC_TRUE, &statReduce);CHKERRQ(ierr); ierr = MPI_Reduce(&stats,&globalStats,1,statType,statReduce,0,comm);CHKERRQ(ierr); ierr = MPI_Op_free(&statReduce);CHKERRQ(ierr); ierr = MPI_Type_free(&statType);CHKERRQ(ierr); } ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); if (!rank) { count = globalStats.count; min = globalStats.min; max = globalStats.max; mean = globalStats.sum / globalStats.count; stdev = PetscSqrtReal(globalStats.squaresum / globalStats.count - mean * mean); } ierr = PetscPrintf(comm,"Mesh with %d cells, shape condition numbers: min = %g, max = %g, mean = %g, stddev = %g\n", count, (double) min, (double) max, (double) mean, (double) stdev); ierr = PetscFree2(J,invJ);CHKERRQ(ierr); ierr = DMPlexGetCoarseDM(dm,&dmCoarse);CHKERRQ(ierr); if (dmCoarse) { ierr = TestCellShape(dmCoarse);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PetscErrorCode SetupDiscretization(DM dm, AppCtx *user) { DM cdm = dm; const PetscInt dim = user->dim; const PetscInt id = 1; PetscFE feAux = NULL; PetscFE feBd = NULL; PetscFE feCh = NULL; PetscFE fe; PetscDS prob; PetscErrorCode ierr; PetscFunctionBeginUser; /* Create finite element */ ierr = PetscFECreateDefault(dm, dim, 1, PETSC_TRUE, NULL, -1, &fe);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) fe, "potential");CHKERRQ(ierr); if (user->bcType == NEUMANN) { ierr = PetscFECreateDefault(dm, dim-1, 1, PETSC_TRUE, "bd_", -1, &feBd);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject) feBd, "potential");CHKERRQ(ierr); } if (user->variableCoefficient == COEFF_FIELD) { PetscQuadrature q; ierr = PetscFECreateDefault(dm, dim, 1, PETSC_TRUE, "mat_", -1, &feAux);CHKERRQ(ierr); ierr = PetscFEGetQuadrature(fe, &q);CHKERRQ(ierr); ierr = PetscFESetQuadrature(feAux, q);CHKERRQ(ierr); } if (user->check) {ierr = PetscFECreateDefault(dm, dim, 1, PETSC_TRUE, "ch_", -1, &feCh);CHKERRQ(ierr);} /* Set discretization and boundary conditions for each mesh */ while (cdm) { ierr = DMGetDS(cdm, &prob);CHKERRQ(ierr); ierr = PetscDSSetDiscretization(prob, 0, (PetscObject) fe);CHKERRQ(ierr); ierr = PetscDSSetBdDiscretization(prob, 0, (PetscObject) feBd);CHKERRQ(ierr); if (feAux) { DM dmAux; PetscDS probAux; ierr = DMClone(cdm, &dmAux);CHKERRQ(ierr); ierr = DMPlexCopyCoordinates(cdm, dmAux);CHKERRQ(ierr); ierr = DMGetDS(dmAux, &probAux);CHKERRQ(ierr); ierr = PetscDSSetDiscretization(probAux, 0, (PetscObject) feAux);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "dmAux", (PetscObject) dmAux);CHKERRQ(ierr); ierr = SetupMaterial(cdm, dmAux, user);CHKERRQ(ierr); ierr = DMDestroy(&dmAux);CHKERRQ(ierr); } if (feCh) { DM dmCh; PetscDS probCh; ierr = DMClone(cdm, &dmCh);CHKERRQ(ierr); ierr = DMPlexCopyCoordinates(cdm, dmCh);CHKERRQ(ierr); ierr = DMGetDS(dmCh, &probCh);CHKERRQ(ierr); ierr = PetscDSSetDiscretization(probCh, 0, (PetscObject) feCh);CHKERRQ(ierr); ierr = PetscObjectCompose((PetscObject) dm, "dmCh", (PetscObject) dmCh);CHKERRQ(ierr); ierr = DMDestroy(&dmCh);CHKERRQ(ierr); } ierr = SetupProblem(cdm, user);CHKERRQ(ierr); ierr = DMPlexAddBoundary(cdm, user->bcType == DIRICHLET, "wall", user->bcType == NEUMANN ? "boundary" : "marker", 0, user->exactFuncs[0], 1, &id, user);CHKERRQ(ierr); ierr = DMPlexGetCoarseDM(cdm, &cdm);CHKERRQ(ierr); } ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); ierr = PetscFEDestroy(&feBd);CHKERRQ(ierr); ierr = PetscFEDestroy(&feAux);CHKERRQ(ierr); ierr = PetscFEDestroy(&feCh);CHKERRQ(ierr); PetscFunctionReturn(0); }