static char help[] = "testing periodic bc\n"; #include #define nvar 2 int main(int argc, char **argv) { PetscErrorCode ierr; DM dm, dmDist = NULL; PetscSection sec; PetscInt dim = 2, numFields = 1, overlap = 1, numBC, i; PetscInt numComp[1]; // number of components per field PetscInt numDof[3]; PetscBool interpolate = PETSC_TRUE, useCone = PETSC_TRUE, useClosure = PETSC_TRUE; PetscMPIInt rank, size; ierr = PetscInitialize(&argc, &argv, (char*)0, help); CHKERRQ(ierr); MPI_Comm_rank(PETSC_COMM_WORLD, &rank); MPI_Comm_size(PETSC_COMM_WORLD, &size); // read mesh from gmsh file //ierr = DMPlexCreateGmshFromFile(PETSC_COMM_WORLD, "ug_periodic.msh", interpolate, &dm); CHKERRQ(ierr); // set periodicity information (periodic in x and y) //const DMBoundaryType bd[] = {DM_BOUNDARY_PERIODIC, DM_BOUNDARY_PERIODIC}; //ierr = DMSetPeriodicity(dm, PETSC_TRUE, NULL, NULL, bd); CHKERRQ(ierr); PetscCall(DMCreate(PETSC_COMM_WORLD, &dm)); PetscCall(DMSetType(dm, DMPLEX)); PetscCall(DMSetFromOptions(dm)); PetscCall(DMViewFromOptions(dm, NULL, "-dm_view")); // set partitioner type to Parmetis PetscPartitioner part; ierr = DMPlexGetPartitioner(dm, &part); CHKERRQ(ierr); ierr = PetscPartitionerSetType(part, PETSCPARTITIONERSIMPLE); CHKERRQ(ierr); ierr = PetscPartitionerSetFromOptions(part); CHKERRQ(ierr); // distribute mesh over processes; ierr = DMSetBasicAdjacency(dm, useCone, useClosure); CHKERRQ(ierr); ierr = DMPlexDistribute(dm, overlap, NULL, &dmDist); CHKERRQ(ierr); if(dmDist) { ierr = DMDestroy(&dm); CHKERRQ(ierr); dm = dmDist; } ierr = DMSetNumFields(dm, numFields); CHKERRQ(ierr); ierr = DMSetAdjacency(dm, 0, useCone, useClosure); CHKERRQ(ierr); // setup FV PetscFV fv; ierr = PetscFVCreate(PETSC_COMM_WORLD, &fv); CHKERRQ(ierr); ierr = PetscFVSetType(fv, PETSCFVUPWIND); CHKERRQ(ierr); ierr = PetscFVSetNumComponents(fv, nvar); CHKERRQ(ierr); ierr = PetscFVSetSpatialDimension(fv, dim); CHKERRQ(ierr); ierr = PetscFVSetFromOptions(fv); CHKERRQ(ierr); ierr = PetscFVSetUp(fv); CHKERRQ(ierr); // create field for solution u numComp[0] = nvar; // six components for(i=0; icentroid[0], fg->centroid[1], fg->normal[0], fg->normal[1]); PetscReal len = PetscSqrtReal(PetscPowReal(fg->normal[0],2) + PetscPowReal(fg->normal[1],2)); if(PetscAbs(len - 2.5) > 1.0e-10) { PetscPrintf(PETSC_COMM_SELF,"===> Face length incorrect = %f, should be 2.5\n", len); } // cell geometry for(PetscInt i=0; icentroid[0], cg->centroid[1], cg->volume); } PetscPrintf(PETSC_COMM_WORLD, "\n"); } // cleanup ierr = PetscFVDestroy(&fv); CHKERRQ(ierr); ierr = VecRestoreArrayRead(faceGeom, &fgeom); CHKERRQ(ierr); ierr = VecRestoreArrayRead(cellGeom, &cgeom); CHKERRQ(ierr); ierr = PetscSectionDestroy(&sec); CHKERRQ(ierr); ierr = DMDestroy(&dm); CHKERRQ(ierr); ierr = PetscFinalize(); CHKERRQ(ierr); return ierr; }