xref: /petsc/src/dm/dt/tests/ex5.c (revision 5f80ce2ab25dff0f4601e710601cbbcecf323266)
1c4762a1bSJed Brown static char help[] = "Tests affine subspaces.\n\n";
2c4762a1bSJed Brown 
3c4762a1bSJed Brown #include <petscfe.h>
4c4762a1bSJed Brown #include <petscdmplex.h>
5c4762a1bSJed Brown #include <petscdmshell.h>
6c4762a1bSJed Brown 
7c4762a1bSJed Brown int main(int argc, char **argv)
8c4762a1bSJed Brown {
9c4762a1bSJed Brown   DM             dm;
10c4762a1bSJed Brown   PetscFE        fe;
11c4762a1bSJed Brown   PetscSpace     space;
12c4762a1bSJed Brown   PetscDualSpace dualspace, dualsubspace;
13c4762a1bSJed Brown   PetscInt       dim = 2, Nc = 3, cStart, cEnd;
14c4762a1bSJed Brown   PetscBool      simplex = PETSC_TRUE;
15c4762a1bSJed Brown   MPI_Comm       comm;
16c4762a1bSJed Brown   PetscErrorCode ierr;
17c4762a1bSJed Brown 
18c4762a1bSJed Brown   ierr = PetscInitialize(&argc,&argv,NULL,help);if (ierr) return ierr;
19c4762a1bSJed Brown   comm = PETSC_COMM_WORLD;
20c4762a1bSJed Brown   ierr = PetscOptionsBegin(comm,"","Options for subspace test","none");CHKERRQ(ierr);
21*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsRangeInt("-dim", "The spatial dimension","ex5.c",dim,&dim,NULL,1,3));
22*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsBool("-simplex", "Test simplex element","ex5.c",simplex,&simplex,NULL));
23*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsBoundedInt("-num_comp", "Number of components in space","ex5.c",Nc,&Nc,NULL,1));
241e1ea65dSPierre Jolivet   ierr = PetscOptionsEnd();CHKERRQ(ierr);
25*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMShellCreate(comm,&dm));
26*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFECreateDefault(comm,dim,Nc,simplex,NULL,PETSC_DEFAULT,&fe));
27*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMDestroy(&dm));
28*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFESetName(fe, "solution"));
29*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFEGetBasisSpace(fe,&space));
30*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSpaceGetNumComponents(space,&Nc));
31*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFEGetDualSpace(fe,&dualspace));
32*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscDualSpaceGetHeightSubspace(dualspace,1,&dualsubspace));
33*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscDualSpaceGetDM(dualspace,&dm));
34*5f80ce2aSJacob Faibussowitsch   CHKERRQ(DMPlexGetHeightStratum(dm,0,&cStart,&cEnd));
35c4762a1bSJed Brown   if (cEnd > cStart) {
36c4762a1bSJed Brown     PetscInt coneSize;
37c4762a1bSJed Brown 
38*5f80ce2aSJacob Faibussowitsch     CHKERRQ(DMPlexGetConeSize(dm,cStart,&coneSize));
39c4762a1bSJed Brown     if (coneSize) {
40c4762a1bSJed Brown       PetscFE traceFE;
41c4762a1bSJed Brown       const PetscInt *cone;
42c4762a1bSJed Brown       PetscInt        point, nSub, nFull;
43c4762a1bSJed Brown       PetscReal       xi0[3] = {-1., -1., -1.};
44c4762a1bSJed Brown       PetscScalar     *outSub, *outFull;
45c4762a1bSJed Brown       PetscReal       *testSub, *testFull;
46c4762a1bSJed Brown       PetscTabulation Tsub, Tfull;
47c4762a1bSJed Brown       PetscReal       J[9], detJ;
48c4762a1bSJed Brown       PetscInt        i, j;
49c4762a1bSJed Brown       PetscSection    sectionFull;
50c4762a1bSJed Brown       Vec             vecFull;
51c4762a1bSJed Brown       PetscScalar     *arrayFull, *arraySub;
52c4762a1bSJed Brown       PetscReal       err;
53c4762a1bSJed Brown       PetscRandom     rand;
54c4762a1bSJed Brown 
55*5f80ce2aSJacob Faibussowitsch       CHKERRQ(DMPlexGetCone(dm,cStart,&cone));
56c4762a1bSJed Brown       point = cone[0];
57*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscFECreatePointTrace(fe,point,&traceFE));
58*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscFESetUp(traceFE));
59*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscFEViewFromOptions(traceFE,NULL,"-trace_fe_view"));
60*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscMalloc4(dim - 1,&testSub,dim,&testFull,Nc,&outSub,Nc,&outFull));
61*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscRandomCreate(PETSC_COMM_SELF,&rand));
62*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscRandomSetFromOptions(rand));
63*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscRandomSetInterval(rand,-1.,1.));
64c4762a1bSJed Brown       /* create a random point in the trace domain */
65c4762a1bSJed Brown       for (i = 0; i < dim - 1; i++) {
66*5f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscRandomGetValueReal(rand,&testSub[i]));
67c4762a1bSJed Brown       }
68*5f80ce2aSJacob Faibussowitsch       CHKERRQ(DMPlexComputeCellGeometryFEM(dm,point,NULL,testFull,J,NULL,&detJ));
69c4762a1bSJed Brown       /* project it into the full domain */
70c4762a1bSJed Brown       for (i = 0; i < dim; i++) {
71c4762a1bSJed Brown         for (j = 0; j < dim - 1; j++) testFull[i] += J[i * dim + j] * (testSub[j] - xi0[j]);
72c4762a1bSJed Brown       }
73c4762a1bSJed Brown       /* create a random vector in the full domain */
74*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscFEGetDimension(fe,&nFull));
75*5f80ce2aSJacob Faibussowitsch       CHKERRQ(VecCreateSeq(PETSC_COMM_SELF,nFull,&vecFull));
76*5f80ce2aSJacob Faibussowitsch       CHKERRQ(VecGetArray(vecFull,&arrayFull));
77c4762a1bSJed Brown       for (i = 0; i < nFull; i++) {
78*5f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscRandomGetValue(rand,&arrayFull[i]));
79c4762a1bSJed Brown       }
80*5f80ce2aSJacob Faibussowitsch       CHKERRQ(VecRestoreArray(vecFull,&arrayFull));
81c4762a1bSJed Brown       /* create a vector on the trace domain */
82*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscFEGetDimension(traceFE,&nSub));
83c4762a1bSJed Brown       /* get the subset of the original finite element space that is supported on the trace space */
84*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscDualSpaceGetSection(dualspace,&sectionFull));
85*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscSectionSetUp(sectionFull));
86c4762a1bSJed Brown       /* get the trace degrees of freedom */
87*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscMalloc1(nSub,&arraySub));
88*5f80ce2aSJacob Faibussowitsch       CHKERRQ(DMPlexVecGetClosure(dm,sectionFull,vecFull,point,&nSub,&arraySub));
89c4762a1bSJed Brown       /* get the tabulations */
90*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscFECreateTabulation(traceFE,1,1,testSub,0,&Tsub));
91*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscFECreateTabulation(fe,1,1,testFull,0,&Tfull));
92c4762a1bSJed Brown       for (i = 0; i < Nc; i++) {
93c4762a1bSJed Brown         outSub[i] = 0.0;
94c4762a1bSJed Brown         for (j = 0; j < nSub; j++) {
95c4762a1bSJed Brown           outSub[i] += Tsub->T[0][j * Nc + i] * arraySub[j];
96c4762a1bSJed Brown         }
97c4762a1bSJed Brown       }
98*5f80ce2aSJacob Faibussowitsch       CHKERRQ(VecGetArray(vecFull,&arrayFull));
99c4762a1bSJed Brown       err = 0.0;
100c4762a1bSJed Brown       for (i = 0; i < Nc; i++) {
101c4762a1bSJed Brown         PetscScalar diff;
102c4762a1bSJed Brown 
103c4762a1bSJed Brown         outFull[i] = 0.0;
104c4762a1bSJed Brown         for (j = 0; j < nFull; j++) {
105c4762a1bSJed Brown           outFull[i] += Tfull->T[0][j * Nc + i] * arrayFull[j];
106c4762a1bSJed Brown         }
107c4762a1bSJed Brown         diff = outFull[i] - outSub[i];
108c4762a1bSJed Brown         err += PetscRealPart(PetscConj(diff) * diff);
109c4762a1bSJed Brown       }
110c4762a1bSJed Brown       err = PetscSqrtReal(err);
111c4762a1bSJed Brown       if (err > PETSC_SMALL) {
11298921bdaSJacob Faibussowitsch         SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Trace FE error %g",err);
113c4762a1bSJed Brown       }
114*5f80ce2aSJacob Faibussowitsch       CHKERRQ(VecRestoreArray(vecFull,&arrayFull));
115*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscTabulationDestroy(&Tfull));
116*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscTabulationDestroy(&Tsub));
117c4762a1bSJed Brown       /* clean up */
118*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscFree(arraySub));
119*5f80ce2aSJacob Faibussowitsch       CHKERRQ(VecDestroy(&vecFull));
120*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscRandomDestroy(&rand));
121*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscFree4(testSub,testFull,outSub,outFull));
122*5f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscFEDestroy(&traceFE));
123c4762a1bSJed Brown     }
124c4762a1bSJed Brown   }
125*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFEDestroy(&fe));
126c4762a1bSJed Brown   ierr = PetscFinalize();
127c4762a1bSJed Brown   return ierr;
128c4762a1bSJed Brown }
129c4762a1bSJed Brown 
130c4762a1bSJed Brown /*TEST
131c4762a1bSJed Brown   test:
132c4762a1bSJed Brown     suffix: 0
133c4762a1bSJed Brown     args: -petscspace_degree 1 -trace_fe_view
134c4762a1bSJed Brown TEST*/
135