xref: /petsc/src/dm/impls/plex/tests/ex101.c (revision 53b735f80d8abba57081ee21f195942af5a4ca31)
1*53b735f8SJames Wright static char help[] = "Verify isoperiodic cone corrections";
2*53b735f8SJames Wright 
3*53b735f8SJames Wright #include <petscdmplex.h>
4*53b735f8SJames Wright 
5*53b735f8SJames Wright // Creates periodic solution on a [0,1] x D domain for D dimension
6*53b735f8SJames Wright static PetscErrorCode project_function(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx)
7*53b735f8SJames Wright {
8*53b735f8SJames Wright   PetscReal x_tot = 0;
9*53b735f8SJames Wright 
10*53b735f8SJames Wright   PetscFunctionBeginUser;
11*53b735f8SJames Wright   for (PetscInt d = 0; d < dim; d++) x_tot += x[d];
12*53b735f8SJames Wright   for (PetscInt c = 0; c < Nc; c++) {
13*53b735f8SJames Wright     PetscScalar value = PetscSinReal(2 * M_PI * x_tot);
14*53b735f8SJames Wright     if (PetscAbsScalar(value) < 1e-7) value = 0.;
15*53b735f8SJames Wright     u[c] = value;
16*53b735f8SJames Wright   }
17*53b735f8SJames Wright   PetscFunctionReturn(PETSC_SUCCESS);
18*53b735f8SJames Wright }
19*53b735f8SJames Wright 
20*53b735f8SJames Wright PetscErrorCode CreateFEField(DM dm)
21*53b735f8SJames Wright {
22*53b735f8SJames Wright   PetscInt degree;
23*53b735f8SJames Wright 
24*53b735f8SJames Wright   PetscFunctionBeginUser;
25*53b735f8SJames Wright   { // Get degree of the coords section
26*53b735f8SJames Wright     PetscFE    fe_coords;
27*53b735f8SJames Wright     PetscSpace coord_space;
28*53b735f8SJames Wright     DM         cdm;
29*53b735f8SJames Wright 
30*53b735f8SJames Wright     PetscCall(DMGetCoordinateDM(dm, &cdm));
31*53b735f8SJames Wright     PetscCall(DMGetField(cdm, 0, NULL, (PetscObject *)&fe_coords));
32*53b735f8SJames Wright     PetscCall(PetscFEGetBasisSpace(fe_coords, &coord_space));
33*53b735f8SJames Wright     PetscCall(PetscSpaceGetDegree(coord_space, &degree, NULL));
34*53b735f8SJames Wright   }
35*53b735f8SJames Wright 
36*53b735f8SJames Wright   PetscCall(DMClearFields(dm));
37*53b735f8SJames Wright   PetscCall(DMSetLocalSection(dm, NULL)); // See https://gitlab.com/petsc/petsc/-/issues/1669
38*53b735f8SJames Wright 
39*53b735f8SJames Wright   { // Setup fe to load in the initial condition data
40*53b735f8SJames Wright     PetscFE  fe;
41*53b735f8SJames Wright     PetscInt dim;
42*53b735f8SJames Wright 
43*53b735f8SJames Wright     PetscCall(DMGetDimension(dm, &dim));
44*53b735f8SJames Wright     PetscCall(PetscFECreateLagrange(PETSC_COMM_SELF, dim, 1, PETSC_FALSE, degree, PETSC_DETERMINE, &fe));
45*53b735f8SJames Wright     PetscCall(DMAddField(dm, NULL, (PetscObject)fe));
46*53b735f8SJames Wright     PetscCall(DMCreateDS(dm));
47*53b735f8SJames Wright     PetscCall(PetscFEDestroy(&fe));
48*53b735f8SJames Wright   }
49*53b735f8SJames Wright   PetscFunctionReturn(PETSC_SUCCESS);
50*53b735f8SJames Wright }
51*53b735f8SJames Wright 
52*53b735f8SJames Wright int main(int argc, char **argv)
53*53b735f8SJames Wright {
54*53b735f8SJames Wright   MPI_Comm  comm;
55*53b735f8SJames Wright   DM        dm = NULL;
56*53b735f8SJames Wright   Vec       V, V_G2L, V_local;
57*53b735f8SJames Wright   PetscReal norm;
58*53b735f8SJames Wright   PetscErrorCode (*funcs)(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) = {project_function};
59*53b735f8SJames Wright 
60*53b735f8SJames Wright   PetscFunctionBeginUser;
61*53b735f8SJames Wright   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
62*53b735f8SJames Wright   comm = PETSC_COMM_WORLD;
63*53b735f8SJames Wright 
64*53b735f8SJames Wright   PetscCall(DMCreate(comm, &dm));
65*53b735f8SJames Wright   PetscCall(DMSetType(dm, DMPLEX));
66*53b735f8SJames Wright   PetscCall(PetscObjectSetName((PetscObject)dm, "ex101_dm"));
67*53b735f8SJames Wright   PetscCall(DMSetFromOptions(dm));
68*53b735f8SJames Wright   PetscCall(DMViewFromOptions(dm, NULL, "-dm_view"));
69*53b735f8SJames Wright   PetscCall(CreateFEField(dm));
70*53b735f8SJames Wright 
71*53b735f8SJames Wright   // Verify that projected function on global vector (then projected onto local vector) is equal to projected function onto a local vector
72*53b735f8SJames Wright   PetscCall(DMGetLocalVector(dm, &V_G2L));
73*53b735f8SJames Wright   PetscCall(DMGetGlobalVector(dm, &V));
74*53b735f8SJames Wright   PetscCall(DMProjectFunction(dm, 0, &funcs, NULL, INSERT_VALUES, V));
75*53b735f8SJames Wright   PetscCall(DMGlobalToLocal(dm, V, INSERT_VALUES, V_G2L));
76*53b735f8SJames Wright 
77*53b735f8SJames Wright   PetscCall(DMGetLocalVector(dm, &V_local));
78*53b735f8SJames Wright   PetscCall(DMProjectFunctionLocal(dm, 0, &funcs, NULL, INSERT_VALUES, V_local));
79*53b735f8SJames Wright 
80*53b735f8SJames Wright   PetscCall(VecAXPY(V_local, -1, V_G2L));
81*53b735f8SJames Wright   PetscCall(VecNorm(V_local, NORM_2, &norm));
82*53b735f8SJames Wright   PetscReal tol = PetscDefined(USE_REAL___FLOAT128) ? 1e-12 : 1e4 * PETSC_MACHINE_EPSILON;
83*53b735f8SJames Wright   PetscCheck(norm < tol, PETSC_COMM_SELF, PETSC_ERR_PLIB, "GlobalToLocal result does not match Local projection by norm %g", (double)norm);
84*53b735f8SJames Wright 
85*53b735f8SJames Wright   PetscCall(DMRestoreGlobalVector(dm, &V));
86*53b735f8SJames Wright   PetscCall(DMRestoreLocalVector(dm, &V_G2L));
87*53b735f8SJames Wright   PetscCall(DMRestoreLocalVector(dm, &V_local));
88*53b735f8SJames Wright   PetscCall(DMDestroy(&dm));
89*53b735f8SJames Wright 
90*53b735f8SJames Wright   PetscCall(PetscFinalize());
91*53b735f8SJames Wright   return 0;
92*53b735f8SJames Wright }
93*53b735f8SJames Wright 
94*53b735f8SJames Wright /*TEST
95*53b735f8SJames Wright 
96*53b735f8SJames Wright   test:
97*53b735f8SJames Wright     nsize: 2
98*53b735f8SJames Wright     args: -dm_plex_shape zbox -dm_plex_simplex 0 -dm_plex_dim 3 -dm_plex_box_faces 1,2,3 -dm_coord_space -dm_coord_petscspace_degree 3
99*53b735f8SJames Wright     args: -dm_plex_box_bd periodic,periodic,periodic -dm_view ::ascii_info_detail -petscpartitioner_type simple
100*53b735f8SJames Wright 
101*53b735f8SJames Wright   test:
102*53b735f8SJames Wright     requires: cgns
103*53b735f8SJames Wright     suffix: cgns
104*53b735f8SJames Wright     nsize: 3
105*53b735f8SJames Wright     args: -dm_plex_filename ${wPETSC_DIR}/share/petsc/datafiles/meshes/2x2x2_Q3_wave.cgns -dm_plex_cgns_parallel -dm_view ::ascii_info_detail -dm_plex_box_label true -dm_plex_box_label_bd periodic,periodic,periodic -petscpartitioner_type simple
106*53b735f8SJames Wright 
107*53b735f8SJames Wright TEST*/
108