static char help[] = "Tests DMComposite routines.\n\n"; #include #include #include #include #include int main(int argc, char **argv) { PetscInt nredundant1 = 5, nredundant2 = 2, i; ISLocalToGlobalMapping *ltog; PetscMPIInt rank, size; DM packer; Vec global, local1, local2, redundant1, redundant2; PF pf; DM da1, da2, dmred1, dmred2; PetscScalar *redundant1a, *redundant2a; PetscViewer sviewer; PetscBool gather_add = PETSC_FALSE; PetscFunctionBeginUser; PetscCall(PetscInitialize(&argc, &argv, NULL, help)); PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size)); PetscCall(PetscOptionsGetBool(NULL, NULL, "-gather_add", &gather_add, NULL)); PetscCall(DMCompositeCreate(PETSC_COMM_WORLD, &packer)); PetscCall(DMRedundantCreate(PETSC_COMM_WORLD, 0, nredundant1, &dmred1)); PetscCall(DMCreateLocalVector(dmred1, &redundant1)); PetscCall(DMCompositeAddDM(packer, dmred1)); PetscCall(DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, 8, 1, 1, NULL, &da1)); PetscCall(DMSetFromOptions(da1)); PetscCall(DMSetUp(da1)); PetscCall(DMCreateLocalVector(da1, &local1)); PetscCall(DMCompositeAddDM(packer, da1)); PetscCall(DMRedundantCreate(PETSC_COMM_WORLD, 1 % size, nredundant2, &dmred2)); PetscCall(DMCreateLocalVector(dmred2, &redundant2)); PetscCall(DMCompositeAddDM(packer, dmred2)); PetscCall(DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_NONE, 6, 1, 1, NULL, &da2)); PetscCall(DMSetFromOptions(da2)); PetscCall(DMSetUp(da2)); PetscCall(DMCreateLocalVector(da2, &local2)); PetscCall(DMCompositeAddDM(packer, da2)); PetscCall(DMCreateGlobalVector(packer, &global)); PetscCall(PFCreate(PETSC_COMM_WORLD, 1, 1, &pf)); PetscCall(PFSetType(pf, PFIDENTITY, NULL)); PetscCall(PFApplyVec(pf, NULL, global)); PetscCall(PFDestroy(&pf)); PetscCall(VecView(global, PETSC_VIEWER_STDOUT_WORLD)); PetscCall(DMCompositeScatter(packer, global, redundant1, local1, redundant2, local2)); PetscCall(PetscViewerASCIIPushSynchronized(PETSC_VIEWER_STDOUT_WORLD)); PetscCall(PetscViewerGetSubViewer(PETSC_VIEWER_STDOUT_WORLD, PETSC_COMM_SELF, &sviewer)); PetscCall(PetscViewerASCIIPrintf(sviewer, "[%d] My part of redundant1 vector\n", rank)); PetscCall(VecView(redundant1, sviewer)); PetscCall(PetscViewerRestoreSubViewer(PETSC_VIEWER_STDOUT_WORLD, PETSC_COMM_SELF, &sviewer)); PetscCall(PetscViewerGetSubViewer(PETSC_VIEWER_STDOUT_WORLD, PETSC_COMM_SELF, &sviewer)); PetscCall(PetscViewerASCIIPrintf(sviewer, "[%d] My part of da1 vector\n", rank)); PetscCall(VecView(local1, sviewer)); PetscCall(PetscViewerRestoreSubViewer(PETSC_VIEWER_STDOUT_WORLD, PETSC_COMM_SELF, &sviewer)); PetscCall(PetscViewerGetSubViewer(PETSC_VIEWER_STDOUT_WORLD, PETSC_COMM_SELF, &sviewer)); PetscCall(PetscViewerASCIIPrintf(sviewer, "[%d] My part of redundant2 vector\n", rank)); PetscCall(VecView(redundant2, sviewer)); PetscCall(PetscViewerRestoreSubViewer(PETSC_VIEWER_STDOUT_WORLD, PETSC_COMM_SELF, &sviewer)); PetscCall(PetscViewerGetSubViewer(PETSC_VIEWER_STDOUT_WORLD, PETSC_COMM_SELF, &sviewer)); PetscCall(PetscViewerASCIIPrintf(sviewer, "[%d] My part of da2 vector\n", rank)); PetscCall(VecView(local2, sviewer)); PetscCall(PetscViewerRestoreSubViewer(PETSC_VIEWER_STDOUT_WORLD, PETSC_COMM_SELF, &sviewer)); PetscCall(PetscViewerASCIIPopSynchronized(PETSC_VIEWER_STDOUT_WORLD)); PetscCall(VecGetArray(redundant1, &redundant1a)); PetscCall(VecGetArray(redundant2, &redundant2a)); for (i = 0; i < nredundant1; i++) redundant1a[i] = (rank + 2) * i; for (i = 0; i < nredundant2; i++) redundant2a[i] = (rank + 10) * i; PetscCall(VecRestoreArray(redundant1, &redundant1a)); PetscCall(VecRestoreArray(redundant2, &redundant2a)); PetscCall(DMCompositeGather(packer, gather_add ? ADD_VALUES : INSERT_VALUES, global, redundant1, local1, redundant2, local2)); PetscCall(VecView(global, PETSC_VIEWER_STDOUT_WORLD)); /* get the global numbering for each subvector element */ PetscCall(DMCompositeGetISLocalToGlobalMappings(packer, <og)); PetscCall(PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD, "Local to global mapping of redundant1 vector\n")); PetscCall(ISLocalToGlobalMappingView(ltog[0], PETSC_VIEWER_STDOUT_WORLD)); PetscCall(PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD, "Local to global mapping of local1 vector\n")); PetscCall(ISLocalToGlobalMappingView(ltog[1], PETSC_VIEWER_STDOUT_WORLD)); PetscCall(PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD, "Local to global mapping of redundant2 vector\n")); PetscCall(ISLocalToGlobalMappingView(ltog[2], PETSC_VIEWER_STDOUT_WORLD)); PetscCall(PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_WORLD, "Local to global mapping of local2 vector\n")); PetscCall(ISLocalToGlobalMappingView(ltog[3], PETSC_VIEWER_STDOUT_WORLD)); for (i = 0; i < 4; i++) PetscCall(ISLocalToGlobalMappingDestroy(<og[i])); PetscCall(PetscFree(ltog)); PetscCall(DMDestroy(&da1)); PetscCall(DMDestroy(&dmred1)); PetscCall(DMDestroy(&dmred2)); PetscCall(DMDestroy(&da2)); PetscCall(VecDestroy(&redundant1)); PetscCall(VecDestroy(&redundant2)); PetscCall(VecDestroy(&local1)); PetscCall(VecDestroy(&local2)); PetscCall(VecDestroy(&global)); PetscCall(DMDestroy(&packer)); PetscCall(PetscFinalize()); return 0; } /*TEST build: requires: !complex test: nsize: 3 test: suffix: 2 nsize: 3 args: -gather_add TEST*/