17b197a28SMatthew G. Knepley static char help[] = "Fermions on a hypercubic lattice.\n\n"; 27b197a28SMatthew G. Knepley 37b197a28SMatthew G. Knepley #include <petscdmplex.h> 47b197a28SMatthew G. Knepley #include <petscsnes.h> 57b197a28SMatthew G. Knepley 67b197a28SMatthew G. Knepley /* Common operations: 77b197a28SMatthew G. Knepley 87b197a28SMatthew G. Knepley - View the input \psi as ASCII in lexicographic order: -psi_view 97b197a28SMatthew G. Knepley */ 107b197a28SMatthew G. Knepley 117b197a28SMatthew G. Knepley const PetscReal M = 1.0; 127b197a28SMatthew G. Knepley 137b197a28SMatthew G. Knepley typedef struct { 14*fc229b03SMatthew G. Knepley PetscBool printTr; // Print the traversal 15*fc229b03SMatthew G. Knepley PetscBool usePV; // Use Pauli-Villars preconditioning 167b197a28SMatthew G. Knepley } AppCtx; 177b197a28SMatthew G. Knepley 187b197a28SMatthew G. Knepley PetscErrorCode ProcessOptions(MPI_Comm comm, AppCtx *options) 197b197a28SMatthew G. Knepley { 207b197a28SMatthew G. Knepley PetscFunctionBegin; 21*fc229b03SMatthew G. Knepley options->printTr = PETSC_FALSE; 227b197a28SMatthew G. Knepley options->usePV = PETSC_TRUE; 237b197a28SMatthew G. Knepley 247b197a28SMatthew G. Knepley PetscOptionsBegin(comm, "", "Meshing Problem Options", "DMPLEX"); 25*fc229b03SMatthew G. Knepley PetscCall(PetscOptionsBool("-print_traversal", "Print the mesh traversal", "ex1.c", options->printTr, &options->printTr, NULL)); 267b197a28SMatthew G. Knepley PetscCall(PetscOptionsBool("-use_pv", "Use Pauli-Villars preconditioning", "ex1.c", options->usePV, &options->usePV, NULL)); 277b197a28SMatthew G. Knepley PetscOptionsEnd(); 283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 297b197a28SMatthew G. Knepley } 307b197a28SMatthew G. Knepley 317b197a28SMatthew G. Knepley PetscErrorCode CreateMesh(MPI_Comm comm, AppCtx *user, DM *dm) 327b197a28SMatthew G. Knepley { 337b197a28SMatthew G. Knepley PetscFunctionBegin; 347b197a28SMatthew G. Knepley PetscCall(DMCreate(comm, dm)); 357b197a28SMatthew G. Knepley PetscCall(DMSetType(*dm, DMPLEX)); 367b197a28SMatthew G. Knepley PetscCall(DMSetFromOptions(*dm)); 377b197a28SMatthew G. Knepley PetscCall(DMViewFromOptions(*dm, NULL, "-dm_view")); 383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 397b197a28SMatthew G. Knepley } 407b197a28SMatthew G. Knepley 417b197a28SMatthew G. Knepley static PetscErrorCode SetupDiscretization(DM dm, AppCtx *ctx) 427b197a28SMatthew G. Knepley { 437b197a28SMatthew G. Knepley PetscSection s; 447b197a28SMatthew G. Knepley PetscInt vStart, vEnd, v; 457b197a28SMatthew G. Knepley 467b197a28SMatthew G. Knepley PetscFunctionBegin; 477b197a28SMatthew G. Knepley PetscCall(PetscSectionCreate(PETSC_COMM_SELF, &s)); 487b197a28SMatthew G. Knepley PetscCall(DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd)); 497b197a28SMatthew G. Knepley PetscCall(PetscSectionSetChart(s, vStart, vEnd)); 507b197a28SMatthew G. Knepley for (v = vStart; v < vEnd; ++v) { 517b197a28SMatthew G. Knepley PetscCall(PetscSectionSetDof(s, v, 12)); 527b197a28SMatthew G. Knepley /* TODO Divide the values into fields/components */ 537b197a28SMatthew G. Knepley } 547b197a28SMatthew G. Knepley PetscCall(PetscSectionSetUp(s)); 557b197a28SMatthew G. Knepley PetscCall(DMSetLocalSection(dm, s)); 567b197a28SMatthew G. Knepley PetscCall(PetscSectionDestroy(&s)); 573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 587b197a28SMatthew G. Knepley } 597b197a28SMatthew G. Knepley 607b197a28SMatthew G. Knepley static PetscErrorCode SetupAuxDiscretization(DM dm, AppCtx *user) 617b197a28SMatthew G. Knepley { 627b197a28SMatthew G. Knepley DM dmAux, coordDM; 637b197a28SMatthew G. Knepley PetscSection s; 647b197a28SMatthew G. Knepley Vec gauge; 657b197a28SMatthew G. Knepley PetscInt eStart, eEnd, e; 667b197a28SMatthew G. Knepley 677b197a28SMatthew G. Knepley PetscFunctionBegin; 687b197a28SMatthew G. Knepley /* MUST call DMGetCoordinateDM() in order to get p4est setup if present */ 697b197a28SMatthew G. Knepley PetscCall(DMGetCoordinateDM(dm, &coordDM)); 707b197a28SMatthew G. Knepley PetscCall(DMClone(dm, &dmAux)); 717b197a28SMatthew G. Knepley PetscCall(DMSetCoordinateDM(dmAux, coordDM)); 727b197a28SMatthew G. Knepley PetscCall(PetscSectionCreate(PETSC_COMM_SELF, &s)); 737b197a28SMatthew G. Knepley PetscCall(DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd)); 747b197a28SMatthew G. Knepley PetscCall(PetscSectionSetChart(s, eStart, eEnd)); 757b197a28SMatthew G. Knepley for (e = eStart; e < eEnd; ++e) { 767b197a28SMatthew G. Knepley /* TODO Should we store the whole SU(3) matrix, or the symmetric part? */ 777b197a28SMatthew G. Knepley PetscCall(PetscSectionSetDof(s, e, 9)); 787b197a28SMatthew G. Knepley } 797b197a28SMatthew G. Knepley PetscCall(PetscSectionSetUp(s)); 807b197a28SMatthew G. Knepley PetscCall(DMSetLocalSection(dmAux, s)); 817b197a28SMatthew G. Knepley PetscCall(PetscSectionDestroy(&s)); 827b197a28SMatthew G. Knepley PetscCall(DMCreateLocalVector(dmAux, &gauge)); 837b197a28SMatthew G. Knepley PetscCall(DMDestroy(&dmAux)); 847b197a28SMatthew G. Knepley PetscCall(DMSetAuxiliaryVec(dm, NULL, 0, 0, gauge)); 857b197a28SMatthew G. Knepley PetscCall(VecDestroy(&gauge)); 863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 877b197a28SMatthew G. Knepley } 887b197a28SMatthew G. Knepley 897b197a28SMatthew G. Knepley static PetscErrorCode PrintVertex(DM dm, PetscInt v) 907b197a28SMatthew G. Knepley { 917b197a28SMatthew G. Knepley MPI_Comm comm; 927b197a28SMatthew G. Knepley PetscContainer c; 937b197a28SMatthew G. Knepley PetscInt *extent; 947b197a28SMatthew G. Knepley PetscInt dim, cStart, cEnd, sum; 957b197a28SMatthew G. Knepley 967b197a28SMatthew G. Knepley PetscFunctionBeginUser; 977b197a28SMatthew G. Knepley PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 987b197a28SMatthew G. Knepley PetscCall(DMGetDimension(dm, &dim)); 997b197a28SMatthew G. Knepley PetscCall(DMPlexGetHeightStratum(dm, 0, &cStart, &cEnd)); 1007b197a28SMatthew G. Knepley PetscCall(PetscObjectQuery((PetscObject)dm, "_extent", (PetscObject *)&c)); 1017b197a28SMatthew G. Knepley PetscCall(PetscContainerGetPointer(c, (void **)&extent)); 1027b197a28SMatthew G. Knepley sum = 1; 1037b197a28SMatthew G. Knepley PetscCall(PetscPrintf(comm, "Vertex %" PetscInt_FMT ":", v)); 1047b197a28SMatthew G. Knepley for (PetscInt d = 0; d < dim; ++d) { 1057b197a28SMatthew G. Knepley PetscCall(PetscPrintf(comm, " %" PetscInt_FMT, (v / sum) % extent[d])); 1067b197a28SMatthew G. Knepley if (d < dim) sum *= extent[d]; 1077b197a28SMatthew G. Knepley } 1083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1097b197a28SMatthew G. Knepley } 1107b197a28SMatthew G. Knepley 1117b197a28SMatthew G. Knepley // Apply \gamma_\mu 1127b197a28SMatthew G. Knepley static PetscErrorCode ComputeGamma(PetscInt d, PetscInt ldx, PetscScalar f[]) 1137b197a28SMatthew G. Knepley { 1147b197a28SMatthew G. Knepley const PetscScalar fin[4] = {f[0 * ldx], f[1 * ldx], f[2 * ldx], f[3 * ldx]}; 1157b197a28SMatthew G. Knepley 1167b197a28SMatthew G. Knepley PetscFunctionBeginHot; 1177b197a28SMatthew G. Knepley switch (d) { 1187b197a28SMatthew G. Knepley case 0: 1197b197a28SMatthew G. Knepley f[0 * ldx] = PETSC_i * fin[3]; 1207b197a28SMatthew G. Knepley f[1 * ldx] = PETSC_i * fin[2]; 1217b197a28SMatthew G. Knepley f[2 * ldx] = -PETSC_i * fin[1]; 1227b197a28SMatthew G. Knepley f[3 * ldx] = -PETSC_i * fin[0]; 1237b197a28SMatthew G. Knepley break; 1247b197a28SMatthew G. Knepley case 1: 1257b197a28SMatthew G. Knepley f[0 * ldx] = -fin[3]; 1267b197a28SMatthew G. Knepley f[1 * ldx] = fin[2]; 1277b197a28SMatthew G. Knepley f[2 * ldx] = fin[1]; 1287b197a28SMatthew G. Knepley f[3 * ldx] = -fin[0]; 1297b197a28SMatthew G. Knepley break; 1307b197a28SMatthew G. Knepley case 2: 1317b197a28SMatthew G. Knepley f[0 * ldx] = PETSC_i * fin[2]; 1327b197a28SMatthew G. Knepley f[1 * ldx] = -PETSC_i * fin[3]; 1337b197a28SMatthew G. Knepley f[2 * ldx] = -PETSC_i * fin[0]; 1347b197a28SMatthew G. Knepley f[3 * ldx] = PETSC_i * fin[1]; 1357b197a28SMatthew G. Knepley break; 1367b197a28SMatthew G. Knepley case 3: 1377b197a28SMatthew G. Knepley f[0 * ldx] = fin[2]; 1387b197a28SMatthew G. Knepley f[1 * ldx] = fin[3]; 1397b197a28SMatthew G. Knepley f[2 * ldx] = fin[0]; 1407b197a28SMatthew G. Knepley f[3 * ldx] = fin[1]; 1417b197a28SMatthew G. Knepley break; 1427b197a28SMatthew G. Knepley default: 1437b197a28SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Direction for gamma %" PetscInt_FMT " not in [0, 4)", d); 1447b197a28SMatthew G. Knepley } 1453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1467b197a28SMatthew G. Knepley } 1477b197a28SMatthew G. Knepley 1487b197a28SMatthew G. Knepley // Apply (1 \pm \gamma_\mu)/2 1497b197a28SMatthew G. Knepley static PetscErrorCode ComputeGammaFactor(PetscInt d, PetscBool forward, PetscInt ldx, PetscScalar f[]) 1507b197a28SMatthew G. Knepley { 1517b197a28SMatthew G. Knepley const PetscReal sign = forward ? -1. : 1.; 1527b197a28SMatthew G. Knepley const PetscScalar fin[4] = {f[0 * ldx], f[1 * ldx], f[2 * ldx], f[3 * ldx]}; 1537b197a28SMatthew G. Knepley 1547b197a28SMatthew G. Knepley PetscFunctionBeginHot; 1557b197a28SMatthew G. Knepley switch (d) { 1567b197a28SMatthew G. Knepley case 0: 1577b197a28SMatthew G. Knepley f[0 * ldx] += sign * PETSC_i * fin[3]; 1587b197a28SMatthew G. Knepley f[1 * ldx] += sign * PETSC_i * fin[2]; 1597b197a28SMatthew G. Knepley f[2 * ldx] += sign * -PETSC_i * fin[1]; 1607b197a28SMatthew G. Knepley f[3 * ldx] += sign * -PETSC_i * fin[0]; 1617b197a28SMatthew G. Knepley break; 1627b197a28SMatthew G. Knepley case 1: 1637b197a28SMatthew G. Knepley f[0 * ldx] += -sign * fin[3]; 1647b197a28SMatthew G. Knepley f[1 * ldx] += sign * fin[2]; 1657b197a28SMatthew G. Knepley f[2 * ldx] += sign * fin[1]; 1667b197a28SMatthew G. Knepley f[3 * ldx] += -sign * fin[0]; 1677b197a28SMatthew G. Knepley break; 1687b197a28SMatthew G. Knepley case 2: 1697b197a28SMatthew G. Knepley f[0 * ldx] += sign * PETSC_i * fin[2]; 1707b197a28SMatthew G. Knepley f[1 * ldx] += sign * -PETSC_i * fin[3]; 1717b197a28SMatthew G. Knepley f[2 * ldx] += sign * -PETSC_i * fin[0]; 1727b197a28SMatthew G. Knepley f[3 * ldx] += sign * PETSC_i * fin[1]; 1737b197a28SMatthew G. Knepley break; 1747b197a28SMatthew G. Knepley case 3: 1757b197a28SMatthew G. Knepley f[0 * ldx] += sign * fin[2]; 1767b197a28SMatthew G. Knepley f[1 * ldx] += sign * fin[3]; 1777b197a28SMatthew G. Knepley f[2 * ldx] += sign * fin[0]; 1787b197a28SMatthew G. Knepley f[3 * ldx] += sign * fin[1]; 1797b197a28SMatthew G. Knepley break; 1807b197a28SMatthew G. Knepley default: 1817b197a28SMatthew G. Knepley SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Direction for gamma %" PetscInt_FMT " not in [0, 4)", d); 1827b197a28SMatthew G. Knepley } 1837b197a28SMatthew G. Knepley f[0 * ldx] *= 0.5; 1847b197a28SMatthew G. Knepley f[1 * ldx] *= 0.5; 1857b197a28SMatthew G. Knepley f[2 * ldx] *= 0.5; 1867b197a28SMatthew G. Knepley f[3 * ldx] *= 0.5; 1873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1887b197a28SMatthew G. Knepley } 1897b197a28SMatthew G. Knepley 1907b197a28SMatthew G. Knepley #include <petsc/private/dmpleximpl.h> 1917b197a28SMatthew G. Knepley 1927b197a28SMatthew G. Knepley // ComputeAction() sums the action of 1/2 (1 \pm \gamma_\mu) U \psi into f 1937b197a28SMatthew G. Knepley static PetscErrorCode ComputeAction(PetscInt d, PetscBool forward, const PetscScalar U[], const PetscScalar psi[], PetscScalar f[]) 1947b197a28SMatthew G. Knepley { 1957b197a28SMatthew G. Knepley PetscScalar tmp[12]; 1967b197a28SMatthew G. Knepley 1977b197a28SMatthew G. Knepley PetscFunctionBeginHot; 1987b197a28SMatthew G. Knepley // Apply U 1997b197a28SMatthew G. Knepley for (PetscInt beta = 0; beta < 4; ++beta) { 2007b197a28SMatthew G. Knepley if (forward) DMPlex_Mult3D_Internal(U, 1, &psi[beta * 3], &tmp[beta * 3]); 2017b197a28SMatthew G. Knepley else DMPlex_MultTranspose3D_Internal(U, 1, &psi[beta * 3], &tmp[beta * 3]); 2027b197a28SMatthew G. Knepley } 2037b197a28SMatthew G. Knepley // Apply (1 \pm \gamma_\mu)/2 to each color 2047b197a28SMatthew G. Knepley for (PetscInt c = 0; c < 3; ++c) PetscCall(ComputeGammaFactor(d, forward, 3, &tmp[c])); 2057b197a28SMatthew G. Knepley // Note that we are subtracting this contribution 2067b197a28SMatthew G. Knepley for (PetscInt i = 0; i < 12; ++i) f[i] -= tmp[i]; 2073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2087b197a28SMatthew G. Knepley } 2097b197a28SMatthew G. Knepley 2107b197a28SMatthew G. Knepley /* 2117b197a28SMatthew G. Knepley The assembly loop runs over vertices. Each vertex has 2d edges in its support. The edges are ordered first by the dimension along which they run, and second from smaller to larger index, expect for edges which loop periodically. The vertices on edges are also ordered from smaller to larger index except for periodic edges. 2127b197a28SMatthew G. Knepley */ 213*fc229b03SMatthew G. Knepley static PetscErrorCode ComputeResidualLocal(DM dm, Vec u, Vec f) 2147b197a28SMatthew G. Knepley { 215de19e7feSJoseph Pusztay DM dmAux; 216de19e7feSJoseph Pusztay Vec gauge; 217de19e7feSJoseph Pusztay PetscSection s, sGauge; 2187b197a28SMatthew G. Knepley const PetscScalar *ua; 219de19e7feSJoseph Pusztay PetscScalar *fa, *link; 2207b197a28SMatthew G. Knepley PetscInt dim, vStart, vEnd; 2217b197a28SMatthew G. Knepley 2227b197a28SMatthew G. Knepley PetscFunctionBeginUser; 2237b197a28SMatthew G. Knepley PetscCall(DMGetDimension(dm, &dim)); 2247b197a28SMatthew G. Knepley PetscCall(DMGetLocalSection(dm, &s)); 2257b197a28SMatthew G. Knepley PetscCall(DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd)); 2267b197a28SMatthew G. Knepley PetscCall(VecGetArrayRead(u, &ua)); 2277b197a28SMatthew G. Knepley PetscCall(VecGetArray(f, &fa)); 228de19e7feSJoseph Pusztay 229de19e7feSJoseph Pusztay PetscCall(DMGetAuxiliaryVec(dm, NULL, 0, 0, &gauge)); 230de19e7feSJoseph Pusztay PetscCall(VecGetDM(gauge, &dmAux)); 231de19e7feSJoseph Pusztay PetscCall(DMGetLocalSection(dmAux, &sGauge)); 232de19e7feSJoseph Pusztay PetscCall(VecGetArray(gauge, &link)); 2337b197a28SMatthew G. Knepley // Loop over y 2347b197a28SMatthew G. Knepley for (PetscInt v = vStart; v < vEnd; ++v) { 2357b197a28SMatthew G. Knepley const PetscInt *supp; 2367b197a28SMatthew G. Knepley PetscInt xdof, xoff; 2377b197a28SMatthew G. Knepley 2387b197a28SMatthew G. Knepley PetscCall(DMPlexGetSupport(dm, v, &supp)); 2397b197a28SMatthew G. Knepley PetscCall(PetscSectionGetDof(s, v, &xdof)); 2407b197a28SMatthew G. Knepley PetscCall(PetscSectionGetOffset(s, v, &xoff)); 2417b197a28SMatthew G. Knepley // Diagonal 2427b197a28SMatthew G. Knepley for (PetscInt i = 0; i < xdof; ++i) fa[xoff + i] += (M + 4) * ua[xoff + i]; 2437b197a28SMatthew G. Knepley // Loop over mu 2447b197a28SMatthew G. Knepley for (PetscInt d = 0; d < dim; ++d) { 2457b197a28SMatthew G. Knepley const PetscInt *cone; 246de19e7feSJoseph Pusztay PetscInt yoff, goff; 2477b197a28SMatthew G. Knepley 2487b197a28SMatthew G. Knepley // Left action -(1 + \gamma_\mu)/2 \otimes U^\dagger_\mu(y) \delta_{x - \mu,y} \psi(y) 2497b197a28SMatthew G. Knepley PetscCall(DMPlexGetCone(dm, supp[2 * d + 0], &cone)); 2507b197a28SMatthew G. Knepley PetscCall(PetscSectionGetOffset(s, cone[0], &yoff)); 251de19e7feSJoseph Pusztay PetscCall(PetscSectionGetOffset(sGauge, supp[2 * d + 0], &goff)); 252de19e7feSJoseph Pusztay PetscCall(ComputeAction(d, PETSC_FALSE, &link[goff], &ua[yoff], &fa[xoff])); 2537b197a28SMatthew G. Knepley // Right edge -(1 - \gamma_\mu)/2 \otimes U_\mu(x) \delta_{x + \mu,y} \psi(y) 2547b197a28SMatthew G. Knepley PetscCall(DMPlexGetCone(dm, supp[2 * d + 1], &cone)); 2557b197a28SMatthew G. Knepley PetscCall(PetscSectionGetOffset(s, cone[1], &yoff)); 256de19e7feSJoseph Pusztay PetscCall(PetscSectionGetOffset(sGauge, supp[2 * d + 1], &goff)); 257de19e7feSJoseph Pusztay PetscCall(ComputeAction(d, PETSC_TRUE, &link[goff], &ua[yoff], &fa[xoff])); 2587b197a28SMatthew G. Knepley } 2597b197a28SMatthew G. Knepley } 2607b197a28SMatthew G. Knepley PetscCall(VecRestoreArray(f, &fa)); 261de19e7feSJoseph Pusztay PetscCall(VecRestoreArray(gauge, &link)); 2627b197a28SMatthew G. Knepley PetscCall(VecRestoreArrayRead(u, &ua)); 2633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2647b197a28SMatthew G. Knepley } 2657b197a28SMatthew G. Knepley 266*fc229b03SMatthew G. Knepley static PetscErrorCode ComputeResidual(DM dm, Vec u, Vec f) 267*fc229b03SMatthew G. Knepley { 268*fc229b03SMatthew G. Knepley Vec lu, lf; 269*fc229b03SMatthew G. Knepley 270*fc229b03SMatthew G. Knepley PetscFunctionBegin; 271*fc229b03SMatthew G. Knepley PetscCall(DMGetLocalVector(dm, &lu)); 272*fc229b03SMatthew G. Knepley PetscCall(DMGetLocalVector(dm, &lf)); 273*fc229b03SMatthew G. Knepley PetscCall(DMGlobalToLocalBegin(dm, u, INSERT_VALUES, lu)); 274*fc229b03SMatthew G. Knepley PetscCall(DMGlobalToLocalEnd(dm, u, INSERT_VALUES, lu)); 275*fc229b03SMatthew G. Knepley PetscCall(VecSet(lf, 0.)); 276*fc229b03SMatthew G. Knepley PetscCall(ComputeResidualLocal(dm, lu, lf)); 277*fc229b03SMatthew G. Knepley PetscCall(DMLocalToGlobalBegin(dm, lf, INSERT_VALUES, f)); 278*fc229b03SMatthew G. Knepley PetscCall(DMLocalToGlobalEnd(dm, lf, INSERT_VALUES, f)); 279*fc229b03SMatthew G. Knepley PetscCall(DMRestoreLocalVector(dm, &lu)); 280*fc229b03SMatthew G. Knepley PetscCall(DMRestoreLocalVector(dm, &lf)); 281*fc229b03SMatthew G. Knepley PetscFunctionReturn(PETSC_SUCCESS); 282*fc229b03SMatthew G. Knepley } 283*fc229b03SMatthew G. Knepley 2847b197a28SMatthew G. Knepley static PetscErrorCode CreateJacobian(DM dm, Mat *J) 2857b197a28SMatthew G. Knepley { 2867b197a28SMatthew G. Knepley PetscFunctionBegin; 2873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2887b197a28SMatthew G. Knepley } 2897b197a28SMatthew G. Knepley 2907b197a28SMatthew G. Knepley static PetscErrorCode ComputeJacobian(DM dm, Vec u, Mat J) 2917b197a28SMatthew G. Knepley { 2927b197a28SMatthew G. Knepley PetscFunctionBegin; 2933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2947b197a28SMatthew G. Knepley } 2957b197a28SMatthew G. Knepley 2967b197a28SMatthew G. Knepley static PetscErrorCode PrintTraversal(DM dm) 2977b197a28SMatthew G. Knepley { 2987b197a28SMatthew G. Knepley MPI_Comm comm; 2997b197a28SMatthew G. Knepley PetscInt vStart, vEnd; 3007b197a28SMatthew G. Knepley 3017b197a28SMatthew G. Knepley PetscFunctionBeginUser; 3027b197a28SMatthew G. Knepley PetscCall(PetscObjectGetComm((PetscObject)dm, &comm)); 3037b197a28SMatthew G. Knepley PetscCall(DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd)); 3047b197a28SMatthew G. Knepley for (PetscInt v = vStart; v < vEnd; ++v) { 3057b197a28SMatthew G. Knepley const PetscInt *supp; 3067b197a28SMatthew G. Knepley PetscInt Ns; 3077b197a28SMatthew G. Knepley 3087b197a28SMatthew G. Knepley PetscCall(DMPlexGetSupportSize(dm, v, &Ns)); 3097b197a28SMatthew G. Knepley PetscCall(DMPlexGetSupport(dm, v, &supp)); 3107b197a28SMatthew G. Knepley PetscCall(PrintVertex(dm, v)); 3117b197a28SMatthew G. Knepley PetscCall(PetscPrintf(comm, "\n")); 3127b197a28SMatthew G. Knepley for (PetscInt s = 0; s < Ns; ++s) { 3137b197a28SMatthew G. Knepley const PetscInt *cone; 3147b197a28SMatthew G. Knepley 3157b197a28SMatthew G. Knepley PetscCall(DMPlexGetCone(dm, supp[s], &cone)); 3167b197a28SMatthew G. Knepley PetscCall(PetscPrintf(comm, " Edge %" PetscInt_FMT ": ", supp[s])); 3177b197a28SMatthew G. Knepley PetscCall(PrintVertex(dm, cone[0])); 3187b197a28SMatthew G. Knepley PetscCall(PetscPrintf(comm, " -- ")); 3197b197a28SMatthew G. Knepley PetscCall(PrintVertex(dm, cone[1])); 3207b197a28SMatthew G. Knepley PetscCall(PetscPrintf(comm, "\n")); 3217b197a28SMatthew G. Knepley } 3227b197a28SMatthew G. Knepley } 3233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3247b197a28SMatthew G. Knepley } 3257b197a28SMatthew G. Knepley 3267b197a28SMatthew G. Knepley static PetscErrorCode ComputeFFT(Mat FT, PetscInt Nc, Vec x, Vec p) 3277b197a28SMatthew G. Knepley { 328*fc229b03SMatthew G. Knepley Vec *xComp, *pComp, xTmp, pTmp; 3297b197a28SMatthew G. Knepley PetscInt n, N; 3307b197a28SMatthew G. Knepley 3317b197a28SMatthew G. Knepley PetscFunctionBeginUser; 3327b197a28SMatthew G. Knepley PetscCall(PetscMalloc2(Nc, &xComp, Nc, &pComp)); 3337b197a28SMatthew G. Knepley PetscCall(VecGetLocalSize(x, &n)); 3347b197a28SMatthew G. Knepley PetscCall(VecGetSize(x, &N)); 3357b197a28SMatthew G. Knepley for (PetscInt i = 0; i < Nc; ++i) { 3367b197a28SMatthew G. Knepley const char *vtype; 3377b197a28SMatthew G. Knepley 3387b197a28SMatthew G. Knepley // HACK: Make these from another DM up front 3397b197a28SMatthew G. Knepley PetscCall(VecCreate(PetscObjectComm((PetscObject)x), &xComp[i])); 3407b197a28SMatthew G. Knepley PetscCall(VecGetType(x, &vtype)); 3417b197a28SMatthew G. Knepley PetscCall(VecSetType(xComp[i], vtype)); 3427b197a28SMatthew G. Knepley PetscCall(VecSetSizes(xComp[i], n / Nc, N / Nc)); 3437b197a28SMatthew G. Knepley PetscCall(VecDuplicate(xComp[i], &pComp[i])); 3447b197a28SMatthew G. Knepley } 345*fc229b03SMatthew G. Knepley PetscCall(MatCreateVecsFFTW(FT, &xTmp, &pTmp, NULL)); 3467b197a28SMatthew G. Knepley PetscCall(VecStrideGatherAll(x, xComp, INSERT_VALUES)); 347*fc229b03SMatthew G. Knepley for (PetscInt i = 0; i < Nc; ++i) { 348*fc229b03SMatthew G. Knepley PetscCall(VecScatterPetscToFFTW(FT, xComp[i], xTmp)); 349*fc229b03SMatthew G. Knepley PetscCall(MatMult(FT, xTmp, pTmp)); 350*fc229b03SMatthew G. Knepley PetscCall(VecScatterFFTWToPetsc(FT, pTmp, pComp[i])); 351*fc229b03SMatthew G. Knepley } 3527b197a28SMatthew G. Knepley PetscCall(VecStrideScatterAll(pComp, p, INSERT_VALUES)); 3537b197a28SMatthew G. Knepley for (PetscInt i = 0; i < Nc; ++i) { 3547b197a28SMatthew G. Knepley PetscCall(VecDestroy(&xComp[i])); 3557b197a28SMatthew G. Knepley PetscCall(VecDestroy(&pComp[i])); 3567b197a28SMatthew G. Knepley } 357*fc229b03SMatthew G. Knepley PetscCall(VecDestroy(&xTmp)); 358*fc229b03SMatthew G. Knepley PetscCall(VecDestroy(&pTmp)); 3597b197a28SMatthew G. Knepley PetscCall(PetscFree2(xComp, pComp)); 3603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3617b197a28SMatthew G. Knepley } 3627b197a28SMatthew G. Knepley 363de19e7feSJoseph Pusztay // Sets each link to be the identity for the free field test 364de19e7feSJoseph Pusztay static PetscErrorCode SetGauge_Identity(DM dm) 365de19e7feSJoseph Pusztay { 366de19e7feSJoseph Pusztay DM auxDM; 367de19e7feSJoseph Pusztay Vec auxVec; 368de19e7feSJoseph Pusztay PetscSection s; 369de19e7feSJoseph Pusztay PetscScalar id[9] = {1., 0., 0., 0., 1., 0., 0., 0., 1.}; 370de19e7feSJoseph Pusztay PetscInt eStart, eEnd; 371de19e7feSJoseph Pusztay 372de19e7feSJoseph Pusztay PetscFunctionBegin; 373de19e7feSJoseph Pusztay PetscCall(DMGetAuxiliaryVec(dm, NULL, 0, 0, &auxVec)); 374de19e7feSJoseph Pusztay PetscCall(VecGetDM(auxVec, &auxDM)); 375de19e7feSJoseph Pusztay PetscCall(DMGetLocalSection(auxDM, &s)); 376de19e7feSJoseph Pusztay PetscCall(DMPlexGetDepthStratum(dm, 1, &eStart, &eEnd)); 377aa624791SPierre Jolivet for (PetscInt i = eStart; i < eEnd; ++i) PetscCall(VecSetValuesSection(auxVec, s, i, id, INSERT_VALUES)); 378de19e7feSJoseph Pusztay PetscCall(VecViewFromOptions(auxVec, NULL, "-gauge_view")); 3793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 380de19e7feSJoseph Pusztay } 381de19e7feSJoseph Pusztay 3827b197a28SMatthew G. Knepley /* 3837b197a28SMatthew G. Knepley Test the action of the Wilson operator in the free field case U = I, 3847b197a28SMatthew G. Knepley 3857b197a28SMatthew G. Knepley \eta(x) = D_W(x - y) \psi(y) 3867b197a28SMatthew G. Knepley 3877b197a28SMatthew G. Knepley The Wilson operator is a convolution for the free field, so we can check that by the convolution theorem 3887b197a28SMatthew G. Knepley 3897b197a28SMatthew G. Knepley \hat\eta(x) = \mathcal{F}(D_W(x - y) \psi(y)) 3907b197a28SMatthew G. Knepley = \hat D_W(p) \mathcal{F}\psi(p) 3917b197a28SMatthew G. Knepley 3927b197a28SMatthew G. Knepley The Fourier series for the Wilson operator is 3937b197a28SMatthew G. Knepley 3947b197a28SMatthew G. Knepley M + \sum_\mu 2 \sin^2(p_\mu / 2) + i \gamma_\mu \sin(p_\mu) 3957b197a28SMatthew G. Knepley */ 3967b197a28SMatthew G. Knepley static PetscErrorCode TestFreeField(DM dm) 3977b197a28SMatthew G. Knepley { 3987b197a28SMatthew G. Knepley PetscSection s; 3997b197a28SMatthew G. Knepley Mat FT; 4007b197a28SMatthew G. Knepley Vec psi, psiHat; 4017b197a28SMatthew G. Knepley Vec eta, etaHat; 4027b197a28SMatthew G. Knepley Vec DHat; // The product \hat D_w \hat psi 4037b197a28SMatthew G. Knepley PetscRandom r; 4047b197a28SMatthew G. Knepley const PetscScalar *psih; 4057b197a28SMatthew G. Knepley PetscScalar *dh; 4067b197a28SMatthew G. Knepley PetscReal *coef, nrm; 4077b197a28SMatthew G. Knepley const PetscInt *extent, Nc = 12; 4087b197a28SMatthew G. Knepley PetscInt dim, V = 1, vStart, vEnd; 4097b197a28SMatthew G. Knepley PetscContainer c; 4107b197a28SMatthew G. Knepley PetscBool constRhs = PETSC_FALSE; 411*fc229b03SMatthew G. Knepley PetscMPIInt size; 4127b197a28SMatthew G. Knepley 4137b197a28SMatthew G. Knepley PetscFunctionBeginUser; 414*fc229b03SMatthew G. Knepley PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)dm), &size)); 415*fc229b03SMatthew G. Knepley if (size > 1) PetscFunctionReturn(PETSC_SUCCESS); 4167b197a28SMatthew G. Knepley PetscCall(PetscOptionsGetBool(NULL, NULL, "-const_rhs", &constRhs, NULL)); 4177b197a28SMatthew G. Knepley 418de19e7feSJoseph Pusztay PetscCall(SetGauge_Identity(dm)); 4197b197a28SMatthew G. Knepley PetscCall(DMGetLocalSection(dm, &s)); 4207b197a28SMatthew G. Knepley PetscCall(DMGetGlobalVector(dm, &psi)); 4217b197a28SMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)psi, "psi")); 4227b197a28SMatthew G. Knepley PetscCall(DMGetGlobalVector(dm, &psiHat)); 4237b197a28SMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)psiHat, "psihat")); 4247b197a28SMatthew G. Knepley PetscCall(DMGetGlobalVector(dm, &eta)); 4257b197a28SMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)eta, "eta")); 4267b197a28SMatthew G. Knepley PetscCall(DMGetGlobalVector(dm, &etaHat)); 4277b197a28SMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)etaHat, "etahat")); 4287b197a28SMatthew G. Knepley PetscCall(DMGetGlobalVector(dm, &DHat)); 4297b197a28SMatthew G. Knepley PetscCall(PetscObjectSetName((PetscObject)DHat, "Dhat")); 4307b197a28SMatthew G. Knepley PetscCall(PetscRandomCreate(PETSC_COMM_SELF, &r)); 4317b197a28SMatthew G. Knepley PetscCall(PetscRandomSetType(r, PETSCRAND48)); 4327b197a28SMatthew G. Knepley if (constRhs) PetscCall(VecSet(psi, 1.)); 4337b197a28SMatthew G. Knepley else PetscCall(VecSetRandom(psi, r)); 4347b197a28SMatthew G. Knepley PetscCall(PetscRandomDestroy(&r)); 4357b197a28SMatthew G. Knepley 4367b197a28SMatthew G. Knepley PetscCall(DMGetDimension(dm, &dim)); 4377b197a28SMatthew G. Knepley PetscCall(DMPlexGetDepthStratum(dm, 0, &vStart, &vEnd)); 4387b197a28SMatthew G. Knepley PetscCall(PetscObjectQuery((PetscObject)dm, "_extent", (PetscObject *)&c)); 4397b197a28SMatthew G. Knepley PetscCall(PetscContainerGetPointer(c, (void **)&extent)); 4407b197a28SMatthew G. Knepley PetscCall(MatCreateFFT(PetscObjectComm((PetscObject)dm), dim, extent, MATFFTW, &FT)); 4417b197a28SMatthew G. Knepley 4427b197a28SMatthew G. Knepley PetscCall(PetscMalloc1(dim, &coef)); 4437b197a28SMatthew G. Knepley for (PetscInt d = 0; d < dim; ++d) { 4447b197a28SMatthew G. Knepley coef[d] = 2. * PETSC_PI / extent[d]; 4457b197a28SMatthew G. Knepley V *= extent[d]; 4467b197a28SMatthew G. Knepley } 4477b197a28SMatthew G. Knepley PetscCall(ComputeResidual(dm, psi, eta)); 448*fc229b03SMatthew G. Knepley PetscCall(VecViewFromOptions(psi, NULL, "-psi_view")); 4497b197a28SMatthew G. Knepley PetscCall(VecViewFromOptions(eta, NULL, "-eta_view")); 4507b197a28SMatthew G. Knepley PetscCall(ComputeFFT(FT, Nc, psi, psiHat)); 4517b197a28SMatthew G. Knepley PetscCall(VecScale(psiHat, 1. / V)); 4527b197a28SMatthew G. Knepley PetscCall(ComputeFFT(FT, Nc, eta, etaHat)); 4537b197a28SMatthew G. Knepley PetscCall(VecScale(etaHat, 1. / V)); 4547b197a28SMatthew G. Knepley PetscCall(VecGetArrayRead(psiHat, &psih)); 4557b197a28SMatthew G. Knepley PetscCall(VecGetArray(DHat, &dh)); 4567b197a28SMatthew G. Knepley for (PetscInt v = vStart; v < vEnd; ++v) { 4577b197a28SMatthew G. Knepley PetscScalar tmp[12], tmp1 = 0.; 4587b197a28SMatthew G. Knepley PetscInt dof, off; 4597b197a28SMatthew G. Knepley 4607b197a28SMatthew G. Knepley PetscCall(PetscSectionGetDof(s, v, &dof)); 4617b197a28SMatthew G. Knepley PetscCall(PetscSectionGetOffset(s, v, &off)); 4627b197a28SMatthew G. Knepley for (PetscInt d = 0, prod = 1; d < dim; prod *= extent[d], ++d) { 4637b197a28SMatthew G. Knepley const PetscInt idx = (v / prod) % extent[d]; 4647b197a28SMatthew G. Knepley 4657b197a28SMatthew G. Knepley tmp1 += 2. * PetscSqr(PetscSinReal(0.5 * coef[d] * idx)); 4667b197a28SMatthew G. Knepley for (PetscInt i = 0; i < dof; ++i) tmp[i] = PETSC_i * PetscSinReal(coef[d] * idx) * psih[off + i]; 4673ba16761SJacob Faibussowitsch for (PetscInt c = 0; c < 3; ++c) PetscCall(ComputeGamma(d, 3, &tmp[c])); 4687b197a28SMatthew G. Knepley for (PetscInt i = 0; i < dof; ++i) dh[off + i] += tmp[i]; 4697b197a28SMatthew G. Knepley } 4707b197a28SMatthew G. Knepley for (PetscInt i = 0; i < dof; ++i) dh[off + i] += (M + tmp1) * psih[off + i]; 4717b197a28SMatthew G. Knepley } 4727b197a28SMatthew G. Knepley PetscCall(VecRestoreArrayRead(psiHat, &psih)); 4737b197a28SMatthew G. Knepley PetscCall(VecRestoreArray(DHat, &dh)); 4747b197a28SMatthew G. Knepley 4757b197a28SMatthew G. Knepley { 4767b197a28SMatthew G. Knepley Vec *etaComp, *DComp; 4777b197a28SMatthew G. Knepley PetscInt n, N; 4787b197a28SMatthew G. Knepley 4797b197a28SMatthew G. Knepley PetscCall(PetscMalloc2(Nc, &etaComp, Nc, &DComp)); 4807b197a28SMatthew G. Knepley PetscCall(VecGetLocalSize(etaHat, &n)); 4817b197a28SMatthew G. Knepley PetscCall(VecGetSize(etaHat, &N)); 4827b197a28SMatthew G. Knepley for (PetscInt i = 0; i < Nc; ++i) { 4837b197a28SMatthew G. Knepley const char *vtype; 4847b197a28SMatthew G. Knepley 4857b197a28SMatthew G. Knepley // HACK: Make these from another DM up front 4867b197a28SMatthew G. Knepley PetscCall(VecCreate(PetscObjectComm((PetscObject)etaHat), &etaComp[i])); 4877b197a28SMatthew G. Knepley PetscCall(VecGetType(etaHat, &vtype)); 4887b197a28SMatthew G. Knepley PetscCall(VecSetType(etaComp[i], vtype)); 4897b197a28SMatthew G. Knepley PetscCall(VecSetSizes(etaComp[i], n / Nc, N / Nc)); 4907b197a28SMatthew G. Knepley PetscCall(VecDuplicate(etaComp[i], &DComp[i])); 4917b197a28SMatthew G. Knepley } 4927b197a28SMatthew G. Knepley PetscCall(VecStrideGatherAll(etaHat, etaComp, INSERT_VALUES)); 4937b197a28SMatthew G. Knepley PetscCall(VecStrideGatherAll(DHat, DComp, INSERT_VALUES)); 4947b197a28SMatthew G. Knepley for (PetscInt i = 0; i < Nc; ++i) { 4957b197a28SMatthew G. Knepley if (!i) { 4967b197a28SMatthew G. Knepley PetscCall(VecViewFromOptions(etaComp[i], NULL, "-etahat_view")); 4977b197a28SMatthew G. Knepley PetscCall(VecViewFromOptions(DComp[i], NULL, "-dhat_view")); 4987b197a28SMatthew G. Knepley } 4997b197a28SMatthew G. Knepley PetscCall(VecAXPY(etaComp[i], -1., DComp[i])); 5007b197a28SMatthew G. Knepley PetscCall(VecNorm(etaComp[i], NORM_INFINITY, &nrm)); 5017b197a28SMatthew G. Knepley PetscCall(PetscPrintf(PETSC_COMM_SELF, " Slice %" PetscInt_FMT ": %g\n", i, (double)nrm)); 5027b197a28SMatthew G. Knepley } 5037b197a28SMatthew G. Knepley PetscCall(VecStrideScatterAll(etaComp, etaHat, INSERT_VALUES)); 5047b197a28SMatthew G. Knepley for (PetscInt i = 0; i < Nc; ++i) { 5057b197a28SMatthew G. Knepley PetscCall(VecDestroy(&etaComp[i])); 5067b197a28SMatthew G. Knepley PetscCall(VecDestroy(&DComp[i])); 5077b197a28SMatthew G. Knepley } 5087b197a28SMatthew G. Knepley PetscCall(PetscFree2(etaComp, DComp)); 5097b197a28SMatthew G. Knepley PetscCall(VecNorm(etaHat, NORM_INFINITY, &nrm)); 5107b197a28SMatthew G. Knepley PetscCheck(nrm < PETSC_SMALL, PetscObjectComm((PetscObject)dm), PETSC_ERR_PLIB, "Free field test failed: %g", (double)nrm); 5117b197a28SMatthew G. Knepley } 5127b197a28SMatthew G. Knepley 5137b197a28SMatthew G. Knepley PetscCall(PetscFree(coef)); 5147b197a28SMatthew G. Knepley PetscCall(MatDestroy(&FT)); 5157b197a28SMatthew G. Knepley PetscCall(DMRestoreGlobalVector(dm, &psi)); 5167b197a28SMatthew G. Knepley PetscCall(DMRestoreGlobalVector(dm, &psiHat)); 5177b197a28SMatthew G. Knepley PetscCall(DMRestoreGlobalVector(dm, &eta)); 5187b197a28SMatthew G. Knepley PetscCall(DMRestoreGlobalVector(dm, &etaHat)); 5197b197a28SMatthew G. Knepley PetscCall(DMRestoreGlobalVector(dm, &DHat)); 5203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5217b197a28SMatthew G. Knepley } 5227b197a28SMatthew G. Knepley 5237b197a28SMatthew G. Knepley int main(int argc, char **argv) 5247b197a28SMatthew G. Knepley { 5257b197a28SMatthew G. Knepley DM dm; 5267b197a28SMatthew G. Knepley Vec u, f; 5277b197a28SMatthew G. Knepley Mat J; 5287b197a28SMatthew G. Knepley AppCtx user; 5297b197a28SMatthew G. Knepley 5307b197a28SMatthew G. Knepley PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 5317b197a28SMatthew G. Knepley PetscCall(ProcessOptions(PETSC_COMM_WORLD, &user)); 5327b197a28SMatthew G. Knepley PetscCall(CreateMesh(PETSC_COMM_WORLD, &user, &dm)); 5337b197a28SMatthew G. Knepley PetscCall(SetupDiscretization(dm, &user)); 5347b197a28SMatthew G. Knepley PetscCall(SetupAuxDiscretization(dm, &user)); 5357b197a28SMatthew G. Knepley PetscCall(DMCreateGlobalVector(dm, &u)); 5367b197a28SMatthew G. Knepley PetscCall(DMCreateGlobalVector(dm, &f)); 537*fc229b03SMatthew G. Knepley if (user.printTr) PetscCall(PrintTraversal(dm)); 5387b197a28SMatthew G. Knepley PetscCall(ComputeResidual(dm, u, f)); 5397b197a28SMatthew G. Knepley PetscCall(VecViewFromOptions(f, NULL, "-res_view")); 5407b197a28SMatthew G. Knepley PetscCall(CreateJacobian(dm, &J)); 5417b197a28SMatthew G. Knepley PetscCall(ComputeJacobian(dm, u, J)); 5427b197a28SMatthew G. Knepley PetscCall(VecViewFromOptions(u, NULL, "-sol_view")); 5437b197a28SMatthew G. Knepley PetscCall(TestFreeField(dm)); 5447b197a28SMatthew G. Knepley PetscCall(VecDestroy(&f)); 5457b197a28SMatthew G. Knepley PetscCall(VecDestroy(&u)); 5467b197a28SMatthew G. Knepley PetscCall(DMDestroy(&dm)); 5477b197a28SMatthew G. Knepley PetscCall(PetscFinalize()); 5487b197a28SMatthew G. Knepley return 0; 5497b197a28SMatthew G. Knepley } 5507b197a28SMatthew G. Knepley 5517b197a28SMatthew G. Knepley /*TEST 5527b197a28SMatthew G. Knepley 5537b197a28SMatthew G. Knepley build: 5547b197a28SMatthew G. Knepley requires: complex 5557b197a28SMatthew G. Knepley 5567b197a28SMatthew G. Knepley test: 5577b197a28SMatthew G. Knepley requires: fftw 5587b197a28SMatthew G. Knepley suffix: dirac_free_field 5597b197a28SMatthew G. Knepley args: -dm_plex_dim 4 -dm_plex_shape hypercubic -dm_plex_box_faces 3,3,3,3 -dm_view -sol_view \ 5607b197a28SMatthew G. Knepley -dm_plex_check_symmetry -dm_plex_check_skeleton -dm_plex_check_faces -dm_plex_check_pointsf 5617b197a28SMatthew G. Knepley 562*fc229b03SMatthew G. Knepley # Problem on rank 3 on MacOSX 563*fc229b03SMatthew G. Knepley test: 564*fc229b03SMatthew G. Knepley requires: fftw 565*fc229b03SMatthew G. Knepley suffix: dirac_free_field_par 566*fc229b03SMatthew G. Knepley nsize: 16 567*fc229b03SMatthew G. Knepley args: -dm_plex_dim 4 -dm_plex_shape hypercubic -dm_plex_box_faces 4,4,4,4 -dm_view -sol_view \ 568*fc229b03SMatthew G. Knepley -dm_plex_check_symmetry -dm_plex_check_skeleton -dm_plex_check_faces -dm_plex_check_pointsf 569*fc229b03SMatthew G. Knepley 5707b197a28SMatthew G. Knepley TEST*/ 571