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 **/ 144eaf62fffSJeremy 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 149f04ea552SJeremy L Thompson if (op->is_interface_setup) 150e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1517a982d89SJeremy L. Thompson 152e15f9bd0SJeremy L Thompson CeedQFunction qf = op->qf; 153f04ea552SJeremy L Thompson if (op->is_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 181f04ea552SJeremy L Thompson op->is_interface_setup = true; 182e15f9bd0SJeremy L Thompson if (op->qf && op->qf != CEED_QFUNCTION_NONE) 183e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 184f04ea552SJeremy L Thompson op->qf->is_immutable = true; 185e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 186e15f9bd0SJeremy L Thompson if (op->dqf && op->dqf != CEED_QFUNCTION_NONE) 187e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 188f04ea552SJeremy L Thompson op->dqf->is_immutable = true; 189e15f9bd0SJeremy L Thompson // LCOV_EXCL_STOP 190e15f9bd0SJeremy L Thompson if (op->dqfT && op->dqfT != CEED_QFUNCTION_NONE) 191e15f9bd0SJeremy L Thompson // LCOV_EXCL_START 192f04ea552SJeremy L Thompson op->dqfT->is_immutable = true; 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 /** 270eaf62fffSJeremy L Thompson @brief Find the active vector basis for a CeedOperator 271eaf62fffSJeremy L Thompson 272eaf62fffSJeremy L Thompson @param[in] op CeedOperator to find active basis for 273eaf62fffSJeremy L Thompson @param[out] active_basis Basis for active input vector 274eaf62fffSJeremy L Thompson 275eaf62fffSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 276eaf62fffSJeremy L Thompson 277eaf62fffSJeremy L Thompson @ ref Developer 278eaf62fffSJeremy L Thompson **/ 279eaf62fffSJeremy L Thompson int CeedOperatorGetActiveBasis(CeedOperator op, CeedBasis *active_basis) { 280eaf62fffSJeremy L Thompson *active_basis = NULL; 281eaf62fffSJeremy L Thompson for (int i = 0; i < op->qf->num_input_fields; i++) 282eaf62fffSJeremy L Thompson if (op->input_fields[i]->vec == CEED_VECTOR_ACTIVE) { 283eaf62fffSJeremy L Thompson *active_basis = op->input_fields[i]->basis; 284eaf62fffSJeremy L Thompson break; 285eaf62fffSJeremy L Thompson } 286eaf62fffSJeremy L Thompson 287eaf62fffSJeremy L Thompson if (!*active_basis) { 288eaf62fffSJeremy L Thompson // LCOV_EXCL_START 289eaf62fffSJeremy L Thompson int ierr; 290eaf62fffSJeremy L Thompson Ceed ceed; 291eaf62fffSJeremy L Thompson ierr = CeedOperatorGetCeed(op, &ceed); CeedChk(ierr); 292eaf62fffSJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 293eaf62fffSJeremy L Thompson "No active CeedBasis found"); 294eaf62fffSJeremy L Thompson // LCOV_EXCL_STOP 295eaf62fffSJeremy L Thompson } 296eaf62fffSJeremy L Thompson return CEED_ERROR_SUCCESS; 297eaf62fffSJeremy L Thompson } 298eaf62fffSJeremy L Thompson 299eaf62fffSJeremy 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 **/ 309eaf62fffSJeremy 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, 324eaf62fffSJeremy 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 number of arguments associated with a CeedOperator 3407a982d89SJeremy L. Thompson 3417a982d89SJeremy L. Thompson @param op CeedOperator 342d1d35e2fSjeremylt @param[out] num_args Variable to store vector number of arguments 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 349d1d35e2fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *num_args) { 350f04ea552SJeremy L Thompson if (op->is_composite) 3517a982d89SJeremy L. Thompson // LCOV_EXCL_START 352e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 353e15f9bd0SJeremy L Thompson "Not defined for composite operators"); 3547a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 3557a982d89SJeremy L. Thompson 356d1d35e2fSjeremylt *num_args = op->num_fields; 357e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3587a982d89SJeremy L. Thompson } 3597a982d89SJeremy L. Thompson 3607a982d89SJeremy L. Thompson /** 3617a982d89SJeremy L. Thompson @brief Get the setup status of a CeedOperator 3627a982d89SJeremy L. Thompson 3637a982d89SJeremy L. Thompson @param op CeedOperator 364d1d35e2fSjeremylt @param[out] is_setup_done Variable to store setup status 3657a982d89SJeremy L. Thompson 3667a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3677a982d89SJeremy L. Thompson 3687a982d89SJeremy L. Thompson @ref Backend 3697a982d89SJeremy L. Thompson **/ 3707a982d89SJeremy L. Thompson 371d1d35e2fSjeremylt int CeedOperatorIsSetupDone(CeedOperator op, bool *is_setup_done) { 372f04ea552SJeremy L Thompson *is_setup_done = op->is_backend_setup; 373e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3747a982d89SJeremy L. Thompson } 3757a982d89SJeremy L. Thompson 3767a982d89SJeremy L. Thompson /** 3777a982d89SJeremy L. Thompson @brief Get the QFunction associated with a CeedOperator 3787a982d89SJeremy L. Thompson 3797a982d89SJeremy L. Thompson @param op CeedOperator 3807a982d89SJeremy L. Thompson @param[out] qf Variable to store QFunction 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 3877a982d89SJeremy L. Thompson int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 388f04ea552SJeremy L Thompson if (op->is_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 3947a982d89SJeremy L. Thompson *qf = op->qf; 395e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3967a982d89SJeremy L. Thompson } 3977a982d89SJeremy L. Thompson 3987a982d89SJeremy L. Thompson /** 399c04a41a7SJeremy L Thompson @brief Get a boolean value indicating if the CeedOperator is composite 400c04a41a7SJeremy L Thompson 401c04a41a7SJeremy L Thompson @param op CeedOperator 402d1d35e2fSjeremylt @param[out] is_composite Variable to store composite status 403c04a41a7SJeremy L Thompson 404c04a41a7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 405c04a41a7SJeremy L Thompson 406c04a41a7SJeremy L Thompson @ref Backend 407c04a41a7SJeremy L Thompson **/ 408c04a41a7SJeremy L Thompson 409d1d35e2fSjeremylt int CeedOperatorIsComposite(CeedOperator op, bool *is_composite) { 410f04ea552SJeremy L Thompson *is_composite = op->is_composite; 411e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 412c04a41a7SJeremy L Thompson } 413c04a41a7SJeremy L Thompson 414c04a41a7SJeremy L Thompson /** 415d1d35e2fSjeremylt @brief Get the number of sub_operators associated with a CeedOperator 4167a982d89SJeremy L. Thompson 4177a982d89SJeremy L. Thompson @param op CeedOperator 418d1d35e2fSjeremylt @param[out] num_suboperators Variable to store number of sub_operators 4197a982d89SJeremy L. Thompson 4207a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4217a982d89SJeremy L. Thompson 4227a982d89SJeremy L. Thompson @ref Backend 4237a982d89SJeremy L. Thompson **/ 4247a982d89SJeremy L. Thompson 425d1d35e2fSjeremylt int CeedOperatorGetNumSub(CeedOperator op, CeedInt *num_suboperators) { 426f04ea552SJeremy L Thompson if (!op->is_composite) 4277a982d89SJeremy L. Thompson // LCOV_EXCL_START 428e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 4297a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4307a982d89SJeremy L. Thompson 431d1d35e2fSjeremylt *num_suboperators = op->num_suboperators; 432e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4337a982d89SJeremy L. Thompson } 4347a982d89SJeremy L. Thompson 4357a982d89SJeremy L. Thompson /** 436d1d35e2fSjeremylt @brief Get the list of sub_operators associated with a CeedOperator 4377a982d89SJeremy L. Thompson 4387a982d89SJeremy L. Thompson @param op CeedOperator 439d1d35e2fSjeremylt @param[out] sub_operators Variable to store list of sub_operators 4407a982d89SJeremy L. Thompson 4417a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4427a982d89SJeremy L. Thompson 4437a982d89SJeremy L. Thompson @ref Backend 4447a982d89SJeremy L. Thompson **/ 4457a982d89SJeremy L. Thompson 446d1d35e2fSjeremylt int CeedOperatorGetSubList(CeedOperator op, CeedOperator **sub_operators) { 447f04ea552SJeremy L Thompson if (!op->is_composite) 4487a982d89SJeremy L. Thompson // LCOV_EXCL_START 449e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, "Not a composite operator"); 4507a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 4517a982d89SJeremy L. Thompson 452d1d35e2fSjeremylt *sub_operators = op->sub_operators; 453e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4547a982d89SJeremy L. Thompson } 4557a982d89SJeremy L. Thompson 4567a982d89SJeremy L. Thompson /** 4577a982d89SJeremy L. Thompson @brief Get the backend data of a CeedOperator 4587a982d89SJeremy L. Thompson 4597a982d89SJeremy L. Thompson @param op CeedOperator 4607a982d89SJeremy L. Thompson @param[out] data Variable to store data 4617a982d89SJeremy L. Thompson 4627a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4637a982d89SJeremy L. Thompson 4647a982d89SJeremy L. Thompson @ref Backend 4657a982d89SJeremy L. Thompson **/ 4667a982d89SJeremy L. Thompson 467777ff853SJeremy L Thompson int CeedOperatorGetData(CeedOperator op, void *data) { 468777ff853SJeremy L Thompson *(void **)data = op->data; 469e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4707a982d89SJeremy L. Thompson } 4717a982d89SJeremy L. Thompson 4727a982d89SJeremy L. Thompson /** 4737a982d89SJeremy L. Thompson @brief Set the backend data of a CeedOperator 4747a982d89SJeremy L. Thompson 4757a982d89SJeremy L. Thompson @param[out] op CeedOperator 4767a982d89SJeremy L. Thompson @param data Data to set 4777a982d89SJeremy L. Thompson 4787a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4797a982d89SJeremy L. Thompson 4807a982d89SJeremy L. Thompson @ref Backend 4817a982d89SJeremy L. Thompson **/ 4827a982d89SJeremy L. Thompson 483777ff853SJeremy L Thompson int CeedOperatorSetData(CeedOperator op, void *data) { 484777ff853SJeremy L Thompson op->data = data; 485e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4867a982d89SJeremy L. Thompson } 4877a982d89SJeremy L. Thompson 4887a982d89SJeremy L. Thompson /** 48934359f16Sjeremylt @brief Increment the reference counter for a CeedOperator 49034359f16Sjeremylt 49134359f16Sjeremylt @param op CeedOperator to increment the reference counter 49234359f16Sjeremylt 49334359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 49434359f16Sjeremylt 49534359f16Sjeremylt @ref Backend 49634359f16Sjeremylt **/ 4979560d06aSjeremylt int CeedOperatorReference(CeedOperator op) { 49834359f16Sjeremylt op->ref_count++; 49934359f16Sjeremylt return CEED_ERROR_SUCCESS; 50034359f16Sjeremylt } 50134359f16Sjeremylt 50234359f16Sjeremylt /** 5037a982d89SJeremy L. Thompson @brief Set the setup flag of a CeedOperator to True 5047a982d89SJeremy L. Thompson 5057a982d89SJeremy L. Thompson @param op CeedOperator 5067a982d89SJeremy L. Thompson 5077a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5087a982d89SJeremy L. Thompson 5097a982d89SJeremy L. Thompson @ref Backend 5107a982d89SJeremy L. Thompson **/ 5117a982d89SJeremy L. Thompson 5127a982d89SJeremy L. Thompson int CeedOperatorSetSetupDone(CeedOperator op) { 513f04ea552SJeremy L Thompson op->is_backend_setup = true; 514e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5157a982d89SJeremy L. Thompson } 5167a982d89SJeremy L. Thompson 5177a982d89SJeremy L. Thompson /// @} 5187a982d89SJeremy L. Thompson 5197a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5207a982d89SJeremy L. Thompson /// CeedOperator Public API 5217a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5227a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorUser 523dfdf5a53Sjeremylt /// @{ 524d7b241e6Sjeremylt 525d7b241e6Sjeremylt /** 5260219ea01SJeremy L Thompson @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and 5270219ea01SJeremy L Thompson CeedElemRestriction can be associated with CeedQFunction fields with 5280219ea01SJeremy L Thompson \ref CeedOperatorSetField. 529d7b241e6Sjeremylt 530b11c1e72Sjeremylt @param ceed A Ceed object where the CeedOperator will be created 531d7b241e6Sjeremylt @param qf QFunction defining the action of the operator at quadrature points 53234138859Sjeremylt @param dqf QFunction defining the action of the Jacobian of @a qf (or 5334cc79fe7SJed Brown @ref CEED_QFUNCTION_NONE) 534d7b241e6Sjeremylt @param dqfT QFunction defining the action of the transpose of the Jacobian 5354cc79fe7SJed Brown of @a qf (or @ref CEED_QFUNCTION_NONE) 536b11c1e72Sjeremylt @param[out] op Address of the variable where the newly created 537b11c1e72Sjeremylt CeedOperator will be stored 538b11c1e72Sjeremylt 539b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 540dfdf5a53Sjeremylt 5417a982d89SJeremy L. Thompson @ref User 542d7b241e6Sjeremylt */ 543d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, 544d7b241e6Sjeremylt CeedQFunction dqfT, CeedOperator *op) { 545d7b241e6Sjeremylt int ierr; 546d7b241e6Sjeremylt 5475fe0d4faSjeremylt if (!ceed->OperatorCreate) { 5485fe0d4faSjeremylt Ceed delegate; 549aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 5505fe0d4faSjeremylt 5515fe0d4faSjeremylt if (!delegate) 552c042f62fSJeremy L Thompson // LCOV_EXCL_START 553e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 554e15f9bd0SJeremy L Thompson "Backend does not support OperatorCreate"); 555c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 5565fe0d4faSjeremylt 5575fe0d4faSjeremylt ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr); 558e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5595fe0d4faSjeremylt } 5605fe0d4faSjeremylt 561b3b7035fSJeremy L Thompson if (!qf || qf == CEED_QFUNCTION_NONE) 562b3b7035fSJeremy L Thompson // LCOV_EXCL_START 563e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_MINOR, 564e15f9bd0SJeremy L Thompson "Operator must have a valid QFunction."); 565b3b7035fSJeremy L Thompson // LCOV_EXCL_STOP 566d7b241e6Sjeremylt ierr = CeedCalloc(1, op); CeedChk(ierr); 567d7b241e6Sjeremylt (*op)->ceed = ceed; 5689560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 569d1d35e2fSjeremylt (*op)->ref_count = 1; 570d7b241e6Sjeremylt (*op)->qf = qf; 5719560d06aSjeremylt ierr = CeedQFunctionReference(qf); CeedChk(ierr); 572442e7f0bSjeremylt if (dqf && dqf != CEED_QFUNCTION_NONE) { 573d7b241e6Sjeremylt (*op)->dqf = dqf; 5749560d06aSjeremylt ierr = CeedQFunctionReference(dqf); CeedChk(ierr); 575442e7f0bSjeremylt } 576442e7f0bSjeremylt if (dqfT && dqfT != CEED_QFUNCTION_NONE) { 577d7b241e6Sjeremylt (*op)->dqfT = dqfT; 5789560d06aSjeremylt ierr = CeedQFunctionReference(dqfT); CeedChk(ierr); 579442e7f0bSjeremylt } 580d1d35e2fSjeremylt ierr = CeedCalloc(16, &(*op)->input_fields); CeedChk(ierr); 581d1d35e2fSjeremylt ierr = CeedCalloc(16, &(*op)->output_fields); CeedChk(ierr); 582d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 583e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 584d7b241e6Sjeremylt } 585d7b241e6Sjeremylt 586d7b241e6Sjeremylt /** 58752d6035fSJeremy L Thompson @brief Create an operator that composes the action of several operators 58852d6035fSJeremy L Thompson 58952d6035fSJeremy L Thompson @param ceed A Ceed object where the CeedOperator will be created 59052d6035fSJeremy L Thompson @param[out] op Address of the variable where the newly created 59152d6035fSJeremy L Thompson Composite CeedOperator will be stored 59252d6035fSJeremy L Thompson 59352d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 59452d6035fSJeremy L Thompson 5957a982d89SJeremy L. Thompson @ref User 59652d6035fSJeremy L Thompson */ 59752d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) { 59852d6035fSJeremy L Thompson int ierr; 59952d6035fSJeremy L Thompson 60052d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 60152d6035fSJeremy L Thompson Ceed delegate; 602aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 60352d6035fSJeremy L Thompson 604250756a7Sjeremylt if (delegate) { 60552d6035fSJeremy L Thompson ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr); 606e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 60752d6035fSJeremy L Thompson } 608250756a7Sjeremylt } 60952d6035fSJeremy L Thompson 61052d6035fSJeremy L Thompson ierr = CeedCalloc(1, op); CeedChk(ierr); 61152d6035fSJeremy L Thompson (*op)->ceed = ceed; 6129560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 613f04ea552SJeremy L Thompson (*op)->is_composite = true; 614d1d35e2fSjeremylt ierr = CeedCalloc(16, &(*op)->sub_operators); CeedChk(ierr); 615250756a7Sjeremylt 616250756a7Sjeremylt if (ceed->CompositeOperatorCreate) { 61752d6035fSJeremy L Thompson ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr); 618250756a7Sjeremylt } 619e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 62052d6035fSJeremy L Thompson } 62152d6035fSJeremy L Thompson 62252d6035fSJeremy L Thompson /** 6239560d06aSjeremylt @brief Copy the pointer to a CeedOperator. Both pointers should 6249560d06aSjeremylt be destroyed with `CeedOperatorDestroy()`; 6259560d06aSjeremylt Note: If `*op_copy` is non-NULL, then it is assumed that 6269560d06aSjeremylt `*op_copy` is a pointer to a CeedOperator. This 6279560d06aSjeremylt CeedOperator will be destroyed if `*op_copy` is the only 6289560d06aSjeremylt reference to this CeedOperator. 6299560d06aSjeremylt 6309560d06aSjeremylt @param op CeedOperator to copy reference to 6319560d06aSjeremylt @param[out] op_copy Variable to store copied reference 6329560d06aSjeremylt 6339560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 6349560d06aSjeremylt 6359560d06aSjeremylt @ref User 6369560d06aSjeremylt **/ 6379560d06aSjeremylt int CeedOperatorReferenceCopy(CeedOperator op, CeedOperator *op_copy) { 6389560d06aSjeremylt int ierr; 6399560d06aSjeremylt 6409560d06aSjeremylt ierr = CeedOperatorReference(op); CeedChk(ierr); 6419560d06aSjeremylt ierr = CeedOperatorDestroy(op_copy); CeedChk(ierr); 6429560d06aSjeremylt *op_copy = op; 6439560d06aSjeremylt return CEED_ERROR_SUCCESS; 6449560d06aSjeremylt } 6459560d06aSjeremylt 6469560d06aSjeremylt /** 647b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 648d7b241e6Sjeremylt 649d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 650d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 651d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 652d7b241e6Sjeremylt 653d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 654d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 655d7b241e6Sjeremylt input and at most one active output. 656d7b241e6Sjeremylt 6578c91a0c9SJeremy L Thompson @param op CeedOperator on which to provide the field 658d1d35e2fSjeremylt @param field_name Name of the field (to be matched with the name used by 6598795c945Sjeremylt CeedQFunction) 660b11c1e72Sjeremylt @param r CeedElemRestriction 6614cc79fe7SJed Brown @param b CeedBasis in which the field resides or @ref CEED_BASIS_COLLOCATED 662b11c1e72Sjeremylt if collocated with quadrature points 6634cc79fe7SJed Brown @param v CeedVector to be used by CeedOperator or @ref CEED_VECTOR_ACTIVE 6644cc79fe7SJed Brown if field is active or @ref CEED_VECTOR_NONE if using 6654cc79fe7SJed Brown @ref CEED_EVAL_WEIGHT in the QFunction 666b11c1e72Sjeremylt 667b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 668dfdf5a53Sjeremylt 6697a982d89SJeremy L. Thompson @ref User 670b11c1e72Sjeremylt **/ 671d1d35e2fSjeremylt int CeedOperatorSetField(CeedOperator op, const char *field_name, 672a8d32208Sjeremylt CeedElemRestriction r, CeedBasis b, CeedVector v) { 673d7b241e6Sjeremylt int ierr; 674f04ea552SJeremy L Thompson if (op->is_composite) 675c042f62fSJeremy L Thompson // LCOV_EXCL_START 676e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 677e15f9bd0SJeremy L Thompson "Cannot add field to composite operator."); 678c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 679f04ea552SJeremy L Thompson if (op->is_immutable) 680f04ea552SJeremy L Thompson // LCOV_EXCL_START 681f04ea552SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 682f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 683f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 6848b067b84SJed Brown if (!r) 685c042f62fSJeremy L Thompson // LCOV_EXCL_START 686e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 687c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 688d1d35e2fSjeremylt field_name); 689c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 6908b067b84SJed Brown if (!b) 691c042f62fSJeremy L Thompson // LCOV_EXCL_START 692e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 693e15f9bd0SJeremy L Thompson "Basis b for field \"%s\" must be non-NULL.", 694d1d35e2fSjeremylt field_name); 695c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 6968b067b84SJed Brown if (!v) 697c042f62fSJeremy L Thompson // LCOV_EXCL_START 698e1e9e29dSJed Brown return CeedError(op->ceed, CEED_ERROR_INCOMPATIBLE, 699e15f9bd0SJeremy L Thompson "Vector v for field \"%s\" must be non-NULL.", 700d1d35e2fSjeremylt field_name); 701c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 70252d6035fSJeremy L Thompson 703d1d35e2fSjeremylt CeedInt num_elem; 704d1d35e2fSjeremylt ierr = CeedElemRestrictionGetNumElements(r, &num_elem); CeedChk(ierr); 705d1d35e2fSjeremylt if (r != CEED_ELEMRESTRICTION_NONE && op->has_restriction && 706d1d35e2fSjeremylt op->num_elem != num_elem) 707c042f62fSJeremy L Thompson // LCOV_EXCL_START 708e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 7091d102b48SJeremy L Thompson "ElemRestriction with %d elements incompatible with prior " 710d1d35e2fSjeremylt "%d elements", num_elem, op->num_elem); 711c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 712d7b241e6Sjeremylt 71378464608Sjeremylt CeedInt num_qpts = 0; 714e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 715d1d35e2fSjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &num_qpts); CeedChk(ierr); 716d1d35e2fSjeremylt if (op->num_qpts && op->num_qpts != num_qpts) 717c042f62fSJeremy L Thompson // LCOV_EXCL_START 718e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_DIMENSION, 719e15f9bd0SJeremy L Thompson "Basis with %d quadrature points " 720d1d35e2fSjeremylt "incompatible with prior %d points", num_qpts, 721d1d35e2fSjeremylt op->num_qpts); 722c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 723d7b241e6Sjeremylt } 724d1d35e2fSjeremylt CeedQFunctionField qf_field; 725d1d35e2fSjeremylt CeedOperatorField *op_field; 726d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_input_fields; i++) { 727d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->input_fields[i]).field_name)) { 728d1d35e2fSjeremylt qf_field = op->qf->input_fields[i]; 729d1d35e2fSjeremylt op_field = &op->input_fields[i]; 730d7b241e6Sjeremylt goto found; 731d7b241e6Sjeremylt } 732d7b241e6Sjeremylt } 733d1d35e2fSjeremylt for (CeedInt i=0; i<op->qf->num_output_fields; i++) { 734d1d35e2fSjeremylt if (!strcmp(field_name, (*op->qf->output_fields[i]).field_name)) { 735d1d35e2fSjeremylt qf_field = op->qf->output_fields[i]; 736d1d35e2fSjeremylt op_field = &op->output_fields[i]; 737d7b241e6Sjeremylt goto found; 738d7b241e6Sjeremylt } 739d7b241e6Sjeremylt } 740c042f62fSJeremy L Thompson // LCOV_EXCL_START 741e15f9bd0SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_INCOMPLETE, 742e15f9bd0SJeremy L Thompson "QFunction has no knowledge of field '%s'", 743d1d35e2fSjeremylt field_name); 744c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 745d7b241e6Sjeremylt found: 746d1d35e2fSjeremylt ierr = CeedOperatorCheckField(op->ceed, qf_field, r, b); CeedChk(ierr); 747d1d35e2fSjeremylt ierr = CeedCalloc(1, op_field); CeedChk(ierr); 748e15f9bd0SJeremy L Thompson 749d1d35e2fSjeremylt (*op_field)->vec = v; 750e15f9bd0SJeremy L Thompson if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) { 7519560d06aSjeremylt ierr = CeedVectorReference(v); CeedChk(ierr); 752e15f9bd0SJeremy L Thompson } 753e15f9bd0SJeremy L Thompson 754d1d35e2fSjeremylt (*op_field)->elem_restr = r; 7559560d06aSjeremylt ierr = CeedElemRestrictionReference(r); CeedChk(ierr); 756e15f9bd0SJeremy L Thompson if (r != CEED_ELEMRESTRICTION_NONE) { 757d1d35e2fSjeremylt op->num_elem = num_elem; 758d1d35e2fSjeremylt op->has_restriction = true; // Restriction set, but num_elem may be 0 759e15f9bd0SJeremy L Thompson } 760d99fa3c5SJeremy L Thompson 761d1d35e2fSjeremylt (*op_field)->basis = b; 762e15f9bd0SJeremy L Thompson if (b != CEED_BASIS_COLLOCATED) { 763cd4dfc48Sjeremylt if (!op->num_qpts) { 764cd4dfc48Sjeremylt ierr = CeedOperatorSetNumQuadraturePoints(op, num_qpts); CeedChk(ierr); 765cd4dfc48Sjeremylt } 7669560d06aSjeremylt ierr = CeedBasisReference(b); CeedChk(ierr); 767e15f9bd0SJeremy L Thompson } 768e15f9bd0SJeremy L Thompson 769d1d35e2fSjeremylt op->num_fields += 1; 770d1d35e2fSjeremylt size_t len = strlen(field_name); 771d99fa3c5SJeremy L Thompson char *tmp; 772d99fa3c5SJeremy L Thompson ierr = CeedCalloc(len+1, &tmp); CeedChk(ierr); 773d1d35e2fSjeremylt memcpy(tmp, field_name, len+1); 774d1d35e2fSjeremylt (*op_field)->field_name = tmp; 775e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 776d7b241e6Sjeremylt } 777d7b241e6Sjeremylt 778d7b241e6Sjeremylt /** 77943bbe138SJeremy L Thompson @brief Get the CeedOperatorFields of a CeedOperator 78043bbe138SJeremy L Thompson 781f04ea552SJeremy L Thompson Note: Calling this function asserts that setup is complete 782f04ea552SJeremy L Thompson and sets the CeedOperator as immutable. 783f04ea552SJeremy L Thompson 78443bbe138SJeremy L Thompson @param op CeedOperator 78543bbe138SJeremy L Thompson @param[out] input_fields Variable to store input_fields 78643bbe138SJeremy L Thompson @param[out] output_fields Variable to store output_fields 78743bbe138SJeremy L Thompson 78843bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 78943bbe138SJeremy L Thompson 790e9b533fbSJeremy L Thompson @ref Advanced 79143bbe138SJeremy L Thompson **/ 79243bbe138SJeremy L Thompson int CeedOperatorGetFields(CeedOperator op, CeedInt *num_input_fields, 79343bbe138SJeremy L Thompson CeedOperatorField **input_fields, 79443bbe138SJeremy L Thompson CeedInt *num_output_fields, 79543bbe138SJeremy L Thompson CeedOperatorField **output_fields) { 796f04ea552SJeremy L Thompson int ierr; 797f04ea552SJeremy L Thompson 798f04ea552SJeremy L Thompson if (op->is_composite) 79943bbe138SJeremy L Thompson // LCOV_EXCL_START 80043bbe138SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 80143bbe138SJeremy L Thompson "Not defined for composite operator"); 80243bbe138SJeremy L Thompson // LCOV_EXCL_STOP 803f04ea552SJeremy L Thompson ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 80443bbe138SJeremy L Thompson 80543bbe138SJeremy L Thompson if (num_input_fields) *num_input_fields = op->qf->num_input_fields; 80643bbe138SJeremy L Thompson if (input_fields) *input_fields = op->input_fields; 80743bbe138SJeremy L Thompson if (num_output_fields) *num_output_fields = op->qf->num_output_fields; 80843bbe138SJeremy L Thompson if (output_fields) *output_fields = op->output_fields; 80943bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 81043bbe138SJeremy L Thompson } 81143bbe138SJeremy L Thompson 81243bbe138SJeremy L Thompson /** 81328567f8fSJeremy L Thompson @brief Get the name of a CeedOperatorField 81428567f8fSJeremy L Thompson 81528567f8fSJeremy L Thompson @param op_field CeedOperatorField 81628567f8fSJeremy L Thompson @param[out] field_name Variable to store the field name 81728567f8fSJeremy L Thompson 81828567f8fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 81928567f8fSJeremy L Thompson 820e9b533fbSJeremy L Thompson @ref Advanced 82128567f8fSJeremy L Thompson **/ 82228567f8fSJeremy L Thompson int CeedOperatorFieldGetName(CeedOperatorField op_field, char **field_name) { 82328567f8fSJeremy L Thompson *field_name = (char *)op_field->field_name; 82428567f8fSJeremy L Thompson return CEED_ERROR_SUCCESS; 82528567f8fSJeremy L Thompson } 82628567f8fSJeremy L Thompson 82728567f8fSJeremy L Thompson /** 82843bbe138SJeremy L Thompson @brief Get the CeedElemRestriction of a CeedOperatorField 82943bbe138SJeremy L Thompson 83043bbe138SJeremy L Thompson @param op_field CeedOperatorField 83143bbe138SJeremy L Thompson @param[out] rstr Variable to store CeedElemRestriction 83243bbe138SJeremy L Thompson 83343bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 83443bbe138SJeremy L Thompson 835e9b533fbSJeremy L Thompson @ref Advanced 83643bbe138SJeremy L Thompson **/ 83743bbe138SJeremy L Thompson int CeedOperatorFieldGetElemRestriction(CeedOperatorField op_field, 83843bbe138SJeremy L Thompson CeedElemRestriction *rstr) { 83943bbe138SJeremy L Thompson *rstr = op_field->elem_restr; 84043bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 84143bbe138SJeremy L Thompson } 84243bbe138SJeremy L Thompson 84343bbe138SJeremy L Thompson /** 84443bbe138SJeremy L Thompson @brief Get the CeedBasis of a CeedOperatorField 84543bbe138SJeremy L Thompson 84643bbe138SJeremy L Thompson @param op_field CeedOperatorField 84743bbe138SJeremy L Thompson @param[out] basis Variable to store CeedBasis 84843bbe138SJeremy L Thompson 84943bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 85043bbe138SJeremy L Thompson 851e9b533fbSJeremy L Thompson @ref Advanced 85243bbe138SJeremy L Thompson **/ 85343bbe138SJeremy L Thompson int CeedOperatorFieldGetBasis(CeedOperatorField op_field, CeedBasis *basis) { 85443bbe138SJeremy L Thompson *basis = op_field->basis; 85543bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 85643bbe138SJeremy L Thompson } 85743bbe138SJeremy L Thompson 85843bbe138SJeremy L Thompson /** 85943bbe138SJeremy L Thompson @brief Get the CeedVector of a CeedOperatorField 86043bbe138SJeremy L Thompson 86143bbe138SJeremy L Thompson @param op_field CeedOperatorField 86243bbe138SJeremy L Thompson @param[out] vec Variable to store CeedVector 86343bbe138SJeremy L Thompson 86443bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 86543bbe138SJeremy L Thompson 866e9b533fbSJeremy L Thompson @ref Advanced 86743bbe138SJeremy L Thompson **/ 86843bbe138SJeremy L Thompson int CeedOperatorFieldGetVector(CeedOperatorField op_field, CeedVector *vec) { 86943bbe138SJeremy L Thompson *vec = op_field->vec; 87043bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 87143bbe138SJeremy L Thompson } 87243bbe138SJeremy L Thompson 87343bbe138SJeremy L Thompson /** 87452d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 875288c0443SJeremy L Thompson 876d1d35e2fSjeremylt @param[out] composite_op Composite CeedOperator 877d1d35e2fSjeremylt @param sub_op Sub-operator CeedOperator 87852d6035fSJeremy L Thompson 87952d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 88052d6035fSJeremy L Thompson 8817a982d89SJeremy L. Thompson @ref User 88252d6035fSJeremy L Thompson */ 883d1d35e2fSjeremylt int CeedCompositeOperatorAddSub(CeedOperator composite_op, 884d1d35e2fSjeremylt CeedOperator sub_op) { 88534359f16Sjeremylt int ierr; 88634359f16Sjeremylt 887f04ea552SJeremy L Thompson if (!composite_op->is_composite) 888c042f62fSJeremy L Thompson // LCOV_EXCL_START 889d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_MINOR, 890e2f04181SAndrew T. Barker "CeedOperator is not a composite operator"); 891c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 89252d6035fSJeremy L Thompson 893d1d35e2fSjeremylt if (composite_op->num_suboperators == CEED_COMPOSITE_MAX) 894c042f62fSJeremy L Thompson // LCOV_EXCL_START 895d1d35e2fSjeremylt return CeedError(composite_op->ceed, CEED_ERROR_UNSUPPORTED, 896d1d35e2fSjeremylt "Cannot add additional sub_operators"); 897c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 898f04ea552SJeremy L Thompson if (composite_op->is_immutable) 899f04ea552SJeremy L Thompson // LCOV_EXCL_START 900f04ea552SJeremy L Thompson return CeedError(composite_op->ceed, CEED_ERROR_MAJOR, 901f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 902f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 90352d6035fSJeremy L Thompson 904d1d35e2fSjeremylt composite_op->sub_operators[composite_op->num_suboperators] = sub_op; 9059560d06aSjeremylt ierr = CeedOperatorReference(sub_op); CeedChk(ierr); 906d1d35e2fSjeremylt composite_op->num_suboperators++; 907e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 90852d6035fSJeremy L Thompson } 90952d6035fSJeremy L Thompson 91052d6035fSJeremy L Thompson /** 911cd4dfc48Sjeremylt @brief Set the number of quadrature points associated with a CeedOperator. 912cd4dfc48Sjeremylt This should be used when creating a CeedOperator where every 913cd4dfc48Sjeremylt field has a collocated basis. This function cannot be used for 914cd4dfc48Sjeremylt composite CeedOperators. 915cd4dfc48Sjeremylt 916cd4dfc48Sjeremylt @param op CeedOperator 917cd4dfc48Sjeremylt @param num_qpts Number of quadrature points to set 918cd4dfc48Sjeremylt 919cd4dfc48Sjeremylt @return An error code: 0 - success, otherwise - failure 920cd4dfc48Sjeremylt 921e9b533fbSJeremy L Thompson @ref Advanced 922cd4dfc48Sjeremylt **/ 923cd4dfc48Sjeremylt 924cd4dfc48Sjeremylt int CeedOperatorSetNumQuadraturePoints(CeedOperator op, CeedInt num_qpts) { 925f04ea552SJeremy L Thompson if (op->is_composite) 926cd4dfc48Sjeremylt // LCOV_EXCL_START 927cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 928cd4dfc48Sjeremylt "Not defined for composite operator"); 929cd4dfc48Sjeremylt // LCOV_EXCL_STOP 930cd4dfc48Sjeremylt if (op->num_qpts) 931cd4dfc48Sjeremylt // LCOV_EXCL_START 932cd4dfc48Sjeremylt return CeedError(op->ceed, CEED_ERROR_MINOR, 933cd4dfc48Sjeremylt "Number of quadrature points already defined"); 934cd4dfc48Sjeremylt // LCOV_EXCL_STOP 935f04ea552SJeremy L Thompson if (op->is_immutable) 936f04ea552SJeremy L Thompson // LCOV_EXCL_START 937f04ea552SJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MAJOR, 938f04ea552SJeremy L Thompson "Operator cannot be changed after set as immutable"); 939f04ea552SJeremy L Thompson // LCOV_EXCL_STOP 940cd4dfc48Sjeremylt 941cd4dfc48Sjeremylt op->num_qpts = num_qpts; 942cd4dfc48Sjeremylt return CEED_ERROR_SUCCESS; 943cd4dfc48Sjeremylt } 944cd4dfc48Sjeremylt 945cd4dfc48Sjeremylt /** 9467a982d89SJeremy L. Thompson @brief View a CeedOperator 9477a982d89SJeremy L. Thompson 9487a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 9497a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 9507a982d89SJeremy L. Thompson 9517a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 9527a982d89SJeremy L. Thompson 9537a982d89SJeremy L. Thompson @ref User 9547a982d89SJeremy L. Thompson **/ 9557a982d89SJeremy L. Thompson int CeedOperatorView(CeedOperator op, FILE *stream) { 9567a982d89SJeremy L. Thompson int ierr; 9577a982d89SJeremy L. Thompson 958f04ea552SJeremy L Thompson if (op->is_composite) { 9597a982d89SJeremy L. Thompson fprintf(stream, "Composite CeedOperator\n"); 9607a982d89SJeremy L. Thompson 961d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 9627a982d89SJeremy L. Thompson fprintf(stream, " SubOperator [%d]:\n", i); 963d1d35e2fSjeremylt ierr = CeedOperatorSingleView(op->sub_operators[i], 1, stream); 9647a982d89SJeremy L. Thompson CeedChk(ierr); 9657a982d89SJeremy L. Thompson } 9667a982d89SJeremy L. Thompson } else { 9677a982d89SJeremy L. Thompson fprintf(stream, "CeedOperator\n"); 9687a982d89SJeremy L. Thompson ierr = CeedOperatorSingleView(op, 0, stream); CeedChk(ierr); 9697a982d89SJeremy L. Thompson } 970e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9717a982d89SJeremy L. Thompson } 9723bd813ffSjeremylt 9733bd813ffSjeremylt /** 974*b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedOperator 975*b7c9bbdaSJeremy L Thompson 976*b7c9bbdaSJeremy L Thompson @param op CeedOperator 977*b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 978*b7c9bbdaSJeremy L Thompson 979*b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 980*b7c9bbdaSJeremy L Thompson 981*b7c9bbdaSJeremy L Thompson @ref Advanced 982*b7c9bbdaSJeremy L Thompson **/ 983*b7c9bbdaSJeremy L Thompson int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 984*b7c9bbdaSJeremy L Thompson *ceed = op->ceed; 985*b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 986*b7c9bbdaSJeremy L Thompson } 987*b7c9bbdaSJeremy L Thompson 988*b7c9bbdaSJeremy L Thompson /** 989*b7c9bbdaSJeremy L Thompson @brief Get the number of elements associated with a CeedOperator 990*b7c9bbdaSJeremy L Thompson 991*b7c9bbdaSJeremy L Thompson @param op CeedOperator 992*b7c9bbdaSJeremy L Thompson @param[out] num_elem Variable to store number of elements 993*b7c9bbdaSJeremy L Thompson 994*b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 995*b7c9bbdaSJeremy L Thompson 996*b7c9bbdaSJeremy L Thompson @ref Advanced 997*b7c9bbdaSJeremy L Thompson **/ 998*b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumElements(CeedOperator op, CeedInt *num_elem) { 999*b7c9bbdaSJeremy L Thompson if (op->is_composite) 1000*b7c9bbdaSJeremy L Thompson // LCOV_EXCL_START 1001*b7c9bbdaSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 1002*b7c9bbdaSJeremy L Thompson "Not defined for composite operator"); 1003*b7c9bbdaSJeremy L Thompson // LCOV_EXCL_STOP 1004*b7c9bbdaSJeremy L Thompson 1005*b7c9bbdaSJeremy L Thompson *num_elem = op->num_elem; 1006*b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1007*b7c9bbdaSJeremy L Thompson } 1008*b7c9bbdaSJeremy L Thompson 1009*b7c9bbdaSJeremy L Thompson /** 1010*b7c9bbdaSJeremy L Thompson @brief Get the number of quadrature points associated with a CeedOperator 1011*b7c9bbdaSJeremy L Thompson 1012*b7c9bbdaSJeremy L Thompson @param op CeedOperator 1013*b7c9bbdaSJeremy L Thompson @param[out] num_qpts Variable to store vector number of quadrature points 1014*b7c9bbdaSJeremy L Thompson 1015*b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1016*b7c9bbdaSJeremy L Thompson 1017*b7c9bbdaSJeremy L Thompson @ref Advanced 1018*b7c9bbdaSJeremy L Thompson **/ 1019*b7c9bbdaSJeremy L Thompson int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *num_qpts) { 1020*b7c9bbdaSJeremy L Thompson if (op->is_composite) 1021*b7c9bbdaSJeremy L Thompson // LCOV_EXCL_START 1022*b7c9bbdaSJeremy L Thompson return CeedError(op->ceed, CEED_ERROR_MINOR, 1023*b7c9bbdaSJeremy L Thompson "Not defined for composite operator"); 1024*b7c9bbdaSJeremy L Thompson // LCOV_EXCL_STOP 1025*b7c9bbdaSJeremy L Thompson 1026*b7c9bbdaSJeremy L Thompson *num_qpts = op->num_qpts; 1027*b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1028*b7c9bbdaSJeremy L Thompson } 1029*b7c9bbdaSJeremy L Thompson 1030*b7c9bbdaSJeremy L Thompson /** 10313bd813ffSjeremylt @brief Apply CeedOperator to a vector 1032d7b241e6Sjeremylt 1033d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 1034d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 1035d7b241e6Sjeremylt CeedOperatorSetField(). 1036d7b241e6Sjeremylt 1037f04ea552SJeremy L Thompson Note: Calling this function asserts that setup is complete 1038f04ea552SJeremy L Thompson and sets the CeedOperator as immutable. 1039f04ea552SJeremy L Thompson 1040d7b241e6Sjeremylt @param op CeedOperator to apply 10414cc79fe7SJed Brown @param[in] in CeedVector containing input state or @ref CEED_VECTOR_NONE if 104234138859Sjeremylt there are no active inputs 1043b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 10444cc79fe7SJed Brown distinct from @a in) or @ref CEED_VECTOR_NONE if there are no 104534138859Sjeremylt active outputs 1046d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 10474cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1048b11c1e72Sjeremylt 1049b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1050dfdf5a53Sjeremylt 10517a982d89SJeremy L. Thompson @ref User 1052b11c1e72Sjeremylt **/ 1053692c2638Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, 1054692c2638Sjeremylt CeedRequest *request) { 1055d7b241e6Sjeremylt int ierr; 1056e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1057d7b241e6Sjeremylt 1058d1d35e2fSjeremylt if (op->num_elem) { 1059250756a7Sjeremylt // Standard Operator 1060cae8b89aSjeremylt if (op->Apply) { 1061250756a7Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 1062cae8b89aSjeremylt } else { 1063cae8b89aSjeremylt // Zero all output vectors 1064250756a7Sjeremylt CeedQFunction qf = op->qf; 1065d1d35e2fSjeremylt for (CeedInt i=0; i<qf->num_output_fields; i++) { 1066d1d35e2fSjeremylt CeedVector vec = op->output_fields[i]->vec; 1067cae8b89aSjeremylt if (vec == CEED_VECTOR_ACTIVE) 1068cae8b89aSjeremylt vec = out; 1069cae8b89aSjeremylt if (vec != CEED_VECTOR_NONE) { 1070cae8b89aSjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1071cae8b89aSjeremylt } 1072cae8b89aSjeremylt } 1073250756a7Sjeremylt // Apply 1074250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1075250756a7Sjeremylt } 1076f04ea552SJeremy L Thompson } else if (op->is_composite) { 1077250756a7Sjeremylt // Composite Operator 1078250756a7Sjeremylt if (op->ApplyComposite) { 1079250756a7Sjeremylt ierr = op->ApplyComposite(op, in, out, request); CeedChk(ierr); 1080250756a7Sjeremylt } else { 1081d1d35e2fSjeremylt CeedInt num_suboperators; 1082d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1083d1d35e2fSjeremylt CeedOperator *sub_operators; 1084d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1085250756a7Sjeremylt 1086250756a7Sjeremylt // Zero all output vectors 1087250756a7Sjeremylt if (out != CEED_VECTOR_NONE) { 1088cae8b89aSjeremylt ierr = CeedVectorSetValue(out, 0.0); CeedChk(ierr); 1089cae8b89aSjeremylt } 1090d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1091d1d35e2fSjeremylt for (CeedInt j=0; j<sub_operators[i]->qf->num_output_fields; j++) { 1092d1d35e2fSjeremylt CeedVector vec = sub_operators[i]->output_fields[j]->vec; 1093250756a7Sjeremylt if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) { 1094250756a7Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 1095250756a7Sjeremylt } 1096250756a7Sjeremylt } 1097250756a7Sjeremylt } 1098250756a7Sjeremylt // Apply 1099d1d35e2fSjeremylt for (CeedInt i=0; i<op->num_suboperators; i++) { 1100d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(op->sub_operators[i], in, out, request); 1101cae8b89aSjeremylt CeedChk(ierr); 1102cae8b89aSjeremylt } 1103cae8b89aSjeremylt } 1104250756a7Sjeremylt } 1105e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1106cae8b89aSjeremylt } 1107cae8b89aSjeremylt 1108cae8b89aSjeremylt /** 1109cae8b89aSjeremylt @brief Apply CeedOperator to a vector and add result to output vector 1110cae8b89aSjeremylt 1111cae8b89aSjeremylt This computes the action of the operator on the specified (active) input, 1112cae8b89aSjeremylt yielding its (active) output. All inputs and outputs must be specified using 1113cae8b89aSjeremylt CeedOperatorSetField(). 1114cae8b89aSjeremylt 1115cae8b89aSjeremylt @param op CeedOperator to apply 1116cae8b89aSjeremylt @param[in] in CeedVector containing input state or NULL if there are no 1117cae8b89aSjeremylt active inputs 1118cae8b89aSjeremylt @param[out] out CeedVector to sum in result of applying operator (must be 1119cae8b89aSjeremylt distinct from @a in) or NULL if there are no active outputs 1120cae8b89aSjeremylt @param request Address of CeedRequest for non-blocking completion, else 11214cc79fe7SJed Brown @ref CEED_REQUEST_IMMEDIATE 1122cae8b89aSjeremylt 1123cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 1124cae8b89aSjeremylt 11257a982d89SJeremy L. Thompson @ref User 1126cae8b89aSjeremylt **/ 1127cae8b89aSjeremylt int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, 1128cae8b89aSjeremylt CeedRequest *request) { 1129cae8b89aSjeremylt int ierr; 1130e2f04181SAndrew T. Barker ierr = CeedOperatorCheckReady(op); CeedChk(ierr); 1131cae8b89aSjeremylt 1132d1d35e2fSjeremylt if (op->num_elem) { 1133250756a7Sjeremylt // Standard Operator 1134250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 1135f04ea552SJeremy L Thompson } else if (op->is_composite) { 1136250756a7Sjeremylt // Composite Operator 1137250756a7Sjeremylt if (op->ApplyAddComposite) { 1138250756a7Sjeremylt ierr = op->ApplyAddComposite(op, in, out, request); CeedChk(ierr); 1139cae8b89aSjeremylt } else { 1140d1d35e2fSjeremylt CeedInt num_suboperators; 1141d1d35e2fSjeremylt ierr = CeedOperatorGetNumSub(op, &num_suboperators); CeedChk(ierr); 1142d1d35e2fSjeremylt CeedOperator *sub_operators; 1143d1d35e2fSjeremylt ierr = CeedOperatorGetSubList(op, &sub_operators); CeedChk(ierr); 1144250756a7Sjeremylt 1145d1d35e2fSjeremylt for (CeedInt i=0; i<num_suboperators; i++) { 1146d1d35e2fSjeremylt ierr = CeedOperatorApplyAdd(sub_operators[i], in, out, request); 1147cae8b89aSjeremylt CeedChk(ierr); 11481d7d2407SJeremy L Thompson } 1149250756a7Sjeremylt } 1150250756a7Sjeremylt } 1151e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1152d7b241e6Sjeremylt } 1153d7b241e6Sjeremylt 1154d7b241e6Sjeremylt /** 1155b11c1e72Sjeremylt @brief Destroy a CeedOperator 1156d7b241e6Sjeremylt 1157d7b241e6Sjeremylt @param op CeedOperator to destroy 1158b11c1e72Sjeremylt 1159b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1160dfdf5a53Sjeremylt 11617a982d89SJeremy L. Thompson @ref User 1162b11c1e72Sjeremylt **/ 1163d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 1164d7b241e6Sjeremylt int ierr; 1165d7b241e6Sjeremylt 1166d1d35e2fSjeremylt if (!*op || --(*op)->ref_count > 0) return CEED_ERROR_SUCCESS; 1167d7b241e6Sjeremylt if ((*op)->Destroy) { 1168d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 1169d7b241e6Sjeremylt } 1170fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 1171fe2413ffSjeremylt // Free fields 1172d1d35e2fSjeremylt for (int i=0; i<(*op)->num_fields; i++) 1173d1d35e2fSjeremylt if ((*op)->input_fields[i]) { 1174d1d35e2fSjeremylt if ((*op)->input_fields[i]->elem_restr != CEED_ELEMRESTRICTION_NONE) { 1175d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->input_fields[i]->elem_restr); 117671352a93Sjeremylt CeedChk(ierr); 117715910d16Sjeremylt } 1178d1d35e2fSjeremylt if ((*op)->input_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1179d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->input_fields[i]->basis); CeedChk(ierr); 118071352a93Sjeremylt } 1181d1d35e2fSjeremylt if ((*op)->input_fields[i]->vec != CEED_VECTOR_ACTIVE && 1182d1d35e2fSjeremylt (*op)->input_fields[i]->vec != CEED_VECTOR_NONE ) { 1183d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->input_fields[i]->vec); CeedChk(ierr); 118471352a93Sjeremylt } 1185d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]->field_name); CeedChk(ierr); 1186d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields[i]); CeedChk(ierr); 1187fe2413ffSjeremylt } 1188d1d35e2fSjeremylt for (int i=0; i<(*op)->num_fields; i++) 1189d1d35e2fSjeremylt if ((*op)->output_fields[i]) { 1190d1d35e2fSjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->output_fields[i]->elem_restr); 119171352a93Sjeremylt CeedChk(ierr); 1192d1d35e2fSjeremylt if ((*op)->output_fields[i]->basis != CEED_BASIS_COLLOCATED) { 1193d1d35e2fSjeremylt ierr = CeedBasisDestroy(&(*op)->output_fields[i]->basis); CeedChk(ierr); 119471352a93Sjeremylt } 1195d1d35e2fSjeremylt if ((*op)->output_fields[i]->vec != CEED_VECTOR_ACTIVE && 1196d1d35e2fSjeremylt (*op)->output_fields[i]->vec != CEED_VECTOR_NONE ) { 1197d1d35e2fSjeremylt ierr = CeedVectorDestroy(&(*op)->output_fields[i]->vec); CeedChk(ierr); 119871352a93Sjeremylt } 1199d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]->field_name); CeedChk(ierr); 1200d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields[i]); CeedChk(ierr); 1201fe2413ffSjeremylt } 1202d1d35e2fSjeremylt // Destroy sub_operators 1203d1d35e2fSjeremylt for (int i=0; i<(*op)->num_suboperators; i++) 1204d1d35e2fSjeremylt if ((*op)->sub_operators[i]) { 1205d1d35e2fSjeremylt ierr = CeedOperatorDestroy(&(*op)->sub_operators[i]); CeedChk(ierr); 120652d6035fSJeremy L Thompson } 1207d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 1208d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 1209d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 1210fe2413ffSjeremylt 12115107b09fSJeremy L Thompson // Destroy fallback 1212d1d35e2fSjeremylt if ((*op)->op_fallback) { 1213d1d35e2fSjeremylt ierr = (*op)->qf_fallback->Destroy((*op)->qf_fallback); CeedChk(ierr); 1214d1d35e2fSjeremylt ierr = CeedFree(&(*op)->qf_fallback); CeedChk(ierr); 1215d1d35e2fSjeremylt ierr = (*op)->op_fallback->Destroy((*op)->op_fallback); CeedChk(ierr); 1216d1d35e2fSjeremylt ierr = CeedFree(&(*op)->op_fallback); CeedChk(ierr); 12175107b09fSJeremy L Thompson } 12185107b09fSJeremy L Thompson 1219d1d35e2fSjeremylt ierr = CeedFree(&(*op)->input_fields); CeedChk(ierr); 1220d1d35e2fSjeremylt ierr = CeedFree(&(*op)->output_fields); CeedChk(ierr); 1221d1d35e2fSjeremylt ierr = CeedFree(&(*op)->sub_operators); CeedChk(ierr); 1222d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 1223e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1224d7b241e6Sjeremylt } 1225d7b241e6Sjeremylt 1226d7b241e6Sjeremylt /// @} 1227