1d21efd2eSMatthew G. Knepley static const char help[] = "Tests for determining whether a new finite element works"; 2d21efd2eSMatthew G. Knepley 3d21efd2eSMatthew G. Knepley /* 4d21efd2eSMatthew G. Knepley Use -interpolation_view and -l2_projection_view to look at the interpolants. 5d21efd2eSMatthew G. Knepley */ 6d21efd2eSMatthew G. Knepley 7d21efd2eSMatthew G. Knepley #include <petscdmplex.h> 8d21efd2eSMatthew G. Knepley #include <petscfe.h> 9d21efd2eSMatthew G. Knepley #include <petscds.h> 10d21efd2eSMatthew G. Knepley #include <petscsnes.h> 11d21efd2eSMatthew G. Knepley 12d21efd2eSMatthew G. Knepley static void constant(PetscInt dim, PetscInt Nf, PetscInt NfAux, 13d21efd2eSMatthew G. Knepley const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 14d21efd2eSMatthew G. Knepley const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 15d21efd2eSMatthew G. Knepley PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 16d21efd2eSMatthew G. Knepley { 17d21efd2eSMatthew G. Knepley const PetscInt Nc = uOff[1] - uOff[0]; 18d21efd2eSMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) f0[c] += 5.; 19d21efd2eSMatthew G. Knepley } 20d21efd2eSMatthew G. Knepley 21d21efd2eSMatthew G. Knepley static void linear(PetscInt dim, PetscInt Nf, PetscInt NfAux, 22d21efd2eSMatthew G. Knepley const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 23d21efd2eSMatthew G. Knepley const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 24d21efd2eSMatthew G. Knepley PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 25d21efd2eSMatthew G. Knepley { 26d21efd2eSMatthew G. Knepley const PetscInt Nc = uOff[1] - uOff[0]; 27d21efd2eSMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) f0[c] += 5.*x[c]; 28d21efd2eSMatthew G. Knepley } 29d21efd2eSMatthew G. Knepley 30d21efd2eSMatthew G. Knepley static void quadratic(PetscInt dim, PetscInt Nf, PetscInt NfAux, 31d21efd2eSMatthew G. Knepley const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 32d21efd2eSMatthew G. Knepley const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 33d21efd2eSMatthew G. Knepley PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 34d21efd2eSMatthew G. Knepley { 35d21efd2eSMatthew G. Knepley const PetscInt Nc = uOff[1] - uOff[0]; 36d21efd2eSMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) f0[c] += 5.*x[c]*x[c]; 37d21efd2eSMatthew G. Knepley } 38d21efd2eSMatthew G. Knepley 39d21efd2eSMatthew G. Knepley static void trig(PetscInt dim, PetscInt Nf, PetscInt NfAux, 40d21efd2eSMatthew G. Knepley const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 41d21efd2eSMatthew G. Knepley const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 42d21efd2eSMatthew G. Knepley PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 43d21efd2eSMatthew G. Knepley { 44d21efd2eSMatthew G. Knepley const PetscInt Nc = uOff[1] - uOff[0]; 45d21efd2eSMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) f0[c] += PetscCosReal(2.*PETSC_PI*x[c]); 46d21efd2eSMatthew G. Knepley } 47d21efd2eSMatthew G. Knepley 48*e239af90SMatthew G. Knepley /* 49*e239af90SMatthew G. Knepley The prime basis for the Wheeler-Yotov-Xue prism. 50*e239af90SMatthew G. Knepley */ 51*e239af90SMatthew G. Knepley static void prime(PetscInt dim, PetscInt Nf, PetscInt NfAux, 52*e239af90SMatthew G. Knepley const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 53*e239af90SMatthew G. Knepley const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 54*e239af90SMatthew G. Knepley PetscReal t, const PetscReal X[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 55*e239af90SMatthew G. Knepley { 56*e239af90SMatthew G. Knepley PetscReal x = X[0], y = X[1], z = X[2], b = 1 + x + y + z; 57*e239af90SMatthew G. Knepley f0[0] += b + 2.0*x*z + 2.0*y*z + x*y + x*x; 58*e239af90SMatthew G. Knepley f0[1] += b + 2.0*x*z + 2.0*y*z + x*y + y*y; 59*e239af90SMatthew G. Knepley f0[2] += b - 3.0*x*z - 3.0*y*z - 2.0*z*z; 60*e239af90SMatthew G. Knepley } 61*e239af90SMatthew G. Knepley 62*e239af90SMatthew G. Knepley static const char *names[] = {"constant", "linear", "quadratic", "trig", "prime"}; 63*e239af90SMatthew G. Knepley static PetscPointFunc functions[] = { constant, linear, quadratic, trig, prime }; 64d21efd2eSMatthew G. Knepley 65d21efd2eSMatthew G. Knepley typedef struct { 66d21efd2eSMatthew G. Knepley PetscPointFunc exactSol; 67*e239af90SMatthew G. Knepley PetscReal shear,flatten; 68d21efd2eSMatthew G. Knepley } AppCtx; 69d21efd2eSMatthew G. Knepley 70d21efd2eSMatthew G. Knepley static PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 71d21efd2eSMatthew G. Knepley { 72d21efd2eSMatthew G. Knepley char name[PETSC_MAX_PATH_LEN] = "constant"; 73d21efd2eSMatthew G. Knepley PetscInt Nfunc = sizeof(names)/sizeof(char *), i; 74d21efd2eSMatthew G. Knepley PetscErrorCode ierr; 75d21efd2eSMatthew G. Knepley 76d21efd2eSMatthew G. Knepley PetscFunctionBeginUser; 77d21efd2eSMatthew G. Knepley options->exactSol = NULL; 78*e239af90SMatthew G. Knepley options->shear = 0.; 79*e239af90SMatthew G. Knepley options->flatten = 1.; 80d21efd2eSMatthew G. Knepley 81d21efd2eSMatthew G. Knepley ierr = PetscOptionsBegin(comm, "", "FE Test Options", "PETSCFE");CHKERRQ(ierr); 82d21efd2eSMatthew G. Knepley ierr = PetscOptionsString("-func", "Function to project into space", "", name, name, PETSC_MAX_PATH_LEN, NULL);CHKERRQ(ierr); 83*e239af90SMatthew G. Knepley ierr = PetscOptionsReal("-shear", "Factor by which to shear along the x-direction", "", options->shear, &(options->shear), NULL);CHKERRQ(ierr); 84*e239af90SMatthew G. Knepley ierr = PetscOptionsReal("-flatten", "Factor by which to flatten", "", options->flatten, &(options->flatten), NULL);CHKERRQ(ierr); 85d21efd2eSMatthew G. Knepley ierr = PetscOptionsEnd();CHKERRQ(ierr); 86d21efd2eSMatthew G. Knepley 87d21efd2eSMatthew G. Knepley for (i = 0; i < Nfunc; ++i) { 88d21efd2eSMatthew G. Knepley PetscBool flg; 89d21efd2eSMatthew G. Knepley 90d21efd2eSMatthew G. Knepley ierr = PetscStrcmp(name, names[i], &flg);CHKERRQ(ierr); 91d21efd2eSMatthew G. Knepley if (flg) {options->exactSol = functions[i]; break;} 92d21efd2eSMatthew G. Knepley } 93*e239af90SMatthew G. Knepley PetscCheck(options->exactSol, comm, PETSC_ERR_ARG_WRONG, "Invalid test function %s", name); 94d21efd2eSMatthew G. Knepley PetscFunctionReturn(0); 95d21efd2eSMatthew G. Knepley } 96d21efd2eSMatthew G. Knepley 97d21efd2eSMatthew G. Knepley /* The exact solution is the negative of the f0 contribution */ 98d21efd2eSMatthew G. Knepley static PetscErrorCode exactSolution(PetscInt dim, PetscReal time, const PetscReal x[], PetscInt Nc, PetscScalar *u, void *ctx) 99d21efd2eSMatthew G. Knepley { 100d21efd2eSMatthew G. Knepley AppCtx *user = (AppCtx *) ctx; 101*e239af90SMatthew G. Knepley PetscInt uOff[2] = {0, Nc}; 102d21efd2eSMatthew G. Knepley 103d21efd2eSMatthew G. Knepley user->exactSol(dim, 1, 0, uOff, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, time, x, 0, NULL, u); 104d21efd2eSMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) u[c] *= -1.; 105d21efd2eSMatthew G. Knepley return 0; 106d21efd2eSMatthew G. Knepley } 107d21efd2eSMatthew G. Knepley 108d21efd2eSMatthew G. Knepley static void f0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 109d21efd2eSMatthew G. Knepley const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 110d21efd2eSMatthew G. Knepley const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 111d21efd2eSMatthew G. Knepley PetscReal t, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar f0[]) 112d21efd2eSMatthew G. Knepley { 113d21efd2eSMatthew G. Knepley const PetscInt Nc = uOff[1] - uOff[0]; 114d21efd2eSMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) f0[c] += u[c]; 115d21efd2eSMatthew G. Knepley } 116d21efd2eSMatthew G. Knepley 117d21efd2eSMatthew G. Knepley static void g0(PetscInt dim, PetscInt Nf, PetscInt NfAux, 118d21efd2eSMatthew G. Knepley const PetscInt uOff[], const PetscInt uOff_x[], const PetscScalar u[], const PetscScalar u_t[], const PetscScalar u_x[], 119d21efd2eSMatthew G. Knepley const PetscInt aOff[], const PetscInt aOff_x[], const PetscScalar a[], const PetscScalar a_t[], const PetscScalar a_x[], 120d21efd2eSMatthew G. Knepley PetscReal t, PetscReal u_tShift, const PetscReal x[], PetscInt numConstants, const PetscScalar constants[], PetscScalar g0[]) 121d21efd2eSMatthew G. Knepley { 122d21efd2eSMatthew G. Knepley const PetscInt Nc = uOff[1] - uOff[0]; 123d21efd2eSMatthew G. Knepley for (PetscInt c = 0; c < Nc; ++c) g0[c*Nc+c] = 1.0; 124d21efd2eSMatthew G. Knepley } 125d21efd2eSMatthew G. Knepley 126d21efd2eSMatthew G. Knepley static PetscErrorCode SetupProblem(DM dm, AppCtx *user) 127d21efd2eSMatthew G. Knepley { 128d21efd2eSMatthew G. Knepley PetscDS ds; 129d21efd2eSMatthew G. Knepley PetscWeakForm wf; 130d21efd2eSMatthew G. Knepley PetscErrorCode ierr; 131d21efd2eSMatthew G. Knepley 132d21efd2eSMatthew G. Knepley PetscFunctionBeginUser; 133d21efd2eSMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 134d21efd2eSMatthew G. Knepley ierr = PetscDSGetWeakForm(ds, &wf);CHKERRQ(ierr); 135d21efd2eSMatthew G. Knepley ierr = PetscWeakFormSetIndexResidual(wf, NULL, 0, 0, 0, 0, f0, 0, NULL);CHKERRQ(ierr); 136d21efd2eSMatthew G. Knepley ierr = PetscWeakFormSetIndexResidual(wf, NULL, 0, 0, 0, 1, user->exactSol, 0, NULL);CHKERRQ(ierr); 137d21efd2eSMatthew G. Knepley ierr = PetscWeakFormSetIndexJacobian(wf, NULL, 0, 0, 0, 0, 0, g0, 0, NULL, 0, NULL, 0, NULL);CHKERRQ(ierr); 138d21efd2eSMatthew G. Knepley ierr = PetscDSSetExactSolution(ds, 0, exactSolution, user);CHKERRQ(ierr); 139d21efd2eSMatthew G. Knepley PetscFunctionReturn(0); 140d21efd2eSMatthew G. Knepley } 141d21efd2eSMatthew G. Knepley 142d21efd2eSMatthew G. Knepley static PetscErrorCode SetupDiscretization(DM dm, const char name[], AppCtx *user) 143d21efd2eSMatthew G. Knepley { 144d21efd2eSMatthew G. Knepley DM cdm = dm; 145d21efd2eSMatthew G. Knepley PetscFE fe; 146d21efd2eSMatthew G. Knepley char prefix[PETSC_MAX_PATH_LEN]; 147d21efd2eSMatthew G. Knepley PetscErrorCode ierr; 148d21efd2eSMatthew G. Knepley 149d21efd2eSMatthew G. Knepley PetscFunctionBeginUser; 150d21efd2eSMatthew G. Knepley ierr = PetscSNPrintf(prefix, PETSC_MAX_PATH_LEN, "%s_", name);CHKERRQ(ierr); 151d21efd2eSMatthew G. Knepley ierr = DMCreateFEDefault(dm, 1, name ? prefix : NULL, -1, &fe);CHKERRQ(ierr); 152d21efd2eSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) fe, name ? name : "Solution");CHKERRQ(ierr); 153d21efd2eSMatthew G. Knepley /* Set discretization and boundary conditions for each mesh */ 154d21efd2eSMatthew G. Knepley ierr = DMSetField(dm, 0, NULL, (PetscObject) fe);CHKERRQ(ierr); 155d21efd2eSMatthew G. Knepley ierr = DMCreateDS(dm);CHKERRQ(ierr); 156d21efd2eSMatthew G. Knepley ierr = SetupProblem(dm, user);CHKERRQ(ierr); 157d21efd2eSMatthew G. Knepley while (cdm) { 158d21efd2eSMatthew G. Knepley ierr = DMCopyDisc(dm, cdm);CHKERRQ(ierr); 159d21efd2eSMatthew G. Knepley ierr = DMGetCoarseDM(cdm, &cdm);CHKERRQ(ierr); 160d21efd2eSMatthew G. Knepley } 161d21efd2eSMatthew G. Knepley ierr = PetscFEDestroy(&fe);CHKERRQ(ierr); 162d21efd2eSMatthew G. Knepley PetscFunctionReturn(0); 163d21efd2eSMatthew G. Knepley } 164d21efd2eSMatthew G. Knepley 165d21efd2eSMatthew G. Knepley /* This test tells us whether the given function is contained in the approximation space */ 166d21efd2eSMatthew G. Knepley static PetscErrorCode CheckInterpolation(DM dm, AppCtx *user) 167d21efd2eSMatthew G. Knepley { 168d21efd2eSMatthew G. Knepley PetscSimplePointFunc exactSol[1]; 169d21efd2eSMatthew G. Knepley void *exactCtx[1]; 170d21efd2eSMatthew G. Knepley PetscDS ds; 171d21efd2eSMatthew G. Knepley Vec u; 172d21efd2eSMatthew G. Knepley PetscReal error, tol = PETSC_SMALL; 173d21efd2eSMatthew G. Knepley MPI_Comm comm; 174d21efd2eSMatthew G. Knepley PetscErrorCode ierr; 175d21efd2eSMatthew G. Knepley 176d21efd2eSMatthew G. Knepley PetscFunctionBeginUser; 177d21efd2eSMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 178d21efd2eSMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 179d21efd2eSMatthew G. Knepley ierr = DMGetGlobalVector(dm, &u);CHKERRQ(ierr); 180d21efd2eSMatthew G. Knepley ierr = PetscDSGetExactSolution(ds, 0, &exactSol[0], &exactCtx[0]);CHKERRQ(ierr); 181d21efd2eSMatthew G. Knepley ierr = DMProjectFunction(dm, 0.0, exactSol, exactCtx, INSERT_ALL_VALUES, u);CHKERRQ(ierr); 182d21efd2eSMatthew G. Knepley ierr = VecViewFromOptions(u, NULL, "-interpolation_view");CHKERRQ(ierr); 183d21efd2eSMatthew G. Knepley ierr = DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error);CHKERRQ(ierr); 184d21efd2eSMatthew G. Knepley ierr = DMRestoreGlobalVector(dm, &u);CHKERRQ(ierr); 185d21efd2eSMatthew G. Knepley if (error > tol) {ierr = PetscPrintf(comm, "Interpolation tests FAIL at tolerance %g error %g\n", (double) tol, (double) error);CHKERRQ(ierr);} 186d21efd2eSMatthew G. Knepley else {ierr = PetscPrintf(comm, "Interpolation tests pass at tolerance %g\n", (double) tol);CHKERRQ(ierr);} 187d21efd2eSMatthew G. Knepley PetscFunctionReturn(0); 188d21efd2eSMatthew G. Knepley } 189d21efd2eSMatthew G. Knepley 190d21efd2eSMatthew G. Knepley /* This test tells us whether the element is unisolvent (the mass matrix has full rank), and what rate of convergence we achieve */ 191d21efd2eSMatthew G. Knepley static PetscErrorCode CheckL2Projection(DM dm, AppCtx *user) 192d21efd2eSMatthew G. Knepley { 193d21efd2eSMatthew G. Knepley PetscSimplePointFunc exactSol[1]; 194d21efd2eSMatthew G. Knepley void *exactCtx[1]; 195d21efd2eSMatthew G. Knepley SNES snes; 196d21efd2eSMatthew G. Knepley PetscDS ds; 197d21efd2eSMatthew G. Knepley Vec u; 198d21efd2eSMatthew G. Knepley PetscReal error, tol = PETSC_SMALL; 199d21efd2eSMatthew G. Knepley MPI_Comm comm; 200d21efd2eSMatthew G. Knepley PetscErrorCode ierr; 201d21efd2eSMatthew G. Knepley 202d21efd2eSMatthew G. Knepley PetscFunctionBeginUser; 203d21efd2eSMatthew G. Knepley ierr = PetscObjectGetComm((PetscObject) dm, &comm);CHKERRQ(ierr); 204d21efd2eSMatthew G. Knepley ierr = DMGetDS(dm, &ds);CHKERRQ(ierr); 205d21efd2eSMatthew G. Knepley ierr = DMGetGlobalVector(dm, &u);CHKERRQ(ierr); 206d21efd2eSMatthew G. Knepley ierr = PetscDSGetExactSolution(ds, 0, &exactSol[0], &exactCtx[0]);CHKERRQ(ierr); 207d21efd2eSMatthew G. Knepley ierr = SNESCreate(comm, &snes);CHKERRQ(ierr); 208d21efd2eSMatthew G. Knepley ierr = SNESSetDM(snes, dm);CHKERRQ(ierr); 209d21efd2eSMatthew G. Knepley ierr = VecSet(u, 0.0);CHKERRQ(ierr); 210d21efd2eSMatthew G. Knepley ierr = PetscObjectSetName((PetscObject) u, "solution");CHKERRQ(ierr); 211d21efd2eSMatthew G. Knepley ierr = DMPlexSetSNESLocalFEM(dm, user, user, user);CHKERRQ(ierr); 212d21efd2eSMatthew G. Knepley ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); 213d21efd2eSMatthew G. Knepley ierr = DMSNESCheckFromOptions(snes, u);CHKERRQ(ierr); 214d21efd2eSMatthew G. Knepley ierr = SNESSolve(snes, NULL, u);CHKERRQ(ierr); 215d21efd2eSMatthew G. Knepley ierr = SNESDestroy(&snes);CHKERRQ(ierr); 216d21efd2eSMatthew G. Knepley ierr = VecViewFromOptions(u, NULL, "-l2_projection_view");CHKERRQ(ierr); 217d21efd2eSMatthew G. Knepley ierr = DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error);CHKERRQ(ierr); 218d21efd2eSMatthew G. Knepley ierr = DMRestoreGlobalVector(dm, &u);CHKERRQ(ierr); 219d21efd2eSMatthew G. Knepley if (error > tol) {ierr = PetscPrintf(comm, "L2 projection tests FAIL at tolerance %g error %g\n", (double) tol, (double) error);CHKERRQ(ierr);} 220d21efd2eSMatthew G. Knepley else {ierr = PetscPrintf(comm, "L2 projection tests pass at tolerance %g\n", (double) tol);CHKERRQ(ierr);} 221d21efd2eSMatthew G. Knepley PetscFunctionReturn(0); 222d21efd2eSMatthew G. Knepley } 223d21efd2eSMatthew G. Knepley 224*e239af90SMatthew G. Knepley /* Distorts the mesh by shearing in the x-direction and flattening, factors provided in the options. */ 225*e239af90SMatthew G. Knepley static PetscErrorCode DistortMesh(DM dm, AppCtx *user) 226*e239af90SMatthew G. Knepley { 227*e239af90SMatthew G. Knepley Vec coordinates; 228*e239af90SMatthew G. Knepley PetscScalar *ca; 229*e239af90SMatthew G. Knepley PetscInt dE, n, i; 230*e239af90SMatthew G. Knepley PetscErrorCode ierr; 231*e239af90SMatthew G. Knepley 232*e239af90SMatthew G. Knepley PetscFunctionBeginUser; 233*e239af90SMatthew G. Knepley ierr = DMGetCoordinateDim(dm, &dE);CHKERRQ(ierr); 234*e239af90SMatthew G. Knepley ierr = DMGetCoordinates(dm, &coordinates);CHKERRQ(ierr); 235*e239af90SMatthew G. Knepley ierr = VecGetLocalSize(coordinates, &n);CHKERRQ(ierr); 236*e239af90SMatthew G. Knepley ierr = VecGetArray(coordinates, &ca);CHKERRQ(ierr); 237*e239af90SMatthew G. Knepley for (i = 0; i < (n/dE); ++i) { 238*e239af90SMatthew G. Knepley ca[i*dE+0] += user->shear*ca[i*dE+0]; 239*e239af90SMatthew G. Knepley ca[i*dE+1] *= user->flatten; 240*e239af90SMatthew G. Knepley } 241*e239af90SMatthew G. Knepley ierr = VecRestoreArray(coordinates, &ca);CHKERRQ(ierr); 242*e239af90SMatthew G. Knepley PetscFunctionReturn(0); 243*e239af90SMatthew G. Knepley } 244*e239af90SMatthew G. Knepley 245d21efd2eSMatthew G. Knepley int main(int argc, char **argv) 246d21efd2eSMatthew G. Knepley { 247d21efd2eSMatthew G. Knepley DM dm; 248d21efd2eSMatthew G. Knepley AppCtx user; 249d21efd2eSMatthew G. Knepley PetscMPIInt size; 250d21efd2eSMatthew G. Knepley PetscErrorCode ierr; 251d21efd2eSMatthew G. Knepley 252d21efd2eSMatthew G. Knepley ierr = PetscInitialize(&argc, &argv, NULL, help); if (ierr) return ierr; 253d21efd2eSMatthew G. Knepley ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size);CHKERRMPI(ierr); 254*e239af90SMatthew G. Knepley PetscCheck(size == 1, PETSC_COMM_WORLD, PETSC_ERR_SUP, "This is a uniprocessor example only."); 255d21efd2eSMatthew G. Knepley ierr = ProcessOptions(PETSC_COMM_WORLD, &user);CHKERRQ(ierr); 256d21efd2eSMatthew G. Knepley ierr = DMCreate(PETSC_COMM_WORLD, &dm);CHKERRQ(ierr); 257d21efd2eSMatthew G. Knepley ierr = DMSetType(dm, DMPLEX);CHKERRQ(ierr); 258d21efd2eSMatthew G. Knepley ierr = DMSetFromOptions(dm);CHKERRQ(ierr); 259*e239af90SMatthew G. Knepley ierr = DistortMesh(dm,&user);CHKERRQ(ierr); 260*e239af90SMatthew G. Knepley ierr = DMViewFromOptions(dm, NULL, "-dm_view");CHKERRQ(ierr); 261d21efd2eSMatthew G. Knepley ierr = SetupDiscretization(dm, NULL, &user);CHKERRQ(ierr); 262d21efd2eSMatthew G. Knepley 263d21efd2eSMatthew G. Knepley ierr = CheckInterpolation(dm, &user);CHKERRQ(ierr); 264d21efd2eSMatthew G. Knepley ierr = CheckL2Projection(dm, &user);CHKERRQ(ierr); 265d21efd2eSMatthew G. Knepley 266d21efd2eSMatthew G. Knepley ierr = DMDestroy(&dm);CHKERRQ(ierr); 267d21efd2eSMatthew G. Knepley ierr = PetscFinalize(); 268d21efd2eSMatthew G. Knepley return ierr; 269d21efd2eSMatthew G. Knepley } 270d21efd2eSMatthew G. Knepley 271d21efd2eSMatthew G. Knepley /*TEST 272d21efd2eSMatthew G. Knepley 273d21efd2eSMatthew G. Knepley testset: 274d21efd2eSMatthew G. Knepley args: -dm_plex_reference_cell_domain -dm_plex_cell triangle -petscspace_degree 1\ 275d21efd2eSMatthew G. Knepley -snes_error_if_not_converged -ksp_error_if_not_converged -pc_type lu 276d21efd2eSMatthew G. Knepley 277d21efd2eSMatthew G. Knepley test: 278d21efd2eSMatthew G. Knepley suffix: p1_0 279d21efd2eSMatthew G. Knepley args: -func {{constant linear}} 280d21efd2eSMatthew G. Knepley 281d21efd2eSMatthew G. Knepley # Using -dm_refine 2 -convest_num_refine 4 gives convergence rate 2.0 282d21efd2eSMatthew G. Knepley test: 283d21efd2eSMatthew G. Knepley suffix: p1_1 284d21efd2eSMatthew G. Knepley args: -func {{quadratic trig}} \ 285d21efd2eSMatthew G. Knepley -snes_convergence_estimate -convest_num_refine 2 286d21efd2eSMatthew G. Knepley 287d21efd2eSMatthew G. Knepley testset: 288*e239af90SMatthew G. Knepley requires: !complex double 289d21efd2eSMatthew G. Knepley args: -dm_plex_reference_cell_domain -dm_plex_cell triangular_prism \ 290d21efd2eSMatthew G. Knepley -petscspace_type sum \ 291d21efd2eSMatthew G. Knepley -petscspace_variables 3 \ 292d21efd2eSMatthew G. Knepley -petscspace_components 3 \ 293d21efd2eSMatthew G. Knepley -petscspace_sum_spaces 2 \ 294d21efd2eSMatthew G. Knepley -petscspace_sum_concatenate false \ 295d21efd2eSMatthew G. Knepley -sumcomp_0_petscspace_variables 3 \ 296d21efd2eSMatthew G. Knepley -sumcomp_0_petscspace_components 3 \ 297d21efd2eSMatthew G. Knepley -sumcomp_0_petscspace_degree 1 \ 298d21efd2eSMatthew G. Knepley -sumcomp_1_petscspace_variables 3 \ 299d21efd2eSMatthew G. Knepley -sumcomp_1_petscspace_components 3 \ 300d21efd2eSMatthew G. Knepley -sumcomp_1_petscspace_type wxy \ 301d21efd2eSMatthew G. Knepley -petscdualspace_form_degree 0 \ 302d21efd2eSMatthew G. Knepley -petscdualspace_order 1 \ 303d21efd2eSMatthew G. Knepley -petscdualspace_components 3 \ 304d21efd2eSMatthew G. Knepley -snes_error_if_not_converged -ksp_error_if_not_converged -pc_type lu 305d21efd2eSMatthew G. Knepley 306d21efd2eSMatthew G. Knepley test: 307d21efd2eSMatthew G. Knepley suffix: wxy_0 308d21efd2eSMatthew G. Knepley args: -func constant 309d21efd2eSMatthew G. Knepley 310d21efd2eSMatthew G. Knepley test: 311d21efd2eSMatthew G. Knepley suffix: wxy_1 312d21efd2eSMatthew G. Knepley args: -func linear 313d21efd2eSMatthew G. Knepley 314*e239af90SMatthew G. Knepley test: 315*e239af90SMatthew G. Knepley suffix: wxy_2 316*e239af90SMatthew G. Knepley args: -func prime 317*e239af90SMatthew G. Knepley 318*e239af90SMatthew G. Knepley test: 319*e239af90SMatthew G. Knepley suffix: wxy_3 320*e239af90SMatthew G. Knepley args: -func linear -shear 1 -flatten 1e-5 321*e239af90SMatthew G. Knepley 322d21efd2eSMatthew G. Knepley TEST*/ 323