1*9ba83ac0SJeremy L Thompson // Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors. 23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 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 /** 178681d0ea7SJeremy L Thompson @brief Find the active input vector `CeedBasis` for a non-composite `CeedOperator`. 179681d0ea7SJeremy L Thompson 180681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `active_basis` with @ref CeedBasisDestroy(). 181eaf62fffSJeremy L Thompson 182ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to find active `CeedBasis` for 183ca94c3ddSJeremy L Thompson @param[out] active_basis `CeedBasis` for active input vector or `NULL` for composite operator 184eaf62fffSJeremy L Thompson 185eaf62fffSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 186eaf62fffSJeremy L Thompson 187eaf62fffSJeremy L Thompson @ref Developer 188eaf62fffSJeremy L Thompson **/ 189eaf62fffSJeremy L Thompson int CeedOperatorGetActiveBasis(CeedOperator op, CeedBasis *active_basis) { 190506b1a0cSSebastian Grimberg CeedCall(CeedOperatorGetActiveBases(op, active_basis, NULL)); 191506b1a0cSSebastian Grimberg return CEED_ERROR_SUCCESS; 192506b1a0cSSebastian Grimberg } 193506b1a0cSSebastian Grimberg 194506b1a0cSSebastian Grimberg /** 195681d0ea7SJeremy L Thompson @brief Find the active input and output vector `CeedBasis` for a non-composite `CeedOperator`. 196681d0ea7SJeremy L Thompson 197681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the bases with @ref CeedBasisDestroy(). 198506b1a0cSSebastian Grimberg 199ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to find active `CeedBasis` for 200ca94c3ddSJeremy L Thompson @param[out] active_input_basis `CeedBasis` for active input vector or `NULL` for composite operator 201ca94c3ddSJeremy L Thompson @param[out] active_output_basis `CeedBasis` for active output vector or `NULL` for composite operator 202506b1a0cSSebastian Grimberg 203506b1a0cSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 204506b1a0cSSebastian Grimberg 205506b1a0cSSebastian Grimberg @ref Developer 206506b1a0cSSebastian Grimberg **/ 207506b1a0cSSebastian Grimberg int CeedOperatorGetActiveBases(CeedOperator op, CeedBasis *active_input_basis, CeedBasis *active_output_basis) { 2081203703bSJeremy L Thompson bool is_composite; 2091203703bSJeremy L Thompson CeedInt num_input_fields, num_output_fields; 2101203703bSJeremy L Thompson CeedOperatorField *op_input_fields, *op_output_fields; 2111c66c397SJeremy L Thompson 2121203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 2131203703bSJeremy L Thompson CeedCall(CeedOperatorGetFields(op, &num_input_fields, &op_input_fields, &num_output_fields, &op_output_fields)); 2141203703bSJeremy L Thompson 215506b1a0cSSebastian Grimberg if (active_input_basis) { 216506b1a0cSSebastian Grimberg *active_input_basis = NULL; 2171203703bSJeremy L Thompson if (!is_composite) { 2181203703bSJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 2191203703bSJeremy L Thompson CeedVector vec; 2201203703bSJeremy L Thompson 2211203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_input_fields[i], &vec)); 2221203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 2231203703bSJeremy L Thompson CeedBasis basis; 2241203703bSJeremy L Thompson 2251203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(op_input_fields[i], &basis)); 2269bc66399SJeremy L Thompson CeedCheck(!*active_input_basis || *active_input_basis == basis, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, 2279bc66399SJeremy L Thompson "Multiple active input CeedBases found"); 228681d0ea7SJeremy L Thompson if (!*active_input_basis) CeedCall(CeedBasisReferenceCopy(basis, active_input_basis)); 229681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 230eaf62fffSJeremy L Thompson } 231681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 2322b730f8bSJeremy L Thompson } 2339bc66399SJeremy L Thompson CeedCheck(*active_input_basis, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "No active input CeedBasis found"); 234506b1a0cSSebastian Grimberg } 235506b1a0cSSebastian Grimberg } 236506b1a0cSSebastian Grimberg if (active_output_basis) { 237506b1a0cSSebastian Grimberg *active_output_basis = NULL; 2381203703bSJeremy L Thompson if (!is_composite) { 2391203703bSJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 2401203703bSJeremy L Thompson CeedVector vec; 2411203703bSJeremy L Thompson 2421203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_output_fields[i], &vec)); 2431203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 2441203703bSJeremy L Thompson CeedBasis basis; 2451203703bSJeremy L Thompson 2461203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(op_output_fields[i], &basis)); 2479bc66399SJeremy L Thompson CeedCheck(!*active_output_basis || *active_output_basis == basis, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, 2489bc66399SJeremy L Thompson "Multiple active output CeedBases found"); 249681d0ea7SJeremy L Thompson if (!*active_output_basis) CeedCall(CeedBasisReferenceCopy(basis, active_output_basis)); 250681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 251506b1a0cSSebastian Grimberg } 252681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 253506b1a0cSSebastian Grimberg } 2549bc66399SJeremy L Thompson CeedCheck(*active_output_basis, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "No active output CeedBasis found"); 255506b1a0cSSebastian Grimberg } 256506b1a0cSSebastian Grimberg } 257eaf62fffSJeremy L Thompson return CEED_ERROR_SUCCESS; 258eaf62fffSJeremy L Thompson } 259eaf62fffSJeremy L Thompson 260eaf62fffSJeremy L Thompson /** 261681d0ea7SJeremy L Thompson @brief Find the active vector `CeedElemRestriction` for a non-composite `CeedOperator`. 262681d0ea7SJeremy L Thompson 263681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `active_rstr` with @ref CeedElemRestrictionDestroy(). 264e2f04181SAndrew T. Barker 265ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to find active `CeedElemRestriction` for 266ca94c3ddSJeremy L Thompson @param[out] active_rstr `CeedElemRestriction` for active input vector or NULL for composite operator 267e2f04181SAndrew T. Barker 268e2f04181SAndrew T. Barker @return An error code: 0 - success, otherwise - failure 269e2f04181SAndrew T. Barker 270e2f04181SAndrew T. Barker @ref Utility 271e2f04181SAndrew T. Barker **/ 2722b730f8bSJeremy L Thompson int CeedOperatorGetActiveElemRestriction(CeedOperator op, CeedElemRestriction *active_rstr) { 273506b1a0cSSebastian Grimberg CeedCall(CeedOperatorGetActiveElemRestrictions(op, active_rstr, NULL)); 274506b1a0cSSebastian Grimberg return CEED_ERROR_SUCCESS; 275506b1a0cSSebastian Grimberg } 276506b1a0cSSebastian Grimberg 277506b1a0cSSebastian Grimberg /** 278681d0ea7SJeremy L Thompson @brief Find the active input and output vector `CeedElemRestriction` for a non-composite `CeedOperator`. 279681d0ea7SJeremy L Thompson 280681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the restrictions with @ref CeedElemRestrictionDestroy(). 281506b1a0cSSebastian Grimberg 282ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to find active `CeedElemRestriction` for 283ca94c3ddSJeremy L Thompson @param[out] active_input_rstr `CeedElemRestriction` for active input vector or NULL for composite operator 284ca94c3ddSJeremy L Thompson @param[out] active_output_rstr `CeedElemRestriction` for active output vector or NULL for composite operator 285506b1a0cSSebastian Grimberg 286506b1a0cSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 287506b1a0cSSebastian Grimberg 288506b1a0cSSebastian Grimberg @ref Utility 289506b1a0cSSebastian Grimberg **/ 290506b1a0cSSebastian Grimberg int CeedOperatorGetActiveElemRestrictions(CeedOperator op, CeedElemRestriction *active_input_rstr, CeedElemRestriction *active_output_rstr) { 2911203703bSJeremy L Thompson bool is_composite; 2921203703bSJeremy L Thompson CeedInt num_input_fields, num_output_fields; 2931203703bSJeremy L Thompson CeedOperatorField *op_input_fields, *op_output_fields; 2941c66c397SJeremy L Thompson 2951203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 2961203703bSJeremy L Thompson CeedCall(CeedOperatorGetFields(op, &num_input_fields, &op_input_fields, &num_output_fields, &op_output_fields)); 2971203703bSJeremy L Thompson 298506b1a0cSSebastian Grimberg if (active_input_rstr) { 299506b1a0cSSebastian Grimberg *active_input_rstr = NULL; 3001203703bSJeremy L Thompson if (!is_composite) { 3011203703bSJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 3021203703bSJeremy L Thompson CeedVector vec; 3031203703bSJeremy L Thompson 3041203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_input_fields[i], &vec)); 3051203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 3061203703bSJeremy L Thompson CeedElemRestriction rstr; 3071203703bSJeremy L Thompson 3081203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetElemRestriction(op_input_fields[i], &rstr)); 3099bc66399SJeremy L Thompson CeedCheck(!*active_input_rstr || *active_input_rstr == rstr, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, 3109bc66399SJeremy L Thompson "Multiple active input CeedElemRestrictions found"); 311681d0ea7SJeremy L Thompson if (!*active_input_rstr) CeedCall(CeedElemRestrictionReferenceCopy(rstr, active_input_rstr)); 312681d0ea7SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr)); 313e2f04181SAndrew T. Barker } 314681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 3152b730f8bSJeremy L Thompson } 3169bc66399SJeremy L Thompson CeedCheck(*active_input_rstr, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "No active input CeedElemRestriction found"); 317506b1a0cSSebastian Grimberg } 318506b1a0cSSebastian Grimberg } 319506b1a0cSSebastian Grimberg if (active_output_rstr) { 320506b1a0cSSebastian Grimberg *active_output_rstr = NULL; 3211203703bSJeremy L Thompson if (!is_composite) { 3221203703bSJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 3231203703bSJeremy L Thompson CeedVector vec; 3241203703bSJeremy L Thompson 3251203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_output_fields[i], &vec)); 3261203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 3271203703bSJeremy L Thompson CeedElemRestriction rstr; 3281203703bSJeremy L Thompson 3291203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetElemRestriction(op_output_fields[i], &rstr)); 3309bc66399SJeremy L Thompson CeedCheck(!*active_output_rstr || *active_output_rstr == rstr, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, 3319bc66399SJeremy L Thompson "Multiple active output CeedElemRestrictions found"); 332681d0ea7SJeremy L Thompson if (!*active_output_rstr) CeedCall(CeedElemRestrictionReferenceCopy(rstr, active_output_rstr)); 333681d0ea7SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr)); 334506b1a0cSSebastian Grimberg } 335681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 336506b1a0cSSebastian Grimberg } 3379bc66399SJeremy L Thompson CeedCheck(*active_output_rstr, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "No active output CeedElemRestriction found"); 338506b1a0cSSebastian Grimberg } 339506b1a0cSSebastian Grimberg } 340e2f04181SAndrew T. Barker return CEED_ERROR_SUCCESS; 341e2f04181SAndrew T. Barker } 342e2f04181SAndrew T. Barker 343d8dd9a91SJeremy L Thompson /** 344ca94c3ddSJeremy L Thompson @brief Set `CeedQFunctionContext` field values of the specified type. 3454385fb7fSSebastian Grimberg 346ca94c3ddSJeremy L Thompson For composite operators, the value is set in all sub-operator `CeedQFunctionContext` that have a matching `field_name`. 347ca94c3ddSJeremy 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. 348d8dd9a91SJeremy L Thompson 349ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 350ea61e9acSJeremy L Thompson @param[in] field_label Label of field to set 351ea61e9acSJeremy L Thompson @param[in] field_type Type of field to set 3522788fa27SJeremy L Thompson @param[in] values Values to set 353d8dd9a91SJeremy L Thompson 354d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 355d8dd9a91SJeremy L Thompson 3566ab8e59fSJames Wright @ref Developer 357d8dd9a91SJeremy L Thompson **/ 3582788fa27SJeremy L Thompson static int CeedOperatorContextSetGeneric(CeedOperator op, CeedContextFieldLabel field_label, CeedContextFieldType field_type, void *values) { 3591c66c397SJeremy L Thompson bool is_composite = false; 3601c66c397SJeremy L Thompson 3619bc66399SJeremy L Thompson CeedCheck(field_label, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3623668ca4bSJeremy L Thompson 3635ac9af79SJeremy L Thompson // Check if field_label and op correspond 3645ac9af79SJeremy L Thompson if (field_label->from_op) { 3655ac9af79SJeremy L Thompson CeedInt index = -1; 3665ac9af79SJeremy L Thompson 3675ac9af79SJeremy L Thompson for (CeedInt i = 0; i < op->num_context_labels; i++) { 3685ac9af79SJeremy L Thompson if (op->context_labels[i] == field_label) index = i; 3695ac9af79SJeremy L Thompson } 3709bc66399SJeremy L Thompson CeedCheck(index != -1, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "ContextFieldLabel does not correspond to the operator"); 3715ac9af79SJeremy L Thompson } 3725ac9af79SJeremy L Thompson 3732b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 374d8dd9a91SJeremy L Thompson if (is_composite) { 375d8dd9a91SJeremy L Thompson CeedInt num_sub; 376d8dd9a91SJeremy L Thompson CeedOperator *sub_operators; 377d8dd9a91SJeremy L Thompson 378ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_sub)); 379ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 3809bc66399SJeremy L Thompson CeedCheck(num_sub == field_label->num_sub_labels, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, 3819bc66399SJeremy L Thompson "Composite operator modified after ContextFieldLabel created"); 382d8dd9a91SJeremy L Thompson 383d8dd9a91SJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 3841203703bSJeremy L Thompson CeedQFunctionContext ctx; 3851203703bSJeremy L Thompson 3861485364cSJeremy L Thompson CeedCall(CeedOperatorGetContext(sub_operators[i], &ctx)); 387d8dd9a91SJeremy L Thompson // Try every sub-operator, ok if some sub-operators do not have field 3881485364cSJeremy L Thompson if (ctx && field_label->sub_labels[i]) { 3891203703bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label->sub_labels[i], field_type, values)); 390d8dd9a91SJeremy L Thompson } 3911485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 392d8dd9a91SJeremy L Thompson } 393d8dd9a91SJeremy L Thompson } else { 3941203703bSJeremy L Thompson CeedQFunctionContext ctx; 3951203703bSJeremy L Thompson 3961485364cSJeremy L Thompson CeedCall(CeedOperatorGetContext(op, &ctx)); 3979bc66399SJeremy L Thompson CeedCheck(ctx, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "QFunction does not have context data"); 3981203703bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, field_type, values)); 3991485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 4002788fa27SJeremy L Thompson } 4016d95ab46SJeremy L Thompson CeedCall(CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(op, true)); 4022788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4032788fa27SJeremy L Thompson } 4042788fa27SJeremy L Thompson 4052788fa27SJeremy L Thompson /** 406ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field values of the specified type, read-only. 4074385fb7fSSebastian Grimberg 408ca94c3ddSJeremy L Thompson For composite operators, the values retrieved are for the first sub-operator `CeedQFunctionContext` that have a matching `field_name`. 409ca94c3ddSJeremy 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. 4102788fa27SJeremy L Thompson 411ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 4122788fa27SJeremy L Thompson @param[in] field_label Label of field to set 4132788fa27SJeremy L Thompson @param[in] field_type Type of field to set 414c5d0f995SJed Brown @param[out] num_values Number of values of type `field_type` in array `values` 415c5d0f995SJed Brown @param[out] values Values in the label 4162788fa27SJeremy L Thompson 4172788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4182788fa27SJeremy L Thompson 4196ab8e59fSJames Wright @ref Developer 4202788fa27SJeremy L Thompson **/ 4212788fa27SJeremy L Thompson static int CeedOperatorContextGetGenericRead(CeedOperator op, CeedContextFieldLabel field_label, CeedContextFieldType field_type, size_t *num_values, 4222788fa27SJeremy L Thompson void *values) { 4231c66c397SJeremy L Thompson bool is_composite = false; 4241c66c397SJeremy L Thompson 4259bc66399SJeremy L Thompson CeedCheck(field_label, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4262788fa27SJeremy L Thompson 4272788fa27SJeremy L Thompson *(void **)values = NULL; 4282788fa27SJeremy L Thompson *num_values = 0; 4292788fa27SJeremy L Thompson 4305ac9af79SJeremy L Thompson // Check if field_label and op correspond 4315ac9af79SJeremy L Thompson if (field_label->from_op) { 4325ac9af79SJeremy L Thompson CeedInt index = -1; 4335ac9af79SJeremy L Thompson 4345ac9af79SJeremy L Thompson for (CeedInt i = 0; i < op->num_context_labels; i++) { 4355ac9af79SJeremy L Thompson if (op->context_labels[i] == field_label) index = i; 4365ac9af79SJeremy L Thompson } 4379bc66399SJeremy L Thompson CeedCheck(index != -1, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "ContextFieldLabel does not correspond to the operator"); 4385ac9af79SJeremy L Thompson } 4395ac9af79SJeremy L Thompson 4402788fa27SJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 4412788fa27SJeremy L Thompson if (is_composite) { 4422788fa27SJeremy L Thompson CeedInt num_sub; 4432788fa27SJeremy L Thompson CeedOperator *sub_operators; 4442788fa27SJeremy L Thompson 445ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_sub)); 446ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 4479bc66399SJeremy L Thompson CeedCheck(num_sub == field_label->num_sub_labels, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, 4489bc66399SJeremy L Thompson "Composite operator modified after ContextFieldLabel created"); 4492788fa27SJeremy L Thompson 4502788fa27SJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 4511203703bSJeremy L Thompson CeedQFunctionContext ctx; 4521203703bSJeremy L Thompson 4531485364cSJeremy L Thompson CeedCall(CeedOperatorGetContext(sub_operators[i], &ctx)); 4542788fa27SJeremy L Thompson // Try every sub-operator, ok if some sub-operators do not have field 4551485364cSJeremy L Thompson if (ctx && field_label->sub_labels[i]) { 4561203703bSJeremy L Thompson CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label->sub_labels[i], field_type, num_values, values)); 4571485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 4582788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4592788fa27SJeremy L Thompson } 4601485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 4612788fa27SJeremy L Thompson } 4622788fa27SJeremy L Thompson } else { 4631203703bSJeremy L Thompson CeedQFunctionContext ctx; 4641203703bSJeremy L Thompson 4651485364cSJeremy L Thompson CeedCall(CeedOperatorGetContext(op, &ctx)); 4669bc66399SJeremy L Thompson CeedCheck(ctx, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "QFunction does not have context data"); 4671203703bSJeremy L Thompson CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, field_type, num_values, values)); 4681485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 4692788fa27SJeremy L Thompson } 4702788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4712788fa27SJeremy L Thompson } 4722788fa27SJeremy L Thompson 4732788fa27SJeremy L Thompson /** 474ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field values of the specified type, read-only. 4754385fb7fSSebastian Grimberg 476ca94c3ddSJeremy L Thompson For composite operators, the values restored are for the first sub-operator `CeedQFunctionContext` that have a matching `field_name`. 477ca94c3ddSJeremy 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. 4782788fa27SJeremy L Thompson 479ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 4802788fa27SJeremy L Thompson @param[in] field_label Label of field to set 4812788fa27SJeremy L Thompson @param[in] field_type Type of field to set 482c5d0f995SJed Brown @param[in] values Values array to restore 4832788fa27SJeremy L Thompson 4842788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4852788fa27SJeremy L Thompson 4866ab8e59fSJames Wright @ref Developer 4872788fa27SJeremy L Thompson **/ 4882788fa27SJeremy L Thompson static int CeedOperatorContextRestoreGenericRead(CeedOperator op, CeedContextFieldLabel field_label, CeedContextFieldType field_type, void *values) { 4891c66c397SJeremy L Thompson bool is_composite = false; 4901c66c397SJeremy L Thompson 4919bc66399SJeremy L Thompson CeedCheck(field_label, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4922788fa27SJeremy L Thompson 4935ac9af79SJeremy L Thompson // Check if field_label and op correspond 4945ac9af79SJeremy L Thompson if (field_label->from_op) { 4955ac9af79SJeremy L Thompson CeedInt index = -1; 4965ac9af79SJeremy L Thompson 4975ac9af79SJeremy L Thompson for (CeedInt i = 0; i < op->num_context_labels; i++) { 4985ac9af79SJeremy L Thompson if (op->context_labels[i] == field_label) index = i; 4995ac9af79SJeremy L Thompson } 5009bc66399SJeremy L Thompson CeedCheck(index != -1, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "ContextFieldLabel does not correspond to the operator"); 5015ac9af79SJeremy L Thompson } 5025ac9af79SJeremy L Thompson 5032788fa27SJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 5042788fa27SJeremy L Thompson if (is_composite) { 5052788fa27SJeremy L Thompson CeedInt num_sub; 5062788fa27SJeremy L Thompson CeedOperator *sub_operators; 5072788fa27SJeremy L Thompson 508ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_sub)); 509ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 5109bc66399SJeremy L Thompson CeedCheck(num_sub == field_label->num_sub_labels, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, 5119bc66399SJeremy L Thompson "Composite operator modified after ContextFieldLabel created"); 5122788fa27SJeremy L Thompson 5132788fa27SJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 5141203703bSJeremy L Thompson CeedQFunctionContext ctx; 5151203703bSJeremy L Thompson 5161485364cSJeremy L Thompson CeedCall(CeedOperatorGetContext(sub_operators[i], &ctx)); 5172788fa27SJeremy L Thompson // Try every sub-operator, ok if some sub-operators do not have field 5181485364cSJeremy L Thompson if (ctx && field_label->sub_labels[i]) { 5191203703bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label->sub_labels[i], field_type, values)); 5201485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 5212788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 5222788fa27SJeremy L Thompson } 5231485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 5242788fa27SJeremy L Thompson } 5252788fa27SJeremy L Thompson } else { 5261203703bSJeremy L Thompson CeedQFunctionContext ctx; 5271203703bSJeremy L Thompson 5281485364cSJeremy L Thompson CeedCall(CeedOperatorGetContext(op, &ctx)); 5299bc66399SJeremy L Thompson CeedCheck(ctx, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "QFunction does not have context data"); 5301203703bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, field_type, values)); 5311485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 532d8dd9a91SJeremy L Thompson } 533d8dd9a91SJeremy L Thompson return CEED_ERROR_SUCCESS; 534d8dd9a91SJeremy L Thompson } 535d8dd9a91SJeremy L Thompson 5367a982d89SJeremy L. Thompson /// @} 5377a982d89SJeremy L. Thompson 5387a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5397a982d89SJeremy L. Thompson /// CeedOperator Backend API 5407a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5417a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorBackend 5427a982d89SJeremy L. Thompson /// @{ 5437a982d89SJeremy L. Thompson 5447a982d89SJeremy L. Thompson /** 545ca94c3ddSJeremy L Thompson @brief Get the number of arguments associated with a `CeedOperator` 5467a982d89SJeremy L. Thompson 547ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 548d1d35e2fSjeremylt @param[out] num_args Variable to store vector number of arguments 5497a982d89SJeremy L. Thompson 5507a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5517a982d89SJeremy L. Thompson 5527a982d89SJeremy L. Thompson @ref Backend 5537a982d89SJeremy L. Thompson **/ 554d1d35e2fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *num_args) { 5551203703bSJeremy L Thompson bool is_composite; 5561203703bSJeremy L Thompson 5571203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 5586e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Not defined for composite operators"); 559d1d35e2fSjeremylt *num_args = op->num_fields; 560e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5617a982d89SJeremy L. Thompson } 5627a982d89SJeremy L. Thompson 5637a982d89SJeremy L. Thompson /** 5649463e855SJeremy L Thompson @brief Get the tensor product status of all bases for a `CeedOperator`. 5659463e855SJeremy L Thompson 5669463e855SJeremy L Thompson `has_tensor_bases` is only set to `true` if every field uses a tensor-product basis. 5679463e855SJeremy L Thompson 5689463e855SJeremy L Thompson @param[in] op `CeedOperator` 5699463e855SJeremy L Thompson @param[out] has_tensor_bases Variable to store tensor bases status 5709463e855SJeremy L Thompson 5719463e855SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 5729463e855SJeremy L Thompson 5739463e855SJeremy L Thompson @ref Backend 5749463e855SJeremy L Thompson **/ 5759463e855SJeremy L Thompson int CeedOperatorHasTensorBases(CeedOperator op, bool *has_tensor_bases) { 5769463e855SJeremy L Thompson CeedInt num_inputs, num_outputs; 5779463e855SJeremy L Thompson CeedOperatorField *input_fields, *output_fields; 5789463e855SJeremy L Thompson 5799463e855SJeremy L Thompson CeedCall(CeedOperatorGetFields(op, &num_inputs, &input_fields, &num_outputs, &output_fields)); 5809463e855SJeremy L Thompson *has_tensor_bases = true; 5819463e855SJeremy L Thompson for (CeedInt i = 0; i < num_inputs; i++) { 5829463e855SJeremy L Thompson bool is_tensor; 5839463e855SJeremy L Thompson CeedBasis basis; 5849463e855SJeremy L Thompson 5859463e855SJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(input_fields[i], &basis)); 5869463e855SJeremy L Thompson if (basis != CEED_BASIS_NONE) { 5879463e855SJeremy L Thompson CeedCall(CeedBasisIsTensor(basis, &is_tensor)); 588025ec10cSJeremy L Thompson *has_tensor_bases = *has_tensor_bases & is_tensor; 5899463e855SJeremy L Thompson } 590681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 5919463e855SJeremy L Thompson } 5929463e855SJeremy L Thompson for (CeedInt i = 0; i < num_outputs; i++) { 5939463e855SJeremy L Thompson bool is_tensor; 5949463e855SJeremy L Thompson CeedBasis basis; 5959463e855SJeremy L Thompson 5969463e855SJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(output_fields[i], &basis)); 5979463e855SJeremy L Thompson if (basis != CEED_BASIS_NONE) { 5989463e855SJeremy L Thompson CeedCall(CeedBasisIsTensor(basis, &is_tensor)); 599025ec10cSJeremy L Thompson *has_tensor_bases = *has_tensor_bases & is_tensor; 6009463e855SJeremy L Thompson } 601681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 6029463e855SJeremy L Thompson } 6039463e855SJeremy L Thompson return CEED_ERROR_SUCCESS; 6049463e855SJeremy L Thompson } 6059463e855SJeremy L Thompson 6069463e855SJeremy L Thompson /** 6071203703bSJeremy L Thompson @brief Get a boolean value indicating if the `CeedOperator` is immutable 6081203703bSJeremy L Thompson 6091203703bSJeremy L Thompson @param[in] op `CeedOperator` 6101203703bSJeremy L Thompson @param[out] is_immutable Variable to store immutability status 6111203703bSJeremy L Thompson 6121203703bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 6131203703bSJeremy L Thompson 6141203703bSJeremy L Thompson @ref Backend 6151203703bSJeremy L Thompson **/ 6161203703bSJeremy L Thompson int CeedOperatorIsImmutable(CeedOperator op, bool *is_immutable) { 6171203703bSJeremy L Thompson *is_immutable = op->is_immutable; 6181203703bSJeremy L Thompson return CEED_ERROR_SUCCESS; 6191203703bSJeremy L Thompson } 6201203703bSJeremy L Thompson 6211203703bSJeremy L Thompson /** 622ca94c3ddSJeremy L Thompson @brief Get the setup status of a `CeedOperator` 6237a982d89SJeremy L. Thompson 624ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 625d1d35e2fSjeremylt @param[out] is_setup_done Variable to store setup status 6267a982d89SJeremy L. Thompson 6277a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6287a982d89SJeremy L. Thompson 6297a982d89SJeremy L. Thompson @ref Backend 6307a982d89SJeremy L. Thompson **/ 631d1d35e2fSjeremylt int CeedOperatorIsSetupDone(CeedOperator op, bool *is_setup_done) { 632f04ea552SJeremy L Thompson *is_setup_done = op->is_backend_setup; 633e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6347a982d89SJeremy L. Thompson } 6357a982d89SJeremy L. Thompson 6367a982d89SJeremy L. Thompson /** 637ca94c3ddSJeremy L Thompson @brief Get the `CeedQFunction` associated with a `CeedOperator` 6387a982d89SJeremy L. Thompson 639ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 640ca94c3ddSJeremy L Thompson @param[out] qf Variable to store `CeedQFunction` 6417a982d89SJeremy L. Thompson 6427a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6437a982d89SJeremy L. Thompson 6447a982d89SJeremy L. Thompson @ref Backend 6457a982d89SJeremy L. Thompson **/ 6467a982d89SJeremy L. Thompson int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 6471203703bSJeremy L Thompson bool is_composite; 6481203703bSJeremy L Thompson 6491203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 6506e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Not defined for composite operator"); 651c11e12f4SJeremy L Thompson *qf = NULL; 652c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionReferenceCopy(op->qf, qf)); 653e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6547a982d89SJeremy L. Thompson } 6557a982d89SJeremy L. Thompson 6567a982d89SJeremy L. Thompson /** 657ca94c3ddSJeremy L Thompson @brief Get a boolean value indicating if the `CeedOperator` is composite 658c04a41a7SJeremy L Thompson 659ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 660d1d35e2fSjeremylt @param[out] is_composite Variable to store composite status 661c04a41a7SJeremy L Thompson 662c04a41a7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 663c04a41a7SJeremy L Thompson 664c04a41a7SJeremy L Thompson @ref Backend 665c04a41a7SJeremy L Thompson **/ 666d1d35e2fSjeremylt int CeedOperatorIsComposite(CeedOperator op, bool *is_composite) { 667f04ea552SJeremy L Thompson *is_composite = op->is_composite; 668e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 669c04a41a7SJeremy L Thompson } 670c04a41a7SJeremy L Thompson 671c04a41a7SJeremy L Thompson /** 672ca94c3ddSJeremy L Thompson @brief Get the backend data of a `CeedOperator` 6737a982d89SJeremy L. Thompson 674ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 6757a982d89SJeremy L. Thompson @param[out] data Variable to store data 6767a982d89SJeremy L. Thompson 6777a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6787a982d89SJeremy L. Thompson 6797a982d89SJeremy L. Thompson @ref Backend 6807a982d89SJeremy L. Thompson **/ 681777ff853SJeremy L Thompson int CeedOperatorGetData(CeedOperator op, void *data) { 682777ff853SJeremy L Thompson *(void **)data = op->data; 683e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6847a982d89SJeremy L. Thompson } 6857a982d89SJeremy L. Thompson 6867a982d89SJeremy L. Thompson /** 687ca94c3ddSJeremy L Thompson @brief Set the backend data of a `CeedOperator` 6887a982d89SJeremy L. Thompson 689ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 690ea61e9acSJeremy L Thompson @param[in] data Data to set 6917a982d89SJeremy L. Thompson 6927a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6937a982d89SJeremy L. Thompson 6947a982d89SJeremy L. Thompson @ref Backend 6957a982d89SJeremy L. Thompson **/ 696777ff853SJeremy L Thompson int CeedOperatorSetData(CeedOperator op, void *data) { 697777ff853SJeremy L Thompson op->data = data; 698e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6997a982d89SJeremy L. Thompson } 7007a982d89SJeremy L. Thompson 7017a982d89SJeremy L. Thompson /** 702ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `CeedOperator` 70334359f16Sjeremylt 704ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` to increment the reference counter 70534359f16Sjeremylt 70634359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 70734359f16Sjeremylt 70834359f16Sjeremylt @ref Backend 70934359f16Sjeremylt **/ 7109560d06aSjeremylt int CeedOperatorReference(CeedOperator op) { 71134359f16Sjeremylt op->ref_count++; 71234359f16Sjeremylt return CEED_ERROR_SUCCESS; 71334359f16Sjeremylt } 71434359f16Sjeremylt 71534359f16Sjeremylt /** 716ca94c3ddSJeremy L Thompson @brief Set the setup flag of a `CeedOperator` to `true` 7177a982d89SJeremy L. Thompson 718ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 7197a982d89SJeremy L. Thompson 7207a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 7217a982d89SJeremy L. Thompson 7227a982d89SJeremy L. Thompson @ref Backend 7237a982d89SJeremy L. Thompson **/ 7247a982d89SJeremy L. Thompson int CeedOperatorSetSetupDone(CeedOperator op) { 725f04ea552SJeremy L Thompson op->is_backend_setup = true; 726e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7277a982d89SJeremy L. Thompson } 7287a982d89SJeremy L. Thompson 7297a982d89SJeremy L. Thompson /// @} 7307a982d89SJeremy L. Thompson 7317a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 7327a982d89SJeremy L. Thompson /// CeedOperator Public API 7337a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 7347a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorUser 735dfdf5a53Sjeremylt /// @{ 736d7b241e6Sjeremylt 737d7b241e6Sjeremylt /** 738ca94c3ddSJeremy L Thompson @brief Create a `CeedOperator` and associate a `CeedQFunction`. 7394385fb7fSSebastian Grimberg 740ca94c3ddSJeremy L Thompson A `CeedBasis` and `CeedElemRestriction` can be associated with `CeedQFunction` fields with @ref CeedOperatorSetField(). 741d7b241e6Sjeremylt 742ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedOperator` 743ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` defining the action of the operator at quadrature points 744ca94c3ddSJeremy L Thompson @param[in] dqf `CeedQFunction` defining the action of the Jacobian of `qf` (or @ref CEED_QFUNCTION_NONE) 745ca94c3ddSJeremy L Thompson @param[in] dqfT `CeedQFunction` defining the action of the transpose of the Jacobian of `qf` (or @ref CEED_QFUNCTION_NONE) 746ca94c3ddSJeremy L Thompson @param[out] op Address of the variable where the newly created `CeedOperator` will be stored 747b11c1e72Sjeremylt 748b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 749dfdf5a53Sjeremylt 7507a982d89SJeremy L. Thompson @ref User 751d7b241e6Sjeremylt */ 7522b730f8bSJeremy L Thompson int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, CeedQFunction dqfT, CeedOperator *op) { 7535fe0d4faSjeremylt if (!ceed->OperatorCreate) { 7545fe0d4faSjeremylt Ceed delegate; 7556574a04fSJeremy L Thompson 7562b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Operator")); 7571ef3a2a9SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedOperatorCreate"); 7582b730f8bSJeremy L Thompson CeedCall(CeedOperatorCreate(delegate, qf, dqf, dqfT, op)); 7599bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 760e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7615fe0d4faSjeremylt } 7625fe0d4faSjeremylt 763ca94c3ddSJeremy L Thompson CeedCheck(qf && qf != CEED_QFUNCTION_NONE, ceed, CEED_ERROR_MINOR, "Operator must have a valid CeedQFunction."); 764db002c03SJeremy L Thompson 7652b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, op)); 766db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*op)->ceed)); 767d1d35e2fSjeremylt (*op)->ref_count = 1; 7682b104005SJeremy L Thompson (*op)->input_size = -1; 7692b104005SJeremy L Thompson (*op)->output_size = -1; 770db002c03SJeremy L Thompson CeedCall(CeedQFunctionReferenceCopy(qf, &(*op)->qf)); 771db002c03SJeremy L Thompson if (dqf && dqf != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionReferenceCopy(dqf, &(*op)->dqf)); 772db002c03SJeremy L Thompson if (dqfT && dqfT != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionReferenceCopy(dqfT, &(*op)->dqfT)); 7732b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*op)->input_fields)); 7742b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*op)->output_fields)); 7752b730f8bSJeremy L Thompson CeedCall(ceed->OperatorCreate(*op)); 776e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 777d7b241e6Sjeremylt } 778d7b241e6Sjeremylt 779d7b241e6Sjeremylt /** 780ca94c3ddSJeremy L Thompson @brief Create a `CeedOperator` for evaluation at evaluation at arbitrary points in each element. 78148acf710SJeremy L Thompson 782ca94c3ddSJeremy L Thompson A `CeedBasis` and `CeedElemRestriction` can be associated with `CeedQFunction` fields with `CeedOperator` SetField. 783ca94c3ddSJeremy L Thompson The locations of each point are set with @ref CeedOperatorAtPointsSetPoints(). 78448acf710SJeremy L Thompson 785ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedOperator` 786ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` defining the action of the operator at quadrature points 787ca94c3ddSJeremy L Thompson @param[in] dqf `CeedQFunction` defining the action of the Jacobian of @a qf (or @ref CEED_QFUNCTION_NONE) 788ca94c3ddSJeremy L Thompson @param[in] dqfT `CeedQFunction` defining the action of the transpose of the Jacobian of @a qf (or @ref CEED_QFUNCTION_NONE) 78948acf710SJeremy L Thompson @param[out] op Address of the variable where the newly created CeedOperator will be stored 79048acf710SJeremy L Thompson 79148acf710SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 79248acf710SJeremy L Thompson 79348acf710SJeremy L Thompson @ref User 79448acf710SJeremy L Thompson */ 79548acf710SJeremy L Thompson int CeedOperatorCreateAtPoints(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, CeedQFunction dqfT, CeedOperator *op) { 79648acf710SJeremy L Thompson if (!ceed->OperatorCreateAtPoints) { 79748acf710SJeremy L Thompson Ceed delegate; 79848acf710SJeremy L Thompson 79948acf710SJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Operator")); 8001ef3a2a9SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedOperatorCreateAtPoints"); 80148acf710SJeremy L Thompson CeedCall(CeedOperatorCreateAtPoints(delegate, qf, dqf, dqfT, op)); 8029bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 80348acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 80448acf710SJeremy L Thompson } 80548acf710SJeremy L Thompson 806ca94c3ddSJeremy L Thompson CeedCheck(qf && qf != CEED_QFUNCTION_NONE, ceed, CEED_ERROR_MINOR, "Operator must have a valid CeedQFunction."); 80748acf710SJeremy L Thompson 80848acf710SJeremy L Thompson CeedCall(CeedCalloc(1, op)); 80948acf710SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*op)->ceed)); 81048acf710SJeremy L Thompson (*op)->ref_count = 1; 81148acf710SJeremy L Thompson (*op)->is_at_points = true; 81248acf710SJeremy L Thompson (*op)->input_size = -1; 81348acf710SJeremy L Thompson (*op)->output_size = -1; 81448acf710SJeremy L Thompson CeedCall(CeedQFunctionReferenceCopy(qf, &(*op)->qf)); 81548acf710SJeremy L Thompson if (dqf && dqf != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionReferenceCopy(dqf, &(*op)->dqf)); 81648acf710SJeremy L Thompson if (dqfT && dqfT != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionReferenceCopy(dqfT, &(*op)->dqfT)); 81748acf710SJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*op)->input_fields)); 81848acf710SJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*op)->output_fields)); 81948acf710SJeremy L Thompson CeedCall(ceed->OperatorCreateAtPoints(*op)); 82048acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 82148acf710SJeremy L Thompson } 82248acf710SJeremy L Thompson 82348acf710SJeremy L Thompson /** 824ca94c3ddSJeremy L Thompson @brief Create a composite `CeedOperator` that composes the action of several `CeedOperator` 82552d6035fSJeremy L Thompson 826ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedOperator` 827ca94c3ddSJeremy L Thompson @param[out] op Address of the variable where the newly created composite `CeedOperator` will be stored 82852d6035fSJeremy L Thompson 82952d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 83052d6035fSJeremy L Thompson 8317a982d89SJeremy L. Thompson @ref User 83252d6035fSJeremy L Thompson */ 833ed094490SJeremy L Thompson int CeedOperatorCreateComposite(Ceed ceed, CeedOperator *op) { 83452d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 83552d6035fSJeremy L Thompson Ceed delegate; 83652d6035fSJeremy L Thompson 8371c66c397SJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Operator")); 838250756a7Sjeremylt if (delegate) { 839ed094490SJeremy L Thompson CeedCall(CeedOperatorCreateComposite(delegate, op)); 8409bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 841e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 84252d6035fSJeremy L Thompson } 843250756a7Sjeremylt } 84452d6035fSJeremy L Thompson 8452b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, op)); 846db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*op)->ceed)); 847996d9ab5SJed Brown (*op)->ref_count = 1; 848f04ea552SJeremy L Thompson (*op)->is_composite = true; 8492b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_COMPOSITE_MAX, &(*op)->sub_operators)); 8502b104005SJeremy L Thompson (*op)->input_size = -1; 8512b104005SJeremy L Thompson (*op)->output_size = -1; 852250756a7Sjeremylt 853db002c03SJeremy L Thompson if (ceed->CompositeOperatorCreate) CeedCall(ceed->CompositeOperatorCreate(*op)); 854e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 85552d6035fSJeremy L Thompson } 85652d6035fSJeremy L Thompson 85752d6035fSJeremy L Thompson /** 858ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedOperator`. 8594385fb7fSSebastian Grimberg 860ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedOperatorDestroy(). 861512bb800SJeremy L Thompson 862ca94c3ddSJeremy 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`. 863ca94c3ddSJeremy L Thompson This `CeedOperator` will be destroyed if `*op_copy` is the only reference to this `CeedOperator`. 8649560d06aSjeremylt 865ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to copy reference to 866ea61e9acSJeremy L Thompson @param[in,out] op_copy Variable to store copied reference 8679560d06aSjeremylt 8689560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 8699560d06aSjeremylt 8709560d06aSjeremylt @ref User 8719560d06aSjeremylt **/ 8729560d06aSjeremylt int CeedOperatorReferenceCopy(CeedOperator op, CeedOperator *op_copy) { 8732b730f8bSJeremy L Thompson CeedCall(CeedOperatorReference(op)); 8742b730f8bSJeremy L Thompson CeedCall(CeedOperatorDestroy(op_copy)); 8759560d06aSjeremylt *op_copy = op; 8769560d06aSjeremylt return CEED_ERROR_SUCCESS; 8779560d06aSjeremylt } 8789560d06aSjeremylt 8799560d06aSjeremylt /** 880ca94c3ddSJeremy L Thompson @brief Provide a field to a `CeedOperator` for use by its `CeedQFunction`. 881d7b241e6Sjeremylt 882ca94c3ddSJeremy L Thompson This function is used to specify both active and passive fields to a `CeedOperator`. 883bafebce1SSebastian Grimberg For passive fields, a `CeedVector` `vec` must be provided. 884ea61e9acSJeremy L Thompson Passive fields can inputs or outputs (updated in-place when operator is applied). 885d7b241e6Sjeremylt 886ca94c3ddSJeremy L Thompson Active fields must be specified using this function, but their data (in a `CeedVector`) is passed in @ref CeedOperatorApply(). 887ca94c3ddSJeremy L Thompson There can be at most one active input `CeedVector` and at most one active output@ref CeedVector passed to @ref CeedOperatorApply(). 888d7b241e6Sjeremylt 889528a22edSJeremy L Thompson The number of quadrature points must agree across all points. 890bafebce1SSebastian Grimberg When using @ref CEED_BASIS_NONE, the number of quadrature points is determined by the element size of `rstr`. 891528a22edSJeremy L Thompson 892ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` on which to provide the field 893ca94c3ddSJeremy L Thompson @param[in] field_name Name of the field (to be matched with the name used by `CeedQFunction`) 894bafebce1SSebastian Grimberg @param[in] rstr `CeedElemRestriction` 895bafebce1SSebastian Grimberg @param[in] basis `CeedBasis` in which the field resides or @ref CEED_BASIS_NONE if collocated with quadrature points 896bafebce1SSebastian 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` 897b11c1e72Sjeremylt 898b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 899dfdf5a53Sjeremylt 9007a982d89SJeremy L. Thompson @ref User 901b11c1e72Sjeremylt **/ 902bafebce1SSebastian Grimberg int CeedOperatorSetField(CeedOperator op, const char *field_name, CeedElemRestriction rstr, CeedBasis basis, CeedVector vec) { 9031203703bSJeremy L Thompson bool is_input = true, is_at_points, is_composite, is_immutable; 9041203703bSJeremy L Thompson CeedInt num_elem = 0, num_qpts = 0, num_input_fields, num_output_fields; 9051203703bSJeremy L Thompson CeedQFunction qf; 9061203703bSJeremy L Thompson CeedQFunctionField qf_field, *qf_input_fields, *qf_output_fields; 9071c66c397SJeremy L Thompson CeedOperatorField *op_field; 9081c66c397SJeremy L Thompson 9091203703bSJeremy L Thompson CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 9101203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 9111203703bSJeremy L Thompson CeedCall(CeedOperatorIsImmutable(op, &is_immutable)); 9129bc66399SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "Cannot add field to composite operator."); 9139bc66399SJeremy L Thompson CeedCheck(!is_immutable, CeedOperatorReturnCeed(op), CEED_ERROR_MAJOR, "Operator cannot be changed after set as immutable"); 9149bc66399SJeremy L Thompson CeedCheck(rstr, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "CeedElemRestriction rstr for field \"%s\" must be non-NULL.", field_name); 9159bc66399SJeremy L Thompson CeedCheck(basis, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "CeedBasis basis for field \"%s\" must be non-NULL.", field_name); 9169bc66399SJeremy L Thompson CeedCheck(vec, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "CeedVector vec for field \"%s\" must be non-NULL.", field_name); 91752d6035fSJeremy L Thompson 918bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 9199bc66399SJeremy L Thompson CeedCheck(rstr == CEED_ELEMRESTRICTION_NONE || !op->has_restriction || num_elem == op->num_elem, CeedOperatorReturnCeed(op), CEED_ERROR_DIMENSION, 920ca94c3ddSJeremy L Thompson "CeedElemRestriction with %" CeedInt_FMT " elements incompatible with prior %" CeedInt_FMT " elements", num_elem, op->num_elem); 9212c7e7413SJeremy L Thompson { 9222c7e7413SJeremy L Thompson CeedRestrictionType rstr_type; 9232c7e7413SJeremy L Thompson 924bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 92548acf710SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) { 9269bc66399SJeremy L Thompson CeedCheck(is_at_points, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, 9279bc66399SJeremy L Thompson "CeedElemRestriction AtPoints not supported for standard operator fields"); 9289bc66399SJeremy L Thompson CeedCheck(basis == CEED_BASIS_NONE, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, 9299bc66399SJeremy L Thompson "CeedElemRestriction AtPoints must be used with CEED_BASIS_NONE"); 93048acf710SJeremy L Thompson if (!op->first_points_rstr) { 931bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &op->first_points_rstr)); 93248acf710SJeremy L Thompson } else { 93348acf710SJeremy L Thompson bool are_compatible; 93448acf710SJeremy L Thompson 935bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionAtPointsAreCompatible(op->first_points_rstr, rstr, &are_compatible)); 9369bc66399SJeremy L Thompson CeedCheck(are_compatible, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 937ca94c3ddSJeremy L Thompson "CeedElemRestriction must have compatible offsets with previously set CeedElemRestriction"); 93848acf710SJeremy L Thompson } 93948acf710SJeremy L Thompson } 9402c7e7413SJeremy L Thompson } 941d7b241e6Sjeremylt 942bafebce1SSebastian Grimberg if (basis == CEED_BASIS_NONE) CeedCall(CeedElemRestrictionGetElementSize(rstr, &num_qpts)); 943bafebce1SSebastian Grimberg else CeedCall(CeedBasisGetNumQuadraturePoints(basis, &num_qpts)); 9449bc66399SJeremy L Thompson CeedCheck(op->num_qpts == 0 || num_qpts == op->num_qpts, CeedOperatorReturnCeed(op), CEED_ERROR_DIMENSION, 945ca94c3ddSJeremy L Thompson "%s must correspond to the same number of quadrature points as previously added CeedBases. Found %" CeedInt_FMT 946528a22edSJeremy L Thompson " quadrature points but expected %" CeedInt_FMT " quadrature points.", 947bafebce1SSebastian Grimberg basis == CEED_BASIS_NONE ? "CeedElemRestriction" : "CeedBasis", num_qpts, op->num_qpts); 9481203703bSJeremy L Thompson 9491203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 9501203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFields(qf, &num_input_fields, &qf_input_fields, &num_output_fields, &qf_output_fields)); 951c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 9521203703bSJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 9536f8994e9SJeremy L Thompson const char *qf_field_name; 9541203703bSJeremy L Thompson 9551203703bSJeremy L Thompson CeedCall(CeedQFunctionFieldGetName(qf_input_fields[i], &qf_field_name)); 9561203703bSJeremy L Thompson if (!strcmp(field_name, qf_field_name)) { 9571203703bSJeremy L Thompson qf_field = qf_input_fields[i]; 958d1d35e2fSjeremylt op_field = &op->input_fields[i]; 959d7b241e6Sjeremylt goto found; 960d7b241e6Sjeremylt } 961d7b241e6Sjeremylt } 9622b104005SJeremy L Thompson is_input = false; 9631203703bSJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 9646f8994e9SJeremy L Thompson const char *qf_field_name; 9651203703bSJeremy L Thompson 9661203703bSJeremy L Thompson CeedCall(CeedQFunctionFieldGetName(qf_output_fields[i], &qf_field_name)); 9671203703bSJeremy L Thompson if (!strcmp(field_name, qf_field_name)) { 9681203703bSJeremy L Thompson qf_field = qf_output_fields[i]; 969d1d35e2fSjeremylt op_field = &op->output_fields[i]; 970d7b241e6Sjeremylt goto found; 971d7b241e6Sjeremylt } 972d7b241e6Sjeremylt } 973c042f62fSJeremy L Thompson // LCOV_EXCL_START 9749bc66399SJeremy L Thompson return CeedError(CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "CeedQFunction has no knowledge of field '%s'", field_name); 975c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 976d7b241e6Sjeremylt found: 9779bc66399SJeremy L Thompson CeedCall(CeedOperatorCheckField(CeedOperatorReturnCeed(op), qf_field, rstr, basis)); 9782b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, op_field)); 979e15f9bd0SJeremy L Thompson 980bafebce1SSebastian Grimberg if (vec == CEED_VECTOR_ACTIVE) { 9812b104005SJeremy L Thompson CeedSize l_size; 9821c66c397SJeremy L Thompson 983bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &l_size)); 9842b104005SJeremy L Thompson if (is_input) { 9852b104005SJeremy L Thompson if (op->input_size == -1) op->input_size = l_size; 9869bc66399SJeremy L Thompson CeedCheck(l_size == op->input_size, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 987249f8407SJeremy L Thompson "LVector size %" CeedSize_FMT " does not match previous size %" CeedSize_FMT "", l_size, op->input_size); 9882b104005SJeremy L Thompson } else { 9892b104005SJeremy L Thompson if (op->output_size == -1) op->output_size = l_size; 9909bc66399SJeremy L Thompson CeedCheck(l_size == op->output_size, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 991249f8407SJeremy L Thompson "LVector size %" CeedSize_FMT " does not match previous size %" CeedSize_FMT "", l_size, op->output_size); 9922b104005SJeremy L Thompson } 9932b730f8bSJeremy L Thompson } 9942b104005SJeremy L Thompson 995bafebce1SSebastian Grimberg CeedCall(CeedVectorReferenceCopy(vec, &(*op_field)->vec)); 996bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*op_field)->elem_rstr)); 997bafebce1SSebastian Grimberg if (rstr != CEED_ELEMRESTRICTION_NONE && !op->has_restriction) { 998d1d35e2fSjeremylt op->num_elem = num_elem; 999d1d35e2fSjeremylt op->has_restriction = true; // Restriction set, but num_elem may be 0 1000e15f9bd0SJeremy L Thompson } 1001bafebce1SSebastian Grimberg CeedCall(CeedBasisReferenceCopy(basis, &(*op_field)->basis)); 10022a3ff1c9SZach Atkins if (op->num_qpts == 0 && !is_at_points) op->num_qpts = num_qpts; // no consistent number of qpts for OperatorAtPoints 1003d1d35e2fSjeremylt op->num_fields += 1; 10042b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(field_name, (char **)&(*op_field)->field_name)); 1005e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1006d7b241e6Sjeremylt } 1007d7b241e6Sjeremylt 1008d7b241e6Sjeremylt /** 1009ca94c3ddSJeremy L Thompson @brief Get the `CeedOperator` Field of a `CeedOperator`. 101043bbe138SJeremy L Thompson 1011ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 1012f04ea552SJeremy L Thompson 1013ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1014f74ec584SJeremy L Thompson @param[out] num_input_fields Variable to store number of input fields 1015ca94c3ddSJeremy L Thompson @param[out] input_fields Variable to store input fields 1016f74ec584SJeremy L Thompson @param[out] num_output_fields Variable to store number of output fields 1017ca94c3ddSJeremy L Thompson @param[out] output_fields Variable to store output fields 101843bbe138SJeremy L Thompson 101943bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 102043bbe138SJeremy L Thompson 1021e9b533fbSJeremy L Thompson @ref Advanced 102243bbe138SJeremy L Thompson **/ 10232b730f8bSJeremy L Thompson int CeedOperatorGetFields(CeedOperator op, CeedInt *num_input_fields, CeedOperatorField **input_fields, CeedInt *num_output_fields, 102443bbe138SJeremy L Thompson CeedOperatorField **output_fields) { 10251203703bSJeremy L Thompson bool is_composite; 10261203703bSJeremy L Thompson CeedQFunction qf; 10271203703bSJeremy L Thompson 10281203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 10296e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Not defined for composite operator"); 10302b730f8bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 103143bbe138SJeremy L Thompson 10321203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 10331203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFields(qf, num_input_fields, NULL, num_output_fields, NULL)); 1034c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 103543bbe138SJeremy L Thompson if (input_fields) *input_fields = op->input_fields; 103643bbe138SJeremy L Thompson if (output_fields) *output_fields = op->output_fields; 103743bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 103843bbe138SJeremy L Thompson } 103943bbe138SJeremy L Thompson 104043bbe138SJeremy L Thompson /** 1041ca94c3ddSJeremy L Thompson @brief Set the arbitrary points in each element for a `CeedOperator` at points. 104248acf710SJeremy L Thompson 1043ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 104448acf710SJeremy L Thompson 1045ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` at points 1046ca94c3ddSJeremy L Thompson @param[in] rstr_points `CeedElemRestriction` for the coordinates of each point by element 1047ca94c3ddSJeremy L Thompson @param[in] point_coords `CeedVector` holding coordinates of each point 104848acf710SJeremy L Thompson 104948acf710SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 105048acf710SJeremy L Thompson 105148acf710SJeremy L Thompson @ref Advanced 105248acf710SJeremy L Thompson **/ 105348acf710SJeremy L Thompson int CeedOperatorAtPointsSetPoints(CeedOperator op, CeedElemRestriction rstr_points, CeedVector point_coords) { 10541203703bSJeremy L Thompson bool is_at_points, is_immutable; 10552a3ff1c9SZach Atkins 10562a3ff1c9SZach Atkins CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 10571203703bSJeremy L Thompson CeedCall(CeedOperatorIsImmutable(op, &is_immutable)); 10589bc66399SJeremy L Thompson CeedCheck(is_at_points, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for operator at points"); 10599bc66399SJeremy L Thompson CeedCheck(!is_immutable, CeedOperatorReturnCeed(op), CEED_ERROR_MAJOR, "Operator cannot be changed after set as immutable"); 106048acf710SJeremy L Thompson 106148acf710SJeremy L Thompson if (!op->first_points_rstr) { 106248acf710SJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(rstr_points, &op->first_points_rstr)); 106348acf710SJeremy L Thompson } else { 106448acf710SJeremy L Thompson bool are_compatible; 106548acf710SJeremy L Thompson 106648acf710SJeremy L Thompson CeedCall(CeedElemRestrictionAtPointsAreCompatible(op->first_points_rstr, rstr_points, &are_compatible)); 10679bc66399SJeremy L Thompson CeedCheck(are_compatible, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 1068ca94c3ddSJeremy L Thompson "CeedElemRestriction must have compatible offsets with previously set field CeedElemRestriction"); 106948acf710SJeremy L Thompson } 107048acf710SJeremy L Thompson 107148acf710SJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(rstr_points, &op->rstr_points)); 107248acf710SJeremy L Thompson CeedCall(CeedVectorReferenceCopy(point_coords, &op->point_coords)); 107348acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 107448acf710SJeremy L Thompson } 107548acf710SJeremy L Thompson 107648acf710SJeremy L Thompson /** 1077b594f9faSZach Atkins @brief Get a boolean value indicating if the `CeedOperator` was created with `CeedOperatorCreateAtPoints` 1078b594f9faSZach Atkins 1079b594f9faSZach Atkins @param[in] op `CeedOperator` 1080b594f9faSZach Atkins @param[out] is_at_points Variable to store at points status 1081b594f9faSZach Atkins 1082b594f9faSZach Atkins @return An error code: 0 - success, otherwise - failure 1083b594f9faSZach Atkins 1084b594f9faSZach Atkins @ref User 1085b594f9faSZach Atkins **/ 1086b594f9faSZach Atkins int CeedOperatorIsAtPoints(CeedOperator op, bool *is_at_points) { 1087b594f9faSZach Atkins *is_at_points = op->is_at_points; 1088b594f9faSZach Atkins return CEED_ERROR_SUCCESS; 1089b594f9faSZach Atkins } 1090b594f9faSZach Atkins 1091b594f9faSZach Atkins /** 1092ca94c3ddSJeremy L Thompson @brief Get the arbitrary points in each element for a `CeedOperator` at points. 109348acf710SJeremy L Thompson 1094ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 109548acf710SJeremy L Thompson 1096ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` at points 1097ca94c3ddSJeremy L Thompson @param[out] rstr_points Variable to hold `CeedElemRestriction` for the coordinates of each point by element 1098ca94c3ddSJeremy L Thompson @param[out] point_coords Variable to hold `CeedVector` holding coordinates of each point 109948acf710SJeremy L Thompson 110048acf710SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 110148acf710SJeremy L Thompson 110248acf710SJeremy L Thompson @ref Advanced 110348acf710SJeremy L Thompson **/ 110448acf710SJeremy L Thompson int CeedOperatorAtPointsGetPoints(CeedOperator op, CeedElemRestriction *rstr_points, CeedVector *point_coords) { 11052a3ff1c9SZach Atkins bool is_at_points; 11062a3ff1c9SZach Atkins 11072a3ff1c9SZach Atkins CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 11086e536b99SJeremy L Thompson CeedCheck(is_at_points, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for operator at points"); 110948acf710SJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 111048acf710SJeremy L Thompson 11113f919cbcSJeremy L Thompson if (rstr_points) { 11123f919cbcSJeremy L Thompson *rstr_points = NULL; 11133f919cbcSJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(op->rstr_points, rstr_points)); 11143f919cbcSJeremy L Thompson } 11153f919cbcSJeremy L Thompson if (point_coords) { 11163f919cbcSJeremy L Thompson *point_coords = NULL; 11173f919cbcSJeremy L Thompson CeedCall(CeedVectorReferenceCopy(op->point_coords, point_coords)); 11183f919cbcSJeremy L Thompson } 111948acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 112048acf710SJeremy L Thompson } 112148acf710SJeremy L Thompson 112248acf710SJeremy L Thompson /** 1123be9c6463SJeremy L Thompson @brief Get a `CeedOperator` Field of a `CeedOperator` from its name. 1124be9c6463SJeremy L Thompson 1125be9c6463SJeremy L Thompson `op_field` is set to `NULL` if the field is not found. 1126de5900adSJames Wright 1127ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 1128de5900adSJames Wright 1129ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1130ca94c3ddSJeremy L Thompson @param[in] field_name Name of desired `CeedOperator` Field 1131ca94c3ddSJeremy L Thompson @param[out] op_field `CeedOperator` Field corresponding to the name 1132de5900adSJames Wright 1133de5900adSJames Wright @return An error code: 0 - success, otherwise - failure 1134de5900adSJames Wright 1135de5900adSJames Wright @ref Advanced 1136de5900adSJames Wright **/ 1137de5900adSJames Wright int CeedOperatorGetFieldByName(CeedOperator op, const char *field_name, CeedOperatorField *op_field) { 11386f8994e9SJeremy L Thompson const char *name; 1139de5900adSJames Wright CeedInt num_input_fields, num_output_fields; 1140de5900adSJames Wright CeedOperatorField *input_fields, *output_fields; 1141de5900adSJames Wright 1142be9c6463SJeremy L Thompson *op_field = NULL; 11431c66c397SJeremy L Thompson CeedCall(CeedOperatorGetFields(op, &num_input_fields, &input_fields, &num_output_fields, &output_fields)); 1144de5900adSJames Wright for (CeedInt i = 0; i < num_input_fields; i++) { 1145de5900adSJames Wright CeedCall(CeedOperatorFieldGetName(input_fields[i], &name)); 1146de5900adSJames Wright if (!strcmp(name, field_name)) { 1147de5900adSJames Wright *op_field = input_fields[i]; 1148de5900adSJames Wright return CEED_ERROR_SUCCESS; 1149de5900adSJames Wright } 1150de5900adSJames Wright } 1151de5900adSJames Wright for (CeedInt i = 0; i < num_output_fields; i++) { 1152de5900adSJames Wright CeedCall(CeedOperatorFieldGetName(output_fields[i], &name)); 1153de5900adSJames Wright if (!strcmp(name, field_name)) { 1154de5900adSJames Wright *op_field = output_fields[i]; 1155de5900adSJames Wright return CEED_ERROR_SUCCESS; 1156de5900adSJames Wright } 1157de5900adSJames Wright } 1158be9c6463SJeremy L Thompson return CEED_ERROR_SUCCESS; 1159de5900adSJames Wright } 1160de5900adSJames Wright 1161de5900adSJames Wright /** 1162ca94c3ddSJeremy L Thompson @brief Get the name of a `CeedOperator` Field 116328567f8fSJeremy L Thompson 1164ca94c3ddSJeremy L Thompson @param[in] op_field `CeedOperator` Field 116528567f8fSJeremy L Thompson @param[out] field_name Variable to store the field name 116628567f8fSJeremy L Thompson 116728567f8fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 116828567f8fSJeremy L Thompson 1169e9b533fbSJeremy L Thompson @ref Advanced 117028567f8fSJeremy L Thompson **/ 11716f8994e9SJeremy L Thompson int CeedOperatorFieldGetName(CeedOperatorField op_field, const char **field_name) { 11726f8994e9SJeremy L Thompson *field_name = op_field->field_name; 117328567f8fSJeremy L Thompson return CEED_ERROR_SUCCESS; 117428567f8fSJeremy L Thompson } 117528567f8fSJeremy L Thompson 117628567f8fSJeremy L Thompson /** 1177681d0ea7SJeremy L Thompson @brief Get the `CeedElemRestriction` of a `CeedOperator` Field. 1178681d0ea7SJeremy L Thompson 1179681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `rstr` with @ref CeedElemRestrictionDestroy(). 118043bbe138SJeremy L Thompson 1181ca94c3ddSJeremy L Thompson @param[in] op_field `CeedOperator` Field 1182ca94c3ddSJeremy L Thompson @param[out] rstr Variable to store `CeedElemRestriction` 118343bbe138SJeremy L Thompson 118443bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 118543bbe138SJeremy L Thompson 1186e9b533fbSJeremy L Thompson @ref Advanced 118743bbe138SJeremy L Thompson **/ 11882b730f8bSJeremy L Thompson int CeedOperatorFieldGetElemRestriction(CeedOperatorField op_field, CeedElemRestriction *rstr) { 1189681d0ea7SJeremy L Thompson *rstr = NULL; 1190681d0ea7SJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(op_field->elem_rstr, rstr)); 119143bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 119243bbe138SJeremy L Thompson } 119343bbe138SJeremy L Thompson 119443bbe138SJeremy L Thompson /** 1195681d0ea7SJeremy L Thompson @brief Get the `CeedBasis` of a `CeedOperator` Field. 1196681d0ea7SJeremy L Thompson 1197681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `basis` with @ref CeedBasisDestroy(). 119843bbe138SJeremy L Thompson 1199ca94c3ddSJeremy L Thompson @param[in] op_field `CeedOperator` Field 1200ca94c3ddSJeremy L Thompson @param[out] basis Variable to store `CeedBasis` 120143bbe138SJeremy L Thompson 120243bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 120343bbe138SJeremy L Thompson 1204e9b533fbSJeremy L Thompson @ref Advanced 120543bbe138SJeremy L Thompson **/ 120643bbe138SJeremy L Thompson int CeedOperatorFieldGetBasis(CeedOperatorField op_field, CeedBasis *basis) { 1207681d0ea7SJeremy L Thompson *basis = NULL; 1208681d0ea7SJeremy L Thompson CeedCall(CeedBasisReferenceCopy(op_field->basis, basis)); 120943bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 121043bbe138SJeremy L Thompson } 121143bbe138SJeremy L Thompson 121243bbe138SJeremy L Thompson /** 1213681d0ea7SJeremy L Thompson @brief Get the `CeedVector` of a `CeedOperator` Field. 1214681d0ea7SJeremy L Thompson 1215681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `vec` with @ref CeedVectorDestroy(). 121643bbe138SJeremy L Thompson 1217ca94c3ddSJeremy L Thompson @param[in] op_field `CeedOperator` Field 1218ca94c3ddSJeremy L Thompson @param[out] vec Variable to store `CeedVector` 121943bbe138SJeremy L Thompson 122043bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 122143bbe138SJeremy L Thompson 1222e9b533fbSJeremy L Thompson @ref Advanced 122343bbe138SJeremy L Thompson **/ 122443bbe138SJeremy L Thompson int CeedOperatorFieldGetVector(CeedOperatorField op_field, CeedVector *vec) { 1225681d0ea7SJeremy L Thompson *vec = NULL; 1226681d0ea7SJeremy L Thompson CeedCall(CeedVectorReferenceCopy(op_field->vec, vec)); 122743bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 122843bbe138SJeremy L Thompson } 122943bbe138SJeremy L Thompson 123043bbe138SJeremy L Thompson /** 1231ab747706SJeremy L Thompson @brief Get the data of a `CeedOperator` Field. 1232ab747706SJeremy L Thompson 1233681d0ea7SJeremy L Thompson Any arguments set as `NULL` are ignored.. 1234681d0ea7SJeremy L Thompson 1235681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `rstr`, `basis`, and `vec`. 1236ab747706SJeremy L Thompson 1237ab747706SJeremy L Thompson @param[in] op_field `CeedOperator` Field 1238ab747706SJeremy L Thompson @param[out] field_name Variable to store the field name 1239ab747706SJeremy L Thompson @param[out] rstr Variable to store `CeedElemRestriction` 1240ab747706SJeremy L Thompson @param[out] basis Variable to store `CeedBasis` 1241ab747706SJeremy L Thompson @param[out] vec Variable to store `CeedVector` 1242ab747706SJeremy L Thompson 1243ab747706SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1244ab747706SJeremy L Thompson 1245ab747706SJeremy L Thompson @ref Advanced 1246ab747706SJeremy L Thompson **/ 12476f8994e9SJeremy L Thompson int CeedOperatorFieldGetData(CeedOperatorField op_field, const char **field_name, CeedElemRestriction *rstr, CeedBasis *basis, CeedVector *vec) { 1248ab747706SJeremy L Thompson if (field_name) CeedCall(CeedOperatorFieldGetName(op_field, field_name)); 1249ab747706SJeremy L Thompson if (rstr) CeedCall(CeedOperatorFieldGetElemRestriction(op_field, rstr)); 1250ab747706SJeremy L Thompson if (basis) CeedCall(CeedOperatorFieldGetBasis(op_field, basis)); 1251ab747706SJeremy L Thompson if (vec) CeedCall(CeedOperatorFieldGetVector(op_field, vec)); 1252ab747706SJeremy L Thompson return CEED_ERROR_SUCCESS; 1253ab747706SJeremy L Thompson } 1254ab747706SJeremy L Thompson 1255ab747706SJeremy L Thompson /** 1256ca94c3ddSJeremy L Thompson @brief Add a sub-operator to a composite `CeedOperator` 1257288c0443SJeremy L Thompson 1258ca94c3ddSJeremy L Thompson @param[in,out] composite_op Composite `CeedOperator` 1259ca94c3ddSJeremy L Thompson @param[in] sub_op Sub-operator `CeedOperator` 126052d6035fSJeremy L Thompson 126152d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 126252d6035fSJeremy L Thompson 12637a982d89SJeremy L. Thompson @ref User 126452d6035fSJeremy L Thompson */ 1265ed094490SJeremy L Thompson int CeedOperatorCompositeAddSub(CeedOperator composite_op, CeedOperator sub_op) { 12661203703bSJeremy L Thompson bool is_immutable; 12671203703bSJeremy L Thompson 12689bc66399SJeremy L Thompson CeedCheck(composite_op->is_composite, CeedOperatorReturnCeed(composite_op), CEED_ERROR_MINOR, "CeedOperator is not a composite operator"); 12699bc66399SJeremy L Thompson CeedCheck(composite_op->num_suboperators < CEED_COMPOSITE_MAX, CeedOperatorReturnCeed(composite_op), CEED_ERROR_UNSUPPORTED, 12709bc66399SJeremy L Thompson "Cannot add additional sub-operators"); 12711203703bSJeremy L Thompson CeedCall(CeedOperatorIsImmutable(composite_op, &is_immutable)); 12729bc66399SJeremy L Thompson CeedCheck(!is_immutable, CeedOperatorReturnCeed(composite_op), CEED_ERROR_MAJOR, "Operator cannot be changed after set as immutable"); 12732b730f8bSJeremy L Thompson 12742b730f8bSJeremy L Thompson { 12752b730f8bSJeremy L Thompson CeedSize input_size, output_size; 12761c66c397SJeremy L Thompson 12772b730f8bSJeremy L Thompson CeedCall(CeedOperatorGetActiveVectorLengths(sub_op, &input_size, &output_size)); 12782b730f8bSJeremy L Thompson if (composite_op->input_size == -1) composite_op->input_size = input_size; 12792b730f8bSJeremy L Thompson if (composite_op->output_size == -1) composite_op->output_size = output_size; 12802b730f8bSJeremy L Thompson // Note, a size of -1 means no active vector restriction set, so no incompatibility 12819bc66399SJeremy L Thompson CeedCheck((input_size == -1 || input_size == composite_op->input_size) && (output_size == -1 || output_size == composite_op->output_size), 12829bc66399SJeremy L Thompson CeedOperatorReturnCeed(composite_op), CEED_ERROR_MAJOR, 1283249f8407SJeremy L Thompson "Sub-operators must have compatible dimensions; composite operator of shape (%" CeedSize_FMT ", %" CeedSize_FMT 1284249f8407SJeremy L Thompson ") not compatible with sub-operator of " 1285249f8407SJeremy L Thompson "shape (%" CeedSize_FMT ", %" CeedSize_FMT ")", 12862b730f8bSJeremy L Thompson composite_op->input_size, composite_op->output_size, input_size, output_size); 12872b730f8bSJeremy L Thompson } 12882b730f8bSJeremy L Thompson 1289d1d35e2fSjeremylt composite_op->sub_operators[composite_op->num_suboperators] = sub_op; 12902b730f8bSJeremy L Thompson CeedCall(CeedOperatorReference(sub_op)); 1291d1d35e2fSjeremylt composite_op->num_suboperators++; 1292e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 129352d6035fSJeremy L Thompson } 129452d6035fSJeremy L Thompson 129552d6035fSJeremy L Thompson /** 1296ca94c3ddSJeremy L Thompson @brief Get the number of sub-operators associated with a `CeedOperator` 129775f0d5a4SJeremy L Thompson 1298ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1299ca94c3ddSJeremy L Thompson @param[out] num_suboperators Variable to store number of sub-operators 130075f0d5a4SJeremy L Thompson 130175f0d5a4SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 130275f0d5a4SJeremy L Thompson 130375f0d5a4SJeremy L Thompson @ref Backend 130475f0d5a4SJeremy L Thompson **/ 1305ed094490SJeremy L Thompson int CeedOperatorCompositeGetNumSub(CeedOperator op, CeedInt *num_suboperators) { 13061203703bSJeremy L Thompson bool is_composite; 13071203703bSJeremy L Thompson 13081203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 13096e536b99SJeremy L Thompson CeedCheck(is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for a composite operator"); 131075f0d5a4SJeremy L Thompson *num_suboperators = op->num_suboperators; 131175f0d5a4SJeremy L Thompson return CEED_ERROR_SUCCESS; 131275f0d5a4SJeremy L Thompson } 131375f0d5a4SJeremy L Thompson 131475f0d5a4SJeremy L Thompson /** 1315ca94c3ddSJeremy L Thompson @brief Get the list of sub-operators associated with a `CeedOperator` 131675f0d5a4SJeremy L Thompson 1317ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1318ca94c3ddSJeremy L Thompson @param[out] sub_operators Variable to store list of sub-operators 131975f0d5a4SJeremy L Thompson 132075f0d5a4SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 132175f0d5a4SJeremy L Thompson 132275f0d5a4SJeremy L Thompson @ref Backend 132375f0d5a4SJeremy L Thompson **/ 1324ed094490SJeremy L Thompson int CeedOperatorCompositeGetSubList(CeedOperator op, CeedOperator **sub_operators) { 13251203703bSJeremy L Thompson bool is_composite; 13261203703bSJeremy L Thompson 13271203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 13286e536b99SJeremy L Thompson CeedCheck(is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for a composite operator"); 132975f0d5a4SJeremy L Thompson *sub_operators = op->sub_operators; 133075f0d5a4SJeremy L Thompson return CEED_ERROR_SUCCESS; 133175f0d5a4SJeremy L Thompson } 133275f0d5a4SJeremy L Thompson 133375f0d5a4SJeremy L Thompson /** 13348a297abdSJames Wright @brief Get a sub `CeedOperator` of a composite `CeedOperator` from its name. 13358a297abdSJames Wright 13368a297abdSJames Wright `sub_op` is set to `NULL` if the sub operator is not found. 13378a297abdSJames Wright 13388a297abdSJames Wright Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 13398a297abdSJames Wright 13408a297abdSJames Wright @param[in] op Composite `CeedOperator` 13418a297abdSJames Wright @param[in] op_name Name of desired sub `CeedOperator` 13428a297abdSJames Wright @param[out] sub_op Sub `CeedOperator` corresponding to the name 13438a297abdSJames Wright 13448a297abdSJames Wright @return An error code: 0 - success, otherwise - failure 13458a297abdSJames Wright 13468a297abdSJames Wright @ref Advanced 13478a297abdSJames Wright **/ 1348ed094490SJeremy L Thompson int CeedOperatorCompositeGetSubByName(CeedOperator op, const char *op_name, CeedOperator *sub_op) { 13498a297abdSJames Wright bool is_composite; 13508a297abdSJames Wright CeedInt num_sub_ops; 13518a297abdSJames Wright CeedOperator *sub_ops; 13528a297abdSJames Wright 13538a297abdSJames Wright CeedCall(CeedOperatorIsComposite(op, &is_composite)); 13548a297abdSJames Wright CeedCheck(is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for a composite operator"); 13558a297abdSJames Wright *sub_op = NULL; 1356ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_sub_ops)); 1357ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_ops)); 13588a297abdSJames Wright for (CeedInt i = 0; i < num_sub_ops; i++) { 13598a297abdSJames Wright if (sub_ops[i]->name && !strcmp(op_name, sub_ops[i]->name)) { 13608a297abdSJames Wright *sub_op = sub_ops[i]; 13618a297abdSJames Wright return CEED_ERROR_SUCCESS; 13628a297abdSJames Wright } 13638a297abdSJames Wright } 13648a297abdSJames Wright return CEED_ERROR_SUCCESS; 13658a297abdSJames Wright } 13668a297abdSJames Wright 13678a297abdSJames Wright /** 1368ca94c3ddSJeremy L Thompson @brief Check if a `CeedOperator` is ready to be used. 13694db537f9SJeremy L Thompson 1370ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to check 13714db537f9SJeremy L Thompson 13724db537f9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 13734db537f9SJeremy L Thompson 13744db537f9SJeremy L Thompson @ref User 13754db537f9SJeremy L Thompson **/ 13764db537f9SJeremy L Thompson int CeedOperatorCheckReady(CeedOperator op) { 13771203703bSJeremy L Thompson bool is_at_points, is_composite; 13781203703bSJeremy L Thompson CeedQFunction qf = NULL; 13794db537f9SJeremy L Thompson 13802b730f8bSJeremy L Thompson if (op->is_interface_setup) return CEED_ERROR_SUCCESS; 13814db537f9SJeremy L Thompson 13821203703bSJeremy L Thompson CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 13831203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 13841203703bSJeremy L Thompson if (!is_composite) CeedCall(CeedOperatorGetQFunction(op, &qf)); 13851203703bSJeremy L Thompson if (is_composite) { 13861203703bSJeremy L Thompson CeedInt num_suboperators; 13871203703bSJeremy L Thompson 1388ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 13891203703bSJeremy L Thompson if (!num_suboperators) { 139043622462SJeremy L Thompson // Empty operator setup 139143622462SJeremy L Thompson op->input_size = 0; 139243622462SJeremy L Thompson op->output_size = 0; 139343622462SJeremy L Thompson } else { 13941203703bSJeremy L Thompson CeedOperator *sub_operators; 13951203703bSJeremy L Thompson 1396ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 13971203703bSJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 13981203703bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(sub_operators[i])); 13994db537f9SJeremy L Thompson } 14002b104005SJeremy L Thompson // Sub-operators could be modified after adding to composite operator 14012b104005SJeremy L Thompson // Need to verify no lvec incompatibility from any changes 14022b104005SJeremy L Thompson CeedSize input_size, output_size; 14032b730f8bSJeremy L Thompson CeedCall(CeedOperatorGetActiveVectorLengths(op, &input_size, &output_size)); 140443622462SJeremy L Thompson } 14054db537f9SJeremy L Thompson } else { 14061203703bSJeremy L Thompson CeedInt num_input_fields, num_output_fields; 14071203703bSJeremy L Thompson 14089bc66399SJeremy L Thompson CeedCheck(op->num_fields > 0, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "No operator fields set"); 14091203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFields(qf, &num_input_fields, NULL, &num_output_fields, NULL)); 14109bc66399SJeremy L Thompson CeedCheck(op->num_fields == num_input_fields + num_output_fields, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, 14119bc66399SJeremy L Thompson "Not all operator fields set"); 14129bc66399SJeremy L Thompson CeedCheck(op->has_restriction, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "At least one restriction required"); 14139bc66399SJeremy L Thompson CeedCheck(op->num_qpts > 0 || is_at_points, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, 1414ca94c3ddSJeremy L Thompson "At least one non-collocated CeedBasis is required or the number of quadrature points must be set"); 14152b730f8bSJeremy L Thompson } 14164db537f9SJeremy L Thompson 14174db537f9SJeremy L Thompson // Flag as immutable and ready 14184db537f9SJeremy L Thompson op->is_interface_setup = true; 14191203703bSJeremy L Thompson if (qf && qf != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionSetImmutable(qf)); 1420c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 14211203703bSJeremy L Thompson if (op->dqf && op->dqf != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionSetImmutable(op->dqf)); 14221203703bSJeremy L Thompson if (op->dqfT && op->dqfT != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionSetImmutable(op->dqfT)); 14234db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 14244db537f9SJeremy L Thompson } 14254db537f9SJeremy L Thompson 14264db537f9SJeremy L Thompson /** 1427ca94c3ddSJeremy L Thompson @brief Get vector lengths for the active input and/or output `CeedVector` of a `CeedOperator`. 14284385fb7fSSebastian Grimberg 1429ca94c3ddSJeremy L Thompson Note: Lengths of `-1` indicate that the CeedOperator does not have an active input and/or output. 1430c9366a6bSJeremy L Thompson 1431ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1432ca94c3ddSJeremy L Thompson @param[out] input_size Variable to store active input vector length, or `NULL` 1433ca94c3ddSJeremy L Thompson @param[out] output_size Variable to store active output vector length, or `NULL` 1434c9366a6bSJeremy L Thompson 1435c9366a6bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1436c9366a6bSJeremy L Thompson 1437c9366a6bSJeremy L Thompson @ref User 1438c9366a6bSJeremy L Thompson **/ 14392b730f8bSJeremy L Thompson int CeedOperatorGetActiveVectorLengths(CeedOperator op, CeedSize *input_size, CeedSize *output_size) { 1440c9366a6bSJeremy L Thompson bool is_composite; 1441c9366a6bSJeremy L Thompson 14422b104005SJeremy L Thompson if (input_size) *input_size = op->input_size; 14432b104005SJeremy L Thompson if (output_size) *output_size = op->output_size; 1444c9366a6bSJeremy L Thompson 14452b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 14462b104005SJeremy L Thompson if (is_composite && (op->input_size == -1 || op->output_size == -1)) { 14471203703bSJeremy L Thompson CeedInt num_suboperators; 14481203703bSJeremy L Thompson CeedOperator *sub_operators; 14491203703bSJeremy L Thompson 1450ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 1451ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 14521203703bSJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 1453c9366a6bSJeremy L Thompson CeedSize sub_input_size, sub_output_size; 14541c66c397SJeremy L Thompson 14551203703bSJeremy L Thompson CeedCall(CeedOperatorGetActiveVectorLengths(sub_operators[i], &sub_input_size, &sub_output_size)); 14562b104005SJeremy L Thompson if (op->input_size == -1) op->input_size = sub_input_size; 14572b104005SJeremy L Thompson if (op->output_size == -1) op->output_size = sub_output_size; 14582b104005SJeremy L Thompson // Note, a size of -1 means no active vector restriction set, so no incompatibility 14596e536b99SJeremy L Thompson CeedCheck((sub_input_size == -1 || sub_input_size == op->input_size) && (sub_output_size == -1 || sub_output_size == op->output_size), 14606e536b99SJeremy L Thompson CeedOperatorReturnCeed(op), CEED_ERROR_MAJOR, 1461249f8407SJeremy L Thompson "Sub-operators must have compatible dimensions; composite operator of shape (%" CeedSize_FMT ", %" CeedSize_FMT 1462249f8407SJeremy L Thompson ") not compatible with sub-operator of " 1463249f8407SJeremy L Thompson "shape (%" CeedSize_FMT ", %" CeedSize_FMT ")", 14642b104005SJeremy L Thompson op->input_size, op->output_size, input_size, output_size); 1465c9366a6bSJeremy L Thompson } 14662b730f8bSJeremy L Thompson } 1467c9366a6bSJeremy L Thompson return CEED_ERROR_SUCCESS; 1468c9366a6bSJeremy L Thompson } 1469c9366a6bSJeremy L Thompson 1470c9366a6bSJeremy L Thompson /** 1471ca94c3ddSJeremy L Thompson @brief Set reuse of `CeedQFunction` data in `CeedOperatorLinearAssemble*()` functions. 14724385fb7fSSebastian Grimberg 1473ca94c3ddSJeremy L Thompson When `reuse_assembly_data = false` (default), the `CeedQFunction` associated with this `CeedOperator` is re-assembled every time a `CeedOperatorLinearAssemble*()` function is called. 1474ca94c3ddSJeremy L Thompson When `reuse_assembly_data = true`, the `CeedQFunction` associated with this `CeedOperator` is reused between calls to @ref CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(). 14758b919e6bSJeremy L Thompson 1476ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1477beecbf24SJeremy L Thompson @param[in] reuse_assembly_data Boolean flag setting assembly data reuse 14788b919e6bSJeremy L Thompson 14798b919e6bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 14808b919e6bSJeremy L Thompson 14818b919e6bSJeremy L Thompson @ref Advanced 14828b919e6bSJeremy L Thompson **/ 14832b730f8bSJeremy L Thompson int CeedOperatorSetQFunctionAssemblyReuse(CeedOperator op, bool reuse_assembly_data) { 14848b919e6bSJeremy L Thompson bool is_composite; 14858b919e6bSJeremy L Thompson 14862b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 14878b919e6bSJeremy L Thompson if (is_composite) { 14888b919e6bSJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 14892b730f8bSJeremy L Thompson CeedCall(CeedOperatorSetQFunctionAssemblyReuse(op->sub_operators[i], reuse_assembly_data)); 14908b919e6bSJeremy L Thompson } 14918b919e6bSJeremy L Thompson } else { 14927d5185d7SSebastian Grimberg CeedQFunctionAssemblyData data; 14937d5185d7SSebastian Grimberg 14947d5185d7SSebastian Grimberg CeedCall(CeedOperatorGetQFunctionAssemblyData(op, &data)); 14957d5185d7SSebastian Grimberg CeedCall(CeedQFunctionAssemblyDataSetReuse(data, reuse_assembly_data)); 1496beecbf24SJeremy L Thompson } 1497beecbf24SJeremy L Thompson return CEED_ERROR_SUCCESS; 1498beecbf24SJeremy L Thompson } 1499beecbf24SJeremy L Thompson 1500beecbf24SJeremy L Thompson /** 1501ca94c3ddSJeremy L Thompson @brief Mark `CeedQFunction` data as updated and the `CeedQFunction` as requiring re-assembly. 1502beecbf24SJeremy L Thompson 1503ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 15046e15d496SJeremy L Thompson @param[in] needs_data_update Boolean flag setting assembly data reuse 1505beecbf24SJeremy L Thompson 1506beecbf24SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1507beecbf24SJeremy L Thompson 1508beecbf24SJeremy L Thompson @ref Advanced 1509beecbf24SJeremy L Thompson **/ 15102b730f8bSJeremy L Thompson int CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(CeedOperator op, bool needs_data_update) { 1511beecbf24SJeremy L Thompson bool is_composite; 1512beecbf24SJeremy L Thompson 15132b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 1514beecbf24SJeremy L Thompson if (is_composite) { 15151203703bSJeremy L Thompson CeedInt num_suboperators; 15161203703bSJeremy L Thompson CeedOperator *sub_operators; 15171203703bSJeremy L Thompson 1518ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 1519ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 15201203703bSJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 15211203703bSJeremy L Thompson CeedCall(CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(sub_operators[i], needs_data_update)); 1522beecbf24SJeremy L Thompson } 1523beecbf24SJeremy L Thompson } else { 15247d5185d7SSebastian Grimberg CeedQFunctionAssemblyData data; 15257d5185d7SSebastian Grimberg 15267d5185d7SSebastian Grimberg CeedCall(CeedOperatorGetQFunctionAssemblyData(op, &data)); 15277d5185d7SSebastian Grimberg CeedCall(CeedQFunctionAssemblyDataSetUpdateNeeded(data, needs_data_update)); 15288b919e6bSJeremy L Thompson } 15298b919e6bSJeremy L Thompson return CEED_ERROR_SUCCESS; 15308b919e6bSJeremy L Thompson } 15318b919e6bSJeremy L Thompson 15328b919e6bSJeremy L Thompson /** 1533ca94c3ddSJeremy L Thompson @brief Set name of `CeedOperator` for @ref CeedOperatorView() output 1534ea6b5821SJeremy L Thompson 1535ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 1536ea61e9acSJeremy L Thompson @param[in] name Name to set, or NULL to remove previously set name 1537ea6b5821SJeremy L Thompson 1538ea6b5821SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1539ea6b5821SJeremy L Thompson 1540ea6b5821SJeremy L Thompson @ref User 1541ea6b5821SJeremy L Thompson **/ 1542ea6b5821SJeremy L Thompson int CeedOperatorSetName(CeedOperator op, const char *name) { 1543ea6b5821SJeremy L Thompson char *name_copy; 1544ea6b5821SJeremy L Thompson size_t name_len = name ? strlen(name) : 0; 1545ea6b5821SJeremy L Thompson 15462b730f8bSJeremy L Thompson CeedCall(CeedFree(&op->name)); 1547ea6b5821SJeremy L Thompson if (name_len > 0) { 15482b730f8bSJeremy L Thompson CeedCall(CeedCalloc(name_len + 1, &name_copy)); 1549ea6b5821SJeremy L Thompson memcpy(name_copy, name, name_len); 1550ea6b5821SJeremy L Thompson op->name = name_copy; 1551ea6b5821SJeremy L Thompson } 1552ea6b5821SJeremy L Thompson return CEED_ERROR_SUCCESS; 1553ea6b5821SJeremy L Thompson } 1554ea6b5821SJeremy L Thompson 1555ea6b5821SJeremy L Thompson /** 1556d3d5610dSJeremy L Thompson @brief Get name of `CeedOperator` 1557d3d5610dSJeremy L Thompson 1558d3d5610dSJeremy L Thompson @param[in] op `CeedOperator` 1559d3d5610dSJeremy L Thompson @param[in,out] name Address of variable to hold currently set name 1560d3d5610dSJeremy L Thompson 1561d3d5610dSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1562d3d5610dSJeremy L Thompson 1563d3d5610dSJeremy L Thompson @ref User 1564d3d5610dSJeremy L Thompson **/ 1565d3d5610dSJeremy L Thompson int CeedOperatorGetName(CeedOperator op, const char **name) { 1566d3d5610dSJeremy L Thompson if (op->name) { 1567d3d5610dSJeremy L Thompson *name = op->name; 1568d3d5610dSJeremy L Thompson } else if (!op->is_composite) { 1569d3d5610dSJeremy L Thompson CeedQFunction qf; 1570d3d5610dSJeremy L Thompson 1571d3d5610dSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 1572d3d5610dSJeremy L Thompson if (qf) CeedCall(CeedQFunctionGetName(qf, name)); 1573d3d5610dSJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 1574d3d5610dSJeremy L Thompson } 1575d3d5610dSJeremy L Thompson return CEED_ERROR_SUCCESS; 1576d3d5610dSJeremy L Thompson } 1577d3d5610dSJeremy L Thompson 1578d3d5610dSJeremy L Thompson /** 1579935f026aSJeremy L Thompson @brief Core logic for viewing a `CeedOperator` 15807a982d89SJeremy L. Thompson 1581935f026aSJeremy L Thompson @param[in] op `CeedOperator` to view brief summary 1582ca94c3ddSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 15838bf1b130SJames Wright @param[in] is_full Whether to write full operator view or terse 15847a982d89SJeremy L. Thompson 15857a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 15866ab8e59fSJames Wright 15876ab8e59fSJames Wright @ref Developer 15887a982d89SJeremy L. Thompson **/ 15898bf1b130SJames Wright static int CeedOperatorView_Core(CeedOperator op, FILE *stream, bool is_full) { 1590d3d5610dSJeremy L Thompson bool has_name, is_composite, is_at_points; 15915a526491SJeremy L Thompson char *tabs = NULL; 1592d3d5610dSJeremy L Thompson const char *name = NULL; 15935a526491SJeremy L Thompson CeedInt num_tabs = 0; 15947a982d89SJeremy L. Thompson 1595d3d5610dSJeremy L Thompson CeedCall(CeedOperatorGetName(op, &name)); 1596d3d5610dSJeremy L Thompson has_name = name ? strlen(name) : false; 15971203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 159899f7f61fSJeremy L Thompson CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 15995a526491SJeremy L Thompson // Set tabs 16005a526491SJeremy L Thompson CeedCall(CeedOperatorGetNumViewTabs(op, &num_tabs)); 16014c789ea2SJeremy L Thompson CeedCall(CeedCalloc(CEED_TAB_WIDTH * (num_tabs + is_composite) + 1, &tabs)); 16024c789ea2SJeremy L Thompson for (CeedInt i = 0; i < CEED_TAB_WIDTH * num_tabs; i++) tabs[i] = ' '; 16031203703bSJeremy L Thompson if (is_composite) { 16041203703bSJeremy L Thompson CeedInt num_suboperators; 16051203703bSJeremy L Thompson CeedOperator *sub_operators; 16061203703bSJeremy L Thompson 1607ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 1608ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 1609df1daa62SZach Atkins fprintf(stream, "%s", tabs); 1610d3d5610dSJeremy L Thompson fprintf(stream, "Composite CeedOperator%s%s\n", has_name ? " - " : "", has_name ? name : ""); 16114c789ea2SJeremy L Thompson for (CeedInt i = 0; i < CEED_TAB_WIDTH; i++) tabs[CEED_TAB_WIDTH * num_tabs + i] = ' '; 16121203703bSJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 16131203703bSJeremy L Thompson has_name = sub_operators[i]->name; 1614df1daa62SZach Atkins fprintf(stream, "%s", tabs); 161599f7f61fSJeremy L Thompson fprintf(stream, "SubOperator%s %" CeedInt_FMT "%s%s%s\n", is_at_points ? " AtPoints" : "", i, has_name ? " - " : "", 161699f7f61fSJeremy L Thompson has_name ? sub_operators[i]->name : "", is_full ? ":" : ""); 16175a526491SJeremy L Thompson if (is_full) CeedCall(CeedOperatorSingleView(sub_operators[i], tabs, stream)); 16187a982d89SJeremy L. Thompson } 16197a982d89SJeremy L. Thompson } else { 1620df1daa62SZach Atkins fprintf(stream, "%s", tabs); 1621d3d5610dSJeremy L Thompson fprintf(stream, "CeedOperator%s%s%s\n", is_at_points ? " AtPoints" : "", has_name ? " - " : "", has_name ? name : ""); 16225a526491SJeremy L Thompson if (is_full) CeedCall(CeedOperatorSingleView(op, tabs, stream)); 16237a982d89SJeremy L. Thompson } 16245a526491SJeremy L Thompson CeedCall(CeedFree(&tabs)); 16255a526491SJeremy L Thompson return CEED_ERROR_SUCCESS; 16265a526491SJeremy L Thompson } 16275a526491SJeremy L Thompson 16285a526491SJeremy L Thompson /** 16295a526491SJeremy L Thompson @brief Set the number of tabs to indent for @ref CeedOperatorView() output 16305a526491SJeremy L Thompson 16315a526491SJeremy L Thompson @param[in] op `CeedOperator` to set the number of view tabs 16325a526491SJeremy L Thompson @param[in] num_tabs Number of view tabs to set 16335a526491SJeremy L Thompson 16345a526491SJeremy L Thompson @return Error code: 0 - success, otherwise - failure 16355a526491SJeremy L Thompson 16365a526491SJeremy L Thompson @ref User 16375a526491SJeremy L Thompson **/ 16385a526491SJeremy L Thompson int CeedOperatorSetNumViewTabs(CeedOperator op, CeedInt num_tabs) { 16395a526491SJeremy L Thompson CeedCheck(num_tabs >= 0, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Number of view tabs must be non-negative"); 16405a526491SJeremy L Thompson op->num_tabs = num_tabs; 1641e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 16427a982d89SJeremy L. Thompson } 16433bd813ffSjeremylt 16443bd813ffSjeremylt /** 1645690992b2SZach Atkins @brief Get the number of tabs to indent for @ref CeedOperatorView() output 1646690992b2SZach Atkins 1647690992b2SZach Atkins @param[in] op `CeedOperator` to get the number of view tabs 1648690992b2SZach Atkins @param[out] num_tabs Number of view tabs 1649690992b2SZach Atkins 1650690992b2SZach Atkins @return Error code: 0 - success, otherwise - failure 1651690992b2SZach Atkins 1652690992b2SZach Atkins @ref User 1653690992b2SZach Atkins **/ 1654690992b2SZach Atkins int CeedOperatorGetNumViewTabs(CeedOperator op, CeedInt *num_tabs) { 1655690992b2SZach Atkins *num_tabs = op->num_tabs; 1656690992b2SZach Atkins return CEED_ERROR_SUCCESS; 1657690992b2SZach Atkins } 1658690992b2SZach Atkins 1659690992b2SZach Atkins /** 1660935f026aSJeremy L Thompson @brief View a `CeedOperator` 1661935f026aSJeremy L Thompson 1662935f026aSJeremy L Thompson @param[in] op `CeedOperator` to view 1663935f026aSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 1664935f026aSJeremy L Thompson 1665935f026aSJeremy L Thompson @return Error code: 0 - success, otherwise - failure 1666935f026aSJeremy L Thompson 1667935f026aSJeremy L Thompson @ref User 1668935f026aSJeremy L Thompson **/ 1669935f026aSJeremy L Thompson int CeedOperatorView(CeedOperator op, FILE *stream) { 1670935f026aSJeremy L Thompson CeedCall(CeedOperatorView_Core(op, stream, true)); 1671935f026aSJeremy L Thompson return CEED_ERROR_SUCCESS; 1672935f026aSJeremy L Thompson } 1673935f026aSJeremy L Thompson 1674935f026aSJeremy L Thompson /** 1675935f026aSJeremy L Thompson @brief View a brief summary `CeedOperator` 1676935f026aSJeremy L Thompson 1677935f026aSJeremy L Thompson @param[in] op `CeedOperator` to view brief summary 1678935f026aSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 1679935f026aSJeremy L Thompson 1680935f026aSJeremy L Thompson @return Error code: 0 - success, otherwise - failure 1681935f026aSJeremy L Thompson 1682935f026aSJeremy L Thompson @ref User 1683935f026aSJeremy L Thompson **/ 1684935f026aSJeremy L Thompson int CeedOperatorViewTerse(CeedOperator op, FILE *stream) { 1685935f026aSJeremy L Thompson CeedCall(CeedOperatorView_Core(op, stream, false)); 1686935f026aSJeremy L Thompson return CEED_ERROR_SUCCESS; 1687935f026aSJeremy L Thompson } 1688935f026aSJeremy L Thompson 1689935f026aSJeremy L Thompson /** 1690ca94c3ddSJeremy L Thompson @brief Get the `Ceed` associated with a `CeedOperator` 1691b7c9bbdaSJeremy L Thompson 1692ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1693ca94c3ddSJeremy L Thompson @param[out] ceed Variable to store `Ceed` 1694b7c9bbdaSJeremy L Thompson 1695b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1696b7c9bbdaSJeremy L Thompson 1697b7c9bbdaSJeremy L Thompson @ref Advanced 1698b7c9bbdaSJeremy L Thompson **/ 1699b7c9bbdaSJeremy L Thompson int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 17009bc66399SJeremy L Thompson *ceed = NULL; 17019bc66399SJeremy L Thompson CeedCall(CeedReferenceCopy(CeedOperatorReturnCeed(op), ceed)); 1702b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1703b7c9bbdaSJeremy L Thompson } 1704b7c9bbdaSJeremy L Thompson 1705b7c9bbdaSJeremy L Thompson /** 17066e536b99SJeremy L Thompson @brief Return the `Ceed` associated with a `CeedOperator` 17076e536b99SJeremy L Thompson 17086e536b99SJeremy L Thompson @param[in] op `CeedOperator` 17096e536b99SJeremy L Thompson 17106e536b99SJeremy L Thompson @return `Ceed` associated with the `op` 17116e536b99SJeremy L Thompson 17126e536b99SJeremy L Thompson @ref Advanced 17136e536b99SJeremy L Thompson **/ 17146e536b99SJeremy L Thompson Ceed CeedOperatorReturnCeed(CeedOperator op) { return op->ceed; } 17156e536b99SJeremy L Thompson 17166e536b99SJeremy L Thompson /** 1717ca94c3ddSJeremy L Thompson @brief Get the number of elements associated with a `CeedOperator` 1718b7c9bbdaSJeremy L Thompson 1719ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1720b7c9bbdaSJeremy L Thompson @param[out] num_elem Variable to store number of elements 1721b7c9bbdaSJeremy L Thompson 1722b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1723b7c9bbdaSJeremy L Thompson 1724b7c9bbdaSJeremy L Thompson @ref Advanced 1725b7c9bbdaSJeremy L Thompson **/ 1726b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumElements(CeedOperator op, CeedInt *num_elem) { 17271203703bSJeremy L Thompson bool is_composite; 17281203703bSJeremy L Thompson 17291203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 17306e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Not defined for composite operator"); 1731b7c9bbdaSJeremy L Thompson *num_elem = op->num_elem; 1732b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1733b7c9bbdaSJeremy L Thompson } 1734b7c9bbdaSJeremy L Thompson 1735b7c9bbdaSJeremy L Thompson /** 1736ca94c3ddSJeremy L Thompson @brief Get the number of quadrature points associated with a `CeedOperator` 1737b7c9bbdaSJeremy L Thompson 1738ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1739b7c9bbdaSJeremy L Thompson @param[out] num_qpts Variable to store vector number of quadrature points 1740b7c9bbdaSJeremy L Thompson 1741b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1742b7c9bbdaSJeremy L Thompson 1743b7c9bbdaSJeremy L Thompson @ref Advanced 1744b7c9bbdaSJeremy L Thompson **/ 1745b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *num_qpts) { 17461203703bSJeremy L Thompson bool is_composite; 17471203703bSJeremy L Thompson 17481203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 17496e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Not defined for composite operator"); 1750b7c9bbdaSJeremy L Thompson *num_qpts = op->num_qpts; 1751b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1752b7c9bbdaSJeremy L Thompson } 1753b7c9bbdaSJeremy L Thompson 1754b7c9bbdaSJeremy L Thompson /** 1755ca94c3ddSJeremy L Thompson @brief Estimate number of FLOPs required to apply `CeedOperator` on the active `CeedVector` 17566e15d496SJeremy L Thompson 1757ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to estimate FLOPs for 1758ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 17596e15d496SJeremy L Thompson 17606e15d496SJeremy L Thompson @ref Backend 17616e15d496SJeremy L Thompson **/ 17629d36ca50SJeremy L Thompson int CeedOperatorGetFlopsEstimate(CeedOperator op, CeedSize *flops) { 17636e15d496SJeremy L Thompson bool is_composite; 17641c66c397SJeremy L Thompson 17652b730f8bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 17666e15d496SJeremy L Thompson 17676e15d496SJeremy L Thompson *flops = 0; 17682b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 17696e15d496SJeremy L Thompson if (is_composite) { 17706e15d496SJeremy L Thompson CeedInt num_suboperators; 17711c66c397SJeremy L Thompson 1772ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 17736e15d496SJeremy L Thompson CeedOperator *sub_operators; 1774ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 17756e15d496SJeremy L Thompson 17766e15d496SJeremy L Thompson // FLOPs for each suboperator 17776e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 17789d36ca50SJeremy L Thompson CeedSize suboperator_flops; 17791c66c397SJeremy L Thompson 17802b730f8bSJeremy L Thompson CeedCall(CeedOperatorGetFlopsEstimate(sub_operators[i], &suboperator_flops)); 17816e15d496SJeremy L Thompson *flops += suboperator_flops; 17826e15d496SJeremy L Thompson } 17836e15d496SJeremy L Thompson } else { 17843f919cbcSJeremy L Thompson bool is_at_points; 17853f919cbcSJeremy L Thompson CeedInt num_input_fields, num_output_fields, num_elem = 0, num_points = 0; 17861203703bSJeremy L Thompson CeedQFunction qf; 17871203703bSJeremy L Thompson CeedQFunctionField *qf_input_fields, *qf_output_fields; 17881203703bSJeremy L Thompson CeedOperatorField *op_input_fields, *op_output_fields; 17891c66c397SJeremy L Thompson 17903f919cbcSJeremy L Thompson CeedCall(CeedOperatorGetNumElements(op, &num_elem)); 179119feff82SJeremy L Thompson if (num_elem == 0) return CEED_ERROR_SUCCESS; 179219feff82SJeremy L Thompson CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 17933f919cbcSJeremy L Thompson if (is_at_points) { 17943f919cbcSJeremy L Thompson CeedMemType mem_type; 17953f919cbcSJeremy L Thompson CeedElemRestriction rstr_points = NULL; 17963f919cbcSJeremy L Thompson 17973f919cbcSJeremy L Thompson CeedCall(CeedOperatorAtPointsGetPoints(op, &rstr_points, NULL)); 17983f919cbcSJeremy L Thompson CeedCall(CeedGetPreferredMemType(CeedOperatorReturnCeed(op), &mem_type)); 17993f919cbcSJeremy L Thompson if (mem_type == CEED_MEM_DEVICE) { 18003f919cbcSJeremy L Thompson // Device backends pad out to the same number of points per element 18013f919cbcSJeremy L Thompson CeedCall(CeedElemRestrictionGetMaxPointsInElement(rstr_points, &num_points)); 18023f919cbcSJeremy L Thompson } else { 18033f919cbcSJeremy L Thompson num_points = 0; 18043f919cbcSJeremy L Thompson for (CeedInt i = 0; i < num_elem; i++) { 18053f919cbcSJeremy L Thompson CeedInt points_in_elem = 0; 18063f919cbcSJeremy L Thompson 18073f919cbcSJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr_points, i, &points_in_elem)); 18083f919cbcSJeremy L Thompson num_points += points_in_elem; 18093f919cbcSJeremy L Thompson } 18103f919cbcSJeremy L Thompson num_points = num_points / num_elem + (num_points % num_elem > 0); 18113f919cbcSJeremy L Thompson } 18123f919cbcSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr_points)); 18133f919cbcSJeremy L Thompson } 18141203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 18151203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFields(qf, &num_input_fields, &qf_input_fields, &num_output_fields, &qf_output_fields)); 1816c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 18171203703bSJeremy L Thompson CeedCall(CeedOperatorGetFields(op, NULL, &op_input_fields, NULL, &op_output_fields)); 18184385fb7fSSebastian Grimberg 18196e15d496SJeremy L Thompson // Input FLOPs 18206e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 18211203703bSJeremy L Thompson CeedVector vec; 18226e15d496SJeremy L Thompson 18231203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_input_fields[i], &vec)); 18241203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 18251203703bSJeremy L Thompson CeedEvalMode eval_mode; 18261203703bSJeremy L Thompson CeedSize rstr_flops, basis_flops; 18271203703bSJeremy L Thompson CeedElemRestriction rstr; 18281203703bSJeremy L Thompson CeedBasis basis; 18291203703bSJeremy L Thompson 18301203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetElemRestriction(op_input_fields[i], &rstr)); 18311203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetFlopsEstimate(rstr, CEED_NOTRANSPOSE, &rstr_flops)); 1832681d0ea7SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr)); 1833edb2538eSJeremy L Thompson *flops += rstr_flops; 18341203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(op_input_fields[i], &basis)); 18351203703bSJeremy L Thompson CeedCall(CeedQFunctionFieldGetEvalMode(qf_input_fields[i], &eval_mode)); 18363f919cbcSJeremy L Thompson CeedCall(CeedBasisGetFlopsEstimate(basis, CEED_NOTRANSPOSE, eval_mode, is_at_points, num_points, &basis_flops)); 1837681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 18386e15d496SJeremy L Thompson *flops += basis_flops * num_elem; 18396e15d496SJeremy L Thompson } 1840681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 18416e15d496SJeremy L Thompson } 18426e15d496SJeremy L Thompson // QF FLOPs 18431c66c397SJeremy L Thompson { 18449d36ca50SJeremy L Thompson CeedInt num_qpts; 18459d36ca50SJeremy L Thompson CeedSize qf_flops; 18461203703bSJeremy L Thompson CeedQFunction qf; 18471c66c397SJeremy L Thompson 18483f919cbcSJeremy L Thompson if (is_at_points) num_qpts = num_points; 18493f919cbcSJeremy L Thompson else CeedCall(CeedOperatorGetNumQuadraturePoints(op, &num_qpts)); 18501203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 18511203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFlopsEstimate(qf, &qf_flops)); 1852c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 18536e536b99SJeremy L Thompson CeedCheck(qf_flops > -1, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, 18546e536b99SJeremy L Thompson "Must set CeedQFunction FLOPs estimate with CeedQFunctionSetUserFlopsEstimate"); 18556e15d496SJeremy L Thompson *flops += num_elem * num_qpts * qf_flops; 18561c66c397SJeremy L Thompson } 18571c66c397SJeremy L Thompson 18586e15d496SJeremy L Thompson // Output FLOPs 18596e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 18601203703bSJeremy L Thompson CeedVector vec; 18616e15d496SJeremy L Thompson 18621203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_output_fields[i], &vec)); 18631203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 18641203703bSJeremy L Thompson CeedEvalMode eval_mode; 18651203703bSJeremy L Thompson CeedSize rstr_flops, basis_flops; 18661203703bSJeremy L Thompson CeedElemRestriction rstr; 18671203703bSJeremy L Thompson CeedBasis basis; 18681203703bSJeremy L Thompson 18691203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetElemRestriction(op_output_fields[i], &rstr)); 18701203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetFlopsEstimate(rstr, CEED_TRANSPOSE, &rstr_flops)); 1871681d0ea7SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr)); 1872edb2538eSJeremy L Thompson *flops += rstr_flops; 18731203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(op_output_fields[i], &basis)); 18741203703bSJeremy L Thompson CeedCall(CeedQFunctionFieldGetEvalMode(qf_output_fields[i], &eval_mode)); 18753f919cbcSJeremy L Thompson CeedCall(CeedBasisGetFlopsEstimate(basis, CEED_TRANSPOSE, eval_mode, is_at_points, num_points, &basis_flops)); 1876681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 18776e15d496SJeremy L Thompson *flops += basis_flops * num_elem; 18786e15d496SJeremy L Thompson } 1879681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 18806e15d496SJeremy L Thompson } 18816e15d496SJeremy L Thompson } 18826e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 18836e15d496SJeremy L Thompson } 18846e15d496SJeremy L Thompson 18856e15d496SJeremy L Thompson /** 1886ca94c3ddSJeremy L Thompson @brief Get `CeedQFunction` global context for a `CeedOperator`. 18879fd66db6SSebastian Grimberg 1888ca94c3ddSJeremy L Thompson The caller is responsible for destroying `ctx` returned from this function via @ref CeedQFunctionContextDestroy(). 1889512bb800SJeremy L Thompson 1890ca94c3ddSJeremy 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`. 1891ca94c3ddSJeremy L Thompson This `CeedQFunctionContext` will be destroyed if `ctx` is the only reference to this `CeedQFunctionContext`. 18920126412dSJeremy L Thompson 1893ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1894ca94c3ddSJeremy L Thompson @param[out] ctx Variable to store `CeedQFunctionContext` 18950126412dSJeremy L Thompson 18960126412dSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 18970126412dSJeremy L Thompson 1898859c15bbSJames Wright @ref Advanced 18990126412dSJeremy L Thompson **/ 19000126412dSJeremy L Thompson int CeedOperatorGetContext(CeedOperator op, CeedQFunctionContext *ctx) { 19011203703bSJeremy L Thompson bool is_composite; 19021203703bSJeremy L Thompson CeedQFunction qf; 19031203703bSJeremy L Thompson CeedQFunctionContext qf_ctx; 19041203703bSJeremy L Thompson 19051203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 19066e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "Cannot retrieve CeedQFunctionContext for composite operator"); 19071203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 19081203703bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &qf_ctx)); 1909c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 19101485364cSJeremy L Thompson *ctx = NULL; 19111203703bSJeremy L Thompson if (qf_ctx) CeedCall(CeedQFunctionContextReferenceCopy(qf_ctx, ctx)); 19120126412dSJeremy L Thompson return CEED_ERROR_SUCCESS; 19130126412dSJeremy L Thompson } 19140126412dSJeremy L Thompson 19150126412dSJeremy L Thompson /** 1916ca94c3ddSJeremy L Thompson @brief Get label for a registered `CeedQFunctionContext` field, or `NULL` if no field has been registered with this `field_name`. 19173668ca4bSJeremy L Thompson 1918ca94c3ddSJeremy L Thompson Fields are registered via `CeedQFunctionContextRegister*()` functions (eg. @ref CeedQFunctionContextRegisterDouble()). 1919859c15bbSJames Wright 1920ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 19213668ca4bSJeremy L Thompson @param[in] field_name Name of field to retrieve label 19223668ca4bSJeremy L Thompson @param[out] field_label Variable to field label 19233668ca4bSJeremy L Thompson 19243668ca4bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 19253668ca4bSJeremy L Thompson 19263668ca4bSJeremy L Thompson @ref User 19273668ca4bSJeremy L Thompson **/ 192817b0d5c6SJeremy L Thompson int CeedOperatorGetContextFieldLabel(CeedOperator op, const char *field_name, CeedContextFieldLabel *field_label) { 19291c66c397SJeremy L Thompson bool is_composite, field_found = false; 19301c66c397SJeremy L Thompson 19312b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 19322b730f8bSJeremy L Thompson 19333668ca4bSJeremy L Thompson if (is_composite) { 1934a98a090bSJeremy L Thompson // Composite operator 1935a98a090bSJeremy L Thompson // -- Check if composite label already created 19363668ca4bSJeremy L Thompson for (CeedInt i = 0; i < op->num_context_labels; i++) { 19373668ca4bSJeremy L Thompson if (!strcmp(op->context_labels[i]->name, field_name)) { 19383668ca4bSJeremy L Thompson *field_label = op->context_labels[i]; 19393668ca4bSJeremy L Thompson return CEED_ERROR_SUCCESS; 19403668ca4bSJeremy L Thompson } 19413668ca4bSJeremy L Thompson } 19423668ca4bSJeremy L Thompson 1943a98a090bSJeremy L Thompson // -- Create composite label if needed 19443668ca4bSJeremy L Thompson CeedInt num_sub; 19453668ca4bSJeremy L Thompson CeedOperator *sub_operators; 19463668ca4bSJeremy L Thompson CeedContextFieldLabel new_field_label; 19473668ca4bSJeremy L Thompson 19482b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &new_field_label)); 1949ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_sub)); 1950ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 19512b730f8bSJeremy L Thompson CeedCall(CeedCalloc(num_sub, &new_field_label->sub_labels)); 19523668ca4bSJeremy L Thompson new_field_label->num_sub_labels = num_sub; 19533668ca4bSJeremy L Thompson 19543668ca4bSJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 19553668ca4bSJeremy L Thompson if (sub_operators[i]->qf->ctx) { 19563668ca4bSJeremy L Thompson CeedContextFieldLabel new_field_label_i; 19571c66c397SJeremy L Thompson 19582b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldLabel(sub_operators[i]->qf->ctx, field_name, &new_field_label_i)); 19593668ca4bSJeremy L Thompson if (new_field_label_i) { 1960a98a090bSJeremy L Thompson field_found = true; 19613668ca4bSJeremy L Thompson new_field_label->sub_labels[i] = new_field_label_i; 19623668ca4bSJeremy L Thompson new_field_label->name = new_field_label_i->name; 19633668ca4bSJeremy L Thompson new_field_label->description = new_field_label_i->description; 19642b730f8bSJeremy L Thompson if (new_field_label->type && new_field_label->type != new_field_label_i->type) { 19657bfe0f0eSJeremy L Thompson // LCOV_EXCL_START 19662b730f8bSJeremy L Thompson CeedCall(CeedFree(&new_field_label)); 19676e536b99SJeremy L Thompson return CeedError(CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "Incompatible field types on sub-operator contexts. %s != %s", 19682b730f8bSJeremy L Thompson CeedContextFieldTypes[new_field_label->type], CeedContextFieldTypes[new_field_label_i->type]); 19697bfe0f0eSJeremy L Thompson // LCOV_EXCL_STOP 19707bfe0f0eSJeremy L Thompson } else { 19717bfe0f0eSJeremy L Thompson new_field_label->type = new_field_label_i->type; 19727bfe0f0eSJeremy L Thompson } 19732b730f8bSJeremy L Thompson if (new_field_label->num_values != 0 && new_field_label->num_values != new_field_label_i->num_values) { 19747bfe0f0eSJeremy L Thompson // LCOV_EXCL_START 19752b730f8bSJeremy L Thompson CeedCall(CeedFree(&new_field_label)); 19766e536b99SJeremy L Thompson return CeedError(CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 19776e536b99SJeremy L Thompson "Incompatible field number of values on sub-operator contexts. %zu != %zu", new_field_label->num_values, 19786e536b99SJeremy L Thompson new_field_label_i->num_values); 19797bfe0f0eSJeremy L Thompson // LCOV_EXCL_STOP 19807bfe0f0eSJeremy L Thompson } else { 19817bfe0f0eSJeremy L Thompson new_field_label->num_values = new_field_label_i->num_values; 19827bfe0f0eSJeremy L Thompson } 19833668ca4bSJeremy L Thompson } 19843668ca4bSJeremy L Thompson } 19853668ca4bSJeremy L Thompson } 1986a98a090bSJeremy L Thompson // -- Cleanup if field was found 1987a98a090bSJeremy L Thompson if (field_found) { 1988a98a090bSJeremy L Thompson *field_label = new_field_label; 1989a98a090bSJeremy L Thompson } else { 19903668ca4bSJeremy L Thompson // LCOV_EXCL_START 19912b730f8bSJeremy L Thompson CeedCall(CeedFree(&new_field_label->sub_labels)); 19922b730f8bSJeremy L Thompson CeedCall(CeedFree(&new_field_label)); 19933668ca4bSJeremy L Thompson *field_label = NULL; 19943668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 19955ac9af79SJeremy L Thompson } 19965ac9af79SJeremy L Thompson } else { 19971203703bSJeremy L Thompson CeedQFunction qf; 19981203703bSJeremy L Thompson CeedQFunctionContext ctx; 19991203703bSJeremy L Thompson 2000a98a090bSJeremy L Thompson // Single, non-composite operator 20011203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 20021203703bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &ctx)); 2003c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 20041203703bSJeremy L Thompson if (ctx) { 20051203703bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldLabel(ctx, field_name, field_label)); 2006a98a090bSJeremy L Thompson } else { 2007a98a090bSJeremy L Thompson *field_label = NULL; 2008a98a090bSJeremy L Thompson } 20095ac9af79SJeremy L Thompson } 20105ac9af79SJeremy L Thompson 20115ac9af79SJeremy L Thompson // Set label in operator 20125ac9af79SJeremy L Thompson if (*field_label) { 20135ac9af79SJeremy L Thompson (*field_label)->from_op = true; 20145ac9af79SJeremy L Thompson 20153668ca4bSJeremy L Thompson // Move new composite label to operator 20163668ca4bSJeremy L Thompson if (op->num_context_labels == 0) { 20172b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &op->context_labels)); 20183668ca4bSJeremy L Thompson op->max_context_labels = 1; 20193668ca4bSJeremy L Thompson } else if (op->num_context_labels == op->max_context_labels) { 20202b730f8bSJeremy L Thompson CeedCall(CeedRealloc(2 * op->num_context_labels, &op->context_labels)); 20213668ca4bSJeremy L Thompson op->max_context_labels *= 2; 20223668ca4bSJeremy L Thompson } 20235ac9af79SJeremy L Thompson op->context_labels[op->num_context_labels] = *field_label; 20243668ca4bSJeremy L Thompson op->num_context_labels++; 20253668ca4bSJeremy L Thompson } 20263668ca4bSJeremy L Thompson return CEED_ERROR_SUCCESS; 20273668ca4bSJeremy L Thompson } 20283668ca4bSJeremy L Thompson 20293668ca4bSJeremy L Thompson /** 2030ca94c3ddSJeremy L Thompson @brief Set `CeedQFunctionContext` field holding double precision values. 20314385fb7fSSebastian Grimberg 2032ca94c3ddSJeremy L Thompson For composite operators, the values are set in all sub-operator `CeedQFunctionContext` that have a matching `field_name`. 2033d8dd9a91SJeremy L Thompson 2034ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 20352788fa27SJeremy L Thompson @param[in] field_label Label of field to set 2036ea61e9acSJeremy L Thompson @param[in] values Values to set 2037d8dd9a91SJeremy L Thompson 2038d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2039d8dd9a91SJeremy L Thompson 2040d8dd9a91SJeremy L Thompson @ref User 2041d8dd9a91SJeremy L Thompson **/ 204217b0d5c6SJeremy L Thompson int CeedOperatorSetContextDouble(CeedOperator op, CeedContextFieldLabel field_label, double *values) { 20432b730f8bSJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_DOUBLE, values); 2044d8dd9a91SJeremy L Thompson } 2045d8dd9a91SJeremy L Thompson 2046d8dd9a91SJeremy L Thompson /** 2047ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field holding double precision values, read-only. 20484385fb7fSSebastian Grimberg 2049ca94c3ddSJeremy L Thompson For composite operators, the values correspond to the first sub-operator `CeedQFunctionContext` that has a matching `field_name`. 20502788fa27SJeremy L Thompson 2051ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 20522788fa27SJeremy L Thompson @param[in] field_label Label of field to get 20532788fa27SJeremy L Thompson @param[out] num_values Number of values in the field label 20542788fa27SJeremy L Thompson @param[out] values Pointer to context values 20552788fa27SJeremy L Thompson 20562788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 20572788fa27SJeremy L Thompson 20582788fa27SJeremy L Thompson @ref User 20592788fa27SJeremy L Thompson **/ 206017b0d5c6SJeremy L Thompson int CeedOperatorGetContextDoubleRead(CeedOperator op, CeedContextFieldLabel field_label, size_t *num_values, const double **values) { 20612788fa27SJeremy L Thompson return CeedOperatorContextGetGenericRead(op, field_label, CEED_CONTEXT_FIELD_DOUBLE, num_values, values); 20622788fa27SJeremy L Thompson } 20632788fa27SJeremy L Thompson 20642788fa27SJeremy L Thompson /** 2065ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field holding double precision values, read-only. 20662788fa27SJeremy L Thompson 2067ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 20682788fa27SJeremy L Thompson @param[in] field_label Label of field to restore 20692788fa27SJeremy L Thompson @param[out] values Pointer to context values 20702788fa27SJeremy L Thompson 20712788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 20722788fa27SJeremy L Thompson 20732788fa27SJeremy L Thompson @ref User 20742788fa27SJeremy L Thompson **/ 207517b0d5c6SJeremy L Thompson int CeedOperatorRestoreContextDoubleRead(CeedOperator op, CeedContextFieldLabel field_label, const double **values) { 20762788fa27SJeremy L Thompson return CeedOperatorContextRestoreGenericRead(op, field_label, CEED_CONTEXT_FIELD_DOUBLE, values); 20772788fa27SJeremy L Thompson } 20782788fa27SJeremy L Thompson 20792788fa27SJeremy L Thompson /** 2080ca94c3ddSJeremy L Thompson @brief Set `CeedQFunctionContext` field holding `int32` values. 20814385fb7fSSebastian Grimberg 2082ca94c3ddSJeremy L Thompson For composite operators, the values are set in all sub-operator `CeedQFunctionContext` that have a matching `field_name`. 2083d8dd9a91SJeremy L Thompson 2084ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 2085ea61e9acSJeremy L Thompson @param[in] field_label Label of field to set 2086ea61e9acSJeremy L Thompson @param[in] values Values to set 2087d8dd9a91SJeremy L Thompson 2088d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2089d8dd9a91SJeremy L Thompson 2090d8dd9a91SJeremy L Thompson @ref User 2091d8dd9a91SJeremy L Thompson **/ 209223dbfd29SJeremy L Thompson int CeedOperatorSetContextInt32(CeedOperator op, CeedContextFieldLabel field_label, int32_t *values) { 20932b730f8bSJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_INT32, values); 2094d8dd9a91SJeremy L Thompson } 2095d8dd9a91SJeremy L Thompson 2096d8dd9a91SJeremy L Thompson /** 2097ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field holding `int32` values, read-only. 20984385fb7fSSebastian Grimberg 2099ca94c3ddSJeremy L Thompson For composite operators, the values correspond to the first sub-operator `CeedQFunctionContext` that has a matching `field_name`. 21002788fa27SJeremy L Thompson 2101ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 21022788fa27SJeremy L Thompson @param[in] field_label Label of field to get 2103ca94c3ddSJeremy L Thompson @param[out] num_values Number of `int32` values in `values` 21042788fa27SJeremy L Thompson @param[out] values Pointer to context values 21052788fa27SJeremy L Thompson 21062788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21072788fa27SJeremy L Thompson 21082788fa27SJeremy L Thompson @ref User 21092788fa27SJeremy L Thompson **/ 211023dbfd29SJeremy L Thompson int CeedOperatorGetContextInt32Read(CeedOperator op, CeedContextFieldLabel field_label, size_t *num_values, const int32_t **values) { 21112788fa27SJeremy L Thompson return CeedOperatorContextGetGenericRead(op, field_label, CEED_CONTEXT_FIELD_INT32, num_values, values); 21122788fa27SJeremy L Thompson } 21132788fa27SJeremy L Thompson 21142788fa27SJeremy L Thompson /** 2115ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field holding `int32` values, read-only. 21162788fa27SJeremy L Thompson 2117ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 21182788fa27SJeremy L Thompson @param[in] field_label Label of field to get 21192788fa27SJeremy L Thompson @param[out] values Pointer to context values 21202788fa27SJeremy L Thompson 21212788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21222788fa27SJeremy L Thompson 21232788fa27SJeremy L Thompson @ref User 21242788fa27SJeremy L Thompson **/ 212523dbfd29SJeremy L Thompson int CeedOperatorRestoreContextInt32Read(CeedOperator op, CeedContextFieldLabel field_label, const int32_t **values) { 21262788fa27SJeremy L Thompson return CeedOperatorContextRestoreGenericRead(op, field_label, CEED_CONTEXT_FIELD_INT32, values); 21272788fa27SJeremy L Thompson } 21282788fa27SJeremy L Thompson 21292788fa27SJeremy L Thompson /** 2130ca94c3ddSJeremy L Thompson @brief Set `CeedQFunctionContext` field holding boolean values. 21315b6ec284SJeremy L Thompson 2132ca94c3ddSJeremy L Thompson For composite operators, the values are set in all sub-operator `CeedQFunctionContext` that have a matching `field_name`. 21335b6ec284SJeremy L Thompson 2134ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 21355b6ec284SJeremy L Thompson @param[in] field_label Label of field to set 21365b6ec284SJeremy L Thompson @param[in] values Values to set 21375b6ec284SJeremy L Thompson 21385b6ec284SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21395b6ec284SJeremy L Thompson 21405b6ec284SJeremy L Thompson @ref User 21415b6ec284SJeremy L Thompson **/ 21425b6ec284SJeremy L Thompson int CeedOperatorSetContextBoolean(CeedOperator op, CeedContextFieldLabel field_label, bool *values) { 21435b6ec284SJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_BOOL, values); 21445b6ec284SJeremy L Thompson } 21455b6ec284SJeremy L Thompson 21465b6ec284SJeremy L Thompson /** 2147ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field holding boolean values, read-only. 21485b6ec284SJeremy L Thompson 2149ca94c3ddSJeremy L Thompson For composite operators, the values correspond to the first sub-operator `CeedQFunctionContext` that has a matching `field_name`. 21505b6ec284SJeremy L Thompson 2151ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 21525b6ec284SJeremy L Thompson @param[in] field_label Label of field to get 2153ca94c3ddSJeremy L Thompson @param[out] num_values Number of boolean values in `values` 21545b6ec284SJeremy L Thompson @param[out] values Pointer to context values 21555b6ec284SJeremy L Thompson 21565b6ec284SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21575b6ec284SJeremy L Thompson 21585b6ec284SJeremy L Thompson @ref User 21595b6ec284SJeremy L Thompson **/ 21605b6ec284SJeremy L Thompson int CeedOperatorGetContextBooleanRead(CeedOperator op, CeedContextFieldLabel field_label, size_t *num_values, const bool **values) { 21615b6ec284SJeremy L Thompson return CeedOperatorContextGetGenericRead(op, field_label, CEED_CONTEXT_FIELD_BOOL, num_values, values); 21625b6ec284SJeremy L Thompson } 21635b6ec284SJeremy L Thompson 21645b6ec284SJeremy L Thompson /** 2165ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field holding boolean values, read-only. 21665b6ec284SJeremy L Thompson 2167ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 21685b6ec284SJeremy L Thompson @param[in] field_label Label of field to get 21695b6ec284SJeremy L Thompson @param[out] values Pointer to context values 21705b6ec284SJeremy L Thompson 21715b6ec284SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21725b6ec284SJeremy L Thompson 21735b6ec284SJeremy L Thompson @ref User 21745b6ec284SJeremy L Thompson **/ 21755b6ec284SJeremy L Thompson int CeedOperatorRestoreContextBooleanRead(CeedOperator op, CeedContextFieldLabel field_label, const bool **values) { 21765b6ec284SJeremy L Thompson return CeedOperatorContextRestoreGenericRead(op, field_label, CEED_CONTEXT_FIELD_BOOL, values); 21775b6ec284SJeremy L Thompson } 21785b6ec284SJeremy L Thompson 21795b6ec284SJeremy L Thompson /** 2180ca94c3ddSJeremy L Thompson @brief Apply `CeedOperator` to a `CeedVector`. 2181d7b241e6Sjeremylt 2182ea61e9acSJeremy L Thompson This computes the action of the operator on the specified (active) input, yielding its (active) output. 2183ca94c3ddSJeremy L Thompson All inputs and outputs must be specified using @ref CeedOperatorSetField(). 2184d7b241e6Sjeremylt 21855da5ab9fSZach Atkins @note Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 2186f04ea552SJeremy L Thompson 2187ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to apply 2188ca94c3ddSJeremy L Thompson @param[in] in `CeedVector` containing input state or @ref CEED_VECTOR_NONE if there are no active inputs 2189ca94c3ddSJeremy 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 2190ca94c3ddSJeremy L Thompson @param[in] request Address of @ref CeedRequest for non-blocking completion, else @ref CEED_REQUEST_IMMEDIATE 2191b11c1e72Sjeremylt 2192b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 2193dfdf5a53Sjeremylt 21947a982d89SJeremy L. Thompson @ref User 2195b11c1e72Sjeremylt **/ 21962b730f8bSJeremy L Thompson int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, CeedRequest *request) { 21971203703bSJeremy L Thompson bool is_composite; 21981203703bSJeremy L Thompson 21992b730f8bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 2200d7b241e6Sjeremylt 22011203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 22020db52efcSZach Atkins if (is_composite && op->ApplyComposite) { 2203250756a7Sjeremylt // Composite Operator 22042b730f8bSJeremy L Thompson CeedCall(op->ApplyComposite(op, in, out, request)); 22050db52efcSZach Atkins } else if (!is_composite && op->Apply) { 22063ca2b39bSJeremy L Thompson // Standard Operator 22073ca2b39bSJeremy L Thompson CeedCall(op->Apply(op, in, out, request)); 22083ca2b39bSJeremy L Thompson } else { 22090db52efcSZach Atkins // Standard or composite, default to zeroing out and calling ApplyAddActive 22100db52efcSZach Atkins // Zero active output 22110db52efcSZach Atkins if (out != CEED_VECTOR_NONE) CeedCall(CeedVectorSetValue(out, 0.0)); 22121203703bSJeremy L Thompson 22130db52efcSZach Atkins // ApplyAddActive 22140db52efcSZach Atkins CeedCall(CeedOperatorApplyAddActive(op, in, out, request)); 2215250756a7Sjeremylt } 2216e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2217cae8b89aSjeremylt } 2218cae8b89aSjeremylt 2219cae8b89aSjeremylt /** 2220ca94c3ddSJeremy L Thompson @brief Apply `CeedOperator` to a `CeedVector` and add result to output `CeedVector`. 2221cae8b89aSjeremylt 2222ea61e9acSJeremy L Thompson This computes the action of the operator on the specified (active) input, yielding its (active) output. 2223ca94c3ddSJeremy L Thompson All inputs and outputs must be specified using @ref CeedOperatorSetField(). 2224cae8b89aSjeremylt 22255da5ab9fSZach Atkins @note Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 22265da5ab9fSZach Atkins @warning This function adds into ALL outputs, including passive outputs. To only add into the active output, use `CeedOperatorApplyAddActive()`. 22275da5ab9fSZach Atkins @see `CeedOperatorApplyAddActive()` 22285da5ab9fSZach Atkins 2229ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to apply 2230ca94c3ddSJeremy L Thompson @param[in] in `CeedVector` containing input state or @ref CEED_VECTOR_NONE if there are no active inputs 2231ca94c3ddSJeremy 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 2232ca94c3ddSJeremy L Thompson @param[in] request Address of @ref CeedRequest for non-blocking completion, else @ref CEED_REQUEST_IMMEDIATE 2233cae8b89aSjeremylt 2234cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 2235cae8b89aSjeremylt 22367a982d89SJeremy L. Thompson @ref User 2237cae8b89aSjeremylt **/ 22382b730f8bSJeremy L Thompson int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, CeedRequest *request) { 22391203703bSJeremy L Thompson bool is_composite; 22401203703bSJeremy L Thompson 22412b730f8bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 2242cae8b89aSjeremylt 22431203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 22441203703bSJeremy L Thompson if (is_composite) { 2245250756a7Sjeremylt // Composite Operator 2246250756a7Sjeremylt if (op->ApplyAddComposite) { 22472b730f8bSJeremy L Thompson CeedCall(op->ApplyAddComposite(op, in, out, request)); 2248cae8b89aSjeremylt } else { 2249d1d35e2fSjeremylt CeedInt num_suboperators; 2250d1d35e2fSjeremylt CeedOperator *sub_operators; 2251250756a7Sjeremylt 2252ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 2253ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 2254d1d35e2fSjeremylt for (CeedInt i = 0; i < num_suboperators; i++) { 22552b730f8bSJeremy L Thompson CeedCall(CeedOperatorApplyAdd(sub_operators[i], in, out, request)); 22561d7d2407SJeremy L Thompson } 2257250756a7Sjeremylt } 22581203703bSJeremy L Thompson } else if (op->num_elem > 0) { 22593ca2b39bSJeremy L Thompson // Standard Operator 22603ca2b39bSJeremy L Thompson CeedCall(op->ApplyAdd(op, in, out, request)); 2261250756a7Sjeremylt } 2262e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2263d7b241e6Sjeremylt } 2264d7b241e6Sjeremylt 2265d7b241e6Sjeremylt /** 22665da5ab9fSZach Atkins @brief Apply `CeedOperator` to a `CeedVector` and add result to output `CeedVector`. Only sums into active outputs, overwrites passive outputs. 22675da5ab9fSZach Atkins 22685da5ab9fSZach Atkins This computes the action of the operator on the specified (active) input, yielding its (active) output. 22695da5ab9fSZach Atkins All inputs and outputs must be specified using @ref CeedOperatorSetField(). 22705da5ab9fSZach Atkins 22715da5ab9fSZach Atkins @note Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 22725da5ab9fSZach Atkins 22735da5ab9fSZach Atkins @param[in] op `CeedOperator` to apply 22745da5ab9fSZach Atkins @param[in] in `CeedVector` containing input state or @ref CEED_VECTOR_NONE if there are no active inputs 22755da5ab9fSZach 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 22765da5ab9fSZach Atkins @param[in] request Address of @ref CeedRequest for non-blocking completion, else @ref CEED_REQUEST_IMMEDIATE 22775da5ab9fSZach Atkins 22785da5ab9fSZach Atkins @return An error code: 0 - success, otherwise - failure 22795da5ab9fSZach Atkins 22805da5ab9fSZach Atkins @ref User 22815da5ab9fSZach Atkins **/ 22825da5ab9fSZach Atkins int CeedOperatorApplyAddActive(CeedOperator op, CeedVector in, CeedVector out, CeedRequest *request) { 22835da5ab9fSZach Atkins bool is_composite; 22845da5ab9fSZach Atkins 22855da5ab9fSZach Atkins CeedCall(CeedOperatorCheckReady(op)); 22865da5ab9fSZach Atkins 22875da5ab9fSZach Atkins CeedCall(CeedOperatorIsComposite(op, &is_composite)); 22885da5ab9fSZach Atkins if (is_composite) { 22895da5ab9fSZach Atkins // Composite Operator 22905da5ab9fSZach Atkins CeedInt num_suboperators; 22915da5ab9fSZach Atkins CeedOperator *sub_operators; 22925da5ab9fSZach Atkins 2293ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 2294ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 22955da5ab9fSZach Atkins 22965da5ab9fSZach Atkins // Zero all output vectors 22975da5ab9fSZach Atkins for (CeedInt i = 0; i < num_suboperators; i++) { 22985da5ab9fSZach Atkins CeedInt num_output_fields; 22995da5ab9fSZach Atkins CeedOperatorField *output_fields; 23005da5ab9fSZach Atkins 23015da5ab9fSZach Atkins CeedCall(CeedOperatorGetFields(sub_operators[i], NULL, NULL, &num_output_fields, &output_fields)); 23025da5ab9fSZach Atkins for (CeedInt j = 0; j < num_output_fields; j++) { 23035da5ab9fSZach Atkins CeedVector vec; 23045da5ab9fSZach Atkins 23055da5ab9fSZach Atkins CeedCall(CeedOperatorFieldGetVector(output_fields[j], &vec)); 23065da5ab9fSZach Atkins if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) CeedCall(CeedVectorSetValue(vec, 0.0)); 23075da5ab9fSZach Atkins CeedCall(CeedVectorDestroy(&vec)); 23085da5ab9fSZach Atkins } 23095da5ab9fSZach Atkins } 23105da5ab9fSZach Atkins // ApplyAdd 23115da5ab9fSZach Atkins CeedCall(CeedOperatorApplyAdd(op, in, out, request)); 23125da5ab9fSZach Atkins } else { 23135da5ab9fSZach Atkins // Standard Operator 23145da5ab9fSZach Atkins CeedInt num_output_fields; 23155da5ab9fSZach Atkins CeedOperatorField *output_fields; 23165da5ab9fSZach Atkins 23175da5ab9fSZach Atkins CeedCall(CeedOperatorGetFields(op, NULL, NULL, &num_output_fields, &output_fields)); 23185da5ab9fSZach Atkins // Zero all output vectors 23195da5ab9fSZach Atkins for (CeedInt i = 0; i < num_output_fields; i++) { 23205da5ab9fSZach Atkins CeedVector vec; 23215da5ab9fSZach Atkins 23225da5ab9fSZach Atkins CeedCall(CeedOperatorFieldGetVector(output_fields[i], &vec)); 23235da5ab9fSZach Atkins if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) CeedCall(CeedVectorSetValue(vec, 0.0)); 23245da5ab9fSZach Atkins CeedCall(CeedVectorDestroy(&vec)); 23255da5ab9fSZach Atkins } 23265da5ab9fSZach Atkins // ApplyAdd 23275da5ab9fSZach Atkins CeedCall(CeedOperatorApplyAdd(op, in, out, request)); 23285da5ab9fSZach Atkins } 23295da5ab9fSZach Atkins return CEED_ERROR_SUCCESS; 23305da5ab9fSZach Atkins } 23315da5ab9fSZach Atkins 23325da5ab9fSZach Atkins /** 2333536b928cSSebastian Grimberg @brief Destroy temporary assembly data associated with a `CeedOperator` 2334536b928cSSebastian Grimberg 2335536b928cSSebastian Grimberg @param[in,out] op `CeedOperator` whose assembly data to destroy 2336536b928cSSebastian Grimberg 2337536b928cSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 2338536b928cSSebastian Grimberg 2339536b928cSSebastian Grimberg @ref User 2340536b928cSSebastian Grimberg **/ 2341536b928cSSebastian Grimberg int CeedOperatorAssemblyDataStrip(CeedOperator op) { 2342536b928cSSebastian Grimberg bool is_composite; 2343536b928cSSebastian Grimberg 2344536b928cSSebastian Grimberg CeedCall(CeedQFunctionAssemblyDataDestroy(&op->qf_assembled)); 2345536b928cSSebastian Grimberg CeedCall(CeedOperatorAssemblyDataDestroy(&op->op_assembled)); 2346536b928cSSebastian Grimberg CeedCall(CeedOperatorIsComposite(op, &is_composite)); 2347536b928cSSebastian Grimberg if (is_composite) { 2348536b928cSSebastian Grimberg CeedInt num_suboperators; 2349536b928cSSebastian Grimberg CeedOperator *sub_operators; 2350536b928cSSebastian Grimberg 2351ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 2352ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 2353536b928cSSebastian Grimberg for (CeedInt i = 0; i < num_suboperators; i++) { 2354536b928cSSebastian Grimberg CeedCall(CeedQFunctionAssemblyDataDestroy(&sub_operators[i]->qf_assembled)); 2355536b928cSSebastian Grimberg CeedCall(CeedOperatorAssemblyDataDestroy(&sub_operators[i]->op_assembled)); 2356536b928cSSebastian Grimberg } 2357536b928cSSebastian Grimberg } 2358536b928cSSebastian Grimberg return CEED_ERROR_SUCCESS; 2359536b928cSSebastian Grimberg } 2360536b928cSSebastian Grimberg 2361536b928cSSebastian Grimberg /** 2362ca94c3ddSJeremy L Thompson @brief Destroy a `CeedOperator` 2363d7b241e6Sjeremylt 2364ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` to destroy 2365b11c1e72Sjeremylt 2366b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 2367dfdf5a53Sjeremylt 23687a982d89SJeremy L. Thompson @ref User 2369b11c1e72Sjeremylt **/ 2370d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 2371ad6481ceSJeremy L Thompson if (!*op || --(*op)->ref_count > 0) { 2372ad6481ceSJeremy L Thompson *op = NULL; 2373ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 2374ad6481ceSJeremy L Thompson } 2375f883f0a5SSebastian Grimberg // Backend destroy 2376f883f0a5SSebastian Grimberg if ((*op)->Destroy) { 2377f883f0a5SSebastian Grimberg CeedCall((*op)->Destroy(*op)); 2378f883f0a5SSebastian Grimberg } 2379fe2413ffSjeremylt // Free fields 23802b730f8bSJeremy L Thompson for (CeedInt i = 0; i < (*op)->num_fields; i++) { 2381d1d35e2fSjeremylt if ((*op)->input_fields[i]) { 2382437c7c90SJeremy L Thompson if ((*op)->input_fields[i]->elem_rstr != CEED_ELEMRESTRICTION_NONE) { 2383437c7c90SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&(*op)->input_fields[i]->elem_rstr)); 238415910d16Sjeremylt } 2385356036faSJeremy L Thompson if ((*op)->input_fields[i]->basis != CEED_BASIS_NONE) { 23862b730f8bSJeremy L Thompson CeedCall(CeedBasisDestroy(&(*op)->input_fields[i]->basis)); 238771352a93Sjeremylt } 23882b730f8bSJeremy L Thompson if ((*op)->input_fields[i]->vec != CEED_VECTOR_ACTIVE && (*op)->input_fields[i]->vec != CEED_VECTOR_NONE) { 23892b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&(*op)->input_fields[i]->vec)); 239071352a93Sjeremylt } 23912b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->input_fields[i]->field_name)); 23922b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->input_fields[i])); 2393fe2413ffSjeremylt } 23942b730f8bSJeremy L Thompson } 23952b730f8bSJeremy L Thompson for (CeedInt i = 0; i < (*op)->num_fields; i++) { 2396d1d35e2fSjeremylt if ((*op)->output_fields[i]) { 2397437c7c90SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&(*op)->output_fields[i]->elem_rstr)); 2398356036faSJeremy L Thompson if ((*op)->output_fields[i]->basis != CEED_BASIS_NONE) { 23992b730f8bSJeremy L Thompson CeedCall(CeedBasisDestroy(&(*op)->output_fields[i]->basis)); 240071352a93Sjeremylt } 24012b730f8bSJeremy L Thompson if ((*op)->output_fields[i]->vec != CEED_VECTOR_ACTIVE && (*op)->output_fields[i]->vec != CEED_VECTOR_NONE) { 24022b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&(*op)->output_fields[i]->vec)); 240371352a93Sjeremylt } 24042b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->output_fields[i]->field_name)); 24052b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->output_fields[i])); 24062b730f8bSJeremy L Thompson } 2407fe2413ffSjeremylt } 2408f883f0a5SSebastian Grimberg CeedCall(CeedFree(&(*op)->input_fields)); 2409f883f0a5SSebastian Grimberg CeedCall(CeedFree(&(*op)->output_fields)); 2410f883f0a5SSebastian Grimberg // Destroy AtPoints data 241148acf710SJeremy L Thompson CeedCall(CeedVectorDestroy(&(*op)->point_coords)); 241248acf710SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&(*op)->rstr_points)); 241348acf710SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&(*op)->first_points_rstr)); 2414c6b536a8SSebastian Grimberg // Destroy assembly data (must happen before destroying sub_operators) 2415f883f0a5SSebastian Grimberg CeedCall(CeedOperatorAssemblyDataStrip(*op)); 2416d1d35e2fSjeremylt // Destroy sub_operators 24172b730f8bSJeremy L Thompson for (CeedInt i = 0; i < (*op)->num_suboperators; i++) { 2418d1d35e2fSjeremylt if ((*op)->sub_operators[i]) { 24192b730f8bSJeremy L Thompson CeedCall(CeedOperatorDestroy(&(*op)->sub_operators[i])); 242052d6035fSJeremy L Thompson } 24212b730f8bSJeremy L Thompson } 2422f883f0a5SSebastian Grimberg CeedCall(CeedFree(&(*op)->sub_operators)); 24232b730f8bSJeremy L Thompson CeedCall(CeedQFunctionDestroy(&(*op)->qf)); 24242b730f8bSJeremy L Thompson CeedCall(CeedQFunctionDestroy(&(*op)->dqf)); 24252b730f8bSJeremy L Thompson CeedCall(CeedQFunctionDestroy(&(*op)->dqfT)); 24263668ca4bSJeremy L Thompson // Destroy any composite labels 24275ac9af79SJeremy L Thompson if ((*op)->is_composite) { 24283668ca4bSJeremy L Thompson for (CeedInt i = 0; i < (*op)->num_context_labels; i++) { 24292b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->context_labels[i]->sub_labels)); 24302b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->context_labels[i])); 24313668ca4bSJeremy L Thompson } 24325ac9af79SJeremy L Thompson } 24332b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->context_labels)); 2434fe2413ffSjeremylt 24355107b09fSJeremy L Thompson // Destroy fallback 24362b730f8bSJeremy L Thompson CeedCall(CeedOperatorDestroy(&(*op)->op_fallback)); 24375107b09fSJeremy L Thompson 24382b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->name)); 2439f883f0a5SSebastian Grimberg CeedCall(CeedDestroy(&(*op)->ceed)); 24402b730f8bSJeremy L Thompson CeedCall(CeedFree(op)); 2441e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2442d7b241e6Sjeremylt } 2443d7b241e6Sjeremylt 2444d7b241e6Sjeremylt /// @} 2445