xref: /petsc/src/dm/impls/plex/tests/ex46.c (revision 84ff8c8b54fd7c9cb88641c01dfe6357ec5f72d0)
1 static char help[] = "Tests 1D nested mesh refinement.\n\n";
2 
3 #include <petscdmplex.h>
4 #include <petscds.h>
5 
6 typedef struct {
7   PetscInt             Nr;       /* Number of refinements */
8   PetscSimplePointFunc funcs[1]; /* Functions to test */
9 } AppCtx;
10 
11 static PetscErrorCode constant(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
12 {
13   u[0] = 1.;
14   return 0;
15 }
16 
17 static PetscErrorCode linear(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
18 {
19   u[0] = 2.*x[0] + 1.;
20   return 0;
21 }
22 
23 static PetscErrorCode quadratic(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
24 {
25   u[0] = 3.*x[0]*x[0] + 2.*x[0] + 1.;
26   return 0;
27 }
28 
29 static PetscErrorCode cubic(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
30 {
31   u[0] = 4.*x[0]*x[0]*x[0] + 3.*x[0]*x[0] + 2.*x[0] + 1.;
32   return 0;
33 }
34 
35 static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options)
36 {
37   PetscErrorCode ierr;
38 
39   PetscFunctionBeginUser;
40   options->Nr = 1;
41   ierr = PetscOptionsBegin(comm, "", "1D Refinement Options", "DMPLEX");CHKERRQ(ierr);
42   ierr = PetscOptionsInt("-num_refine", "Refine cycles", "ex46.c", options->Nr, &options->Nr, NULL);CHKERRQ(ierr);
43   ierr = PetscOptionsEnd();CHKERRQ(ierr);
44   PetscFunctionReturn(0);
45 }
46 
47 static PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm)
48 {
49   PetscErrorCode ierr;
50 
51   PetscFunctionBeginUser;
52   ierr = DMCreate(comm, dm);CHKERRQ(ierr);
53   ierr = DMSetType(*dm, DMPLEX);CHKERRQ(ierr);
54   ierr = DMSetFromOptions(*dm);CHKERRQ(ierr);
55   ierr = DMSetApplicationContext(*dm, user);CHKERRQ(ierr);
56   ierr = DMViewFromOptions(*dm, NULL, "-dm_view");CHKERRQ(ierr);
57   PetscFunctionReturn(0);
58 }
59 
60 static PetscErrorCode SetupDiscretization(DM dm, AppCtx *user)
61 {
62   DM             cdm = dm;
63   PetscFE        fe;
64   PetscSpace     sp;
65   PetscInt       dim, deg;
66   PetscErrorCode ierr;
67 
68   PetscFunctionBeginUser;
69   ierr = DMGetDimension(dm, &dim);CHKERRQ(ierr);
70   ierr = PetscFECreateDefault(PETSC_COMM_SELF, dim, 1, PETSC_FALSE, NULL, -1, &fe);CHKERRQ(ierr);
71   ierr = PetscObjectSetName((PetscObject) fe, "scalar");CHKERRQ(ierr);
72   ierr = DMSetField(dm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr);
73   ierr = DMCreateDS(dm);CHKERRQ(ierr);
74   while (cdm) {
75     ierr = DMCopyDisc(dm,cdm);CHKERRQ(ierr);
76     ierr = DMGetCoarseDM(cdm, &cdm);CHKERRQ(ierr);
77   }
78   ierr = PetscFEGetBasisSpace(fe, &sp);CHKERRQ(ierr);
79   ierr = PetscSpaceGetDegree(sp, &deg, NULL);CHKERRQ(ierr);
80   switch (deg) {
81   case 0: user->funcs[0] = constant;break;
82   case 1: user->funcs[0] = linear;break;
83   case 2: user->funcs[0] = quadratic;break;
84   case 3: user->funcs[0] = cubic;break;
85   default: SETERRQ1(PetscObjectComm((PetscObject) dm), PETSC_ERR_ARG_OUTOFRANGE, "Could not determine function to test for degree %D", deg);
86   }
87   ierr = PetscFEDestroy(&fe);CHKERRQ(ierr);
88   PetscFunctionReturn(0);
89 }
90 
91 static PetscErrorCode CheckError(DM dm, Vec u, PetscSimplePointFunc funcs[])
92 {
93   PetscReal      error, tol = PETSC_SMALL;
94   MPI_Comm       comm;
95   PetscErrorCode ierr;
96 
97   PetscFunctionBeginUser;
98   ierr = DMComputeL2Diff(dm, 0.0, funcs, NULL, u, &error);CHKERRQ(ierr);
99   ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr);
100   if (error > tol) {ierr = PetscPrintf(comm, "Function tests FAIL at tolerance %g error %g\n", (double)tol,(double) error);CHKERRQ(ierr);}
101   else             {ierr = PetscPrintf(comm, "Function tests pass at tolerance %g\n", (double)tol);CHKERRQ(ierr);}
102   PetscFunctionReturn(0);
103 }
104 
105 int main(int argc, char **argv)
106 {
107   DM             dm;
108   Vec            u;
109   AppCtx         user;
110   PetscInt       cStart, cEnd, c, r;
111   PetscErrorCode ierr;
112 
113   ierr = PetscInitialize(&argc, &argv, NULL, help);if (ierr) return ierr;
114   ierr = ProcessOptions(PETSC_COMM_WORLD, &user);CHKERRQ(ierr);
115   ierr = CreateMesh(PETSC_COMM_WORLD, &user, &dm);CHKERRQ(ierr);
116   ierr = SetupDiscretization(dm, &user);CHKERRQ(ierr);
117   ierr = DMGetGlobalVector(dm, &u);CHKERRQ(ierr);
118   ierr = DMProjectFunction(dm, 0.0, user.funcs, NULL, INSERT_ALL_VALUES, u);CHKERRQ(ierr);
119   ierr = CheckError(dm, u, user.funcs);CHKERRQ(ierr);
120   for (r = 0; r < user.Nr; ++r) {
121     DM      adm;
122     DMLabel adapt;
123     Vec     au;
124     Mat     Interp;
125 
126     ierr = DMLabelCreate(PETSC_COMM_SELF, "adapt", &adapt);CHKERRQ(ierr);
127     ierr = DMLabelSetDefaultValue(adapt, DM_ADAPT_COARSEN);CHKERRQ(ierr);
128     ierr = DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd);CHKERRQ(ierr);
129     for (c = cStart; c < cEnd; ++c) {
130       if (c % 2) {ierr = DMLabelSetValue(adapt, c, DM_ADAPT_REFINE);CHKERRQ(ierr);}
131     }
132     ierr = DMAdaptLabel(dm, adapt, &adm);CHKERRQ(ierr);
133     ierr = DMLabelDestroy(&adapt);CHKERRQ(ierr);
134     ierr = PetscObjectSetName((PetscObject) adm, "Adapted Mesh");CHKERRQ(ierr);
135     ierr = DMViewFromOptions(adm, NULL, "-dm_view");CHKERRQ(ierr);
136 
137     ierr = DMCreateInterpolation(dm, adm, &Interp, NULL);CHKERRQ(ierr);
138     ierr = DMGetGlobalVector(adm, &au);CHKERRQ(ierr);
139     ierr = MatInterpolate(Interp, u, au);CHKERRQ(ierr);
140     ierr = CheckError(adm, au, user.funcs);CHKERRQ(ierr);
141     ierr = MatDestroy(&Interp);CHKERRQ(ierr);
142     ierr = DMRestoreGlobalVector(dm, &u);CHKERRQ(ierr);
143     ierr = DMDestroy(&dm);CHKERRQ(ierr);
144     dm   = adm;
145     u    = au;
146   }
147   ierr = DMRestoreGlobalVector(dm, &u);CHKERRQ(ierr);
148   ierr = DMDestroy(&dm);CHKERRQ(ierr);
149   ierr = PetscFinalize();
150   return ierr;
151 }
152 
153 /*TEST
154 
155   test:
156     suffix: 0
157     args: -num_refine 4 -petscspace_degree 3 \
158           -dm_plex_dim 1 -dm_plex_box_faces 5 -dm_plex_transform_type refine_1d -dm_plex_hash_location -dm_view
159 
160 TEST*/
161