1*3d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 2*3d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3*3d8e8822SJeremy L Thompson // 4*3d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 5*3d8e8822SJeremy L Thompson // 6*3d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 7*3d8e8822SJeremy 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" 125754ecacSJeremy L Thompson #include "../include/structs.h" 135754ecacSJeremy L Thompson #include "../include/utils.h" 145754ecacSJeremy L Thompson #include "../qfunctions/traction-boundary.h" // Traction boundaries 155754ecacSJeremy L Thompson #include "../qfunctions/constant-force.h" // Constant forcing function 165754ecacSJeremy L Thompson #include "../qfunctions/manufactured-force.h" // Manufactured solution forcing 175754ecacSJeremy L Thompson 185754ecacSJeremy L Thompson #if PETSC_VERSION_LT(3,14,0) 195754ecacSJeremy L Thompson # define DMPlexGetClosureIndices(a,b,c,d,e,f,g,h,i) DMPlexGetClosureIndices(a,b,c,d,f,g,i) 205754ecacSJeremy L Thompson # define DMPlexRestoreClosureIndices(a,b,c,d,e,f,g,h,i) DMPlexRestoreClosureIndices(a,b,c,d,f,g,i) 215754ecacSJeremy L Thompson #endif 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] = { 285754ecacSJeremy L Thompson [FORCE_NONE] = { 295754ecacSJeremy L Thompson .setup_forcing = NULL, 305754ecacSJeremy L Thompson .setup_forcing_loc = NULL 315754ecacSJeremy L Thompson }, 325754ecacSJeremy L Thompson [FORCE_CONST] = { 335754ecacSJeremy L Thompson .setup_forcing = SetupConstantForce, 345754ecacSJeremy L Thompson .setup_forcing_loc = SetupConstantForce_loc 355754ecacSJeremy L Thompson }, 365754ecacSJeremy L Thompson [FORCE_MMS] = { 375754ecacSJeremy L Thompson .setup_forcing = SetupMMSForce, 385754ecacSJeremy L Thompson .setup_forcing_loc = SetupMMSForce_loc 395754ecacSJeremy L Thompson } 405754ecacSJeremy L Thompson }; 415754ecacSJeremy L Thompson 425754ecacSJeremy L Thompson // ----------------------------------------------------------------------------- 435754ecacSJeremy L Thompson // libCEED Functions 445754ecacSJeremy L Thompson // ----------------------------------------------------------------------------- 455754ecacSJeremy L Thompson // Destroy libCEED objects 465754ecacSJeremy L Thompson PetscErrorCode CeedDataDestroy(CeedInt level, CeedData data) { 475754ecacSJeremy L Thompson PetscErrorCode ierr; 485754ecacSJeremy L Thompson 495754ecacSJeremy L Thompson PetscFunctionBegin; 505754ecacSJeremy L Thompson 515754ecacSJeremy L Thompson // Vectors 525754ecacSJeremy L Thompson CeedVectorDestroy(&data->x_ceed); 535754ecacSJeremy L Thompson CeedVectorDestroy(&data->y_ceed); 545754ecacSJeremy L Thompson CeedVectorDestroy(&data->geo_data); 555754ecacSJeremy L Thompson for (CeedInt i = 0; i < SOLIDS_MAX_NUMBER_FIELDS; i++) 565754ecacSJeremy L Thompson CeedVectorDestroy(&data->stored_fields[i]); 575754ecacSJeremy L Thompson CeedVectorDestroy(&data->geo_data_diagnostic); 585754ecacSJeremy L Thompson CeedVectorDestroy(&data->true_soln); 595754ecacSJeremy L Thompson // Restrictions 605754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_x); 615754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_u); 625754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_geo_data_i); 635754ecacSJeremy L Thompson for (CeedInt i = 0; i < SOLIDS_MAX_NUMBER_FIELDS; i++) 645754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_stored_fields_i[i]); 655754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_energy); 665754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_diagnostic); 675754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&data->elem_restr_geo_data_diagnostic_i); 685754ecacSJeremy L Thompson // Bases 695754ecacSJeremy L Thompson CeedBasisDestroy(&data->basis_x); 705754ecacSJeremy L Thompson CeedBasisDestroy(&data->basis_u); 715754ecacSJeremy L Thompson CeedBasisDestroy(&data->basis_energy); 725754ecacSJeremy L Thompson CeedBasisDestroy(&data->basis_diagnostic); 735754ecacSJeremy L Thompson // QFunctions 745754ecacSJeremy L Thompson CeedQFunctionDestroy(&data->qf_residual); 755754ecacSJeremy L Thompson CeedQFunctionDestroy(&data->qf_jacobian); 765754ecacSJeremy L Thompson CeedQFunctionDestroy(&data->qf_energy); 775754ecacSJeremy L Thompson CeedQFunctionDestroy(&data->qf_diagnostic); 785754ecacSJeremy L Thompson // Operators 795754ecacSJeremy L Thompson CeedOperatorDestroy(&data->op_residual); 805754ecacSJeremy L Thompson CeedOperatorDestroy(&data->op_jacobian); 815754ecacSJeremy L Thompson CeedOperatorDestroy(&data->op_energy); 825754ecacSJeremy L Thompson CeedOperatorDestroy(&data->op_diagnostic); 835754ecacSJeremy L Thompson // Restriction and Prolongation data 845754ecacSJeremy L Thompson CeedBasisDestroy(&data->basis_c_to_f); 855754ecacSJeremy L Thompson CeedOperatorDestroy(&data->op_prolong); 865754ecacSJeremy L Thompson CeedOperatorDestroy(&data->op_restrict); 875754ecacSJeremy L Thompson 885754ecacSJeremy L Thompson ierr = PetscFree(data); CHKERRQ(ierr); 895754ecacSJeremy L Thompson 905754ecacSJeremy L Thompson PetscFunctionReturn(0); 915754ecacSJeremy L Thompson }; 925754ecacSJeremy L Thompson 935754ecacSJeremy L Thompson // Utility function to create local CEED restriction from DMPlex 947ed3e4cdSJeremy L Thompson PetscErrorCode CreateRestrictionFromPlex(Ceed ceed, DM dm, CeedInt height, 957ed3e4cdSJeremy L Thompson DMLabel domain_label, CeedInt value, CeedElemRestriction *elem_restr) { 967ed3e4cdSJeremy L Thompson PetscInt num_elem, elem_size, num_dof, num_comp, *elem_restr_offsets; 975754ecacSJeremy L Thompson PetscErrorCode ierr; 985754ecacSJeremy L Thompson 995754ecacSJeremy L Thompson PetscFunctionBeginUser; 1007ed3e4cdSJeremy L Thompson ierr = DMPlexGetLocalOffsets(dm, domain_label, value, height, 0, &num_elem, 1017ed3e4cdSJeremy L Thompson &elem_size, &num_comp, &num_dof, &elem_restr_offsets); 1027ed3e4cdSJeremy L Thompson CHKERRQ(ierr); 1035754ecacSJeremy L Thompson 1047ed3e4cdSJeremy L Thompson CeedElemRestrictionCreate(ceed, num_elem, elem_size, num_comp, 1057ed3e4cdSJeremy L Thompson 1, num_dof, CEED_MEM_HOST, CEED_COPY_VALUES, 1067ed3e4cdSJeremy L Thompson elem_restr_offsets, elem_restr); 1077ed3e4cdSJeremy L Thompson ierr = PetscFree(elem_restr_offsets); CHKERRQ(ierr); 1085754ecacSJeremy L Thompson 1095754ecacSJeremy L Thompson PetscFunctionReturn(0); 1105754ecacSJeremy L Thompson }; 1115754ecacSJeremy L Thompson 1125754ecacSJeremy L Thompson // Utility function to get Ceed Restriction for each domain 1135754ecacSJeremy L Thompson PetscErrorCode GetRestrictionForDomain(Ceed ceed, DM dm, CeedInt height, 1145754ecacSJeremy L Thompson DMLabel domain_label, PetscInt value, 1157ed3e4cdSJeremy L Thompson CeedInt Q, CeedInt q_data_size, 1165754ecacSJeremy L Thompson CeedElemRestriction *elem_restr_q, 1175754ecacSJeremy L Thompson CeedElemRestriction *elem_restr_x, 1185754ecacSJeremy L Thompson CeedElemRestriction *elem_restr_qd_i) { 1195754ecacSJeremy L Thompson 1205754ecacSJeremy L Thompson DM dm_coord; 1215754ecacSJeremy L Thompson CeedInt dim, num_local_elem; 1225754ecacSJeremy L Thompson CeedInt Q_dim; 1235754ecacSJeremy L Thompson PetscErrorCode ierr; 1245754ecacSJeremy L Thompson 1255754ecacSJeremy L Thompson PetscFunctionBeginUser; 1265754ecacSJeremy L Thompson 1275754ecacSJeremy L Thompson ierr = DMGetDimension(dm, &dim); CHKERRQ(ierr); 1285754ecacSJeremy L Thompson dim -= height; 1295754ecacSJeremy L Thompson Q_dim = CeedIntPow(Q, dim); 1305754ecacSJeremy L Thompson ierr = DMGetCoordinateDM(dm, &dm_coord); CHKERRQ(ierr); 1315754ecacSJeremy L Thompson ierr = DMPlexSetClosurePermutationTensor(dm_coord, PETSC_DETERMINE, NULL); 1325754ecacSJeremy L Thompson CHKERRQ(ierr); 1335754ecacSJeremy L Thompson if (elem_restr_q) { 1347ed3e4cdSJeremy L Thompson ierr = CreateRestrictionFromPlex(ceed, dm, height, domain_label, value, 1355754ecacSJeremy L Thompson elem_restr_q); CHKERRQ(ierr); 1365754ecacSJeremy L Thompson } 1375754ecacSJeremy L Thompson if (elem_restr_x) { 1387ed3e4cdSJeremy L Thompson ierr = CreateRestrictionFromPlex(ceed, dm_coord, height, domain_label, 1395754ecacSJeremy L Thompson value, elem_restr_x); CHKERRQ(ierr); 1405754ecacSJeremy L Thompson } 1415754ecacSJeremy L Thompson if (elem_restr_qd_i) { 1425754ecacSJeremy L Thompson CeedElemRestrictionGetNumElements(*elem_restr_q, &num_local_elem); 1435754ecacSJeremy L Thompson CeedElemRestrictionCreateStrided(ceed, num_local_elem, Q_dim, 1445754ecacSJeremy L Thompson q_data_size, q_data_size*num_local_elem*Q_dim, 1455754ecacSJeremy L Thompson CEED_STRIDES_BACKEND, elem_restr_qd_i); 1465754ecacSJeremy L Thompson } 1475754ecacSJeremy L Thompson 1485754ecacSJeremy L Thompson PetscFunctionReturn(0); 1495754ecacSJeremy L Thompson }; 1505754ecacSJeremy L Thompson 1515754ecacSJeremy L Thompson // Set up libCEED on the fine grid for a given degree 1525754ecacSJeremy L Thompson PetscErrorCode SetupLibceedFineLevel(DM dm, DM dm_energy, DM dm_diagnostic, 1535754ecacSJeremy L Thompson Ceed ceed, AppCtx app_ctx, 1545754ecacSJeremy L Thompson CeedQFunctionContext phys_ctx, 1555754ecacSJeremy L Thompson ProblemData problem_data, 1565754ecacSJeremy L Thompson PetscInt fine_level, PetscInt num_comp_u, 1575754ecacSJeremy L Thompson PetscInt U_g_size, PetscInt U_loc_size, 1585754ecacSJeremy L Thompson CeedVector force_ceed, 1595754ecacSJeremy L Thompson CeedVector neumann_ceed, CeedData *data) { 1605754ecacSJeremy L Thompson int ierr; 1615754ecacSJeremy L Thompson CeedInt P = app_ctx->level_degrees[fine_level] + 1; 1625754ecacSJeremy L Thompson CeedInt Q = app_ctx->level_degrees[fine_level] + 1 + app_ctx->q_extra; 1635754ecacSJeremy L Thompson CeedInt dim, num_comp_x, num_comp_e = 1, num_comp_d = 5; 1645754ecacSJeremy L Thompson CeedInt num_qpts; 165a61c78d6SJeremy L Thompson CeedInt q_data_size = problem_data.q_data_size; 1665754ecacSJeremy L Thompson forcingType forcing_choice = app_ctx->forcing_choice; 1675754ecacSJeremy L Thompson DM dm_coord; 1685754ecacSJeremy L Thompson Vec coords; 1695754ecacSJeremy L Thompson PetscInt c_start, c_end, num_elem; 1705754ecacSJeremy L Thompson const PetscScalar *coordArray; 1715754ecacSJeremy L Thompson CeedVector x_coord; 1725754ecacSJeremy L Thompson CeedQFunction qf_setup_geo, qf_residual, qf_jacobian, qf_energy, qf_diagnostic; 1735754ecacSJeremy L Thompson CeedOperator op_setup_geo, op_residual, op_jacobian, op_energy, op_diagnostic; 1745754ecacSJeremy L Thompson 1755754ecacSJeremy L Thompson PetscFunctionBeginUser; 1765754ecacSJeremy L Thompson 1775754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 1785754ecacSJeremy L Thompson // libCEED bases 1795754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 1805754ecacSJeremy L Thompson ierr = DMGetDimension(dm, &dim); CHKERRQ(ierr); 1815754ecacSJeremy L Thompson num_comp_x = dim; 1825754ecacSJeremy L Thompson // -- Coordinate basis 1835754ecacSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_x, 2, Q, 1845754ecacSJeremy L Thompson problem_data.quadrature_mode, 1855754ecacSJeremy L Thompson &data[fine_level]->basis_x); 1865754ecacSJeremy L Thompson // -- Solution basis 1875754ecacSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_u, P, Q, 1885754ecacSJeremy L Thompson problem_data.quadrature_mode, 1895754ecacSJeremy L Thompson &data[fine_level]->basis_u); 1905754ecacSJeremy L Thompson // -- Energy basis 1915754ecacSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_e, P, Q, 1925754ecacSJeremy L Thompson problem_data.quadrature_mode, 1935754ecacSJeremy L Thompson &data[fine_level]->basis_energy); 1945754ecacSJeremy L Thompson // -- Diagnostic output basis 1955754ecacSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_u, P, P, CEED_GAUSS_LOBATTO, 1965754ecacSJeremy L Thompson &data[fine_level]->basis_diagnostic); 1975754ecacSJeremy L Thompson 1985754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 1995754ecacSJeremy L Thompson // libCEED restrictions 2005754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 2015754ecacSJeremy L Thompson ierr = DMGetCoordinateDM(dm, &dm_coord); CHKERRQ(ierr); 2025754ecacSJeremy L Thompson ierr = DMPlexSetClosurePermutationTensor(dm_coord, PETSC_DETERMINE, NULL); 2035754ecacSJeremy L Thompson CHKERRQ(ierr); 2045754ecacSJeremy L Thompson 2055754ecacSJeremy L Thompson // -- Coordinate restriction 2067ed3e4cdSJeremy L Thompson ierr = CreateRestrictionFromPlex(ceed, dm_coord, 0, 0, 0, 2075754ecacSJeremy L Thompson &(data[fine_level]->elem_restr_x)); 2085754ecacSJeremy L Thompson CHKERRQ(ierr); 2095754ecacSJeremy L Thompson // -- Solution restriction 2107ed3e4cdSJeremy L Thompson ierr = CreateRestrictionFromPlex(ceed, dm, 0, 0, 0, 2115754ecacSJeremy L Thompson &data[fine_level]->elem_restr_u); 2125754ecacSJeremy L Thompson CHKERRQ(ierr); 2135754ecacSJeremy L Thompson // -- Energy restriction 2147ed3e4cdSJeremy L Thompson ierr = CreateRestrictionFromPlex(ceed, dm_energy, 0, 0, 0, 2155754ecacSJeremy L Thompson &data[fine_level]->elem_restr_energy); 2165754ecacSJeremy L Thompson CHKERRQ(ierr); 2175754ecacSJeremy L Thompson // -- Diagnostic data restriction 2187ed3e4cdSJeremy L Thompson ierr = CreateRestrictionFromPlex(ceed, dm_diagnostic, 0, 0, 0, 2195754ecacSJeremy L Thompson &data[fine_level]->elem_restr_diagnostic); 2205754ecacSJeremy L Thompson CHKERRQ(ierr); 2215754ecacSJeremy L Thompson 2225754ecacSJeremy L Thompson // -- Stored data at quadrature points 2235754ecacSJeremy L Thompson ierr = DMPlexGetHeightStratum(dm, 0, &c_start, &c_end); CHKERRQ(ierr); 2245754ecacSJeremy L Thompson num_elem = c_end - c_start; 2255754ecacSJeremy L Thompson CeedBasisGetNumQuadraturePoints(data[fine_level]->basis_u, &num_qpts); 2265754ecacSJeremy L Thompson // ---- Geometric data restriction, residual and Jacobian operators 227a61c78d6SJeremy L Thompson CeedElemRestrictionCreateStrided(ceed, num_elem, num_qpts, q_data_size, 228a61c78d6SJeremy L Thompson num_elem*num_qpts*q_data_size, 2295754ecacSJeremy L Thompson CEED_STRIDES_BACKEND, 2305754ecacSJeremy L Thompson &data[fine_level]->elem_restr_geo_data_i); 2315754ecacSJeremy L Thompson // ---- Stored field restrictions 2325754ecacSJeremy L Thompson for (CeedInt i = 0; i < problem_data.number_fields_stored; i++) { 2335754ecacSJeremy L Thompson CeedElemRestrictionCreateStrided(ceed, num_elem, num_qpts, 2345754ecacSJeremy L Thompson problem_data.field_sizes[i], 2355754ecacSJeremy L Thompson num_elem*num_qpts*problem_data.field_sizes[i], 2365754ecacSJeremy L Thompson CEED_STRIDES_BACKEND, 2375754ecacSJeremy L Thompson &data[fine_level]->elem_restr_stored_fields_i[i]); 2385754ecacSJeremy L Thompson } 2395754ecacSJeremy L Thompson // ---- Geometric data restriction, diagnostic operator 240a61c78d6SJeremy L Thompson CeedElemRestrictionCreateStrided(ceed, num_elem, P*P*P, q_data_size, 241a61c78d6SJeremy L Thompson num_elem*P*P*P*q_data_size, 2425754ecacSJeremy L Thompson CEED_STRIDES_BACKEND, 2435754ecacSJeremy L Thompson &data[fine_level]->elem_restr_geo_data_diagnostic_i); 2445754ecacSJeremy L Thompson 2455754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 2465754ecacSJeremy L Thompson // Element coordinates 2475754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 2485754ecacSJeremy L Thompson ierr = DMGetCoordinatesLocal(dm, &coords); CHKERRQ(ierr); 2495754ecacSJeremy L Thompson ierr = VecGetArrayRead(coords, &coordArray); CHKERRQ(ierr); 2505754ecacSJeremy L Thompson 2515754ecacSJeremy L Thompson CeedElemRestrictionCreateVector(data[fine_level]->elem_restr_x, &x_coord, NULL); 2525754ecacSJeremy L Thompson CeedVectorSetArray(x_coord, CEED_MEM_HOST, CEED_COPY_VALUES, 2535754ecacSJeremy L Thompson (PetscScalar *)coordArray); 2545754ecacSJeremy L Thompson ierr = VecRestoreArrayRead(coords, &coordArray); CHKERRQ(ierr); 2555754ecacSJeremy L Thompson 2565754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 2575754ecacSJeremy L Thompson // Persistent libCEED vectors 2585754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 2595754ecacSJeremy L Thompson // -- Operator action variables 2605754ecacSJeremy L Thompson CeedVectorCreate(ceed, U_loc_size, &data[fine_level]->x_ceed); 2615754ecacSJeremy L Thompson CeedVectorCreate(ceed, U_loc_size, &data[fine_level]->y_ceed); 2625754ecacSJeremy L Thompson // -- Geometric data vector 263a61c78d6SJeremy L Thompson CeedVectorCreate(ceed, num_elem*num_qpts*q_data_size, 2645754ecacSJeremy L Thompson &data[fine_level]->geo_data); 2655754ecacSJeremy L Thompson // -- Stored field vectors 2665754ecacSJeremy L Thompson for (CeedInt i = 0; i < problem_data.number_fields_stored; i++) { 2675754ecacSJeremy L Thompson CeedVectorCreate(ceed, num_elem*num_qpts*problem_data.field_sizes[i], 2685754ecacSJeremy L Thompson &data[fine_level]->stored_fields[i]); 2695754ecacSJeremy L Thompson } 2705754ecacSJeremy L Thompson // -- Collocated geometric data vector 271a61c78d6SJeremy L Thompson CeedVectorCreate(ceed, num_elem*P*P*P*q_data_size, 2725754ecacSJeremy L Thompson &data[fine_level]->geo_data_diagnostic); 2735754ecacSJeremy L Thompson 2745754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 2755754ecacSJeremy L Thompson // Geometric factor computation 2765754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 2775754ecacSJeremy L Thompson // Create the QFunction and Operator that computes the quadrature data 2785754ecacSJeremy L Thompson // geo_data returns dXdx_i,j and w * det. 2795754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 2805754ecacSJeremy L Thompson // -- QFunction 2815754ecacSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.setup_geo, 2825754ecacSJeremy L Thompson problem_data.setup_geo_loc, &qf_setup_geo); 2835754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_setup_geo, "dx", num_comp_x*dim, CEED_EVAL_GRAD); 2845754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_setup_geo, "weight", 1, CEED_EVAL_WEIGHT); 285a61c78d6SJeremy L Thompson CeedQFunctionAddOutput(qf_setup_geo, "qdata", q_data_size, CEED_EVAL_NONE); 2865754ecacSJeremy L Thompson // -- Operator 2875754ecacSJeremy L Thompson CeedOperatorCreate(ceed, qf_setup_geo, CEED_QFUNCTION_NONE, 2885754ecacSJeremy L Thompson CEED_QFUNCTION_NONE, &op_setup_geo); 2895754ecacSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "dx", data[fine_level]->elem_restr_x, 2905754ecacSJeremy L Thompson data[fine_level]->basis_x, CEED_VECTOR_ACTIVE); 2915754ecacSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "weight", CEED_ELEMRESTRICTION_NONE, 2925754ecacSJeremy L Thompson data[fine_level]->basis_x, CEED_VECTOR_NONE); 293a61c78d6SJeremy L Thompson CeedOperatorSetField(op_setup_geo, "qdata", 2945754ecacSJeremy L Thompson data[fine_level]->elem_restr_geo_data_i, 2955754ecacSJeremy L Thompson CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE); 2965754ecacSJeremy L Thompson // -- Compute the quadrature data 2975754ecacSJeremy L Thompson CeedOperatorApply(op_setup_geo, x_coord, data[fine_level]->geo_data, 2985754ecacSJeremy L Thompson CEED_REQUEST_IMMEDIATE); 2995754ecacSJeremy L Thompson // -- Cleanup 3005754ecacSJeremy L Thompson CeedQFunctionDestroy(&qf_setup_geo); 3015754ecacSJeremy L Thompson CeedOperatorDestroy(&op_setup_geo); 3025754ecacSJeremy L Thompson 3035754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 3045754ecacSJeremy L Thompson // Local residual evaluator 3055754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 3065754ecacSJeremy L Thompson // Create the QFunction and Operator that computes the residual of the 3075754ecacSJeremy L Thompson // non-linear PDE. 3085754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 3095754ecacSJeremy L Thompson // -- QFunction 3105754ecacSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.residual, 3115754ecacSJeremy L Thompson problem_data.residual_loc, &qf_residual); 3125754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_residual, "du", num_comp_u*dim, CEED_EVAL_GRAD); 313a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_residual, "qdata", q_data_size, CEED_EVAL_NONE); 3145754ecacSJeremy L Thompson CeedQFunctionAddOutput(qf_residual, "dv", num_comp_u*dim, CEED_EVAL_GRAD); 3155754ecacSJeremy L Thompson for (CeedInt i = 0; i < problem_data.number_fields_stored; i++) { 3165754ecacSJeremy L Thompson CeedQFunctionAddOutput(qf_residual, problem_data.field_names[i], 3175754ecacSJeremy L Thompson problem_data.field_sizes[i], CEED_EVAL_NONE); 3185754ecacSJeremy L Thompson } 3195754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_residual, phys_ctx); 3205754ecacSJeremy L Thompson // -- Operator 3215754ecacSJeremy L Thompson CeedOperatorCreate(ceed, qf_residual, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, 3225754ecacSJeremy L Thompson &op_residual); 3235754ecacSJeremy L Thompson CeedOperatorSetField(op_residual, "du", data[fine_level]->elem_restr_u, 3245754ecacSJeremy L Thompson data[fine_level]->basis_u, CEED_VECTOR_ACTIVE); 325a61c78d6SJeremy L Thompson CeedOperatorSetField(op_residual, "qdata", 3265754ecacSJeremy L Thompson data[fine_level]->elem_restr_geo_data_i, 3275754ecacSJeremy L Thompson CEED_BASIS_COLLOCATED, data[fine_level]->geo_data); 3285754ecacSJeremy L Thompson CeedOperatorSetField(op_residual, "dv", data[fine_level]->elem_restr_u, 3295754ecacSJeremy L Thompson data[fine_level]->basis_u, CEED_VECTOR_ACTIVE); 3305754ecacSJeremy L Thompson for (CeedInt i = 0; i < problem_data.number_fields_stored; i++) { 3315754ecacSJeremy L Thompson CeedOperatorSetField(op_residual, problem_data.field_names[i], 3325754ecacSJeremy L Thompson data[fine_level]->elem_restr_stored_fields_i[i], 3335754ecacSJeremy L Thompson CEED_BASIS_COLLOCATED, 3345754ecacSJeremy L Thompson data[fine_level]->stored_fields[i]); 3355754ecacSJeremy L Thompson } 3365754ecacSJeremy L Thompson // -- Save libCEED data 3375754ecacSJeremy L Thompson data[fine_level]->qf_residual = qf_residual; 3385754ecacSJeremy L Thompson data[fine_level]->op_residual = op_residual; 3395754ecacSJeremy L Thompson 3405754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 3415754ecacSJeremy L Thompson // Jacobian evaluator 3425754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 3435754ecacSJeremy L Thompson // Create the QFunction and Operator that computes the action of the 3445754ecacSJeremy L Thompson // Jacobian for each linear solve. 3455754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 3465754ecacSJeremy L Thompson // -- QFunction 3475754ecacSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.jacobian, 3485754ecacSJeremy L Thompson problem_data.jacobian_loc, &qf_jacobian); 3495754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_jacobian, "delta du", num_comp_u*dim, CEED_EVAL_GRAD); 350a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_jacobian, "qdata", q_data_size, CEED_EVAL_NONE); 3515754ecacSJeremy L Thompson for (CeedInt i = 0; i < problem_data.number_fields_stored; i++) { 3525754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_jacobian, problem_data.field_names[i], 3535754ecacSJeremy L Thompson problem_data.field_sizes[i], CEED_EVAL_NONE); 3545754ecacSJeremy L Thompson } 3555754ecacSJeremy L Thompson CeedQFunctionAddOutput(qf_jacobian, "delta dv", num_comp_u*dim, CEED_EVAL_GRAD); 3565754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_jacobian, phys_ctx); 3575754ecacSJeremy L Thompson // -- Operator 3585754ecacSJeremy L Thompson CeedOperatorCreate(ceed, qf_jacobian, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, 3595754ecacSJeremy L Thompson &op_jacobian); 3605754ecacSJeremy L Thompson CeedOperatorSetField(op_jacobian, "delta du", data[fine_level]->elem_restr_u, 3615754ecacSJeremy L Thompson data[fine_level]->basis_u, CEED_VECTOR_ACTIVE); 362a61c78d6SJeremy L Thompson CeedOperatorSetField(op_jacobian, "qdata", 3635754ecacSJeremy L Thompson data[fine_level]->elem_restr_geo_data_i, 3645754ecacSJeremy L Thompson CEED_BASIS_COLLOCATED, data[fine_level]->geo_data); 3655754ecacSJeremy L Thompson CeedOperatorSetField(op_jacobian, "delta dv", data[fine_level]->elem_restr_u, 3665754ecacSJeremy L Thompson data[fine_level]->basis_u, CEED_VECTOR_ACTIVE); 3675754ecacSJeremy L Thompson for (CeedInt i = 0; i < problem_data.number_fields_stored; i++) { 3685754ecacSJeremy L Thompson CeedOperatorSetField(op_jacobian, problem_data.field_names[i], 3695754ecacSJeremy L Thompson data[fine_level]->elem_restr_stored_fields_i[i], 3705754ecacSJeremy L Thompson CEED_BASIS_COLLOCATED, 3715754ecacSJeremy L Thompson data[fine_level]->stored_fields[i]); 3725754ecacSJeremy L Thompson } 3735754ecacSJeremy L Thompson // -- Save libCEED data 3745754ecacSJeremy L Thompson data[fine_level]->qf_jacobian = qf_jacobian; 3755754ecacSJeremy L Thompson data[fine_level]->op_jacobian = op_jacobian; 3765754ecacSJeremy L Thompson 3775754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 3785754ecacSJeremy L Thompson // Traction boundary conditions, if needed 3795754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 3805754ecacSJeremy L Thompson if (app_ctx->bc_traction_count > 0) { 3815754ecacSJeremy L Thompson // -- Setup 3825754ecacSJeremy L Thompson DMLabel domain_label; 3835754ecacSJeremy L Thompson ierr = DMGetLabel(dm, "Face Sets", &domain_label); CHKERRQ(ierr); 3845754ecacSJeremy L Thompson ierr = DMGetDimension(dm, &dim); CHKERRQ(ierr); 3855754ecacSJeremy L Thompson 3865754ecacSJeremy L Thompson // -- Basis 3875754ecacSJeremy L Thompson CeedInt height = 1; 3885754ecacSJeremy L Thompson CeedBasis basis_x_face, basis_u_face; 3895754ecacSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim - height, num_comp_x, 2, Q, 3905754ecacSJeremy L Thompson problem_data.quadrature_mode, &basis_x_face); 3915754ecacSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim - height, num_comp_u, P, Q, 3925754ecacSJeremy L Thompson problem_data.quadrature_mode, &basis_u_face); 3935754ecacSJeremy L Thompson // -- QFunction 3945754ecacSJeremy L Thompson CeedQFunction qf_traction; 3955754ecacSJeremy L Thompson CeedQFunctionContext traction_ctx; 3965754ecacSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, SetupTractionBCs, SetupTractionBCs_loc, 3975754ecacSJeremy L Thompson &qf_traction); 3985754ecacSJeremy L Thompson CeedQFunctionContextCreate(ceed, &traction_ctx); 3995754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_traction, traction_ctx); 4005754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_traction, "dx", num_comp_x*(num_comp_x - height), 4015754ecacSJeremy L Thompson CEED_EVAL_GRAD); 4025754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_traction, "weight", 1, CEED_EVAL_WEIGHT); 4035754ecacSJeremy L Thompson CeedQFunctionAddOutput(qf_traction, "v", num_comp_u, CEED_EVAL_INTERP); 4045754ecacSJeremy L Thompson 4055754ecacSJeremy L Thompson // -- Compute contribution on each boundary face 4065754ecacSJeremy L Thompson for (CeedInt i = 0; i < app_ctx->bc_traction_count; i++) { 4075754ecacSJeremy L Thompson CeedElemRestriction elem_restr_x_face, elem_restr_u_face; 4085754ecacSJeremy L Thompson CeedOperator op_traction; 4095754ecacSJeremy L Thompson CeedQFunctionContextSetData(traction_ctx, CEED_MEM_HOST, CEED_USE_POINTER, 4105754ecacSJeremy L Thompson 3 * sizeof(CeedScalar), 4115754ecacSJeremy L Thompson app_ctx->bc_traction_vector[i]); 4125754ecacSJeremy L Thompson // Setup restriction 4137ed3e4cdSJeremy L Thompson ierr = GetRestrictionForDomain(ceed, dm, 1, domain_label, 4147ed3e4cdSJeremy L Thompson app_ctx->bc_traction_faces[i], Q, 4155754ecacSJeremy L Thompson 0, &elem_restr_u_face, &elem_restr_x_face, NULL); 4165754ecacSJeremy L Thompson CHKERRQ(ierr); 4175754ecacSJeremy L Thompson // ---- Create boundary Operator 4185754ecacSJeremy L Thompson CeedOperatorCreate(ceed, qf_traction, NULL, NULL, &op_traction); 4195754ecacSJeremy L Thompson CeedOperatorSetField(op_traction, "dx", elem_restr_x_face, basis_x_face, 4205754ecacSJeremy L Thompson CEED_VECTOR_ACTIVE); 4215754ecacSJeremy L Thompson CeedOperatorSetField(op_traction, "weight", CEED_ELEMRESTRICTION_NONE, 4225754ecacSJeremy L Thompson basis_x_face, CEED_VECTOR_NONE); 4235754ecacSJeremy L Thompson CeedOperatorSetField(op_traction, "v", elem_restr_u_face, 4245754ecacSJeremy L Thompson basis_u_face, CEED_VECTOR_ACTIVE); 4255754ecacSJeremy L Thompson // ---- Compute traction on face 4265754ecacSJeremy L Thompson CeedOperatorApplyAdd(op_traction, x_coord, neumann_ceed, 4275754ecacSJeremy L Thompson CEED_REQUEST_IMMEDIATE); 4285754ecacSJeremy L Thompson // ---- Cleanup 4295754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&elem_restr_x_face); 4305754ecacSJeremy L Thompson CeedElemRestrictionDestroy(&elem_restr_u_face); 4315754ecacSJeremy L Thompson CeedOperatorDestroy(&op_traction); 4325754ecacSJeremy L Thompson } 4335754ecacSJeremy L Thompson // -- Cleanup 4345754ecacSJeremy L Thompson CeedBasisDestroy(&basis_x_face); 4355754ecacSJeremy L Thompson CeedBasisDestroy(&basis_u_face); 4365754ecacSJeremy L Thompson CeedQFunctionDestroy(&qf_traction); 4375754ecacSJeremy L Thompson CeedQFunctionContextDestroy(&traction_ctx); 4385754ecacSJeremy L Thompson } 4395754ecacSJeremy L Thompson 4405754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 4415754ecacSJeremy L Thompson // Forcing term, if needed 4425754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 4435754ecacSJeremy L Thompson // Create the QFunction and Operator that computes the forcing term (RHS) 4445754ecacSJeremy L Thompson // for the non-linear PDE. 4455754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 4465754ecacSJeremy L Thompson if (forcing_choice != FORCE_NONE) { 4475754ecacSJeremy L Thompson CeedQFunction qf_setup_force; 4485754ecacSJeremy L Thompson CeedOperator op_setup_force; 4495754ecacSJeremy L Thompson 4505754ecacSJeremy L Thompson // -- QFunction 4515754ecacSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, 4525754ecacSJeremy L Thompson forcing_options[forcing_choice].setup_forcing, 4535754ecacSJeremy L Thompson forcing_options[forcing_choice].setup_forcing_loc, 4545754ecacSJeremy L Thompson &qf_setup_force); 4555754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_setup_force, "x", num_comp_x, CEED_EVAL_INTERP); 456a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_setup_force, "qdata", q_data_size, 4575754ecacSJeremy L Thompson CEED_EVAL_NONE); 4585754ecacSJeremy L Thompson CeedQFunctionAddOutput(qf_setup_force, "force", num_comp_u, CEED_EVAL_INTERP); 4595754ecacSJeremy L Thompson if (forcing_choice == FORCE_MMS) { 4605754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_setup_force, phys_ctx); 4615754ecacSJeremy L Thompson } else { 4625754ecacSJeremy L Thompson CeedQFunctionContext ctxForcing; 4635754ecacSJeremy L Thompson CeedQFunctionContextCreate(ceed, &ctxForcing); 4645754ecacSJeremy L Thompson CeedQFunctionContextSetData(ctxForcing, CEED_MEM_HOST, CEED_USE_POINTER, 4655754ecacSJeremy L Thompson sizeof(*app_ctx->forcing_vector), 4665754ecacSJeremy L Thompson app_ctx->forcing_vector); 4675754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_setup_force, ctxForcing); 4685754ecacSJeremy L Thompson CeedQFunctionContextDestroy(&ctxForcing); 4695754ecacSJeremy L Thompson } 4705754ecacSJeremy L Thompson // -- Operator 4715754ecacSJeremy L Thompson CeedOperatorCreate(ceed, qf_setup_force, CEED_QFUNCTION_NONE, 4725754ecacSJeremy L Thompson CEED_QFUNCTION_NONE, &op_setup_force); 4735754ecacSJeremy L Thompson CeedOperatorSetField(op_setup_force, "x", data[fine_level]->elem_restr_x, 4745754ecacSJeremy L Thompson data[fine_level]->basis_x, CEED_VECTOR_ACTIVE); 475a61c78d6SJeremy L Thompson CeedOperatorSetField(op_setup_force, "qdata", 4765754ecacSJeremy L Thompson data[fine_level]->elem_restr_geo_data_i, 4775754ecacSJeremy L Thompson CEED_BASIS_COLLOCATED, data[fine_level]->geo_data); 4785754ecacSJeremy L Thompson CeedOperatorSetField(op_setup_force, "force", data[fine_level]->elem_restr_u, 4795754ecacSJeremy L Thompson data[fine_level]->basis_u, CEED_VECTOR_ACTIVE); 4805754ecacSJeremy L Thompson // -- Compute forcing term 4815754ecacSJeremy L Thompson CeedOperatorApply(op_setup_force, x_coord, force_ceed, CEED_REQUEST_IMMEDIATE); 4825754ecacSJeremy L Thompson // -- Cleanup 4835754ecacSJeremy L Thompson CeedQFunctionDestroy(&qf_setup_force); 4845754ecacSJeremy L Thompson CeedOperatorDestroy(&op_setup_force); 4855754ecacSJeremy L Thompson } 4865754ecacSJeremy L Thompson 4875754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 4885754ecacSJeremy L Thompson // True solution, for MMS 4895754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 4905754ecacSJeremy L Thompson // Create the QFunction and Operator that computes the true solution at 4915754ecacSJeremy L Thompson // the mesh nodes for validation with the manufactured solution. 4925754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 4935754ecacSJeremy L Thompson if (problem_data.true_soln) { 4945754ecacSJeremy L Thompson CeedScalar *true_array; 4955754ecacSJeremy L Thompson const CeedScalar *mult_array; 4965754ecacSJeremy L Thompson CeedVector mult_vec; 4975754ecacSJeremy L Thompson CeedBasis basis_x_true; 4985754ecacSJeremy L Thompson CeedQFunction qf_true; 4995754ecacSJeremy L Thompson CeedOperator op_true; 5005754ecacSJeremy L Thompson 5015754ecacSJeremy L Thompson // -- Solution vector 5025754ecacSJeremy L Thompson CeedVectorCreate(ceed, U_loc_size, &(data[fine_level]->true_soln)); 5035754ecacSJeremy L Thompson // -- Basis 5045754ecacSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_x, 2, P, CEED_GAUSS_LOBATTO, 5055754ecacSJeremy L Thompson &basis_x_true); 5065754ecacSJeremy L Thompson // QFunction 5075754ecacSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.true_soln, 5085754ecacSJeremy L Thompson problem_data.true_soln_loc, &qf_true); 5095754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_true, "x", num_comp_x, CEED_EVAL_INTERP); 510a61c78d6SJeremy L Thompson CeedQFunctionAddOutput(qf_true, "true solution", num_comp_u, CEED_EVAL_NONE); 5115754ecacSJeremy L Thompson // Operator 5125754ecacSJeremy L Thompson CeedOperatorCreate(ceed, qf_true, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, 5135754ecacSJeremy L Thompson &op_true); 5145754ecacSJeremy L Thompson CeedOperatorSetField(op_true, "x", data[fine_level]->elem_restr_x, basis_x_true, 5155754ecacSJeremy L Thompson CEED_VECTOR_ACTIVE); 516a61c78d6SJeremy L Thompson CeedOperatorSetField(op_true, "true solution", data[fine_level]->elem_restr_u, 5175754ecacSJeremy L Thompson CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE); 5185754ecacSJeremy L Thompson // -- Compute true solution 5195754ecacSJeremy L Thompson CeedOperatorApply(op_true, x_coord, data[fine_level]->true_soln, 5205754ecacSJeremy L Thompson CEED_REQUEST_IMMEDIATE); 5215754ecacSJeremy L Thompson // -- Multiplicity calculation 5225754ecacSJeremy L Thompson CeedElemRestrictionCreateVector(data[fine_level]->elem_restr_u, &mult_vec, 5235754ecacSJeremy L Thompson NULL); 5245754ecacSJeremy L Thompson CeedVectorSetValue(mult_vec, 0.); 5255754ecacSJeremy L Thompson CeedElemRestrictionGetMultiplicity(data[fine_level]->elem_restr_u, mult_vec); 5265754ecacSJeremy L Thompson // -- Multiplicity correction 5275754ecacSJeremy L Thompson CeedVectorGetArray(data[fine_level]->true_soln, CEED_MEM_HOST, &true_array); 5285754ecacSJeremy L Thompson CeedVectorGetArrayRead(mult_vec, CEED_MEM_HOST, &mult_array); 5295754ecacSJeremy L Thompson for (CeedInt i = 0; i < U_loc_size; i++) 5305754ecacSJeremy L Thompson true_array[i] /= mult_array[i]; 5315754ecacSJeremy L Thompson CeedVectorRestoreArray(data[fine_level]->true_soln, &true_array); 5325754ecacSJeremy L Thompson CeedVectorRestoreArrayRead(mult_vec, &mult_array); 5335754ecacSJeremy L Thompson // -- Cleanup 5345754ecacSJeremy L Thompson CeedVectorDestroy(&mult_vec); 5355754ecacSJeremy L Thompson CeedBasisDestroy(&basis_x_true); 5365754ecacSJeremy L Thompson CeedQFunctionDestroy(&qf_true); 5375754ecacSJeremy L Thompson CeedOperatorDestroy(&op_true); 5385754ecacSJeremy L Thompson } 5395754ecacSJeremy L Thompson 5405754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 5415754ecacSJeremy L Thompson // Local energy computation 5425754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 5435754ecacSJeremy L Thompson // Create the QFunction and Operator that computes the strain energy 5445754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 5455754ecacSJeremy L Thompson // -- QFunction 5465754ecacSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.energy, 5475754ecacSJeremy L Thompson problem_data.energy_loc, &qf_energy); 5485754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_energy, "du", num_comp_u*dim, CEED_EVAL_GRAD); 549a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_energy, "qdata", q_data_size, CEED_EVAL_NONE); 5505754ecacSJeremy L Thompson CeedQFunctionAddOutput(qf_energy, "energy", num_comp_e, CEED_EVAL_INTERP); 5515754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_energy, phys_ctx); 5525754ecacSJeremy L Thompson // -- Operator 5535754ecacSJeremy L Thompson CeedOperatorCreate(ceed, qf_energy, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, 5545754ecacSJeremy L Thompson &op_energy); 5555754ecacSJeremy L Thompson CeedOperatorSetField(op_energy, "du", data[fine_level]->elem_restr_u, 5565754ecacSJeremy L Thompson data[fine_level]->basis_u, CEED_VECTOR_ACTIVE); 557a61c78d6SJeremy L Thompson CeedOperatorSetField(op_energy, "qdata", 5585754ecacSJeremy L Thompson data[fine_level]->elem_restr_geo_data_i, 5595754ecacSJeremy L Thompson CEED_BASIS_COLLOCATED, data[fine_level]->geo_data); 5605754ecacSJeremy L Thompson CeedOperatorSetField(op_energy, "energy", data[fine_level]->elem_restr_energy, 5615754ecacSJeremy L Thompson data[fine_level]->basis_energy, CEED_VECTOR_ACTIVE); 5625754ecacSJeremy L Thompson // -- Save libCEED data 5635754ecacSJeremy L Thompson data[fine_level]->qf_energy = qf_energy; 5645754ecacSJeremy L Thompson data[fine_level]->op_energy = op_energy; 5655754ecacSJeremy L Thompson 5665754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 5675754ecacSJeremy L Thompson // Diagnostic value computation 5685754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 5695754ecacSJeremy L Thompson // Create the QFunction and Operator that computes nodal diagnostic quantities 5705754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 5715754ecacSJeremy L Thompson // Geometric factors 5725754ecacSJeremy L Thompson // -- Coordinate basis 5735754ecacSJeremy L Thompson CeedBasis basis_x; 5745754ecacSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_x, 2, Q, CEED_GAUSS_LOBATTO, 5755754ecacSJeremy L Thompson &basis_x); 5765754ecacSJeremy L Thompson // -- QFunction 5775754ecacSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.setup_geo, 5785754ecacSJeremy L Thompson problem_data.setup_geo_loc, &qf_setup_geo); 5795754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_setup_geo, "dx", num_comp_x*dim, CEED_EVAL_GRAD); 5805754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_setup_geo, "weight", 1, CEED_EVAL_WEIGHT); 581a61c78d6SJeremy L Thompson CeedQFunctionAddOutput(qf_setup_geo, "qdata", q_data_size, CEED_EVAL_NONE); 5825754ecacSJeremy L Thompson // -- Operator 5835754ecacSJeremy L Thompson CeedOperatorCreate(ceed, qf_setup_geo, CEED_QFUNCTION_NONE, 5845754ecacSJeremy L Thompson CEED_QFUNCTION_NONE, &op_setup_geo); 5855754ecacSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "dx", data[fine_level]->elem_restr_x, 5865754ecacSJeremy L Thompson basis_x, CEED_VECTOR_ACTIVE); 5875754ecacSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "weight", CEED_ELEMRESTRICTION_NONE, 5885754ecacSJeremy L Thompson basis_x, CEED_VECTOR_NONE); 589a61c78d6SJeremy L Thompson CeedOperatorSetField(op_setup_geo, "qdata", 5905754ecacSJeremy L Thompson data[fine_level]->elem_restr_geo_data_diagnostic_i, 5915754ecacSJeremy L Thompson CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE); 5925754ecacSJeremy L Thompson // -- Compute the quadrature data 5935754ecacSJeremy L Thompson CeedOperatorApply(op_setup_geo, x_coord, data[fine_level]->geo_data_diagnostic, 5945754ecacSJeremy L Thompson CEED_REQUEST_IMMEDIATE); 5955754ecacSJeremy L Thompson // -- Cleanup 5965754ecacSJeremy L Thompson CeedBasisDestroy(&basis_x); 5975754ecacSJeremy L Thompson CeedQFunctionDestroy(&qf_setup_geo); 5985754ecacSJeremy L Thompson CeedOperatorDestroy(&op_setup_geo); 5995754ecacSJeremy L Thompson 6005754ecacSJeremy L Thompson // Diagnostic quantities 6015754ecacSJeremy L Thompson // -- QFunction 6025754ecacSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, problem_data.diagnostic, 6035754ecacSJeremy L Thompson problem_data.diagnostic_loc, &qf_diagnostic); 6045754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_diagnostic, "u", num_comp_u, CEED_EVAL_INTERP); 6055754ecacSJeremy L Thompson CeedQFunctionAddInput(qf_diagnostic, "du", num_comp_u*dim, CEED_EVAL_GRAD); 606a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_diagnostic, "qdata", q_data_size, CEED_EVAL_NONE); 607a61c78d6SJeremy L Thompson CeedQFunctionAddOutput(qf_diagnostic, "diagnostic values", 608a61c78d6SJeremy L Thompson num_comp_u + num_comp_d, CEED_EVAL_NONE); 6095754ecacSJeremy L Thompson CeedQFunctionSetContext(qf_diagnostic, phys_ctx); 6105754ecacSJeremy L Thompson // -- Operator 6115754ecacSJeremy L Thompson CeedOperatorCreate(ceed, qf_diagnostic, CEED_QFUNCTION_NONE, 6125754ecacSJeremy L Thompson CEED_QFUNCTION_NONE, &op_diagnostic); 6135754ecacSJeremy L Thompson CeedOperatorSetField(op_diagnostic, "u", data[fine_level]->elem_restr_u, 6145754ecacSJeremy L Thompson data[fine_level]->basis_diagnostic, CEED_VECTOR_ACTIVE); 6155754ecacSJeremy L Thompson CeedOperatorSetField(op_diagnostic, "du", data[fine_level]->elem_restr_u, 6165754ecacSJeremy L Thompson data[fine_level]->basis_diagnostic, CEED_VECTOR_ACTIVE); 617a61c78d6SJeremy L Thompson CeedOperatorSetField(op_diagnostic, "qdata", 6185754ecacSJeremy L Thompson data[fine_level]->elem_restr_geo_data_diagnostic_i, 6195754ecacSJeremy L Thompson CEED_BASIS_COLLOCATED, data[fine_level]->geo_data_diagnostic); 620a61c78d6SJeremy L Thompson CeedOperatorSetField(op_diagnostic, "diagnostic values", 6215754ecacSJeremy L Thompson data[fine_level]->elem_restr_diagnostic, 6225754ecacSJeremy L Thompson CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE); 6235754ecacSJeremy L Thompson // -- Save libCEED data 6245754ecacSJeremy L Thompson data[fine_level]->qf_diagnostic = qf_diagnostic; 6255754ecacSJeremy L Thompson data[fine_level]->op_diagnostic = op_diagnostic; 6265754ecacSJeremy L Thompson 6275754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 6285754ecacSJeremy L Thompson // Cleanup 6295754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 6305754ecacSJeremy L Thompson CeedVectorDestroy(&x_coord); 6315754ecacSJeremy L Thompson 6325754ecacSJeremy L Thompson PetscFunctionReturn(0); 6335754ecacSJeremy L Thompson }; 6345754ecacSJeremy L Thompson 6355754ecacSJeremy L Thompson // Set up libCEED multigrid level for a given degree 6365754ecacSJeremy L Thompson // Prolongation and Restriction are between level and level+1 6375754ecacSJeremy L Thompson PetscErrorCode SetupLibceedLevel(DM dm, Ceed ceed, AppCtx app_ctx, 6385754ecacSJeremy L Thompson ProblemData problem_data, PetscInt level, 6395754ecacSJeremy L Thompson PetscInt num_comp_u, PetscInt U_g_size, 6405754ecacSJeremy L Thompson PetscInt U_loc_size, CeedVector fine_mult, 6415754ecacSJeremy L Thompson CeedData *data) { 6425754ecacSJeremy L Thompson PetscErrorCode ierr; 6435754ecacSJeremy L Thompson CeedInt fine_level = app_ctx->num_levels - 1; 6445754ecacSJeremy L Thompson CeedInt P = app_ctx->level_degrees[level] + 1; 6455754ecacSJeremy L Thompson CeedInt Q = app_ctx->level_degrees[fine_level] + 1 + app_ctx->q_extra; 6465754ecacSJeremy L Thompson CeedInt dim; 6475754ecacSJeremy L Thompson CeedOperator op_jacobian, op_prolong, op_restrict; 6485754ecacSJeremy L Thompson 6495754ecacSJeremy L Thompson PetscFunctionBeginUser; 6505754ecacSJeremy L Thompson 6515754ecacSJeremy L Thompson ierr = DMGetDimension(dm, &dim); CHKERRQ(ierr); 6525754ecacSJeremy L Thompson 6535754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 6545754ecacSJeremy L Thompson // libCEED restrictions 6555754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 6565754ecacSJeremy L Thompson // -- Solution restriction 6577ed3e4cdSJeremy L Thompson ierr = CreateRestrictionFromPlex(ceed, dm, 0, 0, 0, 6585754ecacSJeremy L Thompson &data[level]->elem_restr_u); 6595754ecacSJeremy L Thompson CHKERRQ(ierr); 6605754ecacSJeremy L Thompson 6615754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 6625754ecacSJeremy L Thompson // libCEED bases 6635754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 6645754ecacSJeremy L Thompson // -- Solution basis 6655754ecacSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, num_comp_u, P, Q, 6665754ecacSJeremy L Thompson problem_data.quadrature_mode, 6675754ecacSJeremy L Thompson &data[level]->basis_u); 6685754ecacSJeremy L Thompson 6695754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 6705754ecacSJeremy L Thompson // Persistent libCEED vectors 6715754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 6725754ecacSJeremy L Thompson CeedVectorCreate(ceed, U_loc_size, &data[level]->x_ceed); 6735754ecacSJeremy L Thompson CeedVectorCreate(ceed, U_loc_size, &data[level]->y_ceed); 6745754ecacSJeremy L Thompson 6755754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 6765754ecacSJeremy L Thompson // Coarse Grid, Prolongation, and Restriction Operators 6775754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 6785754ecacSJeremy L Thompson // Create the Operators that compute the prolongation and 6795754ecacSJeremy L Thompson // restriction between the p-multigrid levels and the coarse grid eval. 6805754ecacSJeremy L Thompson // --------------------------------------------------------------------------- 6815754ecacSJeremy L Thompson CeedOperatorMultigridLevelCreate(data[level+1]->op_jacobian, fine_mult, 6825754ecacSJeremy L Thompson data[level]->elem_restr_u, data[level]->basis_u, 6835754ecacSJeremy L Thompson &op_jacobian, &op_prolong, &op_restrict); 6845754ecacSJeremy L Thompson 6855754ecacSJeremy L Thompson // -- Save libCEED data 6865754ecacSJeremy L Thompson data[level]->op_jacobian = op_jacobian; 6875754ecacSJeremy L Thompson data[level+1]->op_prolong = op_prolong; 6885754ecacSJeremy L Thompson data[level+1]->op_restrict = op_restrict; 6895754ecacSJeremy L Thompson 6905754ecacSJeremy L Thompson PetscFunctionReturn(0); 6915754ecacSJeremy L Thompson }; 692