15aed82e4SJeremy L Thompson // Copyright (c) 2017-2024, 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 #if PETSC_VERSION_LT(3, 14, 0) 245754ecacSJeremy L Thompson #define DMPlexGetClosureIndices(a, b, c, d, e, f, g, h, i) DMPlexGetClosureIndices(a, b, c, d, f, g, i) 255754ecacSJeremy L Thompson #define DMPlexRestoreClosureIndices(a, b, c, d, e, f, g, h, i) DMPlexRestoreClosureIndices(a, b, c, d, f, g, i) 265754ecacSJeremy L Thompson #endif 275754ecacSJeremy L Thompson 285754ecacSJeremy L Thompson // ----------------------------------------------------------------------------- 295754ecacSJeremy L Thompson // Problem options 305754ecacSJeremy L Thompson // ----------------------------------------------------------------------------- 315754ecacSJeremy L Thompson // Forcing function data 325754ecacSJeremy L Thompson forcingData forcing_options[3] = { 332b730f8bSJeremy L Thompson [FORCE_NONE] = {.setup_forcing = NULL, .setup_forcing_loc = NULL }, 342b730f8bSJeremy L Thompson [FORCE_CONST] = {.setup_forcing = SetupConstantForce, .setup_forcing_loc = SetupConstantForce_loc}, 352b730f8bSJeremy L Thompson [FORCE_MMS] = {.setup_forcing = SetupMMSForce, .setup_forcing_loc = SetupMMSForce_loc } 365754ecacSJeremy L Thompson }; 375754ecacSJeremy L Thompson 385754ecacSJeremy L Thompson // ----------------------------------------------------------------------------- 395754ecacSJeremy L Thompson // libCEED Functions 405754ecacSJeremy L Thompson // ----------------------------------------------------------------------------- 415754ecacSJeremy L Thompson // Destroy libCEED objects 425754ecacSJeremy L Thompson PetscErrorCode CeedDataDestroy(CeedInt level, CeedData data) { 435754ecacSJeremy L Thompson PetscFunctionBegin; 445754ecacSJeremy L Thompson 455754ecacSJeremy L Thompson // Vectors 465754ecacSJeremy L Thompson CeedVectorDestroy(&data->x_ceed); 475754ecacSJeremy L Thompson CeedVectorDestroy(&data->y_ceed); 485754ecacSJeremy L Thompson CeedVectorDestroy(&data->geo_data); 492b730f8bSJeremy L Thompson for (CeedInt i = 0; i < SOLIDS_MAX_NUMBER_FIELDS; i++) CeedVectorDestroy(&data->stored_fields[i]); 505754ecacSJeremy L Thompson CeedVectorDestroy(&data->geo_data_diagnostic); 515754ecacSJeremy L Thompson CeedVectorDestroy(&data->true_soln); 525754ecacSJeremy L Thompson // Restrictions 535754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_x); 545754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_u); 555754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_geo_data_i); 562b730f8bSJeremy L Thompson for (CeedInt i = 0; i < SOLIDS_MAX_NUMBER_FIELDS; i++) CeedElemRestrictionDestroy(&data->elem_restr_stored_fields_i[i]); 575754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_energy); 585754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_diagnostic); 595754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_geo_data_diagnostic_i); 605754ecacSJeremy L Thompson // Bases 615754ecacSJeremy L Thompson CeedBasisDestroy(&data->basis_x); 625754ecacSJeremy L Thompson CeedBasisDestroy(&data->basis_u); 635754ecacSJeremy L Thompson CeedBasisDestroy(&data->basis_energy); 645754ecacSJeremy L Thompson CeedBasisDestroy(&data->basis_diagnostic); 655754ecacSJeremy L Thompson // QFunctions 665754ecacSJeremy L Thompson CeedQFunctionDestroy(&data->qf_residual); 675754ecacSJeremy L Thompson CeedQFunctionDestroy(&data->qf_jacobian); 685754ecacSJeremy L Thompson CeedQFunctionDestroy(&data->qf_energy); 695754ecacSJeremy L Thompson CeedQFunctionDestroy(&data->qf_diagnostic); 705754ecacSJeremy L Thompson // Operators 715754ecacSJeremy L Thompson CeedOperatorDestroy(&data->op_residual); 725754ecacSJeremy L Thompson CeedOperatorDestroy(&data->op_jacobian); 735754ecacSJeremy L Thompson CeedOperatorDestroy(&data->op_energy); 745754ecacSJeremy L Thompson CeedOperatorDestroy(&data->op_diagnostic); 755754ecacSJeremy L Thompson // Restriction and Prolongation data 765754ecacSJeremy L Thompson CeedBasisDestroy(&data->basis_c_to_f); 775754ecacSJeremy L Thompson CeedOperatorDestroy(&data->op_prolong); 785754ecacSJeremy L Thompson CeedOperatorDestroy(&data->op_restrict); 795754ecacSJeremy L Thompson 802b730f8bSJeremy L Thompson PetscCall(PetscFree(data)); 815754ecacSJeremy L Thompson 82ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 835754ecacSJeremy L Thompson }; 845754ecacSJeremy L Thompson 855754ecacSJeremy L Thompson // Utility function to create local CEED restriction from DMPlex 862b730f8bSJeremy L Thompson PetscErrorCode CreateRestrictionFromPlex(Ceed ceed, DM dm, CeedInt height, DMLabel domain_label, CeedInt value, CeedElemRestriction *elem_restr) { 87*4d00b080SJeremy L Thompson PetscInt num_elem, elem_size, num_dof, num_comp, *elem_restr_offsets_petsc; 88*4d00b080SJeremy L Thompson CeedInt *elem_restr_offsets_ceed; 895754ecacSJeremy L Thompson 905754ecacSJeremy L Thompson PetscFunctionBeginUser; 91*4d00b080SJeremy L Thompson PetscCall(DMPlexGetLocalOffsets(dm, domain_label, value, height, 0, &num_elem, &elem_size, &num_comp, &num_dof, &elem_restr_offsets_petsc)); 925754ecacSJeremy L Thompson 93*4d00b080SJeremy L Thompson PetscCall(IntArrayPetscToCeed(num_elem * elem_size, &elem_restr_offsets_petsc, &elem_restr_offsets_ceed)); 94*4d00b080SJeremy 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); 95*4d00b080SJeremy L Thompson PetscCall(PetscFree(elem_restr_offsets_ceed)); 965754ecacSJeremy L Thompson 97ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 985754ecacSJeremy L Thompson }; 995754ecacSJeremy L Thompson 1005754ecacSJeremy L Thompson // Utility function to get Ceed Restriction for each domain 1012b730f8bSJeremy L Thompson PetscErrorCode GetRestrictionForDomain(Ceed ceed, DM dm, CeedInt height, DMLabel domain_label, PetscInt value, CeedInt Q, CeedInt q_data_size, 1022b730f8bSJeremy L Thompson CeedElemRestriction *elem_restr_q, CeedElemRestriction *elem_restr_x, CeedElemRestriction *elem_restr_qd_i) { 1035754ecacSJeremy L Thompson DM dm_coord; 104*4d00b080SJeremy L Thompson CeedInt num_local_elem, Q_dim; 105*4d00b080SJeremy L Thompson PetscInt dim; 1065754ecacSJeremy L Thompson 1075754ecacSJeremy L Thompson PetscFunctionBeginUser; 1085754ecacSJeremy L Thompson 1092b730f8bSJeremy L Thompson PetscCall(DMGetDimension(dm, &dim)); 1105754ecacSJeremy L Thompson dim -= height; 1115754ecacSJeremy L Thompson Q_dim = CeedIntPow(Q, dim); 1122b730f8bSJeremy L Thompson PetscCall(DMGetCoordinateDM(dm, &dm_coord)); 1132b730f8bSJeremy L Thompson PetscCall(DMPlexSetClosurePermutationTensor(dm_coord, PETSC_DETERMINE, NULL)); 1145754ecacSJeremy L Thompson if (elem_restr_q) { 1152b730f8bSJeremy L Thompson PetscCall(CreateRestrictionFromPlex(ceed, dm, height, domain_label, value, elem_restr_q)); 1165754ecacSJeremy L Thompson } 1175754ecacSJeremy L Thompson if (elem_restr_x) { 1182b730f8bSJeremy L Thompson PetscCall(CreateRestrictionFromPlex(ceed, dm_coord, height, domain_label, value, elem_restr_x)); 1195754ecacSJeremy L Thompson } 1205754ecacSJeremy L Thompson if (elem_restr_qd_i) { 1215754ecacSJeremy L Thompson CeedElemRestrictionGetNumElements(*elem_restr_q, &num_local_elem); 1222b730f8bSJeremy L Thompson CeedElemRestrictionCreateStrided(ceed, num_local_elem, Q_dim, q_data_size, q_data_size * num_local_elem * Q_dim, CEED_STRIDES_BACKEND, 1232b730f8bSJeremy L Thompson elem_restr_qd_i); 1245754ecacSJeremy L Thompson } 1255754ecacSJeremy L Thompson 126ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 1275754ecacSJeremy L Thompson }; 1285754ecacSJeremy L Thompson 1295754ecacSJeremy L Thompson // Set up libCEED on the fine grid for a given degree 1302b730f8bSJeremy L Thompson PetscErrorCode SetupLibceedFineLevel(DM dm, DM dm_energy, DM dm_diagnostic, Ceed ceed, AppCtx app_ctx, CeedQFunctionContext phys_ctx, 1312b730f8bSJeremy L Thompson ProblemData problem_data, PetscInt fine_level, PetscInt num_comp_u, PetscInt U_g_size, PetscInt U_loc_size, 1322b730f8bSJeremy L Thompson CeedVector force_ceed, CeedVector neumann_ceed, CeedData *data) { 1335754ecacSJeremy L Thompson CeedInt P = app_ctx->level_degrees[fine_level] + 1; 1345754ecacSJeremy L Thompson CeedInt Q = app_ctx->level_degrees[fine_level] + 1 + app_ctx->q_extra; 135*4d00b080SJeremy L Thompson CeedInt num_comp_x, num_comp_e = 1, num_comp_d = 5; 1365754ecacSJeremy L Thompson CeedInt num_qpts; 137a61c78d6SJeremy L Thompson CeedInt q_data_size = problem_data.q_data_size; 1385754ecacSJeremy L Thompson forcingType forcing_choice = app_ctx->forcing_choice; 1395754ecacSJeremy L Thompson DM dm_coord; 1405754ecacSJeremy L Thompson Vec coords; 141*4d00b080SJeremy L Thompson PetscInt c_start, c_end, num_elem, dim; 1425754ecacSJeremy L Thompson const PetscScalar *coordArray; 1435754ecacSJeremy L Thompson CeedVector x_coord; 1445754ecacSJeremy L Thompson CeedQFunction qf_setup_geo, qf_residual, qf_jacobian, qf_energy, qf_diagnostic; 1455754ecacSJeremy L Thompson CeedOperator op_setup_geo, op_residual, op_jacobian, op_energy, op_diagnostic; 1465754ecacSJeremy L Thompson 1475754ecacSJeremy L Thompson PetscFunctionBeginUser; 1485754ecacSJeremy L Thompson 1495754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 1505754ecacSJeremy L Thompson // libCEED bases 1515754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 1522b730f8bSJeremy L Thompson PetscCall(DMGetDimension(dm, &dim)); 1535754ecacSJeremy L Thompson num_comp_x = dim; 1545754ecacSJeremy L Thompson // -- Coordinate basis 1552b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_x, 2, Q, problem_data.quadrature_mode, &data[fine_level]->basis_x); 1565754ecacSJeremy L Thompson // -- Solution basis 1572b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_u, P, Q, problem_data.quadrature_mode, &data[fine_level]->basis_u); 1585754ecacSJeremy L Thompson // -- Energy basis 1592b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_e, P, Q, problem_data.quadrature_mode, &data[fine_level]->basis_energy); 1605754ecacSJeremy L Thompson // -- Diagnostic output basis 1612b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_u, P, P, CEED_GAUSS_LOBATTO, &data[fine_level]->basis_diagnostic); 1625754ecacSJeremy L Thompson 1635754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 1645754ecacSJeremy L Thompson // libCEED restrictions 1655754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 1662b730f8bSJeremy L Thompson PetscCall(DMGetCoordinateDM(dm, &dm_coord)); 1672b730f8bSJeremy L Thompson PetscCall(DMPlexSetClosurePermutationTensor(dm_coord, PETSC_DETERMINE, NULL)); 1685754ecacSJeremy L Thompson 1695754ecacSJeremy L Thompson // -- Coordinate restriction 1702b730f8bSJeremy L Thompson PetscCall(CreateRestrictionFromPlex(ceed, dm_coord, 0, 0, 0, &(data[fine_level]->elem_restr_x))); 1715754ecacSJeremy L Thompson // -- Solution restriction 1722b730f8bSJeremy L Thompson PetscCall(CreateRestrictionFromPlex(ceed, dm, 0, 0, 0, &data[fine_level]->elem_restr_u)); 1735754ecacSJeremy L Thompson // -- Energy restriction 1742b730f8bSJeremy L Thompson PetscCall(CreateRestrictionFromPlex(ceed, dm_energy, 0, 0, 0, &data[fine_level]->elem_restr_energy)); 1755754ecacSJeremy L Thompson // -- Diagnostic data restriction 1762b730f8bSJeremy L Thompson PetscCall(CreateRestrictionFromPlex(ceed, dm_diagnostic, 0, 0, 0, &data[fine_level]->elem_restr_diagnostic)); 1775754ecacSJeremy L Thompson 1785754ecacSJeremy L Thompson // -- Stored data at quadrature points 1792b730f8bSJeremy L Thompson PetscCall(DMPlexGetHeightStratum(dm, 0, &c_start, &c_end)); 1805754ecacSJeremy L Thompson num_elem = c_end - c_start; 1815754ecacSJeremy L Thompson CeedBasisGetNumQuadraturePoints(data[fine_level]->basis_u, &num_qpts); 1825754ecacSJeremy L Thompson // ---- Geometric data restriction, residual and Jacobian operators 1832b730f8bSJeremy L Thompson CeedElemRestrictionCreateStrided(ceed, num_elem, num_qpts, q_data_size, num_elem * num_qpts * q_data_size, CEED_STRIDES_BACKEND, 1845754ecacSJeremy L Thompson &data[fine_level]->elem_restr_geo_data_i); 1855754ecacSJeremy L Thompson // ---- Stored field restrictions 1865754ecacSJeremy L Thompson for (CeedInt i = 0; i < problem_data.number_fields_stored; i++) { 1872b730f8bSJeremy L Thompson CeedElemRestrictionCreateStrided(ceed, num_elem, num_qpts, problem_data.field_sizes[i], num_elem * num_qpts * problem_data.field_sizes[i], 1882b730f8bSJeremy L Thompson CEED_STRIDES_BACKEND, &data[fine_level]->elem_restr_stored_fields_i[i]); 1895754ecacSJeremy L Thompson } 1905754ecacSJeremy L Thompson // ---- Geometric data restriction, diagnostic operator 1912b730f8bSJeremy L Thompson CeedElemRestrictionCreateStrided(ceed, num_elem, P * P * P, q_data_size, num_elem * P * P * P * q_data_size, CEED_STRIDES_BACKEND, 1925754ecacSJeremy L Thompson &data[fine_level]->elem_restr_geo_data_diagnostic_i); 1935754ecacSJeremy L Thompson 1945754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 1955754ecacSJeremy L Thompson // Element coordinates 1965754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 1972b730f8bSJeremy L Thompson PetscCall(DMGetCoordinatesLocal(dm, &coords)); 1982b730f8bSJeremy L Thompson PetscCall(VecGetArrayRead(coords, &coordArray)); 1995754ecacSJeremy L Thompson 2005754ecacSJeremy L Thompson CeedElemRestrictionCreateVector(data[fine_level]->elem_restr_x, &x_coord, NULL); 2012b730f8bSJeremy L Thompson CeedVectorSetArray(x_coord, CEED_MEM_HOST, CEED_COPY_VALUES, (PetscScalar *)coordArray); 2022b730f8bSJeremy L Thompson PetscCall(VecRestoreArrayRead(coords, &coordArray)); 2035754ecacSJeremy L Thompson 2045754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 2055754ecacSJeremy L Thompson // Persistent libCEED vectors 2065754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 2075754ecacSJeremy L Thompson // -- Operator action variables 2085754ecacSJeremy L Thompson CeedVectorCreate(ceed, U_loc_size, &data[fine_level]->x_ceed); 2095754ecacSJeremy L Thompson CeedVectorCreate(ceed, U_loc_size, &data[fine_level]->y_ceed); 2105754ecacSJeremy L Thompson // -- Geometric data vector 2112b730f8bSJeremy L Thompson CeedVectorCreate(ceed, num_elem * num_qpts * q_data_size, &data[fine_level]->geo_data); 2125754ecacSJeremy L Thompson // -- Stored field vectors 2135754ecacSJeremy L Thompson for (CeedInt i = 0; i < problem_data.number_fields_stored; i++) { 2142b730f8bSJeremy L Thompson CeedVectorCreate(ceed, num_elem * num_qpts * problem_data.field_sizes[i], &data[fine_level]->stored_fields[i]); 2155754ecacSJeremy L Thompson } 2165754ecacSJeremy L Thompson // -- Collocated geometric data vector 2172b730f8bSJeremy L Thompson CeedVectorCreate(ceed, num_elem * P * P * P * q_data_size, &data[fine_level]->geo_data_diagnostic); 2185754ecacSJeremy L Thompson 2195754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 2205754ecacSJeremy L Thompson // Geometric factor computation 2215754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 222ea61e9acSJeremy L Thompson // Create the QFunction and Operator that computes the quadrature data geo_data returns dXdx_i,j and w * det. 2235754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 2245754ecacSJeremy L Thompson // -- QFunction 2252b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.setup_geo, problem_data.setup_geo_loc, &qf_setup_geo); 2265754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_setup_geo, "dx", num_comp_x * dim, CEED_EVAL_GRAD); 2275754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_setup_geo, "weight", 1, CEED_EVAL_WEIGHT); 228a61c78d6SJeremy L Thompson CeedQFunctionAddOutput(qf_setup_geo, "qdata", q_data_size, CEED_EVAL_NONE); 2295754ecacSJeremy L Thompson // -- Operator 2302b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_setup_geo, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_setup_geo); 2312b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "dx", data[fine_level]->elem_restr_x, data[fine_level]->basis_x, CEED_VECTOR_ACTIVE); 2322b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "weight", CEED_ELEMRESTRICTION_NONE, data[fine_level]->basis_x, CEED_VECTOR_NONE); 233356036faSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "qdata", data[fine_level]->elem_restr_geo_data_i, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE); 2345754ecacSJeremy L Thompson // -- Compute the quadrature data 2352b730f8bSJeremy L Thompson CeedOperatorApply(op_setup_geo, x_coord, data[fine_level]->geo_data, CEED_REQUEST_IMMEDIATE); 2365754ecacSJeremy L Thompson // -- Cleanup 2375754ecacSJeremy L Thompson CeedQFunctionDestroy(&qf_setup_geo); 2385754ecacSJeremy L Thompson CeedOperatorDestroy(&op_setup_geo); 2395754ecacSJeremy L Thompson 2405754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 2415754ecacSJeremy L Thompson // Local residual evaluator 2425754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 243ea61e9acSJeremy L Thompson // Create the QFunction and Operator that computes the residual of the non-linear PDE. 2445754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 2455754ecacSJeremy L Thompson // -- QFunction 2462b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.residual, problem_data.residual_loc, &qf_residual); 2475754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_residual, "du", num_comp_u * dim, CEED_EVAL_GRAD); 248a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_residual, "qdata", q_data_size, CEED_EVAL_NONE); 2495754ecacSJeremy L Thompson CeedQFunctionAddOutput(qf_residual, "dv", num_comp_u * dim, CEED_EVAL_GRAD); 2505754ecacSJeremy L Thompson for (CeedInt i = 0; i < problem_data.number_fields_stored; i++) { 2512b730f8bSJeremy L Thompson CeedQFunctionAddOutput(qf_residual, problem_data.field_names[i], problem_data.field_sizes[i], CEED_EVAL_NONE); 2525754ecacSJeremy L Thompson } 2535754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_residual, phys_ctx); 2545754ecacSJeremy L Thompson // -- Operator 2552b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_residual, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_residual); 2562b730f8bSJeremy L Thompson CeedOperatorSetField(op_residual, "du", data[fine_level]->elem_restr_u, data[fine_level]->basis_u, CEED_VECTOR_ACTIVE); 257356036faSJeremy L Thompson CeedOperatorSetField(op_residual, "qdata", data[fine_level]->elem_restr_geo_data_i, CEED_BASIS_NONE, data[fine_level]->geo_data); 2582b730f8bSJeremy L Thompson CeedOperatorSetField(op_residual, "dv", data[fine_level]->elem_restr_u, data[fine_level]->basis_u, CEED_VECTOR_ACTIVE); 2595754ecacSJeremy L Thompson for (CeedInt i = 0; i < problem_data.number_fields_stored; i++) { 260356036faSJeremy L Thompson CeedOperatorSetField(op_residual, problem_data.field_names[i], data[fine_level]->elem_restr_stored_fields_i[i], CEED_BASIS_NONE, 2615754ecacSJeremy L Thompson data[fine_level]->stored_fields[i]); 2625754ecacSJeremy L Thompson } 2635754ecacSJeremy L Thompson // -- Save libCEED data 2645754ecacSJeremy L Thompson data[fine_level]->qf_residual = qf_residual; 2655754ecacSJeremy L Thompson data[fine_level]->op_residual = op_residual; 2665754ecacSJeremy L Thompson 2675754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 2685754ecacSJeremy L Thompson // Jacobian evaluator 2695754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 270ea61e9acSJeremy L Thompson // Create the QFunction and Operator that computes the action of the Jacobian for each linear solve. 2715754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 2725754ecacSJeremy L Thompson // -- QFunction 2732b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.jacobian, problem_data.jacobian_loc, &qf_jacobian); 2745754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_jacobian, "delta du", num_comp_u * dim, CEED_EVAL_GRAD); 275a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_jacobian, "qdata", q_data_size, CEED_EVAL_NONE); 2765754ecacSJeremy L Thompson for (CeedInt i = 0; i < problem_data.number_fields_stored; i++) { 2772b730f8bSJeremy L Thompson CeedQFunctionAddInput(qf_jacobian, problem_data.field_names[i], problem_data.field_sizes[i], CEED_EVAL_NONE); 2785754ecacSJeremy L Thompson } 2795754ecacSJeremy L Thompson CeedQFunctionAddOutput(qf_jacobian, "delta dv", num_comp_u * dim, CEED_EVAL_GRAD); 2805754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_jacobian, phys_ctx); 2815754ecacSJeremy L Thompson // -- Operator 2822b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_jacobian, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_jacobian); 2832b730f8bSJeremy L Thompson CeedOperatorSetField(op_jacobian, "delta du", data[fine_level]->elem_restr_u, data[fine_level]->basis_u, CEED_VECTOR_ACTIVE); 284356036faSJeremy L Thompson CeedOperatorSetField(op_jacobian, "qdata", data[fine_level]->elem_restr_geo_data_i, CEED_BASIS_NONE, data[fine_level]->geo_data); 2852b730f8bSJeremy L Thompson CeedOperatorSetField(op_jacobian, "delta dv", data[fine_level]->elem_restr_u, data[fine_level]->basis_u, CEED_VECTOR_ACTIVE); 2865754ecacSJeremy L Thompson for (CeedInt i = 0; i < problem_data.number_fields_stored; i++) { 287356036faSJeremy L Thompson CeedOperatorSetField(op_jacobian, problem_data.field_names[i], data[fine_level]->elem_restr_stored_fields_i[i], CEED_BASIS_NONE, 2885754ecacSJeremy L Thompson data[fine_level]->stored_fields[i]); 2895754ecacSJeremy L Thompson } 2905754ecacSJeremy L Thompson // -- Save libCEED data 2915754ecacSJeremy L Thompson data[fine_level]->qf_jacobian = qf_jacobian; 2925754ecacSJeremy L Thompson data[fine_level]->op_jacobian = op_jacobian; 2935754ecacSJeremy L Thompson 2945754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 2955754ecacSJeremy L Thompson // Traction boundary conditions, if needed 2965754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 2975754ecacSJeremy L Thompson if (app_ctx->bc_traction_count > 0) { 2985754ecacSJeremy L Thompson // -- Setup 2995754ecacSJeremy L Thompson DMLabel domain_label; 3002b730f8bSJeremy L Thompson PetscCall(DMGetLabel(dm, "Face Sets", &domain_label)); 3012b730f8bSJeremy L Thompson PetscCall(DMGetDimension(dm, &dim)); 3025754ecacSJeremy L Thompson 3035754ecacSJeremy L Thompson // -- Basis 3045754ecacSJeremy L Thompson CeedInt height = 1; 3055754ecacSJeremy L Thompson CeedBasis basis_x_face, basis_u_face; 3062b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim - height, num_comp_x, 2, Q, problem_data.quadrature_mode, &basis_x_face); 3072b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim - height, num_comp_u, P, Q, problem_data.quadrature_mode, &basis_u_face); 3085754ecacSJeremy L Thompson // -- QFunction 3095754ecacSJeremy L Thompson CeedQFunction qf_traction; 3105754ecacSJeremy L Thompson CeedQFunctionContext traction_ctx; 3112b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, SetupTractionBCs, SetupTractionBCs_loc, &qf_traction); 3125754ecacSJeremy L Thompson CeedQFunctionContextCreate(ceed, &traction_ctx); 3135754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_traction, traction_ctx); 3142b730f8bSJeremy L Thompson CeedQFunctionAddInput(qf_traction, "dx", num_comp_x * (num_comp_x - height), CEED_EVAL_GRAD); 3155754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_traction, "weight", 1, CEED_EVAL_WEIGHT); 3165754ecacSJeremy L Thompson CeedQFunctionAddOutput(qf_traction, "v", num_comp_u, CEED_EVAL_INTERP); 3175754ecacSJeremy L Thompson 3185754ecacSJeremy L Thompson // -- Compute contribution on each boundary face 3195754ecacSJeremy L Thompson for (CeedInt i = 0; i < app_ctx->bc_traction_count; i++) { 3205754ecacSJeremy L Thompson CeedElemRestriction elem_restr_x_face, elem_restr_u_face; 3215754ecacSJeremy L Thompson CeedOperator op_traction; 3222b730f8bSJeremy L Thompson CeedQFunctionContextSetData(traction_ctx, CEED_MEM_HOST, CEED_USE_POINTER, 3 * sizeof(CeedScalar), app_ctx->bc_traction_vector[i]); 3235754ecacSJeremy L Thompson // Setup restriction 3242b730f8bSJeremy L Thompson PetscCall( 3252b730f8bSJeremy L Thompson GetRestrictionForDomain(ceed, dm, 1, domain_label, app_ctx->bc_traction_faces[i], Q, 0, &elem_restr_u_face, &elem_restr_x_face, NULL)); 3265754ecacSJeremy L Thompson // ---- Create boundary Operator 3275754ecacSJeremy L Thompson CeedOperatorCreate(ceed, qf_traction, NULL, NULL, &op_traction); 3282b730f8bSJeremy L Thompson CeedOperatorSetField(op_traction, "dx", elem_restr_x_face, basis_x_face, CEED_VECTOR_ACTIVE); 3292b730f8bSJeremy L Thompson CeedOperatorSetField(op_traction, "weight", CEED_ELEMRESTRICTION_NONE, basis_x_face, CEED_VECTOR_NONE); 3302b730f8bSJeremy L Thompson CeedOperatorSetField(op_traction, "v", elem_restr_u_face, basis_u_face, CEED_VECTOR_ACTIVE); 3315754ecacSJeremy L Thompson // ---- Compute traction on face 3322b730f8bSJeremy L Thompson CeedOperatorApplyAdd(op_traction, x_coord, neumann_ceed, CEED_REQUEST_IMMEDIATE); 3335754ecacSJeremy L Thompson // ---- Cleanup 3345754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&elem_restr_x_face); 3355754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&elem_restr_u_face); 3365754ecacSJeremy L Thompson CeedOperatorDestroy(&op_traction); 3375754ecacSJeremy L Thompson } 3385754ecacSJeremy L Thompson // -- Cleanup 3395754ecacSJeremy L Thompson CeedBasisDestroy(&basis_x_face); 3405754ecacSJeremy L Thompson CeedBasisDestroy(&basis_u_face); 3415754ecacSJeremy L Thompson CeedQFunctionDestroy(&qf_traction); 3425754ecacSJeremy L Thompson CeedQFunctionContextDestroy(&traction_ctx); 3435754ecacSJeremy L Thompson } 3445754ecacSJeremy L Thompson 3455754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 3465754ecacSJeremy L Thompson // Forcing term, if needed 3475754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 348ea61e9acSJeremy L Thompson // Create the QFunction and Operator that computes the forcing term (RHS) for the non-linear PDE. 3495754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 3505754ecacSJeremy L Thompson if (forcing_choice != FORCE_NONE) { 3515754ecacSJeremy L Thompson CeedQFunction qf_setup_force; 3525754ecacSJeremy L Thompson CeedOperator op_setup_force; 3535754ecacSJeremy L Thompson 3545754ecacSJeremy L Thompson // -- QFunction 3552b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, forcing_options[forcing_choice].setup_forcing, forcing_options[forcing_choice].setup_forcing_loc, 3565754ecacSJeremy L Thompson &qf_setup_force); 3575754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_setup_force, "x", num_comp_x, CEED_EVAL_INTERP); 3582b730f8bSJeremy L Thompson CeedQFunctionAddInput(qf_setup_force, "qdata", q_data_size, CEED_EVAL_NONE); 3595754ecacSJeremy L Thompson CeedQFunctionAddOutput(qf_setup_force, "force", num_comp_u, CEED_EVAL_INTERP); 3605754ecacSJeremy L Thompson if (forcing_choice == FORCE_MMS) { 3615754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_setup_force, phys_ctx); 3625754ecacSJeremy L Thompson } else { 3635754ecacSJeremy L Thompson CeedQFunctionContext ctxForcing; 3645754ecacSJeremy L Thompson CeedQFunctionContextCreate(ceed, &ctxForcing); 3652b730f8bSJeremy L Thompson CeedQFunctionContextSetData(ctxForcing, CEED_MEM_HOST, CEED_USE_POINTER, sizeof(*app_ctx->forcing_vector), app_ctx->forcing_vector); 3665754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_setup_force, ctxForcing); 3675754ecacSJeremy L Thompson CeedQFunctionContextDestroy(&ctxForcing); 3685754ecacSJeremy L Thompson } 3695754ecacSJeremy L Thompson // -- Operator 3702b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_setup_force, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_setup_force); 3712b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_force, "x", data[fine_level]->elem_restr_x, data[fine_level]->basis_x, CEED_VECTOR_ACTIVE); 372356036faSJeremy L Thompson CeedOperatorSetField(op_setup_force, "qdata", data[fine_level]->elem_restr_geo_data_i, CEED_BASIS_NONE, data[fine_level]->geo_data); 3732b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_force, "force", data[fine_level]->elem_restr_u, data[fine_level]->basis_u, CEED_VECTOR_ACTIVE); 3745754ecacSJeremy L Thompson // -- Compute forcing term 3755754ecacSJeremy L Thompson CeedOperatorApply(op_setup_force, x_coord, force_ceed, CEED_REQUEST_IMMEDIATE); 3765754ecacSJeremy L Thompson // -- Cleanup 3775754ecacSJeremy L Thompson CeedQFunctionDestroy(&qf_setup_force); 3785754ecacSJeremy L Thompson CeedOperatorDestroy(&op_setup_force); 3795754ecacSJeremy L Thompson } 3805754ecacSJeremy L Thompson 3815754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 3825754ecacSJeremy L Thompson // True solution, for MMS 3835754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 384ea61e9acSJeremy L Thompson // Create the QFunction and Operator that computes the true solution at the mesh nodes for validation with the manufactured solution. 3855754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 3865754ecacSJeremy L Thompson if (problem_data.true_soln) { 3875754ecacSJeremy L Thompson CeedScalar *true_array; 3885754ecacSJeremy L Thompson const CeedScalar *mult_array; 3895754ecacSJeremy L Thompson CeedVector mult_vec; 3905754ecacSJeremy L Thompson CeedBasis basis_x_true; 3915754ecacSJeremy L Thompson CeedQFunction qf_true; 3925754ecacSJeremy L Thompson CeedOperator op_true; 3935754ecacSJeremy L Thompson 3945754ecacSJeremy L Thompson // -- Solution vector 3955754ecacSJeremy L Thompson CeedVectorCreate(ceed, U_loc_size, &(data[fine_level]->true_soln)); 3965754ecacSJeremy L Thompson // -- Basis 3972b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_x, 2, P, CEED_GAUSS_LOBATTO, &basis_x_true); 3985754ecacSJeremy L Thompson // QFunction 3992b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.true_soln, problem_data.true_soln_loc, &qf_true); 4005754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_true, "x", num_comp_x, CEED_EVAL_INTERP); 401a61c78d6SJeremy L Thompson CeedQFunctionAddOutput(qf_true, "true solution", num_comp_u, CEED_EVAL_NONE); 4025754ecacSJeremy L Thompson // Operator 4032b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_true, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_true); 4042b730f8bSJeremy L Thompson CeedOperatorSetField(op_true, "x", data[fine_level]->elem_restr_x, basis_x_true, CEED_VECTOR_ACTIVE); 405356036faSJeremy L Thompson CeedOperatorSetField(op_true, "true solution", data[fine_level]->elem_restr_u, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE); 4065754ecacSJeremy L Thompson // -- Compute true solution 4072b730f8bSJeremy L Thompson CeedOperatorApply(op_true, x_coord, data[fine_level]->true_soln, CEED_REQUEST_IMMEDIATE); 4085754ecacSJeremy L Thompson // -- Multiplicity calculation 4092b730f8bSJeremy L Thompson CeedElemRestrictionCreateVector(data[fine_level]->elem_restr_u, &mult_vec, NULL); 4105754ecacSJeremy L Thompson CeedVectorSetValue(mult_vec, 0.); 4115754ecacSJeremy L Thompson CeedElemRestrictionGetMultiplicity(data[fine_level]->elem_restr_u, mult_vec); 4125754ecacSJeremy L Thompson // -- Multiplicity correction 4135754ecacSJeremy L Thompson CeedVectorGetArray(data[fine_level]->true_soln, CEED_MEM_HOST, &true_array); 4145754ecacSJeremy L Thompson CeedVectorGetArrayRead(mult_vec, CEED_MEM_HOST, &mult_array); 4152b730f8bSJeremy L Thompson for (CeedInt i = 0; i < U_loc_size; i++) true_array[i] /= mult_array[i]; 4165754ecacSJeremy L Thompson CeedVectorRestoreArray(data[fine_level]->true_soln, &true_array); 4175754ecacSJeremy L Thompson CeedVectorRestoreArrayRead(mult_vec, &mult_array); 4185754ecacSJeremy L Thompson // -- Cleanup 4195754ecacSJeremy L Thompson CeedVectorDestroy(&mult_vec); 4205754ecacSJeremy L Thompson CeedBasisDestroy(&basis_x_true); 4215754ecacSJeremy L Thompson CeedQFunctionDestroy(&qf_true); 4225754ecacSJeremy L Thompson CeedOperatorDestroy(&op_true); 4235754ecacSJeremy L Thompson } 4245754ecacSJeremy L Thompson 4255754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 4265754ecacSJeremy L Thompson // Local energy computation 4275754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 4285754ecacSJeremy L Thompson // Create the QFunction and Operator that computes the strain energy 4295754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 4305754ecacSJeremy L Thompson // -- QFunction 4312b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.energy, problem_data.energy_loc, &qf_energy); 4325754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_energy, "du", num_comp_u * dim, CEED_EVAL_GRAD); 433a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_energy, "qdata", q_data_size, CEED_EVAL_NONE); 4345754ecacSJeremy L Thompson CeedQFunctionAddOutput(qf_energy, "energy", num_comp_e, CEED_EVAL_INTERP); 4355754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_energy, phys_ctx); 4365754ecacSJeremy L Thompson // -- Operator 4372b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_energy, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_energy); 4382b730f8bSJeremy L Thompson CeedOperatorSetField(op_energy, "du", data[fine_level]->elem_restr_u, data[fine_level]->basis_u, CEED_VECTOR_ACTIVE); 439356036faSJeremy L Thompson CeedOperatorSetField(op_energy, "qdata", data[fine_level]->elem_restr_geo_data_i, CEED_BASIS_NONE, data[fine_level]->geo_data); 4402b730f8bSJeremy L Thompson CeedOperatorSetField(op_energy, "energy", data[fine_level]->elem_restr_energy, data[fine_level]->basis_energy, CEED_VECTOR_ACTIVE); 4415754ecacSJeremy L Thompson // -- Save libCEED data 4425754ecacSJeremy L Thompson data[fine_level]->qf_energy = qf_energy; 4435754ecacSJeremy L Thompson data[fine_level]->op_energy = op_energy; 4445754ecacSJeremy L Thompson 4455754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 4465754ecacSJeremy L Thompson // Diagnostic value computation 4475754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 4485754ecacSJeremy L Thompson // Create the QFunction and Operator that computes nodal diagnostic quantities 4495754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 4505754ecacSJeremy L Thompson // Geometric factors 4515754ecacSJeremy L Thompson // -- Coordinate basis 4525754ecacSJeremy L Thompson CeedBasis basis_x; 4532b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_x, 2, Q, CEED_GAUSS_LOBATTO, &basis_x); 4545754ecacSJeremy L Thompson // -- QFunction 4552b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.setup_geo, problem_data.setup_geo_loc, &qf_setup_geo); 4565754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_setup_geo, "dx", num_comp_x * dim, CEED_EVAL_GRAD); 4575754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_setup_geo, "weight", 1, CEED_EVAL_WEIGHT); 458a61c78d6SJeremy L Thompson CeedQFunctionAddOutput(qf_setup_geo, "qdata", q_data_size, CEED_EVAL_NONE); 4595754ecacSJeremy L Thompson // -- Operator 4602b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_setup_geo, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_setup_geo); 4612b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "dx", data[fine_level]->elem_restr_x, basis_x, CEED_VECTOR_ACTIVE); 4622b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "weight", CEED_ELEMRESTRICTION_NONE, basis_x, CEED_VECTOR_NONE); 463356036faSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "qdata", data[fine_level]->elem_restr_geo_data_diagnostic_i, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE); 4645754ecacSJeremy L Thompson // -- Compute the quadrature data 4652b730f8bSJeremy L Thompson CeedOperatorApply(op_setup_geo, x_coord, data[fine_level]->geo_data_diagnostic, CEED_REQUEST_IMMEDIATE); 4665754ecacSJeremy L Thompson // -- Cleanup 4675754ecacSJeremy L Thompson CeedBasisDestroy(&basis_x); 4685754ecacSJeremy L Thompson CeedQFunctionDestroy(&qf_setup_geo); 4695754ecacSJeremy L Thompson CeedOperatorDestroy(&op_setup_geo); 4705754ecacSJeremy L Thompson 4715754ecacSJeremy L Thompson // Diagnostic quantities 4725754ecacSJeremy L Thompson // -- QFunction 4732b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.diagnostic, problem_data.diagnostic_loc, &qf_diagnostic); 4745754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_diagnostic, "u", num_comp_u, CEED_EVAL_INTERP); 4755754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_diagnostic, "du", num_comp_u * dim, CEED_EVAL_GRAD); 476a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_diagnostic, "qdata", q_data_size, CEED_EVAL_NONE); 4772b730f8bSJeremy L Thompson CeedQFunctionAddOutput(qf_diagnostic, "diagnostic values", num_comp_u + num_comp_d, CEED_EVAL_NONE); 4785754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_diagnostic, phys_ctx); 4795754ecacSJeremy L Thompson // -- Operator 4802b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_diagnostic, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_diagnostic); 4812b730f8bSJeremy L Thompson CeedOperatorSetField(op_diagnostic, "u", data[fine_level]->elem_restr_u, data[fine_level]->basis_diagnostic, CEED_VECTOR_ACTIVE); 4822b730f8bSJeremy L Thompson CeedOperatorSetField(op_diagnostic, "du", data[fine_level]->elem_restr_u, data[fine_level]->basis_diagnostic, CEED_VECTOR_ACTIVE); 483356036faSJeremy L Thompson CeedOperatorSetField(op_diagnostic, "qdata", data[fine_level]->elem_restr_geo_data_diagnostic_i, CEED_BASIS_NONE, 4842b730f8bSJeremy L Thompson data[fine_level]->geo_data_diagnostic); 485356036faSJeremy L Thompson CeedOperatorSetField(op_diagnostic, "diagnostic values", data[fine_level]->elem_restr_diagnostic, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE); 4865754ecacSJeremy L Thompson // -- Save libCEED data 4875754ecacSJeremy L Thompson data[fine_level]->qf_diagnostic = qf_diagnostic; 4885754ecacSJeremy L Thompson data[fine_level]->op_diagnostic = op_diagnostic; 4895754ecacSJeremy L Thompson 4905754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 4915754ecacSJeremy L Thompson // Cleanup 4925754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 4935754ecacSJeremy L Thompson CeedVectorDestroy(&x_coord); 4945754ecacSJeremy L Thompson 495ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 4965754ecacSJeremy L Thompson }; 4975754ecacSJeremy L Thompson 4985754ecacSJeremy L Thompson // Set up libCEED multigrid level for a given degree 4995754ecacSJeremy L Thompson // Prolongation and Restriction are between level and level+1 5002b730f8bSJeremy L Thompson PetscErrorCode SetupLibceedLevel(DM dm, Ceed ceed, AppCtx app_ctx, ProblemData problem_data, PetscInt level, PetscInt num_comp_u, PetscInt U_g_size, 5012b730f8bSJeremy L Thompson PetscInt U_loc_size, CeedVector fine_mult, CeedData *data) { 5025754ecacSJeremy L Thompson CeedInt fine_level = app_ctx->num_levels - 1; 5035754ecacSJeremy L Thompson CeedInt P = app_ctx->level_degrees[level] + 1; 5045754ecacSJeremy L Thompson CeedInt Q = app_ctx->level_degrees[fine_level] + 1 + app_ctx->q_extra; 505*4d00b080SJeremy L Thompson PetscInt dim; 5065754ecacSJeremy L Thompson CeedOperator op_jacobian, op_prolong, op_restrict; 5075754ecacSJeremy L Thompson 5085754ecacSJeremy L Thompson PetscFunctionBeginUser; 5095754ecacSJeremy L Thompson 5102b730f8bSJeremy L Thompson PetscCall(DMGetDimension(dm, &dim)); 5115754ecacSJeremy L Thompson 5125754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 5135754ecacSJeremy L Thompson // libCEED restrictions 5145754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 5155754ecacSJeremy L Thompson // -- Solution restriction 5162b730f8bSJeremy L Thompson PetscCall(CreateRestrictionFromPlex(ceed, dm, 0, 0, 0, &data[level]->elem_restr_u)); 5175754ecacSJeremy L Thompson 5185754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 5195754ecacSJeremy L Thompson // libCEED bases 5205754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 5215754ecacSJeremy L Thompson // -- Solution basis 5222b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_u, P, Q, problem_data.quadrature_mode, &data[level]->basis_u); 5235754ecacSJeremy L Thompson 5245754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 5255754ecacSJeremy L Thompson // Persistent libCEED vectors 5265754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 5275754ecacSJeremy L Thompson CeedVectorCreate(ceed, U_loc_size, &data[level]->x_ceed); 5285754ecacSJeremy L Thompson CeedVectorCreate(ceed, U_loc_size, &data[level]->y_ceed); 5295754ecacSJeremy L Thompson 5305754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 5315754ecacSJeremy L Thompson // Coarse Grid, Prolongation, and Restriction Operators 5325754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 533ea61e9acSJeremy L Thompson // Create the Operators that compute the prolongation and restriction between the p-multigrid levels and the coarse grid eval. 5345754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 5352b730f8bSJeremy L Thompson CeedOperatorMultigridLevelCreate(data[level + 1]->op_jacobian, fine_mult, data[level]->elem_restr_u, data[level]->basis_u, &op_jacobian, 5362b730f8bSJeremy L Thompson &op_prolong, &op_restrict); 5375754ecacSJeremy L Thompson 5385754ecacSJeremy L Thompson // -- Save libCEED data 5395754ecacSJeremy L Thompson data[level]->op_jacobian = op_jacobian; 5405754ecacSJeremy L Thompson data[level + 1]->op_prolong = op_prolong; 5415754ecacSJeremy L Thompson data[level + 1]->op_restrict = op_restrict; 5425754ecacSJeremy L Thompson 543ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 5445754ecacSJeremy L Thompson }; 545