1*9ba83ac0SJeremy L Thompson // Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors.
23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
33d8e8822SJeremy L Thompson //
43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause
53d8e8822SJeremy L Thompson //
63d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed
73d8e8822SJeremy L Thompson
85754ecacSJeremy L Thompson /// @file
95754ecacSJeremy L Thompson /// libCEED setup for solid mechanics example using PETSc
105754ecacSJeremy L Thompson
115754ecacSJeremy L Thompson #include "../include/setup-libceed.h"
122b730f8bSJeremy L Thompson
1349aac155SJeremy L Thompson #include <ceed.h>
1449aac155SJeremy L Thompson #include <petscdmplex.h>
1549aac155SJeremy L Thompson #include <petscmat.h>
1649aac155SJeremy L Thompson
175754ecacSJeremy L Thompson #include "../include/structs.h"
185754ecacSJeremy L Thompson #include "../include/utils.h"
195754ecacSJeremy L Thompson #include "../qfunctions/constant-force.h" // Constant forcing function
205754ecacSJeremy L Thompson #include "../qfunctions/manufactured-force.h" // Manufactured solution forcing
212b730f8bSJeremy L Thompson #include "../qfunctions/traction-boundary.h" // Traction boundaries
225754ecacSJeremy L Thompson
235754ecacSJeremy L Thompson // -----------------------------------------------------------------------------
245754ecacSJeremy L Thompson // Problem options
255754ecacSJeremy L Thompson // -----------------------------------------------------------------------------
265754ecacSJeremy L Thompson // Forcing function data
275754ecacSJeremy L Thompson forcingData forcing_options[3] = {
282b730f8bSJeremy L Thompson [FORCE_NONE] = {.setup_forcing = NULL, .setup_forcing_loc = NULL },
292b730f8bSJeremy L Thompson [FORCE_CONST] = {.setup_forcing = SetupConstantForce, .setup_forcing_loc = SetupConstantForce_loc},
302b730f8bSJeremy L Thompson [FORCE_MMS] = {.setup_forcing = SetupMMSForce, .setup_forcing_loc = SetupMMSForce_loc }
315754ecacSJeremy L Thompson };
325754ecacSJeremy L Thompson
335754ecacSJeremy L Thompson // -----------------------------------------------------------------------------
345754ecacSJeremy L Thompson // libCEED Functions
355754ecacSJeremy L Thompson // -----------------------------------------------------------------------------
365754ecacSJeremy L Thompson // Destroy libCEED objects
CeedDataDestroy(CeedInt level,CeedData data)375754ecacSJeremy L Thompson PetscErrorCode CeedDataDestroy(CeedInt level, CeedData data) {
385754ecacSJeremy L Thompson PetscFunctionBegin;
395754ecacSJeremy L Thompson
405754ecacSJeremy L Thompson // Vectors
415754ecacSJeremy L Thompson CeedVectorDestroy(&data->x_ceed);
425754ecacSJeremy L Thompson CeedVectorDestroy(&data->y_ceed);
435754ecacSJeremy L Thompson CeedVectorDestroy(&data->geo_data);
442b730f8bSJeremy L Thompson for (CeedInt i = 0; i < SOLIDS_MAX_NUMBER_FIELDS; i++) CeedVectorDestroy(&data->stored_fields[i]);
455754ecacSJeremy L Thompson CeedVectorDestroy(&data->geo_data_diagnostic);
465754ecacSJeremy L Thompson CeedVectorDestroy(&data->true_soln);
475754ecacSJeremy L Thompson // Restrictions
485754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_x);
495754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_u);
505754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_geo_data_i);
512b730f8bSJeremy L Thompson for (CeedInt i = 0; i < SOLIDS_MAX_NUMBER_FIELDS; i++) CeedElemRestrictionDestroy(&data->elem_restr_stored_fields_i[i]);
525754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_energy);
535754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_diagnostic);
545754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_geo_data_diagnostic_i);
555754ecacSJeremy L Thompson // Bases
565754ecacSJeremy L Thompson CeedBasisDestroy(&data->basis_x);
575754ecacSJeremy L Thompson CeedBasisDestroy(&data->basis_u);
585754ecacSJeremy L Thompson CeedBasisDestroy(&data->basis_energy);
595754ecacSJeremy L Thompson CeedBasisDestroy(&data->basis_diagnostic);
605754ecacSJeremy L Thompson // QFunctions
615754ecacSJeremy L Thompson CeedQFunctionDestroy(&data->qf_residual);
625754ecacSJeremy L Thompson CeedQFunctionDestroy(&data->qf_jacobian);
635754ecacSJeremy L Thompson CeedQFunctionDestroy(&data->qf_energy);
645754ecacSJeremy L Thompson CeedQFunctionDestroy(&data->qf_diagnostic);
655754ecacSJeremy L Thompson // Operators
665754ecacSJeremy L Thompson CeedOperatorDestroy(&data->op_residual);
675754ecacSJeremy L Thompson CeedOperatorDestroy(&data->op_jacobian);
685754ecacSJeremy L Thompson CeedOperatorDestroy(&data->op_energy);
695754ecacSJeremy L Thompson CeedOperatorDestroy(&data->op_diagnostic);
705754ecacSJeremy L Thompson // Restriction and Prolongation data
715754ecacSJeremy L Thompson CeedBasisDestroy(&data->basis_c_to_f);
725754ecacSJeremy L Thompson CeedOperatorDestroy(&data->op_prolong);
735754ecacSJeremy L Thompson CeedOperatorDestroy(&data->op_restrict);
745754ecacSJeremy L Thompson
752b730f8bSJeremy L Thompson PetscCall(PetscFree(data));
765754ecacSJeremy L Thompson
77ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS);
785754ecacSJeremy L Thompson };
795754ecacSJeremy L Thompson
805754ecacSJeremy L Thompson // Utility function to create local CEED restriction from DMPlex
CreateRestrictionFromPlex(Ceed ceed,DM dm,CeedInt height,DMLabel domain_label,CeedInt value,CeedElemRestriction * elem_restr)812b730f8bSJeremy L Thompson PetscErrorCode CreateRestrictionFromPlex(Ceed ceed, DM dm, CeedInt height, DMLabel domain_label, CeedInt value, CeedElemRestriction *elem_restr) {
824d00b080SJeremy L Thompson PetscInt num_elem, elem_size, num_dof, num_comp, *elem_restr_offsets_petsc;
834d00b080SJeremy L Thompson CeedInt *elem_restr_offsets_ceed;
845754ecacSJeremy L Thompson
855754ecacSJeremy L Thompson PetscFunctionBeginUser;
864d00b080SJeremy L Thompson PetscCall(DMPlexGetLocalOffsets(dm, domain_label, value, height, 0, &num_elem, &elem_size, &num_comp, &num_dof, &elem_restr_offsets_petsc));
875754ecacSJeremy L Thompson
884d00b080SJeremy L Thompson PetscCall(IntArrayPetscToCeed(num_elem * elem_size, &elem_restr_offsets_petsc, &elem_restr_offsets_ceed));
894d00b080SJeremy L Thompson CeedElemRestrictionCreate(ceed, num_elem, elem_size, num_comp, 1, num_dof, CEED_MEM_HOST, CEED_COPY_VALUES, elem_restr_offsets_ceed, elem_restr);
904d00b080SJeremy L Thompson PetscCall(PetscFree(elem_restr_offsets_ceed));
915754ecacSJeremy L Thompson
92ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS);
935754ecacSJeremy L Thompson };
945754ecacSJeremy L Thompson
955754ecacSJeremy L Thompson // Utility function to get Ceed Restriction for each domain
GetRestrictionForDomain(Ceed ceed,DM dm,CeedInt height,DMLabel domain_label,PetscInt value,CeedInt Q,CeedInt q_data_size,CeedElemRestriction * elem_restr_q,CeedElemRestriction * elem_restr_x,CeedElemRestriction * elem_restr_qd_i)962b730f8bSJeremy L Thompson PetscErrorCode GetRestrictionForDomain(Ceed ceed, DM dm, CeedInt height, DMLabel domain_label, PetscInt value, CeedInt Q, CeedInt q_data_size,
972b730f8bSJeremy L Thompson CeedElemRestriction *elem_restr_q, CeedElemRestriction *elem_restr_x, CeedElemRestriction *elem_restr_qd_i) {
985754ecacSJeremy L Thompson DM dm_coord;
994d00b080SJeremy L Thompson CeedInt num_local_elem, Q_dim;
1004d00b080SJeremy L Thompson PetscInt dim;
1015754ecacSJeremy L Thompson
1025754ecacSJeremy L Thompson PetscFunctionBeginUser;
1035754ecacSJeremy L Thompson
1042b730f8bSJeremy L Thompson PetscCall(DMGetDimension(dm, &dim));
1055754ecacSJeremy L Thompson dim -= height;
1065754ecacSJeremy L Thompson Q_dim = CeedIntPow(Q, dim);
1072b730f8bSJeremy L Thompson PetscCall(DMGetCoordinateDM(dm, &dm_coord));
1082b730f8bSJeremy L Thompson PetscCall(DMPlexSetClosurePermutationTensor(dm_coord, PETSC_DETERMINE, NULL));
1095754ecacSJeremy L Thompson if (elem_restr_q) {
1102b730f8bSJeremy L Thompson PetscCall(CreateRestrictionFromPlex(ceed, dm, height, domain_label, value, elem_restr_q));
1115754ecacSJeremy L Thompson }
1125754ecacSJeremy L Thompson if (elem_restr_x) {
1132b730f8bSJeremy L Thompson PetscCall(CreateRestrictionFromPlex(ceed, dm_coord, height, domain_label, value, elem_restr_x));
1145754ecacSJeremy L Thompson }
1155754ecacSJeremy L Thompson if (elem_restr_qd_i) {
1165754ecacSJeremy L Thompson CeedElemRestrictionGetNumElements(*elem_restr_q, &num_local_elem);
1172b730f8bSJeremy L Thompson CeedElemRestrictionCreateStrided(ceed, num_local_elem, Q_dim, q_data_size, q_data_size * num_local_elem * Q_dim, CEED_STRIDES_BACKEND,
1182b730f8bSJeremy L Thompson elem_restr_qd_i);
1195754ecacSJeremy L Thompson }
1205754ecacSJeremy L Thompson
121ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS);
1225754ecacSJeremy L Thompson };
1235754ecacSJeremy L Thompson
1245754ecacSJeremy L Thompson // Set up libCEED on the fine grid for a given degree
SetupLibceedFineLevel(DM dm,DM dm_energy,DM dm_diagnostic,Ceed ceed,AppCtx app_ctx,CeedQFunctionContext phys_ctx,ProblemData problem_data,PetscInt fine_level,PetscInt num_comp_u,PetscInt U_g_size,PetscInt U_loc_size,CeedVector force_ceed,CeedVector neumann_ceed,CeedData * data)1252b730f8bSJeremy L Thompson PetscErrorCode SetupLibceedFineLevel(DM dm, DM dm_energy, DM dm_diagnostic, Ceed ceed, AppCtx app_ctx, CeedQFunctionContext phys_ctx,
1262b730f8bSJeremy L Thompson ProblemData problem_data, PetscInt fine_level, PetscInt num_comp_u, PetscInt U_g_size, PetscInt U_loc_size,
1272b730f8bSJeremy L Thompson CeedVector force_ceed, CeedVector neumann_ceed, CeedData *data) {
1285754ecacSJeremy L Thompson CeedInt P = app_ctx->level_degrees[fine_level] + 1;
1295754ecacSJeremy L Thompson CeedInt Q = app_ctx->level_degrees[fine_level] + 1 + app_ctx->q_extra;
1304d00b080SJeremy L Thompson CeedInt num_comp_x, num_comp_e = 1, num_comp_d = 5;
1315754ecacSJeremy L Thompson CeedInt num_qpts;
132a61c78d6SJeremy L Thompson CeedInt q_data_size = problem_data.q_data_size;
1335754ecacSJeremy L Thompson forcingType forcing_choice = app_ctx->forcing_choice;
1345754ecacSJeremy L Thompson DM dm_coord;
1355754ecacSJeremy L Thompson Vec coords;
1364d00b080SJeremy L Thompson PetscInt c_start, c_end, num_elem, dim;
1375754ecacSJeremy L Thompson const PetscScalar *coordArray;
1385754ecacSJeremy L Thompson CeedVector x_coord;
1395754ecacSJeremy L Thompson CeedQFunction qf_setup_geo, qf_residual, qf_jacobian, qf_energy, qf_diagnostic;
1405754ecacSJeremy L Thompson CeedOperator op_setup_geo, op_residual, op_jacobian, op_energy, op_diagnostic;
1415754ecacSJeremy L Thompson
1425754ecacSJeremy L Thompson PetscFunctionBeginUser;
1435754ecacSJeremy L Thompson
1445754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
1455754ecacSJeremy L Thompson // libCEED bases
1465754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
1472b730f8bSJeremy L Thompson PetscCall(DMGetDimension(dm, &dim));
1485754ecacSJeremy L Thompson num_comp_x = dim;
1495754ecacSJeremy L Thompson // -- Coordinate basis
1502b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_x, 2, Q, problem_data.quadrature_mode, &data[fine_level]->basis_x);
1515754ecacSJeremy L Thompson // -- Solution basis
1522b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_u, P, Q, problem_data.quadrature_mode, &data[fine_level]->basis_u);
1535754ecacSJeremy L Thompson // -- Energy basis
1542b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_e, P, Q, problem_data.quadrature_mode, &data[fine_level]->basis_energy);
1555754ecacSJeremy L Thompson // -- Diagnostic output basis
1562b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_u, P, P, CEED_GAUSS_LOBATTO, &data[fine_level]->basis_diagnostic);
1575754ecacSJeremy L Thompson
1585754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
1595754ecacSJeremy L Thompson // libCEED restrictions
1605754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
1612b730f8bSJeremy L Thompson PetscCall(DMGetCoordinateDM(dm, &dm_coord));
1622b730f8bSJeremy L Thompson PetscCall(DMPlexSetClosurePermutationTensor(dm_coord, PETSC_DETERMINE, NULL));
1635754ecacSJeremy L Thompson
1645754ecacSJeremy L Thompson // -- Coordinate restriction
1652b730f8bSJeremy L Thompson PetscCall(CreateRestrictionFromPlex(ceed, dm_coord, 0, 0, 0, &(data[fine_level]->elem_restr_x)));
1665754ecacSJeremy L Thompson // -- Solution restriction
1672b730f8bSJeremy L Thompson PetscCall(CreateRestrictionFromPlex(ceed, dm, 0, 0, 0, &data[fine_level]->elem_restr_u));
1685754ecacSJeremy L Thompson // -- Energy restriction
1692b730f8bSJeremy L Thompson PetscCall(CreateRestrictionFromPlex(ceed, dm_energy, 0, 0, 0, &data[fine_level]->elem_restr_energy));
1705754ecacSJeremy L Thompson // -- Diagnostic data restriction
1712b730f8bSJeremy L Thompson PetscCall(CreateRestrictionFromPlex(ceed, dm_diagnostic, 0, 0, 0, &data[fine_level]->elem_restr_diagnostic));
1725754ecacSJeremy L Thompson
1735754ecacSJeremy L Thompson // -- Stored data at quadrature points
1742b730f8bSJeremy L Thompson PetscCall(DMPlexGetHeightStratum(dm, 0, &c_start, &c_end));
1755754ecacSJeremy L Thompson num_elem = c_end - c_start;
1765754ecacSJeremy L Thompson CeedBasisGetNumQuadraturePoints(data[fine_level]->basis_u, &num_qpts);
1775754ecacSJeremy L Thompson // ---- Geometric data restriction, residual and Jacobian operators
1782b730f8bSJeremy L Thompson CeedElemRestrictionCreateStrided(ceed, num_elem, num_qpts, q_data_size, num_elem * num_qpts * q_data_size, CEED_STRIDES_BACKEND,
1795754ecacSJeremy L Thompson &data[fine_level]->elem_restr_geo_data_i);
1805754ecacSJeremy L Thompson // ---- Stored field restrictions
1815754ecacSJeremy L Thompson for (CeedInt i = 0; i < problem_data.number_fields_stored; i++) {
1822b730f8bSJeremy L Thompson CeedElemRestrictionCreateStrided(ceed, num_elem, num_qpts, problem_data.field_sizes[i], num_elem * num_qpts * problem_data.field_sizes[i],
1832b730f8bSJeremy L Thompson CEED_STRIDES_BACKEND, &data[fine_level]->elem_restr_stored_fields_i[i]);
1845754ecacSJeremy L Thompson }
1855754ecacSJeremy L Thompson // ---- Geometric data restriction, diagnostic operator
1862b730f8bSJeremy L Thompson CeedElemRestrictionCreateStrided(ceed, num_elem, P * P * P, q_data_size, num_elem * P * P * P * q_data_size, CEED_STRIDES_BACKEND,
1875754ecacSJeremy L Thompson &data[fine_level]->elem_restr_geo_data_diagnostic_i);
1885754ecacSJeremy L Thompson
1895754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
1905754ecacSJeremy L Thompson // Element coordinates
1915754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
1922b730f8bSJeremy L Thompson PetscCall(DMGetCoordinatesLocal(dm, &coords));
1932b730f8bSJeremy L Thompson PetscCall(VecGetArrayRead(coords, &coordArray));
1945754ecacSJeremy L Thompson
1955754ecacSJeremy L Thompson CeedElemRestrictionCreateVector(data[fine_level]->elem_restr_x, &x_coord, NULL);
1962b730f8bSJeremy L Thompson CeedVectorSetArray(x_coord, CEED_MEM_HOST, CEED_COPY_VALUES, (PetscScalar *)coordArray);
1972b730f8bSJeremy L Thompson PetscCall(VecRestoreArrayRead(coords, &coordArray));
1985754ecacSJeremy L Thompson
1995754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
2005754ecacSJeremy L Thompson // Persistent libCEED vectors
2015754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
2025754ecacSJeremy L Thompson // -- Operator action variables
2035754ecacSJeremy L Thompson CeedVectorCreate(ceed, U_loc_size, &data[fine_level]->x_ceed);
2045754ecacSJeremy L Thompson CeedVectorCreate(ceed, U_loc_size, &data[fine_level]->y_ceed);
2055754ecacSJeremy L Thompson // -- Geometric data vector
2062b730f8bSJeremy L Thompson CeedVectorCreate(ceed, num_elem * num_qpts * q_data_size, &data[fine_level]->geo_data);
2075754ecacSJeremy L Thompson // -- Stored field vectors
2085754ecacSJeremy L Thompson for (CeedInt i = 0; i < problem_data.number_fields_stored; i++) {
2092b730f8bSJeremy L Thompson CeedVectorCreate(ceed, num_elem * num_qpts * problem_data.field_sizes[i], &data[fine_level]->stored_fields[i]);
2105754ecacSJeremy L Thompson }
2115754ecacSJeremy L Thompson // -- Collocated geometric data vector
2122b730f8bSJeremy L Thompson CeedVectorCreate(ceed, num_elem * P * P * P * q_data_size, &data[fine_level]->geo_data_diagnostic);
2135754ecacSJeremy L Thompson
2145754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
2155754ecacSJeremy L Thompson // Geometric factor computation
2165754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
217ea61e9acSJeremy L Thompson // Create the QFunction and Operator that computes the quadrature data geo_data returns dXdx_i,j and w * det.
2185754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
2195754ecacSJeremy L Thompson // -- QFunction
2202b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.setup_geo, problem_data.setup_geo_loc, &qf_setup_geo);
2215754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_setup_geo, "dx", num_comp_x * dim, CEED_EVAL_GRAD);
2225754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_setup_geo, "weight", 1, CEED_EVAL_WEIGHT);
223a61c78d6SJeremy L Thompson CeedQFunctionAddOutput(qf_setup_geo, "qdata", q_data_size, CEED_EVAL_NONE);
2245754ecacSJeremy L Thompson // -- Operator
2252b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_setup_geo, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_setup_geo);
2262b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "dx", data[fine_level]->elem_restr_x, data[fine_level]->basis_x, CEED_VECTOR_ACTIVE);
2272b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "weight", CEED_ELEMRESTRICTION_NONE, data[fine_level]->basis_x, CEED_VECTOR_NONE);
228356036faSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "qdata", data[fine_level]->elem_restr_geo_data_i, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE);
2295754ecacSJeremy L Thompson // -- Compute the quadrature data
2302b730f8bSJeremy L Thompson CeedOperatorApply(op_setup_geo, x_coord, data[fine_level]->geo_data, CEED_REQUEST_IMMEDIATE);
2315754ecacSJeremy L Thompson // -- Cleanup
2325754ecacSJeremy L Thompson CeedQFunctionDestroy(&qf_setup_geo);
2335754ecacSJeremy L Thompson CeedOperatorDestroy(&op_setup_geo);
2345754ecacSJeremy L Thompson
2355754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
2365754ecacSJeremy L Thompson // Local residual evaluator
2375754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
238ea61e9acSJeremy L Thompson // Create the QFunction and Operator that computes the residual of the non-linear PDE.
2395754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
2405754ecacSJeremy L Thompson // -- QFunction
2412b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.residual, problem_data.residual_loc, &qf_residual);
2425754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_residual, "du", num_comp_u * dim, CEED_EVAL_GRAD);
243a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_residual, "qdata", q_data_size, CEED_EVAL_NONE);
2445754ecacSJeremy L Thompson CeedQFunctionAddOutput(qf_residual, "dv", num_comp_u * dim, CEED_EVAL_GRAD);
2455754ecacSJeremy L Thompson for (CeedInt i = 0; i < problem_data.number_fields_stored; i++) {
2462b730f8bSJeremy L Thompson CeedQFunctionAddOutput(qf_residual, problem_data.field_names[i], problem_data.field_sizes[i], CEED_EVAL_NONE);
2475754ecacSJeremy L Thompson }
2485754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_residual, phys_ctx);
2495754ecacSJeremy L Thompson // -- Operator
2502b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_residual, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_residual);
2512b730f8bSJeremy L Thompson CeedOperatorSetField(op_residual, "du", data[fine_level]->elem_restr_u, data[fine_level]->basis_u, CEED_VECTOR_ACTIVE);
252356036faSJeremy L Thompson CeedOperatorSetField(op_residual, "qdata", data[fine_level]->elem_restr_geo_data_i, CEED_BASIS_NONE, data[fine_level]->geo_data);
2532b730f8bSJeremy L Thompson CeedOperatorSetField(op_residual, "dv", data[fine_level]->elem_restr_u, data[fine_level]->basis_u, CEED_VECTOR_ACTIVE);
2545754ecacSJeremy L Thompson for (CeedInt i = 0; i < problem_data.number_fields_stored; i++) {
255356036faSJeremy L Thompson CeedOperatorSetField(op_residual, problem_data.field_names[i], data[fine_level]->elem_restr_stored_fields_i[i], CEED_BASIS_NONE,
2565754ecacSJeremy L Thompson data[fine_level]->stored_fields[i]);
2575754ecacSJeremy L Thompson }
2585754ecacSJeremy L Thompson // -- Save libCEED data
2595754ecacSJeremy L Thompson data[fine_level]->qf_residual = qf_residual;
2605754ecacSJeremy L Thompson data[fine_level]->op_residual = op_residual;
2615754ecacSJeremy L Thompson
2625754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
2635754ecacSJeremy L Thompson // Jacobian evaluator
2645754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
265ea61e9acSJeremy L Thompson // Create the QFunction and Operator that computes the action of the Jacobian for each linear solve.
2665754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
2675754ecacSJeremy L Thompson // -- QFunction
2682b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.jacobian, problem_data.jacobian_loc, &qf_jacobian);
2695754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_jacobian, "delta du", num_comp_u * dim, CEED_EVAL_GRAD);
270a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_jacobian, "qdata", q_data_size, CEED_EVAL_NONE);
2715754ecacSJeremy L Thompson for (CeedInt i = 0; i < problem_data.number_fields_stored; i++) {
2722b730f8bSJeremy L Thompson CeedQFunctionAddInput(qf_jacobian, problem_data.field_names[i], problem_data.field_sizes[i], CEED_EVAL_NONE);
2735754ecacSJeremy L Thompson }
2745754ecacSJeremy L Thompson CeedQFunctionAddOutput(qf_jacobian, "delta dv", num_comp_u * dim, CEED_EVAL_GRAD);
2755754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_jacobian, phys_ctx);
2765754ecacSJeremy L Thompson // -- Operator
2772b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_jacobian, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_jacobian);
2782b730f8bSJeremy L Thompson CeedOperatorSetField(op_jacobian, "delta du", data[fine_level]->elem_restr_u, data[fine_level]->basis_u, CEED_VECTOR_ACTIVE);
279356036faSJeremy L Thompson CeedOperatorSetField(op_jacobian, "qdata", data[fine_level]->elem_restr_geo_data_i, CEED_BASIS_NONE, data[fine_level]->geo_data);
2802b730f8bSJeremy L Thompson CeedOperatorSetField(op_jacobian, "delta dv", data[fine_level]->elem_restr_u, data[fine_level]->basis_u, CEED_VECTOR_ACTIVE);
2815754ecacSJeremy L Thompson for (CeedInt i = 0; i < problem_data.number_fields_stored; i++) {
282356036faSJeremy L Thompson CeedOperatorSetField(op_jacobian, problem_data.field_names[i], data[fine_level]->elem_restr_stored_fields_i[i], CEED_BASIS_NONE,
2835754ecacSJeremy L Thompson data[fine_level]->stored_fields[i]);
2845754ecacSJeremy L Thompson }
2855754ecacSJeremy L Thompson // -- Save libCEED data
2865754ecacSJeremy L Thompson data[fine_level]->qf_jacobian = qf_jacobian;
2875754ecacSJeremy L Thompson data[fine_level]->op_jacobian = op_jacobian;
2885754ecacSJeremy L Thompson
2895754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
2905754ecacSJeremy L Thompson // Traction boundary conditions, if needed
2915754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
2925754ecacSJeremy L Thompson if (app_ctx->bc_traction_count > 0) {
2935754ecacSJeremy L Thompson // -- Setup
2945754ecacSJeremy L Thompson DMLabel domain_label;
2952b730f8bSJeremy L Thompson PetscCall(DMGetLabel(dm, "Face Sets", &domain_label));
2962b730f8bSJeremy L Thompson PetscCall(DMGetDimension(dm, &dim));
2975754ecacSJeremy L Thompson
2985754ecacSJeremy L Thompson // -- Basis
2995754ecacSJeremy L Thompson CeedInt height = 1;
3005754ecacSJeremy L Thompson CeedBasis basis_x_face, basis_u_face;
3012b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim - height, num_comp_x, 2, Q, problem_data.quadrature_mode, &basis_x_face);
3022b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim - height, num_comp_u, P, Q, problem_data.quadrature_mode, &basis_u_face);
3035754ecacSJeremy L Thompson // -- QFunction
3045754ecacSJeremy L Thompson CeedQFunction qf_traction;
3055754ecacSJeremy L Thompson CeedQFunctionContext traction_ctx;
3062b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, SetupTractionBCs, SetupTractionBCs_loc, &qf_traction);
3075754ecacSJeremy L Thompson CeedQFunctionContextCreate(ceed, &traction_ctx);
3085754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_traction, traction_ctx);
3092b730f8bSJeremy L Thompson CeedQFunctionAddInput(qf_traction, "dx", num_comp_x * (num_comp_x - height), CEED_EVAL_GRAD);
3105754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_traction, "weight", 1, CEED_EVAL_WEIGHT);
3115754ecacSJeremy L Thompson CeedQFunctionAddOutput(qf_traction, "v", num_comp_u, CEED_EVAL_INTERP);
3125754ecacSJeremy L Thompson
3135754ecacSJeremy L Thompson // -- Compute contribution on each boundary face
3145754ecacSJeremy L Thompson for (CeedInt i = 0; i < app_ctx->bc_traction_count; i++) {
3155754ecacSJeremy L Thompson CeedElemRestriction elem_restr_x_face, elem_restr_u_face;
3165754ecacSJeremy L Thompson CeedOperator op_traction;
3172b730f8bSJeremy L Thompson CeedQFunctionContextSetData(traction_ctx, CEED_MEM_HOST, CEED_USE_POINTER, 3 * sizeof(CeedScalar), app_ctx->bc_traction_vector[i]);
3185754ecacSJeremy L Thompson // Setup restriction
3191a8516d0SJames Wright PetscCall(GetRestrictionForDomain(ceed, dm, 1, domain_label, app_ctx->bc_traction_faces[i], Q, 0, &elem_restr_u_face, &elem_restr_x_face,
3201a8516d0SJames Wright NULL));
3215754ecacSJeremy L Thompson // ---- Create boundary Operator
3225754ecacSJeremy L Thompson CeedOperatorCreate(ceed, qf_traction, NULL, NULL, &op_traction);
3232b730f8bSJeremy L Thompson CeedOperatorSetField(op_traction, "dx", elem_restr_x_face, basis_x_face, CEED_VECTOR_ACTIVE);
3242b730f8bSJeremy L Thompson CeedOperatorSetField(op_traction, "weight", CEED_ELEMRESTRICTION_NONE, basis_x_face, CEED_VECTOR_NONE);
3252b730f8bSJeremy L Thompson CeedOperatorSetField(op_traction, "v", elem_restr_u_face, basis_u_face, CEED_VECTOR_ACTIVE);
3265754ecacSJeremy L Thompson // ---- Compute traction on face
3272b730f8bSJeremy L Thompson CeedOperatorApplyAdd(op_traction, x_coord, neumann_ceed, CEED_REQUEST_IMMEDIATE);
3285754ecacSJeremy L Thompson // ---- Cleanup
3295754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&elem_restr_x_face);
3305754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&elem_restr_u_face);
3315754ecacSJeremy L Thompson CeedOperatorDestroy(&op_traction);
3325754ecacSJeremy L Thompson }
3335754ecacSJeremy L Thompson // -- Cleanup
3345754ecacSJeremy L Thompson CeedBasisDestroy(&basis_x_face);
3355754ecacSJeremy L Thompson CeedBasisDestroy(&basis_u_face);
3365754ecacSJeremy L Thompson CeedQFunctionDestroy(&qf_traction);
3375754ecacSJeremy L Thompson CeedQFunctionContextDestroy(&traction_ctx);
3385754ecacSJeremy L Thompson }
3395754ecacSJeremy L Thompson
3405754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
3415754ecacSJeremy L Thompson // Forcing term, if needed
3425754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
343ea61e9acSJeremy L Thompson // Create the QFunction and Operator that computes the forcing term (RHS) for the non-linear PDE.
3445754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
3455754ecacSJeremy L Thompson if (forcing_choice != FORCE_NONE) {
3465754ecacSJeremy L Thompson CeedQFunction qf_setup_force;
3475754ecacSJeremy L Thompson CeedOperator op_setup_force;
3485754ecacSJeremy L Thompson
3495754ecacSJeremy L Thompson // -- QFunction
3502b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, forcing_options[forcing_choice].setup_forcing, forcing_options[forcing_choice].setup_forcing_loc,
3515754ecacSJeremy L Thompson &qf_setup_force);
3525754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_setup_force, "x", num_comp_x, CEED_EVAL_INTERP);
3532b730f8bSJeremy L Thompson CeedQFunctionAddInput(qf_setup_force, "qdata", q_data_size, CEED_EVAL_NONE);
3545754ecacSJeremy L Thompson CeedQFunctionAddOutput(qf_setup_force, "force", num_comp_u, CEED_EVAL_INTERP);
3555754ecacSJeremy L Thompson if (forcing_choice == FORCE_MMS) {
3565754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_setup_force, phys_ctx);
3575754ecacSJeremy L Thompson } else {
3585754ecacSJeremy L Thompson CeedQFunctionContext ctxForcing;
3595754ecacSJeremy L Thompson CeedQFunctionContextCreate(ceed, &ctxForcing);
3602b730f8bSJeremy L Thompson CeedQFunctionContextSetData(ctxForcing, CEED_MEM_HOST, CEED_USE_POINTER, sizeof(*app_ctx->forcing_vector), app_ctx->forcing_vector);
3615754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_setup_force, ctxForcing);
3625754ecacSJeremy L Thompson CeedQFunctionContextDestroy(&ctxForcing);
3635754ecacSJeremy L Thompson }
3645754ecacSJeremy L Thompson // -- Operator
3652b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_setup_force, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_setup_force);
3662b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_force, "x", data[fine_level]->elem_restr_x, data[fine_level]->basis_x, CEED_VECTOR_ACTIVE);
367356036faSJeremy L Thompson CeedOperatorSetField(op_setup_force, "qdata", data[fine_level]->elem_restr_geo_data_i, CEED_BASIS_NONE, data[fine_level]->geo_data);
3682b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_force, "force", data[fine_level]->elem_restr_u, data[fine_level]->basis_u, CEED_VECTOR_ACTIVE);
3695754ecacSJeremy L Thompson // -- Compute forcing term
3705754ecacSJeremy L Thompson CeedOperatorApply(op_setup_force, x_coord, force_ceed, CEED_REQUEST_IMMEDIATE);
3715754ecacSJeremy L Thompson // -- Cleanup
3725754ecacSJeremy L Thompson CeedQFunctionDestroy(&qf_setup_force);
3735754ecacSJeremy L Thompson CeedOperatorDestroy(&op_setup_force);
3745754ecacSJeremy L Thompson }
3755754ecacSJeremy L Thompson
3765754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
3775754ecacSJeremy L Thompson // True solution, for MMS
3785754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
379ea61e9acSJeremy L Thompson // Create the QFunction and Operator that computes the true solution at the mesh nodes for validation with the manufactured solution.
3805754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
3815754ecacSJeremy L Thompson if (problem_data.true_soln) {
3825754ecacSJeremy L Thompson CeedScalar *true_array;
3835754ecacSJeremy L Thompson const CeedScalar *mult_array;
3845754ecacSJeremy L Thompson CeedVector mult_vec;
3855754ecacSJeremy L Thompson CeedBasis basis_x_true;
3865754ecacSJeremy L Thompson CeedQFunction qf_true;
3875754ecacSJeremy L Thompson CeedOperator op_true;
3885754ecacSJeremy L Thompson
3895754ecacSJeremy L Thompson // -- Solution vector
3905754ecacSJeremy L Thompson CeedVectorCreate(ceed, U_loc_size, &(data[fine_level]->true_soln));
3915754ecacSJeremy L Thompson // -- Basis
3922b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_x, 2, P, CEED_GAUSS_LOBATTO, &basis_x_true);
3935754ecacSJeremy L Thompson // QFunction
3942b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.true_soln, problem_data.true_soln_loc, &qf_true);
3955754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_true, "x", num_comp_x, CEED_EVAL_INTERP);
396a61c78d6SJeremy L Thompson CeedQFunctionAddOutput(qf_true, "true solution", num_comp_u, CEED_EVAL_NONE);
3975754ecacSJeremy L Thompson // Operator
3982b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_true, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_true);
3992b730f8bSJeremy L Thompson CeedOperatorSetField(op_true, "x", data[fine_level]->elem_restr_x, basis_x_true, CEED_VECTOR_ACTIVE);
400356036faSJeremy L Thompson CeedOperatorSetField(op_true, "true solution", data[fine_level]->elem_restr_u, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE);
4015754ecacSJeremy L Thompson // -- Compute true solution
4022b730f8bSJeremy L Thompson CeedOperatorApply(op_true, x_coord, data[fine_level]->true_soln, CEED_REQUEST_IMMEDIATE);
4035754ecacSJeremy L Thompson // -- Multiplicity calculation
4042b730f8bSJeremy L Thompson CeedElemRestrictionCreateVector(data[fine_level]->elem_restr_u, &mult_vec, NULL);
4055754ecacSJeremy L Thompson CeedVectorSetValue(mult_vec, 0.);
4065754ecacSJeremy L Thompson CeedElemRestrictionGetMultiplicity(data[fine_level]->elem_restr_u, mult_vec);
4075754ecacSJeremy L Thompson // -- Multiplicity correction
4085754ecacSJeremy L Thompson CeedVectorGetArray(data[fine_level]->true_soln, CEED_MEM_HOST, &true_array);
4095754ecacSJeremy L Thompson CeedVectorGetArrayRead(mult_vec, CEED_MEM_HOST, &mult_array);
4102b730f8bSJeremy L Thompson for (CeedInt i = 0; i < U_loc_size; i++) true_array[i] /= mult_array[i];
4115754ecacSJeremy L Thompson CeedVectorRestoreArray(data[fine_level]->true_soln, &true_array);
4125754ecacSJeremy L Thompson CeedVectorRestoreArrayRead(mult_vec, &mult_array);
4135754ecacSJeremy L Thompson // -- Cleanup
4145754ecacSJeremy L Thompson CeedVectorDestroy(&mult_vec);
4155754ecacSJeremy L Thompson CeedBasisDestroy(&basis_x_true);
4165754ecacSJeremy L Thompson CeedQFunctionDestroy(&qf_true);
4175754ecacSJeremy L Thompson CeedOperatorDestroy(&op_true);
4185754ecacSJeremy L Thompson }
4195754ecacSJeremy L Thompson
4205754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
4215754ecacSJeremy L Thompson // Local energy computation
4225754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
4235754ecacSJeremy L Thompson // Create the QFunction and Operator that computes the strain energy
4245754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
4255754ecacSJeremy L Thompson // -- QFunction
4262b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.energy, problem_data.energy_loc, &qf_energy);
4275754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_energy, "du", num_comp_u * dim, CEED_EVAL_GRAD);
428a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_energy, "qdata", q_data_size, CEED_EVAL_NONE);
4295754ecacSJeremy L Thompson CeedQFunctionAddOutput(qf_energy, "energy", num_comp_e, CEED_EVAL_INTERP);
4305754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_energy, phys_ctx);
4315754ecacSJeremy L Thompson // -- Operator
4322b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_energy, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_energy);
4332b730f8bSJeremy L Thompson CeedOperatorSetField(op_energy, "du", data[fine_level]->elem_restr_u, data[fine_level]->basis_u, CEED_VECTOR_ACTIVE);
434356036faSJeremy L Thompson CeedOperatorSetField(op_energy, "qdata", data[fine_level]->elem_restr_geo_data_i, CEED_BASIS_NONE, data[fine_level]->geo_data);
4352b730f8bSJeremy L Thompson CeedOperatorSetField(op_energy, "energy", data[fine_level]->elem_restr_energy, data[fine_level]->basis_energy, CEED_VECTOR_ACTIVE);
4365754ecacSJeremy L Thompson // -- Save libCEED data
4375754ecacSJeremy L Thompson data[fine_level]->qf_energy = qf_energy;
4385754ecacSJeremy L Thompson data[fine_level]->op_energy = op_energy;
4395754ecacSJeremy L Thompson
4405754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
4415754ecacSJeremy L Thompson // Diagnostic value computation
4425754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
4435754ecacSJeremy L Thompson // Create the QFunction and Operator that computes nodal diagnostic quantities
4445754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
4455754ecacSJeremy L Thompson // Geometric factors
4465754ecacSJeremy L Thompson // -- Coordinate basis
4475754ecacSJeremy L Thompson CeedBasis basis_x;
4482b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_x, 2, Q, CEED_GAUSS_LOBATTO, &basis_x);
4495754ecacSJeremy L Thompson // -- QFunction
4502b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.setup_geo, problem_data.setup_geo_loc, &qf_setup_geo);
4515754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_setup_geo, "dx", num_comp_x * dim, CEED_EVAL_GRAD);
4525754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_setup_geo, "weight", 1, CEED_EVAL_WEIGHT);
453a61c78d6SJeremy L Thompson CeedQFunctionAddOutput(qf_setup_geo, "qdata", q_data_size, CEED_EVAL_NONE);
4545754ecacSJeremy L Thompson // -- Operator
4552b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_setup_geo, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_setup_geo);
4562b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "dx", data[fine_level]->elem_restr_x, basis_x, CEED_VECTOR_ACTIVE);
4572b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "weight", CEED_ELEMRESTRICTION_NONE, basis_x, CEED_VECTOR_NONE);
458356036faSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "qdata", data[fine_level]->elem_restr_geo_data_diagnostic_i, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE);
4595754ecacSJeremy L Thompson // -- Compute the quadrature data
4602b730f8bSJeremy L Thompson CeedOperatorApply(op_setup_geo, x_coord, data[fine_level]->geo_data_diagnostic, CEED_REQUEST_IMMEDIATE);
4615754ecacSJeremy L Thompson // -- Cleanup
4625754ecacSJeremy L Thompson CeedBasisDestroy(&basis_x);
4635754ecacSJeremy L Thompson CeedQFunctionDestroy(&qf_setup_geo);
4645754ecacSJeremy L Thompson CeedOperatorDestroy(&op_setup_geo);
4655754ecacSJeremy L Thompson
4665754ecacSJeremy L Thompson // Diagnostic quantities
4675754ecacSJeremy L Thompson // -- QFunction
4682b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.diagnostic, problem_data.diagnostic_loc, &qf_diagnostic);
4695754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_diagnostic, "u", num_comp_u, CEED_EVAL_INTERP);
4705754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_diagnostic, "du", num_comp_u * dim, CEED_EVAL_GRAD);
471a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_diagnostic, "qdata", q_data_size, CEED_EVAL_NONE);
4722b730f8bSJeremy L Thompson CeedQFunctionAddOutput(qf_diagnostic, "diagnostic values", num_comp_u + num_comp_d, CEED_EVAL_NONE);
4735754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_diagnostic, phys_ctx);
4745754ecacSJeremy L Thompson // -- Operator
4752b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_diagnostic, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_diagnostic);
4762b730f8bSJeremy L Thompson CeedOperatorSetField(op_diagnostic, "u", data[fine_level]->elem_restr_u, data[fine_level]->basis_diagnostic, CEED_VECTOR_ACTIVE);
4772b730f8bSJeremy L Thompson CeedOperatorSetField(op_diagnostic, "du", data[fine_level]->elem_restr_u, data[fine_level]->basis_diagnostic, CEED_VECTOR_ACTIVE);
478356036faSJeremy L Thompson CeedOperatorSetField(op_diagnostic, "qdata", data[fine_level]->elem_restr_geo_data_diagnostic_i, CEED_BASIS_NONE,
4792b730f8bSJeremy L Thompson data[fine_level]->geo_data_diagnostic);
480356036faSJeremy L Thompson CeedOperatorSetField(op_diagnostic, "diagnostic values", data[fine_level]->elem_restr_diagnostic, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE);
4815754ecacSJeremy L Thompson // -- Save libCEED data
4825754ecacSJeremy L Thompson data[fine_level]->qf_diagnostic = qf_diagnostic;
4835754ecacSJeremy L Thompson data[fine_level]->op_diagnostic = op_diagnostic;
4845754ecacSJeremy L Thompson
4855754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
4865754ecacSJeremy L Thompson // Cleanup
4875754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
4885754ecacSJeremy L Thompson CeedVectorDestroy(&x_coord);
4895754ecacSJeremy L Thompson
490ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS);
4915754ecacSJeremy L Thompson };
4925754ecacSJeremy L Thompson
4935754ecacSJeremy L Thompson // Set up libCEED multigrid level for a given degree
4945754ecacSJeremy L Thompson // Prolongation and Restriction are between level and level+1
SetupLibceedLevel(DM dm,Ceed ceed,AppCtx app_ctx,ProblemData problem_data,PetscInt level,PetscInt num_comp_u,PetscInt U_g_size,PetscInt U_loc_size,CeedVector fine_mult,CeedData * data)4952b730f8bSJeremy L Thompson PetscErrorCode SetupLibceedLevel(DM dm, Ceed ceed, AppCtx app_ctx, ProblemData problem_data, PetscInt level, PetscInt num_comp_u, PetscInt U_g_size,
4962b730f8bSJeremy L Thompson PetscInt U_loc_size, CeedVector fine_mult, CeedData *data) {
4975754ecacSJeremy L Thompson CeedInt fine_level = app_ctx->num_levels - 1;
4985754ecacSJeremy L Thompson CeedInt P = app_ctx->level_degrees[level] + 1;
4995754ecacSJeremy L Thompson CeedInt Q = app_ctx->level_degrees[fine_level] + 1 + app_ctx->q_extra;
5004d00b080SJeremy L Thompson PetscInt dim;
5015754ecacSJeremy L Thompson CeedOperator op_jacobian, op_prolong, op_restrict;
5025754ecacSJeremy L Thompson
5035754ecacSJeremy L Thompson PetscFunctionBeginUser;
5045754ecacSJeremy L Thompson
5052b730f8bSJeremy L Thompson PetscCall(DMGetDimension(dm, &dim));
5065754ecacSJeremy L Thompson
5075754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
5085754ecacSJeremy L Thompson // libCEED restrictions
5095754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
5105754ecacSJeremy L Thompson // -- Solution restriction
5112b730f8bSJeremy L Thompson PetscCall(CreateRestrictionFromPlex(ceed, dm, 0, 0, 0, &data[level]->elem_restr_u));
5125754ecacSJeremy L Thompson
5135754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
5145754ecacSJeremy L Thompson // libCEED bases
5155754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
5165754ecacSJeremy L Thompson // -- Solution basis
5172b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_u, P, Q, problem_data.quadrature_mode, &data[level]->basis_u);
5185754ecacSJeremy L Thompson
5195754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
5205754ecacSJeremy L Thompson // Persistent libCEED vectors
5215754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
5225754ecacSJeremy L Thompson CeedVectorCreate(ceed, U_loc_size, &data[level]->x_ceed);
5235754ecacSJeremy L Thompson CeedVectorCreate(ceed, U_loc_size, &data[level]->y_ceed);
5245754ecacSJeremy L Thompson
5255754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
5265754ecacSJeremy L Thompson // Coarse Grid, Prolongation, and Restriction Operators
5275754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
528ea61e9acSJeremy L Thompson // Create the Operators that compute the prolongation and restriction between the p-multigrid levels and the coarse grid eval.
5295754ecacSJeremy L Thompson // ---------------------------------------------------------------------------
5302b730f8bSJeremy L Thompson CeedOperatorMultigridLevelCreate(data[level + 1]->op_jacobian, fine_mult, data[level]->elem_restr_u, data[level]->basis_u, &op_jacobian,
5312b730f8bSJeremy L Thompson &op_prolong, &op_restrict);
5325754ecacSJeremy L Thompson
5335754ecacSJeremy L Thompson // -- Save libCEED data
5345754ecacSJeremy L Thompson data[level]->op_jacobian = op_jacobian;
5355754ecacSJeremy L Thompson data[level + 1]->op_prolong = op_prolong;
5365754ecacSJeremy L Thompson data[level + 1]->op_restrict = op_restrict;
5375754ecacSJeremy L Thompson
538ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS);
5395754ecacSJeremy L Thompson };
540