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 /** 207eaf62fffSJeremy L Thompson @brief Find the active vector basis for a CeedOperator 208eaf62fffSJeremy L Thompson 209eaf62fffSJeremy L Thompson @param[in] op CeedOperator to find active basis for 210eaf62fffSJeremy L Thompson @param[out] active_basis Basis for active input vector 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; 218eaf62fffSJeremy L Thompson for (int i = 0; i < op->qf->num_input_fields; i++) 219eaf62fffSJeremy L Thompson if (op->input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 220eaf62fffSJeremy L Thompson *active_basis = op->input_fields[i]->basis; 221eaf62fffSJeremy L Thompson break; 222eaf62fffSJeremy L Thompson } 223eaf62fffSJeremy L Thompson 224eaf62fffSJeremy L Thompson if (!*active_basis) { 225eaf62fffSJeremy L Thompson // LCOV_EXCL_START 226eaf62fffSJeremy L Thompson int ierr; 227eaf62fffSJeremy L Thompson Ceed ceed; 228eaf62fffSJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 229eaf62fffSJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 230eaf62fffSJeremy L Thompson "No active CeedBasis found"); 231eaf62fffSJeremy L Thompson // LCOV_EXCL_STOP 232eaf62fffSJeremy L Thompson } 233eaf62fffSJeremy L Thompson return CEED_ERROR_SUCCESS; 234eaf62fffSJeremy L Thompson } 235eaf62fffSJeremy L Thompson 236eaf62fffSJeremy L Thompson /** 237e2f04181SAndrew T. Barker @brief Find the active vector ElemRestriction for a CeedOperator 238e2f04181SAndrew T. Barker 239e2f04181SAndrew T. Barker @param[in] op CeedOperator to find active basis for 240d1d35e2fSjeremylt @param[out] active_rstr ElemRestriction for active input vector 241e2f04181SAndrew T. Barker 242e2f04181SAndrew T. Barker @return An error code: 0 - success, otherwise - failure 243e2f04181SAndrew T. Barker 244e2f04181SAndrew T. Barker @ref Utility 245e2f04181SAndrew T. Barker **/ 246eaf62fffSJeremy L Thompson int CeedOperatorGetActiveElemRestriction(CeedOperator op, 247d1d35e2fSjeremylt CeedElemRestriction *active_rstr) { 248d1d35e2fSjeremylt *active_rstr = NULL; 249d1d35e2fSjeremylt for (int i = 0; i < op->qf->num_input_fields; i++) 250d1d35e2fSjeremylt if (op->input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 251d1d35e2fSjeremylt *active_rstr = op->input_fields[i]->elem_restr; 252e2f04181SAndrew T. Barker break; 253e2f04181SAndrew T. Barker } 254e2f04181SAndrew T. Barker 255d1d35e2fSjeremylt if (!*active_rstr) { 256e2f04181SAndrew T. Barker // LCOV_EXCL_START 257e2f04181SAndrew T. Barker int ierr; 258e2f04181SAndrew T. Barker Ceed ceed; 259e2f04181SAndrew T. Barker ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 260e2f04181SAndrew T. Barker return CeedError(ceed, CEED_ERROR_INCOMPLETE, 261eaf62fffSJeremy L Thompson "No active CeedElemRestriction found"); 262e2f04181SAndrew T. Barker // LCOV_EXCL_STOP 263e2f04181SAndrew T. Barker } 264e2f04181SAndrew T. Barker return CEED_ERROR_SUCCESS; 265e2f04181SAndrew T. Barker } 266e2f04181SAndrew T. Barker 267*d8dd9a91SJeremy L Thompson /** 268*d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field value of the specified type. 269*d8dd9a91SJeremy L Thompson For composite operators, the value is set in all 270*d8dd9a91SJeremy L Thompson sub-operator QFunctionContexts that have a matching `field_name`. 271*d8dd9a91SJeremy L Thompson A non-zero error code is returned for single operators 272*d8dd9a91SJeremy L Thompson that do not have a matching field of the same type or composite 273*d8dd9a91SJeremy L Thompson operators that do not have any field of a matching type. 274*d8dd9a91SJeremy L Thompson 275*d8dd9a91SJeremy L Thompson @param op CeedOperator 276*d8dd9a91SJeremy L Thompson @param field_name Name of field to set 277*d8dd9a91SJeremy L Thompson @param field_type Type of field to set 278*d8dd9a91SJeremy L Thompson @param value Value to set 279*d8dd9a91SJeremy L Thompson 280*d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 281*d8dd9a91SJeremy L Thompson 282*d8dd9a91SJeremy L Thompson @ref User 283*d8dd9a91SJeremy L Thompson **/ 284*d8dd9a91SJeremy L Thompson static int CeedOperatorContextSetGeneric(CeedOperator op, 285*d8dd9a91SJeremy L Thompson const char *field_name, CeedContextFieldType field_type, void *value) { 286*d8dd9a91SJeremy L Thompson int ierr; 287*d8dd9a91SJeremy L Thompson bool is_set = false, is_composite = false; 288*d8dd9a91SJeremy L Thompson 289*d8dd9a91SJeremy L Thompson ierr = CeedOperatorIsComposite(op, &is_composite); CeedChk(ierr); 290*d8dd9a91SJeremy L Thompson 291*d8dd9a91SJeremy L Thompson if (is_composite) { 292*d8dd9a91SJeremy L Thompson CeedInt num_sub; 293*d8dd9a91SJeremy L Thompson CeedOperator *sub_operators; 294*d8dd9a91SJeremy L Thompson 295*d8dd9a91SJeremy L Thompson ierr = CeedOperatorGetNumSub(op, &num_sub); CeedChk(ierr); 296*d8dd9a91SJeremy L Thompson ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 297*d8dd9a91SJeremy L Thompson 298*d8dd9a91SJeremy L Thompson for (CeedInt i = 0; i < num_sub; i++) { 299*d8dd9a91SJeremy L Thompson // Try every sub-operator, ok if some sub-operators do not have field 300*d8dd9a91SJeremy L Thompson if (sub_operators[i]->qf->ctx) { 301*d8dd9a91SJeremy L Thompson bool is_set_i = false; 302*d8dd9a91SJeremy L Thompson ierr = CeedQFunctionContextSetGeneric(sub_operators[i]->qf->ctx, field_name, 303*d8dd9a91SJeremy L Thompson field_type, &is_set_i, value); 304*d8dd9a91SJeremy L Thompson CeedChk(ierr); 305*d8dd9a91SJeremy L Thompson is_set = is_set || is_set_i; 306*d8dd9a91SJeremy L Thompson } 307*d8dd9a91SJeremy L Thompson } 308*d8dd9a91SJeremy L Thompson } else { 309*d8dd9a91SJeremy L Thompson if (!op->qf->ctx) 310*d8dd9a91SJeremy L Thompson // LCOV_EXCL_START 311*d8dd9a91SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_UNSUPPORTED, 312*d8dd9a91SJeremy L Thompson "QFunction does not have context data"); 313*d8dd9a91SJeremy L Thompson // LCOV_EXCL_STOP 314*d8dd9a91SJeremy L Thompson 315*d8dd9a91SJeremy L Thompson ierr = CeedQFunctionContextSetGeneric(op->qf->ctx, field_name, 316*d8dd9a91SJeremy L Thompson field_type, &is_set, value); CeedChk(ierr); 317*d8dd9a91SJeremy L Thompson } 318*d8dd9a91SJeremy L Thompson 319*d8dd9a91SJeremy L Thompson if (!is_set) 320*d8dd9a91SJeremy L Thompson // LCOV_EXCL_START 321*d8dd9a91SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_UNSUPPORTED, 322*d8dd9a91SJeremy L Thompson "QFunctionContext field with name \"%s\" not registered", 323*d8dd9a91SJeremy L Thompson field_name); 324*d8dd9a91SJeremy L Thompson // LCOV_EXCL_STOP 325*d8dd9a91SJeremy L Thompson 326*d8dd9a91SJeremy L Thompson return CEED_ERROR_SUCCESS; 327*d8dd9a91SJeremy L Thompson } 328*d8dd9a91SJeremy L Thompson 3297a982d89SJeremy L. Thompson /// @} 3307a982d89SJeremy L. Thompson 3317a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3327a982d89SJeremy L. Thompson /// CeedOperator Backend API 3337a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3347a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorBackend 3357a982d89SJeremy L. Thompson /// @{ 3367a982d89SJeremy L. Thompson 3377a982d89SJeremy L. Thompson /** 3387a982d89SJeremy L. Thompson @brief Get the number of arguments associated with a CeedOperator 3397a982d89SJeremy L. Thompson 3407a982d89SJeremy L. Thompson @param op CeedOperator 341d1d35e2fSjeremylt @param[out] num_args Variable to store vector number of arguments 3427a982d89SJeremy L. Thompson 3437a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3447a982d89SJeremy L. Thompson 3457a982d89SJeremy L. Thompson @ref Backend 3467a982d89SJeremy L. Thompson **/ 3477a982d89SJeremy L. Thompson 348d1d35e2fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *num_args) { 349f04ea552SJeremy L Thompson if (op->is_composite) 3507a982d89SJeremy L. Thompson // LCOV_EXCL_START 351e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 352e15f9bd0SJeremy L Thompson "Not defined for composite operators"); 3537a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 3547a982d89SJeremy L. Thompson 355d1d35e2fSjeremylt *num_args = op->num_fields; 356e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3577a982d89SJeremy L. Thompson } 3587a982d89SJeremy L. Thompson 3597a982d89SJeremy L. Thompson /** 3607a982d89SJeremy L. Thompson @brief Get the setup status of a CeedOperator 3617a982d89SJeremy L. Thompson 3627a982d89SJeremy L. Thompson @param op CeedOperator 363d1d35e2fSjeremylt @param[out] is_setup_done Variable to store setup status 3647a982d89SJeremy L. Thompson 3657a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3667a982d89SJeremy L. Thompson 3677a982d89SJeremy L. Thompson @ref Backend 3687a982d89SJeremy L. Thompson **/ 3697a982d89SJeremy L. Thompson 370d1d35e2fSjeremylt int CeedOperatorIsSetupDone(CeedOperator op, bool *is_setup_done) { 371f04ea552SJeremy L Thompson *is_setup_done = op->is_backend_setup; 372e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3737a982d89SJeremy L. Thompson } 3747a982d89SJeremy L. Thompson 3757a982d89SJeremy L. Thompson /** 3767a982d89SJeremy L. Thompson @brief Get the QFunction associated with a CeedOperator 3777a982d89SJeremy L. Thompson 3787a982d89SJeremy L. Thompson @param op CeedOperator 3797a982d89SJeremy L. Thompson @param[out] qf Variable to store QFunction 3807a982d89SJeremy L. Thompson 3817a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3827a982d89SJeremy L. Thompson 3837a982d89SJeremy L. Thompson @ref Backend 3847a982d89SJeremy L. Thompson **/ 3857a982d89SJeremy L. Thompson 3867a982d89SJeremy L. Thompson int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 387f04ea552SJeremy L Thompson if (op->is_composite) 3887a982d89SJeremy L. Thompson // LCOV_EXCL_START 389e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 390e15f9bd0SJeremy L Thompson "Not defined for composite operator"); 3917a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 3927a982d89SJeremy L. Thompson 3937a982d89SJeremy L. Thompson *qf = op->qf; 394e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3957a982d89SJeremy L. Thompson } 3967a982d89SJeremy L. Thompson 3977a982d89SJeremy L. Thompson /** 398c04a41a7SJeremy L Thompson @brief Get a boolean value indicating if the CeedOperator is composite 399c04a41a7SJeremy L Thompson 400c04a41a7SJeremy L Thompson @param op CeedOperator 401d1d35e2fSjeremylt @param[out] is_composite Variable to store composite status 402c04a41a7SJeremy L Thompson 403c04a41a7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 404c04a41a7SJeremy L Thompson 405c04a41a7SJeremy L Thompson @ref Backend 406c04a41a7SJeremy L Thompson **/ 407c04a41a7SJeremy L Thompson 408d1d35e2fSjeremylt int CeedOperatorIsComposite(CeedOperator op, bool *is_composite) { 409f04ea552SJeremy L Thompson *is_composite = op->is_composite; 410e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 411c04a41a7SJeremy L Thompson } 412c04a41a7SJeremy L Thompson 413c04a41a7SJeremy L Thompson /** 414d1d35e2fSjeremylt @brief Get the number of sub_operators associated with a CeedOperator 4157a982d89SJeremy L. Thompson 4167a982d89SJeremy L. Thompson @param op CeedOperator 417d1d35e2fSjeremylt @param[out] num_suboperators Variable to store number of sub_operators 4187a982d89SJeremy L. Thompson 4197a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4207a982d89SJeremy L. Thompson 4217a982d89SJeremy L. Thompson @ref Backend 4227a982d89SJeremy L. Thompson **/ 4237a982d89SJeremy L. Thompson 424d1d35e2fSjeremylt int CeedOperatorGetNumSub(CeedOperator op, CeedInt *num_suboperators) { 425f04ea552SJeremy L Thompson if (!op->is_composite) 4267a982d89SJeremy L. Thompson // LCOV_EXCL_START 427e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 4287a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4297a982d89SJeremy L. Thompson 430d1d35e2fSjeremylt *num_suboperators = op->num_suboperators; 431e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4327a982d89SJeremy L. Thompson } 4337a982d89SJeremy L. Thompson 4347a982d89SJeremy L. Thompson /** 435d1d35e2fSjeremylt @brief Get the list of sub_operators associated with a CeedOperator 4367a982d89SJeremy L. Thompson 4377a982d89SJeremy L. Thompson @param op CeedOperator 438d1d35e2fSjeremylt @param[out] sub_operators Variable to store list of sub_operators 4397a982d89SJeremy L. Thompson 4407a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4417a982d89SJeremy L. Thompson 4427a982d89SJeremy L. Thompson @ref Backend 4437a982d89SJeremy L. Thompson **/ 4447a982d89SJeremy L. Thompson 445d1d35e2fSjeremylt int CeedOperatorGetSubList(CeedOperator op, CeedOperator **sub_operators) { 446f04ea552SJeremy L Thompson if (!op->is_composite) 4477a982d89SJeremy L. Thompson // LCOV_EXCL_START 448e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 4497a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4507a982d89SJeremy L. Thompson 451d1d35e2fSjeremylt *sub_operators = op->sub_operators; 452e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4537a982d89SJeremy L. Thompson } 4547a982d89SJeremy L. Thompson 4557a982d89SJeremy L. Thompson /** 4567a982d89SJeremy L. Thompson @brief Get the backend data of a CeedOperator 4577a982d89SJeremy L. Thompson 4587a982d89SJeremy L. Thompson @param op CeedOperator 4597a982d89SJeremy L. Thompson @param[out] data Variable to store data 4607a982d89SJeremy L. Thompson 4617a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4627a982d89SJeremy L. Thompson 4637a982d89SJeremy L. Thompson @ref Backend 4647a982d89SJeremy L. Thompson **/ 4657a982d89SJeremy L. Thompson 466777ff853SJeremy L Thompson int CeedOperatorGetData(CeedOperator op, void *data) { 467777ff853SJeremy L Thompson *(void **)data = op->data; 468e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4697a982d89SJeremy L. Thompson } 4707a982d89SJeremy L. Thompson 4717a982d89SJeremy L. Thompson /** 4727a982d89SJeremy L. Thompson @brief Set the backend data of a CeedOperator 4737a982d89SJeremy L. Thompson 4747a982d89SJeremy L. Thompson @param[out] op CeedOperator 4757a982d89SJeremy L. Thompson @param data Data to set 4767a982d89SJeremy L. Thompson 4777a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4787a982d89SJeremy L. Thompson 4797a982d89SJeremy L. Thompson @ref Backend 4807a982d89SJeremy L. Thompson **/ 4817a982d89SJeremy L. Thompson 482777ff853SJeremy L Thompson int CeedOperatorSetData(CeedOperator op, void *data) { 483777ff853SJeremy L Thompson op->data = data; 484e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4857a982d89SJeremy L. Thompson } 4867a982d89SJeremy L. Thompson 4877a982d89SJeremy L. Thompson /** 48834359f16Sjeremylt @brief Increment the reference counter for a CeedOperator 48934359f16Sjeremylt 49034359f16Sjeremylt @param op CeedOperator to increment the reference counter 49134359f16Sjeremylt 49234359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 49334359f16Sjeremylt 49434359f16Sjeremylt @ref Backend 49534359f16Sjeremylt **/ 4969560d06aSjeremylt int CeedOperatorReference(CeedOperator op) { 49734359f16Sjeremylt op->ref_count++; 49834359f16Sjeremylt return CEED_ERROR_SUCCESS; 49934359f16Sjeremylt } 50034359f16Sjeremylt 50134359f16Sjeremylt /** 5027a982d89SJeremy L. Thompson @brief Set the setup flag of a CeedOperator to True 5037a982d89SJeremy L. Thompson 5047a982d89SJeremy L. Thompson @param op CeedOperator 5057a982d89SJeremy L. Thompson 5067a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5077a982d89SJeremy L. Thompson 5087a982d89SJeremy L. Thompson @ref Backend 5097a982d89SJeremy L. Thompson **/ 5107a982d89SJeremy L. Thompson 5117a982d89SJeremy L. Thompson int CeedOperatorSetSetupDone(CeedOperator op) { 512f04ea552SJeremy L Thompson op->is_backend_setup = true; 513e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5147a982d89SJeremy L. Thompson } 5157a982d89SJeremy L. Thompson 5167a982d89SJeremy L. Thompson /// @} 5177a982d89SJeremy L. Thompson 5187a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5197a982d89SJeremy L. Thompson /// CeedOperator Public API 5207a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5217a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorUser 522dfdf5a53Sjeremylt /// @{ 523d7b241e6Sjeremylt 524d7b241e6Sjeremylt /** 5250219ea01SJeremy L Thompson @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and 5260219ea01SJeremy L Thompson CeedElemRestriction can be associated with CeedQFunction fields with 5270219ea01SJeremy L Thompson \ref CeedOperatorSetField. 528d7b241e6Sjeremylt 529b11c1e72Sjeremylt @param ceed A Ceed object where the CeedOperator will be created 530d7b241e6Sjeremylt @param qf QFunction defining the action of the operator at quadrature points 53134138859Sjeremylt @param dqf QFunction defining the action of the Jacobian of @a qf (or 5324cc79fe7SJed Brown @ref CEED_QFUNCTION_NONE) 533d7b241e6Sjeremylt @param dqfT QFunction defining the action of the transpose of the Jacobian 5344cc79fe7SJed Brown of @a qf (or @ref CEED_QFUNCTION_NONE) 535b11c1e72Sjeremylt @param[out] op Address of the variable where the newly created 536b11c1e72Sjeremylt CeedOperator will be stored 537b11c1e72Sjeremylt 538b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 539dfdf5a53Sjeremylt 5407a982d89SJeremy L. Thompson @ref User 541d7b241e6Sjeremylt */ 542d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, 543d7b241e6Sjeremylt CeedQFunction dqfT, CeedOperator *op) { 544d7b241e6Sjeremylt int ierr; 545d7b241e6Sjeremylt 5465fe0d4faSjeremylt if (!ceed->OperatorCreate) { 5475fe0d4faSjeremylt Ceed delegate; 548aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 5495fe0d4faSjeremylt 5505fe0d4faSjeremylt if (!delegate) 551c042f62fSJeremy L Thompson // LCOV_EXCL_START 552e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 553e15f9bd0SJeremy L Thompson "Backend does not support OperatorCreate"); 554c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 5555fe0d4faSjeremylt 5565fe0d4faSjeremylt ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr); 557e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5585fe0d4faSjeremylt } 5595fe0d4faSjeremylt 560b3b7035fSJeremy L Thompson if (!qf || qf == CEED_QFUNCTION_NONE) 561b3b7035fSJeremy L Thompson // LCOV_EXCL_START 562e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 563e15f9bd0SJeremy L Thompson "Operator must have a valid QFunction."); 564b3b7035fSJeremy L Thompson // LCOV_EXCL_STOP 565d7b241e6Sjeremylt ierr = CeedCalloc(1, op); CeedChk(ierr); 566d7b241e6Sjeremylt (*op)->ceed = ceed; 5679560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 568d1d35e2fSjeremylt (*op)->ref_count = 1; 569d7b241e6Sjeremylt (*op)->qf = qf; 5709560d06aSjeremylt ierr = CeedQFunctionReference(qf); CeedChk(ierr); 571442e7f0bSjeremylt if (dqf && dqf != CEED_QFUNCTION_NONE) { 572d7b241e6Sjeremylt (*op)->dqf = dqf; 5739560d06aSjeremylt ierr = CeedQFunctionReference(dqf); CeedChk(ierr); 574442e7f0bSjeremylt } 575442e7f0bSjeremylt if (dqfT && dqfT != CEED_QFUNCTION_NONE) { 576d7b241e6Sjeremylt (*op)->dqfT = dqfT; 5779560d06aSjeremylt ierr = CeedQFunctionReference(dqfT); CeedChk(ierr); 578442e7f0bSjeremylt } 579bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_FIELD_MAX, &(*op)->input_fields); CeedChk(ierr); 580bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_FIELD_MAX, &(*op)->output_fields); CeedChk(ierr); 581d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 582e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 583d7b241e6Sjeremylt } 584d7b241e6Sjeremylt 585d7b241e6Sjeremylt /** 58652d6035fSJeremy L Thompson @brief Create an operator that composes the action of several operators 58752d6035fSJeremy L Thompson 58852d6035fSJeremy L Thompson @param ceed A Ceed object where the CeedOperator will be created 58952d6035fSJeremy L Thompson @param[out] op Address of the variable where the newly created 59052d6035fSJeremy L Thompson Composite CeedOperator will be stored 59152d6035fSJeremy L Thompson 59252d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 59352d6035fSJeremy L Thompson 5947a982d89SJeremy L. Thompson @ref User 59552d6035fSJeremy L Thompson */ 59652d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) { 59752d6035fSJeremy L Thompson int ierr; 59852d6035fSJeremy L Thompson 59952d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 60052d6035fSJeremy L Thompson Ceed delegate; 601aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 60252d6035fSJeremy L Thompson 603250756a7Sjeremylt if (delegate) { 60452d6035fSJeremy L Thompson ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr); 605e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 60652d6035fSJeremy L Thompson } 607250756a7Sjeremylt } 60852d6035fSJeremy L Thompson 60952d6035fSJeremy L Thompson ierr = CeedCalloc(1, op); CeedChk(ierr); 61052d6035fSJeremy L Thompson (*op)->ceed = ceed; 6119560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 612f04ea552SJeremy L Thompson (*op)->is_composite = true; 613bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_COMPOSITE_MAX, &(*op)->sub_operators); CeedChk(ierr); 614250756a7Sjeremylt 615250756a7Sjeremylt if (ceed->CompositeOperatorCreate) { 61652d6035fSJeremy L Thompson ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr); 617250756a7Sjeremylt } 618e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 61952d6035fSJeremy L Thompson } 62052d6035fSJeremy L Thompson 62152d6035fSJeremy L Thompson /** 6229560d06aSjeremylt @brief Copy the pointer to a CeedOperator. Both pointers should 6239560d06aSjeremylt be destroyed with `CeedOperatorDestroy()`; 6249560d06aSjeremylt Note: If `*op_copy` is non-NULL, then it is assumed that 6259560d06aSjeremylt `*op_copy` is a pointer to a CeedOperator. This 6269560d06aSjeremylt CeedOperator will be destroyed if `*op_copy` is the only 6279560d06aSjeremylt reference to this CeedOperator. 6289560d06aSjeremylt 6299560d06aSjeremylt @param op CeedOperator to copy reference to 6309560d06aSjeremylt @param[out] op_copy Variable to store copied reference 6319560d06aSjeremylt 6329560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 6339560d06aSjeremylt 6349560d06aSjeremylt @ref User 6359560d06aSjeremylt **/ 6369560d06aSjeremylt int CeedOperatorReferenceCopy(CeedOperator op, CeedOperator *op_copy) { 6379560d06aSjeremylt int ierr; 6389560d06aSjeremylt 6399560d06aSjeremylt ierr = CeedOperatorReference(op); CeedChk(ierr); 6409560d06aSjeremylt ierr = CeedOperatorDestroy(op_copy); CeedChk(ierr); 6419560d06aSjeremylt *op_copy = op; 6429560d06aSjeremylt return CEED_ERROR_SUCCESS; 6439560d06aSjeremylt } 6449560d06aSjeremylt 6459560d06aSjeremylt /** 646b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 647d7b241e6Sjeremylt 648d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 649d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 650d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 651d7b241e6Sjeremylt 652d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 653d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 654d7b241e6Sjeremylt input and at most one active output. 655d7b241e6Sjeremylt 6568c91a0c9SJeremy L Thompson @param op CeedOperator on which to provide the field 657d1d35e2fSjeremylt @param field_name Name of the field (to be matched with the name used by 6588795c945Sjeremylt CeedQFunction) 659b11c1e72Sjeremylt @param r CeedElemRestriction 6604cc79fe7SJed Brown @param b CeedBasis in which the field resides or @ref CEED_BASIS_COLLOCATED 661b11c1e72Sjeremylt if collocated with quadrature points 6624cc79fe7SJed Brown @param v CeedVector to be used by CeedOperator or @ref CEED_VECTOR_ACTIVE 6634cc79fe7SJed Brown if field is active or @ref CEED_VECTOR_NONE if using 6644cc79fe7SJed Brown @ref CEED_EVAL_WEIGHT in the QFunction 665b11c1e72Sjeremylt 666b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 667dfdf5a53Sjeremylt 6687a982d89SJeremy L. Thompson @ref User 669b11c1e72Sjeremylt **/ 670d1d35e2fSjeremylt int CeedOperatorSetField(CeedOperator op, const char *field_name, 671a8d32208Sjeremylt CeedElemRestriction r, CeedBasis b, CeedVector v) { 672d7b241e6Sjeremylt int ierr; 673f04ea552SJeremy L Thompson if (op->is_composite) 674c042f62fSJeremy L Thompson // LCOV_EXCL_START 675e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 676e15f9bd0SJeremy L Thompson "Cannot add field to composite operator."); 677c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 678f04ea552SJeremy L Thompson if (op->is_immutable) 679f04ea552SJeremy L Thompson // LCOV_EXCL_START 680f04ea552SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 681f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 682f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 6838b067b84SJed Brown if (!r) 684c042f62fSJeremy L Thompson // LCOV_EXCL_START 685e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 686c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 687d1d35e2fSjeremylt field_name); 688c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 6898b067b84SJed Brown if (!b) 690c042f62fSJeremy L Thompson // LCOV_EXCL_START 691e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 692e15f9bd0SJeremy L Thompson "Basis b for field \"%s\" must be non-NULL.", 693d1d35e2fSjeremylt field_name); 694c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 6958b067b84SJed Brown if (!v) 696c042f62fSJeremy L Thompson // LCOV_EXCL_START 697e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 698e15f9bd0SJeremy L Thompson "Vector v for field \"%s\" must be non-NULL.", 699d1d35e2fSjeremylt field_name); 700c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 70152d6035fSJeremy L Thompson 702d1d35e2fSjeremylt CeedInt num_elem; 703d1d35e2fSjeremylt ierr = CeedElemRestrictionGetNumElements(r, &num_elem); CeedChk(ierr); 704d1d35e2fSjeremylt if (r != CEED_ELEMRESTRICTION_NONE && op->has_restriction && 705d1d35e2fSjeremylt op->num_elem != num_elem) 706c042f62fSJeremy L Thompson // LCOV_EXCL_START 707e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 7081d102b48SJeremy L Thompson "ElemRestriction with %d elements incompatible with prior " 709d1d35e2fSjeremylt "%d elements", num_elem, op->num_elem); 710c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 711d7b241e6Sjeremylt 71278464608Sjeremylt CeedInt num_qpts = 0; 713e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 714d1d35e2fSjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &num_qpts); CeedChk(ierr); 715d1d35e2fSjeremylt if (op->num_qpts && op->num_qpts != num_qpts) 716c042f62fSJeremy L Thompson // LCOV_EXCL_START 717e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 718e15f9bd0SJeremy L Thompson "Basis with %d quadrature points " 719d1d35e2fSjeremylt "incompatible with prior %d points", num_qpts, 720d1d35e2fSjeremylt op->num_qpts); 721c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 722d7b241e6Sjeremylt } 723d1d35e2fSjeremylt CeedQFunctionField qf_field; 724d1d35e2fSjeremylt CeedOperatorField *op_field; 725d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_input_fields; i++) { 726d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->input_fields[i]).field_name)) { 727d1d35e2fSjeremylt qf_field = op->qf->input_fields[i]; 728d1d35e2fSjeremylt op_field = &op->input_fields[i]; 729d7b241e6Sjeremylt goto found; 730d7b241e6Sjeremylt } 731d7b241e6Sjeremylt } 732d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_output_fields; i++) { 733d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->output_fields[i]).field_name)) { 734d1d35e2fSjeremylt qf_field = op->qf->output_fields[i]; 735d1d35e2fSjeremylt op_field = &op->output_fields[i]; 736d7b241e6Sjeremylt goto found; 737d7b241e6Sjeremylt } 738d7b241e6Sjeremylt } 739c042f62fSJeremy L Thompson // LCOV_EXCL_START 740e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPLETE, 741e15f9bd0SJeremy L Thompson "QFunction has no knowledge of field '%s'", 742d1d35e2fSjeremylt field_name); 743c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 744d7b241e6Sjeremylt found: 745d1d35e2fSjeremylt ierr = CeedOperatorCheckField(op->ceed, qf_field, r, b); CeedChk(ierr); 746d1d35e2fSjeremylt ierr = CeedCalloc(1, op_field); CeedChk(ierr); 747e15f9bd0SJeremy L Thompson 748d1d35e2fSjeremylt (*op_field)->vec = v; 749e15f9bd0SJeremy L Thompson if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) { 7509560d06aSjeremylt ierr = CeedVectorReference(v); CeedChk(ierr); 751e15f9bd0SJeremy L Thompson } 752e15f9bd0SJeremy L Thompson 753d1d35e2fSjeremylt (*op_field)->elem_restr = r; 7549560d06aSjeremylt ierr = CeedElemRestrictionReference(r); CeedChk(ierr); 755e15f9bd0SJeremy L Thompson if (r != CEED_ELEMRESTRICTION_NONE) { 756d1d35e2fSjeremylt op->num_elem = num_elem; 757d1d35e2fSjeremylt op->has_restriction = true; // Restriction set, but num_elem may be 0 758e15f9bd0SJeremy L Thompson } 759d99fa3c5SJeremy L Thompson 760d1d35e2fSjeremylt (*op_field)->basis = b; 761e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 762cd4dfc48Sjeremylt if (!op->num_qpts) { 763cd4dfc48Sjeremylt ierr = CeedOperatorSetNumQuadraturePoints(op, num_qpts); CeedChk(ierr); 764cd4dfc48Sjeremylt } 7659560d06aSjeremylt ierr = CeedBasisReference(b); CeedChk(ierr); 766e15f9bd0SJeremy L Thompson } 767e15f9bd0SJeremy L Thompson 768d1d35e2fSjeremylt op->num_fields += 1; 769f7e22acaSJeremy L Thompson ierr = CeedStringAllocCopy(field_name, (char **)&(*op_field)->field_name); 770f7e22acaSJeremy L Thompson CeedChk(ierr); 771e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 772d7b241e6Sjeremylt } 773d7b241e6Sjeremylt 774d7b241e6Sjeremylt /** 77543bbe138SJeremy L Thompson @brief Get the CeedOperatorFields of a CeedOperator 77643bbe138SJeremy L Thompson 777f04ea552SJeremy L Thompson Note: Calling this function asserts that setup is complete 778f04ea552SJeremy L Thompson and sets the CeedOperator as immutable. 779f04ea552SJeremy L Thompson 78043bbe138SJeremy L Thompson @param op CeedOperator 781f74ec584SJeremy L Thompson @param[out] num_input_fields Variable to store number of input fields 78243bbe138SJeremy L Thompson @param[out] input_fields Variable to store input_fields 783f74ec584SJeremy L Thompson @param[out] num_output_fields Variable to store number of output fields 78443bbe138SJeremy L Thompson @param[out] output_fields Variable to store output_fields 78543bbe138SJeremy L Thompson 78643bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 78743bbe138SJeremy L Thompson 788e9b533fbSJeremy L Thompson @ref Advanced 78943bbe138SJeremy L Thompson **/ 79043bbe138SJeremy L Thompson int CeedOperatorGetFields(CeedOperator op, CeedInt *num_input_fields, 79143bbe138SJeremy L Thompson CeedOperatorField **input_fields, 79243bbe138SJeremy L Thompson CeedInt *num_output_fields, 79343bbe138SJeremy L Thompson CeedOperatorField **output_fields) { 794f04ea552SJeremy L Thompson int ierr; 795f04ea552SJeremy L Thompson 796f04ea552SJeremy L Thompson if (op->is_composite) 79743bbe138SJeremy L Thompson // LCOV_EXCL_START 79843bbe138SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 79943bbe138SJeremy L Thompson "Not defined for composite operator"); 80043bbe138SJeremy L Thompson // LCOV_EXCL_STOP 801f04ea552SJeremy L Thompson ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 80243bbe138SJeremy L Thompson 80343bbe138SJeremy L Thompson if (num_input_fields) *num_input_fields = op->qf->num_input_fields; 80443bbe138SJeremy L Thompson if (input_fields) *input_fields = op->input_fields; 80543bbe138SJeremy L Thompson if (num_output_fields) *num_output_fields = op->qf->num_output_fields; 80643bbe138SJeremy L Thompson if (output_fields) *output_fields = op->output_fields; 80743bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 80843bbe138SJeremy L Thompson } 80943bbe138SJeremy L Thompson 81043bbe138SJeremy L Thompson /** 81128567f8fSJeremy L Thompson @brief Get the name of a CeedOperatorField 81228567f8fSJeremy L Thompson 81328567f8fSJeremy L Thompson @param op_field CeedOperatorField 81428567f8fSJeremy L Thompson @param[out] field_name Variable to store the field name 81528567f8fSJeremy L Thompson 81628567f8fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 81728567f8fSJeremy L Thompson 818e9b533fbSJeremy L Thompson @ref Advanced 81928567f8fSJeremy L Thompson **/ 82028567f8fSJeremy L Thompson int CeedOperatorFieldGetName(CeedOperatorField op_field, char **field_name) { 82128567f8fSJeremy L Thompson *field_name = (char *)op_field->field_name; 82228567f8fSJeremy L Thompson return CEED_ERROR_SUCCESS; 82328567f8fSJeremy L Thompson } 82428567f8fSJeremy L Thompson 82528567f8fSJeremy L Thompson /** 82643bbe138SJeremy L Thompson @brief Get the CeedElemRestriction of a CeedOperatorField 82743bbe138SJeremy L Thompson 82843bbe138SJeremy L Thompson @param op_field CeedOperatorField 82943bbe138SJeremy L Thompson @param[out] rstr Variable to store CeedElemRestriction 83043bbe138SJeremy L Thompson 83143bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 83243bbe138SJeremy L Thompson 833e9b533fbSJeremy L Thompson @ref Advanced 83443bbe138SJeremy L Thompson **/ 83543bbe138SJeremy L Thompson int CeedOperatorFieldGetElemRestriction(CeedOperatorField op_field, 83643bbe138SJeremy L Thompson CeedElemRestriction *rstr) { 83743bbe138SJeremy L Thompson *rstr = op_field->elem_restr; 83843bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 83943bbe138SJeremy L Thompson } 84043bbe138SJeremy L Thompson 84143bbe138SJeremy L Thompson /** 84243bbe138SJeremy L Thompson @brief Get the CeedBasis of a CeedOperatorField 84343bbe138SJeremy L Thompson 84443bbe138SJeremy L Thompson @param op_field CeedOperatorField 84543bbe138SJeremy L Thompson @param[out] basis Variable to store CeedBasis 84643bbe138SJeremy L Thompson 84743bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 84843bbe138SJeremy L Thompson 849e9b533fbSJeremy L Thompson @ref Advanced 85043bbe138SJeremy L Thompson **/ 85143bbe138SJeremy L Thompson int CeedOperatorFieldGetBasis(CeedOperatorField op_field, CeedBasis *basis) { 85243bbe138SJeremy L Thompson *basis = op_field->basis; 85343bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 85443bbe138SJeremy L Thompson } 85543bbe138SJeremy L Thompson 85643bbe138SJeremy L Thompson /** 85743bbe138SJeremy L Thompson @brief Get the CeedVector of a CeedOperatorField 85843bbe138SJeremy L Thompson 85943bbe138SJeremy L Thompson @param op_field CeedOperatorField 86043bbe138SJeremy L Thompson @param[out] vec Variable to store CeedVector 86143bbe138SJeremy L Thompson 86243bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 86343bbe138SJeremy L Thompson 864e9b533fbSJeremy L Thompson @ref Advanced 86543bbe138SJeremy L Thompson **/ 86643bbe138SJeremy L Thompson int CeedOperatorFieldGetVector(CeedOperatorField op_field, CeedVector *vec) { 86743bbe138SJeremy L Thompson *vec = op_field->vec; 86843bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 86943bbe138SJeremy L Thompson } 87043bbe138SJeremy L Thompson 87143bbe138SJeremy L Thompson /** 87252d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 873288c0443SJeremy L Thompson 874d1d35e2fSjeremylt @param[out] composite_op Composite CeedOperator 875d1d35e2fSjeremylt @param sub_op Sub-operator CeedOperator 87652d6035fSJeremy L Thompson 87752d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 87852d6035fSJeremy L Thompson 8797a982d89SJeremy L. Thompson @ref User 88052d6035fSJeremy L Thompson */ 881d1d35e2fSjeremylt int CeedCompositeOperatorAddSub(CeedOperator composite_op, 882d1d35e2fSjeremylt CeedOperator sub_op) { 88334359f16Sjeremylt int ierr; 88434359f16Sjeremylt 885f04ea552SJeremy L Thompson if (!composite_op->is_composite) 886c042f62fSJeremy L Thompson // LCOV_EXCL_START 887d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_MINOR, 888e2f04181SAndrew T. Barker "CeedOperator is not a composite operator"); 889c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 89052d6035fSJeremy L Thompson 891d1d35e2fSjeremylt if (composite_op->num_suboperators == CEED_COMPOSITE_MAX) 892c042f62fSJeremy L Thompson // LCOV_EXCL_START 893d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_UNSUPPORTED, 894d1d35e2fSjeremylt "Cannot add additional sub_operators"); 895c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 896f04ea552SJeremy L Thompson if (composite_op->is_immutable) 897f04ea552SJeremy L Thompson // LCOV_EXCL_START 898f04ea552SJeremy L Thompson return CeedError(composite_op->ceed, CEED_ERROR_MAJOR, 899f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 900f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 90152d6035fSJeremy L Thompson 902d1d35e2fSjeremylt composite_op->sub_operators[composite_op->num_suboperators] = sub_op; 9039560d06aSjeremylt ierr = CeedOperatorReference(sub_op); CeedChk(ierr); 904d1d35e2fSjeremylt composite_op->num_suboperators++; 905e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 90652d6035fSJeremy L Thompson } 90752d6035fSJeremy L Thompson 90852d6035fSJeremy L Thompson /** 9094db537f9SJeremy L Thompson @brief Check if a CeedOperator is ready to be used. 9104db537f9SJeremy L Thompson 9114db537f9SJeremy L Thompson @param[in] op CeedOperator to check 9124db537f9SJeremy L Thompson 9134db537f9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 9144db537f9SJeremy L Thompson 9154db537f9SJeremy L Thompson @ref User 9164db537f9SJeremy L Thompson **/ 9174db537f9SJeremy L Thompson int CeedOperatorCheckReady(CeedOperator op) { 9184db537f9SJeremy L Thompson int ierr; 9194db537f9SJeremy L Thompson Ceed ceed; 9204db537f9SJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 9214db537f9SJeremy L Thompson 9224db537f9SJeremy L Thompson if (op->is_interface_setup) 9234db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 9244db537f9SJeremy L Thompson 9254db537f9SJeremy L Thompson CeedQFunction qf = op->qf; 9264db537f9SJeremy L Thompson if (op->is_composite) { 9274db537f9SJeremy L Thompson if (!op->num_suboperators) 9284db537f9SJeremy L Thompson // LCOV_EXCL_START 9294db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "No sub_operators set"); 9304db537f9SJeremy L Thompson // LCOV_EXCL_STOP 9314db537f9SJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 9324db537f9SJeremy L Thompson ierr = CeedOperatorCheckReady(op->sub_operators[i]); CeedChk(ierr); 9334db537f9SJeremy L Thompson } 9344db537f9SJeremy L Thompson } else { 9354db537f9SJeremy L Thompson if (op->num_fields == 0) 9364db537f9SJeremy L Thompson // LCOV_EXCL_START 9374db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "No operator fields set"); 9384db537f9SJeremy L Thompson // LCOV_EXCL_STOP 9394db537f9SJeremy L Thompson if (op->num_fields < qf->num_input_fields + qf->num_output_fields) 9404db537f9SJeremy L Thompson // LCOV_EXCL_START 9414db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "Not all operator fields set"); 9424db537f9SJeremy L Thompson // LCOV_EXCL_STOP 9434db537f9SJeremy L Thompson if (!op->has_restriction) 9444db537f9SJeremy L Thompson // LCOV_EXCL_START 9454db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, 9464db537f9SJeremy L Thompson "At least one restriction required"); 9474db537f9SJeremy L Thompson // LCOV_EXCL_STOP 9484db537f9SJeremy L Thompson if (op->num_qpts == 0) 9494db537f9SJeremy L Thompson // LCOV_EXCL_START 9504db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, 9514db537f9SJeremy L Thompson "At least one non-collocated basis is required " 9524db537f9SJeremy L Thompson "or the number of quadrature points must be set"); 9534db537f9SJeremy L Thompson // LCOV_EXCL_STOP 9544db537f9SJeremy L Thompson } 9554db537f9SJeremy L Thompson 9564db537f9SJeremy L Thompson // Flag as immutable and ready 9574db537f9SJeremy L Thompson op->is_interface_setup = true; 9584db537f9SJeremy L Thompson if (op->qf && op->qf != CEED_QFUNCTION_NONE) 9594db537f9SJeremy L Thompson // LCOV_EXCL_START 9604db537f9SJeremy L Thompson op->qf->is_immutable = true; 9614db537f9SJeremy L Thompson // LCOV_EXCL_STOP 9624db537f9SJeremy L Thompson if (op->dqf && op->dqf != CEED_QFUNCTION_NONE) 9634db537f9SJeremy L Thompson // LCOV_EXCL_START 9644db537f9SJeremy L Thompson op->dqf->is_immutable = true; 9654db537f9SJeremy L Thompson // LCOV_EXCL_STOP 9664db537f9SJeremy L Thompson if (op->dqfT && op->dqfT != CEED_QFUNCTION_NONE) 9674db537f9SJeremy L Thompson // LCOV_EXCL_START 9684db537f9SJeremy L Thompson op->dqfT->is_immutable = true; 9694db537f9SJeremy L Thompson // LCOV_EXCL_STOP 9704db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 9714db537f9SJeremy L Thompson } 9724db537f9SJeremy L Thompson 9734db537f9SJeremy L Thompson /** 974cd4dfc48Sjeremylt @brief Set the number of quadrature points associated with a CeedOperator. 975cd4dfc48Sjeremylt This should be used when creating a CeedOperator where every 976cd4dfc48Sjeremylt field has a collocated basis. This function cannot be used for 977cd4dfc48Sjeremylt composite CeedOperators. 978cd4dfc48Sjeremylt 979cd4dfc48Sjeremylt @param op CeedOperator 980cd4dfc48Sjeremylt @param num_qpts Number of quadrature points to set 981cd4dfc48Sjeremylt 982cd4dfc48Sjeremylt @return An error code: 0 - success, otherwise - failure 983cd4dfc48Sjeremylt 984e9b533fbSJeremy L Thompson @ref Advanced 985cd4dfc48Sjeremylt **/ 986cd4dfc48Sjeremylt int CeedOperatorSetNumQuadraturePoints(CeedOperator op, CeedInt num_qpts) { 987f04ea552SJeremy L Thompson if (op->is_composite) 988cd4dfc48Sjeremylt // LCOV_EXCL_START 989cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 990cd4dfc48Sjeremylt "Not defined for composite operator"); 991cd4dfc48Sjeremylt // LCOV_EXCL_STOP 992cd4dfc48Sjeremylt if (op->num_qpts) 993cd4dfc48Sjeremylt // LCOV_EXCL_START 994cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 995cd4dfc48Sjeremylt "Number of quadrature points already defined"); 996cd4dfc48Sjeremylt // LCOV_EXCL_STOP 997f04ea552SJeremy L Thompson if (op->is_immutable) 998f04ea552SJeremy L Thompson // LCOV_EXCL_START 999f04ea552SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 1000f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 1001f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 1002cd4dfc48Sjeremylt 1003cd4dfc48Sjeremylt op->num_qpts = num_qpts; 1004cd4dfc48Sjeremylt return CEED_ERROR_SUCCESS; 1005cd4dfc48Sjeremylt } 1006cd4dfc48Sjeremylt 1007cd4dfc48Sjeremylt /** 10087a982d89SJeremy L. Thompson @brief View a CeedOperator 10097a982d89SJeremy L. Thompson 10107a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 10117a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 10127a982d89SJeremy L. Thompson 10137a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 10147a982d89SJeremy L. Thompson 10157a982d89SJeremy L. Thompson @ref User 10167a982d89SJeremy L. Thompson **/ 10177a982d89SJeremy L. Thompson int CeedOperatorView(CeedOperator op, FILE *stream) { 10187a982d89SJeremy L. Thompson int ierr; 10197a982d89SJeremy L. Thompson 1020f04ea552SJeremy L Thompson if (op->is_composite) { 10217a982d89SJeremy L. Thompson fprintf(stream, "Composite CeedOperator\n"); 10227a982d89SJeremy L. Thompson 1023d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 10247a982d89SJeremy L. Thompson fprintf(stream, " SubOperator [%d]:\n", i); 1025d1d35e2fSjeremylt ierr = CeedOperatorSingleView(op->sub_operators[i], 1, stream); 10267a982d89SJeremy L. Thompson CeedChk(ierr); 10277a982d89SJeremy L. Thompson } 10287a982d89SJeremy L. Thompson } else { 10297a982d89SJeremy L. Thompson fprintf(stream, "CeedOperator\n"); 10307a982d89SJeremy L. Thompson ierr = CeedOperatorSingleView(op, 0, stream); CeedChk(ierr); 10317a982d89SJeremy L. Thompson } 1032e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 10337a982d89SJeremy L. Thompson } 10343bd813ffSjeremylt 10353bd813ffSjeremylt /** 1036b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedOperator 1037b7c9bbdaSJeremy L Thompson 1038b7c9bbdaSJeremy L Thompson @param op CeedOperator 1039b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 1040b7c9bbdaSJeremy L Thompson 1041b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1042b7c9bbdaSJeremy L Thompson 1043b7c9bbdaSJeremy L Thompson @ref Advanced 1044b7c9bbdaSJeremy L Thompson **/ 1045b7c9bbdaSJeremy L Thompson int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 1046b7c9bbdaSJeremy L Thompson *ceed = op->ceed; 1047b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1048b7c9bbdaSJeremy L Thompson } 1049b7c9bbdaSJeremy L Thompson 1050b7c9bbdaSJeremy L Thompson /** 1051b7c9bbdaSJeremy L Thompson @brief Get the number of elements associated with a CeedOperator 1052b7c9bbdaSJeremy L Thompson 1053b7c9bbdaSJeremy L Thompson @param op CeedOperator 1054b7c9bbdaSJeremy L Thompson @param[out] num_elem Variable to store number of elements 1055b7c9bbdaSJeremy L Thompson 1056b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1057b7c9bbdaSJeremy L Thompson 1058b7c9bbdaSJeremy L Thompson @ref Advanced 1059b7c9bbdaSJeremy L Thompson **/ 1060b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumElements(CeedOperator op, CeedInt *num_elem) { 1061b7c9bbdaSJeremy L Thompson if (op->is_composite) 1062b7c9bbdaSJeremy L Thompson // LCOV_EXCL_START 1063b7c9bbdaSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 1064b7c9bbdaSJeremy L Thompson "Not defined for composite operator"); 1065b7c9bbdaSJeremy L Thompson // LCOV_EXCL_STOP 1066b7c9bbdaSJeremy L Thompson 1067b7c9bbdaSJeremy L Thompson *num_elem = op->num_elem; 1068b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1069b7c9bbdaSJeremy L Thompson } 1070b7c9bbdaSJeremy L Thompson 1071b7c9bbdaSJeremy L Thompson /** 1072b7c9bbdaSJeremy L Thompson @brief Get the number of quadrature points associated with a CeedOperator 1073b7c9bbdaSJeremy L Thompson 1074b7c9bbdaSJeremy L Thompson @param op CeedOperator 1075b7c9bbdaSJeremy L Thompson @param[out] num_qpts Variable to store vector number of quadrature points 1076b7c9bbdaSJeremy L Thompson 1077b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1078b7c9bbdaSJeremy L Thompson 1079b7c9bbdaSJeremy L Thompson @ref Advanced 1080b7c9bbdaSJeremy L Thompson **/ 1081b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *num_qpts) { 1082b7c9bbdaSJeremy L Thompson if (op->is_composite) 1083b7c9bbdaSJeremy L Thompson // LCOV_EXCL_START 1084b7c9bbdaSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 1085b7c9bbdaSJeremy L Thompson "Not defined for composite operator"); 1086b7c9bbdaSJeremy L Thompson // LCOV_EXCL_STOP 1087b7c9bbdaSJeremy L Thompson 1088b7c9bbdaSJeremy L Thompson *num_qpts = op->num_qpts; 1089b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1090b7c9bbdaSJeremy L Thompson } 1091b7c9bbdaSJeremy L Thompson 1092b7c9bbdaSJeremy L Thompson /** 1093*d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field holding a double precision value. 1094*d8dd9a91SJeremy L Thompson For composite operators, the value is set in all 1095*d8dd9a91SJeremy L Thompson sub-operator QFunctionContexts that have a matching `field_name`. 1096*d8dd9a91SJeremy L Thompson 1097*d8dd9a91SJeremy L Thompson @param op CeedOperator 1098*d8dd9a91SJeremy L Thompson @param field_name Name of field to register 1099*d8dd9a91SJeremy L Thompson @param value Value to set 1100*d8dd9a91SJeremy L Thompson 1101*d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1102*d8dd9a91SJeremy L Thompson 1103*d8dd9a91SJeremy L Thompson @ref User 1104*d8dd9a91SJeremy L Thompson **/ 1105*d8dd9a91SJeremy L Thompson int CeedOperatorContextSetDouble(CeedOperator op, const char *field_name, 1106*d8dd9a91SJeremy L Thompson double value) { 1107*d8dd9a91SJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_name, CEED_CONTEXT_FIELD_DOUBLE, 1108*d8dd9a91SJeremy L Thompson &value); 1109*d8dd9a91SJeremy L Thompson } 1110*d8dd9a91SJeremy L Thompson 1111*d8dd9a91SJeremy L Thompson /** 1112*d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field holding an int32 value. 1113*d8dd9a91SJeremy L Thompson For composite operators, the value is set in all 1114*d8dd9a91SJeremy L Thompson sub-operator QFunctionContexts that have a matching `field_name`. 1115*d8dd9a91SJeremy L Thompson 1116*d8dd9a91SJeremy L Thompson @param op CeedOperator 1117*d8dd9a91SJeremy L Thompson @param field_name Name of field to set 1118*d8dd9a91SJeremy L Thompson @param value Value to set 1119*d8dd9a91SJeremy L Thompson 1120*d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1121*d8dd9a91SJeremy L Thompson 1122*d8dd9a91SJeremy L Thompson @ref User 1123*d8dd9a91SJeremy L Thompson **/ 1124*d8dd9a91SJeremy L Thompson int CeedOperatorContextSetInt32(CeedOperator op, const char *field_name, 1125*d8dd9a91SJeremy L Thompson int value) { 1126*d8dd9a91SJeremy L Thompson return CeedOperatorContextSetGeneric(op, field_name, CEED_CONTEXT_FIELD_INT32, 1127*d8dd9a91SJeremy L Thompson &value); 1128*d8dd9a91SJeremy L Thompson return CEED_ERROR_SUCCESS; 1129*d8dd9a91SJeremy L Thompson } 1130*d8dd9a91SJeremy L Thompson 1131*d8dd9a91SJeremy L Thompson /** 11323bd813ffSjeremylt @brief Apply CeedOperator to a vector 1133d7b241e6Sjeremylt 1134d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 1135d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 1136d7b241e6Sjeremylt CeedOperatorSetField(). 1137d7b241e6Sjeremylt 1138f04ea552SJeremy L Thompson Note: Calling this function asserts that setup is complete 1139f04ea552SJeremy L Thompson and sets the CeedOperator as immutable. 1140f04ea552SJeremy L Thompson 1141d7b241e6Sjeremylt @param op CeedOperator to apply 11424cc79fe7SJed Brown @param[in] in CeedVector containing input state or @ref CEED_VECTOR_NONE if 114334138859Sjeremylt there are no active inputs 1144b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 11454cc79fe7SJed Brown distinct from @a in) or @ref CEED_VECTOR_NONE if there are no 114634138859Sjeremylt active outputs 1147d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 11484cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1149b11c1e72Sjeremylt 1150b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1151dfdf5a53Sjeremylt 11527a982d89SJeremy L. Thompson @ref User 1153b11c1e72Sjeremylt **/ 1154692c2638Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, 1155692c2638Sjeremylt CeedRequest *request) { 1156d7b241e6Sjeremylt int ierr; 1157e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1158d7b241e6Sjeremylt 1159d1d35e2fSjeremylt if (op->num_elem) { 1160250756a7Sjeremylt // Standard Operator 1161cae8b89aSjeremylt if (op->Apply) { 1162250756a7Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 1163cae8b89aSjeremylt } else { 1164cae8b89aSjeremylt // Zero all output vectors 1165250756a7Sjeremylt CeedQFunction qf = op->qf; 1166d1d35e2fSjeremylt for (CeedInt i=0; i<qf->num_output_fields; i++) { 1167d1d35e2fSjeremylt CeedVector vec = op->output_fields[i]->vec; 1168cae8b89aSjeremylt if (vec == CEED_VECTOR_ACTIVE) 1169cae8b89aSjeremylt vec = out; 1170cae8b89aSjeremylt if (vec != CEED_VECTOR_NONE) { 1171cae8b89aSjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1172cae8b89aSjeremylt } 1173cae8b89aSjeremylt } 1174250756a7Sjeremylt // Apply 1175250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1176250756a7Sjeremylt } 1177f04ea552SJeremy L Thompson } else if (op->is_composite) { 1178250756a7Sjeremylt // Composite Operator 1179250756a7Sjeremylt if (op->ApplyComposite) { 1180250756a7Sjeremylt ierr = op->ApplyComposite(op, in, out, request); CeedChk(ierr); 1181250756a7Sjeremylt } else { 1182d1d35e2fSjeremylt CeedInt num_suboperators; 1183d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1184d1d35e2fSjeremylt CeedOperator *sub_operators; 1185d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1186250756a7Sjeremylt 1187250756a7Sjeremylt // Zero all output vectors 1188250756a7Sjeremylt if (out != CEED_VECTOR_NONE) { 1189cae8b89aSjeremylt ierr = CeedVectorSetValue(out, 0.0); CeedChk(ierr); 1190cae8b89aSjeremylt } 1191d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1192d1d35e2fSjeremylt for (CeedInt j=0; j<sub_operators[i]->qf->num_output_fields; j++) { 1193d1d35e2fSjeremylt CeedVector vec = sub_operators[i]->output_fields[j]->vec; 1194250756a7Sjeremylt if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) { 1195250756a7Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1196250756a7Sjeremylt } 1197250756a7Sjeremylt } 1198250756a7Sjeremylt } 1199250756a7Sjeremylt // Apply 1200d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 1201d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(op->sub_operators[i], in, out, request); 1202cae8b89aSjeremylt CeedChk(ierr); 1203cae8b89aSjeremylt } 1204cae8b89aSjeremylt } 1205250756a7Sjeremylt } 1206e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1207cae8b89aSjeremylt } 1208cae8b89aSjeremylt 1209cae8b89aSjeremylt /** 1210cae8b89aSjeremylt @brief Apply CeedOperator to a vector and add result to output vector 1211cae8b89aSjeremylt 1212cae8b89aSjeremylt This computes the action of the operator on the specified (active) input, 1213cae8b89aSjeremylt yielding its (active) output. All inputs and outputs must be specified using 1214cae8b89aSjeremylt CeedOperatorSetField(). 1215cae8b89aSjeremylt 1216cae8b89aSjeremylt @param op CeedOperator to apply 1217cae8b89aSjeremylt @param[in] in CeedVector containing input state or NULL if there are no 1218cae8b89aSjeremylt active inputs 1219cae8b89aSjeremylt @param[out] out CeedVector to sum in result of applying operator (must be 1220cae8b89aSjeremylt distinct from @a in) or NULL if there are no active outputs 1221cae8b89aSjeremylt @param request Address of CeedRequest for non-blocking completion, else 12224cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1223cae8b89aSjeremylt 1224cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 1225cae8b89aSjeremylt 12267a982d89SJeremy L. Thompson @ref User 1227cae8b89aSjeremylt **/ 1228cae8b89aSjeremylt int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, 1229cae8b89aSjeremylt CeedRequest *request) { 1230cae8b89aSjeremylt int ierr; 1231e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1232cae8b89aSjeremylt 1233d1d35e2fSjeremylt if (op->num_elem) { 1234250756a7Sjeremylt // Standard Operator 1235250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1236f04ea552SJeremy L Thompson } else if (op->is_composite) { 1237250756a7Sjeremylt // Composite Operator 1238250756a7Sjeremylt if (op->ApplyAddComposite) { 1239250756a7Sjeremylt ierr = op->ApplyAddComposite(op, in, out, request); CeedChk(ierr); 1240cae8b89aSjeremylt } else { 1241d1d35e2fSjeremylt CeedInt num_suboperators; 1242d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1243d1d35e2fSjeremylt CeedOperator *sub_operators; 1244d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1245250756a7Sjeremylt 1246d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1247d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(sub_operators[i], in, out, request); 1248cae8b89aSjeremylt CeedChk(ierr); 12491d7d2407SJeremy L Thompson } 1250250756a7Sjeremylt } 1251250756a7Sjeremylt } 1252e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1253d7b241e6Sjeremylt } 1254d7b241e6Sjeremylt 1255d7b241e6Sjeremylt /** 1256b11c1e72Sjeremylt @brief Destroy a CeedOperator 1257d7b241e6Sjeremylt 1258d7b241e6Sjeremylt @param op CeedOperator to destroy 1259b11c1e72Sjeremylt 1260b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1261dfdf5a53Sjeremylt 12627a982d89SJeremy L. Thompson @ref User 1263b11c1e72Sjeremylt **/ 1264d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 1265d7b241e6Sjeremylt int ierr; 1266d7b241e6Sjeremylt 1267d1d35e2fSjeremylt if (!*op || --(*op)->ref_count > 0) return CEED_ERROR_SUCCESS; 1268d7b241e6Sjeremylt if ((*op)->Destroy) { 1269d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 1270d7b241e6Sjeremylt } 1271fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 1272fe2413ffSjeremylt // Free fields 1273d1d35e2fSjeremylt for (int i=0; i<(*op)->num_fields; i++) 1274d1d35e2fSjeremylt if ((*op)->input_fields[i]) { 1275d1d35e2fSjeremylt if ((*op)->input_fields[i]->elem_restr != CEED_ELEMRESTRICTION_NONE) { 1276d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->input_fields[i]->elem_restr); 127771352a93Sjeremylt CeedChk(ierr); 127815910d16Sjeremylt } 1279d1d35e2fSjeremylt if ((*op)->input_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1280d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->input_fields[i]->basis); CeedChk(ierr); 128171352a93Sjeremylt } 1282d1d35e2fSjeremylt if ((*op)->input_fields[i]->vec != CEED_VECTOR_ACTIVE && 1283d1d35e2fSjeremylt (*op)->input_fields[i]->vec != CEED_VECTOR_NONE ) { 1284d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->input_fields[i]->vec); CeedChk(ierr); 128571352a93Sjeremylt } 1286d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]->field_name); CeedChk(ierr); 1287d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]); CeedChk(ierr); 1288fe2413ffSjeremylt } 1289d1d35e2fSjeremylt for (int i=0; i<(*op)->num_fields; i++) 1290d1d35e2fSjeremylt if ((*op)->output_fields[i]) { 1291d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->output_fields[i]->elem_restr); 129271352a93Sjeremylt CeedChk(ierr); 1293d1d35e2fSjeremylt if ((*op)->output_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1294d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->output_fields[i]->basis); CeedChk(ierr); 129571352a93Sjeremylt } 1296d1d35e2fSjeremylt if ((*op)->output_fields[i]->vec != CEED_VECTOR_ACTIVE && 1297d1d35e2fSjeremylt (*op)->output_fields[i]->vec != CEED_VECTOR_NONE ) { 1298d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->output_fields[i]->vec); CeedChk(ierr); 129971352a93Sjeremylt } 1300d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]->field_name); CeedChk(ierr); 1301d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]); CeedChk(ierr); 1302fe2413ffSjeremylt } 1303d1d35e2fSjeremylt // Destroy sub_operators 1304d1d35e2fSjeremylt for (int i=0; i<(*op)->num_suboperators; i++) 1305d1d35e2fSjeremylt if ((*op)->sub_operators[i]) { 1306d1d35e2fSjeremylt ierr = CeedOperatorDestroy(&(*op)->sub_operators[i]); CeedChk(ierr); 130752d6035fSJeremy L Thompson } 1308d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 1309d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 1310d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 1311fe2413ffSjeremylt 13125107b09fSJeremy L Thompson // Destroy fallback 1313d1d35e2fSjeremylt if ((*op)->op_fallback) { 1314d1d35e2fSjeremylt ierr = (*op)->qf_fallback->Destroy((*op)->qf_fallback); CeedChk(ierr); 1315d1d35e2fSjeremylt ierr = CeedFree(&(*op)->qf_fallback); CeedChk(ierr); 131670a7ffb3SJeremy L Thompson ierr = CeedVectorDestroy(&(*op)->op_fallback->qf_assembled); CeedChk(ierr); 131770a7ffb3SJeremy L Thompson ierr = CeedElemRestrictionDestroy(&(*op)->op_fallback->qf_assembled_rstr); 131870a7ffb3SJeremy L Thompson CeedChk(ierr); 1319d1d35e2fSjeremylt ierr = (*op)->op_fallback->Destroy((*op)->op_fallback); CeedChk(ierr); 1320d1d35e2fSjeremylt ierr = CeedFree(&(*op)->op_fallback); CeedChk(ierr); 13215107b09fSJeremy L Thompson } 13225107b09fSJeremy L Thompson 132370a7ffb3SJeremy L Thompson // Destroy QF assembly cache 132470a7ffb3SJeremy L Thompson ierr = CeedVectorDestroy(&(*op)->qf_assembled); CeedChk(ierr); 132570a7ffb3SJeremy L Thompson ierr = CeedElemRestrictionDestroy(&(*op)->qf_assembled_rstr); CeedChk(ierr); 132670a7ffb3SJeremy L Thompson 1327d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields); CeedChk(ierr); 1328d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields); CeedChk(ierr); 1329d1d35e2fSjeremylt ierr = CeedFree(&(*op)->sub_operators); CeedChk(ierr); 1330d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 1331e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1332d7b241e6Sjeremylt } 1333d7b241e6Sjeremylt 1334d7b241e6Sjeremylt /// @} 1335