19ba83ac0SJeremy L Thompson // Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors. 23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3d7b241e6Sjeremylt // 43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 5d7b241e6Sjeremylt // 63d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 7d7b241e6Sjeremylt 83d576824SJeremy L Thompson #include <ceed-impl.h> 949aac155SJeremy L Thompson #include <ceed.h> 102b730f8bSJeremy L Thompson #include <ceed/backend.h> 113d576824SJeremy L Thompson #include <stdbool.h> 123d576824SJeremy L Thompson #include <stdio.h> 133d576824SJeremy L Thompson #include <string.h> 14d7b241e6Sjeremylt 15dfdf5a53Sjeremylt /// @file 167a982d89SJeremy L. Thompson /// Implementation of CeedOperator interfaces 177a982d89SJeremy L. Thompson 187a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 197a982d89SJeremy L. Thompson /// CeedOperator Library Internal Functions 207a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 217a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorDeveloper 227a982d89SJeremy L. Thompson /// @{ 237a982d89SJeremy L. Thompson 247a982d89SJeremy L. Thompson /** 25ca94c3ddSJeremy L Thompson @brief Check if a `CeedOperator` Field matches the `CeedQFunction` Field 26e15f9bd0SJeremy L Thompson 27ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object for error handling 28ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunction` Field matching `CeedOperator` Field 29bafebce1SSebastian Grimberg @param[in] rstr `CeedOperator` Field `CeedElemRestriction` 30bafebce1SSebastian Grimberg @param[in] basis `CeedOperator` Field `CeedBasis` 31e15f9bd0SJeremy L Thompson 32e15f9bd0SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 33e15f9bd0SJeremy L Thompson 34e15f9bd0SJeremy L Thompson @ref Developer 35e15f9bd0SJeremy L Thompson **/ 36bafebce1SSebastian Grimberg static int CeedOperatorCheckField(Ceed ceed, CeedQFunctionField qf_field, CeedElemRestriction rstr, CeedBasis basis) { 376f8994e9SJeremy L Thompson const char *field_name; 381203703bSJeremy L Thompson CeedInt dim = 1, num_comp = 1, q_comp = 1, rstr_num_comp = 1, size; 391203703bSJeremy L Thompson CeedEvalMode eval_mode; 401203703bSJeremy L Thompson 411203703bSJeremy L Thompson // Field data 42ab747706SJeremy L Thompson CeedCall(CeedQFunctionFieldGetData(qf_field, &field_name, &size, &eval_mode)); 432b730f8bSJeremy L Thompson 44e15f9bd0SJeremy L Thompson // Restriction 45bafebce1SSebastian Grimberg CeedCheck((rstr == CEED_ELEMRESTRICTION_NONE) == (eval_mode == CEED_EVAL_WEIGHT), ceed, CEED_ERROR_INCOMPATIBLE, 466574a04fSJeremy L Thompson "CEED_ELEMRESTRICTION_NONE and CEED_EVAL_WEIGHT must be used together."); 47bafebce1SSebastian Grimberg if (rstr != CEED_ELEMRESTRICTION_NONE) { 48bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionGetNumComponents(rstr, &rstr_num_comp)); 49e1e9e29dSJed Brown } 50e15f9bd0SJeremy L Thompson // Basis 51bafebce1SSebastian Grimberg CeedCheck((basis == CEED_BASIS_NONE) == (eval_mode == CEED_EVAL_NONE), ceed, CEED_ERROR_INCOMPATIBLE, 52356036faSJeremy L Thompson "CEED_BASIS_NONE and CEED_EVAL_NONE must be used together."); 53bafebce1SSebastian Grimberg if (basis != CEED_BASIS_NONE) { 54bafebce1SSebastian Grimberg CeedCall(CeedBasisGetDimension(basis, &dim)); 55bafebce1SSebastian Grimberg CeedCall(CeedBasisGetNumComponents(basis, &num_comp)); 56bafebce1SSebastian Grimberg CeedCall(CeedBasisGetNumQuadratureComponents(basis, eval_mode, &q_comp)); 57bafebce1SSebastian Grimberg CeedCheck(rstr == CEED_ELEMRESTRICTION_NONE || rstr_num_comp == num_comp, ceed, CEED_ERROR_DIMENSION, 58ca94c3ddSJeremy L Thompson "Field '%s' of size %" CeedInt_FMT " and EvalMode %s: CeedElemRestriction has %" CeedInt_FMT 59ca94c3ddSJeremy L Thompson " components, but CeedBasis has %" CeedInt_FMT " components", 601203703bSJeremy L Thompson field_name, size, CeedEvalModes[eval_mode], rstr_num_comp, num_comp); 61e15f9bd0SJeremy L Thompson } 62e15f9bd0SJeremy L Thompson // Field size 63d1d35e2fSjeremylt switch (eval_mode) { 64e15f9bd0SJeremy L Thompson case CEED_EVAL_NONE: 65edb2538eSJeremy L Thompson CeedCheck(size == rstr_num_comp, ceed, CEED_ERROR_DIMENSION, 661203703bSJeremy L Thompson "Field '%s' of size %" CeedInt_FMT " and EvalMode %s: CeedElemRestriction has %" CeedInt_FMT " components", field_name, size, 671203703bSJeremy L Thompson CeedEvalModes[eval_mode], rstr_num_comp); 68e15f9bd0SJeremy L Thompson break; 69e15f9bd0SJeremy L Thompson case CEED_EVAL_INTERP: 70c4e3f59bSSebastian Grimberg case CEED_EVAL_GRAD: 71c4e3f59bSSebastian Grimberg case CEED_EVAL_DIV: 72c4e3f59bSSebastian Grimberg case CEED_EVAL_CURL: 736574a04fSJeremy L Thompson CeedCheck(size == num_comp * q_comp, ceed, CEED_ERROR_DIMENSION, 741203703bSJeremy L Thompson "Field '%s' of size %" CeedInt_FMT " and EvalMode %s: CeedElemRestriction/Basis has %" CeedInt_FMT " components", field_name, size, 751203703bSJeremy L Thompson CeedEvalModes[eval_mode], num_comp * q_comp); 76e15f9bd0SJeremy L Thompson break; 77e15f9bd0SJeremy L Thompson case CEED_EVAL_WEIGHT: 78d1d35e2fSjeremylt // No additional checks required 79e15f9bd0SJeremy L Thompson break; 80e15f9bd0SJeremy L Thompson } 81e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 827a982d89SJeremy L. Thompson } 837a982d89SJeremy L. Thompson 847a982d89SJeremy L. Thompson /** 85ca94c3ddSJeremy L Thompson @brief View a field of a `CeedOperator` 867a982d89SJeremy L. Thompson 871203703bSJeremy L Thompson @param[in] op_field `CeedOperator` Field to view 88ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunction` Field (carries field name) 89d1d35e2fSjeremylt @param[in] field_number Number of field being viewed 905a526491SJeremy L Thompson @param[in] tabs Tabs to append before each line 91b7fd8817SJeremy L Thompson @param[in] is_input `true` for an input field; `false` for output field 92ca94c3ddSJeremy L Thompson @param[in] stream Stream to view to, e.g., `stdout` 937a982d89SJeremy L. Thompson 947a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 957a982d89SJeremy L. Thompson 967a982d89SJeremy L. Thompson @ref Utility 977a982d89SJeremy L. Thompson **/ 98b7fd8817SJeremy L Thompson static int CeedOperatorFieldView(CeedOperatorField op_field, CeedQFunctionField qf_field, CeedInt field_number, const char *tabs, bool is_input, 995a526491SJeremy L Thompson FILE *stream) { 100b7fd8817SJeremy L Thompson const char *field_type = is_input ? "Input" : "Output"; 1016f8994e9SJeremy L Thompson const char *field_name; 1021203703bSJeremy L Thompson CeedInt size; 1031203703bSJeremy L Thompson CeedEvalMode eval_mode; 1041203703bSJeremy L Thompson CeedVector vec; 1051203703bSJeremy L Thompson CeedBasis basis; 1061203703bSJeremy L Thompson 1071203703bSJeremy L Thompson // Field data 108ab747706SJeremy L Thompson CeedCall(CeedQFunctionFieldGetData(qf_field, &field_name, &size, &eval_mode)); 109ab747706SJeremy L Thompson CeedCall(CeedOperatorFieldGetData(op_field, NULL, NULL, &basis, &vec)); 1107a982d89SJeremy L. Thompson 1112b730f8bSJeremy L Thompson fprintf(stream, 1122b730f8bSJeremy L Thompson "%s %s field %" CeedInt_FMT 1132b730f8bSJeremy L Thompson ":\n" 1147a982d89SJeremy L. Thompson "%s Name: \"%s\"\n", 115b7fd8817SJeremy L Thompson tabs, field_type, field_number, tabs, field_name); 1165a526491SJeremy L Thompson fprintf(stream, "%s Size: %" CeedInt_FMT "\n", tabs, size); 1175a526491SJeremy L Thompson fprintf(stream, "%s EvalMode: %s\n", tabs, CeedEvalModes[eval_mode]); 1185a526491SJeremy L Thompson if (basis == CEED_BASIS_NONE) fprintf(stream, "%s No basis\n", tabs); 1195a526491SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) fprintf(stream, "%s Active vector\n", tabs); 1205a526491SJeremy L Thompson else if (vec == CEED_VECTOR_NONE) fprintf(stream, "%s No vector\n", tabs); 121681d0ea7SJeremy L Thompson 122681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 123681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 124e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1257a982d89SJeremy L. Thompson } 1267a982d89SJeremy L. Thompson 1277a982d89SJeremy L. Thompson /** 128ca94c3ddSJeremy L Thompson @brief View a single `CeedOperator` 1297a982d89SJeremy L. Thompson 130ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to view 1315a526491SJeremy L Thompson @param[in] tabs Tabs to append before each new line 132ca94c3ddSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 1337a982d89SJeremy L. Thompson 1347a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 1357a982d89SJeremy L. Thompson 1367a982d89SJeremy L. Thompson @ref Utility 1377a982d89SJeremy L. Thompson **/ 1385a526491SJeremy L Thompson int CeedOperatorSingleView(CeedOperator op, const char *tabs, FILE *stream) { 13999f7f61fSJeremy L Thompson bool is_at_points; 1401203703bSJeremy L Thompson CeedInt num_elem, num_qpts, total_fields = 0, num_input_fields, num_output_fields; 1411203703bSJeremy L Thompson CeedQFunction qf; 1421203703bSJeremy L Thompson CeedQFunctionField *qf_input_fields, *qf_output_fields; 1431203703bSJeremy L Thompson CeedOperatorField *op_input_fields, *op_output_fields; 1447a982d89SJeremy L. Thompson 14599f7f61fSJeremy L Thompson CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 1462b730f8bSJeremy L Thompson CeedCall(CeedOperatorGetNumElements(op, &num_elem)); 1472b730f8bSJeremy L Thompson CeedCall(CeedOperatorGetNumQuadraturePoints(op, &num_qpts)); 1482b730f8bSJeremy L Thompson CeedCall(CeedOperatorGetNumArgs(op, &total_fields)); 1491203703bSJeremy L Thompson CeedCall(CeedOperatorGetFields(op, &num_input_fields, &op_input_fields, &num_output_fields, &op_output_fields)); 1501203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 1511203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFields(qf, NULL, &qf_input_fields, NULL, &qf_output_fields)); 152c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 1531c66c397SJeremy L Thompson 15499f7f61fSJeremy L Thompson if (is_at_points) { 15599f7f61fSJeremy L Thompson CeedInt max_points = 0; 15699f7f61fSJeremy L Thompson CeedElemRestriction rstr_points; 15799f7f61fSJeremy L Thompson 15899f7f61fSJeremy L Thompson CeedCall(CeedOperatorAtPointsGetPoints(op, &rstr_points, NULL)); 15999f7f61fSJeremy L Thompson CeedCall(CeedElemRestrictionGetMaxPointsInElement(rstr_points, &max_points)); 1605a526491SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " elements with %" CeedInt_FMT " max points each\n", tabs, num_elem, max_points); 16199f7f61fSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr_points)); 16299f7f61fSJeremy L Thompson } else { 1635a526491SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " elements with %" CeedInt_FMT " quadrature points each\n", tabs, num_elem, num_qpts); 16499f7f61fSJeremy L Thompson } 1655a526491SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " field%s\n", tabs, total_fields, total_fields > 1 ? "s" : ""); 1665a526491SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " input field%s:\n", tabs, num_input_fields, num_input_fields > 1 ? "s" : ""); 1671203703bSJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 1685a526491SJeremy L Thompson CeedCall(CeedOperatorFieldView(op_input_fields[i], qf_input_fields[i], i, tabs, 1, stream)); 1697a982d89SJeremy L. Thompson } 1705a526491SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " output field%s:\n", tabs, num_output_fields, num_output_fields > 1 ? "s" : ""); 1711203703bSJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 1725a526491SJeremy L Thompson CeedCall(CeedOperatorFieldView(op_output_fields[i], qf_output_fields[i], i, tabs, 0, stream)); 1737a982d89SJeremy L. Thompson } 174e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1757a982d89SJeremy L. Thompson } 1767a982d89SJeremy L. Thompson 177d99fa3c5SJeremy L Thompson /** 178b0f67a9cSJeremy L Thompson @brief View a `CeedOperator` passed as a `CeedObject` 179b0f67a9cSJeremy L Thompson 180b0f67a9cSJeremy L Thompson @param[in] op `CeedOperator` to view 181b0f67a9cSJeremy L Thompson @param[in] stream Filestream to write to 182b0f67a9cSJeremy L Thompson 183b0f67a9cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 184b0f67a9cSJeremy L Thompson 185b0f67a9cSJeremy L Thompson @ref Developer 186b0f67a9cSJeremy L Thompson **/ 187b0f67a9cSJeremy L Thompson static int CeedOperatorView_Object(CeedObject op, FILE *stream) { 188b0f67a9cSJeremy L Thompson CeedCall(CeedOperatorView((CeedOperator)op, stream)); 189b0f67a9cSJeremy L Thompson return CEED_ERROR_SUCCESS; 190b0f67a9cSJeremy L Thompson } 191b0f67a9cSJeremy L Thompson 192b0f67a9cSJeremy L Thompson /** 193*6c328a79SJeremy L Thompson @brief Destroy a `CeedOperator` passed as a `CeedObject` 194*6c328a79SJeremy L Thompson 195*6c328a79SJeremy L Thompson @param[in,out] op Address of `CeedOperator` to destroy 196*6c328a79SJeremy L Thompson 197*6c328a79SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 198*6c328a79SJeremy L Thompson 199*6c328a79SJeremy L Thompson @ref Developer 200*6c328a79SJeremy L Thompson **/ 201*6c328a79SJeremy L Thompson static int CeedOperatorDestroy_Object(CeedObject *op) { 202*6c328a79SJeremy L Thompson CeedCall(CeedOperatorDestroy((CeedOperator *)op)); 203*6c328a79SJeremy L Thompson return CEED_ERROR_SUCCESS; 204*6c328a79SJeremy L Thompson } 205*6c328a79SJeremy L Thompson 206*6c328a79SJeremy L Thompson /** 207681d0ea7SJeremy L Thompson @brief Find the active input vector `CeedBasis` for a non-composite `CeedOperator`. 208681d0ea7SJeremy L Thompson 209681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `active_basis` with @ref CeedBasisDestroy(). 210eaf62fffSJeremy L Thompson 211ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to find active `CeedBasis` for 212ca94c3ddSJeremy L Thompson @param[out] active_basis `CeedBasis` for active input vector or `NULL` for composite operator 213eaf62fffSJeremy L Thompson 214eaf62fffSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 215eaf62fffSJeremy L Thompson 216eaf62fffSJeremy L Thompson @ref Developer 217eaf62fffSJeremy L Thompson **/ 218eaf62fffSJeremy L Thompson int CeedOperatorGetActiveBasis(CeedOperator op, CeedBasis *active_basis) { 219506b1a0cSSebastian Grimberg CeedCall(CeedOperatorGetActiveBases(op, active_basis, NULL)); 220506b1a0cSSebastian Grimberg return CEED_ERROR_SUCCESS; 221506b1a0cSSebastian Grimberg } 222506b1a0cSSebastian Grimberg 223506b1a0cSSebastian Grimberg /** 224681d0ea7SJeremy L Thompson @brief Find the active input and output vector `CeedBasis` for a non-composite `CeedOperator`. 225681d0ea7SJeremy L Thompson 226681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the bases with @ref CeedBasisDestroy(). 227506b1a0cSSebastian Grimberg 228ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to find active `CeedBasis` for 229ca94c3ddSJeremy L Thompson @param[out] active_input_basis `CeedBasis` for active input vector or `NULL` for composite operator 230ca94c3ddSJeremy L Thompson @param[out] active_output_basis `CeedBasis` for active output vector or `NULL` for composite operator 231506b1a0cSSebastian Grimberg 232506b1a0cSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 233506b1a0cSSebastian Grimberg 234506b1a0cSSebastian Grimberg @ref Developer 235506b1a0cSSebastian Grimberg **/ 236506b1a0cSSebastian Grimberg int CeedOperatorGetActiveBases(CeedOperator op, CeedBasis *active_input_basis, CeedBasis *active_output_basis) { 2371203703bSJeremy L Thompson bool is_composite; 2381203703bSJeremy L Thompson CeedInt num_input_fields, num_output_fields; 2391203703bSJeremy L Thompson CeedOperatorField *op_input_fields, *op_output_fields; 2401c66c397SJeremy L Thompson 2411203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 2421203703bSJeremy L Thompson CeedCall(CeedOperatorGetFields(op, &num_input_fields, &op_input_fields, &num_output_fields, &op_output_fields)); 2431203703bSJeremy L Thompson 244506b1a0cSSebastian Grimberg if (active_input_basis) { 245506b1a0cSSebastian Grimberg *active_input_basis = NULL; 2461203703bSJeremy L Thompson if (!is_composite) { 2471203703bSJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 2481203703bSJeremy L Thompson CeedVector vec; 2491203703bSJeremy L Thompson 2501203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_input_fields[i], &vec)); 2511203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 2521203703bSJeremy L Thompson CeedBasis basis; 2531203703bSJeremy L Thompson 2541203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(op_input_fields[i], &basis)); 2559bc66399SJeremy L Thompson CeedCheck(!*active_input_basis || *active_input_basis == basis, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, 2569bc66399SJeremy L Thompson "Multiple active input CeedBases found"); 257681d0ea7SJeremy L Thompson if (!*active_input_basis) CeedCall(CeedBasisReferenceCopy(basis, active_input_basis)); 258681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 259eaf62fffSJeremy L Thompson } 260681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 2612b730f8bSJeremy L Thompson } 2629bc66399SJeremy L Thompson CeedCheck(*active_input_basis, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "No active input CeedBasis found"); 263506b1a0cSSebastian Grimberg } 264506b1a0cSSebastian Grimberg } 265506b1a0cSSebastian Grimberg if (active_output_basis) { 266506b1a0cSSebastian Grimberg *active_output_basis = NULL; 2671203703bSJeremy L Thompson if (!is_composite) { 2681203703bSJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 2691203703bSJeremy L Thompson CeedVector vec; 2701203703bSJeremy L Thompson 2711203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_output_fields[i], &vec)); 2721203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 2731203703bSJeremy L Thompson CeedBasis basis; 2741203703bSJeremy L Thompson 2751203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(op_output_fields[i], &basis)); 2769bc66399SJeremy L Thompson CeedCheck(!*active_output_basis || *active_output_basis == basis, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, 2779bc66399SJeremy L Thompson "Multiple active output CeedBases found"); 278681d0ea7SJeremy L Thompson if (!*active_output_basis) CeedCall(CeedBasisReferenceCopy(basis, active_output_basis)); 279681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 280506b1a0cSSebastian Grimberg } 281681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 282506b1a0cSSebastian Grimberg } 2839bc66399SJeremy L Thompson CeedCheck(*active_output_basis, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "No active output CeedBasis found"); 284506b1a0cSSebastian Grimberg } 285506b1a0cSSebastian Grimberg } 286eaf62fffSJeremy L Thompson return CEED_ERROR_SUCCESS; 287eaf62fffSJeremy L Thompson } 288eaf62fffSJeremy L Thompson 289eaf62fffSJeremy L Thompson /** 290681d0ea7SJeremy L Thompson @brief Find the active vector `CeedElemRestriction` for a non-composite `CeedOperator`. 291681d0ea7SJeremy L Thompson 292681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `active_rstr` with @ref CeedElemRestrictionDestroy(). 293e2f04181SAndrew T. Barker 294ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to find active `CeedElemRestriction` for 295ca94c3ddSJeremy L Thompson @param[out] active_rstr `CeedElemRestriction` for active input vector or NULL for composite operator 296e2f04181SAndrew T. Barker 297e2f04181SAndrew T. Barker @return An error code: 0 - success, otherwise - failure 298e2f04181SAndrew T. Barker 299e2f04181SAndrew T. Barker @ref Utility 300e2f04181SAndrew T. Barker **/ 3012b730f8bSJeremy L Thompson int CeedOperatorGetActiveElemRestriction(CeedOperator op, CeedElemRestriction *active_rstr) { 302506b1a0cSSebastian Grimberg CeedCall(CeedOperatorGetActiveElemRestrictions(op, active_rstr, NULL)); 303506b1a0cSSebastian Grimberg return CEED_ERROR_SUCCESS; 304506b1a0cSSebastian Grimberg } 305506b1a0cSSebastian Grimberg 306506b1a0cSSebastian Grimberg /** 307681d0ea7SJeremy L Thompson @brief Find the active input and output vector `CeedElemRestriction` for a non-composite `CeedOperator`. 308681d0ea7SJeremy L Thompson 309681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the restrictions with @ref CeedElemRestrictionDestroy(). 310506b1a0cSSebastian Grimberg 311ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to find active `CeedElemRestriction` for 312ca94c3ddSJeremy L Thompson @param[out] active_input_rstr `CeedElemRestriction` for active input vector or NULL for composite operator 313ca94c3ddSJeremy L Thompson @param[out] active_output_rstr `CeedElemRestriction` for active output vector or NULL for composite operator 314506b1a0cSSebastian Grimberg 315506b1a0cSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 316506b1a0cSSebastian Grimberg 317506b1a0cSSebastian Grimberg @ref Utility 318506b1a0cSSebastian Grimberg **/ 319506b1a0cSSebastian Grimberg int CeedOperatorGetActiveElemRestrictions(CeedOperator op, CeedElemRestriction *active_input_rstr, CeedElemRestriction *active_output_rstr) { 3201203703bSJeremy L Thompson bool is_composite; 3211203703bSJeremy L Thompson CeedInt num_input_fields, num_output_fields; 3221203703bSJeremy L Thompson CeedOperatorField *op_input_fields, *op_output_fields; 3231c66c397SJeremy L Thompson 3241203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 3251203703bSJeremy L Thompson CeedCall(CeedOperatorGetFields(op, &num_input_fields, &op_input_fields, &num_output_fields, &op_output_fields)); 3261203703bSJeremy L Thompson 327506b1a0cSSebastian Grimberg if (active_input_rstr) { 328506b1a0cSSebastian Grimberg *active_input_rstr = NULL; 3291203703bSJeremy L Thompson if (!is_composite) { 3301203703bSJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 3311203703bSJeremy L Thompson CeedVector vec; 3321203703bSJeremy L Thompson 3331203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_input_fields[i], &vec)); 3341203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 3351203703bSJeremy L Thompson CeedElemRestriction rstr; 3361203703bSJeremy L Thompson 3371203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetElemRestriction(op_input_fields[i], &rstr)); 3389bc66399SJeremy L Thompson CeedCheck(!*active_input_rstr || *active_input_rstr == rstr, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, 3399bc66399SJeremy L Thompson "Multiple active input CeedElemRestrictions found"); 340681d0ea7SJeremy L Thompson if (!*active_input_rstr) CeedCall(CeedElemRestrictionReferenceCopy(rstr, active_input_rstr)); 341681d0ea7SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr)); 342e2f04181SAndrew T. Barker } 343681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 3442b730f8bSJeremy L Thompson } 3459bc66399SJeremy L Thompson CeedCheck(*active_input_rstr, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "No active input CeedElemRestriction found"); 346506b1a0cSSebastian Grimberg } 347506b1a0cSSebastian Grimberg } 348506b1a0cSSebastian Grimberg if (active_output_rstr) { 349506b1a0cSSebastian Grimberg *active_output_rstr = NULL; 3501203703bSJeremy L Thompson if (!is_composite) { 3511203703bSJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 3521203703bSJeremy L Thompson CeedVector vec; 3531203703bSJeremy L Thompson 3541203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_output_fields[i], &vec)); 3551203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 3561203703bSJeremy L Thompson CeedElemRestriction rstr; 3571203703bSJeremy L Thompson 3581203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetElemRestriction(op_output_fields[i], &rstr)); 3599bc66399SJeremy L Thompson CeedCheck(!*active_output_rstr || *active_output_rstr == rstr, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, 3609bc66399SJeremy L Thompson "Multiple active output CeedElemRestrictions found"); 361681d0ea7SJeremy L Thompson if (!*active_output_rstr) CeedCall(CeedElemRestrictionReferenceCopy(rstr, active_output_rstr)); 362681d0ea7SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr)); 363506b1a0cSSebastian Grimberg } 364681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 365506b1a0cSSebastian Grimberg } 3669bc66399SJeremy L Thompson CeedCheck(*active_output_rstr, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "No active output CeedElemRestriction found"); 367506b1a0cSSebastian Grimberg } 368506b1a0cSSebastian Grimberg } 369e2f04181SAndrew T. Barker return CEED_ERROR_SUCCESS; 370e2f04181SAndrew T. Barker } 371e2f04181SAndrew T. Barker 372d8dd9a91SJeremy L Thompson /** 373ca94c3ddSJeremy L Thompson @brief Set `CeedQFunctionContext` field values of the specified type. 3744385fb7fSSebastian Grimberg 375ca94c3ddSJeremy L Thompson For composite operators, the value is set in all sub-operator `CeedQFunctionContext` that have a matching `field_name`. 376ca94c3ddSJeremy L Thompson A non-zero error code is returned for single operators that do not have a matching field of the same type or composite operators that do not have any field of a matching type. 377d8dd9a91SJeremy L Thompson 378ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 379ea61e9acSJeremy L Thompson @param[in] field_label Label of field to set 380ea61e9acSJeremy L Thompson @param[in] field_type Type of field to set 3812788fa27SJeremy L Thompson @param[in] values Values to set 382d8dd9a91SJeremy L Thompson 383d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 384d8dd9a91SJeremy L Thompson 3856ab8e59fSJames Wright @ref Developer 386d8dd9a91SJeremy L Thompson **/ 3872788fa27SJeremy L Thompson static int CeedOperatorContextSetGeneric(CeedOperator op, CeedContextFieldLabel field_label, CeedContextFieldType field_type, void *values) { 3881c66c397SJeremy L Thompson bool is_composite = false; 3891c66c397SJeremy L Thompson 3909bc66399SJeremy L Thompson CeedCheck(field_label, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3913668ca4bSJeremy L Thompson 3925ac9af79SJeremy L Thompson // Check if field_label and op correspond 3935ac9af79SJeremy L Thompson if (field_label->from_op) { 3945ac9af79SJeremy L Thompson CeedInt index = -1; 3955ac9af79SJeremy L Thompson 3965ac9af79SJeremy L Thompson for (CeedInt i = 0; i < op->num_context_labels; i++) { 3975ac9af79SJeremy L Thompson if (op->context_labels[i] == field_label) index = i; 3985ac9af79SJeremy L Thompson } 3999bc66399SJeremy L Thompson CeedCheck(index != -1, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "ContextFieldLabel does not correspond to the operator"); 4005ac9af79SJeremy L Thompson } 4015ac9af79SJeremy L Thompson 4022b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 403d8dd9a91SJeremy L Thompson if (is_composite) { 404d8dd9a91SJeremy L Thompson CeedInt num_sub; 405d8dd9a91SJeremy L Thompson CeedOperator *sub_operators; 406d8dd9a91SJeremy L Thompson 407ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_sub)); 408ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 4099bc66399SJeremy L Thompson CeedCheck(num_sub == field_label->num_sub_labels, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, 4109bc66399SJeremy L Thompson "Composite operator modified after ContextFieldLabel created"); 411d8dd9a91SJeremy L Thompson 412d8dd9a91SJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 4131203703bSJeremy L Thompson CeedQFunctionContext ctx; 4141203703bSJeremy L Thompson 4151485364cSJeremy L Thompson CeedCall(CeedOperatorGetContext(sub_operators[i], &ctx)); 416d8dd9a91SJeremy L Thompson // Try every sub-operator, ok if some sub-operators do not have field 4171485364cSJeremy L Thompson if (ctx && field_label->sub_labels[i]) { 4181203703bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label->sub_labels[i], field_type, values)); 419d8dd9a91SJeremy L Thompson } 4201485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 421d8dd9a91SJeremy L Thompson } 422d8dd9a91SJeremy L Thompson } else { 4231203703bSJeremy L Thompson CeedQFunctionContext ctx; 4241203703bSJeremy L Thompson 4251485364cSJeremy L Thompson CeedCall(CeedOperatorGetContext(op, &ctx)); 4269bc66399SJeremy L Thompson CeedCheck(ctx, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "QFunction does not have context data"); 4271203703bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, field_type, values)); 4281485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 4292788fa27SJeremy L Thompson } 4306d95ab46SJeremy L Thompson CeedCall(CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(op, true)); 4312788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4322788fa27SJeremy L Thompson } 4332788fa27SJeremy L Thompson 4342788fa27SJeremy L Thompson /** 435ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field values of the specified type, read-only. 4364385fb7fSSebastian Grimberg 437ca94c3ddSJeremy L Thompson For composite operators, the values retrieved are for the first sub-operator `CeedQFunctionContext` that have a matching `field_name`. 438ca94c3ddSJeremy L Thompson A non-zero error code is returned for single operators that do not have a matching field of the same type or composite operators that do not have any field of a matching type. 4392788fa27SJeremy L Thompson 440ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 4412788fa27SJeremy L Thompson @param[in] field_label Label of field to set 4422788fa27SJeremy L Thompson @param[in] field_type Type of field to set 443c5d0f995SJed Brown @param[out] num_values Number of values of type `field_type` in array `values` 444c5d0f995SJed Brown @param[out] values Values in the label 4452788fa27SJeremy L Thompson 4462788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4472788fa27SJeremy L Thompson 4486ab8e59fSJames Wright @ref Developer 4492788fa27SJeremy L Thompson **/ 4502788fa27SJeremy L Thompson static int CeedOperatorContextGetGenericRead(CeedOperator op, CeedContextFieldLabel field_label, CeedContextFieldType field_type, size_t *num_values, 4512788fa27SJeremy L Thompson void *values) { 4521c66c397SJeremy L Thompson bool is_composite = false; 4531c66c397SJeremy L Thompson 4549bc66399SJeremy L Thompson CeedCheck(field_label, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4552788fa27SJeremy L Thompson 4562788fa27SJeremy L Thompson *(void **)values = NULL; 4572788fa27SJeremy L Thompson *num_values = 0; 4582788fa27SJeremy L Thompson 4595ac9af79SJeremy L Thompson // Check if field_label and op correspond 4605ac9af79SJeremy L Thompson if (field_label->from_op) { 4615ac9af79SJeremy L Thompson CeedInt index = -1; 4625ac9af79SJeremy L Thompson 4635ac9af79SJeremy L Thompson for (CeedInt i = 0; i < op->num_context_labels; i++) { 4645ac9af79SJeremy L Thompson if (op->context_labels[i] == field_label) index = i; 4655ac9af79SJeremy L Thompson } 4669bc66399SJeremy L Thompson CeedCheck(index != -1, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "ContextFieldLabel does not correspond to the operator"); 4675ac9af79SJeremy L Thompson } 4685ac9af79SJeremy L Thompson 4692788fa27SJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 4702788fa27SJeremy L Thompson if (is_composite) { 4712788fa27SJeremy L Thompson CeedInt num_sub; 4722788fa27SJeremy L Thompson CeedOperator *sub_operators; 4732788fa27SJeremy L Thompson 474ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_sub)); 475ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 4769bc66399SJeremy L Thompson CeedCheck(num_sub == field_label->num_sub_labels, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, 4779bc66399SJeremy L Thompson "Composite operator modified after ContextFieldLabel created"); 4782788fa27SJeremy L Thompson 4792788fa27SJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 4801203703bSJeremy L Thompson CeedQFunctionContext ctx; 4811203703bSJeremy L Thompson 4821485364cSJeremy L Thompson CeedCall(CeedOperatorGetContext(sub_operators[i], &ctx)); 4832788fa27SJeremy L Thompson // Try every sub-operator, ok if some sub-operators do not have field 4841485364cSJeremy L Thompson if (ctx && field_label->sub_labels[i]) { 4851203703bSJeremy L Thompson CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label->sub_labels[i], field_type, num_values, values)); 4861485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 4872788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4882788fa27SJeremy L Thompson } 4891485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 4902788fa27SJeremy L Thompson } 4912788fa27SJeremy L Thompson } else { 4921203703bSJeremy L Thompson CeedQFunctionContext ctx; 4931203703bSJeremy L Thompson 4941485364cSJeremy L Thompson CeedCall(CeedOperatorGetContext(op, &ctx)); 4959bc66399SJeremy L Thompson CeedCheck(ctx, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "QFunction does not have context data"); 4961203703bSJeremy L Thompson CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, field_type, num_values, values)); 4971485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 4982788fa27SJeremy L Thompson } 4992788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 5002788fa27SJeremy L Thompson } 5012788fa27SJeremy L Thompson 5022788fa27SJeremy L Thompson /** 503ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field values of the specified type, read-only. 5044385fb7fSSebastian Grimberg 505ca94c3ddSJeremy L Thompson For composite operators, the values restored are for the first sub-operator `CeedQFunctionContext` that have a matching `field_name`. 506ca94c3ddSJeremy L Thompson A non-zero error code is returned for single operators that do not have a matching field of the same type or composite operators that do not have any field of a matching type. 5072788fa27SJeremy L Thompson 508ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 5092788fa27SJeremy L Thompson @param[in] field_label Label of field to set 5102788fa27SJeremy L Thompson @param[in] field_type Type of field to set 511c5d0f995SJed Brown @param[in] values Values array to restore 5122788fa27SJeremy L Thompson 5132788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 5142788fa27SJeremy L Thompson 5156ab8e59fSJames Wright @ref Developer 5162788fa27SJeremy L Thompson **/ 5172788fa27SJeremy L Thompson static int CeedOperatorContextRestoreGenericRead(CeedOperator op, CeedContextFieldLabel field_label, CeedContextFieldType field_type, void *values) { 5181c66c397SJeremy L Thompson bool is_composite = false; 5191c66c397SJeremy L Thompson 5209bc66399SJeremy L Thompson CeedCheck(field_label, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "Invalid field label"); 5212788fa27SJeremy L Thompson 5225ac9af79SJeremy L Thompson // Check if field_label and op correspond 5235ac9af79SJeremy L Thompson if (field_label->from_op) { 5245ac9af79SJeremy L Thompson CeedInt index = -1; 5255ac9af79SJeremy L Thompson 5265ac9af79SJeremy L Thompson for (CeedInt i = 0; i < op->num_context_labels; i++) { 5275ac9af79SJeremy L Thompson if (op->context_labels[i] == field_label) index = i; 5285ac9af79SJeremy L Thompson } 5299bc66399SJeremy L Thompson CeedCheck(index != -1, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "ContextFieldLabel does not correspond to the operator"); 5305ac9af79SJeremy L Thompson } 5315ac9af79SJeremy L Thompson 5322788fa27SJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 5332788fa27SJeremy L Thompson if (is_composite) { 5342788fa27SJeremy L Thompson CeedInt num_sub; 5352788fa27SJeremy L Thompson CeedOperator *sub_operators; 5362788fa27SJeremy L Thompson 537ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_sub)); 538ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 5399bc66399SJeremy L Thompson CeedCheck(num_sub == field_label->num_sub_labels, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, 5409bc66399SJeremy L Thompson "Composite operator modified after ContextFieldLabel created"); 5412788fa27SJeremy L Thompson 5422788fa27SJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 5431203703bSJeremy L Thompson CeedQFunctionContext ctx; 5441203703bSJeremy L Thompson 5451485364cSJeremy L Thompson CeedCall(CeedOperatorGetContext(sub_operators[i], &ctx)); 5462788fa27SJeremy L Thompson // Try every sub-operator, ok if some sub-operators do not have field 5471485364cSJeremy L Thompson if (ctx && field_label->sub_labels[i]) { 5481203703bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label->sub_labels[i], field_type, values)); 5491485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 5502788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 5512788fa27SJeremy L Thompson } 5521485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 5532788fa27SJeremy L Thompson } 5542788fa27SJeremy L Thompson } else { 5551203703bSJeremy L Thompson CeedQFunctionContext ctx; 5561203703bSJeremy L Thompson 5571485364cSJeremy L Thompson CeedCall(CeedOperatorGetContext(op, &ctx)); 5589bc66399SJeremy L Thompson CeedCheck(ctx, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "QFunction does not have context data"); 5591203703bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, field_type, values)); 5601485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 561d8dd9a91SJeremy L Thompson } 562d8dd9a91SJeremy L Thompson return CEED_ERROR_SUCCESS; 563d8dd9a91SJeremy L Thompson } 564d8dd9a91SJeremy L Thompson 5657a982d89SJeremy L. Thompson /// @} 5667a982d89SJeremy L. Thompson 5677a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5687a982d89SJeremy L. Thompson /// CeedOperator Backend API 5697a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5707a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorBackend 5717a982d89SJeremy L. Thompson /// @{ 5727a982d89SJeremy L. Thompson 5737a982d89SJeremy L. Thompson /** 574ca94c3ddSJeremy L Thompson @brief Get the number of arguments associated with a `CeedOperator` 5757a982d89SJeremy L. Thompson 576ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 577d1d35e2fSjeremylt @param[out] num_args Variable to store vector number of arguments 5787a982d89SJeremy L. Thompson 5797a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5807a982d89SJeremy L. Thompson 5817a982d89SJeremy L. Thompson @ref Backend 5827a982d89SJeremy L. Thompson **/ 583d1d35e2fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *num_args) { 5841203703bSJeremy L Thompson bool is_composite; 5851203703bSJeremy L Thompson 5861203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 5876e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Not defined for composite operators"); 588d1d35e2fSjeremylt *num_args = op->num_fields; 589e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5907a982d89SJeremy L. Thompson } 5917a982d89SJeremy L. Thompson 5927a982d89SJeremy L. Thompson /** 5939463e855SJeremy L Thompson @brief Get the tensor product status of all bases for a `CeedOperator`. 5949463e855SJeremy L Thompson 5959463e855SJeremy L Thompson `has_tensor_bases` is only set to `true` if every field uses a tensor-product basis. 5969463e855SJeremy L Thompson 5979463e855SJeremy L Thompson @param[in] op `CeedOperator` 5989463e855SJeremy L Thompson @param[out] has_tensor_bases Variable to store tensor bases status 5999463e855SJeremy L Thompson 6009463e855SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 6019463e855SJeremy L Thompson 6029463e855SJeremy L Thompson @ref Backend 6039463e855SJeremy L Thompson **/ 6049463e855SJeremy L Thompson int CeedOperatorHasTensorBases(CeedOperator op, bool *has_tensor_bases) { 6059463e855SJeremy L Thompson CeedInt num_inputs, num_outputs; 6069463e855SJeremy L Thompson CeedOperatorField *input_fields, *output_fields; 6079463e855SJeremy L Thompson 6089463e855SJeremy L Thompson CeedCall(CeedOperatorGetFields(op, &num_inputs, &input_fields, &num_outputs, &output_fields)); 6099463e855SJeremy L Thompson *has_tensor_bases = true; 6109463e855SJeremy L Thompson for (CeedInt i = 0; i < num_inputs; i++) { 6119463e855SJeremy L Thompson bool is_tensor; 6129463e855SJeremy L Thompson CeedBasis basis; 6139463e855SJeremy L Thompson 6149463e855SJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(input_fields[i], &basis)); 6159463e855SJeremy L Thompson if (basis != CEED_BASIS_NONE) { 6169463e855SJeremy L Thompson CeedCall(CeedBasisIsTensor(basis, &is_tensor)); 617025ec10cSJeremy L Thompson *has_tensor_bases = *has_tensor_bases & is_tensor; 6189463e855SJeremy L Thompson } 619681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 6209463e855SJeremy L Thompson } 6219463e855SJeremy L Thompson for (CeedInt i = 0; i < num_outputs; i++) { 6229463e855SJeremy L Thompson bool is_tensor; 6239463e855SJeremy L Thompson CeedBasis basis; 6249463e855SJeremy L Thompson 6259463e855SJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(output_fields[i], &basis)); 6269463e855SJeremy L Thompson if (basis != CEED_BASIS_NONE) { 6279463e855SJeremy L Thompson CeedCall(CeedBasisIsTensor(basis, &is_tensor)); 628025ec10cSJeremy L Thompson *has_tensor_bases = *has_tensor_bases & is_tensor; 6299463e855SJeremy L Thompson } 630681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 6319463e855SJeremy L Thompson } 6329463e855SJeremy L Thompson return CEED_ERROR_SUCCESS; 6339463e855SJeremy L Thompson } 6349463e855SJeremy L Thompson 6359463e855SJeremy L Thompson /** 6361203703bSJeremy L Thompson @brief Get a boolean value indicating if the `CeedOperator` is immutable 6371203703bSJeremy L Thompson 6381203703bSJeremy L Thompson @param[in] op `CeedOperator` 6391203703bSJeremy L Thompson @param[out] is_immutable Variable to store immutability status 6401203703bSJeremy L Thompson 6411203703bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 6421203703bSJeremy L Thompson 6431203703bSJeremy L Thompson @ref Backend 6441203703bSJeremy L Thompson **/ 6451203703bSJeremy L Thompson int CeedOperatorIsImmutable(CeedOperator op, bool *is_immutable) { 6461203703bSJeremy L Thompson *is_immutable = op->is_immutable; 6471203703bSJeremy L Thompson return CEED_ERROR_SUCCESS; 6481203703bSJeremy L Thompson } 6491203703bSJeremy L Thompson 6501203703bSJeremy L Thompson /** 651ca94c3ddSJeremy L Thompson @brief Get the setup status of a `CeedOperator` 6527a982d89SJeremy L. Thompson 653ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 654d1d35e2fSjeremylt @param[out] is_setup_done Variable to store setup status 6557a982d89SJeremy L. Thompson 6567a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6577a982d89SJeremy L. Thompson 6587a982d89SJeremy L. Thompson @ref Backend 6597a982d89SJeremy L. Thompson **/ 660d1d35e2fSjeremylt int CeedOperatorIsSetupDone(CeedOperator op, bool *is_setup_done) { 661f04ea552SJeremy L Thompson *is_setup_done = op->is_backend_setup; 662e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6637a982d89SJeremy L. Thompson } 6647a982d89SJeremy L. Thompson 6657a982d89SJeremy L. Thompson /** 666ca94c3ddSJeremy L Thompson @brief Get the `CeedQFunction` associated with a `CeedOperator` 6677a982d89SJeremy L. Thompson 668ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 669ca94c3ddSJeremy L Thompson @param[out] qf Variable to store `CeedQFunction` 6707a982d89SJeremy L. Thompson 6717a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6727a982d89SJeremy L. Thompson 6737a982d89SJeremy L. Thompson @ref Backend 6747a982d89SJeremy L. Thompson **/ 6757a982d89SJeremy L. Thompson int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 6761203703bSJeremy L Thompson bool is_composite; 6771203703bSJeremy L Thompson 6781203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 6796e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Not defined for composite operator"); 680c11e12f4SJeremy L Thompson *qf = NULL; 681c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionReferenceCopy(op->qf, qf)); 682e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6837a982d89SJeremy L. Thompson } 6847a982d89SJeremy L. Thompson 6857a982d89SJeremy L. Thompson /** 686ca94c3ddSJeremy L Thompson @brief Get a boolean value indicating if the `CeedOperator` is composite 687c04a41a7SJeremy L Thompson 688ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 689d1d35e2fSjeremylt @param[out] is_composite Variable to store composite status 690c04a41a7SJeremy L Thompson 691c04a41a7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 692c04a41a7SJeremy L Thompson 693c04a41a7SJeremy L Thompson @ref Backend 694c04a41a7SJeremy L Thompson **/ 695d1d35e2fSjeremylt int CeedOperatorIsComposite(CeedOperator op, bool *is_composite) { 696f04ea552SJeremy L Thompson *is_composite = op->is_composite; 697e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 698c04a41a7SJeremy L Thompson } 699c04a41a7SJeremy L Thompson 700c04a41a7SJeremy L Thompson /** 701ca94c3ddSJeremy L Thompson @brief Get the backend data of a `CeedOperator` 7027a982d89SJeremy L. Thompson 703ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 7047a982d89SJeremy L. Thompson @param[out] data Variable to store data 7057a982d89SJeremy L. Thompson 7067a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 7077a982d89SJeremy L. Thompson 7087a982d89SJeremy L. Thompson @ref Backend 7097a982d89SJeremy L. Thompson **/ 710777ff853SJeremy L Thompson int CeedOperatorGetData(CeedOperator op, void *data) { 711777ff853SJeremy L Thompson *(void **)data = op->data; 712e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7137a982d89SJeremy L. Thompson } 7147a982d89SJeremy L. Thompson 7157a982d89SJeremy L. Thompson /** 716ca94c3ddSJeremy L Thompson @brief Set the backend data of a `CeedOperator` 7177a982d89SJeremy L. Thompson 718ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 719ea61e9acSJeremy L Thompson @param[in] data Data to set 7207a982d89SJeremy L. Thompson 7217a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 7227a982d89SJeremy L. Thompson 7237a982d89SJeremy L. Thompson @ref Backend 7247a982d89SJeremy L. Thompson **/ 725777ff853SJeremy L Thompson int CeedOperatorSetData(CeedOperator op, void *data) { 726777ff853SJeremy L Thompson op->data = data; 727e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7287a982d89SJeremy L. Thompson } 7297a982d89SJeremy L. Thompson 7307a982d89SJeremy L. Thompson /** 731ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `CeedOperator` 73234359f16Sjeremylt 733ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` to increment the reference counter 73434359f16Sjeremylt 73534359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 73634359f16Sjeremylt 73734359f16Sjeremylt @ref Backend 73834359f16Sjeremylt **/ 7399560d06aSjeremylt int CeedOperatorReference(CeedOperator op) { 740b0f67a9cSJeremy L Thompson CeedCall(CeedObjectReference((CeedObject)op)); 74134359f16Sjeremylt return CEED_ERROR_SUCCESS; 74234359f16Sjeremylt } 74334359f16Sjeremylt 74434359f16Sjeremylt /** 745ca94c3ddSJeremy L Thompson @brief Set the setup flag of a `CeedOperator` to `true` 7467a982d89SJeremy L. Thompson 747ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 7487a982d89SJeremy L. Thompson 7497a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 7507a982d89SJeremy L. Thompson 7517a982d89SJeremy L. Thompson @ref Backend 7527a982d89SJeremy L. Thompson **/ 7537a982d89SJeremy L. Thompson int CeedOperatorSetSetupDone(CeedOperator op) { 754f04ea552SJeremy L Thompson op->is_backend_setup = true; 755e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7567a982d89SJeremy L. Thompson } 7577a982d89SJeremy L. Thompson 7587a982d89SJeremy L. Thompson /// @} 7597a982d89SJeremy L. Thompson 7607a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 7617a982d89SJeremy L. Thompson /// CeedOperator Public API 7627a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 7637a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorUser 764dfdf5a53Sjeremylt /// @{ 765d7b241e6Sjeremylt 766d7b241e6Sjeremylt /** 767ca94c3ddSJeremy L Thompson @brief Create a `CeedOperator` and associate a `CeedQFunction`. 7684385fb7fSSebastian Grimberg 769ca94c3ddSJeremy L Thompson A `CeedBasis` and `CeedElemRestriction` can be associated with `CeedQFunction` fields with @ref CeedOperatorSetField(). 770d7b241e6Sjeremylt 771ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedOperator` 772ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` defining the action of the operator at quadrature points 773ca94c3ddSJeremy L Thompson @param[in] dqf `CeedQFunction` defining the action of the Jacobian of `qf` (or @ref CEED_QFUNCTION_NONE) 774ca94c3ddSJeremy L Thompson @param[in] dqfT `CeedQFunction` defining the action of the transpose of the Jacobian of `qf` (or @ref CEED_QFUNCTION_NONE) 775ca94c3ddSJeremy L Thompson @param[out] op Address of the variable where the newly created `CeedOperator` will be stored 776b11c1e72Sjeremylt 777b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 778dfdf5a53Sjeremylt 7797a982d89SJeremy L. Thompson @ref User 780d7b241e6Sjeremylt */ 7812b730f8bSJeremy L Thompson int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, CeedQFunction dqfT, CeedOperator *op) { 7825fe0d4faSjeremylt if (!ceed->OperatorCreate) { 7835fe0d4faSjeremylt Ceed delegate; 7846574a04fSJeremy L Thompson 7852b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Operator")); 7861ef3a2a9SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedOperatorCreate"); 7872b730f8bSJeremy L Thompson CeedCall(CeedOperatorCreate(delegate, qf, dqf, dqfT, op)); 7889bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 789e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7905fe0d4faSjeremylt } 7915fe0d4faSjeremylt 792ca94c3ddSJeremy L Thompson CeedCheck(qf && qf != CEED_QFUNCTION_NONE, ceed, CEED_ERROR_MINOR, "Operator must have a valid CeedQFunction."); 793db002c03SJeremy L Thompson 7942b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, op)); 795*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedOperatorView_Object, CeedOperatorDestroy_Object, &(*op)->obj)); 7962b104005SJeremy L Thompson (*op)->input_size = -1; 7972b104005SJeremy L Thompson (*op)->output_size = -1; 798db002c03SJeremy L Thompson CeedCall(CeedQFunctionReferenceCopy(qf, &(*op)->qf)); 799db002c03SJeremy L Thompson if (dqf && dqf != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionReferenceCopy(dqf, &(*op)->dqf)); 800db002c03SJeremy L Thompson if (dqfT && dqfT != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionReferenceCopy(dqfT, &(*op)->dqfT)); 8012b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*op)->input_fields)); 8022b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*op)->output_fields)); 8032b730f8bSJeremy L Thompson CeedCall(ceed->OperatorCreate(*op)); 804e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 805d7b241e6Sjeremylt } 806d7b241e6Sjeremylt 807d7b241e6Sjeremylt /** 808ca94c3ddSJeremy L Thompson @brief Create a `CeedOperator` for evaluation at evaluation at arbitrary points in each element. 80948acf710SJeremy L Thompson 810ca94c3ddSJeremy L Thompson A `CeedBasis` and `CeedElemRestriction` can be associated with `CeedQFunction` fields with `CeedOperator` SetField. 811ca94c3ddSJeremy L Thompson The locations of each point are set with @ref CeedOperatorAtPointsSetPoints(). 81248acf710SJeremy L Thompson 813ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedOperator` 814ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` defining the action of the operator at quadrature points 815ca94c3ddSJeremy L Thompson @param[in] dqf `CeedQFunction` defining the action of the Jacobian of @a qf (or @ref CEED_QFUNCTION_NONE) 816ca94c3ddSJeremy L Thompson @param[in] dqfT `CeedQFunction` defining the action of the transpose of the Jacobian of @a qf (or @ref CEED_QFUNCTION_NONE) 81748acf710SJeremy L Thompson @param[out] op Address of the variable where the newly created CeedOperator will be stored 81848acf710SJeremy L Thompson 81948acf710SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 82048acf710SJeremy L Thompson 82148acf710SJeremy L Thompson @ref User 82248acf710SJeremy L Thompson */ 82348acf710SJeremy L Thompson int CeedOperatorCreateAtPoints(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, CeedQFunction dqfT, CeedOperator *op) { 82448acf710SJeremy L Thompson if (!ceed->OperatorCreateAtPoints) { 82548acf710SJeremy L Thompson Ceed delegate; 82648acf710SJeremy L Thompson 82748acf710SJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Operator")); 8281ef3a2a9SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedOperatorCreateAtPoints"); 82948acf710SJeremy L Thompson CeedCall(CeedOperatorCreateAtPoints(delegate, qf, dqf, dqfT, op)); 8309bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 83148acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 83248acf710SJeremy L Thompson } 83348acf710SJeremy L Thompson 834ca94c3ddSJeremy L Thompson CeedCheck(qf && qf != CEED_QFUNCTION_NONE, ceed, CEED_ERROR_MINOR, "Operator must have a valid CeedQFunction."); 83548acf710SJeremy L Thompson 83648acf710SJeremy L Thompson CeedCall(CeedCalloc(1, op)); 837*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedOperatorView_Object, CeedOperatorDestroy_Object, &(*op)->obj)); 83848acf710SJeremy L Thompson (*op)->is_at_points = true; 83948acf710SJeremy L Thompson (*op)->input_size = -1; 84048acf710SJeremy L Thompson (*op)->output_size = -1; 84148acf710SJeremy L Thompson CeedCall(CeedQFunctionReferenceCopy(qf, &(*op)->qf)); 84248acf710SJeremy L Thompson if (dqf && dqf != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionReferenceCopy(dqf, &(*op)->dqf)); 84348acf710SJeremy L Thompson if (dqfT && dqfT != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionReferenceCopy(dqfT, &(*op)->dqfT)); 84448acf710SJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*op)->input_fields)); 84548acf710SJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*op)->output_fields)); 84648acf710SJeremy L Thompson CeedCall(ceed->OperatorCreateAtPoints(*op)); 84748acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 84848acf710SJeremy L Thompson } 84948acf710SJeremy L Thompson 85048acf710SJeremy L Thompson /** 851ca94c3ddSJeremy L Thompson @brief Create a composite `CeedOperator` that composes the action of several `CeedOperator` 85252d6035fSJeremy L Thompson 853ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedOperator` 854ca94c3ddSJeremy L Thompson @param[out] op Address of the variable where the newly created composite `CeedOperator` will be stored 85552d6035fSJeremy L Thompson 85652d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 85752d6035fSJeremy L Thompson 8587a982d89SJeremy L. Thompson @ref User 85952d6035fSJeremy L Thompson */ 860ed094490SJeremy L Thompson int CeedOperatorCreateComposite(Ceed ceed, CeedOperator *op) { 86152d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 86252d6035fSJeremy L Thompson Ceed delegate; 86352d6035fSJeremy L Thompson 8641c66c397SJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Operator")); 865250756a7Sjeremylt if (delegate) { 866ed094490SJeremy L Thompson CeedCall(CeedOperatorCreateComposite(delegate, op)); 8679bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 868e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 86952d6035fSJeremy L Thompson } 870250756a7Sjeremylt } 87152d6035fSJeremy L Thompson 8722b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, op)); 873*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedOperatorView_Object, CeedOperatorDestroy_Object, &(*op)->obj)); 874f04ea552SJeremy L Thompson (*op)->is_composite = true; 8752b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_COMPOSITE_MAX, &(*op)->sub_operators)); 8762b104005SJeremy L Thompson (*op)->input_size = -1; 8772b104005SJeremy L Thompson (*op)->output_size = -1; 878250756a7Sjeremylt 879db002c03SJeremy L Thompson if (ceed->CompositeOperatorCreate) CeedCall(ceed->CompositeOperatorCreate(*op)); 880e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 88152d6035fSJeremy L Thompson } 88252d6035fSJeremy L Thompson 88352d6035fSJeremy L Thompson /** 884ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedOperator`. 8854385fb7fSSebastian Grimberg 886ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedOperatorDestroy(). 887512bb800SJeremy L Thompson 888ca94c3ddSJeremy L Thompson Note: If the value of `*op_copy` passed to this function is non-`NULL`, then it is assumed that `*op_copy` is a pointer to a `CeedOperator`. 889ca94c3ddSJeremy L Thompson This `CeedOperator` will be destroyed if `*op_copy` is the only reference to this `CeedOperator`. 8909560d06aSjeremylt 891ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to copy reference to 892ea61e9acSJeremy L Thompson @param[in,out] op_copy Variable to store copied reference 8939560d06aSjeremylt 8949560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 8959560d06aSjeremylt 8969560d06aSjeremylt @ref User 8979560d06aSjeremylt **/ 8989560d06aSjeremylt int CeedOperatorReferenceCopy(CeedOperator op, CeedOperator *op_copy) { 8992b730f8bSJeremy L Thompson CeedCall(CeedOperatorReference(op)); 9002b730f8bSJeremy L Thompson CeedCall(CeedOperatorDestroy(op_copy)); 9019560d06aSjeremylt *op_copy = op; 9029560d06aSjeremylt return CEED_ERROR_SUCCESS; 9039560d06aSjeremylt } 9049560d06aSjeremylt 9059560d06aSjeremylt /** 906ca94c3ddSJeremy L Thompson @brief Provide a field to a `CeedOperator` for use by its `CeedQFunction`. 907d7b241e6Sjeremylt 908ca94c3ddSJeremy L Thompson This function is used to specify both active and passive fields to a `CeedOperator`. 909bafebce1SSebastian Grimberg For passive fields, a `CeedVector` `vec` must be provided. 910ea61e9acSJeremy L Thompson Passive fields can inputs or outputs (updated in-place when operator is applied). 911d7b241e6Sjeremylt 912ca94c3ddSJeremy L Thompson Active fields must be specified using this function, but their data (in a `CeedVector`) is passed in @ref CeedOperatorApply(). 913ca94c3ddSJeremy L Thompson There can be at most one active input `CeedVector` and at most one active output@ref CeedVector passed to @ref CeedOperatorApply(). 914d7b241e6Sjeremylt 915528a22edSJeremy L Thompson The number of quadrature points must agree across all points. 916bafebce1SSebastian Grimberg When using @ref CEED_BASIS_NONE, the number of quadrature points is determined by the element size of `rstr`. 917528a22edSJeremy L Thompson 918ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` on which to provide the field 919ca94c3ddSJeremy L Thompson @param[in] field_name Name of the field (to be matched with the name used by `CeedQFunction`) 920bafebce1SSebastian Grimberg @param[in] rstr `CeedElemRestriction` 921bafebce1SSebastian Grimberg @param[in] basis `CeedBasis` in which the field resides or @ref CEED_BASIS_NONE if collocated with quadrature points 922bafebce1SSebastian Grimberg @param[in] vec `CeedVector` to be used by CeedOperator or @ref CEED_VECTOR_ACTIVE if field is active or @ref CEED_VECTOR_NONE if using @ref CEED_EVAL_WEIGHT in the `CeedQFunction` 923b11c1e72Sjeremylt 924b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 925dfdf5a53Sjeremylt 9267a982d89SJeremy L. Thompson @ref User 927b11c1e72Sjeremylt **/ 928bafebce1SSebastian Grimberg int CeedOperatorSetField(CeedOperator op, const char *field_name, CeedElemRestriction rstr, CeedBasis basis, CeedVector vec) { 9291203703bSJeremy L Thompson bool is_input = true, is_at_points, is_composite, is_immutable; 9301203703bSJeremy L Thompson CeedInt num_elem = 0, num_qpts = 0, num_input_fields, num_output_fields; 9311203703bSJeremy L Thompson CeedQFunction qf; 9321203703bSJeremy L Thompson CeedQFunctionField qf_field, *qf_input_fields, *qf_output_fields; 9331c66c397SJeremy L Thompson CeedOperatorField *op_field; 9341c66c397SJeremy L Thompson 9351203703bSJeremy L Thompson CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 9361203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 9371203703bSJeremy L Thompson CeedCall(CeedOperatorIsImmutable(op, &is_immutable)); 9389bc66399SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "Cannot add field to composite operator."); 9399bc66399SJeremy L Thompson CeedCheck(!is_immutable, CeedOperatorReturnCeed(op), CEED_ERROR_MAJOR, "Operator cannot be changed after set as immutable"); 9409bc66399SJeremy L Thompson CeedCheck(rstr, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "CeedElemRestriction rstr for field \"%s\" must be non-NULL.", field_name); 9419bc66399SJeremy L Thompson CeedCheck(basis, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "CeedBasis basis for field \"%s\" must be non-NULL.", field_name); 9429bc66399SJeremy L Thompson CeedCheck(vec, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "CeedVector vec for field \"%s\" must be non-NULL.", field_name); 94352d6035fSJeremy L Thompson 944bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 9459bc66399SJeremy L Thompson CeedCheck(rstr == CEED_ELEMRESTRICTION_NONE || !op->has_restriction || num_elem == op->num_elem, CeedOperatorReturnCeed(op), CEED_ERROR_DIMENSION, 946ca94c3ddSJeremy L Thompson "CeedElemRestriction with %" CeedInt_FMT " elements incompatible with prior %" CeedInt_FMT " elements", num_elem, op->num_elem); 9472c7e7413SJeremy L Thompson { 9482c7e7413SJeremy L Thompson CeedRestrictionType rstr_type; 9492c7e7413SJeremy L Thompson 950bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 95148acf710SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) { 9529bc66399SJeremy L Thompson CeedCheck(is_at_points, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, 9539bc66399SJeremy L Thompson "CeedElemRestriction AtPoints not supported for standard operator fields"); 9549bc66399SJeremy L Thompson CeedCheck(basis == CEED_BASIS_NONE, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, 9559bc66399SJeremy L Thompson "CeedElemRestriction AtPoints must be used with CEED_BASIS_NONE"); 95648acf710SJeremy L Thompson if (!op->first_points_rstr) { 957bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &op->first_points_rstr)); 95848acf710SJeremy L Thompson } else { 95948acf710SJeremy L Thompson bool are_compatible; 96048acf710SJeremy L Thompson 961bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionAtPointsAreCompatible(op->first_points_rstr, rstr, &are_compatible)); 9629bc66399SJeremy L Thompson CeedCheck(are_compatible, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 963ca94c3ddSJeremy L Thompson "CeedElemRestriction must have compatible offsets with previously set CeedElemRestriction"); 96448acf710SJeremy L Thompson } 96548acf710SJeremy L Thompson } 9662c7e7413SJeremy L Thompson } 967d7b241e6Sjeremylt 968bafebce1SSebastian Grimberg if (basis == CEED_BASIS_NONE) CeedCall(CeedElemRestrictionGetElementSize(rstr, &num_qpts)); 969bafebce1SSebastian Grimberg else CeedCall(CeedBasisGetNumQuadraturePoints(basis, &num_qpts)); 9709bc66399SJeremy L Thompson CeedCheck(op->num_qpts == 0 || num_qpts == op->num_qpts, CeedOperatorReturnCeed(op), CEED_ERROR_DIMENSION, 971ca94c3ddSJeremy L Thompson "%s must correspond to the same number of quadrature points as previously added CeedBases. Found %" CeedInt_FMT 972528a22edSJeremy L Thompson " quadrature points but expected %" CeedInt_FMT " quadrature points.", 973bafebce1SSebastian Grimberg basis == CEED_BASIS_NONE ? "CeedElemRestriction" : "CeedBasis", num_qpts, op->num_qpts); 9741203703bSJeremy L Thompson 9751203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 9761203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFields(qf, &num_input_fields, &qf_input_fields, &num_output_fields, &qf_output_fields)); 977c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 9781203703bSJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 9796f8994e9SJeremy L Thompson const char *qf_field_name; 9801203703bSJeremy L Thompson 9811203703bSJeremy L Thompson CeedCall(CeedQFunctionFieldGetName(qf_input_fields[i], &qf_field_name)); 9821203703bSJeremy L Thompson if (!strcmp(field_name, qf_field_name)) { 9831203703bSJeremy L Thompson qf_field = qf_input_fields[i]; 984d1d35e2fSjeremylt op_field = &op->input_fields[i]; 985d7b241e6Sjeremylt goto found; 986d7b241e6Sjeremylt } 987d7b241e6Sjeremylt } 9882b104005SJeremy L Thompson is_input = false; 9891203703bSJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 9906f8994e9SJeremy L Thompson const char *qf_field_name; 9911203703bSJeremy L Thompson 9921203703bSJeremy L Thompson CeedCall(CeedQFunctionFieldGetName(qf_output_fields[i], &qf_field_name)); 9931203703bSJeremy L Thompson if (!strcmp(field_name, qf_field_name)) { 9941203703bSJeremy L Thompson qf_field = qf_output_fields[i]; 995d1d35e2fSjeremylt op_field = &op->output_fields[i]; 996d7b241e6Sjeremylt goto found; 997d7b241e6Sjeremylt } 998d7b241e6Sjeremylt } 999c042f62fSJeremy L Thompson // LCOV_EXCL_START 10009bc66399SJeremy L Thompson return CeedError(CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "CeedQFunction has no knowledge of field '%s'", field_name); 1001c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1002d7b241e6Sjeremylt found: 10039bc66399SJeremy L Thompson CeedCall(CeedOperatorCheckField(CeedOperatorReturnCeed(op), qf_field, rstr, basis)); 10042b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, op_field)); 1005e15f9bd0SJeremy L Thompson 1006bafebce1SSebastian Grimberg if (vec == CEED_VECTOR_ACTIVE) { 10072b104005SJeremy L Thompson CeedSize l_size; 10081c66c397SJeremy L Thompson 1009bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &l_size)); 10102b104005SJeremy L Thompson if (is_input) { 10112b104005SJeremy L Thompson if (op->input_size == -1) op->input_size = l_size; 10129bc66399SJeremy L Thompson CeedCheck(l_size == op->input_size, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 1013249f8407SJeremy L Thompson "LVector size %" CeedSize_FMT " does not match previous size %" CeedSize_FMT "", l_size, op->input_size); 10142b104005SJeremy L Thompson } else { 10152b104005SJeremy L Thompson if (op->output_size == -1) op->output_size = l_size; 10169bc66399SJeremy L Thompson CeedCheck(l_size == op->output_size, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 1017249f8407SJeremy L Thompson "LVector size %" CeedSize_FMT " does not match previous size %" CeedSize_FMT "", l_size, op->output_size); 10182b104005SJeremy L Thompson } 10192b730f8bSJeremy L Thompson } 10202b104005SJeremy L Thompson 1021bafebce1SSebastian Grimberg CeedCall(CeedVectorReferenceCopy(vec, &(*op_field)->vec)); 1022bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*op_field)->elem_rstr)); 1023bafebce1SSebastian Grimberg if (rstr != CEED_ELEMRESTRICTION_NONE && !op->has_restriction) { 1024d1d35e2fSjeremylt op->num_elem = num_elem; 1025d1d35e2fSjeremylt op->has_restriction = true; // Restriction set, but num_elem may be 0 1026e15f9bd0SJeremy L Thompson } 1027bafebce1SSebastian Grimberg CeedCall(CeedBasisReferenceCopy(basis, &(*op_field)->basis)); 10282a3ff1c9SZach Atkins if (op->num_qpts == 0 && !is_at_points) op->num_qpts = num_qpts; // no consistent number of qpts for OperatorAtPoints 1029d1d35e2fSjeremylt op->num_fields += 1; 10302b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(field_name, (char **)&(*op_field)->field_name)); 1031e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1032d7b241e6Sjeremylt } 1033d7b241e6Sjeremylt 1034d7b241e6Sjeremylt /** 1035ca94c3ddSJeremy L Thompson @brief Get the `CeedOperator` Field of a `CeedOperator`. 103643bbe138SJeremy L Thompson 1037ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 1038f04ea552SJeremy L Thompson 1039ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1040f74ec584SJeremy L Thompson @param[out] num_input_fields Variable to store number of input fields 1041ca94c3ddSJeremy L Thompson @param[out] input_fields Variable to store input fields 1042f74ec584SJeremy L Thompson @param[out] num_output_fields Variable to store number of output fields 1043ca94c3ddSJeremy L Thompson @param[out] output_fields Variable to store output fields 104443bbe138SJeremy L Thompson 104543bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 104643bbe138SJeremy L Thompson 1047e9b533fbSJeremy L Thompson @ref Advanced 104843bbe138SJeremy L Thompson **/ 10492b730f8bSJeremy L Thompson int CeedOperatorGetFields(CeedOperator op, CeedInt *num_input_fields, CeedOperatorField **input_fields, CeedInt *num_output_fields, 105043bbe138SJeremy L Thompson CeedOperatorField **output_fields) { 10511203703bSJeremy L Thompson bool is_composite; 10521203703bSJeremy L Thompson CeedQFunction qf; 10531203703bSJeremy L Thompson 10541203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 10556e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Not defined for composite operator"); 10562b730f8bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 105743bbe138SJeremy L Thompson 10581203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 10591203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFields(qf, num_input_fields, NULL, num_output_fields, NULL)); 1060c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 106143bbe138SJeremy L Thompson if (input_fields) *input_fields = op->input_fields; 106243bbe138SJeremy L Thompson if (output_fields) *output_fields = op->output_fields; 106343bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 106443bbe138SJeremy L Thompson } 106543bbe138SJeremy L Thompson 106643bbe138SJeremy L Thompson /** 1067ca94c3ddSJeremy L Thompson @brief Set the arbitrary points in each element for a `CeedOperator` at points. 106848acf710SJeremy L Thompson 1069ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 107048acf710SJeremy L Thompson 1071ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` at points 1072ca94c3ddSJeremy L Thompson @param[in] rstr_points `CeedElemRestriction` for the coordinates of each point by element 1073ca94c3ddSJeremy L Thompson @param[in] point_coords `CeedVector` holding coordinates of each point 107448acf710SJeremy L Thompson 107548acf710SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 107648acf710SJeremy L Thompson 107748acf710SJeremy L Thompson @ref Advanced 107848acf710SJeremy L Thompson **/ 107948acf710SJeremy L Thompson int CeedOperatorAtPointsSetPoints(CeedOperator op, CeedElemRestriction rstr_points, CeedVector point_coords) { 10801203703bSJeremy L Thompson bool is_at_points, is_immutable; 10812a3ff1c9SZach Atkins 10822a3ff1c9SZach Atkins CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 10831203703bSJeremy L Thompson CeedCall(CeedOperatorIsImmutable(op, &is_immutable)); 10849bc66399SJeremy L Thompson CeedCheck(is_at_points, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for operator at points"); 10859bc66399SJeremy L Thompson CeedCheck(!is_immutable, CeedOperatorReturnCeed(op), CEED_ERROR_MAJOR, "Operator cannot be changed after set as immutable"); 108648acf710SJeremy L Thompson 108748acf710SJeremy L Thompson if (!op->first_points_rstr) { 108848acf710SJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(rstr_points, &op->first_points_rstr)); 108948acf710SJeremy L Thompson } else { 109048acf710SJeremy L Thompson bool are_compatible; 109148acf710SJeremy L Thompson 109248acf710SJeremy L Thompson CeedCall(CeedElemRestrictionAtPointsAreCompatible(op->first_points_rstr, rstr_points, &are_compatible)); 10939bc66399SJeremy L Thompson CeedCheck(are_compatible, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 1094ca94c3ddSJeremy L Thompson "CeedElemRestriction must have compatible offsets with previously set field CeedElemRestriction"); 109548acf710SJeremy L Thompson } 109648acf710SJeremy L Thompson 109748acf710SJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(rstr_points, &op->rstr_points)); 109848acf710SJeremy L Thompson CeedCall(CeedVectorReferenceCopy(point_coords, &op->point_coords)); 109948acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 110048acf710SJeremy L Thompson } 110148acf710SJeremy L Thompson 110248acf710SJeremy L Thompson /** 1103b594f9faSZach Atkins @brief Get a boolean value indicating if the `CeedOperator` was created with `CeedOperatorCreateAtPoints` 1104b594f9faSZach Atkins 1105b594f9faSZach Atkins @param[in] op `CeedOperator` 1106b594f9faSZach Atkins @param[out] is_at_points Variable to store at points status 1107b594f9faSZach Atkins 1108b594f9faSZach Atkins @return An error code: 0 - success, otherwise - failure 1109b594f9faSZach Atkins 1110b594f9faSZach Atkins @ref User 1111b594f9faSZach Atkins **/ 1112b594f9faSZach Atkins int CeedOperatorIsAtPoints(CeedOperator op, bool *is_at_points) { 1113b594f9faSZach Atkins *is_at_points = op->is_at_points; 1114b594f9faSZach Atkins return CEED_ERROR_SUCCESS; 1115b594f9faSZach Atkins } 1116b594f9faSZach Atkins 1117b594f9faSZach Atkins /** 1118ca94c3ddSJeremy L Thompson @brief Get the arbitrary points in each element for a `CeedOperator` at points. 111948acf710SJeremy L Thompson 1120ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 112148acf710SJeremy L Thompson 1122ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` at points 1123ca94c3ddSJeremy L Thompson @param[out] rstr_points Variable to hold `CeedElemRestriction` for the coordinates of each point by element 1124ca94c3ddSJeremy L Thompson @param[out] point_coords Variable to hold `CeedVector` holding coordinates of each point 112548acf710SJeremy L Thompson 112648acf710SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 112748acf710SJeremy L Thompson 112848acf710SJeremy L Thompson @ref Advanced 112948acf710SJeremy L Thompson **/ 113048acf710SJeremy L Thompson int CeedOperatorAtPointsGetPoints(CeedOperator op, CeedElemRestriction *rstr_points, CeedVector *point_coords) { 11312a3ff1c9SZach Atkins bool is_at_points; 11322a3ff1c9SZach Atkins 11332a3ff1c9SZach Atkins CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 11346e536b99SJeremy L Thompson CeedCheck(is_at_points, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for operator at points"); 113548acf710SJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 113648acf710SJeremy L Thompson 11373f919cbcSJeremy L Thompson if (rstr_points) { 11383f919cbcSJeremy L Thompson *rstr_points = NULL; 11393f919cbcSJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(op->rstr_points, rstr_points)); 11403f919cbcSJeremy L Thompson } 11413f919cbcSJeremy L Thompson if (point_coords) { 11423f919cbcSJeremy L Thompson *point_coords = NULL; 11433f919cbcSJeremy L Thompson CeedCall(CeedVectorReferenceCopy(op->point_coords, point_coords)); 11443f919cbcSJeremy L Thompson } 114548acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 114648acf710SJeremy L Thompson } 114748acf710SJeremy L Thompson 114848acf710SJeremy L Thompson /** 1149be9c6463SJeremy L Thompson @brief Get a `CeedOperator` Field of a `CeedOperator` from its name. 1150be9c6463SJeremy L Thompson 1151be9c6463SJeremy L Thompson `op_field` is set to `NULL` if the field is not found. 1152de5900adSJames Wright 1153ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 1154de5900adSJames Wright 1155ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1156ca94c3ddSJeremy L Thompson @param[in] field_name Name of desired `CeedOperator` Field 1157ca94c3ddSJeremy L Thompson @param[out] op_field `CeedOperator` Field corresponding to the name 1158de5900adSJames Wright 1159de5900adSJames Wright @return An error code: 0 - success, otherwise - failure 1160de5900adSJames Wright 1161de5900adSJames Wright @ref Advanced 1162de5900adSJames Wright **/ 1163de5900adSJames Wright int CeedOperatorGetFieldByName(CeedOperator op, const char *field_name, CeedOperatorField *op_field) { 11646f8994e9SJeremy L Thompson const char *name; 1165de5900adSJames Wright CeedInt num_input_fields, num_output_fields; 1166de5900adSJames Wright CeedOperatorField *input_fields, *output_fields; 1167de5900adSJames Wright 1168be9c6463SJeremy L Thompson *op_field = NULL; 11691c66c397SJeremy L Thompson CeedCall(CeedOperatorGetFields(op, &num_input_fields, &input_fields, &num_output_fields, &output_fields)); 1170de5900adSJames Wright for (CeedInt i = 0; i < num_input_fields; i++) { 1171de5900adSJames Wright CeedCall(CeedOperatorFieldGetName(input_fields[i], &name)); 1172de5900adSJames Wright if (!strcmp(name, field_name)) { 1173de5900adSJames Wright *op_field = input_fields[i]; 1174de5900adSJames Wright return CEED_ERROR_SUCCESS; 1175de5900adSJames Wright } 1176de5900adSJames Wright } 1177de5900adSJames Wright for (CeedInt i = 0; i < num_output_fields; i++) { 1178de5900adSJames Wright CeedCall(CeedOperatorFieldGetName(output_fields[i], &name)); 1179de5900adSJames Wright if (!strcmp(name, field_name)) { 1180de5900adSJames Wright *op_field = output_fields[i]; 1181de5900adSJames Wright return CEED_ERROR_SUCCESS; 1182de5900adSJames Wright } 1183de5900adSJames Wright } 1184be9c6463SJeremy L Thompson return CEED_ERROR_SUCCESS; 1185de5900adSJames Wright } 1186de5900adSJames Wright 1187de5900adSJames Wright /** 1188ca94c3ddSJeremy L Thompson @brief Get the name of a `CeedOperator` Field 118928567f8fSJeremy L Thompson 1190ca94c3ddSJeremy L Thompson @param[in] op_field `CeedOperator` Field 119128567f8fSJeremy L Thompson @param[out] field_name Variable to store the field name 119228567f8fSJeremy L Thompson 119328567f8fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 119428567f8fSJeremy L Thompson 1195e9b533fbSJeremy L Thompson @ref Advanced 119628567f8fSJeremy L Thompson **/ 11976f8994e9SJeremy L Thompson int CeedOperatorFieldGetName(CeedOperatorField op_field, const char **field_name) { 11986f8994e9SJeremy L Thompson *field_name = op_field->field_name; 119928567f8fSJeremy L Thompson return CEED_ERROR_SUCCESS; 120028567f8fSJeremy L Thompson } 120128567f8fSJeremy L Thompson 120228567f8fSJeremy L Thompson /** 1203681d0ea7SJeremy L Thompson @brief Get the `CeedElemRestriction` of a `CeedOperator` Field. 1204681d0ea7SJeremy L Thompson 1205681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `rstr` with @ref CeedElemRestrictionDestroy(). 120643bbe138SJeremy L Thompson 1207ca94c3ddSJeremy L Thompson @param[in] op_field `CeedOperator` Field 1208ca94c3ddSJeremy L Thompson @param[out] rstr Variable to store `CeedElemRestriction` 120943bbe138SJeremy L Thompson 121043bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 121143bbe138SJeremy L Thompson 1212e9b533fbSJeremy L Thompson @ref Advanced 121343bbe138SJeremy L Thompson **/ 12142b730f8bSJeremy L Thompson int CeedOperatorFieldGetElemRestriction(CeedOperatorField op_field, CeedElemRestriction *rstr) { 1215681d0ea7SJeremy L Thompson *rstr = NULL; 1216681d0ea7SJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(op_field->elem_rstr, rstr)); 121743bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 121843bbe138SJeremy L Thompson } 121943bbe138SJeremy L Thompson 122043bbe138SJeremy L Thompson /** 1221681d0ea7SJeremy L Thompson @brief Get the `CeedBasis` of a `CeedOperator` Field. 1222681d0ea7SJeremy L Thompson 1223681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `basis` with @ref CeedBasisDestroy(). 122443bbe138SJeremy L Thompson 1225ca94c3ddSJeremy L Thompson @param[in] op_field `CeedOperator` Field 1226ca94c3ddSJeremy L Thompson @param[out] basis Variable to store `CeedBasis` 122743bbe138SJeremy L Thompson 122843bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 122943bbe138SJeremy L Thompson 1230e9b533fbSJeremy L Thompson @ref Advanced 123143bbe138SJeremy L Thompson **/ 123243bbe138SJeremy L Thompson int CeedOperatorFieldGetBasis(CeedOperatorField op_field, CeedBasis *basis) { 1233681d0ea7SJeremy L Thompson *basis = NULL; 1234681d0ea7SJeremy L Thompson CeedCall(CeedBasisReferenceCopy(op_field->basis, basis)); 123543bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 123643bbe138SJeremy L Thompson } 123743bbe138SJeremy L Thompson 123843bbe138SJeremy L Thompson /** 1239681d0ea7SJeremy L Thompson @brief Get the `CeedVector` of a `CeedOperator` Field. 1240681d0ea7SJeremy L Thompson 1241681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `vec` with @ref CeedVectorDestroy(). 124243bbe138SJeremy L Thompson 1243ca94c3ddSJeremy L Thompson @param[in] op_field `CeedOperator` Field 1244ca94c3ddSJeremy L Thompson @param[out] vec Variable to store `CeedVector` 124543bbe138SJeremy L Thompson 124643bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 124743bbe138SJeremy L Thompson 1248e9b533fbSJeremy L Thompson @ref Advanced 124943bbe138SJeremy L Thompson **/ 125043bbe138SJeremy L Thompson int CeedOperatorFieldGetVector(CeedOperatorField op_field, CeedVector *vec) { 1251681d0ea7SJeremy L Thompson *vec = NULL; 1252681d0ea7SJeremy L Thompson CeedCall(CeedVectorReferenceCopy(op_field->vec, vec)); 125343bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 125443bbe138SJeremy L Thompson } 125543bbe138SJeremy L Thompson 125643bbe138SJeremy L Thompson /** 1257ab747706SJeremy L Thompson @brief Get the data of a `CeedOperator` Field. 1258ab747706SJeremy L Thompson 1259681d0ea7SJeremy L Thompson Any arguments set as `NULL` are ignored.. 1260681d0ea7SJeremy L Thompson 1261681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `rstr`, `basis`, and `vec`. 1262ab747706SJeremy L Thompson 1263ab747706SJeremy L Thompson @param[in] op_field `CeedOperator` Field 1264ab747706SJeremy L Thompson @param[out] field_name Variable to store the field name 1265ab747706SJeremy L Thompson @param[out] rstr Variable to store `CeedElemRestriction` 1266ab747706SJeremy L Thompson @param[out] basis Variable to store `CeedBasis` 1267ab747706SJeremy L Thompson @param[out] vec Variable to store `CeedVector` 1268ab747706SJeremy L Thompson 1269ab747706SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1270ab747706SJeremy L Thompson 1271ab747706SJeremy L Thompson @ref Advanced 1272ab747706SJeremy L Thompson **/ 12736f8994e9SJeremy L Thompson int CeedOperatorFieldGetData(CeedOperatorField op_field, const char **field_name, CeedElemRestriction *rstr, CeedBasis *basis, CeedVector *vec) { 1274ab747706SJeremy L Thompson if (field_name) CeedCall(CeedOperatorFieldGetName(op_field, field_name)); 1275ab747706SJeremy L Thompson if (rstr) CeedCall(CeedOperatorFieldGetElemRestriction(op_field, rstr)); 1276ab747706SJeremy L Thompson if (basis) CeedCall(CeedOperatorFieldGetBasis(op_field, basis)); 1277ab747706SJeremy L Thompson if (vec) CeedCall(CeedOperatorFieldGetVector(op_field, vec)); 1278ab747706SJeremy L Thompson return CEED_ERROR_SUCCESS; 1279ab747706SJeremy L Thompson } 1280ab747706SJeremy L Thompson 1281ab747706SJeremy L Thompson /** 1282ca94c3ddSJeremy L Thompson @brief Add a sub-operator to a composite `CeedOperator` 1283288c0443SJeremy L Thompson 1284ca94c3ddSJeremy L Thompson @param[in,out] composite_op Composite `CeedOperator` 1285ca94c3ddSJeremy L Thompson @param[in] sub_op Sub-operator `CeedOperator` 128652d6035fSJeremy L Thompson 128752d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 128852d6035fSJeremy L Thompson 12897a982d89SJeremy L. Thompson @ref User 129052d6035fSJeremy L Thompson */ 1291ed094490SJeremy L Thompson int CeedOperatorCompositeAddSub(CeedOperator composite_op, CeedOperator sub_op) { 12921203703bSJeremy L Thompson bool is_immutable; 12931203703bSJeremy L Thompson 12949bc66399SJeremy L Thompson CeedCheck(composite_op->is_composite, CeedOperatorReturnCeed(composite_op), CEED_ERROR_MINOR, "CeedOperator is not a composite operator"); 12959bc66399SJeremy L Thompson CeedCheck(composite_op->num_suboperators < CEED_COMPOSITE_MAX, CeedOperatorReturnCeed(composite_op), CEED_ERROR_UNSUPPORTED, 12969bc66399SJeremy L Thompson "Cannot add additional sub-operators"); 12971203703bSJeremy L Thompson CeedCall(CeedOperatorIsImmutable(composite_op, &is_immutable)); 12989bc66399SJeremy L Thompson CeedCheck(!is_immutable, CeedOperatorReturnCeed(composite_op), CEED_ERROR_MAJOR, "Operator cannot be changed after set as immutable"); 12992b730f8bSJeremy L Thompson 13002b730f8bSJeremy L Thompson { 13012b730f8bSJeremy L Thompson CeedSize input_size, output_size; 13021c66c397SJeremy L Thompson 13032b730f8bSJeremy L Thompson CeedCall(CeedOperatorGetActiveVectorLengths(sub_op, &input_size, &output_size)); 13042b730f8bSJeremy L Thompson if (composite_op->input_size == -1) composite_op->input_size = input_size; 13052b730f8bSJeremy L Thompson if (composite_op->output_size == -1) composite_op->output_size = output_size; 13062b730f8bSJeremy L Thompson // Note, a size of -1 means no active vector restriction set, so no incompatibility 13079bc66399SJeremy L Thompson CeedCheck((input_size == -1 || input_size == composite_op->input_size) && (output_size == -1 || output_size == composite_op->output_size), 13089bc66399SJeremy L Thompson CeedOperatorReturnCeed(composite_op), CEED_ERROR_MAJOR, 1309249f8407SJeremy L Thompson "Sub-operators must have compatible dimensions; composite operator of shape (%" CeedSize_FMT ", %" CeedSize_FMT 1310249f8407SJeremy L Thompson ") not compatible with sub-operator of " 1311249f8407SJeremy L Thompson "shape (%" CeedSize_FMT ", %" CeedSize_FMT ")", 13122b730f8bSJeremy L Thompson composite_op->input_size, composite_op->output_size, input_size, output_size); 13132b730f8bSJeremy L Thompson } 13142b730f8bSJeremy L Thompson 1315d1d35e2fSjeremylt composite_op->sub_operators[composite_op->num_suboperators] = sub_op; 13162b730f8bSJeremy L Thompson CeedCall(CeedOperatorReference(sub_op)); 1317d1d35e2fSjeremylt composite_op->num_suboperators++; 1318e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 131952d6035fSJeremy L Thompson } 132052d6035fSJeremy L Thompson 132152d6035fSJeremy L Thompson /** 1322ca94c3ddSJeremy L Thompson @brief Get the number of sub-operators associated with a `CeedOperator` 132375f0d5a4SJeremy L Thompson 1324ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1325ca94c3ddSJeremy L Thompson @param[out] num_suboperators Variable to store number of sub-operators 132675f0d5a4SJeremy L Thompson 132775f0d5a4SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 132875f0d5a4SJeremy L Thompson 132975f0d5a4SJeremy L Thompson @ref Backend 133075f0d5a4SJeremy L Thompson **/ 1331ed094490SJeremy L Thompson int CeedOperatorCompositeGetNumSub(CeedOperator op, CeedInt *num_suboperators) { 13321203703bSJeremy L Thompson bool is_composite; 13331203703bSJeremy L Thompson 13341203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 13356e536b99SJeremy L Thompson CeedCheck(is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for a composite operator"); 133675f0d5a4SJeremy L Thompson *num_suboperators = op->num_suboperators; 133775f0d5a4SJeremy L Thompson return CEED_ERROR_SUCCESS; 133875f0d5a4SJeremy L Thompson } 133975f0d5a4SJeremy L Thompson 134075f0d5a4SJeremy L Thompson /** 1341ca94c3ddSJeremy L Thompson @brief Get the list of sub-operators associated with a `CeedOperator` 134275f0d5a4SJeremy L Thompson 1343ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1344ca94c3ddSJeremy L Thompson @param[out] sub_operators Variable to store list of sub-operators 134575f0d5a4SJeremy L Thompson 134675f0d5a4SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 134775f0d5a4SJeremy L Thompson 134875f0d5a4SJeremy L Thompson @ref Backend 134975f0d5a4SJeremy L Thompson **/ 1350ed094490SJeremy L Thompson int CeedOperatorCompositeGetSubList(CeedOperator op, CeedOperator **sub_operators) { 13511203703bSJeremy L Thompson bool is_composite; 13521203703bSJeremy L Thompson 13531203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 13546e536b99SJeremy L Thompson CeedCheck(is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for a composite operator"); 135575f0d5a4SJeremy L Thompson *sub_operators = op->sub_operators; 135675f0d5a4SJeremy L Thompson return CEED_ERROR_SUCCESS; 135775f0d5a4SJeremy L Thompson } 135875f0d5a4SJeremy L Thompson 135975f0d5a4SJeremy L Thompson /** 13608a297abdSJames Wright @brief Get a sub `CeedOperator` of a composite `CeedOperator` from its name. 13618a297abdSJames Wright 13628a297abdSJames Wright `sub_op` is set to `NULL` if the sub operator is not found. 13638a297abdSJames Wright 13648a297abdSJames Wright Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 13658a297abdSJames Wright 13668a297abdSJames Wright @param[in] op Composite `CeedOperator` 13678a297abdSJames Wright @param[in] op_name Name of desired sub `CeedOperator` 13688a297abdSJames Wright @param[out] sub_op Sub `CeedOperator` corresponding to the name 13698a297abdSJames Wright 13708a297abdSJames Wright @return An error code: 0 - success, otherwise - failure 13718a297abdSJames Wright 13728a297abdSJames Wright @ref Advanced 13738a297abdSJames Wright **/ 1374ed094490SJeremy L Thompson int CeedOperatorCompositeGetSubByName(CeedOperator op, const char *op_name, CeedOperator *sub_op) { 13758a297abdSJames Wright bool is_composite; 13768a297abdSJames Wright CeedInt num_sub_ops; 13778a297abdSJames Wright CeedOperator *sub_ops; 13788a297abdSJames Wright 13798a297abdSJames Wright CeedCall(CeedOperatorIsComposite(op, &is_composite)); 13808a297abdSJames Wright CeedCheck(is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for a composite operator"); 13818a297abdSJames Wright *sub_op = NULL; 1382ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_sub_ops)); 1383ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_ops)); 13848a297abdSJames Wright for (CeedInt i = 0; i < num_sub_ops; i++) { 13858a297abdSJames Wright if (sub_ops[i]->name && !strcmp(op_name, sub_ops[i]->name)) { 13868a297abdSJames Wright *sub_op = sub_ops[i]; 13878a297abdSJames Wright return CEED_ERROR_SUCCESS; 13888a297abdSJames Wright } 13898a297abdSJames Wright } 13908a297abdSJames Wright return CEED_ERROR_SUCCESS; 13918a297abdSJames Wright } 13928a297abdSJames Wright 13938a297abdSJames Wright /** 1394ca94c3ddSJeremy L Thompson @brief Check if a `CeedOperator` is ready to be used. 13954db537f9SJeremy L Thompson 1396ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to check 13974db537f9SJeremy L Thompson 13984db537f9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 13994db537f9SJeremy L Thompson 14004db537f9SJeremy L Thompson @ref User 14014db537f9SJeremy L Thompson **/ 14024db537f9SJeremy L Thompson int CeedOperatorCheckReady(CeedOperator op) { 14031203703bSJeremy L Thompson bool is_at_points, is_composite; 14041203703bSJeremy L Thompson CeedQFunction qf = NULL; 14054db537f9SJeremy L Thompson 14062b730f8bSJeremy L Thompson if (op->is_interface_setup) return CEED_ERROR_SUCCESS; 14074db537f9SJeremy L Thompson 14081203703bSJeremy L Thompson CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 14091203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 14101203703bSJeremy L Thompson if (!is_composite) CeedCall(CeedOperatorGetQFunction(op, &qf)); 14111203703bSJeremy L Thompson if (is_composite) { 14121203703bSJeremy L Thompson CeedInt num_suboperators; 14131203703bSJeremy L Thompson 1414ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 14151203703bSJeremy L Thompson if (!num_suboperators) { 141643622462SJeremy L Thompson // Empty operator setup 141743622462SJeremy L Thompson op->input_size = 0; 141843622462SJeremy L Thompson op->output_size = 0; 141943622462SJeremy L Thompson } else { 14201203703bSJeremy L Thompson CeedOperator *sub_operators; 14211203703bSJeremy L Thompson 1422ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 14231203703bSJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 14241203703bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(sub_operators[i])); 14254db537f9SJeremy L Thompson } 14262b104005SJeremy L Thompson // Sub-operators could be modified after adding to composite operator 14272b104005SJeremy L Thompson // Need to verify no lvec incompatibility from any changes 14282b104005SJeremy L Thompson CeedSize input_size, output_size; 14292b730f8bSJeremy L Thompson CeedCall(CeedOperatorGetActiveVectorLengths(op, &input_size, &output_size)); 143043622462SJeremy L Thompson } 14314db537f9SJeremy L Thompson } else { 14321203703bSJeremy L Thompson CeedInt num_input_fields, num_output_fields; 14331203703bSJeremy L Thompson 14349bc66399SJeremy L Thompson CeedCheck(op->num_fields > 0, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "No operator fields set"); 14351203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFields(qf, &num_input_fields, NULL, &num_output_fields, NULL)); 14369bc66399SJeremy L Thompson CeedCheck(op->num_fields == num_input_fields + num_output_fields, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, 14379bc66399SJeremy L Thompson "Not all operator fields set"); 14389bc66399SJeremy L Thompson CeedCheck(op->has_restriction, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "At least one restriction required"); 14399bc66399SJeremy L Thompson CeedCheck(op->num_qpts > 0 || is_at_points, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, 1440ca94c3ddSJeremy L Thompson "At least one non-collocated CeedBasis is required or the number of quadrature points must be set"); 14412b730f8bSJeremy L Thompson } 14424db537f9SJeremy L Thompson 14434db537f9SJeremy L Thompson // Flag as immutable and ready 14444db537f9SJeremy L Thompson op->is_interface_setup = true; 14451203703bSJeremy L Thompson if (qf && qf != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionSetImmutable(qf)); 1446c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 14471203703bSJeremy L Thompson if (op->dqf && op->dqf != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionSetImmutable(op->dqf)); 14481203703bSJeremy L Thompson if (op->dqfT && op->dqfT != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionSetImmutable(op->dqfT)); 14494db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 14504db537f9SJeremy L Thompson } 14514db537f9SJeremy L Thompson 14524db537f9SJeremy L Thompson /** 1453ca94c3ddSJeremy L Thompson @brief Get vector lengths for the active input and/or output `CeedVector` of a `CeedOperator`. 14544385fb7fSSebastian Grimberg 1455ca94c3ddSJeremy L Thompson Note: Lengths of `-1` indicate that the CeedOperator does not have an active input and/or output. 1456c9366a6bSJeremy L Thompson 1457ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1458ca94c3ddSJeremy L Thompson @param[out] input_size Variable to store active input vector length, or `NULL` 1459ca94c3ddSJeremy L Thompson @param[out] output_size Variable to store active output vector length, or `NULL` 1460c9366a6bSJeremy L Thompson 1461c9366a6bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1462c9366a6bSJeremy L Thompson 1463c9366a6bSJeremy L Thompson @ref User 1464c9366a6bSJeremy L Thompson **/ 14652b730f8bSJeremy L Thompson int CeedOperatorGetActiveVectorLengths(CeedOperator op, CeedSize *input_size, CeedSize *output_size) { 1466c9366a6bSJeremy L Thompson bool is_composite; 1467c9366a6bSJeremy L Thompson 14682b104005SJeremy L Thompson if (input_size) *input_size = op->input_size; 14692b104005SJeremy L Thompson if (output_size) *output_size = op->output_size; 1470c9366a6bSJeremy L Thompson 14712b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 14722b104005SJeremy L Thompson if (is_composite && (op->input_size == -1 || op->output_size == -1)) { 14731203703bSJeremy L Thompson CeedInt num_suboperators; 14741203703bSJeremy L Thompson CeedOperator *sub_operators; 14751203703bSJeremy L Thompson 1476ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 1477ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 14781203703bSJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 1479c9366a6bSJeremy L Thompson CeedSize sub_input_size, sub_output_size; 14801c66c397SJeremy L Thompson 14811203703bSJeremy L Thompson CeedCall(CeedOperatorGetActiveVectorLengths(sub_operators[i], &sub_input_size, &sub_output_size)); 14822b104005SJeremy L Thompson if (op->input_size == -1) op->input_size = sub_input_size; 14832b104005SJeremy L Thompson if (op->output_size == -1) op->output_size = sub_output_size; 14842b104005SJeremy L Thompson // Note, a size of -1 means no active vector restriction set, so no incompatibility 14856e536b99SJeremy L Thompson CeedCheck((sub_input_size == -1 || sub_input_size == op->input_size) && (sub_output_size == -1 || sub_output_size == op->output_size), 14866e536b99SJeremy L Thompson CeedOperatorReturnCeed(op), CEED_ERROR_MAJOR, 1487249f8407SJeremy L Thompson "Sub-operators must have compatible dimensions; composite operator of shape (%" CeedSize_FMT ", %" CeedSize_FMT 1488249f8407SJeremy L Thompson ") not compatible with sub-operator of " 1489249f8407SJeremy L Thompson "shape (%" CeedSize_FMT ", %" CeedSize_FMT ")", 14902b104005SJeremy L Thompson op->input_size, op->output_size, input_size, output_size); 1491c9366a6bSJeremy L Thompson } 14922b730f8bSJeremy L Thompson } 1493c9366a6bSJeremy L Thompson return CEED_ERROR_SUCCESS; 1494c9366a6bSJeremy L Thompson } 1495c9366a6bSJeremy L Thompson 1496c9366a6bSJeremy L Thompson /** 1497ca94c3ddSJeremy L Thompson @brief Set reuse of `CeedQFunction` data in `CeedOperatorLinearAssemble*()` functions. 14984385fb7fSSebastian Grimberg 1499ca94c3ddSJeremy L Thompson When `reuse_assembly_data = false` (default), the `CeedQFunction` associated with this `CeedOperator` is re-assembled every time a `CeedOperatorLinearAssemble*()` function is called. 1500ca94c3ddSJeremy L Thompson When `reuse_assembly_data = true`, the `CeedQFunction` associated with this `CeedOperator` is reused between calls to @ref CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(). 15018b919e6bSJeremy L Thompson 1502ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1503beecbf24SJeremy L Thompson @param[in] reuse_assembly_data Boolean flag setting assembly data reuse 15048b919e6bSJeremy L Thompson 15058b919e6bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 15068b919e6bSJeremy L Thompson 15078b919e6bSJeremy L Thompson @ref Advanced 15088b919e6bSJeremy L Thompson **/ 15092b730f8bSJeremy L Thompson int CeedOperatorSetQFunctionAssemblyReuse(CeedOperator op, bool reuse_assembly_data) { 15108b919e6bSJeremy L Thompson bool is_composite; 15118b919e6bSJeremy L Thompson 15122b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 15138b919e6bSJeremy L Thompson if (is_composite) { 15148b919e6bSJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 15152b730f8bSJeremy L Thompson CeedCall(CeedOperatorSetQFunctionAssemblyReuse(op->sub_operators[i], reuse_assembly_data)); 15168b919e6bSJeremy L Thompson } 15178b919e6bSJeremy L Thompson } else { 15187d5185d7SSebastian Grimberg CeedQFunctionAssemblyData data; 15197d5185d7SSebastian Grimberg 15207d5185d7SSebastian Grimberg CeedCall(CeedOperatorGetQFunctionAssemblyData(op, &data)); 15217d5185d7SSebastian Grimberg CeedCall(CeedQFunctionAssemblyDataSetReuse(data, reuse_assembly_data)); 1522beecbf24SJeremy L Thompson } 1523beecbf24SJeremy L Thompson return CEED_ERROR_SUCCESS; 1524beecbf24SJeremy L Thompson } 1525beecbf24SJeremy L Thompson 1526beecbf24SJeremy L Thompson /** 1527ca94c3ddSJeremy L Thompson @brief Mark `CeedQFunction` data as updated and the `CeedQFunction` as requiring re-assembly. 1528beecbf24SJeremy L Thompson 1529ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 15306e15d496SJeremy L Thompson @param[in] needs_data_update Boolean flag setting assembly data reuse 1531beecbf24SJeremy L Thompson 1532beecbf24SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1533beecbf24SJeremy L Thompson 1534beecbf24SJeremy L Thompson @ref Advanced 1535beecbf24SJeremy L Thompson **/ 15362b730f8bSJeremy L Thompson int CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(CeedOperator op, bool needs_data_update) { 1537beecbf24SJeremy L Thompson bool is_composite; 1538beecbf24SJeremy L Thompson 15392b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 1540beecbf24SJeremy L Thompson if (is_composite) { 15411203703bSJeremy L Thompson CeedInt num_suboperators; 15421203703bSJeremy L Thompson CeedOperator *sub_operators; 15431203703bSJeremy L Thompson 1544ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 1545ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 15461203703bSJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 15471203703bSJeremy L Thompson CeedCall(CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(sub_operators[i], needs_data_update)); 1548beecbf24SJeremy L Thompson } 1549beecbf24SJeremy L Thompson } else { 15507d5185d7SSebastian Grimberg CeedQFunctionAssemblyData data; 15517d5185d7SSebastian Grimberg 15527d5185d7SSebastian Grimberg CeedCall(CeedOperatorGetQFunctionAssemblyData(op, &data)); 15537d5185d7SSebastian Grimberg CeedCall(CeedQFunctionAssemblyDataSetUpdateNeeded(data, needs_data_update)); 15548b919e6bSJeremy L Thompson } 15558b919e6bSJeremy L Thompson return CEED_ERROR_SUCCESS; 15568b919e6bSJeremy L Thompson } 15578b919e6bSJeremy L Thompson 15588b919e6bSJeremy L Thompson /** 1559ca94c3ddSJeremy L Thompson @brief Set name of `CeedOperator` for @ref CeedOperatorView() output 1560ea6b5821SJeremy L Thompson 1561ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 1562ea61e9acSJeremy L Thompson @param[in] name Name to set, or NULL to remove previously set name 1563ea6b5821SJeremy L Thompson 1564ea6b5821SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1565ea6b5821SJeremy L Thompson 1566ea6b5821SJeremy L Thompson @ref User 1567ea6b5821SJeremy L Thompson **/ 1568ea6b5821SJeremy L Thompson int CeedOperatorSetName(CeedOperator op, const char *name) { 1569ea6b5821SJeremy L Thompson char *name_copy; 1570ea6b5821SJeremy L Thompson size_t name_len = name ? strlen(name) : 0; 1571ea6b5821SJeremy L Thompson 15722b730f8bSJeremy L Thompson CeedCall(CeedFree(&op->name)); 1573ea6b5821SJeremy L Thompson if (name_len > 0) { 15742b730f8bSJeremy L Thompson CeedCall(CeedCalloc(name_len + 1, &name_copy)); 1575ea6b5821SJeremy L Thompson memcpy(name_copy, name, name_len); 1576ea6b5821SJeremy L Thompson op->name = name_copy; 1577ea6b5821SJeremy L Thompson } 1578ea6b5821SJeremy L Thompson return CEED_ERROR_SUCCESS; 1579ea6b5821SJeremy L Thompson } 1580ea6b5821SJeremy L Thompson 1581ea6b5821SJeremy L Thompson /** 1582d3d5610dSJeremy L Thompson @brief Get name of `CeedOperator` 1583d3d5610dSJeremy L Thompson 1584d3d5610dSJeremy L Thompson @param[in] op `CeedOperator` 1585d3d5610dSJeremy L Thompson @param[in,out] name Address of variable to hold currently set name 1586d3d5610dSJeremy L Thompson 1587d3d5610dSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1588d3d5610dSJeremy L Thompson 1589d3d5610dSJeremy L Thompson @ref User 1590d3d5610dSJeremy L Thompson **/ 1591d3d5610dSJeremy L Thompson int CeedOperatorGetName(CeedOperator op, const char **name) { 1592d3d5610dSJeremy L Thompson if (op->name) { 1593d3d5610dSJeremy L Thompson *name = op->name; 1594d3d5610dSJeremy L Thompson } else if (!op->is_composite) { 1595d3d5610dSJeremy L Thompson CeedQFunction qf; 1596d3d5610dSJeremy L Thompson 1597d3d5610dSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 1598d3d5610dSJeremy L Thompson if (qf) CeedCall(CeedQFunctionGetName(qf, name)); 1599d3d5610dSJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 1600d3d5610dSJeremy L Thompson } 1601d3d5610dSJeremy L Thompson return CEED_ERROR_SUCCESS; 1602d3d5610dSJeremy L Thompson } 1603d3d5610dSJeremy L Thompson 1604d3d5610dSJeremy L Thompson /** 1605935f026aSJeremy L Thompson @brief Core logic for viewing a `CeedOperator` 16067a982d89SJeremy L. Thompson 1607935f026aSJeremy L Thompson @param[in] op `CeedOperator` to view brief summary 1608ca94c3ddSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 16098bf1b130SJames Wright @param[in] is_full Whether to write full operator view or terse 16107a982d89SJeremy L. Thompson 16117a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 16126ab8e59fSJames Wright 16136ab8e59fSJames Wright @ref Developer 16147a982d89SJeremy L. Thompson **/ 16158bf1b130SJames Wright static int CeedOperatorView_Core(CeedOperator op, FILE *stream, bool is_full) { 1616d3d5610dSJeremy L Thompson bool has_name, is_composite, is_at_points; 16175a526491SJeremy L Thompson char *tabs = NULL; 1618d3d5610dSJeremy L Thompson const char *name = NULL; 16195a526491SJeremy L Thompson CeedInt num_tabs = 0; 16207a982d89SJeremy L. Thompson 1621d3d5610dSJeremy L Thompson CeedCall(CeedOperatorGetName(op, &name)); 1622d3d5610dSJeremy L Thompson has_name = name ? strlen(name) : false; 16231203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 162499f7f61fSJeremy L Thompson CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 16255a526491SJeremy L Thompson // Set tabs 16265a526491SJeremy L Thompson CeedCall(CeedOperatorGetNumViewTabs(op, &num_tabs)); 16274c789ea2SJeremy L Thompson CeedCall(CeedCalloc(CEED_TAB_WIDTH * (num_tabs + is_composite) + 1, &tabs)); 16284c789ea2SJeremy L Thompson for (CeedInt i = 0; i < CEED_TAB_WIDTH * num_tabs; i++) tabs[i] = ' '; 16291203703bSJeremy L Thompson if (is_composite) { 16301203703bSJeremy L Thompson CeedInt num_suboperators; 16311203703bSJeremy L Thompson CeedOperator *sub_operators; 16321203703bSJeremy L Thompson 1633ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 1634ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 1635df1daa62SZach Atkins fprintf(stream, "%s", tabs); 1636d3d5610dSJeremy L Thompson fprintf(stream, "Composite CeedOperator%s%s\n", has_name ? " - " : "", has_name ? name : ""); 16374c789ea2SJeremy L Thompson for (CeedInt i = 0; i < CEED_TAB_WIDTH; i++) tabs[CEED_TAB_WIDTH * num_tabs + i] = ' '; 16381203703bSJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 16391203703bSJeremy L Thompson has_name = sub_operators[i]->name; 1640df1daa62SZach Atkins fprintf(stream, "%s", tabs); 164199f7f61fSJeremy L Thompson fprintf(stream, "SubOperator%s %" CeedInt_FMT "%s%s%s\n", is_at_points ? " AtPoints" : "", i, has_name ? " - " : "", 164299f7f61fSJeremy L Thompson has_name ? sub_operators[i]->name : "", is_full ? ":" : ""); 16435a526491SJeremy L Thompson if (is_full) CeedCall(CeedOperatorSingleView(sub_operators[i], tabs, stream)); 16447a982d89SJeremy L. Thompson } 16457a982d89SJeremy L. Thompson } else { 1646df1daa62SZach Atkins fprintf(stream, "%s", tabs); 1647d3d5610dSJeremy L Thompson fprintf(stream, "CeedOperator%s%s%s\n", is_at_points ? " AtPoints" : "", has_name ? " - " : "", has_name ? name : ""); 16485a526491SJeremy L Thompson if (is_full) CeedCall(CeedOperatorSingleView(op, tabs, stream)); 16497a982d89SJeremy L. Thompson } 16505a526491SJeremy L Thompson CeedCall(CeedFree(&tabs)); 16515a526491SJeremy L Thompson return CEED_ERROR_SUCCESS; 16525a526491SJeremy L Thompson } 16535a526491SJeremy L Thompson 16545a526491SJeremy L Thompson /** 16555a526491SJeremy L Thompson @brief Set the number of tabs to indent for @ref CeedOperatorView() output 16565a526491SJeremy L Thompson 16575a526491SJeremy L Thompson @param[in] op `CeedOperator` to set the number of view tabs 16585a526491SJeremy L Thompson @param[in] num_tabs Number of view tabs to set 16595a526491SJeremy L Thompson 16605a526491SJeremy L Thompson @return Error code: 0 - success, otherwise - failure 16615a526491SJeremy L Thompson 16625a526491SJeremy L Thompson @ref User 16635a526491SJeremy L Thompson **/ 16645a526491SJeremy L Thompson int CeedOperatorSetNumViewTabs(CeedOperator op, CeedInt num_tabs) { 1665a299a25bSJeremy L Thompson CeedCall(CeedObjectSetNumViewTabs((CeedObject)op, num_tabs)); 1666e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 16677a982d89SJeremy L. Thompson } 16683bd813ffSjeremylt 16693bd813ffSjeremylt /** 1670690992b2SZach Atkins @brief Get the number of tabs to indent for @ref CeedOperatorView() output 1671690992b2SZach Atkins 1672690992b2SZach Atkins @param[in] op `CeedOperator` to get the number of view tabs 1673690992b2SZach Atkins @param[out] num_tabs Number of view tabs 1674690992b2SZach Atkins 1675690992b2SZach Atkins @return Error code: 0 - success, otherwise - failure 1676690992b2SZach Atkins 1677690992b2SZach Atkins @ref User 1678690992b2SZach Atkins **/ 1679690992b2SZach Atkins int CeedOperatorGetNumViewTabs(CeedOperator op, CeedInt *num_tabs) { 1680a299a25bSJeremy L Thompson CeedCall(CeedObjectGetNumViewTabs((CeedObject)op, num_tabs)); 1681690992b2SZach Atkins return CEED_ERROR_SUCCESS; 1682690992b2SZach Atkins } 1683690992b2SZach Atkins 1684690992b2SZach Atkins /** 1685935f026aSJeremy L Thompson @brief View a `CeedOperator` 1686935f026aSJeremy L Thompson 1687935f026aSJeremy L Thompson @param[in] op `CeedOperator` to view 1688935f026aSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 1689935f026aSJeremy L Thompson 1690935f026aSJeremy L Thompson @return Error code: 0 - success, otherwise - failure 1691935f026aSJeremy L Thompson 1692935f026aSJeremy L Thompson @ref User 1693935f026aSJeremy L Thompson **/ 1694935f026aSJeremy L Thompson int CeedOperatorView(CeedOperator op, FILE *stream) { 1695935f026aSJeremy L Thompson CeedCall(CeedOperatorView_Core(op, stream, true)); 1696935f026aSJeremy L Thompson return CEED_ERROR_SUCCESS; 1697935f026aSJeremy L Thompson } 1698935f026aSJeremy L Thompson 1699935f026aSJeremy L Thompson /** 1700935f026aSJeremy L Thompson @brief View a brief summary `CeedOperator` 1701935f026aSJeremy L Thompson 1702935f026aSJeremy L Thompson @param[in] op `CeedOperator` to view brief summary 1703935f026aSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 1704935f026aSJeremy L Thompson 1705935f026aSJeremy L Thompson @return Error code: 0 - success, otherwise - failure 1706935f026aSJeremy L Thompson 1707935f026aSJeremy L Thompson @ref User 1708935f026aSJeremy L Thompson **/ 1709935f026aSJeremy L Thompson int CeedOperatorViewTerse(CeedOperator op, FILE *stream) { 1710935f026aSJeremy L Thompson CeedCall(CeedOperatorView_Core(op, stream, false)); 1711935f026aSJeremy L Thompson return CEED_ERROR_SUCCESS; 1712935f026aSJeremy L Thompson } 1713935f026aSJeremy L Thompson 1714935f026aSJeremy L Thompson /** 1715ca94c3ddSJeremy L Thompson @brief Get the `Ceed` associated with a `CeedOperator` 1716b7c9bbdaSJeremy L Thompson 1717ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1718ca94c3ddSJeremy L Thompson @param[out] ceed Variable to store `Ceed` 1719b7c9bbdaSJeremy L Thompson 1720b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1721b7c9bbdaSJeremy L Thompson 1722b7c9bbdaSJeremy L Thompson @ref Advanced 1723b7c9bbdaSJeremy L Thompson **/ 1724b7c9bbdaSJeremy L Thompson int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 1725b0f67a9cSJeremy L Thompson CeedCall(CeedObjectGetCeed((CeedObject)op, ceed)); 1726b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1727b7c9bbdaSJeremy L Thompson } 1728b7c9bbdaSJeremy L Thompson 1729b7c9bbdaSJeremy L Thompson /** 17306e536b99SJeremy L Thompson @brief Return the `Ceed` associated with a `CeedOperator` 17316e536b99SJeremy L Thompson 17326e536b99SJeremy L Thompson @param[in] op `CeedOperator` 17336e536b99SJeremy L Thompson 17346e536b99SJeremy L Thompson @return `Ceed` associated with the `op` 17356e536b99SJeremy L Thompson 17366e536b99SJeremy L Thompson @ref Advanced 17376e536b99SJeremy L Thompson **/ 1738b0f67a9cSJeremy L Thompson Ceed CeedOperatorReturnCeed(CeedOperator op) { return CeedObjectReturnCeed((CeedObject)op); } 17396e536b99SJeremy L Thompson 17406e536b99SJeremy L Thompson /** 1741ca94c3ddSJeremy L Thompson @brief Get the number of elements associated with a `CeedOperator` 1742b7c9bbdaSJeremy L Thompson 1743ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1744b7c9bbdaSJeremy L Thompson @param[out] num_elem Variable to store number of elements 1745b7c9bbdaSJeremy L Thompson 1746b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1747b7c9bbdaSJeremy L Thompson 1748b7c9bbdaSJeremy L Thompson @ref Advanced 1749b7c9bbdaSJeremy L Thompson **/ 1750b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumElements(CeedOperator op, CeedInt *num_elem) { 17511203703bSJeremy L Thompson bool is_composite; 17521203703bSJeremy L Thompson 17531203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 17546e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Not defined for composite operator"); 1755b7c9bbdaSJeremy L Thompson *num_elem = op->num_elem; 1756b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1757b7c9bbdaSJeremy L Thompson } 1758b7c9bbdaSJeremy L Thompson 1759b7c9bbdaSJeremy L Thompson /** 1760ca94c3ddSJeremy L Thompson @brief Get the number of quadrature points associated with a `CeedOperator` 1761b7c9bbdaSJeremy L Thompson 1762ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1763b7c9bbdaSJeremy L Thompson @param[out] num_qpts Variable to store vector number of quadrature points 1764b7c9bbdaSJeremy L Thompson 1765b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1766b7c9bbdaSJeremy L Thompson 1767b7c9bbdaSJeremy L Thompson @ref Advanced 1768b7c9bbdaSJeremy L Thompson **/ 1769b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *num_qpts) { 17701203703bSJeremy L Thompson bool is_composite; 17711203703bSJeremy L Thompson 17721203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 17736e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Not defined for composite operator"); 1774b7c9bbdaSJeremy L Thompson *num_qpts = op->num_qpts; 1775b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1776b7c9bbdaSJeremy L Thompson } 1777b7c9bbdaSJeremy L Thompson 1778b7c9bbdaSJeremy L Thompson /** 1779ca94c3ddSJeremy L Thompson @brief Estimate number of FLOPs required to apply `CeedOperator` on the active `CeedVector` 17806e15d496SJeremy L Thompson 1781ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to estimate FLOPs for 1782ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 17836e15d496SJeremy L Thompson 17846e15d496SJeremy L Thompson @ref Backend 17856e15d496SJeremy L Thompson **/ 17869d36ca50SJeremy L Thompson int CeedOperatorGetFlopsEstimate(CeedOperator op, CeedSize *flops) { 17876e15d496SJeremy L Thompson bool is_composite; 17881c66c397SJeremy L Thompson 17892b730f8bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 17906e15d496SJeremy L Thompson 17916e15d496SJeremy L Thompson *flops = 0; 17922b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 17936e15d496SJeremy L Thompson if (is_composite) { 17946e15d496SJeremy L Thompson CeedInt num_suboperators; 17951c66c397SJeremy L Thompson 1796ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 17976e15d496SJeremy L Thompson CeedOperator *sub_operators; 1798ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 17996e15d496SJeremy L Thompson 18006e15d496SJeremy L Thompson // FLOPs for each suboperator 18016e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 18029d36ca50SJeremy L Thompson CeedSize suboperator_flops; 18031c66c397SJeremy L Thompson 18042b730f8bSJeremy L Thompson CeedCall(CeedOperatorGetFlopsEstimate(sub_operators[i], &suboperator_flops)); 18056e15d496SJeremy L Thompson *flops += suboperator_flops; 18066e15d496SJeremy L Thompson } 18076e15d496SJeremy L Thompson } else { 18083f919cbcSJeremy L Thompson bool is_at_points; 18093f919cbcSJeremy L Thompson CeedInt num_input_fields, num_output_fields, num_elem = 0, num_points = 0; 18101203703bSJeremy L Thompson CeedQFunction qf; 18111203703bSJeremy L Thompson CeedQFunctionField *qf_input_fields, *qf_output_fields; 18121203703bSJeremy L Thompson CeedOperatorField *op_input_fields, *op_output_fields; 18131c66c397SJeremy L Thompson 18143f919cbcSJeremy L Thompson CeedCall(CeedOperatorGetNumElements(op, &num_elem)); 181519feff82SJeremy L Thompson if (num_elem == 0) return CEED_ERROR_SUCCESS; 181619feff82SJeremy L Thompson CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 18173f919cbcSJeremy L Thompson if (is_at_points) { 18183f919cbcSJeremy L Thompson CeedMemType mem_type; 18193f919cbcSJeremy L Thompson CeedElemRestriction rstr_points = NULL; 18203f919cbcSJeremy L Thompson 18213f919cbcSJeremy L Thompson CeedCall(CeedOperatorAtPointsGetPoints(op, &rstr_points, NULL)); 18223f919cbcSJeremy L Thompson CeedCall(CeedGetPreferredMemType(CeedOperatorReturnCeed(op), &mem_type)); 18233f919cbcSJeremy L Thompson if (mem_type == CEED_MEM_DEVICE) { 18243f919cbcSJeremy L Thompson // Device backends pad out to the same number of points per element 18253f919cbcSJeremy L Thompson CeedCall(CeedElemRestrictionGetMaxPointsInElement(rstr_points, &num_points)); 18263f919cbcSJeremy L Thompson } else { 18273f919cbcSJeremy L Thompson num_points = 0; 18283f919cbcSJeremy L Thompson for (CeedInt i = 0; i < num_elem; i++) { 18293f919cbcSJeremy L Thompson CeedInt points_in_elem = 0; 18303f919cbcSJeremy L Thompson 18313f919cbcSJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr_points, i, &points_in_elem)); 18323f919cbcSJeremy L Thompson num_points += points_in_elem; 18333f919cbcSJeremy L Thompson } 18343f919cbcSJeremy L Thompson num_points = num_points / num_elem + (num_points % num_elem > 0); 18353f919cbcSJeremy L Thompson } 18363f919cbcSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr_points)); 18373f919cbcSJeremy L Thompson } 18381203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 18391203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFields(qf, &num_input_fields, &qf_input_fields, &num_output_fields, &qf_output_fields)); 1840c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 18411203703bSJeremy L Thompson CeedCall(CeedOperatorGetFields(op, NULL, &op_input_fields, NULL, &op_output_fields)); 18424385fb7fSSebastian Grimberg 18436e15d496SJeremy L Thompson // Input FLOPs 18446e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 18451203703bSJeremy L Thompson CeedVector vec; 18466e15d496SJeremy L Thompson 18471203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_input_fields[i], &vec)); 18481203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 18491203703bSJeremy L Thompson CeedEvalMode eval_mode; 18501203703bSJeremy L Thompson CeedSize rstr_flops, basis_flops; 18511203703bSJeremy L Thompson CeedElemRestriction rstr; 18521203703bSJeremy L Thompson CeedBasis basis; 18531203703bSJeremy L Thompson 18541203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetElemRestriction(op_input_fields[i], &rstr)); 18551203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetFlopsEstimate(rstr, CEED_NOTRANSPOSE, &rstr_flops)); 1856681d0ea7SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr)); 1857edb2538eSJeremy L Thompson *flops += rstr_flops; 18581203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(op_input_fields[i], &basis)); 18591203703bSJeremy L Thompson CeedCall(CeedQFunctionFieldGetEvalMode(qf_input_fields[i], &eval_mode)); 18603f919cbcSJeremy L Thompson CeedCall(CeedBasisGetFlopsEstimate(basis, CEED_NOTRANSPOSE, eval_mode, is_at_points, num_points, &basis_flops)); 1861681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 18626e15d496SJeremy L Thompson *flops += basis_flops * num_elem; 18636e15d496SJeremy L Thompson } 1864681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 18656e15d496SJeremy L Thompson } 18666e15d496SJeremy L Thompson // QF FLOPs 18671c66c397SJeremy L Thompson { 18689d36ca50SJeremy L Thompson CeedInt num_qpts; 18699d36ca50SJeremy L Thompson CeedSize qf_flops; 18701203703bSJeremy L Thompson CeedQFunction qf; 18711c66c397SJeremy L Thompson 18723f919cbcSJeremy L Thompson if (is_at_points) num_qpts = num_points; 18733f919cbcSJeremy L Thompson else CeedCall(CeedOperatorGetNumQuadraturePoints(op, &num_qpts)); 18741203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 18751203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFlopsEstimate(qf, &qf_flops)); 1876c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 18776e536b99SJeremy L Thompson CeedCheck(qf_flops > -1, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, 18786e536b99SJeremy L Thompson "Must set CeedQFunction FLOPs estimate with CeedQFunctionSetUserFlopsEstimate"); 18796e15d496SJeremy L Thompson *flops += num_elem * num_qpts * qf_flops; 18801c66c397SJeremy L Thompson } 18811c66c397SJeremy L Thompson 18826e15d496SJeremy L Thompson // Output FLOPs 18836e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 18841203703bSJeremy L Thompson CeedVector vec; 18856e15d496SJeremy L Thompson 18861203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_output_fields[i], &vec)); 18871203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 18881203703bSJeremy L Thompson CeedEvalMode eval_mode; 18891203703bSJeremy L Thompson CeedSize rstr_flops, basis_flops; 18901203703bSJeremy L Thompson CeedElemRestriction rstr; 18911203703bSJeremy L Thompson CeedBasis basis; 18921203703bSJeremy L Thompson 18931203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetElemRestriction(op_output_fields[i], &rstr)); 18941203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetFlopsEstimate(rstr, CEED_TRANSPOSE, &rstr_flops)); 1895681d0ea7SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr)); 1896edb2538eSJeremy L Thompson *flops += rstr_flops; 18971203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(op_output_fields[i], &basis)); 18981203703bSJeremy L Thompson CeedCall(CeedQFunctionFieldGetEvalMode(qf_output_fields[i], &eval_mode)); 18993f919cbcSJeremy L Thompson CeedCall(CeedBasisGetFlopsEstimate(basis, CEED_TRANSPOSE, eval_mode, is_at_points, num_points, &basis_flops)); 1900681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 19016e15d496SJeremy L Thompson *flops += basis_flops * num_elem; 19026e15d496SJeremy L Thompson } 1903681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 19046e15d496SJeremy L Thompson } 19056e15d496SJeremy L Thompson } 19066e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 19076e15d496SJeremy L Thompson } 19086e15d496SJeremy L Thompson 19096e15d496SJeremy L Thompson /** 1910ca94c3ddSJeremy L Thompson @brief Get `CeedQFunction` global context for a `CeedOperator`. 19119fd66db6SSebastian Grimberg 1912ca94c3ddSJeremy L Thompson The caller is responsible for destroying `ctx` returned from this function via @ref CeedQFunctionContextDestroy(). 1913512bb800SJeremy L Thompson 1914ca94c3ddSJeremy L Thompson Note: If the value of `ctx` passed into this function is non-`NULL`, then it is assumed that `ctx` is a pointer to a `CeedQFunctionContext`. 1915ca94c3ddSJeremy L Thompson This `CeedQFunctionContext` will be destroyed if `ctx` is the only reference to this `CeedQFunctionContext`. 19160126412dSJeremy L Thompson 1917ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1918ca94c3ddSJeremy L Thompson @param[out] ctx Variable to store `CeedQFunctionContext` 19190126412dSJeremy L Thompson 19200126412dSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 19210126412dSJeremy L Thompson 1922859c15bbSJames Wright @ref Advanced 19230126412dSJeremy L Thompson **/ 19240126412dSJeremy L Thompson int CeedOperatorGetContext(CeedOperator op, CeedQFunctionContext *ctx) { 19251203703bSJeremy L Thompson bool is_composite; 19261203703bSJeremy L Thompson CeedQFunction qf; 19271203703bSJeremy L Thompson CeedQFunctionContext qf_ctx; 19281203703bSJeremy L Thompson 19291203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 19306e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "Cannot retrieve CeedQFunctionContext for composite operator"); 19311203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 19321203703bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &qf_ctx)); 1933c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 19341485364cSJeremy L Thompson *ctx = NULL; 19351203703bSJeremy L Thompson if (qf_ctx) CeedCall(CeedQFunctionContextReferenceCopy(qf_ctx, ctx)); 19360126412dSJeremy L Thompson return CEED_ERROR_SUCCESS; 19370126412dSJeremy L Thompson } 19380126412dSJeremy L Thompson 19390126412dSJeremy L Thompson /** 1940ca94c3ddSJeremy L Thompson @brief Get label for a registered `CeedQFunctionContext` field, or `NULL` if no field has been registered with this `field_name`. 19413668ca4bSJeremy L Thompson 1942ca94c3ddSJeremy L Thompson Fields are registered via `CeedQFunctionContextRegister*()` functions (eg. @ref CeedQFunctionContextRegisterDouble()). 1943859c15bbSJames Wright 1944ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 19453668ca4bSJeremy L Thompson @param[in] field_name Name of field to retrieve label 19463668ca4bSJeremy L Thompson @param[out] field_label Variable to field label 19473668ca4bSJeremy L Thompson 19483668ca4bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 19493668ca4bSJeremy L Thompson 19503668ca4bSJeremy L Thompson @ref User 19513668ca4bSJeremy L Thompson **/ 195217b0d5c6SJeremy L Thompson int CeedOperatorGetContextFieldLabel(CeedOperator op, const char *field_name, CeedContextFieldLabel *field_label) { 19531c66c397SJeremy L Thompson bool is_composite, field_found = false; 19541c66c397SJeremy L Thompson 19552b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 19562b730f8bSJeremy L Thompson 19573668ca4bSJeremy L Thompson if (is_composite) { 1958a98a090bSJeremy L Thompson // Composite operator 1959a98a090bSJeremy L Thompson // -- Check if composite label already created 19603668ca4bSJeremy L Thompson for (CeedInt i = 0; i < op->num_context_labels; i++) { 19613668ca4bSJeremy L Thompson if (!strcmp(op->context_labels[i]->name, field_name)) { 19623668ca4bSJeremy L Thompson *field_label = op->context_labels[i]; 19633668ca4bSJeremy L Thompson return CEED_ERROR_SUCCESS; 19643668ca4bSJeremy L Thompson } 19653668ca4bSJeremy L Thompson } 19663668ca4bSJeremy L Thompson 1967a98a090bSJeremy L Thompson // -- Create composite label if needed 19683668ca4bSJeremy L Thompson CeedInt num_sub; 19693668ca4bSJeremy L Thompson CeedOperator *sub_operators; 19703668ca4bSJeremy L Thompson CeedContextFieldLabel new_field_label; 19713668ca4bSJeremy L Thompson 19722b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &new_field_label)); 1973ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_sub)); 1974ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 19752b730f8bSJeremy L Thompson CeedCall(CeedCalloc(num_sub, &new_field_label->sub_labels)); 19763668ca4bSJeremy L Thompson new_field_label->num_sub_labels = num_sub; 19773668ca4bSJeremy L Thompson 19783668ca4bSJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 19793668ca4bSJeremy L Thompson if (sub_operators[i]->qf->ctx) { 19803668ca4bSJeremy L Thompson CeedContextFieldLabel new_field_label_i; 19811c66c397SJeremy L Thompson 19822b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldLabel(sub_operators[i]->qf->ctx, field_name, &new_field_label_i)); 19833668ca4bSJeremy L Thompson if (new_field_label_i) { 1984a98a090bSJeremy L Thompson field_found = true; 19853668ca4bSJeremy L Thompson new_field_label->sub_labels[i] = new_field_label_i; 19863668ca4bSJeremy L Thompson new_field_label->name = new_field_label_i->name; 19873668ca4bSJeremy L Thompson new_field_label->description = new_field_label_i->description; 19882b730f8bSJeremy L Thompson if (new_field_label->type && new_field_label->type != new_field_label_i->type) { 19897bfe0f0eSJeremy L Thompson // LCOV_EXCL_START 19902b730f8bSJeremy L Thompson CeedCall(CeedFree(&new_field_label)); 19916e536b99SJeremy L Thompson return CeedError(CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "Incompatible field types on sub-operator contexts. %s != %s", 19922b730f8bSJeremy L Thompson CeedContextFieldTypes[new_field_label->type], CeedContextFieldTypes[new_field_label_i->type]); 19937bfe0f0eSJeremy L Thompson // LCOV_EXCL_STOP 19947bfe0f0eSJeremy L Thompson } else { 19957bfe0f0eSJeremy L Thompson new_field_label->type = new_field_label_i->type; 19967bfe0f0eSJeremy L Thompson } 19972b730f8bSJeremy L Thompson if (new_field_label->num_values != 0 && new_field_label->num_values != new_field_label_i->num_values) { 19987bfe0f0eSJeremy L Thompson // LCOV_EXCL_START 19992b730f8bSJeremy L Thompson CeedCall(CeedFree(&new_field_label)); 20006e536b99SJeremy L Thompson return CeedError(CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 20016e536b99SJeremy L Thompson "Incompatible field number of values on sub-operator contexts. %zu != %zu", new_field_label->num_values, 20026e536b99SJeremy L Thompson new_field_label_i->num_values); 20037bfe0f0eSJeremy L Thompson // LCOV_EXCL_STOP 20047bfe0f0eSJeremy L Thompson } else { 20057bfe0f0eSJeremy L Thompson new_field_label->num_values = new_field_label_i->num_values; 20067bfe0f0eSJeremy L Thompson } 20073668ca4bSJeremy L Thompson } 20083668ca4bSJeremy L Thompson } 20093668ca4bSJeremy L Thompson } 2010a98a090bSJeremy L Thompson // -- Cleanup if field was found 2011a98a090bSJeremy L Thompson if (field_found) { 2012a98a090bSJeremy L Thompson *field_label = new_field_label; 2013a98a090bSJeremy L Thompson } else { 20143668ca4bSJeremy L Thompson // LCOV_EXCL_START 20152b730f8bSJeremy L Thompson CeedCall(CeedFree(&new_field_label->sub_labels)); 20162b730f8bSJeremy L Thompson CeedCall(CeedFree(&new_field_label)); 20173668ca4bSJeremy L Thompson *field_label = NULL; 20183668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 20195ac9af79SJeremy L Thompson } 20205ac9af79SJeremy L Thompson } else { 20211203703bSJeremy L Thompson CeedQFunction qf; 20221203703bSJeremy L Thompson CeedQFunctionContext ctx; 20231203703bSJeremy L Thompson 2024a98a090bSJeremy L Thompson // Single, non-composite operator 20251203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 20261203703bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &ctx)); 2027c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 20281203703bSJeremy L Thompson if (ctx) { 20291203703bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldLabel(ctx, field_name, field_label)); 2030a98a090bSJeremy L Thompson } else { 2031a98a090bSJeremy L Thompson *field_label = NULL; 2032a98a090bSJeremy L Thompson } 20335ac9af79SJeremy L Thompson } 20345ac9af79SJeremy L Thompson 20355ac9af79SJeremy L Thompson // Set label in operator 20365ac9af79SJeremy L Thompson if (*field_label) { 20375ac9af79SJeremy L Thompson (*field_label)->from_op = true; 20385ac9af79SJeremy L Thompson 20393668ca4bSJeremy L Thompson // Move new composite label to operator 20403668ca4bSJeremy L Thompson if (op->num_context_labels == 0) { 20412b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &op->context_labels)); 20423668ca4bSJeremy L Thompson op->max_context_labels = 1; 20433668ca4bSJeremy L Thompson } else if (op->num_context_labels == op->max_context_labels) { 20442b730f8bSJeremy L Thompson CeedCall(CeedRealloc(2 * op->num_context_labels, &op->context_labels)); 20453668ca4bSJeremy L Thompson op->max_context_labels *= 2; 20463668ca4bSJeremy L Thompson } 20475ac9af79SJeremy L Thompson op->context_labels[op->num_context_labels] = *field_label; 20483668ca4bSJeremy L Thompson op->num_context_labels++; 20493668ca4bSJeremy L Thompson } 20503668ca4bSJeremy L Thompson return CEED_ERROR_SUCCESS; 20513668ca4bSJeremy L Thompson } 20523668ca4bSJeremy L Thompson 20533668ca4bSJeremy L Thompson /** 2054ca94c3ddSJeremy L Thompson @brief Set `CeedQFunctionContext` field holding double precision values. 20554385fb7fSSebastian Grimberg 2056ca94c3ddSJeremy L Thompson For composite operators, the values are set in all sub-operator `CeedQFunctionContext` that have a matching `field_name`. 2057d8dd9a91SJeremy L Thompson 2058ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 20592788fa27SJeremy L Thompson @param[in] field_label Label of field to set 2060ea61e9acSJeremy L Thompson @param[in] values Values to set 2061d8dd9a91SJeremy L Thompson 2062d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2063d8dd9a91SJeremy L Thompson 2064d8dd9a91SJeremy L Thompson @ref User 2065d8dd9a91SJeremy L Thompson **/ 206617b0d5c6SJeremy L Thompson int CeedOperatorSetContextDouble(CeedOperator op, CeedContextFieldLabel field_label, double *values) { 20672b730f8bSJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_DOUBLE, values); 2068d8dd9a91SJeremy L Thompson } 2069d8dd9a91SJeremy L Thompson 2070d8dd9a91SJeremy L Thompson /** 2071ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field holding double precision values, read-only. 20724385fb7fSSebastian Grimberg 2073ca94c3ddSJeremy L Thompson For composite operators, the values correspond to the first sub-operator `CeedQFunctionContext` that has a matching `field_name`. 20742788fa27SJeremy L Thompson 2075ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 20762788fa27SJeremy L Thompson @param[in] field_label Label of field to get 20772788fa27SJeremy L Thompson @param[out] num_values Number of values in the field label 20782788fa27SJeremy L Thompson @param[out] values Pointer to context values 20792788fa27SJeremy L Thompson 20802788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 20812788fa27SJeremy L Thompson 20822788fa27SJeremy L Thompson @ref User 20832788fa27SJeremy L Thompson **/ 208417b0d5c6SJeremy L Thompson int CeedOperatorGetContextDoubleRead(CeedOperator op, CeedContextFieldLabel field_label, size_t *num_values, const double **values) { 20852788fa27SJeremy L Thompson return CeedOperatorContextGetGenericRead(op, field_label, CEED_CONTEXT_FIELD_DOUBLE, num_values, values); 20862788fa27SJeremy L Thompson } 20872788fa27SJeremy L Thompson 20882788fa27SJeremy L Thompson /** 2089ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field holding double precision values, read-only. 20902788fa27SJeremy L Thompson 2091ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 20922788fa27SJeremy L Thompson @param[in] field_label Label of field to restore 20932788fa27SJeremy L Thompson @param[out] values Pointer to context values 20942788fa27SJeremy L Thompson 20952788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 20962788fa27SJeremy L Thompson 20972788fa27SJeremy L Thompson @ref User 20982788fa27SJeremy L Thompson **/ 209917b0d5c6SJeremy L Thompson int CeedOperatorRestoreContextDoubleRead(CeedOperator op, CeedContextFieldLabel field_label, const double **values) { 21002788fa27SJeremy L Thompson return CeedOperatorContextRestoreGenericRead(op, field_label, CEED_CONTEXT_FIELD_DOUBLE, values); 21012788fa27SJeremy L Thompson } 21022788fa27SJeremy L Thompson 21032788fa27SJeremy L Thompson /** 2104ca94c3ddSJeremy L Thompson @brief Set `CeedQFunctionContext` field holding `int32` values. 21054385fb7fSSebastian Grimberg 2106ca94c3ddSJeremy L Thompson For composite operators, the values are set in all sub-operator `CeedQFunctionContext` that have a matching `field_name`. 2107d8dd9a91SJeremy L Thompson 2108ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 2109ea61e9acSJeremy L Thompson @param[in] field_label Label of field to set 2110ea61e9acSJeremy L Thompson @param[in] values Values to set 2111d8dd9a91SJeremy L Thompson 2112d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2113d8dd9a91SJeremy L Thompson 2114d8dd9a91SJeremy L Thompson @ref User 2115d8dd9a91SJeremy L Thompson **/ 211623dbfd29SJeremy L Thompson int CeedOperatorSetContextInt32(CeedOperator op, CeedContextFieldLabel field_label, int32_t *values) { 21172b730f8bSJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_INT32, values); 2118d8dd9a91SJeremy L Thompson } 2119d8dd9a91SJeremy L Thompson 2120d8dd9a91SJeremy L Thompson /** 2121ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field holding `int32` values, read-only. 21224385fb7fSSebastian Grimberg 2123ca94c3ddSJeremy L Thompson For composite operators, the values correspond to the first sub-operator `CeedQFunctionContext` that has a matching `field_name`. 21242788fa27SJeremy L Thompson 2125ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 21262788fa27SJeremy L Thompson @param[in] field_label Label of field to get 2127ca94c3ddSJeremy L Thompson @param[out] num_values Number of `int32` values in `values` 21282788fa27SJeremy L Thompson @param[out] values Pointer to context values 21292788fa27SJeremy L Thompson 21302788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21312788fa27SJeremy L Thompson 21322788fa27SJeremy L Thompson @ref User 21332788fa27SJeremy L Thompson **/ 213423dbfd29SJeremy L Thompson int CeedOperatorGetContextInt32Read(CeedOperator op, CeedContextFieldLabel field_label, size_t *num_values, const int32_t **values) { 21352788fa27SJeremy L Thompson return CeedOperatorContextGetGenericRead(op, field_label, CEED_CONTEXT_FIELD_INT32, num_values, values); 21362788fa27SJeremy L Thompson } 21372788fa27SJeremy L Thompson 21382788fa27SJeremy L Thompson /** 2139ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field holding `int32` values, read-only. 21402788fa27SJeremy L Thompson 2141ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 21422788fa27SJeremy L Thompson @param[in] field_label Label of field to get 21432788fa27SJeremy L Thompson @param[out] values Pointer to context values 21442788fa27SJeremy L Thompson 21452788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21462788fa27SJeremy L Thompson 21472788fa27SJeremy L Thompson @ref User 21482788fa27SJeremy L Thompson **/ 214923dbfd29SJeremy L Thompson int CeedOperatorRestoreContextInt32Read(CeedOperator op, CeedContextFieldLabel field_label, const int32_t **values) { 21502788fa27SJeremy L Thompson return CeedOperatorContextRestoreGenericRead(op, field_label, CEED_CONTEXT_FIELD_INT32, values); 21512788fa27SJeremy L Thompson } 21522788fa27SJeremy L Thompson 21532788fa27SJeremy L Thompson /** 2154ca94c3ddSJeremy L Thompson @brief Set `CeedQFunctionContext` field holding boolean values. 21555b6ec284SJeremy L Thompson 2156ca94c3ddSJeremy L Thompson For composite operators, the values are set in all sub-operator `CeedQFunctionContext` that have a matching `field_name`. 21575b6ec284SJeremy L Thompson 2158ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 21595b6ec284SJeremy L Thompson @param[in] field_label Label of field to set 21605b6ec284SJeremy L Thompson @param[in] values Values to set 21615b6ec284SJeremy L Thompson 21625b6ec284SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21635b6ec284SJeremy L Thompson 21645b6ec284SJeremy L Thompson @ref User 21655b6ec284SJeremy L Thompson **/ 21665b6ec284SJeremy L Thompson int CeedOperatorSetContextBoolean(CeedOperator op, CeedContextFieldLabel field_label, bool *values) { 21675b6ec284SJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_BOOL, values); 21685b6ec284SJeremy L Thompson } 21695b6ec284SJeremy L Thompson 21705b6ec284SJeremy L Thompson /** 2171ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field holding boolean values, read-only. 21725b6ec284SJeremy L Thompson 2173ca94c3ddSJeremy L Thompson For composite operators, the values correspond to the first sub-operator `CeedQFunctionContext` that has a matching `field_name`. 21745b6ec284SJeremy L Thompson 2175ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 21765b6ec284SJeremy L Thompson @param[in] field_label Label of field to get 2177ca94c3ddSJeremy L Thompson @param[out] num_values Number of boolean values in `values` 21785b6ec284SJeremy L Thompson @param[out] values Pointer to context values 21795b6ec284SJeremy L Thompson 21805b6ec284SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21815b6ec284SJeremy L Thompson 21825b6ec284SJeremy L Thompson @ref User 21835b6ec284SJeremy L Thompson **/ 21845b6ec284SJeremy L Thompson int CeedOperatorGetContextBooleanRead(CeedOperator op, CeedContextFieldLabel field_label, size_t *num_values, const bool **values) { 21855b6ec284SJeremy L Thompson return CeedOperatorContextGetGenericRead(op, field_label, CEED_CONTEXT_FIELD_BOOL, num_values, values); 21865b6ec284SJeremy L Thompson } 21875b6ec284SJeremy L Thompson 21885b6ec284SJeremy L Thompson /** 2189ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field holding boolean values, read-only. 21905b6ec284SJeremy L Thompson 2191ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 21925b6ec284SJeremy L Thompson @param[in] field_label Label of field to get 21935b6ec284SJeremy L Thompson @param[out] values Pointer to context values 21945b6ec284SJeremy L Thompson 21955b6ec284SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21965b6ec284SJeremy L Thompson 21975b6ec284SJeremy L Thompson @ref User 21985b6ec284SJeremy L Thompson **/ 21995b6ec284SJeremy L Thompson int CeedOperatorRestoreContextBooleanRead(CeedOperator op, CeedContextFieldLabel field_label, const bool **values) { 22005b6ec284SJeremy L Thompson return CeedOperatorContextRestoreGenericRead(op, field_label, CEED_CONTEXT_FIELD_BOOL, values); 22015b6ec284SJeremy L Thompson } 22025b6ec284SJeremy L Thompson 22035b6ec284SJeremy L Thompson /** 2204ca94c3ddSJeremy L Thompson @brief Apply `CeedOperator` to a `CeedVector`. 2205d7b241e6Sjeremylt 2206ea61e9acSJeremy L Thompson This computes the action of the operator on the specified (active) input, yielding its (active) output. 2207ca94c3ddSJeremy L Thompson All inputs and outputs must be specified using @ref CeedOperatorSetField(). 2208d7b241e6Sjeremylt 22095da5ab9fSZach Atkins @note Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 2210f04ea552SJeremy L Thompson 2211ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to apply 2212ca94c3ddSJeremy L Thompson @param[in] in `CeedVector` containing input state or @ref CEED_VECTOR_NONE if there are no active inputs 2213ca94c3ddSJeremy L Thompson @param[out] out `CeedVector` to store result of applying operator (must be distinct from `in`) or @ref CEED_VECTOR_NONE if there are no active outputs 2214ca94c3ddSJeremy L Thompson @param[in] request Address of @ref CeedRequest for non-blocking completion, else @ref CEED_REQUEST_IMMEDIATE 2215b11c1e72Sjeremylt 2216b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 2217dfdf5a53Sjeremylt 22187a982d89SJeremy L. Thompson @ref User 2219b11c1e72Sjeremylt **/ 22202b730f8bSJeremy L Thompson int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, CeedRequest *request) { 22211203703bSJeremy L Thompson bool is_composite; 22221203703bSJeremy L Thompson 22232b730f8bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 2224d7b241e6Sjeremylt 22251203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 22260db52efcSZach Atkins if (is_composite && op->ApplyComposite) { 2227250756a7Sjeremylt // Composite Operator 22282b730f8bSJeremy L Thompson CeedCall(op->ApplyComposite(op, in, out, request)); 22290db52efcSZach Atkins } else if (!is_composite && op->Apply) { 22303ca2b39bSJeremy L Thompson // Standard Operator 22313ca2b39bSJeremy L Thompson CeedCall(op->Apply(op, in, out, request)); 22323ca2b39bSJeremy L Thompson } else { 22330db52efcSZach Atkins // Standard or composite, default to zeroing out and calling ApplyAddActive 22340db52efcSZach Atkins // Zero active output 22350db52efcSZach Atkins if (out != CEED_VECTOR_NONE) CeedCall(CeedVectorSetValue(out, 0.0)); 22361203703bSJeremy L Thompson 22370db52efcSZach Atkins // ApplyAddActive 22380db52efcSZach Atkins CeedCall(CeedOperatorApplyAddActive(op, in, out, request)); 2239250756a7Sjeremylt } 2240e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2241cae8b89aSjeremylt } 2242cae8b89aSjeremylt 2243cae8b89aSjeremylt /** 2244ca94c3ddSJeremy L Thompson @brief Apply `CeedOperator` to a `CeedVector` and add result to output `CeedVector`. 2245cae8b89aSjeremylt 2246ea61e9acSJeremy L Thompson This computes the action of the operator on the specified (active) input, yielding its (active) output. 2247ca94c3ddSJeremy L Thompson All inputs and outputs must be specified using @ref CeedOperatorSetField(). 2248cae8b89aSjeremylt 22495da5ab9fSZach Atkins @note Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 22505da5ab9fSZach Atkins @warning This function adds into ALL outputs, including passive outputs. To only add into the active output, use `CeedOperatorApplyAddActive()`. 22515da5ab9fSZach Atkins @see `CeedOperatorApplyAddActive()` 22525da5ab9fSZach Atkins 2253ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to apply 2254ca94c3ddSJeremy L Thompson @param[in] in `CeedVector` containing input state or @ref CEED_VECTOR_NONE if there are no active inputs 2255ca94c3ddSJeremy L Thompson @param[out] out `CeedVector` to sum in result of applying operator (must be distinct from `in`) or @ref CEED_VECTOR_NONE if there are no active outputs 2256ca94c3ddSJeremy L Thompson @param[in] request Address of @ref CeedRequest for non-blocking completion, else @ref CEED_REQUEST_IMMEDIATE 2257cae8b89aSjeremylt 2258cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 2259cae8b89aSjeremylt 22607a982d89SJeremy L. Thompson @ref User 2261cae8b89aSjeremylt **/ 22622b730f8bSJeremy L Thompson int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, CeedRequest *request) { 22631203703bSJeremy L Thompson bool is_composite; 22641203703bSJeremy L Thompson 22652b730f8bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 2266cae8b89aSjeremylt 22671203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 22681203703bSJeremy L Thompson if (is_composite) { 2269250756a7Sjeremylt // Composite Operator 2270250756a7Sjeremylt if (op->ApplyAddComposite) { 22712b730f8bSJeremy L Thompson CeedCall(op->ApplyAddComposite(op, in, out, request)); 2272cae8b89aSjeremylt } else { 2273d1d35e2fSjeremylt CeedInt num_suboperators; 2274d1d35e2fSjeremylt CeedOperator *sub_operators; 2275250756a7Sjeremylt 2276ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 2277ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 2278d1d35e2fSjeremylt for (CeedInt i = 0; i < num_suboperators; i++) { 22792b730f8bSJeremy L Thompson CeedCall(CeedOperatorApplyAdd(sub_operators[i], in, out, request)); 22801d7d2407SJeremy L Thompson } 2281250756a7Sjeremylt } 22821203703bSJeremy L Thompson } else if (op->num_elem > 0) { 22833ca2b39bSJeremy L Thompson // Standard Operator 22843ca2b39bSJeremy L Thompson CeedCall(op->ApplyAdd(op, in, out, request)); 2285250756a7Sjeremylt } 2286e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2287d7b241e6Sjeremylt } 2288d7b241e6Sjeremylt 2289d7b241e6Sjeremylt /** 22905da5ab9fSZach Atkins @brief Apply `CeedOperator` to a `CeedVector` and add result to output `CeedVector`. Only sums into active outputs, overwrites passive outputs. 22915da5ab9fSZach Atkins 22925da5ab9fSZach Atkins This computes the action of the operator on the specified (active) input, yielding its (active) output. 22935da5ab9fSZach Atkins All inputs and outputs must be specified using @ref CeedOperatorSetField(). 22945da5ab9fSZach Atkins 22955da5ab9fSZach Atkins @note Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 22965da5ab9fSZach Atkins 22975da5ab9fSZach Atkins @param[in] op `CeedOperator` to apply 22985da5ab9fSZach Atkins @param[in] in `CeedVector` containing input state or @ref CEED_VECTOR_NONE if there are no active inputs 22995da5ab9fSZach Atkins @param[out] out `CeedVector` to sum in result of applying operator (must be distinct from `in`) or @ref CEED_VECTOR_NONE if there are no active outputs 23005da5ab9fSZach Atkins @param[in] request Address of @ref CeedRequest for non-blocking completion, else @ref CEED_REQUEST_IMMEDIATE 23015da5ab9fSZach Atkins 23025da5ab9fSZach Atkins @return An error code: 0 - success, otherwise - failure 23035da5ab9fSZach Atkins 23045da5ab9fSZach Atkins @ref User 23055da5ab9fSZach Atkins **/ 23065da5ab9fSZach Atkins int CeedOperatorApplyAddActive(CeedOperator op, CeedVector in, CeedVector out, CeedRequest *request) { 23075da5ab9fSZach Atkins bool is_composite; 23085da5ab9fSZach Atkins 23095da5ab9fSZach Atkins CeedCall(CeedOperatorCheckReady(op)); 23105da5ab9fSZach Atkins 23115da5ab9fSZach Atkins CeedCall(CeedOperatorIsComposite(op, &is_composite)); 23125da5ab9fSZach Atkins if (is_composite) { 23135da5ab9fSZach Atkins // Composite Operator 23145da5ab9fSZach Atkins CeedInt num_suboperators; 23155da5ab9fSZach Atkins CeedOperator *sub_operators; 23165da5ab9fSZach Atkins 2317ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 2318ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 23195da5ab9fSZach Atkins 23205da5ab9fSZach Atkins // Zero all output vectors 23215da5ab9fSZach Atkins for (CeedInt i = 0; i < num_suboperators; i++) { 23225da5ab9fSZach Atkins CeedInt num_output_fields; 23235da5ab9fSZach Atkins CeedOperatorField *output_fields; 23245da5ab9fSZach Atkins 23255da5ab9fSZach Atkins CeedCall(CeedOperatorGetFields(sub_operators[i], NULL, NULL, &num_output_fields, &output_fields)); 23265da5ab9fSZach Atkins for (CeedInt j = 0; j < num_output_fields; j++) { 23275da5ab9fSZach Atkins CeedVector vec; 23285da5ab9fSZach Atkins 23295da5ab9fSZach Atkins CeedCall(CeedOperatorFieldGetVector(output_fields[j], &vec)); 23305da5ab9fSZach Atkins if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) CeedCall(CeedVectorSetValue(vec, 0.0)); 23315da5ab9fSZach Atkins CeedCall(CeedVectorDestroy(&vec)); 23325da5ab9fSZach Atkins } 23335da5ab9fSZach Atkins } 23345da5ab9fSZach Atkins // ApplyAdd 23355da5ab9fSZach Atkins CeedCall(CeedOperatorApplyAdd(op, in, out, request)); 23365da5ab9fSZach Atkins } else { 23375da5ab9fSZach Atkins // Standard Operator 23385da5ab9fSZach Atkins CeedInt num_output_fields; 23395da5ab9fSZach Atkins CeedOperatorField *output_fields; 23405da5ab9fSZach Atkins 23415da5ab9fSZach Atkins CeedCall(CeedOperatorGetFields(op, NULL, NULL, &num_output_fields, &output_fields)); 23425da5ab9fSZach Atkins // Zero all output vectors 23435da5ab9fSZach Atkins for (CeedInt i = 0; i < num_output_fields; i++) { 23445da5ab9fSZach Atkins CeedVector vec; 23455da5ab9fSZach Atkins 23465da5ab9fSZach Atkins CeedCall(CeedOperatorFieldGetVector(output_fields[i], &vec)); 23475da5ab9fSZach Atkins if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) CeedCall(CeedVectorSetValue(vec, 0.0)); 23485da5ab9fSZach Atkins CeedCall(CeedVectorDestroy(&vec)); 23495da5ab9fSZach Atkins } 23505da5ab9fSZach Atkins // ApplyAdd 23515da5ab9fSZach Atkins CeedCall(CeedOperatorApplyAdd(op, in, out, request)); 23525da5ab9fSZach Atkins } 23535da5ab9fSZach Atkins return CEED_ERROR_SUCCESS; 23545da5ab9fSZach Atkins } 23555da5ab9fSZach Atkins 23565da5ab9fSZach Atkins /** 2357536b928cSSebastian Grimberg @brief Destroy temporary assembly data associated with a `CeedOperator` 2358536b928cSSebastian Grimberg 2359536b928cSSebastian Grimberg @param[in,out] op `CeedOperator` whose assembly data to destroy 2360536b928cSSebastian Grimberg 2361536b928cSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 2362536b928cSSebastian Grimberg 2363536b928cSSebastian Grimberg @ref User 2364536b928cSSebastian Grimberg **/ 2365536b928cSSebastian Grimberg int CeedOperatorAssemblyDataStrip(CeedOperator op) { 2366536b928cSSebastian Grimberg bool is_composite; 2367536b928cSSebastian Grimberg 2368536b928cSSebastian Grimberg CeedCall(CeedQFunctionAssemblyDataDestroy(&op->qf_assembled)); 2369536b928cSSebastian Grimberg CeedCall(CeedOperatorAssemblyDataDestroy(&op->op_assembled)); 2370536b928cSSebastian Grimberg CeedCall(CeedOperatorIsComposite(op, &is_composite)); 2371536b928cSSebastian Grimberg if (is_composite) { 2372536b928cSSebastian Grimberg CeedInt num_suboperators; 2373536b928cSSebastian Grimberg CeedOperator *sub_operators; 2374536b928cSSebastian Grimberg 2375ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 2376ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 2377536b928cSSebastian Grimberg for (CeedInt i = 0; i < num_suboperators; i++) { 2378536b928cSSebastian Grimberg CeedCall(CeedQFunctionAssemblyDataDestroy(&sub_operators[i]->qf_assembled)); 2379536b928cSSebastian Grimberg CeedCall(CeedOperatorAssemblyDataDestroy(&sub_operators[i]->op_assembled)); 2380536b928cSSebastian Grimberg } 2381536b928cSSebastian Grimberg } 2382536b928cSSebastian Grimberg return CEED_ERROR_SUCCESS; 2383536b928cSSebastian Grimberg } 2384536b928cSSebastian Grimberg 2385536b928cSSebastian Grimberg /** 2386ca94c3ddSJeremy L Thompson @brief Destroy a `CeedOperator` 2387d7b241e6Sjeremylt 2388ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` to destroy 2389b11c1e72Sjeremylt 2390b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 2391dfdf5a53Sjeremylt 23927a982d89SJeremy L. Thompson @ref User 2393b11c1e72Sjeremylt **/ 2394d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 2395b0f67a9cSJeremy L Thompson if (!*op || CeedObjectDereference((CeedObject)*op) > 0) { 2396ad6481ceSJeremy L Thompson *op = NULL; 2397ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 2398ad6481ceSJeremy L Thompson } 2399f883f0a5SSebastian Grimberg // Backend destroy 2400f883f0a5SSebastian Grimberg if ((*op)->Destroy) { 2401f883f0a5SSebastian Grimberg CeedCall((*op)->Destroy(*op)); 2402f883f0a5SSebastian Grimberg } 2403fe2413ffSjeremylt // Free fields 24042b730f8bSJeremy L Thompson for (CeedInt i = 0; i < (*op)->num_fields; i++) { 2405d1d35e2fSjeremylt if ((*op)->input_fields[i]) { 2406437c7c90SJeremy L Thompson if ((*op)->input_fields[i]->elem_rstr != CEED_ELEMRESTRICTION_NONE) { 2407437c7c90SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&(*op)->input_fields[i]->elem_rstr)); 240815910d16Sjeremylt } 2409356036faSJeremy L Thompson if ((*op)->input_fields[i]->basis != CEED_BASIS_NONE) { 24102b730f8bSJeremy L Thompson CeedCall(CeedBasisDestroy(&(*op)->input_fields[i]->basis)); 241171352a93Sjeremylt } 24122b730f8bSJeremy L Thompson if ((*op)->input_fields[i]->vec != CEED_VECTOR_ACTIVE && (*op)->input_fields[i]->vec != CEED_VECTOR_NONE) { 24132b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&(*op)->input_fields[i]->vec)); 241471352a93Sjeremylt } 24152b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->input_fields[i]->field_name)); 24162b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->input_fields[i])); 2417fe2413ffSjeremylt } 24182b730f8bSJeremy L Thompson } 24192b730f8bSJeremy L Thompson for (CeedInt i = 0; i < (*op)->num_fields; i++) { 2420d1d35e2fSjeremylt if ((*op)->output_fields[i]) { 2421437c7c90SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&(*op)->output_fields[i]->elem_rstr)); 2422356036faSJeremy L Thompson if ((*op)->output_fields[i]->basis != CEED_BASIS_NONE) { 24232b730f8bSJeremy L Thompson CeedCall(CeedBasisDestroy(&(*op)->output_fields[i]->basis)); 242471352a93Sjeremylt } 24252b730f8bSJeremy L Thompson if ((*op)->output_fields[i]->vec != CEED_VECTOR_ACTIVE && (*op)->output_fields[i]->vec != CEED_VECTOR_NONE) { 24262b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&(*op)->output_fields[i]->vec)); 242771352a93Sjeremylt } 24282b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->output_fields[i]->field_name)); 24292b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->output_fields[i])); 24302b730f8bSJeremy L Thompson } 2431fe2413ffSjeremylt } 2432f883f0a5SSebastian Grimberg CeedCall(CeedFree(&(*op)->input_fields)); 2433f883f0a5SSebastian Grimberg CeedCall(CeedFree(&(*op)->output_fields)); 2434f883f0a5SSebastian Grimberg // Destroy AtPoints data 243548acf710SJeremy L Thompson CeedCall(CeedVectorDestroy(&(*op)->point_coords)); 243648acf710SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&(*op)->rstr_points)); 243748acf710SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&(*op)->first_points_rstr)); 2438c6b536a8SSebastian Grimberg // Destroy assembly data (must happen before destroying sub_operators) 2439f883f0a5SSebastian Grimberg CeedCall(CeedOperatorAssemblyDataStrip(*op)); 2440d1d35e2fSjeremylt // Destroy sub_operators 24412b730f8bSJeremy L Thompson for (CeedInt i = 0; i < (*op)->num_suboperators; i++) { 2442d1d35e2fSjeremylt if ((*op)->sub_operators[i]) { 24432b730f8bSJeremy L Thompson CeedCall(CeedOperatorDestroy(&(*op)->sub_operators[i])); 244452d6035fSJeremy L Thompson } 24452b730f8bSJeremy L Thompson } 2446f883f0a5SSebastian Grimberg CeedCall(CeedFree(&(*op)->sub_operators)); 24472b730f8bSJeremy L Thompson CeedCall(CeedQFunctionDestroy(&(*op)->qf)); 24482b730f8bSJeremy L Thompson CeedCall(CeedQFunctionDestroy(&(*op)->dqf)); 24492b730f8bSJeremy L Thompson CeedCall(CeedQFunctionDestroy(&(*op)->dqfT)); 24503668ca4bSJeremy L Thompson // Destroy any composite labels 24515ac9af79SJeremy L Thompson if ((*op)->is_composite) { 24523668ca4bSJeremy L Thompson for (CeedInt i = 0; i < (*op)->num_context_labels; i++) { 24532b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->context_labels[i]->sub_labels)); 24542b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->context_labels[i])); 24553668ca4bSJeremy L Thompson } 24565ac9af79SJeremy L Thompson } 24572b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->context_labels)); 2458fe2413ffSjeremylt 24595107b09fSJeremy L Thompson // Destroy fallback 24602b730f8bSJeremy L Thompson CeedCall(CeedOperatorDestroy(&(*op)->op_fallback)); 24615107b09fSJeremy L Thompson 24622b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->name)); 2463*6c328a79SJeremy L Thompson CeedCall(CeedObjectDestroy_Private(&(*op)->obj)); 24642b730f8bSJeremy L Thompson CeedCall(CeedFree(op)); 2465e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2466d7b241e6Sjeremylt } 2467d7b241e6Sjeremylt 2468d7b241e6Sjeremylt /// @} 2469