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 26*d1d35e2fSjeremylt PetscErrorCode SetupJacobianCtx(MPI_Comm comm, AppCtx app_ctx, DM dm, Vec V, 27*d1d35e2fSjeremylt Vec V_loc, CeedData ceed_data, Ceed ceed, 28*d1d35e2fSjeremylt CeedQFunctionContext ctx_phys, 29*d1d35e2fSjeremylt CeedQFunctionContext ctx_phys_smoother, 30*d1d35e2fSjeremylt UserMult jacobian_ctx) { 31ccaff030SJeremy L Thompson PetscErrorCode ierr; 32ccaff030SJeremy L Thompson 33ccaff030SJeremy L Thompson PetscFunctionBeginUser; 34ccaff030SJeremy L Thompson 35ccaff030SJeremy L Thompson // PETSc objects 36*d1d35e2fSjeremylt jacobian_ctx->comm = comm; 37*d1d35e2fSjeremylt jacobian_ctx->dm = dm; 38ccaff030SJeremy L Thompson 39ccaff030SJeremy L Thompson // Work vectors 40*d1d35e2fSjeremylt jacobian_ctx->X_loc = V_loc; 41*d1d35e2fSjeremylt ierr = VecDuplicate(V_loc, &jacobian_ctx->Y_loc); CHKERRQ(ierr); 42*d1d35e2fSjeremylt jacobian_ctx->x_ceed = ceed_data->x_ceed; 43*d1d35e2fSjeremylt jacobian_ctx->y_ceed = ceed_data->y_ceed; 44ccaff030SJeremy L Thompson 45ccaff030SJeremy L Thompson // libCEED operator 46*d1d35e2fSjeremylt jacobian_ctx->op = ceed_data->op_jacob; 47*d1d35e2fSjeremylt jacobian_ctx->qf = ceed_data->qf_jacob; 48ccaff030SJeremy L Thompson 49ccaff030SJeremy L Thompson // Ceed 50*d1d35e2fSjeremylt jacobian_ctx->ceed = ceed; 51ccaff030SJeremy L Thompson 52f7b4142eSJeremy L Thompson // Physics 53*d1d35e2fSjeremylt jacobian_ctx->ctx_phys = ctx_phys; 54*d1d35e2fSjeremylt jacobian_ctx->ctx_phys_smoother = ctx_phys_smoother; 55ccaff030SJeremy L Thompson PetscFunctionReturn(0); 56ccaff030SJeremy L Thompson }; 57ccaff030SJeremy L Thompson 58ccaff030SJeremy L Thompson // Setup context data for prolongation and restriction operators 59*d1d35e2fSjeremylt PetscErrorCode SetupProlongRestrictCtx(MPI_Comm comm, AppCtx app_ctx, DM dm_c, 60*d1d35e2fSjeremylt DM dm_f, Vec V_f, Vec V_loc_c, Vec V_loc_f, 61*d1d35e2fSjeremylt CeedData ceed_data_c, CeedData ceed_data_f, 62*d1d35e2fSjeremylt Ceed ceed, UserMultProlongRestr prolong_restr_ctx) { 63ccaff030SJeremy L Thompson PetscFunctionBeginUser; 64ccaff030SJeremy L Thompson 65ccaff030SJeremy L Thompson // PETSc objects 66*d1d35e2fSjeremylt prolong_restr_ctx->comm = comm; 67*d1d35e2fSjeremylt prolong_restr_ctx->dm_c = dm_c; 68*d1d35e2fSjeremylt prolong_restr_ctx->dm_f = dm_f; 69ccaff030SJeremy L Thompson 70ccaff030SJeremy L Thompson // Work vectors 71*d1d35e2fSjeremylt prolong_restr_ctx->loc_vec_c = V_loc_c; 72*d1d35e2fSjeremylt prolong_restr_ctx->loc_vec_f = V_loc_f; 73*d1d35e2fSjeremylt prolong_restr_ctx->ceed_vec_c = ceed_data_c->x_ceed; 74*d1d35e2fSjeremylt prolong_restr_ctx->ceed_vec_f = ceed_data_f->x_ceed; 75ccaff030SJeremy L Thompson 76ccaff030SJeremy L Thompson // libCEED operators 77*d1d35e2fSjeremylt prolong_restr_ctx->op_prolong = ceed_data_f->op_prolong; 78*d1d35e2fSjeremylt prolong_restr_ctx->op_restrict = ceed_data_f->op_restrict; 79ccaff030SJeremy L Thompson 80ccaff030SJeremy L Thompson // Ceed 81*d1d35e2fSjeremylt prolong_restr_ctx->ceed = ceed; 82ccaff030SJeremy L Thompson PetscFunctionReturn(0); 83ccaff030SJeremy L Thompson }; 84ccaff030SJeremy L Thompson 85ccaff030SJeremy L Thompson // ----------------------------------------------------------------------------- 86ccaff030SJeremy L Thompson // Jacobian setup 87ccaff030SJeremy L Thompson // ----------------------------------------------------------------------------- 88*d1d35e2fSjeremylt PetscErrorCode FormJacobian(SNES snes, Vec U, Mat J, Mat J_pre, void *ctx) { 89ccaff030SJeremy L Thompson PetscErrorCode ierr; 90ccaff030SJeremy L Thompson 91ccaff030SJeremy L Thompson PetscFunctionBeginUser; 92ccaff030SJeremy L Thompson 93ccaff030SJeremy L Thompson // Context data 94*d1d35e2fSjeremylt FormJacobCtx form_jacob_ctx = (FormJacobCtx)ctx; 95*d1d35e2fSjeremylt PetscInt num_levels = form_jacob_ctx->num_levels; 96*d1d35e2fSjeremylt Mat *jacob_mat = form_jacob_ctx->jacob_mat; 97ccaff030SJeremy L Thompson 98e3e3df41Sjeremylt // Update Jacobian on each level 99*d1d35e2fSjeremylt for (PetscInt level = 0; level < num_levels; level++) { 100*d1d35e2fSjeremylt ierr = MatAssemblyBegin(jacob_mat[level], MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 101*d1d35e2fSjeremylt ierr = MatAssemblyEnd(jacob_mat[level], MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 102ccaff030SJeremy L Thompson } 103ccaff030SJeremy L Thompson 104ccaff030SJeremy L Thompson // Form coarse assembled matrix 105*d1d35e2fSjeremylt ierr = VecZeroEntries(form_jacob_ctx->u_coarse); CHKERRQ(ierr); 106*d1d35e2fSjeremylt ierr = SNESComputeJacobianDefaultColor(form_jacob_ctx->snes_coarse, 107*d1d35e2fSjeremylt form_jacob_ctx->u_coarse, 108*d1d35e2fSjeremylt form_jacob_ctx->jacob_mat[0], 109*d1d35e2fSjeremylt form_jacob_ctx->jacob_mat_coarse, NULL); 110ccaff030SJeremy L Thompson CHKERRQ(ierr); 111ccaff030SJeremy L Thompson 112*d1d35e2fSjeremylt // J_pre might be AIJ (e.g., when using coloring), so we need to assemble it 113*d1d35e2fSjeremylt ierr = MatAssemblyBegin(J_pre, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 114*d1d35e2fSjeremylt ierr = MatAssemblyEnd(J_pre, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 115*d1d35e2fSjeremylt if (J != J_pre) { 1160e0d204cSJed Brown ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1170e0d204cSJed Brown ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 1180e0d204cSJed Brown } 119ccaff030SJeremy L Thompson PetscFunctionReturn(0); 120ccaff030SJeremy L Thompson }; 121ccaff030SJeremy L Thompson 122ccaff030SJeremy L Thompson // ----------------------------------------------------------------------------- 123ccaff030SJeremy L Thompson // Output solution for visualization 124ccaff030SJeremy L Thompson // ----------------------------------------------------------------------------- 125*d1d35e2fSjeremylt PetscErrorCode ViewSolution(MPI_Comm comm, AppCtx app_ctx, Vec U, 126*d1d35e2fSjeremylt PetscInt increment, PetscScalar load_increment) { 127ccaff030SJeremy L Thompson PetscErrorCode ierr; 128ccaff030SJeremy L Thompson DM dm; 129ccaff030SJeremy L Thompson PetscViewer viewer; 130*d1d35e2fSjeremylt char output_filename[PETSC_MAX_PATH_LEN]; 131d99129b9SLeila Ghaffari PetscMPIInt rank; 132ccaff030SJeremy L Thompson 133ccaff030SJeremy L Thompson PetscFunctionBeginUser; 134ccaff030SJeremy L Thompson 135d99129b9SLeila Ghaffari // Create output directory 136d99129b9SLeila Ghaffari MPI_Comm_rank(comm, &rank); 137*d1d35e2fSjeremylt if (!rank) {ierr = PetscMkdir(app_ctx->output_dir); CHKERRQ(ierr);} 138d99129b9SLeila Ghaffari 139ccaff030SJeremy L Thompson // Build file name 140*d1d35e2fSjeremylt ierr = PetscSNPrintf(output_filename, sizeof output_filename, 141*d1d35e2fSjeremylt "%s/solution-%03D.vtu", app_ctx->output_dir, 142d99129b9SLeila Ghaffari increment); CHKERRQ(ierr); 143ccaff030SJeremy L Thompson 144050e48ebSJeremy L Thompson // Increment sequence 145ccaff030SJeremy L Thompson ierr = VecGetDM(U, &dm); CHKERRQ(ierr); 146*d1d35e2fSjeremylt ierr = DMSetOutputSequenceNumber(dm, increment, load_increment); CHKERRQ(ierr); 147ccaff030SJeremy L Thompson 148ccaff030SJeremy L Thompson // Output solution vector 149*d1d35e2fSjeremylt ierr = PetscViewerVTKOpen(comm, output_filename, FILE_MODE_WRITE, &viewer); 150ccaff030SJeremy L Thompson CHKERRQ(ierr); 151ccaff030SJeremy L Thompson ierr = VecView(U, viewer); CHKERRQ(ierr); 152ccaff030SJeremy L Thompson ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr); 153ccaff030SJeremy L Thompson 154ccaff030SJeremy L Thompson PetscFunctionReturn(0); 155ccaff030SJeremy L Thompson }; 1565c25879aSJeremy L Thompson 1575c25879aSJeremy L Thompson // ----------------------------------------------------------------------------- 1585c25879aSJeremy L Thompson // Output diagnostic quantities for visualization 1595c25879aSJeremy L Thompson // ----------------------------------------------------------------------------- 1605c25879aSJeremy L Thompson PetscErrorCode ViewDiagnosticQuantities(MPI_Comm comm, DM dmU, 161*d1d35e2fSjeremylt UserMult user, AppCtx app_ctx, Vec U, 162*d1d35e2fSjeremylt CeedElemRestriction elem_restr_diagnostic) { 1635c25879aSJeremy L Thompson PetscErrorCode ierr; 164*d1d35e2fSjeremylt Vec Diagnostic, Y_loc, mult_vec; 165*d1d35e2fSjeremylt CeedVector y_ceed; 1665c25879aSJeremy L Thompson CeedScalar *x, *y; 167*d1d35e2fSjeremylt PetscMemType x_mem_type, y_mem_type; 168*d1d35e2fSjeremylt PetscInt loc_size; 1695c25879aSJeremy L Thompson PetscViewer viewer; 170*d1d35e2fSjeremylt char output_filename[PETSC_MAX_PATH_LEN]; 1715c25879aSJeremy L Thompson 1725c25879aSJeremy L Thompson PetscFunctionBeginUser; 1735c25879aSJeremy L Thompson 1745c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 1755c25879aSJeremy L Thompson // PETSc and libCEED vectors 1765c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 1775c25879aSJeremy L Thompson ierr = DMCreateGlobalVector(user->dm, &Diagnostic); CHKERRQ(ierr); 178f81c27eaSJed Brown ierr = PetscObjectSetName((PetscObject)Diagnostic, ""); CHKERRQ(ierr); 179*d1d35e2fSjeremylt ierr = DMCreateLocalVector(user->dm, &Y_loc); CHKERRQ(ierr); 180*d1d35e2fSjeremylt ierr = VecGetSize(Y_loc, &loc_size); CHKERRQ(ierr); 181*d1d35e2fSjeremylt CeedVectorCreate(user->ceed, loc_size, &y_ceed); 1825c25879aSJeremy L Thompson 1835c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 1845c25879aSJeremy L Thompson // Compute quantities 1855c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 1865c25879aSJeremy L Thompson // -- Global-to-local 187*d1d35e2fSjeremylt ierr = VecZeroEntries(user->X_loc); CHKERRQ(ierr); 188*d1d35e2fSjeremylt ierr = DMPlexInsertBoundaryValues(dmU, PETSC_TRUE, user->X_loc, 189*d1d35e2fSjeremylt user->load_increment, NULL, NULL, NULL); 1905c25879aSJeremy L Thompson CHKERRQ(ierr); 191*d1d35e2fSjeremylt ierr = DMGlobalToLocal(dmU, U, INSERT_VALUES, user->X_loc); CHKERRQ(ierr); 192*d1d35e2fSjeremylt ierr = VecZeroEntries(Y_loc); CHKERRQ(ierr); 1935c25879aSJeremy L Thompson 1945c25879aSJeremy L Thompson // -- Setup CEED vectors 195*d1d35e2fSjeremylt ierr = VecGetArrayReadAndMemType(user->X_loc, (const PetscScalar **)&x, 196*d1d35e2fSjeremylt &x_mem_type); CHKERRQ(ierr); 197*d1d35e2fSjeremylt ierr = VecGetArrayAndMemType(Y_loc, &y, &y_mem_type); CHKERRQ(ierr); 198*d1d35e2fSjeremylt CeedVectorSetArray(user->x_ceed, MemTypeP2C(x_mem_type), CEED_USE_POINTER, x); 199*d1d35e2fSjeremylt CeedVectorSetArray(y_ceed, MemTypeP2C(y_mem_type), CEED_USE_POINTER, y); 2005c25879aSJeremy L Thompson 2015c25879aSJeremy L Thompson // -- Apply CEED operator 202*d1d35e2fSjeremylt CeedOperatorApply(user->op, user->x_ceed, y_ceed, CEED_REQUEST_IMMEDIATE); 2035c25879aSJeremy L Thompson 204*d1d35e2fSjeremylt // -- Restore PETSc vector; keep y_ceed viewing memory of Y_loc for use below 205*d1d35e2fSjeremylt CeedVectorTakeArray(user->x_ceed, MemTypeP2C(x_mem_type), NULL); 206*d1d35e2fSjeremylt ierr = VecRestoreArrayReadAndMemType(user->X_loc, (const PetscScalar **)&x); 2075c25879aSJeremy L Thompson CHKERRQ(ierr); 2085c25879aSJeremy L Thompson 2095c25879aSJeremy L Thompson // -- Local-to-global 2105c25879aSJeremy L Thompson ierr = VecZeroEntries(Diagnostic); CHKERRQ(ierr); 211*d1d35e2fSjeremylt ierr = DMLocalToGlobal(user->dm, Y_loc, ADD_VALUES, Diagnostic); 2125c25879aSJeremy L Thompson CHKERRQ(ierr); 2135c25879aSJeremy L Thompson 2145c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 2155c25879aSJeremy L Thompson // Scale for multiplicity 2165c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 2175c25879aSJeremy L Thompson // -- Setup vectors 218*d1d35e2fSjeremylt ierr = VecDuplicate(Diagnostic, &mult_vec); CHKERRQ(ierr); 219*d1d35e2fSjeremylt ierr = VecZeroEntries(Y_loc); CHKERRQ(ierr); 2205c25879aSJeremy L Thompson 2215c25879aSJeremy L Thompson // -- Compute multiplicity 222*d1d35e2fSjeremylt CeedElemRestrictionGetMultiplicity(elem_restr_diagnostic, y_ceed); 2235c25879aSJeremy L Thompson 2245c25879aSJeremy L Thompson // -- Restore vectors 225*d1d35e2fSjeremylt CeedVectorTakeArray(y_ceed, MemTypeP2C(y_mem_type), NULL); 226*d1d35e2fSjeremylt ierr = VecRestoreArrayAndMemType(Y_loc, &y); CHKERRQ(ierr); 2275c25879aSJeremy L Thompson 2285c25879aSJeremy L Thompson // -- Local-to-global 229*d1d35e2fSjeremylt ierr = VecZeroEntries(mult_vec); CHKERRQ(ierr); 230*d1d35e2fSjeremylt ierr = DMLocalToGlobal(user->dm, Y_loc, ADD_VALUES, mult_vec); 2315c25879aSJeremy L Thompson CHKERRQ(ierr); 2325c25879aSJeremy L Thompson 2335c25879aSJeremy L Thompson // -- Scale 234*d1d35e2fSjeremylt ierr = VecReciprocal(mult_vec); CHKERRQ(ierr); 235*d1d35e2fSjeremylt ierr = VecPointwiseMult(Diagnostic, Diagnostic, mult_vec); 2365c25879aSJeremy L Thompson 2375c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 2385c25879aSJeremy L Thompson // Output solution vector 2395c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 240*d1d35e2fSjeremylt ierr = PetscSNPrintf(output_filename, sizeof output_filename, 241d99129b9SLeila Ghaffari "%s/diagnostic_quantities.vtu", 242*d1d35e2fSjeremylt app_ctx->output_dir); CHKERRQ(ierr); 243*d1d35e2fSjeremylt ierr = PetscViewerVTKOpen(comm, output_filename, FILE_MODE_WRITE, &viewer); 2445c25879aSJeremy L Thompson CHKERRQ(ierr); 2455c25879aSJeremy L Thompson ierr = VecView(Diagnostic, viewer); CHKERRQ(ierr); 2465c25879aSJeremy L Thompson ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr); 2475c25879aSJeremy L Thompson 2485c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 2495c25879aSJeremy L Thompson // Cleanup 2505c25879aSJeremy L Thompson // --------------------------------------------------------------------------- 2515c25879aSJeremy L Thompson ierr = VecDestroy(&Diagnostic); CHKERRQ(ierr); 252*d1d35e2fSjeremylt ierr = VecDestroy(&mult_vec); CHKERRQ(ierr); 253*d1d35e2fSjeremylt ierr = VecDestroy(&Y_loc); CHKERRQ(ierr); 254*d1d35e2fSjeremylt CeedVectorDestroy(&y_ceed); 2555c25879aSJeremy L Thompson 2565c25879aSJeremy L Thompson PetscFunctionReturn(0); 2575c25879aSJeremy L Thompson }; 258