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> 203bd813ffSjeremylt #include <math.h> 213d576824SJeremy L Thompson #include <stdbool.h> 223d576824SJeremy L Thompson #include <stdio.h> 233d576824SJeremy L Thompson #include <string.h> 24d7b241e6Sjeremylt 25dfdf5a53Sjeremylt /// @file 267a982d89SJeremy L. Thompson /// Implementation of CeedOperator interfaces 277a982d89SJeremy L. Thompson 287a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 297a982d89SJeremy L. Thompson /// CeedOperator Library Internal Functions 307a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 317a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorDeveloper 327a982d89SJeremy L. Thompson /// @{ 337a982d89SJeremy L. Thompson 347a982d89SJeremy L. Thompson /** 35e15f9bd0SJeremy L Thompson @brief Check if a CeedOperator Field matches the QFunction Field 36e15f9bd0SJeremy L Thompson 37e15f9bd0SJeremy L Thompson @param[in] ceed Ceed object for error handling 38d1d35e2fSjeremylt @param[in] qf_field QFunction Field matching Operator Field 39e15f9bd0SJeremy L Thompson @param[in] r Operator Field ElemRestriction 40e15f9bd0SJeremy L Thompson @param[in] b Operator Field Basis 41e15f9bd0SJeremy L Thompson 42e15f9bd0SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 43e15f9bd0SJeremy L Thompson 44e15f9bd0SJeremy L Thompson @ref Developer 45e15f9bd0SJeremy L Thompson **/ 46d1d35e2fSjeremylt static int CeedOperatorCheckField(Ceed ceed, CeedQFunctionField qf_field, 47e15f9bd0SJeremy L Thompson CeedElemRestriction r, CeedBasis b) { 48e15f9bd0SJeremy L Thompson int ierr; 49d1d35e2fSjeremylt CeedEvalMode eval_mode = qf_field->eval_mode; 50d1d35e2fSjeremylt CeedInt dim = 1, num_comp = 1, restr_num_comp = 1, size = qf_field->size; 51e15f9bd0SJeremy L Thompson // Restriction 52e15f9bd0SJeremy L Thompson if (r != CEED_ELEMRESTRICTION_NONE) { 53d1d35e2fSjeremylt if (eval_mode == CEED_EVAL_WEIGHT) { 54e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 55e1e9e29dSJed Brown return CeedError(ceed, CEED_ERROR_INCOMPATIBLE, 56e1e9e29dSJed Brown "CEED_ELEMRESTRICTION_NONE should be used " 57e15f9bd0SJeremy L Thompson "for a field with eval mode CEED_EVAL_WEIGHT"); 58e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 59e15f9bd0SJeremy L Thompson } 60d1d35e2fSjeremylt ierr = CeedElemRestrictionGetNumComponents(r, &restr_num_comp); 6178464608Sjeremylt CeedChk(ierr); 62e1e9e29dSJed Brown } 63d1d35e2fSjeremylt if ((r == CEED_ELEMRESTRICTION_NONE) != (eval_mode == CEED_EVAL_WEIGHT)) { 64e1e9e29dSJed Brown // LCOV_EXCL_START 65e1e9e29dSJed Brown return CeedError(ceed, CEED_ERROR_INCOMPATIBLE, 66e1e9e29dSJed Brown "CEED_ELEMRESTRICTION_NONE and CEED_EVAL_WEIGHT " 67e1e9e29dSJed Brown "must be used together."); 68e1e9e29dSJed Brown // LCOV_EXCL_STOP 69e1e9e29dSJed Brown } 70e15f9bd0SJeremy L Thompson // Basis 71e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 72d1d35e2fSjeremylt if (eval_mode == CEED_EVAL_NONE) 738229195eSjeremylt // LCOV_EXCL_START 74e1e9e29dSJed Brown return CeedError(ceed, CEED_ERROR_INCOMPATIBLE, 75d1d35e2fSjeremylt "Field '%s' configured with CEED_EVAL_NONE must " 76d1d35e2fSjeremylt "be used with CEED_BASIS_COLLOCATED", 778229195eSjeremylt // LCOV_EXCL_STOP 78d1d35e2fSjeremylt qf_field->field_name); 79e15f9bd0SJeremy L Thompson ierr = CeedBasisGetDimension(b, &dim); CeedChk(ierr); 80d1d35e2fSjeremylt ierr = CeedBasisGetNumComponents(b, &num_comp); CeedChk(ierr); 81d1d35e2fSjeremylt if (r != CEED_ELEMRESTRICTION_NONE && restr_num_comp != num_comp) { 82e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 83e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 84d1d35e2fSjeremylt "Field '%s' of size %d and EvalMode %s: ElemRestriction " 85d1d35e2fSjeremylt "has %d components, but Basis has %d components", 86d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], 87d1d35e2fSjeremylt restr_num_comp, 88d1d35e2fSjeremylt num_comp); 89e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 90e15f9bd0SJeremy L Thompson } 91e15f9bd0SJeremy L Thompson } 92e15f9bd0SJeremy L Thompson // Field size 93d1d35e2fSjeremylt switch(eval_mode) { 94e15f9bd0SJeremy L Thompson case CEED_EVAL_NONE: 95d1d35e2fSjeremylt if (size != restr_num_comp) 96e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 97e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 98e1e9e29dSJed Brown "Field '%s' of size %d and EvalMode %s: ElemRestriction has %d components", 99d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], 100d1d35e2fSjeremylt restr_num_comp); 101e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 102e15f9bd0SJeremy L Thompson break; 103e15f9bd0SJeremy L Thompson case CEED_EVAL_INTERP: 104d1d35e2fSjeremylt if (size != num_comp) 105e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 106e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 107e1e9e29dSJed Brown "Field '%s' of size %d and EvalMode %s: ElemRestriction/Basis has %d components", 108d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], 109d1d35e2fSjeremylt num_comp); 110e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 111e15f9bd0SJeremy L Thompson break; 112e15f9bd0SJeremy L Thompson case CEED_EVAL_GRAD: 113d1d35e2fSjeremylt if (size != num_comp * dim) 114e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 115e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 116d1d35e2fSjeremylt "Field '%s' of size %d and EvalMode %s in %d dimensions: " 117d1d35e2fSjeremylt "ElemRestriction/Basis has %d components", 118d1d35e2fSjeremylt qf_field->field_name, qf_field->size, CeedEvalModes[qf_field->eval_mode], dim, 119d1d35e2fSjeremylt num_comp); 120e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 121e15f9bd0SJeremy L Thompson break; 122e15f9bd0SJeremy L Thompson case CEED_EVAL_WEIGHT: 123d1d35e2fSjeremylt // No additional checks required 124e15f9bd0SJeremy L Thompson break; 125e15f9bd0SJeremy L Thompson case CEED_EVAL_DIV: 126e15f9bd0SJeremy L Thompson // Not implemented 127e15f9bd0SJeremy L Thompson break; 128e15f9bd0SJeremy L Thompson case CEED_EVAL_CURL: 129e15f9bd0SJeremy L Thompson // Not implemented 130e15f9bd0SJeremy L Thompson break; 131e15f9bd0SJeremy L Thompson } 132e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1337a982d89SJeremy L. Thompson } 1347a982d89SJeremy L. Thompson 1357a982d89SJeremy L. Thompson /** 1367a982d89SJeremy L. Thompson @brief View a field of a CeedOperator 1377a982d89SJeremy L. Thompson 1387a982d89SJeremy L. Thompson @param[in] field Operator field to view 139d1d35e2fSjeremylt @param[in] qf_field QFunction field (carries field name) 140d1d35e2fSjeremylt @param[in] field_number Number of field being viewed 1414c4400c7SValeria Barra @param[in] sub true indicates sub-operator, which increases indentation; false for top-level operator 142d1d35e2fSjeremylt @param[in] input true for an input field; false for output field 1437a982d89SJeremy L. Thompson @param[in] stream Stream to view to, e.g., stdout 1447a982d89SJeremy L. Thompson 1457a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1467a982d89SJeremy L. Thompson 1477a982d89SJeremy L. Thompson @ref Utility 1487a982d89SJeremy L. Thompson **/ 1497a982d89SJeremy L. Thompson static int CeedOperatorFieldView(CeedOperatorField field, 150d1d35e2fSjeremylt CeedQFunctionField qf_field, 151d1d35e2fSjeremylt CeedInt field_number, bool sub, bool input, 1527a982d89SJeremy L. Thompson FILE *stream) { 1537a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 154d1d35e2fSjeremylt const char *in_out = input ? "Input" : "Output"; 1557a982d89SJeremy L. Thompson 1567a982d89SJeremy L. Thompson fprintf(stream, "%s %s Field [%d]:\n" 1577a982d89SJeremy L. Thompson "%s Name: \"%s\"\n", 158d1d35e2fSjeremylt pre, in_out, field_number, pre, qf_field->field_name); 1597a982d89SJeremy L. Thompson 1607a982d89SJeremy L. Thompson if (field->basis == CEED_BASIS_COLLOCATED) 1617a982d89SJeremy L. Thompson fprintf(stream, "%s Collocated basis\n", pre); 1627a982d89SJeremy L. Thompson 1637a982d89SJeremy L. Thompson if (field->vec == CEED_VECTOR_ACTIVE) 1647a982d89SJeremy L. Thompson fprintf(stream, "%s Active vector\n", pre); 1657a982d89SJeremy L. Thompson else if (field->vec == CEED_VECTOR_NONE) 1667a982d89SJeremy L. Thompson fprintf(stream, "%s No vector\n", pre); 167e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1687a982d89SJeremy L. Thompson } 1697a982d89SJeremy L. Thompson 1707a982d89SJeremy L. Thompson /** 1717a982d89SJeremy L. Thompson @brief View a single CeedOperator 1727a982d89SJeremy L. Thompson 1737a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 1747a982d89SJeremy L. Thompson @param[in] sub Boolean flag for sub-operator 1757a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 1767a982d89SJeremy L. Thompson 1777a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 1787a982d89SJeremy L. Thompson 1797a982d89SJeremy L. Thompson @ref Utility 1807a982d89SJeremy L. Thompson **/ 1817a982d89SJeremy L. Thompson int CeedOperatorSingleView(CeedOperator op, bool sub, FILE *stream) { 1827a982d89SJeremy L. Thompson int ierr; 1837a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 1847a982d89SJeremy L. Thompson 18578464608Sjeremylt CeedInt total_fields = 0; 18678464608Sjeremylt ierr = CeedOperatorGetNumArgs(op, &total_fields); CeedChk(ierr); 1877a982d89SJeremy L. Thompson 18878464608Sjeremylt fprintf(stream, "%s %d Field%s\n", pre, total_fields, 18978464608Sjeremylt total_fields>1 ? "s" : ""); 1907a982d89SJeremy L. Thompson 191d1d35e2fSjeremylt fprintf(stream, "%s %d Input Field%s:\n", pre, op->qf->num_input_fields, 192d1d35e2fSjeremylt op->qf->num_input_fields>1 ? "s" : ""); 193d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_input_fields; i++) { 194d1d35e2fSjeremylt ierr = CeedOperatorFieldView(op->input_fields[i], op->qf->input_fields[i], 1957a982d89SJeremy L. Thompson i, sub, 1, stream); CeedChk(ierr); 1967a982d89SJeremy L. Thompson } 1977a982d89SJeremy L. Thompson 198d1d35e2fSjeremylt fprintf(stream, "%s %d Output Field%s:\n", pre, op->qf->num_output_fields, 199d1d35e2fSjeremylt op->qf->num_output_fields>1 ? "s" : ""); 200d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_output_fields; i++) { 201d1d35e2fSjeremylt ierr = CeedOperatorFieldView(op->output_fields[i], op->qf->output_fields[i], 2027a982d89SJeremy L. Thompson i, sub, 0, stream); CeedChk(ierr); 2037a982d89SJeremy L. Thompson } 204e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2057a982d89SJeremy L. Thompson } 2067a982d89SJeremy L. Thompson 207d99fa3c5SJeremy L Thompson /** 208eaf62fffSJeremy L Thompson @brief Find the active vector basis for a CeedOperator 209eaf62fffSJeremy L Thompson 210eaf62fffSJeremy L Thompson @param[in] op CeedOperator to find active basis for 211eaf62fffSJeremy L Thompson @param[out] active_basis Basis for active input vector 212eaf62fffSJeremy L Thompson 213eaf62fffSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 214eaf62fffSJeremy L Thompson 215eaf62fffSJeremy L Thompson @ ref Developer 216eaf62fffSJeremy L Thompson **/ 217eaf62fffSJeremy L Thompson int CeedOperatorGetActiveBasis(CeedOperator op, CeedBasis *active_basis) { 218eaf62fffSJeremy L Thompson *active_basis = NULL; 219eaf62fffSJeremy L Thompson for (int i = 0; i < op->qf->num_input_fields; i++) 220eaf62fffSJeremy L Thompson if (op->input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 221eaf62fffSJeremy L Thompson *active_basis = op->input_fields[i]->basis; 222eaf62fffSJeremy L Thompson break; 223eaf62fffSJeremy L Thompson } 224eaf62fffSJeremy L Thompson 225eaf62fffSJeremy L Thompson if (!*active_basis) { 226eaf62fffSJeremy L Thompson // LCOV_EXCL_START 227eaf62fffSJeremy L Thompson int ierr; 228eaf62fffSJeremy L Thompson Ceed ceed; 229eaf62fffSJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 230eaf62fffSJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 231eaf62fffSJeremy L Thompson "No active CeedBasis found"); 232eaf62fffSJeremy L Thompson // LCOV_EXCL_STOP 233eaf62fffSJeremy L Thompson } 234eaf62fffSJeremy L Thompson return CEED_ERROR_SUCCESS; 235eaf62fffSJeremy L Thompson } 236eaf62fffSJeremy L Thompson 237eaf62fffSJeremy L Thompson /** 238e2f04181SAndrew T. Barker @brief Find the active vector ElemRestriction for a CeedOperator 239e2f04181SAndrew T. Barker 240e2f04181SAndrew T. Barker @param[in] op CeedOperator to find active basis for 241d1d35e2fSjeremylt @param[out] active_rstr ElemRestriction for active input vector 242e2f04181SAndrew T. Barker 243e2f04181SAndrew T. Barker @return An error code: 0 - success, otherwise - failure 244e2f04181SAndrew T. Barker 245e2f04181SAndrew T. Barker @ref Utility 246e2f04181SAndrew T. Barker **/ 247eaf62fffSJeremy L Thompson int CeedOperatorGetActiveElemRestriction(CeedOperator op, 248d1d35e2fSjeremylt CeedElemRestriction *active_rstr) { 249d1d35e2fSjeremylt *active_rstr = NULL; 250d1d35e2fSjeremylt for (int i = 0; i < op->qf->num_input_fields; i++) 251d1d35e2fSjeremylt if (op->input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 252d1d35e2fSjeremylt *active_rstr = op->input_fields[i]->elem_restr; 253e2f04181SAndrew T. Barker break; 254e2f04181SAndrew T. Barker } 255e2f04181SAndrew T. Barker 256d1d35e2fSjeremylt if (!*active_rstr) { 257e2f04181SAndrew T. Barker // LCOV_EXCL_START 258e2f04181SAndrew T. Barker int ierr; 259e2f04181SAndrew T. Barker Ceed ceed; 260e2f04181SAndrew T. Barker ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 261e2f04181SAndrew T. Barker return CeedError(ceed, CEED_ERROR_INCOMPLETE, 262eaf62fffSJeremy L Thompson "No active CeedElemRestriction found"); 263e2f04181SAndrew T. Barker // LCOV_EXCL_STOP 264e2f04181SAndrew T. Barker } 265e2f04181SAndrew T. Barker return CEED_ERROR_SUCCESS; 266e2f04181SAndrew T. Barker } 267e2f04181SAndrew T. Barker 2687a982d89SJeremy L. Thompson /// @} 2697a982d89SJeremy L. Thompson 2707a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2717a982d89SJeremy L. Thompson /// CeedOperator Backend API 2727a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2737a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorBackend 2747a982d89SJeremy L. Thompson /// @{ 2757a982d89SJeremy L. Thompson 2767a982d89SJeremy L. Thompson /** 2777a982d89SJeremy L. Thompson @brief Get the number of arguments associated with a CeedOperator 2787a982d89SJeremy L. Thompson 2797a982d89SJeremy L. Thompson @param op CeedOperator 280d1d35e2fSjeremylt @param[out] num_args Variable to store vector number of arguments 2817a982d89SJeremy L. Thompson 2827a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2837a982d89SJeremy L. Thompson 2847a982d89SJeremy L. Thompson @ref Backend 2857a982d89SJeremy L. Thompson **/ 2867a982d89SJeremy L. Thompson 287d1d35e2fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *num_args) { 288f04ea552SJeremy L Thompson if (op->is_composite) 2897a982d89SJeremy L. Thompson // LCOV_EXCL_START 290e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 291e15f9bd0SJeremy L Thompson "Not defined for composite operators"); 2927a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 2937a982d89SJeremy L. Thompson 294d1d35e2fSjeremylt *num_args = op->num_fields; 295e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2967a982d89SJeremy L. Thompson } 2977a982d89SJeremy L. Thompson 2987a982d89SJeremy L. Thompson /** 2997a982d89SJeremy L. Thompson @brief Get the setup status of a CeedOperator 3007a982d89SJeremy L. Thompson 3017a982d89SJeremy L. Thompson @param op CeedOperator 302d1d35e2fSjeremylt @param[out] is_setup_done Variable to store setup status 3037a982d89SJeremy L. Thompson 3047a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3057a982d89SJeremy L. Thompson 3067a982d89SJeremy L. Thompson @ref Backend 3077a982d89SJeremy L. Thompson **/ 3087a982d89SJeremy L. Thompson 309d1d35e2fSjeremylt int CeedOperatorIsSetupDone(CeedOperator op, bool *is_setup_done) { 310f04ea552SJeremy L Thompson *is_setup_done = op->is_backend_setup; 311e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3127a982d89SJeremy L. Thompson } 3137a982d89SJeremy L. Thompson 3147a982d89SJeremy L. Thompson /** 3157a982d89SJeremy L. Thompson @brief Get the QFunction associated with a CeedOperator 3167a982d89SJeremy L. Thompson 3177a982d89SJeremy L. Thompson @param op CeedOperator 3187a982d89SJeremy L. Thompson @param[out] qf Variable to store QFunction 3197a982d89SJeremy L. Thompson 3207a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3217a982d89SJeremy L. Thompson 3227a982d89SJeremy L. Thompson @ref Backend 3237a982d89SJeremy L. Thompson **/ 3247a982d89SJeremy L. Thompson 3257a982d89SJeremy L. Thompson int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 326f04ea552SJeremy L Thompson if (op->is_composite) 3277a982d89SJeremy L. Thompson // LCOV_EXCL_START 328e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 329e15f9bd0SJeremy L Thompson "Not defined for composite operator"); 3307a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 3317a982d89SJeremy L. Thompson 3327a982d89SJeremy L. Thompson *qf = op->qf; 333e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3347a982d89SJeremy L. Thompson } 3357a982d89SJeremy L. Thompson 3367a982d89SJeremy L. Thompson /** 337c04a41a7SJeremy L Thompson @brief Get a boolean value indicating if the CeedOperator is composite 338c04a41a7SJeremy L Thompson 339c04a41a7SJeremy L Thompson @param op CeedOperator 340d1d35e2fSjeremylt @param[out] is_composite Variable to store composite status 341c04a41a7SJeremy L Thompson 342c04a41a7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 343c04a41a7SJeremy L Thompson 344c04a41a7SJeremy L Thompson @ref Backend 345c04a41a7SJeremy L Thompson **/ 346c04a41a7SJeremy L Thompson 347d1d35e2fSjeremylt int CeedOperatorIsComposite(CeedOperator op, bool *is_composite) { 348f04ea552SJeremy L Thompson *is_composite = op->is_composite; 349e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 350c04a41a7SJeremy L Thompson } 351c04a41a7SJeremy L Thompson 352c04a41a7SJeremy L Thompson /** 353d1d35e2fSjeremylt @brief Get the number of sub_operators associated with a CeedOperator 3547a982d89SJeremy L. Thompson 3557a982d89SJeremy L. Thompson @param op CeedOperator 356d1d35e2fSjeremylt @param[out] num_suboperators Variable to store number of sub_operators 3577a982d89SJeremy L. Thompson 3587a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3597a982d89SJeremy L. Thompson 3607a982d89SJeremy L. Thompson @ref Backend 3617a982d89SJeremy L. Thompson **/ 3627a982d89SJeremy L. Thompson 363d1d35e2fSjeremylt int CeedOperatorGetNumSub(CeedOperator op, CeedInt *num_suboperators) { 364f04ea552SJeremy L Thompson if (!op->is_composite) 3657a982d89SJeremy L. Thompson // LCOV_EXCL_START 366e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 3677a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 3687a982d89SJeremy L. Thompson 369d1d35e2fSjeremylt *num_suboperators = op->num_suboperators; 370e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3717a982d89SJeremy L. Thompson } 3727a982d89SJeremy L. Thompson 3737a982d89SJeremy L. Thompson /** 374d1d35e2fSjeremylt @brief Get the list of sub_operators associated with a CeedOperator 3757a982d89SJeremy L. Thompson 3767a982d89SJeremy L. Thompson @param op CeedOperator 377d1d35e2fSjeremylt @param[out] sub_operators Variable to store list of sub_operators 3787a982d89SJeremy L. Thompson 3797a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3807a982d89SJeremy L. Thompson 3817a982d89SJeremy L. Thompson @ref Backend 3827a982d89SJeremy L. Thompson **/ 3837a982d89SJeremy L. Thompson 384d1d35e2fSjeremylt int CeedOperatorGetSubList(CeedOperator op, CeedOperator **sub_operators) { 385f04ea552SJeremy L Thompson if (!op->is_composite) 3867a982d89SJeremy L. Thompson // LCOV_EXCL_START 387e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 3887a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 3897a982d89SJeremy L. Thompson 390d1d35e2fSjeremylt *sub_operators = op->sub_operators; 391e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3927a982d89SJeremy L. Thompson } 3937a982d89SJeremy L. Thompson 3947a982d89SJeremy L. Thompson /** 3957a982d89SJeremy L. Thompson @brief Get the backend data of a CeedOperator 3967a982d89SJeremy L. Thompson 3977a982d89SJeremy L. Thompson @param op CeedOperator 3987a982d89SJeremy L. Thompson @param[out] data Variable to store data 3997a982d89SJeremy L. Thompson 4007a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4017a982d89SJeremy L. Thompson 4027a982d89SJeremy L. Thompson @ref Backend 4037a982d89SJeremy L. Thompson **/ 4047a982d89SJeremy L. Thompson 405777ff853SJeremy L Thompson int CeedOperatorGetData(CeedOperator op, void *data) { 406777ff853SJeremy L Thompson *(void **)data = op->data; 407e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4087a982d89SJeremy L. Thompson } 4097a982d89SJeremy L. Thompson 4107a982d89SJeremy L. Thompson /** 4117a982d89SJeremy L. Thompson @brief Set the backend data of a CeedOperator 4127a982d89SJeremy L. Thompson 4137a982d89SJeremy L. Thompson @param[out] op CeedOperator 4147a982d89SJeremy L. Thompson @param data Data to set 4157a982d89SJeremy L. Thompson 4167a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4177a982d89SJeremy L. Thompson 4187a982d89SJeremy L. Thompson @ref Backend 4197a982d89SJeremy L. Thompson **/ 4207a982d89SJeremy L. Thompson 421777ff853SJeremy L Thompson int CeedOperatorSetData(CeedOperator op, void *data) { 422777ff853SJeremy L Thompson op->data = data; 423e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4247a982d89SJeremy L. Thompson } 4257a982d89SJeremy L. Thompson 4267a982d89SJeremy L. Thompson /** 42734359f16Sjeremylt @brief Increment the reference counter for a CeedOperator 42834359f16Sjeremylt 42934359f16Sjeremylt @param op CeedOperator to increment the reference counter 43034359f16Sjeremylt 43134359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 43234359f16Sjeremylt 43334359f16Sjeremylt @ref Backend 43434359f16Sjeremylt **/ 4359560d06aSjeremylt int CeedOperatorReference(CeedOperator op) { 43634359f16Sjeremylt op->ref_count++; 43734359f16Sjeremylt return CEED_ERROR_SUCCESS; 43834359f16Sjeremylt } 43934359f16Sjeremylt 44034359f16Sjeremylt /** 4417a982d89SJeremy L. Thompson @brief Set the setup flag of a CeedOperator to True 4427a982d89SJeremy L. Thompson 4437a982d89SJeremy L. Thompson @param op CeedOperator 4447a982d89SJeremy L. Thompson 4457a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4467a982d89SJeremy L. Thompson 4477a982d89SJeremy L. Thompson @ref Backend 4487a982d89SJeremy L. Thompson **/ 4497a982d89SJeremy L. Thompson 4507a982d89SJeremy L. Thompson int CeedOperatorSetSetupDone(CeedOperator op) { 451f04ea552SJeremy L Thompson op->is_backend_setup = true; 452e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4537a982d89SJeremy L. Thompson } 4547a982d89SJeremy L. Thompson 4557a982d89SJeremy L. Thompson /// @} 4567a982d89SJeremy L. Thompson 4577a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4587a982d89SJeremy L. Thompson /// CeedOperator Public API 4597a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4607a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorUser 461dfdf5a53Sjeremylt /// @{ 462d7b241e6Sjeremylt 463d7b241e6Sjeremylt /** 4640219ea01SJeremy L Thompson @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and 4650219ea01SJeremy L Thompson CeedElemRestriction can be associated with CeedQFunction fields with 4660219ea01SJeremy L Thompson \ref CeedOperatorSetField. 467d7b241e6Sjeremylt 468b11c1e72Sjeremylt @param ceed A Ceed object where the CeedOperator will be created 469d7b241e6Sjeremylt @param qf QFunction defining the action of the operator at quadrature points 47034138859Sjeremylt @param dqf QFunction defining the action of the Jacobian of @a qf (or 4714cc79fe7SJed Brown @ref CEED_QFUNCTION_NONE) 472d7b241e6Sjeremylt @param dqfT QFunction defining the action of the transpose of the Jacobian 4734cc79fe7SJed Brown of @a qf (or @ref CEED_QFUNCTION_NONE) 474b11c1e72Sjeremylt @param[out] op Address of the variable where the newly created 475b11c1e72Sjeremylt CeedOperator will be stored 476b11c1e72Sjeremylt 477b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 478dfdf5a53Sjeremylt 4797a982d89SJeremy L. Thompson @ref User 480d7b241e6Sjeremylt */ 481d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, 482d7b241e6Sjeremylt CeedQFunction dqfT, CeedOperator *op) { 483d7b241e6Sjeremylt int ierr; 484d7b241e6Sjeremylt 4855fe0d4faSjeremylt if (!ceed->OperatorCreate) { 4865fe0d4faSjeremylt Ceed delegate; 487aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 4885fe0d4faSjeremylt 4895fe0d4faSjeremylt if (!delegate) 490c042f62fSJeremy L Thompson // LCOV_EXCL_START 491e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 492e15f9bd0SJeremy L Thompson "Backend does not support OperatorCreate"); 493c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 4945fe0d4faSjeremylt 4955fe0d4faSjeremylt ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr); 496e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4975fe0d4faSjeremylt } 4985fe0d4faSjeremylt 499b3b7035fSJeremy L Thompson if (!qf || qf == CEED_QFUNCTION_NONE) 500b3b7035fSJeremy L Thompson // LCOV_EXCL_START 501e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 502e15f9bd0SJeremy L Thompson "Operator must have a valid QFunction."); 503b3b7035fSJeremy L Thompson // LCOV_EXCL_STOP 504d7b241e6Sjeremylt ierr = CeedCalloc(1, op); CeedChk(ierr); 505d7b241e6Sjeremylt (*op)->ceed = ceed; 5069560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 507d1d35e2fSjeremylt (*op)->ref_count = 1; 508d7b241e6Sjeremylt (*op)->qf = qf; 5099560d06aSjeremylt ierr = CeedQFunctionReference(qf); CeedChk(ierr); 510442e7f0bSjeremylt if (dqf && dqf != CEED_QFUNCTION_NONE) { 511d7b241e6Sjeremylt (*op)->dqf = dqf; 5129560d06aSjeremylt ierr = CeedQFunctionReference(dqf); CeedChk(ierr); 513442e7f0bSjeremylt } 514442e7f0bSjeremylt if (dqfT && dqfT != CEED_QFUNCTION_NONE) { 515d7b241e6Sjeremylt (*op)->dqfT = dqfT; 5169560d06aSjeremylt ierr = CeedQFunctionReference(dqfT); CeedChk(ierr); 517442e7f0bSjeremylt } 518d1d35e2fSjeremylt ierr = CeedCalloc(16, &(*op)->input_fields); CeedChk(ierr); 519d1d35e2fSjeremylt ierr = CeedCalloc(16, &(*op)->output_fields); CeedChk(ierr); 520d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 521e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 522d7b241e6Sjeremylt } 523d7b241e6Sjeremylt 524d7b241e6Sjeremylt /** 52552d6035fSJeremy L Thompson @brief Create an operator that composes the action of several operators 52652d6035fSJeremy L Thompson 52752d6035fSJeremy L Thompson @param ceed A Ceed object where the CeedOperator will be created 52852d6035fSJeremy L Thompson @param[out] op Address of the variable where the newly created 52952d6035fSJeremy L Thompson Composite CeedOperator will be stored 53052d6035fSJeremy L Thompson 53152d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 53252d6035fSJeremy L Thompson 5337a982d89SJeremy L. Thompson @ref User 53452d6035fSJeremy L Thompson */ 53552d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) { 53652d6035fSJeremy L Thompson int ierr; 53752d6035fSJeremy L Thompson 53852d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 53952d6035fSJeremy L Thompson Ceed delegate; 540aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 54152d6035fSJeremy L Thompson 542250756a7Sjeremylt if (delegate) { 54352d6035fSJeremy L Thompson ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr); 544e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 54552d6035fSJeremy L Thompson } 546250756a7Sjeremylt } 54752d6035fSJeremy L Thompson 54852d6035fSJeremy L Thompson ierr = CeedCalloc(1, op); CeedChk(ierr); 54952d6035fSJeremy L Thompson (*op)->ceed = ceed; 5509560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 551f04ea552SJeremy L Thompson (*op)->is_composite = true; 552d1d35e2fSjeremylt ierr = CeedCalloc(16, &(*op)->sub_operators); CeedChk(ierr); 553250756a7Sjeremylt 554250756a7Sjeremylt if (ceed->CompositeOperatorCreate) { 55552d6035fSJeremy L Thompson ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr); 556250756a7Sjeremylt } 557e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 55852d6035fSJeremy L Thompson } 55952d6035fSJeremy L Thompson 56052d6035fSJeremy L Thompson /** 5619560d06aSjeremylt @brief Copy the pointer to a CeedOperator. Both pointers should 5629560d06aSjeremylt be destroyed with `CeedOperatorDestroy()`; 5639560d06aSjeremylt Note: If `*op_copy` is non-NULL, then it is assumed that 5649560d06aSjeremylt `*op_copy` is a pointer to a CeedOperator. This 5659560d06aSjeremylt CeedOperator will be destroyed if `*op_copy` is the only 5669560d06aSjeremylt reference to this CeedOperator. 5679560d06aSjeremylt 5689560d06aSjeremylt @param op CeedOperator to copy reference to 5699560d06aSjeremylt @param[out] op_copy Variable to store copied reference 5709560d06aSjeremylt 5719560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 5729560d06aSjeremylt 5739560d06aSjeremylt @ref User 5749560d06aSjeremylt **/ 5759560d06aSjeremylt int CeedOperatorReferenceCopy(CeedOperator op, CeedOperator *op_copy) { 5769560d06aSjeremylt int ierr; 5779560d06aSjeremylt 5789560d06aSjeremylt ierr = CeedOperatorReference(op); CeedChk(ierr); 5799560d06aSjeremylt ierr = CeedOperatorDestroy(op_copy); CeedChk(ierr); 5809560d06aSjeremylt *op_copy = op; 5819560d06aSjeremylt return CEED_ERROR_SUCCESS; 5829560d06aSjeremylt } 5839560d06aSjeremylt 5849560d06aSjeremylt /** 585b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 586d7b241e6Sjeremylt 587d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 588d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 589d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 590d7b241e6Sjeremylt 591d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 592d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 593d7b241e6Sjeremylt input and at most one active output. 594d7b241e6Sjeremylt 5958c91a0c9SJeremy L Thompson @param op CeedOperator on which to provide the field 596d1d35e2fSjeremylt @param field_name Name of the field (to be matched with the name used by 5978795c945Sjeremylt CeedQFunction) 598b11c1e72Sjeremylt @param r CeedElemRestriction 5994cc79fe7SJed Brown @param b CeedBasis in which the field resides or @ref CEED_BASIS_COLLOCATED 600b11c1e72Sjeremylt if collocated with quadrature points 6014cc79fe7SJed Brown @param v CeedVector to be used by CeedOperator or @ref CEED_VECTOR_ACTIVE 6024cc79fe7SJed Brown if field is active or @ref CEED_VECTOR_NONE if using 6034cc79fe7SJed Brown @ref CEED_EVAL_WEIGHT in the QFunction 604b11c1e72Sjeremylt 605b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 606dfdf5a53Sjeremylt 6077a982d89SJeremy L. Thompson @ref User 608b11c1e72Sjeremylt **/ 609d1d35e2fSjeremylt int CeedOperatorSetField(CeedOperator op, const char *field_name, 610a8d32208Sjeremylt CeedElemRestriction r, CeedBasis b, CeedVector v) { 611d7b241e6Sjeremylt int ierr; 612f04ea552SJeremy L Thompson if (op->is_composite) 613c042f62fSJeremy L Thompson // LCOV_EXCL_START 614e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 615e15f9bd0SJeremy L Thompson "Cannot add field to composite operator."); 616c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 617f04ea552SJeremy L Thompson if (op->is_immutable) 618f04ea552SJeremy L Thompson // LCOV_EXCL_START 619f04ea552SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 620f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 621f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 6228b067b84SJed Brown if (!r) 623c042f62fSJeremy L Thompson // LCOV_EXCL_START 624e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 625c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 626d1d35e2fSjeremylt field_name); 627c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 6288b067b84SJed Brown if (!b) 629c042f62fSJeremy L Thompson // LCOV_EXCL_START 630e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 631e15f9bd0SJeremy L Thompson "Basis b for field \"%s\" must be non-NULL.", 632d1d35e2fSjeremylt field_name); 633c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 6348b067b84SJed Brown if (!v) 635c042f62fSJeremy L Thompson // LCOV_EXCL_START 636e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 637e15f9bd0SJeremy L Thompson "Vector v for field \"%s\" must be non-NULL.", 638d1d35e2fSjeremylt field_name); 639c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 64052d6035fSJeremy L Thompson 641d1d35e2fSjeremylt CeedInt num_elem; 642d1d35e2fSjeremylt ierr = CeedElemRestrictionGetNumElements(r, &num_elem); CeedChk(ierr); 643d1d35e2fSjeremylt if (r != CEED_ELEMRESTRICTION_NONE && op->has_restriction && 644d1d35e2fSjeremylt op->num_elem != num_elem) 645c042f62fSJeremy L Thompson // LCOV_EXCL_START 646e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 6471d102b48SJeremy L Thompson "ElemRestriction with %d elements incompatible with prior " 648d1d35e2fSjeremylt "%d elements", num_elem, op->num_elem); 649c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 650d7b241e6Sjeremylt 65178464608Sjeremylt CeedInt num_qpts = 0; 652e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 653d1d35e2fSjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &num_qpts); CeedChk(ierr); 654d1d35e2fSjeremylt if (op->num_qpts && op->num_qpts != num_qpts) 655c042f62fSJeremy L Thompson // LCOV_EXCL_START 656e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 657e15f9bd0SJeremy L Thompson "Basis with %d quadrature points " 658d1d35e2fSjeremylt "incompatible with prior %d points", num_qpts, 659d1d35e2fSjeremylt op->num_qpts); 660c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 661d7b241e6Sjeremylt } 662d1d35e2fSjeremylt CeedQFunctionField qf_field; 663d1d35e2fSjeremylt CeedOperatorField *op_field; 664d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_input_fields; i++) { 665d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->input_fields[i]).field_name)) { 666d1d35e2fSjeremylt qf_field = op->qf->input_fields[i]; 667d1d35e2fSjeremylt op_field = &op->input_fields[i]; 668d7b241e6Sjeremylt goto found; 669d7b241e6Sjeremylt } 670d7b241e6Sjeremylt } 671d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_output_fields; i++) { 672d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->output_fields[i]).field_name)) { 673d1d35e2fSjeremylt qf_field = op->qf->output_fields[i]; 674d1d35e2fSjeremylt op_field = &op->output_fields[i]; 675d7b241e6Sjeremylt goto found; 676d7b241e6Sjeremylt } 677d7b241e6Sjeremylt } 678c042f62fSJeremy L Thompson // LCOV_EXCL_START 679e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPLETE, 680e15f9bd0SJeremy L Thompson "QFunction has no knowledge of field '%s'", 681d1d35e2fSjeremylt field_name); 682c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 683d7b241e6Sjeremylt found: 684d1d35e2fSjeremylt ierr = CeedOperatorCheckField(op->ceed, qf_field, r, b); CeedChk(ierr); 685d1d35e2fSjeremylt ierr = CeedCalloc(1, op_field); CeedChk(ierr); 686e15f9bd0SJeremy L Thompson 687d1d35e2fSjeremylt (*op_field)->vec = v; 688e15f9bd0SJeremy L Thompson if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) { 6899560d06aSjeremylt ierr = CeedVectorReference(v); CeedChk(ierr); 690e15f9bd0SJeremy L Thompson } 691e15f9bd0SJeremy L Thompson 692d1d35e2fSjeremylt (*op_field)->elem_restr = r; 6939560d06aSjeremylt ierr = CeedElemRestrictionReference(r); CeedChk(ierr); 694e15f9bd0SJeremy L Thompson if (r != CEED_ELEMRESTRICTION_NONE) { 695d1d35e2fSjeremylt op->num_elem = num_elem; 696d1d35e2fSjeremylt op->has_restriction = true; // Restriction set, but num_elem may be 0 697e15f9bd0SJeremy L Thompson } 698d99fa3c5SJeremy L Thompson 699d1d35e2fSjeremylt (*op_field)->basis = b; 700e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 701cd4dfc48Sjeremylt if (!op->num_qpts) { 702cd4dfc48Sjeremylt ierr = CeedOperatorSetNumQuadraturePoints(op, num_qpts); CeedChk(ierr); 703cd4dfc48Sjeremylt } 7049560d06aSjeremylt ierr = CeedBasisReference(b); CeedChk(ierr); 705e15f9bd0SJeremy L Thompson } 706e15f9bd0SJeremy L Thompson 707d1d35e2fSjeremylt op->num_fields += 1; 708d1d35e2fSjeremylt size_t len = strlen(field_name); 709d99fa3c5SJeremy L Thompson char *tmp; 710d99fa3c5SJeremy L Thompson ierr = CeedCalloc(len+1, &tmp); CeedChk(ierr); 711d1d35e2fSjeremylt memcpy(tmp, field_name, len+1); 712d1d35e2fSjeremylt (*op_field)->field_name = tmp; 713e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 714d7b241e6Sjeremylt } 715d7b241e6Sjeremylt 716d7b241e6Sjeremylt /** 71743bbe138SJeremy L Thompson @brief Get the CeedOperatorFields of a CeedOperator 71843bbe138SJeremy L Thompson 719f04ea552SJeremy L Thompson Note: Calling this function asserts that setup is complete 720f04ea552SJeremy L Thompson and sets the CeedOperator as immutable. 721f04ea552SJeremy L Thompson 72243bbe138SJeremy L Thompson @param op CeedOperator 72343bbe138SJeremy L Thompson @param[out] input_fields Variable to store input_fields 72443bbe138SJeremy L Thompson @param[out] output_fields Variable to store output_fields 72543bbe138SJeremy L Thompson 72643bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 72743bbe138SJeremy L Thompson 728e9b533fbSJeremy L Thompson @ref Advanced 72943bbe138SJeremy L Thompson **/ 73043bbe138SJeremy L Thompson int CeedOperatorGetFields(CeedOperator op, CeedInt *num_input_fields, 73143bbe138SJeremy L Thompson CeedOperatorField **input_fields, 73243bbe138SJeremy L Thompson CeedInt *num_output_fields, 73343bbe138SJeremy L Thompson CeedOperatorField **output_fields) { 734f04ea552SJeremy L Thompson int ierr; 735f04ea552SJeremy L Thompson 736f04ea552SJeremy L Thompson if (op->is_composite) 73743bbe138SJeremy L Thompson // LCOV_EXCL_START 73843bbe138SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 73943bbe138SJeremy L Thompson "Not defined for composite operator"); 74043bbe138SJeremy L Thompson // LCOV_EXCL_STOP 741f04ea552SJeremy L Thompson ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 74243bbe138SJeremy L Thompson 74343bbe138SJeremy L Thompson if (num_input_fields) *num_input_fields = op->qf->num_input_fields; 74443bbe138SJeremy L Thompson if (input_fields) *input_fields = op->input_fields; 74543bbe138SJeremy L Thompson if (num_output_fields) *num_output_fields = op->qf->num_output_fields; 74643bbe138SJeremy L Thompson if (output_fields) *output_fields = op->output_fields; 74743bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 74843bbe138SJeremy L Thompson } 74943bbe138SJeremy L Thompson 75043bbe138SJeremy L Thompson /** 75128567f8fSJeremy L Thompson @brief Get the name of a CeedOperatorField 75228567f8fSJeremy L Thompson 75328567f8fSJeremy L Thompson @param op_field CeedOperatorField 75428567f8fSJeremy L Thompson @param[out] field_name Variable to store the field name 75528567f8fSJeremy L Thompson 75628567f8fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 75728567f8fSJeremy L Thompson 758e9b533fbSJeremy L Thompson @ref Advanced 75928567f8fSJeremy L Thompson **/ 76028567f8fSJeremy L Thompson int CeedOperatorFieldGetName(CeedOperatorField op_field, char **field_name) { 76128567f8fSJeremy L Thompson *field_name = (char *)op_field->field_name; 76228567f8fSJeremy L Thompson return CEED_ERROR_SUCCESS; 76328567f8fSJeremy L Thompson } 76428567f8fSJeremy L Thompson 76528567f8fSJeremy L Thompson /** 76643bbe138SJeremy L Thompson @brief Get the CeedElemRestriction of a CeedOperatorField 76743bbe138SJeremy L Thompson 76843bbe138SJeremy L Thompson @param op_field CeedOperatorField 76943bbe138SJeremy L Thompson @param[out] rstr Variable to store CeedElemRestriction 77043bbe138SJeremy L Thompson 77143bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 77243bbe138SJeremy L Thompson 773e9b533fbSJeremy L Thompson @ref Advanced 77443bbe138SJeremy L Thompson **/ 77543bbe138SJeremy L Thompson int CeedOperatorFieldGetElemRestriction(CeedOperatorField op_field, 77643bbe138SJeremy L Thompson CeedElemRestriction *rstr) { 77743bbe138SJeremy L Thompson *rstr = op_field->elem_restr; 77843bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 77943bbe138SJeremy L Thompson } 78043bbe138SJeremy L Thompson 78143bbe138SJeremy L Thompson /** 78243bbe138SJeremy L Thompson @brief Get the CeedBasis of a CeedOperatorField 78343bbe138SJeremy L Thompson 78443bbe138SJeremy L Thompson @param op_field CeedOperatorField 78543bbe138SJeremy L Thompson @param[out] basis Variable to store CeedBasis 78643bbe138SJeremy L Thompson 78743bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 78843bbe138SJeremy L Thompson 789e9b533fbSJeremy L Thompson @ref Advanced 79043bbe138SJeremy L Thompson **/ 79143bbe138SJeremy L Thompson int CeedOperatorFieldGetBasis(CeedOperatorField op_field, CeedBasis *basis) { 79243bbe138SJeremy L Thompson *basis = op_field->basis; 79343bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 79443bbe138SJeremy L Thompson } 79543bbe138SJeremy L Thompson 79643bbe138SJeremy L Thompson /** 79743bbe138SJeremy L Thompson @brief Get the CeedVector of a CeedOperatorField 79843bbe138SJeremy L Thompson 79943bbe138SJeremy L Thompson @param op_field CeedOperatorField 80043bbe138SJeremy L Thompson @param[out] vec Variable to store CeedVector 80143bbe138SJeremy L Thompson 80243bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 80343bbe138SJeremy L Thompson 804e9b533fbSJeremy L Thompson @ref Advanced 80543bbe138SJeremy L Thompson **/ 80643bbe138SJeremy L Thompson int CeedOperatorFieldGetVector(CeedOperatorField op_field, CeedVector *vec) { 80743bbe138SJeremy L Thompson *vec = op_field->vec; 80843bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 80943bbe138SJeremy L Thompson } 81043bbe138SJeremy L Thompson 81143bbe138SJeremy L Thompson /** 81252d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 813288c0443SJeremy L Thompson 814d1d35e2fSjeremylt @param[out] composite_op Composite CeedOperator 815d1d35e2fSjeremylt @param sub_op Sub-operator CeedOperator 81652d6035fSJeremy L Thompson 81752d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 81852d6035fSJeremy L Thompson 8197a982d89SJeremy L. Thompson @ref User 82052d6035fSJeremy L Thompson */ 821d1d35e2fSjeremylt int CeedCompositeOperatorAddSub(CeedOperator composite_op, 822d1d35e2fSjeremylt CeedOperator sub_op) { 82334359f16Sjeremylt int ierr; 82434359f16Sjeremylt 825f04ea552SJeremy L Thompson if (!composite_op->is_composite) 826c042f62fSJeremy L Thompson // LCOV_EXCL_START 827d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_MINOR, 828e2f04181SAndrew T. Barker "CeedOperator is not a composite operator"); 829c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 83052d6035fSJeremy L Thompson 831d1d35e2fSjeremylt if (composite_op->num_suboperators == CEED_COMPOSITE_MAX) 832c042f62fSJeremy L Thompson // LCOV_EXCL_START 833d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_UNSUPPORTED, 834d1d35e2fSjeremylt "Cannot add additional sub_operators"); 835c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 836f04ea552SJeremy L Thompson if (composite_op->is_immutable) 837f04ea552SJeremy L Thompson // LCOV_EXCL_START 838f04ea552SJeremy L Thompson return CeedError(composite_op->ceed, CEED_ERROR_MAJOR, 839f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 840f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 84152d6035fSJeremy L Thompson 842d1d35e2fSjeremylt composite_op->sub_operators[composite_op->num_suboperators] = sub_op; 8439560d06aSjeremylt ierr = CeedOperatorReference(sub_op); CeedChk(ierr); 844d1d35e2fSjeremylt composite_op->num_suboperators++; 845e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 84652d6035fSJeremy L Thompson } 84752d6035fSJeremy L Thompson 84852d6035fSJeremy L Thompson /** 849*4db537f9SJeremy L Thompson @brief Check if a CeedOperator is ready to be used. 850*4db537f9SJeremy L Thompson 851*4db537f9SJeremy L Thompson @param[in] op CeedOperator to check 852*4db537f9SJeremy L Thompson 853*4db537f9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 854*4db537f9SJeremy L Thompson 855*4db537f9SJeremy L Thompson @ref User 856*4db537f9SJeremy L Thompson **/ 857*4db537f9SJeremy L Thompson int CeedOperatorCheckReady(CeedOperator op) { 858*4db537f9SJeremy L Thompson int ierr; 859*4db537f9SJeremy L Thompson Ceed ceed; 860*4db537f9SJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 861*4db537f9SJeremy L Thompson 862*4db537f9SJeremy L Thompson if (op->is_interface_setup) 863*4db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 864*4db537f9SJeremy L Thompson 865*4db537f9SJeremy L Thompson CeedQFunction qf = op->qf; 866*4db537f9SJeremy L Thompson if (op->is_composite) { 867*4db537f9SJeremy L Thompson if (!op->num_suboperators) 868*4db537f9SJeremy L Thompson // LCOV_EXCL_START 869*4db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "No sub_operators set"); 870*4db537f9SJeremy L Thompson // LCOV_EXCL_STOP 871*4db537f9SJeremy L Thompson for (CeedInt i = 0; i < op->num_suboperators; i++) { 872*4db537f9SJeremy L Thompson ierr = CeedOperatorCheckReady(op->sub_operators[i]); CeedChk(ierr); 873*4db537f9SJeremy L Thompson } 874*4db537f9SJeremy L Thompson } else { 875*4db537f9SJeremy L Thompson if (op->num_fields == 0) 876*4db537f9SJeremy L Thompson // LCOV_EXCL_START 877*4db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "No operator fields set"); 878*4db537f9SJeremy L Thompson // LCOV_EXCL_STOP 879*4db537f9SJeremy L Thompson if (op->num_fields < qf->num_input_fields + qf->num_output_fields) 880*4db537f9SJeremy L Thompson // LCOV_EXCL_START 881*4db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "Not all operator fields set"); 882*4db537f9SJeremy L Thompson // LCOV_EXCL_STOP 883*4db537f9SJeremy L Thompson if (!op->has_restriction) 884*4db537f9SJeremy L Thompson // LCOV_EXCL_START 885*4db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, 886*4db537f9SJeremy L Thompson "At least one restriction required"); 887*4db537f9SJeremy L Thompson // LCOV_EXCL_STOP 888*4db537f9SJeremy L Thompson if (op->num_qpts == 0) 889*4db537f9SJeremy L Thompson // LCOV_EXCL_START 890*4db537f9SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, 891*4db537f9SJeremy L Thompson "At least one non-collocated basis is required " 892*4db537f9SJeremy L Thompson "or the number of quadrature points must be set"); 893*4db537f9SJeremy L Thompson // LCOV_EXCL_STOP 894*4db537f9SJeremy L Thompson } 895*4db537f9SJeremy L Thompson 896*4db537f9SJeremy L Thompson // Flag as immutable and ready 897*4db537f9SJeremy L Thompson op->is_interface_setup = true; 898*4db537f9SJeremy L Thompson if (op->qf && op->qf != CEED_QFUNCTION_NONE) 899*4db537f9SJeremy L Thompson // LCOV_EXCL_START 900*4db537f9SJeremy L Thompson op->qf->is_immutable = true; 901*4db537f9SJeremy L Thompson // LCOV_EXCL_STOP 902*4db537f9SJeremy L Thompson if (op->dqf && op->dqf != CEED_QFUNCTION_NONE) 903*4db537f9SJeremy L Thompson // LCOV_EXCL_START 904*4db537f9SJeremy L Thompson op->dqf->is_immutable = true; 905*4db537f9SJeremy L Thompson // LCOV_EXCL_STOP 906*4db537f9SJeremy L Thompson if (op->dqfT && op->dqfT != CEED_QFUNCTION_NONE) 907*4db537f9SJeremy L Thompson // LCOV_EXCL_START 908*4db537f9SJeremy L Thompson op->dqfT->is_immutable = true; 909*4db537f9SJeremy L Thompson // LCOV_EXCL_STOP 910*4db537f9SJeremy L Thompson return CEED_ERROR_SUCCESS; 911*4db537f9SJeremy L Thompson } 912*4db537f9SJeremy L Thompson 913*4db537f9SJeremy L Thompson /** 914cd4dfc48Sjeremylt @brief Set the number of quadrature points associated with a CeedOperator. 915cd4dfc48Sjeremylt This should be used when creating a CeedOperator where every 916cd4dfc48Sjeremylt field has a collocated basis. This function cannot be used for 917cd4dfc48Sjeremylt composite CeedOperators. 918cd4dfc48Sjeremylt 919cd4dfc48Sjeremylt @param op CeedOperator 920cd4dfc48Sjeremylt @param num_qpts Number of quadrature points to set 921cd4dfc48Sjeremylt 922cd4dfc48Sjeremylt @return An error code: 0 - success, otherwise - failure 923cd4dfc48Sjeremylt 924e9b533fbSJeremy L Thompson @ref Advanced 925cd4dfc48Sjeremylt **/ 926cd4dfc48Sjeremylt int CeedOperatorSetNumQuadraturePoints(CeedOperator op, CeedInt num_qpts) { 927f04ea552SJeremy L Thompson if (op->is_composite) 928cd4dfc48Sjeremylt // LCOV_EXCL_START 929cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 930cd4dfc48Sjeremylt "Not defined for composite operator"); 931cd4dfc48Sjeremylt // LCOV_EXCL_STOP 932cd4dfc48Sjeremylt if (op->num_qpts) 933cd4dfc48Sjeremylt // LCOV_EXCL_START 934cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 935cd4dfc48Sjeremylt "Number of quadrature points already defined"); 936cd4dfc48Sjeremylt // LCOV_EXCL_STOP 937f04ea552SJeremy L Thompson if (op->is_immutable) 938f04ea552SJeremy L Thompson // LCOV_EXCL_START 939f04ea552SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 940f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 941f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 942cd4dfc48Sjeremylt 943cd4dfc48Sjeremylt op->num_qpts = num_qpts; 944cd4dfc48Sjeremylt return CEED_ERROR_SUCCESS; 945cd4dfc48Sjeremylt } 946cd4dfc48Sjeremylt 947cd4dfc48Sjeremylt /** 9487a982d89SJeremy L. Thompson @brief View a CeedOperator 9497a982d89SJeremy L. Thompson 9507a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 9517a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 9527a982d89SJeremy L. Thompson 9537a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 9547a982d89SJeremy L. Thompson 9557a982d89SJeremy L. Thompson @ref User 9567a982d89SJeremy L. Thompson **/ 9577a982d89SJeremy L. Thompson int CeedOperatorView(CeedOperator op, FILE *stream) { 9587a982d89SJeremy L. Thompson int ierr; 9597a982d89SJeremy L. Thompson 960f04ea552SJeremy L Thompson if (op->is_composite) { 9617a982d89SJeremy L. Thompson fprintf(stream, "Composite CeedOperator\n"); 9627a982d89SJeremy L. Thompson 963d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 9647a982d89SJeremy L. Thompson fprintf(stream, " SubOperator [%d]:\n", i); 965d1d35e2fSjeremylt ierr = CeedOperatorSingleView(op->sub_operators[i], 1, stream); 9667a982d89SJeremy L. Thompson CeedChk(ierr); 9677a982d89SJeremy L. Thompson } 9687a982d89SJeremy L. Thompson } else { 9697a982d89SJeremy L. Thompson fprintf(stream, "CeedOperator\n"); 9707a982d89SJeremy L. Thompson ierr = CeedOperatorSingleView(op, 0, stream); CeedChk(ierr); 9717a982d89SJeremy L. Thompson } 972e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9737a982d89SJeremy L. Thompson } 9743bd813ffSjeremylt 9753bd813ffSjeremylt /** 976b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedOperator 977b7c9bbdaSJeremy L Thompson 978b7c9bbdaSJeremy L Thompson @param op CeedOperator 979b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 980b7c9bbdaSJeremy L Thompson 981b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 982b7c9bbdaSJeremy L Thompson 983b7c9bbdaSJeremy L Thompson @ref Advanced 984b7c9bbdaSJeremy L Thompson **/ 985b7c9bbdaSJeremy L Thompson int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 986b7c9bbdaSJeremy L Thompson *ceed = op->ceed; 987b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 988b7c9bbdaSJeremy L Thompson } 989b7c9bbdaSJeremy L Thompson 990b7c9bbdaSJeremy L Thompson /** 991b7c9bbdaSJeremy L Thompson @brief Get the number of elements associated with a CeedOperator 992b7c9bbdaSJeremy L Thompson 993b7c9bbdaSJeremy L Thompson @param op CeedOperator 994b7c9bbdaSJeremy L Thompson @param[out] num_elem Variable to store number of elements 995b7c9bbdaSJeremy L Thompson 996b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 997b7c9bbdaSJeremy L Thompson 998b7c9bbdaSJeremy L Thompson @ref Advanced 999b7c9bbdaSJeremy L Thompson **/ 1000b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumElements(CeedOperator op, CeedInt *num_elem) { 1001b7c9bbdaSJeremy L Thompson if (op->is_composite) 1002b7c9bbdaSJeremy L Thompson // LCOV_EXCL_START 1003b7c9bbdaSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 1004b7c9bbdaSJeremy L Thompson "Not defined for composite operator"); 1005b7c9bbdaSJeremy L Thompson // LCOV_EXCL_STOP 1006b7c9bbdaSJeremy L Thompson 1007b7c9bbdaSJeremy L Thompson *num_elem = op->num_elem; 1008b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1009b7c9bbdaSJeremy L Thompson } 1010b7c9bbdaSJeremy L Thompson 1011b7c9bbdaSJeremy L Thompson /** 1012b7c9bbdaSJeremy L Thompson @brief Get the number of quadrature points associated with a CeedOperator 1013b7c9bbdaSJeremy L Thompson 1014b7c9bbdaSJeremy L Thompson @param op CeedOperator 1015b7c9bbdaSJeremy L Thompson @param[out] num_qpts Variable to store vector number of quadrature points 1016b7c9bbdaSJeremy L Thompson 1017b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1018b7c9bbdaSJeremy L Thompson 1019b7c9bbdaSJeremy L Thompson @ref Advanced 1020b7c9bbdaSJeremy L Thompson **/ 1021b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *num_qpts) { 1022b7c9bbdaSJeremy L Thompson if (op->is_composite) 1023b7c9bbdaSJeremy L Thompson // LCOV_EXCL_START 1024b7c9bbdaSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 1025b7c9bbdaSJeremy L Thompson "Not defined for composite operator"); 1026b7c9bbdaSJeremy L Thompson // LCOV_EXCL_STOP 1027b7c9bbdaSJeremy L Thompson 1028b7c9bbdaSJeremy L Thompson *num_qpts = op->num_qpts; 1029b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1030b7c9bbdaSJeremy L Thompson } 1031b7c9bbdaSJeremy L Thompson 1032b7c9bbdaSJeremy L Thompson /** 10333bd813ffSjeremylt @brief Apply CeedOperator to a vector 1034d7b241e6Sjeremylt 1035d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 1036d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 1037d7b241e6Sjeremylt CeedOperatorSetField(). 1038d7b241e6Sjeremylt 1039f04ea552SJeremy L Thompson Note: Calling this function asserts that setup is complete 1040f04ea552SJeremy L Thompson and sets the CeedOperator as immutable. 1041f04ea552SJeremy L Thompson 1042d7b241e6Sjeremylt @param op CeedOperator to apply 10434cc79fe7SJed Brown @param[in] in CeedVector containing input state or @ref CEED_VECTOR_NONE if 104434138859Sjeremylt there are no active inputs 1045b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 10464cc79fe7SJed Brown distinct from @a in) or @ref CEED_VECTOR_NONE if there are no 104734138859Sjeremylt active outputs 1048d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 10494cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1050b11c1e72Sjeremylt 1051b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1052dfdf5a53Sjeremylt 10537a982d89SJeremy L. Thompson @ref User 1054b11c1e72Sjeremylt **/ 1055692c2638Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, 1056692c2638Sjeremylt CeedRequest *request) { 1057d7b241e6Sjeremylt int ierr; 1058e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1059d7b241e6Sjeremylt 1060d1d35e2fSjeremylt if (op->num_elem) { 1061250756a7Sjeremylt // Standard Operator 1062cae8b89aSjeremylt if (op->Apply) { 1063250756a7Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 1064cae8b89aSjeremylt } else { 1065cae8b89aSjeremylt // Zero all output vectors 1066250756a7Sjeremylt CeedQFunction qf = op->qf; 1067d1d35e2fSjeremylt for (CeedInt i=0; i<qf->num_output_fields; i++) { 1068d1d35e2fSjeremylt CeedVector vec = op->output_fields[i]->vec; 1069cae8b89aSjeremylt if (vec == CEED_VECTOR_ACTIVE) 1070cae8b89aSjeremylt vec = out; 1071cae8b89aSjeremylt if (vec != CEED_VECTOR_NONE) { 1072cae8b89aSjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1073cae8b89aSjeremylt } 1074cae8b89aSjeremylt } 1075250756a7Sjeremylt // Apply 1076250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1077250756a7Sjeremylt } 1078f04ea552SJeremy L Thompson } else if (op->is_composite) { 1079250756a7Sjeremylt // Composite Operator 1080250756a7Sjeremylt if (op->ApplyComposite) { 1081250756a7Sjeremylt ierr = op->ApplyComposite(op, in, out, request); CeedChk(ierr); 1082250756a7Sjeremylt } else { 1083d1d35e2fSjeremylt CeedInt num_suboperators; 1084d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1085d1d35e2fSjeremylt CeedOperator *sub_operators; 1086d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1087250756a7Sjeremylt 1088250756a7Sjeremylt // Zero all output vectors 1089250756a7Sjeremylt if (out != CEED_VECTOR_NONE) { 1090cae8b89aSjeremylt ierr = CeedVectorSetValue(out, 0.0); CeedChk(ierr); 1091cae8b89aSjeremylt } 1092d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1093d1d35e2fSjeremylt for (CeedInt j=0; j<sub_operators[i]->qf->num_output_fields; j++) { 1094d1d35e2fSjeremylt CeedVector vec = sub_operators[i]->output_fields[j]->vec; 1095250756a7Sjeremylt if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) { 1096250756a7Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1097250756a7Sjeremylt } 1098250756a7Sjeremylt } 1099250756a7Sjeremylt } 1100250756a7Sjeremylt // Apply 1101d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 1102d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(op->sub_operators[i], in, out, request); 1103cae8b89aSjeremylt CeedChk(ierr); 1104cae8b89aSjeremylt } 1105cae8b89aSjeremylt } 1106250756a7Sjeremylt } 1107e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1108cae8b89aSjeremylt } 1109cae8b89aSjeremylt 1110cae8b89aSjeremylt /** 1111cae8b89aSjeremylt @brief Apply CeedOperator to a vector and add result to output vector 1112cae8b89aSjeremylt 1113cae8b89aSjeremylt This computes the action of the operator on the specified (active) input, 1114cae8b89aSjeremylt yielding its (active) output. All inputs and outputs must be specified using 1115cae8b89aSjeremylt CeedOperatorSetField(). 1116cae8b89aSjeremylt 1117cae8b89aSjeremylt @param op CeedOperator to apply 1118cae8b89aSjeremylt @param[in] in CeedVector containing input state or NULL if there are no 1119cae8b89aSjeremylt active inputs 1120cae8b89aSjeremylt @param[out] out CeedVector to sum in result of applying operator (must be 1121cae8b89aSjeremylt distinct from @a in) or NULL if there are no active outputs 1122cae8b89aSjeremylt @param request Address of CeedRequest for non-blocking completion, else 11234cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1124cae8b89aSjeremylt 1125cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 1126cae8b89aSjeremylt 11277a982d89SJeremy L. Thompson @ref User 1128cae8b89aSjeremylt **/ 1129cae8b89aSjeremylt int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, 1130cae8b89aSjeremylt CeedRequest *request) { 1131cae8b89aSjeremylt int ierr; 1132e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1133cae8b89aSjeremylt 1134d1d35e2fSjeremylt if (op->num_elem) { 1135250756a7Sjeremylt // Standard Operator 1136250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1137f04ea552SJeremy L Thompson } else if (op->is_composite) { 1138250756a7Sjeremylt // Composite Operator 1139250756a7Sjeremylt if (op->ApplyAddComposite) { 1140250756a7Sjeremylt ierr = op->ApplyAddComposite(op, in, out, request); CeedChk(ierr); 1141cae8b89aSjeremylt } else { 1142d1d35e2fSjeremylt CeedInt num_suboperators; 1143d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1144d1d35e2fSjeremylt CeedOperator *sub_operators; 1145d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1146250756a7Sjeremylt 1147d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1148d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(sub_operators[i], in, out, request); 1149cae8b89aSjeremylt CeedChk(ierr); 11501d7d2407SJeremy L Thompson } 1151250756a7Sjeremylt } 1152250756a7Sjeremylt } 1153e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1154d7b241e6Sjeremylt } 1155d7b241e6Sjeremylt 1156d7b241e6Sjeremylt /** 1157b11c1e72Sjeremylt @brief Destroy a CeedOperator 1158d7b241e6Sjeremylt 1159d7b241e6Sjeremylt @param op CeedOperator to destroy 1160b11c1e72Sjeremylt 1161b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1162dfdf5a53Sjeremylt 11637a982d89SJeremy L. Thompson @ref User 1164b11c1e72Sjeremylt **/ 1165d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 1166d7b241e6Sjeremylt int ierr; 1167d7b241e6Sjeremylt 1168d1d35e2fSjeremylt if (!*op || --(*op)->ref_count > 0) return CEED_ERROR_SUCCESS; 1169d7b241e6Sjeremylt if ((*op)->Destroy) { 1170d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 1171d7b241e6Sjeremylt } 1172fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 1173fe2413ffSjeremylt // Free fields 1174d1d35e2fSjeremylt for (int i=0; i<(*op)->num_fields; i++) 1175d1d35e2fSjeremylt if ((*op)->input_fields[i]) { 1176d1d35e2fSjeremylt if ((*op)->input_fields[i]->elem_restr != CEED_ELEMRESTRICTION_NONE) { 1177d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->input_fields[i]->elem_restr); 117871352a93Sjeremylt CeedChk(ierr); 117915910d16Sjeremylt } 1180d1d35e2fSjeremylt if ((*op)->input_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1181d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->input_fields[i]->basis); CeedChk(ierr); 118271352a93Sjeremylt } 1183d1d35e2fSjeremylt if ((*op)->input_fields[i]->vec != CEED_VECTOR_ACTIVE && 1184d1d35e2fSjeremylt (*op)->input_fields[i]->vec != CEED_VECTOR_NONE ) { 1185d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->input_fields[i]->vec); CeedChk(ierr); 118671352a93Sjeremylt } 1187d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]->field_name); CeedChk(ierr); 1188d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]); CeedChk(ierr); 1189fe2413ffSjeremylt } 1190d1d35e2fSjeremylt for (int i=0; i<(*op)->num_fields; i++) 1191d1d35e2fSjeremylt if ((*op)->output_fields[i]) { 1192d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->output_fields[i]->elem_restr); 119371352a93Sjeremylt CeedChk(ierr); 1194d1d35e2fSjeremylt if ((*op)->output_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1195d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->output_fields[i]->basis); CeedChk(ierr); 119671352a93Sjeremylt } 1197d1d35e2fSjeremylt if ((*op)->output_fields[i]->vec != CEED_VECTOR_ACTIVE && 1198d1d35e2fSjeremylt (*op)->output_fields[i]->vec != CEED_VECTOR_NONE ) { 1199d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->output_fields[i]->vec); CeedChk(ierr); 120071352a93Sjeremylt } 1201d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]->field_name); CeedChk(ierr); 1202d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]); CeedChk(ierr); 1203fe2413ffSjeremylt } 1204d1d35e2fSjeremylt // Destroy sub_operators 1205d1d35e2fSjeremylt for (int i=0; i<(*op)->num_suboperators; i++) 1206d1d35e2fSjeremylt if ((*op)->sub_operators[i]) { 1207d1d35e2fSjeremylt ierr = CeedOperatorDestroy(&(*op)->sub_operators[i]); CeedChk(ierr); 120852d6035fSJeremy L Thompson } 1209d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 1210d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 1211d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 1212fe2413ffSjeremylt 12135107b09fSJeremy L Thompson // Destroy fallback 1214d1d35e2fSjeremylt if ((*op)->op_fallback) { 1215d1d35e2fSjeremylt ierr = (*op)->qf_fallback->Destroy((*op)->qf_fallback); CeedChk(ierr); 1216d1d35e2fSjeremylt ierr = CeedFree(&(*op)->qf_fallback); CeedChk(ierr); 121770a7ffb3SJeremy L Thompson ierr = CeedVectorDestroy(&(*op)->op_fallback->qf_assembled); CeedChk(ierr); 121870a7ffb3SJeremy L Thompson ierr = CeedElemRestrictionDestroy(&(*op)->op_fallback->qf_assembled_rstr); 121970a7ffb3SJeremy L Thompson CeedChk(ierr); 1220d1d35e2fSjeremylt ierr = (*op)->op_fallback->Destroy((*op)->op_fallback); CeedChk(ierr); 1221d1d35e2fSjeremylt ierr = CeedFree(&(*op)->op_fallback); CeedChk(ierr); 12225107b09fSJeremy L Thompson } 12235107b09fSJeremy L Thompson 122470a7ffb3SJeremy L Thompson // Destroy QF assembly cache 122570a7ffb3SJeremy L Thompson ierr = CeedVectorDestroy(&(*op)->qf_assembled); CeedChk(ierr); 122670a7ffb3SJeremy L Thompson ierr = CeedElemRestrictionDestroy(&(*op)->qf_assembled_rstr); CeedChk(ierr); 122770a7ffb3SJeremy L Thompson 1228d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields); CeedChk(ierr); 1229d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields); CeedChk(ierr); 1230d1d35e2fSjeremylt ierr = CeedFree(&(*op)->sub_operators); CeedChk(ierr); 1231d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 1232e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1233d7b241e6Sjeremylt } 1234d7b241e6Sjeremylt 1235d7b241e6Sjeremylt /// @} 1236