1*5aed82e4SJeremy L Thompson // Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and other CEED contributors. 298285ab4SZach Atkins // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 398285ab4SZach Atkins // 498285ab4SZach Atkins // SPDX-License-Identifier: BSD-2-Clause 598285ab4SZach Atkins // 698285ab4SZach Atkins // This file is part of CEED: http://github.com/ceed 798285ab4SZach Atkins 8e83e87a5Sjeremylt #include "../include/libceedsetup.h" 92b730f8bSJeremy L Thompson 102b730f8bSJeremy L Thompson #include <stdio.h> 112b730f8bSJeremy L Thompson 1278f7fce3SZach Atkins #include "../include/libceedsetup.h" 13e83e87a5Sjeremylt #include "../include/petscutils.h" 14e83e87a5Sjeremylt 15e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 16e83e87a5Sjeremylt // Destroy libCEED operator objects 17e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 18e83e87a5Sjeremylt PetscErrorCode CeedDataDestroy(CeedInt i, CeedData data) { 195dfaedb8SJed Brown PetscFunctionBeginUser; 209b072555Sjeremylt CeedVectorDestroy(&data->q_data); 219b072555Sjeremylt CeedVectorDestroy(&data->x_ceed); 229b072555Sjeremylt CeedVectorDestroy(&data->y_ceed); 239b072555Sjeremylt CeedBasisDestroy(&data->basis_x); 249b072555Sjeremylt CeedBasisDestroy(&data->basis_u); 259b072555Sjeremylt CeedElemRestrictionDestroy(&data->elem_restr_u); 269b072555Sjeremylt CeedElemRestrictionDestroy(&data->elem_restr_x); 279b072555Sjeremylt CeedElemRestrictionDestroy(&data->elem_restr_u_i); 289b072555Sjeremylt CeedElemRestrictionDestroy(&data->elem_restr_qd_i); 299b072555Sjeremylt CeedQFunctionDestroy(&data->qf_apply); 309b072555Sjeremylt CeedOperatorDestroy(&data->op_apply); 31e83e87a5Sjeremylt if (i > 0) { 329b072555Sjeremylt CeedOperatorDestroy(&data->op_prolong); 339b072555Sjeremylt CeedOperatorDestroy(&data->op_restrict); 34e83e87a5Sjeremylt } 352b730f8bSJeremy L Thompson PetscCall(PetscFree(data)); 36ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 37e83e87a5Sjeremylt }; 38e83e87a5Sjeremylt 39e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 40e83e87a5Sjeremylt // Set up libCEED for a given degree 41e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 422b730f8bSJeremy L Thompson PetscErrorCode SetupLibceedByDegree(DM dm, Ceed ceed, CeedInt degree, CeedInt topo_dim, CeedInt q_extra, PetscInt num_comp_x, PetscInt num_comp_u, 432b730f8bSJeremy L Thompson PetscInt g_size, PetscInt xl_size, BPData bp_data, CeedData data, PetscBool setup_rhs, CeedVector rhs_ceed, 44e83e87a5Sjeremylt CeedVector *target) { 459b072555Sjeremylt DM dm_coord; 46e83e87a5Sjeremylt Vec coords; 479b072555Sjeremylt const PetscScalar *coord_array; 489b072555Sjeremylt CeedBasis basis_x, basis_u; 499b072555Sjeremylt CeedElemRestriction elem_restr_x, elem_restr_u, elem_restr_u_i, elem_restr_qd_i; 509b072555Sjeremylt CeedQFunction qf_setup_geo, qf_apply; 519b072555Sjeremylt CeedOperator op_setup_geo, op_apply; 529b072555Sjeremylt CeedVector x_coord, q_data, x_ceed, y_ceed; 532b730f8bSJeremy L Thompson CeedInt num_qpts, c_start, c_end, num_elem, q_data_size = bp_data.q_data_size; 542b730f8bSJeremy L Thompson CeedScalar R = 1; // radius of the sphere 552b730f8bSJeremy L Thompson CeedScalar l = 1.0 / PetscSqrtReal(3.0); // half edge of the inscribed cube 56e83e87a5Sjeremylt 575dfaedb8SJed Brown PetscFunctionBeginUser; 582b730f8bSJeremy L Thompson PetscCall(DMGetCoordinateDM(dm, &dm_coord)); 59129d8736Srezgarshakeri 60129d8736Srezgarshakeri // CEED bases 612b730f8bSJeremy L Thompson PetscCall(CreateBasisFromPlex(ceed, dm_coord, 0, 0, 0, 0, bp_data, &basis_x)); 622b730f8bSJeremy L Thompson PetscCall(CreateBasisFromPlex(ceed, dm, 0, 0, 0, 0, bp_data, &basis_u)); 63129d8736Srezgarshakeri 64129d8736Srezgarshakeri // CEED restrictions 652b730f8bSJeremy L Thompson PetscCall(CreateRestrictionFromPlex(ceed, dm_coord, 0, 0, 0, &elem_restr_x)); 662b730f8bSJeremy L Thompson PetscCall(CreateRestrictionFromPlex(ceed, dm, 0, 0, 0, &elem_restr_u)); 67e83e87a5Sjeremylt 682b730f8bSJeremy L Thompson PetscCall(DMPlexGetHeightStratum(dm, 0, &c_start, &c_end)); 699b072555Sjeremylt num_elem = c_end - c_start; 70129d8736Srezgarshakeri CeedBasisGetNumQuadraturePoints(basis_u, &num_qpts); 71e83e87a5Sjeremylt 722b730f8bSJeremy L Thompson CeedElemRestrictionCreateStrided(ceed, num_elem, num_qpts, num_comp_u, num_comp_u * num_elem * num_qpts, CEED_STRIDES_BACKEND, &elem_restr_u_i); 732b730f8bSJeremy L Thompson CeedElemRestrictionCreateStrided(ceed, num_elem, num_qpts, q_data_size, q_data_size * num_elem * num_qpts, CEED_STRIDES_BACKEND, &elem_restr_qd_i); 74e83e87a5Sjeremylt 75e83e87a5Sjeremylt // Element coordinates 762b730f8bSJeremy L Thompson PetscCall(DMGetCoordinatesLocal(dm, &coords)); 772b730f8bSJeremy L Thompson PetscCall(VecGetArrayRead(coords, &coord_array)); 78e83e87a5Sjeremylt 799b072555Sjeremylt CeedElemRestrictionCreateVector(elem_restr_x, &x_coord, NULL); 802b730f8bSJeremy L Thompson CeedVectorSetArray(x_coord, CEED_MEM_HOST, CEED_COPY_VALUES, (PetscScalar *)coord_array); 812b730f8bSJeremy L Thompson PetscCall(VecRestoreArrayRead(coords, &coord_array)); 82e83e87a5Sjeremylt 83e83e87a5Sjeremylt // Create the persistent vectors that will be needed in setup and apply 849b072555Sjeremylt CeedVectorCreate(ceed, q_data_size * num_elem * num_qpts, &q_data); 859b072555Sjeremylt CeedVectorCreate(ceed, xl_size, &x_ceed); 869b072555Sjeremylt CeedVectorCreate(ceed, xl_size, &y_ceed); 87e83e87a5Sjeremylt 88e83e87a5Sjeremylt // Create the QFunction that builds the context data 892b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, bp_data.setup_geo, bp_data.setup_geo_loc, &qf_setup_geo); 909b072555Sjeremylt CeedQFunctionAddInput(qf_setup_geo, "x", num_comp_x, CEED_EVAL_INTERP); 919b072555Sjeremylt CeedQFunctionAddInput(qf_setup_geo, "dx", num_comp_x * topo_dim, CEED_EVAL_GRAD); 929b072555Sjeremylt CeedQFunctionAddInput(qf_setup_geo, "weight", 1, CEED_EVAL_WEIGHT); 93a61c78d6SJeremy L Thompson CeedQFunctionAddOutput(qf_setup_geo, "qdata", q_data_size, CEED_EVAL_NONE); 94e83e87a5Sjeremylt 95e83e87a5Sjeremylt // Create the operator that builds the quadrature data 969b072555Sjeremylt CeedOperatorCreate(ceed, qf_setup_geo, NULL, NULL, &op_setup_geo); 972b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "x", elem_restr_x, basis_x, CEED_VECTOR_ACTIVE); 982b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "dx", elem_restr_x, basis_x, CEED_VECTOR_ACTIVE); 992b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "weight", CEED_ELEMRESTRICTION_NONE, basis_x, CEED_VECTOR_NONE); 100356036faSJeremy L Thompson CeedOperatorSetField(op_setup_geo, "qdata", elem_restr_qd_i, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE); 101e83e87a5Sjeremylt 1029b072555Sjeremylt // Setup q_data 1039b072555Sjeremylt CeedOperatorApply(op_setup_geo, x_coord, q_data, CEED_REQUEST_IMMEDIATE); 104e83e87a5Sjeremylt 105e83e87a5Sjeremylt // Set up PDE operator 1069b072555Sjeremylt CeedInt in_scale = bp_data.in_mode == CEED_EVAL_GRAD ? topo_dim : 1; 1079b072555Sjeremylt CeedInt out_scale = bp_data.out_mode == CEED_EVAL_GRAD ? topo_dim : 1; 1082b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, bp_data.apply, bp_data.apply_loc, &qf_apply); 1099b072555Sjeremylt CeedQFunctionAddInput(qf_apply, "u", num_comp_u * in_scale, bp_data.in_mode); 110a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_apply, "qdata", q_data_size, CEED_EVAL_NONE); 1119b072555Sjeremylt CeedQFunctionAddOutput(qf_apply, "v", num_comp_u * out_scale, bp_data.out_mode); 112e83e87a5Sjeremylt 113e83e87a5Sjeremylt // Create the mass or diff operator 1149b072555Sjeremylt CeedOperatorCreate(ceed, qf_apply, NULL, NULL, &op_apply); 1159b072555Sjeremylt CeedOperatorSetField(op_apply, "u", elem_restr_u, basis_u, CEED_VECTOR_ACTIVE); 116356036faSJeremy L Thompson CeedOperatorSetField(op_apply, "qdata", elem_restr_qd_i, CEED_BASIS_NONE, q_data); 1179b072555Sjeremylt CeedOperatorSetField(op_apply, "v", elem_restr_u, basis_u, CEED_VECTOR_ACTIVE); 118e83e87a5Sjeremylt 119e83e87a5Sjeremylt // Set up RHS if needed 120e83e87a5Sjeremylt if (setup_rhs) { 1219b072555Sjeremylt CeedQFunction qf_setup_rhs; 1229b072555Sjeremylt CeedOperator op_setup_rhs; 1239b072555Sjeremylt CeedVectorCreate(ceed, num_elem * num_qpts * num_comp_u, target); 124e83e87a5Sjeremylt // Create the q-function that sets up the RHS and true solution 1252b730f8bSJeremy L Thompson CeedQFunctionCreateInterior(ceed, 1, bp_data.setup_rhs, bp_data.setup_rhs_loc, &qf_setup_rhs); 1269b072555Sjeremylt CeedQFunctionAddInput(qf_setup_rhs, "x", num_comp_x, CEED_EVAL_INTERP); 127a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_setup_rhs, "qdata", q_data_size, CEED_EVAL_NONE); 1282b730f8bSJeremy L Thompson CeedQFunctionAddOutput(qf_setup_rhs, "true solution", num_comp_u, CEED_EVAL_NONE); 1299b072555Sjeremylt CeedQFunctionAddOutput(qf_setup_rhs, "rhs", num_comp_u, CEED_EVAL_INTERP); 130e83e87a5Sjeremylt 131e83e87a5Sjeremylt // Create the operator that builds the RHS and true solution 1329b072555Sjeremylt CeedOperatorCreate(ceed, qf_setup_rhs, NULL, NULL, &op_setup_rhs); 1332b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_rhs, "x", elem_restr_x, basis_x, CEED_VECTOR_ACTIVE); 134356036faSJeremy L Thompson CeedOperatorSetField(op_setup_rhs, "qdata", elem_restr_qd_i, CEED_BASIS_NONE, q_data); 135356036faSJeremy L Thompson CeedOperatorSetField(op_setup_rhs, "true solution", elem_restr_u_i, CEED_BASIS_NONE, *target); 1362b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_rhs, "rhs", elem_restr_u, basis_u, CEED_VECTOR_ACTIVE); 137e83e87a5Sjeremylt 138e83e87a5Sjeremylt // Set up the libCEED context 1399b072555Sjeremylt CeedQFunctionContext ctx_rhs_setup; 1409b072555Sjeremylt CeedQFunctionContextCreate(ceed, &ctx_rhs_setup); 1419b072555Sjeremylt CeedScalar rhs_setup_data[2] = {R, l}; 1422b730f8bSJeremy L Thompson CeedQFunctionContextSetData(ctx_rhs_setup, CEED_MEM_HOST, CEED_COPY_VALUES, sizeof rhs_setup_data, &rhs_setup_data); 1439b072555Sjeremylt CeedQFunctionSetContext(qf_setup_rhs, ctx_rhs_setup); 1449b072555Sjeremylt CeedQFunctionContextDestroy(&ctx_rhs_setup); 145e83e87a5Sjeremylt 146e83e87a5Sjeremylt // Setup RHS and target 1479b072555Sjeremylt CeedOperatorApply(op_setup_rhs, x_coord, rhs_ceed, CEED_REQUEST_IMMEDIATE); 148e83e87a5Sjeremylt 149e83e87a5Sjeremylt // Cleanup 1509b072555Sjeremylt CeedQFunctionDestroy(&qf_setup_rhs); 1519b072555Sjeremylt CeedOperatorDestroy(&op_setup_rhs); 152e83e87a5Sjeremylt } 153e83e87a5Sjeremylt 154e83e87a5Sjeremylt // Cleanup 1559b072555Sjeremylt CeedQFunctionDestroy(&qf_setup_geo); 1569b072555Sjeremylt CeedOperatorDestroy(&op_setup_geo); 1579b072555Sjeremylt CeedVectorDestroy(&x_coord); 158e83e87a5Sjeremylt 159e83e87a5Sjeremylt // Save libCEED data required for level 1602b730f8bSJeremy L Thompson data->basis_x = basis_x; 1612b730f8bSJeremy L Thompson data->basis_u = basis_u; 1629b072555Sjeremylt data->elem_restr_x = elem_restr_x; 1639b072555Sjeremylt data->elem_restr_u = elem_restr_u; 1649b072555Sjeremylt data->elem_restr_u_i = elem_restr_u_i; 1659b072555Sjeremylt data->elem_restr_qd_i = elem_restr_qd_i; 1669b072555Sjeremylt data->qf_apply = qf_apply; 1679b072555Sjeremylt data->op_apply = op_apply; 1689b072555Sjeremylt data->q_data = q_data; 1699b072555Sjeremylt data->x_ceed = x_ceed; 1709b072555Sjeremylt data->y_ceed = y_ceed; 171d4d45553Srezgarshakeri data->q_data_size = q_data_size; 172ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 173e83e87a5Sjeremylt }; 174e83e87a5Sjeremylt 175e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 176e83e87a5Sjeremylt // Setup libCEED level transfer operator objects 177e83e87a5Sjeremylt // ----------------------------------------------------------------------------- 1782b730f8bSJeremy L Thompson PetscErrorCode CeedLevelTransferSetup(DM dm, Ceed ceed, CeedInt level, CeedInt num_comp_u, CeedData *data, BPData bp_data, Vec fine_mult) { 179751eb813Srezgarshakeri PetscFunctionBeginUser; 180e83e87a5Sjeremylt // Restriction - Fine to corse 1819b072555Sjeremylt CeedOperator op_restrict; 182e83e87a5Sjeremylt // Interpolation - Corse to fine 1839b072555Sjeremylt CeedOperator op_prolong; 1841c9a79dbSrezgarshakeri // Coarse grid operator 1851c9a79dbSrezgarshakeri CeedOperator op_apply; 1861c9a79dbSrezgarshakeri // Basis 1871c9a79dbSrezgarshakeri CeedBasis basis_u; 1882b730f8bSJeremy L Thompson PetscCall(CreateBasisFromPlex(ceed, dm, 0, 0, 0, 0, bp_data, &basis_u)); 189e83e87a5Sjeremylt 1901c9a79dbSrezgarshakeri // --------------------------------------------------------------------------- 1911c9a79dbSrezgarshakeri // Coarse Grid, Prolongation, and Restriction Operators 1921c9a79dbSrezgarshakeri // --------------------------------------------------------------------------- 1931c9a79dbSrezgarshakeri // Create the Operators that compute the prolongation and 1941c9a79dbSrezgarshakeri // restriction between the p-multigrid levels and the coarse grid eval. 1951c9a79dbSrezgarshakeri // --------------------------------------------------------------------------- 1961c9a79dbSrezgarshakeri // Place in libCEED array 1971c9a79dbSrezgarshakeri PetscMemType m_mem_type; 198179e5961SZach Atkins PetscCall(VecReadP2C(fine_mult, &m_mem_type, data[level]->x_ceed)); 199e83e87a5Sjeremylt 2002b730f8bSJeremy L Thompson CeedOperatorMultigridLevelCreate(data[level]->op_apply, data[level]->x_ceed, data[level - 1]->elem_restr_u, basis_u, &op_apply, &op_prolong, 2012b730f8bSJeremy L Thompson &op_restrict); 202e83e87a5Sjeremylt 2031c9a79dbSrezgarshakeri // Restore PETSc vector 204179e5961SZach Atkins PetscCall(VecReadC2P(data[level]->x_ceed, m_mem_type, fine_mult)); 2052b730f8bSJeremy L Thompson PetscCall(VecZeroEntries(fine_mult)); 2061c9a79dbSrezgarshakeri // -- Save libCEED data 2071c9a79dbSrezgarshakeri data[level - 1]->op_apply = op_apply; 2081c9a79dbSrezgarshakeri data[level]->op_prolong = op_prolong; 2091c9a79dbSrezgarshakeri data[level]->op_restrict = op_restrict; 2101c9a79dbSrezgarshakeri 2111c9a79dbSrezgarshakeri CeedBasisDestroy(&basis_u); 212ee4ca9cbSJames Wright PetscFunctionReturn(PETSC_SUCCESS); 213e83e87a5Sjeremylt }; 214e83e87a5Sjeremylt 21578f7fce3SZach Atkins PetscErrorCode SetupErrorOperator(DM dm, Ceed ceed, BPData bp_data, CeedInt topo_dim, PetscInt num_comp_x, PetscInt num_comp_u, 21678f7fce3SZach Atkins CeedOperator *op_error) { 21778f7fce3SZach Atkins DM dm_coord; 21878f7fce3SZach Atkins Vec coords; 21978f7fce3SZach Atkins const PetscScalar *coord_array; 22078f7fce3SZach Atkins CeedBasis basis_x, basis_u; 22178f7fce3SZach Atkins CeedElemRestriction elem_restr_x, elem_restr_u, elem_restr_u_i, elem_restr_qd_i; 22278f7fce3SZach Atkins CeedQFunction qf_setup_geo, qf_setup_rhs, qf_error; 22378f7fce3SZach Atkins CeedOperator op_setup_geo, op_setup_rhs; 22478f7fce3SZach Atkins CeedVector x_coord, q_data, target, rhs; 22578f7fce3SZach Atkins CeedInt num_qpts, c_start, c_end, num_elem, q_data_size = bp_data.q_data_size; 22678f7fce3SZach Atkins CeedScalar R = 1; // radius of the sphere 22778f7fce3SZach Atkins CeedScalar l = 1.0 / PetscSqrtReal(3.0); // half edge of the inscribed cube 22878f7fce3SZach Atkins 22978f7fce3SZach Atkins PetscFunctionBeginUser; 23078f7fce3SZach Atkins PetscCall(DMGetCoordinateDM(dm, &dm_coord)); 23178f7fce3SZach Atkins 23278f7fce3SZach Atkins // CEED bases 23378f7fce3SZach Atkins PetscCall(CreateBasisFromPlex(ceed, dm_coord, 0, 0, 0, 0, bp_data, &basis_x)); 23478f7fce3SZach Atkins PetscCall(CreateBasisFromPlex(ceed, dm, 0, 0, 0, 0, bp_data, &basis_u)); 23578f7fce3SZach Atkins 23678f7fce3SZach Atkins // CEED restrictions 23778f7fce3SZach Atkins PetscCall(CreateRestrictionFromPlex(ceed, dm_coord, 0, 0, 0, &elem_restr_x)); 23878f7fce3SZach Atkins PetscCall(CreateRestrictionFromPlex(ceed, dm, 0, 0, 0, &elem_restr_u)); 23978f7fce3SZach Atkins 24078f7fce3SZach Atkins PetscCall(DMPlexGetHeightStratum(dm, 0, &c_start, &c_end)); 24178f7fce3SZach Atkins num_elem = c_end - c_start; 24278f7fce3SZach Atkins CeedBasisGetNumQuadraturePoints(basis_u, &num_qpts); 24378f7fce3SZach Atkins 24478f7fce3SZach Atkins CeedElemRestrictionCreateStrided(ceed, num_elem, num_qpts, num_comp_u, num_comp_u * num_elem * num_qpts, CEED_STRIDES_BACKEND, &elem_restr_u_i); 24578f7fce3SZach Atkins CeedElemRestrictionCreateStrided(ceed, num_elem, num_qpts, q_data_size, q_data_size * num_elem * num_qpts, CEED_STRIDES_BACKEND, &elem_restr_qd_i); 24678f7fce3SZach Atkins 24778f7fce3SZach Atkins // Element coordinates 24878f7fce3SZach Atkins PetscCall(DMGetCoordinatesLocal(dm, &coords)); 24978f7fce3SZach Atkins PetscCall(VecGetArrayRead(coords, &coord_array)); 25078f7fce3SZach Atkins 25178f7fce3SZach Atkins CeedElemRestrictionCreateVector(elem_restr_x, &x_coord, NULL); 25278f7fce3SZach Atkins CeedVectorSetArray(x_coord, CEED_MEM_HOST, CEED_COPY_VALUES, (PetscScalar *)coord_array); 25378f7fce3SZach Atkins PetscCall(VecRestoreArrayRead(coords, &coord_array)); 25478f7fce3SZach Atkins 25578f7fce3SZach Atkins // Create the persistent vectors that will be needed in setup and apply 25678f7fce3SZach Atkins CeedVectorCreate(ceed, q_data_size * num_elem * num_qpts, &q_data); 25778f7fce3SZach Atkins 25878f7fce3SZach Atkins // Create the QFunction that builds the context data 25978f7fce3SZach Atkins CeedQFunctionCreateInterior(ceed, 1, bp_data.setup_geo, bp_data.setup_geo_loc, &qf_setup_geo); 26078f7fce3SZach Atkins CeedQFunctionAddInput(qf_setup_geo, "x", num_comp_x, CEED_EVAL_INTERP); 26178f7fce3SZach Atkins CeedQFunctionAddInput(qf_setup_geo, "dx", num_comp_x * topo_dim, CEED_EVAL_GRAD); 26278f7fce3SZach Atkins CeedQFunctionAddInput(qf_setup_geo, "weight", 1, CEED_EVAL_WEIGHT); 26378f7fce3SZach Atkins CeedQFunctionAddOutput(qf_setup_geo, "qdata", q_data_size, CEED_EVAL_NONE); 26478f7fce3SZach Atkins 26578f7fce3SZach Atkins // Create the operator that builds the quadrature data 26678f7fce3SZach Atkins CeedOperatorCreate(ceed, qf_setup_geo, NULL, NULL, &op_setup_geo); 26778f7fce3SZach Atkins CeedOperatorSetField(op_setup_geo, "x", elem_restr_x, basis_x, CEED_VECTOR_ACTIVE); 26878f7fce3SZach Atkins CeedOperatorSetField(op_setup_geo, "dx", elem_restr_x, basis_x, CEED_VECTOR_ACTIVE); 26978f7fce3SZach Atkins CeedOperatorSetField(op_setup_geo, "weight", CEED_ELEMRESTRICTION_NONE, basis_x, CEED_VECTOR_NONE); 27078f7fce3SZach Atkins CeedOperatorSetField(op_setup_geo, "qdata", elem_restr_qd_i, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE); 27178f7fce3SZach Atkins 27278f7fce3SZach Atkins // Setup q_data 27378f7fce3SZach Atkins CeedOperatorApply(op_setup_geo, x_coord, q_data, CEED_REQUEST_IMMEDIATE); 27478f7fce3SZach Atkins 27578f7fce3SZach Atkins // Set up target vector 27678f7fce3SZach Atkins CeedElemRestrictionCreateVector(elem_restr_u, &rhs, NULL); 27778f7fce3SZach Atkins CeedVectorCreate(ceed, num_elem * num_qpts * num_comp_u, &target); 27878f7fce3SZach Atkins // Create the q-function that sets up the RHS and true solution 27978f7fce3SZach Atkins CeedQFunctionCreateInterior(ceed, 1, bp_data.setup_rhs, bp_data.setup_rhs_loc, &qf_setup_rhs); 28078f7fce3SZach Atkins CeedQFunctionAddInput(qf_setup_rhs, "x", num_comp_x, CEED_EVAL_INTERP); 28178f7fce3SZach Atkins CeedQFunctionAddInput(qf_setup_rhs, "qdata", q_data_size, CEED_EVAL_NONE); 28278f7fce3SZach Atkins CeedQFunctionAddOutput(qf_setup_rhs, "true solution", num_comp_u, CEED_EVAL_NONE); 28378f7fce3SZach Atkins CeedQFunctionAddOutput(qf_setup_rhs, "rhs", num_comp_u, CEED_EVAL_INTERP); 28478f7fce3SZach Atkins 28578f7fce3SZach Atkins // Create the operator that builds the RHS and true solution 28678f7fce3SZach Atkins CeedOperatorCreate(ceed, qf_setup_rhs, NULL, NULL, &op_setup_rhs); 28778f7fce3SZach Atkins CeedOperatorSetField(op_setup_rhs, "x", elem_restr_x, basis_x, CEED_VECTOR_ACTIVE); 28878f7fce3SZach Atkins CeedOperatorSetField(op_setup_rhs, "qdata", elem_restr_qd_i, CEED_BASIS_NONE, q_data); 28978f7fce3SZach Atkins CeedOperatorSetField(op_setup_rhs, "true solution", elem_restr_u_i, CEED_BASIS_NONE, target); 29078f7fce3SZach Atkins CeedOperatorSetField(op_setup_rhs, "rhs", elem_restr_u, basis_u, CEED_VECTOR_ACTIVE); 29178f7fce3SZach Atkins 29278f7fce3SZach Atkins // Set up the libCEED context 29378f7fce3SZach Atkins CeedQFunctionContext ctx_rhs_setup; 29478f7fce3SZach Atkins CeedQFunctionContextCreate(ceed, &ctx_rhs_setup); 29578f7fce3SZach Atkins CeedScalar rhs_setup_data[2] = {R, l}; 29678f7fce3SZach Atkins CeedQFunctionContextSetData(ctx_rhs_setup, CEED_MEM_HOST, CEED_COPY_VALUES, sizeof rhs_setup_data, &rhs_setup_data); 29778f7fce3SZach Atkins CeedQFunctionSetContext(qf_setup_rhs, ctx_rhs_setup); 29878f7fce3SZach Atkins CeedQFunctionContextDestroy(&ctx_rhs_setup); 29978f7fce3SZach Atkins 30078f7fce3SZach Atkins // Setup RHS and target 30178f7fce3SZach Atkins CeedOperatorApply(op_setup_rhs, x_coord, rhs, CEED_REQUEST_IMMEDIATE); 30278f7fce3SZach Atkins 30378f7fce3SZach Atkins // Set up error operator 30478f7fce3SZach Atkins // Create the error QFunction 30578f7fce3SZach Atkins CeedQFunctionCreateInterior(ceed, 1, bp_data.error, bp_data.error_loc, &qf_error); 30678f7fce3SZach Atkins CeedQFunctionAddInput(qf_error, "u", num_comp_u, CEED_EVAL_INTERP); 30778f7fce3SZach Atkins CeedQFunctionAddInput(qf_error, "true_soln", num_comp_u, CEED_EVAL_NONE); 30878f7fce3SZach Atkins CeedQFunctionAddInput(qf_error, "qdata", q_data_size, CEED_EVAL_NONE); 30978f7fce3SZach Atkins CeedQFunctionAddOutput(qf_error, "error", num_comp_u, CEED_EVAL_INTERP); 31078f7fce3SZach Atkins 31178f7fce3SZach Atkins // Create the error operator 31278f7fce3SZach Atkins CeedOperatorCreate(ceed, qf_error, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, op_error); 31378f7fce3SZach Atkins CeedOperatorSetField(*op_error, "u", elem_restr_u, basis_u, CEED_VECTOR_ACTIVE); 31478f7fce3SZach Atkins CeedOperatorSetField(*op_error, "true_soln", elem_restr_u_i, CEED_BASIS_NONE, target); 31578f7fce3SZach Atkins CeedOperatorSetField(*op_error, "qdata", elem_restr_qd_i, CEED_BASIS_NONE, q_data); 31678f7fce3SZach Atkins CeedOperatorSetField(*op_error, "error", elem_restr_u, basis_u, CEED_VECTOR_ACTIVE); 31778f7fce3SZach Atkins 31878f7fce3SZach Atkins // Cleanup 31978f7fce3SZach Atkins CeedQFunctionDestroy(&qf_setup_rhs); 32078f7fce3SZach Atkins CeedOperatorDestroy(&op_setup_rhs); 32178f7fce3SZach Atkins CeedQFunctionDestroy(&qf_setup_geo); 32278f7fce3SZach Atkins CeedOperatorDestroy(&op_setup_geo); 32378f7fce3SZach Atkins CeedQFunctionDestroy(&qf_error); 32478f7fce3SZach Atkins CeedVectorDestroy(&x_coord); 32578f7fce3SZach Atkins CeedVectorDestroy(&rhs); 32678f7fce3SZach Atkins CeedVectorDestroy(&target); 32778f7fce3SZach Atkins CeedVectorDestroy(&q_data); 32878f7fce3SZach Atkins CeedElemRestrictionDestroy(&elem_restr_u_i); 32978f7fce3SZach Atkins CeedElemRestrictionDestroy(&elem_restr_qd_i); 33078f7fce3SZach Atkins CeedElemRestrictionDestroy(&elem_restr_x); 33178f7fce3SZach Atkins CeedElemRestrictionDestroy(&elem_restr_u); 33278f7fce3SZach Atkins CeedBasisDestroy(&basis_x); 33378f7fce3SZach Atkins CeedBasisDestroy(&basis_u); 33478f7fce3SZach Atkins 33578f7fce3SZach Atkins PetscFunctionReturn(PETSC_SUCCESS); 33678f7fce3SZach Atkins } 337