xref: /libCEED/examples/solids/src/misc.c (revision 5c25879a8ff80373d5be013119a867f98bfe2528)
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,
28ccaff030SJeremy L Thompson                                 UserMult jacobianCtx) {
29ccaff030SJeremy L Thompson   PetscErrorCode ierr;
30ccaff030SJeremy L Thompson 
31ccaff030SJeremy L Thompson   PetscFunctionBeginUser;
32ccaff030SJeremy L Thompson 
33ccaff030SJeremy L Thompson   // PETSc objects
34ccaff030SJeremy L Thompson   jacobianCtx->comm = comm;
35ccaff030SJeremy L Thompson   jacobianCtx->dm = dm;
36ccaff030SJeremy L Thompson 
37ccaff030SJeremy L Thompson   // Work vectors
38ccaff030SJeremy L Thompson   jacobianCtx->Xloc = Vloc;
39ccaff030SJeremy L Thompson   ierr = VecDuplicate(Vloc, &jacobianCtx->Yloc); CHKERRQ(ierr);
40ccaff030SJeremy L Thompson   jacobianCtx->Xceed = ceedData->xceed;
41ccaff030SJeremy L Thompson   jacobianCtx->Yceed = ceedData->yceed;
42ccaff030SJeremy L Thompson 
43ccaff030SJeremy L Thompson   // libCEED operator
44ccaff030SJeremy L Thompson   jacobianCtx->op = ceedData->opJacob;
45ccaff030SJeremy L Thompson 
46ccaff030SJeremy L Thompson   // Ceed
47ccaff030SJeremy L Thompson   jacobianCtx->ceed = ceed;
48ccaff030SJeremy L Thompson 
49ccaff030SJeremy L Thompson   PetscFunctionReturn(0);
50ccaff030SJeremy L Thompson };
51ccaff030SJeremy L Thompson 
52ccaff030SJeremy L Thompson // Setup context data for prolongation and restriction operators
53ccaff030SJeremy L Thompson PetscErrorCode SetupProlongRestrictCtx(MPI_Comm comm, DM dmC, DM dmF, Vec VF,
54ccaff030SJeremy L Thompson                                        Vec VlocC, Vec VlocF, CeedData ceedDataC,
55ccaff030SJeremy L Thompson                                        CeedData ceedDataF, Ceed ceed,
56ccaff030SJeremy L Thompson                                        UserMultProlongRestr prolongRestrCtx) {
57ccaff030SJeremy L Thompson   PetscErrorCode ierr;
58ccaff030SJeremy L Thompson   PetscScalar *multArray;
59ccaff030SJeremy L Thompson 
60ccaff030SJeremy L Thompson   PetscFunctionBeginUser;
61ccaff030SJeremy L Thompson 
62ccaff030SJeremy L Thompson   // PETSc objects
63ccaff030SJeremy L Thompson   prolongRestrCtx->comm = comm;
64ccaff030SJeremy L Thompson   prolongRestrCtx->dmC = dmC;
65ccaff030SJeremy L Thompson   prolongRestrCtx->dmF = dmF;
66ccaff030SJeremy L Thompson 
67ccaff030SJeremy L Thompson   // Work vectors
68ccaff030SJeremy L Thompson   prolongRestrCtx->locVecC = VlocC;
69ccaff030SJeremy L Thompson   prolongRestrCtx->locVecF = VlocF;
70ccaff030SJeremy L Thompson   prolongRestrCtx->ceedVecC = ceedDataC->xceed;
71ccaff030SJeremy L Thompson   prolongRestrCtx->ceedVecF = ceedDataF->xceed;
72ccaff030SJeremy L Thompson 
73ccaff030SJeremy L Thompson   // libCEED operators
74ccaff030SJeremy L Thompson   prolongRestrCtx->opProlong = ceedDataF->opProlong;
75ccaff030SJeremy L Thompson   prolongRestrCtx->opRestrict = ceedDataF->opRestrict;
76ccaff030SJeremy L Thompson 
77ccaff030SJeremy L Thompson   // Ceed
78ccaff030SJeremy L Thompson   prolongRestrCtx->ceed = ceed;
79ccaff030SJeremy L Thompson 
80ccaff030SJeremy L Thompson   // Multiplicity vector
81ccaff030SJeremy L Thompson   // -- Set libCEED vector
82ccaff030SJeremy L Thompson   ierr = VecZeroEntries(VlocF);
83ccaff030SJeremy L Thompson   ierr = VecGetArray(VlocF, &multArray); CHKERRQ(ierr);
84ccaff030SJeremy L Thompson   CeedVectorSetArray(ceedDataF->xceed, CEED_MEM_HOST, CEED_USE_POINTER,
85ccaff030SJeremy L Thompson                      multArray);
86ccaff030SJeremy L Thompson 
87ccaff030SJeremy L Thompson   // -- Compute multiplicity
88ccaff030SJeremy L Thompson   CeedElemRestrictionGetMultiplicity(ceedDataF->Erestrictu, ceedDataF->xceed);
89ccaff030SJeremy L Thompson 
90ccaff030SJeremy L Thompson   // -- Restore PETSc vector
91ccaff030SJeremy L Thompson   ierr = VecRestoreArray(VlocF, &multArray); CHKERRQ(ierr);
92ccaff030SJeremy L Thompson 
93ccaff030SJeremy L Thompson   // -- Local-to-global
94ccaff030SJeremy L Thompson   ierr = VecZeroEntries(VF); CHKERRQ(ierr);
95ccaff030SJeremy L Thompson   ierr = DMLocalToGlobal(dmF, VlocF, ADD_VALUES, VF); CHKERRQ(ierr);
96ccaff030SJeremy L Thompson 
97ccaff030SJeremy L Thompson   // -- Global-to-local
98ccaff030SJeremy L Thompson   ierr = VecDuplicate(VlocF, &prolongRestrCtx->multVec); CHKERRQ(ierr);
99ccaff030SJeremy L Thompson   ierr = DMGlobalToLocal(dmF, VF, INSERT_VALUES, prolongRestrCtx->multVec);
100ccaff030SJeremy L Thompson   CHKERRQ(ierr);
101ccaff030SJeremy L Thompson 
102ccaff030SJeremy L Thompson   // -- Reciprocal
103ccaff030SJeremy L Thompson   ierr = VecReciprocal(prolongRestrCtx->multVec); CHKERRQ(ierr);
104ccaff030SJeremy L Thompson 
105ccaff030SJeremy L Thompson   // -- Reset work arrays
106ccaff030SJeremy L Thompson   ierr = VecZeroEntries(VF); CHKERRQ(ierr);
107ccaff030SJeremy L Thompson   ierr = VecZeroEntries(VlocF); CHKERRQ(ierr);
108ccaff030SJeremy L Thompson 
109ccaff030SJeremy L Thompson   PetscFunctionReturn(0);
110ccaff030SJeremy L Thompson };
111ccaff030SJeremy L Thompson 
112ccaff030SJeremy L Thompson // -----------------------------------------------------------------------------
113ccaff030SJeremy L Thompson // Jacobian setup
114ccaff030SJeremy L Thompson // -----------------------------------------------------------------------------
115ccaff030SJeremy L Thompson PetscErrorCode FormJacobian(SNES snes, Vec U, Mat J, Mat Jpre, void *ctx) {
116ccaff030SJeremy L Thompson   PetscErrorCode ierr;
117ccaff030SJeremy L Thompson 
118ccaff030SJeremy L Thompson   PetscFunctionBeginUser;
119ccaff030SJeremy L Thompson 
120ccaff030SJeremy L Thompson   // Context data
121ccaff030SJeremy L Thompson   FormJacobCtx  formJacobCtx = (FormJacobCtx)ctx;
122ccaff030SJeremy L Thompson   PetscInt      numLevels = formJacobCtx->numLevels;
123ccaff030SJeremy L Thompson   Mat           *jacobMat = formJacobCtx->jacobMat;
124ccaff030SJeremy L Thompson 
125e3e3df41Sjeremylt   // Update Jacobian on each level
126e3e3df41Sjeremylt   for (PetscInt level = 0; level < numLevels; level++) {
127ccaff030SJeremy L Thompson     ierr = MatAssemblyBegin(jacobMat[level], MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
128ccaff030SJeremy L Thompson     ierr = MatAssemblyEnd(jacobMat[level], MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
129ccaff030SJeremy L Thompson   }
130ccaff030SJeremy L Thompson 
131ccaff030SJeremy L Thompson   // Form coarse assembled matrix
132ccaff030SJeremy L Thompson   ierr = VecZeroEntries(formJacobCtx->Ucoarse); CHKERRQ(ierr);
133ccaff030SJeremy L Thompson   ierr = SNESComputeJacobianDefaultColor(formJacobCtx->snesCoarse,
134ccaff030SJeremy L Thompson                                          formJacobCtx->Ucoarse,
135ccaff030SJeremy L Thompson                                          formJacobCtx->jacobMat[0],
136ccaff030SJeremy L Thompson                                          formJacobCtx->jacobMatCoarse, NULL);
137ccaff030SJeremy L Thompson   CHKERRQ(ierr);
138ccaff030SJeremy L Thompson 
139ccaff030SJeremy L Thompson   // Jpre might be AIJ (e.g., when using coloring), so we need to assemble it
140ccaff030SJeremy L Thompson   ierr = MatAssemblyBegin(Jpre, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
141ccaff030SJeremy L Thompson   ierr = MatAssemblyEnd(Jpre, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1420e0d204cSJed Brown   if (J != Jpre) {
1430e0d204cSJed Brown     ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1440e0d204cSJed Brown     ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1450e0d204cSJed Brown   }
146ccaff030SJeremy L Thompson   PetscFunctionReturn(0);
147ccaff030SJeremy L Thompson };
148ccaff030SJeremy L Thompson 
149ccaff030SJeremy L Thompson // -----------------------------------------------------------------------------
150ccaff030SJeremy L Thompson // Output solution for visualization
151ccaff030SJeremy L Thompson // -----------------------------------------------------------------------------
152ccaff030SJeremy L Thompson PetscErrorCode ViewSolution(MPI_Comm comm, Vec U, PetscInt increment,
153ccaff030SJeremy L Thompson                             PetscScalar loadIncrement) {
154ccaff030SJeremy L Thompson   PetscErrorCode ierr;
155ccaff030SJeremy L Thompson   DM dm;
156ccaff030SJeremy L Thompson   PetscViewer viewer;
157ccaff030SJeremy L Thompson   char outputFilename[PETSC_MAX_PATH_LEN];
158ccaff030SJeremy L Thompson 
159ccaff030SJeremy L Thompson   PetscFunctionBeginUser;
160ccaff030SJeremy L Thompson 
161ccaff030SJeremy L Thompson   // Build file name
162ccaff030SJeremy L Thompson   ierr = PetscSNPrintf(outputFilename, sizeof outputFilename,
163ccaff030SJeremy L Thompson                        "solution-%03D.vtu", increment); CHKERRQ(ierr);
164ccaff030SJeremy L Thompson 
165050e48ebSJeremy L Thompson   // Increment sequence
166ccaff030SJeremy L Thompson   ierr = VecGetDM(U, &dm); CHKERRQ(ierr);
167ccaff030SJeremy L Thompson   ierr = DMSetOutputSequenceNumber(dm, increment, loadIncrement); CHKERRQ(ierr);
168ccaff030SJeremy L Thompson 
169ccaff030SJeremy L Thompson   // Output solution vector
170ccaff030SJeremy L Thompson   ierr = PetscViewerVTKOpen(comm, outputFilename, FILE_MODE_WRITE, &viewer);
171ccaff030SJeremy L Thompson   CHKERRQ(ierr);
172ccaff030SJeremy L Thompson   ierr = VecView(U, viewer); CHKERRQ(ierr);
173ccaff030SJeremy L Thompson   ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr);
174ccaff030SJeremy L Thompson 
175ccaff030SJeremy L Thompson   PetscFunctionReturn(0);
176ccaff030SJeremy L Thompson };
177*5c25879aSJeremy L Thompson 
178*5c25879aSJeremy L Thompson // -----------------------------------------------------------------------------
179*5c25879aSJeremy L Thompson // Output diagnostic quantities for visualization
180*5c25879aSJeremy L Thompson // -----------------------------------------------------------------------------
181*5c25879aSJeremy L Thompson PetscErrorCode ViewDiagnosticQuantities(MPI_Comm comm, DM dmU,
182*5c25879aSJeremy L Thompson                                         UserMult user, Vec U,
183*5c25879aSJeremy L Thompson                                         CeedElemRestriction ErestrictDiagnostic) {
184*5c25879aSJeremy L Thompson   PetscErrorCode ierr;
185*5c25879aSJeremy L Thompson   Vec Diagnostic, Yloc, MultVec;
186*5c25879aSJeremy L Thompson   CeedVector Yceed;
187*5c25879aSJeremy L Thompson   CeedScalar *x, *y;
188*5c25879aSJeremy L Thompson   PetscInt lsz;
189*5c25879aSJeremy L Thompson   PetscViewer viewer;
190*5c25879aSJeremy L Thompson   const char *outputFilename = "diagnostic_quantities.vtu";
191*5c25879aSJeremy L Thompson 
192*5c25879aSJeremy L Thompson   PetscFunctionBeginUser;
193*5c25879aSJeremy L Thompson 
194*5c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
195*5c25879aSJeremy L Thompson   // PETSc and libCEED vectors
196*5c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
197*5c25879aSJeremy L Thompson   ierr = DMCreateGlobalVector(user->dm, &Diagnostic); CHKERRQ(ierr);
198*5c25879aSJeremy L Thompson   ierr = DMCreateLocalVector(user->dm, &Yloc); CHKERRQ(ierr);
199*5c25879aSJeremy L Thompson   ierr = VecGetSize(Yloc, &lsz); CHKERRQ(ierr);
200*5c25879aSJeremy L Thompson   CeedVectorCreate(user->ceed, lsz, &Yceed);
201*5c25879aSJeremy L Thompson 
202*5c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
203*5c25879aSJeremy L Thompson   // Compute quantities
204*5c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
205*5c25879aSJeremy L Thompson   // -- Global-to-local
206*5c25879aSJeremy L Thompson   ierr = VecZeroEntries(user->Xloc); CHKERRQ(ierr);
207*5c25879aSJeremy L Thompson   ierr = DMPlexInsertBoundaryValues(dmU, PETSC_TRUE, user->Xloc,
208*5c25879aSJeremy L Thompson                                     user->loadIncrement, NULL, NULL, NULL);
209*5c25879aSJeremy L Thompson   CHKERRQ(ierr);
210*5c25879aSJeremy L Thompson   ierr = DMGlobalToLocal(dmU, U, INSERT_VALUES, user->Xloc); CHKERRQ(ierr);
211*5c25879aSJeremy L Thompson   ierr = VecZeroEntries(Yloc); CHKERRQ(ierr);
212*5c25879aSJeremy L Thompson 
213*5c25879aSJeremy L Thompson   // -- Setup CEED vectors
214*5c25879aSJeremy L Thompson   ierr = VecGetArrayRead(user->Xloc, (const PetscScalar **)&x);
215*5c25879aSJeremy L Thompson   CHKERRQ(ierr);
216*5c25879aSJeremy L Thompson   ierr = VecGetArray(Yloc, &y); CHKERRQ(ierr);
217*5c25879aSJeremy L Thompson   CeedVectorSetArray(user->Xceed, CEED_MEM_HOST, CEED_USE_POINTER, x);
218*5c25879aSJeremy L Thompson   CeedVectorSetArray(Yceed, CEED_MEM_HOST, CEED_USE_POINTER, y);
219*5c25879aSJeremy L Thompson 
220*5c25879aSJeremy L Thompson   // -- Apply CEED operator
221*5c25879aSJeremy L Thompson   CeedOperatorApply(user->op, user->Xceed, Yceed, CEED_REQUEST_IMMEDIATE);
222*5c25879aSJeremy L Thompson   CeedVectorSyncArray(Yceed, CEED_MEM_HOST);
223*5c25879aSJeremy L Thompson 
224*5c25879aSJeremy L Thompson   // -- Restore PETSc vectors
225*5c25879aSJeremy L Thompson   ierr = VecRestoreArrayRead(user->Xloc, (const PetscScalar **)&x);
226*5c25879aSJeremy L Thompson   CHKERRQ(ierr);
227*5c25879aSJeremy L Thompson 
228*5c25879aSJeremy L Thompson   // -- Local-to-global
229*5c25879aSJeremy L Thompson   ierr = VecZeroEntries(Diagnostic); CHKERRQ(ierr);
230*5c25879aSJeremy L Thompson   ierr = DMLocalToGlobal(user->dm, Yloc, ADD_VALUES, Diagnostic);
231*5c25879aSJeremy L Thompson   CHKERRQ(ierr);
232*5c25879aSJeremy L Thompson 
233*5c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
234*5c25879aSJeremy L Thompson   // Scale for multiplicity
235*5c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
236*5c25879aSJeremy L Thompson   // -- Setup vectors
237*5c25879aSJeremy L Thompson   ierr = VecDuplicate(Diagnostic, &MultVec); CHKERRQ(ierr);
238*5c25879aSJeremy L Thompson   ierr = VecZeroEntries(Yloc); CHKERRQ(ierr);
239*5c25879aSJeremy L Thompson 
240*5c25879aSJeremy L Thompson   // -- Compute multiplicity
241*5c25879aSJeremy L Thompson   CeedElemRestrictionGetMultiplicity(ErestrictDiagnostic, Yceed);
242*5c25879aSJeremy L Thompson 
243*5c25879aSJeremy L Thompson   // -- Restore vectors
244*5c25879aSJeremy L Thompson   ierr = VecRestoreArray(Yloc, &y); CHKERRQ(ierr);
245*5c25879aSJeremy L Thompson 
246*5c25879aSJeremy L Thompson   // -- Local-to-global
247*5c25879aSJeremy L Thompson   ierr = VecZeroEntries(MultVec); CHKERRQ(ierr);
248*5c25879aSJeremy L Thompson   ierr = DMLocalToGlobal(user->dm, Yloc, ADD_VALUES, MultVec);
249*5c25879aSJeremy L Thompson   CHKERRQ(ierr);
250*5c25879aSJeremy L Thompson 
251*5c25879aSJeremy L Thompson   // -- Scale
252*5c25879aSJeremy L Thompson   ierr = VecReciprocal(MultVec); CHKERRQ(ierr);
253*5c25879aSJeremy L Thompson   ierr = VecPointwiseMult(Diagnostic, Diagnostic, MultVec);
254*5c25879aSJeremy L Thompson 
255*5c25879aSJeremy L Thompson 
256*5c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
257*5c25879aSJeremy L Thompson   // Output solution vector
258*5c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
259*5c25879aSJeremy L Thompson   ierr = PetscViewerVTKOpen(comm, outputFilename, FILE_MODE_WRITE, &viewer);
260*5c25879aSJeremy L Thompson   CHKERRQ(ierr);
261*5c25879aSJeremy L Thompson   ierr = VecView(Diagnostic, viewer); CHKERRQ(ierr);
262*5c25879aSJeremy L Thompson   ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr);
263*5c25879aSJeremy L Thompson 
264*5c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
265*5c25879aSJeremy L Thompson   // Cleanup
266*5c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
267*5c25879aSJeremy L Thompson   ierr = VecDestroy(&Diagnostic); CHKERRQ(ierr);
268*5c25879aSJeremy L Thompson   ierr = VecDestroy(&MultVec); CHKERRQ(ierr);
269*5c25879aSJeremy L Thompson   ierr = VecDestroy(&Yloc); CHKERRQ(ierr);
270*5c25879aSJeremy L Thompson   CeedVectorDestroy(&Yceed);
271*5c25879aSJeremy L Thompson 
272*5c25879aSJeremy L Thompson   PetscFunctionReturn(0);
273*5c25879aSJeremy L Thompson };
274