1d7b241e6Sjeremylt // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 2d7b241e6Sjeremylt // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 3d7b241e6Sjeremylt // reserved. See files LICENSE and NOTICE for details. 4d7b241e6Sjeremylt // 5d7b241e6Sjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software 6d7b241e6Sjeremylt // libraries and APIs for efficient high-order finite element and spectral 7d7b241e6Sjeremylt // element discretizations for exascale applications. For more information and 8d7b241e6Sjeremylt // source code availability see http://github.com/ceed. 9d7b241e6Sjeremylt // 10d7b241e6Sjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11d7b241e6Sjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office 12d7b241e6Sjeremylt // of Science and the National Nuclear Security Administration) responsible for 13d7b241e6Sjeremylt // the planning and preparation of a capable exascale ecosystem, including 14d7b241e6Sjeremylt // software, applications, hardware, advanced system engineering and early 15d7b241e6Sjeremylt // testbed platforms, in support of the nation's exascale computing imperative. 16d7b241e6Sjeremylt 17ec3da8bcSJed Brown #include <ceed/ceed.h> 18ec3da8bcSJed Brown #include <ceed/backend.h> 193d576824SJeremy L Thompson #include <ceed-impl.h> 203d576824SJeremy L Thompson #include <stdbool.h> 213d576824SJeremy L Thompson #include <stdio.h> 223d576824SJeremy L Thompson #include <string.h> 23d7b241e6Sjeremylt 24dfdf5a53Sjeremylt /// @file 257a982d89SJeremy L. Thompson /// Implementation of CeedOperator interfaces 267a982d89SJeremy L. Thompson 277a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 287a982d89SJeremy L. Thompson /// CeedOperator Library Internal Functions 297a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 307a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorDeveloper 317a982d89SJeremy L. Thompson /// @{ 327a982d89SJeremy L. Thompson 337a982d89SJeremy L. Thompson /** 34e15f9bd0SJeremy L Thompson @brief Check if a CeedOperator Field matches the QFunction Field 35e15f9bd0SJeremy L Thompson 36e15f9bd0SJeremy L Thompson @param[in] ceed Ceed object for error handling 37d1d35e2fSjeremylt @param[in] qf_field QFunction Field matching Operator Field 38e15f9bd0SJeremy L Thompson @param[in] r Operator Field ElemRestriction 39e15f9bd0SJeremy L Thompson @param[in] b Operator Field Basis 40e15f9bd0SJeremy L Thompson 41e15f9bd0SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 42e15f9bd0SJeremy L Thompson 43e15f9bd0SJeremy L Thompson @ref Developer 44e15f9bd0SJeremy L Thompson **/ 45d1d35e2fSjeremylt static int CeedOperatorCheckField(Ceed ceed, CeedQFunctionField qf_field, 46e15f9bd0SJeremy L Thompson CeedElemRestriction r, CeedBasis b) { 47e15f9bd0SJeremy L Thompson int ierr; 48d1d35e2fSjeremylt CeedEvalMode eval_mode = qf_field->eval_mode; 49d1d35e2fSjeremylt CeedInt dim = 1, num_comp = 1, restr_num_comp = 1, size = qf_field->size; 50e15f9bd0SJeremy L Thompson // Restriction 51e15f9bd0SJeremy L Thompson if (r != CEED_ELEMRESTRICTION_NONE) { 52d1d35e2fSjeremylt if (eval_mode == CEED_EVAL_WEIGHT) { 53e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 54e1e9e29dSJed Brown return CeedError(ceed, CEED_ERROR_INCOMPATIBLE, 55e1e9e29dSJed Brown "CEED_ELEMRESTRICTION_NONE should be used " 56e15f9bd0SJeremy L Thompson "for a field with eval mode CEED_EVAL_WEIGHT"); 57e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 58e15f9bd0SJeremy L Thompson } 59d1d35e2fSjeremylt ierr = CeedElemRestrictionGetNumComponents(r, &restr_num_comp); 6078464608Sjeremylt CeedChk(ierr); 61e1e9e29dSJed Brown } 62d1d35e2fSjeremylt if ((r == CEED_ELEMRESTRICTION_NONE) != (eval_mode == CEED_EVAL_WEIGHT)) { 63e1e9e29dSJed Brown // LCOV_EXCL_START 64e1e9e29dSJed Brown return CeedError(ceed, CEED_ERROR_INCOMPATIBLE, 65e1e9e29dSJed Brown "CEED_ELEMRESTRICTION_NONE and CEED_EVAL_WEIGHT " 66e1e9e29dSJed Brown "must be used together."); 67e1e9e29dSJed Brown // LCOV_EXCL_STOP 68e1e9e29dSJed Brown } 69e15f9bd0SJeremy L Thompson // Basis 70e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 71d1d35e2fSjeremylt if (eval_mode == CEED_EVAL_NONE) 728229195eSjeremylt // LCOV_EXCL_START 73e1e9e29dSJed Brown return CeedError(ceed, CEED_ERROR_INCOMPATIBLE, 74d1d35e2fSjeremylt "Field '%s' configured with CEED_EVAL_NONE must " 75d1d35e2fSjeremylt "be used with CEED_BASIS_COLLOCATED", 768229195eSjeremylt // LCOV_EXCL_STOP 77d1d35e2fSjeremylt qf_field->field_name); 78e15f9bd0SJeremy L Thompson ierr = CeedBasisGetDimension(b, &dim); CeedChk(ierr); 79d1d35e2fSjeremylt ierr = CeedBasisGetNumComponents(b, &num_comp); CeedChk(ierr); 80d1d35e2fSjeremylt if (r != CEED_ELEMRESTRICTION_NONE && restr_num_comp != num_comp) { 81e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 82e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 83d1d35e2fSjeremylt "Field '%s' of size %d and EvalMode %s: ElemRestriction " 84d1d35e2fSjeremylt "has %d components, but Basis has %d components", 85d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], 86d1d35e2fSjeremylt restr_num_comp, 87d1d35e2fSjeremylt num_comp); 88e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 89e15f9bd0SJeremy L Thompson } 90e15f9bd0SJeremy L Thompson } 91e15f9bd0SJeremy L Thompson // Field size 92d1d35e2fSjeremylt switch(eval_mode) { 93e15f9bd0SJeremy L Thompson case CEED_EVAL_NONE: 94d1d35e2fSjeremylt if (size != restr_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 has %d components", 98d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], 99d1d35e2fSjeremylt restr_num_comp); 100e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 101e15f9bd0SJeremy L Thompson break; 102e15f9bd0SJeremy L Thompson case CEED_EVAL_INTERP: 103d1d35e2fSjeremylt if (size != num_comp) 104e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 105e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 106e1e9e29dSJed Brown "Field '%s' of size %d and EvalMode %s: ElemRestriction/Basis has %d components", 107d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], 108d1d35e2fSjeremylt num_comp); 109e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 110e15f9bd0SJeremy L Thompson break; 111e15f9bd0SJeremy L Thompson case CEED_EVAL_GRAD: 112d1d35e2fSjeremylt if (size != num_comp * dim) 113e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 114e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 115d1d35e2fSjeremylt "Field '%s' of size %d and EvalMode %s in %d dimensions: " 116d1d35e2fSjeremylt "ElemRestriction/Basis has %d components", 117d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], dim, 118d1d35e2fSjeremylt num_comp); 119e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 120e15f9bd0SJeremy L Thompson break; 121e15f9bd0SJeremy L Thompson case CEED_EVAL_WEIGHT: 122d1d35e2fSjeremylt // No additional checks required 123e15f9bd0SJeremy L Thompson break; 124e15f9bd0SJeremy L Thompson case CEED_EVAL_DIV: 125e15f9bd0SJeremy L Thompson // Not implemented 126e15f9bd0SJeremy L Thompson break; 127e15f9bd0SJeremy L Thompson case CEED_EVAL_CURL: 128e15f9bd0SJeremy L Thompson // Not implemented 129e15f9bd0SJeremy L Thompson break; 130e15f9bd0SJeremy L Thompson } 131e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1327a982d89SJeremy L. Thompson } 1337a982d89SJeremy L. Thompson 1347a982d89SJeremy L. Thompson /** 1357a982d89SJeremy L. Thompson @brief View a field of a CeedOperator 1367a982d89SJeremy L. Thompson 1377a982d89SJeremy L. Thompson @param[in] field Operator field to view 138d1d35e2fSjeremylt @param[in] qf_field QFunction field (carries field name) 139d1d35e2fSjeremylt @param[in] field_number Number of field being viewed 1404c4400c7SValeria Barra @param[in] sub true indicates sub-operator, which increases indentation; false for top-level operator 141d1d35e2fSjeremylt @param[in] input true for an input field; false for output field 1427a982d89SJeremy L. Thompson @param[in] stream Stream to view to, e.g., stdout 1437a982d89SJeremy L. Thompson 1447a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1457a982d89SJeremy L. Thompson 1467a982d89SJeremy L. Thompson @ref Utility 1477a982d89SJeremy L. Thompson **/ 1487a982d89SJeremy L. Thompson static int CeedOperatorFieldView(CeedOperatorField field, 149d1d35e2fSjeremylt CeedQFunctionField qf_field, 150d1d35e2fSjeremylt CeedInt field_number, bool sub, bool input, 1517a982d89SJeremy L. Thompson FILE *stream) { 1527a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 153d1d35e2fSjeremylt const char *in_out = input ? "Input" : "Output"; 1547a982d89SJeremy L. Thompson 1557a982d89SJeremy L. Thompson fprintf(stream, "%s %s Field [%d]:\n" 1567a982d89SJeremy L. Thompson "%s Name: \"%s\"\n", 157d1d35e2fSjeremylt pre, in_out, field_number, pre, qf_field->field_name); 1587a982d89SJeremy L. Thompson 1597a982d89SJeremy L. Thompson if (field->basis == CEED_BASIS_COLLOCATED) 1607a982d89SJeremy L. Thompson fprintf(stream, "%s Collocated basis\n", pre); 1617a982d89SJeremy L. Thompson 1627a982d89SJeremy L. Thompson if (field->vec == CEED_VECTOR_ACTIVE) 1637a982d89SJeremy L. Thompson fprintf(stream, "%s Active vector\n", pre); 1647a982d89SJeremy L. Thompson else if (field->vec == CEED_VECTOR_NONE) 1657a982d89SJeremy L. Thompson fprintf(stream, "%s No vector\n", pre); 166e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1677a982d89SJeremy L. Thompson } 1687a982d89SJeremy L. Thompson 1697a982d89SJeremy L. Thompson /** 1707a982d89SJeremy L. Thompson @brief View a single CeedOperator 1717a982d89SJeremy L. Thompson 1727a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 1737a982d89SJeremy L. Thompson @param[in] sub Boolean flag for sub-operator 1747a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 1757a982d89SJeremy L. Thompson 1767a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 1777a982d89SJeremy L. Thompson 1787a982d89SJeremy L. Thompson @ref Utility 1797a982d89SJeremy L. Thompson **/ 1807a982d89SJeremy L. Thompson int CeedOperatorSingleView(CeedOperator op, bool sub, FILE *stream) { 1817a982d89SJeremy L. Thompson int ierr; 1827a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 1837a982d89SJeremy L. Thompson 18478464608Sjeremylt CeedInt total_fields = 0; 18578464608Sjeremylt ierr = CeedOperatorGetNumArgs(op, &total_fields); CeedChk(ierr); 1867a982d89SJeremy L. Thompson 18778464608Sjeremylt fprintf(stream, "%s %d Field%s\n", pre, total_fields, 18878464608Sjeremylt total_fields>1 ? "s" : ""); 1897a982d89SJeremy L. Thompson 190d1d35e2fSjeremylt fprintf(stream, "%s %d Input Field%s:\n", pre, op->qf->num_input_fields, 191d1d35e2fSjeremylt op->qf->num_input_fields>1 ? "s" : ""); 192d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_input_fields; i++) { 193d1d35e2fSjeremylt ierr = CeedOperatorFieldView(op->input_fields[i], op->qf->input_fields[i], 1947a982d89SJeremy L. Thompson i, sub, 1, stream); CeedChk(ierr); 1957a982d89SJeremy L. Thompson } 1967a982d89SJeremy L. Thompson 197d1d35e2fSjeremylt fprintf(stream, "%s %d Output Field%s:\n", pre, op->qf->num_output_fields, 198d1d35e2fSjeremylt op->qf->num_output_fields>1 ? "s" : ""); 199d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_output_fields; i++) { 200d1d35e2fSjeremylt ierr = CeedOperatorFieldView(op->output_fields[i], op->qf->output_fields[i], 2017a982d89SJeremy L. Thompson i, sub, 0, stream); CeedChk(ierr); 2027a982d89SJeremy L. Thompson } 203e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2047a982d89SJeremy L. Thompson } 2057a982d89SJeremy L. Thompson 206d99fa3c5SJeremy L Thompson /** 2070f60e0a8SJeremy L Thompson @brief Find the active vector basis for a non-composite CeedOperator 208eaf62fffSJeremy L Thompson 209eaf62fffSJeremy L Thompson @param[in] op CeedOperator to find active basis for 2100f60e0a8SJeremy L Thompson @param[out] active_basis Basis for active input vector or NULL for composite operator 211eaf62fffSJeremy L Thompson 212eaf62fffSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 213eaf62fffSJeremy L Thompson 214eaf62fffSJeremy L Thompson @ ref Developer 215eaf62fffSJeremy L Thompson **/ 216eaf62fffSJeremy L Thompson int CeedOperatorGetActiveBasis(CeedOperator op, CeedBasis *active_basis) { 217eaf62fffSJeremy L Thompson *active_basis = NULL; 2180f60e0a8SJeremy L Thompson if (op->is_composite) return CEED_ERROR_SUCCESS; 219eaf62fffSJeremy L Thompson for (int i = 0; i < op->qf->num_input_fields; i++) 220eaf62fffSJeremy L Thompson if (op->input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 221eaf62fffSJeremy L Thompson *active_basis = op->input_fields[i]->basis; 222eaf62fffSJeremy L Thompson break; 223eaf62fffSJeremy L Thompson } 224eaf62fffSJeremy L Thompson 225eaf62fffSJeremy L Thompson if (!*active_basis) { 226eaf62fffSJeremy L Thompson // LCOV_EXCL_START 227eaf62fffSJeremy L Thompson int ierr; 228eaf62fffSJeremy L Thompson Ceed ceed; 229eaf62fffSJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 230eaf62fffSJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 231eaf62fffSJeremy L Thompson "No active CeedBasis found"); 232eaf62fffSJeremy L Thompson // LCOV_EXCL_STOP 233eaf62fffSJeremy L Thompson } 234eaf62fffSJeremy L Thompson return CEED_ERROR_SUCCESS; 235eaf62fffSJeremy L Thompson } 236eaf62fffSJeremy L Thompson 237eaf62fffSJeremy L Thompson /** 2380f60e0a8SJeremy L Thompson @brief Find the active vector ElemRestriction for a non-composite CeedOperator 239e2f04181SAndrew T. Barker 240e2f04181SAndrew T. Barker @param[in] op CeedOperator to find active basis for 2410f60e0a8SJeremy L Thompson @param[out] active_rstr ElemRestriction for active input vector or NULL for composite operator 242e2f04181SAndrew T. Barker 243e2f04181SAndrew T. Barker @return An error code: 0 - success, otherwise - failure 244e2f04181SAndrew T. Barker 245e2f04181SAndrew T. Barker @ref Utility 246e2f04181SAndrew T. Barker **/ 247eaf62fffSJeremy L Thompson int CeedOperatorGetActiveElemRestriction(CeedOperator op, 248d1d35e2fSjeremylt CeedElemRestriction *active_rstr) { 249d1d35e2fSjeremylt *active_rstr = NULL; 2500f60e0a8SJeremy L Thompson if (op->is_composite) return CEED_ERROR_SUCCESS; 251d1d35e2fSjeremylt for (int i = 0; i < op->qf->num_input_fields; i++) 252d1d35e2fSjeremylt if (op->input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 253d1d35e2fSjeremylt *active_rstr = op->input_fields[i]->elem_restr; 254e2f04181SAndrew T. Barker break; 255e2f04181SAndrew T. Barker } 256e2f04181SAndrew T. Barker 257d1d35e2fSjeremylt if (!*active_rstr) { 258e2f04181SAndrew T. Barker // LCOV_EXCL_START 259e2f04181SAndrew T. Barker int ierr; 260e2f04181SAndrew T. Barker Ceed ceed; 261e2f04181SAndrew T. Barker ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 262e2f04181SAndrew T. Barker return CeedError(ceed, CEED_ERROR_INCOMPLETE, 263eaf62fffSJeremy L Thompson "No active CeedElemRestriction found"); 264e2f04181SAndrew T. Barker // LCOV_EXCL_STOP 265e2f04181SAndrew T. Barker } 266e2f04181SAndrew T. Barker return CEED_ERROR_SUCCESS; 267e2f04181SAndrew T. Barker } 268e2f04181SAndrew T. Barker 269d8dd9a91SJeremy L Thompson /** 270d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field value of the specified type. 271d8dd9a91SJeremy L Thompson For composite operators, the value is set in all 272d8dd9a91SJeremy L Thompson sub-operator QFunctionContexts that have a matching `field_name`. 273d8dd9a91SJeremy L Thompson A non-zero error code is returned for single operators 274d8dd9a91SJeremy L Thompson that do not have a matching field of the same type or composite 275d8dd9a91SJeremy L Thompson operators that do not have any field of a matching type. 276d8dd9a91SJeremy L Thompson 277d8dd9a91SJeremy L Thompson @param op CeedOperator 2783668ca4bSJeremy L Thompson @param field_label Label of field to set 279d8dd9a91SJeremy L Thompson @param field_type Type of field to set 280d8dd9a91SJeremy L Thompson @param value Value to set 281d8dd9a91SJeremy L Thompson 282d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 283d8dd9a91SJeremy L Thompson 284d8dd9a91SJeremy L Thompson @ref User 285d8dd9a91SJeremy L Thompson **/ 286d8dd9a91SJeremy L Thompson static int CeedOperatorContextSetGeneric(CeedOperator op, 2873668ca4bSJeremy L Thompson CeedContextFieldLabel field_label, CeedContextFieldType field_type, 2883668ca4bSJeremy L Thompson void *value) { 289d8dd9a91SJeremy L Thompson int ierr; 290d8dd9a91SJeremy L Thompson 2913668ca4bSJeremy L Thompson if (!field_label) 2923668ca4bSJeremy L Thompson // LCOV_EXCL_START 2933668ca4bSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_UNSUPPORTED, 2943668ca4bSJeremy L Thompson "Invalid field label"); 2953668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 2963668ca4bSJeremy L Thompson 2973668ca4bSJeremy L Thompson bool is_composite = false; 298d8dd9a91SJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 299d8dd9a91SJeremy L Thompson if (is_composite) { 300d8dd9a91SJeremy L Thompson CeedInt num_sub; 301d8dd9a91SJeremy L Thompson CeedOperator *sub_operators; 302d8dd9a91SJeremy L Thompson 303d8dd9a91SJeremy L Thompson ierr = CeedOperatorGetNumSub(op, &num_sub); CeedChk(ierr); 304d8dd9a91SJeremy L Thompson ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 3053668ca4bSJeremy L Thompson if (num_sub != field_label->num_sub_labels) 3063668ca4bSJeremy L Thompson // LCOV_EXCL_START 3073668ca4bSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_UNSUPPORTED, 3083668ca4bSJeremy L Thompson "ContextLabel does not correspond to composite operator.\n" 3093668ca4bSJeremy L Thompson "Use CeedOperatorGetContextFieldLabel()."); 3103668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 311d8dd9a91SJeremy L Thompson 312d8dd9a91SJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 313d8dd9a91SJeremy L Thompson // Try every sub-operator, ok if some sub-operators do not have field 3143668ca4bSJeremy L Thompson if (field_label->sub_labels[i] && sub_operators[i]->qf->ctx) { 3153668ca4bSJeremy L Thompson ierr = CeedQFunctionContextSetGeneric(sub_operators[i]->qf->ctx, 3163668ca4bSJeremy L Thompson field_label->sub_labels[i], 3173668ca4bSJeremy L Thompson field_type, value); CeedChk(ierr); 318d8dd9a91SJeremy L Thompson } 319d8dd9a91SJeremy L Thompson } 320d8dd9a91SJeremy L Thompson } else { 321d8dd9a91SJeremy L Thompson if (!op->qf->ctx) 322d8dd9a91SJeremy L Thompson // LCOV_EXCL_START 323d8dd9a91SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_UNSUPPORTED, 324d8dd9a91SJeremy L Thompson "QFunction does not have context data"); 325d8dd9a91SJeremy L Thompson // LCOV_EXCL_STOP 326d8dd9a91SJeremy L Thompson 3273668ca4bSJeremy L Thompson ierr = CeedQFunctionContextSetGeneric(op->qf->ctx, field_label, 3283668ca4bSJeremy L Thompson field_type, value); CeedChk(ierr); 329d8dd9a91SJeremy L Thompson } 330d8dd9a91SJeremy L Thompson 331d8dd9a91SJeremy L Thompson return CEED_ERROR_SUCCESS; 332d8dd9a91SJeremy L Thompson } 333d8dd9a91SJeremy L Thompson 3347a982d89SJeremy L. Thompson /// @} 3357a982d89SJeremy L. Thompson 3367a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3377a982d89SJeremy L. Thompson /// CeedOperator Backend API 3387a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3397a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorBackend 3407a982d89SJeremy L. Thompson /// @{ 3417a982d89SJeremy L. Thompson 3427a982d89SJeremy L. Thompson /** 3437a982d89SJeremy L. Thompson @brief Get the number of arguments associated with a CeedOperator 3447a982d89SJeremy L. Thompson 3457a982d89SJeremy L. Thompson @param op CeedOperator 346d1d35e2fSjeremylt @param[out] num_args Variable to store vector number of arguments 3477a982d89SJeremy L. Thompson 3487a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3497a982d89SJeremy L. Thompson 3507a982d89SJeremy L. Thompson @ref Backend 3517a982d89SJeremy L. Thompson **/ 3527a982d89SJeremy L. Thompson 353d1d35e2fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *num_args) { 354f04ea552SJeremy L Thompson if (op->is_composite) 3557a982d89SJeremy L. Thompson // LCOV_EXCL_START 356e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 357e15f9bd0SJeremy L Thompson "Not defined for composite operators"); 3587a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 3597a982d89SJeremy L. Thompson 360d1d35e2fSjeremylt *num_args = op->num_fields; 361e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3627a982d89SJeremy L. Thompson } 3637a982d89SJeremy L. Thompson 3647a982d89SJeremy L. Thompson /** 3657a982d89SJeremy L. Thompson @brief Get the setup status of a CeedOperator 3667a982d89SJeremy L. Thompson 3677a982d89SJeremy L. Thompson @param op CeedOperator 368d1d35e2fSjeremylt @param[out] is_setup_done Variable to store setup status 3697a982d89SJeremy L. Thompson 3707a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3717a982d89SJeremy L. Thompson 3727a982d89SJeremy L. Thompson @ref Backend 3737a982d89SJeremy L. Thompson **/ 3747a982d89SJeremy L. Thompson 375d1d35e2fSjeremylt int CeedOperatorIsSetupDone(CeedOperator op, bool *is_setup_done) { 376f04ea552SJeremy L Thompson *is_setup_done = op->is_backend_setup; 377e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3787a982d89SJeremy L. Thompson } 3797a982d89SJeremy L. Thompson 3807a982d89SJeremy L. Thompson /** 3817a982d89SJeremy L. Thompson @brief Get the QFunction associated with a CeedOperator 3827a982d89SJeremy L. Thompson 3837a982d89SJeremy L. Thompson @param op CeedOperator 3847a982d89SJeremy L. Thompson @param[out] qf Variable to store QFunction 3857a982d89SJeremy L. Thompson 3867a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3877a982d89SJeremy L. Thompson 3887a982d89SJeremy L. Thompson @ref Backend 3897a982d89SJeremy L. Thompson **/ 3907a982d89SJeremy L. Thompson 3917a982d89SJeremy L. Thompson int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 392f04ea552SJeremy L Thompson if (op->is_composite) 3937a982d89SJeremy L. Thompson // LCOV_EXCL_START 394e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 395e15f9bd0SJeremy L Thompson "Not defined for composite operator"); 3967a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 3977a982d89SJeremy L. Thompson 3987a982d89SJeremy L. Thompson *qf = op->qf; 399e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4007a982d89SJeremy L. Thompson } 4017a982d89SJeremy L. Thompson 4027a982d89SJeremy L. Thompson /** 403c04a41a7SJeremy L Thompson @brief Get a boolean value indicating if the CeedOperator is composite 404c04a41a7SJeremy L Thompson 405c04a41a7SJeremy L Thompson @param op CeedOperator 406d1d35e2fSjeremylt @param[out] is_composite Variable to store composite status 407c04a41a7SJeremy L Thompson 408c04a41a7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 409c04a41a7SJeremy L Thompson 410c04a41a7SJeremy L Thompson @ref Backend 411c04a41a7SJeremy L Thompson **/ 412c04a41a7SJeremy L Thompson 413d1d35e2fSjeremylt int CeedOperatorIsComposite(CeedOperator op, bool *is_composite) { 414f04ea552SJeremy L Thompson *is_composite = op->is_composite; 415e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 416c04a41a7SJeremy L Thompson } 417c04a41a7SJeremy L Thompson 418c04a41a7SJeremy L Thompson /** 419d1d35e2fSjeremylt @brief Get the number of sub_operators associated with a CeedOperator 4207a982d89SJeremy L. Thompson 4217a982d89SJeremy L. Thompson @param op CeedOperator 422d1d35e2fSjeremylt @param[out] num_suboperators Variable to store number of sub_operators 4237a982d89SJeremy L. Thompson 4247a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4257a982d89SJeremy L. Thompson 4267a982d89SJeremy L. Thompson @ref Backend 4277a982d89SJeremy L. Thompson **/ 4287a982d89SJeremy L. Thompson 429d1d35e2fSjeremylt int CeedOperatorGetNumSub(CeedOperator op, CeedInt *num_suboperators) { 430f04ea552SJeremy L Thompson if (!op->is_composite) 4317a982d89SJeremy L. Thompson // LCOV_EXCL_START 432e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 4337a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4347a982d89SJeremy L. Thompson 435d1d35e2fSjeremylt *num_suboperators = op->num_suboperators; 436e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4377a982d89SJeremy L. Thompson } 4387a982d89SJeremy L. Thompson 4397a982d89SJeremy L. Thompson /** 440d1d35e2fSjeremylt @brief Get the list of sub_operators associated with a CeedOperator 4417a982d89SJeremy L. Thompson 4427a982d89SJeremy L. Thompson @param op CeedOperator 443d1d35e2fSjeremylt @param[out] sub_operators Variable to store list of sub_operators 4447a982d89SJeremy L. Thompson 4457a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4467a982d89SJeremy L. Thompson 4477a982d89SJeremy L. Thompson @ref Backend 4487a982d89SJeremy L. Thompson **/ 4497a982d89SJeremy L. Thompson 450d1d35e2fSjeremylt int CeedOperatorGetSubList(CeedOperator op, CeedOperator **sub_operators) { 451f04ea552SJeremy L Thompson if (!op->is_composite) 4527a982d89SJeremy L. Thompson // LCOV_EXCL_START 453e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 4547a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4557a982d89SJeremy L. Thompson 456d1d35e2fSjeremylt *sub_operators = op->sub_operators; 457e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4587a982d89SJeremy L. Thompson } 4597a982d89SJeremy L. Thompson 4607a982d89SJeremy L. Thompson /** 4617a982d89SJeremy L. Thompson @brief Get the backend data of a CeedOperator 4627a982d89SJeremy L. Thompson 4637a982d89SJeremy L. Thompson @param op CeedOperator 4647a982d89SJeremy L. Thompson @param[out] data Variable to store data 4657a982d89SJeremy L. Thompson 4667a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4677a982d89SJeremy L. Thompson 4687a982d89SJeremy L. Thompson @ref Backend 4697a982d89SJeremy L. Thompson **/ 4707a982d89SJeremy L. Thompson 471777ff853SJeremy L Thompson int CeedOperatorGetData(CeedOperator op, void *data) { 472777ff853SJeremy L Thompson *(void **)data = op->data; 473e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4747a982d89SJeremy L. Thompson } 4757a982d89SJeremy L. Thompson 4767a982d89SJeremy L. Thompson /** 4777a982d89SJeremy L. Thompson @brief Set the backend data of a CeedOperator 4787a982d89SJeremy L. Thompson 4797a982d89SJeremy L. Thompson @param[out] op CeedOperator 4807a982d89SJeremy L. Thompson @param data Data to set 4817a982d89SJeremy L. Thompson 4827a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4837a982d89SJeremy L. Thompson 4847a982d89SJeremy L. Thompson @ref Backend 4857a982d89SJeremy L. Thompson **/ 4867a982d89SJeremy L. Thompson 487777ff853SJeremy L Thompson int CeedOperatorSetData(CeedOperator op, void *data) { 488777ff853SJeremy L Thompson op->data = data; 489e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4907a982d89SJeremy L. Thompson } 4917a982d89SJeremy L. Thompson 4927a982d89SJeremy L. Thompson /** 49334359f16Sjeremylt @brief Increment the reference counter for a CeedOperator 49434359f16Sjeremylt 49534359f16Sjeremylt @param op CeedOperator to increment the reference counter 49634359f16Sjeremylt 49734359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 49834359f16Sjeremylt 49934359f16Sjeremylt @ref Backend 50034359f16Sjeremylt **/ 5019560d06aSjeremylt int CeedOperatorReference(CeedOperator op) { 50234359f16Sjeremylt op->ref_count++; 50334359f16Sjeremylt return CEED_ERROR_SUCCESS; 50434359f16Sjeremylt } 50534359f16Sjeremylt 50634359f16Sjeremylt /** 5077a982d89SJeremy L. Thompson @brief Set the setup flag of a CeedOperator to True 5087a982d89SJeremy L. Thompson 5097a982d89SJeremy L. Thompson @param op CeedOperator 5107a982d89SJeremy L. Thompson 5117a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5127a982d89SJeremy L. Thompson 5137a982d89SJeremy L. Thompson @ref Backend 5147a982d89SJeremy L. Thompson **/ 5157a982d89SJeremy L. Thompson 5167a982d89SJeremy L. Thompson int CeedOperatorSetSetupDone(CeedOperator op) { 517f04ea552SJeremy L Thompson op->is_backend_setup = true; 518e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5197a982d89SJeremy L. Thompson } 5207a982d89SJeremy L. Thompson 5217a982d89SJeremy L. Thompson /// @} 5227a982d89SJeremy L. Thompson 5237a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5247a982d89SJeremy L. Thompson /// CeedOperator Public API 5257a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5267a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorUser 527dfdf5a53Sjeremylt /// @{ 528d7b241e6Sjeremylt 529d7b241e6Sjeremylt /** 5300219ea01SJeremy L Thompson @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and 5310219ea01SJeremy L Thompson CeedElemRestriction can be associated with CeedQFunction fields with 5320219ea01SJeremy L Thompson \ref CeedOperatorSetField. 533d7b241e6Sjeremylt 534b11c1e72Sjeremylt @param ceed A Ceed object where the CeedOperator will be created 535d7b241e6Sjeremylt @param qf QFunction defining the action of the operator at quadrature points 53634138859Sjeremylt @param dqf QFunction defining the action of the Jacobian of @a qf (or 5374cc79fe7SJed Brown @ref CEED_QFUNCTION_NONE) 538d7b241e6Sjeremylt @param dqfT QFunction defining the action of the transpose of the Jacobian 5394cc79fe7SJed Brown of @a qf (or @ref CEED_QFUNCTION_NONE) 540b11c1e72Sjeremylt @param[out] op Address of the variable where the newly created 541b11c1e72Sjeremylt CeedOperator will be stored 542b11c1e72Sjeremylt 543b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 544dfdf5a53Sjeremylt 5457a982d89SJeremy L. Thompson @ref User 546d7b241e6Sjeremylt */ 547d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, 548d7b241e6Sjeremylt CeedQFunction dqfT, CeedOperator *op) { 549d7b241e6Sjeremylt int ierr; 550d7b241e6Sjeremylt 5515fe0d4faSjeremylt if (!ceed->OperatorCreate) { 5525fe0d4faSjeremylt Ceed delegate; 553aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 5545fe0d4faSjeremylt 5555fe0d4faSjeremylt if (!delegate) 556c042f62fSJeremy L Thompson // LCOV_EXCL_START 557e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 558e15f9bd0SJeremy L Thompson "Backend does not support OperatorCreate"); 559c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 5605fe0d4faSjeremylt 5615fe0d4faSjeremylt ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr); 562e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5635fe0d4faSjeremylt } 5645fe0d4faSjeremylt 565b3b7035fSJeremy L Thompson if (!qf || qf == CEED_QFUNCTION_NONE) 566b3b7035fSJeremy L Thompson // LCOV_EXCL_START 567e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 568e15f9bd0SJeremy L Thompson "Operator must have a valid QFunction."); 569b3b7035fSJeremy L Thompson // LCOV_EXCL_STOP 570d7b241e6Sjeremylt ierr = CeedCalloc(1, op); CeedChk(ierr); 571d7b241e6Sjeremylt (*op)->ceed = ceed; 5729560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 573d1d35e2fSjeremylt (*op)->ref_count = 1; 574d7b241e6Sjeremylt (*op)->qf = qf; 575*2b104005SJeremy L Thompson (*op)->input_size = -1; 576*2b104005SJeremy L Thompson (*op)->output_size = -1; 5779560d06aSjeremylt ierr = CeedQFunctionReference(qf); CeedChk(ierr); 578442e7f0bSjeremylt if (dqf && dqf != CEED_QFUNCTION_NONE) { 579d7b241e6Sjeremylt (*op)->dqf = dqf; 5809560d06aSjeremylt ierr = CeedQFunctionReference(dqf); CeedChk(ierr); 581442e7f0bSjeremylt } 582442e7f0bSjeremylt if (dqfT && dqfT != CEED_QFUNCTION_NONE) { 583d7b241e6Sjeremylt (*op)->dqfT = dqfT; 5849560d06aSjeremylt ierr = CeedQFunctionReference(dqfT); CeedChk(ierr); 585442e7f0bSjeremylt } 586480fae85SJeremy L Thompson ierr = CeedQFunctionAssemblyDataCreate(ceed, &(*op)->qf_assembled); 587480fae85SJeremy L Thompson CeedChk(ierr); 588bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_FIELD_MAX, &(*op)->input_fields); CeedChk(ierr); 589bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_FIELD_MAX, &(*op)->output_fields); CeedChk(ierr); 590d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 591e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 592d7b241e6Sjeremylt } 593d7b241e6Sjeremylt 594d7b241e6Sjeremylt /** 59552d6035fSJeremy L Thompson @brief Create an operator that composes the action of several operators 59652d6035fSJeremy L Thompson 59752d6035fSJeremy L Thompson @param ceed A Ceed object where the CeedOperator will be created 59852d6035fSJeremy L Thompson @param[out] op Address of the variable where the newly created 59952d6035fSJeremy L Thompson Composite CeedOperator will be stored 60052d6035fSJeremy L Thompson 60152d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 60252d6035fSJeremy L Thompson 6037a982d89SJeremy L. Thompson @ref User 60452d6035fSJeremy L Thompson */ 60552d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) { 60652d6035fSJeremy L Thompson int ierr; 60752d6035fSJeremy L Thompson 60852d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 60952d6035fSJeremy L Thompson Ceed delegate; 610aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 61152d6035fSJeremy L Thompson 612250756a7Sjeremylt if (delegate) { 61352d6035fSJeremy L Thompson ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr); 614e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 61552d6035fSJeremy L Thompson } 616250756a7Sjeremylt } 61752d6035fSJeremy L Thompson 61852d6035fSJeremy L Thompson ierr = CeedCalloc(1, op); CeedChk(ierr); 61952d6035fSJeremy L Thompson (*op)->ceed = ceed; 6209560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 621f04ea552SJeremy L Thompson (*op)->is_composite = true; 622bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_COMPOSITE_MAX, &(*op)->sub_operators); CeedChk(ierr); 623*2b104005SJeremy L Thompson (*op)->input_size = -1; 624*2b104005SJeremy L Thompson (*op)->output_size = -1; 625250756a7Sjeremylt 626250756a7Sjeremylt if (ceed->CompositeOperatorCreate) { 62752d6035fSJeremy L Thompson ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr); 628250756a7Sjeremylt } 629e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 63052d6035fSJeremy L Thompson } 63152d6035fSJeremy L Thompson 63252d6035fSJeremy L Thompson /** 6339560d06aSjeremylt @brief Copy the pointer to a CeedOperator. Both pointers should 6349560d06aSjeremylt be destroyed with `CeedOperatorDestroy()`; 6359560d06aSjeremylt Note: If `*op_copy` is non-NULL, then it is assumed that 6369560d06aSjeremylt `*op_copy` is a pointer to a CeedOperator. This 6379560d06aSjeremylt CeedOperator will be destroyed if `*op_copy` is the only 6389560d06aSjeremylt reference to this CeedOperator. 6399560d06aSjeremylt 6409560d06aSjeremylt @param op CeedOperator to copy reference to 6419560d06aSjeremylt @param[out] op_copy Variable to store copied reference 6429560d06aSjeremylt 6439560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 6449560d06aSjeremylt 6459560d06aSjeremylt @ref User 6469560d06aSjeremylt **/ 6479560d06aSjeremylt int CeedOperatorReferenceCopy(CeedOperator op, CeedOperator *op_copy) { 6489560d06aSjeremylt int ierr; 6499560d06aSjeremylt 6509560d06aSjeremylt ierr = CeedOperatorReference(op); CeedChk(ierr); 6519560d06aSjeremylt ierr = CeedOperatorDestroy(op_copy); CeedChk(ierr); 6529560d06aSjeremylt *op_copy = op; 6539560d06aSjeremylt return CEED_ERROR_SUCCESS; 6549560d06aSjeremylt } 6559560d06aSjeremylt 6569560d06aSjeremylt /** 657b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 658d7b241e6Sjeremylt 659d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 660d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 661d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 662d7b241e6Sjeremylt 663d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 664d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 665d7b241e6Sjeremylt input and at most one active output. 666d7b241e6Sjeremylt 6678c91a0c9SJeremy L Thompson @param op CeedOperator on which to provide the field 668d1d35e2fSjeremylt @param field_name Name of the field (to be matched with the name used by 6698795c945Sjeremylt CeedQFunction) 670b11c1e72Sjeremylt @param r CeedElemRestriction 6714cc79fe7SJed Brown @param b CeedBasis in which the field resides or @ref CEED_BASIS_COLLOCATED 672b11c1e72Sjeremylt if collocated with quadrature points 6734cc79fe7SJed Brown @param v CeedVector to be used by CeedOperator or @ref CEED_VECTOR_ACTIVE 6744cc79fe7SJed Brown if field is active or @ref CEED_VECTOR_NONE if using 6754cc79fe7SJed Brown @ref CEED_EVAL_WEIGHT in the QFunction 676b11c1e72Sjeremylt 677b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 678dfdf5a53Sjeremylt 6797a982d89SJeremy L. Thompson @ref User 680b11c1e72Sjeremylt **/ 681d1d35e2fSjeremylt int CeedOperatorSetField(CeedOperator op, const char *field_name, 682a8d32208Sjeremylt CeedElemRestriction r, CeedBasis b, CeedVector v) { 683d7b241e6Sjeremylt int ierr; 684f04ea552SJeremy L Thompson if (op->is_composite) 685c042f62fSJeremy L Thompson // LCOV_EXCL_START 686e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 687e15f9bd0SJeremy L Thompson "Cannot add field to composite operator."); 688c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 689f04ea552SJeremy L Thompson if (op->is_immutable) 690f04ea552SJeremy L Thompson // LCOV_EXCL_START 691f04ea552SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 692f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 693f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 6948b067b84SJed Brown if (!r) 695c042f62fSJeremy L Thompson // LCOV_EXCL_START 696e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 697c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 698d1d35e2fSjeremylt field_name); 699c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 7008b067b84SJed Brown if (!b) 701c042f62fSJeremy L Thompson // LCOV_EXCL_START 702e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 703e15f9bd0SJeremy L Thompson "Basis b for field \"%s\" must be non-NULL.", 704d1d35e2fSjeremylt field_name); 705c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 7068b067b84SJed Brown if (!v) 707c042f62fSJeremy L Thompson // LCOV_EXCL_START 708e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 709e15f9bd0SJeremy L Thompson "Vector v for field \"%s\" must be non-NULL.", 710d1d35e2fSjeremylt field_name); 711c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 71252d6035fSJeremy L Thompson 713d1d35e2fSjeremylt CeedInt num_elem; 714d1d35e2fSjeremylt ierr = CeedElemRestrictionGetNumElements(r, &num_elem); CeedChk(ierr); 715d1d35e2fSjeremylt if (r != CEED_ELEMRESTRICTION_NONE && op->has_restriction && 716d1d35e2fSjeremylt op->num_elem != num_elem) 717c042f62fSJeremy L Thompson // LCOV_EXCL_START 718e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 7191d102b48SJeremy L Thompson "ElemRestriction with %d elements incompatible with prior " 720d1d35e2fSjeremylt "%d elements", num_elem, op->num_elem); 721c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 722d7b241e6Sjeremylt 72378464608Sjeremylt CeedInt num_qpts = 0; 724e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 725d1d35e2fSjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &num_qpts); CeedChk(ierr); 726d1d35e2fSjeremylt if (op->num_qpts && op->num_qpts != num_qpts) 727c042f62fSJeremy L Thompson // LCOV_EXCL_START 728e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 729e15f9bd0SJeremy L Thompson "Basis with %d quadrature points " 730d1d35e2fSjeremylt "incompatible with prior %d points", num_qpts, 731d1d35e2fSjeremylt op->num_qpts); 732c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 733d7b241e6Sjeremylt } 734d1d35e2fSjeremylt CeedQFunctionField qf_field; 735d1d35e2fSjeremylt CeedOperatorField *op_field; 736*2b104005SJeremy L Thompson bool is_input = true; 737d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_input_fields; i++) { 738d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->input_fields[i]).field_name)) { 739d1d35e2fSjeremylt qf_field = op->qf->input_fields[i]; 740d1d35e2fSjeremylt op_field = &op->input_fields[i]; 741d7b241e6Sjeremylt goto found; 742d7b241e6Sjeremylt } 743d7b241e6Sjeremylt } 744*2b104005SJeremy L Thompson is_input = false; 745d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_output_fields; i++) { 746d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->output_fields[i]).field_name)) { 747d1d35e2fSjeremylt qf_field = op->qf->output_fields[i]; 748d1d35e2fSjeremylt op_field = &op->output_fields[i]; 749d7b241e6Sjeremylt goto found; 750d7b241e6Sjeremylt } 751d7b241e6Sjeremylt } 752c042f62fSJeremy L Thompson // LCOV_EXCL_START 753e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPLETE, 754e15f9bd0SJeremy L Thompson "QFunction has no knowledge of field '%s'", 755d1d35e2fSjeremylt field_name); 756c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 757d7b241e6Sjeremylt found: 758d1d35e2fSjeremylt ierr = CeedOperatorCheckField(op->ceed, qf_field, r, b); CeedChk(ierr); 759d1d35e2fSjeremylt ierr = CeedCalloc(1, op_field); CeedChk(ierr); 760e15f9bd0SJeremy L Thompson 761*2b104005SJeremy L Thompson if (v == CEED_VECTOR_ACTIVE) { 762*2b104005SJeremy L Thompson CeedSize l_size; 763*2b104005SJeremy L Thompson ierr = CeedElemRestrictionGetLVectorSize(r, &l_size); CeedChk(ierr); 764*2b104005SJeremy L Thompson if (is_input) { 765*2b104005SJeremy L Thompson if (op->input_size == -1) op->input_size = l_size; 766*2b104005SJeremy L Thompson if (l_size != op->input_size) 767*2b104005SJeremy L Thompson // LCOV_EXCL_START 768*2b104005SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 769*2b104005SJeremy L Thompson "LVector size %td does not match previous size %td", 770*2b104005SJeremy L Thompson l_size, op->input_size); 771*2b104005SJeremy L Thompson // LCOV_EXCL_STOP 772*2b104005SJeremy L Thompson } else { 773*2b104005SJeremy L Thompson if (op->output_size == -1) op->output_size = l_size; 774*2b104005SJeremy L Thompson if (l_size != op->output_size) 775*2b104005SJeremy L Thompson // LCOV_EXCL_START 776*2b104005SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 777*2b104005SJeremy L Thompson "LVector size %td does not match previous size %td", 778*2b104005SJeremy L Thompson l_size, op->output_size); 779*2b104005SJeremy L Thompson // LCOV_EXCL_STOP 780*2b104005SJeremy L Thompson } 781*2b104005SJeremy L Thompson } 782*2b104005SJeremy L Thompson 783d1d35e2fSjeremylt (*op_field)->vec = v; 784e15f9bd0SJeremy L Thompson if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) { 7859560d06aSjeremylt ierr = CeedVectorReference(v); CeedChk(ierr); 786e15f9bd0SJeremy L Thompson } 787e15f9bd0SJeremy L Thompson 788d1d35e2fSjeremylt (*op_field)->elem_restr = r; 7899560d06aSjeremylt ierr = CeedElemRestrictionReference(r); CeedChk(ierr); 790e15f9bd0SJeremy L Thompson if (r != CEED_ELEMRESTRICTION_NONE) { 791d1d35e2fSjeremylt op->num_elem = num_elem; 792d1d35e2fSjeremylt op->has_restriction = true; // Restriction set, but num_elem may be 0 793e15f9bd0SJeremy L Thompson } 794d99fa3c5SJeremy L Thompson 795d1d35e2fSjeremylt (*op_field)->basis = b; 796e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 797cd4dfc48Sjeremylt if (!op->num_qpts) { 798cd4dfc48Sjeremylt ierr = CeedOperatorSetNumQuadraturePoints(op, num_qpts); CeedChk(ierr); 799cd4dfc48Sjeremylt } 8009560d06aSjeremylt ierr = CeedBasisReference(b); CeedChk(ierr); 801e15f9bd0SJeremy L Thompson } 802e15f9bd0SJeremy L Thompson 803d1d35e2fSjeremylt op->num_fields += 1; 804f7e22acaSJeremy L Thompson ierr = CeedStringAllocCopy(field_name, (char **)&(*op_field)->field_name); 805f7e22acaSJeremy L Thompson CeedChk(ierr); 806e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 807d7b241e6Sjeremylt } 808d7b241e6Sjeremylt 809d7b241e6Sjeremylt /** 81043bbe138SJeremy L Thompson @brief Get the CeedOperatorFields of a CeedOperator 81143bbe138SJeremy L Thompson 812f04ea552SJeremy L Thompson Note: Calling this function asserts that setup is complete 813f04ea552SJeremy L Thompson and sets the CeedOperator as immutable. 814f04ea552SJeremy L Thompson 81543bbe138SJeremy L Thompson @param op CeedOperator 816f74ec584SJeremy L Thompson @param[out] num_input_fields Variable to store number of input fields 81743bbe138SJeremy L Thompson @param[out] input_fields Variable to store input_fields 818f74ec584SJeremy L Thompson @param[out] num_output_fields Variable to store number of output fields 81943bbe138SJeremy L Thompson @param[out] output_fields Variable to store output_fields 82043bbe138SJeremy L Thompson 82143bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 82243bbe138SJeremy L Thompson 823e9b533fbSJeremy L Thompson @ref Advanced 82443bbe138SJeremy L Thompson **/ 82543bbe138SJeremy L Thompson int CeedOperatorGetFields(CeedOperator op, CeedInt *num_input_fields, 82643bbe138SJeremy L Thompson CeedOperatorField **input_fields, 82743bbe138SJeremy L Thompson CeedInt *num_output_fields, 82843bbe138SJeremy L Thompson CeedOperatorField **output_fields) { 829f04ea552SJeremy L Thompson int ierr; 830f04ea552SJeremy L Thompson 831f04ea552SJeremy L Thompson if (op->is_composite) 83243bbe138SJeremy L Thompson // LCOV_EXCL_START 83343bbe138SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 83443bbe138SJeremy L Thompson "Not defined for composite operator"); 83543bbe138SJeremy L Thompson // LCOV_EXCL_STOP 836f04ea552SJeremy L Thompson ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 83743bbe138SJeremy L Thompson 83843bbe138SJeremy L Thompson if (num_input_fields) *num_input_fields = op->qf->num_input_fields; 83943bbe138SJeremy L Thompson if (input_fields) *input_fields = op->input_fields; 84043bbe138SJeremy L Thompson if (num_output_fields) *num_output_fields = op->qf->num_output_fields; 84143bbe138SJeremy L Thompson if (output_fields) *output_fields = op->output_fields; 84243bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 84343bbe138SJeremy L Thompson } 84443bbe138SJeremy L Thompson 84543bbe138SJeremy L Thompson /** 84628567f8fSJeremy L Thompson @brief Get the name of a CeedOperatorField 84728567f8fSJeremy L Thompson 84828567f8fSJeremy L Thompson @param op_field CeedOperatorField 84928567f8fSJeremy L Thompson @param[out] field_name Variable to store the field name 85028567f8fSJeremy L Thompson 85128567f8fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 85228567f8fSJeremy L Thompson 853e9b533fbSJeremy L Thompson @ref Advanced 85428567f8fSJeremy L Thompson **/ 85528567f8fSJeremy L Thompson int CeedOperatorFieldGetName(CeedOperatorField op_field, char **field_name) { 85628567f8fSJeremy L Thompson *field_name = (char *)op_field->field_name; 85728567f8fSJeremy L Thompson return CEED_ERROR_SUCCESS; 85828567f8fSJeremy L Thompson } 85928567f8fSJeremy L Thompson 86028567f8fSJeremy L Thompson /** 86143bbe138SJeremy L Thompson @brief Get the CeedElemRestriction of a CeedOperatorField 86243bbe138SJeremy L Thompson 86343bbe138SJeremy L Thompson @param op_field CeedOperatorField 86443bbe138SJeremy L Thompson @param[out] rstr Variable to store CeedElemRestriction 86543bbe138SJeremy L Thompson 86643bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 86743bbe138SJeremy L Thompson 868e9b533fbSJeremy L Thompson @ref Advanced 86943bbe138SJeremy L Thompson **/ 87043bbe138SJeremy L Thompson int CeedOperatorFieldGetElemRestriction(CeedOperatorField op_field, 87143bbe138SJeremy L Thompson CeedElemRestriction *rstr) { 87243bbe138SJeremy L Thompson *rstr = op_field->elem_restr; 87343bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 87443bbe138SJeremy L Thompson } 87543bbe138SJeremy L Thompson 87643bbe138SJeremy L Thompson /** 87743bbe138SJeremy L Thompson @brief Get the CeedBasis of a CeedOperatorField 87843bbe138SJeremy L Thompson 87943bbe138SJeremy L Thompson @param op_field CeedOperatorField 88043bbe138SJeremy L Thompson @param[out] basis Variable to store CeedBasis 88143bbe138SJeremy L Thompson 88243bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 88343bbe138SJeremy L Thompson 884e9b533fbSJeremy L Thompson @ref Advanced 88543bbe138SJeremy L Thompson **/ 88643bbe138SJeremy L Thompson int CeedOperatorFieldGetBasis(CeedOperatorField op_field, CeedBasis *basis) { 88743bbe138SJeremy L Thompson *basis = op_field->basis; 88843bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 88943bbe138SJeremy L Thompson } 89043bbe138SJeremy L Thompson 89143bbe138SJeremy L Thompson /** 89243bbe138SJeremy L Thompson @brief Get the CeedVector of a CeedOperatorField 89343bbe138SJeremy L Thompson 89443bbe138SJeremy L Thompson @param op_field CeedOperatorField 89543bbe138SJeremy L Thompson @param[out] vec Variable to store CeedVector 89643bbe138SJeremy L Thompson 89743bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 89843bbe138SJeremy L Thompson 899e9b533fbSJeremy L Thompson @ref Advanced 90043bbe138SJeremy L Thompson **/ 90143bbe138SJeremy L Thompson int CeedOperatorFieldGetVector(CeedOperatorField op_field, CeedVector *vec) { 90243bbe138SJeremy L Thompson *vec = op_field->vec; 90343bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 90443bbe138SJeremy L Thompson } 90543bbe138SJeremy L Thompson 90643bbe138SJeremy L Thompson /** 90752d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 908288c0443SJeremy L Thompson 909d1d35e2fSjeremylt @param[out] composite_op Composite CeedOperator 910d1d35e2fSjeremylt @param sub_op Sub-operator CeedOperator 91152d6035fSJeremy L Thompson 91252d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 91352d6035fSJeremy L Thompson 9147a982d89SJeremy L. Thompson @ref User 91552d6035fSJeremy L Thompson */ 916d1d35e2fSjeremylt int CeedCompositeOperatorAddSub(CeedOperator composite_op, 917d1d35e2fSjeremylt CeedOperator sub_op) { 91834359f16Sjeremylt int ierr; 91934359f16Sjeremylt 920f04ea552SJeremy L Thompson if (!composite_op->is_composite) 921c042f62fSJeremy L Thompson // LCOV_EXCL_START 922d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_MINOR, 923e2f04181SAndrew T. Barker "CeedOperator is not a composite operator"); 924c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 92552d6035fSJeremy L Thompson 926d1d35e2fSjeremylt if (composite_op->num_suboperators == CEED_COMPOSITE_MAX) 927c042f62fSJeremy L Thompson // LCOV_EXCL_START 928d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_UNSUPPORTED, 929*2b104005SJeremy L Thompson "Cannot add additional sub-operators"); 930c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 931f04ea552SJeremy L Thompson if (composite_op->is_immutable) 932f04ea552SJeremy L Thompson // LCOV_EXCL_START 933f04ea552SJeremy L Thompson return CeedError(composite_op->ceed, CEED_ERROR_MAJOR, 934f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 935f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 93652d6035fSJeremy L Thompson 937*2b104005SJeremy L Thompson { 938*2b104005SJeremy L Thompson CeedSize input_size, output_size; 939*2b104005SJeremy L Thompson ierr = CeedOperatorGetActiveVectorLengths(sub_op, &input_size, &output_size); 940*2b104005SJeremy L Thompson CeedChk(ierr); 941*2b104005SJeremy L Thompson if (composite_op->input_size == -1) composite_op->input_size = input_size; 942*2b104005SJeremy L Thompson if (composite_op->output_size == -1) composite_op->output_size = output_size; 943*2b104005SJeremy L Thompson // Note, a size of -1 means no active vector restriction set, so no incompatibility 944*2b104005SJeremy L Thompson if ((input_size != -1 && input_size != composite_op->input_size) || 945*2b104005SJeremy L Thompson (output_size != -1 && output_size != composite_op->output_size)) 946*2b104005SJeremy L Thompson // LCOV_EXCL_START 947*2b104005SJeremy L Thompson return CeedError(composite_op->ceed, CEED_ERROR_MAJOR, 948*2b104005SJeremy L Thompson "Sub-operators must have compatible dimensions; " 949*2b104005SJeremy L Thompson "composite operator of shape (%td, %td) not compatible with " 950*2b104005SJeremy L Thompson "sub-operator of shape (%td, %td)", 951*2b104005SJeremy L Thompson composite_op->input_size, composite_op->output_size, input_size, output_size); 952*2b104005SJeremy L Thompson // LCOV_EXCL_STOP 953*2b104005SJeremy L Thompson } 954*2b104005SJeremy L Thompson 955d1d35e2fSjeremylt composite_op->sub_operators[composite_op->num_suboperators] = sub_op; 9569560d06aSjeremylt ierr = CeedOperatorReference(sub_op); CeedChk(ierr); 957d1d35e2fSjeremylt composite_op->num_suboperators++; 958e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 95952d6035fSJeremy L Thompson } 96052d6035fSJeremy L Thompson 96152d6035fSJeremy L Thompson /** 9624db537f9SJeremy L Thompson @brief Check if a CeedOperator is ready to be used. 9634db537f9SJeremy L Thompson 9644db537f9SJeremy L Thompson @param[in] op CeedOperator to check 9654db537f9SJeremy L Thompson 9664db537f9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 9674db537f9SJeremy L Thompson 9684db537f9SJeremy L Thompson @ref User 9694db537f9SJeremy L Thompson **/ 9704db537f9SJeremy L Thompson int CeedOperatorCheckReady(CeedOperator op) { 9714db537f9SJeremy L Thompson int ierr; 9724db537f9SJeremy L Thompson Ceed ceed; 9734db537f9SJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 9744db537f9SJeremy L Thompson 9754db537f9SJeremy L Thompson if (op->is_interface_setup) 9764db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 9774db537f9SJeremy L Thompson 9784db537f9SJeremy L Thompson CeedQFunction qf = op->qf; 9794db537f9SJeremy L Thompson if (op->is_composite) { 9804db537f9SJeremy L Thompson if (!op->num_suboperators) 9814db537f9SJeremy L Thompson // LCOV_EXCL_START 9824db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "No sub_operators set"); 9834db537f9SJeremy L Thompson // LCOV_EXCL_STOP 9844db537f9SJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 9854db537f9SJeremy L Thompson ierr = CeedOperatorCheckReady(op->sub_operators[i]); CeedChk(ierr); 9864db537f9SJeremy L Thompson } 987*2b104005SJeremy L Thompson // Sub-operators could be modified after adding to composite operator 988*2b104005SJeremy L Thompson // Need to verify no lvec incompatibility from any changes 989*2b104005SJeremy L Thompson CeedSize input_size, output_size; 990*2b104005SJeremy L Thompson ierr = CeedOperatorGetActiveVectorLengths(op, &input_size, &output_size); 991*2b104005SJeremy L Thompson CeedChk(ierr); 9924db537f9SJeremy L Thompson } else { 9934db537f9SJeremy L Thompson if (op->num_fields == 0) 9944db537f9SJeremy L Thompson // LCOV_EXCL_START 9954db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "No operator fields set"); 9964db537f9SJeremy L Thompson // LCOV_EXCL_STOP 9974db537f9SJeremy L Thompson if (op->num_fields < qf->num_input_fields + qf->num_output_fields) 9984db537f9SJeremy L Thompson // LCOV_EXCL_START 9994db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "Not all operator fields set"); 10004db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10014db537f9SJeremy L Thompson if (!op->has_restriction) 10024db537f9SJeremy L Thompson // LCOV_EXCL_START 10034db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, 10044db537f9SJeremy L Thompson "At least one restriction required"); 10054db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10064db537f9SJeremy L Thompson if (op->num_qpts == 0) 10074db537f9SJeremy L Thompson // LCOV_EXCL_START 10084db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, 10094db537f9SJeremy L Thompson "At least one non-collocated basis is required " 10104db537f9SJeremy L Thompson "or the number of quadrature points must be set"); 10114db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10124db537f9SJeremy L Thompson } 10134db537f9SJeremy L Thompson 10144db537f9SJeremy L Thompson // Flag as immutable and ready 10154db537f9SJeremy L Thompson op->is_interface_setup = true; 10164db537f9SJeremy L Thompson if (op->qf && op->qf != CEED_QFUNCTION_NONE) 10174db537f9SJeremy L Thompson // LCOV_EXCL_START 10184db537f9SJeremy L Thompson op->qf->is_immutable = true; 10194db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10204db537f9SJeremy L Thompson if (op->dqf && op->dqf != CEED_QFUNCTION_NONE) 10214db537f9SJeremy L Thompson // LCOV_EXCL_START 10224db537f9SJeremy L Thompson op->dqf->is_immutable = true; 10234db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10244db537f9SJeremy L Thompson if (op->dqfT && op->dqfT != CEED_QFUNCTION_NONE) 10254db537f9SJeremy L Thompson // LCOV_EXCL_START 10264db537f9SJeremy L Thompson op->dqfT->is_immutable = true; 10274db537f9SJeremy L Thompson // LCOV_EXCL_STOP 10284db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 10294db537f9SJeremy L Thompson } 10304db537f9SJeremy L Thompson 10314db537f9SJeremy L Thompson /** 1032c9366a6bSJeremy L Thompson @brief Get vector lengths for the active input and/or output vectors of a CeedOperator. 1033c9366a6bSJeremy L Thompson Note: Lengths of -1 indicate that the CeedOperator does not have an 1034c9366a6bSJeremy L Thompson active input and/or output. 1035c9366a6bSJeremy L Thompson 1036c9366a6bSJeremy L Thompson @param[in] op CeedOperator 1037c9366a6bSJeremy L Thompson @param[out] input_size Variable to store active input vector length, or NULL 1038c9366a6bSJeremy L Thompson @param[out] output_size Variable to store active output vector length, or NULL 1039c9366a6bSJeremy L Thompson 1040c9366a6bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1041c9366a6bSJeremy L Thompson 1042c9366a6bSJeremy L Thompson @ref User 1043c9366a6bSJeremy L Thompson **/ 1044c9366a6bSJeremy L Thompson int CeedOperatorGetActiveVectorLengths(CeedOperator op, CeedSize *input_size, 1045c9366a6bSJeremy L Thompson CeedSize *output_size) { 1046c9366a6bSJeremy L Thompson int ierr; 1047c9366a6bSJeremy L Thompson bool is_composite; 1048c9366a6bSJeremy L Thompson 1049*2b104005SJeremy L Thompson if (input_size) *input_size = op->input_size; 1050*2b104005SJeremy L Thompson if (output_size) *output_size = op->output_size; 1051c9366a6bSJeremy L Thompson 1052c9366a6bSJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 1053*2b104005SJeremy L Thompson if (is_composite && (op->input_size == -1 || op->output_size == -1)) { 1054c9366a6bSJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 1055c9366a6bSJeremy L Thompson CeedSize sub_input_size, sub_output_size; 1056c9366a6bSJeremy L Thompson ierr = CeedOperatorGetActiveVectorLengths(op->sub_operators[i], 1057*2b104005SJeremy L Thompson &sub_input_size, &sub_output_size); CeedChk(ierr); 1058*2b104005SJeremy L Thompson if (op->input_size == -1) op->input_size = sub_input_size; 1059*2b104005SJeremy L Thompson if (op->output_size == -1) op->output_size = sub_output_size; 1060*2b104005SJeremy L Thompson // Note, a size of -1 means no active vector restriction set, so no incompatibility 1061*2b104005SJeremy L Thompson if ((sub_input_size != -1 && sub_input_size != op->input_size) || 1062*2b104005SJeremy L Thompson (sub_output_size != -1 && sub_output_size != op->output_size)) 1063*2b104005SJeremy L Thompson // LCOV_EXCL_START 1064*2b104005SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 1065*2b104005SJeremy L Thompson "Sub-operators must have compatible dimensions; " 1066*2b104005SJeremy L Thompson "composite operator of shape (%td, %td) not compatible with " 1067*2b104005SJeremy L Thompson "sub-operator of shape (%td, %td)", 1068*2b104005SJeremy L Thompson op->input_size, op->output_size, input_size, output_size); 1069*2b104005SJeremy L Thompson // LCOV_EXCL_STOP 1070c9366a6bSJeremy L Thompson } 1071c9366a6bSJeremy L Thompson } 1072c9366a6bSJeremy L Thompson 1073c9366a6bSJeremy L Thompson return CEED_ERROR_SUCCESS; 1074c9366a6bSJeremy L Thompson } 1075c9366a6bSJeremy L Thompson 1076c9366a6bSJeremy L Thompson /** 1077beecbf24SJeremy L Thompson @brief Set reuse of CeedQFunction data in CeedOperatorLinearAssemble* functions. 1078beecbf24SJeremy L Thompson When `reuse_assembly_data = false` (default), the CeedQFunction associated 1079beecbf24SJeremy L Thompson with this CeedOperator is re-assembled every time a `CeedOperatorLinearAssemble*` 1080beecbf24SJeremy L Thompson function is called. 1081beecbf24SJeremy L Thompson When `reuse_assembly_data = true`, the CeedQFunction associated with 1082beecbf24SJeremy L Thompson this CeedOperator is reused between calls to 1083beecbf24SJeremy L Thompson `CeedOperatorSetQFunctionAssemblyDataUpdated`. 10848b919e6bSJeremy L Thompson 1085beecbf24SJeremy L Thompson @param[in] op CeedOperator 1086beecbf24SJeremy L Thompson @param[in] reuse_assembly_data Boolean flag setting assembly data reuse 10878b919e6bSJeremy L Thompson 10888b919e6bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 10898b919e6bSJeremy L Thompson 10908b919e6bSJeremy L Thompson @ref Advanced 10918b919e6bSJeremy L Thompson **/ 1092beecbf24SJeremy L Thompson int CeedOperatorSetQFunctionAssemblyReuse(CeedOperator op, 1093beecbf24SJeremy L Thompson bool reuse_assembly_data) { 10948b919e6bSJeremy L Thompson int ierr; 10958b919e6bSJeremy L Thompson bool is_composite; 10968b919e6bSJeremy L Thompson 10978b919e6bSJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 10988b919e6bSJeremy L Thompson if (is_composite) { 10998b919e6bSJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 1100beecbf24SJeremy L Thompson ierr = CeedOperatorSetQFunctionAssemblyReuse(op->sub_operators[i], 1101beecbf24SJeremy L Thompson reuse_assembly_data); CeedChk(ierr); 11028b919e6bSJeremy L Thompson } 11038b919e6bSJeremy L Thompson } else { 1104beecbf24SJeremy L Thompson ierr = CeedQFunctionAssemblyDataSetReuse(op->qf_assembled, reuse_assembly_data); 1105beecbf24SJeremy L Thompson CeedChk(ierr); 1106beecbf24SJeremy L Thompson } 1107beecbf24SJeremy L Thompson 1108beecbf24SJeremy L Thompson return CEED_ERROR_SUCCESS; 1109beecbf24SJeremy L Thompson } 1110beecbf24SJeremy L Thompson 1111beecbf24SJeremy L Thompson /** 1112beecbf24SJeremy L Thompson @brief Mark CeedQFunction data as updated and the CeedQFunction as requiring re-assembly. 1113beecbf24SJeremy L Thompson 1114beecbf24SJeremy L Thompson @param[in] op CeedOperator 1115beecbf24SJeremy L Thompson @param[in] reuse_assembly_data Boolean flag setting assembly data reuse 1116beecbf24SJeremy L Thompson 1117beecbf24SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1118beecbf24SJeremy L Thompson 1119beecbf24SJeremy L Thompson @ref Advanced 1120beecbf24SJeremy L Thompson **/ 1121beecbf24SJeremy L Thompson int CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(CeedOperator op, 1122beecbf24SJeremy L Thompson bool needs_data_update) { 1123beecbf24SJeremy L Thompson int ierr; 1124beecbf24SJeremy L Thompson bool is_composite; 1125beecbf24SJeremy L Thompson 1126beecbf24SJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 1127beecbf24SJeremy L Thompson if (is_composite) { 1128beecbf24SJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 1129beecbf24SJeremy L Thompson ierr = CeedOperatorSetQFunctionAssemblyDataUpdateNeeded(op->sub_operators[i], 1130beecbf24SJeremy L Thompson needs_data_update); CeedChk(ierr); 1131beecbf24SJeremy L Thompson } 1132beecbf24SJeremy L Thompson } else { 1133beecbf24SJeremy L Thompson ierr = CeedQFunctionAssemblyDataSetUpdateNeeded(op->qf_assembled, 1134beecbf24SJeremy L Thompson needs_data_update); 11358b919e6bSJeremy L Thompson CeedChk(ierr); 11368b919e6bSJeremy L Thompson } 11378b919e6bSJeremy L Thompson 11388b919e6bSJeremy L Thompson return CEED_ERROR_SUCCESS; 11398b919e6bSJeremy L Thompson } 11408b919e6bSJeremy L Thompson 11418b919e6bSJeremy L Thompson /** 1142cd4dfc48Sjeremylt @brief Set the number of quadrature points associated with a CeedOperator. 1143cd4dfc48Sjeremylt This should be used when creating a CeedOperator where every 1144cd4dfc48Sjeremylt field has a collocated basis. This function cannot be used for 1145cd4dfc48Sjeremylt composite CeedOperators. 1146cd4dfc48Sjeremylt 1147cd4dfc48Sjeremylt @param op CeedOperator 1148cd4dfc48Sjeremylt @param num_qpts Number of quadrature points to set 1149cd4dfc48Sjeremylt 1150cd4dfc48Sjeremylt @return An error code: 0 - success, otherwise - failure 1151cd4dfc48Sjeremylt 1152e9b533fbSJeremy L Thompson @ref Advanced 1153cd4dfc48Sjeremylt **/ 1154cd4dfc48Sjeremylt int CeedOperatorSetNumQuadraturePoints(CeedOperator op, CeedInt num_qpts) { 1155f04ea552SJeremy L Thompson if (op->is_composite) 1156cd4dfc48Sjeremylt // LCOV_EXCL_START 1157cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 1158cd4dfc48Sjeremylt "Not defined for composite operator"); 1159cd4dfc48Sjeremylt // LCOV_EXCL_STOP 1160cd4dfc48Sjeremylt if (op->num_qpts) 1161cd4dfc48Sjeremylt // LCOV_EXCL_START 1162cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 1163cd4dfc48Sjeremylt "Number of quadrature points already defined"); 1164cd4dfc48Sjeremylt // LCOV_EXCL_STOP 1165f04ea552SJeremy L Thompson if (op->is_immutable) 1166f04ea552SJeremy L Thompson // LCOV_EXCL_START 1167f04ea552SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 1168f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 1169f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 1170cd4dfc48Sjeremylt 1171cd4dfc48Sjeremylt op->num_qpts = num_qpts; 1172cd4dfc48Sjeremylt return CEED_ERROR_SUCCESS; 1173cd4dfc48Sjeremylt } 1174cd4dfc48Sjeremylt 1175cd4dfc48Sjeremylt /** 11767a982d89SJeremy L. Thompson @brief View a CeedOperator 11777a982d89SJeremy L. Thompson 11787a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 11797a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 11807a982d89SJeremy L. Thompson 11817a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 11827a982d89SJeremy L. Thompson 11837a982d89SJeremy L. Thompson @ref User 11847a982d89SJeremy L. Thompson **/ 11857a982d89SJeremy L. Thompson int CeedOperatorView(CeedOperator op, FILE *stream) { 11867a982d89SJeremy L. Thompson int ierr; 11877a982d89SJeremy L. Thompson 1188f04ea552SJeremy L Thompson if (op->is_composite) { 11897a982d89SJeremy L. Thompson fprintf(stream, "Composite CeedOperator\n"); 11907a982d89SJeremy L. Thompson 1191d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 11927a982d89SJeremy L. Thompson fprintf(stream, " SubOperator [%d]:\n", i); 1193d1d35e2fSjeremylt ierr = CeedOperatorSingleView(op->sub_operators[i], 1, stream); 11947a982d89SJeremy L. Thompson CeedChk(ierr); 11957a982d89SJeremy L. Thompson } 11967a982d89SJeremy L. Thompson } else { 11977a982d89SJeremy L. Thompson fprintf(stream, "CeedOperator\n"); 11987a982d89SJeremy L. Thompson ierr = CeedOperatorSingleView(op, 0, stream); CeedChk(ierr); 11997a982d89SJeremy L. Thompson } 1200e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 12017a982d89SJeremy L. Thompson } 12023bd813ffSjeremylt 12033bd813ffSjeremylt /** 1204b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedOperator 1205b7c9bbdaSJeremy L Thompson 1206b7c9bbdaSJeremy L Thompson @param op CeedOperator 1207b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 1208b7c9bbdaSJeremy L Thompson 1209b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1210b7c9bbdaSJeremy L Thompson 1211b7c9bbdaSJeremy L Thompson @ref Advanced 1212b7c9bbdaSJeremy L Thompson **/ 1213b7c9bbdaSJeremy L Thompson int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 1214b7c9bbdaSJeremy L Thompson *ceed = op->ceed; 1215b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1216b7c9bbdaSJeremy L Thompson } 1217b7c9bbdaSJeremy L Thompson 1218b7c9bbdaSJeremy L Thompson /** 1219b7c9bbdaSJeremy L Thompson @brief Get the number of elements associated with a CeedOperator 1220b7c9bbdaSJeremy L Thompson 1221b7c9bbdaSJeremy L Thompson @param op CeedOperator 1222b7c9bbdaSJeremy L Thompson @param[out] num_elem Variable to store number of elements 1223b7c9bbdaSJeremy L Thompson 1224b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1225b7c9bbdaSJeremy L Thompson 1226b7c9bbdaSJeremy L Thompson @ref Advanced 1227b7c9bbdaSJeremy L Thompson **/ 1228b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumElements(CeedOperator op, CeedInt *num_elem) { 1229b7c9bbdaSJeremy L Thompson if (op->is_composite) 1230b7c9bbdaSJeremy L Thompson // LCOV_EXCL_START 1231b7c9bbdaSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 1232b7c9bbdaSJeremy L Thompson "Not defined for composite operator"); 1233b7c9bbdaSJeremy L Thompson // LCOV_EXCL_STOP 1234b7c9bbdaSJeremy L Thompson 1235b7c9bbdaSJeremy L Thompson *num_elem = op->num_elem; 1236b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1237b7c9bbdaSJeremy L Thompson } 1238b7c9bbdaSJeremy L Thompson 1239b7c9bbdaSJeremy L Thompson /** 1240b7c9bbdaSJeremy L Thompson @brief Get the number of quadrature points associated with a CeedOperator 1241b7c9bbdaSJeremy L Thompson 1242b7c9bbdaSJeremy L Thompson @param op CeedOperator 1243b7c9bbdaSJeremy L Thompson @param[out] num_qpts Variable to store vector number of quadrature points 1244b7c9bbdaSJeremy L Thompson 1245b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1246b7c9bbdaSJeremy L Thompson 1247b7c9bbdaSJeremy L Thompson @ref Advanced 1248b7c9bbdaSJeremy L Thompson **/ 1249b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *num_qpts) { 1250b7c9bbdaSJeremy L Thompson if (op->is_composite) 1251b7c9bbdaSJeremy L Thompson // LCOV_EXCL_START 1252b7c9bbdaSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 1253b7c9bbdaSJeremy L Thompson "Not defined for composite operator"); 1254b7c9bbdaSJeremy L Thompson // LCOV_EXCL_STOP 1255b7c9bbdaSJeremy L Thompson 1256b7c9bbdaSJeremy L Thompson *num_qpts = op->num_qpts; 1257b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1258b7c9bbdaSJeremy L Thompson } 1259b7c9bbdaSJeremy L Thompson 1260b7c9bbdaSJeremy L Thompson /** 12613668ca4bSJeremy L Thompson @brief Get label for a registered QFunctionContext field, or `NULL` if no 12623668ca4bSJeremy L Thompson field has been registered with this `field_name`. 12633668ca4bSJeremy L Thompson 12643668ca4bSJeremy L Thompson @param[in] op CeedOperator 12653668ca4bSJeremy L Thompson @param[in] field_name Name of field to retrieve label 12663668ca4bSJeremy L Thompson @param[out] field_label Variable to field label 12673668ca4bSJeremy L Thompson 12683668ca4bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 12693668ca4bSJeremy L Thompson 12703668ca4bSJeremy L Thompson @ref User 12713668ca4bSJeremy L Thompson **/ 12723668ca4bSJeremy L Thompson int CeedOperatorContextGetFieldLabel(CeedOperator op, 12733668ca4bSJeremy L Thompson const char *field_name, 12743668ca4bSJeremy L Thompson CeedContextFieldLabel *field_label) { 12753668ca4bSJeremy L Thompson int ierr; 12763668ca4bSJeremy L Thompson 12773668ca4bSJeremy L Thompson bool is_composite; 12783668ca4bSJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 12793668ca4bSJeremy L Thompson if (is_composite) { 12803668ca4bSJeremy L Thompson // Check if composite label already created 12813668ca4bSJeremy L Thompson for (CeedInt i=0; i<op->num_context_labels; i++) { 12823668ca4bSJeremy L Thompson if (!strcmp(op->context_labels[i]->name, field_name)) { 12833668ca4bSJeremy L Thompson *field_label = op->context_labels[i]; 12843668ca4bSJeremy L Thompson return CEED_ERROR_SUCCESS; 12853668ca4bSJeremy L Thompson } 12863668ca4bSJeremy L Thompson } 12873668ca4bSJeremy L Thompson 12883668ca4bSJeremy L Thompson // Create composite label if needed 12893668ca4bSJeremy L Thompson CeedInt num_sub; 12903668ca4bSJeremy L Thompson CeedOperator *sub_operators; 12913668ca4bSJeremy L Thompson CeedContextFieldLabel new_field_label; 12923668ca4bSJeremy L Thompson 12933668ca4bSJeremy L Thompson ierr = CeedCalloc(1, &new_field_label); CeedChk(ierr); 12943668ca4bSJeremy L Thompson ierr = CeedOperatorGetNumSub(op, &num_sub); CeedChk(ierr); 12953668ca4bSJeremy L Thompson ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 12963668ca4bSJeremy L Thompson ierr = CeedCalloc(num_sub, &new_field_label->sub_labels); CeedChk(ierr); 12973668ca4bSJeremy L Thompson new_field_label->num_sub_labels = num_sub; 12983668ca4bSJeremy L Thompson 12993668ca4bSJeremy L Thompson bool label_found = false; 13003668ca4bSJeremy L Thompson for (CeedInt i=0; i<num_sub; i++) { 13013668ca4bSJeremy L Thompson if (sub_operators[i]->qf->ctx) { 13023668ca4bSJeremy L Thompson CeedContextFieldLabel new_field_label_i; 13033668ca4bSJeremy L Thompson ierr = CeedQFunctionContextGetFieldLabel(sub_operators[i]->qf->ctx, field_name, 13043668ca4bSJeremy L Thompson &new_field_label_i); CeedChk(ierr); 13053668ca4bSJeremy L Thompson if (new_field_label_i) { 13063668ca4bSJeremy L Thompson label_found = true; 13073668ca4bSJeremy L Thompson new_field_label->sub_labels[i] = new_field_label_i; 13083668ca4bSJeremy L Thompson new_field_label->name = new_field_label_i->name; 13093668ca4bSJeremy L Thompson new_field_label->description = new_field_label_i->description; 13107bfe0f0eSJeremy L Thompson if (new_field_label->type && 13117bfe0f0eSJeremy L Thompson new_field_label->type != new_field_label_i->type) { 13127bfe0f0eSJeremy L Thompson // LCOV_EXCL_START 13137bfe0f0eSJeremy L Thompson ierr = CeedFree(&new_field_label); CeedChk(ierr); 13147bfe0f0eSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 13157bfe0f0eSJeremy L Thompson "Incompatible field types on sub-operator contexts. " 13167bfe0f0eSJeremy L Thompson "%s != %s", 13177bfe0f0eSJeremy L Thompson CeedContextFieldTypes[new_field_label->type], 13187bfe0f0eSJeremy L Thompson CeedContextFieldTypes[new_field_label_i->type]); 13197bfe0f0eSJeremy L Thompson // LCOV_EXCL_STOP 13207bfe0f0eSJeremy L Thompson } else { 13217bfe0f0eSJeremy L Thompson new_field_label->type = new_field_label_i->type; 13227bfe0f0eSJeremy L Thompson } 13237bfe0f0eSJeremy L Thompson if (new_field_label->num_values != 0 && 13247bfe0f0eSJeremy L Thompson new_field_label->num_values != new_field_label_i->num_values) { 13257bfe0f0eSJeremy L Thompson // LCOV_EXCL_START 13267bfe0f0eSJeremy L Thompson ierr = CeedFree(&new_field_label); CeedChk(ierr); 13277bfe0f0eSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 13287bfe0f0eSJeremy L Thompson "Incompatible field number of values on sub-operator" 13297bfe0f0eSJeremy L Thompson " contexts. %ld != %ld", 13307bfe0f0eSJeremy L Thompson new_field_label->num_values, new_field_label_i->num_values); 13317bfe0f0eSJeremy L Thompson // LCOV_EXCL_STOP 13327bfe0f0eSJeremy L Thompson } else { 13337bfe0f0eSJeremy L Thompson new_field_label->num_values = new_field_label_i->num_values; 13347bfe0f0eSJeremy L Thompson } 13353668ca4bSJeremy L Thompson } 13363668ca4bSJeremy L Thompson } 13373668ca4bSJeremy L Thompson } 13383668ca4bSJeremy L Thompson if (!label_found) { 13393668ca4bSJeremy L Thompson // LCOV_EXCL_START 1340a48e5f43SJeremy L Thompson ierr = CeedFree(&new_field_label->sub_labels); CeedChk(ierr); 13413668ca4bSJeremy L Thompson ierr = CeedFree(&new_field_label); CeedChk(ierr); 13423668ca4bSJeremy L Thompson *field_label = NULL; 13433668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 13443668ca4bSJeremy L Thompson } else { 13453668ca4bSJeremy L Thompson // Move new composite label to operator 13463668ca4bSJeremy L Thompson if (op->num_context_labels == 0) { 13473668ca4bSJeremy L Thompson ierr = CeedCalloc(1, &op->context_labels); CeedChk(ierr); 13483668ca4bSJeremy L Thompson op->max_context_labels = 1; 13493668ca4bSJeremy L Thompson } else if (op->num_context_labels == op->max_context_labels) { 13503668ca4bSJeremy L Thompson ierr = CeedRealloc(2*op->num_context_labels, &op->context_labels); 13513668ca4bSJeremy L Thompson CeedChk(ierr); 13523668ca4bSJeremy L Thompson op->max_context_labels *= 2; 13533668ca4bSJeremy L Thompson } 13543668ca4bSJeremy L Thompson op->context_labels[op->num_context_labels] = new_field_label; 13553668ca4bSJeremy L Thompson *field_label = new_field_label; 13563668ca4bSJeremy L Thompson op->num_context_labels++; 13573668ca4bSJeremy L Thompson } 13583668ca4bSJeremy L Thompson 13593668ca4bSJeremy L Thompson return CEED_ERROR_SUCCESS; 13603668ca4bSJeremy L Thompson } else { 13613668ca4bSJeremy L Thompson return CeedQFunctionContextGetFieldLabel(op->qf->ctx, field_name, field_label); 13623668ca4bSJeremy L Thompson } 13633668ca4bSJeremy L Thompson } 13643668ca4bSJeremy L Thompson 13653668ca4bSJeremy L Thompson /** 1366d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field holding a double precision value. 1367d8dd9a91SJeremy L Thompson For composite operators, the value is set in all 1368d8dd9a91SJeremy L Thompson sub-operator QFunctionContexts that have a matching `field_name`. 1369d8dd9a91SJeremy L Thompson 1370d8dd9a91SJeremy L Thompson @param op CeedOperator 13713668ca4bSJeremy L Thompson @param field_label Label of field to register 13727bfe0f0eSJeremy L Thompson @param values Values to set 1373d8dd9a91SJeremy L Thompson 1374d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1375d8dd9a91SJeremy L Thompson 1376d8dd9a91SJeremy L Thompson @ref User 1377d8dd9a91SJeremy L Thompson **/ 13783668ca4bSJeremy L Thompson int CeedOperatorContextSetDouble(CeedOperator op, 13793668ca4bSJeremy L Thompson CeedContextFieldLabel field_label, 13807bfe0f0eSJeremy L Thompson double *values) { 13813668ca4bSJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_DOUBLE, 13827bfe0f0eSJeremy L Thompson values); 1383d8dd9a91SJeremy L Thompson } 1384d8dd9a91SJeremy L Thompson 1385d8dd9a91SJeremy L Thompson /** 1386d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field holding an int32 value. 1387d8dd9a91SJeremy L Thompson For composite operators, the value is set in all 1388d8dd9a91SJeremy L Thompson sub-operator QFunctionContexts that have a matching `field_name`. 1389d8dd9a91SJeremy L Thompson 1390d8dd9a91SJeremy L Thompson @param op CeedOperator 13913668ca4bSJeremy L Thompson @param field_label Label of field to set 13927bfe0f0eSJeremy L Thompson @param values Values to set 1393d8dd9a91SJeremy L Thompson 1394d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1395d8dd9a91SJeremy L Thompson 1396d8dd9a91SJeremy L Thompson @ref User 1397d8dd9a91SJeremy L Thompson **/ 13983668ca4bSJeremy L Thompson int CeedOperatorContextSetInt32(CeedOperator op, 13993668ca4bSJeremy L Thompson CeedContextFieldLabel field_label, 14007bfe0f0eSJeremy L Thompson int *values) { 14013668ca4bSJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_label, CEED_CONTEXT_FIELD_INT32, 14027bfe0f0eSJeremy L Thompson values); 1403d8dd9a91SJeremy L Thompson } 1404d8dd9a91SJeremy L Thompson 1405d8dd9a91SJeremy L Thompson /** 14063bd813ffSjeremylt @brief Apply CeedOperator to a vector 1407d7b241e6Sjeremylt 1408d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 1409d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 1410d7b241e6Sjeremylt CeedOperatorSetField(). 1411d7b241e6Sjeremylt 1412f04ea552SJeremy L Thompson Note: Calling this function asserts that setup is complete 1413f04ea552SJeremy L Thompson and sets the CeedOperator as immutable. 1414f04ea552SJeremy L Thompson 1415d7b241e6Sjeremylt @param op CeedOperator to apply 14164cc79fe7SJed Brown @param[in] in CeedVector containing input state or @ref CEED_VECTOR_NONE if 141734138859Sjeremylt there are no active inputs 1418b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 14194cc79fe7SJed Brown distinct from @a in) or @ref CEED_VECTOR_NONE if there are no 142034138859Sjeremylt active outputs 1421d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 14224cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1423b11c1e72Sjeremylt 1424b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1425dfdf5a53Sjeremylt 14267a982d89SJeremy L. Thompson @ref User 1427b11c1e72Sjeremylt **/ 1428692c2638Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, 1429692c2638Sjeremylt CeedRequest *request) { 1430d7b241e6Sjeremylt int ierr; 1431e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1432d7b241e6Sjeremylt 1433d1d35e2fSjeremylt if (op->num_elem) { 1434250756a7Sjeremylt // Standard Operator 1435cae8b89aSjeremylt if (op->Apply) { 1436250756a7Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 1437cae8b89aSjeremylt } else { 1438cae8b89aSjeremylt // Zero all output vectors 1439250756a7Sjeremylt CeedQFunction qf = op->qf; 1440d1d35e2fSjeremylt for (CeedInt i=0; i<qf->num_output_fields; i++) { 1441d1d35e2fSjeremylt CeedVector vec = op->output_fields[i]->vec; 1442cae8b89aSjeremylt if (vec == CEED_VECTOR_ACTIVE) 1443cae8b89aSjeremylt vec = out; 1444cae8b89aSjeremylt if (vec != CEED_VECTOR_NONE) { 1445cae8b89aSjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1446cae8b89aSjeremylt } 1447cae8b89aSjeremylt } 1448250756a7Sjeremylt // Apply 1449250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1450250756a7Sjeremylt } 1451f04ea552SJeremy L Thompson } else if (op->is_composite) { 1452250756a7Sjeremylt // Composite Operator 1453250756a7Sjeremylt if (op->ApplyComposite) { 1454250756a7Sjeremylt ierr = op->ApplyComposite(op, in, out, request); CeedChk(ierr); 1455250756a7Sjeremylt } else { 1456d1d35e2fSjeremylt CeedInt num_suboperators; 1457d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1458d1d35e2fSjeremylt CeedOperator *sub_operators; 1459d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1460250756a7Sjeremylt 1461250756a7Sjeremylt // Zero all output vectors 1462250756a7Sjeremylt if (out != CEED_VECTOR_NONE) { 1463cae8b89aSjeremylt ierr = CeedVectorSetValue(out, 0.0); CeedChk(ierr); 1464cae8b89aSjeremylt } 1465d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1466d1d35e2fSjeremylt for (CeedInt j=0; j<sub_operators[i]->qf->num_output_fields; j++) { 1467d1d35e2fSjeremylt CeedVector vec = sub_operators[i]->output_fields[j]->vec; 1468250756a7Sjeremylt if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) { 1469250756a7Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1470250756a7Sjeremylt } 1471250756a7Sjeremylt } 1472250756a7Sjeremylt } 1473250756a7Sjeremylt // Apply 1474d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 1475d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(op->sub_operators[i], in, out, request); 1476cae8b89aSjeremylt CeedChk(ierr); 1477cae8b89aSjeremylt } 1478cae8b89aSjeremylt } 1479250756a7Sjeremylt } 1480e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1481cae8b89aSjeremylt } 1482cae8b89aSjeremylt 1483cae8b89aSjeremylt /** 1484cae8b89aSjeremylt @brief Apply CeedOperator to a vector and add result to output vector 1485cae8b89aSjeremylt 1486cae8b89aSjeremylt This computes the action of the operator on the specified (active) input, 1487cae8b89aSjeremylt yielding its (active) output. All inputs and outputs must be specified using 1488cae8b89aSjeremylt CeedOperatorSetField(). 1489cae8b89aSjeremylt 1490cae8b89aSjeremylt @param op CeedOperator to apply 1491cae8b89aSjeremylt @param[in] in CeedVector containing input state or NULL if there are no 1492cae8b89aSjeremylt active inputs 1493cae8b89aSjeremylt @param[out] out CeedVector to sum in result of applying operator (must be 1494cae8b89aSjeremylt distinct from @a in) or NULL if there are no active outputs 1495cae8b89aSjeremylt @param request Address of CeedRequest for non-blocking completion, else 14964cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1497cae8b89aSjeremylt 1498cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 1499cae8b89aSjeremylt 15007a982d89SJeremy L. Thompson @ref User 1501cae8b89aSjeremylt **/ 1502cae8b89aSjeremylt int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, 1503cae8b89aSjeremylt CeedRequest *request) { 1504cae8b89aSjeremylt int ierr; 1505e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1506cae8b89aSjeremylt 1507d1d35e2fSjeremylt if (op->num_elem) { 1508250756a7Sjeremylt // Standard Operator 1509250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1510f04ea552SJeremy L Thompson } else if (op->is_composite) { 1511250756a7Sjeremylt // Composite Operator 1512250756a7Sjeremylt if (op->ApplyAddComposite) { 1513250756a7Sjeremylt ierr = op->ApplyAddComposite(op, in, out, request); CeedChk(ierr); 1514cae8b89aSjeremylt } else { 1515d1d35e2fSjeremylt CeedInt num_suboperators; 1516d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1517d1d35e2fSjeremylt CeedOperator *sub_operators; 1518d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1519250756a7Sjeremylt 1520d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1521d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(sub_operators[i], in, out, request); 1522cae8b89aSjeremylt CeedChk(ierr); 15231d7d2407SJeremy L Thompson } 1524250756a7Sjeremylt } 1525250756a7Sjeremylt } 1526e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1527d7b241e6Sjeremylt } 1528d7b241e6Sjeremylt 1529d7b241e6Sjeremylt /** 1530b11c1e72Sjeremylt @brief Destroy a CeedOperator 1531d7b241e6Sjeremylt 1532d7b241e6Sjeremylt @param op CeedOperator to destroy 1533b11c1e72Sjeremylt 1534b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1535dfdf5a53Sjeremylt 15367a982d89SJeremy L. Thompson @ref User 1537b11c1e72Sjeremylt **/ 1538d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 1539d7b241e6Sjeremylt int ierr; 1540d7b241e6Sjeremylt 1541d1d35e2fSjeremylt if (!*op || --(*op)->ref_count > 0) return CEED_ERROR_SUCCESS; 1542d7b241e6Sjeremylt if ((*op)->Destroy) { 1543d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 1544d7b241e6Sjeremylt } 1545fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 1546fe2413ffSjeremylt // Free fields 15473668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_fields; i++) 1548d1d35e2fSjeremylt if ((*op)->input_fields[i]) { 1549d1d35e2fSjeremylt if ((*op)->input_fields[i]->elem_restr != CEED_ELEMRESTRICTION_NONE) { 1550d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->input_fields[i]->elem_restr); 155171352a93Sjeremylt CeedChk(ierr); 155215910d16Sjeremylt } 1553d1d35e2fSjeremylt if ((*op)->input_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1554d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->input_fields[i]->basis); CeedChk(ierr); 155571352a93Sjeremylt } 1556d1d35e2fSjeremylt if ((*op)->input_fields[i]->vec != CEED_VECTOR_ACTIVE && 1557d1d35e2fSjeremylt (*op)->input_fields[i]->vec != CEED_VECTOR_NONE ) { 1558d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->input_fields[i]->vec); CeedChk(ierr); 155971352a93Sjeremylt } 1560d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]->field_name); CeedChk(ierr); 1561d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]); CeedChk(ierr); 1562fe2413ffSjeremylt } 15633668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_fields; i++) 1564d1d35e2fSjeremylt if ((*op)->output_fields[i]) { 1565d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->output_fields[i]->elem_restr); 156671352a93Sjeremylt CeedChk(ierr); 1567d1d35e2fSjeremylt if ((*op)->output_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1568d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->output_fields[i]->basis); CeedChk(ierr); 156971352a93Sjeremylt } 1570d1d35e2fSjeremylt if ((*op)->output_fields[i]->vec != CEED_VECTOR_ACTIVE && 1571d1d35e2fSjeremylt (*op)->output_fields[i]->vec != CEED_VECTOR_NONE ) { 1572d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->output_fields[i]->vec); CeedChk(ierr); 157371352a93Sjeremylt } 1574d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]->field_name); CeedChk(ierr); 1575d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]); CeedChk(ierr); 1576fe2413ffSjeremylt } 1577d1d35e2fSjeremylt // Destroy sub_operators 15783668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_suboperators; i++) 1579d1d35e2fSjeremylt if ((*op)->sub_operators[i]) { 1580d1d35e2fSjeremylt ierr = CeedOperatorDestroy(&(*op)->sub_operators[i]); CeedChk(ierr); 158152d6035fSJeremy L Thompson } 1582d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 1583d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 1584d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 15853668ca4bSJeremy L Thompson // Destroy any composite labels 15863668ca4bSJeremy L Thompson for (CeedInt i=0; i<(*op)->num_context_labels; i++) { 15873668ca4bSJeremy L Thompson ierr = CeedFree(&(*op)->context_labels[i]->sub_labels); CeedChk(ierr); 15883668ca4bSJeremy L Thompson ierr = CeedFree(&(*op)->context_labels[i]); CeedChk(ierr); 15893668ca4bSJeremy L Thompson } 15903668ca4bSJeremy L Thompson ierr = CeedFree(&(*op)->context_labels); CeedChk(ierr); 1591fe2413ffSjeremylt 15925107b09fSJeremy L Thompson // Destroy fallback 1593d1d35e2fSjeremylt if ((*op)->op_fallback) { 1594d1d35e2fSjeremylt ierr = (*op)->qf_fallback->Destroy((*op)->qf_fallback); CeedChk(ierr); 1595d1d35e2fSjeremylt ierr = CeedFree(&(*op)->qf_fallback); CeedChk(ierr); 1596d1d35e2fSjeremylt ierr = (*op)->op_fallback->Destroy((*op)->op_fallback); CeedChk(ierr); 1597d1d35e2fSjeremylt ierr = CeedFree(&(*op)->op_fallback); CeedChk(ierr); 15985107b09fSJeremy L Thompson } 15995107b09fSJeremy L Thompson 160070a7ffb3SJeremy L Thompson // Destroy QF assembly cache 1601480fae85SJeremy L Thompson ierr = CeedQFunctionAssemblyDataDestroy(&(*op)->qf_assembled); CeedChk(ierr); 160270a7ffb3SJeremy L Thompson 1603d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields); CeedChk(ierr); 1604d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields); CeedChk(ierr); 1605d1d35e2fSjeremylt ierr = CeedFree(&(*op)->sub_operators); CeedChk(ierr); 1606d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 1607e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1608d7b241e6Sjeremylt } 1609d7b241e6Sjeremylt 1610d7b241e6Sjeremylt /// @} 1611