13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, 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 8ec3da8bcSJed Brown #include <ceed/ceed.h> 9ec3da8bcSJed Brown #include <ceed/backend.h> 103d576824SJeremy L Thompson #include <ceed-impl.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 /** 25e15f9bd0SJeremy L Thompson @brief Check if a CeedOperator Field matches the QFunction Field 26e15f9bd0SJeremy L Thompson 27e15f9bd0SJeremy L Thompson @param[in] ceed Ceed object for error handling 28d1d35e2fSjeremylt @param[in] qf_field QFunction Field matching Operator Field 29e15f9bd0SJeremy L Thompson @param[in] r Operator Field ElemRestriction 30e15f9bd0SJeremy L Thompson @param[in] b Operator Field Basis 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 **/ 36d1d35e2fSjeremylt static int CeedOperatorCheckField(Ceed ceed, CeedQFunctionField qf_field, 37e15f9bd0SJeremy L Thompson CeedElemRestriction r, CeedBasis b) { 38e15f9bd0SJeremy L Thompson int ierr; 39d1d35e2fSjeremylt CeedEvalMode eval_mode = qf_field->eval_mode; 40d1d35e2fSjeremylt CeedInt dim = 1, num_comp = 1, restr_num_comp = 1, size = qf_field->size; 41e15f9bd0SJeremy L Thompson // Restriction 42e15f9bd0SJeremy L Thompson if (r != CEED_ELEMRESTRICTION_NONE) { 43d1d35e2fSjeremylt if (eval_mode == CEED_EVAL_WEIGHT) { 44e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 45e1e9e29dSJed Brown return CeedError(ceed, CEED_ERROR_INCOMPATIBLE, 46e1e9e29dSJed Brown "CEED_ELEMRESTRICTION_NONE should be used " 47e15f9bd0SJeremy L Thompson "for a field with eval mode CEED_EVAL_WEIGHT"); 48e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 49e15f9bd0SJeremy L Thompson } 50d1d35e2fSjeremylt ierr = CeedElemRestrictionGetNumComponents(r, &restr_num_comp); 5178464608Sjeremylt CeedChk(ierr); 52e1e9e29dSJed Brown } 53d1d35e2fSjeremylt if ((r == CEED_ELEMRESTRICTION_NONE) != (eval_mode == CEED_EVAL_WEIGHT)) { 54e1e9e29dSJed Brown // LCOV_EXCL_START 55e1e9e29dSJed Brown return CeedError(ceed, CEED_ERROR_INCOMPATIBLE, 56e1e9e29dSJed Brown "CEED_ELEMRESTRICTION_NONE and CEED_EVAL_WEIGHT " 57e1e9e29dSJed Brown "must be used together."); 58e1e9e29dSJed Brown // LCOV_EXCL_STOP 59e1e9e29dSJed Brown } 60e15f9bd0SJeremy L Thompson // Basis 61e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 62d1d35e2fSjeremylt if (eval_mode == CEED_EVAL_NONE) 638229195eSjeremylt // LCOV_EXCL_START 64e1e9e29dSJed Brown return CeedError(ceed, CEED_ERROR_INCOMPATIBLE, 65d1d35e2fSjeremylt "Field '%s' configured with CEED_EVAL_NONE must " 66d1d35e2fSjeremylt "be used with CEED_BASIS_COLLOCATED", 678229195eSjeremylt // LCOV_EXCL_STOP 68d1d35e2fSjeremylt qf_field->field_name); 69e15f9bd0SJeremy L Thompson ierr = CeedBasisGetDimension(b, &dim); CeedChk(ierr); 70d1d35e2fSjeremylt ierr = CeedBasisGetNumComponents(b, &num_comp); CeedChk(ierr); 71d1d35e2fSjeremylt if (r != CEED_ELEMRESTRICTION_NONE && restr_num_comp != num_comp) { 72e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 73e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 74*990fdeb6SJeremy L Thompson "Field '%s' of size %" CeedInt_FMT " and EvalMode %s: ElemRestriction " 75*990fdeb6SJeremy L Thompson "has %" CeedInt_FMT " components, but Basis has %" CeedInt_FMT " components", 76d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], 77d1d35e2fSjeremylt restr_num_comp, 78d1d35e2fSjeremylt num_comp); 79e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 80e15f9bd0SJeremy L Thompson } 81e15f9bd0SJeremy L Thompson } 82e15f9bd0SJeremy L Thompson // Field size 83d1d35e2fSjeremylt switch(eval_mode) { 84e15f9bd0SJeremy L Thompson case CEED_EVAL_NONE: 85d1d35e2fSjeremylt if (size != restr_num_comp) 86e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 87e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 88*990fdeb6SJeremy L Thompson "Field '%s' of size %" CeedInt_FMT " and EvalMode %s: ElemRestriction has " 89*990fdeb6SJeremy L Thompson CeedInt_FMT " components", 90d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], 91d1d35e2fSjeremylt restr_num_comp); 92e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 93e15f9bd0SJeremy L Thompson break; 94e15f9bd0SJeremy L Thompson case CEED_EVAL_INTERP: 95d1d35e2fSjeremylt if (size != num_comp) 96e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 97e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 98*990fdeb6SJeremy L Thompson "Field '%s' of size %" CeedInt_FMT 99*990fdeb6SJeremy L Thompson " and EvalMode %s: ElemRestriction/Basis has " 100*990fdeb6SJeremy L Thompson CeedInt_FMT " components", 101d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], 102d1d35e2fSjeremylt num_comp); 103e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 104e15f9bd0SJeremy L Thompson break; 105e15f9bd0SJeremy L Thompson case CEED_EVAL_GRAD: 106d1d35e2fSjeremylt if (size != num_comp * dim) 107e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 108e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 109*990fdeb6SJeremy L Thompson "Field '%s' of size %" CeedInt_FMT " and EvalMode %s in %" CeedInt_FMT 110*990fdeb6SJeremy L Thompson " dimensions: " 111*990fdeb6SJeremy L Thompson "ElemRestriction/Basis has %" CeedInt_FMT " components", 112d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], dim, 113d1d35e2fSjeremylt num_comp); 114e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 115e15f9bd0SJeremy L Thompson break; 116e15f9bd0SJeremy L Thompson case CEED_EVAL_WEIGHT: 117d1d35e2fSjeremylt // No additional checks required 118e15f9bd0SJeremy L Thompson break; 119e15f9bd0SJeremy L Thompson case CEED_EVAL_DIV: 120e15f9bd0SJeremy L Thompson // Not implemented 121e15f9bd0SJeremy L Thompson break; 122e15f9bd0SJeremy L Thompson case CEED_EVAL_CURL: 123e15f9bd0SJeremy L Thompson // Not implemented 124e15f9bd0SJeremy L Thompson break; 125e15f9bd0SJeremy L Thompson } 126e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1277a982d89SJeremy L. Thompson } 1287a982d89SJeremy L. Thompson 1297a982d89SJeremy L. Thompson /** 1307a982d89SJeremy L. Thompson @brief View a field of a CeedOperator 1317a982d89SJeremy L. Thompson 1327a982d89SJeremy L. Thompson @param[in] field Operator field to view 133d1d35e2fSjeremylt @param[in] qf_field QFunction field (carries field name) 134d1d35e2fSjeremylt @param[in] field_number Number of field being viewed 1354c4400c7SValeria Barra @param[in] sub true indicates sub-operator, which increases indentation; false for top-level operator 136d1d35e2fSjeremylt @param[in] input true for an input field; false for output field 1377a982d89SJeremy L. Thompson @param[in] stream Stream to view to, e.g., stdout 1387a982d89SJeremy L. Thompson 1397a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1407a982d89SJeremy L. Thompson 1417a982d89SJeremy L. Thompson @ref Utility 1427a982d89SJeremy L. Thompson **/ 1437a982d89SJeremy L. Thompson static int CeedOperatorFieldView(CeedOperatorField field, 144d1d35e2fSjeremylt CeedQFunctionField qf_field, 145d1d35e2fSjeremylt CeedInt field_number, bool sub, bool input, 1467a982d89SJeremy L. Thompson FILE *stream) { 1477a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 148d1d35e2fSjeremylt const char *in_out = input ? "Input" : "Output"; 1497a982d89SJeremy L. Thompson 150*990fdeb6SJeremy L Thompson fprintf(stream, "%s %s field %" CeedInt_FMT ":\n" 1517a982d89SJeremy L. Thompson "%s Name: \"%s\"\n", 152d1d35e2fSjeremylt pre, in_out, field_number, pre, qf_field->field_name); 1537a982d89SJeremy L. Thompson 154*990fdeb6SJeremy L Thompson fprintf(stream, "%s Size: %" CeedInt_FMT "\n", pre, qf_field->size); 155f5ebfb90SJeremy L Thompson 156f5ebfb90SJeremy L Thompson fprintf(stream, "%s EvalMode: %s\n", pre, 157f5ebfb90SJeremy L Thompson CeedEvalModes[qf_field->eval_mode]); 158f5ebfb90SJeremy L Thompson 1597a982d89SJeremy L. Thompson if (field->basis == CEED_BASIS_COLLOCATED) 1607a982d89SJeremy L. Thompson fprintf(stream, "%s Collocated basis\n", pre); 1617a982d89SJeremy L. Thompson 1627a982d89SJeremy L. Thompson if (field->vec == CEED_VECTOR_ACTIVE) 1637a982d89SJeremy L. Thompson fprintf(stream, "%s Active vector\n", pre); 1647a982d89SJeremy L. Thompson else if (field->vec == CEED_VECTOR_NONE) 1657a982d89SJeremy L. Thompson fprintf(stream, "%s No vector\n", pre); 166f5ebfb90SJeremy L Thompson 167e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1687a982d89SJeremy L. Thompson } 1697a982d89SJeremy L. Thompson 1707a982d89SJeremy L. Thompson /** 1717a982d89SJeremy L. Thompson @brief View a single CeedOperator 1727a982d89SJeremy L. Thompson 1737a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 1747a982d89SJeremy L. Thompson @param[in] sub Boolean flag for sub-operator 1757a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 1767a982d89SJeremy L. Thompson 1777a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 1787a982d89SJeremy L. Thompson 1797a982d89SJeremy L. Thompson @ref Utility 1807a982d89SJeremy L. Thompson **/ 1817a982d89SJeremy L. Thompson int CeedOperatorSingleView(CeedOperator op, bool sub, FILE *stream) { 1827a982d89SJeremy L. Thompson int ierr; 1837a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 1847a982d89SJeremy L. Thompson 185381e6593SJeremy L Thompson CeedInt num_elem, num_qpts; 186381e6593SJeremy L Thompson ierr = CeedOperatorGetNumElements(op, &num_elem); CeedChk(ierr); 187381e6593SJeremy L Thompson ierr = CeedOperatorGetNumQuadraturePoints(op, &num_qpts); CeedChk(ierr); 188381e6593SJeremy L Thompson 18978464608Sjeremylt CeedInt total_fields = 0; 19078464608Sjeremylt ierr = CeedOperatorGetNumArgs(op, &total_fields); CeedChk(ierr); 191*990fdeb6SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " elements with %" CeedInt_FMT 192*990fdeb6SJeremy L Thompson " quadrature points each\n", 193381e6593SJeremy L Thompson pre, num_elem, num_qpts); 1947a982d89SJeremy L. Thompson 195*990fdeb6SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " field%s\n", pre, total_fields, 19678464608Sjeremylt total_fields>1 ? "s" : ""); 1977a982d89SJeremy L. Thompson 198*990fdeb6SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " input field%s:\n", pre, 199*990fdeb6SJeremy L Thompson op->qf->num_input_fields, 200d1d35e2fSjeremylt op->qf->num_input_fields>1 ? "s" : ""); 201d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_input_fields; i++) { 202d1d35e2fSjeremylt ierr = CeedOperatorFieldView(op->input_fields[i], op->qf->input_fields[i], 2037a982d89SJeremy L. Thompson i, sub, 1, stream); CeedChk(ierr); 2047a982d89SJeremy L. Thompson } 2057a982d89SJeremy L. Thompson 206*990fdeb6SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " output field%s:\n", pre, 207*990fdeb6SJeremy L Thompson op->qf->num_output_fields, 208d1d35e2fSjeremylt op->qf->num_output_fields>1 ? "s" : ""); 209d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_output_fields; i++) { 210d1d35e2fSjeremylt ierr = CeedOperatorFieldView(op->output_fields[i], op->qf->output_fields[i], 2117a982d89SJeremy L. Thompson i, sub, 0, stream); CeedChk(ierr); 2127a982d89SJeremy L. Thompson } 213e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2147a982d89SJeremy L. Thompson } 2157a982d89SJeremy L. Thompson 216d99fa3c5SJeremy L Thompson /** 2170f60e0a8SJeremy L Thompson @brief Find the active vector basis for a non-composite CeedOperator 218eaf62fffSJeremy L Thompson 219eaf62fffSJeremy L Thompson @param[in] op CeedOperator to find active basis for 2200f60e0a8SJeremy L Thompson @param[out] active_basis Basis for active input vector or NULL for composite operator 221eaf62fffSJeremy L Thompson 222eaf62fffSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 223eaf62fffSJeremy L Thompson 224eaf62fffSJeremy L Thompson @ ref Developer 225eaf62fffSJeremy L Thompson **/ 226eaf62fffSJeremy L Thompson int CeedOperatorGetActiveBasis(CeedOperator op, CeedBasis *active_basis) { 227eaf62fffSJeremy L Thompson *active_basis = NULL; 2280f60e0a8SJeremy L Thompson if (op->is_composite) return CEED_ERROR_SUCCESS; 22992ae7e47SJeremy L Thompson for (CeedInt i = 0; i < op->qf->num_input_fields; i++) 230eaf62fffSJeremy L Thompson if (op->input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 231eaf62fffSJeremy L Thompson *active_basis = op->input_fields[i]->basis; 232eaf62fffSJeremy L Thompson break; 233eaf62fffSJeremy L Thompson } 234eaf62fffSJeremy L Thompson 235eaf62fffSJeremy L Thompson if (!*active_basis) { 236eaf62fffSJeremy L Thompson // LCOV_EXCL_START 237eaf62fffSJeremy L Thompson int ierr; 238eaf62fffSJeremy L Thompson Ceed ceed; 239eaf62fffSJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 240eaf62fffSJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 241eaf62fffSJeremy L Thompson "No active CeedBasis found"); 242eaf62fffSJeremy L Thompson // LCOV_EXCL_STOP 243eaf62fffSJeremy L Thompson } 244eaf62fffSJeremy L Thompson return CEED_ERROR_SUCCESS; 245eaf62fffSJeremy L Thompson } 246eaf62fffSJeremy L Thompson 247eaf62fffSJeremy L Thompson /** 2480f60e0a8SJeremy L Thompson @brief Find the active vector ElemRestriction for a non-composite CeedOperator 249e2f04181SAndrew T. Barker 250e2f04181SAndrew T. Barker @param[in] op CeedOperator to find active basis for 2510f60e0a8SJeremy L Thompson @param[out] active_rstr ElemRestriction for active input vector or NULL for composite operator 252e2f04181SAndrew T. Barker 253e2f04181SAndrew T. Barker @return An error code: 0 - success, otherwise - failure 254e2f04181SAndrew T. Barker 255e2f04181SAndrew T. Barker @ref Utility 256e2f04181SAndrew T. Barker **/ 257eaf62fffSJeremy L Thompson int CeedOperatorGetActiveElemRestriction(CeedOperator op, 258d1d35e2fSjeremylt CeedElemRestriction *active_rstr) { 259d1d35e2fSjeremylt *active_rstr = NULL; 2600f60e0a8SJeremy L Thompson if (op->is_composite) return CEED_ERROR_SUCCESS; 26192ae7e47SJeremy L Thompson for (CeedInt i = 0; i < op->qf->num_input_fields; i++) 262d1d35e2fSjeremylt if (op->input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 263d1d35e2fSjeremylt *active_rstr = op->input_fields[i]->elem_restr; 264e2f04181SAndrew T. Barker break; 265e2f04181SAndrew T. Barker } 266e2f04181SAndrew T. Barker 267d1d35e2fSjeremylt if (!*active_rstr) { 268e2f04181SAndrew T. Barker // LCOV_EXCL_START 269e2f04181SAndrew T. Barker int ierr; 270e2f04181SAndrew T. Barker Ceed ceed; 271e2f04181SAndrew T. Barker ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 272e2f04181SAndrew T. Barker return CeedError(ceed, CEED_ERROR_INCOMPLETE, 273eaf62fffSJeremy L Thompson "No active CeedElemRestriction found"); 274e2f04181SAndrew T. Barker // LCOV_EXCL_STOP 275e2f04181SAndrew T. Barker } 276e2f04181SAndrew T. Barker return CEED_ERROR_SUCCESS; 277e2f04181SAndrew T. Barker } 278e2f04181SAndrew T. Barker 279d8dd9a91SJeremy L Thompson /** 280d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field value of the specified type. 281d8dd9a91SJeremy L Thompson For composite operators, the value is set in all 282d8dd9a91SJeremy L Thompson sub-operator QFunctionContexts that have a matching `field_name`. 283d8dd9a91SJeremy L Thompson A non-zero error code is returned for single operators 284d8dd9a91SJeremy L Thompson that do not have a matching field of the same type or composite 285d8dd9a91SJeremy L Thompson operators that do not have any field of a matching type. 286d8dd9a91SJeremy L Thompson 287d8dd9a91SJeremy L Thompson @param op CeedOperator 2883668ca4bSJeremy L Thompson @param field_label Label of field to set 289d8dd9a91SJeremy L Thompson @param field_type Type of field to set 290d8dd9a91SJeremy L Thompson @param value Value to set 291d8dd9a91SJeremy L Thompson 292d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 293d8dd9a91SJeremy L Thompson 294d8dd9a91SJeremy L Thompson @ref User 295d8dd9a91SJeremy L Thompson **/ 296d8dd9a91SJeremy L Thompson static int CeedOperatorContextSetGeneric(CeedOperator op, 2973668ca4bSJeremy L Thompson CeedContextFieldLabel field_label, CeedContextFieldType field_type, 2983668ca4bSJeremy L Thompson void *value) { 299d8dd9a91SJeremy L Thompson int ierr; 300d8dd9a91SJeremy L Thompson 3013668ca4bSJeremy L Thompson if (!field_label) 3023668ca4bSJeremy L Thompson // LCOV_EXCL_START 3033668ca4bSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_UNSUPPORTED, 3043668ca4bSJeremy L Thompson "Invalid field label"); 3053668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 3063668ca4bSJeremy L Thompson 3073668ca4bSJeremy L Thompson bool is_composite = false; 308d8dd9a91SJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 309d8dd9a91SJeremy L Thompson if (is_composite) { 310d8dd9a91SJeremy L Thompson CeedInt num_sub; 311d8dd9a91SJeremy L Thompson CeedOperator *sub_operators; 312d8dd9a91SJeremy L Thompson 313d8dd9a91SJeremy L Thompson ierr = CeedOperatorGetNumSub(op, &num_sub); CeedChk(ierr); 314d8dd9a91SJeremy L Thompson ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 3153668ca4bSJeremy L Thompson if (num_sub != field_label->num_sub_labels) 3163668ca4bSJeremy L Thompson // LCOV_EXCL_START 3173668ca4bSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_UNSUPPORTED, 3183668ca4bSJeremy L Thompson "ContextLabel does not correspond to composite operator.\n" 3193668ca4bSJeremy L Thompson "Use CeedOperatorGetContextFieldLabel()."); 3203668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 321d8dd9a91SJeremy L Thompson 322d8dd9a91SJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 323d8dd9a91SJeremy L Thompson // Try every sub-operator, ok if some sub-operators do not have field 3243668ca4bSJeremy L Thompson if (field_label->sub_labels[i] && sub_operators[i]->qf->ctx) { 3253668ca4bSJeremy L Thompson ierr = CeedQFunctionContextSetGeneric(sub_operators[i]->qf->ctx, 3263668ca4bSJeremy L Thompson field_label->sub_labels[i], 3273668ca4bSJeremy L Thompson field_type, value); CeedChk(ierr); 328d8dd9a91SJeremy L Thompson } 329d8dd9a91SJeremy L Thompson } 330d8dd9a91SJeremy L Thompson } else { 331d8dd9a91SJeremy L Thompson if (!op->qf->ctx) 332d8dd9a91SJeremy L Thompson // LCOV_EXCL_START 333d8dd9a91SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_UNSUPPORTED, 334d8dd9a91SJeremy L Thompson "QFunction does not have context data"); 335d8dd9a91SJeremy L Thompson // LCOV_EXCL_STOP 336d8dd9a91SJeremy L Thompson 3373668ca4bSJeremy L Thompson ierr = CeedQFunctionContextSetGeneric(op->qf->ctx, field_label, 3383668ca4bSJeremy L Thompson field_type, value); CeedChk(ierr); 339d8dd9a91SJeremy L Thompson } 340d8dd9a91SJeremy L Thompson 341d8dd9a91SJeremy L Thompson return CEED_ERROR_SUCCESS; 342d8dd9a91SJeremy L Thompson } 343d8dd9a91SJeremy L Thompson 3447a982d89SJeremy L. Thompson /// @} 3457a982d89SJeremy L. Thompson 3467a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3477a982d89SJeremy L. Thompson /// CeedOperator Backend API 3487a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3497a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorBackend 3507a982d89SJeremy L. Thompson /// @{ 3517a982d89SJeremy L. Thompson 3527a982d89SJeremy L. Thompson /** 3537a982d89SJeremy L. Thompson @brief Get the number of arguments associated with a CeedOperator 3547a982d89SJeremy L. Thompson 3557a982d89SJeremy L. Thompson @param op CeedOperator 356d1d35e2fSjeremylt @param[out] num_args Variable to store vector number of arguments 3577a982d89SJeremy L. Thompson 3587a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3597a982d89SJeremy L. Thompson 3607a982d89SJeremy L. Thompson @ref Backend 3617a982d89SJeremy L. Thompson **/ 3627a982d89SJeremy L. Thompson 363d1d35e2fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *num_args) { 364f04ea552SJeremy L Thompson if (op->is_composite) 3657a982d89SJeremy L. Thompson // LCOV_EXCL_START 366e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 367e15f9bd0SJeremy L Thompson "Not defined for composite operators"); 3687a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 3697a982d89SJeremy L. Thompson 370d1d35e2fSjeremylt *num_args = op->num_fields; 371e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3727a982d89SJeremy L. Thompson } 3737a982d89SJeremy L. Thompson 3747a982d89SJeremy L. Thompson /** 3757a982d89SJeremy L. Thompson @brief Get the setup status of a CeedOperator 3767a982d89SJeremy L. Thompson 3777a982d89SJeremy L. Thompson @param op CeedOperator 378d1d35e2fSjeremylt @param[out] is_setup_done Variable to store setup status 3797a982d89SJeremy L. Thompson 3807a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3817a982d89SJeremy L. Thompson 3827a982d89SJeremy L. Thompson @ref Backend 3837a982d89SJeremy L. Thompson **/ 3847a982d89SJeremy L. Thompson 385d1d35e2fSjeremylt int CeedOperatorIsSetupDone(CeedOperator op, bool *is_setup_done) { 386f04ea552SJeremy L Thompson *is_setup_done = op->is_backend_setup; 387e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3887a982d89SJeremy L. Thompson } 3897a982d89SJeremy L. Thompson 3907a982d89SJeremy L. Thompson /** 3917a982d89SJeremy L. Thompson @brief Get the QFunction associated with a CeedOperator 3927a982d89SJeremy L. Thompson 3937a982d89SJeremy L. Thompson @param op CeedOperator 3947a982d89SJeremy L. Thompson @param[out] qf Variable to store QFunction 3957a982d89SJeremy L. Thompson 3967a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3977a982d89SJeremy L. Thompson 3987a982d89SJeremy L. Thompson @ref Backend 3997a982d89SJeremy L. Thompson **/ 4007a982d89SJeremy L. Thompson 4017a982d89SJeremy L. Thompson int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 402f04ea552SJeremy L Thompson if (op->is_composite) 4037a982d89SJeremy L. Thompson // LCOV_EXCL_START 404e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 405e15f9bd0SJeremy L Thompson "Not defined for composite operator"); 4067a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4077a982d89SJeremy L. Thompson 4087a982d89SJeremy L. Thompson *qf = op->qf; 409e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4107a982d89SJeremy L. Thompson } 4117a982d89SJeremy L. Thompson 4127a982d89SJeremy L. Thompson /** 413c04a41a7SJeremy L Thompson @brief Get a boolean value indicating if the CeedOperator is composite 414c04a41a7SJeremy L Thompson 415c04a41a7SJeremy L Thompson @param op CeedOperator 416d1d35e2fSjeremylt @param[out] is_composite Variable to store composite status 417c04a41a7SJeremy L Thompson 418c04a41a7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 419c04a41a7SJeremy L Thompson 420c04a41a7SJeremy L Thompson @ref Backend 421c04a41a7SJeremy L Thompson **/ 422c04a41a7SJeremy L Thompson 423d1d35e2fSjeremylt int CeedOperatorIsComposite(CeedOperator op, bool *is_composite) { 424f04ea552SJeremy L Thompson *is_composite = op->is_composite; 425e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 426c04a41a7SJeremy L Thompson } 427c04a41a7SJeremy L Thompson 428c04a41a7SJeremy L Thompson /** 429d1d35e2fSjeremylt @brief Get the number of sub_operators associated with a CeedOperator 4307a982d89SJeremy L. Thompson 4317a982d89SJeremy L. Thompson @param op CeedOperator 432d1d35e2fSjeremylt @param[out] num_suboperators Variable to store number of sub_operators 4337a982d89SJeremy L. Thompson 4347a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4357a982d89SJeremy L. Thompson 4367a982d89SJeremy L. Thompson @ref Backend 4377a982d89SJeremy L. Thompson **/ 4387a982d89SJeremy L. Thompson 439d1d35e2fSjeremylt int CeedOperatorGetNumSub(CeedOperator op, CeedInt *num_suboperators) { 440f04ea552SJeremy L Thompson if (!op->is_composite) 4417a982d89SJeremy L. Thompson // LCOV_EXCL_START 442e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 4437a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4447a982d89SJeremy L. Thompson 445d1d35e2fSjeremylt *num_suboperators = op->num_suboperators; 446e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4477a982d89SJeremy L. Thompson } 4487a982d89SJeremy L. Thompson 4497a982d89SJeremy L. Thompson /** 450d1d35e2fSjeremylt @brief Get the list of sub_operators associated with a CeedOperator 4517a982d89SJeremy L. Thompson 4527a982d89SJeremy L. Thompson @param op CeedOperator 453d1d35e2fSjeremylt @param[out] sub_operators Variable to store list of sub_operators 4547a982d89SJeremy L. Thompson 4557a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4567a982d89SJeremy L. Thompson 4577a982d89SJeremy L. Thompson @ref Backend 4587a982d89SJeremy L. Thompson **/ 4597a982d89SJeremy L. Thompson 460d1d35e2fSjeremylt int CeedOperatorGetSubList(CeedOperator op, CeedOperator **sub_operators) { 461f04ea552SJeremy L Thompson if (!op->is_composite) 4627a982d89SJeremy L. Thompson // LCOV_EXCL_START 463e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 4647a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4657a982d89SJeremy L. Thompson 466d1d35e2fSjeremylt *sub_operators = op->sub_operators; 467e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4687a982d89SJeremy L. Thompson } 4697a982d89SJeremy L. Thompson 4707a982d89SJeremy L. Thompson /** 4717a982d89SJeremy L. Thompson @brief Get the backend data of a CeedOperator 4727a982d89SJeremy L. Thompson 4737a982d89SJeremy L. Thompson @param op CeedOperator 4747a982d89SJeremy L. Thompson @param[out] data Variable to store data 4757a982d89SJeremy L. Thompson 4767a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4777a982d89SJeremy L. Thompson 4787a982d89SJeremy L. Thompson @ref Backend 4797a982d89SJeremy L. Thompson **/ 4807a982d89SJeremy L. Thompson 481777ff853SJeremy L Thompson int CeedOperatorGetData(CeedOperator op, void *data) { 482777ff853SJeremy L Thompson *(void **)data = op->data; 483e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4847a982d89SJeremy L. Thompson } 4857a982d89SJeremy L. Thompson 4867a982d89SJeremy L. Thompson /** 4877a982d89SJeremy L. Thompson @brief Set the backend data of a CeedOperator 4887a982d89SJeremy L. Thompson 4897a982d89SJeremy L. Thompson @param[out] op CeedOperator 4907a982d89SJeremy L. Thompson @param data Data to set 4917a982d89SJeremy L. Thompson 4927a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4937a982d89SJeremy L. Thompson 4947a982d89SJeremy L. Thompson @ref Backend 4957a982d89SJeremy L. Thompson **/ 4967a982d89SJeremy L. Thompson 497777ff853SJeremy L Thompson int CeedOperatorSetData(CeedOperator op, void *data) { 498777ff853SJeremy L Thompson op->data = data; 499e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5007a982d89SJeremy L. Thompson } 5017a982d89SJeremy L. Thompson 5027a982d89SJeremy L. Thompson /** 50334359f16Sjeremylt @brief Increment the reference counter for a CeedOperator 50434359f16Sjeremylt 50534359f16Sjeremylt @param op CeedOperator to increment the reference counter 50634359f16Sjeremylt 50734359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 50834359f16Sjeremylt 50934359f16Sjeremylt @ref Backend 51034359f16Sjeremylt **/ 5119560d06aSjeremylt int CeedOperatorReference(CeedOperator op) { 51234359f16Sjeremylt op->ref_count++; 51334359f16Sjeremylt return CEED_ERROR_SUCCESS; 51434359f16Sjeremylt } 51534359f16Sjeremylt 51634359f16Sjeremylt /** 5177a982d89SJeremy L. Thompson @brief Set the setup flag of a CeedOperator to True 5187a982d89SJeremy L. Thompson 5197a982d89SJeremy L. Thompson @param op CeedOperator 5207a982d89SJeremy L. Thompson 5217a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5227a982d89SJeremy L. Thompson 5237a982d89SJeremy L. Thompson @ref Backend 5247a982d89SJeremy L. Thompson **/ 5257a982d89SJeremy L. Thompson 5267a982d89SJeremy L. Thompson int CeedOperatorSetSetupDone(CeedOperator op) { 527f04ea552SJeremy L Thompson op->is_backend_setup = true; 528e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5297a982d89SJeremy L. Thompson } 5307a982d89SJeremy L. Thompson 5317a982d89SJeremy L. Thompson /// @} 5327a982d89SJeremy L. Thompson 5337a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5347a982d89SJeremy L. Thompson /// CeedOperator Public API 5357a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5367a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorUser 537dfdf5a53Sjeremylt /// @{ 538d7b241e6Sjeremylt 539d7b241e6Sjeremylt /** 5400219ea01SJeremy L Thompson @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and 5410219ea01SJeremy L Thompson CeedElemRestriction can be associated with CeedQFunction fields with 5420219ea01SJeremy L Thompson \ref CeedOperatorSetField. 543d7b241e6Sjeremylt 544b11c1e72Sjeremylt @param ceed A Ceed object where the CeedOperator will be created 545d7b241e6Sjeremylt @param qf QFunction defining the action of the operator at quadrature points 54634138859Sjeremylt @param dqf QFunction defining the action of the Jacobian of @a qf (or 5474cc79fe7SJed Brown @ref CEED_QFUNCTION_NONE) 548d7b241e6Sjeremylt @param dqfT QFunction defining the action of the transpose of the Jacobian 5494cc79fe7SJed Brown of @a qf (or @ref CEED_QFUNCTION_NONE) 550b11c1e72Sjeremylt @param[out] op Address of the variable where the newly created 551b11c1e72Sjeremylt CeedOperator will be stored 552b11c1e72Sjeremylt 553b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 554dfdf5a53Sjeremylt 5557a982d89SJeremy L. Thompson @ref User 556d7b241e6Sjeremylt */ 557d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, 558d7b241e6Sjeremylt CeedQFunction dqfT, CeedOperator *op) { 559d7b241e6Sjeremylt int ierr; 560d7b241e6Sjeremylt 5615fe0d4faSjeremylt if (!ceed->OperatorCreate) { 5625fe0d4faSjeremylt Ceed delegate; 563aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 5645fe0d4faSjeremylt 5655fe0d4faSjeremylt if (!delegate) 566c042f62fSJeremy L Thompson // LCOV_EXCL_START 567e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 568e15f9bd0SJeremy L Thompson "Backend does not support OperatorCreate"); 569c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 5705fe0d4faSjeremylt 5715fe0d4faSjeremylt ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr); 572e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5735fe0d4faSjeremylt } 5745fe0d4faSjeremylt 575b3b7035fSJeremy L Thompson if (!qf || qf == CEED_QFUNCTION_NONE) 576b3b7035fSJeremy L Thompson // LCOV_EXCL_START 577e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 578e15f9bd0SJeremy L Thompson "Operator must have a valid QFunction."); 579b3b7035fSJeremy L Thompson // LCOV_EXCL_STOP 580d7b241e6Sjeremylt ierr = CeedCalloc(1, op); CeedChk(ierr); 581d7b241e6Sjeremylt (*op)->ceed = ceed; 5829560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 583d1d35e2fSjeremylt (*op)->ref_count = 1; 584d7b241e6Sjeremylt (*op)->qf = qf; 5852b104005SJeremy L Thompson (*op)->input_size = -1; 5862b104005SJeremy L Thompson (*op)->output_size = -1; 5879560d06aSjeremylt ierr = CeedQFunctionReference(qf); CeedChk(ierr); 588442e7f0bSjeremylt if (dqf && dqf != CEED_QFUNCTION_NONE) { 589d7b241e6Sjeremylt (*op)->dqf = dqf; 5909560d06aSjeremylt ierr = CeedQFunctionReference(dqf); CeedChk(ierr); 591442e7f0bSjeremylt } 592442e7f0bSjeremylt if (dqfT && dqfT != CEED_QFUNCTION_NONE) { 593d7b241e6Sjeremylt (*op)->dqfT = dqfT; 5949560d06aSjeremylt ierr = CeedQFunctionReference(dqfT); CeedChk(ierr); 595442e7f0bSjeremylt } 596480fae85SJeremy L Thompson ierr = CeedQFunctionAssemblyDataCreate(ceed, &(*op)->qf_assembled); 597480fae85SJeremy L Thompson CeedChk(ierr); 598bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_FIELD_MAX, &(*op)->input_fields); CeedChk(ierr); 599bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_FIELD_MAX, &(*op)->output_fields); CeedChk(ierr); 600d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 601e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 602d7b241e6Sjeremylt } 603d7b241e6Sjeremylt 604d7b241e6Sjeremylt /** 60552d6035fSJeremy L Thompson @brief Create an operator that composes the action of several operators 60652d6035fSJeremy L Thompson 60752d6035fSJeremy L Thompson @param ceed A Ceed object where the CeedOperator will be created 60852d6035fSJeremy L Thompson @param[out] op Address of the variable where the newly created 60952d6035fSJeremy L Thompson Composite CeedOperator will be stored 61052d6035fSJeremy L Thompson 61152d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 61252d6035fSJeremy L Thompson 6137a982d89SJeremy L. Thompson @ref User 61452d6035fSJeremy L Thompson */ 61552d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) { 61652d6035fSJeremy L Thompson int ierr; 61752d6035fSJeremy L Thompson 61852d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 61952d6035fSJeremy L Thompson Ceed delegate; 620aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 62152d6035fSJeremy L Thompson 622250756a7Sjeremylt if (delegate) { 62352d6035fSJeremy L Thompson ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr); 624e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 62552d6035fSJeremy L Thompson } 626250756a7Sjeremylt } 62752d6035fSJeremy L Thompson 62852d6035fSJeremy L Thompson ierr = CeedCalloc(1, op); CeedChk(ierr); 62952d6035fSJeremy L Thompson (*op)->ceed = ceed; 6309560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 631f04ea552SJeremy L Thompson (*op)->is_composite = true; 632bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_COMPOSITE_MAX, &(*op)->sub_operators); CeedChk(ierr); 6332b104005SJeremy L Thompson (*op)->input_size = -1; 6342b104005SJeremy L Thompson (*op)->output_size = -1; 635250756a7Sjeremylt 636250756a7Sjeremylt if (ceed->CompositeOperatorCreate) { 63752d6035fSJeremy L Thompson ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr); 638250756a7Sjeremylt } 639e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 64052d6035fSJeremy L Thompson } 64152d6035fSJeremy L Thompson 64252d6035fSJeremy L Thompson /** 6439560d06aSjeremylt @brief Copy the pointer to a CeedOperator. Both pointers should 6449560d06aSjeremylt be destroyed with `CeedOperatorDestroy()`; 6459560d06aSjeremylt Note: If `*op_copy` is non-NULL, then it is assumed that 6469560d06aSjeremylt `*op_copy` is a pointer to a CeedOperator. This 6479560d06aSjeremylt CeedOperator will be destroyed if `*op_copy` is the only 6489560d06aSjeremylt reference to this CeedOperator. 6499560d06aSjeremylt 6509560d06aSjeremylt @param op CeedOperator to copy reference to 6519560d06aSjeremylt @param[out] op_copy Variable to store copied reference 6529560d06aSjeremylt 6539560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 6549560d06aSjeremylt 6559560d06aSjeremylt @ref User 6569560d06aSjeremylt **/ 6579560d06aSjeremylt int CeedOperatorReferenceCopy(CeedOperator op, CeedOperator *op_copy) { 6589560d06aSjeremylt int ierr; 6599560d06aSjeremylt 6609560d06aSjeremylt ierr = CeedOperatorReference(op); CeedChk(ierr); 6619560d06aSjeremylt ierr = CeedOperatorDestroy(op_copy); CeedChk(ierr); 6629560d06aSjeremylt *op_copy = op; 6639560d06aSjeremylt return CEED_ERROR_SUCCESS; 6649560d06aSjeremylt } 6659560d06aSjeremylt 6669560d06aSjeremylt /** 667b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 668d7b241e6Sjeremylt 669d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 670d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 671d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 672d7b241e6Sjeremylt 673d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 674d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 675979e564eSJames Wright input CeedVector and at most one active output CeedVector passed to 676979e564eSJames Wright CeedOperatorApply(). 677d7b241e6Sjeremylt 6788c91a0c9SJeremy L Thompson @param op CeedOperator on which to provide the field 679d1d35e2fSjeremylt @param field_name Name of the field (to be matched with the name used by 6808795c945Sjeremylt CeedQFunction) 681b11c1e72Sjeremylt @param r CeedElemRestriction 6824cc79fe7SJed Brown @param b CeedBasis in which the field resides or @ref CEED_BASIS_COLLOCATED 683b11c1e72Sjeremylt if collocated with quadrature points 6844cc79fe7SJed Brown @param v CeedVector to be used by CeedOperator or @ref CEED_VECTOR_ACTIVE 6854cc79fe7SJed Brown if field is active or @ref CEED_VECTOR_NONE if using 6864cc79fe7SJed Brown @ref CEED_EVAL_WEIGHT in the QFunction 687b11c1e72Sjeremylt 688b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 689dfdf5a53Sjeremylt 6907a982d89SJeremy L. Thompson @ref User 691b11c1e72Sjeremylt **/ 692d1d35e2fSjeremylt int CeedOperatorSetField(CeedOperator op, const char *field_name, 693a8d32208Sjeremylt CeedElemRestriction r, CeedBasis b, CeedVector v) { 694d7b241e6Sjeremylt int ierr; 695f04ea552SJeremy L Thompson if (op->is_composite) 696c042f62fSJeremy L Thompson // LCOV_EXCL_START 697e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 698e15f9bd0SJeremy L Thompson "Cannot add field to composite operator."); 699c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 700f04ea552SJeremy L Thompson if (op->is_immutable) 701f04ea552SJeremy L Thompson // LCOV_EXCL_START 702f04ea552SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 703f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 704f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 7058b067b84SJed Brown if (!r) 706c042f62fSJeremy L Thompson // LCOV_EXCL_START 707e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 708c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 709d1d35e2fSjeremylt field_name); 710c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 7118b067b84SJed Brown if (!b) 712c042f62fSJeremy L Thompson // LCOV_EXCL_START 713e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 714e15f9bd0SJeremy L Thompson "Basis b for field \"%s\" must be non-NULL.", 715d1d35e2fSjeremylt field_name); 716c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 7178b067b84SJed Brown if (!v) 718c042f62fSJeremy L Thompson // LCOV_EXCL_START 719e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 720e15f9bd0SJeremy L Thompson "Vector v for field \"%s\" must be non-NULL.", 721d1d35e2fSjeremylt field_name); 722c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 72352d6035fSJeremy L Thompson 724d1d35e2fSjeremylt CeedInt num_elem; 725d1d35e2fSjeremylt ierr = CeedElemRestrictionGetNumElements(r, &num_elem); CeedChk(ierr); 726d1d35e2fSjeremylt if (r != CEED_ELEMRESTRICTION_NONE && op->has_restriction && 727d1d35e2fSjeremylt op->num_elem != num_elem) 728c042f62fSJeremy L Thompson // LCOV_EXCL_START 729e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 730*990fdeb6SJeremy L Thompson "ElemRestriction with %" CeedInt_FMT " elements incompatible with prior " 731*990fdeb6SJeremy L Thompson CeedInt_FMT " elements", num_elem, op->num_elem); 732c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 733d7b241e6Sjeremylt 73478464608Sjeremylt CeedInt num_qpts = 0; 735e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 736d1d35e2fSjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &num_qpts); CeedChk(ierr); 737d1d35e2fSjeremylt if (op->num_qpts && op->num_qpts != num_qpts) 738c042f62fSJeremy L Thompson // LCOV_EXCL_START 739e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 740*990fdeb6SJeremy L Thompson "Basis with %" CeedInt_FMT " quadrature points " 741*990fdeb6SJeremy L Thompson "incompatible with prior %" CeedInt_FMT " points", num_qpts, 742d1d35e2fSjeremylt op->num_qpts); 743c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 744d7b241e6Sjeremylt } 745d1d35e2fSjeremylt CeedQFunctionField qf_field; 746d1d35e2fSjeremylt CeedOperatorField *op_field; 7472b104005SJeremy L Thompson bool is_input = true; 748d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_input_fields; i++) { 749d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->input_fields[i]).field_name)) { 750d1d35e2fSjeremylt qf_field = op->qf->input_fields[i]; 751d1d35e2fSjeremylt op_field = &op->input_fields[i]; 752d7b241e6Sjeremylt goto found; 753d7b241e6Sjeremylt } 754d7b241e6Sjeremylt } 7552b104005SJeremy L Thompson is_input = false; 756d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_output_fields; i++) { 757d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->output_fields[i]).field_name)) { 758d1d35e2fSjeremylt qf_field = op->qf->output_fields[i]; 759d1d35e2fSjeremylt op_field = &op->output_fields[i]; 760d7b241e6Sjeremylt goto found; 761d7b241e6Sjeremylt } 762d7b241e6Sjeremylt } 763c042f62fSJeremy L Thompson // LCOV_EXCL_START 764e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPLETE, 765e15f9bd0SJeremy L Thompson "QFunction has no knowledge of field '%s'", 766d1d35e2fSjeremylt field_name); 767c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 768d7b241e6Sjeremylt found: 769d1d35e2fSjeremylt ierr = CeedOperatorCheckField(op->ceed, qf_field, r, b); CeedChk(ierr); 770d1d35e2fSjeremylt ierr = CeedCalloc(1, op_field); CeedChk(ierr); 771e15f9bd0SJeremy L Thompson 7722b104005SJeremy L Thompson if (v == CEED_VECTOR_ACTIVE) { 7732b104005SJeremy L Thompson CeedSize l_size; 7742b104005SJeremy L Thompson ierr = CeedElemRestrictionGetLVectorSize(r, &l_size); CeedChk(ierr); 7752b104005SJeremy L Thompson if (is_input) { 7762b104005SJeremy L Thompson if (op->input_size == -1) op->input_size = l_size; 7772b104005SJeremy L Thompson if (l_size != op->input_size) 7782b104005SJeremy L Thompson // LCOV_EXCL_START 7792b104005SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 7802b104005SJeremy L Thompson "LVector size %td does not match previous size %td", 7812b104005SJeremy L Thompson l_size, op->input_size); 7822b104005SJeremy L Thompson // LCOV_EXCL_STOP 7832b104005SJeremy L Thompson } else { 7842b104005SJeremy L Thompson if (op->output_size == -1) op->output_size = l_size; 7852b104005SJeremy L Thompson if (l_size != op->output_size) 7862b104005SJeremy L Thompson // LCOV_EXCL_START 7872b104005SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 7882b104005SJeremy L Thompson "LVector size %td does not match previous size %td", 7892b104005SJeremy L Thompson l_size, op->output_size); 7902b104005SJeremy L Thompson // LCOV_EXCL_STOP 7912b104005SJeremy L Thompson } 7922b104005SJeremy L Thompson } 7932b104005SJeremy L Thompson 794d1d35e2fSjeremylt (*op_field)->vec = v; 795e15f9bd0SJeremy L Thompson if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) { 7969560d06aSjeremylt ierr = CeedVectorReference(v); CeedChk(ierr); 797e15f9bd0SJeremy L Thompson } 798e15f9bd0SJeremy L Thompson 799d1d35e2fSjeremylt (*op_field)->elem_restr = r; 8009560d06aSjeremylt ierr = CeedElemRestrictionReference(r); CeedChk(ierr); 801e15f9bd0SJeremy L Thompson if (r != CEED_ELEMRESTRICTION_NONE) { 802d1d35e2fSjeremylt op->num_elem = num_elem; 803d1d35e2fSjeremylt op->has_restriction = true; // Restriction set, but num_elem may be 0 804e15f9bd0SJeremy L Thompson } 805d99fa3c5SJeremy L Thompson 806d1d35e2fSjeremylt (*op_field)->basis = b; 807e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 808cd4dfc48Sjeremylt if (!op->num_qpts) { 809cd4dfc48Sjeremylt ierr = CeedOperatorSetNumQuadraturePoints(op, num_qpts); CeedChk(ierr); 810cd4dfc48Sjeremylt } 8119560d06aSjeremylt ierr = CeedBasisReference(b); CeedChk(ierr); 812e15f9bd0SJeremy L Thompson } 813e15f9bd0SJeremy L Thompson 814d1d35e2fSjeremylt op->num_fields += 1; 815f7e22acaSJeremy L Thompson ierr = CeedStringAllocCopy(field_name, (char **)&(*op_field)->field_name); 816f7e22acaSJeremy L Thompson CeedChk(ierr); 817e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 818d7b241e6Sjeremylt } 819d7b241e6Sjeremylt 820d7b241e6Sjeremylt /** 82143bbe138SJeremy L Thompson @brief Get the CeedOperatorFields of a CeedOperator 82243bbe138SJeremy L Thompson 823f04ea552SJeremy L Thompson Note: Calling this function asserts that setup is complete 824f04ea552SJeremy L Thompson and sets the CeedOperator as immutable. 825f04ea552SJeremy L Thompson 82643bbe138SJeremy L Thompson @param op CeedOperator 827f74ec584SJeremy L Thompson @param[out] num_input_fields Variable to store number of input fields 82843bbe138SJeremy L Thompson @param[out] input_fields Variable to store input_fields 829f74ec584SJeremy L Thompson @param[out] num_output_fields Variable to store number of output fields 83043bbe138SJeremy L Thompson @param[out] output_fields Variable to store output_fields 83143bbe138SJeremy L Thompson 83243bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 83343bbe138SJeremy L Thompson 834e9b533fbSJeremy L Thompson @ref Advanced 83543bbe138SJeremy L Thompson **/ 83643bbe138SJeremy L Thompson int CeedOperatorGetFields(CeedOperator op, CeedInt *num_input_fields, 83743bbe138SJeremy L Thompson CeedOperatorField **input_fields, 83843bbe138SJeremy L Thompson CeedInt *num_output_fields, 83943bbe138SJeremy L Thompson CeedOperatorField **output_fields) { 840f04ea552SJeremy L Thompson int ierr; 841f04ea552SJeremy L Thompson 842f04ea552SJeremy L Thompson if (op->is_composite) 84343bbe138SJeremy L Thompson // LCOV_EXCL_START 84443bbe138SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 84543bbe138SJeremy L Thompson "Not defined for composite operator"); 84643bbe138SJeremy L Thompson // LCOV_EXCL_STOP 847f04ea552SJeremy L Thompson ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 84843bbe138SJeremy L Thompson 84943bbe138SJeremy L Thompson if (num_input_fields) *num_input_fields = op->qf->num_input_fields; 85043bbe138SJeremy L Thompson if (input_fields) *input_fields = op->input_fields; 85143bbe138SJeremy L Thompson if (num_output_fields) *num_output_fields = op->qf->num_output_fields; 85243bbe138SJeremy L Thompson if (output_fields) *output_fields = op->output_fields; 85343bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 85443bbe138SJeremy L Thompson } 85543bbe138SJeremy L Thompson 85643bbe138SJeremy L Thompson /** 85728567f8fSJeremy L Thompson @brief Get the name of a CeedOperatorField 85828567f8fSJeremy L Thompson 85928567f8fSJeremy L Thompson @param op_field CeedOperatorField 86028567f8fSJeremy L Thompson @param[out] field_name Variable to store the field name 86128567f8fSJeremy L Thompson 86228567f8fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 86328567f8fSJeremy L Thompson 864e9b533fbSJeremy L Thompson @ref Advanced 86528567f8fSJeremy L Thompson **/ 86628567f8fSJeremy L Thompson int CeedOperatorFieldGetName(CeedOperatorField op_field, char **field_name) { 86728567f8fSJeremy L Thompson *field_name = (char *)op_field->field_name; 86828567f8fSJeremy L Thompson return CEED_ERROR_SUCCESS; 86928567f8fSJeremy L Thompson } 87028567f8fSJeremy L Thompson 87128567f8fSJeremy L Thompson /** 87243bbe138SJeremy L Thompson @brief Get the CeedElemRestriction of a CeedOperatorField 87343bbe138SJeremy L Thompson 87443bbe138SJeremy L Thompson @param op_field CeedOperatorField 87543bbe138SJeremy L Thompson @param[out] rstr Variable to store CeedElemRestriction 87643bbe138SJeremy L Thompson 87743bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 87843bbe138SJeremy L Thompson 879e9b533fbSJeremy L Thompson @ref Advanced 88043bbe138SJeremy L Thompson **/ 88143bbe138SJeremy L Thompson int CeedOperatorFieldGetElemRestriction(CeedOperatorField op_field, 88243bbe138SJeremy L Thompson CeedElemRestriction *rstr) { 88343bbe138SJeremy L Thompson *rstr = op_field->elem_restr; 88443bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 88543bbe138SJeremy L Thompson } 88643bbe138SJeremy L Thompson 88743bbe138SJeremy L Thompson /** 88843bbe138SJeremy L Thompson @brief Get the CeedBasis of a CeedOperatorField 88943bbe138SJeremy L Thompson 89043bbe138SJeremy L Thompson @param op_field CeedOperatorField 89143bbe138SJeremy L Thompson @param[out] basis Variable to store CeedBasis 89243bbe138SJeremy L Thompson 89343bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 89443bbe138SJeremy L Thompson 895e9b533fbSJeremy L Thompson @ref Advanced 89643bbe138SJeremy L Thompson **/ 89743bbe138SJeremy L Thompson int CeedOperatorFieldGetBasis(CeedOperatorField op_field, CeedBasis *basis) { 89843bbe138SJeremy L Thompson *basis = op_field->basis; 89943bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 90043bbe138SJeremy L Thompson } 90143bbe138SJeremy L Thompson 90243bbe138SJeremy L Thompson /** 90343bbe138SJeremy L Thompson @brief Get the CeedVector of a CeedOperatorField 90443bbe138SJeremy L Thompson 90543bbe138SJeremy L Thompson @param op_field CeedOperatorField 90643bbe138SJeremy L Thompson @param[out] vec Variable to store CeedVector 90743bbe138SJeremy L Thompson 90843bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 90943bbe138SJeremy L Thompson 910e9b533fbSJeremy L Thompson @ref Advanced 91143bbe138SJeremy L Thompson **/ 91243bbe138SJeremy L Thompson int CeedOperatorFieldGetVector(CeedOperatorField op_field, CeedVector *vec) { 91343bbe138SJeremy L Thompson *vec = op_field->vec; 91443bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 91543bbe138SJeremy L Thompson } 91643bbe138SJeremy L Thompson 91743bbe138SJeremy L Thompson /** 91852d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 919288c0443SJeremy L Thompson 920d1d35e2fSjeremylt @param[out] composite_op Composite CeedOperator 921d1d35e2fSjeremylt @param sub_op Sub-operator CeedOperator 92252d6035fSJeremy L Thompson 92352d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 92452d6035fSJeremy L Thompson 9257a982d89SJeremy L. Thompson @ref User 92652d6035fSJeremy L Thompson */ 927d1d35e2fSjeremylt int CeedCompositeOperatorAddSub(CeedOperator composite_op, 928d1d35e2fSjeremylt CeedOperator sub_op) { 92934359f16Sjeremylt int ierr; 93034359f16Sjeremylt 931f04ea552SJeremy L Thompson if (!composite_op->is_composite) 932c042f62fSJeremy L Thompson // LCOV_EXCL_START 933d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_MINOR, 934e2f04181SAndrew T. Barker "CeedOperator is not a composite operator"); 935c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 93652d6035fSJeremy L Thompson 937d1d35e2fSjeremylt if (composite_op->num_suboperators == CEED_COMPOSITE_MAX) 938c042f62fSJeremy L Thompson // LCOV_EXCL_START 939d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_UNSUPPORTED, 9402b104005SJeremy L Thompson "Cannot add additional sub-operators"); 941c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 942f04ea552SJeremy L Thompson if (composite_op->is_immutable) 943f04ea552SJeremy L Thompson // LCOV_EXCL_START 944f04ea552SJeremy L Thompson return CeedError(composite_op->ceed, CEED_ERROR_MAJOR, 945f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 946f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 94752d6035fSJeremy L Thompson 9482b104005SJeremy L Thompson { 9492b104005SJeremy L Thompson CeedSize input_size, output_size; 9502b104005SJeremy L Thompson ierr = CeedOperatorGetActiveVectorLengths(sub_op, &input_size, &output_size); 9512b104005SJeremy L Thompson CeedChk(ierr); 9522b104005SJeremy L Thompson if (composite_op->input_size == -1) composite_op->input_size = input_size; 9532b104005SJeremy L Thompson if (composite_op->output_size == -1) composite_op->output_size = output_size; 9542b104005SJeremy L Thompson // Note, a size of -1 means no active vector restriction set, so no incompatibility 9552b104005SJeremy L Thompson if ((input_size != -1 && input_size != composite_op->input_size) || 9562b104005SJeremy L Thompson (output_size != -1 && output_size != composite_op->output_size)) 9572b104005SJeremy L Thompson // LCOV_EXCL_START 9582b104005SJeremy L Thompson return CeedError(composite_op->ceed, CEED_ERROR_MAJOR, 9592b104005SJeremy L Thompson "Sub-operators must have compatible dimensions; " 9602b104005SJeremy L Thompson "composite operator of shape (%td, %td) not compatible with " 9612b104005SJeremy L Thompson "sub-operator of shape (%td, %td)", 9622b104005SJeremy L Thompson composite_op->input_size, composite_op->output_size, input_size, output_size); 9632b104005SJeremy L Thompson // LCOV_EXCL_STOP 9642b104005SJeremy L Thompson } 9652b104005SJeremy L Thompson 966d1d35e2fSjeremylt composite_op->sub_operators[composite_op->num_suboperators] = sub_op; 9679560d06aSjeremylt ierr = CeedOperatorReference(sub_op); CeedChk(ierr); 968d1d35e2fSjeremylt composite_op->num_suboperators++; 969e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 97052d6035fSJeremy L Thompson } 97152d6035fSJeremy L Thompson 97252d6035fSJeremy L Thompson /** 9734db537f9SJeremy L Thompson @brief Check if a CeedOperator is ready to be used. 9744db537f9SJeremy L Thompson 9754db537f9SJeremy L Thompson @param[in] op CeedOperator to check 9764db537f9SJeremy L Thompson 9774db537f9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 9784db537f9SJeremy L Thompson 9794db537f9SJeremy L Thompson @ref User 9804db537f9SJeremy L Thompson **/ 9814db537f9SJeremy L Thompson int CeedOperatorCheckReady(CeedOperator op) { 9824db537f9SJeremy L Thompson int ierr; 9834db537f9SJeremy L Thompson Ceed ceed; 9844db537f9SJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 9854db537f9SJeremy L Thompson 9864db537f9SJeremy L Thompson if (op->is_interface_setup) 9874db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 9884db537f9SJeremy L Thompson 9894db537f9SJeremy L Thompson CeedQFunction qf = op->qf; 9904db537f9SJeremy L Thompson if (op->is_composite) { 9914db537f9SJeremy L Thompson if (!op->num_suboperators) 9924db537f9SJeremy L Thompson // LCOV_EXCL_START 9934db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "No sub_operators set"); 9944db537f9SJeremy L Thompson // LCOV_EXCL_STOP 9954db537f9SJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 9964db537f9SJeremy L Thompson ierr = CeedOperatorCheckReady(op->sub_operators[i]); CeedChk(ierr); 9974db537f9SJeremy L Thompson } 9982b104005SJeremy L Thompson // Sub-operators could be modified after adding to composite operator 9992b104005SJeremy L Thompson // Need to verify no lvec incompatibility from any changes 10002b104005SJeremy L Thompson CeedSize input_size, output_size; 10012b104005SJeremy L Thompson ierr = CeedOperatorGetActiveVectorLengths(op, &input_size, &output_size); 10022b104005SJeremy L Thompson CeedChk(ierr); 10034db537f9SJeremy L Thompson } else { 10044db537f9SJeremy L Thompson if (op->num_fields == 0) 10054db537f9SJeremy L Thompson // LCOV_EXCL_START 10064db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "No operator fields set"); 10074db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10084db537f9SJeremy L Thompson if (op->num_fields < qf->num_input_fields + qf->num_output_fields) 10094db537f9SJeremy L Thompson // LCOV_EXCL_START 10104db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "Not all operator fields set"); 10114db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10124db537f9SJeremy L Thompson if (!op->has_restriction) 10134db537f9SJeremy L Thompson // LCOV_EXCL_START 10144db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, 10154db537f9SJeremy L Thompson "At least one restriction required"); 10164db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10174db537f9SJeremy L Thompson if (op->num_qpts == 0) 10184db537f9SJeremy L Thompson // LCOV_EXCL_START 10194db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, 10204db537f9SJeremy L Thompson "At least one non-collocated basis is required " 10214db537f9SJeremy L Thompson "or the number of quadrature points must be set"); 10224db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10234db537f9SJeremy L Thompson } 10244db537f9SJeremy L Thompson 10254db537f9SJeremy L Thompson // Flag as immutable and ready 10264db537f9SJeremy L Thompson op->is_interface_setup = true; 10274db537f9SJeremy L Thompson if (op->qf && op->qf != CEED_QFUNCTION_NONE) 10284db537f9SJeremy L Thompson // LCOV_EXCL_START 10294db537f9SJeremy L Thompson op->qf->is_immutable = true; 10304db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10314db537f9SJeremy L Thompson if (op->dqf && op->dqf != CEED_QFUNCTION_NONE) 10324db537f9SJeremy L Thompson // LCOV_EXCL_START 10334db537f9SJeremy L Thompson op->dqf->is_immutable = true; 10344db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10354db537f9SJeremy L Thompson if (op->dqfT && op->dqfT != CEED_QFUNCTION_NONE) 10364db537f9SJeremy L Thompson // LCOV_EXCL_START 10374db537f9SJeremy L Thompson op->dqfT->is_immutable = true; 10384db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10394db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 10404db537f9SJeremy L Thompson } 10414db537f9SJeremy L Thompson 10424db537f9SJeremy L Thompson /** 1043c9366a6bSJeremy L Thompson @brief Get vector lengths for the active input and/or output vectors of a CeedOperator. 1044c9366a6bSJeremy L Thompson Note: Lengths of -1 indicate that the CeedOperator does not have an 1045c9366a6bSJeremy L Thompson active input and/or output. 1046c9366a6bSJeremy L Thompson 1047c9366a6bSJeremy L Thompson @param[in] op CeedOperator 1048c9366a6bSJeremy L Thompson @param[out] input_size Variable to store active input vector length, or NULL 1049c9366a6bSJeremy L Thompson @param[out] output_size Variable to store active output vector length, or NULL 1050c9366a6bSJeremy L Thompson 1051c9366a6bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1052c9366a6bSJeremy L Thompson 1053c9366a6bSJeremy L Thompson @ref User 1054c9366a6bSJeremy L Thompson **/ 1055c9366a6bSJeremy L Thompson int CeedOperatorGetActiveVectorLengths(CeedOperator op, CeedSize *input_size, 1056c9366a6bSJeremy L Thompson CeedSize *output_size) { 1057c9366a6bSJeremy L Thompson int ierr; 1058c9366a6bSJeremy L Thompson bool is_composite; 1059c9366a6bSJeremy L Thompson 10602b104005SJeremy L Thompson if (input_size) *input_size = op->input_size; 10612b104005SJeremy L Thompson if (output_size) *output_size = op->output_size; 1062c9366a6bSJeremy L Thompson 1063c9366a6bSJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 10642b104005SJeremy L Thompson if (is_composite && (op->input_size == -1 || op->output_size == -1)) { 1065c9366a6bSJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 1066c9366a6bSJeremy L Thompson CeedSize sub_input_size, sub_output_size; 1067c9366a6bSJeremy L Thompson ierr = CeedOperatorGetActiveVectorLengths(op->sub_operators[i], 10682b104005SJeremy L Thompson &sub_input_size, &sub_output_size); CeedChk(ierr); 10692b104005SJeremy L Thompson if (op->input_size == -1) op->input_size = sub_input_size; 10702b104005SJeremy L Thompson if (op->output_size == -1) op->output_size = sub_output_size; 10712b104005SJeremy L Thompson // Note, a size of -1 means no active vector restriction set, so no incompatibility 10722b104005SJeremy L Thompson if ((sub_input_size != -1 && sub_input_size != op->input_size) || 10732b104005SJeremy L Thompson (sub_output_size != -1 && sub_output_size != op->output_size)) 10742b104005SJeremy L Thompson // LCOV_EXCL_START 10752b104005SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 10762b104005SJeremy L Thompson "Sub-operators must have compatible dimensions; " 10772b104005SJeremy L Thompson "composite operator of shape (%td, %td) not compatible with " 10782b104005SJeremy L Thompson "sub-operator of shape (%td, %td)", 10792b104005SJeremy L Thompson op->input_size, op->output_size, input_size, output_size); 10802b104005SJeremy L Thompson // LCOV_EXCL_STOP 1081c9366a6bSJeremy L Thompson } 1082c9366a6bSJeremy L Thompson } 1083c9366a6bSJeremy L Thompson 1084c9366a6bSJeremy L Thompson return CEED_ERROR_SUCCESS; 1085c9366a6bSJeremy L Thompson } 1086c9366a6bSJeremy L Thompson 1087c9366a6bSJeremy L Thompson /** 1088beecbf24SJeremy L Thompson @brief Set reuse of CeedQFunction data in CeedOperatorLinearAssemble* functions. 1089beecbf24SJeremy L Thompson When `reuse_assembly_data = false` (default), the CeedQFunction associated 1090beecbf24SJeremy L Thompson with this CeedOperator is re-assembled every time a `CeedOperatorLinearAssemble*` 1091beecbf24SJeremy L Thompson function is called. 1092beecbf24SJeremy L Thompson When `reuse_assembly_data = true`, the CeedQFunction associated with 1093beecbf24SJeremy L Thompson this CeedOperator is reused between calls to 1094beecbf24SJeremy L Thompson `CeedOperatorSetQFunctionAssemblyDataUpdated`. 10958b919e6bSJeremy L Thompson 1096beecbf24SJeremy L Thompson @param[in] op CeedOperator 1097beecbf24SJeremy L Thompson @param[in] reuse_assembly_data Boolean flag setting assembly data reuse 10988b919e6bSJeremy L Thompson 10998b919e6bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 11008b919e6bSJeremy L Thompson 11018b919e6bSJeremy L Thompson @ref Advanced 11028b919e6bSJeremy L Thompson **/ 1103beecbf24SJeremy L Thompson int CeedOperatorSetQFunctionAssemblyReuse(CeedOperator op, 1104beecbf24SJeremy L Thompson bool reuse_assembly_data) { 11058b919e6bSJeremy L Thompson int ierr; 11068b919e6bSJeremy L Thompson bool is_composite; 11078b919e6bSJeremy L Thompson 11088b919e6bSJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 11098b919e6bSJeremy L Thompson if (is_composite) { 11108b919e6bSJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 1111beecbf24SJeremy L Thompson ierr = CeedOperatorSetQFunctionAssemblyReuse(op->sub_operators[i], 1112beecbf24SJeremy L Thompson reuse_assembly_data); CeedChk(ierr); 11138b919e6bSJeremy L Thompson } 11148b919e6bSJeremy L Thompson } else { 1115beecbf24SJeremy L Thompson ierr = CeedQFunctionAssemblyDataSetReuse(op->qf_assembled, reuse_assembly_data); 1116beecbf24SJeremy L Thompson CeedChk(ierr); 1117beecbf24SJeremy L Thompson } 1118beecbf24SJeremy L Thompson 1119beecbf24SJeremy L Thompson return CEED_ERROR_SUCCESS; 1120beecbf24SJeremy L Thompson } 1121beecbf24SJeremy L Thompson 1122beecbf24SJeremy L Thompson /** 1123beecbf24SJeremy L Thompson @brief Mark CeedQFunction data as updated and the CeedQFunction as requiring re-assembly. 1124beecbf24SJeremy L Thompson 1125beecbf24SJeremy L Thompson @param[in] op CeedOperator 11266e15d496SJeremy L Thompson @param[in] needs_data_update Boolean flag setting assembly data reuse 1127beecbf24SJeremy L Thompson 1128beecbf24SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1129beecbf24SJeremy L Thompson 1130beecbf24SJeremy L Thompson @ref Advanced 1131beecbf24SJeremy L Thompson **/ 1132beecbf24SJeremy L Thompson int CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(CeedOperator op, 1133beecbf24SJeremy L Thompson bool needs_data_update) { 1134beecbf24SJeremy L Thompson int ierr; 1135beecbf24SJeremy L Thompson bool is_composite; 1136beecbf24SJeremy L Thompson 1137beecbf24SJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 1138beecbf24SJeremy L Thompson if (is_composite) { 1139beecbf24SJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 1140beecbf24SJeremy L Thompson ierr = CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(op->sub_operators[i], 1141beecbf24SJeremy L Thompson needs_data_update); CeedChk(ierr); 1142beecbf24SJeremy L Thompson } 1143beecbf24SJeremy L Thompson } else { 1144beecbf24SJeremy L Thompson ierr = CeedQFunctionAssemblyDataSetUpdateNeeded(op->qf_assembled, 1145beecbf24SJeremy L Thompson needs_data_update); 11468b919e6bSJeremy L Thompson CeedChk(ierr); 11478b919e6bSJeremy L Thompson } 11488b919e6bSJeremy L Thompson 11498b919e6bSJeremy L Thompson return CEED_ERROR_SUCCESS; 11508b919e6bSJeremy L Thompson } 11518b919e6bSJeremy L Thompson 11528b919e6bSJeremy L Thompson /** 1153cd4dfc48Sjeremylt @brief Set the number of quadrature points associated with a CeedOperator. 1154cd4dfc48Sjeremylt This should be used when creating a CeedOperator where every 1155cd4dfc48Sjeremylt field has a collocated basis. This function cannot be used for 1156cd4dfc48Sjeremylt composite CeedOperators. 1157cd4dfc48Sjeremylt 1158cd4dfc48Sjeremylt @param op CeedOperator 1159cd4dfc48Sjeremylt @param num_qpts Number of quadrature points to set 1160cd4dfc48Sjeremylt 1161cd4dfc48Sjeremylt @return An error code: 0 - success, otherwise - failure 1162cd4dfc48Sjeremylt 1163e9b533fbSJeremy L Thompson @ref Advanced 1164cd4dfc48Sjeremylt **/ 1165cd4dfc48Sjeremylt int CeedOperatorSetNumQuadraturePoints(CeedOperator op, CeedInt num_qpts) { 1166f04ea552SJeremy L Thompson if (op->is_composite) 1167cd4dfc48Sjeremylt // LCOV_EXCL_START 1168cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 1169cd4dfc48Sjeremylt "Not defined for composite operator"); 1170cd4dfc48Sjeremylt // LCOV_EXCL_STOP 1171cd4dfc48Sjeremylt if (op->num_qpts) 1172cd4dfc48Sjeremylt // LCOV_EXCL_START 1173cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 1174cd4dfc48Sjeremylt "Number of quadrature points already defined"); 1175cd4dfc48Sjeremylt // LCOV_EXCL_STOP 1176f04ea552SJeremy L Thompson if (op->is_immutable) 1177f04ea552SJeremy L Thompson // LCOV_EXCL_START 1178f04ea552SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 1179f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 1180f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 1181cd4dfc48Sjeremylt 1182cd4dfc48Sjeremylt op->num_qpts = num_qpts; 1183cd4dfc48Sjeremylt return CEED_ERROR_SUCCESS; 1184cd4dfc48Sjeremylt } 1185cd4dfc48Sjeremylt 1186cd4dfc48Sjeremylt /** 1187ea6b5821SJeremy L Thompson @brief Set name of CeedOperator for CeedOperatorView output 1188ea6b5821SJeremy L Thompson 1189ea6b5821SJeremy L Thompson @param op CeedOperator 1190ea6b5821SJeremy L Thompson @param name Name to set, or NULL to remove previously set name 1191ea6b5821SJeremy L Thompson 1192ea6b5821SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1193ea6b5821SJeremy L Thompson 1194ea6b5821SJeremy L Thompson @ref User 1195ea6b5821SJeremy L Thompson **/ 1196ea6b5821SJeremy L Thompson int CeedOperatorSetName(CeedOperator op, const char *name) { 1197ea6b5821SJeremy L Thompson int ierr; 1198ea6b5821SJeremy L Thompson char *name_copy; 1199ea6b5821SJeremy L Thompson size_t name_len = name ? strlen(name) : 0; 1200ea6b5821SJeremy L Thompson 1201ea6b5821SJeremy L Thompson ierr = CeedFree(&op->name); CeedChk(ierr); 1202ea6b5821SJeremy L Thompson if (name_len > 0) { 1203ea6b5821SJeremy L Thompson ierr = CeedCalloc(name_len + 1, &name_copy); CeedChk(ierr); 1204ea6b5821SJeremy L Thompson memcpy(name_copy, name, name_len); 1205ea6b5821SJeremy L Thompson op->name = name_copy; 1206ea6b5821SJeremy L Thompson } 1207ea6b5821SJeremy L Thompson 1208ea6b5821SJeremy L Thompson return CEED_ERROR_SUCCESS; 1209ea6b5821SJeremy L Thompson } 1210ea6b5821SJeremy L Thompson 1211ea6b5821SJeremy L Thompson /** 12127a982d89SJeremy L. Thompson @brief View a CeedOperator 12137a982d89SJeremy L. Thompson 12147a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 12157a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 12167a982d89SJeremy L. Thompson 12177a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 12187a982d89SJeremy L. Thompson 12197a982d89SJeremy L. Thompson @ref User 12207a982d89SJeremy L. Thompson **/ 12217a982d89SJeremy L. Thompson int CeedOperatorView(CeedOperator op, FILE *stream) { 12227a982d89SJeremy L. Thompson int ierr; 1223ea6b5821SJeremy L Thompson bool has_name = op->name; 12247a982d89SJeremy L. Thompson 1225f04ea552SJeremy L Thompson if (op->is_composite) { 1226ea6b5821SJeremy L Thompson fprintf(stream, "Composite CeedOperator%s%s\n", 1227ea6b5821SJeremy L Thompson has_name ? " - " : "", has_name ? op->name : ""); 12287a982d89SJeremy L. Thompson 1229d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 1230ea6b5821SJeremy L Thompson has_name = op->sub_operators[i]->name; 1231*990fdeb6SJeremy L Thompson fprintf(stream, " SubOperator %" CeedInt_FMT "%s%s:\n", i, 1232ea6b5821SJeremy L Thompson has_name ? " - " : "", 1233ea6b5821SJeremy L Thompson has_name ? op->sub_operators[i]->name : ""); 1234d1d35e2fSjeremylt ierr = CeedOperatorSingleView(op->sub_operators[i], 1, stream); 12357a982d89SJeremy L. Thompson CeedChk(ierr); 12367a982d89SJeremy L. Thompson } 12377a982d89SJeremy L. Thompson } else { 1238ea6b5821SJeremy L Thompson fprintf(stream, "CeedOperator%s%s\n", 1239ea6b5821SJeremy L Thompson has_name ? " - " : "", has_name ? op->name : ""); 12407a982d89SJeremy L. Thompson ierr = CeedOperatorSingleView(op, 0, stream); CeedChk(ierr); 12417a982d89SJeremy L. Thompson } 1242e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 12437a982d89SJeremy L. Thompson } 12443bd813ffSjeremylt 12453bd813ffSjeremylt /** 1246b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedOperator 1247b7c9bbdaSJeremy L Thompson 1248b7c9bbdaSJeremy L Thompson @param op CeedOperator 1249b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 1250b7c9bbdaSJeremy L Thompson 1251b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1252b7c9bbdaSJeremy L Thompson 1253b7c9bbdaSJeremy L Thompson @ref Advanced 1254b7c9bbdaSJeremy L Thompson **/ 1255b7c9bbdaSJeremy L Thompson int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 1256b7c9bbdaSJeremy L Thompson *ceed = op->ceed; 1257b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1258b7c9bbdaSJeremy L Thompson } 1259b7c9bbdaSJeremy L Thompson 1260b7c9bbdaSJeremy L Thompson /** 1261b7c9bbdaSJeremy L Thompson @brief Get the number of elements associated with a CeedOperator 1262b7c9bbdaSJeremy L Thompson 1263b7c9bbdaSJeremy L Thompson @param op CeedOperator 1264b7c9bbdaSJeremy L Thompson @param[out] num_elem Variable to store number of elements 1265b7c9bbdaSJeremy L Thompson 1266b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1267b7c9bbdaSJeremy L Thompson 1268b7c9bbdaSJeremy L Thompson @ref Advanced 1269b7c9bbdaSJeremy L Thompson **/ 1270b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumElements(CeedOperator op, CeedInt *num_elem) { 1271b7c9bbdaSJeremy L Thompson if (op->is_composite) 1272b7c9bbdaSJeremy L Thompson // LCOV_EXCL_START 1273b7c9bbdaSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 1274b7c9bbdaSJeremy L Thompson "Not defined for composite operator"); 1275b7c9bbdaSJeremy L Thompson // LCOV_EXCL_STOP 1276b7c9bbdaSJeremy L Thompson 1277b7c9bbdaSJeremy L Thompson *num_elem = op->num_elem; 1278b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1279b7c9bbdaSJeremy L Thompson } 1280b7c9bbdaSJeremy L Thompson 1281b7c9bbdaSJeremy L Thompson /** 1282b7c9bbdaSJeremy L Thompson @brief Get the number of quadrature points associated with a CeedOperator 1283b7c9bbdaSJeremy L Thompson 1284b7c9bbdaSJeremy L Thompson @param op CeedOperator 1285b7c9bbdaSJeremy L Thompson @param[out] num_qpts Variable to store vector number of quadrature points 1286b7c9bbdaSJeremy L Thompson 1287b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1288b7c9bbdaSJeremy L Thompson 1289b7c9bbdaSJeremy L Thompson @ref Advanced 1290b7c9bbdaSJeremy L Thompson **/ 1291b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *num_qpts) { 1292b7c9bbdaSJeremy L Thompson if (op->is_composite) 1293b7c9bbdaSJeremy L Thompson // LCOV_EXCL_START 1294b7c9bbdaSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 1295b7c9bbdaSJeremy L Thompson "Not defined for composite operator"); 1296b7c9bbdaSJeremy L Thompson // LCOV_EXCL_STOP 1297b7c9bbdaSJeremy L Thompson 1298b7c9bbdaSJeremy L Thompson *num_qpts = op->num_qpts; 1299b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1300b7c9bbdaSJeremy L Thompson } 1301b7c9bbdaSJeremy L Thompson 1302b7c9bbdaSJeremy L Thompson /** 13036e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedOperator on the active vector 13046e15d496SJeremy L Thompson 13056e15d496SJeremy L Thompson @param op Operator to estimate FLOPs for 13066e15d496SJeremy L Thompson @param flops Address of variable to hold FLOPs estimate 13076e15d496SJeremy L Thompson 13086e15d496SJeremy L Thompson @ref Backend 13096e15d496SJeremy L Thompson **/ 13109d36ca50SJeremy L Thompson int CeedOperatorGetFlopsEstimate(CeedOperator op, CeedSize *flops) { 13116e15d496SJeremy L Thompson int ierr; 13126e15d496SJeremy L Thompson bool is_composite; 13136e15d496SJeremy L Thompson ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 13146e15d496SJeremy L Thompson 13156e15d496SJeremy L Thompson *flops = 0; 13166e15d496SJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 13176e15d496SJeremy L Thompson if (is_composite) { 13186e15d496SJeremy L Thompson CeedInt num_suboperators; 13196e15d496SJeremy L Thompson ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 13206e15d496SJeremy L Thompson CeedOperator *sub_operators; 13216e15d496SJeremy L Thompson ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 13226e15d496SJeremy L Thompson 13236e15d496SJeremy L Thompson // FLOPs for each suboperator 13246e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 13259d36ca50SJeremy L Thompson CeedSize suboperator_flops; 13266e15d496SJeremy L Thompson ierr = CeedOperatorGetFlopsEstimate(sub_operators[i], &suboperator_flops); 13276e15d496SJeremy L Thompson CeedChk(ierr); 13286e15d496SJeremy L Thompson *flops += suboperator_flops; 13296e15d496SJeremy L Thompson } 13306e15d496SJeremy L Thompson } else { 13316e15d496SJeremy L Thompson CeedInt num_input_fields, num_output_fields; 13326e15d496SJeremy L Thompson CeedOperatorField *input_fields, *output_fields; 13336e15d496SJeremy L Thompson 13346e15d496SJeremy L Thompson ierr = CeedOperatorGetFields(op, &num_input_fields, &input_fields, 13356e15d496SJeremy L Thompson &num_output_fields, &output_fields); CeedChk(ierr); 13366e15d496SJeremy L Thompson 13376e15d496SJeremy L Thompson CeedInt num_elem = 0; 13386e15d496SJeremy L Thompson ierr = CeedOperatorGetNumElements(op, &num_elem); CeedChk(ierr); 13396e15d496SJeremy L Thompson // Input FLOPs 13406e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 13416e15d496SJeremy L Thompson if (input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 13429d36ca50SJeremy L Thompson CeedSize restr_flops, basis_flops; 13436e15d496SJeremy L Thompson 13446e15d496SJeremy L Thompson ierr = CeedElemRestrictionGetFlopsEstimate(input_fields[i]->elem_restr, 13456e15d496SJeremy L Thompson CEED_NOTRANSPOSE, &restr_flops); CeedChk(ierr); 13466e15d496SJeremy L Thompson *flops += restr_flops; 13476e15d496SJeremy L Thompson ierr = CeedBasisGetFlopsEstimate(input_fields[i]->basis, CEED_NOTRANSPOSE, 13486e15d496SJeremy L Thompson op->qf->input_fields[i]->eval_mode, &basis_flops); CeedChk(ierr); 13496e15d496SJeremy L Thompson *flops += basis_flops * num_elem; 13506e15d496SJeremy L Thompson } 13516e15d496SJeremy L Thompson } 13526e15d496SJeremy L Thompson // QF FLOPs 13539d36ca50SJeremy L Thompson CeedInt num_qpts; 13549d36ca50SJeremy L Thompson CeedSize qf_flops; 13556e15d496SJeremy L Thompson ierr = CeedOperatorGetNumQuadraturePoints(op, &num_qpts); CeedChk(ierr); 13566e15d496SJeremy L Thompson ierr = CeedQFunctionGetFlopsEstimate(op->qf, &qf_flops); CeedChk(ierr); 13576e15d496SJeremy L Thompson *flops += num_elem * num_qpts * qf_flops; 13586e15d496SJeremy L Thompson // Output FLOPs 13596e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 13606e15d496SJeremy L Thompson if (output_fields[i]->vec == CEED_VECTOR_ACTIVE) { 13619d36ca50SJeremy L Thompson CeedSize restr_flops, basis_flops; 13626e15d496SJeremy L Thompson 13636e15d496SJeremy L Thompson ierr = CeedElemRestrictionGetFlopsEstimate(output_fields[i]->elem_restr, 13646e15d496SJeremy L Thompson CEED_TRANSPOSE, &restr_flops); CeedChk(ierr); 13656e15d496SJeremy L Thompson *flops += restr_flops; 13666e15d496SJeremy L Thompson ierr = CeedBasisGetFlopsEstimate(output_fields[i]->basis, CEED_TRANSPOSE, 13676e15d496SJeremy L Thompson op->qf->output_fields[i]->eval_mode, &basis_flops); CeedChk(ierr); 13686e15d496SJeremy L Thompson *flops += basis_flops * num_elem; 13696e15d496SJeremy L Thompson } 13706e15d496SJeremy L Thompson } 13716e15d496SJeremy L Thompson } 13726e15d496SJeremy L Thompson 13736e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 13746e15d496SJeremy L Thompson } 13756e15d496SJeremy L Thompson 13766e15d496SJeremy L Thompson /** 13773668ca4bSJeremy L Thompson @brief Get label for a registered QFunctionContext field, or `NULL` if no 13783668ca4bSJeremy L Thompson field has been registered with this `field_name`. 13793668ca4bSJeremy L Thompson 13803668ca4bSJeremy L Thompson @param[in] op CeedOperator 13813668ca4bSJeremy L Thompson @param[in] field_name Name of field to retrieve label 13823668ca4bSJeremy L Thompson @param[out] field_label Variable to field label 13833668ca4bSJeremy L Thompson 13843668ca4bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 13853668ca4bSJeremy L Thompson 13863668ca4bSJeremy L Thompson @ref User 13873668ca4bSJeremy L Thompson **/ 13883668ca4bSJeremy L Thompson int CeedOperatorContextGetFieldLabel(CeedOperator op, 13893668ca4bSJeremy L Thompson const char *field_name, 13903668ca4bSJeremy L Thompson CeedContextFieldLabel *field_label) { 13913668ca4bSJeremy L Thompson int ierr; 13923668ca4bSJeremy L Thompson 13933668ca4bSJeremy L Thompson bool is_composite; 13943668ca4bSJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 13953668ca4bSJeremy L Thompson if (is_composite) { 13963668ca4bSJeremy L Thompson // Check if composite label already created 13973668ca4bSJeremy L Thompson for (CeedInt i=0; i<op->num_context_labels; i++) { 13983668ca4bSJeremy L Thompson if (!strcmp(op->context_labels[i]->name, field_name)) { 13993668ca4bSJeremy L Thompson *field_label = op->context_labels[i]; 14003668ca4bSJeremy L Thompson return CEED_ERROR_SUCCESS; 14013668ca4bSJeremy L Thompson } 14023668ca4bSJeremy L Thompson } 14033668ca4bSJeremy L Thompson 14043668ca4bSJeremy L Thompson // Create composite label if needed 14053668ca4bSJeremy L Thompson CeedInt num_sub; 14063668ca4bSJeremy L Thompson CeedOperator *sub_operators; 14073668ca4bSJeremy L Thompson CeedContextFieldLabel new_field_label; 14083668ca4bSJeremy L Thompson 14093668ca4bSJeremy L Thompson ierr = CeedCalloc(1, &new_field_label); CeedChk(ierr); 14103668ca4bSJeremy L Thompson ierr = CeedOperatorGetNumSub(op, &num_sub); CeedChk(ierr); 14113668ca4bSJeremy L Thompson ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 14123668ca4bSJeremy L Thompson ierr = CeedCalloc(num_sub, &new_field_label->sub_labels); CeedChk(ierr); 14133668ca4bSJeremy L Thompson new_field_label->num_sub_labels = num_sub; 14143668ca4bSJeremy L Thompson 14153668ca4bSJeremy L Thompson bool label_found = false; 14163668ca4bSJeremy L Thompson for (CeedInt i=0; i<num_sub; i++) { 14173668ca4bSJeremy L Thompson if (sub_operators[i]->qf->ctx) { 14183668ca4bSJeremy L Thompson CeedContextFieldLabel new_field_label_i; 14193668ca4bSJeremy L Thompson ierr = CeedQFunctionContextGetFieldLabel(sub_operators[i]->qf->ctx, field_name, 14203668ca4bSJeremy L Thompson &new_field_label_i); CeedChk(ierr); 14213668ca4bSJeremy L Thompson if (new_field_label_i) { 14223668ca4bSJeremy L Thompson label_found = true; 14233668ca4bSJeremy L Thompson new_field_label->sub_labels[i] = new_field_label_i; 14243668ca4bSJeremy L Thompson new_field_label->name = new_field_label_i->name; 14253668ca4bSJeremy L Thompson new_field_label->description = new_field_label_i->description; 14267bfe0f0eSJeremy L Thompson if (new_field_label->type && 14277bfe0f0eSJeremy L Thompson new_field_label->type != new_field_label_i->type) { 14287bfe0f0eSJeremy L Thompson // LCOV_EXCL_START 14297bfe0f0eSJeremy L Thompson ierr = CeedFree(&new_field_label); CeedChk(ierr); 14307bfe0f0eSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 14317bfe0f0eSJeremy L Thompson "Incompatible field types on sub-operator contexts. " 14327bfe0f0eSJeremy L Thompson "%s != %s", 14337bfe0f0eSJeremy L Thompson CeedContextFieldTypes[new_field_label->type], 14347bfe0f0eSJeremy L Thompson CeedContextFieldTypes[new_field_label_i->type]); 14357bfe0f0eSJeremy L Thompson // LCOV_EXCL_STOP 14367bfe0f0eSJeremy L Thompson } else { 14377bfe0f0eSJeremy L Thompson new_field_label->type = new_field_label_i->type; 14387bfe0f0eSJeremy L Thompson } 14397bfe0f0eSJeremy L Thompson if (new_field_label->num_values != 0 && 14407bfe0f0eSJeremy L Thompson new_field_label->num_values != new_field_label_i->num_values) { 14417bfe0f0eSJeremy L Thompson // LCOV_EXCL_START 14427bfe0f0eSJeremy L Thompson ierr = CeedFree(&new_field_label); CeedChk(ierr); 14437bfe0f0eSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 14447bfe0f0eSJeremy L Thompson "Incompatible field number of values on sub-operator" 14457bfe0f0eSJeremy L Thompson " contexts. %ld != %ld", 14467bfe0f0eSJeremy L Thompson new_field_label->num_values, new_field_label_i->num_values); 14477bfe0f0eSJeremy L Thompson // LCOV_EXCL_STOP 14487bfe0f0eSJeremy L Thompson } else { 14497bfe0f0eSJeremy L Thompson new_field_label->num_values = new_field_label_i->num_values; 14507bfe0f0eSJeremy L Thompson } 14513668ca4bSJeremy L Thompson } 14523668ca4bSJeremy L Thompson } 14533668ca4bSJeremy L Thompson } 14543668ca4bSJeremy L Thompson if (!label_found) { 14553668ca4bSJeremy L Thompson // LCOV_EXCL_START 1456a48e5f43SJeremy L Thompson ierr = CeedFree(&new_field_label->sub_labels); CeedChk(ierr); 14573668ca4bSJeremy L Thompson ierr = CeedFree(&new_field_label); CeedChk(ierr); 14583668ca4bSJeremy L Thompson *field_label = NULL; 14593668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 14603668ca4bSJeremy L Thompson } else { 14613668ca4bSJeremy L Thompson // Move new composite label to operator 14623668ca4bSJeremy L Thompson if (op->num_context_labels == 0) { 14633668ca4bSJeremy L Thompson ierr = CeedCalloc(1, &op->context_labels); CeedChk(ierr); 14643668ca4bSJeremy L Thompson op->max_context_labels = 1; 14653668ca4bSJeremy L Thompson } else if (op->num_context_labels == op->max_context_labels) { 14663668ca4bSJeremy L Thompson ierr = CeedRealloc(2*op->num_context_labels, &op->context_labels); 14673668ca4bSJeremy L Thompson CeedChk(ierr); 14683668ca4bSJeremy L Thompson op->max_context_labels *= 2; 14693668ca4bSJeremy L Thompson } 14703668ca4bSJeremy L Thompson op->context_labels[op->num_context_labels] = new_field_label; 14713668ca4bSJeremy L Thompson *field_label = new_field_label; 14723668ca4bSJeremy L Thompson op->num_context_labels++; 14733668ca4bSJeremy L Thompson } 14743668ca4bSJeremy L Thompson 14753668ca4bSJeremy L Thompson return CEED_ERROR_SUCCESS; 14763668ca4bSJeremy L Thompson } else { 14773668ca4bSJeremy L Thompson return CeedQFunctionContextGetFieldLabel(op->qf->ctx, field_name, field_label); 14783668ca4bSJeremy L Thompson } 14793668ca4bSJeremy L Thompson } 14803668ca4bSJeremy L Thompson 14813668ca4bSJeremy L Thompson /** 1482d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field holding a double precision value. 1483d8dd9a91SJeremy L Thompson For composite operators, the value is set in all 1484d8dd9a91SJeremy L Thompson sub-operator QFunctionContexts that have a matching `field_name`. 1485d8dd9a91SJeremy L Thompson 1486d8dd9a91SJeremy L Thompson @param op CeedOperator 14873668ca4bSJeremy L Thompson @param field_label Label of field to register 14887bfe0f0eSJeremy L Thompson @param values Values to set 1489d8dd9a91SJeremy L Thompson 1490d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1491d8dd9a91SJeremy L Thompson 1492d8dd9a91SJeremy L Thompson @ref User 1493d8dd9a91SJeremy L Thompson **/ 14943668ca4bSJeremy L Thompson int CeedOperatorContextSetDouble(CeedOperator op, 14953668ca4bSJeremy L Thompson CeedContextFieldLabel field_label, 14967bfe0f0eSJeremy L Thompson double *values) { 14973668ca4bSJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_DOUBLE, 14987bfe0f0eSJeremy L Thompson values); 1499d8dd9a91SJeremy L Thompson } 1500d8dd9a91SJeremy L Thompson 1501d8dd9a91SJeremy L Thompson /** 1502d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field holding an int32 value. 1503d8dd9a91SJeremy L Thompson For composite operators, the value is set in all 1504d8dd9a91SJeremy L Thompson sub-operator QFunctionContexts that have a matching `field_name`. 1505d8dd9a91SJeremy L Thompson 1506d8dd9a91SJeremy L Thompson @param op CeedOperator 15073668ca4bSJeremy L Thompson @param field_label Label of field to set 15087bfe0f0eSJeremy L Thompson @param values Values to set 1509d8dd9a91SJeremy L Thompson 1510d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1511d8dd9a91SJeremy L Thompson 1512d8dd9a91SJeremy L Thompson @ref User 1513d8dd9a91SJeremy L Thompson **/ 15143668ca4bSJeremy L Thompson int CeedOperatorContextSetInt32(CeedOperator op, 15153668ca4bSJeremy L Thompson CeedContextFieldLabel field_label, 15167bfe0f0eSJeremy L Thompson int *values) { 15173668ca4bSJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_INT32, 15187bfe0f0eSJeremy L Thompson values); 1519d8dd9a91SJeremy L Thompson } 1520d8dd9a91SJeremy L Thompson 1521d8dd9a91SJeremy L Thompson /** 15223bd813ffSjeremylt @brief Apply CeedOperator to a vector 1523d7b241e6Sjeremylt 1524d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 1525d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 1526d7b241e6Sjeremylt CeedOperatorSetField(). 1527d7b241e6Sjeremylt 1528f04ea552SJeremy L Thompson Note: Calling this function asserts that setup is complete 1529f04ea552SJeremy L Thompson and sets the CeedOperator as immutable. 1530f04ea552SJeremy L Thompson 1531d7b241e6Sjeremylt @param op CeedOperator to apply 15324cc79fe7SJed Brown @param[in] in CeedVector containing input state or @ref CEED_VECTOR_NONE if 153334138859Sjeremylt there are no active inputs 1534b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 15354cc79fe7SJed Brown distinct from @a in) or @ref CEED_VECTOR_NONE if there are no 153634138859Sjeremylt active outputs 1537d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 15384cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1539b11c1e72Sjeremylt 1540b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1541dfdf5a53Sjeremylt 15427a982d89SJeremy L. Thompson @ref User 1543b11c1e72Sjeremylt **/ 1544692c2638Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, 1545692c2638Sjeremylt CeedRequest *request) { 1546d7b241e6Sjeremylt int ierr; 1547e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1548d7b241e6Sjeremylt 1549d1d35e2fSjeremylt if (op->num_elem) { 1550250756a7Sjeremylt // Standard Operator 1551cae8b89aSjeremylt if (op->Apply) { 1552250756a7Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 1553cae8b89aSjeremylt } else { 1554cae8b89aSjeremylt // Zero all output vectors 1555250756a7Sjeremylt CeedQFunction qf = op->qf; 1556d1d35e2fSjeremylt for (CeedInt i=0; i<qf->num_output_fields; i++) { 1557d1d35e2fSjeremylt CeedVector vec = op->output_fields[i]->vec; 1558cae8b89aSjeremylt if (vec == CEED_VECTOR_ACTIVE) 1559cae8b89aSjeremylt vec = out; 1560cae8b89aSjeremylt if (vec != CEED_VECTOR_NONE) { 1561cae8b89aSjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1562cae8b89aSjeremylt } 1563cae8b89aSjeremylt } 1564250756a7Sjeremylt // Apply 1565250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1566250756a7Sjeremylt } 1567f04ea552SJeremy L Thompson } else if (op->is_composite) { 1568250756a7Sjeremylt // Composite Operator 1569250756a7Sjeremylt if (op->ApplyComposite) { 1570250756a7Sjeremylt ierr = op->ApplyComposite(op, in, out, request); CeedChk(ierr); 1571250756a7Sjeremylt } else { 1572d1d35e2fSjeremylt CeedInt num_suboperators; 1573d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1574d1d35e2fSjeremylt CeedOperator *sub_operators; 1575d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1576250756a7Sjeremylt 1577250756a7Sjeremylt // Zero all output vectors 1578250756a7Sjeremylt if (out != CEED_VECTOR_NONE) { 1579cae8b89aSjeremylt ierr = CeedVectorSetValue(out, 0.0); CeedChk(ierr); 1580cae8b89aSjeremylt } 1581d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1582d1d35e2fSjeremylt for (CeedInt j=0; j<sub_operators[i]->qf->num_output_fields; j++) { 1583d1d35e2fSjeremylt CeedVector vec = sub_operators[i]->output_fields[j]->vec; 1584250756a7Sjeremylt if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) { 1585250756a7Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1586250756a7Sjeremylt } 1587250756a7Sjeremylt } 1588250756a7Sjeremylt } 1589250756a7Sjeremylt // Apply 1590d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 1591d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(op->sub_operators[i], in, out, request); 1592cae8b89aSjeremylt CeedChk(ierr); 1593cae8b89aSjeremylt } 1594cae8b89aSjeremylt } 1595250756a7Sjeremylt } 1596e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1597cae8b89aSjeremylt } 1598cae8b89aSjeremylt 1599cae8b89aSjeremylt /** 1600cae8b89aSjeremylt @brief Apply CeedOperator to a vector and add result to output vector 1601cae8b89aSjeremylt 1602cae8b89aSjeremylt This computes the action of the operator on the specified (active) input, 1603cae8b89aSjeremylt yielding its (active) output. All inputs and outputs must be specified using 1604cae8b89aSjeremylt CeedOperatorSetField(). 1605cae8b89aSjeremylt 1606cae8b89aSjeremylt @param op CeedOperator to apply 1607cae8b89aSjeremylt @param[in] in CeedVector containing input state or NULL if there are no 1608cae8b89aSjeremylt active inputs 1609cae8b89aSjeremylt @param[out] out CeedVector to sum in result of applying operator (must be 1610cae8b89aSjeremylt distinct from @a in) or NULL if there are no active outputs 1611cae8b89aSjeremylt @param request Address of CeedRequest for non-blocking completion, else 16124cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1613cae8b89aSjeremylt 1614cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 1615cae8b89aSjeremylt 16167a982d89SJeremy L. Thompson @ref User 1617cae8b89aSjeremylt **/ 1618cae8b89aSjeremylt int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, 1619cae8b89aSjeremylt CeedRequest *request) { 1620cae8b89aSjeremylt int ierr; 1621e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1622cae8b89aSjeremylt 1623d1d35e2fSjeremylt if (op->num_elem) { 1624250756a7Sjeremylt // Standard Operator 1625250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1626f04ea552SJeremy L Thompson } else if (op->is_composite) { 1627250756a7Sjeremylt // Composite Operator 1628250756a7Sjeremylt if (op->ApplyAddComposite) { 1629250756a7Sjeremylt ierr = op->ApplyAddComposite(op, in, out, request); CeedChk(ierr); 1630cae8b89aSjeremylt } else { 1631d1d35e2fSjeremylt CeedInt num_suboperators; 1632d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1633d1d35e2fSjeremylt CeedOperator *sub_operators; 1634d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1635250756a7Sjeremylt 1636d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1637d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(sub_operators[i], in, out, request); 1638cae8b89aSjeremylt CeedChk(ierr); 16391d7d2407SJeremy L Thompson } 1640250756a7Sjeremylt } 1641250756a7Sjeremylt } 1642e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1643d7b241e6Sjeremylt } 1644d7b241e6Sjeremylt 1645d7b241e6Sjeremylt /** 1646b11c1e72Sjeremylt @brief Destroy a CeedOperator 1647d7b241e6Sjeremylt 1648d7b241e6Sjeremylt @param op CeedOperator to destroy 1649b11c1e72Sjeremylt 1650b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1651dfdf5a53Sjeremylt 16527a982d89SJeremy L. Thompson @ref User 1653b11c1e72Sjeremylt **/ 1654d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 1655d7b241e6Sjeremylt int ierr; 1656d7b241e6Sjeremylt 1657d1d35e2fSjeremylt if (!*op || --(*op)->ref_count > 0) return CEED_ERROR_SUCCESS; 1658d7b241e6Sjeremylt if ((*op)->Destroy) { 1659d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 1660d7b241e6Sjeremylt } 1661fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 1662fe2413ffSjeremylt // Free fields 16633668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_fields; i++) 1664d1d35e2fSjeremylt if ((*op)->input_fields[i]) { 1665d1d35e2fSjeremylt if ((*op)->input_fields[i]->elem_restr != CEED_ELEMRESTRICTION_NONE) { 1666d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->input_fields[i]->elem_restr); 166771352a93Sjeremylt CeedChk(ierr); 166815910d16Sjeremylt } 1669d1d35e2fSjeremylt if ((*op)->input_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1670d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->input_fields[i]->basis); CeedChk(ierr); 167171352a93Sjeremylt } 1672d1d35e2fSjeremylt if ((*op)->input_fields[i]->vec != CEED_VECTOR_ACTIVE && 1673d1d35e2fSjeremylt (*op)->input_fields[i]->vec != CEED_VECTOR_NONE ) { 1674d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->input_fields[i]->vec); CeedChk(ierr); 167571352a93Sjeremylt } 1676d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]->field_name); CeedChk(ierr); 1677d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]); CeedChk(ierr); 1678fe2413ffSjeremylt } 16793668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_fields; i++) 1680d1d35e2fSjeremylt if ((*op)->output_fields[i]) { 1681d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->output_fields[i]->elem_restr); 168271352a93Sjeremylt CeedChk(ierr); 1683d1d35e2fSjeremylt if ((*op)->output_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1684d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->output_fields[i]->basis); CeedChk(ierr); 168571352a93Sjeremylt } 1686d1d35e2fSjeremylt if ((*op)->output_fields[i]->vec != CEED_VECTOR_ACTIVE && 1687d1d35e2fSjeremylt (*op)->output_fields[i]->vec != CEED_VECTOR_NONE ) { 1688d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->output_fields[i]->vec); CeedChk(ierr); 168971352a93Sjeremylt } 1690d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]->field_name); CeedChk(ierr); 1691d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]); CeedChk(ierr); 1692fe2413ffSjeremylt } 1693d1d35e2fSjeremylt // Destroy sub_operators 16943668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_suboperators; i++) 1695d1d35e2fSjeremylt if ((*op)->sub_operators[i]) { 1696d1d35e2fSjeremylt ierr = CeedOperatorDestroy(&(*op)->sub_operators[i]); CeedChk(ierr); 169752d6035fSJeremy L Thompson } 1698d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 1699d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 1700d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 17013668ca4bSJeremy L Thompson // Destroy any composite labels 17023668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_context_labels; i++) { 17033668ca4bSJeremy L Thompson ierr = CeedFree(&(*op)->context_labels[i]->sub_labels); CeedChk(ierr); 17043668ca4bSJeremy L Thompson ierr = CeedFree(&(*op)->context_labels[i]); CeedChk(ierr); 17053668ca4bSJeremy L Thompson } 17063668ca4bSJeremy L Thompson ierr = CeedFree(&(*op)->context_labels); CeedChk(ierr); 1707fe2413ffSjeremylt 17085107b09fSJeremy L Thompson // Destroy fallback 1709805fe78eSJeremy L Thompson ierr = CeedOperatorDestroy(&(*op)->op_fallback); CeedChk(ierr); 17105107b09fSJeremy L Thompson 1711ed9e99e6SJeremy L Thompson // Destroy assembly data 1712480fae85SJeremy L Thompson ierr = CeedQFunctionAssemblyDataDestroy(&(*op)->qf_assembled); CeedChk(ierr); 1713ed9e99e6SJeremy L Thompson ierr = CeedOperatorAssemblyDataDestroy(&(*op)->op_assembled); CeedChk(ierr); 171470a7ffb3SJeremy L Thompson 1715d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields); CeedChk(ierr); 1716d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields); CeedChk(ierr); 1717d1d35e2fSjeremylt ierr = CeedFree(&(*op)->sub_operators); CeedChk(ierr); 1718ea6b5821SJeremy L Thompson ierr = CeedFree(&(*op)->name); CeedChk(ierr); 1719d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 1720e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1721d7b241e6Sjeremylt } 1722d7b241e6Sjeremylt 1723d7b241e6Sjeremylt /// @} 1724