13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3d7b241e6Sjeremylt // 43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 5d7b241e6Sjeremylt // 63d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 7d7b241e6Sjeremylt 8ec3da8bcSJed Brown #include <ceed/ceed.h> 9ec3da8bcSJed Brown #include <ceed/backend.h> 103d576824SJeremy L Thompson #include <ceed-impl.h> 113d576824SJeremy L Thompson #include <stdbool.h> 123d576824SJeremy L Thompson #include <stdio.h> 133d576824SJeremy L Thompson #include <string.h> 14d7b241e6Sjeremylt 15dfdf5a53Sjeremylt /// @file 167a982d89SJeremy L. Thompson /// Implementation of CeedOperator interfaces 177a982d89SJeremy L. Thompson 187a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 197a982d89SJeremy L. Thompson /// CeedOperator Library Internal Functions 207a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 217a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorDeveloper 227a982d89SJeremy L. Thompson /// @{ 237a982d89SJeremy L. Thompson 247a982d89SJeremy L. Thompson /** 25e15f9bd0SJeremy L Thompson @brief Check if a CeedOperator Field matches the QFunction Field 26e15f9bd0SJeremy L Thompson 27e15f9bd0SJeremy L Thompson @param[in] ceed Ceed object for error handling 28d1d35e2fSjeremylt @param[in] qf_field QFunction Field matching Operator Field 29e15f9bd0SJeremy L Thompson @param[in] r Operator Field ElemRestriction 30e15f9bd0SJeremy L Thompson @param[in] b Operator Field Basis 31e15f9bd0SJeremy L Thompson 32e15f9bd0SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 33e15f9bd0SJeremy L Thompson 34e15f9bd0SJeremy L Thompson @ref Developer 35e15f9bd0SJeremy L Thompson **/ 36d1d35e2fSjeremylt static int CeedOperatorCheckField(Ceed ceed, CeedQFunctionField qf_field, 37e15f9bd0SJeremy L Thompson CeedElemRestriction r, CeedBasis b) { 38e15f9bd0SJeremy L Thompson int ierr; 39d1d35e2fSjeremylt CeedEvalMode eval_mode = qf_field->eval_mode; 40d1d35e2fSjeremylt CeedInt dim = 1, num_comp = 1, restr_num_comp = 1, size = qf_field->size; 41e15f9bd0SJeremy L Thompson // Restriction 42e15f9bd0SJeremy L Thompson if (r != CEED_ELEMRESTRICTION_NONE) { 43d1d35e2fSjeremylt if (eval_mode == CEED_EVAL_WEIGHT) { 44e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 45e1e9e29dSJed Brown return CeedError(ceed, CEED_ERROR_INCOMPATIBLE, 46e1e9e29dSJed Brown "CEED_ELEMRESTRICTION_NONE should be used " 47e15f9bd0SJeremy L Thompson "for a field with eval mode CEED_EVAL_WEIGHT"); 48e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 49e15f9bd0SJeremy L Thompson } 50d1d35e2fSjeremylt ierr = CeedElemRestrictionGetNumComponents(r, &restr_num_comp); 5178464608Sjeremylt CeedChk(ierr); 52e1e9e29dSJed Brown } 53d1d35e2fSjeremylt if ((r == CEED_ELEMRESTRICTION_NONE) != (eval_mode == CEED_EVAL_WEIGHT)) { 54e1e9e29dSJed Brown // LCOV_EXCL_START 55e1e9e29dSJed Brown return CeedError(ceed, CEED_ERROR_INCOMPATIBLE, 56e1e9e29dSJed Brown "CEED_ELEMRESTRICTION_NONE and CEED_EVAL_WEIGHT " 57e1e9e29dSJed Brown "must be used together."); 58e1e9e29dSJed Brown // LCOV_EXCL_STOP 59e1e9e29dSJed Brown } 60e15f9bd0SJeremy L Thompson // Basis 61e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 62d1d35e2fSjeremylt if (eval_mode == CEED_EVAL_NONE) 638229195eSjeremylt // LCOV_EXCL_START 64e1e9e29dSJed Brown return CeedError(ceed, CEED_ERROR_INCOMPATIBLE, 65d1d35e2fSjeremylt "Field '%s' configured with CEED_EVAL_NONE must " 66d1d35e2fSjeremylt "be used with CEED_BASIS_COLLOCATED", 678229195eSjeremylt // LCOV_EXCL_STOP 68d1d35e2fSjeremylt qf_field->field_name); 69e15f9bd0SJeremy L Thompson ierr = CeedBasisGetDimension(b, &dim); CeedChk(ierr); 70d1d35e2fSjeremylt ierr = CeedBasisGetNumComponents(b, &num_comp); CeedChk(ierr); 71d1d35e2fSjeremylt if (r != CEED_ELEMRESTRICTION_NONE && restr_num_comp != num_comp) { 72e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 73e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 74d1d35e2fSjeremylt "Field '%s' of size %d and EvalMode %s: ElemRestriction " 75d1d35e2fSjeremylt "has %d components, but Basis has %d components", 76d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], 77d1d35e2fSjeremylt restr_num_comp, 78d1d35e2fSjeremylt num_comp); 79e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 80e15f9bd0SJeremy L Thompson } 81e15f9bd0SJeremy L Thompson } 82e15f9bd0SJeremy L Thompson // Field size 83d1d35e2fSjeremylt switch(eval_mode) { 84e15f9bd0SJeremy L Thompson case CEED_EVAL_NONE: 85d1d35e2fSjeremylt if (size != restr_num_comp) 86e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 87e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 88e1e9e29dSJed Brown "Field '%s' of size %d and EvalMode %s: ElemRestriction has %d components", 89d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], 90d1d35e2fSjeremylt restr_num_comp); 91e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 92e15f9bd0SJeremy L Thompson break; 93e15f9bd0SJeremy L Thompson case CEED_EVAL_INTERP: 94d1d35e2fSjeremylt if (size != num_comp) 95e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 96e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 97e1e9e29dSJed Brown "Field '%s' of size %d and EvalMode %s: ElemRestriction/Basis has %d components", 98d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], 99d1d35e2fSjeremylt num_comp); 100e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 101e15f9bd0SJeremy L Thompson break; 102e15f9bd0SJeremy L Thompson case CEED_EVAL_GRAD: 103d1d35e2fSjeremylt if (size != num_comp * dim) 104e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 105e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 106d1d35e2fSjeremylt "Field '%s' of size %d and EvalMode %s in %d dimensions: " 107d1d35e2fSjeremylt "ElemRestriction/Basis has %d components", 108d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], dim, 109d1d35e2fSjeremylt num_comp); 110e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 111e15f9bd0SJeremy L Thompson break; 112e15f9bd0SJeremy L Thompson case CEED_EVAL_WEIGHT: 113d1d35e2fSjeremylt // No additional checks required 114e15f9bd0SJeremy L Thompson break; 115e15f9bd0SJeremy L Thompson case CEED_EVAL_DIV: 116e15f9bd0SJeremy L Thompson // Not implemented 117e15f9bd0SJeremy L Thompson break; 118e15f9bd0SJeremy L Thompson case CEED_EVAL_CURL: 119e15f9bd0SJeremy L Thompson // Not implemented 120e15f9bd0SJeremy L Thompson break; 121e15f9bd0SJeremy L Thompson } 122e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1237a982d89SJeremy L. Thompson } 1247a982d89SJeremy L. Thompson 1257a982d89SJeremy L. Thompson /** 1267a982d89SJeremy L. Thompson @brief View a field of a CeedOperator 1277a982d89SJeremy L. Thompson 1287a982d89SJeremy L. Thompson @param[in] field Operator field to view 129d1d35e2fSjeremylt @param[in] qf_field QFunction field (carries field name) 130d1d35e2fSjeremylt @param[in] field_number Number of field being viewed 1314c4400c7SValeria Barra @param[in] sub true indicates sub-operator, which increases indentation; false for top-level operator 132d1d35e2fSjeremylt @param[in] input true for an input field; false for output field 1337a982d89SJeremy L. Thompson @param[in] stream Stream to view to, e.g., stdout 1347a982d89SJeremy L. Thompson 1357a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1367a982d89SJeremy L. Thompson 1377a982d89SJeremy L. Thompson @ref Utility 1387a982d89SJeremy L. Thompson **/ 1397a982d89SJeremy L. Thompson static int CeedOperatorFieldView(CeedOperatorField field, 140d1d35e2fSjeremylt CeedQFunctionField qf_field, 141d1d35e2fSjeremylt CeedInt field_number, bool sub, bool input, 1427a982d89SJeremy L. Thompson FILE *stream) { 1437a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 144d1d35e2fSjeremylt const char *in_out = input ? "Input" : "Output"; 1457a982d89SJeremy L. Thompson 146b8bf0bcaSJeremy L Thompson fprintf(stream, "%s %s field %d:\n" 1477a982d89SJeremy L. Thompson "%s Name: \"%s\"\n", 148d1d35e2fSjeremylt pre, in_out, field_number, pre, qf_field->field_name); 1497a982d89SJeremy L. Thompson 150f5ebfb90SJeremy L Thompson fprintf(stream, "%s Size: %d\n", pre, qf_field->size); 151f5ebfb90SJeremy L Thompson 152f5ebfb90SJeremy L Thompson fprintf(stream, "%s EvalMode: %s\n", pre, 153f5ebfb90SJeremy L Thompson CeedEvalModes[qf_field->eval_mode]); 154f5ebfb90SJeremy L Thompson 1557a982d89SJeremy L. Thompson if (field->basis == CEED_BASIS_COLLOCATED) 1567a982d89SJeremy L. Thompson fprintf(stream, "%s Collocated basis\n", pre); 1577a982d89SJeremy L. Thompson 1587a982d89SJeremy L. Thompson if (field->vec == CEED_VECTOR_ACTIVE) 1597a982d89SJeremy L. Thompson fprintf(stream, "%s Active vector\n", pre); 1607a982d89SJeremy L. Thompson else if (field->vec == CEED_VECTOR_NONE) 1617a982d89SJeremy L. Thompson fprintf(stream, "%s No vector\n", pre); 162f5ebfb90SJeremy L Thompson 163e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1647a982d89SJeremy L. Thompson } 1657a982d89SJeremy L. Thompson 1667a982d89SJeremy L. Thompson /** 1677a982d89SJeremy L. Thompson @brief View a single CeedOperator 1687a982d89SJeremy L. Thompson 1697a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 1707a982d89SJeremy L. Thompson @param[in] sub Boolean flag for sub-operator 1717a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 1727a982d89SJeremy L. Thompson 1737a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 1747a982d89SJeremy L. Thompson 1757a982d89SJeremy L. Thompson @ref Utility 1767a982d89SJeremy L. Thompson **/ 1777a982d89SJeremy L. Thompson int CeedOperatorSingleView(CeedOperator op, bool sub, FILE *stream) { 1787a982d89SJeremy L. Thompson int ierr; 1797a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 1807a982d89SJeremy L. Thompson 181381e6593SJeremy L Thompson CeedInt num_elem, num_qpts; 182381e6593SJeremy L Thompson ierr = CeedOperatorGetNumElements(op, &num_elem); CeedChk(ierr); 183381e6593SJeremy L Thompson ierr = CeedOperatorGetNumQuadraturePoints(op, &num_qpts); CeedChk(ierr); 184381e6593SJeremy L Thompson 18578464608Sjeremylt CeedInt total_fields = 0; 18678464608Sjeremylt ierr = CeedOperatorGetNumArgs(op, &total_fields); CeedChk(ierr); 187381e6593SJeremy L Thompson fprintf(stream, "%s %d elements with %d quadrature points each\n", 188381e6593SJeremy L Thompson pre, num_elem, num_qpts); 1897a982d89SJeremy L. Thompson 190b8bf0bcaSJeremy L Thompson fprintf(stream, "%s %d field%s\n", pre, total_fields, 19178464608Sjeremylt total_fields>1 ? "s" : ""); 1927a982d89SJeremy L. Thompson 193b8bf0bcaSJeremy L Thompson fprintf(stream, "%s %d input field%s:\n", pre, op->qf->num_input_fields, 194d1d35e2fSjeremylt op->qf->num_input_fields>1 ? "s" : ""); 195d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_input_fields; i++) { 196d1d35e2fSjeremylt ierr = CeedOperatorFieldView(op->input_fields[i], op->qf->input_fields[i], 1977a982d89SJeremy L. Thompson i, sub, 1, stream); CeedChk(ierr); 1987a982d89SJeremy L. Thompson } 1997a982d89SJeremy L. Thompson 200b8bf0bcaSJeremy L Thompson fprintf(stream, "%s %d output field%s:\n", pre, op->qf->num_output_fields, 201d1d35e2fSjeremylt op->qf->num_output_fields>1 ? "s" : ""); 202d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_output_fields; i++) { 203d1d35e2fSjeremylt ierr = CeedOperatorFieldView(op->output_fields[i], op->qf->output_fields[i], 2047a982d89SJeremy L. Thompson i, sub, 0, stream); CeedChk(ierr); 2057a982d89SJeremy L. Thompson } 206e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2077a982d89SJeremy L. Thompson } 2087a982d89SJeremy L. Thompson 209d99fa3c5SJeremy L Thompson /** 2100f60e0a8SJeremy L Thompson @brief Find the active vector basis for a non-composite CeedOperator 211eaf62fffSJeremy L Thompson 212eaf62fffSJeremy L Thompson @param[in] op CeedOperator to find active basis for 2130f60e0a8SJeremy L Thompson @param[out] active_basis Basis for active input vector or NULL for composite operator 214eaf62fffSJeremy L Thompson 215eaf62fffSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 216eaf62fffSJeremy L Thompson 217eaf62fffSJeremy L Thompson @ ref Developer 218eaf62fffSJeremy L Thompson **/ 219eaf62fffSJeremy L Thompson int CeedOperatorGetActiveBasis(CeedOperator op, CeedBasis *active_basis) { 220eaf62fffSJeremy L Thompson *active_basis = NULL; 2210f60e0a8SJeremy L Thompson if (op->is_composite) return CEED_ERROR_SUCCESS; 22292ae7e47SJeremy L Thompson for (CeedInt i = 0; i < op->qf->num_input_fields; i++) 223eaf62fffSJeremy L Thompson if (op->input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 224eaf62fffSJeremy L Thompson *active_basis = op->input_fields[i]->basis; 225eaf62fffSJeremy L Thompson break; 226eaf62fffSJeremy L Thompson } 227eaf62fffSJeremy L Thompson 228eaf62fffSJeremy L Thompson if (!*active_basis) { 229eaf62fffSJeremy L Thompson // LCOV_EXCL_START 230eaf62fffSJeremy L Thompson int ierr; 231eaf62fffSJeremy L Thompson Ceed ceed; 232eaf62fffSJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 233eaf62fffSJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 234eaf62fffSJeremy L Thompson "No active CeedBasis found"); 235eaf62fffSJeremy L Thompson // LCOV_EXCL_STOP 236eaf62fffSJeremy L Thompson } 237eaf62fffSJeremy L Thompson return CEED_ERROR_SUCCESS; 238eaf62fffSJeremy L Thompson } 239eaf62fffSJeremy L Thompson 240eaf62fffSJeremy L Thompson /** 2410f60e0a8SJeremy L Thompson @brief Find the active vector ElemRestriction for a non-composite CeedOperator 242e2f04181SAndrew T. Barker 243e2f04181SAndrew T. Barker @param[in] op CeedOperator to find active basis for 2440f60e0a8SJeremy L Thompson @param[out] active_rstr ElemRestriction for active input vector or NULL for composite operator 245e2f04181SAndrew T. Barker 246e2f04181SAndrew T. Barker @return An error code: 0 - success, otherwise - failure 247e2f04181SAndrew T. Barker 248e2f04181SAndrew T. Barker @ref Utility 249e2f04181SAndrew T. Barker **/ 250eaf62fffSJeremy L Thompson int CeedOperatorGetActiveElemRestriction(CeedOperator op, 251d1d35e2fSjeremylt CeedElemRestriction *active_rstr) { 252d1d35e2fSjeremylt *active_rstr = NULL; 2530f60e0a8SJeremy L Thompson if (op->is_composite) return CEED_ERROR_SUCCESS; 25492ae7e47SJeremy L Thompson for (CeedInt i = 0; i < op->qf->num_input_fields; i++) 255d1d35e2fSjeremylt if (op->input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 256d1d35e2fSjeremylt *active_rstr = op->input_fields[i]->elem_restr; 257e2f04181SAndrew T. Barker break; 258e2f04181SAndrew T. Barker } 259e2f04181SAndrew T. Barker 260d1d35e2fSjeremylt if (!*active_rstr) { 261e2f04181SAndrew T. Barker // LCOV_EXCL_START 262e2f04181SAndrew T. Barker int ierr; 263e2f04181SAndrew T. Barker Ceed ceed; 264e2f04181SAndrew T. Barker ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 265e2f04181SAndrew T. Barker return CeedError(ceed, CEED_ERROR_INCOMPLETE, 266eaf62fffSJeremy L Thompson "No active CeedElemRestriction found"); 267e2f04181SAndrew T. Barker // LCOV_EXCL_STOP 268e2f04181SAndrew T. Barker } 269e2f04181SAndrew T. Barker return CEED_ERROR_SUCCESS; 270e2f04181SAndrew T. Barker } 271e2f04181SAndrew T. Barker 272d8dd9a91SJeremy L Thompson /** 273d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field value of the specified type. 274d8dd9a91SJeremy L Thompson For composite operators, the value is set in all 275d8dd9a91SJeremy L Thompson sub-operator QFunctionContexts that have a matching `field_name`. 276d8dd9a91SJeremy L Thompson A non-zero error code is returned for single operators 277d8dd9a91SJeremy L Thompson that do not have a matching field of the same type or composite 278d8dd9a91SJeremy L Thompson operators that do not have any field of a matching type. 279d8dd9a91SJeremy L Thompson 280d8dd9a91SJeremy L Thompson @param op CeedOperator 2813668ca4bSJeremy L Thompson @param field_label Label of field to set 282d8dd9a91SJeremy L Thompson @param field_type Type of field to set 283d8dd9a91SJeremy L Thompson @param value Value to set 284d8dd9a91SJeremy L Thompson 285d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 286d8dd9a91SJeremy L Thompson 287d8dd9a91SJeremy L Thompson @ref User 288d8dd9a91SJeremy L Thompson **/ 289d8dd9a91SJeremy L Thompson static int CeedOperatorContextSetGeneric(CeedOperator op, 2903668ca4bSJeremy L Thompson CeedContextFieldLabel field_label, CeedContextFieldType field_type, 2913668ca4bSJeremy L Thompson void *value) { 292d8dd9a91SJeremy L Thompson int ierr; 293d8dd9a91SJeremy L Thompson 2943668ca4bSJeremy L Thompson if (!field_label) 2953668ca4bSJeremy L Thompson // LCOV_EXCL_START 2963668ca4bSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_UNSUPPORTED, 2973668ca4bSJeremy L Thompson "Invalid field label"); 2983668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 2993668ca4bSJeremy L Thompson 3003668ca4bSJeremy L Thompson bool is_composite = false; 301d8dd9a91SJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 302d8dd9a91SJeremy L Thompson if (is_composite) { 303d8dd9a91SJeremy L Thompson CeedInt num_sub; 304d8dd9a91SJeremy L Thompson CeedOperator *sub_operators; 305d8dd9a91SJeremy L Thompson 306d8dd9a91SJeremy L Thompson ierr = CeedOperatorGetNumSub(op, &num_sub); CeedChk(ierr); 307d8dd9a91SJeremy L Thompson ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 3083668ca4bSJeremy L Thompson if (num_sub != field_label->num_sub_labels) 3093668ca4bSJeremy L Thompson // LCOV_EXCL_START 3103668ca4bSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_UNSUPPORTED, 3113668ca4bSJeremy L Thompson "ContextLabel does not correspond to composite operator.\n" 3123668ca4bSJeremy L Thompson "Use CeedOperatorGetContextFieldLabel()."); 3133668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 314d8dd9a91SJeremy L Thompson 315d8dd9a91SJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 316d8dd9a91SJeremy L Thompson // Try every sub-operator, ok if some sub-operators do not have field 3173668ca4bSJeremy L Thompson if (field_label->sub_labels[i] && sub_operators[i]->qf->ctx) { 3183668ca4bSJeremy L Thompson ierr = CeedQFunctionContextSetGeneric(sub_operators[i]->qf->ctx, 3193668ca4bSJeremy L Thompson field_label->sub_labels[i], 3203668ca4bSJeremy L Thompson field_type, value); CeedChk(ierr); 321d8dd9a91SJeremy L Thompson } 322d8dd9a91SJeremy L Thompson } 323d8dd9a91SJeremy L Thompson } else { 324d8dd9a91SJeremy L Thompson if (!op->qf->ctx) 325d8dd9a91SJeremy L Thompson // LCOV_EXCL_START 326d8dd9a91SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_UNSUPPORTED, 327d8dd9a91SJeremy L Thompson "QFunction does not have context data"); 328d8dd9a91SJeremy L Thompson // LCOV_EXCL_STOP 329d8dd9a91SJeremy L Thompson 3303668ca4bSJeremy L Thompson ierr = CeedQFunctionContextSetGeneric(op->qf->ctx, field_label, 3313668ca4bSJeremy L Thompson field_type, value); CeedChk(ierr); 332d8dd9a91SJeremy L Thompson } 333d8dd9a91SJeremy L Thompson 334d8dd9a91SJeremy L Thompson return CEED_ERROR_SUCCESS; 335d8dd9a91SJeremy L Thompson } 336d8dd9a91SJeremy L Thompson 3377a982d89SJeremy L. Thompson /// @} 3387a982d89SJeremy L. Thompson 3397a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3407a982d89SJeremy L. Thompson /// CeedOperator Backend API 3417a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3427a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorBackend 3437a982d89SJeremy L. Thompson /// @{ 3447a982d89SJeremy L. Thompson 3457a982d89SJeremy L. Thompson /** 3467a982d89SJeremy L. Thompson @brief Get the number of arguments associated with a CeedOperator 3477a982d89SJeremy L. Thompson 3487a982d89SJeremy L. Thompson @param op CeedOperator 349d1d35e2fSjeremylt @param[out] num_args Variable to store vector number of arguments 3507a982d89SJeremy L. Thompson 3517a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3527a982d89SJeremy L. Thompson 3537a982d89SJeremy L. Thompson @ref Backend 3547a982d89SJeremy L. Thompson **/ 3557a982d89SJeremy L. Thompson 356d1d35e2fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *num_args) { 357f04ea552SJeremy L Thompson if (op->is_composite) 3587a982d89SJeremy L. Thompson // LCOV_EXCL_START 359e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 360e15f9bd0SJeremy L Thompson "Not defined for composite operators"); 3617a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 3627a982d89SJeremy L. Thompson 363d1d35e2fSjeremylt *num_args = op->num_fields; 364e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3657a982d89SJeremy L. Thompson } 3667a982d89SJeremy L. Thompson 3677a982d89SJeremy L. Thompson /** 3687a982d89SJeremy L. Thompson @brief Get the setup status of a CeedOperator 3697a982d89SJeremy L. Thompson 3707a982d89SJeremy L. Thompson @param op CeedOperator 371d1d35e2fSjeremylt @param[out] is_setup_done Variable to store setup status 3727a982d89SJeremy L. Thompson 3737a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3747a982d89SJeremy L. Thompson 3757a982d89SJeremy L. Thompson @ref Backend 3767a982d89SJeremy L. Thompson **/ 3777a982d89SJeremy L. Thompson 378d1d35e2fSjeremylt int CeedOperatorIsSetupDone(CeedOperator op, bool *is_setup_done) { 379f04ea552SJeremy L Thompson *is_setup_done = op->is_backend_setup; 380e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3817a982d89SJeremy L. Thompson } 3827a982d89SJeremy L. Thompson 3837a982d89SJeremy L. Thompson /** 3847a982d89SJeremy L. Thompson @brief Get the QFunction associated with a CeedOperator 3857a982d89SJeremy L. Thompson 3867a982d89SJeremy L. Thompson @param op CeedOperator 3877a982d89SJeremy L. Thompson @param[out] qf Variable to store QFunction 3887a982d89SJeremy L. Thompson 3897a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3907a982d89SJeremy L. Thompson 3917a982d89SJeremy L. Thompson @ref Backend 3927a982d89SJeremy L. Thompson **/ 3937a982d89SJeremy L. Thompson 3947a982d89SJeremy L. Thompson int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 395f04ea552SJeremy L Thompson if (op->is_composite) 3967a982d89SJeremy L. Thompson // LCOV_EXCL_START 397e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 398e15f9bd0SJeremy L Thompson "Not defined for composite operator"); 3997a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4007a982d89SJeremy L. Thompson 4017a982d89SJeremy L. Thompson *qf = op->qf; 402e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4037a982d89SJeremy L. Thompson } 4047a982d89SJeremy L. Thompson 4057a982d89SJeremy L. Thompson /** 406c04a41a7SJeremy L Thompson @brief Get a boolean value indicating if the CeedOperator is composite 407c04a41a7SJeremy L Thompson 408c04a41a7SJeremy L Thompson @param op CeedOperator 409d1d35e2fSjeremylt @param[out] is_composite Variable to store composite status 410c04a41a7SJeremy L Thompson 411c04a41a7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 412c04a41a7SJeremy L Thompson 413c04a41a7SJeremy L Thompson @ref Backend 414c04a41a7SJeremy L Thompson **/ 415c04a41a7SJeremy L Thompson 416d1d35e2fSjeremylt int CeedOperatorIsComposite(CeedOperator op, bool *is_composite) { 417f04ea552SJeremy L Thompson *is_composite = op->is_composite; 418e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 419c04a41a7SJeremy L Thompson } 420c04a41a7SJeremy L Thompson 421c04a41a7SJeremy L Thompson /** 422d1d35e2fSjeremylt @brief Get the number of sub_operators associated with a CeedOperator 4237a982d89SJeremy L. Thompson 4247a982d89SJeremy L. Thompson @param op CeedOperator 425d1d35e2fSjeremylt @param[out] num_suboperators Variable to store number of sub_operators 4267a982d89SJeremy L. Thompson 4277a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4287a982d89SJeremy L. Thompson 4297a982d89SJeremy L. Thompson @ref Backend 4307a982d89SJeremy L. Thompson **/ 4317a982d89SJeremy L. Thompson 432d1d35e2fSjeremylt int CeedOperatorGetNumSub(CeedOperator op, CeedInt *num_suboperators) { 433f04ea552SJeremy L Thompson if (!op->is_composite) 4347a982d89SJeremy L. Thompson // LCOV_EXCL_START 435e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 4367a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4377a982d89SJeremy L. Thompson 438d1d35e2fSjeremylt *num_suboperators = op->num_suboperators; 439e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4407a982d89SJeremy L. Thompson } 4417a982d89SJeremy L. Thompson 4427a982d89SJeremy L. Thompson /** 443d1d35e2fSjeremylt @brief Get the list of sub_operators associated with a CeedOperator 4447a982d89SJeremy L. Thompson 4457a982d89SJeremy L. Thompson @param op CeedOperator 446d1d35e2fSjeremylt @param[out] sub_operators Variable to store list of sub_operators 4477a982d89SJeremy L. Thompson 4487a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4497a982d89SJeremy L. Thompson 4507a982d89SJeremy L. Thompson @ref Backend 4517a982d89SJeremy L. Thompson **/ 4527a982d89SJeremy L. Thompson 453d1d35e2fSjeremylt int CeedOperatorGetSubList(CeedOperator op, CeedOperator **sub_operators) { 454f04ea552SJeremy L Thompson if (!op->is_composite) 4557a982d89SJeremy L. Thompson // LCOV_EXCL_START 456e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 4577a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4587a982d89SJeremy L. Thompson 459d1d35e2fSjeremylt *sub_operators = op->sub_operators; 460e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4617a982d89SJeremy L. Thompson } 4627a982d89SJeremy L. Thompson 4637a982d89SJeremy L. Thompson /** 4647a982d89SJeremy L. Thompson @brief Get the backend data of a CeedOperator 4657a982d89SJeremy L. Thompson 4667a982d89SJeremy L. Thompson @param op CeedOperator 4677a982d89SJeremy L. Thompson @param[out] data Variable to store data 4687a982d89SJeremy L. Thompson 4697a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4707a982d89SJeremy L. Thompson 4717a982d89SJeremy L. Thompson @ref Backend 4727a982d89SJeremy L. Thompson **/ 4737a982d89SJeremy L. Thompson 474777ff853SJeremy L Thompson int CeedOperatorGetData(CeedOperator op, void *data) { 475777ff853SJeremy L Thompson *(void **)data = op->data; 476e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4777a982d89SJeremy L. Thompson } 4787a982d89SJeremy L. Thompson 4797a982d89SJeremy L. Thompson /** 4807a982d89SJeremy L. Thompson @brief Set the backend data of a CeedOperator 4817a982d89SJeremy L. Thompson 4827a982d89SJeremy L. Thompson @param[out] op CeedOperator 4837a982d89SJeremy L. Thompson @param data Data to set 4847a982d89SJeremy L. Thompson 4857a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4867a982d89SJeremy L. Thompson 4877a982d89SJeremy L. Thompson @ref Backend 4887a982d89SJeremy L. Thompson **/ 4897a982d89SJeremy L. Thompson 490777ff853SJeremy L Thompson int CeedOperatorSetData(CeedOperator op, void *data) { 491777ff853SJeremy L Thompson op->data = data; 492e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4937a982d89SJeremy L. Thompson } 4947a982d89SJeremy L. Thompson 4957a982d89SJeremy L. Thompson /** 49634359f16Sjeremylt @brief Increment the reference counter for a CeedOperator 49734359f16Sjeremylt 49834359f16Sjeremylt @param op CeedOperator to increment the reference counter 49934359f16Sjeremylt 50034359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 50134359f16Sjeremylt 50234359f16Sjeremylt @ref Backend 50334359f16Sjeremylt **/ 5049560d06aSjeremylt int CeedOperatorReference(CeedOperator op) { 50534359f16Sjeremylt op->ref_count++; 50634359f16Sjeremylt return CEED_ERROR_SUCCESS; 50734359f16Sjeremylt } 50834359f16Sjeremylt 50934359f16Sjeremylt /** 5107a982d89SJeremy L. Thompson @brief Set the setup flag of a CeedOperator to True 5117a982d89SJeremy L. Thompson 5127a982d89SJeremy L. Thompson @param op CeedOperator 5137a982d89SJeremy L. Thompson 5147a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5157a982d89SJeremy L. Thompson 5167a982d89SJeremy L. Thompson @ref Backend 5177a982d89SJeremy L. Thompson **/ 5187a982d89SJeremy L. Thompson 5197a982d89SJeremy L. Thompson int CeedOperatorSetSetupDone(CeedOperator op) { 520f04ea552SJeremy L Thompson op->is_backend_setup = true; 521e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5227a982d89SJeremy L. Thompson } 5237a982d89SJeremy L. Thompson 5247a982d89SJeremy L. Thompson /// @} 5257a982d89SJeremy L. Thompson 5267a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5277a982d89SJeremy L. Thompson /// CeedOperator Public API 5287a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5297a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorUser 530dfdf5a53Sjeremylt /// @{ 531d7b241e6Sjeremylt 532d7b241e6Sjeremylt /** 5330219ea01SJeremy L Thompson @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and 5340219ea01SJeremy L Thompson CeedElemRestriction can be associated with CeedQFunction fields with 5350219ea01SJeremy L Thompson \ref CeedOperatorSetField. 536d7b241e6Sjeremylt 537b11c1e72Sjeremylt @param ceed A Ceed object where the CeedOperator will be created 538d7b241e6Sjeremylt @param qf QFunction defining the action of the operator at quadrature points 53934138859Sjeremylt @param dqf QFunction defining the action of the Jacobian of @a qf (or 5404cc79fe7SJed Brown @ref CEED_QFUNCTION_NONE) 541d7b241e6Sjeremylt @param dqfT QFunction defining the action of the transpose of the Jacobian 5424cc79fe7SJed Brown of @a qf (or @ref CEED_QFUNCTION_NONE) 543b11c1e72Sjeremylt @param[out] op Address of the variable where the newly created 544b11c1e72Sjeremylt CeedOperator will be stored 545b11c1e72Sjeremylt 546b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 547dfdf5a53Sjeremylt 5487a982d89SJeremy L. Thompson @ref User 549d7b241e6Sjeremylt */ 550d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, 551d7b241e6Sjeremylt CeedQFunction dqfT, CeedOperator *op) { 552d7b241e6Sjeremylt int ierr; 553d7b241e6Sjeremylt 5545fe0d4faSjeremylt if (!ceed->OperatorCreate) { 5555fe0d4faSjeremylt Ceed delegate; 556aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 5575fe0d4faSjeremylt 5585fe0d4faSjeremylt if (!delegate) 559c042f62fSJeremy L Thompson // LCOV_EXCL_START 560e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 561e15f9bd0SJeremy L Thompson "Backend does not support OperatorCreate"); 562c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 5635fe0d4faSjeremylt 5645fe0d4faSjeremylt ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr); 565e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5665fe0d4faSjeremylt } 5675fe0d4faSjeremylt 568b3b7035fSJeremy L Thompson if (!qf || qf == CEED_QFUNCTION_NONE) 569b3b7035fSJeremy L Thompson // LCOV_EXCL_START 570e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 571e15f9bd0SJeremy L Thompson "Operator must have a valid QFunction."); 572b3b7035fSJeremy L Thompson // LCOV_EXCL_STOP 573d7b241e6Sjeremylt ierr = CeedCalloc(1, op); CeedChk(ierr); 574d7b241e6Sjeremylt (*op)->ceed = ceed; 5759560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 576d1d35e2fSjeremylt (*op)->ref_count = 1; 577d7b241e6Sjeremylt (*op)->qf = qf; 5782b104005SJeremy L Thompson (*op)->input_size = -1; 5792b104005SJeremy L Thompson (*op)->output_size = -1; 5809560d06aSjeremylt ierr = CeedQFunctionReference(qf); CeedChk(ierr); 581442e7f0bSjeremylt if (dqf && dqf != CEED_QFUNCTION_NONE) { 582d7b241e6Sjeremylt (*op)->dqf = dqf; 5839560d06aSjeremylt ierr = CeedQFunctionReference(dqf); CeedChk(ierr); 584442e7f0bSjeremylt } 585442e7f0bSjeremylt if (dqfT && dqfT != CEED_QFUNCTION_NONE) { 586d7b241e6Sjeremylt (*op)->dqfT = dqfT; 5879560d06aSjeremylt ierr = CeedQFunctionReference(dqfT); CeedChk(ierr); 588442e7f0bSjeremylt } 589480fae85SJeremy L Thompson ierr = CeedQFunctionAssemblyDataCreate(ceed, &(*op)->qf_assembled); 590480fae85SJeremy L Thompson CeedChk(ierr); 591bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_FIELD_MAX, &(*op)->input_fields); CeedChk(ierr); 592bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_FIELD_MAX, &(*op)->output_fields); CeedChk(ierr); 593d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 594e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 595d7b241e6Sjeremylt } 596d7b241e6Sjeremylt 597d7b241e6Sjeremylt /** 59852d6035fSJeremy L Thompson @brief Create an operator that composes the action of several operators 59952d6035fSJeremy L Thompson 60052d6035fSJeremy L Thompson @param ceed A Ceed object where the CeedOperator will be created 60152d6035fSJeremy L Thompson @param[out] op Address of the variable where the newly created 60252d6035fSJeremy L Thompson Composite CeedOperator will be stored 60352d6035fSJeremy L Thompson 60452d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 60552d6035fSJeremy L Thompson 6067a982d89SJeremy L. Thompson @ref User 60752d6035fSJeremy L Thompson */ 60852d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) { 60952d6035fSJeremy L Thompson int ierr; 61052d6035fSJeremy L Thompson 61152d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 61252d6035fSJeremy L Thompson Ceed delegate; 613aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 61452d6035fSJeremy L Thompson 615250756a7Sjeremylt if (delegate) { 61652d6035fSJeremy L Thompson ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr); 617e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 61852d6035fSJeremy L Thompson } 619250756a7Sjeremylt } 62052d6035fSJeremy L Thompson 62152d6035fSJeremy L Thompson ierr = CeedCalloc(1, op); CeedChk(ierr); 62252d6035fSJeremy L Thompson (*op)->ceed = ceed; 6239560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 624f04ea552SJeremy L Thompson (*op)->is_composite = true; 625bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_COMPOSITE_MAX, &(*op)->sub_operators); CeedChk(ierr); 6262b104005SJeremy L Thompson (*op)->input_size = -1; 6272b104005SJeremy L Thompson (*op)->output_size = -1; 628250756a7Sjeremylt 629250756a7Sjeremylt if (ceed->CompositeOperatorCreate) { 63052d6035fSJeremy L Thompson ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr); 631250756a7Sjeremylt } 632e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 63352d6035fSJeremy L Thompson } 63452d6035fSJeremy L Thompson 63552d6035fSJeremy L Thompson /** 6369560d06aSjeremylt @brief Copy the pointer to a CeedOperator. Both pointers should 6379560d06aSjeremylt be destroyed with `CeedOperatorDestroy()`; 6389560d06aSjeremylt Note: If `*op_copy` is non-NULL, then it is assumed that 6399560d06aSjeremylt `*op_copy` is a pointer to a CeedOperator. This 6409560d06aSjeremylt CeedOperator will be destroyed if `*op_copy` is the only 6419560d06aSjeremylt reference to this CeedOperator. 6429560d06aSjeremylt 6439560d06aSjeremylt @param op CeedOperator to copy reference to 6449560d06aSjeremylt @param[out] op_copy Variable to store copied reference 6459560d06aSjeremylt 6469560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 6479560d06aSjeremylt 6489560d06aSjeremylt @ref User 6499560d06aSjeremylt **/ 6509560d06aSjeremylt int CeedOperatorReferenceCopy(CeedOperator op, CeedOperator *op_copy) { 6519560d06aSjeremylt int ierr; 6529560d06aSjeremylt 6539560d06aSjeremylt ierr = CeedOperatorReference(op); CeedChk(ierr); 6549560d06aSjeremylt ierr = CeedOperatorDestroy(op_copy); CeedChk(ierr); 6559560d06aSjeremylt *op_copy = op; 6569560d06aSjeremylt return CEED_ERROR_SUCCESS; 6579560d06aSjeremylt } 6589560d06aSjeremylt 6599560d06aSjeremylt /** 660b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 661d7b241e6Sjeremylt 662d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 663d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 664d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 665d7b241e6Sjeremylt 666d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 667d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 668979e564eSJames Wright input CeedVector and at most one active output CeedVector passed to 669979e564eSJames Wright CeedOperatorApply(). 670d7b241e6Sjeremylt 6718c91a0c9SJeremy L Thompson @param op CeedOperator on which to provide the field 672d1d35e2fSjeremylt @param field_name Name of the field (to be matched with the name used by 6738795c945Sjeremylt CeedQFunction) 674b11c1e72Sjeremylt @param r CeedElemRestriction 6754cc79fe7SJed Brown @param b CeedBasis in which the field resides or @ref CEED_BASIS_COLLOCATED 676b11c1e72Sjeremylt if collocated with quadrature points 6774cc79fe7SJed Brown @param v CeedVector to be used by CeedOperator or @ref CEED_VECTOR_ACTIVE 6784cc79fe7SJed Brown if field is active or @ref CEED_VECTOR_NONE if using 6794cc79fe7SJed Brown @ref CEED_EVAL_WEIGHT in the QFunction 680b11c1e72Sjeremylt 681b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 682dfdf5a53Sjeremylt 6837a982d89SJeremy L. Thompson @ref User 684b11c1e72Sjeremylt **/ 685d1d35e2fSjeremylt int CeedOperatorSetField(CeedOperator op, const char *field_name, 686a8d32208Sjeremylt CeedElemRestriction r, CeedBasis b, CeedVector v) { 687d7b241e6Sjeremylt int ierr; 688f04ea552SJeremy L Thompson if (op->is_composite) 689c042f62fSJeremy L Thompson // LCOV_EXCL_START 690e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 691e15f9bd0SJeremy L Thompson "Cannot add field to composite operator."); 692c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 693f04ea552SJeremy L Thompson if (op->is_immutable) 694f04ea552SJeremy L Thompson // LCOV_EXCL_START 695f04ea552SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 696f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 697f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 6988b067b84SJed Brown if (!r) 699c042f62fSJeremy L Thompson // LCOV_EXCL_START 700e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 701c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 702d1d35e2fSjeremylt field_name); 703c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 7048b067b84SJed Brown if (!b) 705c042f62fSJeremy L Thompson // LCOV_EXCL_START 706e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 707e15f9bd0SJeremy L Thompson "Basis b for field \"%s\" must be non-NULL.", 708d1d35e2fSjeremylt field_name); 709c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 7108b067b84SJed Brown if (!v) 711c042f62fSJeremy L Thompson // LCOV_EXCL_START 712e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 713e15f9bd0SJeremy L Thompson "Vector v for field \"%s\" must be non-NULL.", 714d1d35e2fSjeremylt field_name); 715c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 71652d6035fSJeremy L Thompson 717d1d35e2fSjeremylt CeedInt num_elem; 718d1d35e2fSjeremylt ierr = CeedElemRestrictionGetNumElements(r, &num_elem); CeedChk(ierr); 719d1d35e2fSjeremylt if (r != CEED_ELEMRESTRICTION_NONE && op->has_restriction && 720d1d35e2fSjeremylt op->num_elem != num_elem) 721c042f62fSJeremy L Thompson // LCOV_EXCL_START 722e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 7231d102b48SJeremy L Thompson "ElemRestriction with %d elements incompatible with prior " 724d1d35e2fSjeremylt "%d elements", num_elem, op->num_elem); 725c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 726d7b241e6Sjeremylt 72778464608Sjeremylt CeedInt num_qpts = 0; 728e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 729d1d35e2fSjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &num_qpts); CeedChk(ierr); 730d1d35e2fSjeremylt if (op->num_qpts && op->num_qpts != num_qpts) 731c042f62fSJeremy L Thompson // LCOV_EXCL_START 732e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 733e15f9bd0SJeremy L Thompson "Basis with %d quadrature points " 734d1d35e2fSjeremylt "incompatible with prior %d points", num_qpts, 735d1d35e2fSjeremylt op->num_qpts); 736c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 737d7b241e6Sjeremylt } 738d1d35e2fSjeremylt CeedQFunctionField qf_field; 739d1d35e2fSjeremylt CeedOperatorField *op_field; 7402b104005SJeremy L Thompson bool is_input = true; 741d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_input_fields; i++) { 742d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->input_fields[i]).field_name)) { 743d1d35e2fSjeremylt qf_field = op->qf->input_fields[i]; 744d1d35e2fSjeremylt op_field = &op->input_fields[i]; 745d7b241e6Sjeremylt goto found; 746d7b241e6Sjeremylt } 747d7b241e6Sjeremylt } 7482b104005SJeremy L Thompson is_input = false; 749d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_output_fields; i++) { 750d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->output_fields[i]).field_name)) { 751d1d35e2fSjeremylt qf_field = op->qf->output_fields[i]; 752d1d35e2fSjeremylt op_field = &op->output_fields[i]; 753d7b241e6Sjeremylt goto found; 754d7b241e6Sjeremylt } 755d7b241e6Sjeremylt } 756c042f62fSJeremy L Thompson // LCOV_EXCL_START 757e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPLETE, 758e15f9bd0SJeremy L Thompson "QFunction has no knowledge of field '%s'", 759d1d35e2fSjeremylt field_name); 760c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 761d7b241e6Sjeremylt found: 762d1d35e2fSjeremylt ierr = CeedOperatorCheckField(op->ceed, qf_field, r, b); CeedChk(ierr); 763d1d35e2fSjeremylt ierr = CeedCalloc(1, op_field); CeedChk(ierr); 764e15f9bd0SJeremy L Thompson 7652b104005SJeremy L Thompson if (v == CEED_VECTOR_ACTIVE) { 7662b104005SJeremy L Thompson CeedSize l_size; 7672b104005SJeremy L Thompson ierr = CeedElemRestrictionGetLVectorSize(r, &l_size); CeedChk(ierr); 7682b104005SJeremy L Thompson if (is_input) { 7692b104005SJeremy L Thompson if (op->input_size == -1) op->input_size = l_size; 7702b104005SJeremy L Thompson if (l_size != op->input_size) 7712b104005SJeremy L Thompson // LCOV_EXCL_START 7722b104005SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 7732b104005SJeremy L Thompson "LVector size %td does not match previous size %td", 7742b104005SJeremy L Thompson l_size, op->input_size); 7752b104005SJeremy L Thompson // LCOV_EXCL_STOP 7762b104005SJeremy L Thompson } else { 7772b104005SJeremy L Thompson if (op->output_size == -1) op->output_size = l_size; 7782b104005SJeremy L Thompson if (l_size != op->output_size) 7792b104005SJeremy L Thompson // LCOV_EXCL_START 7802b104005SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 7812b104005SJeremy L Thompson "LVector size %td does not match previous size %td", 7822b104005SJeremy L Thompson l_size, op->output_size); 7832b104005SJeremy L Thompson // LCOV_EXCL_STOP 7842b104005SJeremy L Thompson } 7852b104005SJeremy L Thompson } 7862b104005SJeremy L Thompson 787d1d35e2fSjeremylt (*op_field)->vec = v; 788e15f9bd0SJeremy L Thompson if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) { 7899560d06aSjeremylt ierr = CeedVectorReference(v); CeedChk(ierr); 790e15f9bd0SJeremy L Thompson } 791e15f9bd0SJeremy L Thompson 792d1d35e2fSjeremylt (*op_field)->elem_restr = r; 7939560d06aSjeremylt ierr = CeedElemRestrictionReference(r); CeedChk(ierr); 794e15f9bd0SJeremy L Thompson if (r != CEED_ELEMRESTRICTION_NONE) { 795d1d35e2fSjeremylt op->num_elem = num_elem; 796d1d35e2fSjeremylt op->has_restriction = true; // Restriction set, but num_elem may be 0 797e15f9bd0SJeremy L Thompson } 798d99fa3c5SJeremy L Thompson 799d1d35e2fSjeremylt (*op_field)->basis = b; 800e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 801cd4dfc48Sjeremylt if (!op->num_qpts) { 802cd4dfc48Sjeremylt ierr = CeedOperatorSetNumQuadraturePoints(op, num_qpts); CeedChk(ierr); 803cd4dfc48Sjeremylt } 8049560d06aSjeremylt ierr = CeedBasisReference(b); CeedChk(ierr); 805e15f9bd0SJeremy L Thompson } 806e15f9bd0SJeremy L Thompson 807d1d35e2fSjeremylt op->num_fields += 1; 808f7e22acaSJeremy L Thompson ierr = CeedStringAllocCopy(field_name, (char **)&(*op_field)->field_name); 809f7e22acaSJeremy L Thompson CeedChk(ierr); 810e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 811d7b241e6Sjeremylt } 812d7b241e6Sjeremylt 813d7b241e6Sjeremylt /** 81443bbe138SJeremy L Thompson @brief Get the CeedOperatorFields of a CeedOperator 81543bbe138SJeremy L Thompson 816f04ea552SJeremy L Thompson Note: Calling this function asserts that setup is complete 817f04ea552SJeremy L Thompson and sets the CeedOperator as immutable. 818f04ea552SJeremy L Thompson 81943bbe138SJeremy L Thompson @param op CeedOperator 820f74ec584SJeremy L Thompson @param[out] num_input_fields Variable to store number of input fields 82143bbe138SJeremy L Thompson @param[out] input_fields Variable to store input_fields 822f74ec584SJeremy L Thompson @param[out] num_output_fields Variable to store number of output fields 82343bbe138SJeremy L Thompson @param[out] output_fields Variable to store output_fields 82443bbe138SJeremy L Thompson 82543bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 82643bbe138SJeremy L Thompson 827e9b533fbSJeremy L Thompson @ref Advanced 82843bbe138SJeremy L Thompson **/ 82943bbe138SJeremy L Thompson int CeedOperatorGetFields(CeedOperator op, CeedInt *num_input_fields, 83043bbe138SJeremy L Thompson CeedOperatorField **input_fields, 83143bbe138SJeremy L Thompson CeedInt *num_output_fields, 83243bbe138SJeremy L Thompson CeedOperatorField **output_fields) { 833f04ea552SJeremy L Thompson int ierr; 834f04ea552SJeremy L Thompson 835f04ea552SJeremy L Thompson if (op->is_composite) 83643bbe138SJeremy L Thompson // LCOV_EXCL_START 83743bbe138SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 83843bbe138SJeremy L Thompson "Not defined for composite operator"); 83943bbe138SJeremy L Thompson // LCOV_EXCL_STOP 840f04ea552SJeremy L Thompson ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 84143bbe138SJeremy L Thompson 84243bbe138SJeremy L Thompson if (num_input_fields) *num_input_fields = op->qf->num_input_fields; 84343bbe138SJeremy L Thompson if (input_fields) *input_fields = op->input_fields; 84443bbe138SJeremy L Thompson if (num_output_fields) *num_output_fields = op->qf->num_output_fields; 84543bbe138SJeremy L Thompson if (output_fields) *output_fields = op->output_fields; 84643bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 84743bbe138SJeremy L Thompson } 84843bbe138SJeremy L Thompson 84943bbe138SJeremy L Thompson /** 85028567f8fSJeremy L Thompson @brief Get the name of a CeedOperatorField 85128567f8fSJeremy L Thompson 85228567f8fSJeremy L Thompson @param op_field CeedOperatorField 85328567f8fSJeremy L Thompson @param[out] field_name Variable to store the field name 85428567f8fSJeremy L Thompson 85528567f8fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 85628567f8fSJeremy L Thompson 857e9b533fbSJeremy L Thompson @ref Advanced 85828567f8fSJeremy L Thompson **/ 85928567f8fSJeremy L Thompson int CeedOperatorFieldGetName(CeedOperatorField op_field, char **field_name) { 86028567f8fSJeremy L Thompson *field_name = (char *)op_field->field_name; 86128567f8fSJeremy L Thompson return CEED_ERROR_SUCCESS; 86228567f8fSJeremy L Thompson } 86328567f8fSJeremy L Thompson 86428567f8fSJeremy L Thompson /** 86543bbe138SJeremy L Thompson @brief Get the CeedElemRestriction of a CeedOperatorField 86643bbe138SJeremy L Thompson 86743bbe138SJeremy L Thompson @param op_field CeedOperatorField 86843bbe138SJeremy L Thompson @param[out] rstr Variable to store CeedElemRestriction 86943bbe138SJeremy L Thompson 87043bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 87143bbe138SJeremy L Thompson 872e9b533fbSJeremy L Thompson @ref Advanced 87343bbe138SJeremy L Thompson **/ 87443bbe138SJeremy L Thompson int CeedOperatorFieldGetElemRestriction(CeedOperatorField op_field, 87543bbe138SJeremy L Thompson CeedElemRestriction *rstr) { 87643bbe138SJeremy L Thompson *rstr = op_field->elem_restr; 87743bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 87843bbe138SJeremy L Thompson } 87943bbe138SJeremy L Thompson 88043bbe138SJeremy L Thompson /** 88143bbe138SJeremy L Thompson @brief Get the CeedBasis of a CeedOperatorField 88243bbe138SJeremy L Thompson 88343bbe138SJeremy L Thompson @param op_field CeedOperatorField 88443bbe138SJeremy L Thompson @param[out] basis Variable to store CeedBasis 88543bbe138SJeremy L Thompson 88643bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 88743bbe138SJeremy L Thompson 888e9b533fbSJeremy L Thompson @ref Advanced 88943bbe138SJeremy L Thompson **/ 89043bbe138SJeremy L Thompson int CeedOperatorFieldGetBasis(CeedOperatorField op_field, CeedBasis *basis) { 89143bbe138SJeremy L Thompson *basis = op_field->basis; 89243bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 89343bbe138SJeremy L Thompson } 89443bbe138SJeremy L Thompson 89543bbe138SJeremy L Thompson /** 89643bbe138SJeremy L Thompson @brief Get the CeedVector of a CeedOperatorField 89743bbe138SJeremy L Thompson 89843bbe138SJeremy L Thompson @param op_field CeedOperatorField 89943bbe138SJeremy L Thompson @param[out] vec Variable to store CeedVector 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 CeedOperatorFieldGetVector(CeedOperatorField op_field, CeedVector *vec) { 90643bbe138SJeremy L Thompson *vec = op_field->vec; 90743bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 90843bbe138SJeremy L Thompson } 90943bbe138SJeremy L Thompson 91043bbe138SJeremy L Thompson /** 91152d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 912288c0443SJeremy L Thompson 913d1d35e2fSjeremylt @param[out] composite_op Composite CeedOperator 914d1d35e2fSjeremylt @param sub_op Sub-operator CeedOperator 91552d6035fSJeremy L Thompson 91652d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 91752d6035fSJeremy L Thompson 9187a982d89SJeremy L. Thompson @ref User 91952d6035fSJeremy L Thompson */ 920d1d35e2fSjeremylt int CeedCompositeOperatorAddSub(CeedOperator composite_op, 921d1d35e2fSjeremylt CeedOperator sub_op) { 92234359f16Sjeremylt int ierr; 92334359f16Sjeremylt 924f04ea552SJeremy L Thompson if (!composite_op->is_composite) 925c042f62fSJeremy L Thompson // LCOV_EXCL_START 926d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_MINOR, 927e2f04181SAndrew T. Barker "CeedOperator is not a composite operator"); 928c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 92952d6035fSJeremy L Thompson 930d1d35e2fSjeremylt if (composite_op->num_suboperators == CEED_COMPOSITE_MAX) 931c042f62fSJeremy L Thompson // LCOV_EXCL_START 932d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_UNSUPPORTED, 9332b104005SJeremy L Thompson "Cannot add additional sub-operators"); 934c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 935f04ea552SJeremy L Thompson if (composite_op->is_immutable) 936f04ea552SJeremy L Thompson // LCOV_EXCL_START 937f04ea552SJeremy L Thompson return CeedError(composite_op->ceed, CEED_ERROR_MAJOR, 938f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 939f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 94052d6035fSJeremy L Thompson 9412b104005SJeremy L Thompson { 9422b104005SJeremy L Thompson CeedSize input_size, output_size; 9432b104005SJeremy L Thompson ierr = CeedOperatorGetActiveVectorLengths(sub_op, &input_size, &output_size); 9442b104005SJeremy L Thompson CeedChk(ierr); 9452b104005SJeremy L Thompson if (composite_op->input_size == -1) composite_op->input_size = input_size; 9462b104005SJeremy L Thompson if (composite_op->output_size == -1) composite_op->output_size = output_size; 9472b104005SJeremy L Thompson // Note, a size of -1 means no active vector restriction set, so no incompatibility 9482b104005SJeremy L Thompson if ((input_size != -1 && input_size != composite_op->input_size) || 9492b104005SJeremy L Thompson (output_size != -1 && output_size != composite_op->output_size)) 9502b104005SJeremy L Thompson // LCOV_EXCL_START 9512b104005SJeremy L Thompson return CeedError(composite_op->ceed, CEED_ERROR_MAJOR, 9522b104005SJeremy L Thompson "Sub-operators must have compatible dimensions; " 9532b104005SJeremy L Thompson "composite operator of shape (%td, %td) not compatible with " 9542b104005SJeremy L Thompson "sub-operator of shape (%td, %td)", 9552b104005SJeremy L Thompson composite_op->input_size, composite_op->output_size, input_size, output_size); 9562b104005SJeremy L Thompson // LCOV_EXCL_STOP 9572b104005SJeremy L Thompson } 9582b104005SJeremy L Thompson 959d1d35e2fSjeremylt composite_op->sub_operators[composite_op->num_suboperators] = sub_op; 9609560d06aSjeremylt ierr = CeedOperatorReference(sub_op); CeedChk(ierr); 961d1d35e2fSjeremylt composite_op->num_suboperators++; 962e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 96352d6035fSJeremy L Thompson } 96452d6035fSJeremy L Thompson 96552d6035fSJeremy L Thompson /** 9664db537f9SJeremy L Thompson @brief Check if a CeedOperator is ready to be used. 9674db537f9SJeremy L Thompson 9684db537f9SJeremy L Thompson @param[in] op CeedOperator to check 9694db537f9SJeremy L Thompson 9704db537f9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 9714db537f9SJeremy L Thompson 9724db537f9SJeremy L Thompson @ref User 9734db537f9SJeremy L Thompson **/ 9744db537f9SJeremy L Thompson int CeedOperatorCheckReady(CeedOperator op) { 9754db537f9SJeremy L Thompson int ierr; 9764db537f9SJeremy L Thompson Ceed ceed; 9774db537f9SJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 9784db537f9SJeremy L Thompson 9794db537f9SJeremy L Thompson if (op->is_interface_setup) 9804db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 9814db537f9SJeremy L Thompson 9824db537f9SJeremy L Thompson CeedQFunction qf = op->qf; 9834db537f9SJeremy L Thompson if (op->is_composite) { 9844db537f9SJeremy L Thompson if (!op->num_suboperators) 9854db537f9SJeremy L Thompson // LCOV_EXCL_START 9864db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "No sub_operators set"); 9874db537f9SJeremy L Thompson // LCOV_EXCL_STOP 9884db537f9SJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 9894db537f9SJeremy L Thompson ierr = CeedOperatorCheckReady(op->sub_operators[i]); CeedChk(ierr); 9904db537f9SJeremy L Thompson } 9912b104005SJeremy L Thompson // Sub-operators could be modified after adding to composite operator 9922b104005SJeremy L Thompson // Need to verify no lvec incompatibility from any changes 9932b104005SJeremy L Thompson CeedSize input_size, output_size; 9942b104005SJeremy L Thompson ierr = CeedOperatorGetActiveVectorLengths(op, &input_size, &output_size); 9952b104005SJeremy L Thompson CeedChk(ierr); 9964db537f9SJeremy L Thompson } else { 9974db537f9SJeremy L Thompson if (op->num_fields == 0) 9984db537f9SJeremy L Thompson // LCOV_EXCL_START 9994db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "No operator fields set"); 10004db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10014db537f9SJeremy L Thompson if (op->num_fields < qf->num_input_fields + qf->num_output_fields) 10024db537f9SJeremy L Thompson // LCOV_EXCL_START 10034db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "Not all operator fields set"); 10044db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10054db537f9SJeremy L Thompson if (!op->has_restriction) 10064db537f9SJeremy L Thompson // LCOV_EXCL_START 10074db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, 10084db537f9SJeremy L Thompson "At least one restriction required"); 10094db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10104db537f9SJeremy L Thompson if (op->num_qpts == 0) 10114db537f9SJeremy L Thompson // LCOV_EXCL_START 10124db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, 10134db537f9SJeremy L Thompson "At least one non-collocated basis is required " 10144db537f9SJeremy L Thompson "or the number of quadrature points must be set"); 10154db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10164db537f9SJeremy L Thompson } 10174db537f9SJeremy L Thompson 10184db537f9SJeremy L Thompson // Flag as immutable and ready 10194db537f9SJeremy L Thompson op->is_interface_setup = true; 10204db537f9SJeremy L Thompson if (op->qf && op->qf != CEED_QFUNCTION_NONE) 10214db537f9SJeremy L Thompson // LCOV_EXCL_START 10224db537f9SJeremy L Thompson op->qf->is_immutable = true; 10234db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10244db537f9SJeremy L Thompson if (op->dqf && op->dqf != CEED_QFUNCTION_NONE) 10254db537f9SJeremy L Thompson // LCOV_EXCL_START 10264db537f9SJeremy L Thompson op->dqf->is_immutable = true; 10274db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10284db537f9SJeremy L Thompson if (op->dqfT && op->dqfT != CEED_QFUNCTION_NONE) 10294db537f9SJeremy L Thompson // LCOV_EXCL_START 10304db537f9SJeremy L Thompson op->dqfT->is_immutable = true; 10314db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10324db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 10334db537f9SJeremy L Thompson } 10344db537f9SJeremy L Thompson 10354db537f9SJeremy L Thompson /** 1036c9366a6bSJeremy L Thompson @brief Get vector lengths for the active input and/or output vectors of a CeedOperator. 1037c9366a6bSJeremy L Thompson Note: Lengths of -1 indicate that the CeedOperator does not have an 1038c9366a6bSJeremy L Thompson active input and/or output. 1039c9366a6bSJeremy L Thompson 1040c9366a6bSJeremy L Thompson @param[in] op CeedOperator 1041c9366a6bSJeremy L Thompson @param[out] input_size Variable to store active input vector length, or NULL 1042c9366a6bSJeremy L Thompson @param[out] output_size Variable to store active output vector length, or NULL 1043c9366a6bSJeremy L Thompson 1044c9366a6bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1045c9366a6bSJeremy L Thompson 1046c9366a6bSJeremy L Thompson @ref User 1047c9366a6bSJeremy L Thompson **/ 1048c9366a6bSJeremy L Thompson int CeedOperatorGetActiveVectorLengths(CeedOperator op, CeedSize *input_size, 1049c9366a6bSJeremy L Thompson CeedSize *output_size) { 1050c9366a6bSJeremy L Thompson int ierr; 1051c9366a6bSJeremy L Thompson bool is_composite; 1052c9366a6bSJeremy L Thompson 10532b104005SJeremy L Thompson if (input_size) *input_size = op->input_size; 10542b104005SJeremy L Thompson if (output_size) *output_size = op->output_size; 1055c9366a6bSJeremy L Thompson 1056c9366a6bSJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 10572b104005SJeremy L Thompson if (is_composite && (op->input_size == -1 || op->output_size == -1)) { 1058c9366a6bSJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 1059c9366a6bSJeremy L Thompson CeedSize sub_input_size, sub_output_size; 1060c9366a6bSJeremy L Thompson ierr = CeedOperatorGetActiveVectorLengths(op->sub_operators[i], 10612b104005SJeremy L Thompson &sub_input_size, &sub_output_size); CeedChk(ierr); 10622b104005SJeremy L Thompson if (op->input_size == -1) op->input_size = sub_input_size; 10632b104005SJeremy L Thompson if (op->output_size == -1) op->output_size = sub_output_size; 10642b104005SJeremy L Thompson // Note, a size of -1 means no active vector restriction set, so no incompatibility 10652b104005SJeremy L Thompson if ((sub_input_size != -1 && sub_input_size != op->input_size) || 10662b104005SJeremy L Thompson (sub_output_size != -1 && sub_output_size != op->output_size)) 10672b104005SJeremy L Thompson // LCOV_EXCL_START 10682b104005SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 10692b104005SJeremy L Thompson "Sub-operators must have compatible dimensions; " 10702b104005SJeremy L Thompson "composite operator of shape (%td, %td) not compatible with " 10712b104005SJeremy L Thompson "sub-operator of shape (%td, %td)", 10722b104005SJeremy L Thompson op->input_size, op->output_size, input_size, output_size); 10732b104005SJeremy L Thompson // LCOV_EXCL_STOP 1074c9366a6bSJeremy L Thompson } 1075c9366a6bSJeremy L Thompson } 1076c9366a6bSJeremy L Thompson 1077c9366a6bSJeremy L Thompson return CEED_ERROR_SUCCESS; 1078c9366a6bSJeremy L Thompson } 1079c9366a6bSJeremy L Thompson 1080c9366a6bSJeremy L Thompson /** 1081beecbf24SJeremy L Thompson @brief Set reuse of CeedQFunction data in CeedOperatorLinearAssemble* functions. 1082beecbf24SJeremy L Thompson When `reuse_assembly_data = false` (default), the CeedQFunction associated 1083beecbf24SJeremy L Thompson with this CeedOperator is re-assembled every time a `CeedOperatorLinearAssemble*` 1084beecbf24SJeremy L Thompson function is called. 1085beecbf24SJeremy L Thompson When `reuse_assembly_data = true`, the CeedQFunction associated with 1086beecbf24SJeremy L Thompson this CeedOperator is reused between calls to 1087beecbf24SJeremy L Thompson `CeedOperatorSetQFunctionAssemblyDataUpdated`. 10888b919e6bSJeremy L Thompson 1089beecbf24SJeremy L Thompson @param[in] op CeedOperator 1090beecbf24SJeremy L Thompson @param[in] reuse_assembly_data Boolean flag setting assembly data reuse 10918b919e6bSJeremy L Thompson 10928b919e6bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 10938b919e6bSJeremy L Thompson 10948b919e6bSJeremy L Thompson @ref Advanced 10958b919e6bSJeremy L Thompson **/ 1096beecbf24SJeremy L Thompson int CeedOperatorSetQFunctionAssemblyReuse(CeedOperator op, 1097beecbf24SJeremy L Thompson bool reuse_assembly_data) { 10988b919e6bSJeremy L Thompson int ierr; 10998b919e6bSJeremy L Thompson bool is_composite; 11008b919e6bSJeremy L Thompson 11018b919e6bSJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 11028b919e6bSJeremy L Thompson if (is_composite) { 11038b919e6bSJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 1104beecbf24SJeremy L Thompson ierr = CeedOperatorSetQFunctionAssemblyReuse(op->sub_operators[i], 1105beecbf24SJeremy L Thompson reuse_assembly_data); CeedChk(ierr); 11068b919e6bSJeremy L Thompson } 11078b919e6bSJeremy L Thompson } else { 1108beecbf24SJeremy L Thompson ierr = CeedQFunctionAssemblyDataSetReuse(op->qf_assembled, reuse_assembly_data); 1109beecbf24SJeremy L Thompson CeedChk(ierr); 1110beecbf24SJeremy L Thompson } 1111beecbf24SJeremy L Thompson 1112beecbf24SJeremy L Thompson return CEED_ERROR_SUCCESS; 1113beecbf24SJeremy L Thompson } 1114beecbf24SJeremy L Thompson 1115beecbf24SJeremy L Thompson /** 1116beecbf24SJeremy L Thompson @brief Mark CeedQFunction data as updated and the CeedQFunction as requiring re-assembly. 1117beecbf24SJeremy L Thompson 1118beecbf24SJeremy L Thompson @param[in] op CeedOperator 11196e15d496SJeremy L Thompson @param[in] needs_data_update Boolean flag setting assembly data reuse 1120beecbf24SJeremy L Thompson 1121beecbf24SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1122beecbf24SJeremy L Thompson 1123beecbf24SJeremy L Thompson @ref Advanced 1124beecbf24SJeremy L Thompson **/ 1125beecbf24SJeremy L Thompson int CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(CeedOperator op, 1126beecbf24SJeremy L Thompson bool needs_data_update) { 1127beecbf24SJeremy L Thompson int ierr; 1128beecbf24SJeremy L Thompson bool is_composite; 1129beecbf24SJeremy L Thompson 1130beecbf24SJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 1131beecbf24SJeremy L Thompson if (is_composite) { 1132beecbf24SJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 1133beecbf24SJeremy L Thompson ierr = CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(op->sub_operators[i], 1134beecbf24SJeremy L Thompson needs_data_update); CeedChk(ierr); 1135beecbf24SJeremy L Thompson } 1136beecbf24SJeremy L Thompson } else { 1137beecbf24SJeremy L Thompson ierr = CeedQFunctionAssemblyDataSetUpdateNeeded(op->qf_assembled, 1138beecbf24SJeremy L Thompson needs_data_update); 11398b919e6bSJeremy L Thompson CeedChk(ierr); 11408b919e6bSJeremy L Thompson } 11418b919e6bSJeremy L Thompson 11428b919e6bSJeremy L Thompson return CEED_ERROR_SUCCESS; 11438b919e6bSJeremy L Thompson } 11448b919e6bSJeremy L Thompson 11458b919e6bSJeremy L Thompson /** 1146cd4dfc48Sjeremylt @brief Set the number of quadrature points associated with a CeedOperator. 1147cd4dfc48Sjeremylt This should be used when creating a CeedOperator where every 1148cd4dfc48Sjeremylt field has a collocated basis. This function cannot be used for 1149cd4dfc48Sjeremylt composite CeedOperators. 1150cd4dfc48Sjeremylt 1151cd4dfc48Sjeremylt @param op CeedOperator 1152cd4dfc48Sjeremylt @param num_qpts Number of quadrature points to set 1153cd4dfc48Sjeremylt 1154cd4dfc48Sjeremylt @return An error code: 0 - success, otherwise - failure 1155cd4dfc48Sjeremylt 1156e9b533fbSJeremy L Thompson @ref Advanced 1157cd4dfc48Sjeremylt **/ 1158cd4dfc48Sjeremylt int CeedOperatorSetNumQuadraturePoints(CeedOperator op, CeedInt num_qpts) { 1159f04ea552SJeremy L Thompson if (op->is_composite) 1160cd4dfc48Sjeremylt // LCOV_EXCL_START 1161cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 1162cd4dfc48Sjeremylt "Not defined for composite operator"); 1163cd4dfc48Sjeremylt // LCOV_EXCL_STOP 1164cd4dfc48Sjeremylt if (op->num_qpts) 1165cd4dfc48Sjeremylt // LCOV_EXCL_START 1166cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 1167cd4dfc48Sjeremylt "Number of quadrature points already defined"); 1168cd4dfc48Sjeremylt // LCOV_EXCL_STOP 1169f04ea552SJeremy L Thompson if (op->is_immutable) 1170f04ea552SJeremy L Thompson // LCOV_EXCL_START 1171f04ea552SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 1172f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 1173f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 1174cd4dfc48Sjeremylt 1175cd4dfc48Sjeremylt op->num_qpts = num_qpts; 1176cd4dfc48Sjeremylt return CEED_ERROR_SUCCESS; 1177cd4dfc48Sjeremylt } 1178cd4dfc48Sjeremylt 1179cd4dfc48Sjeremylt /** 1180ea6b5821SJeremy L Thompson @brief Set name of CeedOperator for CeedOperatorView output 1181ea6b5821SJeremy L Thompson 1182ea6b5821SJeremy L Thompson @param op CeedOperator 1183ea6b5821SJeremy L Thompson @param name Name to set, or NULL to remove previously set name 1184ea6b5821SJeremy L Thompson 1185ea6b5821SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1186ea6b5821SJeremy L Thompson 1187ea6b5821SJeremy L Thompson @ref User 1188ea6b5821SJeremy L Thompson **/ 1189ea6b5821SJeremy L Thompson int CeedOperatorSetName(CeedOperator op, const char *name) { 1190ea6b5821SJeremy L Thompson int ierr; 1191ea6b5821SJeremy L Thompson char *name_copy; 1192ea6b5821SJeremy L Thompson size_t name_len = name ? strlen(name) : 0; 1193ea6b5821SJeremy L Thompson 1194ea6b5821SJeremy L Thompson ierr = CeedFree(&op->name); CeedChk(ierr); 1195ea6b5821SJeremy L Thompson if (name_len > 0) { 1196ea6b5821SJeremy L Thompson ierr = CeedCalloc(name_len + 1, &name_copy); CeedChk(ierr); 1197ea6b5821SJeremy L Thompson memcpy(name_copy, name, name_len); 1198ea6b5821SJeremy L Thompson op->name = name_copy; 1199ea6b5821SJeremy L Thompson } 1200ea6b5821SJeremy L Thompson 1201ea6b5821SJeremy L Thompson return CEED_ERROR_SUCCESS; 1202ea6b5821SJeremy L Thompson } 1203ea6b5821SJeremy L Thompson 1204ea6b5821SJeremy L Thompson /** 12057a982d89SJeremy L. Thompson @brief View a CeedOperator 12067a982d89SJeremy L. Thompson 12077a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 12087a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 12097a982d89SJeremy L. Thompson 12107a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 12117a982d89SJeremy L. Thompson 12127a982d89SJeremy L. Thompson @ref User 12137a982d89SJeremy L. Thompson **/ 12147a982d89SJeremy L. Thompson int CeedOperatorView(CeedOperator op, FILE *stream) { 12157a982d89SJeremy L. Thompson int ierr; 1216ea6b5821SJeremy L Thompson bool has_name = op->name; 12177a982d89SJeremy L. Thompson 1218f04ea552SJeremy L Thompson if (op->is_composite) { 1219ea6b5821SJeremy L Thompson fprintf(stream, "Composite CeedOperator%s%s\n", 1220ea6b5821SJeremy L Thompson has_name ? " - " : "", has_name ? op->name : ""); 12217a982d89SJeremy L. Thompson 1222d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 1223ea6b5821SJeremy L Thompson has_name = op->sub_operators[i]->name; 1224ea6b5821SJeremy L Thompson fprintf(stream, " SubOperator %d%s%s:\n", i, 1225ea6b5821SJeremy L Thompson has_name ? " - " : "", 1226ea6b5821SJeremy L Thompson has_name ? op->sub_operators[i]->name : ""); 1227d1d35e2fSjeremylt ierr = CeedOperatorSingleView(op->sub_operators[i], 1, stream); 12287a982d89SJeremy L. Thompson CeedChk(ierr); 12297a982d89SJeremy L. Thompson } 12307a982d89SJeremy L. Thompson } else { 1231ea6b5821SJeremy L Thompson fprintf(stream, "CeedOperator%s%s\n", 1232ea6b5821SJeremy L Thompson has_name ? " - " : "", has_name ? op->name : ""); 12337a982d89SJeremy L. Thompson ierr = CeedOperatorSingleView(op, 0, stream); CeedChk(ierr); 12347a982d89SJeremy L. Thompson } 1235e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 12367a982d89SJeremy L. Thompson } 12373bd813ffSjeremylt 12383bd813ffSjeremylt /** 1239b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedOperator 1240b7c9bbdaSJeremy L Thompson 1241b7c9bbdaSJeremy L Thompson @param op CeedOperator 1242b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 1243b7c9bbdaSJeremy L Thompson 1244b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1245b7c9bbdaSJeremy L Thompson 1246b7c9bbdaSJeremy L Thompson @ref Advanced 1247b7c9bbdaSJeremy L Thompson **/ 1248b7c9bbdaSJeremy L Thompson int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 1249b7c9bbdaSJeremy L Thompson *ceed = op->ceed; 1250b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1251b7c9bbdaSJeremy L Thompson } 1252b7c9bbdaSJeremy L Thompson 1253b7c9bbdaSJeremy L Thompson /** 1254b7c9bbdaSJeremy L Thompson @brief Get the number of elements associated with a CeedOperator 1255b7c9bbdaSJeremy L Thompson 1256b7c9bbdaSJeremy L Thompson @param op CeedOperator 1257b7c9bbdaSJeremy L Thompson @param[out] num_elem Variable to store number of elements 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 CeedOperatorGetNumElements(CeedOperator op, CeedInt *num_elem) { 1264b7c9bbdaSJeremy L Thompson if (op->is_composite) 1265b7c9bbdaSJeremy L Thompson // LCOV_EXCL_START 1266b7c9bbdaSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 1267b7c9bbdaSJeremy L Thompson "Not defined for composite operator"); 1268b7c9bbdaSJeremy L Thompson // LCOV_EXCL_STOP 1269b7c9bbdaSJeremy L Thompson 1270b7c9bbdaSJeremy L Thompson *num_elem = op->num_elem; 1271b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1272b7c9bbdaSJeremy L Thompson } 1273b7c9bbdaSJeremy L Thompson 1274b7c9bbdaSJeremy L Thompson /** 1275b7c9bbdaSJeremy L Thompson @brief Get the number of quadrature points associated with a CeedOperator 1276b7c9bbdaSJeremy L Thompson 1277b7c9bbdaSJeremy L Thompson @param op CeedOperator 1278b7c9bbdaSJeremy L Thompson @param[out] num_qpts Variable to store vector number of quadrature points 1279b7c9bbdaSJeremy L Thompson 1280b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1281b7c9bbdaSJeremy L Thompson 1282b7c9bbdaSJeremy L Thompson @ref Advanced 1283b7c9bbdaSJeremy L Thompson **/ 1284b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *num_qpts) { 1285b7c9bbdaSJeremy L Thompson if (op->is_composite) 1286b7c9bbdaSJeremy L Thompson // LCOV_EXCL_START 1287b7c9bbdaSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 1288b7c9bbdaSJeremy L Thompson "Not defined for composite operator"); 1289b7c9bbdaSJeremy L Thompson // LCOV_EXCL_STOP 1290b7c9bbdaSJeremy L Thompson 1291b7c9bbdaSJeremy L Thompson *num_qpts = op->num_qpts; 1292b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1293b7c9bbdaSJeremy L Thompson } 1294b7c9bbdaSJeremy L Thompson 1295b7c9bbdaSJeremy L Thompson /** 12966e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedOperator on the active vector 12976e15d496SJeremy L Thompson 12986e15d496SJeremy L Thompson @param op Operator to estimate FLOPs for 12996e15d496SJeremy L Thompson @param flops Address of variable to hold FLOPs estimate 13006e15d496SJeremy L Thompson 13016e15d496SJeremy L Thompson @ref Backend 13026e15d496SJeremy L Thompson **/ 13039d36ca50SJeremy L Thompson int CeedOperatorGetFlopsEstimate(CeedOperator op, CeedSize *flops) { 13046e15d496SJeremy L Thompson int ierr; 13056e15d496SJeremy L Thompson bool is_composite; 13066e15d496SJeremy L Thompson ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 13076e15d496SJeremy L Thompson 13086e15d496SJeremy L Thompson *flops = 0; 13096e15d496SJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 13106e15d496SJeremy L Thompson if (is_composite) { 13116e15d496SJeremy L Thompson CeedInt num_suboperators; 13126e15d496SJeremy L Thompson ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 13136e15d496SJeremy L Thompson CeedOperator *sub_operators; 13146e15d496SJeremy L Thompson ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 13156e15d496SJeremy L Thompson 13166e15d496SJeremy L Thompson // FLOPs for each suboperator 13176e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_suboperators; i++) { 13189d36ca50SJeremy L Thompson CeedSize suboperator_flops; 13196e15d496SJeremy L Thompson ierr = CeedOperatorGetFlopsEstimate(sub_operators[i], &suboperator_flops); 13206e15d496SJeremy L Thompson CeedChk(ierr); 13216e15d496SJeremy L Thompson *flops += suboperator_flops; 13226e15d496SJeremy L Thompson } 13236e15d496SJeremy L Thompson } else { 13246e15d496SJeremy L Thompson CeedInt num_input_fields, num_output_fields; 13256e15d496SJeremy L Thompson CeedOperatorField *input_fields, *output_fields; 13266e15d496SJeremy L Thompson 13276e15d496SJeremy L Thompson ierr = CeedOperatorGetFields(op, &num_input_fields, &input_fields, 13286e15d496SJeremy L Thompson &num_output_fields, &output_fields); CeedChk(ierr); 13296e15d496SJeremy L Thompson 13306e15d496SJeremy L Thompson CeedInt num_elem = 0; 13316e15d496SJeremy L Thompson ierr = CeedOperatorGetNumElements(op, &num_elem); CeedChk(ierr); 13326e15d496SJeremy L Thompson // Input FLOPs 13336e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_input_fields; i++) { 13346e15d496SJeremy L Thompson if (input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 13359d36ca50SJeremy L Thompson CeedSize restr_flops, basis_flops; 13366e15d496SJeremy L Thompson 13376e15d496SJeremy L Thompson ierr = CeedElemRestrictionGetFlopsEstimate(input_fields[i]->elem_restr, 13386e15d496SJeremy L Thompson CEED_NOTRANSPOSE, &restr_flops); CeedChk(ierr); 13396e15d496SJeremy L Thompson *flops += restr_flops; 13406e15d496SJeremy L Thompson ierr = CeedBasisGetFlopsEstimate(input_fields[i]->basis, CEED_NOTRANSPOSE, 13416e15d496SJeremy L Thompson op->qf->input_fields[i]->eval_mode, &basis_flops); CeedChk(ierr); 13426e15d496SJeremy L Thompson *flops += basis_flops * num_elem; 13436e15d496SJeremy L Thompson } 13446e15d496SJeremy L Thompson } 13456e15d496SJeremy L Thompson // QF FLOPs 13469d36ca50SJeremy L Thompson CeedInt num_qpts; 13479d36ca50SJeremy L Thompson CeedSize qf_flops; 13486e15d496SJeremy L Thompson ierr = CeedOperatorGetNumQuadraturePoints(op, &num_qpts); CeedChk(ierr); 13496e15d496SJeremy L Thompson ierr = CeedQFunctionGetFlopsEstimate(op->qf, &qf_flops); CeedChk(ierr); 13506e15d496SJeremy L Thompson *flops += num_elem * num_qpts * qf_flops; 13516e15d496SJeremy L Thompson // Output FLOPs 13526e15d496SJeremy L Thompson for (CeedInt i = 0; i < num_output_fields; i++) { 13536e15d496SJeremy L Thompson if (output_fields[i]->vec == CEED_VECTOR_ACTIVE) { 13549d36ca50SJeremy L Thompson CeedSize restr_flops, basis_flops; 13556e15d496SJeremy L Thompson 13566e15d496SJeremy L Thompson ierr = CeedElemRestrictionGetFlopsEstimate(output_fields[i]->elem_restr, 13576e15d496SJeremy L Thompson CEED_TRANSPOSE, &restr_flops); CeedChk(ierr); 13586e15d496SJeremy L Thompson *flops += restr_flops; 13596e15d496SJeremy L Thompson ierr = CeedBasisGetFlopsEstimate(output_fields[i]->basis, CEED_TRANSPOSE, 13606e15d496SJeremy L Thompson op->qf->output_fields[i]->eval_mode, &basis_flops); CeedChk(ierr); 13616e15d496SJeremy L Thompson *flops += basis_flops * num_elem; 13626e15d496SJeremy L Thompson } 13636e15d496SJeremy L Thompson } 13646e15d496SJeremy L Thompson } 13656e15d496SJeremy L Thompson 13666e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 13676e15d496SJeremy L Thompson } 13686e15d496SJeremy L Thompson 13696e15d496SJeremy L Thompson /** 13703668ca4bSJeremy L Thompson @brief Get label for a registered QFunctionContext field, or `NULL` if no 13713668ca4bSJeremy L Thompson field has been registered with this `field_name`. 13723668ca4bSJeremy L Thompson 13733668ca4bSJeremy L Thompson @param[in] op CeedOperator 13743668ca4bSJeremy L Thompson @param[in] field_name Name of field to retrieve label 13753668ca4bSJeremy L Thompson @param[out] field_label Variable to field label 13763668ca4bSJeremy L Thompson 13773668ca4bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 13783668ca4bSJeremy L Thompson 13793668ca4bSJeremy L Thompson @ref User 13803668ca4bSJeremy L Thompson **/ 13813668ca4bSJeremy L Thompson int CeedOperatorContextGetFieldLabel(CeedOperator op, 13823668ca4bSJeremy L Thompson const char *field_name, 13833668ca4bSJeremy L Thompson CeedContextFieldLabel *field_label) { 13843668ca4bSJeremy L Thompson int ierr; 13853668ca4bSJeremy L Thompson 13863668ca4bSJeremy L Thompson bool is_composite; 13873668ca4bSJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 13883668ca4bSJeremy L Thompson if (is_composite) { 13893668ca4bSJeremy L Thompson // Check if composite label already created 13903668ca4bSJeremy L Thompson for (CeedInt i=0; i<op->num_context_labels; i++) { 13913668ca4bSJeremy L Thompson if (!strcmp(op->context_labels[i]->name, field_name)) { 13923668ca4bSJeremy L Thompson *field_label = op->context_labels[i]; 13933668ca4bSJeremy L Thompson return CEED_ERROR_SUCCESS; 13943668ca4bSJeremy L Thompson } 13953668ca4bSJeremy L Thompson } 13963668ca4bSJeremy L Thompson 13973668ca4bSJeremy L Thompson // Create composite label if needed 13983668ca4bSJeremy L Thompson CeedInt num_sub; 13993668ca4bSJeremy L Thompson CeedOperator *sub_operators; 14003668ca4bSJeremy L Thompson CeedContextFieldLabel new_field_label; 14013668ca4bSJeremy L Thompson 14023668ca4bSJeremy L Thompson ierr = CeedCalloc(1, &new_field_label); CeedChk(ierr); 14033668ca4bSJeremy L Thompson ierr = CeedOperatorGetNumSub(op, &num_sub); CeedChk(ierr); 14043668ca4bSJeremy L Thompson ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 14053668ca4bSJeremy L Thompson ierr = CeedCalloc(num_sub, &new_field_label->sub_labels); CeedChk(ierr); 14063668ca4bSJeremy L Thompson new_field_label->num_sub_labels = num_sub; 14073668ca4bSJeremy L Thompson 14083668ca4bSJeremy L Thompson bool label_found = false; 14093668ca4bSJeremy L Thompson for (CeedInt i=0; i<num_sub; i++) { 14103668ca4bSJeremy L Thompson if (sub_operators[i]->qf->ctx) { 14113668ca4bSJeremy L Thompson CeedContextFieldLabel new_field_label_i; 14123668ca4bSJeremy L Thompson ierr = CeedQFunctionContextGetFieldLabel(sub_operators[i]->qf->ctx, field_name, 14133668ca4bSJeremy L Thompson &new_field_label_i); CeedChk(ierr); 14143668ca4bSJeremy L Thompson if (new_field_label_i) { 14153668ca4bSJeremy L Thompson label_found = true; 14163668ca4bSJeremy L Thompson new_field_label->sub_labels[i] = new_field_label_i; 14173668ca4bSJeremy L Thompson new_field_label->name = new_field_label_i->name; 14183668ca4bSJeremy L Thompson new_field_label->description = new_field_label_i->description; 14197bfe0f0eSJeremy L Thompson if (new_field_label->type && 14207bfe0f0eSJeremy L Thompson new_field_label->type != new_field_label_i->type) { 14217bfe0f0eSJeremy L Thompson // LCOV_EXCL_START 14227bfe0f0eSJeremy L Thompson ierr = CeedFree(&new_field_label); CeedChk(ierr); 14237bfe0f0eSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 14247bfe0f0eSJeremy L Thompson "Incompatible field types on sub-operator contexts. " 14257bfe0f0eSJeremy L Thompson "%s != %s", 14267bfe0f0eSJeremy L Thompson CeedContextFieldTypes[new_field_label->type], 14277bfe0f0eSJeremy L Thompson CeedContextFieldTypes[new_field_label_i->type]); 14287bfe0f0eSJeremy L Thompson // LCOV_EXCL_STOP 14297bfe0f0eSJeremy L Thompson } else { 14307bfe0f0eSJeremy L Thompson new_field_label->type = new_field_label_i->type; 14317bfe0f0eSJeremy L Thompson } 14327bfe0f0eSJeremy L Thompson if (new_field_label->num_values != 0 && 14337bfe0f0eSJeremy L Thompson new_field_label->num_values != new_field_label_i->num_values) { 14347bfe0f0eSJeremy L Thompson // LCOV_EXCL_START 14357bfe0f0eSJeremy L Thompson ierr = CeedFree(&new_field_label); CeedChk(ierr); 14367bfe0f0eSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 14377bfe0f0eSJeremy L Thompson "Incompatible field number of values on sub-operator" 14387bfe0f0eSJeremy L Thompson " contexts. %ld != %ld", 14397bfe0f0eSJeremy L Thompson new_field_label->num_values, new_field_label_i->num_values); 14407bfe0f0eSJeremy L Thompson // LCOV_EXCL_STOP 14417bfe0f0eSJeremy L Thompson } else { 14427bfe0f0eSJeremy L Thompson new_field_label->num_values = new_field_label_i->num_values; 14437bfe0f0eSJeremy L Thompson } 14443668ca4bSJeremy L Thompson } 14453668ca4bSJeremy L Thompson } 14463668ca4bSJeremy L Thompson } 14473668ca4bSJeremy L Thompson if (!label_found) { 14483668ca4bSJeremy L Thompson // LCOV_EXCL_START 1449a48e5f43SJeremy L Thompson ierr = CeedFree(&new_field_label->sub_labels); CeedChk(ierr); 14503668ca4bSJeremy L Thompson ierr = CeedFree(&new_field_label); CeedChk(ierr); 14513668ca4bSJeremy L Thompson *field_label = NULL; 14523668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 14533668ca4bSJeremy L Thompson } else { 14543668ca4bSJeremy L Thompson // Move new composite label to operator 14553668ca4bSJeremy L Thompson if (op->num_context_labels == 0) { 14563668ca4bSJeremy L Thompson ierr = CeedCalloc(1, &op->context_labels); CeedChk(ierr); 14573668ca4bSJeremy L Thompson op->max_context_labels = 1; 14583668ca4bSJeremy L Thompson } else if (op->num_context_labels == op->max_context_labels) { 14593668ca4bSJeremy L Thompson ierr = CeedRealloc(2*op->num_context_labels, &op->context_labels); 14603668ca4bSJeremy L Thompson CeedChk(ierr); 14613668ca4bSJeremy L Thompson op->max_context_labels *= 2; 14623668ca4bSJeremy L Thompson } 14633668ca4bSJeremy L Thompson op->context_labels[op->num_context_labels] = new_field_label; 14643668ca4bSJeremy L Thompson *field_label = new_field_label; 14653668ca4bSJeremy L Thompson op->num_context_labels++; 14663668ca4bSJeremy L Thompson } 14673668ca4bSJeremy L Thompson 14683668ca4bSJeremy L Thompson return CEED_ERROR_SUCCESS; 14693668ca4bSJeremy L Thompson } else { 14703668ca4bSJeremy L Thompson return CeedQFunctionContextGetFieldLabel(op->qf->ctx, field_name, field_label); 14713668ca4bSJeremy L Thompson } 14723668ca4bSJeremy L Thompson } 14733668ca4bSJeremy L Thompson 14743668ca4bSJeremy L Thompson /** 1475d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field holding a double precision value. 1476d8dd9a91SJeremy L Thompson For composite operators, the value is set in all 1477d8dd9a91SJeremy L Thompson sub-operator QFunctionContexts that have a matching `field_name`. 1478d8dd9a91SJeremy L Thompson 1479d8dd9a91SJeremy L Thompson @param op CeedOperator 14803668ca4bSJeremy L Thompson @param field_label Label of field to register 14817bfe0f0eSJeremy L Thompson @param values Values to set 1482d8dd9a91SJeremy L Thompson 1483d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1484d8dd9a91SJeremy L Thompson 1485d8dd9a91SJeremy L Thompson @ref User 1486d8dd9a91SJeremy L Thompson **/ 14873668ca4bSJeremy L Thompson int CeedOperatorContextSetDouble(CeedOperator op, 14883668ca4bSJeremy L Thompson CeedContextFieldLabel field_label, 14897bfe0f0eSJeremy L Thompson double *values) { 14903668ca4bSJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_DOUBLE, 14917bfe0f0eSJeremy L Thompson values); 1492d8dd9a91SJeremy L Thompson } 1493d8dd9a91SJeremy L Thompson 1494d8dd9a91SJeremy L Thompson /** 1495d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field holding an int32 value. 1496d8dd9a91SJeremy L Thompson For composite operators, the value is set in all 1497d8dd9a91SJeremy L Thompson sub-operator QFunctionContexts that have a matching `field_name`. 1498d8dd9a91SJeremy L Thompson 1499d8dd9a91SJeremy L Thompson @param op CeedOperator 15003668ca4bSJeremy L Thompson @param field_label Label of field to set 15017bfe0f0eSJeremy L Thompson @param values Values to set 1502d8dd9a91SJeremy L Thompson 1503d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1504d8dd9a91SJeremy L Thompson 1505d8dd9a91SJeremy L Thompson @ref User 1506d8dd9a91SJeremy L Thompson **/ 15073668ca4bSJeremy L Thompson int CeedOperatorContextSetInt32(CeedOperator op, 15083668ca4bSJeremy L Thompson CeedContextFieldLabel field_label, 15097bfe0f0eSJeremy L Thompson int *values) { 15103668ca4bSJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_INT32, 15117bfe0f0eSJeremy L Thompson values); 1512d8dd9a91SJeremy L Thompson } 1513d8dd9a91SJeremy L Thompson 1514d8dd9a91SJeremy L Thompson /** 15153bd813ffSjeremylt @brief Apply CeedOperator to a vector 1516d7b241e6Sjeremylt 1517d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 1518d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 1519d7b241e6Sjeremylt CeedOperatorSetField(). 1520d7b241e6Sjeremylt 1521f04ea552SJeremy L Thompson Note: Calling this function asserts that setup is complete 1522f04ea552SJeremy L Thompson and sets the CeedOperator as immutable. 1523f04ea552SJeremy L Thompson 1524d7b241e6Sjeremylt @param op CeedOperator to apply 15254cc79fe7SJed Brown @param[in] in CeedVector containing input state or @ref CEED_VECTOR_NONE if 152634138859Sjeremylt there are no active inputs 1527b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 15284cc79fe7SJed Brown distinct from @a in) or @ref CEED_VECTOR_NONE if there are no 152934138859Sjeremylt active outputs 1530d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 15314cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1532b11c1e72Sjeremylt 1533b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1534dfdf5a53Sjeremylt 15357a982d89SJeremy L. Thompson @ref User 1536b11c1e72Sjeremylt **/ 1537692c2638Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, 1538692c2638Sjeremylt CeedRequest *request) { 1539d7b241e6Sjeremylt int ierr; 1540e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1541d7b241e6Sjeremylt 1542d1d35e2fSjeremylt if (op->num_elem) { 1543250756a7Sjeremylt // Standard Operator 1544cae8b89aSjeremylt if (op->Apply) { 1545250756a7Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 1546cae8b89aSjeremylt } else { 1547cae8b89aSjeremylt // Zero all output vectors 1548250756a7Sjeremylt CeedQFunction qf = op->qf; 1549d1d35e2fSjeremylt for (CeedInt i=0; i<qf->num_output_fields; i++) { 1550d1d35e2fSjeremylt CeedVector vec = op->output_fields[i]->vec; 1551cae8b89aSjeremylt if (vec == CEED_VECTOR_ACTIVE) 1552cae8b89aSjeremylt vec = out; 1553cae8b89aSjeremylt if (vec != CEED_VECTOR_NONE) { 1554cae8b89aSjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1555cae8b89aSjeremylt } 1556cae8b89aSjeremylt } 1557250756a7Sjeremylt // Apply 1558250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1559250756a7Sjeremylt } 1560f04ea552SJeremy L Thompson } else if (op->is_composite) { 1561250756a7Sjeremylt // Composite Operator 1562250756a7Sjeremylt if (op->ApplyComposite) { 1563250756a7Sjeremylt ierr = op->ApplyComposite(op, in, out, request); CeedChk(ierr); 1564250756a7Sjeremylt } else { 1565d1d35e2fSjeremylt CeedInt num_suboperators; 1566d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1567d1d35e2fSjeremylt CeedOperator *sub_operators; 1568d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1569250756a7Sjeremylt 1570250756a7Sjeremylt // Zero all output vectors 1571250756a7Sjeremylt if (out != CEED_VECTOR_NONE) { 1572cae8b89aSjeremylt ierr = CeedVectorSetValue(out, 0.0); CeedChk(ierr); 1573cae8b89aSjeremylt } 1574d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1575d1d35e2fSjeremylt for (CeedInt j=0; j<sub_operators[i]->qf->num_output_fields; j++) { 1576d1d35e2fSjeremylt CeedVector vec = sub_operators[i]->output_fields[j]->vec; 1577250756a7Sjeremylt if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) { 1578250756a7Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1579250756a7Sjeremylt } 1580250756a7Sjeremylt } 1581250756a7Sjeremylt } 1582250756a7Sjeremylt // Apply 1583d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 1584d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(op->sub_operators[i], in, out, request); 1585cae8b89aSjeremylt CeedChk(ierr); 1586cae8b89aSjeremylt } 1587cae8b89aSjeremylt } 1588250756a7Sjeremylt } 1589e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1590cae8b89aSjeremylt } 1591cae8b89aSjeremylt 1592cae8b89aSjeremylt /** 1593cae8b89aSjeremylt @brief Apply CeedOperator to a vector and add result to output vector 1594cae8b89aSjeremylt 1595cae8b89aSjeremylt This computes the action of the operator on the specified (active) input, 1596cae8b89aSjeremylt yielding its (active) output. All inputs and outputs must be specified using 1597cae8b89aSjeremylt CeedOperatorSetField(). 1598cae8b89aSjeremylt 1599cae8b89aSjeremylt @param op CeedOperator to apply 1600cae8b89aSjeremylt @param[in] in CeedVector containing input state or NULL if there are no 1601cae8b89aSjeremylt active inputs 1602cae8b89aSjeremylt @param[out] out CeedVector to sum in result of applying operator (must be 1603cae8b89aSjeremylt distinct from @a in) or NULL if there are no active outputs 1604cae8b89aSjeremylt @param request Address of CeedRequest for non-blocking completion, else 16054cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1606cae8b89aSjeremylt 1607cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 1608cae8b89aSjeremylt 16097a982d89SJeremy L. Thompson @ref User 1610cae8b89aSjeremylt **/ 1611cae8b89aSjeremylt int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, 1612cae8b89aSjeremylt CeedRequest *request) { 1613cae8b89aSjeremylt int ierr; 1614e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1615cae8b89aSjeremylt 1616d1d35e2fSjeremylt if (op->num_elem) { 1617250756a7Sjeremylt // Standard Operator 1618250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1619f04ea552SJeremy L Thompson } else if (op->is_composite) { 1620250756a7Sjeremylt // Composite Operator 1621250756a7Sjeremylt if (op->ApplyAddComposite) { 1622250756a7Sjeremylt ierr = op->ApplyAddComposite(op, in, out, request); CeedChk(ierr); 1623cae8b89aSjeremylt } else { 1624d1d35e2fSjeremylt CeedInt num_suboperators; 1625d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1626d1d35e2fSjeremylt CeedOperator *sub_operators; 1627d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1628250756a7Sjeremylt 1629d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1630d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(sub_operators[i], in, out, request); 1631cae8b89aSjeremylt CeedChk(ierr); 16321d7d2407SJeremy L Thompson } 1633250756a7Sjeremylt } 1634250756a7Sjeremylt } 1635e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1636d7b241e6Sjeremylt } 1637d7b241e6Sjeremylt 1638d7b241e6Sjeremylt /** 1639b11c1e72Sjeremylt @brief Destroy a CeedOperator 1640d7b241e6Sjeremylt 1641d7b241e6Sjeremylt @param op CeedOperator to destroy 1642b11c1e72Sjeremylt 1643b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1644dfdf5a53Sjeremylt 16457a982d89SJeremy L. Thompson @ref User 1646b11c1e72Sjeremylt **/ 1647d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 1648d7b241e6Sjeremylt int ierr; 1649d7b241e6Sjeremylt 1650d1d35e2fSjeremylt if (!*op || --(*op)->ref_count > 0) return CEED_ERROR_SUCCESS; 1651d7b241e6Sjeremylt if ((*op)->Destroy) { 1652d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 1653d7b241e6Sjeremylt } 1654fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 1655fe2413ffSjeremylt // Free fields 16563668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_fields; i++) 1657d1d35e2fSjeremylt if ((*op)->input_fields[i]) { 1658d1d35e2fSjeremylt if ((*op)->input_fields[i]->elem_restr != CEED_ELEMRESTRICTION_NONE) { 1659d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->input_fields[i]->elem_restr); 166071352a93Sjeremylt CeedChk(ierr); 166115910d16Sjeremylt } 1662d1d35e2fSjeremylt if ((*op)->input_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1663d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->input_fields[i]->basis); CeedChk(ierr); 166471352a93Sjeremylt } 1665d1d35e2fSjeremylt if ((*op)->input_fields[i]->vec != CEED_VECTOR_ACTIVE && 1666d1d35e2fSjeremylt (*op)->input_fields[i]->vec != CEED_VECTOR_NONE ) { 1667d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->input_fields[i]->vec); CeedChk(ierr); 166871352a93Sjeremylt } 1669d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]->field_name); CeedChk(ierr); 1670d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]); CeedChk(ierr); 1671fe2413ffSjeremylt } 16723668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_fields; i++) 1673d1d35e2fSjeremylt if ((*op)->output_fields[i]) { 1674d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->output_fields[i]->elem_restr); 167571352a93Sjeremylt CeedChk(ierr); 1676d1d35e2fSjeremylt if ((*op)->output_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1677d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->output_fields[i]->basis); CeedChk(ierr); 167871352a93Sjeremylt } 1679d1d35e2fSjeremylt if ((*op)->output_fields[i]->vec != CEED_VECTOR_ACTIVE && 1680d1d35e2fSjeremylt (*op)->output_fields[i]->vec != CEED_VECTOR_NONE ) { 1681d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->output_fields[i]->vec); CeedChk(ierr); 168271352a93Sjeremylt } 1683d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]->field_name); CeedChk(ierr); 1684d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]); CeedChk(ierr); 1685fe2413ffSjeremylt } 1686d1d35e2fSjeremylt // Destroy sub_operators 16873668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_suboperators; i++) 1688d1d35e2fSjeremylt if ((*op)->sub_operators[i]) { 1689d1d35e2fSjeremylt ierr = CeedOperatorDestroy(&(*op)->sub_operators[i]); CeedChk(ierr); 169052d6035fSJeremy L Thompson } 1691d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 1692d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 1693d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 16943668ca4bSJeremy L Thompson // Destroy any composite labels 16953668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_context_labels; i++) { 16963668ca4bSJeremy L Thompson ierr = CeedFree(&(*op)->context_labels[i]->sub_labels); CeedChk(ierr); 16973668ca4bSJeremy L Thompson ierr = CeedFree(&(*op)->context_labels[i]); CeedChk(ierr); 16983668ca4bSJeremy L Thompson } 16993668ca4bSJeremy L Thompson ierr = CeedFree(&(*op)->context_labels); CeedChk(ierr); 1700fe2413ffSjeremylt 17015107b09fSJeremy L Thompson // Destroy fallback 1702805fe78eSJeremy L Thompson ierr = CeedOperatorDestroy(&(*op)->op_fallback); CeedChk(ierr); 17035107b09fSJeremy L Thompson 1704*ed9e99e6SJeremy L Thompson // Destroy assembly data 1705480fae85SJeremy L Thompson ierr = CeedQFunctionAssemblyDataDestroy(&(*op)->qf_assembled); CeedChk(ierr); 1706*ed9e99e6SJeremy L Thompson ierr = CeedOperatorAssemblyDataDestroy(&(*op)->op_assembled); CeedChk(ierr); 170770a7ffb3SJeremy L Thompson 1708d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields); CeedChk(ierr); 1709d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields); CeedChk(ierr); 1710d1d35e2fSjeremylt ierr = CeedFree(&(*op)->sub_operators); CeedChk(ierr); 1711ea6b5821SJeremy L Thompson ierr = CeedFree(&(*op)->name); CeedChk(ierr); 1712d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 1713e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1714d7b241e6Sjeremylt } 1715d7b241e6Sjeremylt 1716d7b241e6Sjeremylt /// @} 1717