1 static char help[] = "Test for mesh reordering\n\n"; 2 3 #include <petscdmplex.h> 4 5 typedef struct { 6 PetscInt dim; /* The topological mesh dimension */ 7 PetscReal refinementLimit; /* Maximum volume of a refined cell */ 8 PetscInt numFields; /* The number of section fields */ 9 PetscInt *numComponents; /* The number of field components */ 10 PetscInt *numDof; /* The dof signature for the section */ 11 PetscInt numGroups; /* If greater than 1, use grouping in test */ 12 } AppCtx; 13 14 PetscErrorCode ProcessOptions(AppCtx *options) 15 { 16 PetscInt len; 17 PetscBool flg; 18 PetscErrorCode ierr; 19 20 PetscFunctionBegin; 21 options->numFields = 1; 22 options->numComponents = NULL; 23 options->numDof = NULL; 24 options->numGroups = 0; 25 26 ierr = PetscOptionsBegin(PETSC_COMM_SELF, "", "Meshing Problem Options", "DMPLEX");CHKERRQ(ierr); 27 ierr = PetscOptionsBoundedInt("-num_fields", "The number of section fields", "ex10.c", options->numFields, &options->numFields, NULL,1);CHKERRQ(ierr); 28 if (options->numFields) { 29 len = options->numFields; 30 ierr = PetscCalloc1(len, &options->numComponents);CHKERRQ(ierr); 31 ierr = PetscOptionsIntArray("-num_components", "The number of components per field", "ex10.c", options->numComponents, &len, &flg);CHKERRQ(ierr); 32 PetscCheckFalse(flg && (len != options->numFields),PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Length of components array is %D should be %D", len, options->numFields); 33 } 34 ierr = PetscOptionsBoundedInt("-num_groups", "Group permutation by this many label values", "ex10.c", options->numGroups, &options->numGroups, NULL,0);CHKERRQ(ierr); 35 ierr = PetscOptionsEnd();CHKERRQ(ierr); 36 PetscFunctionReturn(0); 37 } 38 39 PetscErrorCode CleanupContext(AppCtx *user) 40 { 41 PetscErrorCode ierr; 42 43 PetscFunctionBegin; 44 ierr = PetscFree(user->numComponents);CHKERRQ(ierr); 45 ierr = PetscFree(user->numDof);CHKERRQ(ierr); 46 PetscFunctionReturn(0); 47 } 48 49 /* This mesh comes from~\cite{saad2003}, Fig. 2.10, p. 70. */ 50 PetscErrorCode CreateTestMesh(MPI_Comm comm, DM *dm, AppCtx *options) 51 { 52 const PetscInt cells[16*3] = {6, 7, 8, 7, 9, 10, 10, 11, 12, 11, 13, 14, 0, 6, 8, 6, 2, 7, 1, 8, 7, 1, 7, 10, 53 2, 9, 7, 10, 9, 4, 1, 10, 12, 10, 4, 11, 12, 11, 3, 3, 11, 14, 11, 4, 13, 14, 13, 5}; 54 const PetscReal coords[15*2] = {0, -3, 0, -1, 2, -1, 0, 1, 2, 1, 55 0, 3, 1, -2, 1, -1, 0, -2, 2, 0, 56 1, 0, 1, 1, 0, 0, 1, 2, 0, 2}; 57 PetscErrorCode ierr; 58 59 PetscFunctionBegin; 60 ierr = DMPlexCreateFromCellListPetsc(comm, 2, 16, 15, 3, PETSC_FALSE, cells, 2, coords, dm);CHKERRQ(ierr); 61 PetscFunctionReturn(0); 62 } 63 64 PetscErrorCode TestReordering(DM dm, AppCtx *user) 65 { 66 DM pdm; 67 IS perm; 68 Mat A, pA; 69 PetscInt bw, pbw; 70 MatOrderingType order = MATORDERINGRCM; 71 PetscErrorCode ierr; 72 73 PetscFunctionBegin; 74 ierr = DMPlexGetOrdering(dm, order, NULL, &perm);CHKERRQ(ierr); 75 ierr = DMPlexPermute(dm, perm, &pdm);CHKERRQ(ierr); 76 ierr = PetscObjectSetOptionsPrefix((PetscObject) pdm, "perm_");CHKERRQ(ierr); 77 ierr = DMSetFromOptions(pdm);CHKERRQ(ierr); 78 ierr = ISDestroy(&perm);CHKERRQ(ierr); 79 ierr = DMViewFromOptions(dm, NULL, "-orig_dm_view");CHKERRQ(ierr); 80 ierr = DMViewFromOptions(pdm, NULL, "-dm_view");CHKERRQ(ierr); 81 ierr = DMCreateMatrix(dm, &A);CHKERRQ(ierr); 82 ierr = DMCreateMatrix(pdm, &pA);CHKERRQ(ierr); 83 ierr = MatComputeBandwidth(A, 0.0, &bw);CHKERRQ(ierr); 84 ierr = MatComputeBandwidth(pA, 0.0, &pbw);CHKERRQ(ierr); 85 ierr = MatViewFromOptions(A, NULL, "-orig_mat_view");CHKERRQ(ierr); 86 ierr = MatViewFromOptions(pA, NULL, "-perm_mat_view");CHKERRQ(ierr); 87 ierr = MatDestroy(&A);CHKERRQ(ierr); 88 ierr = MatDestroy(&pA);CHKERRQ(ierr); 89 ierr = DMDestroy(&pdm);CHKERRQ(ierr); 90 if (pbw > bw) { 91 ierr = PetscPrintf(PetscObjectComm((PetscObject) dm), "Ordering method %s increased bandwidth from %D to %D\n", order, bw, pbw);CHKERRQ(ierr); 92 } else { 93 ierr = PetscPrintf(PetscObjectComm((PetscObject) dm), "Ordering method %s reduced bandwidth from %D to %D\n", order, bw, pbw);CHKERRQ(ierr); 94 } 95 PetscFunctionReturn(0); 96 } 97 98 PetscErrorCode CreateGroupLabel(DM dm, PetscInt numGroups, DMLabel *label, AppCtx *options) 99 { 100 const PetscInt groupA[10] = {15, 3, 13, 12, 2, 10, 7, 6, 0, 4}; 101 const PetscInt groupB[6] = {14, 11, 9, 1, 8, 5}; 102 PetscInt c; 103 PetscErrorCode ierr; 104 105 PetscFunctionBegin; 106 if (numGroups < 2) {*label = NULL; PetscFunctionReturn(0);} 107 PetscCheckFalse(numGroups != 2,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Test only coded for 2 groups, not %D", numGroups); 108 ierr = DMLabelCreate(PETSC_COMM_SELF, "groups", label);CHKERRQ(ierr); 109 for (c = 0; c < 10; ++c) {ierr = DMLabelSetValue(*label, groupA[c], 101);CHKERRQ(ierr);} 110 for (c = 0; c < 6; ++c) {ierr = DMLabelSetValue(*label, groupB[c], 1001);CHKERRQ(ierr);} 111 PetscFunctionReturn(0); 112 } 113 114 PetscErrorCode TestReorderingByGroup(DM dm, AppCtx *user) 115 { 116 DM pdm; 117 DMLabel label; 118 Mat A, pA; 119 MatOrderingType order = MATORDERINGRCM; 120 IS perm; 121 PetscErrorCode ierr; 122 123 PetscFunctionBegin; 124 ierr = CreateGroupLabel(dm, user->numGroups, &label, user);CHKERRQ(ierr); 125 ierr = DMPlexGetOrdering(dm, order, label, &perm);CHKERRQ(ierr); 126 ierr = DMLabelDestroy(&label);CHKERRQ(ierr); 127 ierr = DMPlexPermute(dm, perm, &pdm);CHKERRQ(ierr); 128 ierr = PetscObjectSetOptionsPrefix((PetscObject) pdm, "perm_");CHKERRQ(ierr); 129 ierr = DMSetFromOptions(pdm);CHKERRQ(ierr); 130 ierr = DMViewFromOptions(dm, NULL, "-orig_dm_view");CHKERRQ(ierr); 131 ierr = DMViewFromOptions(pdm, NULL, "-perm_dm_view");CHKERRQ(ierr); 132 ierr = ISDestroy(&perm);CHKERRQ(ierr); 133 ierr = DMCreateMatrix(dm, &A);CHKERRQ(ierr); 134 ierr = DMCreateMatrix(pdm, &pA);CHKERRQ(ierr); 135 ierr = MatViewFromOptions(A, NULL, "-orig_mat_view");CHKERRQ(ierr); 136 ierr = MatViewFromOptions(pA, NULL, "-perm_mat_view");CHKERRQ(ierr); 137 ierr = MatDestroy(&A);CHKERRQ(ierr); 138 ierr = MatDestroy(&pA);CHKERRQ(ierr); 139 ierr = DMDestroy(&pdm);CHKERRQ(ierr); 140 PetscFunctionReturn(0); 141 } 142 143 int main(int argc, char **argv) 144 { 145 DM dm; 146 PetscSection s; 147 AppCtx user; 148 PetscInt dim; 149 PetscErrorCode ierr; 150 151 ierr = PetscInitialize(&argc, &argv, NULL, help);if (ierr) return ierr; 152 ierr = ProcessOptions(&user);CHKERRQ(ierr); 153 if (user.numGroups < 1) { 154 ierr = DMCreate(PETSC_COMM_WORLD, &dm);CHKERRQ(ierr); 155 ierr = DMSetType(dm, DMPLEX);CHKERRQ(ierr); 156 } else { 157 ierr = CreateTestMesh(PETSC_COMM_WORLD, &dm, &user);CHKERRQ(ierr); 158 } 159 ierr = DMSetFromOptions(dm);CHKERRQ(ierr); 160 ierr = DMViewFromOptions(dm, NULL, "-dm_view");CHKERRQ(ierr); 161 ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr); 162 { 163 PetscInt len = (dim+1) * PetscMax(1, user.numFields); 164 PetscBool flg; 165 166 ierr = PetscMalloc1(len, &user.numDof);CHKERRQ(ierr); 167 ierr = PetscOptionsBegin(PETSC_COMM_SELF, "", "Meshing Problem Options", "DMPLEX");CHKERRQ(ierr); 168 ierr = PetscOptionsIntArray("-num_dof", "The dof signature for the section", "ex10.c", user.numDof, &len, &flg);CHKERRQ(ierr); 169 PetscCheckFalse(flg && (len != (dim+1) * PetscMax(1, user.numFields)),PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Length of dof array is %D should be %D", len, (dim+1) * PetscMax(1, user.numFields)); 170 ierr = PetscOptionsEnd();CHKERRQ(ierr); 171 } 172 if (user.numGroups < 1) { 173 ierr = DMSetNumFields(dm, user.numFields);CHKERRQ(ierr); 174 ierr = DMCreateDS(dm);CHKERRQ(ierr); 175 ierr = DMPlexCreateSection(dm, NULL, user.numComponents, user.numDof, 0, NULL, NULL, NULL, NULL, &s);CHKERRQ(ierr); 176 ierr = DMSetLocalSection(dm, s);CHKERRQ(ierr); 177 ierr = PetscSectionDestroy(&s);CHKERRQ(ierr); 178 ierr = TestReordering(dm, &user);CHKERRQ(ierr); 179 } else { 180 ierr = DMSetNumFields(dm, user.numFields);CHKERRQ(ierr); 181 ierr = DMCreateDS(dm);CHKERRQ(ierr); 182 ierr = DMPlexCreateSection(dm, NULL, user.numComponents, user.numDof, 0, NULL, NULL, NULL, NULL, &s);CHKERRQ(ierr); 183 ierr = DMSetLocalSection(dm, s);CHKERRQ(ierr); 184 ierr = PetscSectionDestroy(&s);CHKERRQ(ierr); 185 ierr = TestReorderingByGroup(dm, &user);CHKERRQ(ierr); 186 } 187 ierr = DMDestroy(&dm);CHKERRQ(ierr); 188 ierr = CleanupContext(&user);CHKERRQ(ierr); 189 ierr = PetscFinalize(); 190 return ierr; 191 } 192 193 /*TEST 194 195 # Two cell tests 0-3 196 test: 197 suffix: 0 198 requires: triangle 199 args: -dm_plex_simplex 1 -num_dof 1,0,0 -mat_view -dm_coord_space 0 200 test: 201 suffix: 1 202 args: -dm_plex_simplex 0 -num_dof 1,0,0 -mat_view -dm_coord_space 0 203 test: 204 suffix: 2 205 requires: ctetgen 206 args: -dm_plex_dim 3 -dm_plex_simplex 1 -num_dof 1,0,0,0 -mat_view -dm_coord_space 0 207 test: 208 suffix: 3 209 args: -dm_plex_dim 3 -dm_plex_simplex 0 -num_dof 1,0,0,0 -mat_view -dm_coord_space 0 210 # Refined tests 4-7 211 test: 212 suffix: 4 213 requires: triangle 214 args: -dm_plex_simplex 1 -dm_refine_volume_limit_pre 0.00625 -num_dof 1,0,0 215 test: 216 suffix: 5 217 args: -dm_plex_simplex 0 -dm_refine 1 -num_dof 1,0,0 218 test: 219 suffix: 6 220 requires: ctetgen 221 args: -dm_plex_dim 3 -dm_plex_simplex 1 -dm_refine_volume_limit_pre 0.00625 -num_dof 1,0,0,0 222 test: 223 suffix: 7 224 args: -dm_plex_dim 3 -dm_plex_simplex 0 -dm_refine 1 -num_dof 1,0,0,0 225 # Parallel tests 226 # Grouping tests 227 test: 228 suffix: group_1 229 args: -num_groups 1 -num_dof 1,0,0 -is_view -orig_mat_view -perm_mat_view 230 test: 231 suffix: group_2 232 args: -num_groups 2 -num_dof 1,0,0 -is_view -perm_mat_view 233 234 TEST*/ 235