1ccaff030SJeremy L Thompson // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 2ccaff030SJeremy L Thompson // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 3ccaff030SJeremy L Thompson // reserved. See files LICENSE and NOTICE for details. 4ccaff030SJeremy L Thompson // 5ccaff030SJeremy L Thompson // This file is part of CEED, a collection of benchmarks, miniapps, software 6ccaff030SJeremy L Thompson // libraries and APIs for efficient high-order finite element and spectral 7ccaff030SJeremy L Thompson // element discretizations for exascale applications. For more information and 8ccaff030SJeremy L Thompson // source code availability see http://github.com/ceed. 9ccaff030SJeremy L Thompson // 10ccaff030SJeremy L Thompson // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11ccaff030SJeremy L Thompson // a collaborative effort of two U.S. Department of Energy organizations (Office 12ccaff030SJeremy L Thompson // of Science and the National Nuclear Security Administration) responsible for 13ccaff030SJeremy L Thompson // the planning and preparation of a capable exascale ecosystem, including 14ccaff030SJeremy L Thompson // software, applications, hardware, advanced system engineering and early 15ccaff030SJeremy L Thompson // testbed platforms, in support of the nation's exascale computing imperative. 16ccaff030SJeremy L Thompson 17ccaff030SJeremy L Thompson /// @file 18ccaff030SJeremy L Thompson /// Helper functions for solid mechanics example using PETSc 19ccaff030SJeremy L Thompson 20ccaff030SJeremy L Thompson #include "../elasticity.h" 21ccaff030SJeremy L Thompson 22ccaff030SJeremy L Thompson // ----------------------------------------------------------------------------- 23ccaff030SJeremy L Thompson // Create libCEED operator context 24ccaff030SJeremy L Thompson // ----------------------------------------------------------------------------- 25ccaff030SJeremy L Thompson // Setup context data for Jacobian evaluation 26ccaff030SJeremy L Thompson PetscErrorCode SetupJacobianCtx(MPI_Comm comm, AppCtx appCtx, DM dm, Vec V, 27ccaff030SJeremy L Thompson Vec Vloc, CeedData ceedData, Ceed ceed, 28f7b4142eSJeremy L Thompson Physics phys, Physics physSmoother, 29ccaff030SJeremy L Thompson UserMult jacobianCtx) { 30ccaff030SJeremy L Thompson PetscErrorCode ierr; 31ccaff030SJeremy L Thompson 32ccaff030SJeremy L Thompson PetscFunctionBeginUser; 33ccaff030SJeremy L Thompson 34ccaff030SJeremy L Thompson // PETSc objects 35ccaff030SJeremy L Thompson jacobianCtx->comm = comm; 36ccaff030SJeremy L Thompson jacobianCtx->dm = dm; 37ccaff030SJeremy L Thompson 38ccaff030SJeremy L Thompson // Work vectors 39ccaff030SJeremy L Thompson jacobianCtx->Xloc = Vloc; 40ccaff030SJeremy L Thompson ierr = VecDuplicate(Vloc, &jacobianCtx->Yloc); CHKERRQ(ierr); 41ccaff030SJeremy L Thompson jacobianCtx->Xceed = ceedData->xceed; 42ccaff030SJeremy L Thompson jacobianCtx->Yceed = ceedData->yceed; 43ccaff030SJeremy L Thompson 44ccaff030SJeremy L Thompson // libCEED operator 45ccaff030SJeremy L Thompson jacobianCtx->op = ceedData->opJacob; 46f7b4142eSJeremy L Thompson jacobianCtx->qf = ceedData->qfJacob; 47ccaff030SJeremy L Thompson 48ccaff030SJeremy L Thompson // Ceed 49ccaff030SJeremy L Thompson jacobianCtx->ceed = ceed; 50ccaff030SJeremy L Thompson 51f7b4142eSJeremy L Thompson // Physics 52f7b4142eSJeremy L Thompson jacobianCtx->phys = phys; 53f7b4142eSJeremy L Thompson jacobianCtx->physSmoother = physSmoother; 54f7b4142eSJeremy L Thompson 55*62e9c006SJeremy L Thompson // Get/Restore Array 56*62e9c006SJeremy L Thompson jacobianCtx->memType = appCtx->memTypeRequested; 57*62e9c006SJeremy L Thompson if (appCtx->memTypeRequested == CEED_MEM_HOST) { 58*62e9c006SJeremy L Thompson jacobianCtx->VecGetArray = VecGetArray; 59*62e9c006SJeremy L Thompson jacobianCtx->VecGetArrayRead = VecGetArrayRead; 60*62e9c006SJeremy L Thompson jacobianCtx->VecRestoreArray = VecRestoreArray; 61*62e9c006SJeremy L Thompson jacobianCtx->VecRestoreArrayRead = VecRestoreArrayRead; 62*62e9c006SJeremy L Thompson } else { 63*62e9c006SJeremy L Thompson jacobianCtx->VecGetArray = VecCUDAGetArray; 64*62e9c006SJeremy L Thompson jacobianCtx->VecGetArrayRead = VecCUDAGetArrayRead; 65*62e9c006SJeremy L Thompson jacobianCtx->VecRestoreArray = VecCUDARestoreArray; 66*62e9c006SJeremy L Thompson jacobianCtx->VecRestoreArrayRead = VecCUDARestoreArrayRead; 67*62e9c006SJeremy L Thompson } 68*62e9c006SJeremy L Thompson 69ccaff030SJeremy L Thompson PetscFunctionReturn(0); 70ccaff030SJeremy L Thompson }; 71ccaff030SJeremy L Thompson 72ccaff030SJeremy L Thompson // Setup context data for prolongation and restriction operators 73*62e9c006SJeremy L Thompson PetscErrorCode SetupProlongRestrictCtx(MPI_Comm comm, AppCtx appCtx, DM dmC, 74*62e9c006SJeremy L Thompson DM dmF, Vec VF, Vec VlocC, Vec VlocF, 75*62e9c006SJeremy L Thompson CeedData ceedDataC, CeedData ceedDataF, 76*62e9c006SJeremy L Thompson Ceed ceed, 77ccaff030SJeremy L Thompson UserMultProlongRestr prolongRestrCtx) { 78ccaff030SJeremy L Thompson PetscErrorCode ierr; 79ccaff030SJeremy L Thompson PetscScalar *multArray; 80ccaff030SJeremy L Thompson 81ccaff030SJeremy L Thompson PetscFunctionBeginUser; 82ccaff030SJeremy L Thompson 83ccaff030SJeremy L Thompson // PETSc objects 84ccaff030SJeremy L Thompson prolongRestrCtx->comm = comm; 85ccaff030SJeremy L Thompson prolongRestrCtx->dmC = dmC; 86ccaff030SJeremy L Thompson prolongRestrCtx->dmF = dmF; 87ccaff030SJeremy L Thompson 88ccaff030SJeremy L Thompson // Work vectors 89ccaff030SJeremy L Thompson prolongRestrCtx->locVecC = VlocC; 90ccaff030SJeremy L Thompson prolongRestrCtx->locVecF = VlocF; 91ccaff030SJeremy L Thompson prolongRestrCtx->ceedVecC = ceedDataC->xceed; 92ccaff030SJeremy L Thompson prolongRestrCtx->ceedVecF = ceedDataF->xceed; 93ccaff030SJeremy L Thompson 94ccaff030SJeremy L Thompson // libCEED operators 95ccaff030SJeremy L Thompson prolongRestrCtx->opProlong = ceedDataF->opProlong; 96ccaff030SJeremy L Thompson prolongRestrCtx->opRestrict = ceedDataF->opRestrict; 97ccaff030SJeremy L Thompson 98ccaff030SJeremy L Thompson // Ceed 99ccaff030SJeremy L Thompson prolongRestrCtx->ceed = ceed; 100ccaff030SJeremy L Thompson 101*62e9c006SJeremy L Thompson // Get/Restore Array 102*62e9c006SJeremy L Thompson prolongRestrCtx->memType = appCtx->memTypeRequested; 103*62e9c006SJeremy L Thompson if (appCtx->memTypeRequested == CEED_MEM_HOST) { 104*62e9c006SJeremy L Thompson prolongRestrCtx->VecGetArray = VecGetArray; 105*62e9c006SJeremy L Thompson prolongRestrCtx->VecGetArrayRead = VecGetArrayRead; 106*62e9c006SJeremy L Thompson prolongRestrCtx->VecRestoreArray = VecRestoreArray; 107*62e9c006SJeremy L Thompson prolongRestrCtx->VecRestoreArrayRead = VecRestoreArrayRead; 108*62e9c006SJeremy L Thompson } else { 109*62e9c006SJeremy L Thompson prolongRestrCtx->VecGetArray = VecCUDAGetArray; 110*62e9c006SJeremy L Thompson prolongRestrCtx->VecGetArrayRead = VecCUDAGetArrayRead; 111*62e9c006SJeremy L Thompson prolongRestrCtx->VecRestoreArray = VecCUDARestoreArray; 112*62e9c006SJeremy L Thompson prolongRestrCtx->VecRestoreArrayRead = VecCUDARestoreArrayRead; 113*62e9c006SJeremy L Thompson } 114*62e9c006SJeremy L Thompson 115ccaff030SJeremy L Thompson // Multiplicity vector 116ccaff030SJeremy L Thompson // -- Set libCEED vector 117ccaff030SJeremy L Thompson ierr = VecZeroEntries(VlocF); 118*62e9c006SJeremy L Thompson ierr = prolongRestrCtx->VecGetArray(VlocF, &multArray); CHKERRQ(ierr); 119*62e9c006SJeremy L Thompson CeedVectorSetArray(ceedDataF->xceed, appCtx->memTypeRequested, 120*62e9c006SJeremy L Thompson CEED_USE_POINTER, multArray); 121ccaff030SJeremy L Thompson 122ccaff030SJeremy L Thompson // -- Compute multiplicity 123ccaff030SJeremy L Thompson CeedElemRestrictionGetMultiplicity(ceedDataF->Erestrictu, ceedDataF->xceed); 124ccaff030SJeremy L Thompson 125ccaff030SJeremy L Thompson // -- Restore PETSc vector 126*62e9c006SJeremy L Thompson ierr = prolongRestrCtx->VecRestoreArray(VlocF, &multArray); CHKERRQ(ierr); 127ccaff030SJeremy L Thompson 128ccaff030SJeremy L Thompson // -- Local-to-global 129ccaff030SJeremy L Thompson ierr = VecZeroEntries(VF); CHKERRQ(ierr); 130ccaff030SJeremy L Thompson ierr = DMLocalToGlobal(dmF, VlocF, ADD_VALUES, VF); CHKERRQ(ierr); 131ccaff030SJeremy L Thompson 132ccaff030SJeremy L Thompson // -- Global-to-local 133ccaff030SJeremy L Thompson ierr = VecDuplicate(VlocF, &prolongRestrCtx->multVec); CHKERRQ(ierr); 134ccaff030SJeremy L Thompson ierr = DMGlobalToLocal(dmF, VF, INSERT_VALUES, prolongRestrCtx->multVec); 135ccaff030SJeremy L Thompson CHKERRQ(ierr); 136ccaff030SJeremy L Thompson 137ccaff030SJeremy L Thompson // -- Reciprocal 138ccaff030SJeremy L Thompson ierr = VecReciprocal(prolongRestrCtx->multVec); CHKERRQ(ierr); 139ccaff030SJeremy L Thompson 140ccaff030SJeremy L Thompson // -- Reset work arrays 141ccaff030SJeremy L Thompson ierr = VecZeroEntries(VF); CHKERRQ(ierr); 142ccaff030SJeremy L Thompson ierr = VecZeroEntries(VlocF); CHKERRQ(ierr); 143ccaff030SJeremy L Thompson 144ccaff030SJeremy L Thompson PetscFunctionReturn(0); 145ccaff030SJeremy L Thompson }; 146ccaff030SJeremy L Thompson 147ccaff030SJeremy L Thompson // ----------------------------------------------------------------------------- 148ccaff030SJeremy L Thompson // Jacobian setup 149ccaff030SJeremy L Thompson // ----------------------------------------------------------------------------- 150ccaff030SJeremy L Thompson PetscErrorCode FormJacobian(SNES snes, Vec U, Mat J, Mat Jpre, void *ctx) { 151ccaff030SJeremy L Thompson PetscErrorCode ierr; 152ccaff030SJeremy L Thompson 153ccaff030SJeremy L Thompson PetscFunctionBeginUser; 154ccaff030SJeremy L Thompson 155ccaff030SJeremy L Thompson // Context data 156ccaff030SJeremy L Thompson FormJacobCtx formJacobCtx = (FormJacobCtx)ctx; 157ccaff030SJeremy L Thompson PetscInt numLevels = formJacobCtx->numLevels; 158ccaff030SJeremy L Thompson Mat *jacobMat = formJacobCtx->jacobMat; 159ccaff030SJeremy L Thompson 160e3e3df41Sjeremylt // Update Jacobian on each level 161e3e3df41Sjeremylt for (PetscInt level = 0; level < numLevels; level++) { 162ccaff030SJeremy L Thompson ierr = MatAssemblyBegin(jacobMat[level], MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 163ccaff030SJeremy L Thompson ierr = MatAssemblyEnd(jacobMat[level], MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 164ccaff030SJeremy L Thompson } 165ccaff030SJeremy L Thompson 166ccaff030SJeremy L Thompson // Form coarse assembled matrix 167ccaff030SJeremy L Thompson ierr = VecZeroEntries(formJacobCtx->Ucoarse); CHKERRQ(ierr); 168ccaff030SJeremy L Thompson ierr = SNESComputeJacobianDefaultColor(formJacobCtx->snesCoarse, 169ccaff030SJeremy L Thompson formJacobCtx->Ucoarse, 170ccaff030SJeremy L Thompson formJacobCtx->jacobMat[0], 171ccaff030SJeremy L Thompson formJacobCtx->jacobMatCoarse, NULL); 172ccaff030SJeremy L Thompson CHKERRQ(ierr); 173ccaff030SJeremy L Thompson 174ccaff030SJeremy L Thompson // Jpre might be AIJ (e.g., when using coloring), so we need to assemble it 175ccaff030SJeremy L Thompson ierr = MatAssemblyBegin(Jpre, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 176ccaff030SJeremy L Thompson ierr = MatAssemblyEnd(Jpre, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1770e0d204cSJed Brown if (J != Jpre) { 1780e0d204cSJed Brown ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1790e0d204cSJed Brown ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1800e0d204cSJed Brown } 181ccaff030SJeremy L Thompson PetscFunctionReturn(0); 182ccaff030SJeremy L Thompson }; 183ccaff030SJeremy L Thompson 184ccaff030SJeremy L Thompson // ----------------------------------------------------------------------------- 185ccaff030SJeremy L Thompson // Output solution for visualization 186ccaff030SJeremy L Thompson // ----------------------------------------------------------------------------- 187ccaff030SJeremy L Thompson PetscErrorCode ViewSolution(MPI_Comm comm, Vec U, PetscInt increment, 188ccaff030SJeremy L Thompson PetscScalar loadIncrement) { 189ccaff030SJeremy L Thompson PetscErrorCode ierr; 190ccaff030SJeremy L Thompson DM dm; 191ccaff030SJeremy L Thompson PetscViewer viewer; 192ccaff030SJeremy L Thompson char outputFilename[PETSC_MAX_PATH_LEN]; 193ccaff030SJeremy L Thompson 194ccaff030SJeremy L Thompson PetscFunctionBeginUser; 195ccaff030SJeremy L Thompson 196ccaff030SJeremy L Thompson // Build file name 197ccaff030SJeremy L Thompson ierr = PetscSNPrintf(outputFilename, sizeof outputFilename, 198ccaff030SJeremy L Thompson "solution-%03D.vtu", increment); CHKERRQ(ierr); 199ccaff030SJeremy L Thompson 200050e48ebSJeremy L Thompson // Increment sequence 201ccaff030SJeremy L Thompson ierr = VecGetDM(U, &dm); CHKERRQ(ierr); 202ccaff030SJeremy L Thompson ierr = DMSetOutputSequenceNumber(dm, increment, loadIncrement); CHKERRQ(ierr); 203ccaff030SJeremy L Thompson 204ccaff030SJeremy L Thompson // Output solution vector 205ccaff030SJeremy L Thompson ierr = PetscViewerVTKOpen(comm, outputFilename, FILE_MODE_WRITE, &viewer); 206ccaff030SJeremy L Thompson CHKERRQ(ierr); 207ccaff030SJeremy L Thompson ierr = VecView(U, viewer); CHKERRQ(ierr); 208ccaff030SJeremy L Thompson ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr); 209ccaff030SJeremy L Thompson 210ccaff030SJeremy L Thompson PetscFunctionReturn(0); 211ccaff030SJeremy L Thompson }; 2125c25879aSJeremy L Thompson 2135c25879aSJeremy L Thompson // ----------------------------------------------------------------------------- 2145c25879aSJeremy L Thompson // Output diagnostic quantities for visualization 2155c25879aSJeremy L Thompson // ----------------------------------------------------------------------------- 2165c25879aSJeremy L Thompson PetscErrorCode ViewDiagnosticQuantities(MPI_Comm comm, DM dmU, 2175c25879aSJeremy L Thompson UserMult user, Vec U, 2185c25879aSJeremy L Thompson CeedElemRestriction ErestrictDiagnostic) { 2195c25879aSJeremy L Thompson PetscErrorCode ierr; 2205c25879aSJeremy L Thompson Vec Diagnostic, Yloc, MultVec; 2215c25879aSJeremy L Thompson CeedVector Yceed; 2225c25879aSJeremy L Thompson CeedScalar *x, *y; 2235c25879aSJeremy L Thompson PetscInt lsz; 2245c25879aSJeremy L Thompson PetscViewer viewer; 2255c25879aSJeremy L Thompson const char *outputFilename = "diagnostic_quantities.vtu"; 2265c25879aSJeremy L Thompson 2275c25879aSJeremy L Thompson PetscFunctionBeginUser; 2285c25879aSJeremy L Thompson 2295c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 2305c25879aSJeremy L Thompson // PETSc and libCEED vectors 2315c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 2325c25879aSJeremy L Thompson ierr = DMCreateGlobalVector(user->dm, &Diagnostic); CHKERRQ(ierr); 233f81c27eaSJed Brown ierr = PetscObjectSetName((PetscObject)Diagnostic, ""); CHKERRQ(ierr); 2345c25879aSJeremy L Thompson ierr = DMCreateLocalVector(user->dm, &Yloc); CHKERRQ(ierr); 2355c25879aSJeremy L Thompson ierr = VecGetSize(Yloc, &lsz); CHKERRQ(ierr); 2365c25879aSJeremy L Thompson CeedVectorCreate(user->ceed, lsz, &Yceed); 2375c25879aSJeremy L Thompson 2385c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 2395c25879aSJeremy L Thompson // Compute quantities 2405c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 2415c25879aSJeremy L Thompson // -- Global-to-local 2425c25879aSJeremy L Thompson ierr = VecZeroEntries(user->Xloc); CHKERRQ(ierr); 2435c25879aSJeremy L Thompson ierr = DMPlexInsertBoundaryValues(dmU, PETSC_TRUE, user->Xloc, 2445c25879aSJeremy L Thompson user->loadIncrement, NULL, NULL, NULL); 2455c25879aSJeremy L Thompson CHKERRQ(ierr); 2465c25879aSJeremy L Thompson ierr = DMGlobalToLocal(dmU, U, INSERT_VALUES, user->Xloc); CHKERRQ(ierr); 2475c25879aSJeremy L Thompson ierr = VecZeroEntries(Yloc); CHKERRQ(ierr); 2485c25879aSJeremy L Thompson 2495c25879aSJeremy L Thompson // -- Setup CEED vectors 250*62e9c006SJeremy L Thompson ierr = user->VecGetArrayRead(user->Xloc, (const PetscScalar **)&x); 2515c25879aSJeremy L Thompson CHKERRQ(ierr); 252*62e9c006SJeremy L Thompson ierr = user->VecGetArray(Yloc, &y); CHKERRQ(ierr); 253*62e9c006SJeremy L Thompson CeedVectorSetArray(user->Xceed, user->memType, CEED_USE_POINTER, x); 254*62e9c006SJeremy L Thompson CeedVectorSetArray(Yceed, user->memType, CEED_USE_POINTER, y); 2555c25879aSJeremy L Thompson 2565c25879aSJeremy L Thompson // -- Apply CEED operator 2575c25879aSJeremy L Thompson CeedOperatorApply(user->op, user->Xceed, Yceed, CEED_REQUEST_IMMEDIATE); 258*62e9c006SJeremy L Thompson CeedVectorSyncArray(Yceed, user->memType); 2595c25879aSJeremy L Thompson 2605c25879aSJeremy L Thompson // -- Restore PETSc vectors 261*62e9c006SJeremy L Thompson ierr = user->VecRestoreArrayRead(user->Xloc, (const PetscScalar **)&x); 2625c25879aSJeremy L Thompson CHKERRQ(ierr); 2635c25879aSJeremy L Thompson 2645c25879aSJeremy L Thompson // -- Local-to-global 2655c25879aSJeremy L Thompson ierr = VecZeroEntries(Diagnostic); CHKERRQ(ierr); 2665c25879aSJeremy L Thompson ierr = DMLocalToGlobal(user->dm, Yloc, ADD_VALUES, Diagnostic); 2675c25879aSJeremy L Thompson CHKERRQ(ierr); 2685c25879aSJeremy L Thompson 2695c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 2705c25879aSJeremy L Thompson // Scale for multiplicity 2715c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 2725c25879aSJeremy L Thompson // -- Setup vectors 2735c25879aSJeremy L Thompson ierr = VecDuplicate(Diagnostic, &MultVec); CHKERRQ(ierr); 2745c25879aSJeremy L Thompson ierr = VecZeroEntries(Yloc); CHKERRQ(ierr); 2755c25879aSJeremy L Thompson 2765c25879aSJeremy L Thompson // -- Compute multiplicity 2775c25879aSJeremy L Thompson CeedElemRestrictionGetMultiplicity(ErestrictDiagnostic, Yceed); 2785c25879aSJeremy L Thompson 2795c25879aSJeremy L Thompson // -- Restore vectors 280*62e9c006SJeremy L Thompson ierr = user->VecRestoreArray(Yloc, &y); CHKERRQ(ierr); 2815c25879aSJeremy L Thompson 2825c25879aSJeremy L Thompson // -- Local-to-global 2835c25879aSJeremy L Thompson ierr = VecZeroEntries(MultVec); CHKERRQ(ierr); 2845c25879aSJeremy L Thompson ierr = DMLocalToGlobal(user->dm, Yloc, ADD_VALUES, MultVec); 2855c25879aSJeremy L Thompson CHKERRQ(ierr); 2865c25879aSJeremy L Thompson 2875c25879aSJeremy L Thompson // -- Scale 2885c25879aSJeremy L Thompson ierr = VecReciprocal(MultVec); CHKERRQ(ierr); 2895c25879aSJeremy L Thompson ierr = VecPointwiseMult(Diagnostic, Diagnostic, MultVec); 2905c25879aSJeremy L Thompson 2915c25879aSJeremy L Thompson 2925c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 2935c25879aSJeremy L Thompson // Output solution vector 2945c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 2955c25879aSJeremy L Thompson ierr = PetscViewerVTKOpen(comm, outputFilename, FILE_MODE_WRITE, &viewer); 2965c25879aSJeremy L Thompson CHKERRQ(ierr); 2975c25879aSJeremy L Thompson ierr = VecView(Diagnostic, viewer); CHKERRQ(ierr); 2985c25879aSJeremy L Thompson ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr); 2995c25879aSJeremy L Thompson 3005c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 3015c25879aSJeremy L Thompson // Cleanup 3025c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 3035c25879aSJeremy L Thompson ierr = VecDestroy(&Diagnostic); CHKERRQ(ierr); 3045c25879aSJeremy L Thompson ierr = VecDestroy(&MultVec); CHKERRQ(ierr); 3055c25879aSJeremy L Thompson ierr = VecDestroy(&Yloc); CHKERRQ(ierr); 3065c25879aSJeremy L Thompson CeedVectorDestroy(&Yceed); 3075c25879aSJeremy L Thompson 3085c25879aSJeremy L Thompson PetscFunctionReturn(0); 3095c25879aSJeremy L Thompson }; 310