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 Check if a CeedOperator is ready to be used. 1377a982d89SJeremy L. Thompson 1387a982d89SJeremy L. Thompson @param[in] op CeedOperator to check 1397a982d89SJeremy L. Thompson 1407a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1417a982d89SJeremy L. Thompson 1427a982d89SJeremy L. Thompson @ref Developer 1437a982d89SJeremy L. Thompson **/ 144*eaf62fffSJeremy L Thompson int CeedOperatorCheckReady(CeedOperator op) { 145e2f04181SAndrew T. Barker int ierr; 146e2f04181SAndrew T. Barker Ceed ceed; 147e2f04181SAndrew T. Barker ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 148e2f04181SAndrew T. Barker 149d1d35e2fSjeremylt if (op->interface_setup) 150e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1517a982d89SJeremy L. Thompson 152e15f9bd0SJeremy L Thompson CeedQFunction qf = op->qf; 1537a982d89SJeremy L. Thompson if (op->composite) { 154d1d35e2fSjeremylt if (!op->num_suboperators) 1557a982d89SJeremy L. Thompson // LCOV_EXCL_START 156d1d35e2fSjeremylt return CeedError(ceed, CEED_ERROR_INCOMPLETE, "No sub_operators set"); 1577a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 1587a982d89SJeremy L. Thompson } else { 159d1d35e2fSjeremylt if (op->num_fields == 0) 1607a982d89SJeremy L. Thompson // LCOV_EXCL_START 161e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "No operator fields set"); 1627a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 163d1d35e2fSjeremylt if (op->num_fields < qf->num_input_fields + qf->num_output_fields) 1647a982d89SJeremy L. Thompson // LCOV_EXCL_START 165e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, "Not all operator fields set"); 1667a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 167d1d35e2fSjeremylt if (!op->has_restriction) 1687a982d89SJeremy L. Thompson // LCOV_EXCL_START 169e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, 170e15f9bd0SJeremy L Thompson "At least one restriction required"); 1717a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 172d1d35e2fSjeremylt if (op->num_qpts == 0) 1737a982d89SJeremy L. Thompson // LCOV_EXCL_START 174e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_INCOMPLETE, 175cd4dfc48Sjeremylt "At least one non-collocated basis is required " 176cd4dfc48Sjeremylt "or the number of quadrature points must be set"); 1777a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 1787a982d89SJeremy L. Thompson } 1797a982d89SJeremy L. Thompson 180e15f9bd0SJeremy L Thompson // Flag as immutable and ready 181d1d35e2fSjeremylt op->interface_setup = true; 182e15f9bd0SJeremy L Thompson if (op->qf && op->qf != CEED_QFUNCTION_NONE) 183e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 184d1d35e2fSjeremylt op->qf->operators_set++; 185e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 186e15f9bd0SJeremy L Thompson if (op->dqf && op->dqf != CEED_QFUNCTION_NONE) 187e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 188d1d35e2fSjeremylt op->dqf->operators_set++; 189e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 190e15f9bd0SJeremy L Thompson if (op->dqfT && op->dqfT != CEED_QFUNCTION_NONE) 191e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 192d1d35e2fSjeremylt op->dqfT->operators_set++; 193e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 194e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1957a982d89SJeremy L. Thompson } 1967a982d89SJeremy L. Thompson 1977a982d89SJeremy L. Thompson /** 1987a982d89SJeremy L. Thompson @brief View a field of a CeedOperator 1997a982d89SJeremy L. Thompson 2007a982d89SJeremy L. Thompson @param[in] field Operator field to view 201d1d35e2fSjeremylt @param[in] qf_field QFunction field (carries field name) 202d1d35e2fSjeremylt @param[in] field_number Number of field being viewed 2034c4400c7SValeria Barra @param[in] sub true indicates sub-operator, which increases indentation; false for top-level operator 204d1d35e2fSjeremylt @param[in] input true for an input field; false for output field 2057a982d89SJeremy L. Thompson @param[in] stream Stream to view to, e.g., stdout 2067a982d89SJeremy L. Thompson 2077a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2087a982d89SJeremy L. Thompson 2097a982d89SJeremy L. Thompson @ref Utility 2107a982d89SJeremy L. Thompson **/ 2117a982d89SJeremy L. Thompson static int CeedOperatorFieldView(CeedOperatorField field, 212d1d35e2fSjeremylt CeedQFunctionField qf_field, 213d1d35e2fSjeremylt CeedInt field_number, bool sub, bool input, 2147a982d89SJeremy L. Thompson FILE *stream) { 2157a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 216d1d35e2fSjeremylt const char *in_out = input ? "Input" : "Output"; 2177a982d89SJeremy L. Thompson 2187a982d89SJeremy L. Thompson fprintf(stream, "%s %s Field [%d]:\n" 2197a982d89SJeremy L. Thompson "%s Name: \"%s\"\n", 220d1d35e2fSjeremylt pre, in_out, field_number, pre, qf_field->field_name); 2217a982d89SJeremy L. Thompson 2227a982d89SJeremy L. Thompson if (field->basis == CEED_BASIS_COLLOCATED) 2237a982d89SJeremy L. Thompson fprintf(stream, "%s Collocated basis\n", pre); 2247a982d89SJeremy L. Thompson 2257a982d89SJeremy L. Thompson if (field->vec == CEED_VECTOR_ACTIVE) 2267a982d89SJeremy L. Thompson fprintf(stream, "%s Active vector\n", pre); 2277a982d89SJeremy L. Thompson else if (field->vec == CEED_VECTOR_NONE) 2287a982d89SJeremy L. Thompson fprintf(stream, "%s No vector\n", pre); 229e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2307a982d89SJeremy L. Thompson } 2317a982d89SJeremy L. Thompson 2327a982d89SJeremy L. Thompson /** 2337a982d89SJeremy L. Thompson @brief View a single CeedOperator 2347a982d89SJeremy L. Thompson 2357a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 2367a982d89SJeremy L. Thompson @param[in] sub Boolean flag for sub-operator 2377a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 2387a982d89SJeremy L. Thompson 2397a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 2407a982d89SJeremy L. Thompson 2417a982d89SJeremy L. Thompson @ref Utility 2427a982d89SJeremy L. Thompson **/ 2437a982d89SJeremy L. Thompson int CeedOperatorSingleView(CeedOperator op, bool sub, FILE *stream) { 2447a982d89SJeremy L. Thompson int ierr; 2457a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 2467a982d89SJeremy L. Thompson 24778464608Sjeremylt CeedInt total_fields = 0; 24878464608Sjeremylt ierr = CeedOperatorGetNumArgs(op, &total_fields); CeedChk(ierr); 2497a982d89SJeremy L. Thompson 25078464608Sjeremylt fprintf(stream, "%s %d Field%s\n", pre, total_fields, 25178464608Sjeremylt total_fields>1 ? "s" : ""); 2527a982d89SJeremy L. Thompson 253d1d35e2fSjeremylt fprintf(stream, "%s %d Input Field%s:\n", pre, op->qf->num_input_fields, 254d1d35e2fSjeremylt op->qf->num_input_fields>1 ? "s" : ""); 255d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_input_fields; i++) { 256d1d35e2fSjeremylt ierr = CeedOperatorFieldView(op->input_fields[i], op->qf->input_fields[i], 2577a982d89SJeremy L. Thompson i, sub, 1, stream); CeedChk(ierr); 2587a982d89SJeremy L. Thompson } 2597a982d89SJeremy L. Thompson 260d1d35e2fSjeremylt fprintf(stream, "%s %d Output Field%s:\n", pre, op->qf->num_output_fields, 261d1d35e2fSjeremylt op->qf->num_output_fields>1 ? "s" : ""); 262d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_output_fields; i++) { 263d1d35e2fSjeremylt ierr = CeedOperatorFieldView(op->output_fields[i], op->qf->output_fields[i], 2647a982d89SJeremy L. Thompson i, sub, 0, stream); CeedChk(ierr); 2657a982d89SJeremy L. Thompson } 266e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2677a982d89SJeremy L. Thompson } 2687a982d89SJeremy L. Thompson 269d99fa3c5SJeremy L Thompson /** 270*eaf62fffSJeremy L Thompson @brief Find the active vector basis for a CeedOperator 271*eaf62fffSJeremy L Thompson 272*eaf62fffSJeremy L Thompson @param[in] op CeedOperator to find active basis for 273*eaf62fffSJeremy L Thompson @param[out] active_basis Basis for active input vector 274*eaf62fffSJeremy L Thompson 275*eaf62fffSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 276*eaf62fffSJeremy L Thompson 277*eaf62fffSJeremy L Thompson @ ref Developer 278*eaf62fffSJeremy L Thompson **/ 279*eaf62fffSJeremy L Thompson int CeedOperatorGetActiveBasis(CeedOperator op, CeedBasis *active_basis) { 280*eaf62fffSJeremy L Thompson *active_basis = NULL; 281*eaf62fffSJeremy L Thompson for (int i = 0; i < op->qf->num_input_fields; i++) 282*eaf62fffSJeremy L Thompson if (op->input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 283*eaf62fffSJeremy L Thompson *active_basis = op->input_fields[i]->basis; 284*eaf62fffSJeremy L Thompson break; 285*eaf62fffSJeremy L Thompson } 286*eaf62fffSJeremy L Thompson 287*eaf62fffSJeremy L Thompson if (!*active_basis) { 288*eaf62fffSJeremy L Thompson // LCOV_EXCL_START 289*eaf62fffSJeremy L Thompson int ierr; 290*eaf62fffSJeremy L Thompson Ceed ceed; 291*eaf62fffSJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 292*eaf62fffSJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 293*eaf62fffSJeremy L Thompson "No active CeedBasis found"); 294*eaf62fffSJeremy L Thompson // LCOV_EXCL_STOP 295*eaf62fffSJeremy L Thompson } 296*eaf62fffSJeremy L Thompson return CEED_ERROR_SUCCESS; 297*eaf62fffSJeremy L Thompson } 298*eaf62fffSJeremy L Thompson 299*eaf62fffSJeremy L Thompson /** 300e2f04181SAndrew T. Barker @brief Find the active vector ElemRestriction for a CeedOperator 301e2f04181SAndrew T. Barker 302e2f04181SAndrew T. Barker @param[in] op CeedOperator to find active basis for 303d1d35e2fSjeremylt @param[out] active_rstr ElemRestriction for active input vector 304e2f04181SAndrew T. Barker 305e2f04181SAndrew T. Barker @return An error code: 0 - success, otherwise - failure 306e2f04181SAndrew T. Barker 307e2f04181SAndrew T. Barker @ref Utility 308e2f04181SAndrew T. Barker **/ 309*eaf62fffSJeremy L Thompson int CeedOperatorGetActiveElemRestriction(CeedOperator op, 310d1d35e2fSjeremylt CeedElemRestriction *active_rstr) { 311d1d35e2fSjeremylt *active_rstr = NULL; 312d1d35e2fSjeremylt for (int i = 0; i < op->qf->num_input_fields; i++) 313d1d35e2fSjeremylt if (op->input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 314d1d35e2fSjeremylt *active_rstr = op->input_fields[i]->elem_restr; 315e2f04181SAndrew T. Barker break; 316e2f04181SAndrew T. Barker } 317e2f04181SAndrew T. Barker 318d1d35e2fSjeremylt if (!*active_rstr) { 319e2f04181SAndrew T. Barker // LCOV_EXCL_START 320e2f04181SAndrew T. Barker int ierr; 321e2f04181SAndrew T. Barker Ceed ceed; 322e2f04181SAndrew T. Barker ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 323e2f04181SAndrew T. Barker return CeedError(ceed, CEED_ERROR_INCOMPLETE, 324*eaf62fffSJeremy L Thompson "No active CeedElemRestriction found"); 325e2f04181SAndrew T. Barker // LCOV_EXCL_STOP 326e2f04181SAndrew T. Barker } 327e2f04181SAndrew T. Barker return CEED_ERROR_SUCCESS; 328e2f04181SAndrew T. Barker } 329e2f04181SAndrew T. Barker 3307a982d89SJeremy L. Thompson /// @} 3317a982d89SJeremy L. Thompson 3327a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3337a982d89SJeremy L. Thompson /// CeedOperator Backend API 3347a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3357a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorBackend 3367a982d89SJeremy L. Thompson /// @{ 3377a982d89SJeremy L. Thompson 3387a982d89SJeremy L. Thompson /** 3397a982d89SJeremy L. Thompson @brief Get the Ceed associated with a CeedOperator 3407a982d89SJeremy L. Thompson 3417a982d89SJeremy L. Thompson @param op CeedOperator 3427a982d89SJeremy L. Thompson @param[out] ceed Variable to store Ceed 3437a982d89SJeremy L. Thompson 3447a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3457a982d89SJeremy L. Thompson 3467a982d89SJeremy L. Thompson @ref Backend 3477a982d89SJeremy L. Thompson **/ 3487a982d89SJeremy L. Thompson 3497a982d89SJeremy L. Thompson int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 3507a982d89SJeremy L. Thompson *ceed = op->ceed; 351e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3527a982d89SJeremy L. Thompson } 3537a982d89SJeremy L. Thompson 3547a982d89SJeremy L. Thompson /** 3557a982d89SJeremy L. Thompson @brief Get the number of elements associated with a CeedOperator 3567a982d89SJeremy L. Thompson 3577a982d89SJeremy L. Thompson @param op CeedOperator 358d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 3597a982d89SJeremy L. Thompson 3607a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3617a982d89SJeremy L. Thompson 3627a982d89SJeremy L. Thompson @ref Backend 3637a982d89SJeremy L. Thompson **/ 3647a982d89SJeremy L. Thompson 365d1d35e2fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *num_elem) { 3667a982d89SJeremy L. Thompson if (op->composite) 3677a982d89SJeremy L. Thompson // LCOV_EXCL_START 368e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 369e15f9bd0SJeremy L Thompson "Not defined for composite operator"); 3707a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 3717a982d89SJeremy L. Thompson 372d1d35e2fSjeremylt *num_elem = op->num_elem; 373e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3747a982d89SJeremy L. Thompson } 3757a982d89SJeremy L. Thompson 3767a982d89SJeremy L. Thompson /** 3777a982d89SJeremy L. Thompson @brief Get the number of quadrature points associated with a CeedOperator 3787a982d89SJeremy L. Thompson 3797a982d89SJeremy L. Thompson @param op CeedOperator 380d1d35e2fSjeremylt @param[out] num_qpts Variable to store vector number of quadrature points 3817a982d89SJeremy L. Thompson 3827a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3837a982d89SJeremy L. Thompson 3847a982d89SJeremy L. Thompson @ref Backend 3857a982d89SJeremy L. Thompson **/ 3867a982d89SJeremy L. Thompson 387d1d35e2fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *num_qpts) { 3887a982d89SJeremy L. Thompson if (op->composite) 3897a982d89SJeremy L. Thompson // LCOV_EXCL_START 390e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 391e15f9bd0SJeremy L Thompson "Not defined for composite operator"); 3927a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 3937a982d89SJeremy L. Thompson 394d1d35e2fSjeremylt *num_qpts = op->num_qpts; 395e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3967a982d89SJeremy L. Thompson } 3977a982d89SJeremy L. Thompson 3987a982d89SJeremy L. Thompson /** 3997a982d89SJeremy L. Thompson @brief Get the number of arguments associated with a CeedOperator 4007a982d89SJeremy L. Thompson 4017a982d89SJeremy L. Thompson @param op CeedOperator 402d1d35e2fSjeremylt @param[out] num_args Variable to store vector number of arguments 4037a982d89SJeremy L. Thompson 4047a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4057a982d89SJeremy L. Thompson 4067a982d89SJeremy L. Thompson @ref Backend 4077a982d89SJeremy L. Thompson **/ 4087a982d89SJeremy L. Thompson 409d1d35e2fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *num_args) { 4107a982d89SJeremy L. Thompson if (op->composite) 4117a982d89SJeremy L. Thompson // LCOV_EXCL_START 412e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 413e15f9bd0SJeremy L Thompson "Not defined for composite operators"); 4147a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4157a982d89SJeremy L. Thompson 416d1d35e2fSjeremylt *num_args = op->num_fields; 417e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4187a982d89SJeremy L. Thompson } 4197a982d89SJeremy L. Thompson 4207a982d89SJeremy L. Thompson /** 4217a982d89SJeremy L. Thompson @brief Get the setup status of a CeedOperator 4227a982d89SJeremy L. Thompson 4237a982d89SJeremy L. Thompson @param op CeedOperator 424d1d35e2fSjeremylt @param[out] is_setup_done Variable to store setup status 4257a982d89SJeremy L. Thompson 4267a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4277a982d89SJeremy L. Thompson 4287a982d89SJeremy L. Thompson @ref Backend 4297a982d89SJeremy L. Thompson **/ 4307a982d89SJeremy L. Thompson 431d1d35e2fSjeremylt int CeedOperatorIsSetupDone(CeedOperator op, bool *is_setup_done) { 432d1d35e2fSjeremylt *is_setup_done = op->backend_setup; 433e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4347a982d89SJeremy L. Thompson } 4357a982d89SJeremy L. Thompson 4367a982d89SJeremy L. Thompson /** 4377a982d89SJeremy L. Thompson @brief Get the QFunction associated with a CeedOperator 4387a982d89SJeremy L. Thompson 4397a982d89SJeremy L. Thompson @param op CeedOperator 4407a982d89SJeremy L. Thompson @param[out] qf Variable to store QFunction 4417a982d89SJeremy L. Thompson 4427a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4437a982d89SJeremy L. Thompson 4447a982d89SJeremy L. Thompson @ref Backend 4457a982d89SJeremy L. Thompson **/ 4467a982d89SJeremy L. Thompson 4477a982d89SJeremy L. Thompson int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 4487a982d89SJeremy L. Thompson if (op->composite) 4497a982d89SJeremy L. Thompson // LCOV_EXCL_START 450e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 451e15f9bd0SJeremy L Thompson "Not defined for composite operator"); 4527a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4537a982d89SJeremy L. Thompson 4547a982d89SJeremy L. Thompson *qf = op->qf; 455e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4567a982d89SJeremy L. Thompson } 4577a982d89SJeremy L. Thompson 4587a982d89SJeremy L. Thompson /** 459c04a41a7SJeremy L Thompson @brief Get a boolean value indicating if the CeedOperator is composite 460c04a41a7SJeremy L Thompson 461c04a41a7SJeremy L Thompson @param op CeedOperator 462d1d35e2fSjeremylt @param[out] is_composite Variable to store composite status 463c04a41a7SJeremy L Thompson 464c04a41a7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 465c04a41a7SJeremy L Thompson 466c04a41a7SJeremy L Thompson @ref Backend 467c04a41a7SJeremy L Thompson **/ 468c04a41a7SJeremy L Thompson 469d1d35e2fSjeremylt int CeedOperatorIsComposite(CeedOperator op, bool *is_composite) { 470d1d35e2fSjeremylt *is_composite = op->composite; 471e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 472c04a41a7SJeremy L Thompson } 473c04a41a7SJeremy L Thompson 474c04a41a7SJeremy L Thompson /** 475d1d35e2fSjeremylt @brief Get the number of sub_operators associated with a CeedOperator 4767a982d89SJeremy L. Thompson 4777a982d89SJeremy L. Thompson @param op CeedOperator 478d1d35e2fSjeremylt @param[out] num_suboperators Variable to store number of sub_operators 4797a982d89SJeremy L. Thompson 4807a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4817a982d89SJeremy L. Thompson 4827a982d89SJeremy L. Thompson @ref Backend 4837a982d89SJeremy L. Thompson **/ 4847a982d89SJeremy L. Thompson 485d1d35e2fSjeremylt int CeedOperatorGetNumSub(CeedOperator op, CeedInt *num_suboperators) { 4867a982d89SJeremy L. Thompson if (!op->composite) 4877a982d89SJeremy L. Thompson // LCOV_EXCL_START 488e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 4897a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4907a982d89SJeremy L. Thompson 491d1d35e2fSjeremylt *num_suboperators = op->num_suboperators; 492e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4937a982d89SJeremy L. Thompson } 4947a982d89SJeremy L. Thompson 4957a982d89SJeremy L. Thompson /** 496d1d35e2fSjeremylt @brief Get the list of sub_operators associated with a CeedOperator 4977a982d89SJeremy L. Thompson 4987a982d89SJeremy L. Thompson @param op CeedOperator 499d1d35e2fSjeremylt @param[out] sub_operators Variable to store list of sub_operators 5007a982d89SJeremy L. Thompson 5017a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5027a982d89SJeremy L. Thompson 5037a982d89SJeremy L. Thompson @ref Backend 5047a982d89SJeremy L. Thompson **/ 5057a982d89SJeremy L. Thompson 506d1d35e2fSjeremylt int CeedOperatorGetSubList(CeedOperator op, CeedOperator **sub_operators) { 5077a982d89SJeremy L. Thompson if (!op->composite) 5087a982d89SJeremy L. Thompson // LCOV_EXCL_START 509e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 5107a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 5117a982d89SJeremy L. Thompson 512d1d35e2fSjeremylt *sub_operators = op->sub_operators; 513e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5147a982d89SJeremy L. Thompson } 5157a982d89SJeremy L. Thompson 5167a982d89SJeremy L. Thompson /** 5177a982d89SJeremy L. Thompson @brief Get the backend data of a CeedOperator 5187a982d89SJeremy L. Thompson 5197a982d89SJeremy L. Thompson @param op CeedOperator 5207a982d89SJeremy L. Thompson @param[out] data Variable to store data 5217a982d89SJeremy L. Thompson 5227a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5237a982d89SJeremy L. Thompson 5247a982d89SJeremy L. Thompson @ref Backend 5257a982d89SJeremy L. Thompson **/ 5267a982d89SJeremy L. Thompson 527777ff853SJeremy L Thompson int CeedOperatorGetData(CeedOperator op, void *data) { 528777ff853SJeremy L Thompson *(void **)data = op->data; 529e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5307a982d89SJeremy L. Thompson } 5317a982d89SJeremy L. Thompson 5327a982d89SJeremy L. Thompson /** 5337a982d89SJeremy L. Thompson @brief Set the backend data of a CeedOperator 5347a982d89SJeremy L. Thompson 5357a982d89SJeremy L. Thompson @param[out] op CeedOperator 5367a982d89SJeremy L. Thompson @param data Data to set 5377a982d89SJeremy L. Thompson 5387a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5397a982d89SJeremy L. Thompson 5407a982d89SJeremy L. Thompson @ref Backend 5417a982d89SJeremy L. Thompson **/ 5427a982d89SJeremy L. Thompson 543777ff853SJeremy L Thompson int CeedOperatorSetData(CeedOperator op, void *data) { 544777ff853SJeremy L Thompson op->data = data; 545e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5467a982d89SJeremy L. Thompson } 5477a982d89SJeremy L. Thompson 5487a982d89SJeremy L. Thompson /** 54934359f16Sjeremylt @brief Increment the reference counter for a CeedOperator 55034359f16Sjeremylt 55134359f16Sjeremylt @param op CeedOperator to increment the reference counter 55234359f16Sjeremylt 55334359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 55434359f16Sjeremylt 55534359f16Sjeremylt @ref Backend 55634359f16Sjeremylt **/ 5579560d06aSjeremylt int CeedOperatorReference(CeedOperator op) { 55834359f16Sjeremylt op->ref_count++; 55934359f16Sjeremylt return CEED_ERROR_SUCCESS; 56034359f16Sjeremylt } 56134359f16Sjeremylt 56234359f16Sjeremylt /** 5637a982d89SJeremy L. Thompson @brief Set the setup flag of a CeedOperator to True 5647a982d89SJeremy L. Thompson 5657a982d89SJeremy L. Thompson @param op CeedOperator 5667a982d89SJeremy L. Thompson 5677a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5687a982d89SJeremy L. Thompson 5697a982d89SJeremy L. Thompson @ref Backend 5707a982d89SJeremy L. Thompson **/ 5717a982d89SJeremy L. Thompson 5727a982d89SJeremy L. Thompson int CeedOperatorSetSetupDone(CeedOperator op) { 573d1d35e2fSjeremylt op->backend_setup = true; 574e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5757a982d89SJeremy L. Thompson } 5767a982d89SJeremy L. Thompson 5777a982d89SJeremy L. Thompson /** 5787a982d89SJeremy L. Thompson @brief Get the CeedOperatorFields of a CeedOperator 5797a982d89SJeremy L. Thompson 5807a982d89SJeremy L. Thompson @param op CeedOperator 581d1d35e2fSjeremylt @param[out] input_fields Variable to store input_fields 582d1d35e2fSjeremylt @param[out] output_fields Variable to store output_fields 5837a982d89SJeremy L. Thompson 5847a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5857a982d89SJeremy L. Thompson 5867a982d89SJeremy L. Thompson @ref Backend 5877a982d89SJeremy L. Thompson **/ 5887a982d89SJeremy L. Thompson 589d1d35e2fSjeremylt int CeedOperatorGetFields(CeedOperator op, CeedOperatorField **input_fields, 590d1d35e2fSjeremylt CeedOperatorField **output_fields) { 5917a982d89SJeremy L. Thompson if (op->composite) 5927a982d89SJeremy L. Thompson // LCOV_EXCL_START 593e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 594e15f9bd0SJeremy L Thompson "Not defined for composite operator"); 5957a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 5967a982d89SJeremy L. Thompson 597d1d35e2fSjeremylt if (input_fields) *input_fields = op->input_fields; 598d1d35e2fSjeremylt if (output_fields) *output_fields = op->output_fields; 599e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6007a982d89SJeremy L. Thompson } 6017a982d89SJeremy L. Thompson 6027a982d89SJeremy L. Thompson /** 6037a982d89SJeremy L. Thompson @brief Get the CeedElemRestriction of a CeedOperatorField 6047a982d89SJeremy L. Thompson 605d1d35e2fSjeremylt @param op_field CeedOperatorField 6067a982d89SJeremy L. Thompson @param[out] rstr Variable to store CeedElemRestriction 6077a982d89SJeremy L. Thompson 6087a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6097a982d89SJeremy L. Thompson 6107a982d89SJeremy L. Thompson @ref Backend 6117a982d89SJeremy L. Thompson **/ 6127a982d89SJeremy L. Thompson 613d1d35e2fSjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField op_field, 6147a982d89SJeremy L. Thompson CeedElemRestriction *rstr) { 615d1d35e2fSjeremylt *rstr = op_field->elem_restr; 616e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6177a982d89SJeremy L. Thompson } 6187a982d89SJeremy L. Thompson 6197a982d89SJeremy L. Thompson /** 6207a982d89SJeremy L. Thompson @brief Get the CeedBasis of a CeedOperatorField 6217a982d89SJeremy L. Thompson 622d1d35e2fSjeremylt @param op_field CeedOperatorField 6237a982d89SJeremy L. Thompson @param[out] basis Variable to store CeedBasis 6247a982d89SJeremy L. Thompson 6257a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6267a982d89SJeremy L. Thompson 6277a982d89SJeremy L. Thompson @ref Backend 6287a982d89SJeremy L. Thompson **/ 6297a982d89SJeremy L. Thompson 630d1d35e2fSjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField op_field, CeedBasis *basis) { 631d1d35e2fSjeremylt *basis = op_field->basis; 632e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6337a982d89SJeremy L. Thompson } 6347a982d89SJeremy L. Thompson 6357a982d89SJeremy L. Thompson /** 6367a982d89SJeremy L. Thompson @brief Get the CeedVector of a CeedOperatorField 6377a982d89SJeremy L. Thompson 638d1d35e2fSjeremylt @param op_field CeedOperatorField 6397a982d89SJeremy L. Thompson @param[out] vec Variable to store CeedVector 6407a982d89SJeremy L. Thompson 6417a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6427a982d89SJeremy L. Thompson 6437a982d89SJeremy L. Thompson @ref Backend 6447a982d89SJeremy L. Thompson **/ 6457a982d89SJeremy L. Thompson 646d1d35e2fSjeremylt int CeedOperatorFieldGetVector(CeedOperatorField op_field, CeedVector *vec) { 647d1d35e2fSjeremylt *vec = op_field->vec; 648e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6497a982d89SJeremy L. Thompson } 6507a982d89SJeremy L. Thompson 6517a982d89SJeremy L. Thompson /// @} 6527a982d89SJeremy L. Thompson 6537a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 6547a982d89SJeremy L. Thompson /// CeedOperator Public API 6557a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 6567a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorUser 657dfdf5a53Sjeremylt /// @{ 658d7b241e6Sjeremylt 659d7b241e6Sjeremylt /** 6600219ea01SJeremy L Thompson @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and 6610219ea01SJeremy L Thompson CeedElemRestriction can be associated with CeedQFunction fields with 6620219ea01SJeremy L Thompson \ref CeedOperatorSetField. 663d7b241e6Sjeremylt 664b11c1e72Sjeremylt @param ceed A Ceed object where the CeedOperator will be created 665d7b241e6Sjeremylt @param qf QFunction defining the action of the operator at quadrature points 66634138859Sjeremylt @param dqf QFunction defining the action of the Jacobian of @a qf (or 6674cc79fe7SJed Brown @ref CEED_QFUNCTION_NONE) 668d7b241e6Sjeremylt @param dqfT QFunction defining the action of the transpose of the Jacobian 6694cc79fe7SJed Brown of @a qf (or @ref CEED_QFUNCTION_NONE) 670b11c1e72Sjeremylt @param[out] op Address of the variable where the newly created 671b11c1e72Sjeremylt CeedOperator will be stored 672b11c1e72Sjeremylt 673b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 674dfdf5a53Sjeremylt 6757a982d89SJeremy L. Thompson @ref User 676d7b241e6Sjeremylt */ 677d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, 678d7b241e6Sjeremylt CeedQFunction dqfT, CeedOperator *op) { 679d7b241e6Sjeremylt int ierr; 680d7b241e6Sjeremylt 6815fe0d4faSjeremylt if (!ceed->OperatorCreate) { 6825fe0d4faSjeremylt Ceed delegate; 683aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 6845fe0d4faSjeremylt 6855fe0d4faSjeremylt if (!delegate) 686c042f62fSJeremy L Thompson // LCOV_EXCL_START 687e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 688e15f9bd0SJeremy L Thompson "Backend does not support OperatorCreate"); 689c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 6905fe0d4faSjeremylt 6915fe0d4faSjeremylt ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr); 692e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6935fe0d4faSjeremylt } 6945fe0d4faSjeremylt 695b3b7035fSJeremy L Thompson if (!qf || qf == CEED_QFUNCTION_NONE) 696b3b7035fSJeremy L Thompson // LCOV_EXCL_START 697e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 698e15f9bd0SJeremy L Thompson "Operator must have a valid QFunction."); 699b3b7035fSJeremy L Thompson // LCOV_EXCL_STOP 700d7b241e6Sjeremylt ierr = CeedCalloc(1, op); CeedChk(ierr); 701d7b241e6Sjeremylt (*op)->ceed = ceed; 7029560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 703d1d35e2fSjeremylt (*op)->ref_count = 1; 704d7b241e6Sjeremylt (*op)->qf = qf; 7059560d06aSjeremylt ierr = CeedQFunctionReference(qf); CeedChk(ierr); 706442e7f0bSjeremylt if (dqf && dqf != CEED_QFUNCTION_NONE) { 707d7b241e6Sjeremylt (*op)->dqf = dqf; 7089560d06aSjeremylt ierr = CeedQFunctionReference(dqf); CeedChk(ierr); 709442e7f0bSjeremylt } 710442e7f0bSjeremylt if (dqfT && dqfT != CEED_QFUNCTION_NONE) { 711d7b241e6Sjeremylt (*op)->dqfT = dqfT; 7129560d06aSjeremylt ierr = CeedQFunctionReference(dqfT); CeedChk(ierr); 713442e7f0bSjeremylt } 714d1d35e2fSjeremylt ierr = CeedCalloc(16, &(*op)->input_fields); CeedChk(ierr); 715d1d35e2fSjeremylt ierr = CeedCalloc(16, &(*op)->output_fields); CeedChk(ierr); 716d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 717e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 718d7b241e6Sjeremylt } 719d7b241e6Sjeremylt 720d7b241e6Sjeremylt /** 72152d6035fSJeremy L Thompson @brief Create an operator that composes the action of several operators 72252d6035fSJeremy L Thompson 72352d6035fSJeremy L Thompson @param ceed A Ceed object where the CeedOperator will be created 72452d6035fSJeremy L Thompson @param[out] op Address of the variable where the newly created 72552d6035fSJeremy L Thompson Composite CeedOperator will be stored 72652d6035fSJeremy L Thompson 72752d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 72852d6035fSJeremy L Thompson 7297a982d89SJeremy L. Thompson @ref User 73052d6035fSJeremy L Thompson */ 73152d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) { 73252d6035fSJeremy L Thompson int ierr; 73352d6035fSJeremy L Thompson 73452d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 73552d6035fSJeremy L Thompson Ceed delegate; 736aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 73752d6035fSJeremy L Thompson 738250756a7Sjeremylt if (delegate) { 73952d6035fSJeremy L Thompson ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr); 740e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 74152d6035fSJeremy L Thompson } 742250756a7Sjeremylt } 74352d6035fSJeremy L Thompson 74452d6035fSJeremy L Thompson ierr = CeedCalloc(1, op); CeedChk(ierr); 74552d6035fSJeremy L Thompson (*op)->ceed = ceed; 7469560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 74752d6035fSJeremy L Thompson (*op)->composite = true; 748d1d35e2fSjeremylt ierr = CeedCalloc(16, &(*op)->sub_operators); CeedChk(ierr); 749250756a7Sjeremylt 750250756a7Sjeremylt if (ceed->CompositeOperatorCreate) { 75152d6035fSJeremy L Thompson ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr); 752250756a7Sjeremylt } 753e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 75452d6035fSJeremy L Thompson } 75552d6035fSJeremy L Thompson 75652d6035fSJeremy L Thompson /** 7579560d06aSjeremylt @brief Copy the pointer to a CeedOperator. Both pointers should 7589560d06aSjeremylt be destroyed with `CeedOperatorDestroy()`; 7599560d06aSjeremylt Note: If `*op_copy` is non-NULL, then it is assumed that 7609560d06aSjeremylt `*op_copy` is a pointer to a CeedOperator. This 7619560d06aSjeremylt CeedOperator will be destroyed if `*op_copy` is the only 7629560d06aSjeremylt reference to this CeedOperator. 7639560d06aSjeremylt 7649560d06aSjeremylt @param op CeedOperator to copy reference to 7659560d06aSjeremylt @param[out] op_copy Variable to store copied reference 7669560d06aSjeremylt 7679560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 7689560d06aSjeremylt 7699560d06aSjeremylt @ref User 7709560d06aSjeremylt **/ 7719560d06aSjeremylt int CeedOperatorReferenceCopy(CeedOperator op, CeedOperator *op_copy) { 7729560d06aSjeremylt int ierr; 7739560d06aSjeremylt 7749560d06aSjeremylt ierr = CeedOperatorReference(op); CeedChk(ierr); 7759560d06aSjeremylt ierr = CeedOperatorDestroy(op_copy); CeedChk(ierr); 7769560d06aSjeremylt *op_copy = op; 7779560d06aSjeremylt return CEED_ERROR_SUCCESS; 7789560d06aSjeremylt } 7799560d06aSjeremylt 7809560d06aSjeremylt /** 781b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 782d7b241e6Sjeremylt 783d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 784d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 785d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 786d7b241e6Sjeremylt 787d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 788d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 789d7b241e6Sjeremylt input and at most one active output. 790d7b241e6Sjeremylt 7918c91a0c9SJeremy L Thompson @param op CeedOperator on which to provide the field 792d1d35e2fSjeremylt @param field_name Name of the field (to be matched with the name used by 7938795c945Sjeremylt CeedQFunction) 794b11c1e72Sjeremylt @param r CeedElemRestriction 7954cc79fe7SJed Brown @param b CeedBasis in which the field resides or @ref CEED_BASIS_COLLOCATED 796b11c1e72Sjeremylt if collocated with quadrature points 7974cc79fe7SJed Brown @param v CeedVector to be used by CeedOperator or @ref CEED_VECTOR_ACTIVE 7984cc79fe7SJed Brown if field is active or @ref CEED_VECTOR_NONE if using 7994cc79fe7SJed Brown @ref CEED_EVAL_WEIGHT in the QFunction 800b11c1e72Sjeremylt 801b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 802dfdf5a53Sjeremylt 8037a982d89SJeremy L. Thompson @ref User 804b11c1e72Sjeremylt **/ 805d1d35e2fSjeremylt int CeedOperatorSetField(CeedOperator op, const char *field_name, 806a8d32208Sjeremylt CeedElemRestriction r, CeedBasis b, CeedVector v) { 807d7b241e6Sjeremylt int ierr; 80852d6035fSJeremy L Thompson if (op->composite) 809c042f62fSJeremy L Thompson // LCOV_EXCL_START 810e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 811e15f9bd0SJeremy L Thompson "Cannot add field to composite operator."); 812c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 8138b067b84SJed Brown if (!r) 814c042f62fSJeremy L Thompson // LCOV_EXCL_START 815e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 816c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 817d1d35e2fSjeremylt field_name); 818c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 8198b067b84SJed Brown if (!b) 820c042f62fSJeremy L Thompson // LCOV_EXCL_START 821e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 822e15f9bd0SJeremy L Thompson "Basis b for field \"%s\" must be non-NULL.", 823d1d35e2fSjeremylt field_name); 824c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 8258b067b84SJed Brown if (!v) 826c042f62fSJeremy L Thompson // LCOV_EXCL_START 827e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 828e15f9bd0SJeremy L Thompson "Vector v for field \"%s\" must be non-NULL.", 829d1d35e2fSjeremylt field_name); 830c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 83152d6035fSJeremy L Thompson 832d1d35e2fSjeremylt CeedInt num_elem; 833d1d35e2fSjeremylt ierr = CeedElemRestrictionGetNumElements(r, &num_elem); CeedChk(ierr); 834d1d35e2fSjeremylt if (r != CEED_ELEMRESTRICTION_NONE && op->has_restriction && 835d1d35e2fSjeremylt op->num_elem != num_elem) 836c042f62fSJeremy L Thompson // LCOV_EXCL_START 837e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 8381d102b48SJeremy L Thompson "ElemRestriction with %d elements incompatible with prior " 839d1d35e2fSjeremylt "%d elements", num_elem, op->num_elem); 840c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 841d7b241e6Sjeremylt 84278464608Sjeremylt CeedInt num_qpts = 0; 843e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 844d1d35e2fSjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &num_qpts); CeedChk(ierr); 845d1d35e2fSjeremylt if (op->num_qpts && op->num_qpts != num_qpts) 846c042f62fSJeremy L Thompson // LCOV_EXCL_START 847e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 848e15f9bd0SJeremy L Thompson "Basis with %d quadrature points " 849d1d35e2fSjeremylt "incompatible with prior %d points", num_qpts, 850d1d35e2fSjeremylt op->num_qpts); 851c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 852d7b241e6Sjeremylt } 853d1d35e2fSjeremylt CeedQFunctionField qf_field; 854d1d35e2fSjeremylt CeedOperatorField *op_field; 855d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_input_fields; i++) { 856d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->input_fields[i]).field_name)) { 857d1d35e2fSjeremylt qf_field = op->qf->input_fields[i]; 858d1d35e2fSjeremylt op_field = &op->input_fields[i]; 859d7b241e6Sjeremylt goto found; 860d7b241e6Sjeremylt } 861d7b241e6Sjeremylt } 862d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_output_fields; i++) { 863d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->output_fields[i]).field_name)) { 864d1d35e2fSjeremylt qf_field = op->qf->output_fields[i]; 865d1d35e2fSjeremylt op_field = &op->output_fields[i]; 866d7b241e6Sjeremylt goto found; 867d7b241e6Sjeremylt } 868d7b241e6Sjeremylt } 869c042f62fSJeremy L Thompson // LCOV_EXCL_START 870e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPLETE, 871e15f9bd0SJeremy L Thompson "QFunction has no knowledge of field '%s'", 872d1d35e2fSjeremylt field_name); 873c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 874d7b241e6Sjeremylt found: 875d1d35e2fSjeremylt ierr = CeedOperatorCheckField(op->ceed, qf_field, r, b); CeedChk(ierr); 876d1d35e2fSjeremylt ierr = CeedCalloc(1, op_field); CeedChk(ierr); 877e15f9bd0SJeremy L Thompson 878d1d35e2fSjeremylt (*op_field)->vec = v; 879e15f9bd0SJeremy L Thompson if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) { 8809560d06aSjeremylt ierr = CeedVectorReference(v); CeedChk(ierr); 881e15f9bd0SJeremy L Thompson } 882e15f9bd0SJeremy L Thompson 883d1d35e2fSjeremylt (*op_field)->elem_restr = r; 8849560d06aSjeremylt ierr = CeedElemRestrictionReference(r); CeedChk(ierr); 885e15f9bd0SJeremy L Thompson if (r != CEED_ELEMRESTRICTION_NONE) { 886d1d35e2fSjeremylt op->num_elem = num_elem; 887d1d35e2fSjeremylt op->has_restriction = true; // Restriction set, but num_elem may be 0 888e15f9bd0SJeremy L Thompson } 889d99fa3c5SJeremy L Thompson 890d1d35e2fSjeremylt (*op_field)->basis = b; 891e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 892cd4dfc48Sjeremylt if (!op->num_qpts) { 893cd4dfc48Sjeremylt ierr = CeedOperatorSetNumQuadraturePoints(op, num_qpts); CeedChk(ierr); 894cd4dfc48Sjeremylt } 8959560d06aSjeremylt ierr = CeedBasisReference(b); CeedChk(ierr); 896e15f9bd0SJeremy L Thompson } 897e15f9bd0SJeremy L Thompson 898d1d35e2fSjeremylt op->num_fields += 1; 899d1d35e2fSjeremylt size_t len = strlen(field_name); 900d99fa3c5SJeremy L Thompson char *tmp; 901d99fa3c5SJeremy L Thompson ierr = CeedCalloc(len+1, &tmp); CeedChk(ierr); 902d1d35e2fSjeremylt memcpy(tmp, field_name, len+1); 903d1d35e2fSjeremylt (*op_field)->field_name = tmp; 904e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 905d7b241e6Sjeremylt } 906d7b241e6Sjeremylt 907d7b241e6Sjeremylt /** 90852d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 909288c0443SJeremy L Thompson 910d1d35e2fSjeremylt @param[out] composite_op Composite CeedOperator 911d1d35e2fSjeremylt @param sub_op Sub-operator CeedOperator 91252d6035fSJeremy L Thompson 91352d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 91452d6035fSJeremy L Thompson 9157a982d89SJeremy L. Thompson @ref User 91652d6035fSJeremy L Thompson */ 917d1d35e2fSjeremylt int CeedCompositeOperatorAddSub(CeedOperator composite_op, 918d1d35e2fSjeremylt CeedOperator sub_op) { 91934359f16Sjeremylt int ierr; 92034359f16Sjeremylt 921d1d35e2fSjeremylt if (!composite_op->composite) 922c042f62fSJeremy L Thompson // LCOV_EXCL_START 923d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_MINOR, 924e2f04181SAndrew T. Barker "CeedOperator is not a composite operator"); 925c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 92652d6035fSJeremy L Thompson 927d1d35e2fSjeremylt if (composite_op->num_suboperators == CEED_COMPOSITE_MAX) 928c042f62fSJeremy L Thompson // LCOV_EXCL_START 929d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_UNSUPPORTED, 930d1d35e2fSjeremylt "Cannot add additional sub_operators"); 931c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 93252d6035fSJeremy L Thompson 933d1d35e2fSjeremylt composite_op->sub_operators[composite_op->num_suboperators] = sub_op; 9349560d06aSjeremylt ierr = CeedOperatorReference(sub_op); CeedChk(ierr); 935d1d35e2fSjeremylt composite_op->num_suboperators++; 936e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 93752d6035fSJeremy L Thompson } 93852d6035fSJeremy L Thompson 93952d6035fSJeremy L Thompson /** 940cd4dfc48Sjeremylt @brief Set the number of quadrature points associated with a CeedOperator. 941cd4dfc48Sjeremylt This should be used when creating a CeedOperator where every 942cd4dfc48Sjeremylt field has a collocated basis. This function cannot be used for 943cd4dfc48Sjeremylt composite CeedOperators. 944cd4dfc48Sjeremylt 945cd4dfc48Sjeremylt @param op CeedOperator 946cd4dfc48Sjeremylt @param num_qpts Number of quadrature points to set 947cd4dfc48Sjeremylt 948cd4dfc48Sjeremylt @return An error code: 0 - success, otherwise - failure 949cd4dfc48Sjeremylt 950cd4dfc48Sjeremylt @ref Backend 951cd4dfc48Sjeremylt **/ 952cd4dfc48Sjeremylt 953cd4dfc48Sjeremylt int CeedOperatorSetNumQuadraturePoints(CeedOperator op, CeedInt num_qpts) { 954cd4dfc48Sjeremylt if (op->composite) 955cd4dfc48Sjeremylt // LCOV_EXCL_START 956cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 957cd4dfc48Sjeremylt "Not defined for composite operator"); 958cd4dfc48Sjeremylt // LCOV_EXCL_STOP 959cd4dfc48Sjeremylt if (op->num_qpts) 960cd4dfc48Sjeremylt // LCOV_EXCL_START 961cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 962cd4dfc48Sjeremylt "Number of quadrature points already defined"); 963cd4dfc48Sjeremylt // LCOV_EXCL_STOP 964cd4dfc48Sjeremylt 965cd4dfc48Sjeremylt op->num_qpts = num_qpts; 966cd4dfc48Sjeremylt return CEED_ERROR_SUCCESS; 967cd4dfc48Sjeremylt } 968cd4dfc48Sjeremylt 969cd4dfc48Sjeremylt /** 9707a982d89SJeremy L. Thompson @brief View a CeedOperator 9717a982d89SJeremy L. Thompson 9727a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 9737a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 9747a982d89SJeremy L. Thompson 9757a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 9767a982d89SJeremy L. Thompson 9777a982d89SJeremy L. Thompson @ref User 9787a982d89SJeremy L. Thompson **/ 9797a982d89SJeremy L. Thompson int CeedOperatorView(CeedOperator op, FILE *stream) { 9807a982d89SJeremy L. Thompson int ierr; 9817a982d89SJeremy L. Thompson 9827a982d89SJeremy L. Thompson if (op->composite) { 9837a982d89SJeremy L. Thompson fprintf(stream, "Composite CeedOperator\n"); 9847a982d89SJeremy L. Thompson 985d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 9867a982d89SJeremy L. Thompson fprintf(stream, " SubOperator [%d]:\n", i); 987d1d35e2fSjeremylt ierr = CeedOperatorSingleView(op->sub_operators[i], 1, stream); 9887a982d89SJeremy L. Thompson CeedChk(ierr); 9897a982d89SJeremy L. Thompson } 9907a982d89SJeremy L. Thompson } else { 9917a982d89SJeremy L. Thompson fprintf(stream, "CeedOperator\n"); 9927a982d89SJeremy L. Thompson ierr = CeedOperatorSingleView(op, 0, stream); CeedChk(ierr); 9937a982d89SJeremy L. Thompson } 994e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9957a982d89SJeremy L. Thompson } 9963bd813ffSjeremylt 9973bd813ffSjeremylt /** 9983bd813ffSjeremylt @brief Apply CeedOperator to a vector 999d7b241e6Sjeremylt 1000d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 1001d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 1002d7b241e6Sjeremylt CeedOperatorSetField(). 1003d7b241e6Sjeremylt 1004d7b241e6Sjeremylt @param op CeedOperator to apply 10054cc79fe7SJed Brown @param[in] in CeedVector containing input state or @ref CEED_VECTOR_NONE if 100634138859Sjeremylt there are no active inputs 1007b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 10084cc79fe7SJed Brown distinct from @a in) or @ref CEED_VECTOR_NONE if there are no 100934138859Sjeremylt active outputs 1010d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 10114cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1012b11c1e72Sjeremylt 1013b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1014dfdf5a53Sjeremylt 10157a982d89SJeremy L. Thompson @ref User 1016b11c1e72Sjeremylt **/ 1017692c2638Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, 1018692c2638Sjeremylt CeedRequest *request) { 1019d7b241e6Sjeremylt int ierr; 1020e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1021d7b241e6Sjeremylt 1022d1d35e2fSjeremylt if (op->num_elem) { 1023250756a7Sjeremylt // Standard Operator 1024cae8b89aSjeremylt if (op->Apply) { 1025250756a7Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 1026cae8b89aSjeremylt } else { 1027cae8b89aSjeremylt // Zero all output vectors 1028250756a7Sjeremylt CeedQFunction qf = op->qf; 1029d1d35e2fSjeremylt for (CeedInt i=0; i<qf->num_output_fields; i++) { 1030d1d35e2fSjeremylt CeedVector vec = op->output_fields[i]->vec; 1031cae8b89aSjeremylt if (vec == CEED_VECTOR_ACTIVE) 1032cae8b89aSjeremylt vec = out; 1033cae8b89aSjeremylt if (vec != CEED_VECTOR_NONE) { 1034cae8b89aSjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1035cae8b89aSjeremylt } 1036cae8b89aSjeremylt } 1037250756a7Sjeremylt // Apply 1038250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1039250756a7Sjeremylt } 1040250756a7Sjeremylt } else if (op->composite) { 1041250756a7Sjeremylt // Composite Operator 1042250756a7Sjeremylt if (op->ApplyComposite) { 1043250756a7Sjeremylt ierr = op->ApplyComposite(op, in, out, request); CeedChk(ierr); 1044250756a7Sjeremylt } else { 1045d1d35e2fSjeremylt CeedInt num_suboperators; 1046d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1047d1d35e2fSjeremylt CeedOperator *sub_operators; 1048d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1049250756a7Sjeremylt 1050250756a7Sjeremylt // Zero all output vectors 1051250756a7Sjeremylt if (out != CEED_VECTOR_NONE) { 1052cae8b89aSjeremylt ierr = CeedVectorSetValue(out, 0.0); CeedChk(ierr); 1053cae8b89aSjeremylt } 1054d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1055d1d35e2fSjeremylt for (CeedInt j=0; j<sub_operators[i]->qf->num_output_fields; j++) { 1056d1d35e2fSjeremylt CeedVector vec = sub_operators[i]->output_fields[j]->vec; 1057250756a7Sjeremylt if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) { 1058250756a7Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1059250756a7Sjeremylt } 1060250756a7Sjeremylt } 1061250756a7Sjeremylt } 1062250756a7Sjeremylt // Apply 1063d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 1064d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(op->sub_operators[i], in, out, request); 1065cae8b89aSjeremylt CeedChk(ierr); 1066cae8b89aSjeremylt } 1067cae8b89aSjeremylt } 1068250756a7Sjeremylt } 1069e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1070cae8b89aSjeremylt } 1071cae8b89aSjeremylt 1072cae8b89aSjeremylt /** 1073cae8b89aSjeremylt @brief Apply CeedOperator to a vector and add result to output vector 1074cae8b89aSjeremylt 1075cae8b89aSjeremylt This computes the action of the operator on the specified (active) input, 1076cae8b89aSjeremylt yielding its (active) output. All inputs and outputs must be specified using 1077cae8b89aSjeremylt CeedOperatorSetField(). 1078cae8b89aSjeremylt 1079cae8b89aSjeremylt @param op CeedOperator to apply 1080cae8b89aSjeremylt @param[in] in CeedVector containing input state or NULL if there are no 1081cae8b89aSjeremylt active inputs 1082cae8b89aSjeremylt @param[out] out CeedVector to sum in result of applying operator (must be 1083cae8b89aSjeremylt distinct from @a in) or NULL if there are no active outputs 1084cae8b89aSjeremylt @param request Address of CeedRequest for non-blocking completion, else 10854cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1086cae8b89aSjeremylt 1087cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 1088cae8b89aSjeremylt 10897a982d89SJeremy L. Thompson @ref User 1090cae8b89aSjeremylt **/ 1091cae8b89aSjeremylt int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, 1092cae8b89aSjeremylt CeedRequest *request) { 1093cae8b89aSjeremylt int ierr; 1094e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1095cae8b89aSjeremylt 1096d1d35e2fSjeremylt if (op->num_elem) { 1097250756a7Sjeremylt // Standard Operator 1098250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1099250756a7Sjeremylt } else if (op->composite) { 1100250756a7Sjeremylt // Composite Operator 1101250756a7Sjeremylt if (op->ApplyAddComposite) { 1102250756a7Sjeremylt ierr = op->ApplyAddComposite(op, in, out, request); CeedChk(ierr); 1103cae8b89aSjeremylt } else { 1104d1d35e2fSjeremylt CeedInt num_suboperators; 1105d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1106d1d35e2fSjeremylt CeedOperator *sub_operators; 1107d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1108250756a7Sjeremylt 1109d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1110d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(sub_operators[i], in, out, request); 1111cae8b89aSjeremylt CeedChk(ierr); 11121d7d2407SJeremy L Thompson } 1113250756a7Sjeremylt } 1114250756a7Sjeremylt } 1115e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1116d7b241e6Sjeremylt } 1117d7b241e6Sjeremylt 1118d7b241e6Sjeremylt /** 1119b11c1e72Sjeremylt @brief Destroy a CeedOperator 1120d7b241e6Sjeremylt 1121d7b241e6Sjeremylt @param op CeedOperator to destroy 1122b11c1e72Sjeremylt 1123b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1124dfdf5a53Sjeremylt 11257a982d89SJeremy L. Thompson @ref User 1126b11c1e72Sjeremylt **/ 1127d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 1128d7b241e6Sjeremylt int ierr; 1129d7b241e6Sjeremylt 1130d1d35e2fSjeremylt if (!*op || --(*op)->ref_count > 0) return CEED_ERROR_SUCCESS; 1131d7b241e6Sjeremylt if ((*op)->Destroy) { 1132d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 1133d7b241e6Sjeremylt } 1134fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 1135fe2413ffSjeremylt // Free fields 1136d1d35e2fSjeremylt for (int i=0; i<(*op)->num_fields; i++) 1137d1d35e2fSjeremylt if ((*op)->input_fields[i]) { 1138d1d35e2fSjeremylt if ((*op)->input_fields[i]->elem_restr != CEED_ELEMRESTRICTION_NONE) { 1139d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->input_fields[i]->elem_restr); 114071352a93Sjeremylt CeedChk(ierr); 114115910d16Sjeremylt } 1142d1d35e2fSjeremylt if ((*op)->input_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1143d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->input_fields[i]->basis); CeedChk(ierr); 114471352a93Sjeremylt } 1145d1d35e2fSjeremylt if ((*op)->input_fields[i]->vec != CEED_VECTOR_ACTIVE && 1146d1d35e2fSjeremylt (*op)->input_fields[i]->vec != CEED_VECTOR_NONE ) { 1147d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->input_fields[i]->vec); CeedChk(ierr); 114871352a93Sjeremylt } 1149d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]->field_name); CeedChk(ierr); 1150d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]); CeedChk(ierr); 1151fe2413ffSjeremylt } 1152d1d35e2fSjeremylt for (int i=0; i<(*op)->num_fields; i++) 1153d1d35e2fSjeremylt if ((*op)->output_fields[i]) { 1154d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->output_fields[i]->elem_restr); 115571352a93Sjeremylt CeedChk(ierr); 1156d1d35e2fSjeremylt if ((*op)->output_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1157d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->output_fields[i]->basis); CeedChk(ierr); 115871352a93Sjeremylt } 1159d1d35e2fSjeremylt if ((*op)->output_fields[i]->vec != CEED_VECTOR_ACTIVE && 1160d1d35e2fSjeremylt (*op)->output_fields[i]->vec != CEED_VECTOR_NONE ) { 1161d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->output_fields[i]->vec); CeedChk(ierr); 116271352a93Sjeremylt } 1163d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]->field_name); CeedChk(ierr); 1164d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]); CeedChk(ierr); 1165fe2413ffSjeremylt } 1166d1d35e2fSjeremylt // Destroy sub_operators 1167d1d35e2fSjeremylt for (int i=0; i<(*op)->num_suboperators; i++) 1168d1d35e2fSjeremylt if ((*op)->sub_operators[i]) { 1169d1d35e2fSjeremylt ierr = CeedOperatorDestroy(&(*op)->sub_operators[i]); CeedChk(ierr); 117052d6035fSJeremy L Thompson } 1171e15f9bd0SJeremy L Thompson if ((*op)->qf) 1172e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 1173d1d35e2fSjeremylt (*op)->qf->operators_set--; 1174e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 1175d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 1176e15f9bd0SJeremy L Thompson if ((*op)->dqf && (*op)->dqf != CEED_QFUNCTION_NONE) 1177e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 1178d1d35e2fSjeremylt (*op)->dqf->operators_set--; 1179e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 1180d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 1181e15f9bd0SJeremy L Thompson if ((*op)->dqfT && (*op)->dqfT != CEED_QFUNCTION_NONE) 1182e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 1183d1d35e2fSjeremylt (*op)->dqfT->operators_set--; 1184e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 1185d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 1186fe2413ffSjeremylt 11875107b09fSJeremy L Thompson // Destroy fallback 1188d1d35e2fSjeremylt if ((*op)->op_fallback) { 1189d1d35e2fSjeremylt ierr = (*op)->qf_fallback->Destroy((*op)->qf_fallback); CeedChk(ierr); 1190d1d35e2fSjeremylt ierr = CeedFree(&(*op)->qf_fallback); CeedChk(ierr); 1191d1d35e2fSjeremylt ierr = (*op)->op_fallback->Destroy((*op)->op_fallback); CeedChk(ierr); 1192d1d35e2fSjeremylt ierr = CeedFree(&(*op)->op_fallback); CeedChk(ierr); 11935107b09fSJeremy L Thompson } 11945107b09fSJeremy L Thompson 1195d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields); CeedChk(ierr); 1196d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields); CeedChk(ierr); 1197d1d35e2fSjeremylt ierr = CeedFree(&(*op)->sub_operators); CeedChk(ierr); 1198d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 1199e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1200d7b241e6Sjeremylt } 1201d7b241e6Sjeremylt 1202d7b241e6Sjeremylt /// @} 1203