19ba83ac0SJeremy L Thompson // Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors. 23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3d7b241e6Sjeremylt // 43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 5d7b241e6Sjeremylt // 63d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 7d7b241e6Sjeremylt 83d576824SJeremy L Thompson #include <ceed-impl.h> 949aac155SJeremy L Thompson #include <ceed.h> 102b730f8bSJeremy L Thompson #include <ceed/backend.h> 113d576824SJeremy L Thompson #include <stdbool.h> 123d576824SJeremy L Thompson #include <stdio.h> 133d576824SJeremy L Thompson #include <string.h> 14d7b241e6Sjeremylt 15dfdf5a53Sjeremylt /// @file 167a982d89SJeremy L. Thompson /// Implementation of CeedOperator interfaces 177a982d89SJeremy L. Thompson 187a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 197a982d89SJeremy L. Thompson /// CeedOperator Library Internal Functions 207a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 217a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorDeveloper 227a982d89SJeremy L. Thompson /// @{ 237a982d89SJeremy L. Thompson 247a982d89SJeremy L. Thompson /** 25ca94c3ddSJeremy L Thompson @brief Check if a `CeedOperator` Field matches the `CeedQFunction` Field 26e15f9bd0SJeremy L Thompson 27ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object for error handling 28ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunction` Field matching `CeedOperator` Field 29bafebce1SSebastian Grimberg @param[in] rstr `CeedOperator` Field `CeedElemRestriction` 30bafebce1SSebastian Grimberg @param[in] basis `CeedOperator` Field `CeedBasis` 31e15f9bd0SJeremy L Thompson 32e15f9bd0SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 33e15f9bd0SJeremy L Thompson 34e15f9bd0SJeremy L Thompson @ref Developer 35e15f9bd0SJeremy L Thompson **/ 36bafebce1SSebastian Grimberg static int CeedOperatorCheckField(Ceed ceed, CeedQFunctionField qf_field, CeedElemRestriction rstr, CeedBasis basis) { 376f8994e9SJeremy L Thompson const char *field_name; 381203703bSJeremy L Thompson CeedInt dim = 1, num_comp = 1, q_comp = 1, rstr_num_comp = 1, size; 391203703bSJeremy L Thompson CeedEvalMode eval_mode; 401203703bSJeremy L Thompson 411203703bSJeremy L Thompson // Field data 42ab747706SJeremy L Thompson CeedCall(CeedQFunctionFieldGetData(qf_field, &field_name, &size, &eval_mode)); 432b730f8bSJeremy L Thompson 44e15f9bd0SJeremy L Thompson // Restriction 45bafebce1SSebastian Grimberg CeedCheck((rstr == CEED_ELEMRESTRICTION_NONE) == (eval_mode == CEED_EVAL_WEIGHT), ceed, CEED_ERROR_INCOMPATIBLE, 466574a04fSJeremy L Thompson "CEED_ELEMRESTRICTION_NONE and CEED_EVAL_WEIGHT must be used together."); 47bafebce1SSebastian Grimberg if (rstr != CEED_ELEMRESTRICTION_NONE) { 48bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionGetNumComponents(rstr, &rstr_num_comp)); 49e1e9e29dSJed Brown } 50e15f9bd0SJeremy L Thompson // Basis 51bafebce1SSebastian Grimberg CeedCheck((basis == CEED_BASIS_NONE) == (eval_mode == CEED_EVAL_NONE), ceed, CEED_ERROR_INCOMPATIBLE, 52356036faSJeremy L Thompson "CEED_BASIS_NONE and CEED_EVAL_NONE must be used together."); 53bafebce1SSebastian Grimberg if (basis != CEED_BASIS_NONE) { 54bafebce1SSebastian Grimberg CeedCall(CeedBasisGetDimension(basis, &dim)); 55bafebce1SSebastian Grimberg CeedCall(CeedBasisGetNumComponents(basis, &num_comp)); 56bafebce1SSebastian Grimberg CeedCall(CeedBasisGetNumQuadratureComponents(basis, eval_mode, &q_comp)); 57bafebce1SSebastian Grimberg CeedCheck(rstr == CEED_ELEMRESTRICTION_NONE || rstr_num_comp == num_comp, ceed, CEED_ERROR_DIMENSION, 58ca94c3ddSJeremy L Thompson "Field '%s' of size %" CeedInt_FMT " and EvalMode %s: CeedElemRestriction has %" CeedInt_FMT 59ca94c3ddSJeremy L Thompson " components, but CeedBasis has %" CeedInt_FMT " components", 601203703bSJeremy L Thompson field_name, size, CeedEvalModes[eval_mode], rstr_num_comp, num_comp); 61e15f9bd0SJeremy L Thompson } 62e15f9bd0SJeremy L Thompson // Field size 63d1d35e2fSjeremylt switch (eval_mode) { 64e15f9bd0SJeremy L Thompson case CEED_EVAL_NONE: 65edb2538eSJeremy L Thompson CeedCheck(size == rstr_num_comp, ceed, CEED_ERROR_DIMENSION, 661203703bSJeremy L Thompson "Field '%s' of size %" CeedInt_FMT " and EvalMode %s: CeedElemRestriction has %" CeedInt_FMT " components", field_name, size, 671203703bSJeremy L Thompson CeedEvalModes[eval_mode], rstr_num_comp); 68e15f9bd0SJeremy L Thompson break; 69e15f9bd0SJeremy L Thompson case CEED_EVAL_INTERP: 70c4e3f59bSSebastian Grimberg case CEED_EVAL_GRAD: 71c4e3f59bSSebastian Grimberg case CEED_EVAL_DIV: 72c4e3f59bSSebastian Grimberg case CEED_EVAL_CURL: 736574a04fSJeremy L Thompson CeedCheck(size == num_comp * q_comp, ceed, CEED_ERROR_DIMENSION, 741203703bSJeremy L Thompson "Field '%s' of size %" CeedInt_FMT " and EvalMode %s: CeedElemRestriction/Basis has %" CeedInt_FMT " components", field_name, size, 751203703bSJeremy L Thompson CeedEvalModes[eval_mode], num_comp * q_comp); 76e15f9bd0SJeremy L Thompson break; 77e15f9bd0SJeremy L Thompson case CEED_EVAL_WEIGHT: 78d1d35e2fSjeremylt // No additional checks required 79e15f9bd0SJeremy L Thompson break; 80e15f9bd0SJeremy L Thompson } 81e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 827a982d89SJeremy L. Thompson } 837a982d89SJeremy L. Thompson 847a982d89SJeremy L. Thompson /** 85ca94c3ddSJeremy L Thompson @brief View a field of a `CeedOperator` 867a982d89SJeremy L. Thompson 871203703bSJeremy L Thompson @param[in] op_field `CeedOperator` Field to view 88ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunction` Field (carries field name) 89d1d35e2fSjeremylt @param[in] field_number Number of field being viewed 905a526491SJeremy L Thompson @param[in] tabs Tabs to append before each line 91b7fd8817SJeremy L Thompson @param[in] is_input `true` for an input field; `false` for output field 92ca94c3ddSJeremy L Thompson @param[in] stream Stream to view to, e.g., `stdout` 937a982d89SJeremy L. Thompson 947a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 957a982d89SJeremy L. Thompson 967a982d89SJeremy L. Thompson @ref Utility 977a982d89SJeremy L. Thompson **/ 98b7fd8817SJeremy L Thompson static int CeedOperatorFieldView(CeedOperatorField op_field, CeedQFunctionField qf_field, CeedInt field_number, const char *tabs, bool is_input, 995a526491SJeremy L Thompson FILE *stream) { 100b7fd8817SJeremy L Thompson const char *field_type = is_input ? "Input" : "Output"; 1016f8994e9SJeremy L Thompson const char *field_name; 1021203703bSJeremy L Thompson CeedInt size; 1031203703bSJeremy L Thompson CeedEvalMode eval_mode; 1041203703bSJeremy L Thompson CeedVector vec; 1051203703bSJeremy L Thompson CeedBasis basis; 1061203703bSJeremy L Thompson 1071203703bSJeremy L Thompson // Field data 108ab747706SJeremy L Thompson CeedCall(CeedQFunctionFieldGetData(qf_field, &field_name, &size, &eval_mode)); 109ab747706SJeremy L Thompson CeedCall(CeedOperatorFieldGetData(op_field, NULL, NULL, &basis, &vec)); 1107a982d89SJeremy L. Thompson 1112b730f8bSJeremy L Thompson fprintf(stream, 1122b730f8bSJeremy L Thompson "%s %s field %" CeedInt_FMT 1132b730f8bSJeremy L Thompson ":\n" 1147a982d89SJeremy L. Thompson "%s Name: \"%s\"\n", 115b7fd8817SJeremy L Thompson tabs, field_type, field_number, tabs, field_name); 1165a526491SJeremy L Thompson fprintf(stream, "%s Size: %" CeedInt_FMT "\n", tabs, size); 1175a526491SJeremy L Thompson fprintf(stream, "%s EvalMode: %s\n", tabs, CeedEvalModes[eval_mode]); 1185a526491SJeremy L Thompson if (basis == CEED_BASIS_NONE) fprintf(stream, "%s No basis\n", tabs); 1195a526491SJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) fprintf(stream, "%s Active vector\n", tabs); 1205a526491SJeremy L Thompson else if (vec == CEED_VECTOR_NONE) fprintf(stream, "%s No vector\n", tabs); 121681d0ea7SJeremy L Thompson 122681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 123681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 124e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1257a982d89SJeremy L. Thompson } 1267a982d89SJeremy L. Thompson 1277a982d89SJeremy L. Thompson /** 128ca94c3ddSJeremy L Thompson @brief View a single `CeedOperator` 1297a982d89SJeremy L. Thompson 130ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to view 1315a526491SJeremy L Thompson @param[in] tabs Tabs to append before each new line 132ca94c3ddSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 1337a982d89SJeremy L. Thompson 1347a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 1357a982d89SJeremy L. Thompson 1367a982d89SJeremy L. Thompson @ref Utility 1377a982d89SJeremy L. Thompson **/ 1385a526491SJeremy L Thompson int CeedOperatorSingleView(CeedOperator op, const char *tabs, FILE *stream) { 13999f7f61fSJeremy L Thompson bool is_at_points; 1401203703bSJeremy L Thompson CeedInt num_elem, num_qpts, total_fields = 0, num_input_fields, num_output_fields; 1411203703bSJeremy L Thompson CeedQFunction qf; 1421203703bSJeremy L Thompson CeedQFunctionField *qf_input_fields, *qf_output_fields; 1431203703bSJeremy L Thompson CeedOperatorField *op_input_fields, *op_output_fields; 1447a982d89SJeremy L. Thompson 14599f7f61fSJeremy L Thompson CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 1462b730f8bSJeremy L Thompson CeedCall(CeedOperatorGetNumElements(op, &num_elem)); 1472b730f8bSJeremy L Thompson CeedCall(CeedOperatorGetNumQuadraturePoints(op, &num_qpts)); 1482b730f8bSJeremy L Thompson CeedCall(CeedOperatorGetNumArgs(op, &total_fields)); 1491203703bSJeremy L Thompson CeedCall(CeedOperatorGetFields(op, &num_input_fields, &op_input_fields, &num_output_fields, &op_output_fields)); 1501203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 1511203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFields(qf, NULL, &qf_input_fields, NULL, &qf_output_fields)); 152c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 1531c66c397SJeremy L Thompson 15499f7f61fSJeremy L Thompson if (is_at_points) { 15599f7f61fSJeremy L Thompson CeedInt max_points = 0; 15699f7f61fSJeremy L Thompson CeedElemRestriction rstr_points; 15799f7f61fSJeremy L Thompson 15899f7f61fSJeremy L Thompson CeedCall(CeedOperatorAtPointsGetPoints(op, &rstr_points, NULL)); 15999f7f61fSJeremy L Thompson CeedCall(CeedElemRestrictionGetMaxPointsInElement(rstr_points, &max_points)); 1605a526491SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " elements with %" CeedInt_FMT " max points each\n", tabs, num_elem, max_points); 16199f7f61fSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr_points)); 16299f7f61fSJeremy L Thompson } else { 1635a526491SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " elements with %" CeedInt_FMT " quadrature points each\n", tabs, num_elem, num_qpts); 16499f7f61fSJeremy L Thompson } 1655a526491SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " field%s\n", tabs, total_fields, total_fields > 1 ? "s" : ""); 1665a526491SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " input field%s:\n", tabs, num_input_fields, num_input_fields > 1 ? "s" : ""); 1671203703bSJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 1685a526491SJeremy L Thompson CeedCall(CeedOperatorFieldView(op_input_fields[i], qf_input_fields[i], i, tabs, 1, stream)); 1697a982d89SJeremy L. Thompson } 1705a526491SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " output field%s:\n", tabs, num_output_fields, num_output_fields > 1 ? "s" : ""); 1711203703bSJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 1725a526491SJeremy L Thompson CeedCall(CeedOperatorFieldView(op_output_fields[i], qf_output_fields[i], i, tabs, 0, stream)); 1737a982d89SJeremy L. Thompson } 174e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1757a982d89SJeremy L. Thompson } 1767a982d89SJeremy L. Thompson 177d99fa3c5SJeremy L Thompson /** 178b0f67a9cSJeremy L Thompson @brief View a `CeedOperator` passed as a `CeedObject` 179b0f67a9cSJeremy L Thompson 180b0f67a9cSJeremy L Thompson @param[in] op `CeedOperator` to view 181b0f67a9cSJeremy L Thompson @param[in] stream Filestream to write to 182b0f67a9cSJeremy L Thompson 183b0f67a9cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 184b0f67a9cSJeremy L Thompson 185b0f67a9cSJeremy L Thompson @ref Developer 186b0f67a9cSJeremy L Thompson **/ 187b0f67a9cSJeremy L Thompson static int CeedOperatorView_Object(CeedObject op, FILE *stream) { 188b0f67a9cSJeremy L Thompson CeedCall(CeedOperatorView((CeedOperator)op, stream)); 189b0f67a9cSJeremy L Thompson return CEED_ERROR_SUCCESS; 190b0f67a9cSJeremy L Thompson } 191b0f67a9cSJeremy L Thompson 192b0f67a9cSJeremy L Thompson /** 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) { 726b0f67a9cSJeremy L Thompson CeedCall(CeedObjectReference((CeedObject)op)); 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)); 781b0f67a9cSJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedOperatorView_Object, &(*op)->obj)); 7822b104005SJeremy L Thompson (*op)->input_size = -1; 7832b104005SJeremy L Thompson (*op)->output_size = -1; 784db002c03SJeremy L Thompson CeedCall(CeedQFunctionReferenceCopy(qf, &(*op)->qf)); 785db002c03SJeremy L Thompson if (dqf && dqf != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionReferenceCopy(dqf, &(*op)->dqf)); 786db002c03SJeremy L Thompson if (dqfT && dqfT != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionReferenceCopy(dqfT, &(*op)->dqfT)); 7872b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*op)->input_fields)); 7882b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*op)->output_fields)); 7892b730f8bSJeremy L Thompson CeedCall(ceed->OperatorCreate(*op)); 790e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 791d7b241e6Sjeremylt } 792d7b241e6Sjeremylt 793d7b241e6Sjeremylt /** 794ca94c3ddSJeremy L Thompson @brief Create a `CeedOperator` for evaluation at evaluation at arbitrary points in each element. 79548acf710SJeremy L Thompson 796ca94c3ddSJeremy L Thompson A `CeedBasis` and `CeedElemRestriction` can be associated with `CeedQFunction` fields with `CeedOperator` SetField. 797ca94c3ddSJeremy L Thompson The locations of each point are set with @ref CeedOperatorAtPointsSetPoints(). 79848acf710SJeremy L Thompson 799ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedOperator` 800ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` defining the action of the operator at quadrature points 801ca94c3ddSJeremy L Thompson @param[in] dqf `CeedQFunction` defining the action of the Jacobian of @a qf (or @ref CEED_QFUNCTION_NONE) 802ca94c3ddSJeremy L Thompson @param[in] dqfT `CeedQFunction` defining the action of the transpose of the Jacobian of @a qf (or @ref CEED_QFUNCTION_NONE) 80348acf710SJeremy L Thompson @param[out] op Address of the variable where the newly created CeedOperator will be stored 80448acf710SJeremy L Thompson 80548acf710SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 80648acf710SJeremy L Thompson 80748acf710SJeremy L Thompson @ref User 80848acf710SJeremy L Thompson */ 80948acf710SJeremy L Thompson int CeedOperatorCreateAtPoints(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, CeedQFunction dqfT, CeedOperator *op) { 81048acf710SJeremy L Thompson if (!ceed->OperatorCreateAtPoints) { 81148acf710SJeremy L Thompson Ceed delegate; 81248acf710SJeremy L Thompson 81348acf710SJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Operator")); 8141ef3a2a9SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedOperatorCreateAtPoints"); 81548acf710SJeremy L Thompson CeedCall(CeedOperatorCreateAtPoints(delegate, qf, dqf, dqfT, op)); 8169bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 81748acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 81848acf710SJeremy L Thompson } 81948acf710SJeremy L Thompson 820ca94c3ddSJeremy L Thompson CeedCheck(qf && qf != CEED_QFUNCTION_NONE, ceed, CEED_ERROR_MINOR, "Operator must have a valid CeedQFunction."); 82148acf710SJeremy L Thompson 82248acf710SJeremy L Thompson CeedCall(CeedCalloc(1, op)); 823b0f67a9cSJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedOperatorView_Object, &(*op)->obj)); 82448acf710SJeremy L Thompson (*op)->is_at_points = true; 82548acf710SJeremy L Thompson (*op)->input_size = -1; 82648acf710SJeremy L Thompson (*op)->output_size = -1; 82748acf710SJeremy L Thompson CeedCall(CeedQFunctionReferenceCopy(qf, &(*op)->qf)); 82848acf710SJeremy L Thompson if (dqf && dqf != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionReferenceCopy(dqf, &(*op)->dqf)); 82948acf710SJeremy L Thompson if (dqfT && dqfT != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionReferenceCopy(dqfT, &(*op)->dqfT)); 83048acf710SJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*op)->input_fields)); 83148acf710SJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*op)->output_fields)); 83248acf710SJeremy L Thompson CeedCall(ceed->OperatorCreateAtPoints(*op)); 83348acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 83448acf710SJeremy L Thompson } 83548acf710SJeremy L Thompson 83648acf710SJeremy L Thompson /** 837ca94c3ddSJeremy L Thompson @brief Create a composite `CeedOperator` that composes the action of several `CeedOperator` 83852d6035fSJeremy L Thompson 839ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedOperator` 840ca94c3ddSJeremy L Thompson @param[out] op Address of the variable where the newly created composite `CeedOperator` will be stored 84152d6035fSJeremy L Thompson 84252d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 84352d6035fSJeremy L Thompson 8447a982d89SJeremy L. Thompson @ref User 84552d6035fSJeremy L Thompson */ 846ed094490SJeremy L Thompson int CeedOperatorCreateComposite(Ceed ceed, CeedOperator *op) { 84752d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 84852d6035fSJeremy L Thompson Ceed delegate; 84952d6035fSJeremy L Thompson 8501c66c397SJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Operator")); 851250756a7Sjeremylt if (delegate) { 852ed094490SJeremy L Thompson CeedCall(CeedOperatorCreateComposite(delegate, op)); 8539bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 854e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 85552d6035fSJeremy L Thompson } 856250756a7Sjeremylt } 85752d6035fSJeremy L Thompson 8582b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, op)); 859b0f67a9cSJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedOperatorView_Object, &(*op)->obj)); 860f04ea552SJeremy L Thompson (*op)->is_composite = true; 8612b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_COMPOSITE_MAX, &(*op)->sub_operators)); 8622b104005SJeremy L Thompson (*op)->input_size = -1; 8632b104005SJeremy L Thompson (*op)->output_size = -1; 864250756a7Sjeremylt 865db002c03SJeremy L Thompson if (ceed->CompositeOperatorCreate) CeedCall(ceed->CompositeOperatorCreate(*op)); 866e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 86752d6035fSJeremy L Thompson } 86852d6035fSJeremy L Thompson 86952d6035fSJeremy L Thompson /** 870ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedOperator`. 8714385fb7fSSebastian Grimberg 872ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedOperatorDestroy(). 873512bb800SJeremy L Thompson 874ca94c3ddSJeremy 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`. 875ca94c3ddSJeremy L Thompson This `CeedOperator` will be destroyed if `*op_copy` is the only reference to this `CeedOperator`. 8769560d06aSjeremylt 877ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to copy reference to 878ea61e9acSJeremy L Thompson @param[in,out] op_copy Variable to store copied reference 8799560d06aSjeremylt 8809560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 8819560d06aSjeremylt 8829560d06aSjeremylt @ref User 8839560d06aSjeremylt **/ 8849560d06aSjeremylt int CeedOperatorReferenceCopy(CeedOperator op, CeedOperator *op_copy) { 8852b730f8bSJeremy L Thompson CeedCall(CeedOperatorReference(op)); 8862b730f8bSJeremy L Thompson CeedCall(CeedOperatorDestroy(op_copy)); 8879560d06aSjeremylt *op_copy = op; 8889560d06aSjeremylt return CEED_ERROR_SUCCESS; 8899560d06aSjeremylt } 8909560d06aSjeremylt 8919560d06aSjeremylt /** 892ca94c3ddSJeremy L Thompson @brief Provide a field to a `CeedOperator` for use by its `CeedQFunction`. 893d7b241e6Sjeremylt 894ca94c3ddSJeremy L Thompson This function is used to specify both active and passive fields to a `CeedOperator`. 895bafebce1SSebastian Grimberg For passive fields, a `CeedVector` `vec` must be provided. 896ea61e9acSJeremy L Thompson Passive fields can inputs or outputs (updated in-place when operator is applied). 897d7b241e6Sjeremylt 898ca94c3ddSJeremy L Thompson Active fields must be specified using this function, but their data (in a `CeedVector`) is passed in @ref CeedOperatorApply(). 899ca94c3ddSJeremy L Thompson There can be at most one active input `CeedVector` and at most one active output@ref CeedVector passed to @ref CeedOperatorApply(). 900d7b241e6Sjeremylt 901528a22edSJeremy L Thompson The number of quadrature points must agree across all points. 902bafebce1SSebastian Grimberg When using @ref CEED_BASIS_NONE, the number of quadrature points is determined by the element size of `rstr`. 903528a22edSJeremy L Thompson 904ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` on which to provide the field 905ca94c3ddSJeremy L Thompson @param[in] field_name Name of the field (to be matched with the name used by `CeedQFunction`) 906bafebce1SSebastian Grimberg @param[in] rstr `CeedElemRestriction` 907bafebce1SSebastian Grimberg @param[in] basis `CeedBasis` in which the field resides or @ref CEED_BASIS_NONE if collocated with quadrature points 908bafebce1SSebastian 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` 909b11c1e72Sjeremylt 910b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 911dfdf5a53Sjeremylt 9127a982d89SJeremy L. Thompson @ref User 913b11c1e72Sjeremylt **/ 914bafebce1SSebastian Grimberg int CeedOperatorSetField(CeedOperator op, const char *field_name, CeedElemRestriction rstr, CeedBasis basis, CeedVector vec) { 9151203703bSJeremy L Thompson bool is_input = true, is_at_points, is_composite, is_immutable; 9161203703bSJeremy L Thompson CeedInt num_elem = 0, num_qpts = 0, num_input_fields, num_output_fields; 9171203703bSJeremy L Thompson CeedQFunction qf; 9181203703bSJeremy L Thompson CeedQFunctionField qf_field, *qf_input_fields, *qf_output_fields; 9191c66c397SJeremy L Thompson CeedOperatorField *op_field; 9201c66c397SJeremy L Thompson 9211203703bSJeremy L Thompson CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 9221203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 9231203703bSJeremy L Thompson CeedCall(CeedOperatorIsImmutable(op, &is_immutable)); 9249bc66399SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "Cannot add field to composite operator."); 9259bc66399SJeremy L Thompson CeedCheck(!is_immutable, CeedOperatorReturnCeed(op), CEED_ERROR_MAJOR, "Operator cannot be changed after set as immutable"); 9269bc66399SJeremy L Thompson CeedCheck(rstr, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "CeedElemRestriction rstr for field \"%s\" must be non-NULL.", field_name); 9279bc66399SJeremy L Thompson CeedCheck(basis, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "CeedBasis basis for field \"%s\" must be non-NULL.", field_name); 9289bc66399SJeremy L Thompson CeedCheck(vec, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "CeedVector vec for field \"%s\" must be non-NULL.", field_name); 92952d6035fSJeremy L Thompson 930bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 9319bc66399SJeremy L Thompson CeedCheck(rstr == CEED_ELEMRESTRICTION_NONE || !op->has_restriction || num_elem == op->num_elem, CeedOperatorReturnCeed(op), CEED_ERROR_DIMENSION, 932ca94c3ddSJeremy L Thompson "CeedElemRestriction with %" CeedInt_FMT " elements incompatible with prior %" CeedInt_FMT " elements", num_elem, op->num_elem); 9332c7e7413SJeremy L Thompson { 9342c7e7413SJeremy L Thompson CeedRestrictionType rstr_type; 9352c7e7413SJeremy L Thompson 936bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 93748acf710SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) { 9389bc66399SJeremy L Thompson CeedCheck(is_at_points, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, 9399bc66399SJeremy L Thompson "CeedElemRestriction AtPoints not supported for standard operator fields"); 9409bc66399SJeremy L Thompson CeedCheck(basis == CEED_BASIS_NONE, CeedOperatorReturnCeed(op), CEED_ERROR_UNSUPPORTED, 9419bc66399SJeremy L Thompson "CeedElemRestriction AtPoints must be used with CEED_BASIS_NONE"); 94248acf710SJeremy L Thompson if (!op->first_points_rstr) { 943bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &op->first_points_rstr)); 94448acf710SJeremy L Thompson } else { 94548acf710SJeremy L Thompson bool are_compatible; 94648acf710SJeremy L Thompson 947bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionAtPointsAreCompatible(op->first_points_rstr, rstr, &are_compatible)); 9489bc66399SJeremy L Thompson CeedCheck(are_compatible, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 949ca94c3ddSJeremy L Thompson "CeedElemRestriction must have compatible offsets with previously set CeedElemRestriction"); 95048acf710SJeremy L Thompson } 95148acf710SJeremy L Thompson } 9522c7e7413SJeremy L Thompson } 953d7b241e6Sjeremylt 954bafebce1SSebastian Grimberg if (basis == CEED_BASIS_NONE) CeedCall(CeedElemRestrictionGetElementSize(rstr, &num_qpts)); 955bafebce1SSebastian Grimberg else CeedCall(CeedBasisGetNumQuadraturePoints(basis, &num_qpts)); 9569bc66399SJeremy L Thompson CeedCheck(op->num_qpts == 0 || num_qpts == op->num_qpts, CeedOperatorReturnCeed(op), CEED_ERROR_DIMENSION, 957ca94c3ddSJeremy L Thompson "%s must correspond to the same number of quadrature points as previously added CeedBases. Found %" CeedInt_FMT 958528a22edSJeremy L Thompson " quadrature points but expected %" CeedInt_FMT " quadrature points.", 959bafebce1SSebastian Grimberg basis == CEED_BASIS_NONE ? "CeedElemRestriction" : "CeedBasis", num_qpts, op->num_qpts); 9601203703bSJeremy L Thompson 9611203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 9621203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFields(qf, &num_input_fields, &qf_input_fields, &num_output_fields, &qf_output_fields)); 963c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 9641203703bSJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 9656f8994e9SJeremy L Thompson const char *qf_field_name; 9661203703bSJeremy L Thompson 9671203703bSJeremy L Thompson CeedCall(CeedQFunctionFieldGetName(qf_input_fields[i], &qf_field_name)); 9681203703bSJeremy L Thompson if (!strcmp(field_name, qf_field_name)) { 9691203703bSJeremy L Thompson qf_field = qf_input_fields[i]; 970d1d35e2fSjeremylt op_field = &op->input_fields[i]; 971d7b241e6Sjeremylt goto found; 972d7b241e6Sjeremylt } 973d7b241e6Sjeremylt } 9742b104005SJeremy L Thompson is_input = false; 9751203703bSJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 9766f8994e9SJeremy L Thompson const char *qf_field_name; 9771203703bSJeremy L Thompson 9781203703bSJeremy L Thompson CeedCall(CeedQFunctionFieldGetName(qf_output_fields[i], &qf_field_name)); 9791203703bSJeremy L Thompson if (!strcmp(field_name, qf_field_name)) { 9801203703bSJeremy L Thompson qf_field = qf_output_fields[i]; 981d1d35e2fSjeremylt op_field = &op->output_fields[i]; 982d7b241e6Sjeremylt goto found; 983d7b241e6Sjeremylt } 984d7b241e6Sjeremylt } 985c042f62fSJeremy L Thompson // LCOV_EXCL_START 9869bc66399SJeremy L Thompson return CeedError(CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "CeedQFunction has no knowledge of field '%s'", field_name); 987c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 988d7b241e6Sjeremylt found: 9899bc66399SJeremy L Thompson CeedCall(CeedOperatorCheckField(CeedOperatorReturnCeed(op), qf_field, rstr, basis)); 9902b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, op_field)); 991e15f9bd0SJeremy L Thompson 992bafebce1SSebastian Grimberg if (vec == CEED_VECTOR_ACTIVE) { 9932b104005SJeremy L Thompson CeedSize l_size; 9941c66c397SJeremy L Thompson 995bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &l_size)); 9962b104005SJeremy L Thompson if (is_input) { 9972b104005SJeremy L Thompson if (op->input_size == -1) op->input_size = l_size; 9989bc66399SJeremy L Thompson CeedCheck(l_size == op->input_size, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 999249f8407SJeremy L Thompson "LVector size %" CeedSize_FMT " does not match previous size %" CeedSize_FMT "", l_size, op->input_size); 10002b104005SJeremy L Thompson } else { 10012b104005SJeremy L Thompson if (op->output_size == -1) op->output_size = l_size; 10029bc66399SJeremy L Thompson CeedCheck(l_size == op->output_size, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 1003249f8407SJeremy L Thompson "LVector size %" CeedSize_FMT " does not match previous size %" CeedSize_FMT "", l_size, op->output_size); 10042b104005SJeremy L Thompson } 10052b730f8bSJeremy L Thompson } 10062b104005SJeremy L Thompson 1007bafebce1SSebastian Grimberg CeedCall(CeedVectorReferenceCopy(vec, &(*op_field)->vec)); 1008bafebce1SSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*op_field)->elem_rstr)); 1009bafebce1SSebastian Grimberg if (rstr != CEED_ELEMRESTRICTION_NONE && !op->has_restriction) { 1010d1d35e2fSjeremylt op->num_elem = num_elem; 1011d1d35e2fSjeremylt op->has_restriction = true; // Restriction set, but num_elem may be 0 1012e15f9bd0SJeremy L Thompson } 1013bafebce1SSebastian Grimberg CeedCall(CeedBasisReferenceCopy(basis, &(*op_field)->basis)); 10142a3ff1c9SZach Atkins if (op->num_qpts == 0 && !is_at_points) op->num_qpts = num_qpts; // no consistent number of qpts for OperatorAtPoints 1015d1d35e2fSjeremylt op->num_fields += 1; 10162b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(field_name, (char **)&(*op_field)->field_name)); 1017e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1018d7b241e6Sjeremylt } 1019d7b241e6Sjeremylt 1020d7b241e6Sjeremylt /** 1021ca94c3ddSJeremy L Thompson @brief Get the `CeedOperator` Field of a `CeedOperator`. 102243bbe138SJeremy L Thompson 1023ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 1024f04ea552SJeremy L Thompson 1025ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1026f74ec584SJeremy L Thompson @param[out] num_input_fields Variable to store number of input fields 1027ca94c3ddSJeremy L Thompson @param[out] input_fields Variable to store input fields 1028f74ec584SJeremy L Thompson @param[out] num_output_fields Variable to store number of output fields 1029ca94c3ddSJeremy L Thompson @param[out] output_fields Variable to store output fields 103043bbe138SJeremy L Thompson 103143bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 103243bbe138SJeremy L Thompson 1033e9b533fbSJeremy L Thompson @ref Advanced 103443bbe138SJeremy L Thompson **/ 10352b730f8bSJeremy L Thompson int CeedOperatorGetFields(CeedOperator op, CeedInt *num_input_fields, CeedOperatorField **input_fields, CeedInt *num_output_fields, 103643bbe138SJeremy L Thompson CeedOperatorField **output_fields) { 10371203703bSJeremy L Thompson bool is_composite; 10381203703bSJeremy L Thompson CeedQFunction qf; 10391203703bSJeremy L Thompson 10401203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 10416e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Not defined for composite operator"); 10422b730f8bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 104343bbe138SJeremy L Thompson 10441203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 10451203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFields(qf, num_input_fields, NULL, num_output_fields, NULL)); 1046c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 104743bbe138SJeremy L Thompson if (input_fields) *input_fields = op->input_fields; 104843bbe138SJeremy L Thompson if (output_fields) *output_fields = op->output_fields; 104943bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 105043bbe138SJeremy L Thompson } 105143bbe138SJeremy L Thompson 105243bbe138SJeremy L Thompson /** 1053ca94c3ddSJeremy L Thompson @brief Set the arbitrary points in each element for a `CeedOperator` at points. 105448acf710SJeremy L Thompson 1055ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 105648acf710SJeremy L Thompson 1057ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` at points 1058ca94c3ddSJeremy L Thompson @param[in] rstr_points `CeedElemRestriction` for the coordinates of each point by element 1059ca94c3ddSJeremy L Thompson @param[in] point_coords `CeedVector` holding coordinates of each point 106048acf710SJeremy L Thompson 106148acf710SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 106248acf710SJeremy L Thompson 106348acf710SJeremy L Thompson @ref Advanced 106448acf710SJeremy L Thompson **/ 106548acf710SJeremy L Thompson int CeedOperatorAtPointsSetPoints(CeedOperator op, CeedElemRestriction rstr_points, CeedVector point_coords) { 10661203703bSJeremy L Thompson bool is_at_points, is_immutable; 10672a3ff1c9SZach Atkins 10682a3ff1c9SZach Atkins CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 10691203703bSJeremy L Thompson CeedCall(CeedOperatorIsImmutable(op, &is_immutable)); 10709bc66399SJeremy L Thompson CeedCheck(is_at_points, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for operator at points"); 10719bc66399SJeremy L Thompson CeedCheck(!is_immutable, CeedOperatorReturnCeed(op), CEED_ERROR_MAJOR, "Operator cannot be changed after set as immutable"); 107248acf710SJeremy L Thompson 107348acf710SJeremy L Thompson if (!op->first_points_rstr) { 107448acf710SJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(rstr_points, &op->first_points_rstr)); 107548acf710SJeremy L Thompson } else { 107648acf710SJeremy L Thompson bool are_compatible; 107748acf710SJeremy L Thompson 107848acf710SJeremy L Thompson CeedCall(CeedElemRestrictionAtPointsAreCompatible(op->first_points_rstr, rstr_points, &are_compatible)); 10799bc66399SJeremy L Thompson CeedCheck(are_compatible, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 1080ca94c3ddSJeremy L Thompson "CeedElemRestriction must have compatible offsets with previously set field CeedElemRestriction"); 108148acf710SJeremy L Thompson } 108248acf710SJeremy L Thompson 108348acf710SJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(rstr_points, &op->rstr_points)); 108448acf710SJeremy L Thompson CeedCall(CeedVectorReferenceCopy(point_coords, &op->point_coords)); 108548acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 108648acf710SJeremy L Thompson } 108748acf710SJeremy L Thompson 108848acf710SJeremy L Thompson /** 1089b594f9faSZach Atkins @brief Get a boolean value indicating if the `CeedOperator` was created with `CeedOperatorCreateAtPoints` 1090b594f9faSZach Atkins 1091b594f9faSZach Atkins @param[in] op `CeedOperator` 1092b594f9faSZach Atkins @param[out] is_at_points Variable to store at points status 1093b594f9faSZach Atkins 1094b594f9faSZach Atkins @return An error code: 0 - success, otherwise - failure 1095b594f9faSZach Atkins 1096b594f9faSZach Atkins @ref User 1097b594f9faSZach Atkins **/ 1098b594f9faSZach Atkins int CeedOperatorIsAtPoints(CeedOperator op, bool *is_at_points) { 1099b594f9faSZach Atkins *is_at_points = op->is_at_points; 1100b594f9faSZach Atkins return CEED_ERROR_SUCCESS; 1101b594f9faSZach Atkins } 1102b594f9faSZach Atkins 1103b594f9faSZach Atkins /** 1104ca94c3ddSJeremy L Thompson @brief Get the arbitrary points in each element for a `CeedOperator` at points. 110548acf710SJeremy L Thompson 1106ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 110748acf710SJeremy L Thompson 1108ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` at points 1109ca94c3ddSJeremy L Thompson @param[out] rstr_points Variable to hold `CeedElemRestriction` for the coordinates of each point by element 1110ca94c3ddSJeremy L Thompson @param[out] point_coords Variable to hold `CeedVector` holding coordinates of each point 111148acf710SJeremy L Thompson 111248acf710SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 111348acf710SJeremy L Thompson 111448acf710SJeremy L Thompson @ref Advanced 111548acf710SJeremy L Thompson **/ 111648acf710SJeremy L Thompson int CeedOperatorAtPointsGetPoints(CeedOperator op, CeedElemRestriction *rstr_points, CeedVector *point_coords) { 11172a3ff1c9SZach Atkins bool is_at_points; 11182a3ff1c9SZach Atkins 11192a3ff1c9SZach Atkins CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 11206e536b99SJeremy L Thompson CeedCheck(is_at_points, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for operator at points"); 112148acf710SJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 112248acf710SJeremy L Thompson 11233f919cbcSJeremy L Thompson if (rstr_points) { 11243f919cbcSJeremy L Thompson *rstr_points = NULL; 11253f919cbcSJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(op->rstr_points, rstr_points)); 11263f919cbcSJeremy L Thompson } 11273f919cbcSJeremy L Thompson if (point_coords) { 11283f919cbcSJeremy L Thompson *point_coords = NULL; 11293f919cbcSJeremy L Thompson CeedCall(CeedVectorReferenceCopy(op->point_coords, point_coords)); 11303f919cbcSJeremy L Thompson } 113148acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 113248acf710SJeremy L Thompson } 113348acf710SJeremy L Thompson 113448acf710SJeremy L Thompson /** 1135be9c6463SJeremy L Thompson @brief Get a `CeedOperator` Field of a `CeedOperator` from its name. 1136be9c6463SJeremy L Thompson 1137be9c6463SJeremy L Thompson `op_field` is set to `NULL` if the field is not found. 1138de5900adSJames Wright 1139ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 1140de5900adSJames Wright 1141ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1142ca94c3ddSJeremy L Thompson @param[in] field_name Name of desired `CeedOperator` Field 1143ca94c3ddSJeremy L Thompson @param[out] op_field `CeedOperator` Field corresponding to the name 1144de5900adSJames Wright 1145de5900adSJames Wright @return An error code: 0 - success, otherwise - failure 1146de5900adSJames Wright 1147de5900adSJames Wright @ref Advanced 1148de5900adSJames Wright **/ 1149de5900adSJames Wright int CeedOperatorGetFieldByName(CeedOperator op, const char *field_name, CeedOperatorField *op_field) { 11506f8994e9SJeremy L Thompson const char *name; 1151de5900adSJames Wright CeedInt num_input_fields, num_output_fields; 1152de5900adSJames Wright CeedOperatorField *input_fields, *output_fields; 1153de5900adSJames Wright 1154be9c6463SJeremy L Thompson *op_field = NULL; 11551c66c397SJeremy L Thompson CeedCall(CeedOperatorGetFields(op, &num_input_fields, &input_fields, &num_output_fields, &output_fields)); 1156de5900adSJames Wright for (CeedInt i = 0; i < num_input_fields; i++) { 1157de5900adSJames Wright CeedCall(CeedOperatorFieldGetName(input_fields[i], &name)); 1158de5900adSJames Wright if (!strcmp(name, field_name)) { 1159de5900adSJames Wright *op_field = input_fields[i]; 1160de5900adSJames Wright return CEED_ERROR_SUCCESS; 1161de5900adSJames Wright } 1162de5900adSJames Wright } 1163de5900adSJames Wright for (CeedInt i = 0; i < num_output_fields; i++) { 1164de5900adSJames Wright CeedCall(CeedOperatorFieldGetName(output_fields[i], &name)); 1165de5900adSJames Wright if (!strcmp(name, field_name)) { 1166de5900adSJames Wright *op_field = output_fields[i]; 1167de5900adSJames Wright return CEED_ERROR_SUCCESS; 1168de5900adSJames Wright } 1169de5900adSJames Wright } 1170be9c6463SJeremy L Thompson return CEED_ERROR_SUCCESS; 1171de5900adSJames Wright } 1172de5900adSJames Wright 1173de5900adSJames Wright /** 1174ca94c3ddSJeremy L Thompson @brief Get the name of a `CeedOperator` Field 117528567f8fSJeremy L Thompson 1176ca94c3ddSJeremy L Thompson @param[in] op_field `CeedOperator` Field 117728567f8fSJeremy L Thompson @param[out] field_name Variable to store the field name 117828567f8fSJeremy L Thompson 117928567f8fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 118028567f8fSJeremy L Thompson 1181e9b533fbSJeremy L Thompson @ref Advanced 118228567f8fSJeremy L Thompson **/ 11836f8994e9SJeremy L Thompson int CeedOperatorFieldGetName(CeedOperatorField op_field, const char **field_name) { 11846f8994e9SJeremy L Thompson *field_name = op_field->field_name; 118528567f8fSJeremy L Thompson return CEED_ERROR_SUCCESS; 118628567f8fSJeremy L Thompson } 118728567f8fSJeremy L Thompson 118828567f8fSJeremy L Thompson /** 1189681d0ea7SJeremy L Thompson @brief Get the `CeedElemRestriction` of a `CeedOperator` Field. 1190681d0ea7SJeremy L Thompson 1191681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `rstr` with @ref CeedElemRestrictionDestroy(). 119243bbe138SJeremy L Thompson 1193ca94c3ddSJeremy L Thompson @param[in] op_field `CeedOperator` Field 1194ca94c3ddSJeremy L Thompson @param[out] rstr Variable to store `CeedElemRestriction` 119543bbe138SJeremy L Thompson 119643bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 119743bbe138SJeremy L Thompson 1198e9b533fbSJeremy L Thompson @ref Advanced 119943bbe138SJeremy L Thompson **/ 12002b730f8bSJeremy L Thompson int CeedOperatorFieldGetElemRestriction(CeedOperatorField op_field, CeedElemRestriction *rstr) { 1201681d0ea7SJeremy L Thompson *rstr = NULL; 1202681d0ea7SJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(op_field->elem_rstr, rstr)); 120343bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 120443bbe138SJeremy L Thompson } 120543bbe138SJeremy L Thompson 120643bbe138SJeremy L Thompson /** 1207681d0ea7SJeremy L Thompson @brief Get the `CeedBasis` of a `CeedOperator` Field. 1208681d0ea7SJeremy L Thompson 1209681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `basis` with @ref CeedBasisDestroy(). 121043bbe138SJeremy L Thompson 1211ca94c3ddSJeremy L Thompson @param[in] op_field `CeedOperator` Field 1212ca94c3ddSJeremy L Thompson @param[out] basis Variable to store `CeedBasis` 121343bbe138SJeremy L Thompson 121443bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 121543bbe138SJeremy L Thompson 1216e9b533fbSJeremy L Thompson @ref Advanced 121743bbe138SJeremy L Thompson **/ 121843bbe138SJeremy L Thompson int CeedOperatorFieldGetBasis(CeedOperatorField op_field, CeedBasis *basis) { 1219681d0ea7SJeremy L Thompson *basis = NULL; 1220681d0ea7SJeremy L Thompson CeedCall(CeedBasisReferenceCopy(op_field->basis, basis)); 122143bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 122243bbe138SJeremy L Thompson } 122343bbe138SJeremy L Thompson 122443bbe138SJeremy L Thompson /** 1225681d0ea7SJeremy L Thompson @brief Get the `CeedVector` of a `CeedOperator` Field. 1226681d0ea7SJeremy L Thompson 1227681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `vec` with @ref CeedVectorDestroy(). 122843bbe138SJeremy L Thompson 1229ca94c3ddSJeremy L Thompson @param[in] op_field `CeedOperator` Field 1230ca94c3ddSJeremy L Thompson @param[out] vec Variable to store `CeedVector` 123143bbe138SJeremy L Thompson 123243bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 123343bbe138SJeremy L Thompson 1234e9b533fbSJeremy L Thompson @ref Advanced 123543bbe138SJeremy L Thompson **/ 123643bbe138SJeremy L Thompson int CeedOperatorFieldGetVector(CeedOperatorField op_field, CeedVector *vec) { 1237681d0ea7SJeremy L Thompson *vec = NULL; 1238681d0ea7SJeremy L Thompson CeedCall(CeedVectorReferenceCopy(op_field->vec, vec)); 123943bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 124043bbe138SJeremy L Thompson } 124143bbe138SJeremy L Thompson 124243bbe138SJeremy L Thompson /** 1243ab747706SJeremy L Thompson @brief Get the data of a `CeedOperator` Field. 1244ab747706SJeremy L Thompson 1245681d0ea7SJeremy L Thompson Any arguments set as `NULL` are ignored.. 1246681d0ea7SJeremy L Thompson 1247681d0ea7SJeremy L Thompson Note: Caller is responsible for destroying the `rstr`, `basis`, and `vec`. 1248ab747706SJeremy L Thompson 1249ab747706SJeremy L Thompson @param[in] op_field `CeedOperator` Field 1250ab747706SJeremy L Thompson @param[out] field_name Variable to store the field name 1251ab747706SJeremy L Thompson @param[out] rstr Variable to store `CeedElemRestriction` 1252ab747706SJeremy L Thompson @param[out] basis Variable to store `CeedBasis` 1253ab747706SJeremy L Thompson @param[out] vec Variable to store `CeedVector` 1254ab747706SJeremy L Thompson 1255ab747706SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1256ab747706SJeremy L Thompson 1257ab747706SJeremy L Thompson @ref Advanced 1258ab747706SJeremy L Thompson **/ 12596f8994e9SJeremy L Thompson int CeedOperatorFieldGetData(CeedOperatorField op_field, const char **field_name, CeedElemRestriction *rstr, CeedBasis *basis, CeedVector *vec) { 1260ab747706SJeremy L Thompson if (field_name) CeedCall(CeedOperatorFieldGetName(op_field, field_name)); 1261ab747706SJeremy L Thompson if (rstr) CeedCall(CeedOperatorFieldGetElemRestriction(op_field, rstr)); 1262ab747706SJeremy L Thompson if (basis) CeedCall(CeedOperatorFieldGetBasis(op_field, basis)); 1263ab747706SJeremy L Thompson if (vec) CeedCall(CeedOperatorFieldGetVector(op_field, vec)); 1264ab747706SJeremy L Thompson return CEED_ERROR_SUCCESS; 1265ab747706SJeremy L Thompson } 1266ab747706SJeremy L Thompson 1267ab747706SJeremy L Thompson /** 1268ca94c3ddSJeremy L Thompson @brief Add a sub-operator to a composite `CeedOperator` 1269288c0443SJeremy L Thompson 1270ca94c3ddSJeremy L Thompson @param[in,out] composite_op Composite `CeedOperator` 1271ca94c3ddSJeremy L Thompson @param[in] sub_op Sub-operator `CeedOperator` 127252d6035fSJeremy L Thompson 127352d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 127452d6035fSJeremy L Thompson 12757a982d89SJeremy L. Thompson @ref User 127652d6035fSJeremy L Thompson */ 1277ed094490SJeremy L Thompson int CeedOperatorCompositeAddSub(CeedOperator composite_op, CeedOperator sub_op) { 12781203703bSJeremy L Thompson bool is_immutable; 12791203703bSJeremy L Thompson 12809bc66399SJeremy L Thompson CeedCheck(composite_op->is_composite, CeedOperatorReturnCeed(composite_op), CEED_ERROR_MINOR, "CeedOperator is not a composite operator"); 12819bc66399SJeremy L Thompson CeedCheck(composite_op->num_suboperators < CEED_COMPOSITE_MAX, CeedOperatorReturnCeed(composite_op), CEED_ERROR_UNSUPPORTED, 12829bc66399SJeremy L Thompson "Cannot add additional sub-operators"); 12831203703bSJeremy L Thompson CeedCall(CeedOperatorIsImmutable(composite_op, &is_immutable)); 12849bc66399SJeremy L Thompson CeedCheck(!is_immutable, CeedOperatorReturnCeed(composite_op), CEED_ERROR_MAJOR, "Operator cannot be changed after set as immutable"); 12852b730f8bSJeremy L Thompson 12862b730f8bSJeremy L Thompson { 12872b730f8bSJeremy L Thompson CeedSize input_size, output_size; 12881c66c397SJeremy L Thompson 12892b730f8bSJeremy L Thompson CeedCall(CeedOperatorGetActiveVectorLengths(sub_op, &input_size, &output_size)); 12902b730f8bSJeremy L Thompson if (composite_op->input_size == -1) composite_op->input_size = input_size; 12912b730f8bSJeremy L Thompson if (composite_op->output_size == -1) composite_op->output_size = output_size; 12922b730f8bSJeremy L Thompson // Note, a size of -1 means no active vector restriction set, so no incompatibility 12939bc66399SJeremy L Thompson CeedCheck((input_size == -1 || input_size == composite_op->input_size) && (output_size == -1 || output_size == composite_op->output_size), 12949bc66399SJeremy L Thompson CeedOperatorReturnCeed(composite_op), CEED_ERROR_MAJOR, 1295249f8407SJeremy L Thompson "Sub-operators must have compatible dimensions; composite operator of shape (%" CeedSize_FMT ", %" CeedSize_FMT 1296249f8407SJeremy L Thompson ") not compatible with sub-operator of " 1297249f8407SJeremy L Thompson "shape (%" CeedSize_FMT ", %" CeedSize_FMT ")", 12982b730f8bSJeremy L Thompson composite_op->input_size, composite_op->output_size, input_size, output_size); 12992b730f8bSJeremy L Thompson } 13002b730f8bSJeremy L Thompson 1301d1d35e2fSjeremylt composite_op->sub_operators[composite_op->num_suboperators] = sub_op; 13022b730f8bSJeremy L Thompson CeedCall(CeedOperatorReference(sub_op)); 1303d1d35e2fSjeremylt composite_op->num_suboperators++; 1304e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 130552d6035fSJeremy L Thompson } 130652d6035fSJeremy L Thompson 130752d6035fSJeremy L Thompson /** 1308ca94c3ddSJeremy L Thompson @brief Get the number of sub-operators associated with a `CeedOperator` 130975f0d5a4SJeremy L Thompson 1310ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1311ca94c3ddSJeremy L Thompson @param[out] num_suboperators Variable to store number of sub-operators 131275f0d5a4SJeremy L Thompson 131375f0d5a4SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 131475f0d5a4SJeremy L Thompson 131575f0d5a4SJeremy L Thompson @ref Backend 131675f0d5a4SJeremy L Thompson **/ 1317ed094490SJeremy L Thompson int CeedOperatorCompositeGetNumSub(CeedOperator op, CeedInt *num_suboperators) { 13181203703bSJeremy L Thompson bool is_composite; 13191203703bSJeremy L Thompson 13201203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 13216e536b99SJeremy L Thompson CeedCheck(is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for a composite operator"); 132275f0d5a4SJeremy L Thompson *num_suboperators = op->num_suboperators; 132375f0d5a4SJeremy L Thompson return CEED_ERROR_SUCCESS; 132475f0d5a4SJeremy L Thompson } 132575f0d5a4SJeremy L Thompson 132675f0d5a4SJeremy L Thompson /** 1327ca94c3ddSJeremy L Thompson @brief Get the list of sub-operators associated with a `CeedOperator` 132875f0d5a4SJeremy L Thompson 1329ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1330ca94c3ddSJeremy L Thompson @param[out] sub_operators Variable to store list of sub-operators 133175f0d5a4SJeremy L Thompson 133275f0d5a4SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 133375f0d5a4SJeremy L Thompson 133475f0d5a4SJeremy L Thompson @ref Backend 133575f0d5a4SJeremy L Thompson **/ 1336ed094490SJeremy L Thompson int CeedOperatorCompositeGetSubList(CeedOperator op, CeedOperator **sub_operators) { 13371203703bSJeremy L Thompson bool is_composite; 13381203703bSJeremy L Thompson 13391203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 13406e536b99SJeremy L Thompson CeedCheck(is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for a composite operator"); 134175f0d5a4SJeremy L Thompson *sub_operators = op->sub_operators; 134275f0d5a4SJeremy L Thompson return CEED_ERROR_SUCCESS; 134375f0d5a4SJeremy L Thompson } 134475f0d5a4SJeremy L Thompson 134575f0d5a4SJeremy L Thompson /** 13468a297abdSJames Wright @brief Get a sub `CeedOperator` of a composite `CeedOperator` from its name. 13478a297abdSJames Wright 13488a297abdSJames Wright `sub_op` is set to `NULL` if the sub operator is not found. 13498a297abdSJames Wright 13508a297abdSJames Wright Note: Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 13518a297abdSJames Wright 13528a297abdSJames Wright @param[in] op Composite `CeedOperator` 13538a297abdSJames Wright @param[in] op_name Name of desired sub `CeedOperator` 13548a297abdSJames Wright @param[out] sub_op Sub `CeedOperator` corresponding to the name 13558a297abdSJames Wright 13568a297abdSJames Wright @return An error code: 0 - success, otherwise - failure 13578a297abdSJames Wright 13588a297abdSJames Wright @ref Advanced 13598a297abdSJames Wright **/ 1360ed094490SJeremy L Thompson int CeedOperatorCompositeGetSubByName(CeedOperator op, const char *op_name, CeedOperator *sub_op) { 13618a297abdSJames Wright bool is_composite; 13628a297abdSJames Wright CeedInt num_sub_ops; 13638a297abdSJames Wright CeedOperator *sub_ops; 13648a297abdSJames Wright 13658a297abdSJames Wright CeedCall(CeedOperatorIsComposite(op, &is_composite)); 13668a297abdSJames Wright CeedCheck(is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Only defined for a composite operator"); 13678a297abdSJames Wright *sub_op = NULL; 1368ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_sub_ops)); 1369ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_ops)); 13708a297abdSJames Wright for (CeedInt i = 0; i < num_sub_ops; i++) { 13718a297abdSJames Wright if (sub_ops[i]->name && !strcmp(op_name, sub_ops[i]->name)) { 13728a297abdSJames Wright *sub_op = sub_ops[i]; 13738a297abdSJames Wright return CEED_ERROR_SUCCESS; 13748a297abdSJames Wright } 13758a297abdSJames Wright } 13768a297abdSJames Wright return CEED_ERROR_SUCCESS; 13778a297abdSJames Wright } 13788a297abdSJames Wright 13798a297abdSJames Wright /** 1380ca94c3ddSJeremy L Thompson @brief Check if a `CeedOperator` is ready to be used. 13814db537f9SJeremy L Thompson 1382ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to check 13834db537f9SJeremy L Thompson 13844db537f9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 13854db537f9SJeremy L Thompson 13864db537f9SJeremy L Thompson @ref User 13874db537f9SJeremy L Thompson **/ 13884db537f9SJeremy L Thompson int CeedOperatorCheckReady(CeedOperator op) { 13891203703bSJeremy L Thompson bool is_at_points, is_composite; 13901203703bSJeremy L Thompson CeedQFunction qf = NULL; 13914db537f9SJeremy L Thompson 13922b730f8bSJeremy L Thompson if (op->is_interface_setup) return CEED_ERROR_SUCCESS; 13934db537f9SJeremy L Thompson 13941203703bSJeremy L Thompson CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 13951203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 13961203703bSJeremy L Thompson if (!is_composite) CeedCall(CeedOperatorGetQFunction(op, &qf)); 13971203703bSJeremy L Thompson if (is_composite) { 13981203703bSJeremy L Thompson CeedInt num_suboperators; 13991203703bSJeremy L Thompson 1400ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 14011203703bSJeremy L Thompson if (!num_suboperators) { 140243622462SJeremy L Thompson // Empty operator setup 140343622462SJeremy L Thompson op->input_size = 0; 140443622462SJeremy L Thompson op->output_size = 0; 140543622462SJeremy L Thompson } else { 14061203703bSJeremy L Thompson CeedOperator *sub_operators; 14071203703bSJeremy L Thompson 1408ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 14091203703bSJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 14101203703bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(sub_operators[i])); 14114db537f9SJeremy L Thompson } 14122b104005SJeremy L Thompson // Sub-operators could be modified after adding to composite operator 14132b104005SJeremy L Thompson // Need to verify no lvec incompatibility from any changes 14142b104005SJeremy L Thompson CeedSize input_size, output_size; 14152b730f8bSJeremy L Thompson CeedCall(CeedOperatorGetActiveVectorLengths(op, &input_size, &output_size)); 141643622462SJeremy L Thompson } 14174db537f9SJeremy L Thompson } else { 14181203703bSJeremy L Thompson CeedInt num_input_fields, num_output_fields; 14191203703bSJeremy L Thompson 14209bc66399SJeremy L Thompson CeedCheck(op->num_fields > 0, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "No operator fields set"); 14211203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFields(qf, &num_input_fields, NULL, &num_output_fields, NULL)); 14229bc66399SJeremy L Thompson CeedCheck(op->num_fields == num_input_fields + num_output_fields, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, 14239bc66399SJeremy L Thompson "Not all operator fields set"); 14249bc66399SJeremy L Thompson CeedCheck(op->has_restriction, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, "At least one restriction required"); 14259bc66399SJeremy L Thompson CeedCheck(op->num_qpts > 0 || is_at_points, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, 1426ca94c3ddSJeremy L Thompson "At least one non-collocated CeedBasis is required or the number of quadrature points must be set"); 14272b730f8bSJeremy L Thompson } 14284db537f9SJeremy L Thompson 14294db537f9SJeremy L Thompson // Flag as immutable and ready 14304db537f9SJeremy L Thompson op->is_interface_setup = true; 14311203703bSJeremy L Thompson if (qf && qf != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionSetImmutable(qf)); 1432c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 14331203703bSJeremy L Thompson if (op->dqf && op->dqf != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionSetImmutable(op->dqf)); 14341203703bSJeremy L Thompson if (op->dqfT && op->dqfT != CEED_QFUNCTION_NONE) CeedCall(CeedQFunctionSetImmutable(op->dqfT)); 14354db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 14364db537f9SJeremy L Thompson } 14374db537f9SJeremy L Thompson 14384db537f9SJeremy L Thompson /** 1439ca94c3ddSJeremy L Thompson @brief Get vector lengths for the active input and/or output `CeedVector` of a `CeedOperator`. 14404385fb7fSSebastian Grimberg 1441ca94c3ddSJeremy L Thompson Note: Lengths of `-1` indicate that the CeedOperator does not have an active input and/or output. 1442c9366a6bSJeremy L Thompson 1443ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1444ca94c3ddSJeremy L Thompson @param[out] input_size Variable to store active input vector length, or `NULL` 1445ca94c3ddSJeremy L Thompson @param[out] output_size Variable to store active output vector length, or `NULL` 1446c9366a6bSJeremy L Thompson 1447c9366a6bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1448c9366a6bSJeremy L Thompson 1449c9366a6bSJeremy L Thompson @ref User 1450c9366a6bSJeremy L Thompson **/ 14512b730f8bSJeremy L Thompson int CeedOperatorGetActiveVectorLengths(CeedOperator op, CeedSize *input_size, CeedSize *output_size) { 1452c9366a6bSJeremy L Thompson bool is_composite; 1453c9366a6bSJeremy L Thompson 14542b104005SJeremy L Thompson if (input_size) *input_size = op->input_size; 14552b104005SJeremy L Thompson if (output_size) *output_size = op->output_size; 1456c9366a6bSJeremy L Thompson 14572b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 14582b104005SJeremy L Thompson if (is_composite && (op->input_size == -1 || op->output_size == -1)) { 14591203703bSJeremy L Thompson CeedInt num_suboperators; 14601203703bSJeremy L Thompson CeedOperator *sub_operators; 14611203703bSJeremy L Thompson 1462ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 1463ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 14641203703bSJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 1465c9366a6bSJeremy L Thompson CeedSize sub_input_size, sub_output_size; 14661c66c397SJeremy L Thompson 14671203703bSJeremy L Thompson CeedCall(CeedOperatorGetActiveVectorLengths(sub_operators[i], &sub_input_size, &sub_output_size)); 14682b104005SJeremy L Thompson if (op->input_size == -1) op->input_size = sub_input_size; 14692b104005SJeremy L Thompson if (op->output_size == -1) op->output_size = sub_output_size; 14702b104005SJeremy L Thompson // Note, a size of -1 means no active vector restriction set, so no incompatibility 14716e536b99SJeremy L Thompson CeedCheck((sub_input_size == -1 || sub_input_size == op->input_size) && (sub_output_size == -1 || sub_output_size == op->output_size), 14726e536b99SJeremy L Thompson CeedOperatorReturnCeed(op), CEED_ERROR_MAJOR, 1473249f8407SJeremy L Thompson "Sub-operators must have compatible dimensions; composite operator of shape (%" CeedSize_FMT ", %" CeedSize_FMT 1474249f8407SJeremy L Thompson ") not compatible with sub-operator of " 1475249f8407SJeremy L Thompson "shape (%" CeedSize_FMT ", %" CeedSize_FMT ")", 14762b104005SJeremy L Thompson op->input_size, op->output_size, input_size, output_size); 1477c9366a6bSJeremy L Thompson } 14782b730f8bSJeremy L Thompson } 1479c9366a6bSJeremy L Thompson return CEED_ERROR_SUCCESS; 1480c9366a6bSJeremy L Thompson } 1481c9366a6bSJeremy L Thompson 1482c9366a6bSJeremy L Thompson /** 1483ca94c3ddSJeremy L Thompson @brief Set reuse of `CeedQFunction` data in `CeedOperatorLinearAssemble*()` functions. 14844385fb7fSSebastian Grimberg 1485ca94c3ddSJeremy L Thompson When `reuse_assembly_data = false` (default), the `CeedQFunction` associated with this `CeedOperator` is re-assembled every time a `CeedOperatorLinearAssemble*()` function is called. 1486ca94c3ddSJeremy L Thompson When `reuse_assembly_data = true`, the `CeedQFunction` associated with this `CeedOperator` is reused between calls to @ref CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(). 14878b919e6bSJeremy L Thompson 1488ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1489beecbf24SJeremy L Thompson @param[in] reuse_assembly_data Boolean flag setting assembly data reuse 14908b919e6bSJeremy L Thompson 14918b919e6bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 14928b919e6bSJeremy L Thompson 14938b919e6bSJeremy L Thompson @ref Advanced 14948b919e6bSJeremy L Thompson **/ 14952b730f8bSJeremy L Thompson int CeedOperatorSetQFunctionAssemblyReuse(CeedOperator op, bool reuse_assembly_data) { 14968b919e6bSJeremy L Thompson bool is_composite; 14978b919e6bSJeremy L Thompson 14982b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 14998b919e6bSJeremy L Thompson if (is_composite) { 15008b919e6bSJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 15012b730f8bSJeremy L Thompson CeedCall(CeedOperatorSetQFunctionAssemblyReuse(op->sub_operators[i], reuse_assembly_data)); 15028b919e6bSJeremy L Thompson } 15038b919e6bSJeremy L Thompson } else { 15047d5185d7SSebastian Grimberg CeedQFunctionAssemblyData data; 15057d5185d7SSebastian Grimberg 15067d5185d7SSebastian Grimberg CeedCall(CeedOperatorGetQFunctionAssemblyData(op, &data)); 15077d5185d7SSebastian Grimberg CeedCall(CeedQFunctionAssemblyDataSetReuse(data, reuse_assembly_data)); 1508beecbf24SJeremy L Thompson } 1509beecbf24SJeremy L Thompson return CEED_ERROR_SUCCESS; 1510beecbf24SJeremy L Thompson } 1511beecbf24SJeremy L Thompson 1512beecbf24SJeremy L Thompson /** 1513ca94c3ddSJeremy L Thompson @brief Mark `CeedQFunction` data as updated and the `CeedQFunction` as requiring re-assembly. 1514beecbf24SJeremy L Thompson 1515ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 15166e15d496SJeremy L Thompson @param[in] needs_data_update Boolean flag setting assembly data reuse 1517beecbf24SJeremy L Thompson 1518beecbf24SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1519beecbf24SJeremy L Thompson 1520beecbf24SJeremy L Thompson @ref Advanced 1521beecbf24SJeremy L Thompson **/ 15222b730f8bSJeremy L Thompson int CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(CeedOperator op, bool needs_data_update) { 1523beecbf24SJeremy L Thompson bool is_composite; 1524beecbf24SJeremy L Thompson 15252b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 1526beecbf24SJeremy L Thompson if (is_composite) { 15271203703bSJeremy L Thompson CeedInt num_suboperators; 15281203703bSJeremy L Thompson CeedOperator *sub_operators; 15291203703bSJeremy L Thompson 1530ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 1531ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 15321203703bSJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 15331203703bSJeremy L Thompson CeedCall(CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(sub_operators[i], needs_data_update)); 1534beecbf24SJeremy L Thompson } 1535beecbf24SJeremy L Thompson } else { 15367d5185d7SSebastian Grimberg CeedQFunctionAssemblyData data; 15377d5185d7SSebastian Grimberg 15387d5185d7SSebastian Grimberg CeedCall(CeedOperatorGetQFunctionAssemblyData(op, &data)); 15397d5185d7SSebastian Grimberg CeedCall(CeedQFunctionAssemblyDataSetUpdateNeeded(data, needs_data_update)); 15408b919e6bSJeremy L Thompson } 15418b919e6bSJeremy L Thompson return CEED_ERROR_SUCCESS; 15428b919e6bSJeremy L Thompson } 15438b919e6bSJeremy L Thompson 15448b919e6bSJeremy L Thompson /** 1545ca94c3ddSJeremy L Thompson @brief Set name of `CeedOperator` for @ref CeedOperatorView() output 1546ea6b5821SJeremy L Thompson 1547ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 1548ea61e9acSJeremy L Thompson @param[in] name Name to set, or NULL to remove previously set name 1549ea6b5821SJeremy L Thompson 1550ea6b5821SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1551ea6b5821SJeremy L Thompson 1552ea6b5821SJeremy L Thompson @ref User 1553ea6b5821SJeremy L Thompson **/ 1554ea6b5821SJeremy L Thompson int CeedOperatorSetName(CeedOperator op, const char *name) { 1555ea6b5821SJeremy L Thompson char *name_copy; 1556ea6b5821SJeremy L Thompson size_t name_len = name ? strlen(name) : 0; 1557ea6b5821SJeremy L Thompson 15582b730f8bSJeremy L Thompson CeedCall(CeedFree(&op->name)); 1559ea6b5821SJeremy L Thompson if (name_len > 0) { 15602b730f8bSJeremy L Thompson CeedCall(CeedCalloc(name_len + 1, &name_copy)); 1561ea6b5821SJeremy L Thompson memcpy(name_copy, name, name_len); 1562ea6b5821SJeremy L Thompson op->name = name_copy; 1563ea6b5821SJeremy L Thompson } 1564ea6b5821SJeremy L Thompson return CEED_ERROR_SUCCESS; 1565ea6b5821SJeremy L Thompson } 1566ea6b5821SJeremy L Thompson 1567ea6b5821SJeremy L Thompson /** 1568d3d5610dSJeremy L Thompson @brief Get name of `CeedOperator` 1569d3d5610dSJeremy L Thompson 1570d3d5610dSJeremy L Thompson @param[in] op `CeedOperator` 1571d3d5610dSJeremy L Thompson @param[in,out] name Address of variable to hold currently set name 1572d3d5610dSJeremy L Thompson 1573d3d5610dSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1574d3d5610dSJeremy L Thompson 1575d3d5610dSJeremy L Thompson @ref User 1576d3d5610dSJeremy L Thompson **/ 1577d3d5610dSJeremy L Thompson int CeedOperatorGetName(CeedOperator op, const char **name) { 1578d3d5610dSJeremy L Thompson if (op->name) { 1579d3d5610dSJeremy L Thompson *name = op->name; 1580d3d5610dSJeremy L Thompson } else if (!op->is_composite) { 1581d3d5610dSJeremy L Thompson CeedQFunction qf; 1582d3d5610dSJeremy L Thompson 1583d3d5610dSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 1584d3d5610dSJeremy L Thompson if (qf) CeedCall(CeedQFunctionGetName(qf, name)); 1585d3d5610dSJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 1586d3d5610dSJeremy L Thompson } 1587d3d5610dSJeremy L Thompson return CEED_ERROR_SUCCESS; 1588d3d5610dSJeremy L Thompson } 1589d3d5610dSJeremy L Thompson 1590d3d5610dSJeremy L Thompson /** 1591935f026aSJeremy L Thompson @brief Core logic for viewing a `CeedOperator` 15927a982d89SJeremy L. Thompson 1593935f026aSJeremy L Thompson @param[in] op `CeedOperator` to view brief summary 1594ca94c3ddSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 15958bf1b130SJames Wright @param[in] is_full Whether to write full operator view or terse 15967a982d89SJeremy L. Thompson 15977a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 15986ab8e59fSJames Wright 15996ab8e59fSJames Wright @ref Developer 16007a982d89SJeremy L. Thompson **/ 16018bf1b130SJames Wright static int CeedOperatorView_Core(CeedOperator op, FILE *stream, bool is_full) { 1602d3d5610dSJeremy L Thompson bool has_name, is_composite, is_at_points; 16035a526491SJeremy L Thompson char *tabs = NULL; 1604d3d5610dSJeremy L Thompson const char *name = NULL; 16055a526491SJeremy L Thompson CeedInt num_tabs = 0; 16067a982d89SJeremy L. Thompson 1607d3d5610dSJeremy L Thompson CeedCall(CeedOperatorGetName(op, &name)); 1608d3d5610dSJeremy L Thompson has_name = name ? strlen(name) : false; 16091203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 161099f7f61fSJeremy L Thompson CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 16115a526491SJeremy L Thompson // Set tabs 16125a526491SJeremy L Thompson CeedCall(CeedOperatorGetNumViewTabs(op, &num_tabs)); 16134c789ea2SJeremy L Thompson CeedCall(CeedCalloc(CEED_TAB_WIDTH * (num_tabs + is_composite) + 1, &tabs)); 16144c789ea2SJeremy L Thompson for (CeedInt i = 0; i < CEED_TAB_WIDTH * num_tabs; i++) tabs[i] = ' '; 16151203703bSJeremy L Thompson if (is_composite) { 16161203703bSJeremy L Thompson CeedInt num_suboperators; 16171203703bSJeremy L Thompson CeedOperator *sub_operators; 16181203703bSJeremy L Thompson 1619ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 1620ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 1621df1daa62SZach Atkins fprintf(stream, "%s", tabs); 1622d3d5610dSJeremy L Thompson fprintf(stream, "Composite CeedOperator%s%s\n", has_name ? " - " : "", has_name ? name : ""); 16234c789ea2SJeremy L Thompson for (CeedInt i = 0; i < CEED_TAB_WIDTH; i++) tabs[CEED_TAB_WIDTH * num_tabs + i] = ' '; 16241203703bSJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 16251203703bSJeremy L Thompson has_name = sub_operators[i]->name; 1626df1daa62SZach Atkins fprintf(stream, "%s", tabs); 162799f7f61fSJeremy L Thompson fprintf(stream, "SubOperator%s %" CeedInt_FMT "%s%s%s\n", is_at_points ? " AtPoints" : "", i, has_name ? " - " : "", 162899f7f61fSJeremy L Thompson has_name ? sub_operators[i]->name : "", is_full ? ":" : ""); 16295a526491SJeremy L Thompson if (is_full) CeedCall(CeedOperatorSingleView(sub_operators[i], tabs, stream)); 16307a982d89SJeremy L. Thompson } 16317a982d89SJeremy L. Thompson } else { 1632df1daa62SZach Atkins fprintf(stream, "%s", tabs); 1633d3d5610dSJeremy L Thompson fprintf(stream, "CeedOperator%s%s%s\n", is_at_points ? " AtPoints" : "", has_name ? " - " : "", has_name ? name : ""); 16345a526491SJeremy L Thompson if (is_full) CeedCall(CeedOperatorSingleView(op, tabs, stream)); 16357a982d89SJeremy L. Thompson } 16365a526491SJeremy L Thompson CeedCall(CeedFree(&tabs)); 16375a526491SJeremy L Thompson return CEED_ERROR_SUCCESS; 16385a526491SJeremy L Thompson } 16395a526491SJeremy L Thompson 16405a526491SJeremy L Thompson /** 16415a526491SJeremy L Thompson @brief Set the number of tabs to indent for @ref CeedOperatorView() output 16425a526491SJeremy L Thompson 16435a526491SJeremy L Thompson @param[in] op `CeedOperator` to set the number of view tabs 16445a526491SJeremy L Thompson @param[in] num_tabs Number of view tabs to set 16455a526491SJeremy L Thompson 16465a526491SJeremy L Thompson @return Error code: 0 - success, otherwise - failure 16475a526491SJeremy L Thompson 16485a526491SJeremy L Thompson @ref User 16495a526491SJeremy L Thompson **/ 16505a526491SJeremy L Thompson int CeedOperatorSetNumViewTabs(CeedOperator op, CeedInt num_tabs) { 1651*a299a25bSJeremy L Thompson CeedCall(CeedObjectSetNumViewTabs((CeedObject)op, num_tabs)); 1652e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 16537a982d89SJeremy L. Thompson } 16543bd813ffSjeremylt 16553bd813ffSjeremylt /** 1656690992b2SZach Atkins @brief Get the number of tabs to indent for @ref CeedOperatorView() output 1657690992b2SZach Atkins 1658690992b2SZach Atkins @param[in] op `CeedOperator` to get the number of view tabs 1659690992b2SZach Atkins @param[out] num_tabs Number of view tabs 1660690992b2SZach Atkins 1661690992b2SZach Atkins @return Error code: 0 - success, otherwise - failure 1662690992b2SZach Atkins 1663690992b2SZach Atkins @ref User 1664690992b2SZach Atkins **/ 1665690992b2SZach Atkins int CeedOperatorGetNumViewTabs(CeedOperator op, CeedInt *num_tabs) { 1666*a299a25bSJeremy L Thompson CeedCall(CeedObjectGetNumViewTabs((CeedObject)op, num_tabs)); 1667690992b2SZach Atkins return CEED_ERROR_SUCCESS; 1668690992b2SZach Atkins } 1669690992b2SZach Atkins 1670690992b2SZach Atkins /** 1671935f026aSJeremy L Thompson @brief View a `CeedOperator` 1672935f026aSJeremy L Thompson 1673935f026aSJeremy L Thompson @param[in] op `CeedOperator` to view 1674935f026aSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 1675935f026aSJeremy L Thompson 1676935f026aSJeremy L Thompson @return Error code: 0 - success, otherwise - failure 1677935f026aSJeremy L Thompson 1678935f026aSJeremy L Thompson @ref User 1679935f026aSJeremy L Thompson **/ 1680935f026aSJeremy L Thompson int CeedOperatorView(CeedOperator op, FILE *stream) { 1681935f026aSJeremy L Thompson CeedCall(CeedOperatorView_Core(op, stream, true)); 1682935f026aSJeremy L Thompson return CEED_ERROR_SUCCESS; 1683935f026aSJeremy L Thompson } 1684935f026aSJeremy L Thompson 1685935f026aSJeremy L Thompson /** 1686935f026aSJeremy L Thompson @brief View a brief summary `CeedOperator` 1687935f026aSJeremy L Thompson 1688935f026aSJeremy L Thompson @param[in] op `CeedOperator` to view brief summary 1689935f026aSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 1690935f026aSJeremy L Thompson 1691935f026aSJeremy L Thompson @return Error code: 0 - success, otherwise - failure 1692935f026aSJeremy L Thompson 1693935f026aSJeremy L Thompson @ref User 1694935f026aSJeremy L Thompson **/ 1695935f026aSJeremy L Thompson int CeedOperatorViewTerse(CeedOperator op, FILE *stream) { 1696935f026aSJeremy L Thompson CeedCall(CeedOperatorView_Core(op, stream, false)); 1697935f026aSJeremy L Thompson return CEED_ERROR_SUCCESS; 1698935f026aSJeremy L Thompson } 1699935f026aSJeremy L Thompson 1700935f026aSJeremy L Thompson /** 1701ca94c3ddSJeremy L Thompson @brief Get the `Ceed` associated with a `CeedOperator` 1702b7c9bbdaSJeremy L Thompson 1703ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1704ca94c3ddSJeremy L Thompson @param[out] ceed Variable to store `Ceed` 1705b7c9bbdaSJeremy L Thompson 1706b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1707b7c9bbdaSJeremy L Thompson 1708b7c9bbdaSJeremy L Thompson @ref Advanced 1709b7c9bbdaSJeremy L Thompson **/ 1710b7c9bbdaSJeremy L Thompson int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 1711b0f67a9cSJeremy L Thompson CeedCall(CeedObjectGetCeed((CeedObject)op, ceed)); 1712b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1713b7c9bbdaSJeremy L Thompson } 1714b7c9bbdaSJeremy L Thompson 1715b7c9bbdaSJeremy L Thompson /** 17166e536b99SJeremy L Thompson @brief Return the `Ceed` associated with a `CeedOperator` 17176e536b99SJeremy L Thompson 17186e536b99SJeremy L Thompson @param[in] op `CeedOperator` 17196e536b99SJeremy L Thompson 17206e536b99SJeremy L Thompson @return `Ceed` associated with the `op` 17216e536b99SJeremy L Thompson 17226e536b99SJeremy L Thompson @ref Advanced 17236e536b99SJeremy L Thompson **/ 1724b0f67a9cSJeremy L Thompson Ceed CeedOperatorReturnCeed(CeedOperator op) { return CeedObjectReturnCeed((CeedObject)op); } 17256e536b99SJeremy L Thompson 17266e536b99SJeremy L Thompson /** 1727ca94c3ddSJeremy L Thompson @brief Get the number of elements associated with a `CeedOperator` 1728b7c9bbdaSJeremy L Thompson 1729ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1730b7c9bbdaSJeremy L Thompson @param[out] num_elem Variable to store number of elements 1731b7c9bbdaSJeremy L Thompson 1732b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1733b7c9bbdaSJeremy L Thompson 1734b7c9bbdaSJeremy L Thompson @ref Advanced 1735b7c9bbdaSJeremy L Thompson **/ 1736b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumElements(CeedOperator op, CeedInt *num_elem) { 17371203703bSJeremy L Thompson bool is_composite; 17381203703bSJeremy L Thompson 17391203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 17406e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Not defined for composite operator"); 1741b7c9bbdaSJeremy L Thompson *num_elem = op->num_elem; 1742b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1743b7c9bbdaSJeremy L Thompson } 1744b7c9bbdaSJeremy L Thompson 1745b7c9bbdaSJeremy L Thompson /** 1746ca94c3ddSJeremy L Thompson @brief Get the number of quadrature points associated with a `CeedOperator` 1747b7c9bbdaSJeremy L Thompson 1748ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1749b7c9bbdaSJeremy L Thompson @param[out] num_qpts Variable to store vector number of quadrature points 1750b7c9bbdaSJeremy L Thompson 1751b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1752b7c9bbdaSJeremy L Thompson 1753b7c9bbdaSJeremy L Thompson @ref Advanced 1754b7c9bbdaSJeremy L Thompson **/ 1755b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *num_qpts) { 17561203703bSJeremy L Thompson bool is_composite; 17571203703bSJeremy L Thompson 17581203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 17596e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_MINOR, "Not defined for composite operator"); 1760b7c9bbdaSJeremy L Thompson *num_qpts = op->num_qpts; 1761b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1762b7c9bbdaSJeremy L Thompson } 1763b7c9bbdaSJeremy L Thompson 1764b7c9bbdaSJeremy L Thompson /** 1765ca94c3ddSJeremy L Thompson @brief Estimate number of FLOPs required to apply `CeedOperator` on the active `CeedVector` 17666e15d496SJeremy L Thompson 1767ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to estimate FLOPs for 1768ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 17696e15d496SJeremy L Thompson 17706e15d496SJeremy L Thompson @ref Backend 17716e15d496SJeremy L Thompson **/ 17729d36ca50SJeremy L Thompson int CeedOperatorGetFlopsEstimate(CeedOperator op, CeedSize *flops) { 17736e15d496SJeremy L Thompson bool is_composite; 17741c66c397SJeremy L Thompson 17752b730f8bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 17766e15d496SJeremy L Thompson 17776e15d496SJeremy L Thompson *flops = 0; 17782b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 17796e15d496SJeremy L Thompson if (is_composite) { 17806e15d496SJeremy L Thompson CeedInt num_suboperators; 17811c66c397SJeremy L Thompson 1782ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 17836e15d496SJeremy L Thompson CeedOperator *sub_operators; 1784ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 17856e15d496SJeremy L Thompson 17866e15d496SJeremy L Thompson // FLOPs for each suboperator 17876e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 17889d36ca50SJeremy L Thompson CeedSize suboperator_flops; 17891c66c397SJeremy L Thompson 17902b730f8bSJeremy L Thompson CeedCall(CeedOperatorGetFlopsEstimate(sub_operators[i], &suboperator_flops)); 17916e15d496SJeremy L Thompson *flops += suboperator_flops; 17926e15d496SJeremy L Thompson } 17936e15d496SJeremy L Thompson } else { 17943f919cbcSJeremy L Thompson bool is_at_points; 17953f919cbcSJeremy L Thompson CeedInt num_input_fields, num_output_fields, num_elem = 0, num_points = 0; 17961203703bSJeremy L Thompson CeedQFunction qf; 17971203703bSJeremy L Thompson CeedQFunctionField *qf_input_fields, *qf_output_fields; 17981203703bSJeremy L Thompson CeedOperatorField *op_input_fields, *op_output_fields; 17991c66c397SJeremy L Thompson 18003f919cbcSJeremy L Thompson CeedCall(CeedOperatorGetNumElements(op, &num_elem)); 180119feff82SJeremy L Thompson if (num_elem == 0) return CEED_ERROR_SUCCESS; 180219feff82SJeremy L Thompson CeedCall(CeedOperatorIsAtPoints(op, &is_at_points)); 18033f919cbcSJeremy L Thompson if (is_at_points) { 18043f919cbcSJeremy L Thompson CeedMemType mem_type; 18053f919cbcSJeremy L Thompson CeedElemRestriction rstr_points = NULL; 18063f919cbcSJeremy L Thompson 18073f919cbcSJeremy L Thompson CeedCall(CeedOperatorAtPointsGetPoints(op, &rstr_points, NULL)); 18083f919cbcSJeremy L Thompson CeedCall(CeedGetPreferredMemType(CeedOperatorReturnCeed(op), &mem_type)); 18093f919cbcSJeremy L Thompson if (mem_type == CEED_MEM_DEVICE) { 18103f919cbcSJeremy L Thompson // Device backends pad out to the same number of points per element 18113f919cbcSJeremy L Thompson CeedCall(CeedElemRestrictionGetMaxPointsInElement(rstr_points, &num_points)); 18123f919cbcSJeremy L Thompson } else { 18133f919cbcSJeremy L Thompson num_points = 0; 18143f919cbcSJeremy L Thompson for (CeedInt i = 0; i < num_elem; i++) { 18153f919cbcSJeremy L Thompson CeedInt points_in_elem = 0; 18163f919cbcSJeremy L Thompson 18173f919cbcSJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr_points, i, &points_in_elem)); 18183f919cbcSJeremy L Thompson num_points += points_in_elem; 18193f919cbcSJeremy L Thompson } 18203f919cbcSJeremy L Thompson num_points = num_points / num_elem + (num_points % num_elem > 0); 18213f919cbcSJeremy L Thompson } 18223f919cbcSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr_points)); 18233f919cbcSJeremy L Thompson } 18241203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 18251203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFields(qf, &num_input_fields, &qf_input_fields, &num_output_fields, &qf_output_fields)); 1826c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 18271203703bSJeremy L Thompson CeedCall(CeedOperatorGetFields(op, NULL, &op_input_fields, NULL, &op_output_fields)); 18284385fb7fSSebastian Grimberg 18296e15d496SJeremy L Thompson // Input FLOPs 18306e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 18311203703bSJeremy L Thompson CeedVector vec; 18326e15d496SJeremy L Thompson 18331203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_input_fields[i], &vec)); 18341203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 18351203703bSJeremy L Thompson CeedEvalMode eval_mode; 18361203703bSJeremy L Thompson CeedSize rstr_flops, basis_flops; 18371203703bSJeremy L Thompson CeedElemRestriction rstr; 18381203703bSJeremy L Thompson CeedBasis basis; 18391203703bSJeremy L Thompson 18401203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetElemRestriction(op_input_fields[i], &rstr)); 18411203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetFlopsEstimate(rstr, CEED_NOTRANSPOSE, &rstr_flops)); 1842681d0ea7SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr)); 1843edb2538eSJeremy L Thompson *flops += rstr_flops; 18441203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(op_input_fields[i], &basis)); 18451203703bSJeremy L Thompson CeedCall(CeedQFunctionFieldGetEvalMode(qf_input_fields[i], &eval_mode)); 18463f919cbcSJeremy L Thompson CeedCall(CeedBasisGetFlopsEstimate(basis, CEED_NOTRANSPOSE, eval_mode, is_at_points, num_points, &basis_flops)); 1847681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 18486e15d496SJeremy L Thompson *flops += basis_flops * num_elem; 18496e15d496SJeremy L Thompson } 1850681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 18516e15d496SJeremy L Thompson } 18526e15d496SJeremy L Thompson // QF FLOPs 18531c66c397SJeremy L Thompson { 18549d36ca50SJeremy L Thompson CeedInt num_qpts; 18559d36ca50SJeremy L Thompson CeedSize qf_flops; 18561203703bSJeremy L Thompson CeedQFunction qf; 18571c66c397SJeremy L Thompson 18583f919cbcSJeremy L Thompson if (is_at_points) num_qpts = num_points; 18593f919cbcSJeremy L Thompson else CeedCall(CeedOperatorGetNumQuadraturePoints(op, &num_qpts)); 18601203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 18611203703bSJeremy L Thompson CeedCall(CeedQFunctionGetFlopsEstimate(qf, &qf_flops)); 1862c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 18636e536b99SJeremy L Thompson CeedCheck(qf_flops > -1, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPLETE, 18646e536b99SJeremy L Thompson "Must set CeedQFunction FLOPs estimate with CeedQFunctionSetUserFlopsEstimate"); 18656e15d496SJeremy L Thompson *flops += num_elem * num_qpts * qf_flops; 18661c66c397SJeremy L Thompson } 18671c66c397SJeremy L Thompson 18686e15d496SJeremy L Thompson // Output FLOPs 18696e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 18701203703bSJeremy L Thompson CeedVector vec; 18716e15d496SJeremy L Thompson 18721203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetVector(op_output_fields[i], &vec)); 18731203703bSJeremy L Thompson if (vec == CEED_VECTOR_ACTIVE) { 18741203703bSJeremy L Thompson CeedEvalMode eval_mode; 18751203703bSJeremy L Thompson CeedSize rstr_flops, basis_flops; 18761203703bSJeremy L Thompson CeedElemRestriction rstr; 18771203703bSJeremy L Thompson CeedBasis basis; 18781203703bSJeremy L Thompson 18791203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetElemRestriction(op_output_fields[i], &rstr)); 18801203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetFlopsEstimate(rstr, CEED_TRANSPOSE, &rstr_flops)); 1881681d0ea7SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&rstr)); 1882edb2538eSJeremy L Thompson *flops += rstr_flops; 18831203703bSJeremy L Thompson CeedCall(CeedOperatorFieldGetBasis(op_output_fields[i], &basis)); 18841203703bSJeremy L Thompson CeedCall(CeedQFunctionFieldGetEvalMode(qf_output_fields[i], &eval_mode)); 18853f919cbcSJeremy L Thompson CeedCall(CeedBasisGetFlopsEstimate(basis, CEED_TRANSPOSE, eval_mode, is_at_points, num_points, &basis_flops)); 1886681d0ea7SJeremy L Thompson CeedCall(CeedBasisDestroy(&basis)); 18876e15d496SJeremy L Thompson *flops += basis_flops * num_elem; 18886e15d496SJeremy L Thompson } 1889681d0ea7SJeremy L Thompson CeedCall(CeedVectorDestroy(&vec)); 18906e15d496SJeremy L Thompson } 18916e15d496SJeremy L Thompson } 18926e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 18936e15d496SJeremy L Thompson } 18946e15d496SJeremy L Thompson 18956e15d496SJeremy L Thompson /** 1896ca94c3ddSJeremy L Thompson @brief Get `CeedQFunction` global context for a `CeedOperator`. 18979fd66db6SSebastian Grimberg 1898ca94c3ddSJeremy L Thompson The caller is responsible for destroying `ctx` returned from this function via @ref CeedQFunctionContextDestroy(). 1899512bb800SJeremy L Thompson 1900ca94c3ddSJeremy 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`. 1901ca94c3ddSJeremy L Thompson This `CeedQFunctionContext` will be destroyed if `ctx` is the only reference to this `CeedQFunctionContext`. 19020126412dSJeremy L Thompson 1903ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 1904ca94c3ddSJeremy L Thompson @param[out] ctx Variable to store `CeedQFunctionContext` 19050126412dSJeremy L Thompson 19060126412dSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 19070126412dSJeremy L Thompson 1908859c15bbSJames Wright @ref Advanced 19090126412dSJeremy L Thompson **/ 19100126412dSJeremy L Thompson int CeedOperatorGetContext(CeedOperator op, CeedQFunctionContext *ctx) { 19111203703bSJeremy L Thompson bool is_composite; 19121203703bSJeremy L Thompson CeedQFunction qf; 19131203703bSJeremy L Thompson CeedQFunctionContext qf_ctx; 19141203703bSJeremy L Thompson 19151203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 19166e536b99SJeremy L Thompson CeedCheck(!is_composite, CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "Cannot retrieve CeedQFunctionContext for composite operator"); 19171203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 19181203703bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &qf_ctx)); 1919c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 19201485364cSJeremy L Thompson *ctx = NULL; 19211203703bSJeremy L Thompson if (qf_ctx) CeedCall(CeedQFunctionContextReferenceCopy(qf_ctx, ctx)); 19220126412dSJeremy L Thompson return CEED_ERROR_SUCCESS; 19230126412dSJeremy L Thompson } 19240126412dSJeremy L Thompson 19250126412dSJeremy L Thompson /** 1926ca94c3ddSJeremy L Thompson @brief Get label for a registered `CeedQFunctionContext` field, or `NULL` if no field has been registered with this `field_name`. 19273668ca4bSJeremy L Thompson 1928ca94c3ddSJeremy L Thompson Fields are registered via `CeedQFunctionContextRegister*()` functions (eg. @ref CeedQFunctionContextRegisterDouble()). 1929859c15bbSJames Wright 1930ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 19313668ca4bSJeremy L Thompson @param[in] field_name Name of field to retrieve label 19323668ca4bSJeremy L Thompson @param[out] field_label Variable to field label 19333668ca4bSJeremy L Thompson 19343668ca4bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 19353668ca4bSJeremy L Thompson 19363668ca4bSJeremy L Thompson @ref User 19373668ca4bSJeremy L Thompson **/ 193817b0d5c6SJeremy L Thompson int CeedOperatorGetContextFieldLabel(CeedOperator op, const char *field_name, CeedContextFieldLabel *field_label) { 19391c66c397SJeremy L Thompson bool is_composite, field_found = false; 19401c66c397SJeremy L Thompson 19412b730f8bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 19422b730f8bSJeremy L Thompson 19433668ca4bSJeremy L Thompson if (is_composite) { 1944a98a090bSJeremy L Thompson // Composite operator 1945a98a090bSJeremy L Thompson // -- Check if composite label already created 19463668ca4bSJeremy L Thompson for (CeedInt i = 0; i < op->num_context_labels; i++) { 19473668ca4bSJeremy L Thompson if (!strcmp(op->context_labels[i]->name, field_name)) { 19483668ca4bSJeremy L Thompson *field_label = op->context_labels[i]; 19493668ca4bSJeremy L Thompson return CEED_ERROR_SUCCESS; 19503668ca4bSJeremy L Thompson } 19513668ca4bSJeremy L Thompson } 19523668ca4bSJeremy L Thompson 1953a98a090bSJeremy L Thompson // -- Create composite label if needed 19543668ca4bSJeremy L Thompson CeedInt num_sub; 19553668ca4bSJeremy L Thompson CeedOperator *sub_operators; 19563668ca4bSJeremy L Thompson CeedContextFieldLabel new_field_label; 19573668ca4bSJeremy L Thompson 19582b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &new_field_label)); 1959ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_sub)); 1960ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 19612b730f8bSJeremy L Thompson CeedCall(CeedCalloc(num_sub, &new_field_label->sub_labels)); 19623668ca4bSJeremy L Thompson new_field_label->num_sub_labels = num_sub; 19633668ca4bSJeremy L Thompson 19643668ca4bSJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 19653668ca4bSJeremy L Thompson if (sub_operators[i]->qf->ctx) { 19663668ca4bSJeremy L Thompson CeedContextFieldLabel new_field_label_i; 19671c66c397SJeremy L Thompson 19682b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldLabel(sub_operators[i]->qf->ctx, field_name, &new_field_label_i)); 19693668ca4bSJeremy L Thompson if (new_field_label_i) { 1970a98a090bSJeremy L Thompson field_found = true; 19713668ca4bSJeremy L Thompson new_field_label->sub_labels[i] = new_field_label_i; 19723668ca4bSJeremy L Thompson new_field_label->name = new_field_label_i->name; 19733668ca4bSJeremy L Thompson new_field_label->description = new_field_label_i->description; 19742b730f8bSJeremy L Thompson if (new_field_label->type && new_field_label->type != new_field_label_i->type) { 19757bfe0f0eSJeremy L Thompson // LCOV_EXCL_START 19762b730f8bSJeremy L Thompson CeedCall(CeedFree(&new_field_label)); 19776e536b99SJeremy L Thompson return CeedError(CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, "Incompatible field types on sub-operator contexts. %s != %s", 19782b730f8bSJeremy L Thompson CeedContextFieldTypes[new_field_label->type], CeedContextFieldTypes[new_field_label_i->type]); 19797bfe0f0eSJeremy L Thompson // LCOV_EXCL_STOP 19807bfe0f0eSJeremy L Thompson } else { 19817bfe0f0eSJeremy L Thompson new_field_label->type = new_field_label_i->type; 19827bfe0f0eSJeremy L Thompson } 19832b730f8bSJeremy L Thompson if (new_field_label->num_values != 0 && new_field_label->num_values != new_field_label_i->num_values) { 19847bfe0f0eSJeremy L Thompson // LCOV_EXCL_START 19852b730f8bSJeremy L Thompson CeedCall(CeedFree(&new_field_label)); 19866e536b99SJeremy L Thompson return CeedError(CeedOperatorReturnCeed(op), CEED_ERROR_INCOMPATIBLE, 19876e536b99SJeremy L Thompson "Incompatible field number of values on sub-operator contexts. %zu != %zu", new_field_label->num_values, 19886e536b99SJeremy L Thompson new_field_label_i->num_values); 19897bfe0f0eSJeremy L Thompson // LCOV_EXCL_STOP 19907bfe0f0eSJeremy L Thompson } else { 19917bfe0f0eSJeremy L Thompson new_field_label->num_values = new_field_label_i->num_values; 19927bfe0f0eSJeremy L Thompson } 19933668ca4bSJeremy L Thompson } 19943668ca4bSJeremy L Thompson } 19953668ca4bSJeremy L Thompson } 1996a98a090bSJeremy L Thompson // -- Cleanup if field was found 1997a98a090bSJeremy L Thompson if (field_found) { 1998a98a090bSJeremy L Thompson *field_label = new_field_label; 1999a98a090bSJeremy L Thompson } else { 20003668ca4bSJeremy L Thompson // LCOV_EXCL_START 20012b730f8bSJeremy L Thompson CeedCall(CeedFree(&new_field_label->sub_labels)); 20022b730f8bSJeremy L Thompson CeedCall(CeedFree(&new_field_label)); 20033668ca4bSJeremy L Thompson *field_label = NULL; 20043668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 20055ac9af79SJeremy L Thompson } 20065ac9af79SJeremy L Thompson } else { 20071203703bSJeremy L Thompson CeedQFunction qf; 20081203703bSJeremy L Thompson CeedQFunctionContext ctx; 20091203703bSJeremy L Thompson 2010a98a090bSJeremy L Thompson // Single, non-composite operator 20111203703bSJeremy L Thompson CeedCall(CeedOperatorGetQFunction(op, &qf)); 20121203703bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &ctx)); 2013c11e12f4SJeremy L Thompson CeedCall(CeedQFunctionDestroy(&qf)); 20141203703bSJeremy L Thompson if (ctx) { 20151203703bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldLabel(ctx, field_name, field_label)); 2016a98a090bSJeremy L Thompson } else { 2017a98a090bSJeremy L Thompson *field_label = NULL; 2018a98a090bSJeremy L Thompson } 20195ac9af79SJeremy L Thompson } 20205ac9af79SJeremy L Thompson 20215ac9af79SJeremy L Thompson // Set label in operator 20225ac9af79SJeremy L Thompson if (*field_label) { 20235ac9af79SJeremy L Thompson (*field_label)->from_op = true; 20245ac9af79SJeremy L Thompson 20253668ca4bSJeremy L Thompson // Move new composite label to operator 20263668ca4bSJeremy L Thompson if (op->num_context_labels == 0) { 20272b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &op->context_labels)); 20283668ca4bSJeremy L Thompson op->max_context_labels = 1; 20293668ca4bSJeremy L Thompson } else if (op->num_context_labels == op->max_context_labels) { 20302b730f8bSJeremy L Thompson CeedCall(CeedRealloc(2 * op->num_context_labels, &op->context_labels)); 20313668ca4bSJeremy L Thompson op->max_context_labels *= 2; 20323668ca4bSJeremy L Thompson } 20335ac9af79SJeremy L Thompson op->context_labels[op->num_context_labels] = *field_label; 20343668ca4bSJeremy L Thompson op->num_context_labels++; 20353668ca4bSJeremy L Thompson } 20363668ca4bSJeremy L Thompson return CEED_ERROR_SUCCESS; 20373668ca4bSJeremy L Thompson } 20383668ca4bSJeremy L Thompson 20393668ca4bSJeremy L Thompson /** 2040ca94c3ddSJeremy L Thompson @brief Set `CeedQFunctionContext` field holding double precision values. 20414385fb7fSSebastian Grimberg 2042ca94c3ddSJeremy L Thompson For composite operators, the values are set in all sub-operator `CeedQFunctionContext` that have a matching `field_name`. 2043d8dd9a91SJeremy L Thompson 2044ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 20452788fa27SJeremy L Thompson @param[in] field_label Label of field to set 2046ea61e9acSJeremy L Thompson @param[in] values Values to set 2047d8dd9a91SJeremy L Thompson 2048d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2049d8dd9a91SJeremy L Thompson 2050d8dd9a91SJeremy L Thompson @ref User 2051d8dd9a91SJeremy L Thompson **/ 205217b0d5c6SJeremy L Thompson int CeedOperatorSetContextDouble(CeedOperator op, CeedContextFieldLabel field_label, double *values) { 20532b730f8bSJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_DOUBLE, values); 2054d8dd9a91SJeremy L Thompson } 2055d8dd9a91SJeremy L Thompson 2056d8dd9a91SJeremy L Thompson /** 2057ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field holding double precision values, read-only. 20584385fb7fSSebastian Grimberg 2059ca94c3ddSJeremy L Thompson For composite operators, the values correspond to the first sub-operator `CeedQFunctionContext` that has a matching `field_name`. 20602788fa27SJeremy L Thompson 2061ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 20622788fa27SJeremy L Thompson @param[in] field_label Label of field to get 20632788fa27SJeremy L Thompson @param[out] num_values Number of values in the field label 20642788fa27SJeremy L Thompson @param[out] values Pointer to context values 20652788fa27SJeremy L Thompson 20662788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 20672788fa27SJeremy L Thompson 20682788fa27SJeremy L Thompson @ref User 20692788fa27SJeremy L Thompson **/ 207017b0d5c6SJeremy L Thompson int CeedOperatorGetContextDoubleRead(CeedOperator op, CeedContextFieldLabel field_label, size_t *num_values, const double **values) { 20712788fa27SJeremy L Thompson return CeedOperatorContextGetGenericRead(op, field_label, CEED_CONTEXT_FIELD_DOUBLE, num_values, values); 20722788fa27SJeremy L Thompson } 20732788fa27SJeremy L Thompson 20742788fa27SJeremy L Thompson /** 2075ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field holding double precision values, read-only. 20762788fa27SJeremy L Thompson 2077ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 20782788fa27SJeremy L Thompson @param[in] field_label Label of field to restore 20792788fa27SJeremy L Thompson @param[out] values Pointer to context values 20802788fa27SJeremy L Thompson 20812788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 20822788fa27SJeremy L Thompson 20832788fa27SJeremy L Thompson @ref User 20842788fa27SJeremy L Thompson **/ 208517b0d5c6SJeremy L Thompson int CeedOperatorRestoreContextDoubleRead(CeedOperator op, CeedContextFieldLabel field_label, const double **values) { 20862788fa27SJeremy L Thompson return CeedOperatorContextRestoreGenericRead(op, field_label, CEED_CONTEXT_FIELD_DOUBLE, values); 20872788fa27SJeremy L Thompson } 20882788fa27SJeremy L Thompson 20892788fa27SJeremy L Thompson /** 2090ca94c3ddSJeremy L Thompson @brief Set `CeedQFunctionContext` field holding `int32` values. 20914385fb7fSSebastian Grimberg 2092ca94c3ddSJeremy L Thompson For composite operators, the values are set in all sub-operator `CeedQFunctionContext` that have a matching `field_name`. 2093d8dd9a91SJeremy L Thompson 2094ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 2095ea61e9acSJeremy L Thompson @param[in] field_label Label of field to set 2096ea61e9acSJeremy L Thompson @param[in] values Values to set 2097d8dd9a91SJeremy L Thompson 2098d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2099d8dd9a91SJeremy L Thompson 2100d8dd9a91SJeremy L Thompson @ref User 2101d8dd9a91SJeremy L Thompson **/ 210223dbfd29SJeremy L Thompson int CeedOperatorSetContextInt32(CeedOperator op, CeedContextFieldLabel field_label, int32_t *values) { 21032b730f8bSJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_INT32, values); 2104d8dd9a91SJeremy L Thompson } 2105d8dd9a91SJeremy L Thompson 2106d8dd9a91SJeremy L Thompson /** 2107ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field holding `int32` values, read-only. 21084385fb7fSSebastian Grimberg 2109ca94c3ddSJeremy L Thompson For composite operators, the values correspond to the first sub-operator `CeedQFunctionContext` that has a matching `field_name`. 21102788fa27SJeremy L Thompson 2111ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 21122788fa27SJeremy L Thompson @param[in] field_label Label of field to get 2113ca94c3ddSJeremy L Thompson @param[out] num_values Number of `int32` values in `values` 21142788fa27SJeremy L Thompson @param[out] values Pointer to context values 21152788fa27SJeremy L Thompson 21162788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21172788fa27SJeremy L Thompson 21182788fa27SJeremy L Thompson @ref User 21192788fa27SJeremy L Thompson **/ 212023dbfd29SJeremy L Thompson int CeedOperatorGetContextInt32Read(CeedOperator op, CeedContextFieldLabel field_label, size_t *num_values, const int32_t **values) { 21212788fa27SJeremy L Thompson return CeedOperatorContextGetGenericRead(op, field_label, CEED_CONTEXT_FIELD_INT32, num_values, values); 21222788fa27SJeremy L Thompson } 21232788fa27SJeremy L Thompson 21242788fa27SJeremy L Thompson /** 2125ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field holding `int32` values, read-only. 21262788fa27SJeremy L Thompson 2127ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 21282788fa27SJeremy L Thompson @param[in] field_label Label of field to get 21292788fa27SJeremy L Thompson @param[out] values Pointer to context values 21302788fa27SJeremy L Thompson 21312788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21322788fa27SJeremy L Thompson 21332788fa27SJeremy L Thompson @ref User 21342788fa27SJeremy L Thompson **/ 213523dbfd29SJeremy L Thompson int CeedOperatorRestoreContextInt32Read(CeedOperator op, CeedContextFieldLabel field_label, const int32_t **values) { 21362788fa27SJeremy L Thompson return CeedOperatorContextRestoreGenericRead(op, field_label, CEED_CONTEXT_FIELD_INT32, values); 21372788fa27SJeremy L Thompson } 21382788fa27SJeremy L Thompson 21392788fa27SJeremy L Thompson /** 2140ca94c3ddSJeremy L Thompson @brief Set `CeedQFunctionContext` field holding boolean values. 21415b6ec284SJeremy L Thompson 2142ca94c3ddSJeremy L Thompson For composite operators, the values are set in all sub-operator `CeedQFunctionContext` that have a matching `field_name`. 21435b6ec284SJeremy L Thompson 2144ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` 21455b6ec284SJeremy L Thompson @param[in] field_label Label of field to set 21465b6ec284SJeremy L Thompson @param[in] values Values to set 21475b6ec284SJeremy L Thompson 21485b6ec284SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21495b6ec284SJeremy L Thompson 21505b6ec284SJeremy L Thompson @ref User 21515b6ec284SJeremy L Thompson **/ 21525b6ec284SJeremy L Thompson int CeedOperatorSetContextBoolean(CeedOperator op, CeedContextFieldLabel field_label, bool *values) { 21535b6ec284SJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_BOOL, values); 21545b6ec284SJeremy L Thompson } 21555b6ec284SJeremy L Thompson 21565b6ec284SJeremy L Thompson /** 2157ca94c3ddSJeremy L Thompson @brief Get `CeedQFunctionContext` field holding boolean values, read-only. 21585b6ec284SJeremy L Thompson 2159ca94c3ddSJeremy L Thompson For composite operators, the values correspond to the first sub-operator `CeedQFunctionContext` that has a matching `field_name`. 21605b6ec284SJeremy L Thompson 2161ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 21625b6ec284SJeremy L Thompson @param[in] field_label Label of field to get 2163ca94c3ddSJeremy L Thompson @param[out] num_values Number of boolean values in `values` 21645b6ec284SJeremy L Thompson @param[out] values Pointer to context values 21655b6ec284SJeremy L Thompson 21665b6ec284SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21675b6ec284SJeremy L Thompson 21685b6ec284SJeremy L Thompson @ref User 21695b6ec284SJeremy L Thompson **/ 21705b6ec284SJeremy L Thompson int CeedOperatorGetContextBooleanRead(CeedOperator op, CeedContextFieldLabel field_label, size_t *num_values, const bool **values) { 21715b6ec284SJeremy L Thompson return CeedOperatorContextGetGenericRead(op, field_label, CEED_CONTEXT_FIELD_BOOL, num_values, values); 21725b6ec284SJeremy L Thompson } 21735b6ec284SJeremy L Thompson 21745b6ec284SJeremy L Thompson /** 2175ca94c3ddSJeremy L Thompson @brief Restore `CeedQFunctionContext` field holding boolean values, read-only. 21765b6ec284SJeremy L Thompson 2177ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` 21785b6ec284SJeremy L Thompson @param[in] field_label Label of field to get 21795b6ec284SJeremy L Thompson @param[out] values Pointer to context values 21805b6ec284SJeremy L Thompson 21815b6ec284SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21825b6ec284SJeremy L Thompson 21835b6ec284SJeremy L Thompson @ref User 21845b6ec284SJeremy L Thompson **/ 21855b6ec284SJeremy L Thompson int CeedOperatorRestoreContextBooleanRead(CeedOperator op, CeedContextFieldLabel field_label, const bool **values) { 21865b6ec284SJeremy L Thompson return CeedOperatorContextRestoreGenericRead(op, field_label, CEED_CONTEXT_FIELD_BOOL, values); 21875b6ec284SJeremy L Thompson } 21885b6ec284SJeremy L Thompson 21895b6ec284SJeremy L Thompson /** 2190ca94c3ddSJeremy L Thompson @brief Apply `CeedOperator` to a `CeedVector`. 2191d7b241e6Sjeremylt 2192ea61e9acSJeremy L Thompson This computes the action of the operator on the specified (active) input, yielding its (active) output. 2193ca94c3ddSJeremy L Thompson All inputs and outputs must be specified using @ref CeedOperatorSetField(). 2194d7b241e6Sjeremylt 21955da5ab9fSZach Atkins @note Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 2196f04ea552SJeremy L Thompson 2197ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to apply 2198ca94c3ddSJeremy L Thompson @param[in] in `CeedVector` containing input state or @ref CEED_VECTOR_NONE if there are no active inputs 2199ca94c3ddSJeremy 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 2200ca94c3ddSJeremy L Thompson @param[in] request Address of @ref CeedRequest for non-blocking completion, else @ref CEED_REQUEST_IMMEDIATE 2201b11c1e72Sjeremylt 2202b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 2203dfdf5a53Sjeremylt 22047a982d89SJeremy L. Thompson @ref User 2205b11c1e72Sjeremylt **/ 22062b730f8bSJeremy L Thompson int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, CeedRequest *request) { 22071203703bSJeremy L Thompson bool is_composite; 22081203703bSJeremy L Thompson 22092b730f8bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 2210d7b241e6Sjeremylt 22111203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 22120db52efcSZach Atkins if (is_composite && op->ApplyComposite) { 2213250756a7Sjeremylt // Composite Operator 22142b730f8bSJeremy L Thompson CeedCall(op->ApplyComposite(op, in, out, request)); 22150db52efcSZach Atkins } else if (!is_composite && op->Apply) { 22163ca2b39bSJeremy L Thompson // Standard Operator 22173ca2b39bSJeremy L Thompson CeedCall(op->Apply(op, in, out, request)); 22183ca2b39bSJeremy L Thompson } else { 22190db52efcSZach Atkins // Standard or composite, default to zeroing out and calling ApplyAddActive 22200db52efcSZach Atkins // Zero active output 22210db52efcSZach Atkins if (out != CEED_VECTOR_NONE) CeedCall(CeedVectorSetValue(out, 0.0)); 22221203703bSJeremy L Thompson 22230db52efcSZach Atkins // ApplyAddActive 22240db52efcSZach Atkins CeedCall(CeedOperatorApplyAddActive(op, in, out, request)); 2225250756a7Sjeremylt } 2226e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2227cae8b89aSjeremylt } 2228cae8b89aSjeremylt 2229cae8b89aSjeremylt /** 2230ca94c3ddSJeremy L Thompson @brief Apply `CeedOperator` to a `CeedVector` and add result to output `CeedVector`. 2231cae8b89aSjeremylt 2232ea61e9acSJeremy L Thompson This computes the action of the operator on the specified (active) input, yielding its (active) output. 2233ca94c3ddSJeremy L Thompson All inputs and outputs must be specified using @ref CeedOperatorSetField(). 2234cae8b89aSjeremylt 22355da5ab9fSZach Atkins @note Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 22365da5ab9fSZach Atkins @warning This function adds into ALL outputs, including passive outputs. To only add into the active output, use `CeedOperatorApplyAddActive()`. 22375da5ab9fSZach Atkins @see `CeedOperatorApplyAddActive()` 22385da5ab9fSZach Atkins 2239ca94c3ddSJeremy L Thompson @param[in] op `CeedOperator` to apply 2240ca94c3ddSJeremy L Thompson @param[in] in `CeedVector` containing input state or @ref CEED_VECTOR_NONE if there are no active inputs 2241ca94c3ddSJeremy 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 2242ca94c3ddSJeremy L Thompson @param[in] request Address of @ref CeedRequest for non-blocking completion, else @ref CEED_REQUEST_IMMEDIATE 2243cae8b89aSjeremylt 2244cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 2245cae8b89aSjeremylt 22467a982d89SJeremy L. Thompson @ref User 2247cae8b89aSjeremylt **/ 22482b730f8bSJeremy L Thompson int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, CeedRequest *request) { 22491203703bSJeremy L Thompson bool is_composite; 22501203703bSJeremy L Thompson 22512b730f8bSJeremy L Thompson CeedCall(CeedOperatorCheckReady(op)); 2252cae8b89aSjeremylt 22531203703bSJeremy L Thompson CeedCall(CeedOperatorIsComposite(op, &is_composite)); 22541203703bSJeremy L Thompson if (is_composite) { 2255250756a7Sjeremylt // Composite Operator 2256250756a7Sjeremylt if (op->ApplyAddComposite) { 22572b730f8bSJeremy L Thompson CeedCall(op->ApplyAddComposite(op, in, out, request)); 2258cae8b89aSjeremylt } else { 2259d1d35e2fSjeremylt CeedInt num_suboperators; 2260d1d35e2fSjeremylt CeedOperator *sub_operators; 2261250756a7Sjeremylt 2262ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 2263ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 2264d1d35e2fSjeremylt for (CeedInt i = 0; i < num_suboperators; i++) { 22652b730f8bSJeremy L Thompson CeedCall(CeedOperatorApplyAdd(sub_operators[i], in, out, request)); 22661d7d2407SJeremy L Thompson } 2267250756a7Sjeremylt } 22681203703bSJeremy L Thompson } else if (op->num_elem > 0) { 22693ca2b39bSJeremy L Thompson // Standard Operator 22703ca2b39bSJeremy L Thompson CeedCall(op->ApplyAdd(op, in, out, request)); 2271250756a7Sjeremylt } 2272e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2273d7b241e6Sjeremylt } 2274d7b241e6Sjeremylt 2275d7b241e6Sjeremylt /** 22765da5ab9fSZach Atkins @brief Apply `CeedOperator` to a `CeedVector` and add result to output `CeedVector`. Only sums into active outputs, overwrites passive outputs. 22775da5ab9fSZach Atkins 22785da5ab9fSZach Atkins This computes the action of the operator on the specified (active) input, yielding its (active) output. 22795da5ab9fSZach Atkins All inputs and outputs must be specified using @ref CeedOperatorSetField(). 22805da5ab9fSZach Atkins 22815da5ab9fSZach Atkins @note Calling this function asserts that setup is complete and sets the `CeedOperator` as immutable. 22825da5ab9fSZach Atkins 22835da5ab9fSZach Atkins @param[in] op `CeedOperator` to apply 22845da5ab9fSZach Atkins @param[in] in `CeedVector` containing input state or @ref CEED_VECTOR_NONE if there are no active inputs 22855da5ab9fSZach 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 22865da5ab9fSZach Atkins @param[in] request Address of @ref CeedRequest for non-blocking completion, else @ref CEED_REQUEST_IMMEDIATE 22875da5ab9fSZach Atkins 22885da5ab9fSZach Atkins @return An error code: 0 - success, otherwise - failure 22895da5ab9fSZach Atkins 22905da5ab9fSZach Atkins @ref User 22915da5ab9fSZach Atkins **/ 22925da5ab9fSZach Atkins int CeedOperatorApplyAddActive(CeedOperator op, CeedVector in, CeedVector out, CeedRequest *request) { 22935da5ab9fSZach Atkins bool is_composite; 22945da5ab9fSZach Atkins 22955da5ab9fSZach Atkins CeedCall(CeedOperatorCheckReady(op)); 22965da5ab9fSZach Atkins 22975da5ab9fSZach Atkins CeedCall(CeedOperatorIsComposite(op, &is_composite)); 22985da5ab9fSZach Atkins if (is_composite) { 22995da5ab9fSZach Atkins // Composite Operator 23005da5ab9fSZach Atkins CeedInt num_suboperators; 23015da5ab9fSZach Atkins CeedOperator *sub_operators; 23025da5ab9fSZach Atkins 2303ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 2304ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 23055da5ab9fSZach Atkins 23065da5ab9fSZach Atkins // Zero all output vectors 23075da5ab9fSZach Atkins for (CeedInt i = 0; i < num_suboperators; i++) { 23085da5ab9fSZach Atkins CeedInt num_output_fields; 23095da5ab9fSZach Atkins CeedOperatorField *output_fields; 23105da5ab9fSZach Atkins 23115da5ab9fSZach Atkins CeedCall(CeedOperatorGetFields(sub_operators[i], NULL, NULL, &num_output_fields, &output_fields)); 23125da5ab9fSZach Atkins for (CeedInt j = 0; j < num_output_fields; j++) { 23135da5ab9fSZach Atkins CeedVector vec; 23145da5ab9fSZach Atkins 23155da5ab9fSZach Atkins CeedCall(CeedOperatorFieldGetVector(output_fields[j], &vec)); 23165da5ab9fSZach Atkins if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) CeedCall(CeedVectorSetValue(vec, 0.0)); 23175da5ab9fSZach Atkins CeedCall(CeedVectorDestroy(&vec)); 23185da5ab9fSZach Atkins } 23195da5ab9fSZach Atkins } 23205da5ab9fSZach Atkins // ApplyAdd 23215da5ab9fSZach Atkins CeedCall(CeedOperatorApplyAdd(op, in, out, request)); 23225da5ab9fSZach Atkins } else { 23235da5ab9fSZach Atkins // Standard Operator 23245da5ab9fSZach Atkins CeedInt num_output_fields; 23255da5ab9fSZach Atkins CeedOperatorField *output_fields; 23265da5ab9fSZach Atkins 23275da5ab9fSZach Atkins CeedCall(CeedOperatorGetFields(op, NULL, NULL, &num_output_fields, &output_fields)); 23285da5ab9fSZach Atkins // Zero all output vectors 23295da5ab9fSZach Atkins for (CeedInt i = 0; i < num_output_fields; i++) { 23305da5ab9fSZach Atkins CeedVector vec; 23315da5ab9fSZach Atkins 23325da5ab9fSZach Atkins CeedCall(CeedOperatorFieldGetVector(output_fields[i], &vec)); 23335da5ab9fSZach Atkins if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) CeedCall(CeedVectorSetValue(vec, 0.0)); 23345da5ab9fSZach Atkins CeedCall(CeedVectorDestroy(&vec)); 23355da5ab9fSZach Atkins } 23365da5ab9fSZach Atkins // ApplyAdd 23375da5ab9fSZach Atkins CeedCall(CeedOperatorApplyAdd(op, in, out, request)); 23385da5ab9fSZach Atkins } 23395da5ab9fSZach Atkins return CEED_ERROR_SUCCESS; 23405da5ab9fSZach Atkins } 23415da5ab9fSZach Atkins 23425da5ab9fSZach Atkins /** 2343536b928cSSebastian Grimberg @brief Destroy temporary assembly data associated with a `CeedOperator` 2344536b928cSSebastian Grimberg 2345536b928cSSebastian Grimberg @param[in,out] op `CeedOperator` whose assembly data to destroy 2346536b928cSSebastian Grimberg 2347536b928cSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 2348536b928cSSebastian Grimberg 2349536b928cSSebastian Grimberg @ref User 2350536b928cSSebastian Grimberg **/ 2351536b928cSSebastian Grimberg int CeedOperatorAssemblyDataStrip(CeedOperator op) { 2352536b928cSSebastian Grimberg bool is_composite; 2353536b928cSSebastian Grimberg 2354536b928cSSebastian Grimberg CeedCall(CeedQFunctionAssemblyDataDestroy(&op->qf_assembled)); 2355536b928cSSebastian Grimberg CeedCall(CeedOperatorAssemblyDataDestroy(&op->op_assembled)); 2356536b928cSSebastian Grimberg CeedCall(CeedOperatorIsComposite(op, &is_composite)); 2357536b928cSSebastian Grimberg if (is_composite) { 2358536b928cSSebastian Grimberg CeedInt num_suboperators; 2359536b928cSSebastian Grimberg CeedOperator *sub_operators; 2360536b928cSSebastian Grimberg 2361ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetNumSub(op, &num_suboperators)); 2362ed094490SJeremy L Thompson CeedCall(CeedOperatorCompositeGetSubList(op, &sub_operators)); 2363536b928cSSebastian Grimberg for (CeedInt i = 0; i < num_suboperators; i++) { 2364536b928cSSebastian Grimberg CeedCall(CeedQFunctionAssemblyDataDestroy(&sub_operators[i]->qf_assembled)); 2365536b928cSSebastian Grimberg CeedCall(CeedOperatorAssemblyDataDestroy(&sub_operators[i]->op_assembled)); 2366536b928cSSebastian Grimberg } 2367536b928cSSebastian Grimberg } 2368536b928cSSebastian Grimberg return CEED_ERROR_SUCCESS; 2369536b928cSSebastian Grimberg } 2370536b928cSSebastian Grimberg 2371536b928cSSebastian Grimberg /** 2372ca94c3ddSJeremy L Thompson @brief Destroy a `CeedOperator` 2373d7b241e6Sjeremylt 2374ca94c3ddSJeremy L Thompson @param[in,out] op `CeedOperator` to destroy 2375b11c1e72Sjeremylt 2376b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 2377dfdf5a53Sjeremylt 23787a982d89SJeremy L. Thompson @ref User 2379b11c1e72Sjeremylt **/ 2380d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 2381b0f67a9cSJeremy L Thompson if (!*op || CeedObjectDereference((CeedObject)*op) > 0) { 2382ad6481ceSJeremy L Thompson *op = NULL; 2383ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 2384ad6481ceSJeremy L Thompson } 2385f883f0a5SSebastian Grimberg // Backend destroy 2386f883f0a5SSebastian Grimberg if ((*op)->Destroy) { 2387f883f0a5SSebastian Grimberg CeedCall((*op)->Destroy(*op)); 2388f883f0a5SSebastian Grimberg } 2389fe2413ffSjeremylt // Free fields 23902b730f8bSJeremy L Thompson for (CeedInt i = 0; i < (*op)->num_fields; i++) { 2391d1d35e2fSjeremylt if ((*op)->input_fields[i]) { 2392437c7c90SJeremy L Thompson if ((*op)->input_fields[i]->elem_rstr != CEED_ELEMRESTRICTION_NONE) { 2393437c7c90SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&(*op)->input_fields[i]->elem_rstr)); 239415910d16Sjeremylt } 2395356036faSJeremy L Thompson if ((*op)->input_fields[i]->basis != CEED_BASIS_NONE) { 23962b730f8bSJeremy L Thompson CeedCall(CeedBasisDestroy(&(*op)->input_fields[i]->basis)); 239771352a93Sjeremylt } 23982b730f8bSJeremy L Thompson if ((*op)->input_fields[i]->vec != CEED_VECTOR_ACTIVE && (*op)->input_fields[i]->vec != CEED_VECTOR_NONE) { 23992b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&(*op)->input_fields[i]->vec)); 240071352a93Sjeremylt } 24012b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->input_fields[i]->field_name)); 24022b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->input_fields[i])); 2403fe2413ffSjeremylt } 24042b730f8bSJeremy L Thompson } 24052b730f8bSJeremy L Thompson for (CeedInt i = 0; i < (*op)->num_fields; i++) { 2406d1d35e2fSjeremylt if ((*op)->output_fields[i]) { 2407437c7c90SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&(*op)->output_fields[i]->elem_rstr)); 2408356036faSJeremy L Thompson if ((*op)->output_fields[i]->basis != CEED_BASIS_NONE) { 24092b730f8bSJeremy L Thompson CeedCall(CeedBasisDestroy(&(*op)->output_fields[i]->basis)); 241071352a93Sjeremylt } 24112b730f8bSJeremy L Thompson if ((*op)->output_fields[i]->vec != CEED_VECTOR_ACTIVE && (*op)->output_fields[i]->vec != CEED_VECTOR_NONE) { 24122b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&(*op)->output_fields[i]->vec)); 241371352a93Sjeremylt } 24142b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->output_fields[i]->field_name)); 24152b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->output_fields[i])); 24162b730f8bSJeremy L Thompson } 2417fe2413ffSjeremylt } 2418f883f0a5SSebastian Grimberg CeedCall(CeedFree(&(*op)->input_fields)); 2419f883f0a5SSebastian Grimberg CeedCall(CeedFree(&(*op)->output_fields)); 2420f883f0a5SSebastian Grimberg // Destroy AtPoints data 242148acf710SJeremy L Thompson CeedCall(CeedVectorDestroy(&(*op)->point_coords)); 242248acf710SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&(*op)->rstr_points)); 242348acf710SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(&(*op)->first_points_rstr)); 2424c6b536a8SSebastian Grimberg // Destroy assembly data (must happen before destroying sub_operators) 2425f883f0a5SSebastian Grimberg CeedCall(CeedOperatorAssemblyDataStrip(*op)); 2426d1d35e2fSjeremylt // Destroy sub_operators 24272b730f8bSJeremy L Thompson for (CeedInt i = 0; i < (*op)->num_suboperators; i++) { 2428d1d35e2fSjeremylt if ((*op)->sub_operators[i]) { 24292b730f8bSJeremy L Thompson CeedCall(CeedOperatorDestroy(&(*op)->sub_operators[i])); 243052d6035fSJeremy L Thompson } 24312b730f8bSJeremy L Thompson } 2432f883f0a5SSebastian Grimberg CeedCall(CeedFree(&(*op)->sub_operators)); 24332b730f8bSJeremy L Thompson CeedCall(CeedQFunctionDestroy(&(*op)->qf)); 24342b730f8bSJeremy L Thompson CeedCall(CeedQFunctionDestroy(&(*op)->dqf)); 24352b730f8bSJeremy L Thompson CeedCall(CeedQFunctionDestroy(&(*op)->dqfT)); 24363668ca4bSJeremy L Thompson // Destroy any composite labels 24375ac9af79SJeremy L Thompson if ((*op)->is_composite) { 24383668ca4bSJeremy L Thompson for (CeedInt i = 0; i < (*op)->num_context_labels; i++) { 24392b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->context_labels[i]->sub_labels)); 24402b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->context_labels[i])); 24413668ca4bSJeremy L Thompson } 24425ac9af79SJeremy L Thompson } 24432b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->context_labels)); 2444fe2413ffSjeremylt 24455107b09fSJeremy L Thompson // Destroy fallback 24462b730f8bSJeremy L Thompson CeedCall(CeedOperatorDestroy(&(*op)->op_fallback)); 24475107b09fSJeremy L Thompson 24482b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*op)->name)); 2449b0f67a9cSJeremy L Thompson CeedCall(CeedObjectDestroy(&(*op)->obj)); 24502b730f8bSJeremy L Thompson CeedCall(CeedFree(op)); 2451e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2452d7b241e6Sjeremylt } 2453d7b241e6Sjeremylt 2454d7b241e6Sjeremylt /// @} 2455