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", 67d1d35e2fSjeremylt qf_field->field_name); 68*41bdf1c9SJeremy L Thompson // LCOV_EXCL_STOP 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, 74990fdeb6SJeremy L Thompson "Field '%s' of size %" CeedInt_FMT " and EvalMode %s: ElemRestriction " 75990fdeb6SJeremy 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 } 81*41bdf1c9SJeremy L Thompson } else if (eval_mode != CEED_EVAL_NONE) { 82*41bdf1c9SJeremy L Thompson // LCOV_EXCL_START 83*41bdf1c9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPATIBLE, 84*41bdf1c9SJeremy L Thompson "Field '%s' configured with %s cannot " 85*41bdf1c9SJeremy L Thompson "be used with CEED_BASIS_COLLOCATED", 86*41bdf1c9SJeremy L Thompson qf_field->field_name, CeedEvalModes[eval_mode]); 87*41bdf1c9SJeremy L Thompson // LCOV_EXCL_STOP 88*41bdf1c9SJeremy L Thompson 89e15f9bd0SJeremy L Thompson } 90e15f9bd0SJeremy L Thompson // Field size 91d1d35e2fSjeremylt switch(eval_mode) { 92e15f9bd0SJeremy L Thompson case CEED_EVAL_NONE: 93d1d35e2fSjeremylt if (size != restr_num_comp) 94e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 95e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 96990fdeb6SJeremy L Thompson "Field '%s' of size %" CeedInt_FMT " and EvalMode %s: ElemRestriction has " 97990fdeb6SJeremy L Thompson CeedInt_FMT " components", 98d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], 99d1d35e2fSjeremylt restr_num_comp); 100e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 101e15f9bd0SJeremy L Thompson break; 102e15f9bd0SJeremy L Thompson case CEED_EVAL_INTERP: 103d1d35e2fSjeremylt if (size != num_comp) 104e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 105e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 106990fdeb6SJeremy L Thompson "Field '%s' of size %" CeedInt_FMT 107990fdeb6SJeremy L Thompson " and EvalMode %s: ElemRestriction/Basis has " 108990fdeb6SJeremy L Thompson CeedInt_FMT " components", 109d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], 110d1d35e2fSjeremylt num_comp); 111e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 112e15f9bd0SJeremy L Thompson break; 113e15f9bd0SJeremy L Thompson case CEED_EVAL_GRAD: 114d1d35e2fSjeremylt if (size != num_comp * dim) 115e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 116e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 117990fdeb6SJeremy L Thompson "Field '%s' of size %" CeedInt_FMT " and EvalMode %s in %" CeedInt_FMT 118990fdeb6SJeremy L Thompson " dimensions: " 119990fdeb6SJeremy L Thompson "ElemRestriction/Basis has %" CeedInt_FMT " components", 120d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], dim, 121d1d35e2fSjeremylt num_comp); 122e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 123e15f9bd0SJeremy L Thompson break; 124e15f9bd0SJeremy L Thompson case CEED_EVAL_WEIGHT: 125d1d35e2fSjeremylt // No additional checks required 126e15f9bd0SJeremy L Thompson break; 127e15f9bd0SJeremy L Thompson case CEED_EVAL_DIV: 128e15f9bd0SJeremy L Thompson // Not implemented 129e15f9bd0SJeremy L Thompson break; 130e15f9bd0SJeremy L Thompson case CEED_EVAL_CURL: 131e15f9bd0SJeremy L Thompson // Not implemented 132e15f9bd0SJeremy L Thompson break; 133e15f9bd0SJeremy L Thompson } 134e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1357a982d89SJeremy L. Thompson } 1367a982d89SJeremy L. Thompson 1377a982d89SJeremy L. Thompson /** 1387a982d89SJeremy L. Thompson @brief View a field of a CeedOperator 1397a982d89SJeremy L. Thompson 1407a982d89SJeremy L. Thompson @param[in] field Operator field to view 141d1d35e2fSjeremylt @param[in] qf_field QFunction field (carries field name) 142d1d35e2fSjeremylt @param[in] field_number Number of field being viewed 1434c4400c7SValeria Barra @param[in] sub true indicates sub-operator, which increases indentation; false for top-level operator 144d1d35e2fSjeremylt @param[in] input true for an input field; false for output field 1457a982d89SJeremy L. Thompson @param[in] stream Stream to view to, e.g., stdout 1467a982d89SJeremy L. Thompson 1477a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1487a982d89SJeremy L. Thompson 1497a982d89SJeremy L. Thompson @ref Utility 1507a982d89SJeremy L. Thompson **/ 1517a982d89SJeremy L. Thompson static int CeedOperatorFieldView(CeedOperatorField field, 152d1d35e2fSjeremylt CeedQFunctionField qf_field, 153d1d35e2fSjeremylt CeedInt field_number, bool sub, bool input, 1547a982d89SJeremy L. Thompson FILE *stream) { 1557a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 156d1d35e2fSjeremylt const char *in_out = input ? "Input" : "Output"; 1577a982d89SJeremy L. Thompson 158990fdeb6SJeremy L Thompson fprintf(stream, "%s %s field %" CeedInt_FMT ":\n" 1597a982d89SJeremy L. Thompson "%s Name: \"%s\"\n", 160d1d35e2fSjeremylt pre, in_out, field_number, pre, qf_field->field_name); 1617a982d89SJeremy L. Thompson 162990fdeb6SJeremy L Thompson fprintf(stream, "%s Size: %" CeedInt_FMT "\n", pre, qf_field->size); 163f5ebfb90SJeremy L Thompson 164f5ebfb90SJeremy L Thompson fprintf(stream, "%s EvalMode: %s\n", pre, 165f5ebfb90SJeremy L Thompson CeedEvalModes[qf_field->eval_mode]); 166f5ebfb90SJeremy L Thompson 1677a982d89SJeremy L. Thompson if (field->basis == CEED_BASIS_COLLOCATED) 1687a982d89SJeremy L. Thompson fprintf(stream, "%s Collocated basis\n", pre); 1697a982d89SJeremy L. Thompson 1707a982d89SJeremy L. Thompson if (field->vec == CEED_VECTOR_ACTIVE) 1717a982d89SJeremy L. Thompson fprintf(stream, "%s Active vector\n", pre); 1727a982d89SJeremy L. Thompson else if (field->vec == CEED_VECTOR_NONE) 1737a982d89SJeremy L. Thompson fprintf(stream, "%s No vector\n", pre); 174f5ebfb90SJeremy L Thompson 175e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1767a982d89SJeremy L. Thompson } 1777a982d89SJeremy L. Thompson 1787a982d89SJeremy L. Thompson /** 1797a982d89SJeremy L. Thompson @brief View a single CeedOperator 1807a982d89SJeremy L. Thompson 1817a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 1827a982d89SJeremy L. Thompson @param[in] sub Boolean flag for sub-operator 1837a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 1847a982d89SJeremy L. Thompson 1857a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 1867a982d89SJeremy L. Thompson 1877a982d89SJeremy L. Thompson @ref Utility 1887a982d89SJeremy L. Thompson **/ 1897a982d89SJeremy L. Thompson int CeedOperatorSingleView(CeedOperator op, bool sub, FILE *stream) { 1907a982d89SJeremy L. Thompson int ierr; 1917a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 1927a982d89SJeremy L. Thompson 193381e6593SJeremy L Thompson CeedInt num_elem, num_qpts; 194381e6593SJeremy L Thompson ierr = CeedOperatorGetNumElements(op, &num_elem); CeedChk(ierr); 195381e6593SJeremy L Thompson ierr = CeedOperatorGetNumQuadraturePoints(op, &num_qpts); CeedChk(ierr); 196381e6593SJeremy L Thompson 19778464608Sjeremylt CeedInt total_fields = 0; 19878464608Sjeremylt ierr = CeedOperatorGetNumArgs(op, &total_fields); CeedChk(ierr); 199990fdeb6SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " elements with %" CeedInt_FMT 200990fdeb6SJeremy L Thompson " quadrature points each\n", 201381e6593SJeremy L Thompson pre, num_elem, num_qpts); 2027a982d89SJeremy L. Thompson 203990fdeb6SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " field%s\n", pre, total_fields, 20478464608Sjeremylt total_fields>1 ? "s" : ""); 2057a982d89SJeremy L. Thompson 206990fdeb6SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " input field%s:\n", pre, 207990fdeb6SJeremy L Thompson op->qf->num_input_fields, 208d1d35e2fSjeremylt op->qf->num_input_fields>1 ? "s" : ""); 209d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_input_fields; i++) { 210d1d35e2fSjeremylt ierr = CeedOperatorFieldView(op->input_fields[i], op->qf->input_fields[i], 2117a982d89SJeremy L. Thompson i, sub, 1, stream); CeedChk(ierr); 2127a982d89SJeremy L. Thompson } 2137a982d89SJeremy L. Thompson 214990fdeb6SJeremy L Thompson fprintf(stream, "%s %" CeedInt_FMT " output field%s:\n", pre, 215990fdeb6SJeremy L Thompson op->qf->num_output_fields, 216d1d35e2fSjeremylt op->qf->num_output_fields>1 ? "s" : ""); 217d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_output_fields; i++) { 218d1d35e2fSjeremylt ierr = CeedOperatorFieldView(op->output_fields[i], op->qf->output_fields[i], 2197a982d89SJeremy L. Thompson i, sub, 0, stream); CeedChk(ierr); 2207a982d89SJeremy L. Thompson } 221e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2227a982d89SJeremy L. Thompson } 2237a982d89SJeremy L. Thompson 224d99fa3c5SJeremy L Thompson /** 2250f60e0a8SJeremy L Thompson @brief Find the active vector basis for a non-composite CeedOperator 226eaf62fffSJeremy L Thompson 227eaf62fffSJeremy L Thompson @param[in] op CeedOperator to find active basis for 2280f60e0a8SJeremy L Thompson @param[out] active_basis Basis for active input vector or NULL for composite operator 229eaf62fffSJeremy L Thompson 230eaf62fffSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 231eaf62fffSJeremy L Thompson 232eaf62fffSJeremy L Thompson @ ref Developer 233eaf62fffSJeremy L Thompson **/ 234eaf62fffSJeremy L Thompson int CeedOperatorGetActiveBasis(CeedOperator op, CeedBasis *active_basis) { 235eaf62fffSJeremy L Thompson *active_basis = NULL; 2360f60e0a8SJeremy L Thompson if (op->is_composite) return CEED_ERROR_SUCCESS; 23792ae7e47SJeremy L Thompson for (CeedInt i = 0; i < op->qf->num_input_fields; i++) 238eaf62fffSJeremy L Thompson if (op->input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 239eaf62fffSJeremy L Thompson *active_basis = op->input_fields[i]->basis; 240eaf62fffSJeremy L Thompson break; 241eaf62fffSJeremy L Thompson } 242eaf62fffSJeremy L Thompson 243eaf62fffSJeremy L Thompson if (!*active_basis) { 244eaf62fffSJeremy L Thompson // LCOV_EXCL_START 245eaf62fffSJeremy L Thompson int ierr; 246eaf62fffSJeremy L Thompson Ceed ceed; 247eaf62fffSJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 248eaf62fffSJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 249eaf62fffSJeremy L Thompson "No active CeedBasis found"); 250eaf62fffSJeremy L Thompson // LCOV_EXCL_STOP 251eaf62fffSJeremy L Thompson } 252eaf62fffSJeremy L Thompson return CEED_ERROR_SUCCESS; 253eaf62fffSJeremy L Thompson } 254eaf62fffSJeremy L Thompson 255eaf62fffSJeremy L Thompson /** 2560f60e0a8SJeremy L Thompson @brief Find the active vector ElemRestriction for a non-composite CeedOperator 257e2f04181SAndrew T. Barker 258e2f04181SAndrew T. Barker @param[in] op CeedOperator to find active basis for 2590f60e0a8SJeremy L Thompson @param[out] active_rstr ElemRestriction for active input vector or NULL for composite operator 260e2f04181SAndrew T. Barker 261e2f04181SAndrew T. Barker @return An error code: 0 - success, otherwise - failure 262e2f04181SAndrew T. Barker 263e2f04181SAndrew T. Barker @ref Utility 264e2f04181SAndrew T. Barker **/ 265eaf62fffSJeremy L Thompson int CeedOperatorGetActiveElemRestriction(CeedOperator op, 266d1d35e2fSjeremylt CeedElemRestriction *active_rstr) { 267d1d35e2fSjeremylt *active_rstr = NULL; 2680f60e0a8SJeremy L Thompson if (op->is_composite) return CEED_ERROR_SUCCESS; 26992ae7e47SJeremy L Thompson for (CeedInt i = 0; i < op->qf->num_input_fields; i++) 270d1d35e2fSjeremylt if (op->input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 271d1d35e2fSjeremylt *active_rstr = op->input_fields[i]->elem_restr; 272e2f04181SAndrew T. Barker break; 273e2f04181SAndrew T. Barker } 274e2f04181SAndrew T. Barker 275d1d35e2fSjeremylt if (!*active_rstr) { 276e2f04181SAndrew T. Barker // LCOV_EXCL_START 277e2f04181SAndrew T. Barker int ierr; 278e2f04181SAndrew T. Barker Ceed ceed; 279e2f04181SAndrew T. Barker ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 280e2f04181SAndrew T. Barker return CeedError(ceed, CEED_ERROR_INCOMPLETE, 281eaf62fffSJeremy L Thompson "No active CeedElemRestriction found"); 282e2f04181SAndrew T. Barker // LCOV_EXCL_STOP 283e2f04181SAndrew T. Barker } 284e2f04181SAndrew T. Barker return CEED_ERROR_SUCCESS; 285e2f04181SAndrew T. Barker } 286e2f04181SAndrew T. Barker 287d8dd9a91SJeremy L Thompson /** 288d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field value of the specified type. 289d8dd9a91SJeremy L Thompson For composite operators, the value is set in all 290d8dd9a91SJeremy L Thompson sub-operator QFunctionContexts that have a matching `field_name`. 291d8dd9a91SJeremy L Thompson A non-zero error code is returned for single operators 292d8dd9a91SJeremy L Thompson that do not have a matching field of the same type or composite 293d8dd9a91SJeremy L Thompson operators that do not have any field of a matching type. 294d8dd9a91SJeremy L Thompson 295d8dd9a91SJeremy L Thompson @param op CeedOperator 2963668ca4bSJeremy L Thompson @param field_label Label of field to set 297d8dd9a91SJeremy L Thompson @param field_type Type of field to set 298d8dd9a91SJeremy L Thompson @param value Value to set 299d8dd9a91SJeremy L Thompson 300d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 301d8dd9a91SJeremy L Thompson 302d8dd9a91SJeremy L Thompson @ref User 303d8dd9a91SJeremy L Thompson **/ 304d8dd9a91SJeremy L Thompson static int CeedOperatorContextSetGeneric(CeedOperator op, 3053668ca4bSJeremy L Thompson CeedContextFieldLabel field_label, CeedContextFieldType field_type, 3063668ca4bSJeremy L Thompson void *value) { 307d8dd9a91SJeremy L Thompson int ierr; 308d8dd9a91SJeremy L Thompson 3093668ca4bSJeremy L Thompson if (!field_label) 3103668ca4bSJeremy L Thompson // LCOV_EXCL_START 3113668ca4bSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_UNSUPPORTED, 3123668ca4bSJeremy L Thompson "Invalid field label"); 3133668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 3143668ca4bSJeremy L Thompson 3153668ca4bSJeremy L Thompson bool is_composite = false; 316d8dd9a91SJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 317d8dd9a91SJeremy L Thompson if (is_composite) { 318d8dd9a91SJeremy L Thompson CeedInt num_sub; 319d8dd9a91SJeremy L Thompson CeedOperator *sub_operators; 320d8dd9a91SJeremy L Thompson 321d8dd9a91SJeremy L Thompson ierr = CeedOperatorGetNumSub(op, &num_sub); CeedChk(ierr); 322d8dd9a91SJeremy L Thompson ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 3233668ca4bSJeremy L Thompson if (num_sub != field_label->num_sub_labels) 3243668ca4bSJeremy L Thompson // LCOV_EXCL_START 3253668ca4bSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_UNSUPPORTED, 3263668ca4bSJeremy L Thompson "ContextLabel does not correspond to composite operator.\n" 3273668ca4bSJeremy L Thompson "Use CeedOperatorGetContextFieldLabel()."); 3283668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 329d8dd9a91SJeremy L Thompson 330d8dd9a91SJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 331d8dd9a91SJeremy L Thompson // Try every sub-operator, ok if some sub-operators do not have field 3323668ca4bSJeremy L Thompson if (field_label->sub_labels[i] && sub_operators[i]->qf->ctx) { 3333668ca4bSJeremy L Thompson ierr = CeedQFunctionContextSetGeneric(sub_operators[i]->qf->ctx, 3343668ca4bSJeremy L Thompson field_label->sub_labels[i], 3353668ca4bSJeremy L Thompson field_type, value); CeedChk(ierr); 336d8dd9a91SJeremy L Thompson } 337d8dd9a91SJeremy L Thompson } 338d8dd9a91SJeremy L Thompson } else { 339d8dd9a91SJeremy L Thompson if (!op->qf->ctx) 340d8dd9a91SJeremy L Thompson // LCOV_EXCL_START 341d8dd9a91SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_UNSUPPORTED, 342d8dd9a91SJeremy L Thompson "QFunction does not have context data"); 343d8dd9a91SJeremy L Thompson // LCOV_EXCL_STOP 344d8dd9a91SJeremy L Thompson 3453668ca4bSJeremy L Thompson ierr = CeedQFunctionContextSetGeneric(op->qf->ctx, field_label, 3463668ca4bSJeremy L Thompson field_type, value); CeedChk(ierr); 347d8dd9a91SJeremy L Thompson } 348d8dd9a91SJeremy L Thompson 349d8dd9a91SJeremy L Thompson return CEED_ERROR_SUCCESS; 350d8dd9a91SJeremy L Thompson } 351d8dd9a91SJeremy L Thompson 3527a982d89SJeremy L. Thompson /// @} 3537a982d89SJeremy L. Thompson 3547a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3557a982d89SJeremy L. Thompson /// CeedOperator Backend API 3567a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3577a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorBackend 3587a982d89SJeremy L. Thompson /// @{ 3597a982d89SJeremy L. Thompson 3607a982d89SJeremy L. Thompson /** 3617a982d89SJeremy L. Thompson @brief Get the number of arguments associated with a CeedOperator 3627a982d89SJeremy L. Thompson 3637a982d89SJeremy L. Thompson @param op CeedOperator 364d1d35e2fSjeremylt @param[out] num_args Variable to store vector number of arguments 3657a982d89SJeremy L. Thompson 3667a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3677a982d89SJeremy L. Thompson 3687a982d89SJeremy L. Thompson @ref Backend 3697a982d89SJeremy L. Thompson **/ 3707a982d89SJeremy L. Thompson 371d1d35e2fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *num_args) { 372f04ea552SJeremy L Thompson if (op->is_composite) 3737a982d89SJeremy L. Thompson // LCOV_EXCL_START 374e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 375e15f9bd0SJeremy L Thompson "Not defined for composite operators"); 3767a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 3777a982d89SJeremy L. Thompson 378d1d35e2fSjeremylt *num_args = op->num_fields; 379e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3807a982d89SJeremy L. Thompson } 3817a982d89SJeremy L. Thompson 3827a982d89SJeremy L. Thompson /** 3837a982d89SJeremy L. Thompson @brief Get the setup status of a CeedOperator 3847a982d89SJeremy L. Thompson 3857a982d89SJeremy L. Thompson @param op CeedOperator 386d1d35e2fSjeremylt @param[out] is_setup_done Variable to store setup status 3877a982d89SJeremy L. Thompson 3887a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3897a982d89SJeremy L. Thompson 3907a982d89SJeremy L. Thompson @ref Backend 3917a982d89SJeremy L. Thompson **/ 3927a982d89SJeremy L. Thompson 393d1d35e2fSjeremylt int CeedOperatorIsSetupDone(CeedOperator op, bool *is_setup_done) { 394f04ea552SJeremy L Thompson *is_setup_done = op->is_backend_setup; 395e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3967a982d89SJeremy L. Thompson } 3977a982d89SJeremy L. Thompson 3987a982d89SJeremy L. Thompson /** 3997a982d89SJeremy L. Thompson @brief Get the QFunction associated with a CeedOperator 4007a982d89SJeremy L. Thompson 4017a982d89SJeremy L. Thompson @param op CeedOperator 4027a982d89SJeremy L. Thompson @param[out] qf Variable to store QFunction 4037a982d89SJeremy L. Thompson 4047a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4057a982d89SJeremy L. Thompson 4067a982d89SJeremy L. Thompson @ref Backend 4077a982d89SJeremy L. Thompson **/ 4087a982d89SJeremy L. Thompson 4097a982d89SJeremy L. Thompson int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 410f04ea552SJeremy L Thompson if (op->is_composite) 4117a982d89SJeremy L. Thompson // LCOV_EXCL_START 412e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 413e15f9bd0SJeremy L Thompson "Not defined for composite operator"); 4147a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4157a982d89SJeremy L. Thompson 4167a982d89SJeremy L. Thompson *qf = op->qf; 417e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4187a982d89SJeremy L. Thompson } 4197a982d89SJeremy L. Thompson 4207a982d89SJeremy L. Thompson /** 421c04a41a7SJeremy L Thompson @brief Get a boolean value indicating if the CeedOperator is composite 422c04a41a7SJeremy L Thompson 423c04a41a7SJeremy L Thompson @param op CeedOperator 424d1d35e2fSjeremylt @param[out] is_composite Variable to store composite status 425c04a41a7SJeremy L Thompson 426c04a41a7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 427c04a41a7SJeremy L Thompson 428c04a41a7SJeremy L Thompson @ref Backend 429c04a41a7SJeremy L Thompson **/ 430c04a41a7SJeremy L Thompson 431d1d35e2fSjeremylt int CeedOperatorIsComposite(CeedOperator op, bool *is_composite) { 432f04ea552SJeremy L Thompson *is_composite = op->is_composite; 433e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 434c04a41a7SJeremy L Thompson } 435c04a41a7SJeremy L Thompson 436c04a41a7SJeremy L Thompson /** 437d1d35e2fSjeremylt @brief Get the number of sub_operators associated with a CeedOperator 4387a982d89SJeremy L. Thompson 4397a982d89SJeremy L. Thompson @param op CeedOperator 440d1d35e2fSjeremylt @param[out] num_suboperators Variable to store number of sub_operators 4417a982d89SJeremy L. Thompson 4427a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4437a982d89SJeremy L. Thompson 4447a982d89SJeremy L. Thompson @ref Backend 4457a982d89SJeremy L. Thompson **/ 4467a982d89SJeremy L. Thompson 447d1d35e2fSjeremylt int CeedOperatorGetNumSub(CeedOperator op, CeedInt *num_suboperators) { 448f04ea552SJeremy L Thompson if (!op->is_composite) 4497a982d89SJeremy L. Thompson // LCOV_EXCL_START 450e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 4517a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4527a982d89SJeremy L. Thompson 453d1d35e2fSjeremylt *num_suboperators = op->num_suboperators; 454e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4557a982d89SJeremy L. Thompson } 4567a982d89SJeremy L. Thompson 4577a982d89SJeremy L. Thompson /** 458d1d35e2fSjeremylt @brief Get the list of sub_operators associated with a CeedOperator 4597a982d89SJeremy L. Thompson 4607a982d89SJeremy L. Thompson @param op CeedOperator 461d1d35e2fSjeremylt @param[out] sub_operators Variable to store list of sub_operators 4627a982d89SJeremy L. Thompson 4637a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4647a982d89SJeremy L. Thompson 4657a982d89SJeremy L. Thompson @ref Backend 4667a982d89SJeremy L. Thompson **/ 4677a982d89SJeremy L. Thompson 468d1d35e2fSjeremylt int CeedOperatorGetSubList(CeedOperator op, CeedOperator **sub_operators) { 469f04ea552SJeremy L Thompson if (!op->is_composite) 4707a982d89SJeremy L. Thompson // LCOV_EXCL_START 471e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 4727a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4737a982d89SJeremy L. Thompson 474d1d35e2fSjeremylt *sub_operators = op->sub_operators; 475e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4767a982d89SJeremy L. Thompson } 4777a982d89SJeremy L. Thompson 4787a982d89SJeremy L. Thompson /** 4797a982d89SJeremy L. Thompson @brief Get the backend data of a CeedOperator 4807a982d89SJeremy L. Thompson 4817a982d89SJeremy L. Thompson @param op CeedOperator 4827a982d89SJeremy L. Thompson @param[out] data Variable to store data 4837a982d89SJeremy L. Thompson 4847a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4857a982d89SJeremy L. Thompson 4867a982d89SJeremy L. Thompson @ref Backend 4877a982d89SJeremy L. Thompson **/ 4887a982d89SJeremy L. Thompson 489777ff853SJeremy L Thompson int CeedOperatorGetData(CeedOperator op, void *data) { 490777ff853SJeremy L Thompson *(void **)data = op->data; 491e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4927a982d89SJeremy L. Thompson } 4937a982d89SJeremy L. Thompson 4947a982d89SJeremy L. Thompson /** 4957a982d89SJeremy L. Thompson @brief Set the backend data of a CeedOperator 4967a982d89SJeremy L. Thompson 4977a982d89SJeremy L. Thompson @param[out] op CeedOperator 4987a982d89SJeremy L. Thompson @param data Data to set 4997a982d89SJeremy L. Thompson 5007a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5017a982d89SJeremy L. Thompson 5027a982d89SJeremy L. Thompson @ref Backend 5037a982d89SJeremy L. Thompson **/ 5047a982d89SJeremy L. Thompson 505777ff853SJeremy L Thompson int CeedOperatorSetData(CeedOperator op, void *data) { 506777ff853SJeremy L Thompson op->data = data; 507e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5087a982d89SJeremy L. Thompson } 5097a982d89SJeremy L. Thompson 5107a982d89SJeremy L. Thompson /** 51134359f16Sjeremylt @brief Increment the reference counter for a CeedOperator 51234359f16Sjeremylt 51334359f16Sjeremylt @param op CeedOperator to increment the reference counter 51434359f16Sjeremylt 51534359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 51634359f16Sjeremylt 51734359f16Sjeremylt @ref Backend 51834359f16Sjeremylt **/ 5199560d06aSjeremylt int CeedOperatorReference(CeedOperator op) { 52034359f16Sjeremylt op->ref_count++; 52134359f16Sjeremylt return CEED_ERROR_SUCCESS; 52234359f16Sjeremylt } 52334359f16Sjeremylt 52434359f16Sjeremylt /** 5257a982d89SJeremy L. Thompson @brief Set the setup flag of a CeedOperator to True 5267a982d89SJeremy L. Thompson 5277a982d89SJeremy L. Thompson @param op CeedOperator 5287a982d89SJeremy L. Thompson 5297a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5307a982d89SJeremy L. Thompson 5317a982d89SJeremy L. Thompson @ref Backend 5327a982d89SJeremy L. Thompson **/ 5337a982d89SJeremy L. Thompson 5347a982d89SJeremy L. Thompson int CeedOperatorSetSetupDone(CeedOperator op) { 535f04ea552SJeremy L Thompson op->is_backend_setup = true; 536e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5377a982d89SJeremy L. Thompson } 5387a982d89SJeremy L. Thompson 5397a982d89SJeremy L. Thompson /// @} 5407a982d89SJeremy L. Thompson 5417a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5427a982d89SJeremy L. Thompson /// CeedOperator Public API 5437a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5447a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorUser 545dfdf5a53Sjeremylt /// @{ 546d7b241e6Sjeremylt 547d7b241e6Sjeremylt /** 5480219ea01SJeremy L Thompson @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and 5490219ea01SJeremy L Thompson CeedElemRestriction can be associated with CeedQFunction fields with 5500219ea01SJeremy L Thompson \ref CeedOperatorSetField. 551d7b241e6Sjeremylt 552b11c1e72Sjeremylt @param ceed A Ceed object where the CeedOperator will be created 553d7b241e6Sjeremylt @param qf QFunction defining the action of the operator at quadrature points 55434138859Sjeremylt @param dqf QFunction defining the action of the Jacobian of @a qf (or 5554cc79fe7SJed Brown @ref CEED_QFUNCTION_NONE) 556d7b241e6Sjeremylt @param dqfT QFunction defining the action of the transpose of the Jacobian 5574cc79fe7SJed Brown of @a qf (or @ref CEED_QFUNCTION_NONE) 558b11c1e72Sjeremylt @param[out] op Address of the variable where the newly created 559b11c1e72Sjeremylt CeedOperator will be stored 560b11c1e72Sjeremylt 561b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 562dfdf5a53Sjeremylt 5637a982d89SJeremy L. Thompson @ref User 564d7b241e6Sjeremylt */ 565d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, 566d7b241e6Sjeremylt CeedQFunction dqfT, CeedOperator *op) { 567d7b241e6Sjeremylt int ierr; 568d7b241e6Sjeremylt 5695fe0d4faSjeremylt if (!ceed->OperatorCreate) { 5705fe0d4faSjeremylt Ceed delegate; 571aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 5725fe0d4faSjeremylt 5735fe0d4faSjeremylt if (!delegate) 574c042f62fSJeremy L Thompson // LCOV_EXCL_START 575e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 576e15f9bd0SJeremy L Thompson "Backend does not support OperatorCreate"); 577c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 5785fe0d4faSjeremylt 5795fe0d4faSjeremylt ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr); 580e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5815fe0d4faSjeremylt } 5825fe0d4faSjeremylt 583b3b7035fSJeremy L Thompson if (!qf || qf == CEED_QFUNCTION_NONE) 584b3b7035fSJeremy L Thompson // LCOV_EXCL_START 585e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 586e15f9bd0SJeremy L Thompson "Operator must have a valid QFunction."); 587b3b7035fSJeremy L Thompson // LCOV_EXCL_STOP 588d7b241e6Sjeremylt ierr = CeedCalloc(1, op); CeedChk(ierr); 589d7b241e6Sjeremylt (*op)->ceed = ceed; 5909560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 591d1d35e2fSjeremylt (*op)->ref_count = 1; 592d7b241e6Sjeremylt (*op)->qf = qf; 5932b104005SJeremy L Thompson (*op)->input_size = -1; 5942b104005SJeremy L Thompson (*op)->output_size = -1; 5959560d06aSjeremylt ierr = CeedQFunctionReference(qf); CeedChk(ierr); 596442e7f0bSjeremylt if (dqf && dqf != CEED_QFUNCTION_NONE) { 597d7b241e6Sjeremylt (*op)->dqf = dqf; 5989560d06aSjeremylt ierr = CeedQFunctionReference(dqf); CeedChk(ierr); 599442e7f0bSjeremylt } 600442e7f0bSjeremylt if (dqfT && dqfT != CEED_QFUNCTION_NONE) { 601d7b241e6Sjeremylt (*op)->dqfT = dqfT; 6029560d06aSjeremylt ierr = CeedQFunctionReference(dqfT); CeedChk(ierr); 603442e7f0bSjeremylt } 604480fae85SJeremy L Thompson ierr = CeedQFunctionAssemblyDataCreate(ceed, &(*op)->qf_assembled); 605480fae85SJeremy L Thompson CeedChk(ierr); 606bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_FIELD_MAX, &(*op)->input_fields); CeedChk(ierr); 607bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_FIELD_MAX, &(*op)->output_fields); CeedChk(ierr); 608d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 609e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 610d7b241e6Sjeremylt } 611d7b241e6Sjeremylt 612d7b241e6Sjeremylt /** 61352d6035fSJeremy L Thompson @brief Create an operator that composes the action of several operators 61452d6035fSJeremy L Thompson 61552d6035fSJeremy L Thompson @param ceed A Ceed object where the CeedOperator will be created 61652d6035fSJeremy L Thompson @param[out] op Address of the variable where the newly created 61752d6035fSJeremy L Thompson Composite CeedOperator will be stored 61852d6035fSJeremy L Thompson 61952d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 62052d6035fSJeremy L Thompson 6217a982d89SJeremy L. Thompson @ref User 62252d6035fSJeremy L Thompson */ 62352d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) { 62452d6035fSJeremy L Thompson int ierr; 62552d6035fSJeremy L Thompson 62652d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 62752d6035fSJeremy L Thompson Ceed delegate; 628aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 62952d6035fSJeremy L Thompson 630250756a7Sjeremylt if (delegate) { 63152d6035fSJeremy L Thompson ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr); 632e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 63352d6035fSJeremy L Thompson } 634250756a7Sjeremylt } 63552d6035fSJeremy L Thompson 63652d6035fSJeremy L Thompson ierr = CeedCalloc(1, op); CeedChk(ierr); 63752d6035fSJeremy L Thompson (*op)->ceed = ceed; 6389560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 639f04ea552SJeremy L Thompson (*op)->is_composite = true; 640bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_COMPOSITE_MAX, &(*op)->sub_operators); CeedChk(ierr); 6412b104005SJeremy L Thompson (*op)->input_size = -1; 6422b104005SJeremy L Thompson (*op)->output_size = -1; 643250756a7Sjeremylt 644250756a7Sjeremylt if (ceed->CompositeOperatorCreate) { 64552d6035fSJeremy L Thompson ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr); 646250756a7Sjeremylt } 647e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 64852d6035fSJeremy L Thompson } 64952d6035fSJeremy L Thompson 65052d6035fSJeremy L Thompson /** 6519560d06aSjeremylt @brief Copy the pointer to a CeedOperator. Both pointers should 6529560d06aSjeremylt be destroyed with `CeedOperatorDestroy()`; 6539560d06aSjeremylt Note: If `*op_copy` is non-NULL, then it is assumed that 6549560d06aSjeremylt `*op_copy` is a pointer to a CeedOperator. This 6559560d06aSjeremylt CeedOperator will be destroyed if `*op_copy` is the only 6569560d06aSjeremylt reference to this CeedOperator. 6579560d06aSjeremylt 6589560d06aSjeremylt @param op CeedOperator to copy reference to 6599560d06aSjeremylt @param[out] op_copy Variable to store copied reference 6609560d06aSjeremylt 6619560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 6629560d06aSjeremylt 6639560d06aSjeremylt @ref User 6649560d06aSjeremylt **/ 6659560d06aSjeremylt int CeedOperatorReferenceCopy(CeedOperator op, CeedOperator *op_copy) { 6669560d06aSjeremylt int ierr; 6679560d06aSjeremylt 6689560d06aSjeremylt ierr = CeedOperatorReference(op); CeedChk(ierr); 6699560d06aSjeremylt ierr = CeedOperatorDestroy(op_copy); CeedChk(ierr); 6709560d06aSjeremylt *op_copy = op; 6719560d06aSjeremylt return CEED_ERROR_SUCCESS; 6729560d06aSjeremylt } 6739560d06aSjeremylt 6749560d06aSjeremylt /** 675b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 676d7b241e6Sjeremylt 677d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 678d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 679d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 680d7b241e6Sjeremylt 681d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 682d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 683979e564eSJames Wright input CeedVector and at most one active output CeedVector passed to 684979e564eSJames Wright CeedOperatorApply(). 685d7b241e6Sjeremylt 6868c91a0c9SJeremy L Thompson @param op CeedOperator on which to provide the field 687d1d35e2fSjeremylt @param field_name Name of the field (to be matched with the name used by 6888795c945Sjeremylt CeedQFunction) 689b11c1e72Sjeremylt @param r CeedElemRestriction 6904cc79fe7SJed Brown @param b CeedBasis in which the field resides or @ref CEED_BASIS_COLLOCATED 691b11c1e72Sjeremylt if collocated with quadrature points 6924cc79fe7SJed Brown @param v CeedVector to be used by CeedOperator or @ref CEED_VECTOR_ACTIVE 6934cc79fe7SJed Brown if field is active or @ref CEED_VECTOR_NONE if using 6944cc79fe7SJed Brown @ref CEED_EVAL_WEIGHT in the QFunction 695b11c1e72Sjeremylt 696b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 697dfdf5a53Sjeremylt 6987a982d89SJeremy L. Thompson @ref User 699b11c1e72Sjeremylt **/ 700d1d35e2fSjeremylt int CeedOperatorSetField(CeedOperator op, const char *field_name, 701a8d32208Sjeremylt CeedElemRestriction r, CeedBasis b, CeedVector v) { 702d7b241e6Sjeremylt int ierr; 703f04ea552SJeremy L Thompson if (op->is_composite) 704c042f62fSJeremy L Thompson // LCOV_EXCL_START 705e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 706e15f9bd0SJeremy L Thompson "Cannot add field to composite operator."); 707c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 708f04ea552SJeremy L Thompson if (op->is_immutable) 709f04ea552SJeremy L Thompson // LCOV_EXCL_START 710f04ea552SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 711f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 712f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 7138b067b84SJed Brown if (!r) 714c042f62fSJeremy L Thompson // LCOV_EXCL_START 715e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 716c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 717d1d35e2fSjeremylt field_name); 718c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 7198b067b84SJed Brown if (!b) 720c042f62fSJeremy L Thompson // LCOV_EXCL_START 721e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 722e15f9bd0SJeremy L Thompson "Basis b for field \"%s\" must be non-NULL.", 723d1d35e2fSjeremylt field_name); 724c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 7258b067b84SJed Brown if (!v) 726c042f62fSJeremy L Thompson // LCOV_EXCL_START 727e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 728e15f9bd0SJeremy L Thompson "Vector v for field \"%s\" must be non-NULL.", 729d1d35e2fSjeremylt field_name); 730c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 73152d6035fSJeremy L Thompson 732d1d35e2fSjeremylt CeedInt num_elem; 733d1d35e2fSjeremylt ierr = CeedElemRestrictionGetNumElements(r, &num_elem); CeedChk(ierr); 734d1d35e2fSjeremylt if (r != CEED_ELEMRESTRICTION_NONE && op->has_restriction && 735d1d35e2fSjeremylt op->num_elem != num_elem) 736c042f62fSJeremy L Thompson // LCOV_EXCL_START 737e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 738990fdeb6SJeremy L Thompson "ElemRestriction with %" CeedInt_FMT " elements incompatible with prior " 739990fdeb6SJeremy L Thompson CeedInt_FMT " elements", num_elem, op->num_elem); 740c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 741d7b241e6Sjeremylt 74278464608Sjeremylt CeedInt num_qpts = 0; 743e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 744d1d35e2fSjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &num_qpts); CeedChk(ierr); 745d1d35e2fSjeremylt if (op->num_qpts && op->num_qpts != num_qpts) 746c042f62fSJeremy L Thompson // LCOV_EXCL_START 747e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 748990fdeb6SJeremy L Thompson "Basis with %" CeedInt_FMT " quadrature points " 749990fdeb6SJeremy L Thompson "incompatible with prior %" CeedInt_FMT " points", num_qpts, 750d1d35e2fSjeremylt op->num_qpts); 751c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 752d7b241e6Sjeremylt } 753d1d35e2fSjeremylt CeedQFunctionField qf_field; 754d1d35e2fSjeremylt CeedOperatorField *op_field; 7552b104005SJeremy L Thompson bool is_input = true; 756d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_input_fields; i++) { 757d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->input_fields[i]).field_name)) { 758d1d35e2fSjeremylt qf_field = op->qf->input_fields[i]; 759d1d35e2fSjeremylt op_field = &op->input_fields[i]; 760d7b241e6Sjeremylt goto found; 761d7b241e6Sjeremylt } 762d7b241e6Sjeremylt } 7632b104005SJeremy L Thompson is_input = false; 764d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_output_fields; i++) { 765d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->output_fields[i]).field_name)) { 766d1d35e2fSjeremylt qf_field = op->qf->output_fields[i]; 767d1d35e2fSjeremylt op_field = &op->output_fields[i]; 768d7b241e6Sjeremylt goto found; 769d7b241e6Sjeremylt } 770d7b241e6Sjeremylt } 771c042f62fSJeremy L Thompson // LCOV_EXCL_START 772e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPLETE, 773e15f9bd0SJeremy L Thompson "QFunction has no knowledge of field '%s'", 774d1d35e2fSjeremylt field_name); 775c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 776d7b241e6Sjeremylt found: 777d1d35e2fSjeremylt ierr = CeedOperatorCheckField(op->ceed, qf_field, r, b); CeedChk(ierr); 778d1d35e2fSjeremylt ierr = CeedCalloc(1, op_field); CeedChk(ierr); 779e15f9bd0SJeremy L Thompson 7802b104005SJeremy L Thompson if (v == CEED_VECTOR_ACTIVE) { 7812b104005SJeremy L Thompson CeedSize l_size; 7822b104005SJeremy L Thompson ierr = CeedElemRestrictionGetLVectorSize(r, &l_size); CeedChk(ierr); 7832b104005SJeremy L Thompson if (is_input) { 7842b104005SJeremy L Thompson if (op->input_size == -1) op->input_size = l_size; 7852b104005SJeremy L Thompson if (l_size != op->input_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->input_size); 7902b104005SJeremy L Thompson // LCOV_EXCL_STOP 7912b104005SJeremy L Thompson } else { 7922b104005SJeremy L Thompson if (op->output_size == -1) op->output_size = l_size; 7932b104005SJeremy L Thompson if (l_size != op->output_size) 7942b104005SJeremy L Thompson // LCOV_EXCL_START 7952b104005SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 7962b104005SJeremy L Thompson "LVector size %td does not match previous size %td", 7972b104005SJeremy L Thompson l_size, op->output_size); 7982b104005SJeremy L Thompson // LCOV_EXCL_STOP 7992b104005SJeremy L Thompson } 8002b104005SJeremy L Thompson } 8012b104005SJeremy L Thompson 802d1d35e2fSjeremylt (*op_field)->vec = v; 803e15f9bd0SJeremy L Thompson if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) { 8049560d06aSjeremylt ierr = CeedVectorReference(v); CeedChk(ierr); 805e15f9bd0SJeremy L Thompson } 806e15f9bd0SJeremy L Thompson 807d1d35e2fSjeremylt (*op_field)->elem_restr = r; 8089560d06aSjeremylt ierr = CeedElemRestrictionReference(r); CeedChk(ierr); 809e15f9bd0SJeremy L Thompson if (r != CEED_ELEMRESTRICTION_NONE) { 810d1d35e2fSjeremylt op->num_elem = num_elem; 811d1d35e2fSjeremylt op->has_restriction = true; // Restriction set, but num_elem may be 0 812e15f9bd0SJeremy L Thompson } 813d99fa3c5SJeremy L Thompson 814d1d35e2fSjeremylt (*op_field)->basis = b; 815e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 816cd4dfc48Sjeremylt if (!op->num_qpts) { 817cd4dfc48Sjeremylt ierr = CeedOperatorSetNumQuadraturePoints(op, num_qpts); CeedChk(ierr); 818cd4dfc48Sjeremylt } 8199560d06aSjeremylt ierr = CeedBasisReference(b); CeedChk(ierr); 820e15f9bd0SJeremy L Thompson } 821e15f9bd0SJeremy L Thompson 822d1d35e2fSjeremylt op->num_fields += 1; 823f7e22acaSJeremy L Thompson ierr = CeedStringAllocCopy(field_name, (char **)&(*op_field)->field_name); 824f7e22acaSJeremy L Thompson CeedChk(ierr); 825e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 826d7b241e6Sjeremylt } 827d7b241e6Sjeremylt 828d7b241e6Sjeremylt /** 82943bbe138SJeremy L Thompson @brief Get the CeedOperatorFields of a CeedOperator 83043bbe138SJeremy L Thompson 831f04ea552SJeremy L Thompson Note: Calling this function asserts that setup is complete 832f04ea552SJeremy L Thompson and sets the CeedOperator as immutable. 833f04ea552SJeremy L Thompson 83443bbe138SJeremy L Thompson @param op CeedOperator 835f74ec584SJeremy L Thompson @param[out] num_input_fields Variable to store number of input fields 83643bbe138SJeremy L Thompson @param[out] input_fields Variable to store input_fields 837f74ec584SJeremy L Thompson @param[out] num_output_fields Variable to store number of output fields 83843bbe138SJeremy L Thompson @param[out] output_fields Variable to store output_fields 83943bbe138SJeremy L Thompson 84043bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 84143bbe138SJeremy L Thompson 842e9b533fbSJeremy L Thompson @ref Advanced 84343bbe138SJeremy L Thompson **/ 84443bbe138SJeremy L Thompson int CeedOperatorGetFields(CeedOperator op, CeedInt *num_input_fields, 84543bbe138SJeremy L Thompson CeedOperatorField **input_fields, 84643bbe138SJeremy L Thompson CeedInt *num_output_fields, 84743bbe138SJeremy L Thompson CeedOperatorField **output_fields) { 848f04ea552SJeremy L Thompson int ierr; 849f04ea552SJeremy L Thompson 850f04ea552SJeremy L Thompson if (op->is_composite) 85143bbe138SJeremy L Thompson // LCOV_EXCL_START 85243bbe138SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 85343bbe138SJeremy L Thompson "Not defined for composite operator"); 85443bbe138SJeremy L Thompson // LCOV_EXCL_STOP 855f04ea552SJeremy L Thompson ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 85643bbe138SJeremy L Thompson 85743bbe138SJeremy L Thompson if (num_input_fields) *num_input_fields = op->qf->num_input_fields; 85843bbe138SJeremy L Thompson if (input_fields) *input_fields = op->input_fields; 85943bbe138SJeremy L Thompson if (num_output_fields) *num_output_fields = op->qf->num_output_fields; 86043bbe138SJeremy L Thompson if (output_fields) *output_fields = op->output_fields; 86143bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 86243bbe138SJeremy L Thompson } 86343bbe138SJeremy L Thompson 86443bbe138SJeremy L Thompson /** 86528567f8fSJeremy L Thompson @brief Get the name of a CeedOperatorField 86628567f8fSJeremy L Thompson 86728567f8fSJeremy L Thompson @param op_field CeedOperatorField 86828567f8fSJeremy L Thompson @param[out] field_name Variable to store the field name 86928567f8fSJeremy L Thompson 87028567f8fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 87128567f8fSJeremy L Thompson 872e9b533fbSJeremy L Thompson @ref Advanced 87328567f8fSJeremy L Thompson **/ 87428567f8fSJeremy L Thompson int CeedOperatorFieldGetName(CeedOperatorField op_field, char **field_name) { 87528567f8fSJeremy L Thompson *field_name = (char *)op_field->field_name; 87628567f8fSJeremy L Thompson return CEED_ERROR_SUCCESS; 87728567f8fSJeremy L Thompson } 87828567f8fSJeremy L Thompson 87928567f8fSJeremy L Thompson /** 88043bbe138SJeremy L Thompson @brief Get the CeedElemRestriction of a CeedOperatorField 88143bbe138SJeremy L Thompson 88243bbe138SJeremy L Thompson @param op_field CeedOperatorField 88343bbe138SJeremy L Thompson @param[out] rstr Variable to store CeedElemRestriction 88443bbe138SJeremy L Thompson 88543bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 88643bbe138SJeremy L Thompson 887e9b533fbSJeremy L Thompson @ref Advanced 88843bbe138SJeremy L Thompson **/ 88943bbe138SJeremy L Thompson int CeedOperatorFieldGetElemRestriction(CeedOperatorField op_field, 89043bbe138SJeremy L Thompson CeedElemRestriction *rstr) { 89143bbe138SJeremy L Thompson *rstr = op_field->elem_restr; 89243bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 89343bbe138SJeremy L Thompson } 89443bbe138SJeremy L Thompson 89543bbe138SJeremy L Thompson /** 89643bbe138SJeremy L Thompson @brief Get the CeedBasis of a CeedOperatorField 89743bbe138SJeremy L Thompson 89843bbe138SJeremy L Thompson @param op_field CeedOperatorField 89943bbe138SJeremy L Thompson @param[out] basis Variable to store CeedBasis 90043bbe138SJeremy L Thompson 90143bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 90243bbe138SJeremy L Thompson 903e9b533fbSJeremy L Thompson @ref Advanced 90443bbe138SJeremy L Thompson **/ 90543bbe138SJeremy L Thompson int CeedOperatorFieldGetBasis(CeedOperatorField op_field, CeedBasis *basis) { 90643bbe138SJeremy L Thompson *basis = op_field->basis; 90743bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 90843bbe138SJeremy L Thompson } 90943bbe138SJeremy L Thompson 91043bbe138SJeremy L Thompson /** 91143bbe138SJeremy L Thompson @brief Get the CeedVector of a CeedOperatorField 91243bbe138SJeremy L Thompson 91343bbe138SJeremy L Thompson @param op_field CeedOperatorField 91443bbe138SJeremy L Thompson @param[out] vec Variable to store CeedVector 91543bbe138SJeremy L Thompson 91643bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 91743bbe138SJeremy L Thompson 918e9b533fbSJeremy L Thompson @ref Advanced 91943bbe138SJeremy L Thompson **/ 92043bbe138SJeremy L Thompson int CeedOperatorFieldGetVector(CeedOperatorField op_field, CeedVector *vec) { 92143bbe138SJeremy L Thompson *vec = op_field->vec; 92243bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 92343bbe138SJeremy L Thompson } 92443bbe138SJeremy L Thompson 92543bbe138SJeremy L Thompson /** 92652d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 927288c0443SJeremy L Thompson 928d1d35e2fSjeremylt @param[out] composite_op Composite CeedOperator 929d1d35e2fSjeremylt @param sub_op Sub-operator CeedOperator 93052d6035fSJeremy L Thompson 93152d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 93252d6035fSJeremy L Thompson 9337a982d89SJeremy L. Thompson @ref User 93452d6035fSJeremy L Thompson */ 935d1d35e2fSjeremylt int CeedCompositeOperatorAddSub(CeedOperator composite_op, 936d1d35e2fSjeremylt CeedOperator sub_op) { 93734359f16Sjeremylt int ierr; 93834359f16Sjeremylt 939f04ea552SJeremy L Thompson if (!composite_op->is_composite) 940c042f62fSJeremy L Thompson // LCOV_EXCL_START 941d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_MINOR, 942e2f04181SAndrew T. Barker "CeedOperator is not a composite operator"); 943c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 94452d6035fSJeremy L Thompson 945d1d35e2fSjeremylt if (composite_op->num_suboperators == CEED_COMPOSITE_MAX) 946c042f62fSJeremy L Thompson // LCOV_EXCL_START 947d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_UNSUPPORTED, 9482b104005SJeremy L Thompson "Cannot add additional sub-operators"); 949c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 950f04ea552SJeremy L Thompson if (composite_op->is_immutable) 951f04ea552SJeremy L Thompson // LCOV_EXCL_START 952f04ea552SJeremy L Thompson return CeedError(composite_op->ceed, CEED_ERROR_MAJOR, 953f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 954f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 95552d6035fSJeremy L Thompson 9562b104005SJeremy L Thompson { 9572b104005SJeremy L Thompson CeedSize input_size, output_size; 9582b104005SJeremy L Thompson ierr = CeedOperatorGetActiveVectorLengths(sub_op, &input_size, &output_size); 9592b104005SJeremy L Thompson CeedChk(ierr); 9602b104005SJeremy L Thompson if (composite_op->input_size == -1) composite_op->input_size = input_size; 9612b104005SJeremy L Thompson if (composite_op->output_size == -1) composite_op->output_size = output_size; 9622b104005SJeremy L Thompson // Note, a size of -1 means no active vector restriction set, so no incompatibility 9632b104005SJeremy L Thompson if ((input_size != -1 && input_size != composite_op->input_size) || 9642b104005SJeremy L Thompson (output_size != -1 && output_size != composite_op->output_size)) 9652b104005SJeremy L Thompson // LCOV_EXCL_START 9662b104005SJeremy L Thompson return CeedError(composite_op->ceed, CEED_ERROR_MAJOR, 9672b104005SJeremy L Thompson "Sub-operators must have compatible dimensions; " 9682b104005SJeremy L Thompson "composite operator of shape (%td, %td) not compatible with " 9692b104005SJeremy L Thompson "sub-operator of shape (%td, %td)", 9702b104005SJeremy L Thompson composite_op->input_size, composite_op->output_size, input_size, output_size); 9712b104005SJeremy L Thompson // LCOV_EXCL_STOP 9722b104005SJeremy L Thompson } 9732b104005SJeremy L Thompson 974d1d35e2fSjeremylt composite_op->sub_operators[composite_op->num_suboperators] = sub_op; 9759560d06aSjeremylt ierr = CeedOperatorReference(sub_op); CeedChk(ierr); 976d1d35e2fSjeremylt composite_op->num_suboperators++; 977e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 97852d6035fSJeremy L Thompson } 97952d6035fSJeremy L Thompson 98052d6035fSJeremy L Thompson /** 9814db537f9SJeremy L Thompson @brief Check if a CeedOperator is ready to be used. 9824db537f9SJeremy L Thompson 9834db537f9SJeremy L Thompson @param[in] op CeedOperator to check 9844db537f9SJeremy L Thompson 9854db537f9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 9864db537f9SJeremy L Thompson 9874db537f9SJeremy L Thompson @ref User 9884db537f9SJeremy L Thompson **/ 9894db537f9SJeremy L Thompson int CeedOperatorCheckReady(CeedOperator op) { 9904db537f9SJeremy L Thompson int ierr; 9914db537f9SJeremy L Thompson Ceed ceed; 9924db537f9SJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 9934db537f9SJeremy L Thompson 9944db537f9SJeremy L Thompson if (op->is_interface_setup) 9954db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 9964db537f9SJeremy L Thompson 9974db537f9SJeremy L Thompson CeedQFunction qf = op->qf; 9984db537f9SJeremy L Thompson if (op->is_composite) { 9994db537f9SJeremy L Thompson if (!op->num_suboperators) 10004db537f9SJeremy L Thompson // LCOV_EXCL_START 10014db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "No sub_operators set"); 10024db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10034db537f9SJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 10044db537f9SJeremy L Thompson ierr = CeedOperatorCheckReady(op->sub_operators[i]); CeedChk(ierr); 10054db537f9SJeremy L Thompson } 10062b104005SJeremy L Thompson // Sub-operators could be modified after adding to composite operator 10072b104005SJeremy L Thompson // Need to verify no lvec incompatibility from any changes 10082b104005SJeremy L Thompson CeedSize input_size, output_size; 10092b104005SJeremy L Thompson ierr = CeedOperatorGetActiveVectorLengths(op, &input_size, &output_size); 10102b104005SJeremy L Thompson CeedChk(ierr); 10114db537f9SJeremy L Thompson } else { 10124db537f9SJeremy L Thompson if (op->num_fields == 0) 10134db537f9SJeremy L Thompson // LCOV_EXCL_START 10144db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "No operator fields set"); 10154db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10164db537f9SJeremy L Thompson if (op->num_fields < qf->num_input_fields + qf->num_output_fields) 10174db537f9SJeremy L Thompson // LCOV_EXCL_START 10184db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "Not all operator fields set"); 10194db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10204db537f9SJeremy L Thompson if (!op->has_restriction) 10214db537f9SJeremy L Thompson // LCOV_EXCL_START 10224db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, 10234db537f9SJeremy L Thompson "At least one restriction required"); 10244db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10254db537f9SJeremy L Thompson if (op->num_qpts == 0) 10264db537f9SJeremy L Thompson // LCOV_EXCL_START 10274db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, 10284db537f9SJeremy L Thompson "At least one non-collocated basis is required " 10294db537f9SJeremy L Thompson "or the number of quadrature points must be set"); 10304db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10314db537f9SJeremy L Thompson } 10324db537f9SJeremy L Thompson 10334db537f9SJeremy L Thompson // Flag as immutable and ready 10344db537f9SJeremy L Thompson op->is_interface_setup = true; 10354db537f9SJeremy L Thompson if (op->qf && op->qf != CEED_QFUNCTION_NONE) 10364db537f9SJeremy L Thompson // LCOV_EXCL_START 10374db537f9SJeremy L Thompson op->qf->is_immutable = true; 10384db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10394db537f9SJeremy L Thompson if (op->dqf && op->dqf != CEED_QFUNCTION_NONE) 10404db537f9SJeremy L Thompson // LCOV_EXCL_START 10414db537f9SJeremy L Thompson op->dqf->is_immutable = true; 10424db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10434db537f9SJeremy L Thompson if (op->dqfT && op->dqfT != CEED_QFUNCTION_NONE) 10444db537f9SJeremy L Thompson // LCOV_EXCL_START 10454db537f9SJeremy L Thompson op->dqfT->is_immutable = true; 10464db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10474db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 10484db537f9SJeremy L Thompson } 10494db537f9SJeremy L Thompson 10504db537f9SJeremy L Thompson /** 1051c9366a6bSJeremy L Thompson @brief Get vector lengths for the active input and/or output vectors of a CeedOperator. 1052c9366a6bSJeremy L Thompson Note: Lengths of -1 indicate that the CeedOperator does not have an 1053c9366a6bSJeremy L Thompson active input and/or output. 1054c9366a6bSJeremy L Thompson 1055c9366a6bSJeremy L Thompson @param[in] op CeedOperator 1056c9366a6bSJeremy L Thompson @param[out] input_size Variable to store active input vector length, or NULL 1057c9366a6bSJeremy L Thompson @param[out] output_size Variable to store active output vector length, or NULL 1058c9366a6bSJeremy L Thompson 1059c9366a6bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1060c9366a6bSJeremy L Thompson 1061c9366a6bSJeremy L Thompson @ref User 1062c9366a6bSJeremy L Thompson **/ 1063c9366a6bSJeremy L Thompson int CeedOperatorGetActiveVectorLengths(CeedOperator op, CeedSize *input_size, 1064c9366a6bSJeremy L Thompson CeedSize *output_size) { 1065c9366a6bSJeremy L Thompson int ierr; 1066c9366a6bSJeremy L Thompson bool is_composite; 1067c9366a6bSJeremy L Thompson 10682b104005SJeremy L Thompson if (input_size) *input_size = op->input_size; 10692b104005SJeremy L Thompson if (output_size) *output_size = op->output_size; 1070c9366a6bSJeremy L Thompson 1071c9366a6bSJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 10722b104005SJeremy L Thompson if (is_composite && (op->input_size == -1 || op->output_size == -1)) { 1073c9366a6bSJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 1074c9366a6bSJeremy L Thompson CeedSize sub_input_size, sub_output_size; 1075c9366a6bSJeremy L Thompson ierr = CeedOperatorGetActiveVectorLengths(op->sub_operators[i], 10762b104005SJeremy L Thompson &sub_input_size, &sub_output_size); CeedChk(ierr); 10772b104005SJeremy L Thompson if (op->input_size == -1) op->input_size = sub_input_size; 10782b104005SJeremy L Thompson if (op->output_size == -1) op->output_size = sub_output_size; 10792b104005SJeremy L Thompson // Note, a size of -1 means no active vector restriction set, so no incompatibility 10802b104005SJeremy L Thompson if ((sub_input_size != -1 && sub_input_size != op->input_size) || 10812b104005SJeremy L Thompson (sub_output_size != -1 && sub_output_size != op->output_size)) 10822b104005SJeremy L Thompson // LCOV_EXCL_START 10832b104005SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 10842b104005SJeremy L Thompson "Sub-operators must have compatible dimensions; " 10852b104005SJeremy L Thompson "composite operator of shape (%td, %td) not compatible with " 10862b104005SJeremy L Thompson "sub-operator of shape (%td, %td)", 10872b104005SJeremy L Thompson op->input_size, op->output_size, input_size, output_size); 10882b104005SJeremy L Thompson // LCOV_EXCL_STOP 1089c9366a6bSJeremy L Thompson } 1090c9366a6bSJeremy L Thompson } 1091c9366a6bSJeremy L Thompson 1092c9366a6bSJeremy L Thompson return CEED_ERROR_SUCCESS; 1093c9366a6bSJeremy L Thompson } 1094c9366a6bSJeremy L Thompson 1095c9366a6bSJeremy L Thompson /** 1096beecbf24SJeremy L Thompson @brief Set reuse of CeedQFunction data in CeedOperatorLinearAssemble* functions. 1097beecbf24SJeremy L Thompson When `reuse_assembly_data = false` (default), the CeedQFunction associated 1098beecbf24SJeremy L Thompson with this CeedOperator is re-assembled every time a `CeedOperatorLinearAssemble*` 1099beecbf24SJeremy L Thompson function is called. 1100beecbf24SJeremy L Thompson When `reuse_assembly_data = true`, the CeedQFunction associated with 1101beecbf24SJeremy L Thompson this CeedOperator is reused between calls to 1102beecbf24SJeremy L Thompson `CeedOperatorSetQFunctionAssemblyDataUpdated`. 11038b919e6bSJeremy L Thompson 1104beecbf24SJeremy L Thompson @param[in] op CeedOperator 1105beecbf24SJeremy L Thompson @param[in] reuse_assembly_data Boolean flag setting assembly data reuse 11068b919e6bSJeremy L Thompson 11078b919e6bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 11088b919e6bSJeremy L Thompson 11098b919e6bSJeremy L Thompson @ref Advanced 11108b919e6bSJeremy L Thompson **/ 1111beecbf24SJeremy L Thompson int CeedOperatorSetQFunctionAssemblyReuse(CeedOperator op, 1112beecbf24SJeremy L Thompson bool reuse_assembly_data) { 11138b919e6bSJeremy L Thompson int ierr; 11148b919e6bSJeremy L Thompson bool is_composite; 11158b919e6bSJeremy L Thompson 11168b919e6bSJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 11178b919e6bSJeremy L Thompson if (is_composite) { 11188b919e6bSJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 1119beecbf24SJeremy L Thompson ierr = CeedOperatorSetQFunctionAssemblyReuse(op->sub_operators[i], 1120beecbf24SJeremy L Thompson reuse_assembly_data); CeedChk(ierr); 11218b919e6bSJeremy L Thompson } 11228b919e6bSJeremy L Thompson } else { 1123beecbf24SJeremy L Thompson ierr = CeedQFunctionAssemblyDataSetReuse(op->qf_assembled, reuse_assembly_data); 1124beecbf24SJeremy L Thompson CeedChk(ierr); 1125beecbf24SJeremy L Thompson } 1126beecbf24SJeremy L Thompson 1127beecbf24SJeremy L Thompson return CEED_ERROR_SUCCESS; 1128beecbf24SJeremy L Thompson } 1129beecbf24SJeremy L Thompson 1130beecbf24SJeremy L Thompson /** 1131beecbf24SJeremy L Thompson @brief Mark CeedQFunction data as updated and the CeedQFunction as requiring re-assembly. 1132beecbf24SJeremy L Thompson 1133beecbf24SJeremy L Thompson @param[in] op CeedOperator 11346e15d496SJeremy L Thompson @param[in] needs_data_update Boolean flag setting assembly data reuse 1135beecbf24SJeremy L Thompson 1136beecbf24SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1137beecbf24SJeremy L Thompson 1138beecbf24SJeremy L Thompson @ref Advanced 1139beecbf24SJeremy L Thompson **/ 1140beecbf24SJeremy L Thompson int CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(CeedOperator op, 1141beecbf24SJeremy L Thompson bool needs_data_update) { 1142beecbf24SJeremy L Thompson int ierr; 1143beecbf24SJeremy L Thompson bool is_composite; 1144beecbf24SJeremy L Thompson 1145beecbf24SJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 1146beecbf24SJeremy L Thompson if (is_composite) { 1147beecbf24SJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 1148beecbf24SJeremy L Thompson ierr = CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(op->sub_operators[i], 1149beecbf24SJeremy L Thompson needs_data_update); CeedChk(ierr); 1150beecbf24SJeremy L Thompson } 1151beecbf24SJeremy L Thompson } else { 1152beecbf24SJeremy L Thompson ierr = CeedQFunctionAssemblyDataSetUpdateNeeded(op->qf_assembled, 1153beecbf24SJeremy L Thompson needs_data_update); 11548b919e6bSJeremy L Thompson CeedChk(ierr); 11558b919e6bSJeremy L Thompson } 11568b919e6bSJeremy L Thompson 11578b919e6bSJeremy L Thompson return CEED_ERROR_SUCCESS; 11588b919e6bSJeremy L Thompson } 11598b919e6bSJeremy L Thompson 11608b919e6bSJeremy L Thompson /** 1161cd4dfc48Sjeremylt @brief Set the number of quadrature points associated with a CeedOperator. 1162cd4dfc48Sjeremylt This should be used when creating a CeedOperator where every 1163cd4dfc48Sjeremylt field has a collocated basis. This function cannot be used for 1164cd4dfc48Sjeremylt composite CeedOperators. 1165cd4dfc48Sjeremylt 1166cd4dfc48Sjeremylt @param op CeedOperator 1167cd4dfc48Sjeremylt @param num_qpts Number of quadrature points to set 1168cd4dfc48Sjeremylt 1169cd4dfc48Sjeremylt @return An error code: 0 - success, otherwise - failure 1170cd4dfc48Sjeremylt 1171e9b533fbSJeremy L Thompson @ref Advanced 1172cd4dfc48Sjeremylt **/ 1173cd4dfc48Sjeremylt int CeedOperatorSetNumQuadraturePoints(CeedOperator op, CeedInt num_qpts) { 1174f04ea552SJeremy L Thompson if (op->is_composite) 1175cd4dfc48Sjeremylt // LCOV_EXCL_START 1176cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 1177cd4dfc48Sjeremylt "Not defined for composite operator"); 1178cd4dfc48Sjeremylt // LCOV_EXCL_STOP 1179cd4dfc48Sjeremylt if (op->num_qpts) 1180cd4dfc48Sjeremylt // LCOV_EXCL_START 1181cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 1182cd4dfc48Sjeremylt "Number of quadrature points already defined"); 1183cd4dfc48Sjeremylt // LCOV_EXCL_STOP 1184f04ea552SJeremy L Thompson if (op->is_immutable) 1185f04ea552SJeremy L Thompson // LCOV_EXCL_START 1186f04ea552SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 1187f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 1188f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 1189cd4dfc48Sjeremylt 1190cd4dfc48Sjeremylt op->num_qpts = num_qpts; 1191cd4dfc48Sjeremylt return CEED_ERROR_SUCCESS; 1192cd4dfc48Sjeremylt } 1193cd4dfc48Sjeremylt 1194cd4dfc48Sjeremylt /** 1195ea6b5821SJeremy L Thompson @brief Set name of CeedOperator for CeedOperatorView output 1196ea6b5821SJeremy L Thompson 1197ea6b5821SJeremy L Thompson @param op CeedOperator 1198ea6b5821SJeremy L Thompson @param name Name to set, or NULL to remove previously set name 1199ea6b5821SJeremy L Thompson 1200ea6b5821SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1201ea6b5821SJeremy L Thompson 1202ea6b5821SJeremy L Thompson @ref User 1203ea6b5821SJeremy L Thompson **/ 1204ea6b5821SJeremy L Thompson int CeedOperatorSetName(CeedOperator op, const char *name) { 1205ea6b5821SJeremy L Thompson int ierr; 1206ea6b5821SJeremy L Thompson char *name_copy; 1207ea6b5821SJeremy L Thompson size_t name_len = name ? strlen(name) : 0; 1208ea6b5821SJeremy L Thompson 1209ea6b5821SJeremy L Thompson ierr = CeedFree(&op->name); CeedChk(ierr); 1210ea6b5821SJeremy L Thompson if (name_len > 0) { 1211ea6b5821SJeremy L Thompson ierr = CeedCalloc(name_len + 1, &name_copy); CeedChk(ierr); 1212ea6b5821SJeremy L Thompson memcpy(name_copy, name, name_len); 1213ea6b5821SJeremy L Thompson op->name = name_copy; 1214ea6b5821SJeremy L Thompson } 1215ea6b5821SJeremy L Thompson 1216ea6b5821SJeremy L Thompson return CEED_ERROR_SUCCESS; 1217ea6b5821SJeremy L Thompson } 1218ea6b5821SJeremy L Thompson 1219ea6b5821SJeremy L Thompson /** 12207a982d89SJeremy L. Thompson @brief View a CeedOperator 12217a982d89SJeremy L. Thompson 12227a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 12237a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 12247a982d89SJeremy L. Thompson 12257a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 12267a982d89SJeremy L. Thompson 12277a982d89SJeremy L. Thompson @ref User 12287a982d89SJeremy L. Thompson **/ 12297a982d89SJeremy L. Thompson int CeedOperatorView(CeedOperator op, FILE *stream) { 12307a982d89SJeremy L. Thompson int ierr; 1231ea6b5821SJeremy L Thompson bool has_name = op->name; 12327a982d89SJeremy L. Thompson 1233f04ea552SJeremy L Thompson if (op->is_composite) { 1234ea6b5821SJeremy L Thompson fprintf(stream, "Composite CeedOperator%s%s\n", 1235ea6b5821SJeremy L Thompson has_name ? " - " : "", has_name ? op->name : ""); 12367a982d89SJeremy L. Thompson 1237d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 1238ea6b5821SJeremy L Thompson has_name = op->sub_operators[i]->name; 1239990fdeb6SJeremy L Thompson fprintf(stream, " SubOperator %" CeedInt_FMT "%s%s:\n", i, 1240ea6b5821SJeremy L Thompson has_name ? " - " : "", 1241ea6b5821SJeremy L Thompson has_name ? op->sub_operators[i]->name : ""); 1242d1d35e2fSjeremylt ierr = CeedOperatorSingleView(op->sub_operators[i], 1, stream); 12437a982d89SJeremy L. Thompson CeedChk(ierr); 12447a982d89SJeremy L. Thompson } 12457a982d89SJeremy L. Thompson } else { 1246ea6b5821SJeremy L Thompson fprintf(stream, "CeedOperator%s%s\n", 1247ea6b5821SJeremy L Thompson has_name ? " - " : "", has_name ? op->name : ""); 12487a982d89SJeremy L. Thompson ierr = CeedOperatorSingleView(op, 0, stream); CeedChk(ierr); 12497a982d89SJeremy L. Thompson } 1250e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 12517a982d89SJeremy L. Thompson } 12523bd813ffSjeremylt 12533bd813ffSjeremylt /** 1254b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedOperator 1255b7c9bbdaSJeremy L Thompson 1256b7c9bbdaSJeremy L Thompson @param op CeedOperator 1257b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 1258b7c9bbdaSJeremy L Thompson 1259b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1260b7c9bbdaSJeremy L Thompson 1261b7c9bbdaSJeremy L Thompson @ref Advanced 1262b7c9bbdaSJeremy L Thompson **/ 1263b7c9bbdaSJeremy L Thompson int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 1264b7c9bbdaSJeremy L Thompson *ceed = op->ceed; 1265b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1266b7c9bbdaSJeremy L Thompson } 1267b7c9bbdaSJeremy L Thompson 1268b7c9bbdaSJeremy L Thompson /** 1269b7c9bbdaSJeremy L Thompson @brief Get the number of elements associated with a CeedOperator 1270b7c9bbdaSJeremy L Thompson 1271b7c9bbdaSJeremy L Thompson @param op CeedOperator 1272b7c9bbdaSJeremy L Thompson @param[out] num_elem Variable to store number of elements 1273b7c9bbdaSJeremy L Thompson 1274b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1275b7c9bbdaSJeremy L Thompson 1276b7c9bbdaSJeremy L Thompson @ref Advanced 1277b7c9bbdaSJeremy L Thompson **/ 1278b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumElements(CeedOperator op, CeedInt *num_elem) { 1279b7c9bbdaSJeremy L Thompson if (op->is_composite) 1280b7c9bbdaSJeremy L Thompson // LCOV_EXCL_START 1281b7c9bbdaSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 1282b7c9bbdaSJeremy L Thompson "Not defined for composite operator"); 1283b7c9bbdaSJeremy L Thompson // LCOV_EXCL_STOP 1284b7c9bbdaSJeremy L Thompson 1285b7c9bbdaSJeremy L Thompson *num_elem = op->num_elem; 1286b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1287b7c9bbdaSJeremy L Thompson } 1288b7c9bbdaSJeremy L Thompson 1289b7c9bbdaSJeremy L Thompson /** 1290b7c9bbdaSJeremy L Thompson @brief Get the number of quadrature points associated with a CeedOperator 1291b7c9bbdaSJeremy L Thompson 1292b7c9bbdaSJeremy L Thompson @param op CeedOperator 1293b7c9bbdaSJeremy L Thompson @param[out] num_qpts Variable to store vector number of quadrature points 1294b7c9bbdaSJeremy L Thompson 1295b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1296b7c9bbdaSJeremy L Thompson 1297b7c9bbdaSJeremy L Thompson @ref Advanced 1298b7c9bbdaSJeremy L Thompson **/ 1299b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *num_qpts) { 1300b7c9bbdaSJeremy L Thompson if (op->is_composite) 1301b7c9bbdaSJeremy L Thompson // LCOV_EXCL_START 1302b7c9bbdaSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 1303b7c9bbdaSJeremy L Thompson "Not defined for composite operator"); 1304b7c9bbdaSJeremy L Thompson // LCOV_EXCL_STOP 1305b7c9bbdaSJeremy L Thompson 1306b7c9bbdaSJeremy L Thompson *num_qpts = op->num_qpts; 1307b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1308b7c9bbdaSJeremy L Thompson } 1309b7c9bbdaSJeremy L Thompson 1310b7c9bbdaSJeremy L Thompson /** 13116e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedOperator on the active vector 13126e15d496SJeremy L Thompson 13136e15d496SJeremy L Thompson @param op Operator to estimate FLOPs for 13146e15d496SJeremy L Thompson @param flops Address of variable to hold FLOPs estimate 13156e15d496SJeremy L Thompson 13166e15d496SJeremy L Thompson @ref Backend 13176e15d496SJeremy L Thompson **/ 13189d36ca50SJeremy L Thompson int CeedOperatorGetFlopsEstimate(CeedOperator op, CeedSize *flops) { 13196e15d496SJeremy L Thompson int ierr; 13206e15d496SJeremy L Thompson bool is_composite; 13216e15d496SJeremy L Thompson ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 13226e15d496SJeremy L Thompson 13236e15d496SJeremy L Thompson *flops = 0; 13246e15d496SJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 13256e15d496SJeremy L Thompson if (is_composite) { 13266e15d496SJeremy L Thompson CeedInt num_suboperators; 13276e15d496SJeremy L Thompson ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 13286e15d496SJeremy L Thompson CeedOperator *sub_operators; 13296e15d496SJeremy L Thompson ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 13306e15d496SJeremy L Thompson 13316e15d496SJeremy L Thompson // FLOPs for each suboperator 13326e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 13339d36ca50SJeremy L Thompson CeedSize suboperator_flops; 13346e15d496SJeremy L Thompson ierr = CeedOperatorGetFlopsEstimate(sub_operators[i], &suboperator_flops); 13356e15d496SJeremy L Thompson CeedChk(ierr); 13366e15d496SJeremy L Thompson *flops += suboperator_flops; 13376e15d496SJeremy L Thompson } 13386e15d496SJeremy L Thompson } else { 13396e15d496SJeremy L Thompson CeedInt num_input_fields, num_output_fields; 13406e15d496SJeremy L Thompson CeedOperatorField *input_fields, *output_fields; 13416e15d496SJeremy L Thompson 13426e15d496SJeremy L Thompson ierr = CeedOperatorGetFields(op, &num_input_fields, &input_fields, 13436e15d496SJeremy L Thompson &num_output_fields, &output_fields); CeedChk(ierr); 13446e15d496SJeremy L Thompson 13456e15d496SJeremy L Thompson CeedInt num_elem = 0; 13466e15d496SJeremy L Thompson ierr = CeedOperatorGetNumElements(op, &num_elem); CeedChk(ierr); 13476e15d496SJeremy L Thompson // Input FLOPs 13486e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 13496e15d496SJeremy L Thompson if (input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 13509d36ca50SJeremy L Thompson CeedSize restr_flops, basis_flops; 13516e15d496SJeremy L Thompson 13526e15d496SJeremy L Thompson ierr = CeedElemRestrictionGetFlopsEstimate(input_fields[i]->elem_restr, 13536e15d496SJeremy L Thompson CEED_NOTRANSPOSE, &restr_flops); CeedChk(ierr); 13546e15d496SJeremy L Thompson *flops += restr_flops; 13556e15d496SJeremy L Thompson ierr = CeedBasisGetFlopsEstimate(input_fields[i]->basis, CEED_NOTRANSPOSE, 13566e15d496SJeremy L Thompson op->qf->input_fields[i]->eval_mode, &basis_flops); CeedChk(ierr); 13576e15d496SJeremy L Thompson *flops += basis_flops * num_elem; 13586e15d496SJeremy L Thompson } 13596e15d496SJeremy L Thompson } 13606e15d496SJeremy L Thompson // QF FLOPs 13619d36ca50SJeremy L Thompson CeedInt num_qpts; 13629d36ca50SJeremy L Thompson CeedSize qf_flops; 13636e15d496SJeremy L Thompson ierr = CeedOperatorGetNumQuadraturePoints(op, &num_qpts); CeedChk(ierr); 13646e15d496SJeremy L Thompson ierr = CeedQFunctionGetFlopsEstimate(op->qf, &qf_flops); CeedChk(ierr); 13656e15d496SJeremy L Thompson *flops += num_elem * num_qpts * qf_flops; 13666e15d496SJeremy L Thompson // Output FLOPs 13676e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 13686e15d496SJeremy L Thompson if (output_fields[i]->vec == CEED_VECTOR_ACTIVE) { 13699d36ca50SJeremy L Thompson CeedSize restr_flops, basis_flops; 13706e15d496SJeremy L Thompson 13716e15d496SJeremy L Thompson ierr = CeedElemRestrictionGetFlopsEstimate(output_fields[i]->elem_restr, 13726e15d496SJeremy L Thompson CEED_TRANSPOSE, &restr_flops); CeedChk(ierr); 13736e15d496SJeremy L Thompson *flops += restr_flops; 13746e15d496SJeremy L Thompson ierr = CeedBasisGetFlopsEstimate(output_fields[i]->basis, CEED_TRANSPOSE, 13756e15d496SJeremy L Thompson op->qf->output_fields[i]->eval_mode, &basis_flops); CeedChk(ierr); 13766e15d496SJeremy L Thompson *flops += basis_flops * num_elem; 13776e15d496SJeremy L Thompson } 13786e15d496SJeremy L Thompson } 13796e15d496SJeremy L Thompson } 13806e15d496SJeremy L Thompson 13816e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 13826e15d496SJeremy L Thompson } 13836e15d496SJeremy L Thompson 13846e15d496SJeremy L Thompson /** 13853668ca4bSJeremy L Thompson @brief Get label for a registered QFunctionContext field, or `NULL` if no 13863668ca4bSJeremy L Thompson field has been registered with this `field_name`. 13873668ca4bSJeremy L Thompson 13883668ca4bSJeremy L Thompson @param[in] op CeedOperator 13893668ca4bSJeremy L Thompson @param[in] field_name Name of field to retrieve label 13903668ca4bSJeremy L Thompson @param[out] field_label Variable to field label 13913668ca4bSJeremy L Thompson 13923668ca4bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 13933668ca4bSJeremy L Thompson 13943668ca4bSJeremy L Thompson @ref User 13953668ca4bSJeremy L Thompson **/ 13963668ca4bSJeremy L Thompson int CeedOperatorContextGetFieldLabel(CeedOperator op, 13973668ca4bSJeremy L Thompson const char *field_name, 13983668ca4bSJeremy L Thompson CeedContextFieldLabel *field_label) { 13993668ca4bSJeremy L Thompson int ierr; 14003668ca4bSJeremy L Thompson 14013668ca4bSJeremy L Thompson bool is_composite; 14023668ca4bSJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 14033668ca4bSJeremy L Thompson if (is_composite) { 14043668ca4bSJeremy L Thompson // Check if composite label already created 14053668ca4bSJeremy L Thompson for (CeedInt i=0; i<op->num_context_labels; i++) { 14063668ca4bSJeremy L Thompson if (!strcmp(op->context_labels[i]->name, field_name)) { 14073668ca4bSJeremy L Thompson *field_label = op->context_labels[i]; 14083668ca4bSJeremy L Thompson return CEED_ERROR_SUCCESS; 14093668ca4bSJeremy L Thompson } 14103668ca4bSJeremy L Thompson } 14113668ca4bSJeremy L Thompson 14123668ca4bSJeremy L Thompson // Create composite label if needed 14133668ca4bSJeremy L Thompson CeedInt num_sub; 14143668ca4bSJeremy L Thompson CeedOperator *sub_operators; 14153668ca4bSJeremy L Thompson CeedContextFieldLabel new_field_label; 14163668ca4bSJeremy L Thompson 14173668ca4bSJeremy L Thompson ierr = CeedCalloc(1, &new_field_label); CeedChk(ierr); 14183668ca4bSJeremy L Thompson ierr = CeedOperatorGetNumSub(op, &num_sub); CeedChk(ierr); 14193668ca4bSJeremy L Thompson ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 14203668ca4bSJeremy L Thompson ierr = CeedCalloc(num_sub, &new_field_label->sub_labels); CeedChk(ierr); 14213668ca4bSJeremy L Thompson new_field_label->num_sub_labels = num_sub; 14223668ca4bSJeremy L Thompson 14233668ca4bSJeremy L Thompson bool label_found = false; 14243668ca4bSJeremy L Thompson for (CeedInt i=0; i<num_sub; i++) { 14253668ca4bSJeremy L Thompson if (sub_operators[i]->qf->ctx) { 14263668ca4bSJeremy L Thompson CeedContextFieldLabel new_field_label_i; 14273668ca4bSJeremy L Thompson ierr = CeedQFunctionContextGetFieldLabel(sub_operators[i]->qf->ctx, field_name, 14283668ca4bSJeremy L Thompson &new_field_label_i); CeedChk(ierr); 14293668ca4bSJeremy L Thompson if (new_field_label_i) { 14303668ca4bSJeremy L Thompson label_found = true; 14313668ca4bSJeremy L Thompson new_field_label->sub_labels[i] = new_field_label_i; 14323668ca4bSJeremy L Thompson new_field_label->name = new_field_label_i->name; 14333668ca4bSJeremy L Thompson new_field_label->description = new_field_label_i->description; 14347bfe0f0eSJeremy L Thompson if (new_field_label->type && 14357bfe0f0eSJeremy L Thompson new_field_label->type != new_field_label_i->type) { 14367bfe0f0eSJeremy L Thompson // LCOV_EXCL_START 14377bfe0f0eSJeremy L Thompson ierr = CeedFree(&new_field_label); CeedChk(ierr); 14387bfe0f0eSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 14397bfe0f0eSJeremy L Thompson "Incompatible field types on sub-operator contexts. " 14407bfe0f0eSJeremy L Thompson "%s != %s", 14417bfe0f0eSJeremy L Thompson CeedContextFieldTypes[new_field_label->type], 14427bfe0f0eSJeremy L Thompson CeedContextFieldTypes[new_field_label_i->type]); 14437bfe0f0eSJeremy L Thompson // LCOV_EXCL_STOP 14447bfe0f0eSJeremy L Thompson } else { 14457bfe0f0eSJeremy L Thompson new_field_label->type = new_field_label_i->type; 14467bfe0f0eSJeremy L Thompson } 14477bfe0f0eSJeremy L Thompson if (new_field_label->num_values != 0 && 14487bfe0f0eSJeremy L Thompson new_field_label->num_values != new_field_label_i->num_values) { 14497bfe0f0eSJeremy L Thompson // LCOV_EXCL_START 14507bfe0f0eSJeremy L Thompson ierr = CeedFree(&new_field_label); CeedChk(ierr); 14517bfe0f0eSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 14527bfe0f0eSJeremy L Thompson "Incompatible field number of values on sub-operator" 14537bfe0f0eSJeremy L Thompson " contexts. %ld != %ld", 14547bfe0f0eSJeremy L Thompson new_field_label->num_values, new_field_label_i->num_values); 14557bfe0f0eSJeremy L Thompson // LCOV_EXCL_STOP 14567bfe0f0eSJeremy L Thompson } else { 14577bfe0f0eSJeremy L Thompson new_field_label->num_values = new_field_label_i->num_values; 14587bfe0f0eSJeremy L Thompson } 14593668ca4bSJeremy L Thompson } 14603668ca4bSJeremy L Thompson } 14613668ca4bSJeremy L Thompson } 14623668ca4bSJeremy L Thompson if (!label_found) { 14633668ca4bSJeremy L Thompson // LCOV_EXCL_START 1464a48e5f43SJeremy L Thompson ierr = CeedFree(&new_field_label->sub_labels); CeedChk(ierr); 14653668ca4bSJeremy L Thompson ierr = CeedFree(&new_field_label); CeedChk(ierr); 14663668ca4bSJeremy L Thompson *field_label = NULL; 14673668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 14683668ca4bSJeremy L Thompson } else { 14693668ca4bSJeremy L Thompson // Move new composite label to operator 14703668ca4bSJeremy L Thompson if (op->num_context_labels == 0) { 14713668ca4bSJeremy L Thompson ierr = CeedCalloc(1, &op->context_labels); CeedChk(ierr); 14723668ca4bSJeremy L Thompson op->max_context_labels = 1; 14733668ca4bSJeremy L Thompson } else if (op->num_context_labels == op->max_context_labels) { 14743668ca4bSJeremy L Thompson ierr = CeedRealloc(2*op->num_context_labels, &op->context_labels); 14753668ca4bSJeremy L Thompson CeedChk(ierr); 14763668ca4bSJeremy L Thompson op->max_context_labels *= 2; 14773668ca4bSJeremy L Thompson } 14783668ca4bSJeremy L Thompson op->context_labels[op->num_context_labels] = new_field_label; 14793668ca4bSJeremy L Thompson *field_label = new_field_label; 14803668ca4bSJeremy L Thompson op->num_context_labels++; 14813668ca4bSJeremy L Thompson } 14823668ca4bSJeremy L Thompson 14833668ca4bSJeremy L Thompson return CEED_ERROR_SUCCESS; 14843668ca4bSJeremy L Thompson } else { 14853668ca4bSJeremy L Thompson return CeedQFunctionContextGetFieldLabel(op->qf->ctx, field_name, field_label); 14863668ca4bSJeremy L Thompson } 14873668ca4bSJeremy L Thompson } 14883668ca4bSJeremy L Thompson 14893668ca4bSJeremy L Thompson /** 1490d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field holding a double precision value. 1491d8dd9a91SJeremy L Thompson For composite operators, the value is set in all 1492d8dd9a91SJeremy L Thompson sub-operator QFunctionContexts that have a matching `field_name`. 1493d8dd9a91SJeremy L Thompson 1494d8dd9a91SJeremy L Thompson @param op CeedOperator 14953668ca4bSJeremy L Thompson @param field_label Label of field to register 14967bfe0f0eSJeremy L Thompson @param values Values to set 1497d8dd9a91SJeremy L Thompson 1498d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1499d8dd9a91SJeremy L Thompson 1500d8dd9a91SJeremy L Thompson @ref User 1501d8dd9a91SJeremy L Thompson **/ 15023668ca4bSJeremy L Thompson int CeedOperatorContextSetDouble(CeedOperator op, 15033668ca4bSJeremy L Thompson CeedContextFieldLabel field_label, 15047bfe0f0eSJeremy L Thompson double *values) { 15053668ca4bSJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_DOUBLE, 15067bfe0f0eSJeremy L Thompson values); 1507d8dd9a91SJeremy L Thompson } 1508d8dd9a91SJeremy L Thompson 1509d8dd9a91SJeremy L Thompson /** 1510d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field holding an int32 value. 1511d8dd9a91SJeremy L Thompson For composite operators, the value is set in all 1512d8dd9a91SJeremy L Thompson sub-operator QFunctionContexts that have a matching `field_name`. 1513d8dd9a91SJeremy L Thompson 1514d8dd9a91SJeremy L Thompson @param op CeedOperator 15153668ca4bSJeremy L Thompson @param field_label Label of field to set 15167bfe0f0eSJeremy L Thompson @param values Values to set 1517d8dd9a91SJeremy L Thompson 1518d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1519d8dd9a91SJeremy L Thompson 1520d8dd9a91SJeremy L Thompson @ref User 1521d8dd9a91SJeremy L Thompson **/ 15223668ca4bSJeremy L Thompson int CeedOperatorContextSetInt32(CeedOperator op, 15233668ca4bSJeremy L Thompson CeedContextFieldLabel field_label, 15247bfe0f0eSJeremy L Thompson int *values) { 15253668ca4bSJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_INT32, 15267bfe0f0eSJeremy L Thompson values); 1527d8dd9a91SJeremy L Thompson } 1528d8dd9a91SJeremy L Thompson 1529d8dd9a91SJeremy L Thompson /** 15303bd813ffSjeremylt @brief Apply CeedOperator to a vector 1531d7b241e6Sjeremylt 1532d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 1533d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 1534d7b241e6Sjeremylt CeedOperatorSetField(). 1535d7b241e6Sjeremylt 1536f04ea552SJeremy L Thompson Note: Calling this function asserts that setup is complete 1537f04ea552SJeremy L Thompson and sets the CeedOperator as immutable. 1538f04ea552SJeremy L Thompson 1539d7b241e6Sjeremylt @param op CeedOperator to apply 15404cc79fe7SJed Brown @param[in] in CeedVector containing input state or @ref CEED_VECTOR_NONE if 154134138859Sjeremylt there are no active inputs 1542b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 15434cc79fe7SJed Brown distinct from @a in) or @ref CEED_VECTOR_NONE if there are no 154434138859Sjeremylt active outputs 1545d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 15464cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1547b11c1e72Sjeremylt 1548b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1549dfdf5a53Sjeremylt 15507a982d89SJeremy L. Thompson @ref User 1551b11c1e72Sjeremylt **/ 1552692c2638Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, 1553692c2638Sjeremylt CeedRequest *request) { 1554d7b241e6Sjeremylt int ierr; 1555e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1556d7b241e6Sjeremylt 1557d1d35e2fSjeremylt if (op->num_elem) { 1558250756a7Sjeremylt // Standard Operator 1559cae8b89aSjeremylt if (op->Apply) { 1560250756a7Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 1561cae8b89aSjeremylt } else { 1562cae8b89aSjeremylt // Zero all output vectors 1563250756a7Sjeremylt CeedQFunction qf = op->qf; 1564d1d35e2fSjeremylt for (CeedInt i=0; i<qf->num_output_fields; i++) { 1565d1d35e2fSjeremylt CeedVector vec = op->output_fields[i]->vec; 1566cae8b89aSjeremylt if (vec == CEED_VECTOR_ACTIVE) 1567cae8b89aSjeremylt vec = out; 1568cae8b89aSjeremylt if (vec != CEED_VECTOR_NONE) { 1569cae8b89aSjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1570cae8b89aSjeremylt } 1571cae8b89aSjeremylt } 1572250756a7Sjeremylt // Apply 1573250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1574250756a7Sjeremylt } 1575f04ea552SJeremy L Thompson } else if (op->is_composite) { 1576250756a7Sjeremylt // Composite Operator 1577250756a7Sjeremylt if (op->ApplyComposite) { 1578250756a7Sjeremylt ierr = op->ApplyComposite(op, in, out, request); CeedChk(ierr); 1579250756a7Sjeremylt } else { 1580d1d35e2fSjeremylt CeedInt num_suboperators; 1581d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1582d1d35e2fSjeremylt CeedOperator *sub_operators; 1583d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1584250756a7Sjeremylt 1585250756a7Sjeremylt // Zero all output vectors 1586250756a7Sjeremylt if (out != CEED_VECTOR_NONE) { 1587cae8b89aSjeremylt ierr = CeedVectorSetValue(out, 0.0); CeedChk(ierr); 1588cae8b89aSjeremylt } 1589d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1590d1d35e2fSjeremylt for (CeedInt j=0; j<sub_operators[i]->qf->num_output_fields; j++) { 1591d1d35e2fSjeremylt CeedVector vec = sub_operators[i]->output_fields[j]->vec; 1592250756a7Sjeremylt if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) { 1593250756a7Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1594250756a7Sjeremylt } 1595250756a7Sjeremylt } 1596250756a7Sjeremylt } 1597250756a7Sjeremylt // Apply 1598d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 1599d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(op->sub_operators[i], in, out, request); 1600cae8b89aSjeremylt CeedChk(ierr); 1601cae8b89aSjeremylt } 1602cae8b89aSjeremylt } 1603250756a7Sjeremylt } 1604e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1605cae8b89aSjeremylt } 1606cae8b89aSjeremylt 1607cae8b89aSjeremylt /** 1608cae8b89aSjeremylt @brief Apply CeedOperator to a vector and add result to output vector 1609cae8b89aSjeremylt 1610cae8b89aSjeremylt This computes the action of the operator on the specified (active) input, 1611cae8b89aSjeremylt yielding its (active) output. All inputs and outputs must be specified using 1612cae8b89aSjeremylt CeedOperatorSetField(). 1613cae8b89aSjeremylt 1614cae8b89aSjeremylt @param op CeedOperator to apply 1615cae8b89aSjeremylt @param[in] in CeedVector containing input state or NULL if there are no 1616cae8b89aSjeremylt active inputs 1617cae8b89aSjeremylt @param[out] out CeedVector to sum in result of applying operator (must be 1618cae8b89aSjeremylt distinct from @a in) or NULL if there are no active outputs 1619cae8b89aSjeremylt @param request Address of CeedRequest for non-blocking completion, else 16204cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1621cae8b89aSjeremylt 1622cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 1623cae8b89aSjeremylt 16247a982d89SJeremy L. Thompson @ref User 1625cae8b89aSjeremylt **/ 1626cae8b89aSjeremylt int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, 1627cae8b89aSjeremylt CeedRequest *request) { 1628cae8b89aSjeremylt int ierr; 1629e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1630cae8b89aSjeremylt 1631d1d35e2fSjeremylt if (op->num_elem) { 1632250756a7Sjeremylt // Standard Operator 1633250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1634f04ea552SJeremy L Thompson } else if (op->is_composite) { 1635250756a7Sjeremylt // Composite Operator 1636250756a7Sjeremylt if (op->ApplyAddComposite) { 1637250756a7Sjeremylt ierr = op->ApplyAddComposite(op, in, out, request); CeedChk(ierr); 1638cae8b89aSjeremylt } else { 1639d1d35e2fSjeremylt CeedInt num_suboperators; 1640d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1641d1d35e2fSjeremylt CeedOperator *sub_operators; 1642d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1643250756a7Sjeremylt 1644d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1645d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(sub_operators[i], in, out, request); 1646cae8b89aSjeremylt CeedChk(ierr); 16471d7d2407SJeremy L Thompson } 1648250756a7Sjeremylt } 1649250756a7Sjeremylt } 1650e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1651d7b241e6Sjeremylt } 1652d7b241e6Sjeremylt 1653d7b241e6Sjeremylt /** 1654b11c1e72Sjeremylt @brief Destroy a CeedOperator 1655d7b241e6Sjeremylt 1656d7b241e6Sjeremylt @param op CeedOperator to destroy 1657b11c1e72Sjeremylt 1658b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1659dfdf5a53Sjeremylt 16607a982d89SJeremy L. Thompson @ref User 1661b11c1e72Sjeremylt **/ 1662d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 1663d7b241e6Sjeremylt int ierr; 1664d7b241e6Sjeremylt 1665d1d35e2fSjeremylt if (!*op || --(*op)->ref_count > 0) return CEED_ERROR_SUCCESS; 1666d7b241e6Sjeremylt if ((*op)->Destroy) { 1667d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 1668d7b241e6Sjeremylt } 1669fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 1670fe2413ffSjeremylt // Free fields 16713668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_fields; i++) 1672d1d35e2fSjeremylt if ((*op)->input_fields[i]) { 1673d1d35e2fSjeremylt if ((*op)->input_fields[i]->elem_restr != CEED_ELEMRESTRICTION_NONE) { 1674d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->input_fields[i]->elem_restr); 167571352a93Sjeremylt CeedChk(ierr); 167615910d16Sjeremylt } 1677d1d35e2fSjeremylt if ((*op)->input_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1678d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->input_fields[i]->basis); CeedChk(ierr); 167971352a93Sjeremylt } 1680d1d35e2fSjeremylt if ((*op)->input_fields[i]->vec != CEED_VECTOR_ACTIVE && 1681d1d35e2fSjeremylt (*op)->input_fields[i]->vec != CEED_VECTOR_NONE ) { 1682d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->input_fields[i]->vec); CeedChk(ierr); 168371352a93Sjeremylt } 1684d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]->field_name); CeedChk(ierr); 1685d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]); CeedChk(ierr); 1686fe2413ffSjeremylt } 16873668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_fields; i++) 1688d1d35e2fSjeremylt if ((*op)->output_fields[i]) { 1689d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->output_fields[i]->elem_restr); 169071352a93Sjeremylt CeedChk(ierr); 1691d1d35e2fSjeremylt if ((*op)->output_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1692d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->output_fields[i]->basis); CeedChk(ierr); 169371352a93Sjeremylt } 1694d1d35e2fSjeremylt if ((*op)->output_fields[i]->vec != CEED_VECTOR_ACTIVE && 1695d1d35e2fSjeremylt (*op)->output_fields[i]->vec != CEED_VECTOR_NONE ) { 1696d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->output_fields[i]->vec); CeedChk(ierr); 169771352a93Sjeremylt } 1698d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]->field_name); CeedChk(ierr); 1699d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]); CeedChk(ierr); 1700fe2413ffSjeremylt } 1701d1d35e2fSjeremylt // Destroy sub_operators 17023668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_suboperators; i++) 1703d1d35e2fSjeremylt if ((*op)->sub_operators[i]) { 1704d1d35e2fSjeremylt ierr = CeedOperatorDestroy(&(*op)->sub_operators[i]); CeedChk(ierr); 170552d6035fSJeremy L Thompson } 1706d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 1707d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 1708d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 17093668ca4bSJeremy L Thompson // Destroy any composite labels 17103668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_context_labels; i++) { 17113668ca4bSJeremy L Thompson ierr = CeedFree(&(*op)->context_labels[i]->sub_labels); CeedChk(ierr); 17123668ca4bSJeremy L Thompson ierr = CeedFree(&(*op)->context_labels[i]); CeedChk(ierr); 17133668ca4bSJeremy L Thompson } 17143668ca4bSJeremy L Thompson ierr = CeedFree(&(*op)->context_labels); CeedChk(ierr); 1715fe2413ffSjeremylt 17165107b09fSJeremy L Thompson // Destroy fallback 1717805fe78eSJeremy L Thompson ierr = CeedOperatorDestroy(&(*op)->op_fallback); CeedChk(ierr); 17185107b09fSJeremy L Thompson 1719ed9e99e6SJeremy L Thompson // Destroy assembly data 1720480fae85SJeremy L Thompson ierr = CeedQFunctionAssemblyDataDestroy(&(*op)->qf_assembled); CeedChk(ierr); 1721ed9e99e6SJeremy L Thompson ierr = CeedOperatorAssemblyDataDestroy(&(*op)->op_assembled); CeedChk(ierr); 172270a7ffb3SJeremy L Thompson 1723d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields); CeedChk(ierr); 1724d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields); CeedChk(ierr); 1725d1d35e2fSjeremylt ierr = CeedFree(&(*op)->sub_operators); CeedChk(ierr); 1726ea6b5821SJeremy L Thompson ierr = CeedFree(&(*op)->name); CeedChk(ierr); 1727d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 1728e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1729d7b241e6Sjeremylt } 1730d7b241e6Sjeremylt 1731d7b241e6Sjeremylt /// @} 1732