xref: /libCEED/examples/solids/src/misc.c (revision 6a6c615b31508fbb9571bc7a279f860841ca2097)
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 
5562e9c006SJeremy L Thompson   // Get/Restore Array
5662e9c006SJeremy L Thompson   jacobianCtx->memType = appCtx->memTypeRequested;
5762e9c006SJeremy L Thompson   if (appCtx->memTypeRequested == CEED_MEM_HOST) {
5862e9c006SJeremy L Thompson     jacobianCtx->VecGetArray = VecGetArray;
5962e9c006SJeremy L Thompson     jacobianCtx->VecGetArrayRead = VecGetArrayRead;
6062e9c006SJeremy L Thompson     jacobianCtx->VecRestoreArray = VecRestoreArray;
6162e9c006SJeremy L Thompson     jacobianCtx->VecRestoreArrayRead = VecRestoreArrayRead;
6262e9c006SJeremy L Thompson   } else {
6362e9c006SJeremy L Thompson     jacobianCtx->VecGetArray = VecCUDAGetArray;
6462e9c006SJeremy L Thompson     jacobianCtx->VecGetArrayRead = VecCUDAGetArrayRead;
6562e9c006SJeremy L Thompson     jacobianCtx->VecRestoreArray = VecCUDARestoreArray;
6662e9c006SJeremy L Thompson     jacobianCtx->VecRestoreArrayRead = VecCUDARestoreArrayRead;
6762e9c006SJeremy L Thompson   }
6862e9c006SJeremy L Thompson 
69ccaff030SJeremy L Thompson   PetscFunctionReturn(0);
70ccaff030SJeremy L Thompson };
71ccaff030SJeremy L Thompson 
72ccaff030SJeremy L Thompson // Setup context data for prolongation and restriction operators
7362e9c006SJeremy L Thompson PetscErrorCode SetupProlongRestrictCtx(MPI_Comm comm, AppCtx appCtx, DM dmC,
7462e9c006SJeremy L Thompson                                        DM dmF, Vec VF, Vec VlocC, Vec VlocF,
7562e9c006SJeremy L Thompson                                        CeedData ceedDataC, CeedData ceedDataF,
7662e9c006SJeremy 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 
10162e9c006SJeremy L Thompson   // Get/Restore Array
10262e9c006SJeremy L Thompson   prolongRestrCtx->memType = appCtx->memTypeRequested;
10362e9c006SJeremy L Thompson   if (appCtx->memTypeRequested == CEED_MEM_HOST) {
10462e9c006SJeremy L Thompson     prolongRestrCtx->VecGetArray = VecGetArray;
10562e9c006SJeremy L Thompson     prolongRestrCtx->VecGetArrayRead = VecGetArrayRead;
10662e9c006SJeremy L Thompson     prolongRestrCtx->VecRestoreArray = VecRestoreArray;
10762e9c006SJeremy L Thompson     prolongRestrCtx->VecRestoreArrayRead = VecRestoreArrayRead;
10862e9c006SJeremy L Thompson   } else {
10962e9c006SJeremy L Thompson     prolongRestrCtx->VecGetArray = VecCUDAGetArray;
11062e9c006SJeremy L Thompson     prolongRestrCtx->VecGetArrayRead = VecCUDAGetArrayRead;
11162e9c006SJeremy L Thompson     prolongRestrCtx->VecRestoreArray = VecCUDARestoreArray;
11262e9c006SJeremy L Thompson     prolongRestrCtx->VecRestoreArrayRead = VecCUDARestoreArrayRead;
11362e9c006SJeremy L Thompson   }
11462e9c006SJeremy L Thompson 
115ccaff030SJeremy L Thompson   // Multiplicity vector
116ccaff030SJeremy L Thompson   // -- Set libCEED vector
117ccaff030SJeremy L Thompson   ierr = VecZeroEntries(VlocF);
11862e9c006SJeremy L Thompson   ierr = prolongRestrCtx->VecGetArray(VlocF, &multArray); CHKERRQ(ierr);
11962e9c006SJeremy L Thompson   CeedVectorSetArray(ceedDataF->xceed, appCtx->memTypeRequested,
12062e9c006SJeremy 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*6a6c615bSJeremy L Thompson   CeedVectorTakeArray(ceedDataF->xceed, appCtx->memTypeRequested, NULL);
12762e9c006SJeremy L Thompson   ierr = prolongRestrCtx->VecRestoreArray(VlocF, &multArray); CHKERRQ(ierr);
128ccaff030SJeremy L Thompson 
129ccaff030SJeremy L Thompson   // -- Local-to-global
130ccaff030SJeremy L Thompson   ierr = VecZeroEntries(VF); CHKERRQ(ierr);
131ccaff030SJeremy L Thompson   ierr = DMLocalToGlobal(dmF, VlocF, ADD_VALUES, VF); CHKERRQ(ierr);
132ccaff030SJeremy L Thompson 
133ccaff030SJeremy L Thompson   // -- Global-to-local
134ccaff030SJeremy L Thompson   ierr = VecDuplicate(VlocF, &prolongRestrCtx->multVec); CHKERRQ(ierr);
135ccaff030SJeremy L Thompson   ierr = DMGlobalToLocal(dmF, VF, INSERT_VALUES, prolongRestrCtx->multVec);
136ccaff030SJeremy L Thompson   CHKERRQ(ierr);
137ccaff030SJeremy L Thompson 
138ccaff030SJeremy L Thompson   // -- Reciprocal
139ccaff030SJeremy L Thompson   ierr = VecReciprocal(prolongRestrCtx->multVec); CHKERRQ(ierr);
140ccaff030SJeremy L Thompson 
141ccaff030SJeremy L Thompson   // -- Reset work arrays
142ccaff030SJeremy L Thompson   ierr = VecZeroEntries(VF); CHKERRQ(ierr);
143ccaff030SJeremy L Thompson   ierr = VecZeroEntries(VlocF); CHKERRQ(ierr);
144ccaff030SJeremy L Thompson 
145ccaff030SJeremy L Thompson   PetscFunctionReturn(0);
146ccaff030SJeremy L Thompson };
147ccaff030SJeremy L Thompson 
148ccaff030SJeremy L Thompson // -----------------------------------------------------------------------------
149ccaff030SJeremy L Thompson // Jacobian setup
150ccaff030SJeremy L Thompson // -----------------------------------------------------------------------------
151ccaff030SJeremy L Thompson PetscErrorCode FormJacobian(SNES snes, Vec U, Mat J, Mat Jpre, void *ctx) {
152ccaff030SJeremy L Thompson   PetscErrorCode ierr;
153ccaff030SJeremy L Thompson 
154ccaff030SJeremy L Thompson   PetscFunctionBeginUser;
155ccaff030SJeremy L Thompson 
156ccaff030SJeremy L Thompson   // Context data
157ccaff030SJeremy L Thompson   FormJacobCtx  formJacobCtx = (FormJacobCtx)ctx;
158ccaff030SJeremy L Thompson   PetscInt      numLevels = formJacobCtx->numLevels;
159ccaff030SJeremy L Thompson   Mat           *jacobMat = formJacobCtx->jacobMat;
160ccaff030SJeremy L Thompson 
161e3e3df41Sjeremylt   // Update Jacobian on each level
162e3e3df41Sjeremylt   for (PetscInt level = 0; level < numLevels; level++) {
163ccaff030SJeremy L Thompson     ierr = MatAssemblyBegin(jacobMat[level], MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
164ccaff030SJeremy L Thompson     ierr = MatAssemblyEnd(jacobMat[level], MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
165ccaff030SJeremy L Thompson   }
166ccaff030SJeremy L Thompson 
167ccaff030SJeremy L Thompson   // Form coarse assembled matrix
168ccaff030SJeremy L Thompson   ierr = VecZeroEntries(formJacobCtx->Ucoarse); CHKERRQ(ierr);
169ccaff030SJeremy L Thompson   ierr = SNESComputeJacobianDefaultColor(formJacobCtx->snesCoarse,
170ccaff030SJeremy L Thompson                                          formJacobCtx->Ucoarse,
171ccaff030SJeremy L Thompson                                          formJacobCtx->jacobMat[0],
172ccaff030SJeremy L Thompson                                          formJacobCtx->jacobMatCoarse, NULL);
173ccaff030SJeremy L Thompson   CHKERRQ(ierr);
174ccaff030SJeremy L Thompson 
175ccaff030SJeremy L Thompson   // Jpre might be AIJ (e.g., when using coloring), so we need to assemble it
176ccaff030SJeremy L Thompson   ierr = MatAssemblyBegin(Jpre, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
177ccaff030SJeremy L Thompson   ierr = MatAssemblyEnd(Jpre, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1780e0d204cSJed Brown   if (J != Jpre) {
1790e0d204cSJed Brown     ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1800e0d204cSJed Brown     ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1810e0d204cSJed Brown   }
182ccaff030SJeremy L Thompson   PetscFunctionReturn(0);
183ccaff030SJeremy L Thompson };
184ccaff030SJeremy L Thompson 
185ccaff030SJeremy L Thompson // -----------------------------------------------------------------------------
186ccaff030SJeremy L Thompson // Output solution for visualization
187ccaff030SJeremy L Thompson // -----------------------------------------------------------------------------
188ccaff030SJeremy L Thompson PetscErrorCode ViewSolution(MPI_Comm comm, Vec U, PetscInt increment,
189ccaff030SJeremy L Thompson                             PetscScalar loadIncrement) {
190ccaff030SJeremy L Thompson   PetscErrorCode ierr;
191ccaff030SJeremy L Thompson   DM dm;
192ccaff030SJeremy L Thompson   PetscViewer viewer;
193ccaff030SJeremy L Thompson   char outputFilename[PETSC_MAX_PATH_LEN];
194ccaff030SJeremy L Thompson 
195ccaff030SJeremy L Thompson   PetscFunctionBeginUser;
196ccaff030SJeremy L Thompson 
197ccaff030SJeremy L Thompson   // Build file name
198ccaff030SJeremy L Thompson   ierr = PetscSNPrintf(outputFilename, sizeof outputFilename,
199ccaff030SJeremy L Thompson                        "solution-%03D.vtu", increment); CHKERRQ(ierr);
200ccaff030SJeremy L Thompson 
201050e48ebSJeremy L Thompson   // Increment sequence
202ccaff030SJeremy L Thompson   ierr = VecGetDM(U, &dm); CHKERRQ(ierr);
203ccaff030SJeremy L Thompson   ierr = DMSetOutputSequenceNumber(dm, increment, loadIncrement); CHKERRQ(ierr);
204ccaff030SJeremy L Thompson 
205ccaff030SJeremy L Thompson   // Output solution vector
206ccaff030SJeremy L Thompson   ierr = PetscViewerVTKOpen(comm, outputFilename, FILE_MODE_WRITE, &viewer);
207ccaff030SJeremy L Thompson   CHKERRQ(ierr);
208ccaff030SJeremy L Thompson   ierr = VecView(U, viewer); CHKERRQ(ierr);
209ccaff030SJeremy L Thompson   ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr);
210ccaff030SJeremy L Thompson 
211ccaff030SJeremy L Thompson   PetscFunctionReturn(0);
212ccaff030SJeremy L Thompson };
2135c25879aSJeremy L Thompson 
2145c25879aSJeremy L Thompson // -----------------------------------------------------------------------------
2155c25879aSJeremy L Thompson // Output diagnostic quantities for visualization
2165c25879aSJeremy L Thompson // -----------------------------------------------------------------------------
2175c25879aSJeremy L Thompson PetscErrorCode ViewDiagnosticQuantities(MPI_Comm comm, DM dmU,
2185c25879aSJeremy L Thompson                                         UserMult user, Vec U,
2195c25879aSJeremy L Thompson                                         CeedElemRestriction ErestrictDiagnostic) {
2205c25879aSJeremy L Thompson   PetscErrorCode ierr;
2215c25879aSJeremy L Thompson   Vec Diagnostic, Yloc, MultVec;
2225c25879aSJeremy L Thompson   CeedVector Yceed;
2235c25879aSJeremy L Thompson   CeedScalar *x, *y;
2245c25879aSJeremy L Thompson   PetscInt lsz;
2255c25879aSJeremy L Thompson   PetscViewer viewer;
2265c25879aSJeremy L Thompson   const char *outputFilename = "diagnostic_quantities.vtu";
2275c25879aSJeremy L Thompson 
2285c25879aSJeremy L Thompson   PetscFunctionBeginUser;
2295c25879aSJeremy L Thompson 
2305c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
2315c25879aSJeremy L Thompson   // PETSc and libCEED vectors
2325c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
2335c25879aSJeremy L Thompson   ierr = DMCreateGlobalVector(user->dm, &Diagnostic); CHKERRQ(ierr);
234f81c27eaSJed Brown   ierr = PetscObjectSetName((PetscObject)Diagnostic, ""); CHKERRQ(ierr);
2355c25879aSJeremy L Thompson   ierr = DMCreateLocalVector(user->dm, &Yloc); CHKERRQ(ierr);
2365c25879aSJeremy L Thompson   ierr = VecGetSize(Yloc, &lsz); CHKERRQ(ierr);
2375c25879aSJeremy L Thompson   CeedVectorCreate(user->ceed, lsz, &Yceed);
2385c25879aSJeremy L Thompson 
2395c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
2405c25879aSJeremy L Thompson   // Compute quantities
2415c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
2425c25879aSJeremy L Thompson   // -- Global-to-local
2435c25879aSJeremy L Thompson   ierr = VecZeroEntries(user->Xloc); CHKERRQ(ierr);
2445c25879aSJeremy L Thompson   ierr = DMPlexInsertBoundaryValues(dmU, PETSC_TRUE, user->Xloc,
2455c25879aSJeremy L Thompson                                     user->loadIncrement, NULL, NULL, NULL);
2465c25879aSJeremy L Thompson   CHKERRQ(ierr);
2475c25879aSJeremy L Thompson   ierr = DMGlobalToLocal(dmU, U, INSERT_VALUES, user->Xloc); CHKERRQ(ierr);
2485c25879aSJeremy L Thompson   ierr = VecZeroEntries(Yloc); CHKERRQ(ierr);
2495c25879aSJeremy L Thompson 
2505c25879aSJeremy L Thompson   // -- Setup CEED vectors
25162e9c006SJeremy L Thompson   ierr = user->VecGetArrayRead(user->Xloc, (const PetscScalar **)&x);
2525c25879aSJeremy L Thompson   CHKERRQ(ierr);
25362e9c006SJeremy L Thompson   ierr = user->VecGetArray(Yloc, &y); CHKERRQ(ierr);
25462e9c006SJeremy L Thompson   CeedVectorSetArray(user->Xceed, user->memType, CEED_USE_POINTER, x);
25562e9c006SJeremy L Thompson   CeedVectorSetArray(Yceed, user->memType, CEED_USE_POINTER, y);
2565c25879aSJeremy L Thompson 
2575c25879aSJeremy L Thompson   // -- Apply CEED operator
2585c25879aSJeremy L Thompson   CeedOperatorApply(user->op, user->Xceed, Yceed, CEED_REQUEST_IMMEDIATE);
2595c25879aSJeremy L Thompson 
260*6a6c615bSJeremy L Thompson   // -- Restore PETSc vector
261*6a6c615bSJeremy L Thompson   CeedVectorTakeArray(user->Xceed, user->memType, NULL);
26262e9c006SJeremy L Thompson   ierr = user->VecRestoreArrayRead(user->Xloc, (const PetscScalar **)&x);
2635c25879aSJeremy L Thompson   CHKERRQ(ierr);
2645c25879aSJeremy L Thompson 
2655c25879aSJeremy L Thompson   // -- Local-to-global
2665c25879aSJeremy L Thompson   ierr = VecZeroEntries(Diagnostic); CHKERRQ(ierr);
2675c25879aSJeremy L Thompson   ierr = DMLocalToGlobal(user->dm, Yloc, ADD_VALUES, Diagnostic);
2685c25879aSJeremy L Thompson   CHKERRQ(ierr);
2695c25879aSJeremy L Thompson 
2705c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
2715c25879aSJeremy L Thompson   // Scale for multiplicity
2725c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
2735c25879aSJeremy L Thompson   // -- Setup vectors
2745c25879aSJeremy L Thompson   ierr = VecDuplicate(Diagnostic, &MultVec); CHKERRQ(ierr);
2755c25879aSJeremy L Thompson   ierr = VecZeroEntries(Yloc); CHKERRQ(ierr);
2765c25879aSJeremy L Thompson 
2775c25879aSJeremy L Thompson   // -- Compute multiplicity
2785c25879aSJeremy L Thompson   CeedElemRestrictionGetMultiplicity(ErestrictDiagnostic, Yceed);
2795c25879aSJeremy L Thompson 
2805c25879aSJeremy L Thompson   // -- Restore vectors
281*6a6c615bSJeremy L Thompson   CeedVectorTakeArray(Yceed, user->memType, NULL);
28262e9c006SJeremy L Thompson   ierr = user->VecRestoreArray(Yloc, &y); CHKERRQ(ierr);
2835c25879aSJeremy L Thompson 
2845c25879aSJeremy L Thompson   // -- Local-to-global
2855c25879aSJeremy L Thompson   ierr = VecZeroEntries(MultVec); CHKERRQ(ierr);
2865c25879aSJeremy L Thompson   ierr = DMLocalToGlobal(user->dm, Yloc, ADD_VALUES, MultVec);
2875c25879aSJeremy L Thompson   CHKERRQ(ierr);
2885c25879aSJeremy L Thompson 
2895c25879aSJeremy L Thompson   // -- Scale
2905c25879aSJeremy L Thompson   ierr = VecReciprocal(MultVec); CHKERRQ(ierr);
2915c25879aSJeremy L Thompson   ierr = VecPointwiseMult(Diagnostic, Diagnostic, MultVec);
2925c25879aSJeremy L Thompson 
2935c25879aSJeremy L Thompson 
2945c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
2955c25879aSJeremy L Thompson   // Output solution vector
2965c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
2975c25879aSJeremy L Thompson   ierr = PetscViewerVTKOpen(comm, outputFilename, FILE_MODE_WRITE, &viewer);
2985c25879aSJeremy L Thompson   CHKERRQ(ierr);
2995c25879aSJeremy L Thompson   ierr = VecView(Diagnostic, viewer); CHKERRQ(ierr);
3005c25879aSJeremy L Thompson   ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr);
3015c25879aSJeremy L Thompson 
3025c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
3035c25879aSJeremy L Thompson   // Cleanup
3045c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
3055c25879aSJeremy L Thompson   ierr = VecDestroy(&Diagnostic); CHKERRQ(ierr);
3065c25879aSJeremy L Thompson   ierr = VecDestroy(&MultVec); CHKERRQ(ierr);
3075c25879aSJeremy L Thompson   ierr = VecDestroy(&Yloc); CHKERRQ(ierr);
3085c25879aSJeremy L Thompson   CeedVectorDestroy(&Yceed);
3095c25879aSJeremy L Thompson 
3105c25879aSJeremy L Thompson   PetscFunctionReturn(0);
3115c25879aSJeremy L Thompson };
312