xref: /petsc/src/dm/dt/tests/ex10.c (revision 9371c9d470a9602b6d10a8bf50c9b2280a79e45a)
1*9371c9d4SSatish Balay static char help[] = "Tests implementation of PetscSpace_Sum by solving the Poisson equations using a PetscSpace_Poly and a PetscSpace_Sum and checking that \
2d092c84bSBrandon Whitchurch   solutions agree up to machine precision.\n\n";
3d092c84bSBrandon Whitchurch 
4d092c84bSBrandon Whitchurch #include <petscdmplex.h>
5d092c84bSBrandon Whitchurch #include <petscds.h>
6d092c84bSBrandon Whitchurch #include <petscfe.h>
7d092c84bSBrandon Whitchurch #include <petscsnes.h>
8d092c84bSBrandon Whitchurch /* We are solving the system of equations:
9d092c84bSBrandon Whitchurch  * \vec{u} = -\grad{p}
10d092c84bSBrandon Whitchurch  * \div{u} = f
11d092c84bSBrandon Whitchurch  */
12d092c84bSBrandon Whitchurch 
13d092c84bSBrandon Whitchurch /* Exact solutions for linear velocity
14d092c84bSBrandon Whitchurch    \vec{u} = \vec{x};
15d092c84bSBrandon Whitchurch    p = -0.5*(\vec{x} \cdot \vec{x});
16d092c84bSBrandon Whitchurch    */
17*9371c9d4SSatish Balay static PetscErrorCode linear_u(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
18d092c84bSBrandon Whitchurch   PetscInt c;
19d092c84bSBrandon Whitchurch 
20d092c84bSBrandon Whitchurch   for (c = 0; c < Nc; ++c) u[c] = x[c];
21d092c84bSBrandon Whitchurch   return 0;
22d092c84bSBrandon Whitchurch }
23d092c84bSBrandon Whitchurch 
24*9371c9d4SSatish Balay static PetscErrorCode linear_p(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
25d092c84bSBrandon Whitchurch   PetscInt d;
26d092c84bSBrandon Whitchurch 
27d092c84bSBrandon Whitchurch   u[0] = 0.;
28d092c84bSBrandon Whitchurch   for (d = 0; d < dim; ++d) u[0] += -0.5 * x[d] * x[d];
29d092c84bSBrandon Whitchurch   return 0;
30d092c84bSBrandon Whitchurch }
31d092c84bSBrandon Whitchurch 
32*9371c9d4SSatish Balay static PetscErrorCode linear_divu(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) {
33d092c84bSBrandon Whitchurch   u[0] = dim;
34d092c84bSBrandon Whitchurch   return 0;
35d092c84bSBrandon Whitchurch }
36d092c84bSBrandon Whitchurch 
37d092c84bSBrandon Whitchurch /* fx_v are the residual functions for the equation \vec{u} = \grad{p}. f0_v is the term <v,u>.*/
38*9371c9d4SSatish Balay static void f0_v(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) {
39d092c84bSBrandon Whitchurch   PetscInt i;
40d092c84bSBrandon Whitchurch 
41d092c84bSBrandon Whitchurch   for (i = 0; i < dim; ++i) f0[i] = u[uOff[0] + i];
42d092c84bSBrandon Whitchurch }
43d092c84bSBrandon Whitchurch 
44d092c84bSBrandon Whitchurch /* f1_v is the term <v,-\grad{p}> but we integrate by parts to get <\grad{v}, -p*I> */
45*9371c9d4SSatish Balay static void f1_v(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f1[]) {
46d092c84bSBrandon Whitchurch   PetscInt c;
47d092c84bSBrandon Whitchurch 
48d092c84bSBrandon Whitchurch   for (c = 0; c < dim; ++c) {
49d092c84bSBrandon Whitchurch     PetscInt d;
50d092c84bSBrandon Whitchurch 
51d092c84bSBrandon Whitchurch     for (d = 0; d < dim; ++d) f1[c * dim + d] = (c == d) ? -u[uOff[1]] : 0;
52d092c84bSBrandon Whitchurch   }
53d092c84bSBrandon Whitchurch }
54d092c84bSBrandon Whitchurch 
55d092c84bSBrandon Whitchurch /* Residual function for enforcing \div{u} = f. */
56*9371c9d4SSatish Balay static void f0_q_linear(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) {
57d092c84bSBrandon Whitchurch   PetscScalar rhs, divu = 0;
58d092c84bSBrandon Whitchurch   PetscInt    i;
59d092c84bSBrandon Whitchurch 
602da392ccSBarry Smith   (void)linear_divu(dim, t, x, dim, &rhs, NULL);
61d092c84bSBrandon Whitchurch   for (i = 0; i < dim; ++i) divu += u_x[uOff_x[0] + i * dim + i];
62d092c84bSBrandon Whitchurch   f0[0] = divu - rhs;
63d092c84bSBrandon Whitchurch }
64d092c84bSBrandon Whitchurch 
65d092c84bSBrandon Whitchurch /* Boundary residual. Dirichlet boundary for u means u_bdy=p*n */
66*9371c9d4SSatish Balay static void f0_bd_u_linear(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, const PetscReal x[], const PetscReal n[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) {
67d092c84bSBrandon Whitchurch   PetscScalar pressure;
68d092c84bSBrandon Whitchurch   PetscInt    d;
69d092c84bSBrandon Whitchurch 
70d092c84bSBrandon Whitchurch   (void)linear_p(dim, t, x, dim, &pressure, NULL);
71d092c84bSBrandon Whitchurch   for (d = 0; d < dim; ++d) f0[d] = pressure * n[d];
72d092c84bSBrandon Whitchurch }
73d092c84bSBrandon Whitchurch 
74d092c84bSBrandon Whitchurch /* gx_yz are the jacobian functions obtained by taking the derivative of the y residual w.r.t z*/
75*9371c9d4SSatish Balay static void g0_vu(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) {
76d092c84bSBrandon Whitchurch   PetscInt c;
77d092c84bSBrandon Whitchurch 
78d092c84bSBrandon Whitchurch   for (c = 0; c < dim; ++c) g0[c * dim + c] = 1.0;
79d092c84bSBrandon Whitchurch }
80d092c84bSBrandon Whitchurch 
81*9371c9d4SSatish Balay static void g1_qu(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g1[]) {
82d092c84bSBrandon Whitchurch   PetscInt c;
83d092c84bSBrandon Whitchurch 
84d092c84bSBrandon Whitchurch   for (c = 0; c < dim; ++c) g1[c * dim + c] = 1.0;
85d092c84bSBrandon Whitchurch }
86d092c84bSBrandon Whitchurch 
87*9371c9d4SSatish Balay static void g2_vp(PetscInt dim, PetscInt Nf, PetscInt NfAux, const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g2[]) {
88d092c84bSBrandon Whitchurch   PetscInt c;
89d092c84bSBrandon Whitchurch 
90d092c84bSBrandon Whitchurch   for (c = 0; c < dim; ++c) g2[c * dim + c] = -1.0;
91d092c84bSBrandon Whitchurch }
92d092c84bSBrandon Whitchurch 
93*9371c9d4SSatish Balay typedef struct {
9430602db0SMatthew G. Knepley   PetscInt dummy;
95d092c84bSBrandon Whitchurch } UserCtx;
96d092c84bSBrandon Whitchurch 
97*9371c9d4SSatish Balay static PetscErrorCode CreateMesh(MPI_Comm comm, UserCtx *user, DM *mesh) {
98d092c84bSBrandon Whitchurch   PetscFunctionBegin;
999566063dSJacob Faibussowitsch   PetscCall(DMCreate(comm, mesh));
1009566063dSJacob Faibussowitsch   PetscCall(DMSetType(*mesh, DMPLEX));
1019566063dSJacob Faibussowitsch   PetscCall(DMSetFromOptions(*mesh));
1029566063dSJacob Faibussowitsch   PetscCall(DMSetApplicationContext(*mesh, user));
1039566063dSJacob Faibussowitsch   PetscCall(DMViewFromOptions(*mesh, NULL, "-dm_view"));
104d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
105d092c84bSBrandon Whitchurch }
106d092c84bSBrandon Whitchurch 
107d092c84bSBrandon Whitchurch /* Setup the system of equations that we wish to solve */
108*9371c9d4SSatish Balay static PetscErrorCode SetupProblem(DM dm, UserCtx *user) {
10945480ffeSMatthew G. Knepley   PetscDS        ds;
11045480ffeSMatthew G. Knepley   DMLabel        label;
11145480ffeSMatthew G. Knepley   PetscWeakForm  wf;
112d092c84bSBrandon Whitchurch   const PetscInt id = 1;
11345480ffeSMatthew G. Knepley   PetscInt       bd;
114d092c84bSBrandon Whitchurch 
115d092c84bSBrandon Whitchurch   PetscFunctionBegin;
1169566063dSJacob Faibussowitsch   PetscCall(DMGetDS(dm, &ds));
117d092c84bSBrandon Whitchurch   /* All of these are independent of the user's choice of solution */
1189566063dSJacob Faibussowitsch   PetscCall(PetscDSSetResidual(ds, 0, f0_v, f1_v));
1199566063dSJacob Faibussowitsch   PetscCall(PetscDSSetResidual(ds, 1, f0_q_linear, NULL));
1209566063dSJacob Faibussowitsch   PetscCall(PetscDSSetJacobian(ds, 0, 0, g0_vu, NULL, NULL, NULL));
1219566063dSJacob Faibussowitsch   PetscCall(PetscDSSetJacobian(ds, 0, 1, NULL, NULL, g2_vp, NULL));
1229566063dSJacob Faibussowitsch   PetscCall(PetscDSSetJacobian(ds, 1, 0, NULL, g1_qu, NULL, NULL));
123d092c84bSBrandon Whitchurch 
1249566063dSJacob Faibussowitsch   PetscCall(DMGetLabel(dm, "marker", &label));
1259566063dSJacob Faibussowitsch   PetscCall(PetscDSAddBoundary(ds, DM_BC_NATURAL, "Boundary Integral", label, 1, &id, 0, 0, NULL, (void (*)(void))NULL, NULL, user, &bd));
1269566063dSJacob Faibussowitsch   PetscCall(PetscDSGetBoundary(ds, bd, &wf, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL));
1279566063dSJacob Faibussowitsch   PetscCall(PetscWeakFormSetIndexBdResidual(wf, label, 1, 0, 0, 0, f0_bd_u_linear, 0, NULL));
12845480ffeSMatthew G. Knepley 
1299566063dSJacob Faibussowitsch   PetscCall(PetscDSSetExactSolution(ds, 0, linear_u, NULL));
1308fb5bd83SMatthew G. Knepley   PetscCall(PetscDSSetExactSolution(ds, 1, linear_p, NULL));
131d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
132d092c84bSBrandon Whitchurch }
133d092c84bSBrandon Whitchurch 
134d092c84bSBrandon Whitchurch /* Create the finite element spaces we will use for this system */
135*9371c9d4SSatish Balay static PetscErrorCode SetupDiscretization(DM mesh, DM mesh_sum, PetscErrorCode (*setup)(DM, UserCtx *), UserCtx *user) {
136d092c84bSBrandon Whitchurch   DM        cdm = mesh, cdm_sum = mesh_sum;
137d092c84bSBrandon Whitchurch   PetscFE   u, divu, u_sum, divu_sum;
13830602db0SMatthew G. Knepley   PetscInt  dim;
13930602db0SMatthew G. Knepley   PetscBool simplex;
140d092c84bSBrandon Whitchurch 
141d092c84bSBrandon Whitchurch   PetscFunctionBegin;
1429566063dSJacob Faibussowitsch   PetscCall(DMGetDimension(mesh, &dim));
1439566063dSJacob Faibussowitsch   PetscCall(DMPlexIsSimplex(mesh, &simplex));
144d092c84bSBrandon Whitchurch   /* Create FE objects and give them names so that options can be set from
145d092c84bSBrandon Whitchurch    * command line. Each field gets 2 instances (i.e. velocity and velocity_sum)created twice so that we can compare between approaches. */
1469566063dSJacob Faibussowitsch   PetscCall(PetscFECreateDefault(PetscObjectComm((PetscObject)mesh), dim, dim, simplex, "velocity_", -1, &u));
1479566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetName((PetscObject)u, "velocity"));
1489566063dSJacob Faibussowitsch   PetscCall(PetscFECreateDefault(PetscObjectComm((PetscObject)mesh_sum), dim, dim, simplex, "velocity_sum_", -1, &u_sum));
1499566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetName((PetscObject)u_sum, "velocity_sum"));
1509566063dSJacob Faibussowitsch   PetscCall(PetscFECreateDefault(PetscObjectComm((PetscObject)mesh), dim, 1, simplex, "divu_", -1, &divu));
1519566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetName((PetscObject)divu, "divu"));
1529566063dSJacob Faibussowitsch   PetscCall(PetscFECreateDefault(PetscObjectComm((PetscObject)mesh_sum), dim, 1, simplex, "divu_sum_", -1, &divu_sum));
1539566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetName((PetscObject)divu_sum, "divu_sum"));
154d092c84bSBrandon Whitchurch 
1559566063dSJacob Faibussowitsch   PetscCall(PetscFECopyQuadrature(u, divu));
1569566063dSJacob Faibussowitsch   PetscCall(PetscFECopyQuadrature(u_sum, divu_sum));
157d092c84bSBrandon Whitchurch 
158d092c84bSBrandon Whitchurch   /* Associate the FE objects with the mesh and setup the system */
1599566063dSJacob Faibussowitsch   PetscCall(DMSetField(mesh, 0, NULL, (PetscObject)u));
1609566063dSJacob Faibussowitsch   PetscCall(DMSetField(mesh, 1, NULL, (PetscObject)divu));
1619566063dSJacob Faibussowitsch   PetscCall(DMCreateDS(mesh));
1629566063dSJacob Faibussowitsch   PetscCall((*setup)(mesh, user));
163d092c84bSBrandon Whitchurch 
1649566063dSJacob Faibussowitsch   PetscCall(DMSetField(mesh_sum, 0, NULL, (PetscObject)u_sum));
1659566063dSJacob Faibussowitsch   PetscCall(DMSetField(mesh_sum, 1, NULL, (PetscObject)divu_sum));
1669566063dSJacob Faibussowitsch   PetscCall(DMCreateDS(mesh_sum));
1679566063dSJacob Faibussowitsch   PetscCall((*setup)(mesh_sum, user));
168d092c84bSBrandon Whitchurch 
169d092c84bSBrandon Whitchurch   while (cdm) {
1709566063dSJacob Faibussowitsch     PetscCall(DMCopyDisc(mesh, cdm));
1719566063dSJacob Faibussowitsch     PetscCall(DMGetCoarseDM(cdm, &cdm));
172d092c84bSBrandon Whitchurch   }
173d092c84bSBrandon Whitchurch 
174d092c84bSBrandon Whitchurch   while (cdm_sum) {
1759566063dSJacob Faibussowitsch     PetscCall(DMCopyDisc(mesh_sum, cdm_sum));
1769566063dSJacob Faibussowitsch     PetscCall(DMGetCoarseDM(cdm_sum, &cdm_sum));
177d092c84bSBrandon Whitchurch   }
178d092c84bSBrandon Whitchurch 
179d092c84bSBrandon Whitchurch   /* The Mesh now owns the fields, so we can destroy the FEs created in this
180d092c84bSBrandon Whitchurch    * function */
1819566063dSJacob Faibussowitsch   PetscCall(PetscFEDestroy(&u));
1829566063dSJacob Faibussowitsch   PetscCall(PetscFEDestroy(&divu));
1839566063dSJacob Faibussowitsch   PetscCall(PetscFEDestroy(&u_sum));
1849566063dSJacob Faibussowitsch   PetscCall(PetscFEDestroy(&divu_sum));
1859566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&cdm));
1869566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&cdm_sum));
187d092c84bSBrandon Whitchurch   PetscFunctionReturn(0);
188d092c84bSBrandon Whitchurch }
189d092c84bSBrandon Whitchurch 
190*9371c9d4SSatish Balay int main(int argc, char **argv) {
191d092c84bSBrandon Whitchurch   UserCtx         user;
192d092c84bSBrandon Whitchurch   DM              dm, dm_sum;
193d092c84bSBrandon Whitchurch   SNES            snes, snes_sum;
194d092c84bSBrandon Whitchurch   Vec             u, u_sum;
195d092c84bSBrandon Whitchurch   PetscReal       errNorm;
196d092c84bSBrandon Whitchurch   const PetscReal errTol = PETSC_SMALL;
197d092c84bSBrandon Whitchurch 
198327415f7SBarry Smith   PetscFunctionBeginUser;
1999566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &argv, (char *)0, help));
200d092c84bSBrandon Whitchurch 
201d092c84bSBrandon Whitchurch   /* Set up a snes for the standard approach, one space with 2 components */
2029566063dSJacob Faibussowitsch   PetscCall(SNESCreate(PETSC_COMM_WORLD, &snes));
2039566063dSJacob Faibussowitsch   PetscCall(CreateMesh(PETSC_COMM_WORLD, &user, &dm));
2049566063dSJacob Faibussowitsch   PetscCall(SNESSetDM(snes, dm));
205d092c84bSBrandon Whitchurch 
206d092c84bSBrandon Whitchurch   /* Set up a snes for the sum space approach, where each subspace of the sum space represents one component */
2079566063dSJacob Faibussowitsch   PetscCall(SNESCreate(PETSC_COMM_WORLD, &snes_sum));
2089566063dSJacob Faibussowitsch   PetscCall(CreateMesh(PETSC_COMM_WORLD, &user, &dm_sum));
2099566063dSJacob Faibussowitsch   PetscCall(SNESSetDM(snes_sum, dm_sum));
2109566063dSJacob Faibussowitsch   PetscCall(SetupDiscretization(dm, dm_sum, SetupProblem, &user));
211d092c84bSBrandon Whitchurch 
212d092c84bSBrandon Whitchurch   /* Set up and solve the system using standard approach. */
2139566063dSJacob Faibussowitsch   PetscCall(DMCreateGlobalVector(dm, &u));
2149566063dSJacob Faibussowitsch   PetscCall(VecSet(u, 0.0));
2159566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetName((PetscObject)u, "solution"));
2169566063dSJacob Faibussowitsch   PetscCall(DMPlexSetSNESLocalFEM(dm, &user, &user, &user));
2179566063dSJacob Faibussowitsch   PetscCall(SNESSetFromOptions(snes));
2189566063dSJacob Faibussowitsch   PetscCall(DMSNESCheckFromOptions(snes, u));
2199566063dSJacob Faibussowitsch   PetscCall(SNESSolve(snes, NULL, u));
2209566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &u));
2219566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(u, NULL, "-solution_view"));
222d092c84bSBrandon Whitchurch 
223d092c84bSBrandon Whitchurch   /* Set up and solve the sum space system */
2249566063dSJacob Faibussowitsch   PetscCall(DMCreateGlobalVector(dm_sum, &u_sum));
2259566063dSJacob Faibussowitsch   PetscCall(VecSet(u_sum, 0.0));
2269566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetName((PetscObject)u_sum, "solution_sum"));
2279566063dSJacob Faibussowitsch   PetscCall(DMPlexSetSNESLocalFEM(dm_sum, &user, &user, &user));
2289566063dSJacob Faibussowitsch   PetscCall(SNESSetFromOptions(snes_sum));
2299566063dSJacob Faibussowitsch   PetscCall(DMSNESCheckFromOptions(snes_sum, u_sum));
2309566063dSJacob Faibussowitsch   PetscCall(SNESSolve(snes_sum, NULL, u_sum));
2319566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes_sum, &u_sum));
2329566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(u_sum, NULL, "-solution_sum_view"));
233d092c84bSBrandon Whitchurch 
234d092c84bSBrandon Whitchurch   /* Check if standard solution and sum space solution match to machine precision */
2359566063dSJacob Faibussowitsch   PetscCall(VecAXPY(u_sum, -1, u));
2369566063dSJacob Faibussowitsch   PetscCall(VecNorm(u_sum, NORM_2, &errNorm));
237d0609cedSBarry Smith   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Sum space provides the same solution as a regular space: %s", (errNorm < errTol) ? "true" : "false"));
238d092c84bSBrandon Whitchurch 
239d092c84bSBrandon Whitchurch   /* Cleanup */
2409566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&u_sum));
2419566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&u));
2429566063dSJacob Faibussowitsch   PetscCall(SNESDestroy(&snes_sum));
2439566063dSJacob Faibussowitsch   PetscCall(SNESDestroy(&snes));
2449566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&dm_sum));
2459566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&dm));
2469566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
247b122ec5aSJacob Faibussowitsch   return 0;
248d092c84bSBrandon Whitchurch }
249d092c84bSBrandon Whitchurch 
250d092c84bSBrandon Whitchurch /*TEST
251d092c84bSBrandon Whitchurch   test:
252d092c84bSBrandon Whitchurch     suffix: 2d_lagrange
253d092c84bSBrandon Whitchurch     requires: triangle
25430602db0SMatthew G. Knepley     args: -velocity_petscspace_degree 1 \
255d092c84bSBrandon Whitchurch       -velocity_petscspace_type poly \
256d092c84bSBrandon Whitchurch       -velocity_petscspace_components 2\
257d092c84bSBrandon Whitchurch       -velocity_petscdualspace_type lagrange \
258d092c84bSBrandon Whitchurch       -divu_petscspace_degree 0 \
259d092c84bSBrandon Whitchurch       -divu_petscspace_type poly \
260d092c84bSBrandon Whitchurch       -divu_petscdualspace_lagrange_continuity false \
261d092c84bSBrandon Whitchurch       -velocity_sum_petscfe_default_quadrature_order 1 \
262d092c84bSBrandon Whitchurch       -velocity_sum_petscspace_degree 1 \
263d092c84bSBrandon Whitchurch       -velocity_sum_petscspace_type sum \
264d092c84bSBrandon Whitchurch       -velocity_sum_petscspace_variables 2 \
265d092c84bSBrandon Whitchurch       -velocity_sum_petscspace_components 2 \
266d092c84bSBrandon Whitchurch       -velocity_sum_petscspace_sum_spaces 2 \
267d092c84bSBrandon Whitchurch       -velocity_sum_petscspace_sum_concatenate true \
268d092c84bSBrandon Whitchurch       -velocity_sum_petscdualspace_type lagrange \
269417c287bSToby Isaac       -velocity_sum_sumcomp_0_petscspace_type poly \
270417c287bSToby Isaac       -velocity_sum_sumcomp_0_petscspace_degree 1 \
271417c287bSToby Isaac       -velocity_sum_sumcomp_0_petscspace_variables 2 \
272417c287bSToby Isaac       -velocity_sum_sumcomp_0_petscspace_components 1 \
273417c287bSToby Isaac       -velocity_sum_sumcomp_1_petscspace_type poly \
274417c287bSToby Isaac       -velocity_sum_sumcomp_1_petscspace_degree 1 \
275417c287bSToby Isaac       -velocity_sum_sumcomp_1_petscspace_variables 2 \
276417c287bSToby Isaac       -velocity_sum_sumcomp_1_petscspace_components 1 \
277d092c84bSBrandon Whitchurch       -divu_sum_petscspace_degree 0 \
278d092c84bSBrandon Whitchurch       -divu_sum_petscspace_type sum \
279d092c84bSBrandon Whitchurch       -divu_sum_petscspace_variables 2 \
280d092c84bSBrandon Whitchurch       -divu_sum_petscspace_components 1 \
281d092c84bSBrandon Whitchurch       -divu_sum_petscspace_sum_spaces 1 \
282d092c84bSBrandon Whitchurch       -divu_sum_petscspace_sum_concatenate true \
283d092c84bSBrandon Whitchurch       -divu_sum_petscdualspace_lagrange_continuity false \
284417c287bSToby Isaac       -divu_sum_sumcomp_0_petscspace_type poly \
285417c287bSToby Isaac       -divu_sum_sumcomp_0_petscspace_degree 0 \
286417c287bSToby Isaac       -divu_sum_sumcomp_0_petscspace_variables 2 \
287417c287bSToby Isaac       -divu_sum_sumcomp_0_petscspace_components 1 \
288d092c84bSBrandon Whitchurch       -dm_refine 0 \
289d092c84bSBrandon Whitchurch       -snes_error_if_not_converged \
290d092c84bSBrandon Whitchurch       -ksp_rtol 1e-10 \
291d092c84bSBrandon Whitchurch       -ksp_error_if_not_converged \
292d092c84bSBrandon Whitchurch       -pc_type fieldsplit\
293d092c84bSBrandon Whitchurch       -pc_fieldsplit_type schur\
294d092c84bSBrandon Whitchurch       -divu_sum_petscdualspace_lagrange_continuity false \
295d092c84bSBrandon Whitchurch       -pc_fieldsplit_schur_precondition full
296d092c84bSBrandon Whitchurch TEST*/
297