xref: /libCEED/examples/solids/src/misc.c (revision d99129b90c9b3ad6c1f1c68efbf93e59a7d0d90e)
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,
28777ff853SJeremy L Thompson                                 CeedQFunctionContext ctxPhys,
29777ff853SJeremy L Thompson                                 CeedQFunctionContext ctxPhysSmoother,
30ccaff030SJeremy L Thompson                                 UserMult jacobianCtx) {
31ccaff030SJeremy L Thompson   PetscErrorCode ierr;
32ccaff030SJeremy L Thompson 
33ccaff030SJeremy L Thompson   PetscFunctionBeginUser;
34ccaff030SJeremy L Thompson 
35ccaff030SJeremy L Thompson   // PETSc objects
36ccaff030SJeremy L Thompson   jacobianCtx->comm = comm;
37ccaff030SJeremy L Thompson   jacobianCtx->dm = dm;
38ccaff030SJeremy L Thompson 
39ccaff030SJeremy L Thompson   // Work vectors
40ccaff030SJeremy L Thompson   jacobianCtx->Xloc = Vloc;
41ccaff030SJeremy L Thompson   ierr = VecDuplicate(Vloc, &jacobianCtx->Yloc); CHKERRQ(ierr);
42ccaff030SJeremy L Thompson   jacobianCtx->Xceed = ceedData->xceed;
43ccaff030SJeremy L Thompson   jacobianCtx->Yceed = ceedData->yceed;
44ccaff030SJeremy L Thompson 
45ccaff030SJeremy L Thompson   // libCEED operator
46ccaff030SJeremy L Thompson   jacobianCtx->op = ceedData->opJacob;
47f7b4142eSJeremy L Thompson   jacobianCtx->qf = ceedData->qfJacob;
48ccaff030SJeremy L Thompson 
49ccaff030SJeremy L Thompson   // Ceed
50ccaff030SJeremy L Thompson   jacobianCtx->ceed = ceed;
51ccaff030SJeremy L Thompson 
52f7b4142eSJeremy L Thompson   // Physics
53777ff853SJeremy L Thompson   jacobianCtx->ctxPhys = ctxPhys;
54777ff853SJeremy L Thompson   jacobianCtx->ctxPhysSmoother = ctxPhysSmoother;
55ccaff030SJeremy L Thompson   PetscFunctionReturn(0);
56ccaff030SJeremy L Thompson };
57ccaff030SJeremy L Thompson 
58ccaff030SJeremy L Thompson // Setup context data for prolongation and restriction operators
5962e9c006SJeremy L Thompson PetscErrorCode SetupProlongRestrictCtx(MPI_Comm comm, AppCtx appCtx, DM dmC,
6062e9c006SJeremy L Thompson                                        DM dmF, Vec VF, Vec VlocC, Vec VlocF,
6162e9c006SJeremy L Thompson                                        CeedData ceedDataC, CeedData ceedDataF,
6262e9c006SJeremy L Thompson                                        Ceed ceed,
63ccaff030SJeremy L Thompson                                        UserMultProlongRestr prolongRestrCtx) {
64ccaff030SJeremy L Thompson   PetscFunctionBeginUser;
65ccaff030SJeremy L Thompson 
66ccaff030SJeremy L Thompson   // PETSc objects
67ccaff030SJeremy L Thompson   prolongRestrCtx->comm = comm;
68ccaff030SJeremy L Thompson   prolongRestrCtx->dmC = dmC;
69ccaff030SJeremy L Thompson   prolongRestrCtx->dmF = dmF;
70ccaff030SJeremy L Thompson 
71ccaff030SJeremy L Thompson   // Work vectors
72ccaff030SJeremy L Thompson   prolongRestrCtx->locVecC = VlocC;
73ccaff030SJeremy L Thompson   prolongRestrCtx->locVecF = VlocF;
74ccaff030SJeremy L Thompson   prolongRestrCtx->ceedVecC = ceedDataC->xceed;
75ccaff030SJeremy L Thompson   prolongRestrCtx->ceedVecF = ceedDataF->xceed;
76ccaff030SJeremy L Thompson 
77ccaff030SJeremy L Thompson   // libCEED operators
78ccaff030SJeremy L Thompson   prolongRestrCtx->opProlong = ceedDataF->opProlong;
79ccaff030SJeremy L Thompson   prolongRestrCtx->opRestrict = ceedDataF->opRestrict;
80ccaff030SJeremy L Thompson 
81ccaff030SJeremy L Thompson   // Ceed
82ccaff030SJeremy L Thompson   prolongRestrCtx->ceed = ceed;
83ccaff030SJeremy L Thompson   PetscFunctionReturn(0);
84ccaff030SJeremy L Thompson };
85ccaff030SJeremy L Thompson 
86ccaff030SJeremy L Thompson // -----------------------------------------------------------------------------
87ccaff030SJeremy L Thompson // Jacobian setup
88ccaff030SJeremy L Thompson // -----------------------------------------------------------------------------
89ccaff030SJeremy L Thompson PetscErrorCode FormJacobian(SNES snes, Vec U, Mat J, Mat Jpre, void *ctx) {
90ccaff030SJeremy L Thompson   PetscErrorCode ierr;
91ccaff030SJeremy L Thompson 
92ccaff030SJeremy L Thompson   PetscFunctionBeginUser;
93ccaff030SJeremy L Thompson 
94ccaff030SJeremy L Thompson   // Context data
95ccaff030SJeremy L Thompson   FormJacobCtx  formJacobCtx = (FormJacobCtx)ctx;
96ccaff030SJeremy L Thompson   PetscInt      numLevels = formJacobCtx->numLevels;
97ccaff030SJeremy L Thompson   Mat           *jacobMat = formJacobCtx->jacobMat;
98ccaff030SJeremy L Thompson 
99e3e3df41Sjeremylt   // Update Jacobian on each level
100e3e3df41Sjeremylt   for (PetscInt level = 0; level < numLevels; level++) {
101ccaff030SJeremy L Thompson     ierr = MatAssemblyBegin(jacobMat[level], MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
102ccaff030SJeremy L Thompson     ierr = MatAssemblyEnd(jacobMat[level], MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
103ccaff030SJeremy L Thompson   }
104ccaff030SJeremy L Thompson 
105ccaff030SJeremy L Thompson   // Form coarse assembled matrix
106ccaff030SJeremy L Thompson   ierr = VecZeroEntries(formJacobCtx->Ucoarse); CHKERRQ(ierr);
107ccaff030SJeremy L Thompson   ierr = SNESComputeJacobianDefaultColor(formJacobCtx->snesCoarse,
108ccaff030SJeremy L Thompson                                          formJacobCtx->Ucoarse,
109ccaff030SJeremy L Thompson                                          formJacobCtx->jacobMat[0],
110ccaff030SJeremy L Thompson                                          formJacobCtx->jacobMatCoarse, NULL);
111ccaff030SJeremy L Thompson   CHKERRQ(ierr);
112ccaff030SJeremy L Thompson 
113ccaff030SJeremy L Thompson   // Jpre might be AIJ (e.g., when using coloring), so we need to assemble it
114ccaff030SJeremy L Thompson   ierr = MatAssemblyBegin(Jpre, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
115ccaff030SJeremy L Thompson   ierr = MatAssemblyEnd(Jpre, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1160e0d204cSJed Brown   if (J != Jpre) {
1170e0d204cSJed Brown     ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1180e0d204cSJed Brown     ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1190e0d204cSJed Brown   }
120ccaff030SJeremy L Thompson   PetscFunctionReturn(0);
121ccaff030SJeremy L Thompson };
122ccaff030SJeremy L Thompson 
123ccaff030SJeremy L Thompson // -----------------------------------------------------------------------------
124ccaff030SJeremy L Thompson // Output solution for visualization
125ccaff030SJeremy L Thompson // -----------------------------------------------------------------------------
126*d99129b9SLeila Ghaffari PetscErrorCode ViewSolution(MPI_Comm comm, AppCtx appCtx, Vec U,
127*d99129b9SLeila Ghaffari                             PetscInt increment,
128ccaff030SJeremy L Thompson                             PetscScalar loadIncrement) {
129ccaff030SJeremy L Thompson   PetscErrorCode ierr;
130ccaff030SJeremy L Thompson   DM dm;
131ccaff030SJeremy L Thompson   PetscViewer viewer;
132ccaff030SJeremy L Thompson   char outputFilename[PETSC_MAX_PATH_LEN];
133*d99129b9SLeila Ghaffari   PetscMPIInt rank;
134ccaff030SJeremy L Thompson 
135ccaff030SJeremy L Thompson   PetscFunctionBeginUser;
136ccaff030SJeremy L Thompson 
137*d99129b9SLeila Ghaffari   // Create output directory
138*d99129b9SLeila Ghaffari   MPI_Comm_rank(comm, &rank);
139*d99129b9SLeila Ghaffari   if (!rank) {ierr = PetscMkdir(appCtx->outputdir); CHKERRQ(ierr);}
140*d99129b9SLeila Ghaffari 
141ccaff030SJeremy L Thompson   // Build file name
142ccaff030SJeremy L Thompson   ierr = PetscSNPrintf(outputFilename, sizeof outputFilename,
143*d99129b9SLeila Ghaffari                        "%s/solution-%03D.vtu", appCtx->outputdir,
144*d99129b9SLeila Ghaffari                        increment); CHKERRQ(ierr);
145ccaff030SJeremy L Thompson 
146050e48ebSJeremy L Thompson   // Increment sequence
147ccaff030SJeremy L Thompson   ierr = VecGetDM(U, &dm); CHKERRQ(ierr);
148ccaff030SJeremy L Thompson   ierr = DMSetOutputSequenceNumber(dm, increment, loadIncrement); CHKERRQ(ierr);
149ccaff030SJeremy L Thompson 
150ccaff030SJeremy L Thompson   // Output solution vector
151ccaff030SJeremy L Thompson   ierr = PetscViewerVTKOpen(comm, outputFilename, FILE_MODE_WRITE, &viewer);
152ccaff030SJeremy L Thompson   CHKERRQ(ierr);
153ccaff030SJeremy L Thompson   ierr = VecView(U, viewer); CHKERRQ(ierr);
154ccaff030SJeremy L Thompson   ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr);
155ccaff030SJeremy L Thompson 
156ccaff030SJeremy L Thompson   PetscFunctionReturn(0);
157ccaff030SJeremy L Thompson };
1585c25879aSJeremy L Thompson 
1595c25879aSJeremy L Thompson // -----------------------------------------------------------------------------
1605c25879aSJeremy L Thompson // Output diagnostic quantities for visualization
1615c25879aSJeremy L Thompson // -----------------------------------------------------------------------------
1625c25879aSJeremy L Thompson PetscErrorCode ViewDiagnosticQuantities(MPI_Comm comm, DM dmU,
163*d99129b9SLeila Ghaffari                                         UserMult user, AppCtx appCtx, Vec U,
1645c25879aSJeremy L Thompson                                         CeedElemRestriction ErestrictDiagnostic) {
1655c25879aSJeremy L Thompson   PetscErrorCode ierr;
1665c25879aSJeremy L Thompson   Vec Diagnostic, Yloc, MultVec;
1675c25879aSJeremy L Thompson   CeedVector Yceed;
1685c25879aSJeremy L Thompson   CeedScalar *x, *y;
169b68a8d79SJed Brown   PetscMemType xmemtype, ymemtype;
1705c25879aSJeremy L Thompson   PetscInt lsz;
1715c25879aSJeremy L Thompson   PetscViewer viewer;
172*d99129b9SLeila Ghaffari   char outputFilename[PETSC_MAX_PATH_LEN];
1735c25879aSJeremy L Thompson 
1745c25879aSJeremy L Thompson   PetscFunctionBeginUser;
1755c25879aSJeremy L Thompson 
1765c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
1775c25879aSJeremy L Thompson   // PETSc and libCEED vectors
1785c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
1795c25879aSJeremy L Thompson   ierr = DMCreateGlobalVector(user->dm, &Diagnostic); CHKERRQ(ierr);
180f81c27eaSJed Brown   ierr = PetscObjectSetName((PetscObject)Diagnostic, ""); CHKERRQ(ierr);
1815c25879aSJeremy L Thompson   ierr = DMCreateLocalVector(user->dm, &Yloc); CHKERRQ(ierr);
1825c25879aSJeremy L Thompson   ierr = VecGetSize(Yloc, &lsz); CHKERRQ(ierr);
1835c25879aSJeremy L Thompson   CeedVectorCreate(user->ceed, lsz, &Yceed);
1845c25879aSJeremy L Thompson 
1855c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
1865c25879aSJeremy L Thompson   // Compute quantities
1875c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
1885c25879aSJeremy L Thompson   // -- Global-to-local
1895c25879aSJeremy L Thompson   ierr = VecZeroEntries(user->Xloc); CHKERRQ(ierr);
1905c25879aSJeremy L Thompson   ierr = DMPlexInsertBoundaryValues(dmU, PETSC_TRUE, user->Xloc,
1915c25879aSJeremy L Thompson                                     user->loadIncrement, NULL, NULL, NULL);
1925c25879aSJeremy L Thompson   CHKERRQ(ierr);
1935c25879aSJeremy L Thompson   ierr = DMGlobalToLocal(dmU, U, INSERT_VALUES, user->Xloc); CHKERRQ(ierr);
1945c25879aSJeremy L Thompson   ierr = VecZeroEntries(Yloc); CHKERRQ(ierr);
1955c25879aSJeremy L Thompson 
1965c25879aSJeremy L Thompson   // -- Setup CEED vectors
197b68a8d79SJed Brown   ierr = VecGetArrayReadAndMemType(user->Xloc, (const PetscScalar **)&x,
198b68a8d79SJed Brown                                    &xmemtype); CHKERRQ(ierr);
199b68a8d79SJed Brown   ierr = VecGetArrayAndMemType(Yloc, &y, &ymemtype); CHKERRQ(ierr);
200b68a8d79SJed Brown   CeedVectorSetArray(user->Xceed, MemTypeP2C(xmemtype), CEED_USE_POINTER, x);
201b68a8d79SJed Brown   CeedVectorSetArray(Yceed, MemTypeP2C(ymemtype), CEED_USE_POINTER, y);
2025c25879aSJeremy L Thompson 
2035c25879aSJeremy L Thompson   // -- Apply CEED operator
2045c25879aSJeremy L Thompson   CeedOperatorApply(user->op, user->Xceed, Yceed, CEED_REQUEST_IMMEDIATE);
2055c25879aSJeremy L Thompson 
206b68a8d79SJed Brown   // -- Restore PETSc vector; keep Yceed viewing memory of Yloc for use below
207b68a8d79SJed Brown   CeedVectorTakeArray(user->Xceed, MemTypeP2C(xmemtype), NULL);
208b68a8d79SJed Brown   ierr = VecRestoreArrayReadAndMemType(user->Xloc, (const PetscScalar **)&x);
2095c25879aSJeremy L Thompson   CHKERRQ(ierr);
2105c25879aSJeremy L Thompson 
2115c25879aSJeremy L Thompson   // -- Local-to-global
2125c25879aSJeremy L Thompson   ierr = VecZeroEntries(Diagnostic); CHKERRQ(ierr);
2135c25879aSJeremy L Thompson   ierr = DMLocalToGlobal(user->dm, Yloc, ADD_VALUES, Diagnostic);
2145c25879aSJeremy L Thompson   CHKERRQ(ierr);
2155c25879aSJeremy L Thompson 
2165c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
2175c25879aSJeremy L Thompson   // Scale for multiplicity
2185c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
2195c25879aSJeremy L Thompson   // -- Setup vectors
2205c25879aSJeremy L Thompson   ierr = VecDuplicate(Diagnostic, &MultVec); CHKERRQ(ierr);
2215c25879aSJeremy L Thompson   ierr = VecZeroEntries(Yloc); CHKERRQ(ierr);
2225c25879aSJeremy L Thompson 
2235c25879aSJeremy L Thompson   // -- Compute multiplicity
2245c25879aSJeremy L Thompson   CeedElemRestrictionGetMultiplicity(ErestrictDiagnostic, Yceed);
2255c25879aSJeremy L Thompson 
2265c25879aSJeremy L Thompson   // -- Restore vectors
227b68a8d79SJed Brown   CeedVectorTakeArray(Yceed, MemTypeP2C(ymemtype), NULL);
228b68a8d79SJed Brown   ierr = VecRestoreArrayAndMemType(Yloc, &y); CHKERRQ(ierr);
2295c25879aSJeremy L Thompson 
2305c25879aSJeremy L Thompson   // -- Local-to-global
2315c25879aSJeremy L Thompson   ierr = VecZeroEntries(MultVec); CHKERRQ(ierr);
2325c25879aSJeremy L Thompson   ierr = DMLocalToGlobal(user->dm, Yloc, ADD_VALUES, MultVec);
2335c25879aSJeremy L Thompson   CHKERRQ(ierr);
2345c25879aSJeremy L Thompson 
2355c25879aSJeremy L Thompson   // -- Scale
2365c25879aSJeremy L Thompson   ierr = VecReciprocal(MultVec); CHKERRQ(ierr);
2375c25879aSJeremy L Thompson   ierr = VecPointwiseMult(Diagnostic, Diagnostic, MultVec);
2385c25879aSJeremy L Thompson 
2395c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
2405c25879aSJeremy L Thompson   // Output solution vector
2415c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
242*d99129b9SLeila Ghaffari   ierr = PetscSNPrintf(outputFilename, sizeof outputFilename,
243*d99129b9SLeila Ghaffari                        "%s/diagnostic_quantities.vtu",
244*d99129b9SLeila Ghaffari                        appCtx->outputdir); CHKERRQ(ierr);
2455c25879aSJeremy L Thompson   ierr = PetscViewerVTKOpen(comm, outputFilename, FILE_MODE_WRITE, &viewer);
2465c25879aSJeremy L Thompson   CHKERRQ(ierr);
2475c25879aSJeremy L Thompson   ierr = VecView(Diagnostic, viewer); CHKERRQ(ierr);
2485c25879aSJeremy L Thompson   ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr);
2495c25879aSJeremy L Thompson 
2505c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
2515c25879aSJeremy L Thompson   // Cleanup
2525c25879aSJeremy L Thompson   // ---------------------------------------------------------------------------
2535c25879aSJeremy L Thompson   ierr = VecDestroy(&Diagnostic); CHKERRQ(ierr);
2545c25879aSJeremy L Thompson   ierr = VecDestroy(&MultVec); CHKERRQ(ierr);
2555c25879aSJeremy L Thompson   ierr = VecDestroy(&Yloc); CHKERRQ(ierr);
2565c25879aSJeremy L Thompson   CeedVectorDestroy(&Yceed);
2575c25879aSJeremy L Thompson 
2585c25879aSJeremy L Thompson   PetscFunctionReturn(0);
2595c25879aSJeremy L Thompson };
260