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