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 2677a982d89SJeremy L. Thompson /// @} 2687a982d89SJeremy L. Thompson 2697a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2707a982d89SJeremy L. Thompson /// CeedOperator Backend API 2717a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2727a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorBackend 2737a982d89SJeremy L. Thompson /// @{ 2747a982d89SJeremy L. Thompson 2757a982d89SJeremy L. Thompson /** 2767a982d89SJeremy L. Thompson @brief Get the number of arguments associated with a CeedOperator 2777a982d89SJeremy L. Thompson 2787a982d89SJeremy L. Thompson @param op CeedOperator 279d1d35e2fSjeremylt @param[out] num_args Variable to store vector number of arguments 2807a982d89SJeremy L. Thompson 2817a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2827a982d89SJeremy L. Thompson 2837a982d89SJeremy L. Thompson @ref Backend 2847a982d89SJeremy L. Thompson **/ 2857a982d89SJeremy L. Thompson 286d1d35e2fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *num_args) { 287f04ea552SJeremy L Thompson if (op->is_composite) 2887a982d89SJeremy L. Thompson // LCOV_EXCL_START 289e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 290e15f9bd0SJeremy L Thompson "Not defined for composite operators"); 2917a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 2927a982d89SJeremy L. Thompson 293d1d35e2fSjeremylt *num_args = op->num_fields; 294e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2957a982d89SJeremy L. Thompson } 2967a982d89SJeremy L. Thompson 2977a982d89SJeremy L. Thompson /** 2987a982d89SJeremy L. Thompson @brief Get the setup status of a CeedOperator 2997a982d89SJeremy L. Thompson 3007a982d89SJeremy L. Thompson @param op CeedOperator 301d1d35e2fSjeremylt @param[out] is_setup_done Variable to store setup status 3027a982d89SJeremy L. Thompson 3037a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3047a982d89SJeremy L. Thompson 3057a982d89SJeremy L. Thompson @ref Backend 3067a982d89SJeremy L. Thompson **/ 3077a982d89SJeremy L. Thompson 308d1d35e2fSjeremylt int CeedOperatorIsSetupDone(CeedOperator op, bool *is_setup_done) { 309f04ea552SJeremy L Thompson *is_setup_done = op->is_backend_setup; 310e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3117a982d89SJeremy L. Thompson } 3127a982d89SJeremy L. Thompson 3137a982d89SJeremy L. Thompson /** 3147a982d89SJeremy L. Thompson @brief Get the QFunction associated with a CeedOperator 3157a982d89SJeremy L. Thompson 3167a982d89SJeremy L. Thompson @param op CeedOperator 3177a982d89SJeremy L. Thompson @param[out] qf Variable to store QFunction 3187a982d89SJeremy L. Thompson 3197a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3207a982d89SJeremy L. Thompson 3217a982d89SJeremy L. Thompson @ref Backend 3227a982d89SJeremy L. Thompson **/ 3237a982d89SJeremy L. Thompson 3247a982d89SJeremy L. Thompson int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 325f04ea552SJeremy L Thompson if (op->is_composite) 3267a982d89SJeremy L. Thompson // LCOV_EXCL_START 327e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 328e15f9bd0SJeremy L Thompson "Not defined for composite operator"); 3297a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 3307a982d89SJeremy L. Thompson 3317a982d89SJeremy L. Thompson *qf = op->qf; 332e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3337a982d89SJeremy L. Thompson } 3347a982d89SJeremy L. Thompson 3357a982d89SJeremy L. Thompson /** 336c04a41a7SJeremy L Thompson @brief Get a boolean value indicating if the CeedOperator is composite 337c04a41a7SJeremy L Thompson 338c04a41a7SJeremy L Thompson @param op CeedOperator 339d1d35e2fSjeremylt @param[out] is_composite Variable to store composite status 340c04a41a7SJeremy L Thompson 341c04a41a7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 342c04a41a7SJeremy L Thompson 343c04a41a7SJeremy L Thompson @ref Backend 344c04a41a7SJeremy L Thompson **/ 345c04a41a7SJeremy L Thompson 346d1d35e2fSjeremylt int CeedOperatorIsComposite(CeedOperator op, bool *is_composite) { 347f04ea552SJeremy L Thompson *is_composite = op->is_composite; 348e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 349c04a41a7SJeremy L Thompson } 350c04a41a7SJeremy L Thompson 351c04a41a7SJeremy L Thompson /** 352d1d35e2fSjeremylt @brief Get the number of sub_operators associated with a CeedOperator 3537a982d89SJeremy L. Thompson 3547a982d89SJeremy L. Thompson @param op CeedOperator 355d1d35e2fSjeremylt @param[out] num_suboperators Variable to store number of sub_operators 3567a982d89SJeremy L. Thompson 3577a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3587a982d89SJeremy L. Thompson 3597a982d89SJeremy L. Thompson @ref Backend 3607a982d89SJeremy L. Thompson **/ 3617a982d89SJeremy L. Thompson 362d1d35e2fSjeremylt int CeedOperatorGetNumSub(CeedOperator op, CeedInt *num_suboperators) { 363f04ea552SJeremy L Thompson if (!op->is_composite) 3647a982d89SJeremy L. Thompson // LCOV_EXCL_START 365e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 3667a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 3677a982d89SJeremy L. Thompson 368d1d35e2fSjeremylt *num_suboperators = op->num_suboperators; 369e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3707a982d89SJeremy L. Thompson } 3717a982d89SJeremy L. Thompson 3727a982d89SJeremy L. Thompson /** 373d1d35e2fSjeremylt @brief Get the list of sub_operators associated with a CeedOperator 3747a982d89SJeremy L. Thompson 3757a982d89SJeremy L. Thompson @param op CeedOperator 376d1d35e2fSjeremylt @param[out] sub_operators Variable to store list of sub_operators 3777a982d89SJeremy L. Thompson 3787a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3797a982d89SJeremy L. Thompson 3807a982d89SJeremy L. Thompson @ref Backend 3817a982d89SJeremy L. Thompson **/ 3827a982d89SJeremy L. Thompson 383d1d35e2fSjeremylt int CeedOperatorGetSubList(CeedOperator op, CeedOperator **sub_operators) { 384f04ea552SJeremy L Thompson if (!op->is_composite) 3857a982d89SJeremy L. Thompson // LCOV_EXCL_START 386e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 3877a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 3887a982d89SJeremy L. Thompson 389d1d35e2fSjeremylt *sub_operators = op->sub_operators; 390e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3917a982d89SJeremy L. Thompson } 3927a982d89SJeremy L. Thompson 3937a982d89SJeremy L. Thompson /** 3947a982d89SJeremy L. Thompson @brief Get the backend data of a CeedOperator 3957a982d89SJeremy L. Thompson 3967a982d89SJeremy L. Thompson @param op CeedOperator 3977a982d89SJeremy L. Thompson @param[out] data Variable to store data 3987a982d89SJeremy L. Thompson 3997a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4007a982d89SJeremy L. Thompson 4017a982d89SJeremy L. Thompson @ref Backend 4027a982d89SJeremy L. Thompson **/ 4037a982d89SJeremy L. Thompson 404777ff853SJeremy L Thompson int CeedOperatorGetData(CeedOperator op, void *data) { 405777ff853SJeremy L Thompson *(void **)data = op->data; 406e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4077a982d89SJeremy L. Thompson } 4087a982d89SJeremy L. Thompson 4097a982d89SJeremy L. Thompson /** 4107a982d89SJeremy L. Thompson @brief Set the backend data of a CeedOperator 4117a982d89SJeremy L. Thompson 4127a982d89SJeremy L. Thompson @param[out] op CeedOperator 4137a982d89SJeremy L. Thompson @param data Data to set 4147a982d89SJeremy L. Thompson 4157a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4167a982d89SJeremy L. Thompson 4177a982d89SJeremy L. Thompson @ref Backend 4187a982d89SJeremy L. Thompson **/ 4197a982d89SJeremy L. Thompson 420777ff853SJeremy L Thompson int CeedOperatorSetData(CeedOperator op, void *data) { 421777ff853SJeremy L Thompson op->data = data; 422e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4237a982d89SJeremy L. Thompson } 4247a982d89SJeremy L. Thompson 4257a982d89SJeremy L. Thompson /** 42634359f16Sjeremylt @brief Increment the reference counter for a CeedOperator 42734359f16Sjeremylt 42834359f16Sjeremylt @param op CeedOperator to increment the reference counter 42934359f16Sjeremylt 43034359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 43134359f16Sjeremylt 43234359f16Sjeremylt @ref Backend 43334359f16Sjeremylt **/ 4349560d06aSjeremylt int CeedOperatorReference(CeedOperator op) { 43534359f16Sjeremylt op->ref_count++; 43634359f16Sjeremylt return CEED_ERROR_SUCCESS; 43734359f16Sjeremylt } 43834359f16Sjeremylt 43934359f16Sjeremylt /** 4407a982d89SJeremy L. Thompson @brief Set the setup flag of a CeedOperator to True 4417a982d89SJeremy L. Thompson 4427a982d89SJeremy L. Thompson @param op CeedOperator 4437a982d89SJeremy L. Thompson 4447a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4457a982d89SJeremy L. Thompson 4467a982d89SJeremy L. Thompson @ref Backend 4477a982d89SJeremy L. Thompson **/ 4487a982d89SJeremy L. Thompson 4497a982d89SJeremy L. Thompson int CeedOperatorSetSetupDone(CeedOperator op) { 450f04ea552SJeremy L Thompson op->is_backend_setup = true; 451e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4527a982d89SJeremy L. Thompson } 4537a982d89SJeremy L. Thompson 4547a982d89SJeremy L. Thompson /// @} 4557a982d89SJeremy L. Thompson 4567a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4577a982d89SJeremy L. Thompson /// CeedOperator Public API 4587a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4597a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorUser 460dfdf5a53Sjeremylt /// @{ 461d7b241e6Sjeremylt 462d7b241e6Sjeremylt /** 4630219ea01SJeremy L Thompson @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and 4640219ea01SJeremy L Thompson CeedElemRestriction can be associated with CeedQFunction fields with 4650219ea01SJeremy L Thompson \ref CeedOperatorSetField. 466d7b241e6Sjeremylt 467b11c1e72Sjeremylt @param ceed A Ceed object where the CeedOperator will be created 468d7b241e6Sjeremylt @param qf QFunction defining the action of the operator at quadrature points 46934138859Sjeremylt @param dqf QFunction defining the action of the Jacobian of @a qf (or 4704cc79fe7SJed Brown @ref CEED_QFUNCTION_NONE) 471d7b241e6Sjeremylt @param dqfT QFunction defining the action of the transpose of the Jacobian 4724cc79fe7SJed Brown of @a qf (or @ref CEED_QFUNCTION_NONE) 473b11c1e72Sjeremylt @param[out] op Address of the variable where the newly created 474b11c1e72Sjeremylt CeedOperator will be stored 475b11c1e72Sjeremylt 476b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 477dfdf5a53Sjeremylt 4787a982d89SJeremy L. Thompson @ref User 479d7b241e6Sjeremylt */ 480d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, 481d7b241e6Sjeremylt CeedQFunction dqfT, CeedOperator *op) { 482d7b241e6Sjeremylt int ierr; 483d7b241e6Sjeremylt 4845fe0d4faSjeremylt if (!ceed->OperatorCreate) { 4855fe0d4faSjeremylt Ceed delegate; 486aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 4875fe0d4faSjeremylt 4885fe0d4faSjeremylt if (!delegate) 489c042f62fSJeremy L Thompson // LCOV_EXCL_START 490e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 491e15f9bd0SJeremy L Thompson "Backend does not support OperatorCreate"); 492c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 4935fe0d4faSjeremylt 4945fe0d4faSjeremylt ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr); 495e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4965fe0d4faSjeremylt } 4975fe0d4faSjeremylt 498b3b7035fSJeremy L Thompson if (!qf || qf == CEED_QFUNCTION_NONE) 499b3b7035fSJeremy L Thompson // LCOV_EXCL_START 500e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 501e15f9bd0SJeremy L Thompson "Operator must have a valid QFunction."); 502b3b7035fSJeremy L Thompson // LCOV_EXCL_STOP 503d7b241e6Sjeremylt ierr = CeedCalloc(1, op); CeedChk(ierr); 504d7b241e6Sjeremylt (*op)->ceed = ceed; 5059560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 506d1d35e2fSjeremylt (*op)->ref_count = 1; 507d7b241e6Sjeremylt (*op)->qf = qf; 5089560d06aSjeremylt ierr = CeedQFunctionReference(qf); CeedChk(ierr); 509442e7f0bSjeremylt if (dqf && dqf != CEED_QFUNCTION_NONE) { 510d7b241e6Sjeremylt (*op)->dqf = dqf; 5119560d06aSjeremylt ierr = CeedQFunctionReference(dqf); CeedChk(ierr); 512442e7f0bSjeremylt } 513442e7f0bSjeremylt if (dqfT && dqfT != CEED_QFUNCTION_NONE) { 514d7b241e6Sjeremylt (*op)->dqfT = dqfT; 5159560d06aSjeremylt ierr = CeedQFunctionReference(dqfT); CeedChk(ierr); 516442e7f0bSjeremylt } 517*bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_FIELD_MAX, &(*op)->input_fields); CeedChk(ierr); 518*bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_FIELD_MAX, &(*op)->output_fields); CeedChk(ierr); 519d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 520e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 521d7b241e6Sjeremylt } 522d7b241e6Sjeremylt 523d7b241e6Sjeremylt /** 52452d6035fSJeremy L Thompson @brief Create an operator that composes the action of several operators 52552d6035fSJeremy L Thompson 52652d6035fSJeremy L Thompson @param ceed A Ceed object where the CeedOperator will be created 52752d6035fSJeremy L Thompson @param[out] op Address of the variable where the newly created 52852d6035fSJeremy L Thompson Composite CeedOperator will be stored 52952d6035fSJeremy L Thompson 53052d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 53152d6035fSJeremy L Thompson 5327a982d89SJeremy L. Thompson @ref User 53352d6035fSJeremy L Thompson */ 53452d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) { 53552d6035fSJeremy L Thompson int ierr; 53652d6035fSJeremy L Thompson 53752d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 53852d6035fSJeremy L Thompson Ceed delegate; 539aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 54052d6035fSJeremy L Thompson 541250756a7Sjeremylt if (delegate) { 54252d6035fSJeremy L Thompson ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr); 543e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 54452d6035fSJeremy L Thompson } 545250756a7Sjeremylt } 54652d6035fSJeremy L Thompson 54752d6035fSJeremy L Thompson ierr = CeedCalloc(1, op); CeedChk(ierr); 54852d6035fSJeremy L Thompson (*op)->ceed = ceed; 5499560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 550f04ea552SJeremy L Thompson (*op)->is_composite = true; 551*bf4cb664SJeremy L Thompson ierr = CeedCalloc(CEED_COMPOSITE_MAX, &(*op)->sub_operators); CeedChk(ierr); 552250756a7Sjeremylt 553250756a7Sjeremylt if (ceed->CompositeOperatorCreate) { 55452d6035fSJeremy L Thompson ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr); 555250756a7Sjeremylt } 556e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 55752d6035fSJeremy L Thompson } 55852d6035fSJeremy L Thompson 55952d6035fSJeremy L Thompson /** 5609560d06aSjeremylt @brief Copy the pointer to a CeedOperator. Both pointers should 5619560d06aSjeremylt be destroyed with `CeedOperatorDestroy()`; 5629560d06aSjeremylt Note: If `*op_copy` is non-NULL, then it is assumed that 5639560d06aSjeremylt `*op_copy` is a pointer to a CeedOperator. This 5649560d06aSjeremylt CeedOperator will be destroyed if `*op_copy` is the only 5659560d06aSjeremylt reference to this CeedOperator. 5669560d06aSjeremylt 5679560d06aSjeremylt @param op CeedOperator to copy reference to 5689560d06aSjeremylt @param[out] op_copy Variable to store copied reference 5699560d06aSjeremylt 5709560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 5719560d06aSjeremylt 5729560d06aSjeremylt @ref User 5739560d06aSjeremylt **/ 5749560d06aSjeremylt int CeedOperatorReferenceCopy(CeedOperator op, CeedOperator *op_copy) { 5759560d06aSjeremylt int ierr; 5769560d06aSjeremylt 5779560d06aSjeremylt ierr = CeedOperatorReference(op); CeedChk(ierr); 5789560d06aSjeremylt ierr = CeedOperatorDestroy(op_copy); CeedChk(ierr); 5799560d06aSjeremylt *op_copy = op; 5809560d06aSjeremylt return CEED_ERROR_SUCCESS; 5819560d06aSjeremylt } 5829560d06aSjeremylt 5839560d06aSjeremylt /** 584b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 585d7b241e6Sjeremylt 586d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 587d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 588d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 589d7b241e6Sjeremylt 590d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 591d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 592d7b241e6Sjeremylt input and at most one active output. 593d7b241e6Sjeremylt 5948c91a0c9SJeremy L Thompson @param op CeedOperator on which to provide the field 595d1d35e2fSjeremylt @param field_name Name of the field (to be matched with the name used by 5968795c945Sjeremylt CeedQFunction) 597b11c1e72Sjeremylt @param r CeedElemRestriction 5984cc79fe7SJed Brown @param b CeedBasis in which the field resides or @ref CEED_BASIS_COLLOCATED 599b11c1e72Sjeremylt if collocated with quadrature points 6004cc79fe7SJed Brown @param v CeedVector to be used by CeedOperator or @ref CEED_VECTOR_ACTIVE 6014cc79fe7SJed Brown if field is active or @ref CEED_VECTOR_NONE if using 6024cc79fe7SJed Brown @ref CEED_EVAL_WEIGHT in the QFunction 603b11c1e72Sjeremylt 604b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 605dfdf5a53Sjeremylt 6067a982d89SJeremy L. Thompson @ref User 607b11c1e72Sjeremylt **/ 608d1d35e2fSjeremylt int CeedOperatorSetField(CeedOperator op, const char *field_name, 609a8d32208Sjeremylt CeedElemRestriction r, CeedBasis b, CeedVector v) { 610d7b241e6Sjeremylt int ierr; 611f04ea552SJeremy L Thompson if (op->is_composite) 612c042f62fSJeremy L Thompson // LCOV_EXCL_START 613e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 614e15f9bd0SJeremy L Thompson "Cannot add field to composite operator."); 615c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 616f04ea552SJeremy L Thompson if (op->is_immutable) 617f04ea552SJeremy L Thompson // LCOV_EXCL_START 618f04ea552SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 619f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 620f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 6218b067b84SJed Brown if (!r) 622c042f62fSJeremy L Thompson // LCOV_EXCL_START 623e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 624c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 625d1d35e2fSjeremylt field_name); 626c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 6278b067b84SJed Brown if (!b) 628c042f62fSJeremy L Thompson // LCOV_EXCL_START 629e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 630e15f9bd0SJeremy L Thompson "Basis b for field \"%s\" must be non-NULL.", 631d1d35e2fSjeremylt field_name); 632c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 6338b067b84SJed Brown if (!v) 634c042f62fSJeremy L Thompson // LCOV_EXCL_START 635e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 636e15f9bd0SJeremy L Thompson "Vector v for field \"%s\" must be non-NULL.", 637d1d35e2fSjeremylt field_name); 638c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 63952d6035fSJeremy L Thompson 640d1d35e2fSjeremylt CeedInt num_elem; 641d1d35e2fSjeremylt ierr = CeedElemRestrictionGetNumElements(r, &num_elem); CeedChk(ierr); 642d1d35e2fSjeremylt if (r != CEED_ELEMRESTRICTION_NONE && op->has_restriction && 643d1d35e2fSjeremylt op->num_elem != num_elem) 644c042f62fSJeremy L Thompson // LCOV_EXCL_START 645e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 6461d102b48SJeremy L Thompson "ElemRestriction with %d elements incompatible with prior " 647d1d35e2fSjeremylt "%d elements", num_elem, op->num_elem); 648c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 649d7b241e6Sjeremylt 65078464608Sjeremylt CeedInt num_qpts = 0; 651e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 652d1d35e2fSjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &num_qpts); CeedChk(ierr); 653d1d35e2fSjeremylt if (op->num_qpts && op->num_qpts != num_qpts) 654c042f62fSJeremy L Thompson // LCOV_EXCL_START 655e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 656e15f9bd0SJeremy L Thompson "Basis with %d quadrature points " 657d1d35e2fSjeremylt "incompatible with prior %d points", num_qpts, 658d1d35e2fSjeremylt op->num_qpts); 659c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 660d7b241e6Sjeremylt } 661d1d35e2fSjeremylt CeedQFunctionField qf_field; 662d1d35e2fSjeremylt CeedOperatorField *op_field; 663d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_input_fields; i++) { 664d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->input_fields[i]).field_name)) { 665d1d35e2fSjeremylt qf_field = op->qf->input_fields[i]; 666d1d35e2fSjeremylt op_field = &op->input_fields[i]; 667d7b241e6Sjeremylt goto found; 668d7b241e6Sjeremylt } 669d7b241e6Sjeremylt } 670d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_output_fields; i++) { 671d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->output_fields[i]).field_name)) { 672d1d35e2fSjeremylt qf_field = op->qf->output_fields[i]; 673d1d35e2fSjeremylt op_field = &op->output_fields[i]; 674d7b241e6Sjeremylt goto found; 675d7b241e6Sjeremylt } 676d7b241e6Sjeremylt } 677c042f62fSJeremy L Thompson // LCOV_EXCL_START 678e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPLETE, 679e15f9bd0SJeremy L Thompson "QFunction has no knowledge of field '%s'", 680d1d35e2fSjeremylt field_name); 681c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 682d7b241e6Sjeremylt found: 683d1d35e2fSjeremylt ierr = CeedOperatorCheckField(op->ceed, qf_field, r, b); CeedChk(ierr); 684d1d35e2fSjeremylt ierr = CeedCalloc(1, op_field); CeedChk(ierr); 685e15f9bd0SJeremy L Thompson 686d1d35e2fSjeremylt (*op_field)->vec = v; 687e15f9bd0SJeremy L Thompson if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) { 6889560d06aSjeremylt ierr = CeedVectorReference(v); CeedChk(ierr); 689e15f9bd0SJeremy L Thompson } 690e15f9bd0SJeremy L Thompson 691d1d35e2fSjeremylt (*op_field)->elem_restr = r; 6929560d06aSjeremylt ierr = CeedElemRestrictionReference(r); CeedChk(ierr); 693e15f9bd0SJeremy L Thompson if (r != CEED_ELEMRESTRICTION_NONE) { 694d1d35e2fSjeremylt op->num_elem = num_elem; 695d1d35e2fSjeremylt op->has_restriction = true; // Restriction set, but num_elem may be 0 696e15f9bd0SJeremy L Thompson } 697d99fa3c5SJeremy L Thompson 698d1d35e2fSjeremylt (*op_field)->basis = b; 699e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 700cd4dfc48Sjeremylt if (!op->num_qpts) { 701cd4dfc48Sjeremylt ierr = CeedOperatorSetNumQuadraturePoints(op, num_qpts); CeedChk(ierr); 702cd4dfc48Sjeremylt } 7039560d06aSjeremylt ierr = CeedBasisReference(b); CeedChk(ierr); 704e15f9bd0SJeremy L Thompson } 705e15f9bd0SJeremy L Thompson 706d1d35e2fSjeremylt op->num_fields += 1; 707d1d35e2fSjeremylt size_t len = strlen(field_name); 708d99fa3c5SJeremy L Thompson char *tmp; 709d99fa3c5SJeremy L Thompson ierr = CeedCalloc(len+1, &tmp); CeedChk(ierr); 710d1d35e2fSjeremylt memcpy(tmp, field_name, len+1); 711d1d35e2fSjeremylt (*op_field)->field_name = tmp; 712e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 713d7b241e6Sjeremylt } 714d7b241e6Sjeremylt 715d7b241e6Sjeremylt /** 71643bbe138SJeremy L Thompson @brief Get the CeedOperatorFields of a CeedOperator 71743bbe138SJeremy L Thompson 718f04ea552SJeremy L Thompson Note: Calling this function asserts that setup is complete 719f04ea552SJeremy L Thompson and sets the CeedOperator as immutable. 720f04ea552SJeremy L Thompson 72143bbe138SJeremy L Thompson @param op CeedOperator 722f74ec584SJeremy L Thompson @param[out] num_input_fields Variable to store number of input fields 72343bbe138SJeremy L Thompson @param[out] input_fields Variable to store input_fields 724f74ec584SJeremy L Thompson @param[out] num_output_fields Variable to store number of output fields 72543bbe138SJeremy L Thompson @param[out] output_fields Variable to store output_fields 72643bbe138SJeremy L Thompson 72743bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 72843bbe138SJeremy L Thompson 729e9b533fbSJeremy L Thompson @ref Advanced 73043bbe138SJeremy L Thompson **/ 73143bbe138SJeremy L Thompson int CeedOperatorGetFields(CeedOperator op, CeedInt *num_input_fields, 73243bbe138SJeremy L Thompson CeedOperatorField **input_fields, 73343bbe138SJeremy L Thompson CeedInt *num_output_fields, 73443bbe138SJeremy L Thompson CeedOperatorField **output_fields) { 735f04ea552SJeremy L Thompson int ierr; 736f04ea552SJeremy L Thompson 737f04ea552SJeremy L Thompson if (op->is_composite) 73843bbe138SJeremy L Thompson // LCOV_EXCL_START 73943bbe138SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 74043bbe138SJeremy L Thompson "Not defined for composite operator"); 74143bbe138SJeremy L Thompson // LCOV_EXCL_STOP 742f04ea552SJeremy L Thompson ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 74343bbe138SJeremy L Thompson 74443bbe138SJeremy L Thompson if (num_input_fields) *num_input_fields = op->qf->num_input_fields; 74543bbe138SJeremy L Thompson if (input_fields) *input_fields = op->input_fields; 74643bbe138SJeremy L Thompson if (num_output_fields) *num_output_fields = op->qf->num_output_fields; 74743bbe138SJeremy L Thompson if (output_fields) *output_fields = op->output_fields; 74843bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 74943bbe138SJeremy L Thompson } 75043bbe138SJeremy L Thompson 75143bbe138SJeremy L Thompson /** 75228567f8fSJeremy L Thompson @brief Get the name of a CeedOperatorField 75328567f8fSJeremy L Thompson 75428567f8fSJeremy L Thompson @param op_field CeedOperatorField 75528567f8fSJeremy L Thompson @param[out] field_name Variable to store the field name 75628567f8fSJeremy L Thompson 75728567f8fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 75828567f8fSJeremy L Thompson 759e9b533fbSJeremy L Thompson @ref Advanced 76028567f8fSJeremy L Thompson **/ 76128567f8fSJeremy L Thompson int CeedOperatorFieldGetName(CeedOperatorField op_field, char **field_name) { 76228567f8fSJeremy L Thompson *field_name = (char *)op_field->field_name; 76328567f8fSJeremy L Thompson return CEED_ERROR_SUCCESS; 76428567f8fSJeremy L Thompson } 76528567f8fSJeremy L Thompson 76628567f8fSJeremy L Thompson /** 76743bbe138SJeremy L Thompson @brief Get the CeedElemRestriction of a CeedOperatorField 76843bbe138SJeremy L Thompson 76943bbe138SJeremy L Thompson @param op_field CeedOperatorField 77043bbe138SJeremy L Thompson @param[out] rstr Variable to store CeedElemRestriction 77143bbe138SJeremy L Thompson 77243bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 77343bbe138SJeremy L Thompson 774e9b533fbSJeremy L Thompson @ref Advanced 77543bbe138SJeremy L Thompson **/ 77643bbe138SJeremy L Thompson int CeedOperatorFieldGetElemRestriction(CeedOperatorField op_field, 77743bbe138SJeremy L Thompson CeedElemRestriction *rstr) { 77843bbe138SJeremy L Thompson *rstr = op_field->elem_restr; 77943bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 78043bbe138SJeremy L Thompson } 78143bbe138SJeremy L Thompson 78243bbe138SJeremy L Thompson /** 78343bbe138SJeremy L Thompson @brief Get the CeedBasis of a CeedOperatorField 78443bbe138SJeremy L Thompson 78543bbe138SJeremy L Thompson @param op_field CeedOperatorField 78643bbe138SJeremy L Thompson @param[out] basis Variable to store CeedBasis 78743bbe138SJeremy L Thompson 78843bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 78943bbe138SJeremy L Thompson 790e9b533fbSJeremy L Thompson @ref Advanced 79143bbe138SJeremy L Thompson **/ 79243bbe138SJeremy L Thompson int CeedOperatorFieldGetBasis(CeedOperatorField op_field, CeedBasis *basis) { 79343bbe138SJeremy L Thompson *basis = op_field->basis; 79443bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 79543bbe138SJeremy L Thompson } 79643bbe138SJeremy L Thompson 79743bbe138SJeremy L Thompson /** 79843bbe138SJeremy L Thompson @brief Get the CeedVector of a CeedOperatorField 79943bbe138SJeremy L Thompson 80043bbe138SJeremy L Thompson @param op_field CeedOperatorField 80143bbe138SJeremy L Thompson @param[out] vec Variable to store CeedVector 80243bbe138SJeremy L Thompson 80343bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 80443bbe138SJeremy L Thompson 805e9b533fbSJeremy L Thompson @ref Advanced 80643bbe138SJeremy L Thompson **/ 80743bbe138SJeremy L Thompson int CeedOperatorFieldGetVector(CeedOperatorField op_field, CeedVector *vec) { 80843bbe138SJeremy L Thompson *vec = op_field->vec; 80943bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 81043bbe138SJeremy L Thompson } 81143bbe138SJeremy L Thompson 81243bbe138SJeremy L Thompson /** 81352d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 814288c0443SJeremy L Thompson 815d1d35e2fSjeremylt @param[out] composite_op Composite CeedOperator 816d1d35e2fSjeremylt @param sub_op Sub-operator CeedOperator 81752d6035fSJeremy L Thompson 81852d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 81952d6035fSJeremy L Thompson 8207a982d89SJeremy L. Thompson @ref User 82152d6035fSJeremy L Thompson */ 822d1d35e2fSjeremylt int CeedCompositeOperatorAddSub(CeedOperator composite_op, 823d1d35e2fSjeremylt CeedOperator sub_op) { 82434359f16Sjeremylt int ierr; 82534359f16Sjeremylt 826f04ea552SJeremy L Thompson if (!composite_op->is_composite) 827c042f62fSJeremy L Thompson // LCOV_EXCL_START 828d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_MINOR, 829e2f04181SAndrew T. Barker "CeedOperator is not a composite operator"); 830c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 83152d6035fSJeremy L Thompson 832d1d35e2fSjeremylt if (composite_op->num_suboperators == CEED_COMPOSITE_MAX) 833c042f62fSJeremy L Thompson // LCOV_EXCL_START 834d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_UNSUPPORTED, 835d1d35e2fSjeremylt "Cannot add additional sub_operators"); 836c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 837f04ea552SJeremy L Thompson if (composite_op->is_immutable) 838f04ea552SJeremy L Thompson // LCOV_EXCL_START 839f04ea552SJeremy L Thompson return CeedError(composite_op->ceed, CEED_ERROR_MAJOR, 840f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 841f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 84252d6035fSJeremy L Thompson 843d1d35e2fSjeremylt composite_op->sub_operators[composite_op->num_suboperators] = sub_op; 8449560d06aSjeremylt ierr = CeedOperatorReference(sub_op); CeedChk(ierr); 845d1d35e2fSjeremylt composite_op->num_suboperators++; 846e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 84752d6035fSJeremy L Thompson } 84852d6035fSJeremy L Thompson 84952d6035fSJeremy L Thompson /** 8504db537f9SJeremy L Thompson @brief Check if a CeedOperator is ready to be used. 8514db537f9SJeremy L Thompson 8524db537f9SJeremy L Thompson @param[in] op CeedOperator to check 8534db537f9SJeremy L Thompson 8544db537f9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 8554db537f9SJeremy L Thompson 8564db537f9SJeremy L Thompson @ref User 8574db537f9SJeremy L Thompson **/ 8584db537f9SJeremy L Thompson int CeedOperatorCheckReady(CeedOperator op) { 8594db537f9SJeremy L Thompson int ierr; 8604db537f9SJeremy L Thompson Ceed ceed; 8614db537f9SJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 8624db537f9SJeremy L Thompson 8634db537f9SJeremy L Thompson if (op->is_interface_setup) 8644db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 8654db537f9SJeremy L Thompson 8664db537f9SJeremy L Thompson CeedQFunction qf = op->qf; 8674db537f9SJeremy L Thompson if (op->is_composite) { 8684db537f9SJeremy L Thompson if (!op->num_suboperators) 8694db537f9SJeremy L Thompson // LCOV_EXCL_START 8704db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "No sub_operators set"); 8714db537f9SJeremy L Thompson // LCOV_EXCL_STOP 8724db537f9SJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 8734db537f9SJeremy L Thompson ierr = CeedOperatorCheckReady(op->sub_operators[i]); CeedChk(ierr); 8744db537f9SJeremy L Thompson } 8754db537f9SJeremy L Thompson } else { 8764db537f9SJeremy L Thompson if (op->num_fields == 0) 8774db537f9SJeremy L Thompson // LCOV_EXCL_START 8784db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "No operator fields set"); 8794db537f9SJeremy L Thompson // LCOV_EXCL_STOP 8804db537f9SJeremy L Thompson if (op->num_fields < qf->num_input_fields + qf->num_output_fields) 8814db537f9SJeremy L Thompson // LCOV_EXCL_START 8824db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "Not all operator fields set"); 8834db537f9SJeremy L Thompson // LCOV_EXCL_STOP 8844db537f9SJeremy L Thompson if (!op->has_restriction) 8854db537f9SJeremy L Thompson // LCOV_EXCL_START 8864db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, 8874db537f9SJeremy L Thompson "At least one restriction required"); 8884db537f9SJeremy L Thompson // LCOV_EXCL_STOP 8894db537f9SJeremy L Thompson if (op->num_qpts == 0) 8904db537f9SJeremy L Thompson // LCOV_EXCL_START 8914db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, 8924db537f9SJeremy L Thompson "At least one non-collocated basis is required " 8934db537f9SJeremy L Thompson "or the number of quadrature points must be set"); 8944db537f9SJeremy L Thompson // LCOV_EXCL_STOP 8954db537f9SJeremy L Thompson } 8964db537f9SJeremy L Thompson 8974db537f9SJeremy L Thompson // Flag as immutable and ready 8984db537f9SJeremy L Thompson op->is_interface_setup = true; 8994db537f9SJeremy L Thompson if (op->qf && op->qf != CEED_QFUNCTION_NONE) 9004db537f9SJeremy L Thompson // LCOV_EXCL_START 9014db537f9SJeremy L Thompson op->qf->is_immutable = true; 9024db537f9SJeremy L Thompson // LCOV_EXCL_STOP 9034db537f9SJeremy L Thompson if (op->dqf && op->dqf != CEED_QFUNCTION_NONE) 9044db537f9SJeremy L Thompson // LCOV_EXCL_START 9054db537f9SJeremy L Thompson op->dqf->is_immutable = true; 9064db537f9SJeremy L Thompson // LCOV_EXCL_STOP 9074db537f9SJeremy L Thompson if (op->dqfT && op->dqfT != CEED_QFUNCTION_NONE) 9084db537f9SJeremy L Thompson // LCOV_EXCL_START 9094db537f9SJeremy L Thompson op->dqfT->is_immutable = true; 9104db537f9SJeremy L Thompson // LCOV_EXCL_STOP 9114db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 9124db537f9SJeremy L Thompson } 9134db537f9SJeremy L Thompson 9144db537f9SJeremy L Thompson /** 915cd4dfc48Sjeremylt @brief Set the number of quadrature points associated with a CeedOperator. 916cd4dfc48Sjeremylt This should be used when creating a CeedOperator where every 917cd4dfc48Sjeremylt field has a collocated basis. This function cannot be used for 918cd4dfc48Sjeremylt composite CeedOperators. 919cd4dfc48Sjeremylt 920cd4dfc48Sjeremylt @param op CeedOperator 921cd4dfc48Sjeremylt @param num_qpts Number of quadrature points to set 922cd4dfc48Sjeremylt 923cd4dfc48Sjeremylt @return An error code: 0 - success, otherwise - failure 924cd4dfc48Sjeremylt 925e9b533fbSJeremy L Thompson @ref Advanced 926cd4dfc48Sjeremylt **/ 927cd4dfc48Sjeremylt int CeedOperatorSetNumQuadraturePoints(CeedOperator op, CeedInt num_qpts) { 928f04ea552SJeremy L Thompson if (op->is_composite) 929cd4dfc48Sjeremylt // LCOV_EXCL_START 930cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 931cd4dfc48Sjeremylt "Not defined for composite operator"); 932cd4dfc48Sjeremylt // LCOV_EXCL_STOP 933cd4dfc48Sjeremylt if (op->num_qpts) 934cd4dfc48Sjeremylt // LCOV_EXCL_START 935cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 936cd4dfc48Sjeremylt "Number of quadrature points already defined"); 937cd4dfc48Sjeremylt // LCOV_EXCL_STOP 938f04ea552SJeremy L Thompson if (op->is_immutable) 939f04ea552SJeremy L Thompson // LCOV_EXCL_START 940f04ea552SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 941f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 942f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 943cd4dfc48Sjeremylt 944cd4dfc48Sjeremylt op->num_qpts = num_qpts; 945cd4dfc48Sjeremylt return CEED_ERROR_SUCCESS; 946cd4dfc48Sjeremylt } 947cd4dfc48Sjeremylt 948cd4dfc48Sjeremylt /** 9497a982d89SJeremy L. Thompson @brief View a CeedOperator 9507a982d89SJeremy L. Thompson 9517a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 9527a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 9537a982d89SJeremy L. Thompson 9547a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 9557a982d89SJeremy L. Thompson 9567a982d89SJeremy L. Thompson @ref User 9577a982d89SJeremy L. Thompson **/ 9587a982d89SJeremy L. Thompson int CeedOperatorView(CeedOperator op, FILE *stream) { 9597a982d89SJeremy L. Thompson int ierr; 9607a982d89SJeremy L. Thompson 961f04ea552SJeremy L Thompson if (op->is_composite) { 9627a982d89SJeremy L. Thompson fprintf(stream, "Composite CeedOperator\n"); 9637a982d89SJeremy L. Thompson 964d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 9657a982d89SJeremy L. Thompson fprintf(stream, " SubOperator [%d]:\n", i); 966d1d35e2fSjeremylt ierr = CeedOperatorSingleView(op->sub_operators[i], 1, stream); 9677a982d89SJeremy L. Thompson CeedChk(ierr); 9687a982d89SJeremy L. Thompson } 9697a982d89SJeremy L. Thompson } else { 9707a982d89SJeremy L. Thompson fprintf(stream, "CeedOperator\n"); 9717a982d89SJeremy L. Thompson ierr = CeedOperatorSingleView(op, 0, stream); CeedChk(ierr); 9727a982d89SJeremy L. Thompson } 973e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9747a982d89SJeremy L. Thompson } 9753bd813ffSjeremylt 9763bd813ffSjeremylt /** 977b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedOperator 978b7c9bbdaSJeremy L Thompson 979b7c9bbdaSJeremy L Thompson @param op CeedOperator 980b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 981b7c9bbdaSJeremy L Thompson 982b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 983b7c9bbdaSJeremy L Thompson 984b7c9bbdaSJeremy L Thompson @ref Advanced 985b7c9bbdaSJeremy L Thompson **/ 986b7c9bbdaSJeremy L Thompson int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 987b7c9bbdaSJeremy L Thompson *ceed = op->ceed; 988b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 989b7c9bbdaSJeremy L Thompson } 990b7c9bbdaSJeremy L Thompson 991b7c9bbdaSJeremy L Thompson /** 992b7c9bbdaSJeremy L Thompson @brief Get the number of elements associated with a CeedOperator 993b7c9bbdaSJeremy L Thompson 994b7c9bbdaSJeremy L Thompson @param op CeedOperator 995b7c9bbdaSJeremy L Thompson @param[out] num_elem Variable to store number of elements 996b7c9bbdaSJeremy L Thompson 997b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 998b7c9bbdaSJeremy L Thompson 999b7c9bbdaSJeremy L Thompson @ref Advanced 1000b7c9bbdaSJeremy L Thompson **/ 1001b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumElements(CeedOperator op, CeedInt *num_elem) { 1002b7c9bbdaSJeremy L Thompson if (op->is_composite) 1003b7c9bbdaSJeremy L Thompson // LCOV_EXCL_START 1004b7c9bbdaSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 1005b7c9bbdaSJeremy L Thompson "Not defined for composite operator"); 1006b7c9bbdaSJeremy L Thompson // LCOV_EXCL_STOP 1007b7c9bbdaSJeremy L Thompson 1008b7c9bbdaSJeremy L Thompson *num_elem = op->num_elem; 1009b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1010b7c9bbdaSJeremy L Thompson } 1011b7c9bbdaSJeremy L Thompson 1012b7c9bbdaSJeremy L Thompson /** 1013b7c9bbdaSJeremy L Thompson @brief Get the number of quadrature points associated with a CeedOperator 1014b7c9bbdaSJeremy L Thompson 1015b7c9bbdaSJeremy L Thompson @param op CeedOperator 1016b7c9bbdaSJeremy L Thompson @param[out] num_qpts Variable to store vector number of quadrature points 1017b7c9bbdaSJeremy L Thompson 1018b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1019b7c9bbdaSJeremy L Thompson 1020b7c9bbdaSJeremy L Thompson @ref Advanced 1021b7c9bbdaSJeremy L Thompson **/ 1022b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *num_qpts) { 1023b7c9bbdaSJeremy L Thompson if (op->is_composite) 1024b7c9bbdaSJeremy L Thompson // LCOV_EXCL_START 1025b7c9bbdaSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 1026b7c9bbdaSJeremy L Thompson "Not defined for composite operator"); 1027b7c9bbdaSJeremy L Thompson // LCOV_EXCL_STOP 1028b7c9bbdaSJeremy L Thompson 1029b7c9bbdaSJeremy L Thompson *num_qpts = op->num_qpts; 1030b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1031b7c9bbdaSJeremy L Thompson } 1032b7c9bbdaSJeremy L Thompson 1033b7c9bbdaSJeremy L Thompson /** 10343bd813ffSjeremylt @brief Apply CeedOperator to a vector 1035d7b241e6Sjeremylt 1036d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 1037d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 1038d7b241e6Sjeremylt CeedOperatorSetField(). 1039d7b241e6Sjeremylt 1040f04ea552SJeremy L Thompson Note: Calling this function asserts that setup is complete 1041f04ea552SJeremy L Thompson and sets the CeedOperator as immutable. 1042f04ea552SJeremy L Thompson 1043d7b241e6Sjeremylt @param op CeedOperator to apply 10444cc79fe7SJed Brown @param[in] in CeedVector containing input state or @ref CEED_VECTOR_NONE if 104534138859Sjeremylt there are no active inputs 1046b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 10474cc79fe7SJed Brown distinct from @a in) or @ref CEED_VECTOR_NONE if there are no 104834138859Sjeremylt active outputs 1049d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 10504cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1051b11c1e72Sjeremylt 1052b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1053dfdf5a53Sjeremylt 10547a982d89SJeremy L. Thompson @ref User 1055b11c1e72Sjeremylt **/ 1056692c2638Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, 1057692c2638Sjeremylt CeedRequest *request) { 1058d7b241e6Sjeremylt int ierr; 1059e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1060d7b241e6Sjeremylt 1061d1d35e2fSjeremylt if (op->num_elem) { 1062250756a7Sjeremylt // Standard Operator 1063cae8b89aSjeremylt if (op->Apply) { 1064250756a7Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 1065cae8b89aSjeremylt } else { 1066cae8b89aSjeremylt // Zero all output vectors 1067250756a7Sjeremylt CeedQFunction qf = op->qf; 1068d1d35e2fSjeremylt for (CeedInt i=0; i<qf->num_output_fields; i++) { 1069d1d35e2fSjeremylt CeedVector vec = op->output_fields[i]->vec; 1070cae8b89aSjeremylt if (vec == CEED_VECTOR_ACTIVE) 1071cae8b89aSjeremylt vec = out; 1072cae8b89aSjeremylt if (vec != CEED_VECTOR_NONE) { 1073cae8b89aSjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1074cae8b89aSjeremylt } 1075cae8b89aSjeremylt } 1076250756a7Sjeremylt // Apply 1077250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1078250756a7Sjeremylt } 1079f04ea552SJeremy L Thompson } else if (op->is_composite) { 1080250756a7Sjeremylt // Composite Operator 1081250756a7Sjeremylt if (op->ApplyComposite) { 1082250756a7Sjeremylt ierr = op->ApplyComposite(op, in, out, request); CeedChk(ierr); 1083250756a7Sjeremylt } else { 1084d1d35e2fSjeremylt CeedInt num_suboperators; 1085d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1086d1d35e2fSjeremylt CeedOperator *sub_operators; 1087d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1088250756a7Sjeremylt 1089250756a7Sjeremylt // Zero all output vectors 1090250756a7Sjeremylt if (out != CEED_VECTOR_NONE) { 1091cae8b89aSjeremylt ierr = CeedVectorSetValue(out, 0.0); CeedChk(ierr); 1092cae8b89aSjeremylt } 1093d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1094d1d35e2fSjeremylt for (CeedInt j=0; j<sub_operators[i]->qf->num_output_fields; j++) { 1095d1d35e2fSjeremylt CeedVector vec = sub_operators[i]->output_fields[j]->vec; 1096250756a7Sjeremylt if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) { 1097250756a7Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1098250756a7Sjeremylt } 1099250756a7Sjeremylt } 1100250756a7Sjeremylt } 1101250756a7Sjeremylt // Apply 1102d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 1103d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(op->sub_operators[i], in, out, request); 1104cae8b89aSjeremylt CeedChk(ierr); 1105cae8b89aSjeremylt } 1106cae8b89aSjeremylt } 1107250756a7Sjeremylt } 1108e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1109cae8b89aSjeremylt } 1110cae8b89aSjeremylt 1111cae8b89aSjeremylt /** 1112cae8b89aSjeremylt @brief Apply CeedOperator to a vector and add result to output vector 1113cae8b89aSjeremylt 1114cae8b89aSjeremylt This computes the action of the operator on the specified (active) input, 1115cae8b89aSjeremylt yielding its (active) output. All inputs and outputs must be specified using 1116cae8b89aSjeremylt CeedOperatorSetField(). 1117cae8b89aSjeremylt 1118cae8b89aSjeremylt @param op CeedOperator to apply 1119cae8b89aSjeremylt @param[in] in CeedVector containing input state or NULL if there are no 1120cae8b89aSjeremylt active inputs 1121cae8b89aSjeremylt @param[out] out CeedVector to sum in result of applying operator (must be 1122cae8b89aSjeremylt distinct from @a in) or NULL if there are no active outputs 1123cae8b89aSjeremylt @param request Address of CeedRequest for non-blocking completion, else 11244cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1125cae8b89aSjeremylt 1126cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 1127cae8b89aSjeremylt 11287a982d89SJeremy L. Thompson @ref User 1129cae8b89aSjeremylt **/ 1130cae8b89aSjeremylt int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, 1131cae8b89aSjeremylt CeedRequest *request) { 1132cae8b89aSjeremylt int ierr; 1133e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1134cae8b89aSjeremylt 1135d1d35e2fSjeremylt if (op->num_elem) { 1136250756a7Sjeremylt // Standard Operator 1137250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1138f04ea552SJeremy L Thompson } else if (op->is_composite) { 1139250756a7Sjeremylt // Composite Operator 1140250756a7Sjeremylt if (op->ApplyAddComposite) { 1141250756a7Sjeremylt ierr = op->ApplyAddComposite(op, in, out, request); CeedChk(ierr); 1142cae8b89aSjeremylt } else { 1143d1d35e2fSjeremylt CeedInt num_suboperators; 1144d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1145d1d35e2fSjeremylt CeedOperator *sub_operators; 1146d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1147250756a7Sjeremylt 1148d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1149d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(sub_operators[i], in, out, request); 1150cae8b89aSjeremylt CeedChk(ierr); 11511d7d2407SJeremy L Thompson } 1152250756a7Sjeremylt } 1153250756a7Sjeremylt } 1154e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1155d7b241e6Sjeremylt } 1156d7b241e6Sjeremylt 1157d7b241e6Sjeremylt /** 1158b11c1e72Sjeremylt @brief Destroy a CeedOperator 1159d7b241e6Sjeremylt 1160d7b241e6Sjeremylt @param op CeedOperator to destroy 1161b11c1e72Sjeremylt 1162b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1163dfdf5a53Sjeremylt 11647a982d89SJeremy L. Thompson @ref User 1165b11c1e72Sjeremylt **/ 1166d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 1167d7b241e6Sjeremylt int ierr; 1168d7b241e6Sjeremylt 1169d1d35e2fSjeremylt if (!*op || --(*op)->ref_count > 0) return CEED_ERROR_SUCCESS; 1170d7b241e6Sjeremylt if ((*op)->Destroy) { 1171d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 1172d7b241e6Sjeremylt } 1173fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 1174fe2413ffSjeremylt // Free fields 1175d1d35e2fSjeremylt for (int i=0; i<(*op)->num_fields; i++) 1176d1d35e2fSjeremylt if ((*op)->input_fields[i]) { 1177d1d35e2fSjeremylt if ((*op)->input_fields[i]->elem_restr != CEED_ELEMRESTRICTION_NONE) { 1178d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->input_fields[i]->elem_restr); 117971352a93Sjeremylt CeedChk(ierr); 118015910d16Sjeremylt } 1181d1d35e2fSjeremylt if ((*op)->input_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1182d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->input_fields[i]->basis); CeedChk(ierr); 118371352a93Sjeremylt } 1184d1d35e2fSjeremylt if ((*op)->input_fields[i]->vec != CEED_VECTOR_ACTIVE && 1185d1d35e2fSjeremylt (*op)->input_fields[i]->vec != CEED_VECTOR_NONE ) { 1186d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->input_fields[i]->vec); CeedChk(ierr); 118771352a93Sjeremylt } 1188d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]->field_name); CeedChk(ierr); 1189d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]); CeedChk(ierr); 1190fe2413ffSjeremylt } 1191d1d35e2fSjeremylt for (int i=0; i<(*op)->num_fields; i++) 1192d1d35e2fSjeremylt if ((*op)->output_fields[i]) { 1193d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->output_fields[i]->elem_restr); 119471352a93Sjeremylt CeedChk(ierr); 1195d1d35e2fSjeremylt if ((*op)->output_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1196d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->output_fields[i]->basis); CeedChk(ierr); 119771352a93Sjeremylt } 1198d1d35e2fSjeremylt if ((*op)->output_fields[i]->vec != CEED_VECTOR_ACTIVE && 1199d1d35e2fSjeremylt (*op)->output_fields[i]->vec != CEED_VECTOR_NONE ) { 1200d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->output_fields[i]->vec); CeedChk(ierr); 120171352a93Sjeremylt } 1202d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]->field_name); CeedChk(ierr); 1203d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]); CeedChk(ierr); 1204fe2413ffSjeremylt } 1205d1d35e2fSjeremylt // Destroy sub_operators 1206d1d35e2fSjeremylt for (int i=0; i<(*op)->num_suboperators; i++) 1207d1d35e2fSjeremylt if ((*op)->sub_operators[i]) { 1208d1d35e2fSjeremylt ierr = CeedOperatorDestroy(&(*op)->sub_operators[i]); CeedChk(ierr); 120952d6035fSJeremy L Thompson } 1210d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 1211d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 1212d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 1213fe2413ffSjeremylt 12145107b09fSJeremy L Thompson // Destroy fallback 1215d1d35e2fSjeremylt if ((*op)->op_fallback) { 1216d1d35e2fSjeremylt ierr = (*op)->qf_fallback->Destroy((*op)->qf_fallback); CeedChk(ierr); 1217d1d35e2fSjeremylt ierr = CeedFree(&(*op)->qf_fallback); CeedChk(ierr); 121870a7ffb3SJeremy L Thompson ierr = CeedVectorDestroy(&(*op)->op_fallback->qf_assembled); CeedChk(ierr); 121970a7ffb3SJeremy L Thompson ierr = CeedElemRestrictionDestroy(&(*op)->op_fallback->qf_assembled_rstr); 122070a7ffb3SJeremy L Thompson CeedChk(ierr); 1221d1d35e2fSjeremylt ierr = (*op)->op_fallback->Destroy((*op)->op_fallback); CeedChk(ierr); 1222d1d35e2fSjeremylt ierr = CeedFree(&(*op)->op_fallback); CeedChk(ierr); 12235107b09fSJeremy L Thompson } 12245107b09fSJeremy L Thompson 122570a7ffb3SJeremy L Thompson // Destroy QF assembly cache 122670a7ffb3SJeremy L Thompson ierr = CeedVectorDestroy(&(*op)->qf_assembled); CeedChk(ierr); 122770a7ffb3SJeremy L Thompson ierr = CeedElemRestrictionDestroy(&(*op)->qf_assembled_rstr); CeedChk(ierr); 122870a7ffb3SJeremy L Thompson 1229d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields); CeedChk(ierr); 1230d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields); CeedChk(ierr); 1231d1d35e2fSjeremylt ierr = CeedFree(&(*op)->sub_operators); CeedChk(ierr); 1232d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 1233e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1234d7b241e6Sjeremylt } 1235d7b241e6Sjeremylt 1236d7b241e6Sjeremylt /// @} 1237