xref: /libCEED/examples/solids/src/misc.c (revision d1d35e2f02dc969aee8debf3fd943dd784aa847a)
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