xref: /petsc/src/dm/label/tutorials/ex1.c (revision 3ca90d2d9fe4d5ec7086bd4aee14f89370d16392)
1 static char help[] = "Tests DMLabel operations.\n\n";
2 
3 #include <petscdm.h>
4 #include <petscdmplex.h>
5 
6 PetscErrorCode ViewLabels(DM dm, PetscViewer viewer)
7 {
8   DMLabel        label;
9   const char    *labelName;
10   PetscInt       numLabels, l;
11   PetscErrorCode ierr;
12 
13   PetscFunctionBegin;
14   /* query the number and name of labels*/
15   ierr = DMGetNumLabels(dm, &numLabels);CHKERRQ(ierr);
16   ierr = PetscViewerASCIIPrintf(viewer, "Number of labels: %d\n", numLabels);CHKERRQ(ierr);
17   for (l = 0; l < numLabels; ++l) {
18     IS labelIS, tmpIS;
19 
20     ierr = DMGetLabelName(dm, l, &labelName);CHKERRQ(ierr);
21     ierr = PetscViewerASCIIPrintf(viewer, "Label %d: name: %s\n", l, labelName);CHKERRQ(ierr);
22     ierr = PetscViewerASCIIPrintf(viewer, "IS of values\n");CHKERRQ(ierr);
23     ierr = DMGetLabel(dm, labelName, &label);CHKERRQ(ierr);
24     ierr = DMLabelGetValueIS(label, &labelIS);CHKERRQ(ierr);
25     ierr = ISOnComm(labelIS, PetscObjectComm((PetscObject)viewer), PETSC_USE_POINTER, &tmpIS);CHKERRQ(ierr);
26     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
27     ierr = ISView(tmpIS, viewer);CHKERRQ(ierr);
28     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
29     ierr = ISDestroy(&tmpIS);CHKERRQ(ierr);
30     ierr = ISDestroy(&labelIS);CHKERRQ(ierr);
31     ierr = PetscViewerASCIIPrintf(viewer, "\n");CHKERRQ(ierr);
32   }
33   /* Making sure that string literals work */
34   ierr = PetscViewerASCIIPrintf(viewer,"\n\nCell Set label IS\n");CHKERRQ(ierr);
35   ierr = DMGetLabel(dm, "Cell Sets", &label);CHKERRQ(ierr);
36   if (label) {
37     IS labelIS, tmpIS;
38 
39     ierr = DMLabelGetValueIS(label, &labelIS);CHKERRQ(ierr);
40     ierr = ISOnComm(labelIS, PetscObjectComm((PetscObject)viewer), PETSC_USE_POINTER, &tmpIS);CHKERRQ(ierr);
41     ierr = ISView(tmpIS, viewer);CHKERRQ(ierr);
42     ierr = ISDestroy(&tmpIS);CHKERRQ(ierr);
43     ierr = ISDestroy(&labelIS);CHKERRQ(ierr);
44   }
45   PetscFunctionReturn(0);
46 }
47 
48 PetscErrorCode CheckLabelsSame(DMLabel label0, DMLabel label1)
49 {
50   const char     *name0, *name1;
51   PetscBool       same;
52   char           *msg;
53   PetscErrorCode  ierr;
54 
55   PetscFunctionBegin;
56   ierr = PetscObjectGetName((PetscObject)label0, &name0);CHKERRQ(ierr);
57   ierr = PetscObjectGetName((PetscObject)label1, &name1);CHKERRQ(ierr);
58   ierr = DMLabelCompare(label0, label1, &same, &msg);CHKERRQ(ierr);
59   if (same != (PetscBool) !msg) SETERRQ2(PETSC_COMM_WORLD, PETSC_ERR_PLIB, "DMLabelCompare returns inconsistent same=%d msg=\"%s\"", same, msg);
60   if (!same) SETERRQ3(PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Labels \"%s\" and \"%s\" should not differ! Message:\n%s", name0, name1, msg);
61   /* Test passing NULL, must not fail */
62   ierr = DMLabelCompare(label0, label1, NULL, NULL);CHKERRQ(ierr);
63   ierr = PetscFree(msg);CHKERRQ(ierr);
64   PetscFunctionReturn(0);
65 }
66 
67 PetscErrorCode CheckLabelsNotSame(DMLabel label0, DMLabel label1)
68 {
69   const char     *name0, *name1;
70   PetscBool       same;
71   char           *msg;
72   PetscErrorCode  ierr;
73 
74   PetscFunctionBegin;
75   ierr = PetscObjectGetName((PetscObject)label0, &name0);CHKERRQ(ierr);
76   ierr = PetscObjectGetName((PetscObject)label1, &name1);CHKERRQ(ierr);
77   ierr = DMLabelCompare(label0, label1, &same, &msg);CHKERRQ(ierr);
78   if (same != (PetscBool) !msg) SETERRQ2(PETSC_COMM_WORLD, PETSC_ERR_PLIB, "DMLabelCompare returns inconsistent same=%d msg=\"%s\"", same, msg);
79   if (same) SETERRQ2(PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Labels \"%s\" and \"%s\" should differ!", name0, name1);
80   ierr = PetscPrintf(PETSC_COMM_WORLD, "Compare label \"%s\" with \"%s\": %s\n", name0, name1, msg);CHKERRQ(ierr);
81   ierr = PetscFree(msg);CHKERRQ(ierr);
82   PetscFunctionReturn(0);
83 }
84 
85 PetscErrorCode CheckDMLabelsSame(DM dm0, DM dm1)
86 {
87   const char     *name0, *name1;
88   PetscBool       same;
89   char           *msg;
90   PetscErrorCode  ierr;
91 
92   PetscFunctionBegin;
93   ierr = PetscObjectGetName((PetscObject)dm0, &name0);CHKERRQ(ierr);
94   ierr = PetscObjectGetName((PetscObject)dm1, &name1);CHKERRQ(ierr);
95   ierr = DMCompareLabels(dm0, dm1, &same, &msg);CHKERRQ(ierr);
96   if (same != (PetscBool) !msg) SETERRQ2(PETSC_COMM_WORLD, PETSC_ERR_PLIB, "DMCompareLabels returns inconsistent same=%d msg=\"%s\"", same, msg);
97   if (!same) SETERRQ3(PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Labels of DMs \"%s\" and \"%s\" should not differ! Message:\n%s", name0, name1, msg);
98   /* Test passing NULL, must not fail */
99   ierr = DMCompareLabels(dm0, dm1, NULL, NULL);CHKERRQ(ierr);
100   ierr = PetscFree(msg);CHKERRQ(ierr);
101   PetscFunctionReturn(0);
102 }
103 
104 PetscErrorCode CheckDMLabelsNotSame(DM dm0, DM dm1)
105 {
106   const char     *name0, *name1;
107   PetscBool       same;
108   char           *msg;
109   PetscErrorCode  ierr;
110 
111   PetscFunctionBegin;
112   ierr = PetscObjectGetName((PetscObject)dm0, &name0);CHKERRQ(ierr);
113   ierr = PetscObjectGetName((PetscObject)dm1, &name1);CHKERRQ(ierr);
114   ierr = DMCompareLabels(dm0, dm1, &same, &msg);CHKERRQ(ierr);
115   if (same != (PetscBool) !msg) SETERRQ2(PETSC_COMM_WORLD, PETSC_ERR_PLIB, "DMCompareLabels returns inconsistent same=%d msg=\"%s\"", same, msg);
116   if (same) SETERRQ2(PETSC_COMM_WORLD, PETSC_ERR_PLIB, "Labels of DMs \"%s\" and \"%s\" should differ!", name0, name1);
117   ierr = PetscPrintf(PETSC_COMM_WORLD, "Labels of DMs \"%s\" and \"%s\" differ: %s\n", name0, name1, msg);CHKERRQ(ierr);
118   ierr = PetscFree(msg);CHKERRQ(ierr);
119   PetscFunctionReturn(0);
120 }
121 
122 PetscErrorCode CreateMesh(const char name[], DM *newdm)
123 {
124   DM             dm, dmDist;
125   char           filename[PETSC_MAX_PATH_LEN]="";
126   PetscBool      interpolate = PETSC_FALSE;
127   PetscErrorCode ierr;
128 
129   PetscFunctionBegin;
130   /* initialize and get options */
131   ierr = PetscOptionsBegin(PETSC_COMM_WORLD, NULL, "DMLabel ex1 Options", "DMLabel");CHKERRQ(ierr);
132   ierr = PetscOptionsString("-i", "filename to read", "ex1.c", filename, filename, sizeof(filename), NULL);CHKERRQ(ierr);
133   ierr = PetscOptionsBool("-interpolate", "Generate intermediate mesh elements", "ex1.c", interpolate, &interpolate, NULL);CHKERRQ(ierr);
134   ierr = PetscOptionsEnd();CHKERRQ(ierr);
135 
136   /* create and distribute DM */
137   ierr = DMPlexCreateFromFile(PETSC_COMM_WORLD, filename, interpolate, &dm);CHKERRQ(ierr);
138   ierr = DMPlexDistribute(dm, 0, NULL, &dmDist);CHKERRQ(ierr);
139   if (dmDist) {
140     ierr = DMDestroy(&dm);CHKERRQ(ierr);
141     dm   = dmDist;
142   }
143   ierr = DMSetFromOptions(dm);CHKERRQ(ierr);
144   ierr = PetscObjectSetName((PetscObject)dm, name);CHKERRQ(ierr);
145   *newdm = dm;
146   PetscFunctionReturn(0);
147 }
148 
149 int main(int argc, char **argv)
150 {
151   DM             dm;
152   PetscErrorCode ierr;
153 
154   ierr = PetscInitialize(&argc, &argv, NULL, help);if (ierr) return ierr;
155   ierr = CreateMesh("plex0", &dm);CHKERRQ(ierr);
156   /* add custom labels to test adding/removal */
157   {
158     DMLabel label0, label1, label2, label3;
159     PetscInt p, pStart, pEnd;
160     ierr = DMPlexGetChart(dm, &pStart, &pEnd);CHKERRQ(ierr);
161     /* create label in DM and get from DM */
162     ierr = DMCreateLabel(dm, "label0");CHKERRQ(ierr);
163     ierr = DMGetLabel(dm, "label0", &label0);CHKERRQ(ierr);
164     /* alternative: create standalone label and add to DM; needs to be destroyed */
165     ierr = DMLabelCreate(PETSC_COMM_SELF, "label1", &label1);CHKERRQ(ierr);
166     ierr = DMAddLabel(dm, label1);CHKERRQ(ierr);
167 
168     pEnd = PetscMin(pEnd, pStart + 5);
169     for (p=pStart; p < pEnd; p++) {
170       ierr = DMLabelSetValue(label0, p, 1);CHKERRQ(ierr);
171       ierr = DMLabelSetValue(label1, p, 2);CHKERRQ(ierr);
172     }
173     /* duplicate label */
174     ierr = DMLabelDuplicate(label0, &label2);CHKERRQ(ierr);
175     ierr = DMLabelDuplicate(label1, &label3);CHKERRQ(ierr);
176     ierr = PetscObjectSetName((PetscObject)label2, "label2");CHKERRQ(ierr);
177     ierr = PetscObjectSetName((PetscObject)label3, "label3");CHKERRQ(ierr);
178     ierr = DMAddLabel(dm, label2);CHKERRQ(ierr);
179     ierr = DMAddLabel(dm, label3);CHKERRQ(ierr);
180     /* remove the labels in this scope */
181     ierr = DMLabelDestroy(&label1);CHKERRQ(ierr);
182     ierr = DMLabelDestroy(&label2);CHKERRQ(ierr);
183     ierr = DMLabelDestroy(&label3);CHKERRQ(ierr);
184   }
185 
186   ierr = ViewLabels(dm, PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
187 
188   /* do label perturbations and comparisons */
189   {
190     DMLabel   label0, label1, label2, label3;
191     PetscInt  val;
192     PetscInt  p, pStart, pEnd;
193 
194     ierr = DMGetLabel(dm, "label0", &label0);CHKERRQ(ierr);
195     ierr = DMGetLabel(dm, "label1", &label1);CHKERRQ(ierr);
196     ierr = DMGetLabel(dm, "label2", &label2);CHKERRQ(ierr);
197     ierr = DMGetLabel(dm, "label3", &label3);CHKERRQ(ierr);
198 
199     ierr = CheckLabelsNotSame(label0, label1);CHKERRQ(ierr);
200     ierr = CheckLabelsSame(label0, label2);CHKERRQ(ierr);
201     ierr = CheckLabelsSame(label1, label3);CHKERRQ(ierr);
202 
203     ierr = DMLabelGetDefaultValue(label1, &val);CHKERRQ(ierr);
204     ierr = DMLabelSetDefaultValue(label1, 333);CHKERRQ(ierr);
205     ierr = CheckLabelsNotSame(label1, label3);CHKERRQ(ierr);
206     ierr = DMLabelSetDefaultValue(label1, val);CHKERRQ(ierr);
207     ierr = CheckLabelsSame(label1, label3);CHKERRQ(ierr);
208 
209     ierr = DMLabelGetBounds(label1, &pStart, &pEnd);CHKERRQ(ierr);
210 
211     for (p=pStart; p<pEnd; p++) {
212       ierr = DMLabelGetValue(label1, p, &val);CHKERRQ(ierr);
213       // This is weird. Perhaps we should not need to call DMLabelClearValue()
214       ierr = DMLabelClearValue(label1, p, val);CHKERRQ(ierr);
215       val++;
216       ierr = DMLabelSetValue(label1, p, val);CHKERRQ(ierr);
217     }
218     ierr = CheckLabelsNotSame(label1, label3);CHKERRQ(ierr);
219     for (p=pStart; p<pEnd; p++) {
220       ierr = DMLabelGetValue(label1, p, &val);CHKERRQ(ierr);
221       // This is weird. Perhaps we should not need to call DMLabelClearValue()
222       ierr = DMLabelClearValue(label1, p, val);CHKERRQ(ierr);
223       val--;
224       ierr = DMLabelSetValue(label1, p, val);CHKERRQ(ierr);
225     }
226     ierr = CheckLabelsSame(label1, label3);CHKERRQ(ierr);
227 
228     ierr = DMLabelGetValue(label3, pEnd-1, &val);CHKERRQ(ierr);
229     ierr = DMLabelSetValue(label3, pEnd, val);CHKERRQ(ierr);
230     ierr = CheckLabelsNotSame(label1, label3);CHKERRQ(ierr);
231     // This is weird. Perhaps we should not need to call DMLabelClearValue()
232     ierr = DMLabelClearValue(label3, pEnd, val);CHKERRQ(ierr);
233     ierr = CheckLabelsSame(label1, label3);CHKERRQ(ierr);
234   }
235 
236   {
237     DM        dm1;
238     DMLabel   label02, label12;
239     PetscInt  p = 0, val;
240 
241     ierr = CreateMesh("plex1", &dm1);CHKERRQ(ierr);
242     ierr = CheckDMLabelsNotSame(dm, dm1);CHKERRQ(ierr);
243 
244     ierr = DMCopyLabels(dm, dm1, PETSC_OWN_POINTER, PETSC_FALSE, DM_COPY_LABELS_REPLACE);CHKERRQ(ierr);
245     ierr = CheckDMLabelsSame(dm, dm1);CHKERRQ(ierr);
246 
247     ierr = DMCopyLabels(dm, dm1, PETSC_COPY_VALUES, PETSC_FALSE, DM_COPY_LABELS_REPLACE);CHKERRQ(ierr);
248     ierr = DMGetLabel(dm, "label2", &label02);CHKERRQ(ierr);
249     ierr = DMGetLabel(dm1, "label2", &label12);CHKERRQ(ierr);
250     ierr = CheckLabelsSame(label02, label12);CHKERRQ(ierr);
251 
252     ierr = DMLabelGetValue(label12, p, &val);CHKERRQ(ierr);
253     // This is weird. Perhaps we should not need to call DMLabelClearValue()
254     ierr = DMLabelClearValue(label12, p, val);CHKERRQ(ierr);
255     ierr = DMLabelSetValue(label12, p, val+1);CHKERRQ(ierr);
256     ierr = CheckLabelsNotSame(label02, label12);CHKERRQ(ierr);
257     ierr = CheckDMLabelsNotSame(dm, dm1);CHKERRQ(ierr);
258 
259     // This is weird. Perhaps we should not need to call DMLabelClearValue()
260     ierr = DMLabelClearValue(label12, p, val+1);CHKERRQ(ierr);
261     ierr = DMLabelSetValue(label12, p, val);CHKERRQ(ierr);
262     ierr = CheckLabelsSame(label02, label12);CHKERRQ(ierr);
263     ierr = CheckDMLabelsSame(dm, dm1);CHKERRQ(ierr);
264 
265     ierr = PetscObjectSetName((PetscObject)label12, "label12");CHKERRQ(ierr);
266     ierr = CheckDMLabelsNotSame(dm, dm1);CHKERRQ(ierr);
267     ierr = PetscObjectSetName((PetscObject)label12, "label2");CHKERRQ(ierr);
268     ierr = CheckDMLabelsSame(dm, dm1);CHKERRQ(ierr);
269 
270     ierr = DMDestroy(&dm1);CHKERRQ(ierr);
271   }
272 
273   /* remove label0 and label1 just to test manual removal; let label3 be removed automatically by DMDestroy() */
274   {
275     DMLabel label0, label1, label2;
276     ierr = DMGetLabel(dm, "label0", &label0);CHKERRQ(ierr);
277     ierr = DMGetLabel(dm, "label1", &label1);CHKERRQ(ierr);
278     if (!label0) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_PLIB, "label0 must not be NULL now");
279     if (!label1) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_PLIB, "label1 must not be NULL now");
280     ierr = DMRemoveLabel(dm, "label1", NULL);CHKERRQ(ierr);
281     ierr = DMRemoveLabel(dm, "label2", &label2);CHKERRQ(ierr);
282     ierr = DMRemoveLabelBySelf(dm, &label0, PETSC_TRUE);CHKERRQ(ierr);
283     ierr = DMGetLabel(dm, "label0", &label0);CHKERRQ(ierr);
284     ierr = DMGetLabel(dm, "label1", &label1);CHKERRQ(ierr);
285     if (label0) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_PLIB, "label0 must be NULL now");
286     if (label1) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_PLIB, "label1 must be NULL now");
287     if (!label2) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_PLIB, "label2 must not be NULL now");
288     ierr = DMRemoveLabelBySelf(dm, &label2, PETSC_FALSE);CHKERRQ(ierr); /* this should do nothing */
289     if (!label2) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_PLIB, "label2 must not be NULL now");
290     ierr = DMLabelDestroy(&label2);CHKERRQ(ierr);
291     ierr = DMGetLabel(dm, "label2", &label2);CHKERRQ(ierr);
292     if (label2) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_PLIB, "label2 must be NULL now");
293   }
294 
295   ierr = DMDestroy(&dm);CHKERRQ(ierr);
296   ierr = PetscFinalize();
297   return ierr;
298 }
299 
300 /*TEST
301 
302   test:
303     suffix: 0
304     nsize: {{1 2}separate output}
305     args: -i ${wPETSC_DIR}/share/petsc/datafiles/meshes/blockcylinder-50.exo -interpolate
306     requires: exodusii
307 
308 TEST*/
309