1d275d636SJeremy L Thompson // Copyright (c) 2017-2025, 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 91*b7fd8817SJeremy 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 **/ 98*b7fd8817SJeremy 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) { 100*b7fd8817SJeremy 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", 115*b7fd8817SJeremy 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 /** 1785a526491SJeremy L Thompson @brief Get the number of tabs to indent for @ref CeedOperatorView() output 1795a526491SJeremy L Thompson 1805a526491SJeremy L Thompson @param[in] op `CeedOperator` to get the number of view tabs 1815a526491SJeremy L Thompson @param[out] num_tabs Number of view tabs 1825a526491SJeremy L Thompson 1835a526491SJeremy L Thompson @return Error code: 0 - success, otherwise - failure 1845a526491SJeremy L Thompson 1855a526491SJeremy L Thompson @ref User 1865a526491SJeremy L Thompson **/ 1875a526491SJeremy L Thompson int CeedOperatorGetNumViewTabs(CeedOperator op, CeedInt *num_tabs) { 1885a526491SJeremy L Thompson *num_tabs = op->num_tabs; 1895a526491SJeremy L Thompson return CEED_ERROR_SUCCESS; 1905a526491SJeremy L Thompson } 1915a526491SJeremy L Thompson 1925a526491SJeremy L Thompson /** 193681d0ea7SJeremy L Thompson @brief Find the active input vector `CeedBasis` for a non-composite `CeedOperator`. 194681d0ea7SJeremy L Thompson 195681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `active_basis` with @ref CeedBasisDestroy(). 196eaf62fffSJeremy L Thompson 197ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to find active `CeedBasis` for 198ca94c3ddSJeremy L Thompson @param[out] active_basis `CeedBasis` for active input vector or `NULL` for composite operator 199eaf62fffSJeremy L Thompson 200eaf62fffSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 201eaf62fffSJeremy L Thompson 202eaf62fffSJeremy L Thompson @ref Developer 203eaf62fffSJeremy L Thompson **/ 204eaf62fffSJeremy L Thompson int CeedOperatorGetActiveBasis(CeedOperator op, CeedBasis *active_basis) { 205506b1a0cSSebastian Grimberg CeedCall(CeedOperatorGetActiveBases(op, active_basis, NULL)); 206506b1a0cSSebastian Grimberg return CEED_ERROR_SUCCESS; 207506b1a0cSSebastian Grimberg } 208506b1a0cSSebastian Grimberg 209506b1a0cSSebastian Grimberg /** 210681d0ea7SJeremy L Thompson @brief Find the active input and output vector `CeedBasis` for a non-composite `CeedOperator`. 211681d0ea7SJeremy L Thompson 212681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the bases with @ref CeedBasisDestroy(). 213506b1a0cSSebastian Grimberg 214ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to find active `CeedBasis` for 215ca94c3ddSJeremy L Thompson @param[out] active_input_basis `CeedBasis` for active input vector or `NULL` for composite operator 216ca94c3ddSJeremy L Thompson @param[out] active_output_basis `CeedBasis` for active output vector or `NULL` for composite operator 217506b1a0cSSebastian Grimberg 218506b1a0cSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 219506b1a0cSSebastian Grimberg 220506b1a0cSSebastian Grimberg @ref Developer 221506b1a0cSSebastian Grimberg **/ 222506b1a0cSSebastian Grimberg int CeedOperatorGetActiveBases(CeedOperator op, CeedBasis *active_input_basis, CeedBasis *active_output_basis) { 2231203703bSJeremy L Thompson bool is_composite; 2241203703bSJeremy L Thompson CeedInt num_input_fields, num_output_fields; 2251203703bSJeremy L Thompson CeedOperatorField *op_input_fields, *op_output_fields; 2261c66c397SJeremy L Thompson 2271203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 2281203703bSJeremy L Thompson CeedCall(CeedOperatorGetFields(op, &num_input_fields, &op_input_fields, &num_output_fields, &op_output_fields)); 2291203703bSJeremy L Thompson 230506b1a0cSSebastian Grimberg if (active_input_basis) { 231506b1a0cSSebastian Grimberg *active_input_basis = NULL; 2321203703bSJeremy L Thompson if (!is_composite) { 2331203703bSJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 2341203703bSJeremy L Thompson CeedVector vec; 2351203703bSJeremy L Thompson 2361203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_input_fields[i], &vec)); 2371203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 2381203703bSJeremy L Thompson CeedBasis basis; 2391203703bSJeremy L Thompson 2401203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(op_input_fields[i], &basis)); 2419bc66399SJeremy L Thompson CeedCheck(!*active_input_basis || *active_input_basis == basis, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, 2429bc66399SJeremy L Thompson "Multiple active input CeedBases found"); 243681d0ea7SJeremy L Thompson if (!*active_input_basis) CeedCall(CeedBasisReferenceCopy(basis, active_input_basis)); 244681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 245eaf62fffSJeremy L Thompson } 246681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 2472b730f8bSJeremy L Thompson } 2489bc66399SJeremy L Thompson CeedCheck(*active_input_basis, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "No active input CeedBasis found"); 249506b1a0cSSebastian Grimberg } 250506b1a0cSSebastian Grimberg } 251506b1a0cSSebastian Grimberg if (active_output_basis) { 252506b1a0cSSebastian Grimberg *active_output_basis = NULL; 2531203703bSJeremy L Thompson if (!is_composite) { 2541203703bSJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 2551203703bSJeremy L Thompson CeedVector vec; 2561203703bSJeremy L Thompson 2571203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_output_fields[i], &vec)); 2581203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 2591203703bSJeremy L Thompson CeedBasis basis; 2601203703bSJeremy L Thompson 2611203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(op_output_fields[i], &basis)); 2629bc66399SJeremy L Thompson CeedCheck(!*active_output_basis || *active_output_basis == basis, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, 2639bc66399SJeremy L Thompson "Multiple active output CeedBases found"); 264681d0ea7SJeremy L Thompson if (!*active_output_basis) CeedCall(CeedBasisReferenceCopy(basis, active_output_basis)); 265681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 266506b1a0cSSebastian Grimberg } 267681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 268506b1a0cSSebastian Grimberg } 2699bc66399SJeremy L Thompson CeedCheck(*active_output_basis, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "No active output CeedBasis found"); 270506b1a0cSSebastian Grimberg } 271506b1a0cSSebastian Grimberg } 272eaf62fffSJeremy L Thompson return CEED_ERROR_SUCCESS; 273eaf62fffSJeremy L Thompson } 274eaf62fffSJeremy L Thompson 275eaf62fffSJeremy L Thompson /** 276681d0ea7SJeremy L Thompson @brief Find the active vector `CeedElemRestriction` for a non-composite `CeedOperator`. 277681d0ea7SJeremy L Thompson 278681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `active_rstr` with @ref CeedElemRestrictionDestroy(). 279e2f04181SAndrew T. Barker 280ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to find active `CeedElemRestriction` for 281ca94c3ddSJeremy L Thompson @param[out] active_rstr `CeedElemRestriction` for active input vector or NULL for composite operator 282e2f04181SAndrew T. Barker 283e2f04181SAndrew T. Barker @return An error code: 0 - success, otherwise - failure 284e2f04181SAndrew T. Barker 285e2f04181SAndrew T. Barker @ref Utility 286e2f04181SAndrew T. Barker **/ 2872b730f8bSJeremy L Thompson int CeedOperatorGetActiveElemRestriction(CeedOperator op, CeedElemRestriction *active_rstr) { 288506b1a0cSSebastian Grimberg CeedCall(CeedOperatorGetActiveElemRestrictions(op, active_rstr, NULL)); 289506b1a0cSSebastian Grimberg return CEED_ERROR_SUCCESS; 290506b1a0cSSebastian Grimberg } 291506b1a0cSSebastian Grimberg 292506b1a0cSSebastian Grimberg /** 293681d0ea7SJeremy L Thompson @brief Find the active input and output vector `CeedElemRestriction` for a non-composite `CeedOperator`. 294681d0ea7SJeremy L Thompson 295681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the restrictions with @ref CeedElemRestrictionDestroy(). 296506b1a0cSSebastian Grimberg 297ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to find active `CeedElemRestriction` for 298ca94c3ddSJeremy L Thompson @param[out] active_input_rstr `CeedElemRestriction` for active input vector or NULL for composite operator 299ca94c3ddSJeremy L Thompson @param[out] active_output_rstr `CeedElemRestriction` for active output vector or NULL for composite operator 300506b1a0cSSebastian Grimberg 301506b1a0cSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 302506b1a0cSSebastian Grimberg 303506b1a0cSSebastian Grimberg @ref Utility 304506b1a0cSSebastian Grimberg **/ 305506b1a0cSSebastian Grimberg int CeedOperatorGetActiveElemRestrictions(CeedOperator op, CeedElemRestriction *active_input_rstr, CeedElemRestriction *active_output_rstr) { 3061203703bSJeremy L Thompson bool is_composite; 3071203703bSJeremy L Thompson CeedInt num_input_fields, num_output_fields; 3081203703bSJeremy L Thompson CeedOperatorField *op_input_fields, *op_output_fields; 3091c66c397SJeremy L Thompson 3101203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 3111203703bSJeremy L Thompson CeedCall(CeedOperatorGetFields(op, &num_input_fields, &op_input_fields, &num_output_fields, &op_output_fields)); 3121203703bSJeremy L Thompson 313506b1a0cSSebastian Grimberg if (active_input_rstr) { 314506b1a0cSSebastian Grimberg *active_input_rstr = NULL; 3151203703bSJeremy L Thompson if (!is_composite) { 3161203703bSJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 3171203703bSJeremy L Thompson CeedVector vec; 3181203703bSJeremy L Thompson 3191203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_input_fields[i], &vec)); 3201203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 3211203703bSJeremy L Thompson CeedElemRestriction rstr; 3221203703bSJeremy L Thompson 3231203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetElemRestriction(op_input_fields[i], &rstr)); 3249bc66399SJeremy L Thompson CeedCheck(!*active_input_rstr || *active_input_rstr == rstr, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, 3259bc66399SJeremy L Thompson "Multiple active input CeedElemRestrictions found"); 326681d0ea7SJeremy L Thompson if (!*active_input_rstr) CeedCall(CeedElemRestrictionReferenceCopy(rstr, active_input_rstr)); 327681d0ea7SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr)); 328e2f04181SAndrew T. Barker } 329681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 3302b730f8bSJeremy L Thompson } 3319bc66399SJeremy L Thompson CeedCheck(*active_input_rstr, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "No active input CeedElemRestriction found"); 332506b1a0cSSebastian Grimberg } 333506b1a0cSSebastian Grimberg } 334506b1a0cSSebastian Grimberg if (active_output_rstr) { 335506b1a0cSSebastian Grimberg *active_output_rstr = NULL; 3361203703bSJeremy L Thompson if (!is_composite) { 3371203703bSJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 3381203703bSJeremy L Thompson CeedVector vec; 3391203703bSJeremy L Thompson 3401203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_output_fields[i], &vec)); 3411203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 3421203703bSJeremy L Thompson CeedElemRestriction rstr; 3431203703bSJeremy L Thompson 3441203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetElemRestriction(op_output_fields[i], &rstr)); 3459bc66399SJeremy L Thompson CeedCheck(!*active_output_rstr || *active_output_rstr == rstr, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, 3469bc66399SJeremy L Thompson "Multiple active output CeedElemRestrictions found"); 347681d0ea7SJeremy L Thompson if (!*active_output_rstr) CeedCall(CeedElemRestrictionReferenceCopy(rstr, active_output_rstr)); 348681d0ea7SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr)); 349506b1a0cSSebastian Grimberg } 350681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 351506b1a0cSSebastian Grimberg } 3529bc66399SJeremy L Thompson CeedCheck(*active_output_rstr, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "No active output CeedElemRestriction found"); 353506b1a0cSSebastian Grimberg } 354506b1a0cSSebastian Grimberg } 355e2f04181SAndrew T. Barker return CEED_ERROR_SUCCESS; 356e2f04181SAndrew T. Barker } 357e2f04181SAndrew T. Barker 358d8dd9a91SJeremy L Thompson /** 359ca94c3ddSJeremy L Thompson @brief Set `CeedQFunctionContext` field values of the specified type. 3604385fb7fSSebastian Grimberg 361ca94c3ddSJeremy L Thompson For composite operators, the value is set in all sub-operator `CeedQFunctionContext` that have a matching `field_name`. 362ca94c3ddSJeremy 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. 363d8dd9a91SJeremy L Thompson 364ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 365ea61e9acSJeremy L Thompson @param[in] field_label Label of field to set 366ea61e9acSJeremy L Thompson @param[in] field_type Type of field to set 3672788fa27SJeremy L Thompson @param[in] values Values to set 368d8dd9a91SJeremy L Thompson 369d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 370d8dd9a91SJeremy L Thompson 3716ab8e59fSJames Wright @ref Developer 372d8dd9a91SJeremy L Thompson **/ 3732788fa27SJeremy L Thompson static int CeedOperatorContextSetGeneric(CeedOperator op, CeedContextFieldLabel field_label, CeedContextFieldType field_type, void *values) { 3741c66c397SJeremy L Thompson bool is_composite = false; 3751c66c397SJeremy L Thompson 3769bc66399SJeremy L Thompson CeedCheck(field_label, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3773668ca4bSJeremy L Thompson 3785ac9af79SJeremy L Thompson // Check if field_label and op correspond 3795ac9af79SJeremy L Thompson if (field_label->from_op) { 3805ac9af79SJeremy L Thompson CeedInt index = -1; 3815ac9af79SJeremy L Thompson 3825ac9af79SJeremy L Thompson for (CeedInt i = 0; i < op->num_context_labels; i++) { 3835ac9af79SJeremy L Thompson if (op->context_labels[i] == field_label) index = i; 3845ac9af79SJeremy L Thompson } 3859bc66399SJeremy L Thompson CeedCheck(index != -1, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "ContextFieldLabel does not correspond to the operator"); 3865ac9af79SJeremy L Thompson } 3875ac9af79SJeremy L Thompson 3882b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 389d8dd9a91SJeremy L Thompson if (is_composite) { 390d8dd9a91SJeremy L Thompson CeedInt num_sub; 391d8dd9a91SJeremy L Thompson CeedOperator *sub_operators; 392d8dd9a91SJeremy L Thompson 393ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_sub)); 394ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 3959bc66399SJeremy L Thompson CeedCheck(num_sub == field_label->num_sub_labels, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, 3969bc66399SJeremy L Thompson "Composite operator modified after ContextFieldLabel created"); 397d8dd9a91SJeremy L Thompson 398d8dd9a91SJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 3991203703bSJeremy L Thompson CeedQFunctionContext ctx; 4001203703bSJeremy L Thompson 4011485364cSJeremy L Thompson CeedCall(CeedOperatorGetContext(sub_operators[i], &ctx)); 402d8dd9a91SJeremy L Thompson // Try every sub-operator, ok if some sub-operators do not have field 4031485364cSJeremy L Thompson if (ctx && field_label->sub_labels[i]) { 4041203703bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label->sub_labels[i], field_type, values)); 405d8dd9a91SJeremy L Thompson } 4061485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 407d8dd9a91SJeremy L Thompson } 408d8dd9a91SJeremy L Thompson } else { 4091203703bSJeremy L Thompson CeedQFunctionContext ctx; 4101203703bSJeremy L Thompson 4111485364cSJeremy L Thompson CeedCall(CeedOperatorGetContext(op, &ctx)); 4129bc66399SJeremy L Thompson CeedCheck(ctx, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "QFunction does not have context data"); 4131203703bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, field_type, values)); 4141485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 4152788fa27SJeremy L Thompson } 4166d95ab46SJeremy L Thompson CeedCall(CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(op, true)); 4172788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4182788fa27SJeremy L Thompson } 4192788fa27SJeremy L Thompson 4202788fa27SJeremy L Thompson /** 421ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field values of the specified type, read-only. 4224385fb7fSSebastian Grimberg 423ca94c3ddSJeremy L Thompson For composite operators, the values retrieved are for the first sub-operator `CeedQFunctionContext` that have a matching `field_name`. 424ca94c3ddSJeremy 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. 4252788fa27SJeremy L Thompson 426ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 4272788fa27SJeremy L Thompson @param[in] field_label Label of field to set 4282788fa27SJeremy L Thompson @param[in] field_type Type of field to set 429c5d0f995SJed Brown @param[out] num_values Number of values of type `field_type` in array `values` 430c5d0f995SJed Brown @param[out] values Values in the label 4312788fa27SJeremy L Thompson 4322788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4332788fa27SJeremy L Thompson 4346ab8e59fSJames Wright @ref Developer 4352788fa27SJeremy L Thompson **/ 4362788fa27SJeremy L Thompson static int CeedOperatorContextGetGenericRead(CeedOperator op, CeedContextFieldLabel field_label, CeedContextFieldType field_type, size_t *num_values, 4372788fa27SJeremy L Thompson void *values) { 4381c66c397SJeremy L Thompson bool is_composite = false; 4391c66c397SJeremy L Thompson 4409bc66399SJeremy L Thompson CeedCheck(field_label, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4412788fa27SJeremy L Thompson 4422788fa27SJeremy L Thompson *(void **)values = NULL; 4432788fa27SJeremy L Thompson *num_values = 0; 4442788fa27SJeremy L Thompson 4455ac9af79SJeremy L Thompson // Check if field_label and op correspond 4465ac9af79SJeremy L Thompson if (field_label->from_op) { 4475ac9af79SJeremy L Thompson CeedInt index = -1; 4485ac9af79SJeremy L Thompson 4495ac9af79SJeremy L Thompson for (CeedInt i = 0; i < op->num_context_labels; i++) { 4505ac9af79SJeremy L Thompson if (op->context_labels[i] == field_label) index = i; 4515ac9af79SJeremy L Thompson } 4529bc66399SJeremy L Thompson CeedCheck(index != -1, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "ContextFieldLabel does not correspond to the operator"); 4535ac9af79SJeremy L Thompson } 4545ac9af79SJeremy L Thompson 4552788fa27SJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 4562788fa27SJeremy L Thompson if (is_composite) { 4572788fa27SJeremy L Thompson CeedInt num_sub; 4582788fa27SJeremy L Thompson CeedOperator *sub_operators; 4592788fa27SJeremy L Thompson 460ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_sub)); 461ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 4629bc66399SJeremy L Thompson CeedCheck(num_sub == field_label->num_sub_labels, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, 4639bc66399SJeremy L Thompson "Composite operator modified after ContextFieldLabel created"); 4642788fa27SJeremy L Thompson 4652788fa27SJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 4661203703bSJeremy L Thompson CeedQFunctionContext ctx; 4671203703bSJeremy L Thompson 4681485364cSJeremy L Thompson CeedCall(CeedOperatorGetContext(sub_operators[i], &ctx)); 4692788fa27SJeremy L Thompson // Try every sub-operator, ok if some sub-operators do not have field 4701485364cSJeremy L Thompson if (ctx && field_label->sub_labels[i]) { 4711203703bSJeremy L Thompson CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label->sub_labels[i], field_type, num_values, values)); 4721485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 4732788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4742788fa27SJeremy L Thompson } 4751485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 4762788fa27SJeremy L Thompson } 4772788fa27SJeremy L Thompson } else { 4781203703bSJeremy L Thompson CeedQFunctionContext ctx; 4791203703bSJeremy L Thompson 4801485364cSJeremy L Thompson CeedCall(CeedOperatorGetContext(op, &ctx)); 4819bc66399SJeremy L Thompson CeedCheck(ctx, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "QFunction does not have context data"); 4821203703bSJeremy L Thompson CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, field_type, num_values, values)); 4831485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 4842788fa27SJeremy L Thompson } 4852788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4862788fa27SJeremy L Thompson } 4872788fa27SJeremy L Thompson 4882788fa27SJeremy L Thompson /** 489ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field values of the specified type, read-only. 4904385fb7fSSebastian Grimberg 491ca94c3ddSJeremy L Thompson For composite operators, the values restored are for the first sub-operator `CeedQFunctionContext` that have a matching `field_name`. 492ca94c3ddSJeremy 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. 4932788fa27SJeremy L Thompson 494ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 4952788fa27SJeremy L Thompson @param[in] field_label Label of field to set 4962788fa27SJeremy L Thompson @param[in] field_type Type of field to set 497c5d0f995SJed Brown @param[in] values Values array to restore 4982788fa27SJeremy L Thompson 4992788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 5002788fa27SJeremy L Thompson 5016ab8e59fSJames Wright @ref Developer 5022788fa27SJeremy L Thompson **/ 5032788fa27SJeremy L Thompson static int CeedOperatorContextRestoreGenericRead(CeedOperator op, CeedContextFieldLabel field_label, CeedContextFieldType field_type, void *values) { 5041c66c397SJeremy L Thompson bool is_composite = false; 5051c66c397SJeremy L Thompson 5069bc66399SJeremy L Thompson CeedCheck(field_label, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "Invalid field label"); 5072788fa27SJeremy L Thompson 5085ac9af79SJeremy L Thompson // Check if field_label and op correspond 5095ac9af79SJeremy L Thompson if (field_label->from_op) { 5105ac9af79SJeremy L Thompson CeedInt index = -1; 5115ac9af79SJeremy L Thompson 5125ac9af79SJeremy L Thompson for (CeedInt i = 0; i < op->num_context_labels; i++) { 5135ac9af79SJeremy L Thompson if (op->context_labels[i] == field_label) index = i; 5145ac9af79SJeremy L Thompson } 5159bc66399SJeremy L Thompson CeedCheck(index != -1, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "ContextFieldLabel does not correspond to the operator"); 5165ac9af79SJeremy L Thompson } 5175ac9af79SJeremy L Thompson 5182788fa27SJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 5192788fa27SJeremy L Thompson if (is_composite) { 5202788fa27SJeremy L Thompson CeedInt num_sub; 5212788fa27SJeremy L Thompson CeedOperator *sub_operators; 5222788fa27SJeremy L Thompson 523ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_sub)); 524ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 5259bc66399SJeremy L Thompson CeedCheck(num_sub == field_label->num_sub_labels, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, 5269bc66399SJeremy L Thompson "Composite operator modified after ContextFieldLabel created"); 5272788fa27SJeremy L Thompson 5282788fa27SJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 5291203703bSJeremy L Thompson CeedQFunctionContext ctx; 5301203703bSJeremy L Thompson 5311485364cSJeremy L Thompson CeedCall(CeedOperatorGetContext(sub_operators[i], &ctx)); 5322788fa27SJeremy L Thompson // Try every sub-operator, ok if some sub-operators do not have field 5331485364cSJeremy L Thompson if (ctx && field_label->sub_labels[i]) { 5341203703bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label->sub_labels[i], field_type, values)); 5351485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 5362788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 5372788fa27SJeremy L Thompson } 5381485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 5392788fa27SJeremy L Thompson } 5402788fa27SJeremy L Thompson } else { 5411203703bSJeremy L Thompson CeedQFunctionContext ctx; 5421203703bSJeremy L Thompson 5431485364cSJeremy L Thompson CeedCall(CeedOperatorGetContext(op, &ctx)); 5449bc66399SJeremy L Thompson CeedCheck(ctx, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, "QFunction does not have context data"); 5451203703bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, field_type, values)); 5461485364cSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&ctx)); 547d8dd9a91SJeremy L Thompson } 548d8dd9a91SJeremy L Thompson return CEED_ERROR_SUCCESS; 549d8dd9a91SJeremy L Thompson } 550d8dd9a91SJeremy L Thompson 5517a982d89SJeremy L. Thompson /// @} 5527a982d89SJeremy L. Thompson 5537a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5547a982d89SJeremy L. Thompson /// CeedOperator Backend API 5557a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5567a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorBackend 5577a982d89SJeremy L. Thompson /// @{ 5587a982d89SJeremy L. Thompson 5597a982d89SJeremy L. Thompson /** 560ca94c3ddSJeremy L Thompson @brief Get the number of arguments associated with a `CeedOperator` 5617a982d89SJeremy L. Thompson 562ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 563d1d35e2fSjeremylt @param[out] num_args Variable to store vector number of arguments 5647a982d89SJeremy L. Thompson 5657a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5667a982d89SJeremy L. Thompson 5677a982d89SJeremy L. Thompson @ref Backend 5687a982d89SJeremy L. Thompson **/ 569d1d35e2fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *num_args) { 5701203703bSJeremy L Thompson bool is_composite; 5711203703bSJeremy L Thompson 5721203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 5736e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Not defined for composite operators"); 574d1d35e2fSjeremylt *num_args = op->num_fields; 575e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5767a982d89SJeremy L. Thompson } 5777a982d89SJeremy L. Thompson 5787a982d89SJeremy L. Thompson /** 5799463e855SJeremy L Thompson @brief Get the tensor product status of all bases for a `CeedOperator`. 5809463e855SJeremy L Thompson 5819463e855SJeremy L Thompson `has_tensor_bases` is only set to `true` if every field uses a tensor-product basis. 5829463e855SJeremy L Thompson 5839463e855SJeremy L Thompson @param[in] op `CeedOperator` 5849463e855SJeremy L Thompson @param[out] has_tensor_bases Variable to store tensor bases status 5859463e855SJeremy L Thompson 5869463e855SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 5879463e855SJeremy L Thompson 5889463e855SJeremy L Thompson @ref Backend 5899463e855SJeremy L Thompson **/ 5909463e855SJeremy L Thompson int CeedOperatorHasTensorBases(CeedOperator op, bool *has_tensor_bases) { 5919463e855SJeremy L Thompson CeedInt num_inputs, num_outputs; 5929463e855SJeremy L Thompson CeedOperatorField *input_fields, *output_fields; 5939463e855SJeremy L Thompson 5949463e855SJeremy L Thompson CeedCall(CeedOperatorGetFields(op, &num_inputs, &input_fields, &num_outputs, &output_fields)); 5959463e855SJeremy L Thompson *has_tensor_bases = true; 5969463e855SJeremy L Thompson for (CeedInt i = 0; i < num_inputs; i++) { 5979463e855SJeremy L Thompson bool is_tensor; 5989463e855SJeremy L Thompson CeedBasis basis; 5999463e855SJeremy L Thompson 6009463e855SJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(input_fields[i], &basis)); 6019463e855SJeremy L Thompson if (basis != CEED_BASIS_NONE) { 6029463e855SJeremy L Thompson CeedCall(CeedBasisIsTensor(basis, &is_tensor)); 603025ec10cSJeremy L Thompson *has_tensor_bases = *has_tensor_bases & is_tensor; 6049463e855SJeremy L Thompson } 605681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 6069463e855SJeremy L Thompson } 6079463e855SJeremy L Thompson for (CeedInt i = 0; i < num_outputs; i++) { 6089463e855SJeremy L Thompson bool is_tensor; 6099463e855SJeremy L Thompson CeedBasis basis; 6109463e855SJeremy L Thompson 6119463e855SJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(output_fields[i], &basis)); 6129463e855SJeremy L Thompson if (basis != CEED_BASIS_NONE) { 6139463e855SJeremy L Thompson CeedCall(CeedBasisIsTensor(basis, &is_tensor)); 614025ec10cSJeremy L Thompson *has_tensor_bases = *has_tensor_bases & is_tensor; 6159463e855SJeremy L Thompson } 616681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 6179463e855SJeremy L Thompson } 6189463e855SJeremy L Thompson return CEED_ERROR_SUCCESS; 6199463e855SJeremy L Thompson } 6209463e855SJeremy L Thompson 6219463e855SJeremy L Thompson /** 6221203703bSJeremy L Thompson @brief Get a boolean value indicating if the `CeedOperator` is immutable 6231203703bSJeremy L Thompson 6241203703bSJeremy L Thompson @param[in] op `CeedOperator` 6251203703bSJeremy L Thompson @param[out] is_immutable Variable to store immutability status 6261203703bSJeremy L Thompson 6271203703bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 6281203703bSJeremy L Thompson 6291203703bSJeremy L Thompson @ref Backend 6301203703bSJeremy L Thompson **/ 6311203703bSJeremy L Thompson int CeedOperatorIsImmutable(CeedOperator op, bool *is_immutable) { 6321203703bSJeremy L Thompson *is_immutable = op->is_immutable; 6331203703bSJeremy L Thompson return CEED_ERROR_SUCCESS; 6341203703bSJeremy L Thompson } 6351203703bSJeremy L Thompson 6361203703bSJeremy L Thompson /** 637ca94c3ddSJeremy L Thompson @brief Get the setup status of a `CeedOperator` 6387a982d89SJeremy L. Thompson 639ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 640d1d35e2fSjeremylt @param[out] is_setup_done Variable to store setup status 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 **/ 646d1d35e2fSjeremylt int CeedOperatorIsSetupDone(CeedOperator op, bool *is_setup_done) { 647f04ea552SJeremy L Thompson *is_setup_done = op->is_backend_setup; 648e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6497a982d89SJeremy L. Thompson } 6507a982d89SJeremy L. Thompson 6517a982d89SJeremy L. Thompson /** 652ca94c3ddSJeremy L Thompson @brief Get the `CeedQFunction` associated with a `CeedOperator` 6537a982d89SJeremy L. Thompson 654ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 655ca94c3ddSJeremy L Thompson @param[out] qf Variable to store `CeedQFunction` 6567a982d89SJeremy L. Thompson 6577a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6587a982d89SJeremy L. Thompson 6597a982d89SJeremy L. Thompson @ref Backend 6607a982d89SJeremy L. Thompson **/ 6617a982d89SJeremy L. Thompson int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 6621203703bSJeremy L Thompson bool is_composite; 6631203703bSJeremy L Thompson 6641203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 6656e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Not defined for composite operator"); 666c11e12f4SJeremy L Thompson *qf = NULL; 667c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionReferenceCopy(op->qf, qf)); 668e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6697a982d89SJeremy L. Thompson } 6707a982d89SJeremy L. Thompson 6717a982d89SJeremy L. Thompson /** 672ca94c3ddSJeremy L Thompson @brief Get a boolean value indicating if the `CeedOperator` is composite 673c04a41a7SJeremy L Thompson 674ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 675d1d35e2fSjeremylt @param[out] is_composite Variable to store composite status 676c04a41a7SJeremy L Thompson 677c04a41a7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 678c04a41a7SJeremy L Thompson 679c04a41a7SJeremy L Thompson @ref Backend 680c04a41a7SJeremy L Thompson **/ 681d1d35e2fSjeremylt int CeedOperatorIsComposite(CeedOperator op, bool *is_composite) { 682f04ea552SJeremy L Thompson *is_composite = op->is_composite; 683e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 684c04a41a7SJeremy L Thompson } 685c04a41a7SJeremy L Thompson 686c04a41a7SJeremy L Thompson /** 687ca94c3ddSJeremy L Thompson @brief Get the backend data of a `CeedOperator` 6887a982d89SJeremy L. Thompson 689ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 6907a982d89SJeremy L. Thompson @param[out] data Variable to store data 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 CeedOperatorGetData(CeedOperator op, void *data) { 697777ff853SJeremy L Thompson *(void **)data = op->data; 698e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6997a982d89SJeremy L. Thompson } 7007a982d89SJeremy L. Thompson 7017a982d89SJeremy L. Thompson /** 702ca94c3ddSJeremy L Thompson @brief Set the backend data of a `CeedOperator` 7037a982d89SJeremy L. Thompson 704ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 705ea61e9acSJeremy L Thompson @param[in] data Data to set 7067a982d89SJeremy L. Thompson 7077a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 7087a982d89SJeremy L. Thompson 7097a982d89SJeremy L. Thompson @ref Backend 7107a982d89SJeremy L. Thompson **/ 711777ff853SJeremy L Thompson int CeedOperatorSetData(CeedOperator op, void *data) { 712777ff853SJeremy L Thompson op->data = data; 713e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7147a982d89SJeremy L. Thompson } 7157a982d89SJeremy L. Thompson 7167a982d89SJeremy L. Thompson /** 717ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `CeedOperator` 71834359f16Sjeremylt 719ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` to increment the reference counter 72034359f16Sjeremylt 72134359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 72234359f16Sjeremylt 72334359f16Sjeremylt @ref Backend 72434359f16Sjeremylt **/ 7259560d06aSjeremylt int CeedOperatorReference(CeedOperator op) { 72634359f16Sjeremylt op->ref_count++; 72734359f16Sjeremylt return CEED_ERROR_SUCCESS; 72834359f16Sjeremylt } 72934359f16Sjeremylt 73034359f16Sjeremylt /** 731ca94c3ddSJeremy L Thompson @brief Set the setup flag of a `CeedOperator` to `true` 7327a982d89SJeremy L. Thompson 733ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 7347a982d89SJeremy L. Thompson 7357a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 7367a982d89SJeremy L. Thompson 7377a982d89SJeremy L. Thompson @ref Backend 7387a982d89SJeremy L. Thompson **/ 7397a982d89SJeremy L. Thompson int CeedOperatorSetSetupDone(CeedOperator op) { 740f04ea552SJeremy L Thompson op->is_backend_setup = true; 741e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7427a982d89SJeremy L. Thompson } 7437a982d89SJeremy L. Thompson 7447a982d89SJeremy L. Thompson /// @} 7457a982d89SJeremy L. Thompson 7467a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 7477a982d89SJeremy L. Thompson /// CeedOperator Public API 7487a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 7497a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorUser 750dfdf5a53Sjeremylt /// @{ 751d7b241e6Sjeremylt 752d7b241e6Sjeremylt /** 753ca94c3ddSJeremy L Thompson @brief Create a `CeedOperator` and associate a `CeedQFunction`. 7544385fb7fSSebastian Grimberg 755ca94c3ddSJeremy L Thompson A `CeedBasis` and `CeedElemRestriction` can be associated with `CeedQFunction` fields with @ref CeedOperatorSetField(). 756d7b241e6Sjeremylt 757ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedOperator` 758ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` defining the action of the operator at quadrature points 759ca94c3ddSJeremy L Thompson @param[in] dqf `CeedQFunction` defining the action of the Jacobian of `qf` (or @ref CEED_QFUNCTION_NONE) 760ca94c3ddSJeremy L Thompson @param[in] dqfT `CeedQFunction` defining the action of the transpose of the Jacobian of `qf` (or @ref CEED_QFUNCTION_NONE) 761ca94c3ddSJeremy L Thompson @param[out] op Address of the variable where the newly created `CeedOperator` will be stored 762b11c1e72Sjeremylt 763b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 764dfdf5a53Sjeremylt 7657a982d89SJeremy L. Thompson @ref User 766d7b241e6Sjeremylt */ 7672b730f8bSJeremy L Thompson int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, CeedQFunction dqfT, CeedOperator *op) { 7685fe0d4faSjeremylt if (!ceed->OperatorCreate) { 7695fe0d4faSjeremylt Ceed delegate; 7706574a04fSJeremy L Thompson 7712b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Operator")); 7721ef3a2a9SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedOperatorCreate"); 7732b730f8bSJeremy L Thompson CeedCall(CeedOperatorCreate(delegate, qf, dqf, dqfT, op)); 7749bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 775e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7765fe0d4faSjeremylt } 7775fe0d4faSjeremylt 778ca94c3ddSJeremy L Thompson CeedCheck(qf && qf != CEED_QFUNCTION_NONE, ceed, CEED_ERROR_MINOR, "Operator must have a valid CeedQFunction."); 779db002c03SJeremy L Thompson 7802b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, op)); 781db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*op)->ceed)); 782d1d35e2fSjeremylt (*op)->ref_count = 1; 7832b104005SJeremy L Thompson (*op)->input_size = -1; 7842b104005SJeremy L Thompson (*op)->output_size = -1; 785db002c03SJeremy L Thompson CeedCall(CeedQFunctionReferenceCopy(qf, &(*op)->qf)); 786db002c03SJeremy L Thompson if (dqf && dqf != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionReferenceCopy(dqf, &(*op)->dqf)); 787db002c03SJeremy L Thompson if (dqfT && dqfT != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionReferenceCopy(dqfT, &(*op)->dqfT)); 7882b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*op)->input_fields)); 7892b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*op)->output_fields)); 7902b730f8bSJeremy L Thompson CeedCall(ceed->OperatorCreate(*op)); 791e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 792d7b241e6Sjeremylt } 793d7b241e6Sjeremylt 794d7b241e6Sjeremylt /** 795ca94c3ddSJeremy L Thompson @brief Create a `CeedOperator` for evaluation at evaluation at arbitrary points in each element. 79648acf710SJeremy L Thompson 797ca94c3ddSJeremy L Thompson A `CeedBasis` and `CeedElemRestriction` can be associated with `CeedQFunction` fields with `CeedOperator` SetField. 798ca94c3ddSJeremy L Thompson The locations of each point are set with @ref CeedOperatorAtPointsSetPoints(). 79948acf710SJeremy L Thompson 800ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedOperator` 801ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` defining the action of the operator at quadrature points 802ca94c3ddSJeremy L Thompson @param[in] dqf `CeedQFunction` defining the action of the Jacobian of @a qf (or @ref CEED_QFUNCTION_NONE) 803ca94c3ddSJeremy L Thompson @param[in] dqfT `CeedQFunction` defining the action of the transpose of the Jacobian of @a qf (or @ref CEED_QFUNCTION_NONE) 80448acf710SJeremy L Thompson @param[out] op Address of the variable where the newly created CeedOperator will be stored 80548acf710SJeremy L Thompson 80648acf710SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 80748acf710SJeremy L Thompson 80848acf710SJeremy L Thompson @ref User 80948acf710SJeremy L Thompson */ 81048acf710SJeremy L Thompson int CeedOperatorCreateAtPoints(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, CeedQFunction dqfT, CeedOperator *op) { 81148acf710SJeremy L Thompson if (!ceed->OperatorCreateAtPoints) { 81248acf710SJeremy L Thompson Ceed delegate; 81348acf710SJeremy L Thompson 81448acf710SJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Operator")); 8151ef3a2a9SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedOperatorCreateAtPoints"); 81648acf710SJeremy L Thompson CeedCall(CeedOperatorCreateAtPoints(delegate, qf, dqf, dqfT, op)); 8179bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 81848acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 81948acf710SJeremy L Thompson } 82048acf710SJeremy L Thompson 821ca94c3ddSJeremy L Thompson CeedCheck(qf && qf != CEED_QFUNCTION_NONE, ceed, CEED_ERROR_MINOR, "Operator must have a valid CeedQFunction."); 82248acf710SJeremy L Thompson 82348acf710SJeremy L Thompson CeedCall(CeedCalloc(1, op)); 82448acf710SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*op)->ceed)); 82548acf710SJeremy L Thompson (*op)->ref_count = 1; 82648acf710SJeremy L Thompson (*op)->is_at_points = true; 82748acf710SJeremy L Thompson (*op)->input_size = -1; 82848acf710SJeremy L Thompson (*op)->output_size = -1; 82948acf710SJeremy L Thompson CeedCall(CeedQFunctionReferenceCopy(qf, &(*op)->qf)); 83048acf710SJeremy L Thompson if (dqf && dqf != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionReferenceCopy(dqf, &(*op)->dqf)); 83148acf710SJeremy L Thompson if (dqfT && dqfT != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionReferenceCopy(dqfT, &(*op)->dqfT)); 83248acf710SJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*op)->input_fields)); 83348acf710SJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*op)->output_fields)); 83448acf710SJeremy L Thompson CeedCall(ceed->OperatorCreateAtPoints(*op)); 83548acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 83648acf710SJeremy L Thompson } 83748acf710SJeremy L Thompson 83848acf710SJeremy L Thompson /** 839ca94c3ddSJeremy L Thompson @brief Create a composite `CeedOperator` that composes the action of several `CeedOperator` 84052d6035fSJeremy L Thompson 841ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedOperator` 842ca94c3ddSJeremy L Thompson @param[out] op Address of the variable where the newly created composite `CeedOperator` will be stored 84352d6035fSJeremy L Thompson 84452d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 84552d6035fSJeremy L Thompson 8467a982d89SJeremy L. Thompson @ref User 84752d6035fSJeremy L Thompson */ 848ed094490SJeremy L Thompson int CeedOperatorCreateComposite(Ceed ceed, CeedOperator *op) { 84952d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 85052d6035fSJeremy L Thompson Ceed delegate; 85152d6035fSJeremy L Thompson 8521c66c397SJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Operator")); 853250756a7Sjeremylt if (delegate) { 854ed094490SJeremy L Thompson CeedCall(CeedOperatorCreateComposite(delegate, op)); 8559bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 856e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 85752d6035fSJeremy L Thompson } 858250756a7Sjeremylt } 85952d6035fSJeremy L Thompson 8602b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, op)); 861db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*op)->ceed)); 862996d9ab5SJed Brown (*op)->ref_count = 1; 863f04ea552SJeremy L Thompson (*op)->is_composite = true; 8642b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_COMPOSITE_MAX, &(*op)->sub_operators)); 8652b104005SJeremy L Thompson (*op)->input_size = -1; 8662b104005SJeremy L Thompson (*op)->output_size = -1; 867250756a7Sjeremylt 868db002c03SJeremy L Thompson if (ceed->CompositeOperatorCreate) CeedCall(ceed->CompositeOperatorCreate(*op)); 869e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 87052d6035fSJeremy L Thompson } 87152d6035fSJeremy L Thompson 87252d6035fSJeremy L Thompson /** 873ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedOperator`. 8744385fb7fSSebastian Grimberg 875ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedOperatorDestroy(). 876512bb800SJeremy L Thompson 877ca94c3ddSJeremy 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`. 878ca94c3ddSJeremy L Thompson This `CeedOperator` will be destroyed if `*op_copy` is the only reference to this `CeedOperator`. 8799560d06aSjeremylt 880ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to copy reference to 881ea61e9acSJeremy L Thompson @param[in,out] op_copy Variable to store copied reference 8829560d06aSjeremylt 8839560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 8849560d06aSjeremylt 8859560d06aSjeremylt @ref User 8869560d06aSjeremylt **/ 8879560d06aSjeremylt int CeedOperatorReferenceCopy(CeedOperator op, CeedOperator *op_copy) { 8882b730f8bSJeremy L Thompson CeedCall(CeedOperatorReference(op)); 8892b730f8bSJeremy L Thompson CeedCall(CeedOperatorDestroy(op_copy)); 8909560d06aSjeremylt *op_copy = op; 8919560d06aSjeremylt return CEED_ERROR_SUCCESS; 8929560d06aSjeremylt } 8939560d06aSjeremylt 8949560d06aSjeremylt /** 895ca94c3ddSJeremy L Thompson @brief Provide a field to a `CeedOperator` for use by its `CeedQFunction`. 896d7b241e6Sjeremylt 897ca94c3ddSJeremy L Thompson This function is used to specify both active and passive fields to a `CeedOperator`. 898bafebce1SSebastian Grimberg For passive fields, a `CeedVector` `vec` must be provided. 899ea61e9acSJeremy L Thompson Passive fields can inputs or outputs (updated in-place when operator is applied). 900d7b241e6Sjeremylt 901ca94c3ddSJeremy L Thompson Active fields must be specified using this function, but their data (in a `CeedVector`) is passed in @ref CeedOperatorApply(). 902ca94c3ddSJeremy L Thompson There can be at most one active input `CeedVector` and at most one active output@ref CeedVector passed to @ref CeedOperatorApply(). 903d7b241e6Sjeremylt 904528a22edSJeremy L Thompson The number of quadrature points must agree across all points. 905bafebce1SSebastian Grimberg When using @ref CEED_BASIS_NONE, the number of quadrature points is determined by the element size of `rstr`. 906528a22edSJeremy L Thompson 907ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` on which to provide the field 908ca94c3ddSJeremy L Thompson @param[in] field_name Name of the field (to be matched with the name used by `CeedQFunction`) 909bafebce1SSebastian Grimberg @param[in] rstr `CeedElemRestriction` 910bafebce1SSebastian Grimberg @param[in] basis `CeedBasis` in which the field resides or @ref CEED_BASIS_NONE if collocated with quadrature points 911bafebce1SSebastian 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` 912b11c1e72Sjeremylt 913b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 914dfdf5a53Sjeremylt 9157a982d89SJeremy L. Thompson @ref User 916b11c1e72Sjeremylt **/ 917bafebce1SSebastian Grimberg int CeedOperatorSetField(CeedOperator op, const char *field_name, CeedElemRestriction rstr, CeedBasis basis, CeedVector vec) { 9181203703bSJeremy L Thompson bool is_input = true, is_at_points, is_composite, is_immutable; 9191203703bSJeremy L Thompson CeedInt num_elem = 0, num_qpts = 0, num_input_fields, num_output_fields; 9201203703bSJeremy L Thompson CeedQFunction qf; 9211203703bSJeremy L Thompson CeedQFunctionField qf_field, *qf_input_fields, *qf_output_fields; 9221c66c397SJeremy L Thompson CeedOperatorField *op_field; 9231c66c397SJeremy L Thompson 9241203703bSJeremy L Thompson CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 9251203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 9261203703bSJeremy L Thompson CeedCall(CeedOperatorIsImmutable(op, &is_immutable)); 9279bc66399SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "Cannot add field to composite operator."); 9289bc66399SJeremy L Thompson CeedCheck(!is_immutable, CeedOperatorReturnCeed(op), CEED_ERROR_MAJOR, "Operator cannot be changed after set as immutable"); 9299bc66399SJeremy L Thompson CeedCheck(rstr, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "CeedElemRestriction rstr for field \"%s\" must be non-NULL.", field_name); 9309bc66399SJeremy L Thompson CeedCheck(basis, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "CeedBasis basis for field \"%s\" must be non-NULL.", field_name); 9319bc66399SJeremy L Thompson CeedCheck(vec, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "CeedVector vec for field \"%s\" must be non-NULL.", field_name); 93252d6035fSJeremy L Thompson 933bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 9349bc66399SJeremy L Thompson CeedCheck(rstr == CEED_ELEMRESTRICTION_NONE || !op->has_restriction || num_elem == op->num_elem, CeedOperatorReturnCeed(op), CEED_ERROR_DIMENSION, 935ca94c3ddSJeremy L Thompson "CeedElemRestriction with %" CeedInt_FMT " elements incompatible with prior %" CeedInt_FMT " elements", num_elem, op->num_elem); 9362c7e7413SJeremy L Thompson { 9372c7e7413SJeremy L Thompson CeedRestrictionType rstr_type; 9382c7e7413SJeremy L Thompson 939bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 94048acf710SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) { 9419bc66399SJeremy L Thompson CeedCheck(is_at_points, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, 9429bc66399SJeremy L Thompson "CeedElemRestriction AtPoints not supported for standard operator fields"); 9439bc66399SJeremy L Thompson CeedCheck(basis == CEED_BASIS_NONE, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, 9449bc66399SJeremy L Thompson "CeedElemRestriction AtPoints must be used with CEED_BASIS_NONE"); 94548acf710SJeremy L Thompson if (!op->first_points_rstr) { 946bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &op->first_points_rstr)); 94748acf710SJeremy L Thompson } else { 94848acf710SJeremy L Thompson bool are_compatible; 94948acf710SJeremy L Thompson 950bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionAtPointsAreCompatible(op->first_points_rstr, rstr, &are_compatible)); 9519bc66399SJeremy L Thompson CeedCheck(are_compatible, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 952ca94c3ddSJeremy L Thompson "CeedElemRestriction must have compatible offsets with previously set CeedElemRestriction"); 95348acf710SJeremy L Thompson } 95448acf710SJeremy L Thompson } 9552c7e7413SJeremy L Thompson } 956d7b241e6Sjeremylt 957bafebce1SSebastian Grimberg if (basis == CEED_BASIS_NONE) CeedCall(CeedElemRestrictionGetElementSize(rstr, &num_qpts)); 958bafebce1SSebastian Grimberg else CeedCall(CeedBasisGetNumQuadraturePoints(basis, &num_qpts)); 9599bc66399SJeremy L Thompson CeedCheck(op->num_qpts == 0 || num_qpts == op->num_qpts, CeedOperatorReturnCeed(op), CEED_ERROR_DIMENSION, 960ca94c3ddSJeremy L Thompson "%s must correspond to the same number of quadrature points as previously added CeedBases. Found %" CeedInt_FMT 961528a22edSJeremy L Thompson " quadrature points but expected %" CeedInt_FMT " quadrature points.", 962bafebce1SSebastian Grimberg basis == CEED_BASIS_NONE ? "CeedElemRestriction" : "CeedBasis", num_qpts, op->num_qpts); 9631203703bSJeremy L Thompson 9641203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 9651203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFields(qf, &num_input_fields, &qf_input_fields, &num_output_fields, &qf_output_fields)); 966c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 9671203703bSJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 9686f8994e9SJeremy L Thompson const char *qf_field_name; 9691203703bSJeremy L Thompson 9701203703bSJeremy L Thompson CeedCall(CeedQFunctionFieldGetName(qf_input_fields[i], &qf_field_name)); 9711203703bSJeremy L Thompson if (!strcmp(field_name, qf_field_name)) { 9721203703bSJeremy L Thompson qf_field = qf_input_fields[i]; 973d1d35e2fSjeremylt op_field = &op->input_fields[i]; 974d7b241e6Sjeremylt goto found; 975d7b241e6Sjeremylt } 976d7b241e6Sjeremylt } 9772b104005SJeremy L Thompson is_input = false; 9781203703bSJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 9796f8994e9SJeremy L Thompson const char *qf_field_name; 9801203703bSJeremy L Thompson 9811203703bSJeremy L Thompson CeedCall(CeedQFunctionFieldGetName(qf_output_fields[i], &qf_field_name)); 9821203703bSJeremy L Thompson if (!strcmp(field_name, qf_field_name)) { 9831203703bSJeremy L Thompson qf_field = qf_output_fields[i]; 984d1d35e2fSjeremylt op_field = &op->output_fields[i]; 985d7b241e6Sjeremylt goto found; 986d7b241e6Sjeremylt } 987d7b241e6Sjeremylt } 988c042f62fSJeremy L Thompson // LCOV_EXCL_START 9899bc66399SJeremy L Thompson return CeedError(CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "CeedQFunction has no knowledge of field '%s'", field_name); 990c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 991d7b241e6Sjeremylt found: 9929bc66399SJeremy L Thompson CeedCall(CeedOperatorCheckField(CeedOperatorReturnCeed(op), qf_field, rstr, basis)); 9932b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, op_field)); 994e15f9bd0SJeremy L Thompson 995bafebce1SSebastian Grimberg if (vec == CEED_VECTOR_ACTIVE) { 9962b104005SJeremy L Thompson CeedSize l_size; 9971c66c397SJeremy L Thompson 998bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &l_size)); 9992b104005SJeremy L Thompson if (is_input) { 10002b104005SJeremy L Thompson if (op->input_size == -1) op->input_size = l_size; 10019bc66399SJeremy L Thompson CeedCheck(l_size == op->input_size, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 1002249f8407SJeremy L Thompson "LVector size %" CeedSize_FMT " does not match previous size %" CeedSize_FMT "", l_size, op->input_size); 10032b104005SJeremy L Thompson } else { 10042b104005SJeremy L Thompson if (op->output_size == -1) op->output_size = l_size; 10059bc66399SJeremy L Thompson CeedCheck(l_size == op->output_size, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 1006249f8407SJeremy L Thompson "LVector size %" CeedSize_FMT " does not match previous size %" CeedSize_FMT "", l_size, op->output_size); 10072b104005SJeremy L Thompson } 10082b730f8bSJeremy L Thompson } 10092b104005SJeremy L Thompson 1010bafebce1SSebastian Grimberg CeedCall(CeedVectorReferenceCopy(vec, &(*op_field)->vec)); 1011bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*op_field)->elem_rstr)); 1012bafebce1SSebastian Grimberg if (rstr != CEED_ELEMRESTRICTION_NONE && !op->has_restriction) { 1013d1d35e2fSjeremylt op->num_elem = num_elem; 1014d1d35e2fSjeremylt op->has_restriction = true; // Restriction set, but num_elem may be 0 1015e15f9bd0SJeremy L Thompson } 1016bafebce1SSebastian Grimberg CeedCall(CeedBasisReferenceCopy(basis, &(*op_field)->basis)); 10172a3ff1c9SZach Atkins if (op->num_qpts == 0 && !is_at_points) op->num_qpts = num_qpts; // no consistent number of qpts for OperatorAtPoints 1018d1d35e2fSjeremylt op->num_fields += 1; 10192b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(field_name, (char **)&(*op_field)->field_name)); 1020e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1021d7b241e6Sjeremylt } 1022d7b241e6Sjeremylt 1023d7b241e6Sjeremylt /** 1024ca94c3ddSJeremy L Thompson @brief Get the `CeedOperator` Field of a `CeedOperator`. 102543bbe138SJeremy L Thompson 1026ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 1027f04ea552SJeremy L Thompson 1028ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1029f74ec584SJeremy L Thompson @param[out] num_input_fields Variable to store number of input fields 1030ca94c3ddSJeremy L Thompson @param[out] input_fields Variable to store input fields 1031f74ec584SJeremy L Thompson @param[out] num_output_fields Variable to store number of output fields 1032ca94c3ddSJeremy L Thompson @param[out] output_fields Variable to store output fields 103343bbe138SJeremy L Thompson 103443bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 103543bbe138SJeremy L Thompson 1036e9b533fbSJeremy L Thompson @ref Advanced 103743bbe138SJeremy L Thompson **/ 10382b730f8bSJeremy L Thompson int CeedOperatorGetFields(CeedOperator op, CeedInt *num_input_fields, CeedOperatorField **input_fields, CeedInt *num_output_fields, 103943bbe138SJeremy L Thompson CeedOperatorField **output_fields) { 10401203703bSJeremy L Thompson bool is_composite; 10411203703bSJeremy L Thompson CeedQFunction qf; 10421203703bSJeremy L Thompson 10431203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 10446e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Not defined for composite operator"); 10452b730f8bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 104643bbe138SJeremy L Thompson 10471203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 10481203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFields(qf, num_input_fields, NULL, num_output_fields, NULL)); 1049c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 105043bbe138SJeremy L Thompson if (input_fields) *input_fields = op->input_fields; 105143bbe138SJeremy L Thompson if (output_fields) *output_fields = op->output_fields; 105243bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 105343bbe138SJeremy L Thompson } 105443bbe138SJeremy L Thompson 105543bbe138SJeremy L Thompson /** 1056ca94c3ddSJeremy L Thompson @brief Set the arbitrary points in each element for a `CeedOperator` at points. 105748acf710SJeremy L Thompson 1058ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 105948acf710SJeremy L Thompson 1060ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` at points 1061ca94c3ddSJeremy L Thompson @param[in] rstr_points `CeedElemRestriction` for the coordinates of each point by element 1062ca94c3ddSJeremy L Thompson @param[in] point_coords `CeedVector` holding coordinates of each point 106348acf710SJeremy L Thompson 106448acf710SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 106548acf710SJeremy L Thompson 106648acf710SJeremy L Thompson @ref Advanced 106748acf710SJeremy L Thompson **/ 106848acf710SJeremy L Thompson int CeedOperatorAtPointsSetPoints(CeedOperator op, CeedElemRestriction rstr_points, CeedVector point_coords) { 10691203703bSJeremy L Thompson bool is_at_points, is_immutable; 10702a3ff1c9SZach Atkins 10712a3ff1c9SZach Atkins CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 10721203703bSJeremy L Thompson CeedCall(CeedOperatorIsImmutable(op, &is_immutable)); 10739bc66399SJeremy L Thompson CeedCheck(is_at_points, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for operator at points"); 10749bc66399SJeremy L Thompson CeedCheck(!is_immutable, CeedOperatorReturnCeed(op), CEED_ERROR_MAJOR, "Operator cannot be changed after set as immutable"); 107548acf710SJeremy L Thompson 107648acf710SJeremy L Thompson if (!op->first_points_rstr) { 107748acf710SJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(rstr_points, &op->first_points_rstr)); 107848acf710SJeremy L Thompson } else { 107948acf710SJeremy L Thompson bool are_compatible; 108048acf710SJeremy L Thompson 108148acf710SJeremy L Thompson CeedCall(CeedElemRestrictionAtPointsAreCompatible(op->first_points_rstr, rstr_points, &are_compatible)); 10829bc66399SJeremy L Thompson CeedCheck(are_compatible, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 1083ca94c3ddSJeremy L Thompson "CeedElemRestriction must have compatible offsets with previously set field CeedElemRestriction"); 108448acf710SJeremy L Thompson } 108548acf710SJeremy L Thompson 108648acf710SJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(rstr_points, &op->rstr_points)); 108748acf710SJeremy L Thompson CeedCall(CeedVectorReferenceCopy(point_coords, &op->point_coords)); 108848acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 108948acf710SJeremy L Thompson } 109048acf710SJeremy L Thompson 109148acf710SJeremy L Thompson /** 1092b594f9faSZach Atkins @brief Get a boolean value indicating if the `CeedOperator` was created with `CeedOperatorCreateAtPoints` 1093b594f9faSZach Atkins 1094b594f9faSZach Atkins @param[in] op `CeedOperator` 1095b594f9faSZach Atkins @param[out] is_at_points Variable to store at points status 1096b594f9faSZach Atkins 1097b594f9faSZach Atkins @return An error code: 0 - success, otherwise - failure 1098b594f9faSZach Atkins 1099b594f9faSZach Atkins @ref User 1100b594f9faSZach Atkins **/ 1101b594f9faSZach Atkins int CeedOperatorIsAtPoints(CeedOperator op, bool *is_at_points) { 1102b594f9faSZach Atkins *is_at_points = op->is_at_points; 1103b594f9faSZach Atkins return CEED_ERROR_SUCCESS; 1104b594f9faSZach Atkins } 1105b594f9faSZach Atkins 1106b594f9faSZach Atkins /** 1107ca94c3ddSJeremy L Thompson @brief Get the arbitrary points in each element for a `CeedOperator` at points. 110848acf710SJeremy L Thompson 1109ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 111048acf710SJeremy L Thompson 1111ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` at points 1112ca94c3ddSJeremy L Thompson @param[out] rstr_points Variable to hold `CeedElemRestriction` for the coordinates of each point by element 1113ca94c3ddSJeremy L Thompson @param[out] point_coords Variable to hold `CeedVector` holding coordinates of each point 111448acf710SJeremy L Thompson 111548acf710SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 111648acf710SJeremy L Thompson 111748acf710SJeremy L Thompson @ref Advanced 111848acf710SJeremy L Thompson **/ 111948acf710SJeremy L Thompson int CeedOperatorAtPointsGetPoints(CeedOperator op, CeedElemRestriction *rstr_points, CeedVector *point_coords) { 11202a3ff1c9SZach Atkins bool is_at_points; 11212a3ff1c9SZach Atkins 11222a3ff1c9SZach Atkins CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 11236e536b99SJeremy L Thompson CeedCheck(is_at_points, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for operator at points"); 112448acf710SJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 112548acf710SJeremy L Thompson 11263f919cbcSJeremy L Thompson if (rstr_points) { 11273f919cbcSJeremy L Thompson *rstr_points = NULL; 11283f919cbcSJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(op->rstr_points, rstr_points)); 11293f919cbcSJeremy L Thompson } 11303f919cbcSJeremy L Thompson if (point_coords) { 11313f919cbcSJeremy L Thompson *point_coords = NULL; 11323f919cbcSJeremy L Thompson CeedCall(CeedVectorReferenceCopy(op->point_coords, point_coords)); 11333f919cbcSJeremy L Thompson } 113448acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 113548acf710SJeremy L Thompson } 113648acf710SJeremy L Thompson 113748acf710SJeremy L Thompson /** 1138be9c6463SJeremy L Thompson @brief Get a `CeedOperator` Field of a `CeedOperator` from its name. 1139be9c6463SJeremy L Thompson 1140be9c6463SJeremy L Thompson `op_field` is set to `NULL` if the field is not found. 1141de5900adSJames Wright 1142ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 1143de5900adSJames Wright 1144ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1145ca94c3ddSJeremy L Thompson @param[in] field_name Name of desired `CeedOperator` Field 1146ca94c3ddSJeremy L Thompson @param[out] op_field `CeedOperator` Field corresponding to the name 1147de5900adSJames Wright 1148de5900adSJames Wright @return An error code: 0 - success, otherwise - failure 1149de5900adSJames Wright 1150de5900adSJames Wright @ref Advanced 1151de5900adSJames Wright **/ 1152de5900adSJames Wright int CeedOperatorGetFieldByName(CeedOperator op, const char *field_name, CeedOperatorField *op_field) { 11536f8994e9SJeremy L Thompson const char *name; 1154de5900adSJames Wright CeedInt num_input_fields, num_output_fields; 1155de5900adSJames Wright CeedOperatorField *input_fields, *output_fields; 1156de5900adSJames Wright 1157be9c6463SJeremy L Thompson *op_field = NULL; 11581c66c397SJeremy L Thompson CeedCall(CeedOperatorGetFields(op, &num_input_fields, &input_fields, &num_output_fields, &output_fields)); 1159de5900adSJames Wright for (CeedInt i = 0; i < num_input_fields; i++) { 1160de5900adSJames Wright CeedCall(CeedOperatorFieldGetName(input_fields[i], &name)); 1161de5900adSJames Wright if (!strcmp(name, field_name)) { 1162de5900adSJames Wright *op_field = input_fields[i]; 1163de5900adSJames Wright return CEED_ERROR_SUCCESS; 1164de5900adSJames Wright } 1165de5900adSJames Wright } 1166de5900adSJames Wright for (CeedInt i = 0; i < num_output_fields; i++) { 1167de5900adSJames Wright CeedCall(CeedOperatorFieldGetName(output_fields[i], &name)); 1168de5900adSJames Wright if (!strcmp(name, field_name)) { 1169de5900adSJames Wright *op_field = output_fields[i]; 1170de5900adSJames Wright return CEED_ERROR_SUCCESS; 1171de5900adSJames Wright } 1172de5900adSJames Wright } 1173be9c6463SJeremy L Thompson return CEED_ERROR_SUCCESS; 1174de5900adSJames Wright } 1175de5900adSJames Wright 1176de5900adSJames Wright /** 1177ca94c3ddSJeremy L Thompson @brief Get the name of a `CeedOperator` Field 117828567f8fSJeremy L Thompson 1179ca94c3ddSJeremy L Thompson @param[in] op_field `CeedOperator` Field 118028567f8fSJeremy L Thompson @param[out] field_name Variable to store the field name 118128567f8fSJeremy L Thompson 118228567f8fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 118328567f8fSJeremy L Thompson 1184e9b533fbSJeremy L Thompson @ref Advanced 118528567f8fSJeremy L Thompson **/ 11866f8994e9SJeremy L Thompson int CeedOperatorFieldGetName(CeedOperatorField op_field, const char **field_name) { 11876f8994e9SJeremy L Thompson *field_name = op_field->field_name; 118828567f8fSJeremy L Thompson return CEED_ERROR_SUCCESS; 118928567f8fSJeremy L Thompson } 119028567f8fSJeremy L Thompson 119128567f8fSJeremy L Thompson /** 1192681d0ea7SJeremy L Thompson @brief Get the `CeedElemRestriction` of a `CeedOperator` Field. 1193681d0ea7SJeremy L Thompson 1194681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `rstr` with @ref CeedElemRestrictionDestroy(). 119543bbe138SJeremy L Thompson 1196ca94c3ddSJeremy L Thompson @param[in] op_field `CeedOperator` Field 1197ca94c3ddSJeremy L Thompson @param[out] rstr Variable to store `CeedElemRestriction` 119843bbe138SJeremy L Thompson 119943bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 120043bbe138SJeremy L Thompson 1201e9b533fbSJeremy L Thompson @ref Advanced 120243bbe138SJeremy L Thompson **/ 12032b730f8bSJeremy L Thompson int CeedOperatorFieldGetElemRestriction(CeedOperatorField op_field, CeedElemRestriction *rstr) { 1204681d0ea7SJeremy L Thompson *rstr = NULL; 1205681d0ea7SJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(op_field->elem_rstr, rstr)); 120643bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 120743bbe138SJeremy L Thompson } 120843bbe138SJeremy L Thompson 120943bbe138SJeremy L Thompson /** 1210681d0ea7SJeremy L Thompson @brief Get the `CeedBasis` of a `CeedOperator` Field. 1211681d0ea7SJeremy L Thompson 1212681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `basis` with @ref CeedBasisDestroy(). 121343bbe138SJeremy L Thompson 1214ca94c3ddSJeremy L Thompson @param[in] op_field `CeedOperator` Field 1215ca94c3ddSJeremy L Thompson @param[out] basis Variable to store `CeedBasis` 121643bbe138SJeremy L Thompson 121743bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 121843bbe138SJeremy L Thompson 1219e9b533fbSJeremy L Thompson @ref Advanced 122043bbe138SJeremy L Thompson **/ 122143bbe138SJeremy L Thompson int CeedOperatorFieldGetBasis(CeedOperatorField op_field, CeedBasis *basis) { 1222681d0ea7SJeremy L Thompson *basis = NULL; 1223681d0ea7SJeremy L Thompson CeedCall(CeedBasisReferenceCopy(op_field->basis, basis)); 122443bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 122543bbe138SJeremy L Thompson } 122643bbe138SJeremy L Thompson 122743bbe138SJeremy L Thompson /** 1228681d0ea7SJeremy L Thompson @brief Get the `CeedVector` of a `CeedOperator` Field. 1229681d0ea7SJeremy L Thompson 1230681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `vec` with @ref CeedVectorDestroy(). 123143bbe138SJeremy L Thompson 1232ca94c3ddSJeremy L Thompson @param[in] op_field `CeedOperator` Field 1233ca94c3ddSJeremy L Thompson @param[out] vec Variable to store `CeedVector` 123443bbe138SJeremy L Thompson 123543bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 123643bbe138SJeremy L Thompson 1237e9b533fbSJeremy L Thompson @ref Advanced 123843bbe138SJeremy L Thompson **/ 123943bbe138SJeremy L Thompson int CeedOperatorFieldGetVector(CeedOperatorField op_field, CeedVector *vec) { 1240681d0ea7SJeremy L Thompson *vec = NULL; 1241681d0ea7SJeremy L Thompson CeedCall(CeedVectorReferenceCopy(op_field->vec, vec)); 124243bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 124343bbe138SJeremy L Thompson } 124443bbe138SJeremy L Thompson 124543bbe138SJeremy L Thompson /** 1246ab747706SJeremy L Thompson @brief Get the data of a `CeedOperator` Field. 1247ab747706SJeremy L Thompson 1248681d0ea7SJeremy L Thompson Any arguments set as `NULL` are ignored.. 1249681d0ea7SJeremy L Thompson 1250681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `rstr`, `basis`, and `vec`. 1251ab747706SJeremy L Thompson 1252ab747706SJeremy L Thompson @param[in] op_field `CeedOperator` Field 1253ab747706SJeremy L Thompson @param[out] field_name Variable to store the field name 1254ab747706SJeremy L Thompson @param[out] rstr Variable to store `CeedElemRestriction` 1255ab747706SJeremy L Thompson @param[out] basis Variable to store `CeedBasis` 1256ab747706SJeremy L Thompson @param[out] vec Variable to store `CeedVector` 1257ab747706SJeremy L Thompson 1258ab747706SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1259ab747706SJeremy L Thompson 1260ab747706SJeremy L Thompson @ref Advanced 1261ab747706SJeremy L Thompson **/ 12626f8994e9SJeremy L Thompson int CeedOperatorFieldGetData(CeedOperatorField op_field, const char **field_name, CeedElemRestriction *rstr, CeedBasis *basis, CeedVector *vec) { 1263ab747706SJeremy L Thompson if (field_name) CeedCall(CeedOperatorFieldGetName(op_field, field_name)); 1264ab747706SJeremy L Thompson if (rstr) CeedCall(CeedOperatorFieldGetElemRestriction(op_field, rstr)); 1265ab747706SJeremy L Thompson if (basis) CeedCall(CeedOperatorFieldGetBasis(op_field, basis)); 1266ab747706SJeremy L Thompson if (vec) CeedCall(CeedOperatorFieldGetVector(op_field, vec)); 1267ab747706SJeremy L Thompson return CEED_ERROR_SUCCESS; 1268ab747706SJeremy L Thompson } 1269ab747706SJeremy L Thompson 1270ab747706SJeremy L Thompson /** 1271ca94c3ddSJeremy L Thompson @brief Add a sub-operator to a composite `CeedOperator` 1272288c0443SJeremy L Thompson 1273ca94c3ddSJeremy L Thompson @param[in,out] composite_op Composite `CeedOperator` 1274ca94c3ddSJeremy L Thompson @param[in] sub_op Sub-operator `CeedOperator` 127552d6035fSJeremy L Thompson 127652d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 127752d6035fSJeremy L Thompson 12787a982d89SJeremy L. Thompson @ref User 127952d6035fSJeremy L Thompson */ 1280ed094490SJeremy L Thompson int CeedOperatorCompositeAddSub(CeedOperator composite_op, CeedOperator sub_op) { 12811203703bSJeremy L Thompson bool is_immutable; 12821203703bSJeremy L Thompson 12839bc66399SJeremy L Thompson CeedCheck(composite_op->is_composite, CeedOperatorReturnCeed(composite_op), CEED_ERROR_MINOR, "CeedOperator is not a composite operator"); 12849bc66399SJeremy L Thompson CeedCheck(composite_op->num_suboperators < CEED_COMPOSITE_MAX, CeedOperatorReturnCeed(composite_op), CEED_ERROR_UNSUPPORTED, 12859bc66399SJeremy L Thompson "Cannot add additional sub-operators"); 12861203703bSJeremy L Thompson CeedCall(CeedOperatorIsImmutable(composite_op, &is_immutable)); 12879bc66399SJeremy L Thompson CeedCheck(!is_immutable, CeedOperatorReturnCeed(composite_op), CEED_ERROR_MAJOR, "Operator cannot be changed after set as immutable"); 12882b730f8bSJeremy L Thompson 12892b730f8bSJeremy L Thompson { 12902b730f8bSJeremy L Thompson CeedSize input_size, output_size; 12911c66c397SJeremy L Thompson 12922b730f8bSJeremy L Thompson CeedCall(CeedOperatorGetActiveVectorLengths(sub_op, &input_size, &output_size)); 12932b730f8bSJeremy L Thompson if (composite_op->input_size == -1) composite_op->input_size = input_size; 12942b730f8bSJeremy L Thompson if (composite_op->output_size == -1) composite_op->output_size = output_size; 12952b730f8bSJeremy L Thompson // Note, a size of -1 means no active vector restriction set, so no incompatibility 12969bc66399SJeremy L Thompson CeedCheck((input_size == -1 || input_size == composite_op->input_size) && (output_size == -1 || output_size == composite_op->output_size), 12979bc66399SJeremy L Thompson CeedOperatorReturnCeed(composite_op), CEED_ERROR_MAJOR, 1298249f8407SJeremy L Thompson "Sub-operators must have compatible dimensions; composite operator of shape (%" CeedSize_FMT ", %" CeedSize_FMT 1299249f8407SJeremy L Thompson ") not compatible with sub-operator of " 1300249f8407SJeremy L Thompson "shape (%" CeedSize_FMT ", %" CeedSize_FMT ")", 13012b730f8bSJeremy L Thompson composite_op->input_size, composite_op->output_size, input_size, output_size); 13022b730f8bSJeremy L Thompson } 13032b730f8bSJeremy L Thompson 1304d1d35e2fSjeremylt composite_op->sub_operators[composite_op->num_suboperators] = sub_op; 13052b730f8bSJeremy L Thompson CeedCall(CeedOperatorReference(sub_op)); 1306d1d35e2fSjeremylt composite_op->num_suboperators++; 1307e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 130852d6035fSJeremy L Thompson } 130952d6035fSJeremy L Thompson 131052d6035fSJeremy L Thompson /** 1311ca94c3ddSJeremy L Thompson @brief Get the number of sub-operators associated with a `CeedOperator` 131275f0d5a4SJeremy L Thompson 1313ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1314ca94c3ddSJeremy L Thompson @param[out] num_suboperators Variable to store number of sub-operators 131575f0d5a4SJeremy L Thompson 131675f0d5a4SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 131775f0d5a4SJeremy L Thompson 131875f0d5a4SJeremy L Thompson @ref Backend 131975f0d5a4SJeremy L Thompson **/ 1320ed094490SJeremy L Thompson int CeedOperatorCompositeGetNumSub(CeedOperator op, CeedInt *num_suboperators) { 13211203703bSJeremy L Thompson bool is_composite; 13221203703bSJeremy L Thompson 13231203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 13246e536b99SJeremy L Thompson CeedCheck(is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for a composite operator"); 132575f0d5a4SJeremy L Thompson *num_suboperators = op->num_suboperators; 132675f0d5a4SJeremy L Thompson return CEED_ERROR_SUCCESS; 132775f0d5a4SJeremy L Thompson } 132875f0d5a4SJeremy L Thompson 132975f0d5a4SJeremy L Thompson /** 1330ca94c3ddSJeremy L Thompson @brief Get the list of sub-operators associated with a `CeedOperator` 133175f0d5a4SJeremy L Thompson 1332ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1333ca94c3ddSJeremy L Thompson @param[out] sub_operators Variable to store list of sub-operators 133475f0d5a4SJeremy L Thompson 133575f0d5a4SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 133675f0d5a4SJeremy L Thompson 133775f0d5a4SJeremy L Thompson @ref Backend 133875f0d5a4SJeremy L Thompson **/ 1339ed094490SJeremy L Thompson int CeedOperatorCompositeGetSubList(CeedOperator op, CeedOperator **sub_operators) { 13401203703bSJeremy L Thompson bool is_composite; 13411203703bSJeremy L Thompson 13421203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 13436e536b99SJeremy L Thompson CeedCheck(is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for a composite operator"); 134475f0d5a4SJeremy L Thompson *sub_operators = op->sub_operators; 134575f0d5a4SJeremy L Thompson return CEED_ERROR_SUCCESS; 134675f0d5a4SJeremy L Thompson } 134775f0d5a4SJeremy L Thompson 134875f0d5a4SJeremy L Thompson /** 13498a297abdSJames Wright @brief Get a sub `CeedOperator` of a composite `CeedOperator` from its name. 13508a297abdSJames Wright 13518a297abdSJames Wright `sub_op` is set to `NULL` if the sub operator is not found. 13528a297abdSJames Wright 13538a297abdSJames Wright Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 13548a297abdSJames Wright 13558a297abdSJames Wright @param[in] op Composite `CeedOperator` 13568a297abdSJames Wright @param[in] op_name Name of desired sub `CeedOperator` 13578a297abdSJames Wright @param[out] sub_op Sub `CeedOperator` corresponding to the name 13588a297abdSJames Wright 13598a297abdSJames Wright @return An error code: 0 - success, otherwise - failure 13608a297abdSJames Wright 13618a297abdSJames Wright @ref Advanced 13628a297abdSJames Wright **/ 1363ed094490SJeremy L Thompson int CeedOperatorCompositeGetSubByName(CeedOperator op, const char *op_name, CeedOperator *sub_op) { 13648a297abdSJames Wright bool is_composite; 13658a297abdSJames Wright CeedInt num_sub_ops; 13668a297abdSJames Wright CeedOperator *sub_ops; 13678a297abdSJames Wright 13688a297abdSJames Wright CeedCall(CeedOperatorIsComposite(op, &is_composite)); 13698a297abdSJames Wright CeedCheck(is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for a composite operator"); 13708a297abdSJames Wright *sub_op = NULL; 1371ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_sub_ops)); 1372ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_ops)); 13738a297abdSJames Wright for (CeedInt i = 0; i < num_sub_ops; i++) { 13748a297abdSJames Wright if (sub_ops[i]->name && !strcmp(op_name, sub_ops[i]->name)) { 13758a297abdSJames Wright *sub_op = sub_ops[i]; 13768a297abdSJames Wright return CEED_ERROR_SUCCESS; 13778a297abdSJames Wright } 13788a297abdSJames Wright } 13798a297abdSJames Wright return CEED_ERROR_SUCCESS; 13808a297abdSJames Wright } 13818a297abdSJames Wright 13828a297abdSJames Wright /** 1383ca94c3ddSJeremy L Thompson @brief Check if a `CeedOperator` is ready to be used. 13844db537f9SJeremy L Thompson 1385ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to check 13864db537f9SJeremy L Thompson 13874db537f9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 13884db537f9SJeremy L Thompson 13894db537f9SJeremy L Thompson @ref User 13904db537f9SJeremy L Thompson **/ 13914db537f9SJeremy L Thompson int CeedOperatorCheckReady(CeedOperator op) { 13921203703bSJeremy L Thompson bool is_at_points, is_composite; 13931203703bSJeremy L Thompson CeedQFunction qf = NULL; 13944db537f9SJeremy L Thompson 13952b730f8bSJeremy L Thompson if (op->is_interface_setup) return CEED_ERROR_SUCCESS; 13964db537f9SJeremy L Thompson 13971203703bSJeremy L Thompson CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 13981203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 13991203703bSJeremy L Thompson if (!is_composite) CeedCall(CeedOperatorGetQFunction(op, &qf)); 14001203703bSJeremy L Thompson if (is_composite) { 14011203703bSJeremy L Thompson CeedInt num_suboperators; 14021203703bSJeremy L Thompson 1403ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 14041203703bSJeremy L Thompson if (!num_suboperators) { 140543622462SJeremy L Thompson // Empty operator setup 140643622462SJeremy L Thompson op->input_size = 0; 140743622462SJeremy L Thompson op->output_size = 0; 140843622462SJeremy L Thompson } else { 14091203703bSJeremy L Thompson CeedOperator *sub_operators; 14101203703bSJeremy L Thompson 1411ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 14121203703bSJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 14131203703bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(sub_operators[i])); 14144db537f9SJeremy L Thompson } 14152b104005SJeremy L Thompson // Sub-operators could be modified after adding to composite operator 14162b104005SJeremy L Thompson // Need to verify no lvec incompatibility from any changes 14172b104005SJeremy L Thompson CeedSize input_size, output_size; 14182b730f8bSJeremy L Thompson CeedCall(CeedOperatorGetActiveVectorLengths(op, &input_size, &output_size)); 141943622462SJeremy L Thompson } 14204db537f9SJeremy L Thompson } else { 14211203703bSJeremy L Thompson CeedInt num_input_fields, num_output_fields; 14221203703bSJeremy L Thompson 14239bc66399SJeremy L Thompson CeedCheck(op->num_fields > 0, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "No operator fields set"); 14241203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFields(qf, &num_input_fields, NULL, &num_output_fields, NULL)); 14259bc66399SJeremy L Thompson CeedCheck(op->num_fields == num_input_fields + num_output_fields, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, 14269bc66399SJeremy L Thompson "Not all operator fields set"); 14279bc66399SJeremy L Thompson CeedCheck(op->has_restriction, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "At least one restriction required"); 14289bc66399SJeremy L Thompson CeedCheck(op->num_qpts > 0 || is_at_points, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, 1429ca94c3ddSJeremy L Thompson "At least one non-collocated CeedBasis is required or the number of quadrature points must be set"); 14302b730f8bSJeremy L Thompson } 14314db537f9SJeremy L Thompson 14324db537f9SJeremy L Thompson // Flag as immutable and ready 14334db537f9SJeremy L Thompson op->is_interface_setup = true; 14341203703bSJeremy L Thompson if (qf && qf != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionSetImmutable(qf)); 1435c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 14361203703bSJeremy L Thompson if (op->dqf && op->dqf != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionSetImmutable(op->dqf)); 14371203703bSJeremy L Thompson if (op->dqfT && op->dqfT != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionSetImmutable(op->dqfT)); 14384db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 14394db537f9SJeremy L Thompson } 14404db537f9SJeremy L Thompson 14414db537f9SJeremy L Thompson /** 1442ca94c3ddSJeremy L Thompson @brief Get vector lengths for the active input and/or output `CeedVector` of a `CeedOperator`. 14434385fb7fSSebastian Grimberg 1444ca94c3ddSJeremy L Thompson Note: Lengths of `-1` indicate that the CeedOperator does not have an active input and/or output. 1445c9366a6bSJeremy L Thompson 1446ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1447ca94c3ddSJeremy L Thompson @param[out] input_size Variable to store active input vector length, or `NULL` 1448ca94c3ddSJeremy L Thompson @param[out] output_size Variable to store active output vector length, or `NULL` 1449c9366a6bSJeremy L Thompson 1450c9366a6bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1451c9366a6bSJeremy L Thompson 1452c9366a6bSJeremy L Thompson @ref User 1453c9366a6bSJeremy L Thompson **/ 14542b730f8bSJeremy L Thompson int CeedOperatorGetActiveVectorLengths(CeedOperator op, CeedSize *input_size, CeedSize *output_size) { 1455c9366a6bSJeremy L Thompson bool is_composite; 1456c9366a6bSJeremy L Thompson 14572b104005SJeremy L Thompson if (input_size) *input_size = op->input_size; 14582b104005SJeremy L Thompson if (output_size) *output_size = op->output_size; 1459c9366a6bSJeremy L Thompson 14602b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 14612b104005SJeremy L Thompson if (is_composite && (op->input_size == -1 || op->output_size == -1)) { 14621203703bSJeremy L Thompson CeedInt num_suboperators; 14631203703bSJeremy L Thompson CeedOperator *sub_operators; 14641203703bSJeremy L Thompson 1465ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 1466ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 14671203703bSJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 1468c9366a6bSJeremy L Thompson CeedSize sub_input_size, sub_output_size; 14691c66c397SJeremy L Thompson 14701203703bSJeremy L Thompson CeedCall(CeedOperatorGetActiveVectorLengths(sub_operators[i], &sub_input_size, &sub_output_size)); 14712b104005SJeremy L Thompson if (op->input_size == -1) op->input_size = sub_input_size; 14722b104005SJeremy L Thompson if (op->output_size == -1) op->output_size = sub_output_size; 14732b104005SJeremy L Thompson // Note, a size of -1 means no active vector restriction set, so no incompatibility 14746e536b99SJeremy L Thompson CeedCheck((sub_input_size == -1 || sub_input_size == op->input_size) && (sub_output_size == -1 || sub_output_size == op->output_size), 14756e536b99SJeremy L Thompson CeedOperatorReturnCeed(op), CEED_ERROR_MAJOR, 1476249f8407SJeremy L Thompson "Sub-operators must have compatible dimensions; composite operator of shape (%" CeedSize_FMT ", %" CeedSize_FMT 1477249f8407SJeremy L Thompson ") not compatible with sub-operator of " 1478249f8407SJeremy L Thompson "shape (%" CeedSize_FMT ", %" CeedSize_FMT ")", 14792b104005SJeremy L Thompson op->input_size, op->output_size, input_size, output_size); 1480c9366a6bSJeremy L Thompson } 14812b730f8bSJeremy L Thompson } 1482c9366a6bSJeremy L Thompson return CEED_ERROR_SUCCESS; 1483c9366a6bSJeremy L Thompson } 1484c9366a6bSJeremy L Thompson 1485c9366a6bSJeremy L Thompson /** 1486ca94c3ddSJeremy L Thompson @brief Set reuse of `CeedQFunction` data in `CeedOperatorLinearAssemble*()` functions. 14874385fb7fSSebastian Grimberg 1488ca94c3ddSJeremy L Thompson When `reuse_assembly_data = false` (default), the `CeedQFunction` associated with this `CeedOperator` is re-assembled every time a `CeedOperatorLinearAssemble*()` function is called. 1489ca94c3ddSJeremy L Thompson When `reuse_assembly_data = true`, the `CeedQFunction` associated with this `CeedOperator` is reused between calls to @ref CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(). 14908b919e6bSJeremy L Thompson 1491ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1492beecbf24SJeremy L Thompson @param[in] reuse_assembly_data Boolean flag setting assembly data reuse 14938b919e6bSJeremy L Thompson 14948b919e6bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 14958b919e6bSJeremy L Thompson 14968b919e6bSJeremy L Thompson @ref Advanced 14978b919e6bSJeremy L Thompson **/ 14982b730f8bSJeremy L Thompson int CeedOperatorSetQFunctionAssemblyReuse(CeedOperator op, bool reuse_assembly_data) { 14998b919e6bSJeremy L Thompson bool is_composite; 15008b919e6bSJeremy L Thompson 15012b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 15028b919e6bSJeremy L Thompson if (is_composite) { 15038b919e6bSJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 15042b730f8bSJeremy L Thompson CeedCall(CeedOperatorSetQFunctionAssemblyReuse(op->sub_operators[i], reuse_assembly_data)); 15058b919e6bSJeremy L Thompson } 15068b919e6bSJeremy L Thompson } else { 15077d5185d7SSebastian Grimberg CeedQFunctionAssemblyData data; 15087d5185d7SSebastian Grimberg 15097d5185d7SSebastian Grimberg CeedCall(CeedOperatorGetQFunctionAssemblyData(op, &data)); 15107d5185d7SSebastian Grimberg CeedCall(CeedQFunctionAssemblyDataSetReuse(data, reuse_assembly_data)); 1511beecbf24SJeremy L Thompson } 1512beecbf24SJeremy L Thompson return CEED_ERROR_SUCCESS; 1513beecbf24SJeremy L Thompson } 1514beecbf24SJeremy L Thompson 1515beecbf24SJeremy L Thompson /** 1516ca94c3ddSJeremy L Thompson @brief Mark `CeedQFunction` data as updated and the `CeedQFunction` as requiring re-assembly. 1517beecbf24SJeremy L Thompson 1518ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 15196e15d496SJeremy L Thompson @param[in] needs_data_update Boolean flag setting assembly data reuse 1520beecbf24SJeremy L Thompson 1521beecbf24SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1522beecbf24SJeremy L Thompson 1523beecbf24SJeremy L Thompson @ref Advanced 1524beecbf24SJeremy L Thompson **/ 15252b730f8bSJeremy L Thompson int CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(CeedOperator op, bool needs_data_update) { 1526beecbf24SJeremy L Thompson bool is_composite; 1527beecbf24SJeremy L Thompson 15282b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 1529beecbf24SJeremy L Thompson if (is_composite) { 15301203703bSJeremy L Thompson CeedInt num_suboperators; 15311203703bSJeremy L Thompson CeedOperator *sub_operators; 15321203703bSJeremy L Thompson 1533ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 1534ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 15351203703bSJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 15361203703bSJeremy L Thompson CeedCall(CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(sub_operators[i], needs_data_update)); 1537beecbf24SJeremy L Thompson } 1538beecbf24SJeremy L Thompson } else { 15397d5185d7SSebastian Grimberg CeedQFunctionAssemblyData data; 15407d5185d7SSebastian Grimberg 15417d5185d7SSebastian Grimberg CeedCall(CeedOperatorGetQFunctionAssemblyData(op, &data)); 15427d5185d7SSebastian Grimberg CeedCall(CeedQFunctionAssemblyDataSetUpdateNeeded(data, needs_data_update)); 15438b919e6bSJeremy L Thompson } 15448b919e6bSJeremy L Thompson return CEED_ERROR_SUCCESS; 15458b919e6bSJeremy L Thompson } 15468b919e6bSJeremy L Thompson 15478b919e6bSJeremy L Thompson /** 1548ca94c3ddSJeremy L Thompson @brief Set name of `CeedOperator` for @ref CeedOperatorView() output 1549ea6b5821SJeremy L Thompson 1550ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 1551ea61e9acSJeremy L Thompson @param[in] name Name to set, or NULL to remove previously set name 1552ea6b5821SJeremy L Thompson 1553ea6b5821SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1554ea6b5821SJeremy L Thompson 1555ea6b5821SJeremy L Thompson @ref User 1556ea6b5821SJeremy L Thompson **/ 1557ea6b5821SJeremy L Thompson int CeedOperatorSetName(CeedOperator op, const char *name) { 1558ea6b5821SJeremy L Thompson char *name_copy; 1559ea6b5821SJeremy L Thompson size_t name_len = name ? strlen(name) : 0; 1560ea6b5821SJeremy L Thompson 15612b730f8bSJeremy L Thompson CeedCall(CeedFree(&op->name)); 1562ea6b5821SJeremy L Thompson if (name_len > 0) { 15632b730f8bSJeremy L Thompson CeedCall(CeedCalloc(name_len + 1, &name_copy)); 1564ea6b5821SJeremy L Thompson memcpy(name_copy, name, name_len); 1565ea6b5821SJeremy L Thompson op->name = name_copy; 1566ea6b5821SJeremy L Thompson } 1567ea6b5821SJeremy L Thompson return CEED_ERROR_SUCCESS; 1568ea6b5821SJeremy L Thompson } 1569ea6b5821SJeremy L Thompson 1570ea6b5821SJeremy L Thompson /** 1571d3d5610dSJeremy L Thompson @brief Get name of `CeedOperator` 1572d3d5610dSJeremy L Thompson 1573d3d5610dSJeremy L Thompson @param[in] op `CeedOperator` 1574d3d5610dSJeremy L Thompson @param[in,out] name Address of variable to hold currently set name 1575d3d5610dSJeremy L Thompson 1576d3d5610dSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1577d3d5610dSJeremy L Thompson 1578d3d5610dSJeremy L Thompson @ref User 1579d3d5610dSJeremy L Thompson **/ 1580d3d5610dSJeremy L Thompson int CeedOperatorGetName(CeedOperator op, const char **name) { 1581d3d5610dSJeremy L Thompson if (op->name) { 1582d3d5610dSJeremy L Thompson *name = op->name; 1583d3d5610dSJeremy L Thompson } else if (!op->is_composite) { 1584d3d5610dSJeremy L Thompson CeedQFunction qf; 1585d3d5610dSJeremy L Thompson 1586d3d5610dSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 1587d3d5610dSJeremy L Thompson if (qf) CeedCall(CeedQFunctionGetName(qf, name)); 1588d3d5610dSJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 1589d3d5610dSJeremy L Thompson } 1590d3d5610dSJeremy L Thompson return CEED_ERROR_SUCCESS; 1591d3d5610dSJeremy L Thompson } 1592d3d5610dSJeremy L Thompson 1593d3d5610dSJeremy L Thompson /** 1594935f026aSJeremy L Thompson @brief Core logic for viewing a `CeedOperator` 15957a982d89SJeremy L. Thompson 1596935f026aSJeremy L Thompson @param[in] op `CeedOperator` to view brief summary 1597ca94c3ddSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 15988bf1b130SJames Wright @param[in] is_full Whether to write full operator view or terse 15997a982d89SJeremy L. Thompson 16007a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 16016ab8e59fSJames Wright 16026ab8e59fSJames Wright @ref Developer 16037a982d89SJeremy L. Thompson **/ 16048bf1b130SJames Wright static int CeedOperatorView_Core(CeedOperator op, FILE *stream, bool is_full) { 1605d3d5610dSJeremy L Thompson bool has_name, is_composite, is_at_points; 16065a526491SJeremy L Thompson char *tabs = NULL; 1607d3d5610dSJeremy L Thompson const char *name = NULL; 16085a526491SJeremy L Thompson const CeedInt tab_width = 2; 16095a526491SJeremy L Thompson CeedInt num_tabs = 0; 16107a982d89SJeremy L. Thompson 1611d3d5610dSJeremy L Thompson CeedCall(CeedOperatorGetName(op, &name)); 1612d3d5610dSJeremy L Thompson has_name = name ? strlen(name) : false; 16131203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 161499f7f61fSJeremy L Thompson CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 16155a526491SJeremy L Thompson // Set tabs 16165a526491SJeremy L Thompson CeedCall(CeedOperatorGetNumViewTabs(op, &num_tabs)); 16175a526491SJeremy L Thompson CeedCall(CeedCalloc(tab_width * (num_tabs + is_composite) + 1, &tabs)); 16185a526491SJeremy L Thompson for (CeedInt i = 0; i < tab_width * num_tabs; i++) tabs[i] = ' '; 16191203703bSJeremy L Thompson if (is_composite) { 16201203703bSJeremy L Thompson CeedInt num_suboperators; 16211203703bSJeremy L Thompson CeedOperator *sub_operators; 16221203703bSJeremy L Thompson 1623ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 1624ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 16255a526491SJeremy L Thompson fprintf(stream, tabs); 1626d3d5610dSJeremy L Thompson fprintf(stream, "Composite CeedOperator%s%s\n", has_name ? " - " : "", has_name ? name : ""); 16275a526491SJeremy L Thompson for (CeedInt i = 0; i < tab_width; i++) tabs[tab_width * num_tabs + i] = ' '; 16281203703bSJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 16291203703bSJeremy L Thompson has_name = sub_operators[i]->name; 16305a526491SJeremy L Thompson fprintf(stream, tabs); 163199f7f61fSJeremy L Thompson fprintf(stream, "SubOperator%s %" CeedInt_FMT "%s%s%s\n", is_at_points ? " AtPoints" : "", i, has_name ? " - " : "", 163299f7f61fSJeremy L Thompson has_name ? sub_operators[i]->name : "", is_full ? ":" : ""); 16335a526491SJeremy L Thompson if (is_full) CeedCall(CeedOperatorSingleView(sub_operators[i], tabs, stream)); 16347a982d89SJeremy L. Thompson } 16357a982d89SJeremy L. Thompson } else { 16365a526491SJeremy L Thompson fprintf(stream, tabs); 1637d3d5610dSJeremy L Thompson fprintf(stream, "CeedOperator%s%s%s\n", is_at_points ? " AtPoints" : "", has_name ? " - " : "", has_name ? name : ""); 16385a526491SJeremy L Thompson if (is_full) CeedCall(CeedOperatorSingleView(op, tabs, stream)); 16397a982d89SJeremy L. Thompson } 16405a526491SJeremy L Thompson CeedCall(CeedFree(&tabs)); 16415a526491SJeremy L Thompson return CEED_ERROR_SUCCESS; 16425a526491SJeremy L Thompson } 16435a526491SJeremy L Thompson 16445a526491SJeremy L Thompson /** 16455a526491SJeremy L Thompson @brief Set the number of tabs to indent for @ref CeedOperatorView() output 16465a526491SJeremy L Thompson 16475a526491SJeremy L Thompson @param[in] op `CeedOperator` to set the number of view tabs 16485a526491SJeremy L Thompson @param[in] num_tabs Number of view tabs to set 16495a526491SJeremy L Thompson 16505a526491SJeremy L Thompson @return Error code: 0 - success, otherwise - failure 16515a526491SJeremy L Thompson 16525a526491SJeremy L Thompson @ref User 16535a526491SJeremy L Thompson **/ 16545a526491SJeremy L Thompson int CeedOperatorSetNumViewTabs(CeedOperator op, CeedInt num_tabs) { 16555a526491SJeremy L Thompson CeedCheck(num_tabs >= 0, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Number of view tabs must be non-negative"); 16565a526491SJeremy L Thompson op->num_tabs = num_tabs; 1657e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 16587a982d89SJeremy L. Thompson } 16593bd813ffSjeremylt 16603bd813ffSjeremylt /** 1661935f026aSJeremy L Thompson @brief View a `CeedOperator` 1662935f026aSJeremy L Thompson 1663935f026aSJeremy L Thompson @param[in] op `CeedOperator` to view 1664935f026aSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 1665935f026aSJeremy L Thompson 1666935f026aSJeremy L Thompson @return Error code: 0 - success, otherwise - failure 1667935f026aSJeremy L Thompson 1668935f026aSJeremy L Thompson @ref User 1669935f026aSJeremy L Thompson **/ 1670935f026aSJeremy L Thompson int CeedOperatorView(CeedOperator op, FILE *stream) { 1671935f026aSJeremy L Thompson CeedCall(CeedOperatorView_Core(op, stream, true)); 1672935f026aSJeremy L Thompson return CEED_ERROR_SUCCESS; 1673935f026aSJeremy L Thompson } 1674935f026aSJeremy L Thompson 1675935f026aSJeremy L Thompson /** 1676935f026aSJeremy L Thompson @brief View a brief summary `CeedOperator` 1677935f026aSJeremy L Thompson 1678935f026aSJeremy L Thompson @param[in] op `CeedOperator` to view brief summary 1679935f026aSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 1680935f026aSJeremy L Thompson 1681935f026aSJeremy L Thompson @return Error code: 0 - success, otherwise - failure 1682935f026aSJeremy L Thompson 1683935f026aSJeremy L Thompson @ref User 1684935f026aSJeremy L Thompson **/ 1685935f026aSJeremy L Thompson int CeedOperatorViewTerse(CeedOperator op, FILE *stream) { 1686935f026aSJeremy L Thompson CeedCall(CeedOperatorView_Core(op, stream, false)); 1687935f026aSJeremy L Thompson return CEED_ERROR_SUCCESS; 1688935f026aSJeremy L Thompson } 1689935f026aSJeremy L Thompson 1690935f026aSJeremy L Thompson /** 1691ca94c3ddSJeremy L Thompson @brief Get the `Ceed` associated with a `CeedOperator` 1692b7c9bbdaSJeremy L Thompson 1693ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1694ca94c3ddSJeremy L Thompson @param[out] ceed Variable to store `Ceed` 1695b7c9bbdaSJeremy L Thompson 1696b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1697b7c9bbdaSJeremy L Thompson 1698b7c9bbdaSJeremy L Thompson @ref Advanced 1699b7c9bbdaSJeremy L Thompson **/ 1700b7c9bbdaSJeremy L Thompson int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 17019bc66399SJeremy L Thompson *ceed = NULL; 17029bc66399SJeremy L Thompson CeedCall(CeedReferenceCopy(CeedOperatorReturnCeed(op), ceed)); 1703b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1704b7c9bbdaSJeremy L Thompson } 1705b7c9bbdaSJeremy L Thompson 1706b7c9bbdaSJeremy L Thompson /** 17076e536b99SJeremy L Thompson @brief Return the `Ceed` associated with a `CeedOperator` 17086e536b99SJeremy L Thompson 17096e536b99SJeremy L Thompson @param[in] op `CeedOperator` 17106e536b99SJeremy L Thompson 17116e536b99SJeremy L Thompson @return `Ceed` associated with the `op` 17126e536b99SJeremy L Thompson 17136e536b99SJeremy L Thompson @ref Advanced 17146e536b99SJeremy L Thompson **/ 17156e536b99SJeremy L Thompson Ceed CeedOperatorReturnCeed(CeedOperator op) { return op->ceed; } 17166e536b99SJeremy L Thompson 17176e536b99SJeremy L Thompson /** 1718ca94c3ddSJeremy L Thompson @brief Get the number of elements associated with a `CeedOperator` 1719b7c9bbdaSJeremy L Thompson 1720ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1721b7c9bbdaSJeremy L Thompson @param[out] num_elem Variable to store number of elements 1722b7c9bbdaSJeremy L Thompson 1723b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1724b7c9bbdaSJeremy L Thompson 1725b7c9bbdaSJeremy L Thompson @ref Advanced 1726b7c9bbdaSJeremy L Thompson **/ 1727b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumElements(CeedOperator op, CeedInt *num_elem) { 17281203703bSJeremy L Thompson bool is_composite; 17291203703bSJeremy L Thompson 17301203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 17316e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Not defined for composite operator"); 1732b7c9bbdaSJeremy L Thompson *num_elem = op->num_elem; 1733b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1734b7c9bbdaSJeremy L Thompson } 1735b7c9bbdaSJeremy L Thompson 1736b7c9bbdaSJeremy L Thompson /** 1737ca94c3ddSJeremy L Thompson @brief Get the number of quadrature points associated with a `CeedOperator` 1738b7c9bbdaSJeremy L Thompson 1739ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1740b7c9bbdaSJeremy L Thompson @param[out] num_qpts Variable to store vector number of quadrature points 1741b7c9bbdaSJeremy L Thompson 1742b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1743b7c9bbdaSJeremy L Thompson 1744b7c9bbdaSJeremy L Thompson @ref Advanced 1745b7c9bbdaSJeremy L Thompson **/ 1746b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *num_qpts) { 17471203703bSJeremy L Thompson bool is_composite; 17481203703bSJeremy L Thompson 17491203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 17506e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Not defined for composite operator"); 1751b7c9bbdaSJeremy L Thompson *num_qpts = op->num_qpts; 1752b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1753b7c9bbdaSJeremy L Thompson } 1754b7c9bbdaSJeremy L Thompson 1755b7c9bbdaSJeremy L Thompson /** 1756ca94c3ddSJeremy L Thompson @brief Estimate number of FLOPs required to apply `CeedOperator` on the active `CeedVector` 17576e15d496SJeremy L Thompson 1758ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to estimate FLOPs for 1759ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 17606e15d496SJeremy L Thompson 17616e15d496SJeremy L Thompson @ref Backend 17626e15d496SJeremy L Thompson **/ 17639d36ca50SJeremy L Thompson int CeedOperatorGetFlopsEstimate(CeedOperator op, CeedSize *flops) { 17646e15d496SJeremy L Thompson bool is_composite; 17651c66c397SJeremy L Thompson 17662b730f8bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 17676e15d496SJeremy L Thompson 17686e15d496SJeremy L Thompson *flops = 0; 17692b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 17706e15d496SJeremy L Thompson if (is_composite) { 17716e15d496SJeremy L Thompson CeedInt num_suboperators; 17721c66c397SJeremy L Thompson 1773ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 17746e15d496SJeremy L Thompson CeedOperator *sub_operators; 1775ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 17766e15d496SJeremy L Thompson 17776e15d496SJeremy L Thompson // FLOPs for each suboperator 17786e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 17799d36ca50SJeremy L Thompson CeedSize suboperator_flops; 17801c66c397SJeremy L Thompson 17812b730f8bSJeremy L Thompson CeedCall(CeedOperatorGetFlopsEstimate(sub_operators[i], &suboperator_flops)); 17826e15d496SJeremy L Thompson *flops += suboperator_flops; 17836e15d496SJeremy L Thompson } 17846e15d496SJeremy L Thompson } else { 17853f919cbcSJeremy L Thompson bool is_at_points; 17863f919cbcSJeremy L Thompson CeedInt num_input_fields, num_output_fields, num_elem = 0, num_points = 0; 17871203703bSJeremy L Thompson CeedQFunction qf; 17881203703bSJeremy L Thompson CeedQFunctionField *qf_input_fields, *qf_output_fields; 17891203703bSJeremy L Thompson CeedOperatorField *op_input_fields, *op_output_fields; 17901c66c397SJeremy L Thompson 17913f919cbcSJeremy L Thompson CeedCall(CeedOperatorGetNumElements(op, &num_elem)); 179219feff82SJeremy L Thompson if (num_elem == 0) return CEED_ERROR_SUCCESS; 179319feff82SJeremy L Thompson CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 17943f919cbcSJeremy L Thompson if (is_at_points) { 17953f919cbcSJeremy L Thompson CeedMemType mem_type; 17963f919cbcSJeremy L Thompson CeedElemRestriction rstr_points = NULL; 17973f919cbcSJeremy L Thompson 17983f919cbcSJeremy L Thompson CeedCall(CeedOperatorAtPointsGetPoints(op, &rstr_points, NULL)); 17993f919cbcSJeremy L Thompson CeedCall(CeedGetPreferredMemType(CeedOperatorReturnCeed(op), &mem_type)); 18003f919cbcSJeremy L Thompson if (mem_type == CEED_MEM_DEVICE) { 18013f919cbcSJeremy L Thompson // Device backends pad out to the same number of points per element 18023f919cbcSJeremy L Thompson CeedCall(CeedElemRestrictionGetMaxPointsInElement(rstr_points, &num_points)); 18033f919cbcSJeremy L Thompson } else { 18043f919cbcSJeremy L Thompson num_points = 0; 18053f919cbcSJeremy L Thompson for (CeedInt i = 0; i < num_elem; i++) { 18063f919cbcSJeremy L Thompson CeedInt points_in_elem = 0; 18073f919cbcSJeremy L Thompson 18083f919cbcSJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr_points, i, &points_in_elem)); 18093f919cbcSJeremy L Thompson num_points += points_in_elem; 18103f919cbcSJeremy L Thompson } 18113f919cbcSJeremy L Thompson num_points = num_points / num_elem + (num_points % num_elem > 0); 18123f919cbcSJeremy L Thompson } 18133f919cbcSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr_points)); 18143f919cbcSJeremy L Thompson } 18151203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 18161203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFields(qf, &num_input_fields, &qf_input_fields, &num_output_fields, &qf_output_fields)); 1817c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 18181203703bSJeremy L Thompson CeedCall(CeedOperatorGetFields(op, NULL, &op_input_fields, NULL, &op_output_fields)); 18194385fb7fSSebastian Grimberg 18206e15d496SJeremy L Thompson // Input FLOPs 18216e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 18221203703bSJeremy L Thompson CeedVector vec; 18236e15d496SJeremy L Thompson 18241203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_input_fields[i], &vec)); 18251203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 18261203703bSJeremy L Thompson CeedEvalMode eval_mode; 18271203703bSJeremy L Thompson CeedSize rstr_flops, basis_flops; 18281203703bSJeremy L Thompson CeedElemRestriction rstr; 18291203703bSJeremy L Thompson CeedBasis basis; 18301203703bSJeremy L Thompson 18311203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetElemRestriction(op_input_fields[i], &rstr)); 18321203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetFlopsEstimate(rstr, CEED_NOTRANSPOSE, &rstr_flops)); 1833681d0ea7SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr)); 1834edb2538eSJeremy L Thompson *flops += rstr_flops; 18351203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(op_input_fields[i], &basis)); 18361203703bSJeremy L Thompson CeedCall(CeedQFunctionFieldGetEvalMode(qf_input_fields[i], &eval_mode)); 18373f919cbcSJeremy L Thompson CeedCall(CeedBasisGetFlopsEstimate(basis, CEED_NOTRANSPOSE, eval_mode, is_at_points, num_points, &basis_flops)); 1838681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 18396e15d496SJeremy L Thompson *flops += basis_flops * num_elem; 18406e15d496SJeremy L Thompson } 1841681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 18426e15d496SJeremy L Thompson } 18436e15d496SJeremy L Thompson // QF FLOPs 18441c66c397SJeremy L Thompson { 18459d36ca50SJeremy L Thompson CeedInt num_qpts; 18469d36ca50SJeremy L Thompson CeedSize qf_flops; 18471203703bSJeremy L Thompson CeedQFunction qf; 18481c66c397SJeremy L Thompson 18493f919cbcSJeremy L Thompson if (is_at_points) num_qpts = num_points; 18503f919cbcSJeremy L Thompson else CeedCall(CeedOperatorGetNumQuadraturePoints(op, &num_qpts)); 18511203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 18521203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFlopsEstimate(qf, &qf_flops)); 1853c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 18546e536b99SJeremy L Thompson CeedCheck(qf_flops > -1, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, 18556e536b99SJeremy L Thompson "Must set CeedQFunction FLOPs estimate with CeedQFunctionSetUserFlopsEstimate"); 18566e15d496SJeremy L Thompson *flops += num_elem * num_qpts * qf_flops; 18571c66c397SJeremy L Thompson } 18581c66c397SJeremy L Thompson 18596e15d496SJeremy L Thompson // Output FLOPs 18606e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 18611203703bSJeremy L Thompson CeedVector vec; 18626e15d496SJeremy L Thompson 18631203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_output_fields[i], &vec)); 18641203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 18651203703bSJeremy L Thompson CeedEvalMode eval_mode; 18661203703bSJeremy L Thompson CeedSize rstr_flops, basis_flops; 18671203703bSJeremy L Thompson CeedElemRestriction rstr; 18681203703bSJeremy L Thompson CeedBasis basis; 18691203703bSJeremy L Thompson 18701203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetElemRestriction(op_output_fields[i], &rstr)); 18711203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetFlopsEstimate(rstr, CEED_TRANSPOSE, &rstr_flops)); 1872681d0ea7SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr)); 1873edb2538eSJeremy L Thompson *flops += rstr_flops; 18741203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(op_output_fields[i], &basis)); 18751203703bSJeremy L Thompson CeedCall(CeedQFunctionFieldGetEvalMode(qf_output_fields[i], &eval_mode)); 18763f919cbcSJeremy L Thompson CeedCall(CeedBasisGetFlopsEstimate(basis, CEED_TRANSPOSE, eval_mode, is_at_points, num_points, &basis_flops)); 1877681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 18786e15d496SJeremy L Thompson *flops += basis_flops * num_elem; 18796e15d496SJeremy L Thompson } 1880681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 18816e15d496SJeremy L Thompson } 18826e15d496SJeremy L Thompson } 18836e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 18846e15d496SJeremy L Thompson } 18856e15d496SJeremy L Thompson 18866e15d496SJeremy L Thompson /** 1887ca94c3ddSJeremy L Thompson @brief Get `CeedQFunction` global context for a `CeedOperator`. 18889fd66db6SSebastian Grimberg 1889ca94c3ddSJeremy L Thompson The caller is responsible for destroying `ctx` returned from this function via @ref CeedQFunctionContextDestroy(). 1890512bb800SJeremy L Thompson 1891ca94c3ddSJeremy 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`. 1892ca94c3ddSJeremy L Thompson This `CeedQFunctionContext` will be destroyed if `ctx` is the only reference to this `CeedQFunctionContext`. 18930126412dSJeremy L Thompson 1894ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1895ca94c3ddSJeremy L Thompson @param[out] ctx Variable to store `CeedQFunctionContext` 18960126412dSJeremy L Thompson 18970126412dSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 18980126412dSJeremy L Thompson 1899859c15bbSJames Wright @ref Advanced 19000126412dSJeremy L Thompson **/ 19010126412dSJeremy L Thompson int CeedOperatorGetContext(CeedOperator op, CeedQFunctionContext *ctx) { 19021203703bSJeremy L Thompson bool is_composite; 19031203703bSJeremy L Thompson CeedQFunction qf; 19041203703bSJeremy L Thompson CeedQFunctionContext qf_ctx; 19051203703bSJeremy L Thompson 19061203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 19076e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "Cannot retrieve CeedQFunctionContext for composite operator"); 19081203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 19091203703bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &qf_ctx)); 1910c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 19111485364cSJeremy L Thompson *ctx = NULL; 19121203703bSJeremy L Thompson if (qf_ctx) CeedCall(CeedQFunctionContextReferenceCopy(qf_ctx, ctx)); 19130126412dSJeremy L Thompson return CEED_ERROR_SUCCESS; 19140126412dSJeremy L Thompson } 19150126412dSJeremy L Thompson 19160126412dSJeremy L Thompson /** 1917ca94c3ddSJeremy L Thompson @brief Get label for a registered `CeedQFunctionContext` field, or `NULL` if no field has been registered with this `field_name`. 19183668ca4bSJeremy L Thompson 1919ca94c3ddSJeremy L Thompson Fields are registered via `CeedQFunctionContextRegister*()` functions (eg. @ref CeedQFunctionContextRegisterDouble()). 1920859c15bbSJames Wright 1921ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 19223668ca4bSJeremy L Thompson @param[in] field_name Name of field to retrieve label 19233668ca4bSJeremy L Thompson @param[out] field_label Variable to field label 19243668ca4bSJeremy L Thompson 19253668ca4bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 19263668ca4bSJeremy L Thompson 19273668ca4bSJeremy L Thompson @ref User 19283668ca4bSJeremy L Thompson **/ 192917b0d5c6SJeremy L Thompson int CeedOperatorGetContextFieldLabel(CeedOperator op, const char *field_name, CeedContextFieldLabel *field_label) { 19301c66c397SJeremy L Thompson bool is_composite, field_found = false; 19311c66c397SJeremy L Thompson 19322b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 19332b730f8bSJeremy L Thompson 19343668ca4bSJeremy L Thompson if (is_composite) { 1935a98a090bSJeremy L Thompson // Composite operator 1936a98a090bSJeremy L Thompson // -- Check if composite label already created 19373668ca4bSJeremy L Thompson for (CeedInt i = 0; i < op->num_context_labels; i++) { 19383668ca4bSJeremy L Thompson if (!strcmp(op->context_labels[i]->name, field_name)) { 19393668ca4bSJeremy L Thompson *field_label = op->context_labels[i]; 19403668ca4bSJeremy L Thompson return CEED_ERROR_SUCCESS; 19413668ca4bSJeremy L Thompson } 19423668ca4bSJeremy L Thompson } 19433668ca4bSJeremy L Thompson 1944a98a090bSJeremy L Thompson // -- Create composite label if needed 19453668ca4bSJeremy L Thompson CeedInt num_sub; 19463668ca4bSJeremy L Thompson CeedOperator *sub_operators; 19473668ca4bSJeremy L Thompson CeedContextFieldLabel new_field_label; 19483668ca4bSJeremy L Thompson 19492b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &new_field_label)); 1950ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_sub)); 1951ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 19522b730f8bSJeremy L Thompson CeedCall(CeedCalloc(num_sub, &new_field_label->sub_labels)); 19533668ca4bSJeremy L Thompson new_field_label->num_sub_labels = num_sub; 19543668ca4bSJeremy L Thompson 19553668ca4bSJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 19563668ca4bSJeremy L Thompson if (sub_operators[i]->qf->ctx) { 19573668ca4bSJeremy L Thompson CeedContextFieldLabel new_field_label_i; 19581c66c397SJeremy L Thompson 19592b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldLabel(sub_operators[i]->qf->ctx, field_name, &new_field_label_i)); 19603668ca4bSJeremy L Thompson if (new_field_label_i) { 1961a98a090bSJeremy L Thompson field_found = true; 19623668ca4bSJeremy L Thompson new_field_label->sub_labels[i] = new_field_label_i; 19633668ca4bSJeremy L Thompson new_field_label->name = new_field_label_i->name; 19643668ca4bSJeremy L Thompson new_field_label->description = new_field_label_i->description; 19652b730f8bSJeremy L Thompson if (new_field_label->type && new_field_label->type != new_field_label_i->type) { 19667bfe0f0eSJeremy L Thompson // LCOV_EXCL_START 19672b730f8bSJeremy L Thompson CeedCall(CeedFree(&new_field_label)); 19686e536b99SJeremy L Thompson return CeedError(CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "Incompatible field types on sub-operator contexts. %s != %s", 19692b730f8bSJeremy L Thompson CeedContextFieldTypes[new_field_label->type], CeedContextFieldTypes[new_field_label_i->type]); 19707bfe0f0eSJeremy L Thompson // LCOV_EXCL_STOP 19717bfe0f0eSJeremy L Thompson } else { 19727bfe0f0eSJeremy L Thompson new_field_label->type = new_field_label_i->type; 19737bfe0f0eSJeremy L Thompson } 19742b730f8bSJeremy L Thompson if (new_field_label->num_values != 0 && new_field_label->num_values != new_field_label_i->num_values) { 19757bfe0f0eSJeremy L Thompson // LCOV_EXCL_START 19762b730f8bSJeremy L Thompson CeedCall(CeedFree(&new_field_label)); 19776e536b99SJeremy L Thompson return CeedError(CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 19786e536b99SJeremy L Thompson "Incompatible field number of values on sub-operator contexts. %zu != %zu", new_field_label->num_values, 19796e536b99SJeremy L Thompson new_field_label_i->num_values); 19807bfe0f0eSJeremy L Thompson // LCOV_EXCL_STOP 19817bfe0f0eSJeremy L Thompson } else { 19827bfe0f0eSJeremy L Thompson new_field_label->num_values = new_field_label_i->num_values; 19837bfe0f0eSJeremy L Thompson } 19843668ca4bSJeremy L Thompson } 19853668ca4bSJeremy L Thompson } 19863668ca4bSJeremy L Thompson } 1987a98a090bSJeremy L Thompson // -- Cleanup if field was found 1988a98a090bSJeremy L Thompson if (field_found) { 1989a98a090bSJeremy L Thompson *field_label = new_field_label; 1990a98a090bSJeremy L Thompson } else { 19913668ca4bSJeremy L Thompson // LCOV_EXCL_START 19922b730f8bSJeremy L Thompson CeedCall(CeedFree(&new_field_label->sub_labels)); 19932b730f8bSJeremy L Thompson CeedCall(CeedFree(&new_field_label)); 19943668ca4bSJeremy L Thompson *field_label = NULL; 19953668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 19965ac9af79SJeremy L Thompson } 19975ac9af79SJeremy L Thompson } else { 19981203703bSJeremy L Thompson CeedQFunction qf; 19991203703bSJeremy L Thompson CeedQFunctionContext ctx; 20001203703bSJeremy L Thompson 2001a98a090bSJeremy L Thompson // Single, non-composite operator 20021203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 20031203703bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &ctx)); 2004c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 20051203703bSJeremy L Thompson if (ctx) { 20061203703bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldLabel(ctx, field_name, field_label)); 2007a98a090bSJeremy L Thompson } else { 2008a98a090bSJeremy L Thompson *field_label = NULL; 2009a98a090bSJeremy L Thompson } 20105ac9af79SJeremy L Thompson } 20115ac9af79SJeremy L Thompson 20125ac9af79SJeremy L Thompson // Set label in operator 20135ac9af79SJeremy L Thompson if (*field_label) { 20145ac9af79SJeremy L Thompson (*field_label)->from_op = true; 20155ac9af79SJeremy L Thompson 20163668ca4bSJeremy L Thompson // Move new composite label to operator 20173668ca4bSJeremy L Thompson if (op->num_context_labels == 0) { 20182b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &op->context_labels)); 20193668ca4bSJeremy L Thompson op->max_context_labels = 1; 20203668ca4bSJeremy L Thompson } else if (op->num_context_labels == op->max_context_labels) { 20212b730f8bSJeremy L Thompson CeedCall(CeedRealloc(2 * op->num_context_labels, &op->context_labels)); 20223668ca4bSJeremy L Thompson op->max_context_labels *= 2; 20233668ca4bSJeremy L Thompson } 20245ac9af79SJeremy L Thompson op->context_labels[op->num_context_labels] = *field_label; 20253668ca4bSJeremy L Thompson op->num_context_labels++; 20263668ca4bSJeremy L Thompson } 20273668ca4bSJeremy L Thompson return CEED_ERROR_SUCCESS; 20283668ca4bSJeremy L Thompson } 20293668ca4bSJeremy L Thompson 20303668ca4bSJeremy L Thompson /** 2031ca94c3ddSJeremy L Thompson @brief Set `CeedQFunctionContext` field holding double precision values. 20324385fb7fSSebastian Grimberg 2033ca94c3ddSJeremy L Thompson For composite operators, the values are set in all sub-operator `CeedQFunctionContext` that have a matching `field_name`. 2034d8dd9a91SJeremy L Thompson 2035ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 20362788fa27SJeremy L Thompson @param[in] field_label Label of field to set 2037ea61e9acSJeremy L Thompson @param[in] values Values to set 2038d8dd9a91SJeremy L Thompson 2039d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2040d8dd9a91SJeremy L Thompson 2041d8dd9a91SJeremy L Thompson @ref User 2042d8dd9a91SJeremy L Thompson **/ 204317b0d5c6SJeremy L Thompson int CeedOperatorSetContextDouble(CeedOperator op, CeedContextFieldLabel field_label, double *values) { 20442b730f8bSJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_DOUBLE, values); 2045d8dd9a91SJeremy L Thompson } 2046d8dd9a91SJeremy L Thompson 2047d8dd9a91SJeremy L Thompson /** 2048ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field holding double precision values, read-only. 20494385fb7fSSebastian Grimberg 2050ca94c3ddSJeremy L Thompson For composite operators, the values correspond to the first sub-operator `CeedQFunctionContext` that has a matching `field_name`. 20512788fa27SJeremy L Thompson 2052ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 20532788fa27SJeremy L Thompson @param[in] field_label Label of field to get 20542788fa27SJeremy L Thompson @param[out] num_values Number of values in the field label 20552788fa27SJeremy L Thompson @param[out] values Pointer to context values 20562788fa27SJeremy L Thompson 20572788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 20582788fa27SJeremy L Thompson 20592788fa27SJeremy L Thompson @ref User 20602788fa27SJeremy L Thompson **/ 206117b0d5c6SJeremy L Thompson int CeedOperatorGetContextDoubleRead(CeedOperator op, CeedContextFieldLabel field_label, size_t *num_values, const double **values) { 20622788fa27SJeremy L Thompson return CeedOperatorContextGetGenericRead(op, field_label, CEED_CONTEXT_FIELD_DOUBLE, num_values, values); 20632788fa27SJeremy L Thompson } 20642788fa27SJeremy L Thompson 20652788fa27SJeremy L Thompson /** 2066ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field holding double precision values, read-only. 20672788fa27SJeremy L Thompson 2068ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 20692788fa27SJeremy L Thompson @param[in] field_label Label of field to restore 20702788fa27SJeremy L Thompson @param[out] values Pointer to context values 20712788fa27SJeremy L Thompson 20722788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 20732788fa27SJeremy L Thompson 20742788fa27SJeremy L Thompson @ref User 20752788fa27SJeremy L Thompson **/ 207617b0d5c6SJeremy L Thompson int CeedOperatorRestoreContextDoubleRead(CeedOperator op, CeedContextFieldLabel field_label, const double **values) { 20772788fa27SJeremy L Thompson return CeedOperatorContextRestoreGenericRead(op, field_label, CEED_CONTEXT_FIELD_DOUBLE, values); 20782788fa27SJeremy L Thompson } 20792788fa27SJeremy L Thompson 20802788fa27SJeremy L Thompson /** 2081ca94c3ddSJeremy L Thompson @brief Set `CeedQFunctionContext` field holding `int32` values. 20824385fb7fSSebastian Grimberg 2083ca94c3ddSJeremy L Thompson For composite operators, the values are set in all sub-operator `CeedQFunctionContext` that have a matching `field_name`. 2084d8dd9a91SJeremy L Thompson 2085ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 2086ea61e9acSJeremy L Thompson @param[in] field_label Label of field to set 2087ea61e9acSJeremy L Thompson @param[in] values Values to set 2088d8dd9a91SJeremy L Thompson 2089d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2090d8dd9a91SJeremy L Thompson 2091d8dd9a91SJeremy L Thompson @ref User 2092d8dd9a91SJeremy L Thompson **/ 209323dbfd29SJeremy L Thompson int CeedOperatorSetContextInt32(CeedOperator op, CeedContextFieldLabel field_label, int32_t *values) { 20942b730f8bSJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_INT32, values); 2095d8dd9a91SJeremy L Thompson } 2096d8dd9a91SJeremy L Thompson 2097d8dd9a91SJeremy L Thompson /** 2098ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field holding `int32` values, read-only. 20994385fb7fSSebastian Grimberg 2100ca94c3ddSJeremy L Thompson For composite operators, the values correspond to the first sub-operator `CeedQFunctionContext` that has a matching `field_name`. 21012788fa27SJeremy L Thompson 2102ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 21032788fa27SJeremy L Thompson @param[in] field_label Label of field to get 2104ca94c3ddSJeremy L Thompson @param[out] num_values Number of `int32` values in `values` 21052788fa27SJeremy L Thompson @param[out] values Pointer to context values 21062788fa27SJeremy L Thompson 21072788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21082788fa27SJeremy L Thompson 21092788fa27SJeremy L Thompson @ref User 21102788fa27SJeremy L Thompson **/ 211123dbfd29SJeremy L Thompson int CeedOperatorGetContextInt32Read(CeedOperator op, CeedContextFieldLabel field_label, size_t *num_values, const int32_t **values) { 21122788fa27SJeremy L Thompson return CeedOperatorContextGetGenericRead(op, field_label, CEED_CONTEXT_FIELD_INT32, num_values, values); 21132788fa27SJeremy L Thompson } 21142788fa27SJeremy L Thompson 21152788fa27SJeremy L Thompson /** 2116ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field holding `int32` values, read-only. 21172788fa27SJeremy L Thompson 2118ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 21192788fa27SJeremy L Thompson @param[in] field_label Label of field to get 21202788fa27SJeremy L Thompson @param[out] values Pointer to context values 21212788fa27SJeremy L Thompson 21222788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21232788fa27SJeremy L Thompson 21242788fa27SJeremy L Thompson @ref User 21252788fa27SJeremy L Thompson **/ 212623dbfd29SJeremy L Thompson int CeedOperatorRestoreContextInt32Read(CeedOperator op, CeedContextFieldLabel field_label, const int32_t **values) { 21272788fa27SJeremy L Thompson return CeedOperatorContextRestoreGenericRead(op, field_label, CEED_CONTEXT_FIELD_INT32, values); 21282788fa27SJeremy L Thompson } 21292788fa27SJeremy L Thompson 21302788fa27SJeremy L Thompson /** 2131ca94c3ddSJeremy L Thompson @brief Set `CeedQFunctionContext` field holding boolean values. 21325b6ec284SJeremy L Thompson 2133ca94c3ddSJeremy L Thompson For composite operators, the values are set in all sub-operator `CeedQFunctionContext` that have a matching `field_name`. 21345b6ec284SJeremy L Thompson 2135ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 21365b6ec284SJeremy L Thompson @param[in] field_label Label of field to set 21375b6ec284SJeremy L Thompson @param[in] values Values to set 21385b6ec284SJeremy L Thompson 21395b6ec284SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21405b6ec284SJeremy L Thompson 21415b6ec284SJeremy L Thompson @ref User 21425b6ec284SJeremy L Thompson **/ 21435b6ec284SJeremy L Thompson int CeedOperatorSetContextBoolean(CeedOperator op, CeedContextFieldLabel field_label, bool *values) { 21445b6ec284SJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_BOOL, values); 21455b6ec284SJeremy L Thompson } 21465b6ec284SJeremy L Thompson 21475b6ec284SJeremy L Thompson /** 2148ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field holding boolean values, read-only. 21495b6ec284SJeremy L Thompson 2150ca94c3ddSJeremy L Thompson For composite operators, the values correspond to the first sub-operator `CeedQFunctionContext` that has a matching `field_name`. 21515b6ec284SJeremy L Thompson 2152ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 21535b6ec284SJeremy L Thompson @param[in] field_label Label of field to get 2154ca94c3ddSJeremy L Thompson @param[out] num_values Number of boolean values in `values` 21555b6ec284SJeremy L Thompson @param[out] values Pointer to context values 21565b6ec284SJeremy L Thompson 21575b6ec284SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21585b6ec284SJeremy L Thompson 21595b6ec284SJeremy L Thompson @ref User 21605b6ec284SJeremy L Thompson **/ 21615b6ec284SJeremy L Thompson int CeedOperatorGetContextBooleanRead(CeedOperator op, CeedContextFieldLabel field_label, size_t *num_values, const bool **values) { 21625b6ec284SJeremy L Thompson return CeedOperatorContextGetGenericRead(op, field_label, CEED_CONTEXT_FIELD_BOOL, num_values, values); 21635b6ec284SJeremy L Thompson } 21645b6ec284SJeremy L Thompson 21655b6ec284SJeremy L Thompson /** 2166ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field holding boolean values, read-only. 21675b6ec284SJeremy L Thompson 2168ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 21695b6ec284SJeremy L Thompson @param[in] field_label Label of field to get 21705b6ec284SJeremy L Thompson @param[out] values Pointer to context values 21715b6ec284SJeremy L Thompson 21725b6ec284SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21735b6ec284SJeremy L Thompson 21745b6ec284SJeremy L Thompson @ref User 21755b6ec284SJeremy L Thompson **/ 21765b6ec284SJeremy L Thompson int CeedOperatorRestoreContextBooleanRead(CeedOperator op, CeedContextFieldLabel field_label, const bool **values) { 21775b6ec284SJeremy L Thompson return CeedOperatorContextRestoreGenericRead(op, field_label, CEED_CONTEXT_FIELD_BOOL, values); 21785b6ec284SJeremy L Thompson } 21795b6ec284SJeremy L Thompson 21805b6ec284SJeremy L Thompson /** 2181ca94c3ddSJeremy L Thompson @brief Apply `CeedOperator` to a `CeedVector`. 2182d7b241e6Sjeremylt 2183ea61e9acSJeremy L Thompson This computes the action of the operator on the specified (active) input, yielding its (active) output. 2184ca94c3ddSJeremy L Thompson All inputs and outputs must be specified using @ref CeedOperatorSetField(). 2185d7b241e6Sjeremylt 21865da5ab9fSZach Atkins @note Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 2187f04ea552SJeremy L Thompson 2188ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to apply 2189ca94c3ddSJeremy L Thompson @param[in] in `CeedVector` containing input state or @ref CEED_VECTOR_NONE if there are no active inputs 2190ca94c3ddSJeremy 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 2191ca94c3ddSJeremy L Thompson @param[in] request Address of @ref CeedRequest for non-blocking completion, else @ref CEED_REQUEST_IMMEDIATE 2192b11c1e72Sjeremylt 2193b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 2194dfdf5a53Sjeremylt 21957a982d89SJeremy L. Thompson @ref User 2196b11c1e72Sjeremylt **/ 21972b730f8bSJeremy L Thompson int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, CeedRequest *request) { 21981203703bSJeremy L Thompson bool is_composite; 21991203703bSJeremy L Thompson 22002b730f8bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 2201d7b241e6Sjeremylt 22021203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 22030db52efcSZach Atkins if (is_composite && op->ApplyComposite) { 2204250756a7Sjeremylt // Composite Operator 22052b730f8bSJeremy L Thompson CeedCall(op->ApplyComposite(op, in, out, request)); 22060db52efcSZach Atkins } else if (!is_composite && op->Apply) { 22073ca2b39bSJeremy L Thompson // Standard Operator 22083ca2b39bSJeremy L Thompson CeedCall(op->Apply(op, in, out, request)); 22093ca2b39bSJeremy L Thompson } else { 22100db52efcSZach Atkins // Standard or composite, default to zeroing out and calling ApplyAddActive 22110db52efcSZach Atkins // Zero active output 22120db52efcSZach Atkins if (out != CEED_VECTOR_NONE) CeedCall(CeedVectorSetValue(out, 0.0)); 22131203703bSJeremy L Thompson 22140db52efcSZach Atkins // ApplyAddActive 22150db52efcSZach Atkins CeedCall(CeedOperatorApplyAddActive(op, in, out, request)); 2216250756a7Sjeremylt } 2217e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2218cae8b89aSjeremylt } 2219cae8b89aSjeremylt 2220cae8b89aSjeremylt /** 2221ca94c3ddSJeremy L Thompson @brief Apply `CeedOperator` to a `CeedVector` and add result to output `CeedVector`. 2222cae8b89aSjeremylt 2223ea61e9acSJeremy L Thompson This computes the action of the operator on the specified (active) input, yielding its (active) output. 2224ca94c3ddSJeremy L Thompson All inputs and outputs must be specified using @ref CeedOperatorSetField(). 2225cae8b89aSjeremylt 22265da5ab9fSZach Atkins @note Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 22275da5ab9fSZach Atkins @warning This function adds into ALL outputs, including passive outputs. To only add into the active output, use `CeedOperatorApplyAddActive()`. 22285da5ab9fSZach Atkins @see `CeedOperatorApplyAddActive()` 22295da5ab9fSZach Atkins 2230ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to apply 2231ca94c3ddSJeremy L Thompson @param[in] in `CeedVector` containing input state or @ref CEED_VECTOR_NONE if there are no active inputs 2232ca94c3ddSJeremy 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 2233ca94c3ddSJeremy L Thompson @param[in] request Address of @ref CeedRequest for non-blocking completion, else @ref CEED_REQUEST_IMMEDIATE 2234cae8b89aSjeremylt 2235cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 2236cae8b89aSjeremylt 22377a982d89SJeremy L. Thompson @ref User 2238cae8b89aSjeremylt **/ 22392b730f8bSJeremy L Thompson int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, CeedRequest *request) { 22401203703bSJeremy L Thompson bool is_composite; 22411203703bSJeremy L Thompson 22422b730f8bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 2243cae8b89aSjeremylt 22441203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 22451203703bSJeremy L Thompson if (is_composite) { 2246250756a7Sjeremylt // Composite Operator 2247250756a7Sjeremylt if (op->ApplyAddComposite) { 22482b730f8bSJeremy L Thompson CeedCall(op->ApplyAddComposite(op, in, out, request)); 2249cae8b89aSjeremylt } else { 2250d1d35e2fSjeremylt CeedInt num_suboperators; 2251d1d35e2fSjeremylt CeedOperator *sub_operators; 2252250756a7Sjeremylt 2253ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 2254ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 2255d1d35e2fSjeremylt for (CeedInt i = 0; i < num_suboperators; i++) { 22562b730f8bSJeremy L Thompson CeedCall(CeedOperatorApplyAdd(sub_operators[i], in, out, request)); 22571d7d2407SJeremy L Thompson } 2258250756a7Sjeremylt } 22591203703bSJeremy L Thompson } else if (op->num_elem > 0) { 22603ca2b39bSJeremy L Thompson // Standard Operator 22613ca2b39bSJeremy L Thompson CeedCall(op->ApplyAdd(op, in, out, request)); 2262250756a7Sjeremylt } 2263e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2264d7b241e6Sjeremylt } 2265d7b241e6Sjeremylt 2266d7b241e6Sjeremylt /** 22675da5ab9fSZach Atkins @brief Apply `CeedOperator` to a `CeedVector` and add result to output `CeedVector`. Only sums into active outputs, overwrites passive outputs. 22685da5ab9fSZach Atkins 22695da5ab9fSZach Atkins This computes the action of the operator on the specified (active) input, yielding its (active) output. 22705da5ab9fSZach Atkins All inputs and outputs must be specified using @ref CeedOperatorSetField(). 22715da5ab9fSZach Atkins 22725da5ab9fSZach Atkins @note Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 22735da5ab9fSZach Atkins 22745da5ab9fSZach Atkins @param[in] op `CeedOperator` to apply 22755da5ab9fSZach Atkins @param[in] in `CeedVector` containing input state or @ref CEED_VECTOR_NONE if there are no active inputs 22765da5ab9fSZach 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 22775da5ab9fSZach Atkins @param[in] request Address of @ref CeedRequest for non-blocking completion, else @ref CEED_REQUEST_IMMEDIATE 22785da5ab9fSZach Atkins 22795da5ab9fSZach Atkins @return An error code: 0 - success, otherwise - failure 22805da5ab9fSZach Atkins 22815da5ab9fSZach Atkins @ref User 22825da5ab9fSZach Atkins **/ 22835da5ab9fSZach Atkins int CeedOperatorApplyAddActive(CeedOperator op, CeedVector in, CeedVector out, CeedRequest *request) { 22845da5ab9fSZach Atkins bool is_composite; 22855da5ab9fSZach Atkins 22865da5ab9fSZach Atkins CeedCall(CeedOperatorCheckReady(op)); 22875da5ab9fSZach Atkins 22885da5ab9fSZach Atkins CeedCall(CeedOperatorIsComposite(op, &is_composite)); 22895da5ab9fSZach Atkins if (is_composite) { 22905da5ab9fSZach Atkins // Composite Operator 22915da5ab9fSZach Atkins CeedInt num_suboperators; 22925da5ab9fSZach Atkins CeedOperator *sub_operators; 22935da5ab9fSZach Atkins 2294ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 2295ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 22965da5ab9fSZach Atkins 22975da5ab9fSZach Atkins // Zero all output vectors 22985da5ab9fSZach Atkins for (CeedInt i = 0; i < num_suboperators; i++) { 22995da5ab9fSZach Atkins CeedInt num_output_fields; 23005da5ab9fSZach Atkins CeedOperatorField *output_fields; 23015da5ab9fSZach Atkins 23025da5ab9fSZach Atkins CeedCall(CeedOperatorGetFields(sub_operators[i], NULL, NULL, &num_output_fields, &output_fields)); 23035da5ab9fSZach Atkins for (CeedInt j = 0; j < num_output_fields; j++) { 23045da5ab9fSZach Atkins CeedVector vec; 23055da5ab9fSZach Atkins 23065da5ab9fSZach Atkins CeedCall(CeedOperatorFieldGetVector(output_fields[j], &vec)); 23075da5ab9fSZach Atkins if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) CeedCall(CeedVectorSetValue(vec, 0.0)); 23085da5ab9fSZach Atkins CeedCall(CeedVectorDestroy(&vec)); 23095da5ab9fSZach Atkins } 23105da5ab9fSZach Atkins } 23115da5ab9fSZach Atkins // ApplyAdd 23125da5ab9fSZach Atkins CeedCall(CeedOperatorApplyAdd(op, in, out, request)); 23135da5ab9fSZach Atkins } else { 23145da5ab9fSZach Atkins // Standard Operator 23155da5ab9fSZach Atkins CeedInt num_output_fields; 23165da5ab9fSZach Atkins CeedOperatorField *output_fields; 23175da5ab9fSZach Atkins 23185da5ab9fSZach Atkins CeedCall(CeedOperatorGetFields(op, NULL, NULL, &num_output_fields, &output_fields)); 23195da5ab9fSZach Atkins // Zero all output vectors 23205da5ab9fSZach Atkins for (CeedInt i = 0; i < num_output_fields; i++) { 23215da5ab9fSZach Atkins CeedVector vec; 23225da5ab9fSZach Atkins 23235da5ab9fSZach Atkins CeedCall(CeedOperatorFieldGetVector(output_fields[i], &vec)); 23245da5ab9fSZach Atkins if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) CeedCall(CeedVectorSetValue(vec, 0.0)); 23255da5ab9fSZach Atkins CeedCall(CeedVectorDestroy(&vec)); 23265da5ab9fSZach Atkins } 23275da5ab9fSZach Atkins // ApplyAdd 23285da5ab9fSZach Atkins CeedCall(CeedOperatorApplyAdd(op, in, out, request)); 23295da5ab9fSZach Atkins } 23305da5ab9fSZach Atkins return CEED_ERROR_SUCCESS; 23315da5ab9fSZach Atkins } 23325da5ab9fSZach Atkins 23335da5ab9fSZach Atkins /** 2334536b928cSSebastian Grimberg @brief Destroy temporary assembly data associated with a `CeedOperator` 2335536b928cSSebastian Grimberg 2336536b928cSSebastian Grimberg @param[in,out] op `CeedOperator` whose assembly data to destroy 2337536b928cSSebastian Grimberg 2338536b928cSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 2339536b928cSSebastian Grimberg 2340536b928cSSebastian Grimberg @ref User 2341536b928cSSebastian Grimberg **/ 2342536b928cSSebastian Grimberg int CeedOperatorAssemblyDataStrip(CeedOperator op) { 2343536b928cSSebastian Grimberg bool is_composite; 2344536b928cSSebastian Grimberg 2345536b928cSSebastian Grimberg CeedCall(CeedQFunctionAssemblyDataDestroy(&op->qf_assembled)); 2346536b928cSSebastian Grimberg CeedCall(CeedOperatorAssemblyDataDestroy(&op->op_assembled)); 2347536b928cSSebastian Grimberg CeedCall(CeedOperatorIsComposite(op, &is_composite)); 2348536b928cSSebastian Grimberg if (is_composite) { 2349536b928cSSebastian Grimberg CeedInt num_suboperators; 2350536b928cSSebastian Grimberg CeedOperator *sub_operators; 2351536b928cSSebastian Grimberg 2352ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 2353ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 2354536b928cSSebastian Grimberg for (CeedInt i = 0; i < num_suboperators; i++) { 2355536b928cSSebastian Grimberg CeedCall(CeedQFunctionAssemblyDataDestroy(&sub_operators[i]->qf_assembled)); 2356536b928cSSebastian Grimberg CeedCall(CeedOperatorAssemblyDataDestroy(&sub_operators[i]->op_assembled)); 2357536b928cSSebastian Grimberg } 2358536b928cSSebastian Grimberg } 2359536b928cSSebastian Grimberg return CEED_ERROR_SUCCESS; 2360536b928cSSebastian Grimberg } 2361536b928cSSebastian Grimberg 2362536b928cSSebastian Grimberg /** 2363ca94c3ddSJeremy L Thompson @brief Destroy a `CeedOperator` 2364d7b241e6Sjeremylt 2365ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` to destroy 2366b11c1e72Sjeremylt 2367b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 2368dfdf5a53Sjeremylt 23697a982d89SJeremy L. Thompson @ref User 2370b11c1e72Sjeremylt **/ 2371d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 2372ad6481ceSJeremy L Thompson if (!*op || --(*op)->ref_count > 0) { 2373ad6481ceSJeremy L Thompson *op = NULL; 2374ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 2375ad6481ceSJeremy L Thompson } 2376f883f0a5SSebastian Grimberg // Backend destroy 2377f883f0a5SSebastian Grimberg if ((*op)->Destroy) { 2378f883f0a5SSebastian Grimberg CeedCall((*op)->Destroy(*op)); 2379f883f0a5SSebastian Grimberg } 2380fe2413ffSjeremylt // Free fields 23812b730f8bSJeremy L Thompson for (CeedInt i = 0; i < (*op)->num_fields; i++) { 2382d1d35e2fSjeremylt if ((*op)->input_fields[i]) { 2383437c7c90SJeremy L Thompson if ((*op)->input_fields[i]->elem_rstr != CEED_ELEMRESTRICTION_NONE) { 2384437c7c90SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&(*op)->input_fields[i]->elem_rstr)); 238515910d16Sjeremylt } 2386356036faSJeremy L Thompson if ((*op)->input_fields[i]->basis != CEED_BASIS_NONE) { 23872b730f8bSJeremy L Thompson CeedCall(CeedBasisDestroy(&(*op)->input_fields[i]->basis)); 238871352a93Sjeremylt } 23892b730f8bSJeremy L Thompson if ((*op)->input_fields[i]->vec != CEED_VECTOR_ACTIVE && (*op)->input_fields[i]->vec != CEED_VECTOR_NONE) { 23902b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&(*op)->input_fields[i]->vec)); 239171352a93Sjeremylt } 23922b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->input_fields[i]->field_name)); 23932b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->input_fields[i])); 2394fe2413ffSjeremylt } 23952b730f8bSJeremy L Thompson } 23962b730f8bSJeremy L Thompson for (CeedInt i = 0; i < (*op)->num_fields; i++) { 2397d1d35e2fSjeremylt if ((*op)->output_fields[i]) { 2398437c7c90SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&(*op)->output_fields[i]->elem_rstr)); 2399356036faSJeremy L Thompson if ((*op)->output_fields[i]->basis != CEED_BASIS_NONE) { 24002b730f8bSJeremy L Thompson CeedCall(CeedBasisDestroy(&(*op)->output_fields[i]->basis)); 240171352a93Sjeremylt } 24022b730f8bSJeremy L Thompson if ((*op)->output_fields[i]->vec != CEED_VECTOR_ACTIVE && (*op)->output_fields[i]->vec != CEED_VECTOR_NONE) { 24032b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&(*op)->output_fields[i]->vec)); 240471352a93Sjeremylt } 24052b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->output_fields[i]->field_name)); 24062b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->output_fields[i])); 24072b730f8bSJeremy L Thompson } 2408fe2413ffSjeremylt } 2409f883f0a5SSebastian Grimberg CeedCall(CeedFree(&(*op)->input_fields)); 2410f883f0a5SSebastian Grimberg CeedCall(CeedFree(&(*op)->output_fields)); 2411f883f0a5SSebastian Grimberg // Destroy AtPoints data 241248acf710SJeremy L Thompson CeedCall(CeedVectorDestroy(&(*op)->point_coords)); 241348acf710SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&(*op)->rstr_points)); 241448acf710SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&(*op)->first_points_rstr)); 2415c6b536a8SSebastian Grimberg // Destroy assembly data (must happen before destroying sub_operators) 2416f883f0a5SSebastian Grimberg CeedCall(CeedOperatorAssemblyDataStrip(*op)); 2417d1d35e2fSjeremylt // Destroy sub_operators 24182b730f8bSJeremy L Thompson for (CeedInt i = 0; i < (*op)->num_suboperators; i++) { 2419d1d35e2fSjeremylt if ((*op)->sub_operators[i]) { 24202b730f8bSJeremy L Thompson CeedCall(CeedOperatorDestroy(&(*op)->sub_operators[i])); 242152d6035fSJeremy L Thompson } 24222b730f8bSJeremy L Thompson } 2423f883f0a5SSebastian Grimberg CeedCall(CeedFree(&(*op)->sub_operators)); 24242b730f8bSJeremy L Thompson CeedCall(CeedQFunctionDestroy(&(*op)->qf)); 24252b730f8bSJeremy L Thompson CeedCall(CeedQFunctionDestroy(&(*op)->dqf)); 24262b730f8bSJeremy L Thompson CeedCall(CeedQFunctionDestroy(&(*op)->dqfT)); 24273668ca4bSJeremy L Thompson // Destroy any composite labels 24285ac9af79SJeremy L Thompson if ((*op)->is_composite) { 24293668ca4bSJeremy L Thompson for (CeedInt i = 0; i < (*op)->num_context_labels; i++) { 24302b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->context_labels[i]->sub_labels)); 24312b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->context_labels[i])); 24323668ca4bSJeremy L Thompson } 24335ac9af79SJeremy L Thompson } 24342b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->context_labels)); 2435fe2413ffSjeremylt 24365107b09fSJeremy L Thompson // Destroy fallback 24372b730f8bSJeremy L Thompson CeedCall(CeedOperatorDestroy(&(*op)->op_fallback)); 24385107b09fSJeremy L Thompson 24392b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->name)); 2440f883f0a5SSebastian Grimberg CeedCall(CeedDestroy(&(*op)->ceed)); 24412b730f8bSJeremy L Thompson CeedCall(CeedFree(op)); 2442e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2443d7b241e6Sjeremylt } 2444d7b241e6Sjeremylt 2445d7b241e6Sjeremylt /// @} 2446